summaryrefslogtreecommitdiff
path: root/runtime/utils.cc
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2017-09-21 16:21:43 +0100
committer Vladimir Marko <vmarko@google.com> 2017-09-21 18:41:25 +0100
commitb8a55f8a62b1309efe52ec0290dfdcf60f34a550 (patch)
tree1f2a62ba7c4d4e95577414721cc274d0ee82fe7d /runtime/utils.cc
parent30744106517d64fb218ec5a96edbec797ad5a091 (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.cc63
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) {