Fix JNI Compiler for x86 target
Change-Id: Ia247de328d234c4a57ddd93f394cad2c63e48153
diff --git a/src/jni_compiler_test.cc b/src/jni_compiler_test.cc
index e1332d3..72b5848 100644
--- a/src/jni_compiler_test.cc
+++ b/src/jni_compiler_test.cc
@@ -50,12 +50,12 @@
} else {
method = c->FindVirtualMethod(method_name, method_sig);
}
- ASSERT_TRUE(method != NULL);
+ ASSERT_TRUE(method != NULL) << method_name << " " << method_sig;
if (method->GetCode() != NULL) {
return;
}
CompileMethod(method);
- ASSERT_TRUE(method->GetCode() != NULL);
+ ASSERT_TRUE(method->GetCode() != NULL) << method_name << " " << method_sig;
}
void SetUpForTest(bool direct, const char* method_name, const char* method_sig,
@@ -74,25 +74,26 @@
// JNI operations after runtime start.
env_ = Thread::Current()->GetJniEnv();
jklass_ = env_->FindClass("MyClassNatives");
- ASSERT_TRUE(jklass_ != NULL);
+ ASSERT_TRUE(jklass_ != NULL) << method_name << " " << method_sig;
if (direct) {
jmethod_ = env_->GetStaticMethodID(jklass_, method_name, method_sig);
} else {
jmethod_ = env_->GetMethodID(jklass_, method_name, method_sig);
}
- ASSERT_TRUE(jmethod_ != NULL);
+ ASSERT_TRUE(jmethod_ != NULL) << method_name << " " << method_sig;
if (native_fnptr != NULL) {
JNINativeMethod methods[] = { { method_name, method_sig, native_fnptr } };
- ASSERT_EQ(JNI_OK, env_->RegisterNatives(jklass_, methods, 1));
+ ASSERT_EQ(JNI_OK, env_->RegisterNatives(jklass_, methods, 1))
+ << method_name << " " << method_sig;
} else {
env_->UnregisterNatives(jklass_);
}
jmethodID constructor = env_->GetMethodID(jklass_, "<init>", "()V");
jobj_ = env_->NewObject(jklass_, constructor);
- ASSERT_TRUE(jobj_ != NULL);
+ ASSERT_TRUE(jobj_ != NULL) << method_name << " " << method_sig;
}
public:
@@ -695,6 +696,11 @@
EXPECT_EQ(result, 42);
}
+TEST_F(JniCompilerTest, GetSinkPropertiesNative) {
+ SetUpForTest(false, "getSinkPropertiesNative", "(Ljava/lang/String;)[Ljava/lang/Object;", NULL);
+ // This space intentionally left blank. Just testing compilation succeeds.
+}
+
// This should return jclass, but we're imitating a bug pattern.
jobject Java_MyClassNatives_instanceMethodThatShouldReturnClass(JNIEnv* env, jobject) {
return env->NewStringUTF("not a class!");
diff --git a/src/oat/jni/jni_compiler.cc b/src/oat/jni/jni_compiler.cc
index 9122945..dc1bfc7 100644
--- a/src/oat/jni/jni_compiler.cc
+++ b/src/oat/jni/jni_compiler.cc
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <algorithm>
#include <vector>
#include "calling_convention.h"
@@ -63,11 +64,24 @@
instruction_set = kArm;
}
// Calling conventions used to iterate over parameters to method
- UniquePtr<JniCallingConvention> jni_conv(
+ UniquePtr<JniCallingConvention> main_jni_conv(
JniCallingConvention::Create(is_static, is_synchronized, shorty, instruction_set));
+ bool reference_return = main_jni_conv->IsReturnAReference();
+
UniquePtr<ManagedRuntimeCallingConvention> mr_conv(
ManagedRuntimeCallingConvention::Create(is_static, is_synchronized, shorty, instruction_set));
+ // Calling conventions to call into JNI method "end" possibly passing a returned reference, the
+ // method and the current thread.
+ size_t jni_end_arg_count = 0;
+ if (reference_return) { jni_end_arg_count++; }
+ if (is_synchronized) { jni_end_arg_count++; }
+ const char* jni_end_shorty = jni_end_arg_count == 0 ? "I"
+ : (jni_end_arg_count == 1 ? "II" : "III");
+ UniquePtr<JniCallingConvention> end_jni_conv(
+ JniCallingConvention::Create(is_static, is_synchronized, jni_end_shorty, instruction_set));
+
+
// Assembler that holds generated instructions
UniquePtr<Assembler> jni_asm(Assembler::Create(instruction_set));
bool should_disassemble = false;
@@ -79,49 +93,49 @@
const Offset monitor_exit(OFFSETOF_MEMBER(JNINativeInterface, MonitorExit));
// 1. Build the frame saving all callee saves
- const size_t frame_size(jni_conv->FrameSize());
- const std::vector<ManagedRegister>& callee_save_regs = jni_conv->CalleeSaveRegisters();
+ const size_t frame_size(main_jni_conv->FrameSize());
+ const std::vector<ManagedRegister>& callee_save_regs = main_jni_conv->CalleeSaveRegisters();
__ BuildFrame(frame_size, mr_conv->MethodRegister(), callee_save_regs, mr_conv->EntrySpills());
// 2. Set up the StackIndirectReferenceTable
mr_conv->ResetIterator(FrameOffset(frame_size));
- jni_conv->ResetIterator(FrameOffset(0));
- __ StoreImmediateToFrame(jni_conv->SirtNumRefsOffset(),
- jni_conv->ReferenceCount(),
+ main_jni_conv->ResetIterator(FrameOffset(0));
+ __ StoreImmediateToFrame(main_jni_conv->SirtNumRefsOffset(),
+ main_jni_conv->ReferenceCount(),
mr_conv->InterproceduralScratchRegister());
- __ CopyRawPtrFromThread(jni_conv->SirtLinkOffset(),
+ __ CopyRawPtrFromThread(main_jni_conv->SirtLinkOffset(),
Thread::TopSirtOffset(),
mr_conv->InterproceduralScratchRegister());
__ StoreStackOffsetToThread(Thread::TopSirtOffset(),
- jni_conv->SirtOffset(),
+ main_jni_conv->SirtOffset(),
mr_conv->InterproceduralScratchRegister());
// 3. Place incoming reference arguments into SIRT
- jni_conv->Next(); // Skip JNIEnv*
+ main_jni_conv->Next(); // Skip JNIEnv*
// 3.5. Create Class argument for static methods out of passed method
if (is_static) {
- FrameOffset sirt_offset = jni_conv->CurrentParamSirtEntryOffset();
+ FrameOffset sirt_offset = main_jni_conv->CurrentParamSirtEntryOffset();
// Check sirt offset is within frame
CHECK_LT(sirt_offset.Uint32Value(), frame_size);
- __ LoadRef(jni_conv->InterproceduralScratchRegister(),
+ __ LoadRef(main_jni_conv->InterproceduralScratchRegister(),
mr_conv->MethodRegister(), Method::DeclaringClassOffset());
- __ VerifyObject(jni_conv->InterproceduralScratchRegister(), false);
- __ StoreRef(sirt_offset, jni_conv->InterproceduralScratchRegister());
- jni_conv->Next(); // in SIRT so move to next argument
+ __ VerifyObject(main_jni_conv->InterproceduralScratchRegister(), false);
+ __ StoreRef(sirt_offset, main_jni_conv->InterproceduralScratchRegister());
+ main_jni_conv->Next(); // in SIRT so move to next argument
}
while (mr_conv->HasNext()) {
- CHECK(jni_conv->HasNext());
- bool ref_param = jni_conv->IsCurrentParamAReference();
+ CHECK(main_jni_conv->HasNext());
+ bool ref_param = main_jni_conv->IsCurrentParamAReference();
CHECK(!ref_param || mr_conv->IsCurrentParamAReference());
// References need placing in SIRT and the entry value passing
if (ref_param) {
// Compute SIRT entry, note null is placed in the SIRT but its boxed value
// must be NULL
- FrameOffset sirt_offset = jni_conv->CurrentParamSirtEntryOffset();
+ FrameOffset sirt_offset = main_jni_conv->CurrentParamSirtEntryOffset();
// Check SIRT offset is within frame and doesn't run into the saved segment state
CHECK_LT(sirt_offset.Uint32Value(), frame_size);
CHECK_NE(sirt_offset.Uint32Value(),
- jni_conv->SavedLocalReferenceCookieOffset().Uint32Value());
+ main_jni_conv->SavedLocalReferenceCookieOffset().Uint32Value());
bool input_in_reg = mr_conv->IsCurrentParamInRegister();
bool input_on_stack = mr_conv->IsCurrentParamOnStack();
CHECK(input_in_reg || input_on_stack);
@@ -138,7 +152,7 @@
}
}
mr_conv->Next();
- jni_conv->Next();
+ main_jni_conv->Next();
}
// 4. Write out the end of the quick frames.
@@ -147,8 +161,10 @@
mr_conv->InterproceduralScratchRegister());
// 5. Move frame down to allow space for out going args.
- const size_t out_arg_size = jni_conv->OutArgSize();
- __ IncreaseFrameSize(out_arg_size);
+ const size_t main_out_arg_size = main_jni_conv->OutArgSize();
+ const size_t end_out_arg_size = end_jni_conv->OutArgSize();
+ const size_t max_out_arg_size = std::max(main_out_arg_size, end_out_arg_size);
+ __ IncreaseFrameSize(max_out_arg_size);
// 6. Call into appropriate JniMethodStart passing Thread* so that transition out of Runnable
@@ -157,39 +173,39 @@
// arguments.
uintptr_t jni_start = is_synchronized ? ENTRYPOINT_OFFSET(pJniMethodStartSynchronized)
: ENTRYPOINT_OFFSET(pJniMethodStart);
- jni_conv->ResetIterator(FrameOffset(out_arg_size));
+ main_jni_conv->ResetIterator(FrameOffset(main_out_arg_size));
FrameOffset locked_object_sirt_offset(0);
if (is_synchronized) {
// Pass object for locking.
- jni_conv->Next(); // Skip JNIEnv.
- locked_object_sirt_offset = jni_conv->CurrentParamSirtEntryOffset();
- jni_conv->ResetIterator(FrameOffset(out_arg_size));
- if (jni_conv->IsCurrentParamOnStack()) {
- FrameOffset out_off = jni_conv->CurrentParamStackOffset();
+ main_jni_conv->Next(); // Skip JNIEnv.
+ locked_object_sirt_offset = main_jni_conv->CurrentParamSirtEntryOffset();
+ main_jni_conv->ResetIterator(FrameOffset(main_out_arg_size));
+ if (main_jni_conv->IsCurrentParamOnStack()) {
+ FrameOffset out_off = main_jni_conv->CurrentParamStackOffset();
__ CreateSirtEntry(out_off, locked_object_sirt_offset,
mr_conv->InterproceduralScratchRegister(),
false);
} else {
- ManagedRegister out_reg = jni_conv->CurrentParamRegister();
+ ManagedRegister out_reg = main_jni_conv->CurrentParamRegister();
__ CreateSirtEntry(out_reg, locked_object_sirt_offset,
ManagedRegister::NoRegister(), false);
}
- jni_conv->Next();
+ main_jni_conv->Next();
}
- if (jni_conv->IsCurrentParamInRegister()) {
- __ GetCurrentThread(jni_conv->CurrentParamRegister());
- __ Call(jni_conv->CurrentParamRegister(), Offset(jni_start),
- jni_conv->InterproceduralScratchRegister());
+ if (main_jni_conv->IsCurrentParamInRegister()) {
+ __ GetCurrentThread(main_jni_conv->CurrentParamRegister());
+ __ Call(main_jni_conv->CurrentParamRegister(), Offset(jni_start),
+ main_jni_conv->InterproceduralScratchRegister());
} else {
- __ GetCurrentThread(jni_conv->CurrentParamStackOffset(),
- jni_conv->InterproceduralScratchRegister());
- __ Call(ThreadOffset(jni_start), jni_conv->InterproceduralScratchRegister());
+ __ GetCurrentThread(main_jni_conv->CurrentParamStackOffset(),
+ main_jni_conv->InterproceduralScratchRegister());
+ __ Call(ThreadOffset(jni_start), main_jni_conv->InterproceduralScratchRegister());
}
if (is_synchronized) { // Check for exceptions from monitor enter.
- __ ExceptionPoll(jni_conv->InterproceduralScratchRegister(), out_arg_size);
+ __ ExceptionPoll(main_jni_conv->InterproceduralScratchRegister(), main_out_arg_size);
}
- FrameOffset saved_cookie_offset = jni_conv->SavedLocalReferenceCookieOffset();
- __ Store(saved_cookie_offset, jni_conv->IntReturnRegister(), 4);
+ FrameOffset saved_cookie_offset = main_jni_conv->SavedLocalReferenceCookieOffset();
+ __ Store(saved_cookie_offset, main_jni_conv->IntReturnRegister(), 4);
// 7. Iterate over arguments placing values from managed calling convention in
// to the convention required for a native call (shuffling). For references
@@ -197,7 +213,7 @@
// NULL (which must be encoded as NULL).
// Note: we do this prior to materializing the JNIEnv* and static's jclass to
// give as many free registers for the shuffle as possible
- mr_conv->ResetIterator(FrameOffset(frame_size+out_arg_size));
+ mr_conv->ResetIterator(FrameOffset(frame_size+main_out_arg_size));
uint32_t args_count = 0;
while (mr_conv->HasNext()) {
args_count++;
@@ -208,145 +224,131 @@
// R2, R3; mov R1, R2" instead of "mov R1, R2; mov R2, R3."
// TODO: A reverse iterator to improve readability.
for (uint32_t i = 0; i < args_count; ++i) {
- mr_conv->ResetIterator(FrameOffset(frame_size + out_arg_size));
- jni_conv->ResetIterator(FrameOffset(out_arg_size));
- jni_conv->Next(); // Skip JNIEnv*.
+ mr_conv->ResetIterator(FrameOffset(frame_size + main_out_arg_size));
+ main_jni_conv->ResetIterator(FrameOffset(main_out_arg_size));
+ main_jni_conv->Next(); // Skip JNIEnv*.
if (is_static) {
- jni_conv->Next(); // Skip Class for now.
+ main_jni_conv->Next(); // Skip Class for now.
}
// Skip to the argument we're interested in.
for (uint32_t j = 0; j < args_count - i - 1; ++j) {
mr_conv->Next();
- jni_conv->Next();
+ main_jni_conv->Next();
}
- CopyParameter(jni_asm.get(), mr_conv.get(), jni_conv.get(), frame_size, out_arg_size);
+ CopyParameter(jni_asm.get(), mr_conv.get(), main_jni_conv.get(), frame_size, main_out_arg_size);
}
if (is_static) {
// Create argument for Class
- mr_conv->ResetIterator(FrameOffset(frame_size+out_arg_size));
- jni_conv->ResetIterator(FrameOffset(out_arg_size));
- jni_conv->Next(); // Skip JNIEnv*
- FrameOffset sirt_offset = jni_conv->CurrentParamSirtEntryOffset();
- if (jni_conv->IsCurrentParamOnStack()) {
- FrameOffset out_off = jni_conv->CurrentParamStackOffset();
+ mr_conv->ResetIterator(FrameOffset(frame_size+main_out_arg_size));
+ main_jni_conv->ResetIterator(FrameOffset(main_out_arg_size));
+ main_jni_conv->Next(); // Skip JNIEnv*
+ FrameOffset sirt_offset = main_jni_conv->CurrentParamSirtEntryOffset();
+ if (main_jni_conv->IsCurrentParamOnStack()) {
+ FrameOffset out_off = main_jni_conv->CurrentParamStackOffset();
__ CreateSirtEntry(out_off, sirt_offset,
mr_conv->InterproceduralScratchRegister(),
false);
} else {
- ManagedRegister out_reg = jni_conv->CurrentParamRegister();
+ ManagedRegister out_reg = main_jni_conv->CurrentParamRegister();
__ CreateSirtEntry(out_reg, sirt_offset,
ManagedRegister::NoRegister(), false);
}
}
// 8. Create 1st argument, the JNI environment ptr.
- jni_conv->ResetIterator(FrameOffset(out_arg_size));
+ main_jni_conv->ResetIterator(FrameOffset(main_out_arg_size));
// Register that will hold local indirect reference table
- if (jni_conv->IsCurrentParamInRegister()) {
- ManagedRegister jni_env = jni_conv->CurrentParamRegister();
- DCHECK(!jni_env.Equals(jni_conv->InterproceduralScratchRegister()));
+ if (main_jni_conv->IsCurrentParamInRegister()) {
+ ManagedRegister jni_env = main_jni_conv->CurrentParamRegister();
+ DCHECK(!jni_env.Equals(main_jni_conv->InterproceduralScratchRegister()));
__ LoadRawPtrFromThread(jni_env, Thread::JniEnvOffset());
} else {
- FrameOffset jni_env = jni_conv->CurrentParamStackOffset();
+ FrameOffset jni_env = main_jni_conv->CurrentParamStackOffset();
__ CopyRawPtrFromThread(jni_env, Thread::JniEnvOffset(),
- jni_conv->InterproceduralScratchRegister());
+ main_jni_conv->InterproceduralScratchRegister());
}
// 9. Plant call to native code associated with method.
- __ Call(jni_conv->MethodStackOffset(), Method::NativeMethodOffset(),
+ __ Call(main_jni_conv->MethodStackOffset(), Method::NativeMethodOffset(),
mr_conv->InterproceduralScratchRegister());
// 10. Fix differences in result widths.
if (instruction_set == kX86) {
- if (jni_conv->GetReturnType() == Primitive::kPrimByte ||
- jni_conv->GetReturnType() == Primitive::kPrimShort) {
- __ SignExtend(jni_conv->ReturnRegister(),
- Primitive::ComponentSize(jni_conv->GetReturnType()));
- } else if (jni_conv->GetReturnType() == Primitive::kPrimBoolean ||
- jni_conv->GetReturnType() == Primitive::kPrimChar) {
- __ ZeroExtend(jni_conv->ReturnRegister(),
- Primitive::ComponentSize(jni_conv->GetReturnType()));
+ if (main_jni_conv->GetReturnType() == Primitive::kPrimByte ||
+ main_jni_conv->GetReturnType() == Primitive::kPrimShort) {
+ __ SignExtend(main_jni_conv->ReturnRegister(),
+ Primitive::ComponentSize(main_jni_conv->GetReturnType()));
+ } else if (main_jni_conv->GetReturnType() == Primitive::kPrimBoolean ||
+ main_jni_conv->GetReturnType() == Primitive::kPrimChar) {
+ __ ZeroExtend(main_jni_conv->ReturnRegister(),
+ Primitive::ComponentSize(main_jni_conv->GetReturnType()));
}
}
// 11. Save return value
- bool reference_return = jni_conv->IsReturnAReference();
- FrameOffset return_save_location = jni_conv->ReturnValueSaveLocation();
- if (jni_conv->SizeOfReturnValue() != 0 && !reference_return) {
- CHECK_LT(return_save_location.Uint32Value(), frame_size+out_arg_size);
- __ Store(return_save_location, jni_conv->ReturnRegister(), jni_conv->SizeOfReturnValue());
+ FrameOffset return_save_location = main_jni_conv->ReturnValueSaveLocation();
+ if (main_jni_conv->SizeOfReturnValue() != 0 && !reference_return) {
+ CHECK_LT(return_save_location.Uint32Value(), frame_size+main_out_arg_size);
+ __ Store(return_save_location, main_jni_conv->ReturnRegister(), main_jni_conv->SizeOfReturnValue());
}
// 12. Call into JNI method end possibly passing a returned reference, the method and the current
// thread.
- {
- // Modify iterator for call, important offsets were saved above.
- size_t jni_end_arg_count = 0;
- if (reference_return) { jni_end_arg_count++; }
- if (is_synchronized) { jni_end_arg_count++; }
- const char* jni_end_shorty = jni_end_arg_count == 0 ? "I"
- : (jni_end_arg_count == 1 ? "II" : "III");
- jni_conv.reset(JniCallingConvention::Create(is_static, is_synchronized, jni_end_shorty,
- instruction_set));
- // Ensure out arguments will fit in space taken before (we expect this due to stack alignment).
- size_t jni_end_out_arg_size = jni_conv->OutArgSize();
- CHECK_LE(jni_end_out_arg_size, out_arg_size);
- jni_conv->ResetIterator(FrameOffset(jni_end_out_arg_size));
- }
+ end_jni_conv->ResetIterator(FrameOffset(end_out_arg_size));
uintptr_t jni_end;
if (reference_return) {
// Pass result.
jni_end = is_synchronized ? ENTRYPOINT_OFFSET(pJniMethodEndWithReferenceSynchronized)
: ENTRYPOINT_OFFSET(pJniMethodEndWithReference);
- SetNativeParameter(jni_asm.get(), jni_conv.get(), jni_conv->ReturnRegister());
- jni_conv->Next();
+ SetNativeParameter(jni_asm.get(), end_jni_conv.get(), end_jni_conv->ReturnRegister());
+ end_jni_conv->Next();
} else {
jni_end = is_synchronized ? ENTRYPOINT_OFFSET(pJniMethodEndSynchronized)
: ENTRYPOINT_OFFSET(pJniMethodEnd);
}
// Pass saved local reference state.
- if (jni_conv->IsCurrentParamOnStack()) {
- FrameOffset out_off = jni_conv->CurrentParamStackOffset();
- __ Copy(out_off, saved_cookie_offset, jni_conv->InterproceduralScratchRegister(), 4);
+ if (end_jni_conv->IsCurrentParamOnStack()) {
+ FrameOffset out_off = end_jni_conv->CurrentParamStackOffset();
+ __ Copy(out_off, saved_cookie_offset, end_jni_conv->InterproceduralScratchRegister(), 4);
} else {
- ManagedRegister out_reg = jni_conv->CurrentParamRegister();
+ ManagedRegister out_reg = end_jni_conv->CurrentParamRegister();
__ Load(out_reg, saved_cookie_offset, 4);
}
- jni_conv->Next();
+ end_jni_conv->Next();
if (is_synchronized) {
// Pass object for unlocking.
- if (jni_conv->IsCurrentParamOnStack()) {
- FrameOffset out_off = jni_conv->CurrentParamStackOffset();
+ if (end_jni_conv->IsCurrentParamOnStack()) {
+ FrameOffset out_off = end_jni_conv->CurrentParamStackOffset();
__ CreateSirtEntry(out_off, locked_object_sirt_offset,
- jni_conv->InterproceduralScratchRegister(),
+ end_jni_conv->InterproceduralScratchRegister(),
false);
} else {
- ManagedRegister out_reg = jni_conv->CurrentParamRegister();
+ ManagedRegister out_reg = end_jni_conv->CurrentParamRegister();
__ CreateSirtEntry(out_reg, locked_object_sirt_offset,
ManagedRegister::NoRegister(), false);
}
- jni_conv->Next();
+ end_jni_conv->Next();
}
- if (jni_conv->IsCurrentParamInRegister()) {
- __ GetCurrentThread(jni_conv->CurrentParamRegister());
- __ Call(jni_conv->CurrentParamRegister(), Offset(jni_end),
- jni_conv->InterproceduralScratchRegister());
+ if (end_jni_conv->IsCurrentParamInRegister()) {
+ __ GetCurrentThread(end_jni_conv->CurrentParamRegister());
+ __ Call(end_jni_conv->CurrentParamRegister(), Offset(jni_end),
+ end_jni_conv->InterproceduralScratchRegister());
} else {
- __ GetCurrentThread(jni_conv->CurrentParamStackOffset(),
- jni_conv->InterproceduralScratchRegister());
- __ Call(ThreadOffset(jni_end), jni_conv->InterproceduralScratchRegister());
+ __ GetCurrentThread(end_jni_conv->CurrentParamStackOffset(),
+ end_jni_conv->InterproceduralScratchRegister());
+ __ Call(ThreadOffset(jni_end), end_jni_conv->InterproceduralScratchRegister());
}
// 13. Reload return value
- if (jni_conv->SizeOfReturnValue() != 0 && !reference_return) {
+ if (main_jni_conv->SizeOfReturnValue() != 0 && !reference_return) {
__ Load(mr_conv->ReturnRegister(), return_save_location, mr_conv->SizeOfReturnValue());
}
// 14. Move frame up now we're done with the out arg space.
- __ DecreaseFrameSize(out_arg_size);
+ __ DecreaseFrameSize(max_out_arg_size);
// 15. Process pending exceptions from JNI call or monitor exit.
- __ ExceptionPoll(jni_conv->InterproceduralScratchRegister(), 0);
+ __ ExceptionPoll(main_jni_conv->InterproceduralScratchRegister(), 0);
// 16. Remove activation - no need to restore callee save registers because we didn't clobber
// them.
@@ -365,8 +367,8 @@
return new CompiledMethod(instruction_set,
managed_code,
frame_size,
- jni_conv->CoreSpillMask(),
- jni_conv->FpSpillMask());
+ main_jni_conv->CoreSpillMask(),
+ main_jni_conv->FpSpillMask());
}
// Copy a single parameter from the managed to the JNI calling convention
diff --git a/test/MyClassNatives/MyClassNatives.java b/test/MyClassNatives/MyClassNatives.java
index 2121adf..aec09e5 100644
--- a/test/MyClassNatives/MyClassNatives.java
+++ b/test/MyClassNatives/MyClassNatives.java
@@ -33,6 +33,7 @@
static native void arraycopy(Object src, int src_pos, Object dst, int dst_pos, int length);
native boolean compareAndSwapInt(Object obj, long offset, int expected, int newval);
static native int getText(long val1, Object obj1, long val2, Object obj2);
+ synchronized native Object []getSinkPropertiesNative(String path);
native Class instanceMethodThatShouldReturnClass();
static native Class staticMethodThatShouldReturnClass();