1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #include "v8.h" 29 30 #include "disassembler.h" 31 #include "disasm.h" 32 #include "jsregexp.h" 33 #include "objects-visiting.h" 34 35 namespace v8 { 36 namespace internal { 37 38 #ifdef OBJECT_PRINT 39 40 static const char* TypeToString(InstanceType type); 41 42 43 void MaybeObject::Print(FILE* out) { 44 Object* this_as_object; 45 if (ToObject(&this_as_object)) { 46 if (this_as_object->IsSmi()) { 47 Smi::cast(this_as_object)->SmiPrint(out); 48 } else { 49 HeapObject::cast(this_as_object)->HeapObjectPrint(out); 50 } 51 } else { 52 Failure::cast(this)->FailurePrint(out); 53 } 54 Flush(out); 55 } 56 57 58 void MaybeObject::PrintLn(FILE* out) { 59 Print(out); 60 PrintF(out, "\n"); 61 } 62 63 64 void HeapObject::PrintHeader(FILE* out, const char* id) { 65 PrintF(out, "%p: [%s]\n", reinterpret_cast<void*>(this), id); 66 } 67 68 69 void HeapObject::HeapObjectPrint(FILE* out) { 70 InstanceType instance_type = map()->instance_type(); 71 72 HandleScope scope; 73 if (instance_type < FIRST_NONSTRING_TYPE) { 74 String::cast(this)->StringPrint(out); 75 return; 76 } 77 78 switch (instance_type) { 79 case MAP_TYPE: 80 Map::cast(this)->MapPrint(out); 81 break; 82 case HEAP_NUMBER_TYPE: 83 HeapNumber::cast(this)->HeapNumberPrint(out); 84 break; 85 case FIXED_DOUBLE_ARRAY_TYPE: 86 FixedDoubleArray::cast(this)->FixedDoubleArrayPrint(out); 87 break; 88 case FIXED_ARRAY_TYPE: 89 FixedArray::cast(this)->FixedArrayPrint(out); 90 break; 91 case BYTE_ARRAY_TYPE: 92 ByteArray::cast(this)->ByteArrayPrint(out); 93 break; 94 case FREE_SPACE_TYPE: 95 FreeSpace::cast(this)->FreeSpacePrint(out); 96 break; 97 case EXTERNAL_PIXEL_ARRAY_TYPE: 98 ExternalPixelArray::cast(this)->ExternalPixelArrayPrint(out); 99 break; 100 case EXTERNAL_BYTE_ARRAY_TYPE: 101 ExternalByteArray::cast(this)->ExternalByteArrayPrint(out); 102 break; 103 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: 104 ExternalUnsignedByteArray::cast(this) 105 ->ExternalUnsignedByteArrayPrint(out); 106 break; 107 case EXTERNAL_SHORT_ARRAY_TYPE: 108 ExternalShortArray::cast(this)->ExternalShortArrayPrint(out); 109 break; 110 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE: 111 ExternalUnsignedShortArray::cast(this) 112 ->ExternalUnsignedShortArrayPrint(out); 113 break; 114 case EXTERNAL_INT_ARRAY_TYPE: 115 ExternalIntArray::cast(this)->ExternalIntArrayPrint(out); 116 break; 117 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE: 118 ExternalUnsignedIntArray::cast(this)->ExternalUnsignedIntArrayPrint(out); 119 break; 120 case EXTERNAL_FLOAT_ARRAY_TYPE: 121 ExternalFloatArray::cast(this)->ExternalFloatArrayPrint(out); 122 break; 123 case EXTERNAL_DOUBLE_ARRAY_TYPE: 124 ExternalDoubleArray::cast(this)->ExternalDoubleArrayPrint(out); 125 break; 126 case FILLER_TYPE: 127 PrintF(out, "filler"); 128 break; 129 case JS_OBJECT_TYPE: // fall through 130 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: 131 case JS_ARRAY_TYPE: 132 case JS_REGEXP_TYPE: 133 JSObject::cast(this)->JSObjectPrint(out); 134 break; 135 case ODDBALL_TYPE: 136 Oddball::cast(this)->to_string()->Print(out); 137 break; 138 case JS_FUNCTION_TYPE: 139 JSFunction::cast(this)->JSFunctionPrint(out); 140 break; 141 case JS_GLOBAL_PROXY_TYPE: 142 JSGlobalProxy::cast(this)->JSGlobalProxyPrint(out); 143 break; 144 case JS_GLOBAL_OBJECT_TYPE: 145 JSGlobalObject::cast(this)->JSGlobalObjectPrint(out); 146 break; 147 case JS_BUILTINS_OBJECT_TYPE: 148 JSBuiltinsObject::cast(this)->JSBuiltinsObjectPrint(out); 149 break; 150 case JS_VALUE_TYPE: 151 PrintF(out, "Value wrapper around:"); 152 JSValue::cast(this)->value()->Print(out); 153 break; 154 case JS_DATE_TYPE: 155 JSDate::cast(this)->value()->Print(out); 156 break; 157 case CODE_TYPE: 158 Code::cast(this)->CodePrint(out); 159 break; 160 case JS_PROXY_TYPE: 161 JSProxy::cast(this)->JSProxyPrint(out); 162 break; 163 case JS_FUNCTION_PROXY_TYPE: 164 JSFunctionProxy::cast(this)->JSFunctionProxyPrint(out); 165 break; 166 case JS_WEAK_MAP_TYPE: 167 JSWeakMap::cast(this)->JSWeakMapPrint(out); 168 break; 169 case FOREIGN_TYPE: 170 Foreign::cast(this)->ForeignPrint(out); 171 break; 172 case SHARED_FUNCTION_INFO_TYPE: 173 SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint(out); 174 break; 175 case JS_MESSAGE_OBJECT_TYPE: 176 JSMessageObject::cast(this)->JSMessageObjectPrint(out); 177 break; 178 case JS_GLOBAL_PROPERTY_CELL_TYPE: 179 JSGlobalPropertyCell::cast(this)->JSGlobalPropertyCellPrint(out); 180 break; 181 #define MAKE_STRUCT_CASE(NAME, Name, name) \ 182 case NAME##_TYPE: \ 183 Name::cast(this)->Name##Print(out); \ 184 break; 185 STRUCT_LIST(MAKE_STRUCT_CASE) 186 #undef MAKE_STRUCT_CASE 187 188 default: 189 PrintF(out, "UNKNOWN TYPE %d", map()->instance_type()); 190 UNREACHABLE(); 191 break; 192 } 193 } 194 195 196 void ByteArray::ByteArrayPrint(FILE* out) { 197 PrintF(out, "byte array, data starts at %p", GetDataStartAddress()); 198 } 199 200 201 void FreeSpace::FreeSpacePrint(FILE* out) { 202 PrintF(out, "free space, size %d", Size()); 203 } 204 205 206 void ExternalPixelArray::ExternalPixelArrayPrint(FILE* out) { 207 PrintF(out, "external pixel array"); 208 } 209 210 211 void ExternalByteArray::ExternalByteArrayPrint(FILE* out) { 212 PrintF(out, "external byte array"); 213 } 214 215 216 void ExternalUnsignedByteArray::ExternalUnsignedByteArrayPrint(FILE* out) { 217 PrintF(out, "external unsigned byte array"); 218 } 219 220 221 void ExternalShortArray::ExternalShortArrayPrint(FILE* out) { 222 PrintF(out, "external short array"); 223 } 224 225 226 void ExternalUnsignedShortArray::ExternalUnsignedShortArrayPrint(FILE* out) { 227 PrintF(out, "external unsigned short array"); 228 } 229 230 231 void ExternalIntArray::ExternalIntArrayPrint(FILE* out) { 232 PrintF(out, "external int array"); 233 } 234 235 236 void ExternalUnsignedIntArray::ExternalUnsignedIntArrayPrint(FILE* out) { 237 PrintF(out, "external unsigned int array"); 238 } 239 240 241 void ExternalFloatArray::ExternalFloatArrayPrint(FILE* out) { 242 PrintF(out, "external float array"); 243 } 244 245 246 void ExternalDoubleArray::ExternalDoubleArrayPrint(FILE* out) { 247 PrintF(out, "external double array"); 248 } 249 250 251 void JSObject::PrintProperties(FILE* out) { 252 if (HasFastProperties()) { 253 DescriptorArray* descs = map()->instance_descriptors(); 254 for (int i = 0; i < descs->number_of_descriptors(); i++) { 255 PrintF(out, " "); 256 descs->GetKey(i)->StringPrint(out); 257 PrintF(out, ": "); 258 switch (descs->GetType(i)) { 259 case FIELD: { 260 int index = descs->GetFieldIndex(i); 261 FastPropertyAt(index)->ShortPrint(out); 262 PrintF(out, " (field at offset %d)\n", index); 263 break; 264 } 265 case CONSTANT_FUNCTION: 266 descs->GetConstantFunction(i)->ShortPrint(out); 267 PrintF(out, " (constant function)\n"); 268 break; 269 case CALLBACKS: 270 descs->GetCallbacksObject(i)->ShortPrint(out); 271 PrintF(out, " (callback)\n"); 272 break; 273 case ELEMENTS_TRANSITION: { 274 PrintF(out, "(elements transition to "); 275 Object* descriptor_contents = descs->GetValue(i); 276 if (descriptor_contents->IsMap()) { 277 Map* map = Map::cast(descriptor_contents); 278 PrintElementsKind(out, map->elements_kind()); 279 } else { 280 FixedArray* map_array = FixedArray::cast(descriptor_contents); 281 for (int i = 0; i < map_array->length(); ++i) { 282 Map* map = Map::cast(map_array->get(i)); 283 if (i != 0) { 284 PrintF(out, ", "); 285 } 286 PrintElementsKind(out, map->elements_kind()); 287 } 288 } 289 PrintF(out, ")\n"); 290 break; 291 } 292 case MAP_TRANSITION: 293 PrintF(out, "(map transition)\n"); 294 break; 295 case CONSTANT_TRANSITION: 296 PrintF(out, "(constant transition)\n"); 297 break; 298 case NULL_DESCRIPTOR: 299 PrintF(out, "(null descriptor)\n"); 300 break; 301 case NORMAL: // only in slow mode 302 case HANDLER: // only in lookup results, not in descriptors 303 case INTERCEPTOR: // only in lookup results, not in descriptors 304 UNREACHABLE(); 305 break; 306 } 307 } 308 } else { 309 property_dictionary()->Print(out); 310 } 311 } 312 313 314 void JSObject::PrintElements(FILE* out) { 315 // Don't call GetElementsKind, its validation code can cause the printer to 316 // fail when debugging. 317 switch (map()->elements_kind()) { 318 case FAST_SMI_ONLY_ELEMENTS: 319 case FAST_ELEMENTS: { 320 // Print in array notation for non-sparse arrays. 321 FixedArray* p = FixedArray::cast(elements()); 322 for (int i = 0; i < p->length(); i++) { 323 PrintF(out, " %d: ", i); 324 p->get(i)->ShortPrint(out); 325 PrintF(out, "\n"); 326 } 327 break; 328 } 329 case FAST_DOUBLE_ELEMENTS: { 330 // Print in array notation for non-sparse arrays. 331 if (elements()->length() > 0) { 332 FixedDoubleArray* p = FixedDoubleArray::cast(elements()); 333 for (int i = 0; i < p->length(); i++) { 334 if (p->is_the_hole(i)) { 335 PrintF(out, " %d: <the hole>", i); 336 } else { 337 PrintF(out, " %d: %g", i, p->get_scalar(i)); 338 } 339 PrintF(out, "\n"); 340 } 341 } 342 break; 343 } 344 case EXTERNAL_PIXEL_ELEMENTS: { 345 ExternalPixelArray* p = ExternalPixelArray::cast(elements()); 346 for (int i = 0; i < p->length(); i++) { 347 PrintF(out, " %d: %d\n", i, p->get_scalar(i)); 348 } 349 break; 350 } 351 case EXTERNAL_BYTE_ELEMENTS: { 352 ExternalByteArray* p = ExternalByteArray::cast(elements()); 353 for (int i = 0; i < p->length(); i++) { 354 PrintF(out, " %d: %d\n", i, static_cast<int>(p->get_scalar(i))); 355 } 356 break; 357 } 358 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { 359 ExternalUnsignedByteArray* p = 360 ExternalUnsignedByteArray::cast(elements()); 361 for (int i = 0; i < p->length(); i++) { 362 PrintF(out, " %d: %d\n", i, static_cast<int>(p->get_scalar(i))); 363 } 364 break; 365 } 366 case EXTERNAL_SHORT_ELEMENTS: { 367 ExternalShortArray* p = ExternalShortArray::cast(elements()); 368 for (int i = 0; i < p->length(); i++) { 369 PrintF(out, " %d: %d\n", i, static_cast<int>(p->get_scalar(i))); 370 } 371 break; 372 } 373 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: { 374 ExternalUnsignedShortArray* p = 375 ExternalUnsignedShortArray::cast(elements()); 376 for (int i = 0; i < p->length(); i++) { 377 PrintF(out, " %d: %d\n", i, static_cast<int>(p->get_scalar(i))); 378 } 379 break; 380 } 381 case EXTERNAL_INT_ELEMENTS: { 382 ExternalIntArray* p = ExternalIntArray::cast(elements()); 383 for (int i = 0; i < p->length(); i++) { 384 PrintF(out, " %d: %d\n", i, static_cast<int>(p->get_scalar(i))); 385 } 386 break; 387 } 388 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { 389 ExternalUnsignedIntArray* p = 390 ExternalUnsignedIntArray::cast(elements()); 391 for (int i = 0; i < p->length(); i++) { 392 PrintF(out, " %d: %d\n", i, static_cast<int>(p->get_scalar(i))); 393 } 394 break; 395 } 396 case EXTERNAL_FLOAT_ELEMENTS: { 397 ExternalFloatArray* p = ExternalFloatArray::cast(elements()); 398 for (int i = 0; i < p->length(); i++) { 399 PrintF(out, " %d: %f\n", i, p->get_scalar(i)); 400 } 401 break; 402 } 403 case EXTERNAL_DOUBLE_ELEMENTS: { 404 ExternalDoubleArray* p = ExternalDoubleArray::cast(elements()); 405 for (int i = 0; i < p->length(); i++) { 406 PrintF(out, " %d: %f\n", i, p->get_scalar(i)); 407 } 408 break; 409 } 410 case DICTIONARY_ELEMENTS: 411 elements()->Print(out); 412 break; 413 case NON_STRICT_ARGUMENTS_ELEMENTS: { 414 FixedArray* p = FixedArray::cast(elements()); 415 for (int i = 2; i < p->length(); i++) { 416 PrintF(out, " %d: ", i); 417 p->get(i)->ShortPrint(out); 418 PrintF(out, "\n"); 419 } 420 break; 421 } 422 } 423 } 424 425 426 void JSObject::JSObjectPrint(FILE* out) { 427 PrintF(out, "%p: [JSObject]\n", reinterpret_cast<void*>(this)); 428 PrintF(out, " - map = %p [", reinterpret_cast<void*>(map())); 429 // Don't call GetElementsKind, its validation code can cause the printer to 430 // fail when debugging. 431 PrintElementsKind(out, this->map()->elements_kind()); 432 PrintF(out, 433 "]\n - prototype = %p\n", 434 reinterpret_cast<void*>(GetPrototype())); 435 PrintF(out, " {\n"); 436 PrintProperties(out); 437 PrintElements(out); 438 PrintF(out, " }\n"); 439 } 440 441 442 static const char* TypeToString(InstanceType type) { 443 switch (type) { 444 case INVALID_TYPE: return "INVALID"; 445 case MAP_TYPE: return "MAP"; 446 case HEAP_NUMBER_TYPE: return "HEAP_NUMBER"; 447 case SYMBOL_TYPE: return "SYMBOL"; 448 case ASCII_SYMBOL_TYPE: return "ASCII_SYMBOL"; 449 case CONS_SYMBOL_TYPE: return "CONS_SYMBOL"; 450 case CONS_ASCII_SYMBOL_TYPE: return "CONS_ASCII_SYMBOL"; 451 case EXTERNAL_ASCII_SYMBOL_TYPE: 452 case EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE: 453 case EXTERNAL_SYMBOL_TYPE: return "EXTERNAL_SYMBOL"; 454 case SHORT_EXTERNAL_ASCII_SYMBOL_TYPE: 455 case SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE: 456 case SHORT_EXTERNAL_SYMBOL_TYPE: return "SHORT_EXTERNAL_SYMBOL"; 457 case ASCII_STRING_TYPE: return "ASCII_STRING"; 458 case STRING_TYPE: return "TWO_BYTE_STRING"; 459 case CONS_STRING_TYPE: 460 case CONS_ASCII_STRING_TYPE: return "CONS_STRING"; 461 case EXTERNAL_ASCII_STRING_TYPE: 462 case EXTERNAL_STRING_WITH_ASCII_DATA_TYPE: 463 case EXTERNAL_STRING_TYPE: return "EXTERNAL_STRING"; 464 case SHORT_EXTERNAL_ASCII_STRING_TYPE: 465 case SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE: 466 case SHORT_EXTERNAL_STRING_TYPE: return "SHORT_EXTERNAL_STRING"; 467 case FIXED_ARRAY_TYPE: return "FIXED_ARRAY"; 468 case BYTE_ARRAY_TYPE: return "BYTE_ARRAY"; 469 case FREE_SPACE_TYPE: return "FREE_SPACE"; 470 case EXTERNAL_PIXEL_ARRAY_TYPE: return "EXTERNAL_PIXEL_ARRAY"; 471 case EXTERNAL_BYTE_ARRAY_TYPE: return "EXTERNAL_BYTE_ARRAY"; 472 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: 473 return "EXTERNAL_UNSIGNED_BYTE_ARRAY"; 474 case EXTERNAL_SHORT_ARRAY_TYPE: return "EXTERNAL_SHORT_ARRAY"; 475 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE: 476 return "EXTERNAL_UNSIGNED_SHORT_ARRAY"; 477 case EXTERNAL_INT_ARRAY_TYPE: return "EXTERNAL_INT_ARRAY"; 478 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE: 479 return "EXTERNAL_UNSIGNED_INT_ARRAY"; 480 case EXTERNAL_FLOAT_ARRAY_TYPE: return "EXTERNAL_FLOAT_ARRAY"; 481 case EXTERNAL_DOUBLE_ARRAY_TYPE: return "EXTERNAL_DOUBLE_ARRAY"; 482 case FILLER_TYPE: return "FILLER"; 483 case JS_OBJECT_TYPE: return "JS_OBJECT"; 484 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: return "JS_CONTEXT_EXTENSION_OBJECT"; 485 case ODDBALL_TYPE: return "ODDBALL"; 486 case JS_GLOBAL_PROPERTY_CELL_TYPE: return "JS_GLOBAL_PROPERTY_CELL"; 487 case SHARED_FUNCTION_INFO_TYPE: return "SHARED_FUNCTION_INFO"; 488 case JS_FUNCTION_TYPE: return "JS_FUNCTION"; 489 case CODE_TYPE: return "CODE"; 490 case JS_ARRAY_TYPE: return "JS_ARRAY"; 491 case JS_PROXY_TYPE: return "JS_PROXY"; 492 case JS_WEAK_MAP_TYPE: return "JS_WEAK_MAP"; 493 case JS_REGEXP_TYPE: return "JS_REGEXP"; 494 case JS_VALUE_TYPE: return "JS_VALUE"; 495 case JS_GLOBAL_OBJECT_TYPE: return "JS_GLOBAL_OBJECT"; 496 case JS_BUILTINS_OBJECT_TYPE: return "JS_BUILTINS_OBJECT"; 497 case JS_GLOBAL_PROXY_TYPE: return "JS_GLOBAL_PROXY"; 498 case FOREIGN_TYPE: return "FOREIGN"; 499 case JS_MESSAGE_OBJECT_TYPE: return "JS_MESSAGE_OBJECT_TYPE"; 500 #define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return #NAME; 501 STRUCT_LIST(MAKE_STRUCT_CASE) 502 #undef MAKE_STRUCT_CASE 503 default: return "UNKNOWN"; 504 } 505 } 506 507 508 void Map::MapPrint(FILE* out) { 509 HeapObject::PrintHeader(out, "Map"); 510 PrintF(out, " - type: %s\n", TypeToString(instance_type())); 511 PrintF(out, " - instance size: %d\n", instance_size()); 512 PrintF(out, " - inobject properties: %d\n", inobject_properties()); 513 PrintF(out, " - elements kind: "); 514 PrintElementsKind(out, elements_kind()); 515 PrintF(out, "\n - pre-allocated property fields: %d\n", 516 pre_allocated_property_fields()); 517 PrintF(out, " - unused property fields: %d\n", unused_property_fields()); 518 if (is_hidden_prototype()) { 519 PrintF(out, " - hidden_prototype\n"); 520 } 521 if (has_named_interceptor()) { 522 PrintF(out, " - named_interceptor\n"); 523 } 524 if (has_indexed_interceptor()) { 525 PrintF(out, " - indexed_interceptor\n"); 526 } 527 if (is_undetectable()) { 528 PrintF(out, " - undetectable\n"); 529 } 530 if (has_instance_call_handler()) { 531 PrintF(out, " - instance_call_handler\n"); 532 } 533 if (is_access_check_needed()) { 534 PrintF(out, " - access_check_needed\n"); 535 } 536 PrintF(out, " - instance descriptors: "); 537 instance_descriptors()->ShortPrint(out); 538 PrintF(out, "\n - prototype: "); 539 prototype()->ShortPrint(out); 540 PrintF(out, "\n - constructor: "); 541 constructor()->ShortPrint(out); 542 PrintF(out, "\n"); 543 } 544 545 546 void CodeCache::CodeCachePrint(FILE* out) { 547 HeapObject::PrintHeader(out, "CodeCache"); 548 PrintF(out, "\n - default_cache: "); 549 default_cache()->ShortPrint(out); 550 PrintF(out, "\n - normal_type_cache: "); 551 normal_type_cache()->ShortPrint(out); 552 } 553 554 555 void PolymorphicCodeCache::PolymorphicCodeCachePrint(FILE* out) { 556 HeapObject::PrintHeader(out, "PolymorphicCodeCache"); 557 PrintF(out, "\n - cache: "); 558 cache()->ShortPrint(out); 559 } 560 561 562 void TypeFeedbackInfo::TypeFeedbackInfoPrint(FILE* out) { 563 HeapObject::PrintHeader(out, "TypeFeedbackInfo"); 564 PrintF(out, "\n - ic_total_count: %d, ic_with_type_info_count: %d", 565 ic_total_count(), ic_with_type_info_count()); 566 PrintF(out, "\n - type_feedback_cells: "); 567 type_feedback_cells()->FixedArrayPrint(out); 568 } 569 570 571 void AliasedArgumentsEntry::AliasedArgumentsEntryPrint(FILE* out) { 572 HeapObject::PrintHeader(out, "AliasedArgumentsEntry"); 573 PrintF(out, "\n - aliased_context_slot: %d", aliased_context_slot()); 574 } 575 576 577 void FixedArray::FixedArrayPrint(FILE* out) { 578 HeapObject::PrintHeader(out, "FixedArray"); 579 PrintF(out, " - length: %d", length()); 580 for (int i = 0; i < length(); i++) { 581 PrintF(out, "\n [%d]: ", i); 582 get(i)->ShortPrint(out); 583 } 584 PrintF(out, "\n"); 585 } 586 587 588 void FixedDoubleArray::FixedDoubleArrayPrint(FILE* out) { 589 HeapObject::PrintHeader(out, "FixedDoubleArray"); 590 PrintF(out, " - length: %d", length()); 591 for (int i = 0; i < length(); i++) { 592 if (is_the_hole(i)) { 593 PrintF(out, "\n [%d]: <the hole>", i); 594 } else { 595 PrintF(out, "\n [%d]: %g", i, get_scalar(i)); 596 } 597 } 598 PrintF(out, "\n"); 599 } 600 601 602 void JSValue::JSValuePrint(FILE* out) { 603 HeapObject::PrintHeader(out, "ValueObject"); 604 value()->Print(out); 605 } 606 607 608 void JSMessageObject::JSMessageObjectPrint(FILE* out) { 609 HeapObject::PrintHeader(out, "JSMessageObject"); 610 PrintF(out, " - type: "); 611 type()->ShortPrint(out); 612 PrintF(out, "\n - arguments: "); 613 arguments()->ShortPrint(out); 614 PrintF(out, "\n - start_position: %d", start_position()); 615 PrintF(out, "\n - end_position: %d", end_position()); 616 PrintF(out, "\n - script: "); 617 script()->ShortPrint(out); 618 PrintF(out, "\n - stack_trace: "); 619 stack_trace()->ShortPrint(out); 620 PrintF(out, "\n - stack_frames: "); 621 stack_frames()->ShortPrint(out); 622 PrintF(out, "\n"); 623 } 624 625 626 void String::StringPrint(FILE* out) { 627 if (StringShape(this).IsSymbol()) { 628 PrintF(out, "#"); 629 } else if (StringShape(this).IsCons()) { 630 PrintF(out, "c\""); 631 } else { 632 PrintF(out, "\""); 633 } 634 635 const char truncated_epilogue[] = "...<truncated>"; 636 int len = length(); 637 if (!FLAG_use_verbose_printer) { 638 if (len > 100) { 639 len = 100 - sizeof(truncated_epilogue); 640 } 641 } 642 for (int i = 0; i < len; i++) { 643 PrintF(out, "%c", Get(i)); 644 } 645 if (len != length()) { 646 PrintF(out, "%s", truncated_epilogue); 647 } 648 649 if (!StringShape(this).IsSymbol()) PrintF(out, "\""); 650 } 651 652 653 // This method is only meant to be called from gdb for debugging purposes. 654 // Since the string can also be in two-byte encoding, non-ASCII characters 655 // will be ignored in the output. 656 char* String::ToAsciiArray() { 657 // Static so that subsequent calls frees previously allocated space. 658 // This also means that previous results will be overwritten. 659 static char* buffer = NULL; 660 if (buffer != NULL) free(buffer); 661 buffer = new char[length()+1]; 662 WriteToFlat(this, buffer, 0, length()); 663 buffer[length()] = 0; 664 return buffer; 665 } 666 667 668 static const char* const weekdays[] = { 669 "???", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 670 }; 671 672 void JSDate::JSDatePrint(FILE* out) { 673 HeapObject::PrintHeader(out, "JSDate"); 674 PrintF(out, " - map = 0x%p\n", reinterpret_cast<void*>(map())); 675 PrintF(out, " - value = "); 676 value()->Print(out); 677 if (!year()->IsSmi()) { 678 PrintF(out, " - time = NaN\n"); 679 } else { 680 PrintF(out, " - time = %s %04d/%02d/%02d %02d:%02d:%02d\n", 681 weekdays[weekday()->IsSmi() ? Smi::cast(weekday())->value() + 1 : 0], 682 year()->IsSmi() ? Smi::cast(year())->value() : -1, 683 month()->IsSmi() ? Smi::cast(month())->value() : -1, 684 day()->IsSmi() ? Smi::cast(day())->value() : -1, 685 hour()->IsSmi() ? Smi::cast(hour())->value() : -1, 686 min()->IsSmi() ? Smi::cast(min())->value() : -1, 687 sec()->IsSmi() ? Smi::cast(sec())->value() : -1); 688 } 689 } 690 691 692 void JSProxy::JSProxyPrint(FILE* out) { 693 HeapObject::PrintHeader(out, "JSProxy"); 694 PrintF(out, " - map = 0x%p\n", reinterpret_cast<void*>(map())); 695 PrintF(out, " - handler = "); 696 handler()->Print(out); 697 PrintF(out, " - hash = "); 698 hash()->Print(out); 699 PrintF(out, "\n"); 700 } 701 702 703 void JSFunctionProxy::JSFunctionProxyPrint(FILE* out) { 704 HeapObject::PrintHeader(out, "JSFunctionProxy"); 705 PrintF(out, " - map = 0x%p\n", reinterpret_cast<void*>(map())); 706 PrintF(out, " - handler = "); 707 handler()->Print(out); 708 PrintF(out, " - call_trap = "); 709 call_trap()->Print(out); 710 PrintF(out, " - construct_trap = "); 711 construct_trap()->Print(out); 712 PrintF(out, "\n"); 713 } 714 715 716 void JSWeakMap::JSWeakMapPrint(FILE* out) { 717 HeapObject::PrintHeader(out, "JSWeakMap"); 718 PrintF(out, " - map = 0x%p\n", reinterpret_cast<void*>(map())); 719 PrintF(out, " - table = "); 720 table()->ShortPrint(out); 721 PrintF(out, "\n"); 722 } 723 724 725 void JSFunction::JSFunctionPrint(FILE* out) { 726 HeapObject::PrintHeader(out, "Function"); 727 PrintF(out, " - map = 0x%p\n", reinterpret_cast<void*>(map())); 728 PrintF(out, " - initial_map = "); 729 if (has_initial_map()) { 730 initial_map()->ShortPrint(out); 731 } 732 PrintF(out, "\n - shared_info = "); 733 shared()->ShortPrint(out); 734 PrintF(out, "\n - name = "); 735 shared()->name()->Print(out); 736 PrintF(out, "\n - context = "); 737 unchecked_context()->ShortPrint(out); 738 PrintF(out, "\n - code = "); 739 code()->ShortPrint(out); 740 PrintF(out, "\n"); 741 742 PrintProperties(out); 743 PrintElements(out); 744 745 PrintF(out, "\n"); 746 } 747 748 749 void SharedFunctionInfo::SharedFunctionInfoPrint(FILE* out) { 750 HeapObject::PrintHeader(out, "SharedFunctionInfo"); 751 PrintF(out, " - name: "); 752 name()->ShortPrint(out); 753 PrintF(out, "\n - expected_nof_properties: %d", expected_nof_properties()); 754 PrintF(out, "\n - instance class name = "); 755 instance_class_name()->Print(out); 756 PrintF(out, "\n - code = "); 757 code()->ShortPrint(out); 758 PrintF(out, "\n - source code = "); 759 GetSourceCode()->ShortPrint(out); 760 // Script files are often large, hard to read. 761 // PrintF(out, "\n - script ="); 762 // script()->Print(out); 763 PrintF(out, "\n - function token position = %d", function_token_position()); 764 PrintF(out, "\n - start position = %d", start_position()); 765 PrintF(out, "\n - end position = %d", end_position()); 766 PrintF(out, "\n - is expression = %d", is_expression()); 767 PrintF(out, "\n - debug info = "); 768 debug_info()->ShortPrint(out); 769 PrintF(out, "\n - length = %d", length()); 770 PrintF(out, "\n - has_only_simple_this_property_assignments = %d", 771 has_only_simple_this_property_assignments()); 772 PrintF(out, "\n - this_property_assignments = "); 773 this_property_assignments()->ShortPrint(out); 774 PrintF(out, "\n"); 775 } 776 777 778 void JSGlobalProxy::JSGlobalProxyPrint(FILE* out) { 779 PrintF(out, "global_proxy"); 780 JSObjectPrint(out); 781 PrintF(out, "context : "); 782 context()->ShortPrint(out); 783 PrintF(out, "\n"); 784 } 785 786 787 void JSGlobalObject::JSGlobalObjectPrint(FILE* out) { 788 PrintF(out, "global "); 789 JSObjectPrint(out); 790 PrintF(out, "global context : "); 791 global_context()->ShortPrint(out); 792 PrintF(out, "\n"); 793 } 794 795 796 void JSBuiltinsObject::JSBuiltinsObjectPrint(FILE* out) { 797 PrintF(out, "builtins "); 798 JSObjectPrint(out); 799 } 800 801 802 void JSGlobalPropertyCell::JSGlobalPropertyCellPrint(FILE* out) { 803 HeapObject::PrintHeader(out, "JSGlobalPropertyCell"); 804 } 805 806 807 void Code::CodePrint(FILE* out) { 808 HeapObject::PrintHeader(out, "Code"); 809 #ifdef ENABLE_DISASSEMBLER 810 if (FLAG_use_verbose_printer) { 811 Disassemble(NULL, out); 812 } 813 #endif 814 } 815 816 817 void Foreign::ForeignPrint(FILE* out) { 818 PrintF(out, "foreign address : %p", foreign_address()); 819 } 820 821 822 void AccessorInfo::AccessorInfoPrint(FILE* out) { 823 HeapObject::PrintHeader(out, "AccessorInfo"); 824 PrintF(out, "\n - getter: "); 825 getter()->ShortPrint(out); 826 PrintF(out, "\n - setter: "); 827 setter()->ShortPrint(out); 828 PrintF(out, "\n - name: "); 829 name()->ShortPrint(out); 830 PrintF(out, "\n - data: "); 831 data()->ShortPrint(out); 832 PrintF(out, "\n - flag: "); 833 flag()->ShortPrint(out); 834 } 835 836 837 void AccessorPair::AccessorPairPrint(FILE* out) { 838 HeapObject::PrintHeader(out, "AccessorPair"); 839 PrintF(out, "\n - getter: "); 840 getter()->ShortPrint(out); 841 PrintF(out, "\n - setter: "); 842 setter()->ShortPrint(out); 843 } 844 845 846 void AccessCheckInfo::AccessCheckInfoPrint(FILE* out) { 847 HeapObject::PrintHeader(out, "AccessCheckInfo"); 848 PrintF(out, "\n - named_callback: "); 849 named_callback()->ShortPrint(out); 850 PrintF(out, "\n - indexed_callback: "); 851 indexed_callback()->ShortPrint(out); 852 PrintF(out, "\n - data: "); 853 data()->ShortPrint(out); 854 } 855 856 857 void InterceptorInfo::InterceptorInfoPrint(FILE* out) { 858 HeapObject::PrintHeader(out, "InterceptorInfo"); 859 PrintF(out, "\n - getter: "); 860 getter()->ShortPrint(out); 861 PrintF(out, "\n - setter: "); 862 setter()->ShortPrint(out); 863 PrintF(out, "\n - query: "); 864 query()->ShortPrint(out); 865 PrintF(out, "\n - deleter: "); 866 deleter()->ShortPrint(out); 867 PrintF(out, "\n - enumerator: "); 868 enumerator()->ShortPrint(out); 869 PrintF(out, "\n - data: "); 870 data()->ShortPrint(out); 871 } 872 873 874 void CallHandlerInfo::CallHandlerInfoPrint(FILE* out) { 875 HeapObject::PrintHeader(out, "CallHandlerInfo"); 876 PrintF(out, "\n - callback: "); 877 callback()->ShortPrint(out); 878 PrintF(out, "\n - data: "); 879 data()->ShortPrint(out); 880 PrintF(out, "\n - call_stub_cache: "); 881 } 882 883 884 void FunctionTemplateInfo::FunctionTemplateInfoPrint(FILE* out) { 885 HeapObject::PrintHeader(out, "FunctionTemplateInfo"); 886 PrintF(out, "\n - class name: "); 887 class_name()->ShortPrint(out); 888 PrintF(out, "\n - tag: "); 889 tag()->ShortPrint(out); 890 PrintF(out, "\n - property_list: "); 891 property_list()->ShortPrint(out); 892 PrintF(out, "\n - serial_number: "); 893 serial_number()->ShortPrint(out); 894 PrintF(out, "\n - call_code: "); 895 call_code()->ShortPrint(out); 896 PrintF(out, "\n - property_accessors: "); 897 property_accessors()->ShortPrint(out); 898 PrintF(out, "\n - prototype_template: "); 899 prototype_template()->ShortPrint(out); 900 PrintF(out, "\n - parent_template: "); 901 parent_template()->ShortPrint(out); 902 PrintF(out, "\n - named_property_handler: "); 903 named_property_handler()->ShortPrint(out); 904 PrintF(out, "\n - indexed_property_handler: "); 905 indexed_property_handler()->ShortPrint(out); 906 PrintF(out, "\n - instance_template: "); 907 instance_template()->ShortPrint(out); 908 PrintF(out, "\n - signature: "); 909 signature()->ShortPrint(out); 910 PrintF(out, "\n - access_check_info: "); 911 access_check_info()->ShortPrint(out); 912 PrintF(out, "\n - hidden_prototype: %s", 913 hidden_prototype() ? "true" : "false"); 914 PrintF(out, "\n - undetectable: %s", undetectable() ? "true" : "false"); 915 PrintF(out, "\n - need_access_check: %s", 916 needs_access_check() ? "true" : "false"); 917 } 918 919 920 void ObjectTemplateInfo::ObjectTemplateInfoPrint(FILE* out) { 921 HeapObject::PrintHeader(out, "ObjectTemplateInfo"); 922 PrintF(out, " - tag: "); 923 tag()->ShortPrint(out); 924 PrintF(out, "\n - property_list: "); 925 property_list()->ShortPrint(out); 926 PrintF(out, "\n - constructor: "); 927 constructor()->ShortPrint(out); 928 PrintF(out, "\n - internal_field_count: "); 929 internal_field_count()->ShortPrint(out); 930 PrintF(out, "\n"); 931 } 932 933 934 void SignatureInfo::SignatureInfoPrint(FILE* out) { 935 HeapObject::PrintHeader(out, "SignatureInfo"); 936 PrintF(out, "\n - receiver: "); 937 receiver()->ShortPrint(out); 938 PrintF(out, "\n - args: "); 939 args()->ShortPrint(out); 940 } 941 942 943 void TypeSwitchInfo::TypeSwitchInfoPrint(FILE* out) { 944 HeapObject::PrintHeader(out, "TypeSwitchInfo"); 945 PrintF(out, "\n - types: "); 946 types()->ShortPrint(out); 947 } 948 949 950 void Script::ScriptPrint(FILE* out) { 951 HeapObject::PrintHeader(out, "Script"); 952 PrintF(out, "\n - source: "); 953 source()->ShortPrint(out); 954 PrintF(out, "\n - name: "); 955 name()->ShortPrint(out); 956 PrintF(out, "\n - line_offset: "); 957 line_offset()->ShortPrint(out); 958 PrintF(out, "\n - column_offset: "); 959 column_offset()->ShortPrint(out); 960 PrintF(out, "\n - type: "); 961 type()->ShortPrint(out); 962 PrintF(out, "\n - id: "); 963 id()->ShortPrint(out); 964 PrintF(out, "\n - data: "); 965 data()->ShortPrint(out); 966 PrintF(out, "\n - context data: "); 967 context_data()->ShortPrint(out); 968 PrintF(out, "\n - wrapper: "); 969 wrapper()->ShortPrint(out); 970 PrintF(out, "\n - compilation type: "); 971 compilation_type()->ShortPrint(out); 972 PrintF(out, "\n - line ends: "); 973 line_ends()->ShortPrint(out); 974 PrintF(out, "\n - eval from shared: "); 975 eval_from_shared()->ShortPrint(out); 976 PrintF(out, "\n - eval from instructions offset: "); 977 eval_from_instructions_offset()->ShortPrint(out); 978 PrintF(out, "\n"); 979 } 980 981 982 #ifdef ENABLE_DEBUGGER_SUPPORT 983 void DebugInfo::DebugInfoPrint(FILE* out) { 984 HeapObject::PrintHeader(out, "DebugInfo"); 985 PrintF(out, "\n - shared: "); 986 shared()->ShortPrint(out); 987 PrintF(out, "\n - original_code: "); 988 original_code()->ShortPrint(out); 989 PrintF(out, "\n - code: "); 990 code()->ShortPrint(out); 991 PrintF(out, "\n - break_points: "); 992 break_points()->Print(out); 993 } 994 995 996 void BreakPointInfo::BreakPointInfoPrint(FILE* out) { 997 HeapObject::PrintHeader(out, "BreakPointInfo"); 998 PrintF(out, "\n - code_position: %d", code_position()->value()); 999 PrintF(out, "\n - source_position: %d", source_position()->value()); 1000 PrintF(out, "\n - statement_position: %d", statement_position()->value()); 1001 PrintF(out, "\n - break_point_objects: "); 1002 break_point_objects()->ShortPrint(out); 1003 } 1004 #endif // ENABLE_DEBUGGER_SUPPORT 1005 1006 1007 void DescriptorArray::PrintDescriptors(FILE* out) { 1008 PrintF(out, "Descriptor array %d\n", number_of_descriptors()); 1009 for (int i = 0; i < number_of_descriptors(); i++) { 1010 PrintF(out, " %d: ", i); 1011 Descriptor desc; 1012 Get(i, &desc); 1013 desc.Print(out); 1014 } 1015 PrintF(out, "\n"); 1016 } 1017 1018 1019 #endif // OBJECT_PRINT 1020 1021 1022 } } // namespace v8::internal 1023