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
diff --git a/src/compiler_llvm/compilation_unit.cc b/src/compiler_llvm/compilation_unit.cc
index c5952f0..b3a9c71 100644
--- a/src/compiler_llvm/compilation_unit.cc
+++ b/src/compiler_llvm/compilation_unit.cc
@@ -62,7 +62,7 @@
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 eb92ce4..1db54fc 100644
--- a/src/compiler_llvm/compilation_unit.h
+++ b/src/compiler_llvm/compilation_unit.h
@@ -73,6 +73,11 @@
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 @@
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 2b18903..f9af139 100644
--- a/src/compiler_llvm/compiler_llvm.cc
+++ b/src/compiler_llvm/compiler_llvm.cc
@@ -213,15 +213,16 @@
}
-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" 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 b9f8d00..8bb053e 100644
--- a/src/compiler_llvm/compiler_llvm.h
+++ b/src/compiler_llvm/compiler_llvm.h
@@ -93,12 +93,10 @@
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 adea85d..8f8eff9 100644
--- a/src/compiler_llvm/elf_loader.cc
+++ b/src/compiler_llvm/elf_loader.cc
@@ -84,20 +84,18 @@
}
-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 9e8137f..ea98f61 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 @@
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 097c4f1..285caab 100644
--- a/src/compiler_llvm/jni_compiler.cc
+++ b/src/compiler_llvm/jni_compiler.cc
@@ -52,7 +52,8 @@
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 @@
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 c15dae5..d91293d 100644
--- a/src/compiler_llvm/jni_compiler.h
+++ b/src/compiler_llvm/jni_compiler.h
@@ -84,6 +84,7 @@
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 8b1cef6..57dbf15 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -67,7 +67,7 @@
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 @@
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 @@
// 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 006f763..1ff3a9f 100644
--- a/src/compiler_llvm/method_compiler.h
+++ b/src/compiler_llvm/method_compiler.h
@@ -460,6 +460,8 @@
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 20bd94b..85bfe24 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 @@
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 @@
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 @@
// 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 73d00a1..9cb49b0 100644
--- a/src/compiler_llvm/upcall_compiler.h
+++ b/src/compiler_llvm/upcall_compiler.h
@@ -48,6 +48,7 @@
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 2a9ccba..0000000
--- 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 fb4da34..fb9f0cb 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 f5a2c0e..0000000
--- 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