Removing remaining compiled stubs from image.
Abstract method error stub and jni dlsym lookup stubs are gone.
After this change, the image no longer needs to be executable.
Change-Id: Ic75d72bf7e76e3b8ecc596e82af68ab592dde15e
diff --git a/build/Android.common.mk b/build/Android.common.mk
index 59426a4..c8212ef 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -222,9 +222,6 @@
src/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc \
src/native/sun_misc_Unsafe.cc \
src/oat.cc \
- src/oat/runtime/arm/stub_arm.cc \
- src/oat/runtime/mips/stub_mips.cc \
- src/oat/runtime/x86/stub_x86.cc \
src/oat/utils/arm/assembler_arm.cc \
src/oat/utils/arm/managed_register_arm.cc \
src/oat/utils/assembler.cc \
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 9dee36a..d262a5d 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -1600,7 +1600,7 @@
Runtime* runtime = Runtime::Current();
if (method->IsAbstract()) {
- method->SetCode(runtime->GetAbstractMethodErrorStubArray()->GetData());
+ method->SetCode(GetAbstractMethodErrorStub());
return;
}
diff --git a/src/common_test.h b/src/common_test.h
index 05b0e05..6876274 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -234,8 +234,7 @@
} else {
const void* method_code;
if (method->IsAbstract()) {
- MakeExecutable(runtime_->GetAbstractMethodErrorStubArray());
- method_code = runtime_->GetAbstractMethodErrorStubArray()->GetData();
+ method_code = GetAbstractMethodErrorStub();
} else {
// No code? You must mean to go into the interpreter.
method_code = GetInterpreterEntryPoint();
@@ -353,8 +352,6 @@
CompilerBackend compiler_backend = kQuick;
#endif
- runtime_->SetJniDlsymLookupStub(CompilerDriver::CreateJniDlsymLookupStub(instruction_set));
- runtime_->SetAbstractMethodErrorStubArray(CompilerDriver::CreateAbstractMethodErrorStub(instruction_set));
if (!runtime_->HasResolutionMethod()) {
runtime_->SetResolutionMethod(runtime_->CreateResolutionMethod());
}
@@ -487,8 +484,6 @@
CHECK(method != NULL);
compiler_driver_->CompileOne(method);
MakeExecutable(method);
-
- MakeExecutable(runtime_->GetJniDlsymLookupStub());
}
void CompileDirectMethod(mirror::ClassLoader* class_loader,
diff --git a/src/compiler/driver/compiler_driver.cc b/src/compiler/driver/compiler_driver.cc
index e6f4b67..1660914 100644
--- a/src/compiler/driver/compiler_driver.cc
+++ b/src/compiler/driver/compiler_driver.cc
@@ -28,7 +28,6 @@
#include "dex_file-inl.h"
#include "jni_internal.h"
#include "oat_file.h"
-#include "oat/runtime/stub.h"
#include "object_utils.h"
#include "runtime.h"
#include "gc/card_table-inl.h"
@@ -409,36 +408,6 @@
return res;
}
-mirror::ByteArray* CompilerDriver::CreateJniDlsymLookupStub(InstructionSet instruction_set) {
- switch (instruction_set) {
- case kArm:
- case kThumb2:
- return arm::CreateJniDlsymLookupStub();
- case kMips:
- return mips::CreateJniDlsymLookupStub();
- case kX86:
- return x86::CreateJniDlsymLookupStub();
- default:
- LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
- return NULL;
- }
-}
-
-mirror::ByteArray* CompilerDriver::CreateAbstractMethodErrorStub(InstructionSet instruction_set) {
- switch (instruction_set) {
- case kArm:
- case kThumb2:
- return arm::CreateAbstractMethodErrorStub();
- case kMips:
- return mips::CreateAbstractMethodErrorStub();
- case kX86:
- return x86::CreateAbstractMethodErrorStub();
- default:
- LOG(FATAL) << "Unknown InstructionSet: " << instruction_set;
- return NULL;
- }
-}
-
void CompilerDriver::CompileAll(jobject class_loader,
const std::vector<const DexFile*>& dex_files) {
DCHECK(!Runtime::Current()->IsStarted());
diff --git a/src/compiler/driver/compiler_driver.h b/src/compiler/driver/compiler_driver.h
index 3581f5f..a20e5ef 100644
--- a/src/compiler/driver/compiler_driver.h
+++ b/src/compiler/driver/compiler_driver.h
@@ -102,13 +102,6 @@
CompilerTls* GetTls();
- // Stub to throw AbstractMethodError
- static mirror::ByteArray* CreateAbstractMethodErrorStub(InstructionSet instruction_set)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- static mirror::ByteArray* CreateJniDlsymLookupStub(InstructionSet instruction_set)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
// A class is uniquely located by its DexFile and the class_defs_ table index into that DexFile
typedef std::pair<const DexFile*, uint32_t> ClassReference;
diff --git a/src/dex2oat.cc b/src/dex2oat.cc
index 36b8d26..e41e537 100644
--- a/src/dex2oat.cc
+++ b/src/dex2oat.cc
@@ -372,12 +372,6 @@
}
Runtime* runtime = Runtime::Current();
// if we loaded an existing image, we will reuse values from the image roots.
- if (!runtime->HasJniDlsymLookupStub()) {
- runtime->SetJniDlsymLookupStub(CompilerDriver::CreateJniDlsymLookupStub(instruction_set));
- }
- if (!runtime->HasAbstractMethodErrorStubArray()) {
- runtime->SetAbstractMethodErrorStubArray(CompilerDriver::CreateAbstractMethodErrorStub(instruction_set));
- }
if (!runtime->HasResolutionMethod()) {
runtime->SetResolutionMethod(runtime->CreateResolutionMethod());
}
diff --git a/src/gc/space.cc b/src/gc/space.cc
index d7378c3..bfc3e86 100644
--- a/src/gc/space.cc
+++ b/src/gc/space.cc
@@ -512,12 +512,6 @@
DCHECK_EQ(0, memcmp(&image_header, map->Begin(), sizeof(ImageHeader)));
Runtime* runtime = Runtime::Current();
- mirror::Object* jni_stub_array = image_header.GetImageRoot(ImageHeader::kJniStubArray);
- runtime->SetJniDlsymLookupStub(down_cast<mirror::ByteArray*>(jni_stub_array));
-
- mirror::Object* ame_stub_array = image_header.GetImageRoot(ImageHeader::kAbstractMethodErrorStubArray);
- runtime->SetAbstractMethodErrorStubArray(down_cast<mirror::ByteArray*>(ame_stub_array));
-
mirror::Object* resolution_method = image_header.GetImageRoot(ImageHeader::kResolutionMethod);
runtime->SetResolutionMethod(down_cast<mirror::AbstractMethod*>(resolution_method));
diff --git a/src/image.cc b/src/image.cc
index c746c8e..686a117 100644
--- a/src/image.cc
+++ b/src/image.cc
@@ -24,7 +24,7 @@
namespace art {
const byte ImageHeader::kImageMagic[] = { 'a', 'r', 't', '\n' };
-const byte ImageHeader::kImageVersion[] = { '0', '0', '3', '\0' };
+const byte ImageHeader::kImageVersion[] = { '0', '0', '4', '\0' };
ImageHeader::ImageHeader(uint32_t image_begin,
uint32_t image_roots,
diff --git a/src/image.h b/src/image.h
index 040e3fe..f14d7d1 100644
--- a/src/image.h
+++ b/src/image.h
@@ -81,8 +81,6 @@
}
enum ImageRoot {
- kJniStubArray,
- kAbstractMethodErrorStubArray,
kResolutionMethod,
kCalleeSaveMethod,
kRefsOnlySaveMethod,
diff --git a/src/image_test.cc b/src/image_test.cc
index e4deda3..192e28a 100644
--- a/src/image_test.cc
+++ b/src/image_test.cc
@@ -127,8 +127,6 @@
ASSERT_TRUE(runtime_.get() != NULL);
class_linker_ = runtime_->GetClassLinker();
- ASSERT_TRUE(runtime_->GetJniDlsymLookupStub() != NULL);
-
Heap* heap = Runtime::Current()->GetHeap();
ASSERT_EQ(2U, heap->GetSpaces().size());
ASSERT_TRUE(heap->GetSpaces()[0]->IsImageSpace());
diff --git a/src/image_writer.cc b/src/image_writer.cc
index 16ac385..d9e4353 100644
--- a/src/image_writer.cc
+++ b/src/image_writer.cc
@@ -351,9 +351,6 @@
image_roots(self,
ObjectArray<Object>::Alloc(self, object_array_class,
ImageHeader::kImageRootsMax));
- image_roots->Set(ImageHeader::kJniStubArray, runtime->GetJniDlsymLookupStub());
- image_roots->Set(ImageHeader::kAbstractMethodErrorStubArray,
- runtime->GetAbstractMethodErrorStubArray());
image_roots->Set(ImageHeader::kResolutionMethod, runtime->GetResolutionMethod());
image_roots->Set(ImageHeader::kCalleeSaveMethod,
runtime->GetCalleeSaveMethod(Runtime::kSaveAll));
@@ -478,10 +475,8 @@
// OatWriter replaces the code_ with an offset value.
// Here we readjust to a pointer relative to oat_begin_
if (orig->IsAbstract()) {
- // Abstract methods are pointed to a stub that will throw AbstractMethodError if they are called
- ByteArray* orig_ame_stub_array_ = Runtime::Current()->GetAbstractMethodErrorStubArray();
- ByteArray* copy_ame_stub_array_ = down_cast<ByteArray*>(GetImageAddress(orig_ame_stub_array_));
- copy->SetCode(copy_ame_stub_array_->GetData());
+ // Code for abstract methods is set to the abstract method error stub when we load the image.
+ copy->SetCode(NULL);
return;
}
@@ -495,11 +490,9 @@
copy->SetCode(GetOatAddress(orig->GetOatCodeOffset()));
if (orig->IsNative()) {
- // The native method's pointer is directed to a stub to lookup via dlsym.
+ // The native method's pointer is set to a stub to lookup via dlsym when we load the image.
// Note this is not the code_ pointer, that is handled above.
- ByteArray* orig_jni_stub_array_ = Runtime::Current()->GetJniDlsymLookupStub();
- ByteArray* copy_jni_stub_array_ = down_cast<ByteArray*>(GetImageAddress(orig_jni_stub_array_));
- copy->SetNativeMethod(copy_jni_stub_array_->GetData());
+ copy->SetNativeMethod(NULL);
} else {
// normal (non-abstract non-native) methods have mapping tables to relocate
uint32_t mapping_table_off = orig->GetOatMappingTableOffset();
diff --git a/src/jni_internal.h b/src/jni_internal.h
index 131032a..dc6ca4a 100644
--- a/src/jni_internal.h
+++ b/src/jni_internal.h
@@ -51,7 +51,6 @@
void SetJniGlobalsMax(size_t max);
void JniAbortF(const char* jni_function_name, const char* fmt, ...)
__attribute__((__format__(__printf__, 2, 3)));
-void* FindNativeMethod(Thread* thread);
void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
size_t method_count);
diff --git a/src/mirror/abstract_method.cc b/src/mirror/abstract_method.cc
index 3ab3a93..559b558 100644
--- a/src/mirror/abstract_method.cc
+++ b/src/mirror/abstract_method.cc
@@ -324,7 +324,7 @@
bool AbstractMethod::IsRegistered() const {
void* native_method = GetFieldPtr<void*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, native_method_), false);
CHECK(native_method != NULL);
- void* jni_stub = Runtime::Current()->GetJniDlsymLookupStub()->GetData();
+ void* jni_stub = GetJniDlsymLookupStub();
return native_method != jni_stub;
}
@@ -352,7 +352,7 @@
void AbstractMethod::UnregisterNative(Thread* self) {
CHECK(IsNative()) << PrettyMethod(this);
// restore stub to lookup native pointer via dlsym
- RegisterNative(self, Runtime::Current()->GetJniDlsymLookupStub()->GetData());
+ RegisterNative(self, GetJniDlsymLookupStub());
}
void AbstractMethod::SetNativeMethod(const void* native_method) {
diff --git a/src/oat/runtime/arm/oat_support_entrypoints_arm.cc b/src/oat/runtime/arm/oat_support_entrypoints_arm.cc
index dcf6bb8..1a5fe47 100644
--- a/src/oat/runtime/arm/oat_support_entrypoints_arm.cc
+++ b/src/oat/runtime/arm/oat_support_entrypoints_arm.cc
@@ -109,8 +109,6 @@
extern "C" void art_quick_test_suspend();
// Throw entrypoints.
-extern void ThrowAbstractMethodErrorFromCode(mirror::AbstractMethod* method, Thread* thread,
- mirror::AbstractMethod** sp);
extern "C" void art_quick_deliver_exception_from_code(void*);
extern "C" void art_quick_throw_array_bounds_from_code(int32_t index, int32_t limit);
extern "C" void art_quick_throw_div_zero_from_code();
@@ -156,7 +154,6 @@
points->pHandleFillArrayDataFromCode = art_quick_handle_fill_data_from_code;
// JNI
- points->pFindNativeMethod = FindNativeMethod;
points->pJniMethodStart = JniMethodStart;
points->pJniMethodStartSynchronized = JniMethodStartSynchronized;
points->pJniMethodEnd = JniMethodEnd;
@@ -210,7 +207,6 @@
// Throws
points->pDeliverException = art_quick_deliver_exception_from_code;
- points->pThrowAbstractMethodErrorFromCode = ThrowAbstractMethodErrorFromCode;
points->pThrowArrayBoundsFromCode = art_quick_throw_array_bounds_from_code;
points->pThrowDivZeroFromCode = art_quick_throw_div_zero_from_code;
points->pThrowNoSuchMethodFromCode = art_quick_throw_no_such_method_from_code;
diff --git a/src/oat/runtime/arm/runtime_support_arm.S b/src/oat/runtime/arm/runtime_support_arm.S
index 2aa380b..3578ba0 100644
--- a/src/oat/runtime/arm/runtime_support_arm.S
+++ b/src/oat/runtime/arm/runtime_support_arm.S
@@ -257,6 +257,7 @@
.cfi_adjust_cfa_offset 20
sub sp, #12 @ pad stack pointer to align frame
.pad #12
+ .cfi_adjust_cfa_offset 12
mov r2, r9 @ pass Thread::Current
mov r1, sp @ pass stack pointer
blx artPortableResolutionTrampoline @ (method_idx, sp, Thread*)
@@ -1067,6 +1068,49 @@
END art_quick_deoptimize
/*
+ * Portable abstract method error stub. r0 contains method* on entry. SP unused in portable.
+ */
+ .extern artThrowAbstractMethodErrorFromCode
+ENTRY art_portable_abstract_method_error_stub
+ mov r1, r9 @ pass Thread::Current
+ b artThrowAbstractMethodErrorFromCode @ (Method*, Thread*, SP)
+END art_portable_abstract_method_error_stub
+
+ /*
+ * Quick abstract method error stub. r0 contains method* on entry.
+ */
+ENTRY art_quick_abstract_method_error_stub
+ SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
+ mov r1, r9 @ pass Thread::Current
+ mov r2, sp @ pass SP
+ b artThrowAbstractMethodErrorFromCode @ (Method*, Thread*, SP)
+END art_quick_abstract_method_error_stub
+
+ /*
+ * Jni dlsym lookup stub.
+ */
+ .extern artFindNativeMethod
+ENTRY art_jni_dlsym_lookup_stub
+ push {r0, r1, r2, r3, lr} @ spill regs
+ .save {r0, r1, r2, r3, lr}
+ .pad #20
+ .cfi_adjust_cfa_offset 20
+ sub sp, #12 @ pad stack pointer to align frame
+ .pad #12
+ .cfi_adjust_cfa_offset 12
+ mov r0, r9 @ pass Thread::Current
+ blx artFindNativeMethod @ (Thread*)
+ mov r12, r0 @ save result in r12
+ add sp, #12 @ restore stack pointer
+ .cfi_adjust_cfa_offset -12
+ pop {r0, r1, r2, r3, lr} @ restore regs
+ .cfi_adjust_cfa_offset -20
+ cmp r12, #0 @ is method code null?
+ bxne r12 @ if non-null, tail call to method's code
+ bx lr @ otherwise, return to caller to handle exception
+END art_jni_dlsym_lookup_stub
+
+ /*
* Signed 64-bit integer multiply.
*
* Consider WXxYZ (r1r0 x r3r2) with a long multiply:
diff --git a/src/oat/runtime/arm/stub_arm.cc b/src/oat/runtime/arm/stub_arm.cc
deleted file mode 100644
index 7c97f4c..0000000
--- a/src/oat/runtime/arm/stub_arm.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "jni_internal.h"
-#include "mirror/array.h"
-#include "mirror/object-inl.h"
-#include "oat/utils/arm/assembler_arm.h"
-#include "oat/runtime/oat_support_entrypoints.h"
-#include "oat/runtime/stub.h"
-#include "stack_indirect_reference_table.h"
-#include "sirt_ref.h"
-
-#define __ assembler->
-
-namespace art {
-namespace arm {
-
-typedef void (*ThrowAme)(mirror::AbstractMethod*, Thread*);
-
-mirror::ByteArray* CreateAbstractMethodErrorStub() {
- UniquePtr<ArmAssembler> assembler(static_cast<ArmAssembler*>(Assembler::Create(kArm)));
-#if !defined(ART_USE_PORTABLE_COMPILER)
- // Save callee saves and ready frame for exception delivery
- RegList save = (1 << R4) | (1 << R5) | (1 << R6) | (1 << R7) | (1 << R8) | (1 << R9) |
- (1 << R10) | (1 << R11) | (1 << LR);
- // TODO: enable when GetCalleeSaveMethod is available at stub generation time
- // DCHECK_EQ(save, Runtime::Current()->GetCalleeSaveMethod(Runtime::kSaveAll)->GetCoreSpillMask());
- __ PushList(save); // push {r4-r11, lr} - 9 words of callee saves
- // TODO: enable when GetCalleeSaveMethod is available at stub generation time
- // DCHECK_EQ(Runtime::Current()->GetCalleeSaveMethod(Runtime::kSaveAll)->GetFpSpillMask(), 0xFFFFU);
- __ Emit(0xed2d0a20); // vpush {s0-s31}
-
- __ IncreaseFrameSize(12); // 3 words of space, bottom word will hold callee save Method*
-
- // R0 is the Method* already
- __ mov(R1, ShifterOperand(R9)); // Pass Thread::Current() in R1
- __ mov(R2, ShifterOperand(SP)); // Pass SP in R2
- // Call to throw AbstractMethodError
- __ LoadFromOffset(kLoadWord, R12, TR, ENTRYPOINT_OFFSET(pThrowAbstractMethodErrorFromCode));
- __ mov(PC, ShifterOperand(R12)); // Leaf call to routine that never returns
-
- __ bkpt(0);
-#else // ART_USE_PORTABLE_COMPILER
- // R0 is the Method* already
- __ mov(R1, ShifterOperand(R9)); // Pass Thread::Current() in R1
- // Call to throw AbstractMethodError
- __ LoadFromOffset(kLoadWord, R12, TR, ENTRYPOINT_OFFSET(pThrowAbstractMethodErrorFromCode));
- __ mov(PC, ShifterOperand(R12)); // Leaf call to routine that never returns
-
- __ bkpt(0);
-#endif // ART_USE_PORTABLE_COMPILER
-
- assembler->EmitSlowPaths();
-
- size_t cs = assembler->CodeSize();
- Thread* self = Thread::Current();
- SirtRef<mirror::ByteArray> abstract_stub(self, mirror::ByteArray::Alloc(self, cs));
- CHECK(abstract_stub.get() != NULL);
- MemoryRegion code(abstract_stub->GetData(), abstract_stub->GetLength());
- assembler->FinalizeInstructions(code);
-
- return abstract_stub.get();
-}
-
-mirror::ByteArray* CreateJniDlsymLookupStub() {
- UniquePtr<ArmAssembler> assembler(static_cast<ArmAssembler*>(Assembler::Create(kArm)));
- // Build frame and save argument registers and LR.
- RegList save = (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) | (1 << LR);
- __ PushList(save);
- __ AddConstant(SP, -12); // Ensure 16-byte alignment
- __ mov(R0, ShifterOperand(R9)); // Pass Thread::Current() in R0
- // Call FindNativeMethod
- __ LoadFromOffset(kLoadWord, R12, TR, ENTRYPOINT_OFFSET(pFindNativeMethod));
- __ blx(R12);
- __ mov(R12, ShifterOperand(R0)); // Save result of FindNativeMethod in R12
- __ AddConstant(SP, 12); // Restore registers (including outgoing arguments)
- __ PopList(save);
- __ cmp(R12, ShifterOperand(0));
- __ bx(R12, NE); // If R12 != 0 tail call into native code
- __ bx(LR); // Return to caller to handle exception
-
- assembler->EmitSlowPaths();
-
- size_t cs = assembler->CodeSize();
- Thread* self = Thread::Current();
- SirtRef<mirror::ByteArray> jni_stub(self, mirror::ByteArray::Alloc(self, cs));
- CHECK(jni_stub.get() != NULL);
- MemoryRegion code(jni_stub->GetData(), jni_stub->GetLength());
- assembler->FinalizeInstructions(code);
-
- return jni_stub.get();
-}
-
-} // namespace arm
-} // namespace art
diff --git a/src/oat/runtime/mips/oat_support_entrypoints_mips.cc b/src/oat/runtime/mips/oat_support_entrypoints_mips.cc
index b201b07..eb82c42 100644
--- a/src/oat/runtime/mips/oat_support_entrypoints_mips.cc
+++ b/src/oat/runtime/mips/oat_support_entrypoints_mips.cc
@@ -111,8 +111,6 @@
extern "C" void art_quick_test_suspend();
// Throw entrypoints.
-extern void ThrowAbstractMethodErrorFromCode(mirror::AbstractMethod* method, Thread* thread,
- mirror::AbstractMethod** sp);
extern "C" void art_quick_deliver_exception_from_code(void*);
extern "C" void art_quick_throw_array_bounds_from_code(int32_t index, int32_t limit);
extern "C" void art_quick_throw_div_zero_from_code();
@@ -158,7 +156,6 @@
points->pHandleFillArrayDataFromCode = art_quick_handle_fill_data_from_code;
// JNI
- points->pFindNativeMethod = FindNativeMethod;
points->pJniMethodStart = JniMethodStart;
points->pJniMethodStartSynchronized = JniMethodStartSynchronized;
points->pJniMethodEnd = JniMethodEnd;
@@ -211,7 +208,6 @@
// Throws
points->pDeliverException = art_quick_deliver_exception_from_code;
- points->pThrowAbstractMethodErrorFromCode = ThrowAbstractMethodErrorFromCode;
points->pThrowArrayBoundsFromCode = art_quick_throw_array_bounds_from_code;
points->pThrowDivZeroFromCode = art_quick_throw_div_zero_from_code;
points->pThrowNoSuchMethodFromCode = art_quick_throw_no_such_method_from_code;
diff --git a/src/oat/runtime/mips/runtime_support_mips.S b/src/oat/runtime/mips/runtime_support_mips.S
index f5f8d9b..295e3fe 100644
--- a/src/oat/runtime/mips/runtime_support_mips.S
+++ b/src/oat/runtime/mips/runtime_support_mips.S
@@ -408,10 +408,10 @@
INVOKE_TRAMPOLINE art_quick_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck
INVOKE_TRAMPOLINE art_quick_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck
- /*
+ /*
* Portable resolution trampoline.
*/
- .extern artPortableResolutionTrampoline
+ .extern artPortableResolutionTrampoline
ENTRY art_portable_resolution_trampoline
GENERATE_GLOBAL_POINTER
addiu $sp, $sp, -32 # leave room for $a0, $a1, $a2, $a3, and $ra
@@ -444,10 +444,10 @@
nop
END art_portable_resolution_trampoline
- /*
+ /*
* Quick resolution trampoline.
*/
- .extern artQuickResolutionTrampoline
+ .extern artQuickResolutionTrampoline
ENTRY art_quick_resolution_trampoline
GENERATE_GLOBAL_POINTER
SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME
@@ -482,8 +482,8 @@
* [sp + 16] = JValue* result
* [sp + 20] = result type char
*/
- .type art_portable_invoke_stub, %function
- .global art_portable_invoke_stub
+ .type art_portable_invoke_stub, %function
+ .global art_portable_invoke_stub
art_portable_invoke_stub:
ENTRY art_quick_invoke_stub
GENERATE_GLOBAL_POINTER
@@ -1102,6 +1102,64 @@
END art_quick_deoptimize
/*
+ * Portable abstract method error stub. $a0 contains method* on entry. SP unused in portable.
+ */
+ .extern artThrowAbstractMethodErrorFromCode
+ENTRY art_portable_abstract_method_error_stub
+ GENERATE_GLOBAL_POINTER
+ la $t9, artThrowAbstractMethodErrorFromCode
+ jr $t9 # (Method*, Thread*, SP)
+ move $a1, $s1 # pass Thread::Current
+END art_portable_abstract_method_error_stub
+
+ /*
+ * Quick abstract method error stub. $a0 contains method* on entry.
+ */
+ENTRY art_quick_abstract_method_error_stub
+ GENERATE_GLOBAL_POINTER
+ SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
+ move $a1, $s1 # pass Thread::Current
+ la $t9, artThrowAbstractMethodErrorFromCode
+ jr $t9 # (Method*, Thread*, SP)
+ move $a2, $sp # pass SP
+END art_quick_abstract_method_error_stub
+
+ /*
+ * Jni dlsym lookup stub.
+ */
+ .extern artFindNativeMethod
+ENTRY art_jni_dlsym_lookup_stub
+ GENERATE_GLOBAL_POINTER
+ addiu $sp, $sp, -32 # leave room for $a0, $a1, $a2, $a3, and $ra
+ .cfi_adjust_cfa_offset 32
+ sw $ra, 16($sp)
+ .cfi_rel_offset 31, 16
+ sw $a3, 12($sp)
+ .cfi_rel_offset 7, 12
+ sw $a2, 8($sp)
+ .cfi_rel_offset 6, 8
+ sw $a1, 4($sp)
+ .cfi_rel_offset 5, 4
+ sw $a0, 0($sp)
+ .cfi_rel_offset 4, 0
+ jal artFindNativeMethod # (Thread*)
+ move $a0, $s1 # pass Thread::Current()
+ lw $a0, 0($sp) # restore registers from stack
+ lw $a1, 4($sp)
+ lw $a2, 8($sp)
+ lw $a3, 12($sp)
+ lw $ra, 16($sp)
+ beq $v0, $zero, no_native_code_found
+ addiu $sp, $sp, 32 # restore the stack
+ .cfi_adjust_cfa_offset -32
+ jr $t9 # leaf call to method's code
+ move $t9, $v0 # put method code result in $t9
+no_native_code_found:
+ jr $ra
+ nop
+END art_jni_dlsym_lookup_stub
+
+ /*
* Long integer shift. This is different from the generic 32/64-bit
* binary operations because vAA/vBB are 64-bit but vCC (the shift
* distance) is 32-bit. Also, Dalvik requires us to ignore all but the low
diff --git a/src/oat/runtime/mips/stub_mips.cc b/src/oat/runtime/mips/stub_mips.cc
deleted file mode 100644
index a1adf66..0000000
--- a/src/oat/runtime/mips/stub_mips.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "jni_internal.h"
-#include "mirror/array.h"
-#include "mirror/object-inl.h"
-#include "oat/runtime/oat_support_entrypoints.h"
-#include "oat/runtime/stub.h"
-#include "oat/utils/mips/assembler_mips.h"
-#include "stack_indirect_reference_table.h"
-#include "sirt_ref.h"
-
-#define __ assembler->
-
-namespace art {
-namespace mips {
-
-typedef void (*ThrowAme)(mirror::AbstractMethod*, Thread*);
-
-mirror::ByteArray* CreateAbstractMethodErrorStub() {
- UniquePtr<MipsAssembler> assembler(static_cast<MipsAssembler*>(Assembler::Create(kMips)));
-#if !defined(ART_USE_PORTABLE_COMPILER)
- // Save callee saves and ready frame for exception delivery
- __ AddConstant(SP, SP, -64);
- __ StoreToOffset(kStoreWord, RA, SP, 60);
- __ StoreToOffset(kStoreWord, FP, SP, 56);
- __ StoreToOffset(kStoreWord, S7, SP, 52);
- __ StoreToOffset(kStoreWord, S6, SP, 48);
- __ StoreToOffset(kStoreWord, S5, SP, 44);
- __ StoreToOffset(kStoreWord, S4, SP, 40);
- __ StoreToOffset(kStoreWord, S3, SP, 36);
- __ StoreToOffset(kStoreWord, S2, SP, 32);
- __ StoreToOffset(kStoreWord, S1, SP, 28);
- __ StoreToOffset(kStoreWord, S0, SP, 24);
-
- // A0 is the Method* already
- __ Move(A1, S1); // Pass Thread::Current() in A1
- __ Move(A2, SP); // Pass SP in A2
- // Call to throw AbstractMethodError
- __ LoadFromOffset(kLoadWord, T9, S1, ENTRYPOINT_OFFSET(pThrowAbstractMethodErrorFromCode));
- __ Jr(T9); // Leaf call to routine that never returns
-
- __ Break();
-#else // ART_USE_PORTABLE_COMPILER
- // R0 is the Method* already
- __ Move(A1, S1); // Pass Thread::Current() in A1
- // Call to throw AbstractMethodError
- __ LoadFromOffset(kLoadWord, T9, S1, ENTRYPOINT_OFFSET(pThrowAbstractMethodErrorFromCode));
- __ Jr(T9); // Leaf call to routine that never returns
-
- __ Break();
-#endif // ART_USE_PORTABLE_COMPILER
-
- assembler->EmitSlowPaths();
-
- size_t cs = assembler->CodeSize();
- Thread* self = Thread::Current();
- SirtRef<mirror::ByteArray> abstract_stub(self, mirror::ByteArray::Alloc(self, cs));
- CHECK(abstract_stub.get() != NULL);
- MemoryRegion code(abstract_stub->GetData(), abstract_stub->GetLength());
- assembler->FinalizeInstructions(code);
-
- return abstract_stub.get();
-}
-
-mirror::ByteArray* CreateJniDlsymLookupStub() {
- UniquePtr<MipsAssembler> assembler(static_cast<MipsAssembler*>(Assembler::Create(kMips)));
-
- // Build frame and save argument registers and RA.
- __ AddConstant(SP, SP, -32);
- __ StoreToOffset(kStoreWord, RA, SP, 28);
- __ StoreToOffset(kStoreWord, A3, SP, 24);
- __ StoreToOffset(kStoreWord, A2, SP, 20);
- __ StoreToOffset(kStoreWord, A1, SP, 16);
- __ StoreToOffset(kStoreWord, A0, SP, 12);
-
- __ Move(A0, S1); // Pass Thread::Current() in A0
- __ LoadFromOffset(kLoadWord, T9, S1, ENTRYPOINT_OFFSET(pFindNativeMethod));
- __ Jalr(T9); // Call FindNativeMethod
-
- // Restore frame, argument registers, and RA.
- __ LoadFromOffset(kLoadWord, A0, SP, 12);
- __ LoadFromOffset(kLoadWord, A1, SP, 16);
- __ LoadFromOffset(kLoadWord, A2, SP, 20);
- __ LoadFromOffset(kLoadWord, A3, SP, 24);
- __ LoadFromOffset(kLoadWord, RA, SP, 28);
- __ AddConstant(SP, SP, 32);
-
- Label no_native_code_found;
- __ EmitBranch(V0, ZERO, &no_native_code_found, true);
- __ Move(T9, V0); // Move result into T9
- __ Jr(T9); // If result != 0, tail call method's code
- __ Bind(&no_native_code_found, false);
- __ Jr(RA); // Return to caller to handle exception
-
- assembler->EmitSlowPaths();
-
- size_t cs = assembler->CodeSize();
- Thread* self = Thread::Current();
- SirtRef<mirror::ByteArray> jni_stub(self, mirror::ByteArray::Alloc(self, cs));
- CHECK(jni_stub.get() != NULL);
- MemoryRegion code(jni_stub->GetData(), jni_stub->GetLength());
- assembler->FinalizeInstructions(code);
-
- return jni_stub.get();
-}
-
-} // namespace mips
-} // namespace art
diff --git a/src/oat/runtime/oat_support_entrypoints.h b/src/oat/runtime/oat_support_entrypoints.h
index 5be1e49..72d5348 100644
--- a/src/oat/runtime/oat_support_entrypoints.h
+++ b/src/oat/runtime/oat_support_entrypoints.h
@@ -70,7 +70,6 @@
void (*pHandleFillArrayDataFromCode)(void*, void*);
// JNI
- void* (*pFindNativeMethod)(Thread* thread);
uint32_t (*pJniMethodStart)(Thread*);
uint32_t (*pJniMethodStartSynchronized)(jobject to_lock, Thread* self);
void (*pJniMethodEnd)(uint32_t cookie, Thread* self);
@@ -125,8 +124,6 @@
// Throws
void (*pDeliverException)(void*);
- void (*pThrowAbstractMethodErrorFromCode)(mirror::AbstractMethod* m, Thread* thread,
- mirror::AbstractMethod** sp);
void (*pThrowArrayBoundsFromCode)(int32_t, int32_t);
void (*pThrowDivZeroFromCode)();
void (*pThrowNoSuchMethodFromCode)(int32_t);
@@ -135,7 +132,6 @@
};
// JNI entrypoints.
-extern void* FindNativeMethod(Thread* thread) LOCKS_EXCLUDED(Locks::mutator_lock_);
extern uint32_t JniMethodStart(Thread* self)
UNLOCK_FUNCTION(Locks::mutator_lock_) __attribute__ ((hot));
extern uint32_t JniMethodStartSynchronized(jobject to_lock, Thread* self)
diff --git a/src/oat/runtime/stub.h b/src/oat/runtime/stub.h
deleted file mode 100644
index ee39273..0000000
--- a/src/oat/runtime/stub.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_SRC_OAT_RUNTIME_OAT_RUNTIME_STUB_H_
-#define ART_SRC_OAT_RUNTIME_OAT_RUNTIME_STUB_H_
-
-#include "runtime.h"
-
-namespace art {
-namespace mirror {
-template<class T> class PrimitiveArray;
-typedef PrimitiveArray<int8_t> ByteArray;
-} // namespace mirror
-
-namespace arm {
- mirror::ByteArray* CreateAbstractMethodErrorStub()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- mirror::ByteArray* CreateJniDlsymLookupStub()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-}
-
-namespace mips {
- mirror::ByteArray* CreateAbstractMethodErrorStub()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- mirror::ByteArray* CreateJniDlsymLookupStub()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-}
-
-namespace x86 {
- mirror::ByteArray* CreateAbstractMethodErrorStub()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- mirror::ByteArray* CreateJniDlsymLookupStub()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-}
-
-} // namespace art
-
-#endif // ART_SRC_OAT_RUNTIME_OAT_RUNTIME_STUB_H_
diff --git a/src/oat/runtime/support_jni.cc b/src/oat/runtime/support_jni.cc
index bc9cc45..8f0f7ca 100644
--- a/src/oat/runtime/support_jni.cc
+++ b/src/oat/runtime/support_jni.cc
@@ -27,28 +27,6 @@
namespace art {
-// Used by the JNI dlsym stub to find the native method to invoke if none is registered.
-extern void* FindNativeMethod(Thread* self) {
- Locks::mutator_lock_->AssertNotHeld(self); // We come here as Native.
- DCHECK(Thread::Current() == self);
- ScopedObjectAccess soa(self);
-
- mirror::AbstractMethod* method = self->GetCurrentMethod(NULL);
- DCHECK(method != NULL);
-
- // Lookup symbol address for method, on failure we'll return NULL with an
- // exception set, otherwise we return the address of the method we found.
- void* native_code = soa.Vm()->FindCodeForNativeMethod(method);
- if (native_code == NULL) {
- DCHECK(self->IsExceptionPending());
- return NULL;
- } else {
- // Register so that future calls don't come here
- method->RegisterNative(self, native_code);
- return native_code;
- }
-}
-
// Called on entry to JNI, transition out of Runnable and release share of mutator_lock_.
extern uint32_t JniMethodStart(Thread* self) {
JNIEnvExt* env = self->GetJniEnv();
@@ -184,7 +162,7 @@
// Load expected destination, see Method::RegisterNative
const void* code = reinterpret_cast<const void*>(jni_method->GetNativeGcMap());
if (UNLIKELY(code == NULL)) {
- code = Runtime::Current()->GetJniDlsymLookupStub()->GetData();
+ code = GetJniDlsymLookupStub();
jni_method->RegisterNative(self, code);
}
return code;
diff --git a/src/oat/runtime/support_stubs.cc b/src/oat/runtime/support_stubs.cc
index f78cc79..9f77ae0 100644
--- a/src/oat/runtime/support_stubs.cc
+++ b/src/oat/runtime/support_stubs.cc
@@ -335,9 +335,9 @@
return code;
}
-// Called by the AbstractMethodError. Called by stub code.
-extern void ThrowAbstractMethodErrorFromCode(mirror::AbstractMethod* method, Thread* self,
- mirror::AbstractMethod** sp)
+// Called by the abstract method error stub.
+extern "C" void artThrowAbstractMethodErrorFromCode(mirror::AbstractMethod* method, Thread* self,
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
#if !defined(ART_USE_PORTABLE_COMPILER)
FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
@@ -350,4 +350,26 @@
self->QuickDeliverException();
}
+// Used by the JNI dlsym stub to find the native method to invoke if none is registered.
+extern "C" void* artFindNativeMethod(Thread* self) {
+ Locks::mutator_lock_->AssertNotHeld(self); // We come here as Native.
+ DCHECK(Thread::Current() == self);
+ ScopedObjectAccess soa(self);
+
+ mirror::AbstractMethod* method = self->GetCurrentMethod(NULL);
+ DCHECK(method != NULL);
+
+ // Lookup symbol address for method, on failure we'll return NULL with an
+ // exception set, otherwise we return the address of the method we found.
+ void* native_code = soa.Vm()->FindCodeForNativeMethod(method);
+ if (native_code == NULL) {
+ DCHECK(self->IsExceptionPending());
+ return NULL;
+ } else {
+ // Register so that future calls don't come here
+ method->RegisterNative(self, native_code);
+ return native_code;
+ }
+}
+
} // namespace art
diff --git a/src/oat/runtime/x86/oat_support_entrypoints_x86.cc b/src/oat/runtime/x86/oat_support_entrypoints_x86.cc
index 2e35d78..357bbe0 100644
--- a/src/oat/runtime/x86/oat_support_entrypoints_x86.cc
+++ b/src/oat/runtime/x86/oat_support_entrypoints_x86.cc
@@ -94,8 +94,6 @@
extern "C" void art_quick_test_suspend();
// Throw entrypoints.
-extern void ThrowAbstractMethodErrorFromCode(mirror::AbstractMethod* method, Thread* thread,
- mirror::AbstractMethod** sp);
extern "C" void art_quick_deliver_exception_from_code(void*);
extern "C" void art_quick_throw_array_bounds_from_code(int32_t index, int32_t limit);
extern "C" void art_quick_throw_div_zero_from_code();
@@ -141,7 +139,6 @@
points->pHandleFillArrayDataFromCode = art_quick_handle_fill_data_from_code;
// JNI
- points->pFindNativeMethod = FindNativeMethod;
points->pJniMethodStart = JniMethodStart;
points->pJniMethodStartSynchronized = JniMethodStartSynchronized;
points->pJniMethodEnd = JniMethodEnd;
@@ -194,7 +191,6 @@
// Throws
points->pDeliverException = art_quick_deliver_exception_from_code;
- points->pThrowAbstractMethodErrorFromCode = ThrowAbstractMethodErrorFromCode;
points->pThrowArrayBoundsFromCode = art_quick_throw_array_bounds_from_code;
points->pThrowDivZeroFromCode = art_quick_throw_div_zero_from_code;
points->pThrowNoSuchMethodFromCode = art_quick_throw_no_such_method_from_code;
diff --git a/src/oat/runtime/x86/runtime_support_x86.S b/src/oat/runtime/x86/runtime_support_x86.S
index 22330c9..d3a1fb7 100644
--- a/src/oat/runtime/x86/runtime_support_x86.S
+++ b/src/oat/runtime/x86/runtime_support_x86.S
@@ -307,6 +307,7 @@
DEFINE_FUNCTION art_portable_resolution_trampoline
PUSH ebp // stash %ebp
movl %esp, %ebp // save %esp
+ .cfi_def_cfa_register ebp
subl LITERAL(8), %esp // align stack
movl 8(%ebp), %eax // load the called method* into %eax
leal 8(%ebp), %edx // put the called method* address in %edx
@@ -314,7 +315,9 @@
PUSH edx // pass called method* address
PUSH eax // pass method*
call SYMBOL(artPortableResolutionTrampoline) // (method_idx, sp, Thread*)
- leave // restore the stack
+ leave // restore the stack and %ebp
+ .cfi_def_cfa esp, 4
+ .cfi_restore ebp
cmpl LITERAL(0), %eax // check if returned method code is null
je resolve_fail // if null, jump to return to handle
jmp *%eax // otherwise, tail call to intended method
@@ -330,11 +333,13 @@
movl %esp, %ecx // save stack pointer
PUSH eax // align stack
pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
+ .cfi_adjust_cfa_offset 4
PUSH ecx // pass stack pointer
PUSH eax // pass method*
call SYMBOL(artQuickResolutionTrampoline) // (method_idx, sp, Thread*)
movl %eax, %edi // save returned code pointer in %edi
addl LITERAL(16), %esp // pop arguments
+ .cfi_adjust_cfa_offset -16
POP eax // restore registers
POP ecx
POP edx
@@ -1098,6 +1103,57 @@
END_FUNCTION art_quick_deoptimize
/*
+ * Portable abstract method error stub. method* is at %esp + 4 on entry.
+ */
+DEFINE_FUNCTION art_portable_abstract_method_error_stub
+ PUSH ebp
+ movl %esp, %ebp // Remember SP.
+ .cfi_def_cfa_register ebp
+ subl LITERAL(12), %esp // Align stack.
+ PUSH esp // Pass sp (not used).
+ pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current().
+ pushl 8(%ebp) // Pass Method*.
+ call SYMBOL(artThrowAbstractMethodErrorFromCode) // (Method*, Thread*, SP)
+ leave // Restore the stack and %ebp.
+ .cfi_def_cfa esp, 4
+ .cfi_restore ebp
+ ret // Return to caller to handle pending exception.
+END_FUNCTION art_portable_abstract_method_error_stub
+
+ /*
+ * Quick abstract method error stub. %eax contains method* on entry.
+ */
+DEFINE_FUNCTION art_quick_abstract_method_error_stub
+ SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
+ movl %esp, %ecx // Remember SP.
+ PUSH eax // Align frame.
+ PUSH ecx // Pass SP for Method*.
+ pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current().
+ .cfi_adjust_cfa_offset 4
+ PUSH eax // Pass Method*.
+ call SYMBOL(artThrowAbstractMethodErrorFromCode) // (Method*, Thread*, SP)
+ int3 // Unreachable.
+END_FUNCTION art_quick_abstract_method_error_stub
+
+ /*
+ * Portable resolution trampoline.
+ */
+DEFINE_FUNCTION art_jni_dlsym_lookup_stub
+ subl LITERAL(8), %esp // align stack
+ .cfi_adjust_cfa_offset 8
+ pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
+ .cfi_adjust_cfa_offset 4
+ call SYMBOL(artFindNativeMethod) // (Thread*)
+ addl LITERAL(12), %esp // restore the stack
+ .cfi_adjust_cfa_offset -12
+ cmpl LITERAL(0), %eax // check if returned method code is null
+ je no_native_code_found // if null, jump to return to handle
+ jmp *%eax // otherwise, tail call to intended method
+no_native_code_found:
+ ret
+END_FUNCTION art_jni_dlsym_lookup_stub
+
+ /*
* String's indexOf.
*
* On entry:
diff --git a/src/oat/runtime/x86/stub_x86.cc b/src/oat/runtime/x86/stub_x86.cc
deleted file mode 100644
index 3f85b28..0000000
--- a/src/oat/runtime/x86/stub_x86.cc
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "jni_internal.h"
-#include "mirror/array.h"
-#include "mirror/object-inl.h"
-#include "oat/runtime/oat_support_entrypoints.h"
-#include "oat/runtime/stub.h"
-#include "oat/utils/x86/assembler_x86.h"
-#include "stack_indirect_reference_table.h"
-#include "sirt_ref.h"
-
-#define __ assembler->
-
-namespace art {
-namespace x86 {
-
-typedef void (*ThrowAme)(mirror::AbstractMethod*, Thread*);
-
-mirror::ByteArray* CreateAbstractMethodErrorStub() {
- UniquePtr<X86Assembler> assembler(static_cast<X86Assembler*>(Assembler::Create(kX86)));
-
-#if !defined(ART_USE_PORTABLE_COMPILER)
- // Set up the callee save frame to conform with Runtime::CreateCalleeSaveMethod(kSaveAll)
-
- // return address
- __ pushl(EDI);
- __ pushl(ESI);
- __ pushl(EBP);
- __ pushl(Immediate(0));
- __ pushl(Immediate(0));
- __ pushl(Immediate(0));
- __ pushl(Immediate(0)); // <-- callee save Method* to go here
- __ movl(ECX, ESP); // save ESP
- __ pushl(Immediate(0)); // align frame
- __ pushl(ECX); // pass ESP for Method*
- __ fs()->pushl(Address::Absolute(Thread::SelfOffset())); // Thread*
- __ pushl(EAX); // pass Method*
-
- // Call to throw AbstractMethodError.
- __ Call(ThreadOffset(ENTRYPOINT_OFFSET(pThrowAbstractMethodErrorFromCode)),
- X86ManagedRegister::FromCpuRegister(ECX));
-
- // Call never returns.
- __ int3();
-#else // ART_USE_PORTABLE_COMPILER
- __ pushl(EBP);
- __ movl(EBP, ESP); // save ESP
- __ subl(ESP, Immediate(12)); // Align stack
- __ pushl(ESP); // pass sp (not use)
- __ fs()->pushl(Address::Absolute(Thread::SelfOffset())); // pass thread*
- __ pushl(Address(EBP, 8)); // pass method
- // Call to throw AbstractMethodError.
- __ Call(ThreadOffset(ENTRYPOINT_OFFSET(pThrowAbstractMethodErrorFromCode)),
- X86ManagedRegister::FromCpuRegister(ECX));
- __ leave();
- // Return to caller who will handle pending exception.
- __ ret();
-#endif // ART_USE_PORTABLE_COMPILER
-
- assembler->EmitSlowPaths();
-
- size_t cs = assembler->CodeSize();
- Thread* self = Thread::Current();
- SirtRef<mirror::ByteArray> abstract_stub(self, mirror::ByteArray::Alloc(self, cs));
- CHECK(abstract_stub.get() != NULL);
- MemoryRegion code(abstract_stub->GetData(), abstract_stub->GetLength());
- assembler->FinalizeInstructions(code);
-
- return abstract_stub.get();
-}
-
-mirror::ByteArray* CreateJniDlsymLookupStub() {
- UniquePtr<X86Assembler> assembler(static_cast<X86Assembler*>(Assembler::Create(kX86)));
-
- // Pad stack to ensure 16-byte alignment
- __ pushl(Immediate(0));
- __ pushl(Immediate(0));
- __ fs()->pushl(Address::Absolute(Thread::SelfOffset())); // Thread*
-
- __ Call(ThreadOffset(ENTRYPOINT_OFFSET(pFindNativeMethod)),
- X86ManagedRegister::FromCpuRegister(ECX));
-
- __ addl(ESP, Immediate(12));
-
- Label no_native_code_found; // forward declaration
- __ cmpl(EAX, Immediate(0));
- __ j(kEqual, &no_native_code_found);
-
- __ jmp(EAX); // Tail call into native code
-
- __ Bind(&no_native_code_found);
- __ ret(); // return to caller to handle exception
-
- assembler->EmitSlowPaths();
-
- size_t cs = assembler->CodeSize();
- Thread* self = Thread::Current();
- SirtRef<mirror::ByteArray> jni_stub(self, mirror::ByteArray::Alloc(self, cs));
- CHECK(jni_stub.get() != NULL);
- MemoryRegion code(jni_stub->GetData(), jni_stub->GetLength());
- assembler->FinalizeInstructions(code);
-
- return jni_stub.get();
-}
-
-} // namespace x86
-} // namespace art
diff --git a/src/oatdump.cc b/src/oatdump.cc
index 62af7a9..353abca 100644
--- a/src/oatdump.cc
+++ b/src/oatdump.cc
@@ -82,8 +82,6 @@
}
const char* image_roots_descriptions_[] = {
- "kJniStubArray",
- "kAbstractMethodErrorStubArray",
"kResolutionMethod",
"kCalleeSaveMethod",
"kRefsOnlySaveMethod",
diff --git a/src/runtime.cc b/src/runtime.cc
index b336156..25d26b8 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -82,8 +82,6 @@
signal_catcher_(NULL),
java_vm_(NULL),
pre_allocated_OutOfMemoryError_(NULL),
- jni_stub_array_(NULL),
- abstract_method_error_stub_array_(NULL),
resolution_method_(NULL),
system_class_loader_(NULL),
threads_being_born_(0),
@@ -1065,8 +1063,6 @@
if (pre_allocated_OutOfMemoryError_ != NULL) {
visitor(pre_allocated_OutOfMemoryError_, arg);
}
- visitor(jni_stub_array_, arg);
- visitor(abstract_method_error_stub_array_, arg);
visitor(resolution_method_, arg);
for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
visitor(callee_save_methods_[i], arg);
@@ -1090,19 +1086,6 @@
VisitNonConcurrentRoots(visitor, arg);
}
-void Runtime::SetJniDlsymLookupStub(mirror::ByteArray* jni_stub_array) {
- CHECK(jni_stub_array != NULL) << " jni_stub_array=" << jni_stub_array;
- CHECK(jni_stub_array_ == NULL || jni_stub_array_ == jni_stub_array)
- << "jni_stub_array_=" << jni_stub_array_ << " jni_stub_array=" << jni_stub_array;
- jni_stub_array_ = jni_stub_array;
-}
-
-void Runtime::SetAbstractMethodErrorStubArray(mirror::ByteArray* abstract_method_error_stub_array) {
- CHECK(abstract_method_error_stub_array != NULL);
- CHECK(abstract_method_error_stub_array_ == NULL || abstract_method_error_stub_array_ == abstract_method_error_stub_array);
- abstract_method_error_stub_array_ = abstract_method_error_stub_array;
-}
-
mirror::AbstractMethod* Runtime::CreateResolutionMethod() {
mirror::Class* method_class = mirror::AbstractMethod::GetMethodClass();
Thread* self = Thread::Current();
diff --git a/src/runtime.h b/src/runtime.h
index 93cffbe..c7ccda1 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -242,28 +242,6 @@
void VisitNonConcurrentRoots(RootVisitor* visitor, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool HasJniDlsymLookupStub() const {
- return jni_stub_array_ != NULL;
- }
-
- mirror::ByteArray* GetJniDlsymLookupStub() const {
- CHECK(HasJniDlsymLookupStub());
- return jni_stub_array_;
- }
-
- void SetJniDlsymLookupStub(mirror::ByteArray* jni_stub_array);
-
- bool HasAbstractMethodErrorStubArray() const {
- return abstract_method_error_stub_array_ != NULL;
- }
-
- mirror::ByteArray* GetAbstractMethodErrorStubArray() const {
- CHECK(abstract_method_error_stub_array_ != NULL);
- return abstract_method_error_stub_array_;
- }
-
- void SetAbstractMethodErrorStubArray(mirror::ByteArray* abstract_method_error_stub_array);
-
// Returns a special method that calls into a trampoline for runtime method resolution
mirror::AbstractMethod* GetResolutionMethod() const {
CHECK(HasResolutionMethod());
@@ -397,10 +375,6 @@
mirror::Throwable* pre_allocated_OutOfMemoryError_;
- mirror::ByteArray* jni_stub_array_;
-
- mirror::ByteArray* abstract_method_error_stub_array_;
-
mirror::AbstractMethod* callee_save_methods_[kLastCalleeSaveType];
mirror::AbstractMethod* resolution_method_;
diff --git a/src/runtime_support.h b/src/runtime_support.h
index 2bab323..1c39214 100644
--- a/src/runtime_support.h
+++ b/src/runtime_support.h
@@ -31,8 +31,11 @@
#include "thread.h"
extern "C" void art_interpreter_invoke_handler();
+extern "C" void art_jni_dlsym_lookup_stub();
+extern "C" void art_portable_abstract_method_error_stub();
extern "C" void art_portable_proxy_invoke_handler();
extern "C" void art_portable_resolution_trampoline();
+extern "C" void art_quick_abstract_method_error_stub();
extern "C" void art_quick_deoptimize();
extern "C" void art_quick_instrumentation_entry_from_code(void*);
extern "C" void art_quick_instrumentation_exit_from_code();
@@ -356,9 +359,29 @@
#else
return GetQuickResolutionTrampoline();
#endif
+}
+
+static inline void* GetPortableAbstractMethodErrorStub() {
+ return reinterpret_cast<void*>(art_portable_abstract_method_error_stub);
+}
+
+static inline void* GetQuickAbstractMethodErrorStub() {
+ return reinterpret_cast<void*>(art_quick_abstract_method_error_stub);
+}
+
+// Return address of abstract method error stub for defined compiler.
+static inline void* GetAbstractMethodErrorStub() {
+#if defined(ART_USE_PORTABLE_COMPILER)
+ return GetPortableAbstractMethodErrorStub();
+#else
+ return GetQuickAbstractMethodErrorStub();
+#endif
+}
+
+static inline void* GetJniDlsymLookupStub() {
+ return reinterpret_cast<void*>(art_jni_dlsym_lookup_stub);
+}
} // namespace art
-}
-
#endif // ART_SRC_RUNTIME_SUPPORT_H_
diff --git a/src/thread.cc b/src/thread.cc
index 7021771..8487078 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -1613,7 +1613,6 @@
ENTRY_POINT_INFO(pGetObjInstance),
ENTRY_POINT_INFO(pGetObjStatic),
ENTRY_POINT_INFO(pHandleFillArrayDataFromCode),
- ENTRY_POINT_INFO(pFindNativeMethod),
ENTRY_POINT_INFO(pJniMethodStart),
ENTRY_POINT_INFO(pJniMethodStartSynchronized),
ENTRY_POINT_INFO(pJniMethodEnd),
@@ -1655,7 +1654,6 @@
ENTRY_POINT_INFO(pCheckSuspendFromCode),
ENTRY_POINT_INFO(pTestSuspendFromCode),
ENTRY_POINT_INFO(pDeliverException),
- ENTRY_POINT_INFO(pThrowAbstractMethodErrorFromCode),
ENTRY_POINT_INFO(pThrowArrayBoundsFromCode),
ENTRY_POINT_INFO(pThrowDivZeroFromCode),
ENTRY_POINT_INFO(pThrowNoSuchMethodFromCode),