summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jeff Hao <jeffhao@google.com> 2013-04-24 18:41:58 -0700
committer Jeff Hao <jeffhao@google.com> 2013-04-26 14:50:52 -0700
commit79fe539587d4c09244172d0168eeed0ec9770466 (patch)
tree4fb8fbd03727a74acb4dfde7e969adf32ee32750
parent09b55e1df3b0bcecee25882e45e882887cc8654f (diff)
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
-rw-r--r--build/Android.common.mk3
-rw-r--r--src/class_linker.cc2
-rw-r--r--src/common_test.h7
-rw-r--r--src/compiler/driver/compiler_driver.cc31
-rw-r--r--src/compiler/driver/compiler_driver.h7
-rw-r--r--src/dex2oat.cc6
-rw-r--r--src/gc/space.cc6
-rw-r--r--src/image.cc2
-rw-r--r--src/image.h2
-rw-r--r--src/image_test.cc2
-rw-r--r--src/image_writer.cc15
-rw-r--r--src/jni_internal.h1
-rw-r--r--src/mirror/abstract_method.cc4
-rw-r--r--src/oat/runtime/arm/oat_support_entrypoints_arm.cc4
-rw-r--r--src/oat/runtime/arm/runtime_support_arm.S44
-rw-r--r--src/oat/runtime/arm/stub_arm.cc108
-rw-r--r--src/oat/runtime/mips/oat_support_entrypoints_mips.cc4
-rw-r--r--src/oat/runtime/mips/runtime_support_mips.S70
-rw-r--r--src/oat/runtime/mips/stub_mips.cc122
-rw-r--r--src/oat/runtime/oat_support_entrypoints.h4
-rw-r--r--src/oat/runtime/stub.h51
-rw-r--r--src/oat/runtime/support_jni.cc24
-rw-r--r--src/oat/runtime/support_stubs.cc28
-rw-r--r--src/oat/runtime/x86/oat_support_entrypoints_x86.cc4
-rw-r--r--src/oat/runtime/x86/runtime_support_x86.S58
-rw-r--r--src/oat/runtime/x86/stub_x86.cc121
-rw-r--r--src/oatdump.cc2
-rw-r--r--src/runtime.cc17
-rw-r--r--src/runtime.h26
-rw-r--r--src/runtime_support.h25
-rw-r--r--src/thread.cc2
31 files changed, 224 insertions, 578 deletions
diff --git a/build/Android.common.mk b/build/Android.common.mk
index 59426a4d1d..c8212ef242 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -222,9 +222,6 @@ LIBART_COMMON_SRC_FILES := \
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 9dee36a7b3..d262a5d5a7 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -1600,7 +1600,7 @@ static void LinkCode(SirtRef<mirror::AbstractMethod>& method, const OatFile::Oat
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 05b0e05a7b..6876274b7b 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -234,8 +234,7 @@ class CommonTest : public testing::Test {
} 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 @@ class CommonTest : public testing::Test {
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 @@ class CommonTest : public testing::Test {
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 e6f4b67b91..1660914ce3 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 @@ CompilerTls* CompilerDriver::GetTls() {
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 3581f5f68f..a20e5ef585 100644
--- a/src/compiler/driver/compiler_driver.h
+++ b/src/compiler/driver/compiler_driver.h
@@ -102,13 +102,6 @@ class CompilerDriver {
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 36b8d260a0..e41e537ee0 100644
--- a/src/dex2oat.cc
+++ b/src/dex2oat.cc
@@ -372,12 +372,6 @@ class Dex2Oat {
}
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 d7378c3d70..bfc3e86d0a 100644
--- a/src/gc/space.cc
+++ b/src/gc/space.cc
@@ -512,12 +512,6 @@ ImageSpace* ImageSpace::Create(const std::string& image_file_name) {
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 c746c8e6e3..686a117c99 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 040e3fe36c..f14d7d190a 100644
--- a/src/image.h
+++ b/src/image.h
@@ -81,8 +81,6 @@ class PACKED(4) ImageHeader {
}
enum ImageRoot {
- kJniStubArray,
- kAbstractMethodErrorStubArray,
kResolutionMethod,
kCalleeSaveMethod,
kRefsOnlySaveMethod,
diff --git a/src/image_test.cc b/src/image_test.cc
index e4deda3e6d..192e28ac0e 100644
--- a/src/image_test.cc
+++ b/src/image_test.cc
@@ -127,8 +127,6 @@ TEST_F(ImageTest, WriteRead) {
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 16ac385212..d9e435380d 100644
--- a/src/image_writer.cc
+++ b/src/image_writer.cc
@@ -351,9 +351,6 @@ ObjectArray<Object>* ImageWriter::CreateImageRoots() const {
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 @@ void ImageWriter::FixupMethod(const AbstractMethod* orig, AbstractMethod* copy)
// 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 @@ void ImageWriter::FixupMethod(const AbstractMethod* orig, AbstractMethod* copy)
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 131032a29d..dc6ca4af52 100644
--- a/src/jni_internal.h
+++ b/src/jni_internal.h
@@ -51,7 +51,6 @@ class Thread;
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 3ab3a939a8..559b5581ac 100644
--- a/src/mirror/abstract_method.cc
+++ b/src/mirror/abstract_method.cc
@@ -324,7 +324,7 @@ void AbstractMethod::Invoke(Thread* self, uint32_t* args, uint32_t args_size, JV
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::RegisterNative(Thread* self, const void* native_method) {
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 dcf6bb84d2..1a5fe47e58 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 void CheckSuspendFromCode(Thread* thread);
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 @@ void InitEntryPoints(EntryPoints* points) {
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 @@ void InitEntryPoints(EntryPoints* points) {
// 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 2aa380bb73..3578ba0d16 100644
--- a/src/oat/runtime/arm/runtime_support_arm.S
+++ b/src/oat/runtime/arm/runtime_support_arm.S
@@ -257,6 +257,7 @@ ENTRY art_portable_resolution_trampoline
.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 @@ ENTRY art_quick_deoptimize
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 7c97f4ccb1..0000000000
--- 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 b201b07d17..eb82c42894 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 void CheckSuspendFromCode(Thread* thread);
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 @@ void InitEntryPoints(EntryPoints* points) {
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 @@ void InitEntryPoints(EntryPoints* points) {
// 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 f5f8d9be7a..295e3fe086 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_direct_trampoline_with_access_check, artInvok
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 @@ resolve_fail:
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 @@ END art_quick_resolution_trampoline
* [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 @@ ENTRY art_quick_deoptimize
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 a1adf6687c..0000000000
--- 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 5be1e4908e..72d5348556 100644
--- a/src/oat/runtime/oat_support_entrypoints.h
+++ b/src/oat/runtime/oat_support_entrypoints.h
@@ -70,7 +70,6 @@ struct PACKED(4) EntryPoints {
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 @@ struct PACKED(4) EntryPoints {
// 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 @@ struct PACKED(4) EntryPoints {
};
// 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 ee39273785..0000000000
--- 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 bc9cc45c04..8f0f7ca93d 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 @@ extern "C" const void* artWorkAroundAppJniBugs(Thread* self, intptr_t* sp)
// 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 f78cc79f1b..9f77ae0429 100644
--- a/src/oat/runtime/support_stubs.cc
+++ b/src/oat/runtime/support_stubs.cc
@@ -335,9 +335,9 @@ extern "C" const void* artQuickResolutionTrampoline(mirror::AbstractMethod* call
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 @@ extern void ThrowAbstractMethodErrorFromCode(mirror::AbstractMethod* method, Thr
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 2e35d78503..357bbe0819 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 void CheckSuspendFromCode(Thread* thread);
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 @@ void InitEntryPoints(EntryPoints* points) {
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 @@ void InitEntryPoints(EntryPoints* points) {
// 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 22330c9336..d3a1fb73ff 100644
--- a/src/oat/runtime/x86/runtime_support_x86.S
+++ b/src/oat/runtime/x86/runtime_support_x86.S
@@ -307,6 +307,7 @@ INVOKE_TRAMPOLINE art_quick_invoke_virtual_trampoline_with_access_check, artInvo
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 @@ DEFINE_FUNCTION art_portable_resolution_trampoline
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 @@ DEFINE_FUNCTION art_quick_resolution_trampoline
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 @@ DEFINE_FUNCTION art_quick_deoptimize
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 3f85b2886f..0000000000
--- 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 62af7a99a6..353abcaf03 100644
--- a/src/oatdump.cc
+++ b/src/oatdump.cc
@@ -82,8 +82,6 @@ static void usage() {
}
const char* image_roots_descriptions_[] = {
- "kJniStubArray",
- "kAbstractMethodErrorStubArray",
"kResolutionMethod",
"kCalleeSaveMethod",
"kRefsOnlySaveMethod",
diff --git a/src/runtime.cc b/src/runtime.cc
index b33615622f..25d26b8005 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -82,8 +82,6 @@ Runtime::Runtime()
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 @@ void Runtime::VisitNonThreadRoots(RootVisitor* visitor, void* arg) {
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 @@ void Runtime::VisitRoots(RootVisitor* visitor, void* arg) {
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 93cffbe56e..c7ccda1877 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -242,28 +242,6 @@ class Runtime {
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 @@ class Runtime {
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 2bab3238fd..1c39214ff3 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 @@ static inline void* GetResolutionTrampoline() {
#else
return GetQuickResolutionTrampoline();
#endif
+}
-} // namespace art
+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 70217710bf..84870780a3 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -1613,7 +1613,6 @@ static const EntryPointInfo gThreadEntryPointInfo[] = {
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 @@ static const EntryPointInfo gThreadEntryPointInfo[] = {
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),