Home | History | Annotate | Download | only in src
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/objects.h"
      6 
      7 #include <iomanip>
      8 #include <memory>
      9 
     10 #include "src/disasm.h"
     11 #include "src/disassembler.h"
     12 #include "src/interpreter/bytecodes.h"
     13 #include "src/objects-inl.h"
     14 #include "src/ostreams.h"
     15 #include "src/regexp/jsregexp.h"
     16 
     17 namespace v8 {
     18 namespace internal {
     19 
     20 #ifdef OBJECT_PRINT
     21 
     22 void Object::Print() {
     23   OFStream os(stdout);
     24   this->Print(os);
     25   os << std::flush;
     26 }
     27 
     28 
     29 void Object::Print(std::ostream& os) {  // NOLINT
     30   if (IsSmi()) {
     31     os << "Smi: " << std::hex << "0x" << Smi::cast(this)->value();
     32     os << std::dec << " (" << Smi::cast(this)->value() << ")\n";
     33   } else {
     34     HeapObject::cast(this)->HeapObjectPrint(os);
     35   }
     36 }
     37 
     38 
     39 void HeapObject::PrintHeader(std::ostream& os, const char* id) {  // NOLINT
     40   os << reinterpret_cast<void*>(this) << ": [";
     41   if (id != nullptr) {
     42     os << id;
     43   } else {
     44     os << map()->instance_type();
     45   }
     46   os << "]";
     47 }
     48 
     49 
     50 void HeapObject::HeapObjectPrint(std::ostream& os) {  // NOLINT
     51   InstanceType instance_type = map()->instance_type();
     52 
     53   HandleScope scope(GetIsolate());
     54   if (instance_type < FIRST_NONSTRING_TYPE) {
     55     String::cast(this)->StringPrint(os);
     56     os << "\n";
     57     return;
     58   }
     59 
     60   switch (instance_type) {
     61     case SYMBOL_TYPE:
     62       Symbol::cast(this)->SymbolPrint(os);
     63       break;
     64     case MAP_TYPE:
     65       Map::cast(this)->MapPrint(os);
     66       break;
     67     case HEAP_NUMBER_TYPE:
     68       HeapNumber::cast(this)->HeapNumberPrint(os);
     69       os << "\n";
     70       break;
     71     case MUTABLE_HEAP_NUMBER_TYPE:
     72       os << "<mutable ";
     73       HeapNumber::cast(this)->HeapNumberPrint(os);
     74       os << ">\n";
     75       break;
     76     case SIMD128_VALUE_TYPE:
     77       Simd128Value::cast(this)->Simd128ValuePrint(os);
     78       break;
     79     case FIXED_DOUBLE_ARRAY_TYPE:
     80       FixedDoubleArray::cast(this)->FixedDoubleArrayPrint(os);
     81       break;
     82     case FIXED_ARRAY_TYPE:
     83       FixedArray::cast(this)->FixedArrayPrint(os);
     84       break;
     85     case BYTE_ARRAY_TYPE:
     86       ByteArray::cast(this)->ByteArrayPrint(os);
     87       break;
     88     case BYTECODE_ARRAY_TYPE:
     89       BytecodeArray::cast(this)->BytecodeArrayPrint(os);
     90       break;
     91     case TRANSITION_ARRAY_TYPE:
     92       TransitionArray::cast(this)->TransitionArrayPrint(os);
     93       break;
     94     case FREE_SPACE_TYPE:
     95       FreeSpace::cast(this)->FreeSpacePrint(os);
     96       break;
     97 
     98 #define PRINT_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype, size) \
     99   case Fixed##Type##Array::kInstanceType:                      \
    100     Fixed##Type##Array::cast(this)->FixedTypedArrayPrint(os);  \
    101     break;
    102 
    103     TYPED_ARRAYS(PRINT_FIXED_TYPED_ARRAY)
    104 #undef PRINT_FIXED_TYPED_ARRAY
    105 
    106     case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
    107     case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
    108     case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
    109     case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    110     case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    111     case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    112     case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    113     case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    114     case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    115     case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    116     case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    117     case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    118     case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    119     case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    120     case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    121     case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    122     case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    123     case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    124     case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    125     case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE:
    126     case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE:
    127     case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE:
    128     case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE:
    129     case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE:
    130     case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE:
    131     case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE:
    132     case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE:
    133     case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE:
    134     case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE:
    135     case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE:
    136     case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE:
    137     case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE:
    138     case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
    139     case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
    140     case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE:
    141       JSArrayIterator::cast(this)->JSArrayIteratorPrint(os);
    142       break;
    143 
    144     case FILLER_TYPE:
    145       os << "filler";
    146       break;
    147     case JS_OBJECT_TYPE:  // fall through
    148     case JS_API_OBJECT_TYPE:
    149     case JS_SPECIAL_API_OBJECT_TYPE:
    150     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
    151     case JS_GENERATOR_OBJECT_TYPE:
    152     case JS_PROMISE_TYPE:
    153     case JS_ARGUMENTS_TYPE:
    154     case JS_ERROR_TYPE:
    155       JSObject::cast(this)->JSObjectPrint(os);
    156       break;
    157     case JS_ARRAY_TYPE:
    158       JSArray::cast(this)->JSArrayPrint(os);
    159       break;
    160     case JS_REGEXP_TYPE:
    161       JSRegExp::cast(this)->JSRegExpPrint(os);
    162       break;
    163     case ODDBALL_TYPE:
    164       Oddball::cast(this)->to_string()->Print(os);
    165       break;
    166     case JS_BOUND_FUNCTION_TYPE:
    167       JSBoundFunction::cast(this)->JSBoundFunctionPrint(os);
    168       break;
    169     case JS_FUNCTION_TYPE:
    170       JSFunction::cast(this)->JSFunctionPrint(os);
    171       break;
    172     case JS_GLOBAL_PROXY_TYPE:
    173       JSGlobalProxy::cast(this)->JSGlobalProxyPrint(os);
    174       break;
    175     case JS_GLOBAL_OBJECT_TYPE:
    176       JSGlobalObject::cast(this)->JSGlobalObjectPrint(os);
    177       break;
    178     case JS_VALUE_TYPE:
    179       JSValue::cast(this)->JSValuePrint(os);
    180       break;
    181     case JS_DATE_TYPE:
    182       JSDate::cast(this)->JSDatePrint(os);
    183       break;
    184     case CODE_TYPE:
    185       Code::cast(this)->CodePrint(os);
    186       break;
    187     case JS_PROXY_TYPE:
    188       JSProxy::cast(this)->JSProxyPrint(os);
    189       break;
    190     case JS_SET_TYPE:
    191       JSSet::cast(this)->JSSetPrint(os);
    192       break;
    193     case JS_MAP_TYPE:
    194       JSMap::cast(this)->JSMapPrint(os);
    195       break;
    196     case JS_SET_ITERATOR_TYPE:
    197       JSSetIterator::cast(this)->JSSetIteratorPrint(os);
    198       break;
    199     case JS_MAP_ITERATOR_TYPE:
    200       JSMapIterator::cast(this)->JSMapIteratorPrint(os);
    201       break;
    202     case JS_WEAK_MAP_TYPE:
    203       JSWeakMap::cast(this)->JSWeakMapPrint(os);
    204       break;
    205     case JS_WEAK_SET_TYPE:
    206       JSWeakSet::cast(this)->JSWeakSetPrint(os);
    207       break;
    208     case JS_MODULE_NAMESPACE_TYPE:
    209       JSModuleNamespace::cast(this)->JSModuleNamespacePrint(os);
    210       break;
    211     case FOREIGN_TYPE:
    212       Foreign::cast(this)->ForeignPrint(os);
    213       break;
    214     case SHARED_FUNCTION_INFO_TYPE:
    215       SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint(os);
    216       break;
    217     case JS_MESSAGE_OBJECT_TYPE:
    218       JSMessageObject::cast(this)->JSMessageObjectPrint(os);
    219       break;
    220     case CELL_TYPE:
    221       Cell::cast(this)->CellPrint(os);
    222       break;
    223     case PROPERTY_CELL_TYPE:
    224       PropertyCell::cast(this)->PropertyCellPrint(os);
    225       break;
    226     case WEAK_CELL_TYPE:
    227       WeakCell::cast(this)->WeakCellPrint(os);
    228       break;
    229     case JS_ARRAY_BUFFER_TYPE:
    230       JSArrayBuffer::cast(this)->JSArrayBufferPrint(os);
    231       break;
    232     case JS_TYPED_ARRAY_TYPE:
    233       JSTypedArray::cast(this)->JSTypedArrayPrint(os);
    234       break;
    235     case JS_FIXED_ARRAY_ITERATOR_TYPE:
    236       JSFixedArrayIterator::cast(this)->JSFixedArrayIteratorPrint(os);
    237       break;
    238     case JS_DATA_VIEW_TYPE:
    239       JSDataView::cast(this)->JSDataViewPrint(os);
    240       break;
    241 #define MAKE_STRUCT_CASE(NAME, Name, name) \
    242   case NAME##_TYPE:                        \
    243     Name::cast(this)->Name##Print(os);     \
    244     break;
    245   STRUCT_LIST(MAKE_STRUCT_CASE)
    246 #undef MAKE_STRUCT_CASE
    247 
    248     default:
    249       os << "UNKNOWN TYPE " << map()->instance_type();
    250       UNREACHABLE();
    251       break;
    252   }
    253 }
    254 
    255 
    256 void Simd128Value::Simd128ValuePrint(std::ostream& os) {  // NOLINT
    257 #define PRINT_SIMD128_VALUE(TYPE, Type, type, lane_count, lane_type) \
    258   if (Is##Type()) return Type::cast(this)->Type##Print(os);
    259   SIMD128_TYPES(PRINT_SIMD128_VALUE)
    260 #undef PRINT_SIMD128_VALUE
    261   UNREACHABLE();
    262 }
    263 
    264 
    265 void Float32x4::Float32x4Print(std::ostream& os) {  // NOLINT
    266   char arr[100];
    267   Vector<char> buffer(arr, arraysize(arr));
    268   os << std::string(DoubleToCString(get_lane(0), buffer)) << ", "
    269      << std::string(DoubleToCString(get_lane(1), buffer)) << ", "
    270      << std::string(DoubleToCString(get_lane(2), buffer)) << ", "
    271      << std::string(DoubleToCString(get_lane(3), buffer));
    272 }
    273 
    274 
    275 #define SIMD128_INT_PRINT_FUNCTION(type, lane_count)                \
    276   void type::type##Print(std::ostream& os) {                        \
    277     char arr[100];                                                  \
    278     Vector<char> buffer(arr, arraysize(arr));                       \
    279     os << std::string(IntToCString(get_lane(0), buffer));           \
    280     for (int i = 1; i < lane_count; i++) {                          \
    281       os << ", " << std::string(IntToCString(get_lane(i), buffer)); \
    282     }                                                               \
    283   }
    284 SIMD128_INT_PRINT_FUNCTION(Int32x4, 4)
    285 SIMD128_INT_PRINT_FUNCTION(Uint32x4, 4)
    286 SIMD128_INT_PRINT_FUNCTION(Int16x8, 8)
    287 SIMD128_INT_PRINT_FUNCTION(Uint16x8, 8)
    288 SIMD128_INT_PRINT_FUNCTION(Int8x16, 16)
    289 SIMD128_INT_PRINT_FUNCTION(Uint8x16, 16)
    290 #undef SIMD128_INT_PRINT_FUNCTION
    291 
    292 
    293 #define SIMD128_BOOL_PRINT_FUNCTION(type, lane_count)            \
    294   void type::type##Print(std::ostream& os) {                     \
    295     char arr[100];                                               \
    296     Vector<char> buffer(arr, arraysize(arr));                    \
    297     os << std::string(get_lane(0) ? "true" : "false");           \
    298     for (int i = 1; i < lane_count; i++) {                       \
    299       os << ", " << std::string(get_lane(i) ? "true" : "false"); \
    300     }                                                            \
    301   }
    302 SIMD128_BOOL_PRINT_FUNCTION(Bool32x4, 4)
    303 SIMD128_BOOL_PRINT_FUNCTION(Bool16x8, 8)
    304 SIMD128_BOOL_PRINT_FUNCTION(Bool8x16, 16)
    305 #undef SIMD128_BOOL_PRINT_FUNCTION
    306 
    307 
    308 void ByteArray::ByteArrayPrint(std::ostream& os) {  // NOLINT
    309   os << "byte array, data starts at " << GetDataStartAddress();
    310 }
    311 
    312 
    313 void BytecodeArray::BytecodeArrayPrint(std::ostream& os) {  // NOLINT
    314   Disassemble(os);
    315 }
    316 
    317 
    318 void FreeSpace::FreeSpacePrint(std::ostream& os) {  // NOLINT
    319   os << "free space, size " << Size();
    320 }
    321 
    322 
    323 template <class Traits>
    324 void FixedTypedArray<Traits>::FixedTypedArrayPrint(
    325     std::ostream& os) {  // NOLINT
    326   os << "fixed " << Traits::Designator();
    327 }
    328 
    329 
    330 void JSObject::PrintProperties(std::ostream& os) {  // NOLINT
    331   if (HasFastProperties()) {
    332     DescriptorArray* descs = map()->instance_descriptors();
    333     for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) {
    334       os << "\n   ";
    335       descs->GetKey(i)->NamePrint(os);
    336       os << ": ";
    337       switch (descs->GetType(i)) {
    338         case DATA: {
    339           FieldIndex index = FieldIndex::ForDescriptor(map(), i);
    340           if (IsUnboxedDoubleField(index)) {
    341             os << "<unboxed double> " << RawFastDoublePropertyAt(index);
    342           } else {
    343             os << Brief(RawFastPropertyAt(index));
    344           }
    345           os << " (data field at offset " << index.property_index() << ")";
    346           break;
    347         }
    348         case ACCESSOR: {
    349           FieldIndex index = FieldIndex::ForDescriptor(map(), i);
    350           os << " (accessor field at offset " << index.property_index() << ")";
    351           break;
    352         }
    353         case DATA_CONSTANT:
    354           os << Brief(descs->GetConstant(i)) << " (data constant)";
    355           break;
    356         case ACCESSOR_CONSTANT:
    357           os << Brief(descs->GetCallbacksObject(i)) << " (accessor constant)";
    358           break;
    359       }
    360     }
    361   } else if (IsJSGlobalObject()) {
    362     global_dictionary()->Print(os);
    363   } else {
    364     property_dictionary()->Print(os);
    365   }
    366 }
    367 
    368 namespace {
    369 
    370 template <class T>
    371 double GetScalarElement(T* array, int index) {
    372   return array->get_scalar(index);
    373 }
    374 
    375 double GetScalarElement(FixedDoubleArray* array, int index) {
    376   if (array->is_the_hole(index)) return bit_cast<double>(kHoleNanInt64);
    377   return array->get_scalar(index);
    378 }
    379 
    380 bool is_the_hole(double maybe_hole) {
    381   return bit_cast<uint64_t>(maybe_hole) == kHoleNanInt64;
    382 }
    383 
    384 }  // namespace
    385 
    386 template <class T, bool print_the_hole>
    387 static void DoPrintElements(std::ostream& os, Object* object) {  // NOLINT
    388   T* array = T::cast(object);
    389   if (array->length() == 0) return;
    390   int previous_index = 0;
    391   double previous_value = GetScalarElement(array, 0);
    392   double value = 0.0;
    393   int i;
    394   for (i = 1; i <= array->length(); i++) {
    395     if (i < array->length()) value = GetScalarElement(array, i);
    396     bool values_are_nan = std::isnan(previous_value) && std::isnan(value);
    397     if (i != array->length() && (previous_value == value || values_are_nan) &&
    398         is_the_hole(previous_value) == is_the_hole(value)) {
    399       continue;
    400     }
    401     os << "\n";
    402     std::stringstream ss;
    403     ss << previous_index;
    404     if (previous_index != i - 1) {
    405       ss << '-' << (i - 1);
    406     }
    407     os << std::setw(12) << ss.str() << ": ";
    408     if (print_the_hole && is_the_hole(previous_value)) {
    409       os << "<the_hole>";
    410     } else {
    411       os << previous_value;
    412     }
    413     previous_index = i;
    414     previous_value = value;
    415   }
    416 }
    417 
    418 
    419 void JSObject::PrintElements(std::ostream& os) {  // NOLINT
    420   // Don't call GetElementsKind, its validation code can cause the printer to
    421   // fail when debugging.
    422   if (elements()->length() == 0) return;
    423   switch (map()->elements_kind()) {
    424     case FAST_HOLEY_SMI_ELEMENTS:
    425     case FAST_SMI_ELEMENTS:
    426     case FAST_HOLEY_ELEMENTS:
    427     case FAST_ELEMENTS:
    428     case FAST_STRING_WRAPPER_ELEMENTS: {
    429       // Print in array notation for non-sparse arrays.
    430       FixedArray* array = FixedArray::cast(elements());
    431       Object* previous_value = array->get(0);
    432       Object* value = nullptr;
    433       int previous_index = 0;
    434       int i;
    435       for (i = 1; i <= array->length(); i++) {
    436         if (i < array->length()) value = array->get(i);
    437         if (previous_value == value && i != array->length()) {
    438           continue;
    439         }
    440         os << "\n";
    441         std::stringstream ss;
    442         ss << previous_index;
    443         if (previous_index != i - 1) {
    444           ss << '-' << (i - 1);
    445         }
    446         os << std::setw(12) << ss.str() << ": " << Brief(previous_value);
    447         previous_index = i;
    448         previous_value = value;
    449       }
    450       break;
    451     }
    452     case FAST_HOLEY_DOUBLE_ELEMENTS:
    453     case FAST_DOUBLE_ELEMENTS: {
    454       DoPrintElements<FixedDoubleArray, true>(os, elements());
    455       break;
    456     }
    457 
    458 #define PRINT_ELEMENTS(Type, type, TYPE, elementType, size)     \
    459   case TYPE##_ELEMENTS: {                                       \
    460     DoPrintElements<Fixed##Type##Array, false>(os, elements()); \
    461     break;                                                      \
    462   }
    463       TYPED_ARRAYS(PRINT_ELEMENTS)
    464 #undef PRINT_ELEMENTS
    465 
    466     case DICTIONARY_ELEMENTS:
    467     case SLOW_STRING_WRAPPER_ELEMENTS:
    468       SeededNumberDictionary::cast(elements())->Print(os);
    469       break;
    470     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
    471     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
    472       FixedArray* p = FixedArray::cast(elements());
    473       os << "\n   parameter map:";
    474       for (int i = 2; i < p->length(); i++) {
    475         os << " " << (i - 2) << ":" << Brief(p->get(i));
    476       }
    477       os << "\n   context: " << Brief(p->get(0))
    478          << "\n   arguments: " << Brief(p->get(1));
    479       break;
    480     }
    481     case NO_ELEMENTS:
    482       break;
    483   }
    484 }
    485 
    486 
    487 static void JSObjectPrintHeader(std::ostream& os, JSObject* obj,
    488                                 const char* id) {  // NOLINT
    489   obj->PrintHeader(os, id);
    490   // Don't call GetElementsKind, its validation code can cause the printer to
    491   // fail when debugging.
    492   os << "\n - map = " << reinterpret_cast<void*>(obj->map()) << " [";
    493   if (obj->HasFastProperties()) {
    494     os << "FastProperties";
    495   } else {
    496     os << "DictionaryProperties";
    497   }
    498   PrototypeIterator iter(obj->GetIsolate(), obj);
    499   os << "]\n - prototype = " << reinterpret_cast<void*>(iter.GetCurrent());
    500   os << "\n - elements = " << Brief(obj->elements()) << " ["
    501      << ElementsKindToString(obj->map()->elements_kind());
    502   if (obj->elements()->map() == obj->GetHeap()->fixed_cow_array_map()) {
    503     os << " (COW)";
    504   }
    505   os << "]";
    506   if (obj->GetInternalFieldCount() > 0) {
    507     os << "\n - internal fields: " << obj->GetInternalFieldCount();
    508   }
    509 }
    510 
    511 
    512 static void JSObjectPrintBody(std::ostream& os, JSObject* obj,  // NOLINT
    513                               bool print_elements = true) {
    514   os << "\n - properties = {";
    515   obj->PrintProperties(os);
    516   os << "\n }\n";
    517   if (print_elements && obj->elements()->length() > 0) {
    518     os << " - elements = {";
    519     obj->PrintElements(os);
    520     os << "\n }\n";
    521   }
    522   int internal_fields = obj->GetInternalFieldCount();
    523   if (internal_fields > 0) {
    524     os << " - internal fields = {";
    525     for (int i = 0; i < internal_fields; i++) {
    526       os << "\n    " << Brief(obj->GetInternalField(i));
    527     }
    528     os << "\n }\n";
    529   }
    530 }
    531 
    532 
    533 void JSObject::JSObjectPrint(std::ostream& os) {  // NOLINT
    534   JSObjectPrintHeader(os, this, nullptr);
    535   JSObjectPrintBody(os, this);
    536 }
    537 
    538 void JSArray::JSArrayPrint(std::ostream& os) {  // NOLINT
    539   JSObjectPrintHeader(os, this, "JSArray");
    540   os << "\n - length = " << Brief(this->length());
    541   JSObjectPrintBody(os, this);
    542 }
    543 
    544 
    545 void JSRegExp::JSRegExpPrint(std::ostream& os) {  // NOLINT
    546   JSObjectPrintHeader(os, this, "JSRegExp");
    547   os << "\n - data = " << Brief(data());
    548   JSObjectPrintBody(os, this);
    549 }
    550 
    551 
    552 void Symbol::SymbolPrint(std::ostream& os) {  // NOLINT
    553   HeapObject::PrintHeader(os, "Symbol");
    554   os << "\n - hash: " << Hash();
    555   os << "\n - name: " << Brief(name());
    556   if (name()->IsUndefined(GetIsolate())) {
    557     os << " (" << PrivateSymbolToName() << ")";
    558   }
    559   os << "\n - private: " << is_private();
    560   os << "\n";
    561 }
    562 
    563 
    564 void Map::MapPrint(std::ostream& os) {  // NOLINT
    565   HeapObject::PrintHeader(os, "Map");
    566   os << "\n - type: " << instance_type();
    567   os << "\n - instance size: " << instance_size();
    568   if (IsJSObjectMap()) {
    569     os << "\n - inobject properties: " << GetInObjectProperties();
    570   }
    571   os << "\n - elements kind: " << ElementsKindToString(elements_kind());
    572   os << "\n - unused property fields: " << unused_property_fields();
    573   os << "\n - enum length: ";
    574   if (EnumLength() == kInvalidEnumCacheSentinel) {
    575     os << "invalid";
    576   } else {
    577     os << EnumLength();
    578   }
    579   if (is_deprecated()) os << "\n - deprecated_map";
    580   if (is_stable()) os << "\n - stable_map";
    581   if (is_dictionary_map()) os << "\n - dictionary_map";
    582   if (has_hidden_prototype()) os << "\n - has_hidden_prototype";
    583   if (has_named_interceptor()) os << "\n - named_interceptor";
    584   if (has_indexed_interceptor()) os << "\n - indexed_interceptor";
    585   if (is_undetectable()) os << "\n - undetectable";
    586   if (is_callable()) os << "\n - callable";
    587   if (is_constructor()) os << "\n - constructor";
    588   if (is_access_check_needed()) os << "\n - access_check_needed";
    589   if (!is_extensible()) os << "\n - non-extensible";
    590   if (is_prototype_map()) {
    591     os << "\n - prototype_map";
    592     os << "\n - prototype info: " << Brief(prototype_info());
    593   } else {
    594     os << "\n - back pointer: " << Brief(GetBackPointer());
    595   }
    596   os << "\n - instance descriptors " << (owns_descriptors() ? "(own) " : "")
    597      << "#" << NumberOfOwnDescriptors() << ": "
    598      << Brief(instance_descriptors());
    599   if (FLAG_unbox_double_fields) {
    600     os << "\n - layout descriptor: " << Brief(layout_descriptor());
    601   }
    602   int nof_transitions = TransitionArray::NumberOfTransitions(raw_transitions());
    603   if (nof_transitions > 0) {
    604     os << "\n - transitions #" << nof_transitions << ": "
    605        << Brief(raw_transitions());
    606     TransitionArray::PrintTransitions(os, raw_transitions(), false);
    607   }
    608   os << "\n - prototype: " << Brief(prototype());
    609   os << "\n - constructor: " << Brief(GetConstructor());
    610   os << "\n - code cache: " << Brief(code_cache());
    611   os << "\n - dependent code: " << Brief(dependent_code());
    612   os << "\n - construction counter: " << construction_counter();
    613   os << "\n";
    614 }
    615 
    616 
    617 void TypeFeedbackInfo::TypeFeedbackInfoPrint(std::ostream& os) {  // NOLINT
    618   HeapObject::PrintHeader(os, "TypeFeedbackInfo");
    619   os << "\n - ic_total_count: " << ic_total_count()
    620      << ", ic_with_type_info_count: " << ic_with_type_info_count()
    621      << ", ic_generic_count: " << ic_generic_count() << "\n";
    622 }
    623 
    624 
    625 void AliasedArgumentsEntry::AliasedArgumentsEntryPrint(
    626     std::ostream& os) {  // NOLINT
    627   HeapObject::PrintHeader(os, "AliasedArgumentsEntry");
    628   os << "\n - aliased_context_slot: " << aliased_context_slot();
    629 }
    630 
    631 
    632 void FixedArray::FixedArrayPrint(std::ostream& os) {  // NOLINT
    633   HeapObject::PrintHeader(os, "FixedArray");
    634   os << "\n - length: " << length();
    635   for (int i = 0; i < length(); i++) {
    636     os << "\n  [" << i << "]: " << Brief(get(i));
    637   }
    638   os << "\n";
    639 }
    640 
    641 
    642 void FixedDoubleArray::FixedDoubleArrayPrint(std::ostream& os) {  // NOLINT
    643   HeapObject::PrintHeader(os, "FixedDoubleArray");
    644   os << "\n - length: " << length();
    645   for (int i = 0; i < length(); i++) {
    646     os << "\n  [" << i << "]: ";
    647     if (is_the_hole(i)) {
    648       os << "<the hole>";
    649     } else {
    650       os << get_scalar(i);
    651     }
    652   }
    653   os << "\n";
    654 }
    655 
    656 
    657 void TransitionArray::TransitionArrayPrint(std::ostream& os) {  // NOLINT
    658   HeapObject::PrintHeader(os, "TransitionArray");
    659   os << "\n - capacity: " << length();
    660   for (int i = 0; i < length(); i++) {
    661     os << "\n  [" << i << "]: " << Brief(get(i));
    662     if (i == kNextLinkIndex) os << " (next link)";
    663     if (i == kPrototypeTransitionsIndex) os << " (prototype transitions)";
    664     if (i == kTransitionLengthIndex) os << " (number of transitions)";
    665   }
    666   os << "\n";
    667 }
    668 
    669 template void FeedbackVectorSpecBase<StaticFeedbackVectorSpec>::Print();
    670 template void FeedbackVectorSpecBase<FeedbackVectorSpec>::Print();
    671 
    672 template <typename Derived>
    673 void FeedbackVectorSpecBase<Derived>::Print() {
    674   OFStream os(stdout);
    675   FeedbackVectorSpecPrint(os);
    676   os << std::flush;
    677 }
    678 
    679 template <typename Derived>
    680 void FeedbackVectorSpecBase<Derived>::FeedbackVectorSpecPrint(
    681     std::ostream& os) {  // NOLINT
    682   int slot_count = This()->slots();
    683   os << " - slot_count: " << slot_count;
    684   if (slot_count == 0) {
    685     os << " (empty)\n";
    686     return;
    687   }
    688 
    689   for (int slot = 0, name_index = 0; slot < slot_count;) {
    690     FeedbackVectorSlotKind kind = This()->GetKind(slot);
    691     int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
    692     DCHECK_LT(0, entry_size);
    693 
    694     os << "\n Slot #" << slot << " " << kind;
    695     if (TypeFeedbackMetadata::SlotRequiresName(kind)) {
    696       os << ", " << Brief(*This()->GetName(name_index++));
    697     }
    698 
    699     slot += entry_size;
    700   }
    701   os << "\n";
    702 }
    703 
    704 void TypeFeedbackMetadata::Print() {
    705   OFStream os(stdout);
    706   TypeFeedbackMetadataPrint(os);
    707   os << std::flush;
    708 }
    709 
    710 
    711 void TypeFeedbackMetadata::TypeFeedbackMetadataPrint(
    712     std::ostream& os) {  // NOLINT
    713   HeapObject::PrintHeader(os, "TypeFeedbackMetadata");
    714   os << "\n - length: " << length();
    715   if (length() == 0) {
    716     os << " (empty)\n";
    717     return;
    718   }
    719   os << "\n - slot_count: " << slot_count();
    720 
    721   TypeFeedbackMetadataIterator iter(this);
    722   while (iter.HasNext()) {
    723     FeedbackVectorSlot slot = iter.Next();
    724     FeedbackVectorSlotKind kind = iter.kind();
    725     os << "\n Slot " << slot << " " << kind;
    726     if (TypeFeedbackMetadata::SlotRequiresName(kind)) {
    727       os << ", " << Brief(iter.name());
    728     }
    729   }
    730   os << "\n";
    731 }
    732 
    733 
    734 void TypeFeedbackVector::Print() {
    735   OFStream os(stdout);
    736   TypeFeedbackVectorPrint(os);
    737   os << std::flush;
    738 }
    739 
    740 
    741 void TypeFeedbackVector::TypeFeedbackVectorPrint(std::ostream& os) {  // NOLINT
    742   HeapObject::PrintHeader(os, "TypeFeedbackVector");
    743   os << "\n - length: " << length();
    744   if (length() == 0) {
    745     os << " (empty)\n";
    746     return;
    747   }
    748 
    749   TypeFeedbackMetadataIterator iter(metadata());
    750   while (iter.HasNext()) {
    751     FeedbackVectorSlot slot = iter.Next();
    752     FeedbackVectorSlotKind kind = iter.kind();
    753 
    754     os << "\n Slot " << slot << " " << kind;
    755     if (TypeFeedbackMetadata::SlotRequiresName(kind)) {
    756       os << ", " << Brief(iter.name());
    757     }
    758     os << " ";
    759     switch (kind) {
    760       case FeedbackVectorSlotKind::LOAD_IC: {
    761         LoadICNexus nexus(this, slot);
    762         os << Code::ICState2String(nexus.StateFromFeedback());
    763         break;
    764       }
    765       case FeedbackVectorSlotKind::LOAD_GLOBAL_IC: {
    766         LoadGlobalICNexus nexus(this, slot);
    767         os << Code::ICState2String(nexus.StateFromFeedback());
    768         break;
    769       }
    770       case FeedbackVectorSlotKind::KEYED_LOAD_IC: {
    771         KeyedLoadICNexus nexus(this, slot);
    772         os << Code::ICState2String(nexus.StateFromFeedback());
    773         break;
    774       }
    775       case FeedbackVectorSlotKind::CALL_IC: {
    776         CallICNexus nexus(this, slot);
    777         os << Code::ICState2String(nexus.StateFromFeedback());
    778         break;
    779       }
    780       case FeedbackVectorSlotKind::STORE_IC: {
    781         StoreICNexus nexus(this, slot);
    782         os << Code::ICState2String(nexus.StateFromFeedback());
    783         break;
    784       }
    785       case FeedbackVectorSlotKind::KEYED_STORE_IC: {
    786         KeyedStoreICNexus nexus(this, slot);
    787         os << Code::ICState2String(nexus.StateFromFeedback());
    788         break;
    789       }
    790       case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC: {
    791         BinaryOpICNexus nexus(this, slot);
    792         os << Code::ICState2String(nexus.StateFromFeedback());
    793         break;
    794       }
    795       case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC: {
    796         CompareICNexus nexus(this, slot);
    797         os << Code::ICState2String(nexus.StateFromFeedback());
    798         break;
    799       }
    800       case FeedbackVectorSlotKind::GENERAL:
    801         break;
    802       case FeedbackVectorSlotKind::INVALID:
    803       case FeedbackVectorSlotKind::KINDS_NUMBER:
    804         UNREACHABLE();
    805         break;
    806     }
    807 
    808     int entry_size = iter.entry_size();
    809     for (int i = 0; i < entry_size; i++) {
    810       int index = GetIndex(slot) + i;
    811       os << "\n  [" << index << "]: " << Brief(get(index));
    812     }
    813   }
    814   os << "\n";
    815 }
    816 
    817 
    818 void JSValue::JSValuePrint(std::ostream& os) {  // NOLINT
    819   JSObjectPrintHeader(os, this, "JSValue");
    820   os << "\n - value = " << Brief(value());
    821   JSObjectPrintBody(os, this);
    822 }
    823 
    824 
    825 void JSMessageObject::JSMessageObjectPrint(std::ostream& os) {  // NOLINT
    826   JSObjectPrintHeader(os, this, "JSMessageObject");
    827   os << "\n - type: " << type();
    828   os << "\n - arguments: " << Brief(argument());
    829   os << "\n - start_position: " << start_position();
    830   os << "\n - end_position: " << end_position();
    831   os << "\n - script: " << Brief(script());
    832   os << "\n - stack_frames: " << Brief(stack_frames());
    833   JSObjectPrintBody(os, this);
    834 }
    835 
    836 
    837 void String::StringPrint(std::ostream& os) {  // NOLINT
    838   if (StringShape(this).IsInternalized()) {
    839     os << "#";
    840   } else if (StringShape(this).IsCons()) {
    841     os << "c\"";
    842   } else {
    843     os << "\"";
    844   }
    845 
    846   const char truncated_epilogue[] = "...<truncated>";
    847   int len = length();
    848   if (!FLAG_use_verbose_printer) {
    849     if (len > 100) {
    850       len = 100 - sizeof(truncated_epilogue);
    851     }
    852   }
    853   for (int i = 0; i < len; i++) {
    854     os << AsUC16(Get(i));
    855   }
    856   if (len != length()) {
    857     os << truncated_epilogue;
    858   }
    859 
    860   if (!StringShape(this).IsInternalized()) os << "\"";
    861 }
    862 
    863 
    864 void Name::NamePrint(std::ostream& os) {  // NOLINT
    865   if (IsString()) {
    866     String::cast(this)->StringPrint(os);
    867   } else {
    868     os << Brief(this);
    869   }
    870 }
    871 
    872 
    873 static const char* const weekdays[] = {
    874   "???", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
    875 };
    876 
    877 
    878 void JSDate::JSDatePrint(std::ostream& os) {  // NOLINT
    879   JSObjectPrintHeader(os, this, "JSDate");
    880   os << "\n - value = " << Brief(value());
    881   if (!year()->IsSmi()) {
    882     os << "\n - time = NaN\n";
    883   } else {
    884     // TODO(svenpanne) Add some basic formatting to our streams.
    885     ScopedVector<char> buf(100);
    886     SNPrintF(
    887         buf, "\n - time = %s %04d/%02d/%02d %02d:%02d:%02d\n",
    888         weekdays[weekday()->IsSmi() ? Smi::cast(weekday())->value() + 1 : 0],
    889         year()->IsSmi() ? Smi::cast(year())->value() : -1,
    890         month()->IsSmi() ? Smi::cast(month())->value() : -1,
    891         day()->IsSmi() ? Smi::cast(day())->value() : -1,
    892         hour()->IsSmi() ? Smi::cast(hour())->value() : -1,
    893         min()->IsSmi() ? Smi::cast(min())->value() : -1,
    894         sec()->IsSmi() ? Smi::cast(sec())->value() : -1);
    895     os << buf.start();
    896   }
    897   JSObjectPrintBody(os, this);
    898 }
    899 
    900 
    901 void JSProxy::JSProxyPrint(std::ostream& os) {  // NOLINT
    902   HeapObject::PrintHeader(os, "JSProxy");
    903   os << "\n - map = " << reinterpret_cast<void*>(map());
    904   os << "\n - target = ";
    905   target()->ShortPrint(os);
    906   os << "\n - handler = ";
    907   handler()->ShortPrint(os);
    908   os << "\n - hash = ";
    909   hash()->ShortPrint(os);
    910   os << "\n";
    911 }
    912 
    913 
    914 void JSSet::JSSetPrint(std::ostream& os) {  // NOLINT
    915   JSObjectPrintHeader(os, this, "JSSet");
    916   os << " - table = " << Brief(table());
    917   JSObjectPrintBody(os, this);
    918 }
    919 
    920 
    921 void JSMap::JSMapPrint(std::ostream& os) {  // NOLINT
    922   JSObjectPrintHeader(os, this, "JSMap");
    923   os << " - table = " << Brief(table());
    924   JSObjectPrintBody(os, this);
    925 }
    926 
    927 
    928 template <class Derived, class TableType>
    929 void
    930 OrderedHashTableIterator<Derived, TableType>::OrderedHashTableIteratorPrint(
    931     std::ostream& os) {  // NOLINT
    932   os << "\n - table = " << Brief(table());
    933   os << "\n - index = " << Brief(index());
    934   os << "\n - kind = " << Brief(kind());
    935   os << "\n";
    936 }
    937 
    938 
    939 template void OrderedHashTableIterator<
    940     JSSetIterator,
    941     OrderedHashSet>::OrderedHashTableIteratorPrint(std::ostream& os);  // NOLINT
    942 
    943 
    944 template void OrderedHashTableIterator<
    945     JSMapIterator,
    946     OrderedHashMap>::OrderedHashTableIteratorPrint(std::ostream& os);  // NOLINT
    947 
    948 
    949 void JSSetIterator::JSSetIteratorPrint(std::ostream& os) {  // NOLINT
    950   JSObjectPrintHeader(os, this, "JSSetIterator");
    951   OrderedHashTableIteratorPrint(os);
    952 }
    953 
    954 
    955 void JSMapIterator::JSMapIteratorPrint(std::ostream& os) {  // NOLINT
    956   JSObjectPrintHeader(os, this, "JSMapIterator");
    957   OrderedHashTableIteratorPrint(os);
    958 }
    959 
    960 
    961 void JSWeakMap::JSWeakMapPrint(std::ostream& os) {  // NOLINT
    962   JSObjectPrintHeader(os, this, "JSWeakMap");
    963   os << "\n - table = " << Brief(table());
    964   JSObjectPrintBody(os, this);
    965 }
    966 
    967 
    968 void JSWeakSet::JSWeakSetPrint(std::ostream& os) {  // NOLINT
    969   JSObjectPrintHeader(os, this, "JSWeakSet");
    970   os << "\n - table = " << Brief(table());
    971   JSObjectPrintBody(os, this);
    972 }
    973 
    974 
    975 void JSArrayBuffer::JSArrayBufferPrint(std::ostream& os) {  // NOLINT
    976   JSObjectPrintHeader(os, this, "JSArrayBuffer");
    977   os << "\n - backing_store = " << backing_store();
    978   os << "\n - byte_length = " << Brief(byte_length());
    979   if (was_neutered()) os << "\n - neutered";
    980   JSObjectPrintBody(os, this, !was_neutered());
    981 }
    982 
    983 
    984 void JSTypedArray::JSTypedArrayPrint(std::ostream& os) {  // NOLINT
    985   JSObjectPrintHeader(os, this, "JSTypedArray");
    986   os << "\n - buffer = " << Brief(buffer());
    987   os << "\n - byte_offset = " << Brief(byte_offset());
    988   os << "\n - byte_length = " << Brief(byte_length());
    989   os << "\n - length = " << Brief(length());
    990   if (WasNeutered()) os << "\n - neutered";
    991   JSObjectPrintBody(os, this, !WasNeutered());
    992 }
    993 
    994 void JSArrayIterator::JSArrayIteratorPrint(std::ostream& os) {  // NOLING
    995   JSObjectPrintHeader(os, this, "JSArrayIterator");
    996 
    997   InstanceType instance_type = map()->instance_type();
    998   std::string type;
    999   if (instance_type <= LAST_ARRAY_KEY_ITERATOR_TYPE) {
   1000     type = "keys";
   1001   } else if (instance_type <= LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE) {
   1002     type = "entries";
   1003   } else {
   1004     type = "values";
   1005   }
   1006 
   1007   os << "\n - type = " << type;
   1008   os << "\n - object = " << Brief(object());
   1009   os << "\n - index = " << Brief(index());
   1010 
   1011   JSObjectPrintBody(os, this);
   1012 }
   1013 
   1014 void JSFixedArrayIterator::JSFixedArrayIteratorPrint(
   1015     std::ostream& os) {  // NOLINT
   1016   JSObjectPrintHeader(os, this, "JSFixedArrayIterator");
   1017   os << "\n - array = " << Brief(array());
   1018   os << "\n - index = " << index();
   1019   os << "\n - initial_next = " << Brief(initial_next());
   1020   JSObjectPrintBody(os, this);
   1021 }
   1022 
   1023 void JSDataView::JSDataViewPrint(std::ostream& os) {  // NOLINT
   1024   JSObjectPrintHeader(os, this, "JSDataView");
   1025   os << "\n - buffer =" << Brief(buffer());
   1026   os << "\n - byte_offset = " << Brief(byte_offset());
   1027   os << "\n - byte_length = " << Brief(byte_length());
   1028   if (WasNeutered()) os << "\n - neutered";
   1029   JSObjectPrintBody(os, this, !WasNeutered());
   1030 }
   1031 
   1032 
   1033 void JSBoundFunction::JSBoundFunctionPrint(std::ostream& os) {  // NOLINT
   1034   JSObjectPrintHeader(os, this, "JSBoundFunction");
   1035   os << "\n - bound_target_function = " << Brief(bound_target_function());
   1036   os << "\n - bound_this = " << Brief(bound_this());
   1037   os << "\n - bound_arguments = " << Brief(bound_arguments());
   1038   JSObjectPrintBody(os, this);
   1039 }
   1040 
   1041 
   1042 void JSFunction::JSFunctionPrint(std::ostream& os) {  // NOLINT
   1043   JSObjectPrintHeader(os, this, "Function");
   1044   os << "\n - initial_map = ";
   1045   if (has_initial_map()) os << Brief(initial_map());
   1046   os << "\n - shared_info = " << Brief(shared());
   1047   os << "\n - name = " << Brief(shared()->name());
   1048   os << "\n - formal_parameter_count = "
   1049      << shared()->internal_formal_parameter_count();
   1050   if (IsGeneratorFunction(shared()->kind())) {
   1051     os << "\n   - generator";
   1052   } else if (IsAsyncFunction(shared()->kind())) {
   1053     os << "\n   - async";
   1054   }
   1055   os << "\n - context = " << Brief(context());
   1056   os << "\n - literals = " << Brief(literals());
   1057   os << "\n - code = " << Brief(code());
   1058   JSObjectPrintBody(os, this);
   1059 }
   1060 
   1061 
   1062 void SharedFunctionInfo::SharedFunctionInfoPrint(std::ostream& os) {  // NOLINT
   1063   HeapObject::PrintHeader(os, "SharedFunctionInfo");
   1064   os << "\n - name = " << Brief(name());
   1065   os << "\n - formal_parameter_count = " << internal_formal_parameter_count();
   1066   os << "\n - expected_nof_properties = " << expected_nof_properties();
   1067   os << "\n - ast_node_count = " << ast_node_count();
   1068   os << "\n - instance class name = ";
   1069   instance_class_name()->Print(os);
   1070   os << "\n - code = " << Brief(code());
   1071   if (HasSourceCode()) {
   1072     os << "\n - source code = ";
   1073     String* source = String::cast(Script::cast(script())->source());
   1074     int start = start_position();
   1075     int length = end_position() - start;
   1076     std::unique_ptr<char[]> source_string = source->ToCString(
   1077         DISALLOW_NULLS, FAST_STRING_TRAVERSAL, start, length, NULL);
   1078     os << source_string.get();
   1079   }
   1080   // Script files are often large, hard to read.
   1081   // os << "\n - script =";
   1082   // script()->Print(os);
   1083   if (is_named_expression()) {
   1084     os << "\n - named expression";
   1085   } else if (is_anonymous_expression()) {
   1086     os << "\n - anonymous expression";
   1087   } else if (is_declaration()) {
   1088     os << "\n - declaration";
   1089   }
   1090   os << "\n - function token position = " << function_token_position();
   1091   os << "\n - start position = " << start_position();
   1092   os << "\n - end position = " << end_position();
   1093   os << "\n - debug info = " << Brief(debug_info());
   1094   os << "\n - length = " << length();
   1095   os << "\n - num_literals = " << num_literals();
   1096   os << "\n - optimized_code_map = " << Brief(optimized_code_map());
   1097   os << "\n - feedback_metadata = ";
   1098   feedback_metadata()->TypeFeedbackMetadataPrint(os);
   1099   if (HasBytecodeArray()) {
   1100     os << "\n - bytecode_array = " << bytecode_array();
   1101   }
   1102   os << "\n";
   1103 }
   1104 
   1105 
   1106 void JSGlobalProxy::JSGlobalProxyPrint(std::ostream& os) {  // NOLINT
   1107   JSObjectPrintHeader(os, this, "JSGlobalProxy");
   1108   os << "\n - native context = " << Brief(native_context());
   1109   os << "\n - hash = " << Brief(hash());
   1110   JSObjectPrintBody(os, this);
   1111 }
   1112 
   1113 
   1114 void JSGlobalObject::JSGlobalObjectPrint(std::ostream& os) {  // NOLINT
   1115   JSObjectPrintHeader(os, this, "JSGlobalObject");
   1116   os << "\n - native context = " << Brief(native_context());
   1117   os << "\n - global proxy = " << Brief(global_proxy());
   1118   JSObjectPrintBody(os, this);
   1119 }
   1120 
   1121 
   1122 void Cell::CellPrint(std::ostream& os) {  // NOLINT
   1123   HeapObject::PrintHeader(os, "Cell");
   1124   os << "\n - value: " << Brief(value());
   1125   os << "\n";
   1126 }
   1127 
   1128 
   1129 void PropertyCell::PropertyCellPrint(std::ostream& os) {  // NOLINT
   1130   HeapObject::PrintHeader(os, "PropertyCell");
   1131   os << "\n - value: " << Brief(value());
   1132   os << "\n - details: " << property_details();
   1133   PropertyCellType cell_type = property_details().cell_type();
   1134   os << "\n - cell_type: ";
   1135   if (value()->IsTheHole(GetIsolate())) {
   1136     switch (cell_type) {
   1137       case PropertyCellType::kUninitialized:
   1138         os << "Uninitialized";
   1139         break;
   1140       case PropertyCellType::kInvalidated:
   1141         os << "Invalidated";
   1142         break;
   1143       default:
   1144         os << "??? " << static_cast<int>(cell_type);
   1145         break;
   1146     }
   1147   } else {
   1148     switch (cell_type) {
   1149       case PropertyCellType::kUndefined:
   1150         os << "Undefined";
   1151         break;
   1152       case PropertyCellType::kConstant:
   1153         os << "Constant";
   1154         break;
   1155       case PropertyCellType::kConstantType:
   1156         os << "ConstantType"
   1157            << " (";
   1158         switch (GetConstantType()) {
   1159           case PropertyCellConstantType::kSmi:
   1160             os << "Smi";
   1161             break;
   1162           case PropertyCellConstantType::kStableMap:
   1163             os << "StableMap";
   1164             break;
   1165         }
   1166         os << ")";
   1167         break;
   1168       case PropertyCellType::kMutable:
   1169         os << "Mutable";
   1170         break;
   1171     }
   1172   }
   1173   os << "\n";
   1174 }
   1175 
   1176 
   1177 void WeakCell::WeakCellPrint(std::ostream& os) {  // NOLINT
   1178   HeapObject::PrintHeader(os, "WeakCell");
   1179   if (cleared()) {
   1180     os << "\n - cleared";
   1181   } else {
   1182     os << "\n - value: " << Brief(value());
   1183   }
   1184   os << "\n";
   1185 }
   1186 
   1187 
   1188 void Code::CodePrint(std::ostream& os) {  // NOLINT
   1189   HeapObject::PrintHeader(os, "Code");
   1190   os << "\n";
   1191 #ifdef ENABLE_DISASSEMBLER
   1192   if (FLAG_use_verbose_printer) {
   1193     Disassemble(NULL, os);
   1194   }
   1195 #endif
   1196 }
   1197 
   1198 
   1199 void Foreign::ForeignPrint(std::ostream& os) {  // NOLINT
   1200   os << "foreign address : " << foreign_address();
   1201   os << "\n";
   1202 }
   1203 
   1204 
   1205 void AccessorInfo::AccessorInfoPrint(std::ostream& os) {  // NOLINT
   1206   HeapObject::PrintHeader(os, "AccessorInfo");
   1207   os << "\n - name: " << Brief(name());
   1208   os << "\n - flag: " << flag();
   1209   os << "\n - getter: " << Brief(getter());
   1210   os << "\n - setter: " << Brief(setter());
   1211   os << "\n - js_getter: " << Brief(js_getter());
   1212   os << "\n - data: " << Brief(data());
   1213   os << "\n";
   1214 }
   1215 
   1216 
   1217 void Box::BoxPrint(std::ostream& os) {  // NOLINT
   1218   HeapObject::PrintHeader(os, "Box");
   1219   os << "\n - value: " << Brief(value());
   1220   os << "\n";
   1221 }
   1222 
   1223 void PromiseResolveThenableJobInfo::PromiseResolveThenableJobInfoPrint(
   1224     std::ostream& os) {  // NOLINT
   1225   HeapObject::PrintHeader(os, "PromiseResolveThenableJobInfo");
   1226   os << "\n - thenable: " << Brief(thenable());
   1227   os << "\n - then: " << Brief(then());
   1228   os << "\n - resolve: " << Brief(resolve());
   1229   os << "\n - reject: " << Brief(reject());
   1230   os << "\n - debug id: " << Brief(debug_id());
   1231   os << "\n - debug name: " << Brief(debug_name());
   1232   os << "\n - context: " << Brief(context());
   1233   os << "\n";
   1234 }
   1235 
   1236 void PromiseReactionJobInfo::PromiseReactionJobInfoPrint(
   1237     std::ostream& os) {  // NOLINT
   1238   HeapObject::PrintHeader(os, "PromiseReactionJobInfo");
   1239   os << "\n - value: " << Brief(value());
   1240   os << "\n - tasks: " << Brief(tasks());
   1241   os << "\n - deferred: " << Brief(deferred());
   1242   os << "\n - debug id: " << Brief(debug_id());
   1243   os << "\n - debug name: " << Brief(debug_name());
   1244   os << "\n - reaction context: " << Brief(context());
   1245   os << "\n";
   1246 }
   1247 
   1248 void ModuleInfoEntry::ModuleInfoEntryPrint(std::ostream& os) {  // NOLINT
   1249   HeapObject::PrintHeader(os, "ModuleInfoEntry");
   1250   os << "\n - export_name: " << Brief(export_name());
   1251   os << "\n - local_name: " << Brief(local_name());
   1252   os << "\n - import_name: " << Brief(import_name());
   1253   os << "\n - module_request: " << module_request();
   1254   os << "\n - cell_index: " << cell_index();
   1255   os << "\n - beg_pos: " << beg_pos();
   1256   os << "\n - end_pos: " << end_pos();
   1257   os << "\n";
   1258 }
   1259 
   1260 void Module::ModulePrint(std::ostream& os) {  // NOLINT
   1261   HeapObject::PrintHeader(os, "Module");
   1262   os << "\n - code: " << Brief(code());
   1263   os << "\n - exports: " << Brief(exports());
   1264   os << "\n - requested_modules: " << Brief(requested_modules());
   1265   os << "\n - evaluated: " << evaluated();
   1266   os << "\n";
   1267 }
   1268 
   1269 void JSModuleNamespace::JSModuleNamespacePrint(std::ostream& os) {  // NOLINT
   1270   HeapObject::PrintHeader(os, "JSModuleNamespace");
   1271   os << "\n - module: " << Brief(module());
   1272   os << "\n";
   1273 }
   1274 
   1275 void PrototypeInfo::PrototypeInfoPrint(std::ostream& os) {  // NOLINT
   1276   HeapObject::PrintHeader(os, "PrototypeInfo");
   1277   os << "\n - weak cell: " << Brief(weak_cell());
   1278   os << "\n - prototype users: " << Brief(prototype_users());
   1279   os << "\n - registry slot: " << registry_slot();
   1280   os << "\n - validity cell: " << Brief(validity_cell());
   1281   os << "\n - object create map: " << Brief(object_create_map());
   1282   os << "\n";
   1283 }
   1284 
   1285 void Tuple3::Tuple3Print(std::ostream& os) {  // NOLINT
   1286   HeapObject::PrintHeader(os, "Tuple3");
   1287   os << "\n - value1: " << Brief(value1());
   1288   os << "\n - value2: " << Brief(value2());
   1289   os << "\n - value3: " << Brief(value3());
   1290   os << "\n";
   1291 }
   1292 
   1293 void ContextExtension::ContextExtensionPrint(std::ostream& os) {  // NOLINT
   1294   HeapObject::PrintHeader(os, "ContextExtension");
   1295   os << "\n - scope_info: " << Brief(scope_info());
   1296   os << "\n - extension: " << Brief(extension());
   1297   os << "\n";
   1298 }
   1299 
   1300 
   1301 void AccessorPair::AccessorPairPrint(std::ostream& os) {  // NOLINT
   1302   HeapObject::PrintHeader(os, "AccessorPair");
   1303   os << "\n - getter: " << Brief(getter());
   1304   os << "\n - setter: " << Brief(setter());
   1305   os << "\n";
   1306 }
   1307 
   1308 
   1309 void AccessCheckInfo::AccessCheckInfoPrint(std::ostream& os) {  // NOLINT
   1310   HeapObject::PrintHeader(os, "AccessCheckInfo");
   1311   os << "\n - callback: " << Brief(callback());
   1312   os << "\n - named_interceptor: " << Brief(named_interceptor());
   1313   os << "\n - indexed_interceptor: " << Brief(indexed_interceptor());
   1314   os << "\n - data: " << Brief(data());
   1315   os << "\n";
   1316 }
   1317 
   1318 
   1319 void InterceptorInfo::InterceptorInfoPrint(std::ostream& os) {  // NOLINT
   1320   HeapObject::PrintHeader(os, "InterceptorInfo");
   1321   os << "\n - getter: " << Brief(getter());
   1322   os << "\n - setter: " << Brief(setter());
   1323   os << "\n - query: " << Brief(query());
   1324   os << "\n - deleter: " << Brief(deleter());
   1325   os << "\n - enumerator: " << Brief(enumerator());
   1326   os << "\n - data: " << Brief(data());
   1327   os << "\n";
   1328 }
   1329 
   1330 
   1331 void CallHandlerInfo::CallHandlerInfoPrint(std::ostream& os) {  // NOLINT
   1332   HeapObject::PrintHeader(os, "CallHandlerInfo");
   1333   os << "\n - callback: " << Brief(callback());
   1334   os << "\n - data: " << Brief(data());
   1335   os << "\n";
   1336 }
   1337 
   1338 
   1339 void FunctionTemplateInfo::FunctionTemplateInfoPrint(
   1340     std::ostream& os) {  // NOLINT
   1341   HeapObject::PrintHeader(os, "FunctionTemplateInfo");
   1342   os << "\n - class name: " << Brief(class_name());
   1343   os << "\n - tag: " << Brief(tag());
   1344   os << "\n - serial_number: " << Brief(serial_number());
   1345   os << "\n - property_list: " << Brief(property_list());
   1346   os << "\n - call_code: " << Brief(call_code());
   1347   os << "\n - property_accessors: " << Brief(property_accessors());
   1348   os << "\n - prototype_template: " << Brief(prototype_template());
   1349   os << "\n - parent_template: " << Brief(parent_template());
   1350   os << "\n - named_property_handler: " << Brief(named_property_handler());
   1351   os << "\n - indexed_property_handler: " << Brief(indexed_property_handler());
   1352   os << "\n - instance_template: " << Brief(instance_template());
   1353   os << "\n - signature: " << Brief(signature());
   1354   os << "\n - access_check_info: " << Brief(access_check_info());
   1355   os << "\n - cached_property_name: " << Brief(cached_property_name());
   1356   os << "\n - hidden_prototype: " << (hidden_prototype() ? "true" : "false");
   1357   os << "\n - undetectable: " << (undetectable() ? "true" : "false");
   1358   os << "\n - need_access_check: " << (needs_access_check() ? "true" : "false");
   1359   os << "\n - instantiated: " << (instantiated() ? "true" : "false");
   1360   os << "\n";
   1361 }
   1362 
   1363 
   1364 void ObjectTemplateInfo::ObjectTemplateInfoPrint(std::ostream& os) {  // NOLINT
   1365   HeapObject::PrintHeader(os, "ObjectTemplateInfo");
   1366   os << "\n - tag: " << Brief(tag());
   1367   os << "\n - serial_number: " << Brief(serial_number());
   1368   os << "\n - property_list: " << Brief(property_list());
   1369   os << "\n - property_accessors: " << Brief(property_accessors());
   1370   os << "\n - constructor: " << Brief(constructor());
   1371   os << "\n - internal_field_count: " << internal_field_count();
   1372   os << "\n - immutable_proto: " << (immutable_proto() ? "true" : "false");
   1373   os << "\n";
   1374 }
   1375 
   1376 
   1377 void AllocationSite::AllocationSitePrint(std::ostream& os) {  // NOLINT
   1378   HeapObject::PrintHeader(os, "AllocationSite");
   1379   os << "\n - weak_next: " << Brief(weak_next());
   1380   os << "\n - dependent code: " << Brief(dependent_code());
   1381   os << "\n - nested site: " << Brief(nested_site());
   1382   os << "\n - memento found count: "
   1383      << Brief(Smi::FromInt(memento_found_count()));
   1384   os << "\n - memento create count: "
   1385      << Brief(Smi::FromInt(memento_create_count()));
   1386   os << "\n - pretenure decision: "
   1387      << Brief(Smi::FromInt(pretenure_decision()));
   1388   os << "\n - transition_info: ";
   1389   if (transition_info()->IsSmi()) {
   1390     ElementsKind kind = GetElementsKind();
   1391     os << "Array allocation with ElementsKind " << ElementsKindToString(kind);
   1392   } else if (transition_info()->IsJSArray()) {
   1393     os << "Array literal " << Brief(transition_info());
   1394   } else {
   1395     os << "unknown transition_info" << Brief(transition_info());
   1396   }
   1397   os << "\n";
   1398 }
   1399 
   1400 
   1401 void AllocationMemento::AllocationMementoPrint(std::ostream& os) {  // NOLINT
   1402   HeapObject::PrintHeader(os, "AllocationMemento");
   1403   os << "\n - allocation site: ";
   1404   if (IsValid()) {
   1405     GetAllocationSite()->Print(os);
   1406   } else {
   1407     os << "<invalid>\n";
   1408   }
   1409 }
   1410 
   1411 
   1412 void Script::ScriptPrint(std::ostream& os) {  // NOLINT
   1413   HeapObject::PrintHeader(os, "Script");
   1414   os << "\n - source: " << Brief(source());
   1415   os << "\n - name: " << Brief(name());
   1416   os << "\n - line_offset: " << line_offset();
   1417   os << "\n - column_offset: " << column_offset();
   1418   os << "\n - type: " << type();
   1419   os << "\n - id: " << id();
   1420   os << "\n - context data: " << Brief(context_data());
   1421   os << "\n - wrapper: " << Brief(wrapper());
   1422   os << "\n - compilation type: " << compilation_type();
   1423   os << "\n - line ends: " << Brief(line_ends());
   1424   os << "\n - eval from shared: " << Brief(eval_from_shared());
   1425   os << "\n - eval from position: " << eval_from_position();
   1426   os << "\n - shared function infos: " << Brief(shared_function_infos());
   1427   os << "\n";
   1428 }
   1429 
   1430 
   1431 void DebugInfo::DebugInfoPrint(std::ostream& os) {  // NOLINT
   1432   HeapObject::PrintHeader(os, "DebugInfo");
   1433   os << "\n - shared: " << Brief(shared());
   1434   os << "\n - debug bytecode array: " << Brief(debug_bytecode_array());
   1435   os << "\n - break_points: ";
   1436   break_points()->Print(os);
   1437 }
   1438 
   1439 
   1440 void BreakPointInfo::BreakPointInfoPrint(std::ostream& os) {  // NOLINT
   1441   HeapObject::PrintHeader(os, "BreakPointInfo");
   1442   os << "\n - source_position: " << source_position();
   1443   os << "\n - break_point_objects: " << Brief(break_point_objects());
   1444   os << "\n";
   1445 }
   1446 
   1447 
   1448 static void PrintBitMask(std::ostream& os, uint32_t value) {  // NOLINT
   1449   for (int i = 0; i < 32; i++) {
   1450     if ((i & 7) == 0) os << " ";
   1451     os << (((value & 1) == 0) ? "_" : "x");
   1452     value >>= 1;
   1453   }
   1454 }
   1455 
   1456 
   1457 void LayoutDescriptor::Print() {
   1458   OFStream os(stdout);
   1459   this->Print(os);
   1460   os << std::flush;
   1461 }
   1462 
   1463 
   1464 void LayoutDescriptor::Print(std::ostream& os) {  // NOLINT
   1465   os << "Layout descriptor: ";
   1466   if (IsOddball() && IsUninitialized(HeapObject::cast(this)->GetIsolate())) {
   1467     os << "<uninitialized>";
   1468   } else if (IsFastPointerLayout()) {
   1469     os << "<all tagged>";
   1470   } else if (IsSmi()) {
   1471     os << "fast";
   1472     PrintBitMask(os, static_cast<uint32_t>(Smi::cast(this)->value()));
   1473   } else {
   1474     os << "slow";
   1475     int len = length();
   1476     for (int i = 0; i < len; i++) {
   1477       if (i > 0) os << " |";
   1478       PrintBitMask(os, get_scalar(i));
   1479     }
   1480   }
   1481   os << "\n";
   1482 }
   1483 
   1484 
   1485 #endif  // OBJECT_PRINT
   1486 
   1487 
   1488 #if TRACE_MAPS
   1489 
   1490 
   1491 void Name::NameShortPrint() {
   1492   if (this->IsString()) {
   1493     PrintF("%s", String::cast(this)->ToCString().get());
   1494   } else {
   1495     DCHECK(this->IsSymbol());
   1496     Symbol* s = Symbol::cast(this);
   1497     if (s->name()->IsUndefined(GetIsolate())) {
   1498       PrintF("#<%s>", s->PrivateSymbolToName());
   1499     } else {
   1500       PrintF("<%s>", String::cast(s->name())->ToCString().get());
   1501     }
   1502   }
   1503 }
   1504 
   1505 
   1506 int Name::NameShortPrint(Vector<char> str) {
   1507   if (this->IsString()) {
   1508     return SNPrintF(str, "%s", String::cast(this)->ToCString().get());
   1509   } else {
   1510     DCHECK(this->IsSymbol());
   1511     Symbol* s = Symbol::cast(this);
   1512     if (s->name()->IsUndefined(GetIsolate())) {
   1513       return SNPrintF(str, "#<%s>", s->PrivateSymbolToName());
   1514     } else {
   1515       return SNPrintF(str, "<%s>", String::cast(s->name())->ToCString().get());
   1516     }
   1517   }
   1518 }
   1519 
   1520 
   1521 #endif  // TRACE_MAPS
   1522 
   1523 
   1524 #if defined(DEBUG) || defined(OBJECT_PRINT)
   1525 // This method is only meant to be called from gdb for debugging purposes.
   1526 // Since the string can also be in two-byte encoding, non-Latin1 characters
   1527 // will be ignored in the output.
   1528 char* String::ToAsciiArray() {
   1529   // Static so that subsequent calls frees previously allocated space.
   1530   // This also means that previous results will be overwritten.
   1531   static char* buffer = NULL;
   1532   if (buffer != NULL) delete[] buffer;
   1533   buffer = new char[length() + 1];
   1534   WriteToFlat(this, reinterpret_cast<uint8_t*>(buffer), 0, length());
   1535   buffer[length()] = 0;
   1536   return buffer;
   1537 }
   1538 
   1539 
   1540 void DescriptorArray::Print() {
   1541   OFStream os(stdout);
   1542   this->PrintDescriptors(os);
   1543   os << std::flush;
   1544 }
   1545 
   1546 
   1547 void DescriptorArray::PrintDescriptors(std::ostream& os) {  // NOLINT
   1548   HandleScope scope(GetIsolate());
   1549   os << "Descriptor array #" << number_of_descriptors();
   1550   for (int i = 0; i < number_of_descriptors(); i++) {
   1551     Descriptor desc;
   1552     Get(i, &desc);
   1553     os << "\n " << i << ": " << desc;
   1554   }
   1555   os << "\n";
   1556 }
   1557 
   1558 
   1559 void TransitionArray::Print() {
   1560   OFStream os(stdout);
   1561   TransitionArray::PrintTransitions(os, this);
   1562   os << "\n" << std::flush;
   1563 }
   1564 
   1565 
   1566 void TransitionArray::PrintTransitions(std::ostream& os, Object* transitions,
   1567                                        bool print_header) {  // NOLINT
   1568   int num_transitions = NumberOfTransitions(transitions);
   1569   if (print_header) {
   1570     os << "Transition array #" << num_transitions << ":";
   1571   }
   1572   for (int i = 0; i < num_transitions; i++) {
   1573     Name* key = GetKey(transitions, i);
   1574     Map* target = GetTarget(transitions, i);
   1575     os << "\n     ";
   1576 #ifdef OBJECT_PRINT
   1577     key->NamePrint(os);
   1578 #else
   1579     key->ShortPrint(os);
   1580 #endif
   1581     os << ": ";
   1582     Heap* heap = key->GetHeap();
   1583     if (key == heap->nonextensible_symbol()) {
   1584       os << "(transition to non-extensible)";
   1585     } else if (key == heap->sealed_symbol()) {
   1586       os << "(transition to sealed)";
   1587     } else if (key == heap->frozen_symbol()) {
   1588       os << "(transition to frozen)";
   1589     } else if (key == heap->elements_transition_symbol()) {
   1590       os << "(transition to " << ElementsKindToString(target->elements_kind())
   1591          << ")";
   1592     } else if (key == heap->strict_function_transition_symbol()) {
   1593       os << " (transition to strict function)";
   1594     } else {
   1595       PropertyDetails details = GetTargetDetails(key, target);
   1596       os << "(transition to ";
   1597       if (details.location() == kDescriptor) {
   1598         os << "immutable ";
   1599       }
   1600       os << (details.kind() == kData ? "data" : "accessor");
   1601       if (details.location() == kDescriptor) {
   1602         Object* value =
   1603             target->instance_descriptors()->GetValue(target->LastAdded());
   1604         os << " " << Brief(value);
   1605       }
   1606       os << "), attrs: " << details.attributes();
   1607     }
   1608     os << " -> " << Brief(target);
   1609   }
   1610 }
   1611 
   1612 
   1613 void JSObject::PrintTransitions(std::ostream& os) {  // NOLINT
   1614   Object* transitions = map()->raw_transitions();
   1615   int num_transitions = TransitionArray::NumberOfTransitions(transitions);
   1616   if (num_transitions == 0) return;
   1617   os << "\n - transitions";
   1618   TransitionArray::PrintTransitions(os, transitions, false);
   1619 }
   1620 #endif  // defined(DEBUG) || defined(OBJECT_PRINT)
   1621 }  // namespace internal
   1622 }  // namespace v8
   1623 
   1624 //
   1625 // The following functions are used by our gdb macros.
   1626 //
   1627 extern void _v8_internal_Print_Object(void* object) {
   1628   reinterpret_cast<i::Object*>(object)->Print();
   1629 }
   1630 
   1631 extern void _v8_internal_Print_Code(void* object) {
   1632   i::Isolate* isolate = i::Isolate::Current();
   1633   isolate->FindCodeObject(reinterpret_cast<i::Address>(object))->Print();
   1634 }
   1635 
   1636 extern void _v8_internal_Print_TypeFeedbackVector(void* object) {
   1637   if (reinterpret_cast<i::Object*>(object)->IsSmi()) {
   1638     printf("Not a type feedback vector\n");
   1639   } else {
   1640     reinterpret_cast<i::TypeFeedbackVector*>(object)->Print();
   1641   }
   1642 }
   1643 
   1644 extern void _v8_internal_Print_DescriptorArray(void* object) {
   1645   if (reinterpret_cast<i::Object*>(object)->IsSmi()) {
   1646     printf("Not a descriptor array\n");
   1647   } else {
   1648     reinterpret_cast<i::DescriptorArray*>(object)->Print();
   1649   }
   1650 }
   1651 
   1652 extern void _v8_internal_Print_TransitionArray(void* object) {
   1653   if (reinterpret_cast<i::Object*>(object)->IsSmi()) {
   1654     printf("Not a transition array\n");
   1655   } else {
   1656     reinterpret_cast<i::TransitionArray*>(object)->Print();
   1657   }
   1658 }
   1659 
   1660 extern void _v8_internal_Print_StackTrace() {
   1661   i::Isolate* isolate = i::Isolate::Current();
   1662   isolate->PrintStack(stdout);
   1663 }
   1664