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

Side by Side Diff: vm/object.cc

Issue 10826191: Improve the stack trace output to be more readable. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 4 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « vm/object.h ('k') | vm/object_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/bigint_operations.h" 10 #include "vm/bigint_operations.h"
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 RawClass* Object::icdata_class_ = reinterpret_cast<RawClass*>(RAW_NULL); 94 RawClass* Object::icdata_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
95 RawClass* Object::subtypetestcache_class_ = 95 RawClass* Object::subtypetestcache_class_ =
96 reinterpret_cast<RawClass*>(RAW_NULL); 96 reinterpret_cast<RawClass*>(RAW_NULL);
97 RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); 97 RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
98 RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); 98 RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
99 RawClass* Object::unhandled_exception_class_ = 99 RawClass* Object::unhandled_exception_class_ =
100 reinterpret_cast<RawClass*>(RAW_NULL); 100 reinterpret_cast<RawClass*>(RAW_NULL);
101 RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL); 101 RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
102 #undef RAW_NULL 102 #undef RAW_NULL
103 103
104
105 // Takes a vm internal name and makes it suitable for external user.
106 //
107 // Examples:
108 //
109 // Internal getter and setter prefixes are changed:
110 //
111 // get:foo -> foo
112 // set:foo -> foo=
113 //
114 // Private name mangling is removed, possibly twice:
115 //
116 // _ReceivePortImpl@6be832b -> _ReceivePortImpl
117 // _ReceivePortImpl@6be832b._internal@6be832b -> +ReceivePortImpl._internal
118 //
119 // The trailing . on the default constructor name is dropped:
120 //
121 // List. -> List
122 //
123 // And so forth:
124 //
125 // get:foo@6be832b -> foo
126 // _MyClass@6b3832b. -> _MyClass
127 // _MyClass@6b3832b.named -> _MyClass.named
128 //
129 static RawString* IdentifierPrettyName(const String& name) {
130 intptr_t len = name.Length();
131 intptr_t start = 0;
132 intptr_t at_pos = len; // Position of '@' in the name.
133 intptr_t dot_pos = len; // Position of '.' in the name.
134 bool is_setter = false;
135
136 for (int i = 0; i < name.Length(); i++) {
137 if (name.CharAt(i) == ':') {
138 ASSERT(start == 0);
139 if (name.CharAt(0) == 's') {
140 is_setter = true;
141 }
142 start = i + 1;
143 } else if (name.CharAt(i) == '@') {
144 ASSERT(at_pos == len);
145 at_pos = i;
146 } else if (name.CharAt(i) == '.') {
147 dot_pos = i;
148 break;
149 }
150 }
151 intptr_t limit = (at_pos < dot_pos ? at_pos : dot_pos);
152 if (start == 0 && limit == len) {
153 // This name is fine as it is.
154 return name.raw();
155 }
156
157 const String& result =
158 String::Handle(String::SubString(name, start, (limit - start)));
159
160 // Look for a second '@' now to correctly handle names like
161 // "_ReceivePortImpl@6be832b._internal@6be832b".
162 at_pos = len;
163 for (int i = dot_pos; i < name.Length(); i++) {
164 if (name.CharAt(i) == '@') {
165 ASSERT(at_pos == len);
166 at_pos = i;
167 }
168 }
169
170 intptr_t suffix_len = at_pos - dot_pos;
171 if (suffix_len > 1) {
172 // This is a named constructor. Add the name back to the string.
173 const String& suffix =
174 String::Handle(String::SubString(name, dot_pos, suffix_len));
175 return String::Concat(result, suffix);
176 }
177
178 if (is_setter) {
179 // Setters need to end with '='.
180 const String& suffix = String::Handle(Symbols::Equals());
181 return String::Concat(result, suffix);
182 }
183
184 return result.raw();
185 }
186
187
104 int Object::GetSingletonClassIndex(const RawClass* raw_class) { 188 int Object::GetSingletonClassIndex(const RawClass* raw_class) {
105 ASSERT(raw_class->IsHeapObject()); 189 ASSERT(raw_class->IsHeapObject());
106 if (raw_class == class_class()) { 190 if (raw_class == class_class()) {
107 return kClassClass; 191 return kClassClass;
108 } else if (raw_class == null_class()) { 192 } else if (raw_class == null_class()) {
109 return kNullClass; 193 return kNullClass;
110 } else if (raw_class == dynamic_class()) { 194 } else if (raw_class == dynamic_class()) {
111 return kDynamicClass; 195 return kDynamicClass;
112 } else if (raw_class == void_class()) { 196 } else if (raw_class == void_class()) {
113 return kVoidClass; 197 return kVoidClass;
(...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after
1124 case kUint64Array: 1208 case kUint64Array:
1125 case kExternalUint64Array: 1209 case kExternalUint64Array:
1126 return Symbols::New("Uint64List"); 1210 return Symbols::New("Uint64List");
1127 case kFloat32Array: 1211 case kFloat32Array:
1128 case kExternalFloat32Array: 1212 case kExternalFloat32Array:
1129 return Symbols::New("Float32List"); 1213 return Symbols::New("Float32List");
1130 case kFloat64Array: 1214 case kFloat64Array:
1131 case kExternalFloat64Array: 1215 case kExternalFloat64Array:
1132 return Symbols::New("Float64List"); 1216 return Symbols::New("Float64List");
1133 default: 1217 default:
1134 return Name(); 1218 const String& name = String::Handle(Name());
1219 return IdentifierPrettyName(name);
1135 } 1220 }
1136 UNREACHABLE(); 1221 UNREACHABLE();
1137 } 1222 }
1138 1223
1139 1224
1140 RawType* Class::SignatureType() const { 1225 RawType* Class::SignatureType() const {
1141 ASSERT(IsSignatureClass()); 1226 ASSERT(IsSignatureClass());
1142 const Function& function = Function::Handle(signature_function()); 1227 const Function& function = Function::Handle(signature_function());
1143 ASSERT(!function.IsNull()); 1228 ASSERT(!function.IsNull());
1144 if (function.signature_class() != raw()) { 1229 if (function.signature_class() != raw()) {
(...skipping 3220 matching lines...) Expand 10 before | Expand all | Expand 10 after
4365 } 4450 }
4366 return true; 4451 return true;
4367 } 4452 }
4368 4453
4369 4454
4370 bool Function::HasOptimizedCode() const { 4455 bool Function::HasOptimizedCode() const {
4371 return HasCode() && Code::Handle(raw_ptr()->code_).is_optimized(); 4456 return HasCode() && Code::Handle(raw_ptr()->code_).is_optimized();
4372 } 4457 }
4373 4458
4374 4459
4460 RawString* Function::UserVisibleName() const {
4461 const String& str = String::Handle(name());
4462 return IdentifierPrettyName(str);
4463 }
4464
4465
4466 RawString* Function::QualifiedUserVisibleName() const {
4467 String& tmp = String::Handle();
4468 String& suffix = String::Handle();
4469 const Class& cls = Class::Handle(owner());
4470
4471 if (IsClosureFunction()) {
4472 if (IsLocalFunction()) {
4473 const Function& parent = Function::Handle(parent_function());
4474 tmp = parent.QualifiedUserVisibleName();
4475 } else {
4476 return UserVisibleName();
4477 }
4478 } else {
4479 if (cls.IsTopLevel()) {
4480 return UserVisibleName();
4481 } else {
4482 tmp = cls.UserVisibleName();
4483 }
4484 }
4485 suffix = Symbols::Dot();
4486 tmp = String::Concat(tmp, suffix);
4487 suffix = UserVisibleName();
4488 return String::Concat(tmp, suffix);
4489 }
4490
4491
4375 const char* Function::ToCString() const { 4492 const char* Function::ToCString() const {
4376 const char* static_str = is_static() ? " static" : ""; 4493 const char* static_str = is_static() ? " static" : "";
4377 const char* abstract_str = is_abstract() ? " abstract" : ""; 4494 const char* abstract_str = is_abstract() ? " abstract" : "";
4378 const char* kind_str = NULL; 4495 const char* kind_str = NULL;
4379 const char* const_str = is_const() ? " const" : ""; 4496 const char* const_str = is_const() ? " const" : "";
4380 switch (kind()) { 4497 switch (kind()) {
4381 case RawFunction::kRegularFunction: 4498 case RawFunction::kRegularFunction:
4382 case RawFunction::kClosureFunction: 4499 case RawFunction::kClosureFunction:
4383 case RawFunction::kGetterFunction: 4500 case RawFunction::kGetterFunction:
4384 case RawFunction::kSetterFunction: 4501 case RawFunction::kSetterFunction:
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
4518 } 4635 }
4519 result.set_is_final(is_final); 4636 result.set_is_final(is_final);
4520 result.set_is_const(is_const); 4637 result.set_is_const(is_const);
4521 result.set_owner(owner); 4638 result.set_owner(owner);
4522 result.set_token_pos(token_pos); 4639 result.set_token_pos(token_pos);
4523 result.set_has_initializer(false); 4640 result.set_has_initializer(false);
4524 return result.raw(); 4641 return result.raw();
4525 } 4642 }
4526 4643
4527 4644
4645 RawString* Field::UserVisibleName() const {
4646 const String& str = String::Handle(name());
4647 return IdentifierPrettyName(str);
4648 }
4649
4650
4528 const char* Field::ToCString() const { 4651 const char* Field::ToCString() const {
4529 const char* kF0 = is_static() ? " static" : ""; 4652 const char* kF0 = is_static() ? " static" : "";
4530 const char* kF1 = is_final() ? " final" : ""; 4653 const char* kF1 = is_final() ? " final" : "";
4531 const char* kF2 = is_const() ? " const" : ""; 4654 const char* kF2 = is_const() ? " const" : "";
4532 const char* kFormat = "Field <%s.%s>:%s%s%s"; 4655 const char* kFormat = "Field <%s.%s>:%s%s%s";
4533 const char* field_name = String::Handle(name()).ToCString(); 4656 const char* field_name = String::Handle(name()).ToCString();
4534 const Class& cls = Class::Handle(owner()); 4657 const Class& cls = Class::Handle(owner());
4535 const char* cls_name = String::Handle(cls.Name()).ToCString(); 4658 const char* cls_name = String::Handle(cls.Name()).ToCString();
4536 intptr_t len = 4659 intptr_t len =
4537 OS::SNPrint(NULL, 0, kFormat, cls_name, field_name, kF0, kF1, kF2) + 1; 4660 OS::SNPrint(NULL, 0, kFormat, cls_name, field_name, kF0, kF1, kF2) + 1;
(...skipping 6349 matching lines...) Expand 10 before | Expand all | Expand 10 after
10887 obj = func_list.At(j); 11010 obj = func_list.At(j);
10888 function_array.SetAt(i, obj); 11011 function_array.SetAt(i, obj);
10889 obj = code_list.At(j); 11012 obj = code_list.At(j);
10890 code_array.SetAt(i, obj); 11013 code_array.SetAt(i, obj);
10891 obj = pc_offset_list.At(j); 11014 obj = pc_offset_list.At(j);
10892 pc_offset_array.SetAt(i, obj); 11015 pc_offset_array.SetAt(i, obj);
10893 } 11016 }
10894 } 11017 }
10895 11018
10896 11019
10897 const char* Stacktrace::ToCStringInternal(bool verbose) const { 11020 const char* Stacktrace::ToCString() const {
10898 Function& function = Function::Handle(); 11021 Function& function = Function::Handle();
10899 Code& code = Code::Handle(); 11022 Code& code = Code::Handle();
10900 Class& function_class = Class::Handle(); 11023 Class& owner = Class::Handle();
10901 Script& script = Script::Handle(); 11024 Script& script = Script::Handle();
10902 String& function_name = String::Handle(); 11025 String& function_name = String::Handle();
10903 String& class_name = String::Handle();
10904 String& url = String::Handle(); 11026 String& url = String::Handle();
10905 11027
10906 // Iterate through the stack frames and create C string description 11028 // Iterate through the stack frames and create C string description
10907 // for each frame. 11029 // for each frame.
10908 intptr_t total_len = 0; 11030 intptr_t total_len = 0;
10909 const char* kFormat = verbose ? 11031 const char* kFormat = "#%-6d %s (%s:%d:%d)\n";
10910 " %d. Function: '%s%s%s' url: '%s' line:%d col:%d code-entry: 0x%x\n" :
10911 " %d. Function: '%s%s%s' url: '%s' line:%d col:%d\n";
10912 GrowableArray<char*> frame_strings; 11032 GrowableArray<char*> frame_strings;
10913 for (intptr_t i = 0; i < Length(); i++) { 11033 for (intptr_t i = 0; i < Length(); i++) {
10914 function = FunctionAtFrame(i); 11034 function = FunctionAtFrame(i);
10915 code = CodeAtFrame(i); 11035 code = CodeAtFrame(i);
10916 uword pc = code.EntryPoint() + Smi::Value(PcOffsetAtFrame(i)); 11036 uword pc = code.EntryPoint() + Smi::Value(PcOffsetAtFrame(i));
10917 intptr_t token_pos = code.GetTokenIndexOfPC(pc); 11037 intptr_t token_pos = code.GetTokenIndexOfPC(pc);
10918 function_class = function.owner(); 11038 owner = function.owner();
10919 script = function_class.script(); 11039 script = owner.script();
10920 function_name = function.name(); 11040 function_name = function.QualifiedUserVisibleName();
10921 class_name = function_class.Name();
10922 url = script.url(); 11041 url = script.url();
10923 intptr_t line = -1; 11042 intptr_t line = -1;
10924 intptr_t column = -1; 11043 intptr_t column = -1;
10925 if (token_pos >= 0) { 11044 if (token_pos >= 0) {
10926 script.GetTokenLocation(token_pos, &line, &column); 11045 script.GetTokenLocation(token_pos, &line, &column);
10927 } 11046 }
10928 intptr_t len = OS::SNPrint(NULL, 0, kFormat, 11047 intptr_t len = OS::SNPrint(NULL, 0, kFormat,
10929 i, 11048 i,
10930 class_name.ToCString(),
10931 function_class.IsTopLevel() ? "" : ".",
10932 function_name.ToCString(), 11049 function_name.ToCString(),
10933 url.ToCString(), 11050 url.ToCString(),
10934 line, column, 11051 line, column);
10935 code.EntryPoint());
10936 total_len += len; 11052 total_len += len;
10937 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); 11053 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
10938 OS::SNPrint(chars, (len + 1), kFormat, 11054 OS::SNPrint(chars, (len + 1), kFormat,
10939 i, 11055 i,
10940 class_name.ToCString(),
10941 function_class.IsTopLevel() ? "" : ".",
10942 function_name.ToCString(), 11056 function_name.ToCString(),
10943 url.ToCString(), 11057 url.ToCString(),
10944 line, column, 11058 line, column);
10945 code.EntryPoint());
10946 frame_strings.Add(chars); 11059 frame_strings.Add(chars);
10947 } 11060 }
10948 11061
10949 // Now concatentate the frame descriptions into a single C string. 11062 // Now concatentate the frame descriptions into a single C string.
10950 char* chars = Isolate::Current()->current_zone()->Alloc<char>(total_len + 1); 11063 char* chars = Isolate::Current()->current_zone()->Alloc<char>(total_len + 1);
10951 intptr_t index = 0; 11064 intptr_t index = 0;
10952 for (intptr_t i = 0; i < frame_strings.length(); i++) { 11065 for (intptr_t i = 0; i < frame_strings.length(); i++) {
10953 index += OS::SNPrint((chars + index), 11066 index += OS::SNPrint((chars + index),
10954 (total_len + 1 - index), 11067 (total_len + 1 - index),
10955 "%s", 11068 "%s",
10956 frame_strings[i]); 11069 frame_strings[i]);
10957 } 11070 }
10958 return chars; 11071 return chars;
10959 } 11072 }
10960 11073
10961 11074
10962 const char* Stacktrace::ToCString() const {
10963 return ToCStringInternal(false);
10964 }
10965
10966
10967 void JSRegExp::set_pattern(const String& pattern) const { 11075 void JSRegExp::set_pattern(const String& pattern) const {
10968 StorePointer(&raw_ptr()->pattern_, pattern.raw()); 11076 StorePointer(&raw_ptr()->pattern_, pattern.raw());
10969 } 11077 }
10970 11078
10971 11079
10972 void JSRegExp::set_num_bracket_expressions(intptr_t value) const { 11080 void JSRegExp::set_num_bracket_expressions(intptr_t value) const {
10973 raw_ptr()->num_bracket_expressions_ = Smi::New(value); 11081 raw_ptr()->num_bracket_expressions_ = Smi::New(value);
10974 } 11082 }
10975 11083
10976 11084
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
11055 const char* JSRegExp::ToCString() const { 11163 const char* JSRegExp::ToCString() const {
11056 const String& str = String::Handle(pattern()); 11164 const String& str = String::Handle(pattern());
11057 const char* format = "JSRegExp: pattern=%s flags=%s"; 11165 const char* format = "JSRegExp: pattern=%s flags=%s";
11058 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); 11166 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags());
11059 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); 11167 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
11060 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); 11168 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags());
11061 return chars; 11169 return chars;
11062 } 11170 }
11063 11171
11064 } // namespace dart 11172 } // namespace dart
OLDNEW
« no previous file with comments | « vm/object.h ('k') | vm/object_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698