summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/jni/jni_compiler_test.cc12
-rw-r--r--compiler/utils/x86/jni_macro_assembler_x86.cc30
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());
}
}
}