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 void MaybeObject::Print() { 41 Print(stdout); 42 } 43 44 45 void MaybeObject::Print(FILE* out) { 46 Object* this_as_object; 47 if (ToObject(&this_as_object)) { 48 if (this_as_object->IsSmi()) { 49 Smi::cast(this_as_object)->SmiPrint(out); 50 } else { 51 HeapObject::cast(this_as_object)->HeapObjectPrint(out); 52 } 53 } else { 54 Failure::cast(this)->FailurePrint(out); 55 } 56 Flush(out); 57 } 58 59 60 void MaybeObject::PrintLn() { 61 PrintLn(stdout); 62 } 63 64 65 void MaybeObject::PrintLn(FILE* out) { 66 Print(out); 67 PrintF(out, "\n"); 68 } 69 70 71 void HeapObject::PrintHeader(FILE* out, const char* id) { 72 PrintF(out, "%p: [%s]\n", reinterpret_cast<void*>(this), id); 73 } 74 75 76 void HeapObject::HeapObjectPrint(FILE* out) { 77 InstanceType instance_type = map()->instance_type(); 78 79 HandleScope scope(GetIsolate()); 80 if (instance_type < FIRST_NONSTRING_TYPE) { 81 String::cast(this)->StringPrint(out); 82 return; 83 } 84 85 switch (instance_type) { 86 case SYMBOL_TYPE: 87 Symbol::cast(this)->SymbolPrint(out); 88 break; 89 case MAP_TYPE: 90 Map::cast(this)->MapPrint(out); 91 break; 92 case HEAP_NUMBER_TYPE: 93 HeapNumber::cast(this)->HeapNumberPrint(out); 94 break; 95 case FIXED_DOUBLE_ARRAY_TYPE: 96 FixedDoubleArray::cast(this)->FixedDoubleArrayPrint(out); 97 break; 98 case FIXED_ARRAY_TYPE: 99 FixedArray::cast(this)->FixedArrayPrint(out); 100 break; 101 case BYTE_ARRAY_TYPE: 102 ByteArray::cast(this)->ByteArrayPrint(out); 103 break; 104 case FREE_SPACE_TYPE: 105 FreeSpace::cast(this)->FreeSpacePrint(out); 106 break; 107 case EXTERNAL_PIXEL_ARRAY_TYPE: 108 ExternalPixelArray::cast(this)->ExternalPixelArrayPrint(out); 109 break; 110 case EXTERNAL_BYTE_ARRAY_TYPE: 111 ExternalByteArray::cast(this)->ExternalByteArrayPrint(out); 112 break; 113 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: 114 ExternalUnsignedByteArray::cast(this) 115 ->ExternalUnsignedByteArrayPrint(out); 116 break; 117 case EXTERNAL_SHORT_ARRAY_TYPE: 118 ExternalShortArray::cast(this)->ExternalShortArrayPrint(out); 119 break; 120 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE: 121 ExternalUnsignedShortArray::cast(this) 122 ->ExternalUnsignedShortArrayPrint(out); 123 break; 124 case EXTERNAL_INT_ARRAY_TYPE: 125 ExternalIntArray::cast(this)->ExternalIntArrayPrint(out); 126 break; 127 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE: 128 ExternalUnsignedIntArray::cast(this)->ExternalUnsignedIntArrayPrint(out); 129 break; 130 case EXTERNAL_FLOAT_ARRAY_TYPE: 131 ExternalFloatArray::cast(this)->ExternalFloatArrayPrint(out); 132 break; 133 case EXTERNAL_DOUBLE_ARRAY_TYPE: 134 ExternalDoubleArray::cast(this)->ExternalDoubleArrayPrint(out); 135 break; 136 case FILLER_TYPE: 137 PrintF(out, "filler"); 138 break; 139 case JS_OBJECT_TYPE: // fall through 140 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: 141 case JS_ARRAY_TYPE: 142 case JS_GENERATOR_OBJECT_TYPE: 143 case JS_REGEXP_TYPE: 144 JSObject::cast(this)->JSObjectPrint(out); 145 break; 146 case ODDBALL_TYPE: 147 Oddball::cast(this)->to_string()->Print(out); 148 break; 149 case JS_MODULE_TYPE: 150 JSModule::cast(this)->JSModulePrint(out); 151 break; 152 case JS_FUNCTION_TYPE: 153 JSFunction::cast(this)->JSFunctionPrint(out); 154 break; 155 case JS_GLOBAL_PROXY_TYPE: 156 JSGlobalProxy::cast(this)->JSGlobalProxyPrint(out); 157 break; 158 case JS_GLOBAL_OBJECT_TYPE: 159 JSGlobalObject::cast(this)->JSGlobalObjectPrint(out); 160 break; 161 case JS_BUILTINS_OBJECT_TYPE: 162 JSBuiltinsObject::cast(this)->JSBuiltinsObjectPrint(out); 163 break; 164 case JS_VALUE_TYPE: 165 PrintF(out, "Value wrapper around:"); 166 JSValue::cast(this)->value()->Print(out); 167 break; 168 case JS_DATE_TYPE: 169 JSDate::cast(this)->JSDatePrint(out); 170 break; 171 case CODE_TYPE: 172 Code::cast(this)->CodePrint(out); 173 break; 174 case JS_PROXY_TYPE: 175 JSProxy::cast(this)->JSProxyPrint(out); 176 break; 177 case JS_FUNCTION_PROXY_TYPE: 178 JSFunctionProxy::cast(this)->JSFunctionProxyPrint(out); 179 break; 180 case JS_SET_TYPE: 181 JSSet::cast(this)->JSSetPrint(out); 182 break; 183 case JS_MAP_TYPE: 184 JSMap::cast(this)->JSMapPrint(out); 185 break; 186 case JS_WEAK_MAP_TYPE: 187 JSWeakMap::cast(this)->JSWeakMapPrint(out); 188 break; 189 case JS_WEAK_SET_TYPE: 190 JSWeakSet::cast(this)->JSWeakSetPrint(out); 191 break; 192 case FOREIGN_TYPE: 193 Foreign::cast(this)->ForeignPrint(out); 194 break; 195 case SHARED_FUNCTION_INFO_TYPE: 196 SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint(out); 197 break; 198 case JS_MESSAGE_OBJECT_TYPE: 199 JSMessageObject::cast(this)->JSMessageObjectPrint(out); 200 break; 201 case CELL_TYPE: 202 Cell::cast(this)->CellPrint(out); 203 break; 204 case PROPERTY_CELL_TYPE: 205 PropertyCell::cast(this)->PropertyCellPrint(out); 206 break; 207 case JS_ARRAY_BUFFER_TYPE: 208 JSArrayBuffer::cast(this)->JSArrayBufferPrint(out); 209 break; 210 case JS_TYPED_ARRAY_TYPE: 211 JSTypedArray::cast(this)->JSTypedArrayPrint(out); 212 break; 213 case JS_DATA_VIEW_TYPE: 214 JSDataView::cast(this)->JSDataViewPrint(out); 215 break; 216 #define MAKE_STRUCT_CASE(NAME, Name, name) \ 217 case NAME##_TYPE: \ 218 Name::cast(this)->Name##Print(out); \ 219 break; 220 STRUCT_LIST(MAKE_STRUCT_CASE) 221 #undef MAKE_STRUCT_CASE 222 223 default: 224 PrintF(out, "UNKNOWN TYPE %d", map()->instance_type()); 225 UNREACHABLE(); 226 break; 227 } 228 } 229 230 231 void ByteArray::ByteArrayPrint(FILE* out) { 232 PrintF(out, "byte array, data starts at %p", GetDataStartAddress()); 233 } 234 235 236 void FreeSpace::FreeSpacePrint(FILE* out) { 237 PrintF(out, "free space, size %d", Size()); 238 } 239 240 241 void ExternalPixelArray::ExternalPixelArrayPrint(FILE* out) { 242 PrintF(out, "external pixel array"); 243 } 244 245 246 void ExternalByteArray::ExternalByteArrayPrint(FILE* out) { 247 PrintF(out, "external byte array"); 248 } 249 250 251 void ExternalUnsignedByteArray::ExternalUnsignedByteArrayPrint(FILE* out) { 252 PrintF(out, "external unsigned byte array"); 253 } 254 255 256 void ExternalShortArray::ExternalShortArrayPrint(FILE* out) { 257 PrintF(out, "external short array"); 258 } 259 260 261 void ExternalUnsignedShortArray::ExternalUnsignedShortArrayPrint(FILE* out) { 262 PrintF(out, "external unsigned short array"); 263 } 264 265 266 void ExternalIntArray::ExternalIntArrayPrint(FILE* out) { 267 PrintF(out, "external int array"); 268 } 269 270 271 void ExternalUnsignedIntArray::ExternalUnsignedIntArrayPrint(FILE* out) { 272 PrintF(out, "external unsigned int array"); 273 } 274 275 276 void ExternalFloatArray::ExternalFloatArrayPrint(FILE* out) { 277 PrintF(out, "external float array"); 278 } 279 280 281 void ExternalDoubleArray::ExternalDoubleArrayPrint(FILE* out) { 282 PrintF(out, "external double array"); 283 } 284 285 286 void JSObject::PrintProperties(FILE* out) { 287 if (HasFastProperties()) { 288 DescriptorArray* descs = map()->instance_descriptors(); 289 for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) { 290 PrintF(out, " "); 291 descs->GetKey(i)->NamePrint(out); 292 PrintF(out, ": "); 293 switch (descs->GetType(i)) { 294 case FIELD: { 295 int index = descs->GetFieldIndex(i); 296 RawFastPropertyAt(index)->ShortPrint(out); 297 PrintF(out, " (field at offset %d)\n", index); 298 break; 299 } 300 case CONSTANT: 301 descs->GetConstant(i)->ShortPrint(out); 302 PrintF(out, " (constant)\n"); 303 break; 304 case CALLBACKS: 305 descs->GetCallbacksObject(i)->ShortPrint(out); 306 PrintF(out, " (callback)\n"); 307 break; 308 case NORMAL: // only in slow mode 309 case HANDLER: // only in lookup results, not in descriptors 310 case INTERCEPTOR: // only in lookup results, not in descriptors 311 // There are no transitions in the descriptor array. 312 case TRANSITION: 313 case NONEXISTENT: 314 UNREACHABLE(); 315 break; 316 } 317 } 318 } else { 319 property_dictionary()->Print(out); 320 } 321 } 322 323 324 void JSObject::PrintElements(FILE* out) { 325 // Don't call GetElementsKind, its validation code can cause the printer to 326 // fail when debugging. 327 switch (map()->elements_kind()) { 328 case FAST_HOLEY_SMI_ELEMENTS: 329 case FAST_SMI_ELEMENTS: 330 case FAST_HOLEY_ELEMENTS: 331 case FAST_ELEMENTS: { 332 // Print in array notation for non-sparse arrays. 333 FixedArray* p = FixedArray::cast(elements()); 334 for (int i = 0; i < p->length(); i++) { 335 PrintF(out, " %d: ", i); 336 p->get(i)->ShortPrint(out); 337 PrintF(out, "\n"); 338 } 339 break; 340 } 341 case FAST_HOLEY_DOUBLE_ELEMENTS: 342 case FAST_DOUBLE_ELEMENTS: { 343 // Print in array notation for non-sparse arrays. 344 if (elements()->length() > 0) { 345 FixedDoubleArray* p = FixedDoubleArray::cast(elements()); 346 for (int i = 0; i < p->length(); i++) { 347 if (p->is_the_hole(i)) { 348 PrintF(out, " %d: <the hole>", i); 349 } else { 350 PrintF(out, " %d: %g", i, p->get_scalar(i)); 351 } 352 PrintF(out, "\n"); 353 } 354 } 355 break; 356 } 357 case EXTERNAL_PIXEL_ELEMENTS: { 358 ExternalPixelArray* p = ExternalPixelArray::cast(elements()); 359 for (int i = 0; i < p->length(); i++) { 360 PrintF(out, " %d: %d\n", i, p->get_scalar(i)); 361 } 362 break; 363 } 364 case EXTERNAL_BYTE_ELEMENTS: { 365 ExternalByteArray* p = ExternalByteArray::cast(elements()); 366 for (int i = 0; i < p->length(); i++) { 367 PrintF(out, " %d: %d\n", i, static_cast<int>(p->get_scalar(i))); 368 } 369 break; 370 } 371 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { 372 ExternalUnsignedByteArray* p = 373 ExternalUnsignedByteArray::cast(elements()); 374 for (int i = 0; i < p->length(); i++) { 375 PrintF(out, " %d: %d\n", i, static_cast<int>(p->get_scalar(i))); 376 } 377 break; 378 } 379 case EXTERNAL_SHORT_ELEMENTS: { 380 ExternalShortArray* p = ExternalShortArray::cast(elements()); 381 for (int i = 0; i < p->length(); i++) { 382 PrintF(out, " %d: %d\n", i, static_cast<int>(p->get_scalar(i))); 383 } 384 break; 385 } 386 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: { 387 ExternalUnsignedShortArray* p = 388 ExternalUnsignedShortArray::cast(elements()); 389 for (int i = 0; i < p->length(); i++) { 390 PrintF(out, " %d: %d\n", i, static_cast<int>(p->get_scalar(i))); 391 } 392 break; 393 } 394 case EXTERNAL_INT_ELEMENTS: { 395 ExternalIntArray* p = ExternalIntArray::cast(elements()); 396 for (int i = 0; i < p->length(); i++) { 397 PrintF(out, " %d: %d\n", i, static_cast<int>(p->get_scalar(i))); 398 } 399 break; 400 } 401 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { 402 ExternalUnsignedIntArray* p = 403 ExternalUnsignedIntArray::cast(elements()); 404 for (int i = 0; i < p->length(); i++) { 405 PrintF(out, " %d: %d\n", i, static_cast<int>(p->get_scalar(i))); 406 } 407 break; 408 } 409 case EXTERNAL_FLOAT_ELEMENTS: { 410 ExternalFloatArray* p = ExternalFloatArray::cast(elements()); 411 for (int i = 0; i < p->length(); i++) { 412 PrintF(out, " %d: %f\n", i, p->get_scalar(i)); 413 } 414 break; 415 } 416 case EXTERNAL_DOUBLE_ELEMENTS: { 417 ExternalDoubleArray* p = ExternalDoubleArray::cast(elements()); 418 for (int i = 0; i < p->length(); i++) { 419 PrintF(out, " %d: %f\n", i, p->get_scalar(i)); 420 } 421 break; 422 } 423 case DICTIONARY_ELEMENTS: 424 elements()->Print(out); 425 break; 426 case NON_STRICT_ARGUMENTS_ELEMENTS: { 427 FixedArray* p = FixedArray::cast(elements()); 428 PrintF(out, " parameter map:"); 429 for (int i = 2; i < p->length(); i++) { 430 PrintF(out, " %d:", i - 2); 431 p->get(i)->ShortPrint(out); 432 } 433 PrintF(out, "\n context: "); 434 p->get(0)->ShortPrint(out); 435 PrintF(out, "\n arguments: "); 436 p->get(1)->ShortPrint(out); 437 PrintF(out, "\n"); 438 break; 439 } 440 } 441 } 442 443 444 void JSObject::PrintTransitions(FILE* out) { 445 if (!map()->HasTransitionArray()) return; 446 TransitionArray* transitions = map()->transitions(); 447 for (int i = 0; i < transitions->number_of_transitions(); i++) { 448 PrintF(out, " "); 449 transitions->GetKey(i)->NamePrint(out); 450 PrintF(out, ": "); 451 switch (transitions->GetTargetDetails(i).type()) { 452 case FIELD: { 453 PrintF(out, " (transition to field)\n"); 454 break; 455 } 456 case CONSTANT: 457 PrintF(out, " (transition to constant)\n"); 458 break; 459 case CALLBACKS: 460 PrintF(out, " (transition to callback)\n"); 461 break; 462 // Values below are never in the target descriptor array. 463 case NORMAL: 464 case HANDLER: 465 case INTERCEPTOR: 466 case TRANSITION: 467 case NONEXISTENT: 468 UNREACHABLE(); 469 break; 470 } 471 } 472 } 473 474 475 void JSObject::JSObjectPrint(FILE* out) { 476 PrintF(out, "%p: [JSObject]\n", reinterpret_cast<void*>(this)); 477 PrintF(out, " - map = %p [", reinterpret_cast<void*>(map())); 478 // Don't call GetElementsKind, its validation code can cause the printer to 479 // fail when debugging. 480 PrintElementsKind(out, this->map()->elements_kind()); 481 PrintF(out, 482 "]\n - prototype = %p\n", 483 reinterpret_cast<void*>(GetPrototype())); 484 PrintF(out, " {\n"); 485 PrintProperties(out); 486 PrintTransitions(out); 487 PrintElements(out); 488 PrintF(out, " }\n"); 489 } 490 491 492 void JSModule::JSModulePrint(FILE* out) { 493 HeapObject::PrintHeader(out, "JSModule"); 494 PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map())); 495 PrintF(out, " - context = "); 496 context()->Print(out); 497 PrintF(out, " - scope_info = "); 498 scope_info()->ShortPrint(out); 499 PrintElementsKind(out, this->map()->elements_kind()); 500 PrintF(out, " {\n"); 501 PrintProperties(out); 502 PrintElements(out); 503 PrintF(out, " }\n"); 504 } 505 506 507 static const char* TypeToString(InstanceType type) { 508 switch (type) { 509 #define TYPE_TO_STRING(TYPE) case TYPE: return #TYPE; 510 INSTANCE_TYPE_LIST(TYPE_TO_STRING) 511 #undef TYPE_TO_STRING 512 } 513 UNREACHABLE(); 514 return "UNKNOWN"; // Keep the compiler happy. 515 } 516 517 518 void Symbol::SymbolPrint(FILE* out) { 519 HeapObject::PrintHeader(out, "Symbol"); 520 PrintF(out, " - hash: %d\n", Hash()); 521 PrintF(out, " - name: "); 522 name()->ShortPrint(); 523 PrintF(out, "\n"); 524 } 525 526 527 void Map::MapPrint(FILE* out) { 528 HeapObject::PrintHeader(out, "Map"); 529 PrintF(out, " - type: %s\n", TypeToString(instance_type())); 530 PrintF(out, " - instance size: %d\n", instance_size()); 531 PrintF(out, " - inobject properties: %d\n", inobject_properties()); 532 PrintF(out, " - elements kind: "); 533 PrintElementsKind(out, elements_kind()); 534 PrintF(out, "\n - pre-allocated property fields: %d\n", 535 pre_allocated_property_fields()); 536 PrintF(out, " - unused property fields: %d\n", unused_property_fields()); 537 if (is_hidden_prototype()) { 538 PrintF(out, " - hidden_prototype\n"); 539 } 540 if (has_named_interceptor()) { 541 PrintF(out, " - named_interceptor\n"); 542 } 543 if (has_indexed_interceptor()) { 544 PrintF(out, " - indexed_interceptor\n"); 545 } 546 if (is_undetectable()) { 547 PrintF(out, " - undetectable\n"); 548 } 549 if (has_instance_call_handler()) { 550 PrintF(out, " - instance_call_handler\n"); 551 } 552 if (is_access_check_needed()) { 553 PrintF(out, " - access_check_needed\n"); 554 } 555 PrintF(out, " - back pointer: "); 556 GetBackPointer()->ShortPrint(out); 557 PrintF(out, "\n - instance descriptors %s#%i: ", 558 owns_descriptors() ? "(own) " : "", 559 NumberOfOwnDescriptors()); 560 instance_descriptors()->ShortPrint(out); 561 if (HasTransitionArray()) { 562 PrintF(out, "\n - transitions: "); 563 transitions()->ShortPrint(out); 564 } 565 PrintF(out, "\n - prototype: "); 566 prototype()->ShortPrint(out); 567 PrintF(out, "\n - constructor: "); 568 constructor()->ShortPrint(out); 569 PrintF(out, "\n - code cache: "); 570 code_cache()->ShortPrint(out); 571 PrintF(out, "\n - dependent code: "); 572 dependent_code()->ShortPrint(out); 573 PrintF(out, "\n"); 574 } 575 576 577 void CodeCache::CodeCachePrint(FILE* out) { 578 HeapObject::PrintHeader(out, "CodeCache"); 579 PrintF(out, "\n - default_cache: "); 580 default_cache()->ShortPrint(out); 581 PrintF(out, "\n - normal_type_cache: "); 582 normal_type_cache()->ShortPrint(out); 583 } 584 585 586 void PolymorphicCodeCache::PolymorphicCodeCachePrint(FILE* out) { 587 HeapObject::PrintHeader(out, "PolymorphicCodeCache"); 588 PrintF(out, "\n - cache: "); 589 cache()->ShortPrint(out); 590 } 591 592 593 void TypeFeedbackInfo::TypeFeedbackInfoPrint(FILE* out) { 594 HeapObject::PrintHeader(out, "TypeFeedbackInfo"); 595 PrintF(out, " - ic_total_count: %d, ic_with_type_info_count: %d\n", 596 ic_total_count(), ic_with_type_info_count()); 597 PrintF(out, " - type_feedback_cells: "); 598 type_feedback_cells()->FixedArrayPrint(out); 599 } 600 601 602 void AliasedArgumentsEntry::AliasedArgumentsEntryPrint(FILE* out) { 603 HeapObject::PrintHeader(out, "AliasedArgumentsEntry"); 604 PrintF(out, "\n - aliased_context_slot: %d", aliased_context_slot()); 605 } 606 607 608 void FixedArray::FixedArrayPrint(FILE* out) { 609 HeapObject::PrintHeader(out, "FixedArray"); 610 PrintF(out, " - length: %d", length()); 611 for (int i = 0; i < length(); i++) { 612 PrintF(out, "\n [%d]: ", i); 613 get(i)->ShortPrint(out); 614 } 615 PrintF(out, "\n"); 616 } 617 618 619 void FixedDoubleArray::FixedDoubleArrayPrint(FILE* out) { 620 HeapObject::PrintHeader(out, "FixedDoubleArray"); 621 PrintF(out, " - length: %d", length()); 622 for (int i = 0; i < length(); i++) { 623 if (is_the_hole(i)) { 624 PrintF(out, "\n [%d]: <the hole>", i); 625 } else { 626 PrintF(out, "\n [%d]: %g", i, get_scalar(i)); 627 } 628 } 629 PrintF(out, "\n"); 630 } 631 632 633 void JSValue::JSValuePrint(FILE* out) { 634 HeapObject::PrintHeader(out, "ValueObject"); 635 value()->Print(out); 636 } 637 638 639 void JSMessageObject::JSMessageObjectPrint(FILE* out) { 640 HeapObject::PrintHeader(out, "JSMessageObject"); 641 PrintF(out, " - type: "); 642 type()->ShortPrint(out); 643 PrintF(out, "\n - arguments: "); 644 arguments()->ShortPrint(out); 645 PrintF(out, "\n - start_position: %d", start_position()); 646 PrintF(out, "\n - end_position: %d", end_position()); 647 PrintF(out, "\n - script: "); 648 script()->ShortPrint(out); 649 PrintF(out, "\n - stack_trace: "); 650 stack_trace()->ShortPrint(out); 651 PrintF(out, "\n - stack_frames: "); 652 stack_frames()->ShortPrint(out); 653 PrintF(out, "\n"); 654 } 655 656 657 void String::StringPrint(FILE* out) { 658 if (StringShape(this).IsInternalized()) { 659 PrintF(out, "#"); 660 } else if (StringShape(this).IsCons()) { 661 PrintF(out, "c\""); 662 } else { 663 PrintF(out, "\""); 664 } 665 666 const char truncated_epilogue[] = "...<truncated>"; 667 int len = length(); 668 if (!FLAG_use_verbose_printer) { 669 if (len > 100) { 670 len = 100 - sizeof(truncated_epilogue); 671 } 672 } 673 for (int i = 0; i < len; i++) { 674 PrintF(out, "%c", Get(i)); 675 } 676 if (len != length()) { 677 PrintF(out, "%s", truncated_epilogue); 678 } 679 680 if (!StringShape(this).IsInternalized()) PrintF(out, "\""); 681 } 682 683 684 void Name::NamePrint(FILE* out) { 685 if (IsString()) 686 String::cast(this)->StringPrint(out); 687 else 688 ShortPrint(); 689 } 690 691 692 // This method is only meant to be called from gdb for debugging purposes. 693 // Since the string can also be in two-byte encoding, non-ASCII characters 694 // will be ignored in the output. 695 char* String::ToAsciiArray() { 696 // Static so that subsequent calls frees previously allocated space. 697 // This also means that previous results will be overwritten. 698 static char* buffer = NULL; 699 if (buffer != NULL) free(buffer); 700 buffer = new char[length()+1]; 701 WriteToFlat(this, reinterpret_cast<uint8_t*>(buffer), 0, length()); 702 buffer[length()] = 0; 703 return buffer; 704 } 705 706 707 static const char* const weekdays[] = { 708 "???", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 709 }; 710 711 712 void JSDate::JSDatePrint(FILE* out) { 713 HeapObject::PrintHeader(out, "JSDate"); 714 PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map())); 715 PrintF(out, " - value = "); 716 value()->Print(out); 717 if (!year()->IsSmi()) { 718 PrintF(out, " - time = NaN\n"); 719 } else { 720 PrintF(out, " - time = %s %04d/%02d/%02d %02d:%02d:%02d\n", 721 weekdays[weekday()->IsSmi() ? Smi::cast(weekday())->value() + 1 : 0], 722 year()->IsSmi() ? Smi::cast(year())->value() : -1, 723 month()->IsSmi() ? Smi::cast(month())->value() : -1, 724 day()->IsSmi() ? Smi::cast(day())->value() : -1, 725 hour()->IsSmi() ? Smi::cast(hour())->value() : -1, 726 min()->IsSmi() ? Smi::cast(min())->value() : -1, 727 sec()->IsSmi() ? Smi::cast(sec())->value() : -1); 728 } 729 } 730 731 732 void JSProxy::JSProxyPrint(FILE* out) { 733 HeapObject::PrintHeader(out, "JSProxy"); 734 PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map())); 735 PrintF(out, " - handler = "); 736 handler()->Print(out); 737 PrintF(out, " - hash = "); 738 hash()->Print(out); 739 PrintF(out, "\n"); 740 } 741 742 743 void JSFunctionProxy::JSFunctionProxyPrint(FILE* out) { 744 HeapObject::PrintHeader(out, "JSFunctionProxy"); 745 PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map())); 746 PrintF(out, " - handler = "); 747 handler()->Print(out); 748 PrintF(out, " - call_trap = "); 749 call_trap()->Print(out); 750 PrintF(out, " - construct_trap = "); 751 construct_trap()->Print(out); 752 PrintF(out, "\n"); 753 } 754 755 756 void JSSet::JSSetPrint(FILE* out) { 757 HeapObject::PrintHeader(out, "JSSet"); 758 PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map())); 759 PrintF(out, " - table = "); 760 table()->ShortPrint(out); 761 PrintF(out, "\n"); 762 } 763 764 765 void JSMap::JSMapPrint(FILE* out) { 766 HeapObject::PrintHeader(out, "JSMap"); 767 PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map())); 768 PrintF(out, " - table = "); 769 table()->ShortPrint(out); 770 PrintF(out, "\n"); 771 } 772 773 774 void JSWeakMap::JSWeakMapPrint(FILE* out) { 775 HeapObject::PrintHeader(out, "JSWeakMap"); 776 PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map())); 777 PrintF(out, " - table = "); 778 table()->ShortPrint(out); 779 PrintF(out, "\n"); 780 } 781 782 783 void JSWeakSet::JSWeakSetPrint(FILE* out) { 784 HeapObject::PrintHeader(out, "JSWeakSet"); 785 PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map())); 786 PrintF(out, " - table = "); 787 table()->ShortPrint(out); 788 PrintF(out, "\n"); 789 } 790 791 792 void JSArrayBuffer::JSArrayBufferPrint(FILE* out) { 793 HeapObject::PrintHeader(out, "JSArrayBuffer"); 794 PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map())); 795 PrintF(out, " - backing_store = %p\n", backing_store()); 796 PrintF(out, " - byte_length = "); 797 byte_length()->ShortPrint(out); 798 PrintF(out, "\n"); 799 } 800 801 802 void JSTypedArray::JSTypedArrayPrint(FILE* out) { 803 HeapObject::PrintHeader(out, "JSTypedArray"); 804 PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map())); 805 PrintF(out, " - buffer ="); 806 buffer()->ShortPrint(out); 807 PrintF(out, "\n - byte_offset = "); 808 byte_offset()->ShortPrint(out); 809 PrintF(out, "\n - byte_length = "); 810 byte_length()->ShortPrint(out); 811 PrintF(out, "\n - length = "); 812 length()->ShortPrint(out); 813 PrintF("\n"); 814 PrintElements(out); 815 } 816 817 818 void JSDataView::JSDataViewPrint(FILE* out) { 819 HeapObject::PrintHeader(out, "JSDataView"); 820 PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map())); 821 PrintF(out, " - buffer ="); 822 buffer()->ShortPrint(out); 823 PrintF(out, "\n - byte_offset = "); 824 byte_offset()->ShortPrint(out); 825 PrintF(out, "\n - byte_length = "); 826 byte_length()->ShortPrint(out); 827 PrintF("\n"); 828 } 829 830 831 void JSFunction::JSFunctionPrint(FILE* out) { 832 HeapObject::PrintHeader(out, "Function"); 833 PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map())); 834 PrintF(out, " - initial_map = "); 835 if (has_initial_map()) { 836 initial_map()->ShortPrint(out); 837 } 838 PrintF(out, "\n - shared_info = "); 839 shared()->ShortPrint(out); 840 PrintF(out, "\n - name = "); 841 shared()->name()->Print(out); 842 PrintF(out, "\n - context = "); 843 context()->ShortPrint(out); 844 PrintF(out, "\n - literals = "); 845 literals()->ShortPrint(out); 846 PrintF(out, "\n - code = "); 847 code()->ShortPrint(out); 848 PrintF(out, "\n"); 849 850 PrintProperties(out); 851 PrintElements(out); 852 853 PrintF(out, "\n"); 854 } 855 856 857 void SharedFunctionInfo::SharedFunctionInfoPrint(FILE* out) { 858 HeapObject::PrintHeader(out, "SharedFunctionInfo"); 859 PrintF(out, " - name: "); 860 name()->ShortPrint(out); 861 PrintF(out, "\n - expected_nof_properties: %d", expected_nof_properties()); 862 PrintF(out, "\n - instance class name = "); 863 instance_class_name()->Print(out); 864 PrintF(out, "\n - code = "); 865 code()->ShortPrint(out); 866 if (HasSourceCode()) { 867 PrintF(out, "\n - source code = "); 868 String* source = String::cast(Script::cast(script())->source()); 869 int start = start_position(); 870 int length = end_position() - start; 871 SmartArrayPointer<char> source_string = 872 source->ToCString(DISALLOW_NULLS, 873 FAST_STRING_TRAVERSAL, 874 start, length, NULL); 875 PrintF(out, "%s", *source_string); 876 } 877 // Script files are often large, hard to read. 878 // PrintF(out, "\n - script ="); 879 // script()->Print(out); 880 PrintF(out, "\n - function token position = %d", function_token_position()); 881 PrintF(out, "\n - start position = %d", start_position()); 882 PrintF(out, "\n - end position = %d", end_position()); 883 PrintF(out, "\n - is expression = %d", is_expression()); 884 PrintF(out, "\n - debug info = "); 885 debug_info()->ShortPrint(out); 886 PrintF(out, "\n - length = %d", length()); 887 PrintF(out, "\n - optimized_code_map = "); 888 optimized_code_map()->ShortPrint(out); 889 PrintF(out, "\n"); 890 } 891 892 893 void JSGlobalProxy::JSGlobalProxyPrint(FILE* out) { 894 PrintF(out, "global_proxy "); 895 JSObjectPrint(out); 896 PrintF(out, "native context : "); 897 native_context()->ShortPrint(out); 898 PrintF(out, "\n"); 899 } 900 901 902 void JSGlobalObject::JSGlobalObjectPrint(FILE* out) { 903 PrintF(out, "global "); 904 JSObjectPrint(out); 905 PrintF(out, "native context : "); 906 native_context()->ShortPrint(out); 907 PrintF(out, "\n"); 908 } 909 910 911 void JSBuiltinsObject::JSBuiltinsObjectPrint(FILE* out) { 912 PrintF(out, "builtins "); 913 JSObjectPrint(out); 914 } 915 916 917 void Cell::CellPrint(FILE* out) { 918 HeapObject::PrintHeader(out, "Cell"); 919 } 920 921 922 void PropertyCell::PropertyCellPrint(FILE* out) { 923 HeapObject::PrintHeader(out, "PropertyCell"); 924 } 925 926 927 void Code::CodePrint(FILE* out) { 928 HeapObject::PrintHeader(out, "Code"); 929 #ifdef ENABLE_DISASSEMBLER 930 if (FLAG_use_verbose_printer) { 931 Disassemble(NULL, out); 932 } 933 #endif 934 } 935 936 937 void Foreign::ForeignPrint(FILE* out) { 938 PrintF(out, "foreign address : %p", foreign_address()); 939 } 940 941 942 void ExecutableAccessorInfo::ExecutableAccessorInfoPrint(FILE* out) { 943 HeapObject::PrintHeader(out, "ExecutableAccessorInfo"); 944 PrintF(out, "\n - name: "); 945 name()->ShortPrint(out); 946 PrintF(out, "\n - flag: "); 947 flag()->ShortPrint(out); 948 PrintF(out, "\n - getter: "); 949 getter()->ShortPrint(out); 950 PrintF(out, "\n - setter: "); 951 setter()->ShortPrint(out); 952 PrintF(out, "\n - data: "); 953 data()->ShortPrint(out); 954 } 955 956 957 void DeclaredAccessorInfo::DeclaredAccessorInfoPrint(FILE* out) { 958 HeapObject::PrintHeader(out, "DeclaredAccessorInfo"); 959 PrintF(out, "\n - name: "); 960 name()->ShortPrint(out); 961 PrintF(out, "\n - flag: "); 962 flag()->ShortPrint(out); 963 PrintF(out, "\n - descriptor: "); 964 descriptor()->ShortPrint(out); 965 } 966 967 968 void DeclaredAccessorDescriptor::DeclaredAccessorDescriptorPrint(FILE* out) { 969 HeapObject::PrintHeader(out, "DeclaredAccessorDescriptor"); 970 PrintF(out, "\n - internal field: "); 971 serialized_data()->ShortPrint(out); 972 } 973 974 975 void Box::BoxPrint(FILE* out) { 976 HeapObject::PrintHeader(out, "Box"); 977 PrintF(out, "\n - value: "); 978 value()->ShortPrint(out); 979 } 980 981 982 void AccessorPair::AccessorPairPrint(FILE* out) { 983 HeapObject::PrintHeader(out, "AccessorPair"); 984 PrintF(out, "\n - getter: "); 985 getter()->ShortPrint(out); 986 PrintF(out, "\n - setter: "); 987 setter()->ShortPrint(out); 988 } 989 990 991 void AccessCheckInfo::AccessCheckInfoPrint(FILE* out) { 992 HeapObject::PrintHeader(out, "AccessCheckInfo"); 993 PrintF(out, "\n - named_callback: "); 994 named_callback()->ShortPrint(out); 995 PrintF(out, "\n - indexed_callback: "); 996 indexed_callback()->ShortPrint(out); 997 PrintF(out, "\n - data: "); 998 data()->ShortPrint(out); 999 } 1000 1001 1002 void InterceptorInfo::InterceptorInfoPrint(FILE* out) { 1003 HeapObject::PrintHeader(out, "InterceptorInfo"); 1004 PrintF(out, "\n - getter: "); 1005 getter()->ShortPrint(out); 1006 PrintF(out, "\n - setter: "); 1007 setter()->ShortPrint(out); 1008 PrintF(out, "\n - query: "); 1009 query()->ShortPrint(out); 1010 PrintF(out, "\n - deleter: "); 1011 deleter()->ShortPrint(out); 1012 PrintF(out, "\n - enumerator: "); 1013 enumerator()->ShortPrint(out); 1014 PrintF(out, "\n - data: "); 1015 data()->ShortPrint(out); 1016 } 1017 1018 1019 void CallHandlerInfo::CallHandlerInfoPrint(FILE* out) { 1020 HeapObject::PrintHeader(out, "CallHandlerInfo"); 1021 PrintF(out, "\n - callback: "); 1022 callback()->ShortPrint(out); 1023 PrintF(out, "\n - data: "); 1024 data()->ShortPrint(out); 1025 PrintF(out, "\n - call_stub_cache: "); 1026 } 1027 1028 1029 void FunctionTemplateInfo::FunctionTemplateInfoPrint(FILE* out) { 1030 HeapObject::PrintHeader(out, "FunctionTemplateInfo"); 1031 PrintF(out, "\n - class name: "); 1032 class_name()->ShortPrint(out); 1033 PrintF(out, "\n - tag: "); 1034 tag()->ShortPrint(out); 1035 PrintF(out, "\n - property_list: "); 1036 property_list()->ShortPrint(out); 1037 PrintF(out, "\n - serial_number: "); 1038 serial_number()->ShortPrint(out); 1039 PrintF(out, "\n - call_code: "); 1040 call_code()->ShortPrint(out); 1041 PrintF(out, "\n - property_accessors: "); 1042 property_accessors()->ShortPrint(out); 1043 PrintF(out, "\n - prototype_template: "); 1044 prototype_template()->ShortPrint(out); 1045 PrintF(out, "\n - parent_template: "); 1046 parent_template()->ShortPrint(out); 1047 PrintF(out, "\n - named_property_handler: "); 1048 named_property_handler()->ShortPrint(out); 1049 PrintF(out, "\n - indexed_property_handler: "); 1050 indexed_property_handler()->ShortPrint(out); 1051 PrintF(out, "\n - instance_template: "); 1052 instance_template()->ShortPrint(out); 1053 PrintF(out, "\n - signature: "); 1054 signature()->ShortPrint(out); 1055 PrintF(out, "\n - access_check_info: "); 1056 access_check_info()->ShortPrint(out); 1057 PrintF(out, "\n - hidden_prototype: %s", 1058 hidden_prototype() ? "true" : "false"); 1059 PrintF(out, "\n - undetectable: %s", undetectable() ? "true" : "false"); 1060 PrintF(out, "\n - need_access_check: %s", 1061 needs_access_check() ? "true" : "false"); 1062 } 1063 1064 1065 void ObjectTemplateInfo::ObjectTemplateInfoPrint(FILE* out) { 1066 HeapObject::PrintHeader(out, "ObjectTemplateInfo"); 1067 PrintF(out, " - tag: "); 1068 tag()->ShortPrint(out); 1069 PrintF(out, "\n - property_list: "); 1070 property_list()->ShortPrint(out); 1071 PrintF(out, "\n - constructor: "); 1072 constructor()->ShortPrint(out); 1073 PrintF(out, "\n - internal_field_count: "); 1074 internal_field_count()->ShortPrint(out); 1075 PrintF(out, "\n"); 1076 } 1077 1078 1079 void SignatureInfo::SignatureInfoPrint(FILE* out) { 1080 HeapObject::PrintHeader(out, "SignatureInfo"); 1081 PrintF(out, "\n - receiver: "); 1082 receiver()->ShortPrint(out); 1083 PrintF(out, "\n - args: "); 1084 args()->ShortPrint(out); 1085 } 1086 1087 1088 void TypeSwitchInfo::TypeSwitchInfoPrint(FILE* out) { 1089 HeapObject::PrintHeader(out, "TypeSwitchInfo"); 1090 PrintF(out, "\n - types: "); 1091 types()->ShortPrint(out); 1092 } 1093 1094 1095 void AllocationSite::AllocationSitePrint(FILE* out) { 1096 HeapObject::PrintHeader(out, "AllocationSite"); 1097 PrintF(out, " - weak_next: "); 1098 weak_next()->ShortPrint(out); 1099 PrintF(out, "\n"); 1100 1101 PrintF(out, " - transition_info: "); 1102 if (transition_info()->IsCell()) { 1103 Cell* cell = Cell::cast(transition_info()); 1104 Object* cell_contents = cell->value(); 1105 if (cell_contents->IsSmi()) { 1106 ElementsKind kind = static_cast<ElementsKind>( 1107 Smi::cast(cell_contents)->value()); 1108 PrintF(out, "Array allocation with ElementsKind "); 1109 PrintElementsKind(out, kind); 1110 PrintF(out, "\n"); 1111 return; 1112 } 1113 } else if (transition_info()->IsJSArray()) { 1114 PrintF(out, "Array literal "); 1115 transition_info()->ShortPrint(out); 1116 PrintF(out, "\n"); 1117 return; 1118 } 1119 1120 PrintF(out, "unknown transition_info"); 1121 transition_info()->ShortPrint(out); 1122 PrintF(out, "\n"); 1123 } 1124 1125 1126 void AllocationMemento::AllocationMementoPrint(FILE* out) { 1127 HeapObject::PrintHeader(out, "AllocationMemento"); 1128 PrintF(out, " - allocation site: "); 1129 if (IsValid()) { 1130 GetAllocationSite()->Print(); 1131 } else { 1132 PrintF(out, "<invalid>\n"); 1133 } 1134 } 1135 1136 1137 void Script::ScriptPrint(FILE* out) { 1138 HeapObject::PrintHeader(out, "Script"); 1139 PrintF(out, "\n - source: "); 1140 source()->ShortPrint(out); 1141 PrintF(out, "\n - name: "); 1142 name()->ShortPrint(out); 1143 PrintF(out, "\n - line_offset: "); 1144 line_offset()->ShortPrint(out); 1145 PrintF(out, "\n - column_offset: "); 1146 column_offset()->ShortPrint(out); 1147 PrintF(out, "\n - type: "); 1148 type()->ShortPrint(out); 1149 PrintF(out, "\n - id: "); 1150 id()->ShortPrint(out); 1151 PrintF(out, "\n - data: "); 1152 data()->ShortPrint(out); 1153 PrintF(out, "\n - context data: "); 1154 context_data()->ShortPrint(out); 1155 PrintF(out, "\n - wrapper: "); 1156 wrapper()->ShortPrint(out); 1157 PrintF(out, "\n - compilation type: %d", compilation_type()); 1158 PrintF(out, "\n - line ends: "); 1159 line_ends()->ShortPrint(out); 1160 PrintF(out, "\n - eval from shared: "); 1161 eval_from_shared()->ShortPrint(out); 1162 PrintF(out, "\n - eval from instructions offset: "); 1163 eval_from_instructions_offset()->ShortPrint(out); 1164 PrintF(out, "\n"); 1165 } 1166 1167 1168 #ifdef ENABLE_DEBUGGER_SUPPORT 1169 void DebugInfo::DebugInfoPrint(FILE* out) { 1170 HeapObject::PrintHeader(out, "DebugInfo"); 1171 PrintF(out, "\n - shared: "); 1172 shared()->ShortPrint(out); 1173 PrintF(out, "\n - original_code: "); 1174 original_code()->ShortPrint(out); 1175 PrintF(out, "\n - code: "); 1176 code()->ShortPrint(out); 1177 PrintF(out, "\n - break_points: "); 1178 break_points()->Print(out); 1179 } 1180 1181 1182 void BreakPointInfo::BreakPointInfoPrint(FILE* out) { 1183 HeapObject::PrintHeader(out, "BreakPointInfo"); 1184 PrintF(out, "\n - code_position: %d", code_position()->value()); 1185 PrintF(out, "\n - source_position: %d", source_position()->value()); 1186 PrintF(out, "\n - statement_position: %d", statement_position()->value()); 1187 PrintF(out, "\n - break_point_objects: "); 1188 break_point_objects()->ShortPrint(out); 1189 } 1190 #endif // ENABLE_DEBUGGER_SUPPORT 1191 1192 1193 void DescriptorArray::PrintDescriptors(FILE* out) { 1194 PrintF(out, "Descriptor array %d\n", number_of_descriptors()); 1195 for (int i = 0; i < number_of_descriptors(); i++) { 1196 PrintF(out, " %d: ", i); 1197 Descriptor desc; 1198 Get(i, &desc); 1199 desc.Print(out); 1200 } 1201 PrintF(out, "\n"); 1202 } 1203 1204 1205 void TransitionArray::PrintTransitions(FILE* out) { 1206 PrintF(out, "Transition array %d\n", number_of_transitions()); 1207 for (int i = 0; i < number_of_transitions(); i++) { 1208 PrintF(out, " %d: ", i); 1209 GetKey(i)->NamePrint(out); 1210 PrintF(out, ": "); 1211 switch (GetTargetDetails(i).type()) { 1212 case FIELD: { 1213 PrintF(out, " (transition to field)\n"); 1214 break; 1215 } 1216 case CONSTANT: 1217 PrintF(out, " (transition to constant)\n"); 1218 break; 1219 case CALLBACKS: 1220 PrintF(out, " (transition to callback)\n"); 1221 break; 1222 // Values below are never in the target descriptor array. 1223 case NORMAL: 1224 case HANDLER: 1225 case INTERCEPTOR: 1226 case TRANSITION: 1227 case NONEXISTENT: 1228 UNREACHABLE(); 1229 break; 1230 } 1231 } 1232 PrintF(out, "\n"); 1233 } 1234 1235 1236 #endif // OBJECT_PRINT 1237 1238 1239 } } // namespace v8::internal 1240