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

Side by Side Diff: runtime/vm/object.cc

Issue 219333011: Change how we provide value previews in the vm service. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix tests / gen js Created 6 years, 8 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 | « runtime/vm/object.h ('k') | runtime/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/cpu.h" 10 #include "vm/cpu.h"
(...skipping 12693 matching lines...) Expand 10 before | Expand all | Expand 10 after
12704 const String& type_name = String::Handle(type.UserVisibleName()); 12704 const String& type_name = String::Handle(type.UserVisibleName());
12705 // Calculate the size of the string. 12705 // Calculate the size of the string.
12706 intptr_t len = OS::SNPrint(NULL, 0, kFormat, type_name.ToCString()) + 1; 12706 intptr_t len = OS::SNPrint(NULL, 0, kFormat, type_name.ToCString()) + 1;
12707 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 12707 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
12708 OS::SNPrint(chars, len, kFormat, type_name.ToCString()); 12708 OS::SNPrint(chars, len, kFormat, type_name.ToCString());
12709 return chars; 12709 return chars;
12710 } 12710 }
12711 } 12711 }
12712 12712
12713 12713
12714 const char* Instance::ToUserCString(intptr_t max_len, intptr_t nesting) const {
12715 if (IsNull()) {
12716 return "null";
12717 } else if (raw() == Object::sentinel().raw()) {
12718 return "<not initialized>";
12719 } else if (raw() == Object::transition_sentinel().raw()) {
12720 return "<being initialized>";
12721 } else {
12722 return ToCString();
12723 }
12724 }
12725
12726
12727 void Instance::PrintSharedInstanceJSON(JSONObject* jsobj, bool ref) const { 12714 void Instance::PrintSharedInstanceJSON(JSONObject* jsobj, bool ref) const {
12728 jsobj->AddProperty("type", JSONType(ref)); 12715 jsobj->AddProperty("type", JSONType(ref));
12729 Class& cls = Class::Handle(this->clazz()); 12716 Class& cls = Class::Handle(this->clazz());
12730 jsobj->AddProperty("class", cls); 12717 jsobj->AddProperty("class", cls);
12718 // TODO(turnidge): Provide the type arguments here too.
12731 if (ref) { 12719 if (ref) {
12732 return; 12720 return;
12733 } 12721 }
12734 12722
12735 jsobj->AddProperty("size", raw()->Size()); 12723 if (raw()->IsHeapObject()) {
12724 jsobj->AddProperty("size", raw()->Size());
12725 }
12736 12726
12737 // Walk the superclass chain, adding all instance fields. 12727 // Walk the superclass chain, adding all instance fields.
12738 { 12728 {
12739 Instance& fieldValue = Instance::Handle(); 12729 Instance& fieldValue = Instance::Handle();
12740 JSONArray jsarr(jsobj, "fields"); 12730 JSONArray jsarr(jsobj, "fields");
12741 while (!cls.IsNull()) { 12731 while (!cls.IsNull()) {
12742 const Array& field_array = Array::Handle(cls.fields()); 12732 const Array& field_array = Array::Handle(cls.fields());
12743 Field& field = Field::Handle(); 12733 Field& field = Field::Handle();
12744 if (!field_array.IsNull()) { 12734 if (!field_array.IsNull()) {
12745 for (intptr_t i = 0; i < field_array.Length(); i++) { 12735 for (intptr_t i = 0; i < field_array.Length(); i++) {
(...skipping 22 matching lines...) Expand all
12768 } 12758 }
12769 12759
12770 12760
12771 void Instance::PrintToJSONStream(JSONStream* stream, bool ref) const { 12761 void Instance::PrintToJSONStream(JSONStream* stream, bool ref) const {
12772 JSONObject jsobj(stream); 12762 JSONObject jsobj(stream);
12773 12763
12774 // Handle certain special instance values. 12764 // Handle certain special instance values.
12775 if (IsNull()) { 12765 if (IsNull()) {
12776 jsobj.AddProperty("type", ref ? "@Null" : "Null"); 12766 jsobj.AddProperty("type", ref ? "@Null" : "Null");
12777 jsobj.AddProperty("id", "objects/null"); 12767 jsobj.AddProperty("id", "objects/null");
12778 jsobj.AddProperty("preview", "null"); 12768 jsobj.AddProperty("valueAsString", "null");
12779 return; 12769 return;
12780 } else if (raw() == Object::sentinel().raw()) { 12770 } else if (raw() == Object::sentinel().raw()) {
12781 jsobj.AddProperty("type", ref ? "@Null" : "Null"); 12771 jsobj.AddProperty("type", ref ? "@Null" : "Null");
12782 jsobj.AddProperty("id", "objects/not-initialized"); 12772 jsobj.AddProperty("id", "objects/not-initialized");
12783 jsobj.AddProperty("preview", "<not initialized>"); 12773 jsobj.AddProperty("valueAsString", "<not initialized>");
12784 return; 12774 return;
12785 } else if (raw() == Object::transition_sentinel().raw()) { 12775 } else if (raw() == Object::transition_sentinel().raw()) {
12786 jsobj.AddProperty("type", ref ? "@Null" : "Null"); 12776 jsobj.AddProperty("type", ref ? "@Null" : "Null");
12787 jsobj.AddProperty("id", "objects/being-initialized"); 12777 jsobj.AddProperty("id", "objects/being-initialized");
12788 jsobj.AddProperty("preview", "<being initialized>"); 12778 jsobj.AddProperty("valueAsString", "<being initialized>");
12789 return;
12790 } else if (raw() == Symbols::OptimizedOut().raw()) {
12791 // TODO(turnidge): This is a hack. The user could have this
12792 // special string in their program. Fixing this involves updating
12793 // the debugging api a bit.
12794 jsobj.AddProperty("type", ref ? "@Null" : "Null");
12795 jsobj.AddProperty("id", "objects/optimized-out");
12796 jsobj.AddProperty("preview", "<optimized out>");
12797 return; 12779 return;
12798 } 12780 }
12799 12781
12800 PrintSharedInstanceJSON(&jsobj, ref); 12782 PrintSharedInstanceJSON(&jsobj, ref);
12801 ObjectIdRing* ring = Isolate::Current()->object_id_ring(); 12783 ObjectIdRing* ring = Isolate::Current()->object_id_ring();
12802 const intptr_t id = ring->GetIdForObject(raw()); 12784 const intptr_t id = ring->GetIdForObject(raw());
12803 if (IsClosure()) { 12785 if (IsClosure()) {
12804 const Function& closureFunc = Function::Handle(Closure::function(*this)); 12786 const Function& closureFunc = Function::Handle(Closure::function(*this));
12805 jsobj.AddProperty("closureFunc", closureFunc); 12787 jsobj.AddProperty("closureFunc", closureFunc);
12806 } 12788 }
12807 jsobj.AddPropertyF("id", "objects/%" Pd "", id); 12789 jsobj.AddPropertyF("id", "objects/%" Pd "", id);
12808 jsobj.AddProperty("preview", ToUserCString(40));
12809 if (ref) { 12790 if (ref) {
12810 return; 12791 return;
12811 } 12792 }
12812 } 12793 }
12813 12794
12814 12795
12815 bool AbstractType::IsResolved() const { 12796 bool AbstractType::IsResolved() const {
12816 // AbstractType is an abstract class. 12797 // AbstractType is an abstract class.
12817 UNREACHABLE(); 12798 UNREACHABLE();
12818 return false; 12799 return false;
(...skipping 1697 matching lines...) Expand 10 before | Expand all | Expand 10 after
14516 14497
14517 14498
14518 const char* Number::ToCString() const { 14499 const char* Number::ToCString() const {
14519 // Number is an interface. No instances of Number should exist. 14500 // Number is an interface. No instances of Number should exist.
14520 UNREACHABLE(); 14501 UNREACHABLE();
14521 return "Number"; 14502 return "Number";
14522 } 14503 }
14523 14504
14524 14505
14525 void Number::PrintToJSONStream(JSONStream* stream, bool ref) const { 14506 void Number::PrintToJSONStream(JSONStream* stream, bool ref) const {
14526 Instance::PrintToJSONStream(stream, ref); 14507 JSONObject jsobj(stream);
14508 PrintSharedInstanceJSON(&jsobj, ref);
14509 ObjectIdRing* ring = Isolate::Current()->object_id_ring();
14510 const intptr_t id = ring->GetIdForObject(raw());
14511 jsobj.AddPropertyF("id", "objects/%" Pd "", id);
14512 jsobj.AddProperty("valueAsString", ToCString());
14527 } 14513 }
14528 14514
14529 14515
14530 const char* Integer::ToCString() const { 14516 const char* Integer::ToCString() const {
14531 // Integer is an interface. No instances of Integer should exist. 14517 // Integer is an interface. No instances of Integer should exist.
14532 UNREACHABLE(); 14518 UNREACHABLE();
14533 return "Integer"; 14519 return "Integer";
14534 } 14520 }
14535 14521
14536 14522
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
14958 // Calculate the size of the string. 14944 // Calculate the size of the string.
14959 intptr_t len = OS::SNPrint(NULL, 0, kFormat, Value()) + 1; 14945 intptr_t len = OS::SNPrint(NULL, 0, kFormat, Value()) + 1;
14960 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 14946 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
14961 OS::SNPrint(chars, len, kFormat, Value()); 14947 OS::SNPrint(chars, len, kFormat, Value());
14962 return chars; 14948 return chars;
14963 } 14949 }
14964 14950
14965 14951
14966 void Smi::PrintToJSONStream(JSONStream* stream, bool ref) const { 14952 void Smi::PrintToJSONStream(JSONStream* stream, bool ref) const {
14967 JSONObject jsobj(stream); 14953 JSONObject jsobj(stream);
14968 jsobj.AddProperty("type", JSONType(ref)); 14954 PrintSharedInstanceJSON(&jsobj, ref);
14969 jsobj.AddPropertyF("id", "objects/int-%" Pd "", Value()); 14955 jsobj.AddPropertyF("id", "objects/int-%" Pd "", Value());
14970 class Class& cls = Class::Handle(this->clazz()); 14956 jsobj.AddPropertyF("valueAsString", "%" Pd "", Value());
14971 jsobj.AddProperty("class", cls);
14972 jsobj.AddPropertyF("preview", "%" Pd "", Value());
14973 } 14957 }
14974 14958
14975 14959
14976 RawClass* Smi::Class() { 14960 RawClass* Smi::Class() {
14977 return Isolate::Current()->object_store()->smi_class(); 14961 return Isolate::Current()->object_store()->smi_class();
14978 } 14962 }
14979 14963
14980 14964
14981 void Mint::set_value(int64_t value) const { 14965 void Mint::set_value(int64_t value) const {
14982 raw_ptr()->value_ = value; 14966 raw_ptr()->value_ = value;
(...skipping 1208 matching lines...) Expand 10 before | Expand all | Expand 10 after
16191 } 16175 }
16192 if (len > too_long) { 16176 if (len > too_long) {
16193 // No point going further. 16177 // No point going further.
16194 break; 16178 break;
16195 } 16179 }
16196 } 16180 }
16197 return len; 16181 return len;
16198 } 16182 }
16199 16183
16200 16184
16201 const char* String::ToUserCString(intptr_t max_len, intptr_t nesting) const { 16185 const char* String::ToUserCString(intptr_t max_len) const {
16202 // Compute the needed length for the buffer. 16186 // Compute the needed length for the buffer.
16203 const intptr_t escaped_len = EscapedStringLen(max_len); 16187 const intptr_t escaped_len = EscapedStringLen(max_len);
16204 intptr_t print_len = escaped_len; 16188 intptr_t print_len = escaped_len;
16205 intptr_t buffer_len = escaped_len + 2; // +2 for quotes. 16189 intptr_t buffer_len = escaped_len + 2; // +2 for quotes.
16206 if (buffer_len > max_len) { 16190 if (buffer_len > max_len) {
16207 buffer_len = max_len; // Truncate. 16191 buffer_len = max_len; // Truncate.
16208 print_len = max_len - 5; // -2 for quotes, -3 for elipsis. 16192 print_len = max_len - 5; // -2 for quotes, -3 for elipsis.
16209 } 16193 }
16210 16194
16211 // Allocate the buffer. 16195 // Allocate the buffer.
(...skipping 16 matching lines...) Expand all
16228 buffer[pos++] = '.'; 16212 buffer[pos++] = '.';
16229 } 16213 }
16230 ASSERT(pos <= buffer_len); 16214 ASSERT(pos <= buffer_len);
16231 buffer[pos++] = '\0'; 16215 buffer[pos++] = '\0';
16232 16216
16233 return buffer; 16217 return buffer;
16234 } 16218 }
16235 16219
16236 16220
16237 void String::PrintToJSONStream(JSONStream* stream, bool ref) const { 16221 void String::PrintToJSONStream(JSONStream* stream, bool ref) const {
16238 Instance::PrintToJSONStream(stream, ref); 16222 JSONObject jsobj(stream);
16223 if (raw() == Symbols::OptimizedOut().raw()) {
16224 // TODO(turnidge): This is a hack. The user could have this
16225 // special string in their program. Fixing this involves updating
16226 // the debugging api a bit.
16227 jsobj.AddProperty("type", ref ? "@Null" : "Null");
16228 jsobj.AddProperty("id", "objects/optimized-out");
16229 jsobj.AddProperty("valueAsString", "<optimized out>");
16230 return;
16231 }
16232 PrintSharedInstanceJSON(&jsobj, ref);
16233 ObjectIdRing* ring = Isolate::Current()->object_id_ring();
16234 const intptr_t id = ring->GetIdForObject(raw());
16235 jsobj.AddPropertyF("id", "objects/%" Pd "", id);
16236 jsobj.AddProperty("valueAsString", ToUserCString(1024));
16239 } 16237 }
16240 16238
16241 16239
16242 void String::ToUTF8(uint8_t* utf8_array, intptr_t array_len) const { 16240 void String::ToUTF8(uint8_t* utf8_array, intptr_t array_len) const {
16243 ASSERT(array_len >= Utf8::Length(*this)); 16241 ASSERT(array_len >= Utf8::Length(*this));
16244 Utf8::Encode(*this, reinterpret_cast<char*>(utf8_array), array_len); 16242 Utf8::Encode(*this, reinterpret_cast<char*>(utf8_array), array_len);
16245 } 16243 }
16246 16244
16247 16245
16248 static FinalizablePersistentHandle* AddFinalizer( 16246 static FinalizablePersistentHandle* AddFinalizer(
(...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after
17026 } 17024 }
17027 17025
17028 17026
17029 void Bool::PrintToJSONStream(JSONStream* stream, bool ref) const { 17027 void Bool::PrintToJSONStream(JSONStream* stream, bool ref) const {
17030 const char* str = ToCString(); 17028 const char* str = ToCString();
17031 JSONObject jsobj(stream); 17029 JSONObject jsobj(stream);
17032 jsobj.AddProperty("type", JSONType(ref)); 17030 jsobj.AddProperty("type", JSONType(ref));
17033 jsobj.AddPropertyF("id", "objects/bool-%s", str); 17031 jsobj.AddPropertyF("id", "objects/bool-%s", str);
17034 class Class& cls = Class::Handle(this->clazz()); 17032 class Class& cls = Class::Handle(this->clazz());
17035 jsobj.AddProperty("class", cls); 17033 jsobj.AddProperty("class", cls);
17036 jsobj.AddPropertyF("preview", "%s", str); 17034 jsobj.AddPropertyF("valueAsString", "%s", str);
17037 } 17035 }
17038 17036
17039 17037
17040 bool Array::Equals(const Instance& other) const { 17038 bool Array::Equals(const Instance& other) const {
17041 if (this->raw() == other.raw()) { 17039 if (this->raw() == other.raw()) {
17042 // Both handles point to the same raw instance. 17040 // Both handles point to the same raw instance.
17043 return true; 17041 return true;
17044 } 17042 }
17045 17043
17046 // An Array may be compared to an ImmutableArray. 17044 // An Array may be compared to an ImmutableArray.
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
17345 return "_GrowableList NULL"; 17343 return "_GrowableList NULL";
17346 } 17344 }
17347 const char* format = "Instance(length:%" Pd ") of '_GrowableList'"; 17345 const char* format = "Instance(length:%" Pd ") of '_GrowableList'";
17348 intptr_t len = OS::SNPrint(NULL, 0, format, Length()) + 1; 17346 intptr_t len = OS::SNPrint(NULL, 0, format, Length()) + 1;
17349 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 17347 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
17350 OS::SNPrint(chars, len, format, Length()); 17348 OS::SNPrint(chars, len, format, Length());
17351 return chars; 17349 return chars;
17352 } 17350 }
17353 17351
17354 17352
17355 const char* GrowableObjectArray::ToUserCString(intptr_t max_len,
17356 intptr_t nesting) const {
17357 if (Length() == 0) {
17358 return "[]";
17359 }
17360 if (nesting > 3) {
17361 return "[...]";
17362 }
17363
17364 Isolate* isolate = Isolate::Current();
17365 Zone* zone = isolate->current_zone();
17366 Object& obj = Object::Handle(isolate);
17367 Instance& element = Instance::Handle(isolate);
17368
17369 // Pre-print the suffix that we will use if the string is truncated.
17370 // It is important to know the suffix length when deciding where to
17371 // limit the list.
17372 const intptr_t kMaxTruncSuffixLen = 16;
17373 char trunc_suffix[kMaxTruncSuffixLen];
17374 intptr_t trunc_suffix_len;
17375 if (nesting == 0) {
17376 trunc_suffix_len = OS::SNPrint(trunc_suffix, 16, "...](length:%" Pd ")",
17377 Length());
17378 } else {
17379 trunc_suffix_len = OS::SNPrint(trunc_suffix, 16, "...]");
17380 }
17381 bool truncate = false;
17382
17383 const int kMaxPrintElements = 128;
17384 const char* strings[kMaxPrintElements];
17385 intptr_t print_len = 1; // +1 for "["
17386
17387 // Figure out how many elements will fit in the string.
17388 int i = 0;
17389 while (i < Length()) {
17390 if (i == kMaxPrintElements) {
17391 if (i < Length()) {
17392 truncate = true;
17393 }
17394 break;
17395 }
17396 obj = At(i);
17397 if (!obj.IsNull() && !obj.IsInstance()) {
17398 UNREACHABLE();
17399 return "[<invalid list>]";
17400 }
17401 element ^= obj.raw();
17402
17403 // Choose max child length. This is chosen so that it is small
17404 // enough to maybe fit but not so small that we can't print
17405 // anything.
17406 int child_max_len = max_len - print_len;
17407 if ((i + 1) < Length()) {
17408 child_max_len -= (trunc_suffix_len + 1); // 1 for ","
17409 } else {
17410 child_max_len -= 1; // 1 for "]"
17411 }
17412 if (child_max_len < 8) {
17413 child_max_len = 8;
17414 }
17415
17416 strings[i] = element.ToUserCString(child_max_len, nesting + 1);
17417 print_len += strlen(strings[i]) + 1; // +1 for "," or "]"
17418 i++;
17419 if (print_len > max_len) {
17420 truncate = true;
17421 break;
17422 }
17423 }
17424 if (truncate) {
17425 // Go backwards until there is enough room for the truncation suffix.
17426 while (i >= 0 && (print_len + trunc_suffix_len) > max_len) {
17427 i--;
17428 print_len -= (strlen(strings[i]) + 1); // +1 for ","
17429 }
17430 }
17431
17432 // Finally, allocate and print the string.
17433 int num_to_print = i;
17434 char* buffer = zone->Alloc<char>(print_len + 1); // +1 for "\0"
17435 intptr_t pos = 0;
17436 buffer[pos++] = '[';
17437 for (i = 0; i < num_to_print; i++) {
17438 if ((i + 1) == Length()) {
17439 pos += OS::SNPrint((buffer + pos), (max_len + 1 - pos),
17440 "%s]", strings[i]);
17441 } else {
17442 pos += OS::SNPrint((buffer + pos), (max_len + 1 - pos),
17443 "%s,", strings[i]);
17444 }
17445 }
17446 if (i < Length()) {
17447 pos += OS::SNPrint((buffer + pos), (max_len + 1 - pos), "%s", trunc_suffix);
17448 }
17449 ASSERT(pos <= max_len);
17450 buffer[pos] = '\0';
17451 return buffer;
17452 }
17453
17454
17455 void GrowableObjectArray::PrintToJSONStream(JSONStream* stream, 17353 void GrowableObjectArray::PrintToJSONStream(JSONStream* stream,
17456 bool ref) const { 17354 bool ref) const {
17457 JSONObject jsobj(stream); 17355 JSONObject jsobj(stream);
17458 PrintSharedInstanceJSON(&jsobj, ref); 17356 PrintSharedInstanceJSON(&jsobj, ref);
17459 ObjectIdRing* ring = Isolate::Current()->object_id_ring(); 17357 ObjectIdRing* ring = Isolate::Current()->object_id_ring();
17460 const intptr_t id = ring->GetIdForObject(raw()); 17358 const intptr_t id = ring->GetIdForObject(raw());
17461 jsobj.AddPropertyF("id", "objects/%" Pd "", id); 17359 jsobj.AddPropertyF("id", "objects/%" Pd "", id);
17462 jsobj.AddProperty("length", Length()); 17360 jsobj.AddProperty("length", Length());
17463 if (ref) { 17361 if (ref) {
17464 return; 17362 return;
(...skipping 860 matching lines...) Expand 10 before | Expand all | Expand 10 after
18325 return "_MirrorReference"; 18223 return "_MirrorReference";
18326 } 18224 }
18327 18225
18328 18226
18329 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { 18227 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const {
18330 Instance::PrintToJSONStream(stream, ref); 18228 Instance::PrintToJSONStream(stream, ref);
18331 } 18229 }
18332 18230
18333 18231
18334 } // namespace dart 18232 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698