diff options
author | 2017-09-21 16:21:43 +0100 | |
---|---|---|
committer | 2017-09-21 18:41:25 +0100 | |
commit | b8a55f8a62b1309efe52ec0290dfdcf60f34a550 (patch) | |
tree | 1f2a62ba7c4d4e95577414721cc274d0ee82fe7d /runtime/utils.cc | |
parent | 30744106517d64fb218ec5a96edbec797ad5a091 (diff) |
ART: Faster PrettyMethod().
Rewrite DexFile::PrettyMethod() to avoid copying strings.
This improves the performance, especially when requesting
the signature.
Avoid code duplication in ArtMethod::PrettyMethod() and
delegate to DexFile::PrettyMethod().
10 million invocations of ArtMethod/DexFile::PrettyMethod()
for "void Main.main(java.lang.String[] args)" with (+) or
without (-) signature, time in ms:
host/32-bit host/64-bit angler/32-bit angler/64-bit
AM+: 10407-> 5020 6374-> 3302 32413->13140 17558->10003
DF+: 7280-> 4259 3881-> 2828 19287-> 9331 10343-> 7375
AM-: 2682-> 1599 2025-> 1186 7206-> 4271 7447-> 4166
DF-: 861-> 871 653-> 640 1574-> 1430 1828-> 1712
Test: m test-art-host-gtest
Test: testrunner.py --host
Change-Id: Ifb79abe1a7f4fc6adc10a34f5d49dc6681d06699
Diffstat (limited to 'runtime/utils.cc')
-rw-r--r-- | runtime/utils.cc | 63 |
1 files changed, 15 insertions, 48 deletions
diff --git a/runtime/utils.cc b/runtime/utils.cc index 3fe18c7933..fc1c91ab22 100644 --- a/runtime/utils.cc +++ b/runtime/utils.cc @@ -148,7 +148,7 @@ bool PrintFileToLog(const std::string& file_name, LogSeverity level) { } } -std::string PrettyDescriptor(const char* descriptor) { +void AppendPrettyDescriptor(const char* descriptor, std::string* result) { // Count the number of '['s to get the dimensionality. const char* c = descriptor; size_t dim = 0; @@ -166,74 +166,41 @@ std::string PrettyDescriptor(const char* descriptor) { // To make life easier, we make primitives look like unqualified // reference types. switch (*c) { - case 'B': c = "byte;"; break; - case 'C': c = "char;"; break; - case 'D': c = "double;"; break; - case 'F': c = "float;"; break; - case 'I': c = "int;"; break; - case 'J': c = "long;"; break; - case 'S': c = "short;"; break; - case 'Z': c = "boolean;"; break; - case 'V': c = "void;"; break; // Used when decoding return types. - default: return descriptor; + case 'B': c = "byte;"; break; + case 'C': c = "char;"; break; + case 'D': c = "double;"; break; + case 'F': c = "float;"; break; + case 'I': c = "int;"; break; + case 'J': c = "long;"; break; + case 'S': c = "short;"; break; + case 'Z': c = "boolean;"; break; + case 'V': c = "void;"; break; // Used when decoding return types. + default: result->append(descriptor); return; } } // At this point, 'c' is a string of the form "fully/qualified/Type;" // or "primitive;". Rewrite the type with '.' instead of '/': - std::string result; const char* p = c; while (*p != ';') { char ch = *p++; if (ch == '/') { ch = '.'; } - result.push_back(ch); + result->push_back(ch); } // ...and replace the semicolon with 'dim' "[]" pairs: for (size_t i = 0; i < dim; ++i) { - result += "[]"; + result->append("[]"); } - return result; } -std::string PrettyArguments(const char* signature) { +std::string PrettyDescriptor(const char* descriptor) { std::string result; - result += '('; - CHECK_EQ(*signature, '('); - ++signature; // Skip the '('. - while (*signature != ')') { - size_t argument_length = 0; - while (signature[argument_length] == '[') { - ++argument_length; - } - if (signature[argument_length] == 'L') { - argument_length = (strchr(signature, ';') - signature + 1); - } else { - ++argument_length; - } - { - std::string argument_descriptor(signature, argument_length); - result += PrettyDescriptor(argument_descriptor.c_str()); - } - if (signature[argument_length] != ')') { - result += ", "; - } - signature += argument_length; - } - CHECK_EQ(*signature, ')'); - ++signature; // Skip the ')'. - result += ')'; + AppendPrettyDescriptor(descriptor, &result); return result; } -std::string PrettyReturnType(const char* signature) { - const char* return_type = strchr(signature, ')'); - CHECK(return_type != nullptr); - ++return_type; // Skip ')'. - return PrettyDescriptor(return_type); -} - std::string PrettyJavaAccessFlags(uint32_t access_flags) { std::string result; if ((access_flags & kAccPublic) != 0) { |