diff options
author | Jeff Hao <jeffhao@google.com> | 2013-03-27 15:29:11 -0700 |
---|---|---|
committer | Jeff Hao <jeffhao@google.com> | 2013-03-27 15:29:11 -0700 |
commit | 74180cad94848107cf297d37e72437c5a6eecf1b (patch) | |
tree | 9dfa6f7183bc7d6085a2753483b0f7a93c3ce486 | |
parent | 857fe960a02834c0d6b8792dcc0af8143995cb1f (diff) | |
download | art-74180cad94848107cf297d37e72437c5a6eecf1b.zip art-74180cad94848107cf297d37e72437c5a6eecf1b.tar.gz art-74180cad94848107cf297d37e72437c5a6eecf1b.tar.bz2 |
Remove code related to compiled invoke stubs.
Note that the oat file version is now bumped to 004. A clean-oat will be
necessary after syncing this change.
Change-Id: If8875335b7fcc39b6b40c6f95de07da50da7b6b8
-rw-r--r-- | build/Android.libart-compiler.mk | 3 | ||||
-rw-r--r-- | src/class_linker_test.cc | 1 | ||||
-rw-r--r-- | src/common_test.h | 28 | ||||
-rw-r--r-- | src/compiler/driver/compiler_driver.cc | 74 | ||||
-rw-r--r-- | src/compiler/driver/compiler_driver.h | 19 | ||||
-rw-r--r-- | src/compiler/invoke_stubs/portable/stub_compiler.cc | 144 | ||||
-rw-r--r-- | src/compiler/invoke_stubs/portable/stub_compiler.h | 1 | ||||
-rw-r--r-- | src/compiler/invoke_stubs/quick/jni_internal_arm.cc | 166 | ||||
-rw-r--r-- | src/compiler/invoke_stubs/quick/jni_internal_mips.cc | 177 | ||||
-rw-r--r-- | src/compiler/invoke_stubs/quick/jni_internal_x86.cc | 171 | ||||
-rw-r--r-- | src/compiler/llvm/compiler_llvm.cc | 20 | ||||
-rw-r--r-- | src/compiler/llvm/compiler_llvm.h | 2 | ||||
-rw-r--r-- | src/elf_writer.cc | 15 | ||||
-rw-r--r-- | src/image_writer.cc | 8 | ||||
-rw-r--r-- | src/mirror/abstract_method-inl.h | 10 | ||||
-rw-r--r-- | src/mirror/abstract_method.cc | 14 | ||||
-rw-r--r-- | src/mirror/abstract_method.h | 40 | ||||
-rw-r--r-- | src/oat.cc | 11 | ||||
-rw-r--r-- | src/oat.h | 4 | ||||
-rw-r--r-- | src/oat_file.cc | 29 | ||||
-rw-r--r-- | src/oat_file.h | 10 | ||||
-rw-r--r-- | src/oat_test.cc | 4 | ||||
-rw-r--r-- | src/oat_writer.cc | 83 | ||||
-rw-r--r-- | src/oatdump.cc | 30 |
24 files changed, 24 insertions, 1040 deletions
diff --git a/build/Android.libart-compiler.mk b/build/Android.libart-compiler.mk index 389cc08..fa94490 100644 --- a/build/Android.libart-compiler.mk +++ b/build/Android.libart-compiler.mk @@ -53,9 +53,6 @@ LIBART_COMPILER_SRC_FILES := \ src/compiler/dex/write_elf.cc \ src/compiler/driver/dex_compilation_unit.cc \ src/compiler/invoke_stubs/portable/stub_compiler.cc \ - src/compiler/invoke_stubs/quick/jni_internal_arm.cc \ - src/compiler/invoke_stubs/quick/jni_internal_mips.cc \ - src/compiler/invoke_stubs/quick/jni_internal_x86.cc \ src/compiler/jni/portable/jni_compiler.cc \ src/compiler/jni/quick/arm/calling_convention_arm.cc \ src/compiler/jni/quick/mips/calling_convention_mips.cc \ diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc index e9ba70a..6b8083f 100644 --- a/src/class_linker_test.cc +++ b/src/class_linker_test.cc @@ -478,7 +478,6 @@ struct AbstractMethodOffsets : public CheckOffsets<AbstractMethod> { offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, fp_spill_mask_), "fpSpillMask")); offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, frame_size_in_bytes_), "frameSizeInBytes")); offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, native_gc_map_), "gcMap")); - offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, invoke_stub_), "invokeStub")); offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, mapping_table_), "mappingTable")); offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, method_dex_index_), "methodDexIndex")); offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethod, method_index_), "methodIndex")); diff --git a/src/common_test.h b/src/common_test.h index ad6bcb4..731e1af 100644 --- a/src/common_test.h +++ b/src/common_test.h @@ -188,8 +188,7 @@ class CommonTest : public testing::Test { const uint32_t fp_spill_mask, const uint32_t* mapping_table, const uint16_t* vmap_table, - const uint8_t* gc_map, - const mirror::AbstractMethod::InvokeStub* invoke_stub) { + const uint8_t* gc_map) { return OatFile::OatMethod(NULL, reinterpret_cast<uint32_t>(code), frame_size_in_bytes, @@ -197,8 +196,7 @@ class CommonTest : public testing::Test { fp_spill_mask, reinterpret_cast<uint32_t>(mapping_table), reinterpret_cast<uint32_t>(vmap_table), - reinterpret_cast<uint32_t>(gc_map), - reinterpret_cast<uint32_t>(invoke_stub) + reinterpret_cast<uint32_t>(gc_map) #if defined(ART_USE_PORTABLE_COMPILER) , 0 #endif @@ -207,21 +205,7 @@ class CommonTest : public testing::Test { void MakeExecutable(mirror::AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { CHECK(method != NULL); - - MethodHelper mh(method); - const CompiledInvokeStub* compiled_invoke_stub = - compiler_driver_->FindInvokeStub(mh.IsStatic(), mh.GetShorty()); - CHECK(compiled_invoke_stub != NULL) << PrettyMethod(method); - - const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode(); - MakeExecutable(invoke_stub); - const mirror::AbstractMethod::InvokeStub* method_invoke_stub = - reinterpret_cast<const mirror::AbstractMethod::InvokeStub*>( - CompiledCode::CodePointer(&invoke_stub[0], - compiled_invoke_stub->GetInstructionSet())); - - LOG(INFO) << "MakeExecutable " << PrettyMethod(method) - << " invoke_stub=" << reinterpret_cast<void*>(method_invoke_stub); + LOG(INFO) << "MakeExecutable " << PrettyMethod(method); const CompiledMethod* compiled_method = NULL; if (!method->IsAbstract()) { @@ -247,8 +231,7 @@ class CommonTest : public testing::Test { compiled_method->GetFpSpillMask(), &compiled_method->GetMappingTable()[0], &compiled_method->GetVmapTable()[0], - NULL, - method_invoke_stub); + NULL); oat_method.LinkMethod(method); } else { const void* method_code; @@ -266,8 +249,7 @@ class CommonTest : public testing::Test { 0, NULL, NULL, - NULL, - method_invoke_stub); + NULL); oat_method.LinkMethod(method); } } diff --git a/src/compiler/driver/compiler_driver.cc b/src/compiler/driver/compiler_driver.cc index 169790f..93ba71b 100644 --- a/src/compiler/driver/compiler_driver.cc +++ b/src/compiler/driver/compiler_driver.cc @@ -292,7 +292,6 @@ CompilerDriver::CompilerDriver(CompilerBackend compiler_backend, InstructionSet freezing_constructor_lock_("freezing constructor lock"), compiled_classes_lock_("compiled classes lock"), compiled_methods_lock_("compiled method lock"), - compiled_invoke_stubs_lock_("compiled invoke stubs lock"), compiled_proxy_stubs_lock_("compiled proxy stubs lock"), image_(image), thread_count_(thread_count), @@ -306,9 +305,7 @@ CompilerDriver::CompilerDriver(CompilerBackend compiler_backend, InstructionSet compiler_(NULL), compiler_context_(NULL), jni_compiler_(NULL), - create_invoke_stub_(NULL), - compiler_get_method_code_addr_(NULL), - compiler_get_method_invoke_stub_addr_(NULL) + compiler_get_method_code_addr_(NULL) { std::string compiler_so_name(MakeCompilerSoName(compiler_backend_)); compiler_library_ = dlopen(compiler_so_name.c_str(), RTLD_LAZY); @@ -342,29 +339,6 @@ CompilerDriver::CompilerDriver(CompilerBackend compiler_backend, InstructionSet } if (compiler_backend_ == kPortable) { - create_invoke_stub_ = - FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateLLVMInvokeStub"); - } else { - switch (instruction_set) { - case kArm: - case kThumb2: - create_invoke_stub_ = - FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateArmInvokeStub"); - break; - case kMips: - create_invoke_stub_ = - FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateMipsInvokeStub"); - break; - case kX86: - create_invoke_stub_ = - FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateX86InvokeStub"); - break; - default: - LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; - } - } - - if (compiler_backend_ == kPortable) { create_proxy_stub_ = FindFunction<CreateProxyStubFn>( compiler_so_name, compiler_library_, "ArtCreateProxyStub"); } @@ -386,10 +360,6 @@ CompilerDriver::~CompilerDriver() { STLDeleteValues(&compiled_methods_); } { - MutexLock mu(self, compiled_invoke_stubs_lock_); - STLDeleteValues(&compiled_invoke_stubs_); - } - { MutexLock mu(self, compiled_proxy_stubs_lock_); STLDeleteValues(&compiled_proxy_stubs_); } @@ -1635,14 +1605,6 @@ void CompilerDriver::CompileDexFile(jobject class_loader, const DexFile& dex_fil timings.AddSplit("Compile " + dex_file.GetLocation()); } -static std::string MakeInvokeStubKey(bool is_static, const char* shorty) { - std::string key(shorty); - if (is_static) { - key += "$"; // Must not be a shorty type character. - } - return key; -} - void CompilerDriver::CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags, InvokeType invoke_type, uint32_t class_def_idx, uint32_t method_idx, jobject class_loader, @@ -1693,13 +1655,6 @@ void CompilerDriver::CompileMethod(const DexFile::CodeItem* code_item, uint32_t uint32_t shorty_len; const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx), &shorty_len); bool is_static = (access_flags & kAccStatic) != 0; - std::string key(MakeInvokeStubKey(is_static, shorty)); - CompiledInvokeStub* compiled_invoke_stub = FindInvokeStub(key); - if (compiled_invoke_stub == NULL) { - compiled_invoke_stub = (*create_invoke_stub_)(*this, is_static, shorty, shorty_len); - CHECK(compiled_invoke_stub != NULL); - InsertInvokeStub(key, compiled_invoke_stub); - } if ((compiler_backend_ == kPortable) && !is_static) { CompiledInvokeStub* compiled_proxy_stub = FindProxyStub(shorty); @@ -1717,33 +1672,6 @@ void CompilerDriver::CompileMethod(const DexFile::CodeItem* code_item, uint32_t } } -CompiledInvokeStub* CompilerDriver::FindInvokeStub(bool is_static, const char* shorty) const { - const std::string key(MakeInvokeStubKey(is_static, shorty)); - return FindInvokeStub(key); -} - -CompiledInvokeStub* CompilerDriver::FindInvokeStub(const std::string& key) const { - MutexLock mu(Thread::Current(), compiled_invoke_stubs_lock_); - InvokeStubTable::const_iterator it = compiled_invoke_stubs_.find(key); - if (it == compiled_invoke_stubs_.end()) { - return NULL; - } else { - DCHECK(it->second != NULL); - return it->second; - } -} - -void CompilerDriver::InsertInvokeStub(const std::string& key, CompiledInvokeStub* compiled_invoke_stub) { - MutexLock mu(Thread::Current(), compiled_invoke_stubs_lock_); - InvokeStubTable::iterator it = compiled_invoke_stubs_.find(key); - if (it != compiled_invoke_stubs_.end()) { - // Someone else won the race. - delete compiled_invoke_stub; - } else { - compiled_invoke_stubs_.Put(key, compiled_invoke_stub); - } -} - CompiledInvokeStub* CompilerDriver::FindProxyStub(const char* shorty) const { MutexLock mu(Thread::Current(), compiled_proxy_stubs_lock_); ProxyStubTable::const_iterator it = compiled_proxy_stubs_.find(shorty); diff --git a/src/compiler/driver/compiler_driver.h b/src/compiler/driver/compiler_driver.h index c87d6f7..f398e31 100644 --- a/src/compiler/driver/compiler_driver.h +++ b/src/compiler/driver/compiler_driver.h @@ -122,10 +122,6 @@ class CompilerDriver { CompiledMethod* GetCompiledMethod(MethodReference ref) const LOCKS_EXCLUDED(compiled_methods_lock_); - CompiledInvokeStub* FindInvokeStub(bool is_static, const char* shorty) const; - CompiledInvokeStub* FindInvokeStub(const std::string& key) const - LOCKS_EXCLUDED(compiled_invoke_stubs_lock_); - CompiledInvokeStub* FindProxyStub(const char* shorty) const; void AddRequiresConstructorBarrier(Thread* self, const DexFile* dex_file, size_t class_def_index); @@ -321,9 +317,6 @@ class CompilerDriver { static void CompileClass(const ParallelCompilationManager* context, size_t class_def_index) LOCKS_EXCLUDED(Locks::mutator_lock_); - void InsertInvokeStub(const std::string& key, CompiledInvokeStub* compiled_invoke_stub) - LOCKS_EXCLUDED(compiled_invoke_stubs_lock_); - void InsertProxyStub(const char* shorty, CompiledInvokeStub* compiled_proxy_stub); std::vector<const PatchInformation*> code_to_patch_; @@ -348,10 +341,6 @@ class CompilerDriver { MethodTable compiled_methods_ GUARDED_BY(compiled_methods_lock_); typedef SafeMap<std::string, CompiledInvokeStub*> InvokeStubTable; - // Invocation stubs created to allow invocation of the compiled methods. - mutable Mutex compiled_invoke_stubs_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; - InvokeStubTable compiled_invoke_stubs_ GUARDED_BY(compiled_invoke_stubs_lock_); - typedef SafeMap<std::string, CompiledInvokeStub*> ProxyStubTable; // Proxy stubs created for proxy invocation delegation mutable Mutex compiled_proxy_stubs_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; @@ -387,9 +376,6 @@ class CompilerDriver { uint32_t access_flags, uint32_t method_idx, const DexFile& dex_file); JniCompilerFn jni_compiler_; - typedef CompiledInvokeStub* (*CreateInvokeStubFn)(CompilerDriver& driver, bool is_static, - const char* shorty, uint32_t shorty_len); - CreateInvokeStubFn create_invoke_stub_; pthread_key_t tls_key_; @@ -404,11 +390,6 @@ class CompilerDriver { (const CompilerDriver& driver, const CompiledMethod* cm, const mirror::AbstractMethod* method); CompilerGetMethodCodeAddrFn compiler_get_method_code_addr_; - typedef const mirror::AbstractMethod::InvokeStub* (*CompilerGetMethodInvokeStubAddrFn) - (const CompilerDriver& driver, const CompiledInvokeStub* cm, const mirror::AbstractMethod* method); - CompilerGetMethodInvokeStubAddrFn compiler_get_method_invoke_stub_addr_; - - DISALLOW_COPY_AND_ASSIGN(CompilerDriver); }; diff --git a/src/compiler/invoke_stubs/portable/stub_compiler.cc b/src/compiler/invoke_stubs/portable/stub_compiler.cc index ec6dc30..18a9d2c 100644 --- a/src/compiler/invoke_stubs/portable/stub_compiler.cc +++ b/src/compiler/invoke_stubs/portable/stub_compiler.cc @@ -46,150 +46,6 @@ StubCompiler::StubCompiler(LlvmCompilationUnit* cunit, const CompilerDriver& dri } -CompiledInvokeStub* StubCompiler::CreateInvokeStub(bool is_static, - const char* shorty) { - CHECK(shorty != NULL); - size_t shorty_size = strlen(shorty); - - // Function name - std::string func_name(StringPrintf("invoke_stub_%s%s", shorty, is_static ? "_static" : "")); - - // Get argument types - ::llvm::Type* arg_types[] = { - irb_.getJObjectTy(), // Method object pointer - irb_.getJObjectTy(), // "this" object pointer (NULL for static) - irb_.getJObjectTy(), // Thread object pointer - irb_.getJValueTy()->getPointerTo(), - irb_.getJValueTy()->getPointerTo(), - }; - - // Function type - ::llvm::FunctionType* func_type = - ::llvm::FunctionType::get(irb_.getVoidTy(), arg_types, false); - - // Create function - ::llvm::Function* func = - ::llvm::Function::Create(func_type, ::llvm::Function::InternalLinkage, - func_name, module_); - - - // Create basic block for the body of this function - ::llvm::BasicBlock* block_body = - ::llvm::BasicBlock::Create(*context_, "upcall", func); - - irb_.SetInsertPoint(block_body); - - // Actual arguments - ::llvm::Function::arg_iterator arg_iter = func->arg_begin(); - - ::llvm::Value* method_object_addr = arg_iter++; - ::llvm::Value* callee_this_addr = arg_iter++; - ::llvm::Value* thread_object_addr = arg_iter++; - ::llvm::Value* actual_args_array_addr = arg_iter++; - ::llvm::Value* retval_addr = arg_iter++; - - // Setup thread pointer - ::llvm::Value* old_thread_register = irb_.Runtime().EmitSetCurrentThread(thread_object_addr); - - // Accurate function type - ::llvm::Type* accurate_ret_type = irb_.getJType(shorty[0]); - - std::vector< ::llvm::Type*> accurate_arg_types; - - accurate_arg_types.push_back(irb_.getJObjectTy()); // method object pointer - - if (!is_static) { - accurate_arg_types.push_back(irb_.getJObjectTy()); - } - - for (size_t i = 1; i < shorty_size; ++i) { - accurate_arg_types.push_back(irb_.getJType(shorty[i])); - } - - ::llvm::FunctionType* accurate_func_type = - ::llvm::FunctionType::get(accurate_ret_type, accurate_arg_types, false); - - // Load actual arguments - std::vector< ::llvm::Value*> args; - - args.push_back(method_object_addr); - - if (!is_static) { - args.push_back(callee_this_addr); - } - - for (size_t i = 1; i < shorty_size; ++i) { - char arg_shorty = shorty[i]; - - if (arg_shorty == 'Z' || arg_shorty == 'B' || arg_shorty == 'C' || - arg_shorty == 'S' || arg_shorty == 'I' || arg_shorty == 'J' || - arg_shorty == 'F' || arg_shorty == 'D' || arg_shorty == 'L') { - - ::llvm::Type* arg_type = - irb_.getJType(shorty[i])->getPointerTo(); - - ::llvm::Value* arg_jvalue_addr = - irb_.CreateConstGEP1_32(actual_args_array_addr, i - 1); - - ::llvm::Value* arg_addr = irb_.CreateBitCast(arg_jvalue_addr, arg_type); - - args.push_back(irb_.CreateLoad(arg_addr, kTBAAStackTemp)); - - } else { - LOG(FATAL) << "Unexpected arg shorty for invoke stub: " << shorty[i]; - } - } - - // Invoke managed method now! - ::llvm::Value* code_field_offset_value = - irb_.getPtrEquivInt(mirror::AbstractMethod::GetCodeOffset().Int32Value()); - - ::llvm::Value* code_field_addr = - irb_.CreatePtrDisp(method_object_addr, code_field_offset_value, - accurate_func_type->getPointerTo()->getPointerTo()); - - ::llvm::Value* code_addr = irb_.CreateLoad(code_field_addr, kTBAARuntimeInfo); - - ::llvm::CallInst* retval = irb_.CreateCall(code_addr, args); - for (size_t i = 1; i < shorty_size; ++i) { - switch(shorty[i]) { - case 'Z': - case 'C': - retval->addAttribute(i + (is_static ? 1 : 2), ::llvm::Attribute::ZExt); - break; - - case 'B': - case 'S': - retval->addAttribute(i + (is_static ? 1 : 2), ::llvm::Attribute::SExt); - break; - - default: break; - } - } - - // Store the returned value - if (shorty[0] != 'V') { - ::llvm::Value* ret_addr = - irb_.CreateBitCast(retval_addr, accurate_ret_type->getPointerTo()); - - irb_.CreateStore(retval, ret_addr, kTBAAStackTemp); - } - - // Restore thread register - irb_.Runtime().EmitSetCurrentThread(old_thread_register); - irb_.CreateRetVoid(); - - // Verify the generated function - VERIFY_LLVM_FUNCTION(*func); - - cunit_->Materialize(); - - return new CompiledInvokeStub(cunit_->GetInstructionSet(), - cunit_->GetElfObject(), - func_name); -} - - CompiledInvokeStub* StubCompiler::CreateProxyStub(const char* shorty) { CHECK(shorty != NULL); size_t shorty_size = strlen(shorty); diff --git a/src/compiler/invoke_stubs/portable/stub_compiler.h b/src/compiler/invoke_stubs/portable/stub_compiler.h index ceb8f58..b48620b 100644 --- a/src/compiler/invoke_stubs/portable/stub_compiler.h +++ b/src/compiler/invoke_stubs/portable/stub_compiler.h @@ -41,7 +41,6 @@ class StubCompiler { public: StubCompiler(LlvmCompilationUnit* cunit, const CompilerDriver& compiler); - CompiledInvokeStub* CreateInvokeStub(bool is_static, const char* shorty); CompiledInvokeStub* CreateProxyStub(const char* shorty); private: diff --git a/src/compiler/invoke_stubs/quick/jni_internal_arm.cc b/src/compiler/invoke_stubs/quick/jni_internal_arm.cc deleted file mode 100644 index 1cbe5d9..0000000 --- a/src/compiler/invoke_stubs/quick/jni_internal_arm.cc +++ /dev/null @@ -1,166 +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 <stdint.h> - -#include <algorithm> - -#include "asm_support.h" -#include "compiled_method.h" -#include "compiler/driver/compiler_driver.h" -#include "invoke_arg_array_builder.h" -#include "jni_internal.h" -#include "mirror/abstract_method.h" -#include "oat/utils/arm/assembler_arm.h" -#include "oat/utils/assembler.h" - -namespace art { -namespace arm { - -// Creates a function which invokes a managed method with an array of -// arguments. -// -// At the time of call, the environment looks something like this: -// -// R0 = method pointer -// R1 = receiver pointer or NULL for static methods -// R2 = (managed) thread pointer -// R3 = argument array or NULL for no argument methods -// [SP] = JValue* result or NULL for void returns -// -// As the JNI call has already transitioned the thread into the -// "running" state the remaining responsibilities of this routine are -// to save the native register value and restore the managed thread -// register and transfer arguments from the array into register and on -// the stack, if needed. On return, the thread register must be -// shuffled and the return value must be store into the result JValue. -CompiledInvokeStub* CreateInvokeStub(bool is_static, const char* shorty, uint32_t shorty_len) { - UniquePtr<ArmAssembler> assembler(down_cast<ArmAssembler*>(Assembler::Create(kArm))); -#define __ assembler-> - size_t num_arg_array_bytes = NumArgArrayBytes(shorty, shorty_len); - // Size of frame = spill of R4,R9/LR + Method* + possible receiver + arg array size - // Note, space is left in the frame to flush arguments in registers back to out locations. - size_t unpadded_frame_size = (4 * kPointerSize) + - (is_static ? 0 : kPointerSize) + - num_arg_array_bytes; - size_t frame_size = RoundUp(unpadded_frame_size, kStackAlignment); - - // Spill R4,R9 and LR - RegList save = (1 << R9) | (1 << R4); - __ PushList(save | (1 << LR)); - - // Move the managed thread pointer into R9. - __ mov(R9, ShifterOperand(R2)); - - // Reset R4 to suspend check interval - __ LoadImmediate(R4, SUSPEND_CHECK_INTERVAL); - - // Move frame down for arguments less 3 pushed values above - __ AddConstant(SP, -frame_size + (3 * kPointerSize)); - - // Can either get 3 or 2 arguments into registers - size_t reg_bytes = (is_static ? 3 : 2) * kPointerSize; - if (num_arg_array_bytes <= reg_bytes) { - reg_bytes = num_arg_array_bytes; - } - - // Method* at bottom of frame is null thereby terminating managed stack crawls - __ LoadImmediate(IP, 0, AL); - __ StoreToOffset(kStoreWord, IP, SP, 0); - - // Copy values onto the stack. - size_t src_offset = 0; - size_t dst_offset = (is_static ? 1 : 2) * kPointerSize; - for (size_t i = 1; i < shorty_len; ++i) { - switch (shorty[i]) { - case 'D': - case 'J': - // Move both pointers 64 bits. - __ LoadFromOffset(kLoadWord, IP, R3, src_offset); - src_offset += kPointerSize; - __ StoreToOffset(kStoreWord, IP, SP, dst_offset); - dst_offset += kPointerSize; - - __ LoadFromOffset(kLoadWord, IP, R3, src_offset); - src_offset += kPointerSize; - __ StoreToOffset(kStoreWord, IP, SP, dst_offset); - dst_offset += kPointerSize; - break; - default: - // Move the source pointer sizeof(JValue) and the destination pointer 32 bits. - __ LoadFromOffset(kLoadWord, IP, R3, src_offset); - src_offset += sizeof(JValue); - __ StoreToOffset(kStoreWord, IP, SP, dst_offset); - dst_offset += kPointerSize; - break; - } - } - - // Move all the register arguments into place. - dst_offset = (is_static ? 1 : 2) * kPointerSize; - if (is_static) { - if (reg_bytes > 0 && num_arg_array_bytes > 0) { - __ LoadFromOffset(kLoadWord, R1, SP, dst_offset + 0); - if (reg_bytes > 4 && num_arg_array_bytes > 4) { - __ LoadFromOffset(kLoadWord, R2, SP, dst_offset + 4); - if (reg_bytes > 8 && num_arg_array_bytes > 8) { - __ LoadFromOffset(kLoadWord, R3, SP, dst_offset + 8); - } - } - } - } else { - if (reg_bytes > 0 && num_arg_array_bytes > 0) { - __ LoadFromOffset(kLoadWord, R2, SP, dst_offset + 0); - if (reg_bytes > 4 && num_arg_array_bytes > 4) { - __ LoadFromOffset(kLoadWord, R3, SP, dst_offset + 4); - } - } - } - - // Load the code pointer we are about to call. - __ LoadFromOffset(kLoadWord, IP, R0, mirror::AbstractMethod::GetCodeOffset().Int32Value()); - - // Do the call. - __ blx(IP); - - // If the method returns a value, store it to the result pointer. - if (shorty[0] != 'V') { - // Load the result JValue pointer of the stub caller's out args. - __ LoadFromOffset(kLoadWord, IP, SP, frame_size); - StoreOperandType type = (shorty[0] == 'J' || shorty[0] == 'D') ? kStoreWordPair : kStoreWord; - __ StoreToOffset(type, R0, IP, 0); - } - - // Remove the frame less the spilled R4, R9 and LR - __ AddConstant(SP, frame_size - (3 * kPointerSize)); - - // Pop R4, R9 and the LR into PC - __ PopList(save | (1 << PC)); - // TODO: store native_entry in the stub table - std::vector<uint8_t> code(assembler->CodeSize()); - MemoryRegion region(&code[0], code.size()); - assembler->FinalizeInstructions(region); - return new CompiledInvokeStub(kArm, code); -#undef __ -} - -} // namespace arm -} // namespace art - -extern "C" art::CompiledInvokeStub* ArtCreateArmInvokeStub(art::CompilerDriver& /*compiler*/, bool is_static, - const char* shorty, uint32_t shorty_len) { - return art::arm::CreateInvokeStub(is_static, shorty, shorty_len); -} diff --git a/src/compiler/invoke_stubs/quick/jni_internal_mips.cc b/src/compiler/invoke_stubs/quick/jni_internal_mips.cc deleted file mode 100644 index 133052d..0000000 --- a/src/compiler/invoke_stubs/quick/jni_internal_mips.cc +++ /dev/null @@ -1,177 +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 <stdint.h> - -#include <algorithm> - -#include "asm_support.h" -#include "compiled_method.h" -#include "compiler/driver/compiler_driver.h" -#include "invoke_arg_array_builder.h" -#include "jni_internal.h" -#include "mirror/abstract_method.h" -#include "oat/utils/mips/assembler_mips.h" -#include "oat/utils/assembler.h" - -namespace art { -namespace mips { -// Creates a function which invokes a managed method with an array of -// arguments. -// -// At the time of call, the environment looks something like this: -// -// A0 = method pointer -// A1 = receiver pointer or NULL for static methods -// A2 = (managed) thread pointer -// A3 = argument array or NULL for no argument methods -// [SP] = JValue* result or NULL for void returns -// -// As the JNI call has already transitioned the thread into the -// "running" state the remaining responsibilities of this routine are -// to save the native register value and restore the managed thread -// register and transfer arguments from the array into register and on -// the stack, if needed. On return, the thread register must be -// shuffled and the return value must be store into the result JValue. -CompiledInvokeStub* CreateInvokeStub(bool is_static, const char* shorty, uint32_t shorty_len) { - UniquePtr<MipsAssembler> assembler(down_cast<MipsAssembler*>(Assembler::Create(kMips))); -#define __ assembler-> - size_t num_arg_array_bytes = NumArgArrayBytes(shorty, shorty_len); - // Size of frame = spill of R4,R9/LR + Method* + possible receiver + arg array size - // Note, space is left in the frame to flush arguments in registers back to out locations. - size_t unpadded_frame_size = (4 * kPointerSize) + - (is_static ? 0 : kPointerSize) + - num_arg_array_bytes; - size_t frame_size = RoundUp(unpadded_frame_size, kStackAlignment); - - // Setup frame and spill S0 (rSUSPEND), S1 (rSELF), and RA - __ AddConstant(SP, SP, -frame_size); - __ StoreToOffset(kStoreWord, RA, SP, frame_size - 4); - __ StoreToOffset(kStoreWord, S1, SP, frame_size - 8); - __ StoreToOffset(kStoreWord, S0, SP, frame_size - 12); - - // Move the managed thread pointer into S1. - __ Move(S1, A2); - - // Reset S0 to suspend check interval - __ LoadImmediate(S0, SUSPEND_CHECK_INTERVAL); - - // Can either get 3 or 2 arguments into registers - size_t reg_bytes = (is_static ? 3 : 2) * kPointerSize; - if (num_arg_array_bytes <= reg_bytes) { - reg_bytes = num_arg_array_bytes; - } - - // Method* at bottom of frame is null thereby terminating managed stack crawls - __ StoreToOffset(kStoreWord, ZERO, SP, 0); - - // Copy values onto the stack. - size_t src_offset = 0; - size_t dst_offset = (is_static ? 1 : 2) * kPointerSize; - for (size_t i = 1; i < shorty_len; ++i) { - switch (shorty[i]) { - case 'D': - case 'J': - // Move both pointers 64 bits. - __ LoadFromOffset(kLoadWord, T9, A3, src_offset); - src_offset += kPointerSize; - __ StoreToOffset(kStoreWord, T9, SP, dst_offset); - dst_offset += kPointerSize; - - __ LoadFromOffset(kLoadWord, T9, A3, src_offset); - src_offset += kPointerSize; - __ StoreToOffset(kStoreWord, T9, SP, dst_offset); - dst_offset += kPointerSize; - break; - default: - // Move the source pointer sizeof(JValue) and the destination pointer 32 bits. - __ LoadFromOffset(kLoadWord, T9, A3, src_offset); - src_offset += sizeof(JValue); - __ StoreToOffset(kStoreWord, T9, SP, dst_offset); - dst_offset += kPointerSize; - break; - } - } - - // Move all the register arguments into place. - dst_offset = (is_static ? 1 : 2) * kPointerSize; - if (is_static) { - if (reg_bytes > 0 && num_arg_array_bytes > 0) { - __ LoadFromOffset(kLoadWord, A1, SP, dst_offset + 0); - if (reg_bytes > 4 && num_arg_array_bytes > 4) { - __ LoadFromOffset(kLoadWord, A2, SP, dst_offset + 4); - if (reg_bytes > 8 && num_arg_array_bytes > 8) { - __ LoadFromOffset(kLoadWord, A3, SP, dst_offset + 8); - } - } - } - } else { - if (reg_bytes > 0 && num_arg_array_bytes > 0) { - __ LoadFromOffset(kLoadWord, A2, SP, dst_offset + 0); - if (reg_bytes > 4 && num_arg_array_bytes > 4) { - __ LoadFromOffset(kLoadWord, A3, SP, dst_offset + 4); - } - } - } - - // Load the code pointer we are about to call. - __ LoadFromOffset(kLoadWord, T9, A0, mirror::AbstractMethod::GetCodeOffset().Int32Value()); - - // Do the call. - __ Jalr(T9); - - // If the method returns a value, store it to the result pointer. - if (shorty[0] != 'V') { - // Load the result JValue pointer of the stub caller's out args. - __ LoadFromOffset(kLoadWord, T9, SP, frame_size + 16); - switch (shorty[0]) { - case 'D': - __ StoreDToOffset(D0, T9, 0); - break; - case 'F': - __ StoreFToOffset(F0, T9, 0); - break; - case 'J': - __ StoreToOffset(kStoreWord, V0, T9, 0); - __ StoreToOffset(kStoreWord, V1, T9, 4); - break; - default: - __ StoreToOffset(kStoreWord, V0, T9, 0); - } - } - - // Restore frame and spill regs - __ LoadFromOffset(kLoadWord, S0, SP, frame_size - 12); - __ LoadFromOffset(kLoadWord, S1, SP, frame_size - 8); - __ LoadFromOffset(kLoadWord, RA, SP, frame_size - 4); - __ AddConstant(SP, SP, frame_size); - - __ Jr(RA); - - // TODO: store native_entry in the stub table - std::vector<uint8_t> code(assembler->CodeSize()); - MemoryRegion region(&code[0], code.size()); - assembler->FinalizeInstructions(region); - return new CompiledInvokeStub(kMips, code); -#undef __ -} -} // namespace mips -} // namespace art - -extern "C" art::CompiledInvokeStub* ArtCreateMipsInvokeStub(art::CompilerDriver& /*compiler*/, bool is_static, - const char* shorty, uint32_t shorty_len) { - return art::mips::CreateInvokeStub(is_static, shorty, shorty_len); -} diff --git a/src/compiler/invoke_stubs/quick/jni_internal_x86.cc b/src/compiler/invoke_stubs/quick/jni_internal_x86.cc deleted file mode 100644 index 58d0664..0000000 --- a/src/compiler/invoke_stubs/quick/jni_internal_x86.cc +++ /dev/null @@ -1,171 +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 "compiled_method.h" -#include "compiler/driver/compiler_driver.h" -#include "invoke_arg_array_builder.h" -#include "jni_internal.h" -#include "mirror/abstract_method.h" -#include "oat/utils/assembler.h" -#include "oat/utils/x86/assembler_x86.h" - -namespace art { -namespace x86 { - -// Creates a function which invokes a managed method with an array of -// arguments. -// -// Immediately after the call on X86, the environment looks like this: -// -// [SP+0 ] = Return address -// [SP+4 ] = method pointer -// [SP+8 ] = receiver pointer or NULL for static methods -// [SP+12] = (managed) thread pointer -// [SP+16] = argument array or NULL for no argument methods -// [SP+20] = JValue* result or NULL for void returns -// -// As the JNI call has already transitioned the thread into the -// "running" state the remaining responsibilities of this routine are -// to save the native registers and set up the managed registers. On -// return, the return value must be store into the result JValue. -CompiledInvokeStub* CreateInvokeStub(bool is_static, const char* shorty, uint32_t shorty_len) { - UniquePtr<X86Assembler> assembler(down_cast<X86Assembler*>(Assembler::Create(kX86))); -#define __ assembler-> - size_t num_arg_array_bytes = NumArgArrayBytes(shorty, shorty_len); - // Size of frame = return address + saved EBX + Method* + possible receiver + arg array size - // Note, space is left in the frame to flush arguments in registers back to out locations. - size_t frame_size = 3 * kPointerSize + (is_static ? 0 : kPointerSize) + num_arg_array_bytes; - size_t pad_size = RoundUp(frame_size, kStackAlignment) - frame_size; - - Register rMethod = EAX; - __ movl(rMethod, Address(ESP, 4)); // EAX = method - Register rReceiver = ECX; - if (!is_static) { - __ movl(rReceiver, Address(ESP, 8)); // ECX = receiver - } - // Save EBX - __ pushl(EBX); - Register rArgArray = EBX; - __ movl(rArgArray, Address(ESP, 20)); // EBX = arg array - - // TODO: optimize the frame set up to avoid excessive SP math - // Push padding - if (pad_size != 0) { - __ subl(ESP, Immediate(pad_size)); - } - // Push/copy arguments. - size_t arg_count = (shorty_len - 1); - size_t dst_offset = num_arg_array_bytes; - size_t src_offset = arg_count * sizeof(JValue); - for (size_t i = shorty_len - 1; i > 0; --i) { - switch (shorty[i]) { - case 'D': - case 'J': - // Move both pointers 64 bits. - dst_offset -= kPointerSize; - src_offset -= sizeof(JValue) / 2; - __ pushl(Address(rArgArray, src_offset)); - dst_offset -= kPointerSize; - src_offset -= sizeof(JValue) / 2; - __ pushl(Address(rArgArray, src_offset)); - break; - default: - // Move the source pointer sizeof(JValue) and the destination pointer 32 bits. - dst_offset -= kPointerSize; - src_offset -= sizeof(JValue); - __ pushl(Address(rArgArray, src_offset)); - break; - } - } - - // Backing space for receiver. - if (!is_static) { - __ pushl(Immediate(0)); - } - // Push 0 as NULL Method* thereby terminating managed stack crawls. - __ pushl(Immediate(0)); - if (!is_static) { - if (shorty_len > 1) { - // Receiver already in ECX, pass remaining 2 args in EDX and EBX. - __ movl(EDX, Address(rArgArray, 0)); - if (shorty[1] == 'D' || shorty[1] == 'J') { - __ movl(EBX, Address(rArgArray, sizeof(JValue) / 2)); - } else if (shorty_len > 2) { - __ movl(EBX, Address(rArgArray, sizeof(JValue))); - } - } - } else { - if (shorty_len > 1) { - // Pass remaining 3 args in ECX, EDX and EBX. - __ movl(ECX, Address(rArgArray, 0)); - if (shorty[1] == 'D' || shorty[1] == 'J') { - __ movl(EDX, Address(rArgArray, sizeof(JValue) / 2)); - if (shorty_len > 2) { - __ movl(EBX, Address(rArgArray, sizeof(JValue))); - } - } else if (shorty_len > 2) { - __ movl(EDX, Address(rArgArray, sizeof(JValue))); - if (shorty[2] == 'D' || shorty[2] == 'J') { - __ movl(EBX, Address(rArgArray, sizeof(JValue) + (sizeof(JValue) / 2))); - } else { - __ movl(EBX, Address(rArgArray, sizeof(JValue) + sizeof(JValue))); - } - } - } - } - - __ call(Address(EAX, mirror::AbstractMethod::GetCodeOffset())); // Call code off of method - - // Pop arguments up to EBX and the return address. - __ addl(ESP, Immediate(frame_size + pad_size - (2 * kPointerSize))); - // Restore EBX. - __ popl(EBX); - char ch = shorty[0]; - if (ch != 'V') { - // Load the result JValue pointer. - __ movl(ECX, Address(ESP, 20)); - switch (ch) { - case 'D': - __ movsd(Address(ECX, 0), XMM0); - break; - case 'F': - __ movss(Address(ECX, 0), XMM0); - break; - case 'J': - __ movl(Address(ECX, 0), EAX); - __ movl(Address(ECX, 4), EDX); - break; - default: - __ movl(Address(ECX, 0), EAX); - break; - } - } - __ ret(); - // TODO: store native_entry in the stub table - std::vector<uint8_t> code(assembler->CodeSize()); - MemoryRegion region(&code[0], code.size()); - assembler->FinalizeInstructions(region); - return new CompiledInvokeStub(kX86, code); -#undef __ -} - -} // namespace x86 -} // namespace art - -extern "C" art::CompiledInvokeStub* ArtCreateX86InvokeStub(art::CompilerDriver& /*compiler*/, bool is_static, - const char* shorty, uint32_t shorty_len) { - return art::x86::CreateInvokeStub(is_static, shorty, shorty_len); -} diff --git a/src/compiler/llvm/compiler_llvm.cc b/src/compiler/llvm/compiler_llvm.cc index 3fbc55a..0fa9eec 100644 --- a/src/compiler/llvm/compiler_llvm.cc +++ b/src/compiler/llvm/compiler_llvm.cc @@ -174,17 +174,6 @@ CompileNativeMethod(DexCompilationUnit* dex_compilation_unit) { } -CompiledInvokeStub* CompilerLLVM::CreateInvokeStub(bool is_static, - char const *shorty) { - UniquePtr<LlvmCompilationUnit> cunit(AllocateCompilationUnit()); - - UniquePtr<StubCompiler> stub_compiler( - new StubCompiler(cunit.get(), *compiler_driver_)); - - return stub_compiler->CreateInvokeStub(is_static, shorty); -} - - CompiledInvokeStub* CompilerLLVM::CreateProxyStub(char const *shorty) { UniquePtr<LlvmCompilationUnit> cunit(AllocateCompilationUnit()); @@ -255,15 +244,6 @@ extern "C" art::CompiledMethod* ArtLLVMJniCompileMethod(art::CompilerDriver& dri return result; } -extern "C" art::CompiledInvokeStub* ArtCreateLLVMInvokeStub(art::CompilerDriver& driver, - bool is_static, - const char* shorty, - uint32_t shorty_len) { - art::llvm::CompilerLLVM* compiler_llvm = ContextOf(driver); - art::CompiledInvokeStub* result = compiler_llvm->CreateInvokeStub(is_static, shorty); - return result; -} - extern "C" art::CompiledInvokeStub* ArtCreateProxyStub(art::CompilerDriver& driver, const char* shorty, uint32_t shorty_len) { diff --git a/src/compiler/llvm/compiler_llvm.h b/src/compiler/llvm/compiler_llvm.h index 31973a4..772864c 100644 --- a/src/compiler/llvm/compiler_llvm.h +++ b/src/compiler/llvm/compiler_llvm.h @@ -82,8 +82,6 @@ class CompilerLLVM { CompiledMethod* CompileNativeMethod(DexCompilationUnit* dex_compilation_unit); - CompiledInvokeStub* CreateInvokeStub(bool is_static, const char *shorty); - CompiledInvokeStub* CreateProxyStub(const char *shorty); private: diff --git a/src/elf_writer.cc b/src/elf_writer.cc index 7f90468..185e3be 100644 --- a/src/elf_writer.cc +++ b/src/elf_writer.cc @@ -242,12 +242,6 @@ void ElfWriter::AddMethodInputs(const std::vector<const DexFile*>& dex_files) { if (compiled_method != NULL) { AddCompiledCodeInput(*compiled_method); } - const CompiledInvokeStub* compiled_invoke_stub = compiler_driver_->FindInvokeStub(invoke_type == kStatic, - shorty); - if (compiled_invoke_stub != NULL) { - AddCompiledCodeInput(*compiled_invoke_stub); - } - if (invoke_type != kStatic) { const CompiledInvokeStub* compiled_proxy_stub = compiler_driver_->FindProxyStub(shorty); if (compiled_proxy_stub != NULL) { @@ -392,15 +386,6 @@ void ElfWriter::FixupOatMethodOffsets(const std::vector<const DexFile*>& dex_fil method->SetOatCodeOffset(offset); } } - const CompiledInvokeStub* compiled_invoke_stub = compiler_driver_->FindInvokeStub(invoke_type == kStatic, - shorty); - if (compiled_invoke_stub != NULL) { - uint32_t offset = FixupCompiledCodeOffset(*elf_file.get(), oatdata_address, *compiled_invoke_stub); - if (method != NULL) { - method->SetOatInvokeStubOffset(offset); - } - } - if (invoke_type != kStatic) { const CompiledInvokeStub* compiled_proxy_stub = compiler_driver_->FindProxyStub(shorty); if (compiled_proxy_stub != NULL) { diff --git a/src/image_writer.cc b/src/image_writer.cc index a56a4aa..5638b5b 100644 --- a/src/image_writer.cc +++ b/src/image_writer.cc @@ -479,14 +479,8 @@ void ImageWriter::FixupClass(const Class* orig, Class* copy) { void ImageWriter::FixupMethod(const AbstractMethod* orig, AbstractMethod* copy) { FixupInstanceFields(orig, copy); - // OatWriter replaces the code_ and invoke_stub_ with offset values. + // OatWriter replaces the code_ with an offset value. // Here we readjust to a pointer relative to oat_begin_ - - // Every type of method can have an invoke stub - uint32_t invoke_stub_offset = orig->GetOatInvokeStubOffset(); - const byte* invoke_stub = GetOatAddress(invoke_stub_offset); - copy->SetInvokeStub(reinterpret_cast<AbstractMethod::InvokeStub*>(const_cast<byte*>(invoke_stub))); - 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(); diff --git a/src/mirror/abstract_method-inl.h b/src/mirror/abstract_method-inl.h index e14cce2..2049748 100644 --- a/src/mirror/abstract_method-inl.h +++ b/src/mirror/abstract_method-inl.h @@ -164,16 +164,6 @@ inline uint32_t AbstractMethod::GetOatNativeGcMapOffset() const { return reinterpret_cast<uint32_t>(GetNativeGcMap()); } -inline uint32_t AbstractMethod::GetOatInvokeStubOffset() const { - DCHECK(!Runtime::Current()->IsStarted()); - return reinterpret_cast<uint32_t>(GetInvokeStub()); -} - -inline void AbstractMethod::SetOatInvokeStubOffset(uint32_t invoke_stub_offset) { - DCHECK(!Runtime::Current()->IsStarted()); - SetInvokeStub(reinterpret_cast<InvokeStub*>(invoke_stub_offset)); -} - inline bool AbstractMethod::IsRuntimeMethod() const { return GetDexMethodIndex() == DexFile::kDexNoIndex16; } diff --git a/src/mirror/abstract_method.cc b/src/mirror/abstract_method.cc index 2e56004..f74814c 100644 --- a/src/mirror/abstract_method.cc +++ b/src/mirror/abstract_method.cc @@ -270,10 +270,7 @@ void AbstractMethod::Invoke(Thread* self, uint32_t* args, uint32_t args_size, JV ManagedStack fragment; self->PushManagedStackFragment(&fragment); - // Call the invoke stub associated with the method. - // Pass everything as arguments. - AbstractMethod::InvokeStub* stub = GetInvokeStub(); - + // Call the invoke stub, passing everything as arguments. if (UNLIKELY(!Runtime::Current()->IsStarted())){ LOG(INFO) << "Not invoking " << PrettyMethod(this) << " for a runtime that isn't started"; if (result != NULL) { @@ -285,8 +282,7 @@ void AbstractMethod::Invoke(Thread* self, uint32_t* args, uint32_t args_size, JV if (GetCode() != NULL) { if (!interpret) { if (kLogInvocationStartAndReturn) { - LOG(INFO) << StringPrintf("Invoking '%s' code=%p stub=%p", - PrettyMethod(this).c_str(), GetCode(), stub); + LOG(INFO) << StringPrintf("Invoking '%s' code=%p", PrettyMethod(this).c_str(), GetCode()); } #ifdef ART_USE_PORTABLE_COMPILER (*art_portable_invoke_stub)(this, args, args_size, self, result, result_type); @@ -304,8 +300,7 @@ void AbstractMethod::Invoke(Thread* self, uint32_t* args, uint32_t args_size, JV interpreter::EnterInterpreterFromLLVM(self, shadow_frame, result); } if (kLogInvocationStartAndReturn) { - LOG(INFO) << StringPrintf("Returned '%s' code=%p stub=%p", - PrettyMethod(this).c_str(), GetCode(), stub); + LOG(INFO) << StringPrintf("Returned '%s' code=%p", PrettyMethod(this).c_str(), GetCode()); } } else { if (kLogInvocationStartAndReturn) { @@ -323,8 +318,7 @@ void AbstractMethod::Invoke(Thread* self, uint32_t* args, uint32_t args_size, JV } } else { LOG(INFO) << "Not invoking '" << PrettyMethod(this) - << "' code=" << reinterpret_cast<const void*>(GetCode()) - << " stub=" << reinterpret_cast<void*>(stub); + << "' code=" << reinterpret_cast<const void*>(GetCode()); if (result != NULL) { result->SetJ(0); } diff --git a/src/mirror/abstract_method.h b/src/mirror/abstract_method.h index b91885a..d10031a 100644 --- a/src/mirror/abstract_method.h +++ b/src/mirror/abstract_method.h @@ -39,13 +39,6 @@ class StaticStorageBase; // C++ mirror of java.lang.reflect.Method and java.lang.reflect.Constructor class MANAGED AbstractMethod : public Object { public: - // A function that invokes a method with an array of its arguments. - typedef void InvokeStub(const AbstractMethod* method, - Object* obj, - Thread* thread, - JValue* args, - JValue* result); - Class* GetDeclaringClass() const; void SetDeclaringClass(Class *new_declaring_class) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -345,36 +338,6 @@ class MANAGED AbstractMethod : public Object { void SetNativeMethod(const void*); - // Native to managed invocation stub entry point - InvokeStub* GetInvokeStub() const { - InvokeStub* result = GetFieldPtr<InvokeStub*>( - OFFSET_OF_OBJECT_MEMBER(AbstractMethod, invoke_stub_), false); - // TODO: DCHECK(result != NULL); should be ahead of time compiled - return result; - } - - void SetInvokeStub(InvokeStub* invoke_stub) { - SetFieldPtr<InvokeStub*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, invoke_stub_), - invoke_stub, false); - } - - uint32_t GetInvokeStubSize() const { - uintptr_t invoke_stub = reinterpret_cast<uintptr_t>(GetInvokeStub()); - if (invoke_stub == 0) { - return 0; - } - // TODO: make this Thumb2 specific - invoke_stub &= ~0x1; - return reinterpret_cast<const uint32_t*>(invoke_stub)[-1]; - } - - uint32_t GetOatInvokeStubOffset() const; - void SetOatInvokeStubOffset(uint32_t invoke_stub_offset); - - static MemberOffset GetInvokeStubOffset() { - return OFFSET_OF_OBJECT_MEMBER(AbstractMethod, invoke_stub_); - } - static MemberOffset GetMethodIndexOffset() { return OFFSET_OF_OBJECT_MEMBER(AbstractMethod, method_index_); } @@ -473,9 +436,6 @@ class MANAGED AbstractMethod : public Object { // Garbage collection map of native PC offsets to reference bitmaps. const uint8_t* native_gc_map_; - // Native invocation stub entry point for calling from native to managed code. - InvokeStub* invoke_stub_; - // Mapping from native pc to dex pc const uint32_t* mapping_table_; @@ -22,7 +22,7 @@ namespace art { const uint8_t OatHeader::kOatMagic[] = { 'o', 'a', 't', '\n' }; -const uint8_t OatHeader::kOatVersion[] = { '0', '0', '3', '\0' }; +const uint8_t OatHeader::kOatVersion[] = { '0', '0', '4', '\0' }; OatHeader::OatHeader() { memset(this, 0, sizeof(*this)); @@ -140,8 +140,7 @@ OatMethodOffsets::OatMethodOffsets() fp_spill_mask_(0), mapping_table_offset_(0), vmap_table_offset_(0), - gc_map_offset_(0), - invoke_stub_offset_(0) + gc_map_offset_(0) #if defined(ART_USE_PORTABLE_COMPILER) , proxy_stub_offset_(0) #endif @@ -153,8 +152,7 @@ OatMethodOffsets::OatMethodOffsets(uint32_t code_offset, uint32_t fp_spill_mask, uint32_t mapping_table_offset, uint32_t vmap_table_offset, - uint32_t gc_map_offset, - uint32_t invoke_stub_offset + uint32_t gc_map_offset #if defined(ART_USE_PORTABLE_COMPILER) , uint32_t proxy_stub_offset #endif @@ -165,8 +163,7 @@ OatMethodOffsets::OatMethodOffsets(uint32_t code_offset, fp_spill_mask_(fp_spill_mask), mapping_table_offset_(mapping_table_offset), vmap_table_offset_(vmap_table_offset), - gc_map_offset_(gc_map_offset), - invoke_stub_offset_(invoke_stub_offset) + gc_map_offset_(gc_map_offset) #if defined(ART_USE_PORTABLE_COMPILER) , proxy_stub_offset_(proxy_stub_offset) #endif @@ -81,8 +81,7 @@ class PACKED(4) OatMethodOffsets { uint32_t fp_spill_mask, uint32_t mapping_table_offset, uint32_t vmap_table_offset, - uint32_t gc_map_offset, - uint32_t invoke_stub_offset + uint32_t gc_map_offset #if defined(ART_USE_PORTABLE_COMPILER) , uint32_t proxy_stub_offset #endif @@ -97,7 +96,6 @@ class PACKED(4) OatMethodOffsets { uint32_t mapping_table_offset_; uint32_t vmap_table_offset_; uint32_t gc_map_offset_; - uint32_t invoke_stub_offset_; #if defined(ART_USE_PORTABLE_COMPILER) uint32_t proxy_stub_offset_; diff --git a/src/oat_file.cc b/src/oat_file.cc index 7f7bab9..7c4085e 100644 --- a/src/oat_file.cc +++ b/src/oat_file.cc @@ -344,8 +344,7 @@ const OatFile::OatMethod OatFile::OatClass::GetOatMethod(uint32_t method_index) oat_method_offsets.fp_spill_mask_, oat_method_offsets.mapping_table_offset_, oat_method_offsets.vmap_table_offset_, - oat_method_offsets.gc_map_offset_, - oat_method_offsets.invoke_stub_offset_ + oat_method_offsets.gc_map_offset_ #if defined(ART_USE_PORTABLE_COMPILER) , oat_method_offsets.proxy_stub_offset_ #endif @@ -359,8 +358,7 @@ OatFile::OatMethod::OatMethod(const byte* base, const uint32_t fp_spill_mask, const uint32_t mapping_table_offset, const uint32_t vmap_table_offset, - const uint32_t gc_map_offset, - const uint32_t invoke_stub_offset + const uint32_t gc_map_offset #if defined(ART_USE_PORTABLE_COMPILER) , const uint32_t proxy_stub_offset #endif @@ -372,8 +370,7 @@ OatFile::OatMethod::OatMethod(const byte* base, fp_spill_mask_(fp_spill_mask), mapping_table_offset_(mapping_table_offset), vmap_table_offset_(vmap_table_offset), - native_gc_map_offset_(gc_map_offset), - invoke_stub_offset_(invoke_stub_offset) + native_gc_map_offset_(gc_map_offset) #if defined(ART_USE_PORTABLE_COMPILER) , proxy_stub_offset_(proxy_stub_offset) #endif @@ -417,25 +414,6 @@ uint32_t OatFile::OatMethod::GetCodeSize() const { #endif } -mirror::AbstractMethod::InvokeStub* OatFile::OatMethod::GetInvokeStub() const { - const byte* stub = GetOatPointer<const byte*>(invoke_stub_offset_); - return reinterpret_cast<mirror::AbstractMethod::InvokeStub*>(const_cast<byte*>(stub)); -} - -uint32_t OatFile::OatMethod::GetInvokeStubSize() const { -#if defined(ART_USE_PORTABLE_COMPILER) - return 0; -#else - uintptr_t code = reinterpret_cast<uint32_t>(GetInvokeStub()); - if (code == 0) { - return 0; - } - // TODO: make this Thumb2 specific - code &= ~0x1; - return reinterpret_cast<uint32_t*>(code)[-1]; -#endif -} - #if defined(ART_USE_PORTABLE_COMPILER) const void* OatFile::OatMethod::GetProxyStub() const { return GetOatPointer<const void*>(proxy_stub_offset_); @@ -451,7 +429,6 @@ void OatFile::OatMethod::LinkMethod(mirror::AbstractMethod* method) const { method->SetMappingTable(GetMappingTable()); method->SetVmapTable(GetVmapTable()); method->SetNativeGcMap(GetNativeGcMap()); // Note, used by native methods in work around JNI mode. - method->SetInvokeStub(GetInvokeStub()); } } // namespace art diff --git a/src/oat_file.h b/src/oat_file.h index 4aa18ba..e71db47 100644 --- a/src/oat_file.h +++ b/src/oat_file.h @@ -91,9 +91,6 @@ class OatFile { uint32_t GetNativeGcMapOffset() const { return native_gc_map_offset_; } - uint32_t GetInvokeStubOffset() const { - return invoke_stub_offset_; - } const void* GetCode() const; uint32_t GetCodeSize() const; @@ -108,9 +105,6 @@ class OatFile { return GetOatPointer<const uint8_t*>(native_gc_map_offset_); } - mirror::AbstractMethod::InvokeStub* GetInvokeStub() const; - uint32_t GetInvokeStubSize() const; - #if defined(ART_USE_PORTABLE_COMPILER) const void* GetProxyStub() const; #endif @@ -125,8 +119,7 @@ class OatFile { const uint32_t fp_spill_mask, const uint32_t mapping_table_offset, const uint32_t vmap_table_offset, - const uint32_t gc_map_offset, - const uint32_t invoke_stub_offset + const uint32_t gc_map_offset #if defined(ART_USE_PORTABLE_COMPILER) , const uint32_t proxy_stub_offset #endif @@ -150,7 +143,6 @@ class OatFile { uint32_t mapping_table_offset_; uint32_t vmap_table_offset_; uint32_t native_gc_map_offset_; - uint32_t invoke_stub_offset_; #if defined(ART_USE_PORTABLE_COMPILER) uint32_t proxy_stub_offset_; diff --git a/src/oat_test.cc b/src/oat_test.cc index a2ea71c..78a2e9a 100644 --- a/src/oat_test.cc +++ b/src/oat_test.cc @@ -144,10 +144,10 @@ TEST_F(OatTest, OatHeaderSizeCheck) { // it is time to update OatHeader::kOatVersion EXPECT_EQ(36U, sizeof(OatHeader)); #if !defined(ART_USE_PORTABLE_COMPILER) - EXPECT_EQ(32U, sizeof(OatMethodOffsets)); + EXPECT_EQ(28U, sizeof(OatMethodOffsets)); #else // ART-LLVM has a extra 4 bytes field: proxy_stub_offset_ - EXPECT_EQ(36U, sizeof(OatMethodOffsets)); + EXPECT_EQ(32U, sizeof(OatMethodOffsets)); #endif } diff --git a/src/oat_writer.cc b/src/oat_writer.cc index 622010b..86f1b11 100644 --- a/src/oat_writer.cc +++ b/src/oat_writer.cc @@ -244,8 +244,6 @@ size_t OatWriter::InitOatCodeMethod(size_t offset, size_t oat_class_index, uint32_t mapping_table_offset = 0; uint32_t vmap_table_offset = 0; uint32_t gc_map_offset = 0; - // derived from CompiledInvokeStub if available - uint32_t invoke_stub_offset = 0; #if defined(ART_USE_PORTABLE_COMPILER) uint32_t proxy_stub_offset = 0; #endif @@ -347,35 +345,6 @@ size_t OatWriter::InitOatCodeMethod(size_t offset, size_t oat_class_index, } } - const char* shorty = dex_file->GetMethodShorty(dex_file->GetMethodId(method_idx)); - CompiledInvokeStub* compiled_invoke_stub = compiler_driver_->FindInvokeStub(invoke_type == kStatic, - shorty); - if (compiled_invoke_stub != NULL) { -#if defined(ART_USE_PORTABLE_COMPILER) - compiled_invoke_stub->AddOatdataOffsetToCompliledCodeOffset( - oat_method_offsets_offset + OFFSETOF_MEMBER(OatMethodOffsets, invoke_stub_offset_)); -#else - const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode(); - offset = CompiledMethod::AlignCode(offset, compiler_driver_->GetInstructionSet()); - DCHECK_ALIGNED(offset, kArmAlignment); - uint32_t invoke_stub_size = invoke_stub.size() * sizeof(invoke_stub[0]); - CHECK_NE(invoke_stub_size, 0U); - uint32_t thumb_offset = compiled_invoke_stub->CodeDelta(); - invoke_stub_offset = offset + sizeof(invoke_stub_size) + thumb_offset; - - // Deduplicate invoke stubs - SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = code_offsets_.find(&invoke_stub); - if (stub_iter != code_offsets_.end()) { - invoke_stub_offset = stub_iter->second; - } else { - code_offsets_.Put(&invoke_stub, invoke_stub_offset); - offset += sizeof(invoke_stub_size); // invoke stub size is prepended before code - offset += invoke_stub_size; - oat_header_->UpdateChecksum(&invoke_stub[0], invoke_stub_size); - } -#endif - } - #if defined(ART_USE_PORTABLE_COMPILER) if (invoke_type != kStatic) { CompiledInvokeStub* compiled_proxy_stub = compiler_driver_->FindProxyStub(shorty); @@ -393,8 +362,7 @@ size_t OatWriter::InitOatCodeMethod(size_t offset, size_t oat_class_index, fp_spill_mask, mapping_table_offset, vmap_table_offset, - gc_map_offset, - invoke_stub_offset + gc_map_offset #if defined(ART_USE_PORTABLE_COMPILER) , proxy_stub_offset #endif @@ -421,7 +389,6 @@ size_t OatWriter::InitOatCodeMethod(size_t offset, size_t oat_class_index, } method->SetOatVmapTableOffset(vmap_table_offset); method->SetOatNativeGcMapOffset(gc_map_offset); - method->SetOatInvokeStubOffset(invoke_stub_offset); } return offset; @@ -702,54 +669,6 @@ size_t OatWriter::WriteCodeMethod(OutputStream& out, size_t offset, size_t oat_c DCHECK_OFFSET(); } -#if !defined(ART_USE_PORTABLE_COMPILER) - const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx)); - const CompiledInvokeStub* compiled_invoke_stub = compiler_driver_->FindInvokeStub(is_static, shorty); - if (compiled_invoke_stub != NULL) { - uint32_t aligned_offset = CompiledMethod::AlignCode(offset, - compiler_driver_->GetInstructionSet()); - uint32_t aligned_code_delta = aligned_offset - offset; - if (aligned_code_delta != 0) { - off_t new_offset = out.Seek(aligned_code_delta, kSeekCurrent); - if (static_cast<uint32_t>(new_offset) != aligned_offset) { - PLOG(ERROR) << "Failed to seek to align invoke stub code. Actual: " << new_offset - << " Expected: " << aligned_offset; - return 0; - } - offset += aligned_code_delta; - DCHECK_OFFSET(); - } - DCHECK_ALIGNED(offset, kArmAlignment); - const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode(); - uint32_t invoke_stub_size = invoke_stub.size() * sizeof(invoke_stub[0]); - CHECK_NE(invoke_stub_size, 0U); - - // Deduplicate invoke stubs - size_t invoke_stub_offset = offset + sizeof(invoke_stub_size) + compiled_invoke_stub->CodeDelta(); - SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator stub_iter = - code_offsets_.find(&invoke_stub); - if (stub_iter != code_offsets_.end() - && invoke_stub_offset != method_offsets.invoke_stub_offset_) { - DCHECK(stub_iter->second == method_offsets.invoke_stub_offset_) - << PrettyMethod(method_idx, dex_file); - } else { - DCHECK(invoke_stub_offset == method_offsets.invoke_stub_offset_) << PrettyMethod(method_idx, dex_file); - if (!out.WriteFully(&invoke_stub_size, sizeof(invoke_stub_size))) { - ReportWriteFailure("invoke stub code size", method_idx, dex_file, out); - return 0; - } - offset += sizeof(invoke_stub_size); - DCHECK_OFFSET(); - if (!out.WriteFully(&invoke_stub[0], invoke_stub_size)) { - ReportWriteFailure("invoke stub code", method_idx, dex_file, out); - return 0; - } - offset += invoke_stub_size; - DCHECK_OFFSET(); - } - } -#endif - return offset; } diff --git a/src/oatdump.cc b/src/oatdump.cc index 7e92024..12e93db 100644 --- a/src/oatdump.cc +++ b/src/oatdump.cc @@ -239,7 +239,6 @@ class OatDumper { offsets_.insert(oat_method.GetMappingTableOffset()); offsets_.insert(oat_method.GetVmapTableOffset()); offsets_.insert(oat_method.GetNativeGcMapOffset()); - offsets_.insert(oat_method.GetInvokeStubOffset()); } void DumpOatDexFile(std::ostream& os, const OatFile::OatDexFile& oat_dex_file) { @@ -368,16 +367,6 @@ class OatDumper { DumpCode(indent2_os, oat_method, dex_method_idx, &dex_file, class_def_idx, code_item, method_access_flags); } - { - indent1_os << StringPrintf("INVOKE STUB: %p (offset=0x%08x size=%d)%s\n", - oat_method.GetInvokeStub(), - oat_method.GetInvokeStubOffset(), - oat_method.GetInvokeStubSize(), - oat_method.GetInvokeStub() != NULL ? "..." : ""); - Indenter indent2_filter(indent1_os.rdbuf(), kIndentChar, kIndentBy1Count); - std::ostream indent2_os(&indent2_filter); - DumpInvokeStub(indent2_os, oat_method); - } } void DumpSpillMask(std::ostream& os, uint32_t spill_mask, bool is_float) { @@ -684,12 +673,6 @@ class OatDumper { } } - void DumpInvokeStub(std::ostream& os, const OatFile::OatMethod& oat_method) { - const uint8_t* begin = reinterpret_cast<const uint8_t*>(oat_method.GetInvokeStub()); - const uint8_t* end = begin + oat_method.GetInvokeStubSize(); - disassembler_->Dump(os, begin, end); - } - const std::string host_prefix_; const OatFile& oat_file_; std::vector<const OatFile::OatDexFile*> oat_dex_files_; @@ -1006,11 +989,6 @@ class ImageDumper { DCHECK(method->GetNativeGcMap() == NULL) << PrettyMethod(method); DCHECK(method->GetMappingTable() == NULL) << PrettyMethod(method); bool first_occurrence; - size_t invoke_stub_size = state->ComputeOatSize( - reinterpret_cast<const void*>(method->GetInvokeStub()), &first_occurrence); - if (first_occurrence) { - state->stats_.managed_to_native_code_bytes += invoke_stub_size; - } const void* oat_code = state->GetOatCodeBegin(method); uint32_t oat_code_size = state->GetOatCodeSize(method); state->ComputeOatSize(oat_code, &first_occurrence); @@ -1049,12 +1027,6 @@ class ImageDumper { state->stats_.vmap_table_bytes += vmap_table_bytes; } - // TODO: compute invoke stub using length from oat file. - size_t invoke_stub_size = state->ComputeOatSize( - reinterpret_cast<const void*>(method->GetInvokeStub()), &first_occurrence); - if (first_occurrence) { - state->stats_.native_to_managed_code_bytes += invoke_stub_size; - } const void* oat_code_begin = state->GetOatCodeBegin(method); const void* oat_code_end = state->GetOatCodeEnd(method); uint32_t oat_code_size = state->GetOatCodeSize(method); @@ -1078,7 +1050,7 @@ class ImageDumper { dex_instruction_bytes, gc_map_bytes, pc_mapping_table_bytes); size_t total_size = dex_instruction_bytes + gc_map_bytes + pc_mapping_table_bytes + - vmap_table_bytes + invoke_stub_size + oat_code_size + object_bytes; + vmap_table_bytes + oat_code_size + object_bytes; double expansion = static_cast<double>(oat_code_size) / static_cast<double>(dex_instruction_bytes); |