-
Notifications
You must be signed in to change notification settings - Fork 721
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Adjust arguments to transformed UnsafeAPI calls when offheap is enabled #20333
base: master
Are you sure you want to change the base?
Conversation
When Unsafe.getAndAdd()/getAndSet() is called on an array and offheap changes are enabled, adjust arguments so that dataAddr is passed in as the base address of the object. Signed-off-by: midronij <[email protected]>
@zl-wang here is the |
08378b5
to
318add6
Compare
intrinsics during unsafeFastPath During unsafeFastPath, some UnsafeAPI calls (such as Unsafe.getAndAdd()) are converted to atomic intrinsics (such as atomicFetchAndAdd). When this occurs with offheap allocation enabled, and the object is an array, load dataAddr. Signed-off-by: midronij <[email protected]>
318add6
to
88cb0dc
Compare
{ | ||
//generate array check treetop | ||
TR::Node *constNode = TR::Node::lconst(unsafeCall, ~(J9_SUN_FIELD_OFFSET_MASK)); | ||
TR::Node *unsafeAddress = TR::Node::create(TR::aladd, 2, objectNode, TR::Node::create(TR::land, 2, offsetNode, constNode)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how can you do aladd
before you know if it is an array or not? it is unclear to me what purpose this aladd
is for.
TR::Node *unsafeAddress = TR::Node::create(TR::aladd, 2, objectNode, TR::Node::create(TR::land, 2, offsetNode, constNode)); | ||
TR::Node *vftLoad = TR::Node::createWithSymRef(TR::aloadi, 1, 1, | ||
TR::Node::createWithSymRef(unsafeAddress, | ||
comp()->il.opCodeForDirectLoad(unsafeAddress->getDataType()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
directload opcode is for static field i think ... this code looks contradictory to where the addressing is from.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this is consistent with other areas where runtime array checks are performed, such as with Unsafe.get/put():
TR::Node *objLoad = TR::Node::createWithSymRef(unsafeAddress,
comp()->il.opCodeForDirectLoad(unsafeAddress->getDataType()), 0,
newSymbolReferenceForAddress);
TR::Node *vftLoad = TR::Node::createWithSymRef(TR::aloadi, 1, 1, objLoad,
comp()->getSymRefTab()->findOrCreateVftSymbolRef());
.
.
.
TR::Node *testIsArrayFlag = comp()->fej9()->testIsClassArrayType(vftLoad);
TR::Node *isArrayNode = TR::Node::createif(TR::ificmpne, testIsArrayFlag, TR::Node::create(TR::iconst, 0), NULL);
(from genCodeForUnsafeGetPut())
comp()->il.opCodeForDirectLoad(unsafeAddress->getDataType()), | ||
0, | ||
objectNode->getSymbolReference()), | ||
comp()->getSymRefTab()->findOrCreateVftSymbolRef()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't understand this either: you seemed assuming the previous directload result as an object. at the same time, you look up the opcode through a table (while you know the datatype already).
During the running period of our application, from the thread stack, it has been "staying" at AtomicReferenceArray#getAndSet. A phenomenon similar to livelock has occurred. As a result, the thread is blocked and the application is seriously unrecoverable. I am not sure if it is related to your problem? @midronij @zl-wang thread stack: java version: |
During recognizedCallTransformer and unsafeFastPath,
Unsafe.getAndAdd()
orUnsafe.getAndSet()
can be transformed into anatomicFetchAndAdd
/atomicSwap
helper call. For the UnsafeAPI methods, the destination address is passed in as two separate values: a base object address and an offset. When they are transformed into atomic helper calls, these values are added together and passed in as a single destination address value. However, this does not account for the differing shape of array objects under offheap/balanced GC policy (as opposed to the default, gencon).Thus, this contribution includes the following changes
dataAddr
pointer is loaded and used as the base address.dataAddr
is only used if the object is indeed an array.