diff options
| author | 2012-04-02 02:37:37 +0800 | |
|---|---|---|
| committer | 2012-04-06 17:04:56 -0700 | |
| commit | 937105a220983351695bf4c8924171ba5d17a68c (patch) | |
| tree | 4e259853c80e0d28e12ecf54c6e0ffa178797497 /src/compiler_llvm | |
| parent | 0c717dd1c56bd29cf860d0feda8e629dab2cadb3 (diff) | |
Use ELF function index to distinguish generated functions.
We replaced LLVMLongName and LLVMStubName with ElfFuncName,
and we are using the simple name: Art0, Art1, ..., ArtN,
as the function name of every generated functions. This
gives us 3 benefits:
1. We can avoid the ambiguous function name returned by
LLVMLongName() in some special situation.
2. We don't need to have the art::Method object during
the executable linking procedure. Besides, this will
make bootstrapping easier.
3. Reduce the size of the ELF executable, since we don't
have to save a long function name, which usually contains
more than 30 characters.
Change-Id: Ib698062b272458e847ad5545d7acf33a4dc9eb85
Diffstat (limited to 'src/compiler_llvm')
| -rw-r--r-- | src/compiler_llvm/compilation_unit.cc | 2 | ||||
| -rw-r--r-- | src/compiler_llvm/compilation_unit.h | 6 | ||||
| -rw-r--r-- | src/compiler_llvm/compiler_llvm.cc | 19 | ||||
| -rw-r--r-- | src/compiler_llvm/compiler_llvm.h | 6 | ||||
| -rw-r--r-- | src/compiler_llvm/elf_loader.cc | 12 | ||||
| -rw-r--r-- | src/compiler_llvm/elf_loader.h | 11 | ||||
| -rw-r--r-- | src/compiler_llvm/jni_compiler.cc | 8 | ||||
| -rw-r--r-- | src/compiler_llvm/jni_compiler.h | 1 | ||||
| -rw-r--r-- | src/compiler_llvm/method_compiler.cc | 7 | ||||
| -rw-r--r-- | src/compiler_llvm/method_compiler.h | 2 | ||||
| -rw-r--r-- | src/compiler_llvm/upcall_compiler.cc | 14 | ||||
| -rw-r--r-- | src/compiler_llvm/upcall_compiler.h | 1 | ||||
| -rw-r--r-- | src/compiler_llvm/utils_llvm.cc | 113 | ||||
| -rw-r--r-- | src/compiler_llvm/utils_llvm.h | 19 | ||||
| -rw-r--r-- | src/compiler_llvm/utils_llvm_test.cc | 82 |
15 files changed, 51 insertions, 252 deletions
diff --git a/src/compiler_llvm/compilation_unit.cc b/src/compiler_llvm/compilation_unit.cc index c5952f0195..b3a9c714cf 100644 --- a/src/compiler_llvm/compilation_unit.cc +++ b/src/compiler_llvm/compilation_unit.cc @@ -62,7 +62,7 @@ llvm::Module* makeLLVMModuleContents(llvm::Module* module); CompilationUnit::CompilationUnit(InstructionSet insn_set, size_t elf_idx) : insn_set_(insn_set), elf_idx_(elf_idx), context_(new llvm::LLVMContext()), - mem_usage_(0) { + mem_usage_(0), num_elf_funcs_(0) { // Create the module and include the runtime function declaration module_ = new llvm::Module("art", *context_); diff --git a/src/compiler_llvm/compilation_unit.h b/src/compiler_llvm/compilation_unit.h index eb92ce445a..1db54fc413 100644 --- a/src/compiler_llvm/compilation_unit.h +++ b/src/compiler_llvm/compilation_unit.h @@ -73,6 +73,11 @@ class CompilationUnit { return ElfImage(elf_image_); } + uint16_t AcquireUniqueElfFuncIndex() { + CHECK(num_elf_funcs_ < UINT16_MAX); + return num_elf_funcs_++; + } + bool WriteBitcodeToFile(); bool Materialize(); @@ -101,6 +106,7 @@ class CompilationUnit { std::string bitcode_filename_; size_t mem_usage_; + uint16_t num_elf_funcs_; }; } // namespace compiler_llvm diff --git a/src/compiler_llvm/compiler_llvm.cc b/src/compiler_llvm/compiler_llvm.cc index 2b1890342a..f9af139d52 100644 --- a/src/compiler_llvm/compiler_llvm.cc +++ b/src/compiler_llvm/compiler_llvm.cc @@ -213,15 +213,16 @@ void CompilerLLVM::LoadElfFromCompilationUnit(const CompilationUnit* cunit) { } -const void* CompilerLLVM::GetMethodCodeAddr(const CompiledMethod* cm, - const Method* method) const { - return elf_loader_->GetMethodCodeAddr(cm->GetElfIndex(), method); +const void* CompilerLLVM::GetMethodCodeAddr(const CompiledMethod* cm) const { + return elf_loader_->GetMethodCodeAddr(cm->GetElfIndex(), + cm->GetElfFuncIndex()); } const Method::InvokeStub* CompilerLLVM:: -GetMethodInvokeStubAddr(const CompiledInvokeStub* cm, const Method* method) const { - return elf_loader_->GetMethodInvokeStubAddr(cm->GetElfIndex(), method); +GetMethodInvokeStubAddr(const CompiledInvokeStub* cm) const { + return elf_loader_->GetMethodInvokeStubAddr(cm->GetElfIndex(), + cm->GetElfFuncIndex()); } @@ -353,18 +354,18 @@ extern "C" void compilerLLVMEnableAutoElfLoading(art::Compiler& compiler) { extern "C" const void* compilerLLVMGetMethodCodeAddr(const art::Compiler& compiler, const art::CompiledMethod* cm, - const art::Method* method) { + const art::Method*) { const art::compiler_llvm::CompilerLLVM* compiler_llvm = reinterpret_cast<const art::compiler_llvm::CompilerLLVM*>(compiler.GetCompilerContext()); - return compiler_llvm->GetMethodCodeAddr(cm, method); + return compiler_llvm->GetMethodCodeAddr(cm); } extern "C" const art::Method::InvokeStub* compilerLLVMGetMethodInvokeStubAddr(const art::Compiler& compiler, const art::CompiledInvokeStub* cm, - const art::Method* method) { + const art::Method*) { const art::compiler_llvm::CompilerLLVM* compiler_llvm = reinterpret_cast<const art::compiler_llvm::CompilerLLVM*>(compiler.GetCompilerContext()); - return compiler_llvm->GetMethodInvokeStubAddr(cm, method); + return compiler_llvm->GetMethodInvokeStubAddr(cm); } extern "C" std::vector<art::ElfImage> compilerLLVMGetElfImages(const art::Compiler& compiler) { diff --git a/src/compiler_llvm/compiler_llvm.h b/src/compiler_llvm/compiler_llvm.h index b9f8d0057b..8bb053ed8a 100644 --- a/src/compiler_llvm/compiler_llvm.h +++ b/src/compiler_llvm/compiler_llvm.h @@ -93,12 +93,10 @@ class CompilerLLVM { return (elf_loader_.get() != NULL); } - const void* GetMethodCodeAddr(const CompiledMethod* cm, - const Method* method) const; + const void* GetMethodCodeAddr(const CompiledMethod* cm) const; const Method::InvokeStub* GetMethodInvokeStubAddr( - const CompiledInvokeStub* cm, - const Method* method) const; + const CompiledInvokeStub* cm) const; std::vector<ElfImage> GetElfImages() const; diff --git a/src/compiler_llvm/elf_loader.cc b/src/compiler_llvm/elf_loader.cc index adea85d73f..8f8eff9014 100644 --- a/src/compiler_llvm/elf_loader.cc +++ b/src/compiler_llvm/elf_loader.cc @@ -84,20 +84,18 @@ void ElfLoader::RelocateExecutable() { } -const void* ElfLoader::GetMethodCodeAddr(size_t elf_idx, - const Method* method) const { +const void* ElfLoader::GetMethodCodeAddr(uint16_t elf_idx, + uint16_t elf_func_idx) const { CHECK_LT(elf_idx, executables_.size()); - CHECK(method != NULL); - return GetAddr(elf_idx, LLVMLongName(method).c_str()); + return GetAddr(elf_idx, ElfFuncName(elf_func_idx).c_str()); } const Method::InvokeStub* ElfLoader:: -GetMethodInvokeStubAddr(size_t elf_idx, const Method* method) const { +GetMethodInvokeStubAddr(uint16_t elf_idx, uint16_t elf_func_idx) const { CHECK_LT(elf_idx, executables_.size()); - CHECK(method != NULL); return reinterpret_cast<const Method::InvokeStub*>( - GetAddr(elf_idx, LLVMStubName(method).c_str())); + GetAddr(elf_idx, ElfFuncName(elf_func_idx).c_str())); } diff --git a/src/compiler_llvm/elf_loader.h b/src/compiler_llvm/elf_loader.h index 9e8137f7e6..ea98f61c17 100644 --- a/src/compiler_llvm/elf_loader.h +++ b/src/compiler_llvm/elf_loader.h @@ -26,10 +26,6 @@ #include <vector> namespace art { - class Method; -} - -namespace art { namespace compiler_llvm { class ElfLoader { @@ -41,10 +37,11 @@ class ElfLoader { void RelocateExecutable(); - const void* GetMethodCodeAddr(size_t elf_idx, const Method* method) const; + const void* GetMethodCodeAddr(uint16_t elf_idx, + uint16_t elf_func_idx) const; - const Method::InvokeStub* GetMethodInvokeStubAddr(size_t elf_idx, - const Method* method) const; + const Method::InvokeStub* GetMethodInvokeStubAddr(uint16_t elf_idx, + uint16_t elf_func_idx) const; private: const void* GetAddr(size_t elf_idx, const char* sym_name) const; diff --git a/src/compiler_llvm/jni_compiler.cc b/src/compiler_llvm/jni_compiler.cc index 097c4f11d0..285caaba26 100644 --- a/src/compiler_llvm/jni_compiler.cc +++ b/src/compiler_llvm/jni_compiler.cc @@ -52,7 +52,8 @@ JniCompiler::JniCompiler(CompilationUnit* cunit, class_loader_(oat_compilation_unit->class_loader_), dex_cache_(oat_compilation_unit->dex_cache_), dex_file_(oat_compilation_unit->dex_file_), - method_(dex_cache_->GetResolvedMethod(method_idx_)) { + method_(dex_cache_->GetResolvedMethod(method_idx_)), + elf_func_idx_(cunit_->AcquireUniqueElfFuncIndex()) { // Check: Ensure that the method is resolved CHECK_NE(method_, static_cast<art::Method*>(NULL)); @@ -289,13 +290,14 @@ CompiledMethod* JniCompiler::Compile() { llvm::verifyFunction(*func_, llvm::PrintMessageAction); return new CompiledMethod(cunit_->GetInstructionSet(), - cunit_->GetElfIndex()); + cunit_->GetElfIndex(), + elf_func_idx_); } void JniCompiler::CreateFunction() { // LLVM function name - std::string func_name(LLVMLongName(method_)); + std::string func_name(ElfFuncName(elf_func_idx_)); // Get function type llvm::FunctionType* func_type = diff --git a/src/compiler_llvm/jni_compiler.h b/src/compiler_llvm/jni_compiler.h index c15dae5ca4..d91293de7a 100644 --- a/src/compiler_llvm/jni_compiler.h +++ b/src/compiler_llvm/jni_compiler.h @@ -84,6 +84,7 @@ class JniCompiler { Method* method_; llvm::Function* func_; + uint16_t elf_func_idx_; }; diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc index 8b1cef6a50..57dbf153a8 100644 --- a/src/compiler_llvm/method_compiler.cc +++ b/src/compiler_llvm/method_compiler.cc @@ -67,7 +67,7 @@ MethodCompiler::MethodCompiler(CompilationUnit* cunit, basic_blocks_(code_item_->insns_size_in_code_units_), basic_block_landing_pads_(code_item_->tries_size_, NULL), basic_block_unwind_(NULL), basic_block_unreachable_(NULL), - shadow_frame_(NULL) { + shadow_frame_(NULL), elf_func_idx_(cunit_->AcquireUniqueElfFuncIndex()) { } @@ -78,7 +78,7 @@ MethodCompiler::~MethodCompiler() { void MethodCompiler::CreateFunction() { // LLVM function name - std::string func_name(LLVMLongName(method_)); + std::string func_name(ElfFuncName(elf_func_idx_)); // Get function type llvm::FunctionType* func_type = @@ -3773,7 +3773,8 @@ CompiledMethod *MethodCompiler::Compile() { // Thus, we got our magic number 9. return new CompiledMethod(cunit_->GetInstructionSet(), - cunit_->GetElfIndex()); + cunit_->GetElfIndex(), + elf_func_idx_); } diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h index 006f7634ef..1ff3a9f9df 100644 --- a/src/compiler_llvm/method_compiler.h +++ b/src/compiler_llvm/method_compiler.h @@ -460,6 +460,8 @@ class MethodCompiler { llvm::BasicBlock* basic_block_unreachable_; llvm::AllocaInst* shadow_frame_; + + uint16_t elf_func_idx_; }; diff --git a/src/compiler_llvm/upcall_compiler.cc b/src/compiler_llvm/upcall_compiler.cc index 20bd94b71d..85bfe241dd 100644 --- a/src/compiler_llvm/upcall_compiler.cc +++ b/src/compiler_llvm/upcall_compiler.cc @@ -24,6 +24,7 @@ #include "logging.h" #include "object.h" #include "runtime_support_func.h" +#include "utils_llvm.h" #include <llvm/Analysis/Verifier.h> #include <llvm/BasicBlock.h> @@ -42,7 +43,8 @@ using namespace runtime_support; UpcallCompiler::UpcallCompiler(CompilationUnit* cunit, Compiler& compiler) : cunit_(cunit), compiler_(&compiler), module_(cunit_->GetModule()), - context_(cunit_->GetLLVMContext()), irb_(*cunit_->GetIRBuilder()) { + context_(cunit_->GetLLVMContext()), irb_(*cunit_->GetIRBuilder()), + elf_func_idx_(cunit_->AcquireUniqueElfFuncIndex()) { } @@ -53,13 +55,7 @@ CompiledInvokeStub* UpcallCompiler::CreateStub(bool is_static, size_t shorty_size = strlen(shorty); // Function name - std::string func_name; - - if (is_static) { - StringAppendF(&func_name, "ArtSUpcall_%s", shorty); - } else { - StringAppendF(&func_name, "ArtUpcall_%s", shorty); - } + std::string func_name(ElfFuncName(elf_func_idx_)); // Get argument types llvm::Type* arg_types[] = { @@ -179,7 +175,7 @@ CompiledInvokeStub* UpcallCompiler::CreateStub(bool is_static, // store ret_addr, and ret_void. Beside, we guess that we have to use // 50 bytes to represent one LLVM instruction. - return new CompiledInvokeStub(cunit_->GetElfIndex()); + return new CompiledInvokeStub(cunit_->GetElfIndex(), elf_func_idx_); } diff --git a/src/compiler_llvm/upcall_compiler.h b/src/compiler_llvm/upcall_compiler.h index 73d00a16a7..9cb49b0bd6 100644 --- a/src/compiler_llvm/upcall_compiler.h +++ b/src/compiler_llvm/upcall_compiler.h @@ -48,6 +48,7 @@ class UpcallCompiler { llvm::Module* module_; llvm::LLVMContext* context_; IRBuilder& irb_; + uint16_t elf_func_idx_; }; diff --git a/src/compiler_llvm/utils_llvm.cc b/src/compiler_llvm/utils_llvm.cc deleted file mode 100644 index 2a9ccba875..0000000000 --- a/src/compiler_llvm/utils_llvm.cc +++ /dev/null @@ -1,113 +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. - */ - -#include "utils_llvm.h" - -#include <fcntl.h> -#include <string.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> - -#include "android/librsloader.h" -#include "class_loader.h" -#include "object.h" -#include "object_utils.h" -#include "runtime_support_llvm.h" - -namespace art { - -std::string MangleForLLVM(const std::string& s) { - std::string result; - size_t char_count = CountModifiedUtf8Chars(s.c_str()); - const char* cp = &s[0]; - for (size_t i = 0; i < char_count; ++i) { - uint16_t ch = GetUtf16FromUtf8(&cp); - if (ch == '$' || ch == '<' || ch == '>' || ch > 127) { - StringAppendF(&result, "_0%04x", ch); - } else { - switch (ch) { - case '_': - result += "_1"; - break; - case ';': - result += "_2"; - break; - case '[': - result += "_3"; - break; - case ')': - result += "_4"; - break; - case '/': - result += "_"; - break; - default: - result.push_back(ch); - break; - } - } - } - return result; -} - -std::string LLVMShortName(const Method* m) { - MethodHelper mh(m); - std::string class_name(mh.GetDeclaringClassDescriptor()); - // Remove the leading 'L' and trailing ';'... - CHECK_EQ(class_name[0], 'L') << class_name; - CHECK_EQ(class_name[class_name.size() - 1], ';') << class_name; - class_name.erase(0, 1); - class_name.erase(class_name.size() - 1, 1); - - std::string method_name(mh.GetName()); - - std::string short_name; - short_name += "Art_"; - short_name += MangleForLLVM(class_name); - short_name += "_"; - short_name += MangleForLLVM(method_name); - return short_name; -} - -std::string LLVMLongName(const Method* m) { - std::string long_name; - long_name += LLVMShortName(m); - long_name += "__"; - - std::string signature(MethodHelper(m).GetSignature()); - signature.erase(0, 1); - - long_name += MangleForLLVM(signature); - - return long_name; -} - -std::string LLVMStubName(const Method* m) { - MethodHelper mh(m); - std::string stub_name; - if (m->IsStatic()) { - stub_name += "ArtSUpcall_"; - } else { - stub_name += "ArtUpcall_"; - } - stub_name += mh.GetShorty(); - - return stub_name; -} - -} // namespace art diff --git a/src/compiler_llvm/utils_llvm.h b/src/compiler_llvm/utils_llvm.h index fb4da34ff6..fb9f0cb3f2 100644 --- a/src/compiler_llvm/utils_llvm.h +++ b/src/compiler_llvm/utils_llvm.h @@ -17,26 +17,17 @@ #ifndef ART_SRC_UTILS_LLVM_H_ #define ART_SRC_UTILS_LLVM_H_ -#include "object.h" +#include "stringprintf.h" +#include <stdint.h> #include <string> namespace art { -// Performs LLVM name mangling (similar to MangleForJni with additional '<' and -// '>' being mangled). -std::string MangleForLLVM(const std::string& s); +inline static std::string ElfFuncName(uint16_t elf_func_idx) { + return StringPrintf("Art%u", static_cast<unsigned int>(elf_func_idx)); +} -// Returns the LLVM function name for the non-overloaded method 'm'. -std::string LLVMShortName(const Method* m); - -// Returns the LLVM function name for the overloaded method 'm'. -std::string LLVMLongName(const Method* m); - -// Returns the LLVM stub function name for the overloaded method 'm'. -std::string LLVMStubName(const Method* m); - -void LLVMLinkLoadMethod(const std::string& file_name, Method* method); } // namespace art #endif // ART_SRC_UTILS_LLVM_H_ diff --git a/src/compiler_llvm/utils_llvm_test.cc b/src/compiler_llvm/utils_llvm_test.cc deleted file mode 100644 index f5a2c0ee01..0000000000 --- a/src/compiler_llvm/utils_llvm_test.cc +++ /dev/null @@ -1,82 +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. - */ - -#include "object.h" -#include "common_test.h" -#include "utils_llvm.h" - -namespace art { - -class UtilsLLVMTest : public CommonTest { -}; - -TEST_F(UtilsLLVMTest, MangleForLLVM) { - // Unit test inheritted from MangleForJni - EXPECT_EQ("hello_00024world", MangleForLLVM("hello$world")); - EXPECT_EQ("hello_000a9world", MangleForLLVM("hello\xc2\xa9world")); - EXPECT_EQ("hello_1world", MangleForLLVM("hello_world")); - EXPECT_EQ("Ljava_lang_String_2", MangleForLLVM("Ljava/lang/String;")); - EXPECT_EQ("_3C", MangleForLLVM("[C")); - - // MangleForLLVM()-specific unit test - EXPECT_EQ("_0003cinit_0003e", MangleForLLVM("<init>")); - EXPECT_EQ("_0003cclinit_0003e", MangleForLLVM("<clinit>")); -} - -TEST_F(UtilsLLVMTest, LLVMShortName_LLVMLongName) { - Class* c = class_linker_->FindSystemClass("Ljava/lang/String;"); - ASSERT_TRUE(c != NULL); - Method* m; - - // Unit test inheritted from MangleForJni - m = c->FindVirtualMethod("charAt", "(I)C"); - ASSERT_TRUE(m != NULL); - EXPECT_EQ("Art_java_lang_String_charAt", LLVMShortName(m)); - EXPECT_EQ("Art_java_lang_String_charAt__I", LLVMLongName(m)); - - m = c->FindVirtualMethod("indexOf", "(Ljava/lang/String;I)I"); - ASSERT_TRUE(m != NULL); - EXPECT_EQ("Art_java_lang_String_indexOf", LLVMShortName(m)); - EXPECT_EQ("Art_java_lang_String_indexOf__Ljava_lang_String_2I", LLVMLongName(m)); - - m = c->FindDirectMethod("copyValueOf", "([CII)Ljava/lang/String;"); - ASSERT_TRUE(m != NULL); - EXPECT_EQ("Art_java_lang_String_copyValueOf", LLVMShortName(m)); - EXPECT_EQ("Art_java_lang_String_copyValueOf___3CII", LLVMLongName(m)); - - // MangleForLLVM()-specific unit test - m = c->FindDirectMethod("<init>", "()V"); - ASSERT_TRUE(m != NULL); - EXPECT_EQ("Art_java_lang_String__0003cinit_0003e", LLVMShortName(m)); - EXPECT_EQ("Art_java_lang_String__0003cinit_0003e__", LLVMLongName(m)); - - m = c->FindDirectMethod("<init>", "([C)V"); - ASSERT_TRUE(m != NULL); - EXPECT_EQ("Art_java_lang_String__0003cinit_0003e", LLVMShortName(m)); - EXPECT_EQ("Art_java_lang_String__0003cinit_0003e___3C", LLVMLongName(m)); - - m = c->FindDirectMethod("<init>", "([CII)V"); - ASSERT_TRUE(m != NULL); - EXPECT_EQ("Art_java_lang_String__0003cinit_0003e", LLVMShortName(m)); - EXPECT_EQ("Art_java_lang_String__0003cinit_0003e___3CII", LLVMLongName(m)); - - m = c->FindDirectMethod("<init>", "(Ljava/lang/String;)V"); - ASSERT_TRUE(m != NULL); - EXPECT_EQ("Art_java_lang_String__0003cinit_0003e", LLVMShortName(m)); - EXPECT_EQ("Art_java_lang_String__0003cinit_0003e__Ljava_lang_String_2", LLVMLongName(m)); -} - -} // namespace art |