diff options
| author | 2012-01-31 09:22:09 +0800 | |
|---|---|---|
| committer | 2012-02-15 23:39:54 -0800 | |
| commit | 7e6e33d45f96ca36803455f158d02fd1f5c21a1a (patch) | |
| tree | 8c43cc858851f428c334e127e0f5d8ba2a86303b | |
| parent | fca7e87c4831ac52073bdd0b2c7342488ce286d8 (diff) | |
Add name mangling function for LLVM.
Change-Id: I0fb352e946ef4be532fec540362468dba7a8138b
| -rw-r--r-- | build/Android.common.mk | 8 | ||||
| -rw-r--r-- | src/compiler_llvm/utils_llvm.cc | 89 | ||||
| -rw-r--r-- | src/compiler_llvm/utils_llvm.h | 38 | ||||
| -rw-r--r-- | src/compiler_llvm/utils_llvm_test.cc | 82 |
4 files changed, 216 insertions, 1 deletions
diff --git a/build/Android.common.mk b/build/Android.common.mk index ba421cbcd8..d28cc83635 100644 --- a/build/Android.common.mk +++ b/build/Android.common.mk @@ -219,7 +219,8 @@ LIBART_COMMON_SRC_FILES += \ src/compiler_llvm/frontend.cc \ src/compiler_llvm/ir_builder.cc \ src/compiler_llvm/inferred_reg_category_map.cc \ - src/compiler_llvm/method_compiler.cc + src/compiler_llvm/method_compiler.cc \ + src/compiler_llvm/utils_llvm.cc else LIBART_COMMON_SRC_FILES += \ src/compiler/Dataflow.cc \ @@ -285,6 +286,11 @@ TEST_COMMON_SRC_FILES := \ src/utils_test.cc \ src/zip_archive_test.cc +ifeq ($(ART_USE_LLVM_COMPILER),true) +TEST_COMMON_SRC_FILES += \ + src/compiler_llvm/utils_llvm_test.cc +endif + TEST_TARGET_SRC_FILES := \ $(TEST_COMMON_SRC_FILES) diff --git a/src/compiler_llvm/utils_llvm.cc b/src/compiler_llvm/utils_llvm.cc new file mode 100644 index 0000000000..1a8e8a211b --- /dev/null +++ b/src/compiler_llvm/utils_llvm.cc @@ -0,0 +1,89 @@ +/* + * 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 "class_loader.h" +#include "object.h" +#include "object_utils.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 += "_"; + 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); + signature.erase(signature.begin() + signature.find(')'), signature.end()); + + long_name += MangleForLLVM(signature); + + return long_name; +} + +} // namespace art diff --git a/src/compiler_llvm/utils_llvm.h b/src/compiler_llvm/utils_llvm.h new file mode 100644 index 0000000000..a1624d79a7 --- /dev/null +++ b/src/compiler_llvm/utils_llvm.h @@ -0,0 +1,38 @@ +/* + * 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. + */ + +#ifndef ART_SRC_UTILS_LLVM_H_ +#define ART_SRC_UTILS_LLVM_H_ + +#include "object.h" + +#include <string> + +namespace art { + +// Performs LLVM name mangling (similar to MangleForJni with additional '<' and +// '>' being mangled). +std::string MangleForLLVM(const std::string& s); + +// 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); + +} // 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 new file mode 100644 index 0000000000..f5a2c0ee01 --- /dev/null +++ b/src/compiler_llvm/utils_llvm_test.cc @@ -0,0 +1,82 @@ +/* + * 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 |