This macro has been introduced because:
#1. While VM doesing GC or compacting, the instances inside Java heap might be moved around, which will make the pointers in native code point to illegal address. Using this macro can help GCer to update the reference accordingly after shifting the corresponding instance in Java heap.
#2. The C stack will not be scanned when VM does GC or compacting, means the Java instances been created in native code might be GCed.
Thus you may have your implementation like this:
Note the declared `ary' actually is either a C global or local variable, and the poped out handle is its initial value.
START_TEMPORARY_ROOTS
DECLARE_TEMPORARY_ROOT(ARRAY, ary, popStackAsType(ARRAY));
values = nativeGetValues(); // A native funciton may cause GC or compaction
KNI_SetIntArrayElement(ary, 0, values[0]); // `ary' still remains valid
...
END_TEMPORARY_ROOT
One more thing need to be careful is:
@KVM Porting Guide - An instance method (non-static method) must pop the this argument off the stack after it has popped the rest of the arguments. Failing to pop the this argument in a native instance method will almost surely cause a fatal error in the virtual machine.
But I don't know exactly the reason, I guess that fails the assumption of stack pointer.
No comments:
Post a Comment