Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(682)

Unified Diff: runtime/vm/object.cc

Issue 1368773002: Modify String::IdentifierPrettyName to work with zone allocated temporary strings instead of String… (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | runtime/vm/object_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/object.cc
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 20ca510ad09d14c57d9624f9e4cb5827370db035..563190ec2f67ca010f1cfd0defbe94f55104f460 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -162,6 +162,34 @@ RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
const double MegamorphicCache::kLoadFactor = 0.75;
+static void AppendSubString(Zone* zone,
+ GrowableArray<const char*>* segments,
+ const char* name,
+ intptr_t start_pos, intptr_t len) {
+ char* segment = zone->Alloc<char>(len + 1); // '\0'-terminated.
+ memmove(segment, name + start_pos, len);
+ segment[len] = '\0';
+ segments->Add(segment);
+}
+
+
+static const char* MergeSubStrings(Zone* zone,
+ const GrowableArray<const char*>& segments,
+ intptr_t alloc_len) {
+ char* result = zone->Alloc<char>(alloc_len + 1); // '\0'-terminated
+ intptr_t pos = 0;
+ for (intptr_t k = 0; k < segments.length(); k++) {
+ const char* piece = segments[k];
+ const intptr_t piece_len = strlen(segments[k]);
+ memmove(result + pos, piece, piece_len);
+ pos += piece_len;
+ ASSERT(pos <= alloc_len);
+ }
+ result[pos] = '\0';
+ return result;
+}
+
+
// Takes a vm internal name and makes it suitable for external user.
//
// Examples:
@@ -173,9 +201,10 @@ const double MegamorphicCache::kLoadFactor = 0.75;
//
// Private name mangling is removed, possibly multiple times:
//
-// _ReceivePortImpl@6be832b -> _ReceivePortImpl
-// _ReceivePortImpl@6be832b._internal@6be832b -> _ReceivePortImpl._internal
-// _C@0x2b4ab9cc&_E@0x2b4ab9cc&_F@0x2b4ab9cc -> _C&_E&_F
+// _ReceivePortImpl@709387912 -> _ReceivePortImpl
+// _ReceivePortImpl@709387912._internal@709387912 ->
+// _ReceivePortImpl._internal
+// _C@6328321&_E@6328321&_F@6328321 -> _C&_E&_F
//
// The trailing . on the default constructor name is dropped:
//
@@ -183,29 +212,31 @@ const double MegamorphicCache::kLoadFactor = 0.75;
//
// And so forth:
//
-// get:foo@6be832b -> foo
-// _MyClass@6b3832b. -> _MyClass
-// _MyClass@6b3832b.named -> _MyClass.named
+// get:foo@6328321 -> foo
+// _MyClass@6328321. -> _MyClass
+// _MyClass@6328321.named -> _MyClass.named
//
RawString* String::IdentifierPrettyName(const String& name) {
+ Zone* zone = Thread::Current()->zone();
if (name.Equals(Symbols::TopLevel())) {
// Name of invisible top-level class.
return Symbols::Empty().raw();
}
+ const char* cname = name.ToCString();
+ ASSERT(strlen(cname) == static_cast<size_t>(name.Length()));
+ const intptr_t name_len = name.Length();
// First remove all private name mangling.
- String& unmangled_name = String::Handle(Symbols::Empty().raw());
- String& segment = String::Handle();
intptr_t start_pos = 0;
- for (intptr_t i = 0; i < name.Length(); i++) {
- if (name.CharAt(i) == '@' &&
- (i+1) < name.Length() &&
- (name.CharAt(i+1) >= '0') &&
- (name.CharAt(i+1) <= '9')) {
+ GrowableArray<const char*> unmangled_segments;
+ intptr_t sum_segment_len = 0;
+ for (intptr_t i = 0; i < name_len; i++) {
+ if ((cname[i] == '@') && ((i + 1) < name_len) &&
+ (cname[i + 1] >= '0') && (cname[i + 1] <= '9')) {
// Append the current segment to the unmangled name.
- segment = String::SubString(name, start_pos, (i - start_pos));
- unmangled_name = String::Concat(unmangled_name, segment);
-
+ const intptr_t segment_len = i - start_pos;
+ sum_segment_len += segment_len;
+ AppendSubString(zone, &unmangled_segments, cname, start_pos, segment_len);
// Advance until past the name mangling. The private keys are only
// numbers so we skip until the first non-number.
i++; // Skip the '@'.
@@ -218,21 +249,29 @@ RawString* String::IdentifierPrettyName(const String& name) {
i--; // Account for for-loop increment.
}
}
+
+ const char* unmangled_name = NULL;
if (start_pos == 0) {
// No name unmangling needed, reuse the name that was passed in.
- unmangled_name = name.raw();
+ unmangled_name = cname;
+ sum_segment_len = name_len;
} else if (name.Length() != start_pos) {
// Append the last segment.
- segment = String::SubString(name, start_pos, (name.Length() - start_pos));
- unmangled_name = String::Concat(unmangled_name, segment);
+ const intptr_t segment_len = name.Length() - start_pos;
+ sum_segment_len += segment_len;
+ AppendSubString(zone, &unmangled_segments, cname, start_pos, segment_len);
+ }
+ if (unmangled_name == NULL) {
+ // Merge unmangled_segments.
+ unmangled_name = MergeSubStrings(zone, unmangled_segments, sum_segment_len);
}
- intptr_t len = unmangled_name.Length();
+ intptr_t len = sum_segment_len;
intptr_t start = 0;
intptr_t dot_pos = -1; // Position of '.' in the name, if any.
bool is_setter = false;
for (intptr_t i = start; i < len; i++) {
- if (unmangled_name.CharAt(i) == ':') {
+ if (unmangled_name[i] == ':') {
if (start != 0) {
// Reset and break.
start = 0;
@@ -240,11 +279,11 @@ RawString* String::IdentifierPrettyName(const String& name) {
break;
}
ASSERT(start == 0); // Only one : is possible in getters or setters.
- if (unmangled_name.CharAt(0) == 's') {
+ if (unmangled_name[0] == 's') {
is_setter = true;
}
start = i + 1;
- } else if (unmangled_name.CharAt(i) == '.') {
+ } else if (unmangled_name[i] == '.') {
if (dot_pos != -1) {
// Reset and break.
start = 0;
@@ -258,21 +297,25 @@ RawString* String::IdentifierPrettyName(const String& name) {
if ((start == 0) && (dot_pos == -1)) {
// This unmangled_name is fine as it is.
- return unmangled_name.raw();
+ return Symbols::New(unmangled_name, sum_segment_len);
}
// Drop the trailing dot if needed.
intptr_t end = ((dot_pos + 1) == len) ? dot_pos : len;
- const String& result =
- String::Handle(String::SubString(unmangled_name, start, (end - start)));
-
+ unmangled_segments.Clear();
+ intptr_t final_len = end - start;
+ AppendSubString(zone, &unmangled_segments, unmangled_name, start, final_len);
if (is_setter) {
- // Setters need to end with '='.
- return String::Concat(result, Symbols::Equals());
+ const char* equals = Symbols::Equals().ToCString();
+ const intptr_t equals_len = strlen(equals);
+ AppendSubString(zone, &unmangled_segments, equals, 0, equals_len);
+ final_len += equals_len;
}
- return result.raw();
+ unmangled_name = MergeSubStrings(zone, unmangled_segments, final_len);
+
+ return Symbols::New(unmangled_name);
}
« no previous file with comments | « no previous file | runtime/vm/object_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698