x86: Fix CriticalNative argument spilling in JNI stubs.
Do not move incoming stack arguments before we have spilled
the scratch register ECX.
Fix JniCompilerTest to initialize classes early so that we
really test what we were supposed to. This exposed the x86
bug fixed here.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 172332525
Change-Id: I7c06c8ccf18f5f66772c70f6a9a9a314668ce70d
diff --git a/compiler/jni/jni_compiler_test.cc b/compiler/jni/jni_compiler_test.cc
index 4d40418..3ee7e0e 100644
--- a/compiler/jni/jni_compiler_test.cc
+++ b/compiler/jni/jni_compiler_test.cc
@@ -246,15 +246,23 @@
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 {