diff options
-rw-r--r-- | compiler/jni/jni_compiler_test.cc | 12 | ||||
-rw-r--r-- | compiler/utils/x86/jni_macro_assembler_x86.cc | 30 |
2 files changed, 30 insertions, 12 deletions
diff --git a/compiler/jni/jni_compiler_test.cc b/compiler/jni/jni_compiler_test.cc index 4d40418f6c..3ee7e0ed2f 100644 --- a/compiler/jni/jni_compiler_test.cc +++ b/compiler/jni/jni_compiler_test.cc @@ -246,15 +246,23 @@ class JniCompilerTest : public CommonCompilerTest { const char* method_name, const char* method_sig) { ScopedObjectAccess soa(Thread::Current()); - StackHandleScope<1> hs(soa.Self()); + StackHandleScope<2> hs(soa.Self()); Handle<mirror::ClassLoader> loader( hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); // Compile the native method before starting the runtime - ObjPtr<mirror::Class> c = class_linker_->FindClass(soa.Self(), "LMyClassNatives;", loader); + Handle<mirror::Class> c = + hs.NewHandle(class_linker_->FindClass(soa.Self(), "LMyClassNatives;", loader)); const auto pointer_size = class_linker_->GetImagePointerSize(); ArtMethod* method = c->FindClassMethod(method_name, method_sig, pointer_size); ASSERT_TRUE(method != nullptr) << method_name << " " << method_sig; ASSERT_EQ(direct, method->IsDirect()) << method_name << " " << method_sig; + if (direct) { + // Class initialization could replace the entrypoint, so force + // the initialization before we set up the entrypoint below. + class_linker_->EnsureInitialized( + soa.Self(), c, /*can_init_fields=*/ true, /*can_init_parents=*/ true); + class_linker_->MakeInitializedClassesVisiblyInitialized(soa.Self(), /*wait=*/ true); + } if (check_generic_jni_) { method->SetEntryPointFromQuickCompiledCode(class_linker_->GetRuntimeQuickGenericJniStub()); } else { diff --git a/compiler/utils/x86/jni_macro_assembler_x86.cc b/compiler/utils/x86/jni_macro_assembler_x86.cc index 67ec93d7c6..2c7902b7d9 100644 --- a/compiler/utils/x86/jni_macro_assembler_x86.cc +++ b/compiler/utils/x86/jni_macro_assembler_x86.cc @@ -308,18 +308,28 @@ void X86JNIMacroAssembler::MoveArguments(ArrayRef<ArgumentLocation> dests, const ArgumentLocation& src = srcs[i]; const ArgumentLocation& dest = dests[i]; DCHECK_EQ(src.GetSize(), dest.GetSize()); - if (UNLIKELY(dest.IsRegister())) { - // Native ABI has only stack arguments but we may pass one "hidden arg" in register. - CHECK(!found_hidden_arg); - found_hidden_arg = true; - CHECK(src.IsRegister()); - Move(dest.GetRegister(), src.GetRegister(), dest.GetSize()); - } else { - if (src.IsRegister()) { - Store(dest.GetFrameOffset(), src.GetRegister(), dest.GetSize()); + if (src.IsRegister()) { + if (UNLIKELY(dest.IsRegister())) { + // Native ABI has only stack arguments but we may pass one "hidden arg" in register. + CHECK(!found_hidden_arg); + found_hidden_arg = true; + DCHECK( + !dest.GetRegister().Equals(X86ManagedRegister::FromCpuRegister(GetScratchRegister()))); + Move(dest.GetRegister(), src.GetRegister(), dest.GetSize()); } else { - Copy(dest.GetFrameOffset(), src.GetFrameOffset(), dest.GetSize()); + Store(dest.GetFrameOffset(), src.GetRegister(), dest.GetSize()); } + } else { + // Delay copying until we have spilled all registers, including the scratch register ECX. + } + } + for (size_t i = 0, arg_count = srcs.size(); i != arg_count; ++i) { + const ArgumentLocation& src = srcs[i]; + const ArgumentLocation& dest = dests[i]; + DCHECK_EQ(src.GetSize(), dest.GetSize()); + if (!src.IsRegister()) { + DCHECK(!dest.IsRegister()); + Copy(dest.GetFrameOffset(), src.GetFrameOffset(), dest.GetSize()); } } } |