• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/bootstrapper.h"
11 #include "src/disasm.h"
12 #include "src/disassembler.h"
13 #include "src/instruction-stream.h"
14 #include "src/interpreter/bytecodes.h"
15 #include "src/objects-inl.h"
16 #include "src/objects/arguments-inl.h"
17 #ifdef V8_INTL_SUPPORT
18 #include "src/objects/js-collator-inl.h"
19 #endif  // V8_INTL_SUPPORT
20 #include "src/objects/data-handler-inl.h"
21 #include "src/objects/debug-objects-inl.h"
22 #include "src/objects/hash-table-inl.h"
23 #include "src/objects/js-array-buffer-inl.h"
24 #include "src/objects/js-array-inl.h"
25 #include "src/objects/js-collection-inl.h"
26 #include "src/objects/js-generator-inl.h"
27 #ifdef V8_INTL_SUPPORT
28 #include "src/objects/js-list-format-inl.h"
29 #include "src/objects/js-locale-inl.h"
30 #endif  // V8_INTL_SUPPORT
31 #include "src/objects/js-regexp-inl.h"
32 #include "src/objects/js-regexp-string-iterator-inl.h"
33 #ifdef V8_INTL_SUPPORT
34 #include "src/objects/js-plural-rules-inl.h"
35 #include "src/objects/js-relative-time-format-inl.h"
36 #endif  // V8_INTL_SUPPORT
37 #include "src/objects/literal-objects-inl.h"
38 #include "src/objects/microtask-inl.h"
39 #include "src/objects/module-inl.h"
40 #include "src/objects/promise-inl.h"
41 #include "src/ostreams.h"
42 #include "src/regexp/jsregexp.h"
43 #include "src/transitions-inl.h"
44 #include "src/wasm/wasm-code-manager.h"
45 #include "src/wasm/wasm-engine.h"
46 #include "src/wasm/wasm-objects-inl.h"
47 
48 namespace v8 {
49 namespace internal {
50 
51 #ifdef OBJECT_PRINT
52 
Print()53 void Object::Print() {
54   StdoutStream os;
55   this->Print(os);
56   os << std::flush;
57 }
58 
Print(std::ostream & os)59 void Object::Print(std::ostream& os) {  // NOLINT
60   if (IsSmi()) {
61     os << "Smi: " << std::hex << "0x" << Smi::ToInt(this);
62     os << std::dec << " (" << Smi::ToInt(this) << ")\n";
63   } else {
64     HeapObject::cast(this)->HeapObjectPrint(os);
65   }
66 }
67 
PrintHeader(std::ostream & os,const char * id)68 void HeapObject::PrintHeader(std::ostream& os, const char* id) {  // NOLINT
69   os << reinterpret_cast<void*>(this) << ": [";
70   if (id != nullptr) {
71     os << id;
72   } else {
73     os << map()->instance_type();
74   }
75   os << "]";
76   MemoryChunk* chunk = MemoryChunk::FromAddress(
77       reinterpret_cast<Address>(const_cast<HeapObject*>(this)));
78   if (chunk->owner()->identity() == OLD_SPACE) os << " in OldSpace";
79   if (!IsMap()) os << "\n - map: " << Brief(map());
80 }
81 
HeapObjectPrint(std::ostream & os)82 void HeapObject::HeapObjectPrint(std::ostream& os) {  // NOLINT
83   InstanceType instance_type = map()->instance_type();
84 
85   if (instance_type < FIRST_NONSTRING_TYPE) {
86     String::cast(this)->StringPrint(os);
87     os << "\n";
88     return;
89   }
90 
91   switch (instance_type) {
92     case SYMBOL_TYPE:
93       Symbol::cast(this)->SymbolPrint(os);
94       break;
95     case MAP_TYPE:
96       Map::cast(this)->MapPrint(os);
97       break;
98     case HEAP_NUMBER_TYPE:
99       HeapNumber::cast(this)->HeapNumberPrint(os);
100       os << "\n";
101       break;
102     case MUTABLE_HEAP_NUMBER_TYPE:
103       os << "<mutable ";
104       MutableHeapNumber::cast(this)->MutableHeapNumberPrint(os);
105       os << ">\n";
106       break;
107     case BIGINT_TYPE:
108       BigInt::cast(this)->BigIntPrint(os);
109       os << "\n";
110       break;
111     case FIXED_DOUBLE_ARRAY_TYPE:
112       FixedDoubleArray::cast(this)->FixedDoubleArrayPrint(os);
113       break;
114     case FIXED_ARRAY_TYPE:
115     case BLOCK_CONTEXT_TYPE:
116     case CATCH_CONTEXT_TYPE:
117     case DEBUG_EVALUATE_CONTEXT_TYPE:
118     case EVAL_CONTEXT_TYPE:
119     case FUNCTION_CONTEXT_TYPE:
120     case MODULE_CONTEXT_TYPE:
121     case NATIVE_CONTEXT_TYPE:
122     case SCRIPT_CONTEXT_TYPE:
123     case WITH_CONTEXT_TYPE:
124     case SCRIPT_CONTEXT_TABLE_TYPE:
125       FixedArray::cast(this)->FixedArrayPrint(os);
126       break;
127     case HASH_TABLE_TYPE:
128     case ORDERED_HASH_MAP_TYPE:
129     case ORDERED_HASH_SET_TYPE:
130     case NAME_DICTIONARY_TYPE:
131     case GLOBAL_DICTIONARY_TYPE:
132     case SIMPLE_NUMBER_DICTIONARY_TYPE:
133     case STRING_TABLE_TYPE:
134       ObjectHashTable::cast(this)->ObjectHashTablePrint(os);
135       break;
136     case NUMBER_DICTIONARY_TYPE:
137       NumberDictionary::cast(this)->NumberDictionaryPrint(os);
138       break;
139     case EPHEMERON_HASH_TABLE_TYPE:
140       EphemeronHashTable::cast(this)->EphemeronHashTablePrint(os);
141       break;
142     case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
143       ObjectBoilerplateDescription::cast(this)
144           ->ObjectBoilerplateDescriptionPrint(os);
145       break;
146     case PROPERTY_ARRAY_TYPE:
147       PropertyArray::cast(this)->PropertyArrayPrint(os);
148       break;
149     case BYTE_ARRAY_TYPE:
150       ByteArray::cast(this)->ByteArrayPrint(os);
151       break;
152     case BYTECODE_ARRAY_TYPE:
153       BytecodeArray::cast(this)->BytecodeArrayPrint(os);
154       break;
155     case DESCRIPTOR_ARRAY_TYPE:
156       DescriptorArray::cast(this)->DescriptorArrayPrint(os);
157       break;
158     case TRANSITION_ARRAY_TYPE:
159       TransitionArray::cast(this)->TransitionArrayPrint(os);
160       break;
161     case FEEDBACK_CELL_TYPE:
162       FeedbackCell::cast(this)->FeedbackCellPrint(os);
163       break;
164     case FEEDBACK_VECTOR_TYPE:
165       FeedbackVector::cast(this)->FeedbackVectorPrint(os);
166       break;
167     case FREE_SPACE_TYPE:
168       FreeSpace::cast(this)->FreeSpacePrint(os);
169       break;
170 
171 #define PRINT_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype)      \
172   case Fixed##Type##Array::kInstanceType:                     \
173     Fixed##Type##Array::cast(this)->FixedTypedArrayPrint(os); \
174     break;
175 
176       TYPED_ARRAYS(PRINT_FIXED_TYPED_ARRAY)
177 #undef PRINT_FIXED_TYPED_ARRAY
178 
179     case FILLER_TYPE:
180       os << "filler";
181       break;
182     case JS_OBJECT_TYPE:  // fall through
183     case JS_API_OBJECT_TYPE:
184     case JS_SPECIAL_API_OBJECT_TYPE:
185     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
186     case JS_ASYNC_GENERATOR_OBJECT_TYPE:
187     case JS_ARGUMENTS_TYPE:
188     case JS_ERROR_TYPE:
189     // TODO(titzer): debug printing for more wasm objects
190     case WASM_GLOBAL_TYPE:
191     case WASM_MEMORY_TYPE:
192     case WASM_TABLE_TYPE:
193       JSObject::cast(this)->JSObjectPrint(os);
194       break;
195     case WASM_MODULE_TYPE:
196       WasmModuleObject::cast(this)->WasmModuleObjectPrint(os);
197       break;
198     case WASM_INSTANCE_TYPE:
199       WasmInstanceObject::cast(this)->WasmInstanceObjectPrint(os);
200       break;
201     case JS_GENERATOR_OBJECT_TYPE:
202       JSGeneratorObject::cast(this)->JSGeneratorObjectPrint(os);
203       break;
204     case JS_PROMISE_TYPE:
205       JSPromise::cast(this)->JSPromisePrint(os);
206       break;
207     case JS_ARRAY_TYPE:
208       JSArray::cast(this)->JSArrayPrint(os);
209       break;
210     case JS_REGEXP_TYPE:
211       JSRegExp::cast(this)->JSRegExpPrint(os);
212       break;
213     case JS_REGEXP_STRING_ITERATOR_TYPE:
214       JSRegExpStringIterator::cast(this)->JSRegExpStringIteratorPrint(os);
215       break;
216     case ODDBALL_TYPE:
217       Oddball::cast(this)->to_string()->Print(os);
218       break;
219     case JS_BOUND_FUNCTION_TYPE:
220       JSBoundFunction::cast(this)->JSBoundFunctionPrint(os);
221       break;
222     case JS_FUNCTION_TYPE:
223       JSFunction::cast(this)->JSFunctionPrint(os);
224       break;
225     case JS_GLOBAL_PROXY_TYPE:
226       JSGlobalProxy::cast(this)->JSGlobalProxyPrint(os);
227       break;
228     case JS_GLOBAL_OBJECT_TYPE:
229       JSGlobalObject::cast(this)->JSGlobalObjectPrint(os);
230       break;
231     case JS_VALUE_TYPE:
232       JSValue::cast(this)->JSValuePrint(os);
233       break;
234     case JS_DATE_TYPE:
235       JSDate::cast(this)->JSDatePrint(os);
236       break;
237     case CODE_TYPE:
238       Code::cast(this)->CodePrint(os);
239       break;
240     case CODE_DATA_CONTAINER_TYPE:
241       CodeDataContainer::cast(this)->CodeDataContainerPrint(os);
242       break;
243     case JS_PROXY_TYPE:
244       JSProxy::cast(this)->JSProxyPrint(os);
245       break;
246     case JS_SET_TYPE:
247       JSSet::cast(this)->JSSetPrint(os);
248       break;
249     case JS_MAP_TYPE:
250       JSMap::cast(this)->JSMapPrint(os);
251       break;
252     case JS_SET_KEY_VALUE_ITERATOR_TYPE:
253     case JS_SET_VALUE_ITERATOR_TYPE:
254       JSSetIterator::cast(this)->JSSetIteratorPrint(os);
255       break;
256     case JS_MAP_KEY_ITERATOR_TYPE:
257     case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
258     case JS_MAP_VALUE_ITERATOR_TYPE:
259       JSMapIterator::cast(this)->JSMapIteratorPrint(os);
260       break;
261     case JS_WEAK_MAP_TYPE:
262       JSWeakMap::cast(this)->JSWeakMapPrint(os);
263       break;
264     case JS_WEAK_SET_TYPE:
265       JSWeakSet::cast(this)->JSWeakSetPrint(os);
266       break;
267     case JS_MODULE_NAMESPACE_TYPE:
268       JSModuleNamespace::cast(this)->JSModuleNamespacePrint(os);
269       break;
270     case FOREIGN_TYPE:
271       Foreign::cast(this)->ForeignPrint(os);
272       break;
273     case CALL_HANDLER_INFO_TYPE:
274       CallHandlerInfo::cast(this)->CallHandlerInfoPrint(os);
275       break;
276     case PRE_PARSED_SCOPE_DATA_TYPE:
277       PreParsedScopeData::cast(this)->PreParsedScopeDataPrint(os);
278       break;
279     case UNCOMPILED_DATA_WITHOUT_PRE_PARSED_SCOPE_TYPE:
280       UncompiledDataWithoutPreParsedScope::cast(this)
281           ->UncompiledDataWithoutPreParsedScopePrint(os);
282       break;
283     case UNCOMPILED_DATA_WITH_PRE_PARSED_SCOPE_TYPE:
284       UncompiledDataWithPreParsedScope::cast(this)
285           ->UncompiledDataWithPreParsedScopePrint(os);
286       break;
287     case SHARED_FUNCTION_INFO_TYPE:
288       SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint(os);
289       break;
290     case JS_MESSAGE_OBJECT_TYPE:
291       JSMessageObject::cast(this)->JSMessageObjectPrint(os);
292       break;
293     case CELL_TYPE:
294       Cell::cast(this)->CellPrint(os);
295       break;
296     case PROPERTY_CELL_TYPE:
297       PropertyCell::cast(this)->PropertyCellPrint(os);
298       break;
299     case JS_ARRAY_BUFFER_TYPE:
300       JSArrayBuffer::cast(this)->JSArrayBufferPrint(os);
301       break;
302     case JS_ARRAY_ITERATOR_TYPE:
303       JSArrayIterator::cast(this)->JSArrayIteratorPrint(os);
304       break;
305     case JS_TYPED_ARRAY_TYPE:
306       JSTypedArray::cast(this)->JSTypedArrayPrint(os);
307       break;
308     case JS_DATA_VIEW_TYPE:
309       JSDataView::cast(this)->JSDataViewPrint(os);
310       break;
311 #ifdef V8_INTL_SUPPORT
312     case JS_INTL_COLLATOR_TYPE:
313       JSCollator::cast(this)->JSCollatorPrint(os);
314       break;
315     case JS_INTL_LIST_FORMAT_TYPE:
316       JSListFormat::cast(this)->JSListFormatPrint(os);
317       break;
318     case JS_INTL_LOCALE_TYPE:
319       JSLocale::cast(this)->JSLocalePrint(os);
320       break;
321     case JS_INTL_PLURAL_RULES_TYPE:
322       JSPluralRules::cast(this)->JSPluralRulesPrint(os);
323       break;
324     case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
325       JSRelativeTimeFormat::cast(this)->JSRelativeTimeFormatPrint(os);
326       break;
327 #endif  // V8_INTL_SUPPORT
328 #define MAKE_STRUCT_CASE(NAME, Name, name) \
329   case NAME##_TYPE:                        \
330     Name::cast(this)->Name##Print(os);     \
331     break;
332   STRUCT_LIST(MAKE_STRUCT_CASE)
333 #undef MAKE_STRUCT_CASE
334 
335     case ALLOCATION_SITE_TYPE:
336       AllocationSite::cast(this)->AllocationSitePrint(os);
337       break;
338     case LOAD_HANDLER_TYPE:
339       LoadHandler::cast(this)->LoadHandlerPrint(os);
340       break;
341     case STORE_HANDLER_TYPE:
342       StoreHandler::cast(this)->StoreHandlerPrint(os);
343       break;
344     case SCOPE_INFO_TYPE:
345       ScopeInfo::cast(this)->ScopeInfoPrint(os);
346       break;
347     case FEEDBACK_METADATA_TYPE:
348       FeedbackMetadata::cast(this)->FeedbackMetadataPrint(os);
349       break;
350     case WEAK_FIXED_ARRAY_TYPE:
351       WeakFixedArray::cast(this)->WeakFixedArrayPrint(os);
352       break;
353     case WEAK_ARRAY_LIST_TYPE:
354       WeakArrayList::cast(this)->WeakArrayListPrint(os);
355       break;
356     case INTERNALIZED_STRING_TYPE:
357     case EXTERNAL_INTERNALIZED_STRING_TYPE:
358     case ONE_BYTE_INTERNALIZED_STRING_TYPE:
359     case EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
360     case EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
361     case SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE:
362     case SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
363     case SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
364     case STRING_TYPE:
365     case CONS_STRING_TYPE:
366     case EXTERNAL_STRING_TYPE:
367     case SLICED_STRING_TYPE:
368     case THIN_STRING_TYPE:
369     case ONE_BYTE_STRING_TYPE:
370     case CONS_ONE_BYTE_STRING_TYPE:
371     case EXTERNAL_ONE_BYTE_STRING_TYPE:
372     case SLICED_ONE_BYTE_STRING_TYPE:
373     case THIN_ONE_BYTE_STRING_TYPE:
374     case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
375     case SHORT_EXTERNAL_STRING_TYPE:
376     case SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE:
377     case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
378     case SMALL_ORDERED_HASH_MAP_TYPE:
379     case SMALL_ORDERED_HASH_SET_TYPE:
380     case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
381     case JS_STRING_ITERATOR_TYPE:
382       // TODO(all): Handle these types too.
383       os << "UNKNOWN TYPE " << map()->instance_type();
384       UNREACHABLE();
385       break;
386   }
387 }
388 
ByteArrayPrint(std::ostream & os)389 void ByteArray::ByteArrayPrint(std::ostream& os) {  // NOLINT
390   os << "byte array, data starts at " << GetDataStartAddress();
391 }
392 
BytecodeArrayPrint(std::ostream & os)393 void BytecodeArray::BytecodeArrayPrint(std::ostream& os) {  // NOLINT
394   HeapObject::PrintHeader(os, "BytecodeArray");
395   Disassemble(os);
396 }
397 
398 
FreeSpacePrint(std::ostream & os)399 void FreeSpace::FreeSpacePrint(std::ostream& os) {  // NOLINT
400   os << "free space, size " << Size();
401 }
402 
403 
404 template <class Traits>
FixedTypedArrayPrint(std::ostream & os)405 void FixedTypedArray<Traits>::FixedTypedArrayPrint(
406     std::ostream& os) {  // NOLINT
407   os << "fixed " << Traits::Designator();
408 }
409 
PrintProperties(std::ostream & os)410 bool JSObject::PrintProperties(std::ostream& os) {  // NOLINT
411   if (HasFastProperties()) {
412     DescriptorArray* descs = map()->instance_descriptors();
413     int nof_inobject_properties = map()->GetInObjectProperties();
414     int i = 0;
415     for (; i < map()->NumberOfOwnDescriptors(); i++) {
416       os << "\n    ";
417       descs->GetKey(i)->NamePrint(os);
418       os << ": ";
419       PropertyDetails details = descs->GetDetails(i);
420       switch (details.location()) {
421         case kField: {
422           FieldIndex field_index = FieldIndex::ForDescriptor(map(), i);
423           if (IsUnboxedDoubleField(field_index)) {
424             os << "<unboxed double> " << RawFastDoublePropertyAt(field_index);
425           } else {
426             os << Brief(RawFastPropertyAt(field_index));
427           }
428           break;
429         }
430         case kDescriptor:
431           os << Brief(descs->GetStrongValue(i));
432           break;
433       }
434       os << " ";
435       details.PrintAsFastTo(os, PropertyDetails::kForProperties);
436       if (details.location() != kField) continue;
437       int field_index = details.field_index();
438       if (nof_inobject_properties <= field_index) {
439         field_index -= nof_inobject_properties;
440         os << " properties[" << field_index << "]";
441       }
442     }
443     return i > 0;
444   } else if (IsJSGlobalObject()) {
445     JSGlobalObject::cast(this)->global_dictionary()->Print(os);
446   } else {
447     property_dictionary()->Print(os);
448   }
449   return true;
450 }
451 
452 namespace {
453 
454 template <class T>
IsTheHoleAt(T * array,int index)455 bool IsTheHoleAt(T* array, int index) {
456   return false;
457 }
458 
459 template <>
IsTheHoleAt(FixedDoubleArray * array,int index)460 bool IsTheHoleAt(FixedDoubleArray* array, int index) {
461   return array->is_the_hole(index);
462 }
463 
464 template <class T>
GetScalarElement(T * array,int index)465 double GetScalarElement(T* array, int index) {
466   if (IsTheHoleAt(array, index)) {
467     return std::numeric_limits<double>::quiet_NaN();
468   }
469   return array->get_scalar(index);
470 }
471 
472 template <class T>
DoPrintElements(std::ostream & os,Object * object)473 void DoPrintElements(std::ostream& os, Object* object) {  // NOLINT
474   const bool print_the_hole = std::is_same<T, FixedDoubleArray>::value;
475   T* array = T::cast(object);
476   if (array->length() == 0) return;
477   int previous_index = 0;
478   double previous_value = GetScalarElement(array, 0);
479   double value = 0.0;
480   int i;
481   for (i = 1; i <= array->length(); i++) {
482     if (i < array->length()) value = GetScalarElement(array, i);
483     bool values_are_nan = std::isnan(previous_value) && std::isnan(value);
484     if (i != array->length() && (previous_value == value || values_are_nan) &&
485         IsTheHoleAt(array, i - 1) == IsTheHoleAt(array, i)) {
486       continue;
487     }
488     os << "\n";
489     std::stringstream ss;
490     ss << previous_index;
491     if (previous_index != i - 1) {
492       ss << '-' << (i - 1);
493     }
494     os << std::setw(12) << ss.str() << ": ";
495     if (print_the_hole && IsTheHoleAt(array, i - 1)) {
496       os << "<the_hole>";
497     } else {
498       os << previous_value;
499     }
500     previous_index = i;
501     previous_value = value;
502   }
503 }
504 
505 template <typename T>
PrintFixedArrayElements(std::ostream & os,T * array)506 void PrintFixedArrayElements(std::ostream& os, T* array) {
507   // Print in array notation for non-sparse arrays.
508   Object* previous_value = array->length() > 0 ? array->get(0) : nullptr;
509   Object* value = nullptr;
510   int previous_index = 0;
511   int i;
512   for (i = 1; i <= array->length(); i++) {
513     if (i < array->length()) value = array->get(i);
514     if (previous_value == value && i != array->length()) {
515       continue;
516     }
517     os << "\n";
518     std::stringstream ss;
519     ss << previous_index;
520     if (previous_index != i - 1) {
521       ss << '-' << (i - 1);
522     }
523     os << std::setw(12) << ss.str() << ": " << Brief(previous_value);
524     previous_index = i;
525     previous_value = value;
526   }
527 }
528 
PrintDictionaryElements(std::ostream & os,FixedArrayBase * elements)529 void PrintDictionaryElements(std::ostream& os, FixedArrayBase* elements) {
530   // Print some internal fields
531   NumberDictionary* dict = NumberDictionary::cast(elements);
532   if (dict->requires_slow_elements()) {
533     os << "\n   - requires_slow_elements";
534   } else {
535     os << "\n   - max_number_key: " << dict->max_number_key();
536   }
537   dict->Print(os);
538 }
539 
PrintSloppyArgumentElements(std::ostream & os,ElementsKind kind,SloppyArgumentsElements * elements)540 void PrintSloppyArgumentElements(std::ostream& os, ElementsKind kind,
541                                  SloppyArgumentsElements* elements) {
542   FixedArray* arguments_store = elements->arguments();
543   os << "\n    0: context: " << Brief(elements->context())
544      << "\n    1: arguments_store: " << Brief(arguments_store)
545      << "\n    parameter to context slot map:";
546   for (uint32_t i = 0; i < elements->parameter_map_length(); i++) {
547     uint32_t raw_index = i + SloppyArgumentsElements::kParameterMapStart;
548     Object* mapped_entry = elements->get_mapped_entry(i);
549     os << "\n    " << raw_index << ": param(" << i
550        << "): " << Brief(mapped_entry);
551     if (mapped_entry->IsTheHole()) {
552       os << " in the arguments_store[" << i << "]";
553     } else {
554       os << " in the context";
555     }
556   }
557   if (arguments_store->length() == 0) return;
558   os << "\n }"
559      << "\n - arguments_store: " << Brief(arguments_store) << " "
560      << ElementsKindToString(arguments_store->map()->elements_kind()) << " {";
561   if (kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS) {
562     PrintFixedArrayElements(os, arguments_store);
563   } else {
564     DCHECK_EQ(kind, SLOW_SLOPPY_ARGUMENTS_ELEMENTS);
565     PrintDictionaryElements(os, arguments_store);
566   }
567 }
568 
569 }  // namespace
570 
PrintElements(std::ostream & os)571 void JSObject::PrintElements(std::ostream& os) {  // NOLINT
572   // Don't call GetElementsKind, its validation code can cause the printer to
573   // fail when debugging.
574   os << " - elements: " << Brief(elements()) << " {";
575   if (elements()->length() == 0) {
576     os << " }\n";
577     return;
578   }
579   switch (map()->elements_kind()) {
580     case HOLEY_SMI_ELEMENTS:
581     case PACKED_SMI_ELEMENTS:
582     case HOLEY_ELEMENTS:
583     case PACKED_ELEMENTS:
584     case FAST_STRING_WRAPPER_ELEMENTS: {
585       PrintFixedArrayElements(os, FixedArray::cast(elements()));
586       break;
587     }
588     case HOLEY_DOUBLE_ELEMENTS:
589     case PACKED_DOUBLE_ELEMENTS: {
590       DoPrintElements<FixedDoubleArray>(os, elements());
591       break;
592     }
593 
594 #define PRINT_ELEMENTS(Type, type, TYPE, elementType)    \
595   case TYPE##_ELEMENTS: {                                \
596     DoPrintElements<Fixed##Type##Array>(os, elements()); \
597     break;                                               \
598   }
599       TYPED_ARRAYS(PRINT_ELEMENTS)
600 #undef PRINT_ELEMENTS
601 
602     case DICTIONARY_ELEMENTS:
603     case SLOW_STRING_WRAPPER_ELEMENTS:
604       PrintDictionaryElements(os, elements());
605       break;
606     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
607     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
608       PrintSloppyArgumentElements(os, map()->elements_kind(),
609                                   SloppyArgumentsElements::cast(elements()));
610       break;
611     case NO_ELEMENTS:
612       break;
613   }
614   os << "\n }\n";
615 }
616 
JSObjectPrintHeader(std::ostream & os,JSObject * obj,const char * id)617 static void JSObjectPrintHeader(std::ostream& os, JSObject* obj,
618                                 const char* id) {  // NOLINT
619   Isolate* isolate = obj->GetIsolate();
620   obj->PrintHeader(os, id);
621   // Don't call GetElementsKind, its validation code can cause the printer to
622   // fail when debugging.
623   os << " [";
624   if (obj->HasFastProperties()) {
625     os << "FastProperties";
626   } else {
627     os << "DictionaryProperties";
628   }
629   PrototypeIterator iter(isolate, obj);
630   os << "]\n - prototype: " << Brief(iter.GetCurrent());
631   os << "\n - elements: " << Brief(obj->elements()) << " ["
632      << ElementsKindToString(obj->map()->elements_kind());
633   if (obj->elements()->IsCowArray()) os << " (COW)";
634   os << "]";
635   Object* hash = obj->GetHash();
636   if (hash->IsSmi()) {
637     os << "\n - hash: " << Brief(hash);
638   }
639   if (obj->GetEmbedderFieldCount() > 0) {
640     os << "\n - embedder fields: " << obj->GetEmbedderFieldCount();
641   }
642 }
643 
JSObjectPrintBody(std::ostream & os,JSObject * obj,bool print_elements=true)644 static void JSObjectPrintBody(std::ostream& os,
645                               JSObject* obj,  // NOLINT
646                               bool print_elements = true) {
647   os << "\n - properties: ";
648   Object* properties_or_hash = obj->raw_properties_or_hash();
649   if (!properties_or_hash->IsSmi()) {
650     os << Brief(properties_or_hash);
651   }
652   os << " {";
653   if (obj->PrintProperties(os)) os << "\n ";
654   os << "}\n";
655   if (print_elements && obj->elements()->length() > 0) {
656     obj->PrintElements(os);
657   }
658   int embedder_fields = obj->GetEmbedderFieldCount();
659   if (embedder_fields > 0) {
660     os << " - embedder fields = {";
661     for (int i = 0; i < embedder_fields; i++) {
662       os << "\n    " << obj->GetEmbedderField(i);
663     }
664     os << "\n }\n";
665   }
666 }
667 
JSObjectPrint(std::ostream & os)668 void JSObject::JSObjectPrint(std::ostream& os) {  // NOLINT
669   JSObjectPrintHeader(os, this, nullptr);
670   JSObjectPrintBody(os, this);
671 }
672 
JSGeneratorObjectPrint(std::ostream & os)673 void JSGeneratorObject::JSGeneratorObjectPrint(std::ostream& os) {  // NOLINT
674   JSObjectPrintHeader(os, this, "JSGeneratorObject");
675   os << "\n - function: " << Brief(function());
676   os << "\n - context: " << Brief(context());
677   os << "\n - receiver: " << Brief(receiver());
678   if (is_executing() || is_closed()) {
679     os << "\n - input: " << Brief(input_or_debug_pos());
680   } else {
681     DCHECK(is_suspended());
682     os << "\n - debug pos: " << Brief(input_or_debug_pos());
683   }
684   const char* mode = "(invalid)";
685   switch (resume_mode()) {
686     case kNext:
687       mode = ".next()";
688       break;
689     case kReturn:
690       mode = ".return()";
691       break;
692     case kThrow:
693       mode = ".throw()";
694       break;
695   }
696   os << "\n - resume mode: " << mode;
697   os << "\n - continuation: " << continuation();
698   if (is_closed()) os << " (closed)";
699   if (is_executing()) os << " (executing)";
700   if (is_suspended()) os << " (suspended)";
701   if (is_suspended()) {
702     DisallowHeapAllocation no_gc;
703     SharedFunctionInfo* fun_info = function()->shared();
704     if (fun_info->HasSourceCode()) {
705       Script* script = Script::cast(fun_info->script());
706       int lin = script->GetLineNumber(source_position()) + 1;
707       int col = script->GetColumnNumber(source_position()) + 1;
708       String* script_name = script->name()->IsString()
709                                 ? String::cast(script->name())
710                                 : GetReadOnlyRoots().empty_string();
711       os << "\n - source position: " << source_position();
712       os << " (";
713       script_name->PrintUC16(os);
714       os << ", lin " << lin;
715       os << ", col " << col;
716       os << ")";
717     }
718   }
719   os << "\n - register file: " << Brief(parameters_and_registers());
720   os << "\n";
721 }
722 
JSArrayPrint(std::ostream & os)723 void JSArray::JSArrayPrint(std::ostream& os) {  // NOLINT
724   JSObjectPrintHeader(os, this, "JSArray");
725   os << "\n - length: " << Brief(this->length());
726   JSObjectPrintBody(os, this);
727 }
728 
JSPromisePrint(std::ostream & os)729 void JSPromise::JSPromisePrint(std::ostream& os) {  // NOLINT
730   JSObjectPrintHeader(os, this, "JSPromise");
731   os << "\n - status: " << JSPromise::Status(status());
732   if (status() == Promise::kPending) {
733     os << "\n - reactions: " << Brief(reactions());
734   } else {
735     os << "\n - result: " << Brief(result());
736   }
737   os << "\n - has_handler: " << has_handler();
738   os << "\n ";
739 }
740 
JSRegExpPrint(std::ostream & os)741 void JSRegExp::JSRegExpPrint(std::ostream& os) {  // NOLINT
742   JSObjectPrintHeader(os, this, "JSRegExp");
743   os << "\n - data: " << Brief(data());
744   os << "\n - source: " << Brief(source());
745   JSObjectPrintBody(os, this);
746 }
747 
JSRegExpStringIteratorPrint(std::ostream & os)748 void JSRegExpStringIterator::JSRegExpStringIteratorPrint(
749     std::ostream& os) {  // NOLINT
750   JSObjectPrintHeader(os, this, "JSRegExpStringIterator");
751   os << "\n - regex: " << Brief(iterating_regexp());
752   os << "\n - string: " << Brief(iterating_string());
753   os << "\n - done: " << done();
754   os << "\n - global: " << global();
755   os << "\n - unicode: " << unicode();
756   JSObjectPrintBody(os, this);
757 }
758 
SymbolPrint(std::ostream & os)759 void Symbol::SymbolPrint(std::ostream& os) {  // NOLINT
760   HeapObject::PrintHeader(os, "Symbol");
761   os << "\n - hash: " << Hash();
762   os << "\n - name: " << Brief(name());
763   if (name()->IsUndefined()) {
764     os << " (" << PrivateSymbolToName() << ")";
765   }
766   os << "\n - private: " << is_private();
767   os << "\n";
768 }
769 
MapPrint(std::ostream & os)770 void Map::MapPrint(std::ostream& os) {  // NOLINT
771   HeapObject::PrintHeader(os, "Map");
772   os << "\n - type: " << instance_type();
773   os << "\n - instance size: ";
774   if (instance_size() == kVariableSizeSentinel) {
775     os << "variable";
776   } else {
777     os << instance_size();
778   }
779   if (IsJSObjectMap()) {
780     os << "\n - inobject properties: " << GetInObjectProperties();
781   }
782   os << "\n - elements kind: " << ElementsKindToString(elements_kind());
783   os << "\n - unused property fields: " << UnusedPropertyFields();
784   os << "\n - enum length: ";
785   if (EnumLength() == kInvalidEnumCacheSentinel) {
786     os << "invalid";
787   } else {
788     os << EnumLength();
789   }
790   if (is_deprecated()) os << "\n - deprecated_map";
791   if (is_stable()) os << "\n - stable_map";
792   if (is_migration_target()) os << "\n - migration_target";
793   if (is_dictionary_map()) os << "\n - dictionary_map";
794   if (has_hidden_prototype()) os << "\n - has_hidden_prototype";
795   if (has_named_interceptor()) os << "\n - named_interceptor";
796   if (has_indexed_interceptor()) os << "\n - indexed_interceptor";
797   if (may_have_interesting_symbols()) os << "\n - may_have_interesting_symbols";
798   if (is_undetectable()) os << "\n - undetectable";
799   if (is_callable()) os << "\n - callable";
800   if (is_constructor()) os << "\n - constructor";
801   if (has_prototype_slot()) {
802     os << "\n - has_prototype_slot";
803     if (has_non_instance_prototype()) os << " (non-instance prototype)";
804   }
805   if (is_access_check_needed()) os << "\n - access_check_needed";
806   if (!is_extensible()) os << "\n - non-extensible";
807   if (is_prototype_map()) {
808     os << "\n - prototype_map";
809     os << "\n - prototype info: " << Brief(prototype_info());
810   } else {
811     os << "\n - back pointer: " << Brief(GetBackPointer());
812   }
813   os << "\n - prototype_validity cell: " << Brief(prototype_validity_cell());
814   os << "\n - instance descriptors " << (owns_descriptors() ? "(own) " : "")
815      << "#" << NumberOfOwnDescriptors() << ": "
816      << Brief(instance_descriptors());
817   if (FLAG_unbox_double_fields) {
818     os << "\n - layout descriptor: ";
819     layout_descriptor()->ShortPrint(os);
820   }
821 
822   Isolate* isolate;
823   // Read-only maps can't have transitions, which is fortunate because we need
824   // the isolate to iterate over the transitions.
825   if (Isolate::FromWritableHeapObject(this, &isolate)) {
826     DisallowHeapAllocation no_gc;
827     TransitionsAccessor transitions(isolate, this, &no_gc);
828     int nof_transitions = transitions.NumberOfTransitions();
829     if (nof_transitions > 0) {
830       os << "\n - transitions #" << nof_transitions << ": ";
831       HeapObject* heap_object;
832       Smi* smi;
833       if (raw_transitions()->ToSmi(&smi)) {
834         os << Brief(smi);
835       } else if (raw_transitions()->ToStrongOrWeakHeapObject(&heap_object)) {
836         os << Brief(heap_object);
837       }
838       transitions.PrintTransitions(os);
839     }
840   }
841   os << "\n - prototype: " << Brief(prototype());
842   os << "\n - constructor: " << Brief(GetConstructor());
843   os << "\n - dependent code: " << Brief(dependent_code());
844   os << "\n - construction counter: " << construction_counter();
845   os << "\n";
846 }
847 
DescriptorArrayPrint(std::ostream & os)848 void DescriptorArray::DescriptorArrayPrint(std::ostream& os) {
849   HeapObject::PrintHeader(os, "DescriptorArray");
850   os << "\n - capacity: " << length();
851   EnumCache* enum_cache = GetEnumCache();
852   os << "\n - enum_cache: ";
853   if (enum_cache->keys()->length() == 0) {
854     os << "empty";
855   } else {
856     os << enum_cache->keys()->length();
857     os << "\n   - keys: " << Brief(enum_cache->keys());
858     os << "\n   - indices: " << Brief(enum_cache->indices());
859   }
860   os << "\n - nof descriptors: " << number_of_descriptors();
861   PrintDescriptors(os);
862 }
863 
AliasedArgumentsEntryPrint(std::ostream & os)864 void AliasedArgumentsEntry::AliasedArgumentsEntryPrint(
865     std::ostream& os) {  // NOLINT
866   HeapObject::PrintHeader(os, "AliasedArgumentsEntry");
867   os << "\n - aliased_context_slot: " << aliased_context_slot();
868 }
869 
870 namespace {
PrintFixedArrayWithHeader(std::ostream & os,FixedArray * array,const char * type)871 void PrintFixedArrayWithHeader(std::ostream& os, FixedArray* array,
872                                const char* type) {
873   array->PrintHeader(os, type);
874   os << "\n - length: " << array->length();
875   PrintFixedArrayElements(os, array);
876   os << "\n";
877 }
878 
879 template <typename T>
PrintHashTableWithHeader(std::ostream & os,T * table,const char * type)880 void PrintHashTableWithHeader(std::ostream& os, T* table, const char* type) {
881   table->PrintHeader(os, type);
882   os << "\n - length: " << table->length();
883   os << "\n - elements: " << table->NumberOfElements();
884   os << "\n - deleted: " << table->NumberOfDeletedElements();
885   os << "\n - capacity: " << table->Capacity();
886 
887   os << "\n - elements: {";
888   for (int i = 0; i < table->Capacity(); i++) {
889     os << '\n'
890        << std::setw(12) << i << ": " << Brief(table->KeyAt(i)) << " -> "
891        << Brief(table->ValueAt(i));
892   }
893   os << "\n }\n";
894 }
895 
896 template <typename T>
PrintWeakArrayElements(std::ostream & os,T * array)897 void PrintWeakArrayElements(std::ostream& os, T* array) {
898   // Print in array notation for non-sparse arrays.
899   MaybeObject* previous_value = array->length() > 0 ? array->Get(0) : nullptr;
900   MaybeObject* value = nullptr;
901   int previous_index = 0;
902   int i;
903   for (i = 1; i <= array->length(); i++) {
904     if (i < array->length()) value = array->Get(i);
905     if (previous_value == value && i != array->length()) {
906       continue;
907     }
908     os << "\n";
909     std::stringstream ss;
910     ss << previous_index;
911     if (previous_index != i - 1) {
912       ss << '-' << (i - 1);
913     }
914     os << std::setw(12) << ss.str() << ": " << Brief(previous_value);
915     previous_index = i;
916     previous_value = value;
917   }
918 }
919 
920 }  // namespace
921 
FixedArrayPrint(std::ostream & os)922 void FixedArray::FixedArrayPrint(std::ostream& os) {  // NOLINT
923   PrintFixedArrayWithHeader(os, this, "FixedArray");
924 }
925 
ObjectHashTablePrint(std::ostream & os)926 void ObjectHashTable::ObjectHashTablePrint(std::ostream& os) {
927   PrintHashTableWithHeader(os, this, "ObjectHashTable");
928 }
929 
NumberDictionaryPrint(std::ostream & os)930 void NumberDictionary::NumberDictionaryPrint(std::ostream& os) {
931   PrintHashTableWithHeader(os, this, "NumberDictionary");
932 }
933 
EphemeronHashTablePrint(std::ostream & os)934 void EphemeronHashTable::EphemeronHashTablePrint(std::ostream& os) {
935   PrintHashTableWithHeader(os, this, "EphemeronHashTable");
936 }
937 
ObjectBoilerplateDescriptionPrint(std::ostream & os)938 void ObjectBoilerplateDescription::ObjectBoilerplateDescriptionPrint(
939     std::ostream& os) {
940   PrintFixedArrayWithHeader(os, this, "ObjectBoilerplateDescription");
941 }
942 
PropertyArrayPrint(std::ostream & os)943 void PropertyArray::PropertyArrayPrint(std::ostream& os) {  // NOLINT
944   HeapObject::PrintHeader(os, "PropertyArray");
945   os << "\n - length: " << length();
946   os << "\n - hash: " << Hash();
947   PrintFixedArrayElements(os, this);
948   os << "\n";
949 }
950 
FixedDoubleArrayPrint(std::ostream & os)951 void FixedDoubleArray::FixedDoubleArrayPrint(std::ostream& os) {  // NOLINT
952   HeapObject::PrintHeader(os, "FixedDoubleArray");
953   os << "\n - length: " << length();
954   DoPrintElements<FixedDoubleArray>(os, this);
955   os << "\n";
956 }
957 
WeakFixedArrayPrint(std::ostream & os)958 void WeakFixedArray::WeakFixedArrayPrint(std::ostream& os) {
959   PrintHeader(os, "WeakFixedArray");
960   os << "\n - length: " << length() << "\n";
961   PrintWeakArrayElements(os, this);
962   os << "\n";
963 }
964 
WeakArrayListPrint(std::ostream & os)965 void WeakArrayList::WeakArrayListPrint(std::ostream& os) {
966   PrintHeader(os, "WeakArrayList");
967   os << "\n - capacity: " << capacity();
968   os << "\n - length: " << length() << "\n";
969   PrintWeakArrayElements(os, this);
970   os << "\n";
971 }
972 
TransitionArrayPrint(std::ostream & os)973 void TransitionArray::TransitionArrayPrint(std::ostream& os) {  // NOLINT
974   HeapObject::PrintHeader(os, "TransitionArray");
975   PrintInternal(os);
976 }
977 
FeedbackCellPrint(std::ostream & os)978 void FeedbackCell::FeedbackCellPrint(std::ostream& os) {  // NOLINT
979   HeapObject::PrintHeader(os, "FeedbackCell");
980   ReadOnlyRoots roots = GetReadOnlyRoots();
981   if (map() == roots.no_closures_cell_map()) {
982     os << "\n - no closures";
983   } else if (map() == roots.one_closure_cell_map()) {
984     os << "\n - one closure";
985   } else if (map() == roots.many_closures_cell_map()) {
986     os << "\n - many closures";
987   } else {
988     os << "\n - Invalid FeedbackCell map";
989   }
990   os << " - value: " << Brief(value());
991   os << "\n";
992 }
993 
Print()994 void FeedbackVectorSpec::Print() {
995   StdoutStream os;
996 
997   FeedbackVectorSpecPrint(os);
998 
999   os << std::flush;
1000 }
1001 
FeedbackVectorSpecPrint(std::ostream & os)1002 void FeedbackVectorSpec::FeedbackVectorSpecPrint(std::ostream& os) {  // NOLINT
1003   int slot_count = slots();
1004   os << " - slot_count: " << slot_count;
1005   if (slot_count == 0) {
1006     os << " (empty)\n";
1007     return;
1008   }
1009 
1010   for (int slot = 0; slot < slot_count;) {
1011     FeedbackSlotKind kind = GetKind(FeedbackSlot(slot));
1012     int entry_size = FeedbackMetadata::GetSlotSize(kind);
1013     DCHECK_LT(0, entry_size);
1014     os << "\n Slot #" << slot << " " << kind;
1015     slot += entry_size;
1016   }
1017   os << "\n";
1018 }
1019 
FeedbackMetadataPrint(std::ostream & os)1020 void FeedbackMetadata::FeedbackMetadataPrint(std::ostream& os) {
1021   HeapObject::PrintHeader(os, "FeedbackMetadata");
1022   os << "\n - slot_count: " << slot_count();
1023 
1024   FeedbackMetadataIterator iter(this);
1025   while (iter.HasNext()) {
1026     FeedbackSlot slot = iter.Next();
1027     FeedbackSlotKind kind = iter.kind();
1028     os << "\n Slot " << slot << " " << kind;
1029   }
1030   os << "\n";
1031 }
1032 
FeedbackVectorPrint(std::ostream & os)1033 void FeedbackVector::FeedbackVectorPrint(std::ostream& os) {  // NOLINT
1034   HeapObject::PrintHeader(os, "FeedbackVector");
1035   os << "\n - length: " << length();
1036   if (length() == 0) {
1037     os << " (empty)\n";
1038     return;
1039   }
1040 
1041   os << "\n - shared function info: " << Brief(shared_function_info());
1042   os << "\n - optimized code/marker: ";
1043   if (has_optimized_code()) {
1044     os << Brief(optimized_code());
1045   } else {
1046     os << optimization_marker();
1047   }
1048   os << "\n - invocation count: " << invocation_count();
1049   os << "\n - profiler ticks: " << profiler_ticks();
1050 
1051   FeedbackMetadataIterator iter(metadata());
1052   while (iter.HasNext()) {
1053     FeedbackSlot slot = iter.Next();
1054     FeedbackSlotKind kind = iter.kind();
1055 
1056     os << "\n - slot " << slot << " " << kind << " ";
1057     FeedbackSlotPrint(os, slot);
1058 
1059     int entry_size = iter.entry_size();
1060     if (entry_size > 0) os << " {";
1061     for (int i = 0; i < entry_size; i++) {
1062       int index = GetIndex(slot) + i;
1063       os << "\n     [" << index << "]: " << Brief(get(index));
1064     }
1065     if (entry_size > 0) os << "\n  }";
1066   }
1067   os << "\n";
1068 }
1069 
FeedbackSlotPrint(std::ostream & os,FeedbackSlot slot)1070 void FeedbackVector::FeedbackSlotPrint(std::ostream& os,
1071                                        FeedbackSlot slot) {  // NOLINT
1072   FeedbackNexus nexus(this, slot);
1073   nexus.Print(os);
1074 }
1075 
1076 namespace {
1077 
ICState2String(InlineCacheState state)1078 const char* ICState2String(InlineCacheState state) {
1079   switch (state) {
1080     case UNINITIALIZED:
1081       return "UNINITIALIZED";
1082     case PREMONOMORPHIC:
1083       return "PREMONOMORPHIC";
1084     case MONOMORPHIC:
1085       return "MONOMORPHIC";
1086     case RECOMPUTE_HANDLER:
1087       return "RECOMPUTE_HANDLER";
1088     case POLYMORPHIC:
1089       return "POLYMORPHIC";
1090     case MEGAMORPHIC:
1091       return "MEGAMORPHIC";
1092     case GENERIC:
1093       return "GENERIC";
1094   }
1095   UNREACHABLE();
1096 }
1097 }  // anonymous namespace
1098 
Print(std::ostream & os)1099 void FeedbackNexus::Print(std::ostream& os) {  // NOLINT
1100   switch (kind()) {
1101     case FeedbackSlotKind::kCall:
1102     case FeedbackSlotKind::kLoadProperty:
1103     case FeedbackSlotKind::kLoadKeyed:
1104     case FeedbackSlotKind::kLoadGlobalInsideTypeof:
1105     case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
1106     case FeedbackSlotKind::kStoreNamedSloppy:
1107     case FeedbackSlotKind::kStoreNamedStrict:
1108     case FeedbackSlotKind::kStoreOwnNamed:
1109     case FeedbackSlotKind::kStoreGlobalSloppy:
1110     case FeedbackSlotKind::kStoreGlobalStrict:
1111     case FeedbackSlotKind::kStoreKeyedSloppy:
1112     case FeedbackSlotKind::kInstanceOf:
1113     case FeedbackSlotKind::kStoreDataPropertyInLiteral:
1114     case FeedbackSlotKind::kStoreKeyedStrict:
1115     case FeedbackSlotKind::kStoreInArrayLiteral:
1116     case FeedbackSlotKind::kCloneObject: {
1117       os << ICState2String(StateFromFeedback());
1118       break;
1119     }
1120     case FeedbackSlotKind::kBinaryOp: {
1121       os << "BinaryOp:" << GetBinaryOperationFeedback();
1122       break;
1123     }
1124     case FeedbackSlotKind::kCompareOp: {
1125       os << "CompareOp:" << GetCompareOperationFeedback();
1126       break;
1127     }
1128     case FeedbackSlotKind::kForIn: {
1129       os << "ForIn:" << GetForInFeedback();
1130       break;
1131     }
1132     case FeedbackSlotKind::kCreateClosure:
1133     case FeedbackSlotKind::kLiteral:
1134     case FeedbackSlotKind::kTypeProfile:
1135       break;
1136     case FeedbackSlotKind::kInvalid:
1137     case FeedbackSlotKind::kKindsNumber:
1138       UNREACHABLE();
1139       break;
1140   }
1141 }
1142 
JSValuePrint(std::ostream & os)1143 void JSValue::JSValuePrint(std::ostream& os) {  // NOLINT
1144   JSObjectPrintHeader(os, this, "JSValue");
1145   os << "\n - value: " << Brief(value());
1146   JSObjectPrintBody(os, this);
1147 }
1148 
JSMessageObjectPrint(std::ostream & os)1149 void JSMessageObject::JSMessageObjectPrint(std::ostream& os) {  // NOLINT
1150   JSObjectPrintHeader(os, this, "JSMessageObject");
1151   os << "\n - type: " << type();
1152   os << "\n - arguments: " << Brief(argument());
1153   os << "\n - start_position: " << start_position();
1154   os << "\n - end_position: " << end_position();
1155   os << "\n - script: " << Brief(script());
1156   os << "\n - stack_frames: " << Brief(stack_frames());
1157   JSObjectPrintBody(os, this);
1158 }
1159 
1160 
StringPrint(std::ostream & os)1161 void String::StringPrint(std::ostream& os) {  // NOLINT
1162   if (!HasOnlyOneByteChars()) {
1163     os << "u";
1164   }
1165   if (StringShape(this).IsInternalized()) {
1166     os << "#";
1167   } else if (StringShape(this).IsCons()) {
1168     os << "c\"";
1169   } else if (StringShape(this).IsThin()) {
1170     os << ">\"";
1171   } else {
1172     os << "\"";
1173   }
1174 
1175   const char truncated_epilogue[] = "...<truncated>";
1176   int len = length();
1177   if (!FLAG_use_verbose_printer) {
1178     if (len > 100) {
1179       len = 100 - sizeof(truncated_epilogue);
1180     }
1181   }
1182   for (int i = 0; i < len; i++) {
1183     os << AsUC16(Get(i));
1184   }
1185   if (len != length()) {
1186     os << truncated_epilogue;
1187   }
1188 
1189   if (!StringShape(this).IsInternalized()) os << "\"";
1190 }
1191 
1192 
NamePrint(std::ostream & os)1193 void Name::NamePrint(std::ostream& os) {  // NOLINT
1194   if (IsString()) {
1195     String::cast(this)->StringPrint(os);
1196   } else {
1197     os << Brief(this);
1198   }
1199 }
1200 
1201 
1202 static const char* const weekdays[] = {
1203   "???", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
1204 };
1205 
JSDatePrint(std::ostream & os)1206 void JSDate::JSDatePrint(std::ostream& os) {  // NOLINT
1207   JSObjectPrintHeader(os, this, "JSDate");
1208   os << "\n - value: " << Brief(value());
1209   if (!year()->IsSmi()) {
1210     os << "\n - time = NaN\n";
1211   } else {
1212     // TODO(svenpanne) Add some basic formatting to our streams.
1213     ScopedVector<char> buf(100);
1214     SNPrintF(buf, "\n - time = %s %04d/%02d/%02d %02d:%02d:%02d\n",
1215              weekdays[weekday()->IsSmi() ? Smi::ToInt(weekday()) + 1 : 0],
1216              year()->IsSmi() ? Smi::ToInt(year()) : -1,
1217              month()->IsSmi() ? Smi::ToInt(month()) : -1,
1218              day()->IsSmi() ? Smi::ToInt(day()) : -1,
1219              hour()->IsSmi() ? Smi::ToInt(hour()) : -1,
1220              min()->IsSmi() ? Smi::ToInt(min()) : -1,
1221              sec()->IsSmi() ? Smi::ToInt(sec()) : -1);
1222     os << buf.start();
1223   }
1224   JSObjectPrintBody(os, this);
1225 }
1226 
1227 
JSProxyPrint(std::ostream & os)1228 void JSProxy::JSProxyPrint(std::ostream& os) {  // NOLINT
1229   HeapObject::PrintHeader(os, "JSProxy");
1230   os << "\n - target: ";
1231   target()->ShortPrint(os);
1232   os << "\n - handler: ";
1233   handler()->ShortPrint(os);
1234   os << "\n";
1235 }
1236 
JSSetPrint(std::ostream & os)1237 void JSSet::JSSetPrint(std::ostream& os) {  // NOLINT
1238   JSObjectPrintHeader(os, this, "JSSet");
1239   os << " - table: " << Brief(table());
1240   JSObjectPrintBody(os, this);
1241 }
1242 
JSMapPrint(std::ostream & os)1243 void JSMap::JSMapPrint(std::ostream& os) {  // NOLINT
1244   JSObjectPrintHeader(os, this, "JSMap");
1245   os << " - table: " << Brief(table());
1246   JSObjectPrintBody(os, this);
1247 }
1248 
JSCollectionIteratorPrint(std::ostream & os)1249 void JSCollectionIterator::JSCollectionIteratorPrint(
1250     std::ostream& os) {  // NOLINT
1251   os << "\n - table: " << Brief(table());
1252   os << "\n - index: " << Brief(index());
1253   os << "\n";
1254 }
1255 
JSSetIteratorPrint(std::ostream & os)1256 void JSSetIterator::JSSetIteratorPrint(std::ostream& os) {  // NOLINT
1257   JSObjectPrintHeader(os, this, "JSSetIterator");
1258   JSCollectionIteratorPrint(os);
1259 }
1260 
JSMapIteratorPrint(std::ostream & os)1261 void JSMapIterator::JSMapIteratorPrint(std::ostream& os) {  // NOLINT
1262   JSObjectPrintHeader(os, this, "JSMapIterator");
1263   JSCollectionIteratorPrint(os);
1264 }
1265 
JSWeakMapPrint(std::ostream & os)1266 void JSWeakMap::JSWeakMapPrint(std::ostream& os) {  // NOLINT
1267   JSObjectPrintHeader(os, this, "JSWeakMap");
1268   os << "\n - table: " << Brief(table());
1269   JSObjectPrintBody(os, this);
1270 }
1271 
JSWeakSetPrint(std::ostream & os)1272 void JSWeakSet::JSWeakSetPrint(std::ostream& os) {  // NOLINT
1273   JSObjectPrintHeader(os, this, "JSWeakSet");
1274   os << "\n - table: " << Brief(table());
1275   JSObjectPrintBody(os, this);
1276 }
1277 
JSArrayBufferPrint(std::ostream & os)1278 void JSArrayBuffer::JSArrayBufferPrint(std::ostream& os) {  // NOLINT
1279   JSObjectPrintHeader(os, this, "JSArrayBuffer");
1280   os << "\n - backing_store: " << backing_store();
1281   os << "\n - byte_length: " << Brief(byte_length());
1282   if (is_external()) os << "\n - external";
1283   if (is_neuterable()) os << "\n - neuterable";
1284   if (was_neutered()) os << "\n - neutered";
1285   if (is_shared()) os << "\n - shared";
1286   if (is_wasm_memory()) os << "\n - is_wasm_memory";
1287   if (is_growable()) os << "\n - growable";
1288   JSObjectPrintBody(os, this, !was_neutered());
1289 }
1290 
JSTypedArrayPrint(std::ostream & os)1291 void JSTypedArray::JSTypedArrayPrint(std::ostream& os) {  // NOLINT
1292   JSObjectPrintHeader(os, this, "JSTypedArray");
1293   os << "\n - buffer: " << Brief(buffer());
1294   os << "\n - byte_offset: " << Brief(byte_offset());
1295   os << "\n - byte_length: " << Brief(byte_length());
1296   os << "\n - length: " << Brief(length());
1297   if (WasNeutered()) os << "\n - neutered";
1298   JSObjectPrintBody(os, this, !WasNeutered());
1299 }
1300 
JSArrayIteratorPrint(std::ostream & os)1301 void JSArrayIterator::JSArrayIteratorPrint(std::ostream& os) {  // NOLING
1302   JSObjectPrintHeader(os, this, "JSArrayIterator");
1303   os << "\n - iterated_object: " << Brief(iterated_object());
1304   os << "\n - next_index: " << Brief(next_index());
1305   os << "\n - kind: " << kind();
1306   JSObjectPrintBody(os, this);
1307 }
1308 
JSDataViewPrint(std::ostream & os)1309 void JSDataView::JSDataViewPrint(std::ostream& os) {  // NOLINT
1310   JSObjectPrintHeader(os, this, "JSDataView");
1311   os << "\n - buffer =" << Brief(buffer());
1312   os << "\n - byte_offset: " << Brief(byte_offset());
1313   os << "\n - byte_length: " << Brief(byte_length());
1314   if (WasNeutered()) os << "\n - neutered";
1315   JSObjectPrintBody(os, this, !WasNeutered());
1316 }
1317 
JSBoundFunctionPrint(std::ostream & os)1318 void JSBoundFunction::JSBoundFunctionPrint(std::ostream& os) {  // NOLINT
1319   JSObjectPrintHeader(os, this, "JSBoundFunction");
1320   os << "\n - bound_target_function: " << Brief(bound_target_function());
1321   os << "\n - bound_this: " << Brief(bound_this());
1322   os << "\n - bound_arguments: " << Brief(bound_arguments());
1323   JSObjectPrintBody(os, this);
1324 }
1325 
JSFunctionPrint(std::ostream & os)1326 void JSFunction::JSFunctionPrint(std::ostream& os) {  // NOLINT
1327   Isolate* isolate = GetIsolate();
1328   JSObjectPrintHeader(os, this, "Function");
1329   os << "\n - function prototype: ";
1330   if (has_prototype_slot()) {
1331     if (has_prototype()) {
1332       os << Brief(prototype());
1333       if (map()->has_non_instance_prototype()) {
1334         os << " (non-instance prototype)";
1335       }
1336     }
1337     os << "\n - initial_map: ";
1338     if (has_initial_map()) os << Brief(initial_map());
1339   } else {
1340     os << "<no-prototype-slot>";
1341   }
1342   os << "\n - shared_info: " << Brief(shared());
1343   os << "\n - name: " << Brief(shared()->Name());
1344 
1345   // Print Builtin name for builtin functions
1346   int builtin_index = code()->builtin_index();
1347   if (builtin_index != -1 && !IsInterpreted()) {
1348     if (builtin_index == Builtins::kDeserializeLazy) {
1349       if (shared()->HasBuiltinId()) {
1350         builtin_index = shared()->builtin_id();
1351         os << "\n - builtin: " << isolate->builtins()->name(builtin_index)
1352            << "(lazy)";
1353       }
1354     } else {
1355       os << "\n - builtin: " << isolate->builtins()->name(builtin_index);
1356     }
1357   }
1358 
1359   os << "\n - formal_parameter_count: "
1360      << shared()->internal_formal_parameter_count();
1361   os << "\n - kind: " << shared()->kind();
1362   os << "\n - context: " << Brief(context());
1363   os << "\n - code: " << Brief(code());
1364   if (IsInterpreted()) {
1365     os << "\n - interpreted";
1366     if (shared()->HasBytecodeArray()) {
1367       os << "\n - bytecode: " << shared()->GetBytecodeArray();
1368     }
1369   }
1370   if (WasmExportedFunction::IsWasmExportedFunction(this)) {
1371     WasmExportedFunction* function = WasmExportedFunction::cast(this);
1372     os << "\n - WASM instance "
1373        << reinterpret_cast<void*>(function->instance());
1374     os << "\n - WASM function index " << function->function_index();
1375   }
1376   shared()->PrintSourceCode(os);
1377   JSObjectPrintBody(os, this);
1378   os << "\n - feedback vector: ";
1379   if (!shared()->HasFeedbackMetadata()) {
1380     os << "feedback metadata is not available in SFI\n";
1381   } else if (has_feedback_vector()) {
1382     feedback_vector()->FeedbackVectorPrint(os);
1383   } else {
1384     os << "not available\n";
1385   }
1386 }
1387 
PrintSourceCode(std::ostream & os)1388 void SharedFunctionInfo::PrintSourceCode(std::ostream& os) {
1389   if (HasSourceCode()) {
1390     os << "\n - source code: ";
1391     String* source = String::cast(Script::cast(script())->source());
1392     int start = StartPosition();
1393     int length = EndPosition() - start;
1394     std::unique_ptr<char[]> source_string = source->ToCString(
1395         DISALLOW_NULLS, FAST_STRING_TRAVERSAL, start, length, nullptr);
1396     os << source_string.get();
1397   }
1398 }
1399 
SharedFunctionInfoPrint(std::ostream & os)1400 void SharedFunctionInfo::SharedFunctionInfoPrint(std::ostream& os) {  // NOLINT
1401   HeapObject::PrintHeader(os, "SharedFunctionInfo");
1402   os << "\n - name: ";
1403   if (HasSharedName()) {
1404     os << Brief(Name());
1405   } else {
1406     os << "<no-shared-name>";
1407   }
1408   if (HasInferredName()) {
1409     os << "\n - inferred name: " << Brief(inferred_name());
1410   }
1411   os << "\n - kind: " << kind();
1412   if (needs_home_object()) {
1413     os << "\n - needs_home_object";
1414   }
1415   os << "\n - function_map_index: " << function_map_index();
1416   os << "\n - formal_parameter_count: " << internal_formal_parameter_count();
1417   os << "\n - expected_nof_properties: " << expected_nof_properties();
1418   os << "\n - language_mode: " << language_mode();
1419   os << "\n - data: " << Brief(function_data());
1420   os << "\n - code (from data): " << Brief(GetCode());
1421   PrintSourceCode(os);
1422   // Script files are often large, hard to read.
1423   // os << "\n - script =";
1424   // script()->Print(os);
1425   if (is_named_expression()) {
1426     os << "\n - named expression";
1427   } else if (is_anonymous_expression()) {
1428     os << "\n - anonymous expression";
1429   } else if (is_declaration()) {
1430     os << "\n - declaration";
1431   }
1432   os << "\n - function token position: " << function_token_position();
1433   os << "\n - start position: " << StartPosition();
1434   os << "\n - end position: " << EndPosition();
1435   if (HasDebugInfo()) {
1436     os << "\n - debug info: " << Brief(GetDebugInfo());
1437   } else {
1438     os << "\n - no debug info";
1439   }
1440   os << "\n - scope info: " << Brief(scope_info());
1441   if (HasOuterScopeInfo()) {
1442     os << "\n - outer scope info: " << Brief(GetOuterScopeInfo());
1443   }
1444   os << "\n - length: " << length();
1445   os << "\n - feedback_metadata: ";
1446   if (HasFeedbackMetadata()) {
1447     feedback_metadata()->FeedbackMetadataPrint(os);
1448   } else {
1449     os << "<none>";
1450   }
1451   os << "\n";
1452 }
1453 
JSGlobalProxyPrint(std::ostream & os)1454 void JSGlobalProxy::JSGlobalProxyPrint(std::ostream& os) {  // NOLINT
1455   JSObjectPrintHeader(os, this, "JSGlobalProxy");
1456   if (!GetIsolate()->bootstrapper()->IsActive()) {
1457     os << "\n - native context: " << Brief(native_context());
1458   }
1459   JSObjectPrintBody(os, this);
1460 }
1461 
JSGlobalObjectPrint(std::ostream & os)1462 void JSGlobalObject::JSGlobalObjectPrint(std::ostream& os) {  // NOLINT
1463   JSObjectPrintHeader(os, this, "JSGlobalObject");
1464   if (!GetIsolate()->bootstrapper()->IsActive()) {
1465     os << "\n - native context: " << Brief(native_context());
1466   }
1467   os << "\n - global proxy: " << Brief(global_proxy());
1468   JSObjectPrintBody(os, this);
1469 }
1470 
CellPrint(std::ostream & os)1471 void Cell::CellPrint(std::ostream& os) {  // NOLINT
1472   HeapObject::PrintHeader(os, "Cell");
1473   os << "\n - value: " << Brief(value());
1474   os << "\n";
1475 }
1476 
PropertyCellPrint(std::ostream & os)1477 void PropertyCell::PropertyCellPrint(std::ostream& os) {  // NOLINT
1478   HeapObject::PrintHeader(os, "PropertyCell");
1479   os << "\n - name: ";
1480   name()->NamePrint(os);
1481   os << "\n - value: " << Brief(value());
1482   os << "\n - details: ";
1483   property_details().PrintAsSlowTo(os);
1484   PropertyCellType cell_type = property_details().cell_type();
1485   os << "\n - cell_type: ";
1486   if (value()->IsTheHole()) {
1487     switch (cell_type) {
1488       case PropertyCellType::kUninitialized:
1489         os << "Uninitialized";
1490         break;
1491       case PropertyCellType::kInvalidated:
1492         os << "Invalidated";
1493         break;
1494       default:
1495         os << "??? " << static_cast<int>(cell_type);
1496         break;
1497     }
1498   } else {
1499     switch (cell_type) {
1500       case PropertyCellType::kUndefined:
1501         os << "Undefined";
1502         break;
1503       case PropertyCellType::kConstant:
1504         os << "Constant";
1505         break;
1506       case PropertyCellType::kConstantType:
1507         os << "ConstantType"
1508            << " (";
1509         switch (GetConstantType()) {
1510           case PropertyCellConstantType::kSmi:
1511             os << "Smi";
1512             break;
1513           case PropertyCellConstantType::kStableMap:
1514             os << "StableMap";
1515             break;
1516         }
1517         os << ")";
1518         break;
1519       case PropertyCellType::kMutable:
1520         os << "Mutable";
1521         break;
1522     }
1523   }
1524   os << "\n";
1525 }
1526 
CodePrint(std::ostream & os)1527 void Code::CodePrint(std::ostream& os) {  // NOLINT
1528   HeapObject::PrintHeader(os, "Code");
1529   os << "\n";
1530 #ifdef ENABLE_DISASSEMBLER
1531   if (FLAG_use_verbose_printer) {
1532     Disassemble(nullptr, os);
1533   }
1534 #endif
1535 }
1536 
CodeDataContainerPrint(std::ostream & os)1537 void CodeDataContainer::CodeDataContainerPrint(std::ostream& os) {  // NOLINT
1538   HeapObject::PrintHeader(os, "CodeDataContainer");
1539   os << "\n - kind_specific_flags: " << kind_specific_flags();
1540   os << "\n";
1541 }
1542 
ForeignPrint(std::ostream & os)1543 void Foreign::ForeignPrint(std::ostream& os) {  // NOLINT
1544   os << "foreign address : " << reinterpret_cast<void*>(foreign_address());
1545   os << "\n";
1546 }
1547 
1548 
AccessorInfoPrint(std::ostream & os)1549 void AccessorInfo::AccessorInfoPrint(std::ostream& os) {  // NOLINT
1550   HeapObject::PrintHeader(os, "AccessorInfo");
1551   os << "\n - name: " << Brief(name());
1552   os << "\n - flags: " << flags();
1553   os << "\n - getter: " << Brief(getter());
1554   os << "\n - setter: " << Brief(setter());
1555   os << "\n - js_getter: " << Brief(js_getter());
1556   os << "\n - data: " << Brief(data());
1557   os << "\n";
1558 }
1559 
CallbackTaskPrint(std::ostream & os)1560 void CallbackTask::CallbackTaskPrint(std::ostream& os) {  // NOLINT
1561   HeapObject::PrintHeader(os, "CallbackTask");
1562   os << "\n - callback: " << Brief(callback());
1563   os << "\n - data: " << Brief(data());
1564   os << "\n";
1565 }
1566 
CallableTaskPrint(std::ostream & os)1567 void CallableTask::CallableTaskPrint(std::ostream& os) {  // NOLINT
1568   HeapObject::PrintHeader(os, "CallableTask");
1569   os << "\n - context: " << Brief(context());
1570   os << "\n - callable: " << Brief(callable());
1571   os << "\n";
1572 }
1573 
PromiseFulfillReactionJobTaskPrint(std::ostream & os)1574 void PromiseFulfillReactionJobTask::PromiseFulfillReactionJobTaskPrint(
1575     std::ostream& os) {  // NOLINT
1576   HeapObject::PrintHeader(os, "PromiseFulfillReactionJobTask");
1577   os << "\n - argument: " << Brief(argument());
1578   os << "\n - context: " << Brief(context());
1579   os << "\n - handler: " << Brief(handler());
1580   os << "\n - promise_or_capability: " << Brief(promise_or_capability());
1581   os << "\n";
1582 }
1583 
PromiseRejectReactionJobTaskPrint(std::ostream & os)1584 void PromiseRejectReactionJobTask::PromiseRejectReactionJobTaskPrint(
1585     std::ostream& os) {  // NOLINT
1586   HeapObject::PrintHeader(os, "PromiseRejectReactionJobTask");
1587   os << "\n - argument: " << Brief(argument());
1588   os << "\n - context: " << Brief(context());
1589   os << "\n - handler: " << Brief(handler());
1590   os << "\n - promise_or_capability: " << Brief(promise_or_capability());
1591   os << "\n";
1592 }
1593 
PromiseResolveThenableJobTaskPrint(std::ostream & os)1594 void PromiseResolveThenableJobTask::PromiseResolveThenableJobTaskPrint(
1595     std::ostream& os) {  // NOLINT
1596   HeapObject::PrintHeader(os, "PromiseResolveThenableJobTask");
1597   os << "\n - context: " << Brief(context());
1598   os << "\n - promise_to_resolve: " << Brief(promise_to_resolve());
1599   os << "\n - then: " << Brief(then());
1600   os << "\n - thenable: " << Brief(thenable());
1601   os << "\n";
1602 }
1603 
PromiseCapabilityPrint(std::ostream & os)1604 void PromiseCapability::PromiseCapabilityPrint(std::ostream& os) {  // NOLINT
1605   HeapObject::PrintHeader(os, "PromiseCapability");
1606   os << "\n - promise: " << Brief(promise());
1607   os << "\n - resolve: " << Brief(resolve());
1608   os << "\n - reject: " << Brief(reject());
1609   os << "\n";
1610 }
1611 
PromiseReactionPrint(std::ostream & os)1612 void PromiseReaction::PromiseReactionPrint(std::ostream& os) {  // NOLINT
1613   HeapObject::PrintHeader(os, "PromiseReaction");
1614   os << "\n - next: " << Brief(next());
1615   os << "\n - reject_handler: " << Brief(reject_handler());
1616   os << "\n - fulfill_handler: " << Brief(fulfill_handler());
1617   os << "\n - promise_or_capability: " << Brief(promise_or_capability());
1618   os << "\n";
1619 }
1620 
AsyncGeneratorRequestPrint(std::ostream & os)1621 void AsyncGeneratorRequest::AsyncGeneratorRequestPrint(
1622     std::ostream& os) {  // NOLINT
1623   HeapObject::PrintHeader(os, "AsyncGeneratorRequest");
1624   const char* mode = "Invalid!";
1625   switch (resume_mode()) {
1626     case JSGeneratorObject::kNext:
1627       mode = ".next()";
1628       break;
1629     case JSGeneratorObject::kReturn:
1630       mode = ".return()";
1631       break;
1632     case JSGeneratorObject::kThrow:
1633       mode = ".throw()";
1634       break;
1635   }
1636   os << "\n - resume mode: " << mode;
1637   os << "\n - value: " << Brief(value());
1638   os << "\n - next: " << Brief(next());
1639   os << "\n";
1640 }
1641 
ModuleInfoEntryPrint(std::ostream & os)1642 void ModuleInfoEntry::ModuleInfoEntryPrint(std::ostream& os) {  // NOLINT
1643   HeapObject::PrintHeader(os, "ModuleInfoEntry");
1644   os << "\n - export_name: " << Brief(export_name());
1645   os << "\n - local_name: " << Brief(local_name());
1646   os << "\n - import_name: " << Brief(import_name());
1647   os << "\n - module_request: " << module_request();
1648   os << "\n - cell_index: " << cell_index();
1649   os << "\n - beg_pos: " << beg_pos();
1650   os << "\n - end_pos: " << end_pos();
1651   os << "\n";
1652 }
1653 
ModulePrint(std::ostream & os)1654 void Module::ModulePrint(std::ostream& os) {  // NOLINT
1655   HeapObject::PrintHeader(os, "Module");
1656   os << "\n - origin: " << Brief(script()->GetNameOrSourceURL());
1657   os << "\n - code: " << Brief(code());
1658   os << "\n - exports: " << Brief(exports());
1659   os << "\n - requested_modules: " << Brief(requested_modules());
1660   os << "\n - script: " << Brief(script());
1661   os << "\n - import_meta: " << Brief(import_meta());
1662   os << "\n - status: " << status();
1663   os << "\n - exception: " << Brief(exception());
1664   os << "\n";
1665 }
1666 
JSModuleNamespacePrint(std::ostream & os)1667 void JSModuleNamespace::JSModuleNamespacePrint(std::ostream& os) {  // NOLINT
1668   JSObjectPrintHeader(os, this, "JSModuleNamespace");
1669   os << "\n - module: " << Brief(module());
1670   JSObjectPrintBody(os, this);
1671 }
1672 
PrototypeInfoPrint(std::ostream & os)1673 void PrototypeInfo::PrototypeInfoPrint(std::ostream& os) {  // NOLINT
1674   HeapObject::PrintHeader(os, "PrototypeInfo");
1675   os << "\n - module namespace: " << Brief(module_namespace());
1676   os << "\n - prototype users: " << Brief(prototype_users());
1677   os << "\n - registry slot: " << registry_slot();
1678   os << "\n - object create map: " << Brief(object_create_map());
1679   os << "\n - should_be_fast_map: " << should_be_fast_map();
1680   os << "\n";
1681 }
1682 
Tuple2Print(std::ostream & os)1683 void Tuple2::Tuple2Print(std::ostream& os) {  // NOLINT
1684   HeapObject::PrintHeader(os, "Tuple2");
1685   os << "\n - value1: " << Brief(value1());
1686   os << "\n - value2: " << Brief(value2());
1687   os << "\n";
1688 }
1689 
Tuple3Print(std::ostream & os)1690 void Tuple3::Tuple3Print(std::ostream& os) {  // NOLINT
1691   HeapObject::PrintHeader(os, "Tuple3");
1692   os << "\n - value1: " << Brief(value1());
1693   os << "\n - value2: " << Brief(value2());
1694   os << "\n - value3: " << Brief(value3());
1695   os << "\n";
1696 }
1697 
ArrayBoilerplateDescriptionPrint(std::ostream & os)1698 void ArrayBoilerplateDescription::ArrayBoilerplateDescriptionPrint(
1699     std::ostream& os) {  // NOLINT
1700   HeapObject::PrintHeader(os, "ArrayBoilerplateDescription");
1701   os << "\n - elements kind: " << elements_kind();
1702   os << "\n - constant elements: " << Brief(constant_elements());
1703   os << "\n";
1704 }
1705 
WasmDebugInfoPrint(std::ostream & os)1706 void WasmDebugInfo::WasmDebugInfoPrint(std::ostream& os) {  // NOLINT
1707   HeapObject::PrintHeader(os, "WasmDebugInfo");
1708   os << "\n - wasm_instance: " << Brief(wasm_instance());
1709   os << "\n";
1710 }
1711 
WasmInstanceObjectPrint(std::ostream & os)1712 void WasmInstanceObject::WasmInstanceObjectPrint(std::ostream& os) {  // NOLINT
1713   HeapObject::PrintHeader(os, "WasmInstanceObject");
1714   os << "\n - module_object: " << Brief(module_object());
1715   os << "\n - exports_object: " << Brief(exports_object());
1716   os << "\n - native_context: " << Brief(native_context());
1717   if (has_memory_object()) {
1718     os << "\n - memory_object: " << Brief(memory_object());
1719   }
1720   if (has_globals_buffer()) {
1721     os << "\n - globals_buffer: " << Brief(globals_buffer());
1722   }
1723   if (has_imported_mutable_globals_buffers()) {
1724     os << "\n - imported_mutable_globals_buffers: "
1725        << Brief(imported_mutable_globals_buffers());
1726   }
1727   if (has_debug_info()) {
1728     os << "\n - debug_info: " << Brief(debug_info());
1729   }
1730   if (has_table_object()) {
1731     os << "\n - table_object: " << Brief(table_object());
1732   }
1733   os << "\n - imported_function_instances: "
1734      << Brief(imported_function_instances());
1735   os << "\n - imported_function_callables: "
1736      << Brief(imported_function_callables());
1737   if (has_indirect_function_table_instances()) {
1738     os << "\n - indirect_function_table_instances: "
1739        << Brief(indirect_function_table_instances());
1740   }
1741   if (has_managed_native_allocations()) {
1742     os << "\n - managed_native_allocations: "
1743        << Brief(managed_native_allocations());
1744   }
1745   os << "\n - memory_start: " << static_cast<void*>(memory_start());
1746   os << "\n - memory_size: " << memory_size();
1747   os << "\n - memory_mask: " << AsHex(memory_mask());
1748   os << "\n - imported_function_targets: "
1749      << static_cast<void*>(imported_function_targets());
1750   os << "\n - globals_start: " << static_cast<void*>(globals_start());
1751   os << "\n - imported_mutable_globals: "
1752      << static_cast<void*>(imported_mutable_globals());
1753   os << "\n - indirect_function_table_size: " << indirect_function_table_size();
1754   os << "\n - indirect_function_table_sig_ids: "
1755      << static_cast<void*>(indirect_function_table_sig_ids());
1756   os << "\n - indirect_function_table_targets: "
1757      << static_cast<void*>(indirect_function_table_targets());
1758   os << "\n";
1759 }
1760 
WasmExportedFunctionDataPrint(std::ostream & os)1761 void WasmExportedFunctionData::WasmExportedFunctionDataPrint(
1762     std::ostream& os) {  // NOLINT
1763   HeapObject::PrintHeader(os, "WasmExportedFunctionData");
1764   os << "\n - wrapper_code: " << Brief(wrapper_code());
1765   os << "\n - instance: " << Brief(instance());
1766   os << "\n - function_index: " << function_index();
1767   os << "\n";
1768 }
1769 
WasmModuleObjectPrint(std::ostream & os)1770 void WasmModuleObject::WasmModuleObjectPrint(std::ostream& os) {  // NOLINT
1771   HeapObject::PrintHeader(os, "WasmModuleObject");
1772   os << "\n - module: " << module();
1773   os << "\n - native module: " << native_module();
1774   os << "\n - export wrappers: " << Brief(export_wrappers());
1775   os << "\n - script: " << Brief(script());
1776   if (has_asm_js_offset_table()) {
1777     os << "\n - asm_js_offset_table: " << Brief(asm_js_offset_table());
1778   }
1779   if (has_breakpoint_infos()) {
1780     os << "\n - breakpoint_infos: " << Brief(breakpoint_infos());
1781   }
1782   os << "\n";
1783 }
1784 
LoadHandlerPrint(std::ostream & os)1785 void LoadHandler::LoadHandlerPrint(std::ostream& os) {  // NOLINT
1786   HeapObject::PrintHeader(os, "LoadHandler");
1787   // TODO(ishell): implement printing based on handler kind
1788   os << "\n - handler: " << Brief(smi_handler());
1789   os << "\n - validity_cell: " << Brief(validity_cell());
1790   int data_count = data_field_count();
1791   if (data_count >= 1) {
1792     os << "\n - data1: " << Brief(data1());
1793   }
1794   if (data_count >= 2) {
1795     os << "\n - data2: " << Brief(data2());
1796   }
1797   if (data_count >= 3) {
1798     os << "\n - data3: " << Brief(data3());
1799   }
1800   os << "\n";
1801 }
1802 
StoreHandlerPrint(std::ostream & os)1803 void StoreHandler::StoreHandlerPrint(std::ostream& os) {  // NOLINT
1804   HeapObject::PrintHeader(os, "StoreHandler");
1805   // TODO(ishell): implement printing based on handler kind
1806   os << "\n - handler: " << Brief(smi_handler());
1807   os << "\n - validity_cell: " << Brief(validity_cell());
1808   int data_count = data_field_count();
1809   if (data_count >= 1) {
1810     os << "\n - data1: " << Brief(data1());
1811   }
1812   if (data_count >= 2) {
1813     os << "\n - data2: " << Brief(data2());
1814   }
1815   if (data_count >= 3) {
1816     os << "\n - data3: " << Brief(data3());
1817   }
1818   os << "\n";
1819 }
1820 
AccessorPairPrint(std::ostream & os)1821 void AccessorPair::AccessorPairPrint(std::ostream& os) {  // NOLINT
1822   HeapObject::PrintHeader(os, "AccessorPair");
1823   os << "\n - getter: " << Brief(getter());
1824   os << "\n - setter: " << Brief(setter());
1825   os << "\n";
1826 }
1827 
1828 
AccessCheckInfoPrint(std::ostream & os)1829 void AccessCheckInfo::AccessCheckInfoPrint(std::ostream& os) {  // NOLINT
1830   HeapObject::PrintHeader(os, "AccessCheckInfo");
1831   os << "\n - callback: " << Brief(callback());
1832   os << "\n - named_interceptor: " << Brief(named_interceptor());
1833   os << "\n - indexed_interceptor: " << Brief(indexed_interceptor());
1834   os << "\n - data: " << Brief(data());
1835   os << "\n";
1836 }
1837 
CallHandlerInfoPrint(std::ostream & os)1838 void CallHandlerInfo::CallHandlerInfoPrint(std::ostream& os) {  // NOLINT
1839   HeapObject::PrintHeader(os, "CallHandlerInfo");
1840   os << "\n - callback: " << Brief(callback());
1841   os << "\n - js_callback: " << Brief(js_callback());
1842   os << "\n - data: " << Brief(data());
1843   os << "\n - side_effect_free: "
1844      << (IsSideEffectFreeCallHandlerInfo() ? "true" : "false");
1845   os << "\n";
1846 }
1847 
InterceptorInfoPrint(std::ostream & os)1848 void InterceptorInfo::InterceptorInfoPrint(std::ostream& os) {  // NOLINT
1849   HeapObject::PrintHeader(os, "InterceptorInfo");
1850   os << "\n - getter: " << Brief(getter());
1851   os << "\n - setter: " << Brief(setter());
1852   os << "\n - query: " << Brief(query());
1853   os << "\n - deleter: " << Brief(deleter());
1854   os << "\n - enumerator: " << Brief(enumerator());
1855   os << "\n - data: " << Brief(data());
1856   os << "\n";
1857 }
1858 
1859 
FunctionTemplateInfoPrint(std::ostream & os)1860 void FunctionTemplateInfo::FunctionTemplateInfoPrint(
1861     std::ostream& os) {  // NOLINT
1862   HeapObject::PrintHeader(os, "FunctionTemplateInfo");
1863   os << "\n - class name: " << Brief(class_name());
1864   os << "\n - tag: " << Brief(tag());
1865   os << "\n - serial_number: " << Brief(serial_number());
1866   os << "\n - property_list: " << Brief(property_list());
1867   os << "\n - call_code: " << Brief(call_code());
1868   os << "\n - property_accessors: " << Brief(property_accessors());
1869   os << "\n - prototype_template: " << Brief(prototype_template());
1870   os << "\n - parent_template: " << Brief(parent_template());
1871   os << "\n - named_property_handler: " << Brief(named_property_handler());
1872   os << "\n - indexed_property_handler: " << Brief(indexed_property_handler());
1873   os << "\n - instance_template: " << Brief(instance_template());
1874   os << "\n - signature: " << Brief(signature());
1875   os << "\n - access_check_info: " << Brief(access_check_info());
1876   os << "\n - cached_property_name: " << Brief(cached_property_name());
1877   os << "\n - hidden_prototype: " << (hidden_prototype() ? "true" : "false");
1878   os << "\n - undetectable: " << (undetectable() ? "true" : "false");
1879   os << "\n - need_access_check: " << (needs_access_check() ? "true" : "false");
1880   os << "\n - instantiated: " << (instantiated() ? "true" : "false");
1881   os << "\n";
1882 }
1883 
1884 
ObjectTemplateInfoPrint(std::ostream & os)1885 void ObjectTemplateInfo::ObjectTemplateInfoPrint(std::ostream& os) {  // NOLINT
1886   HeapObject::PrintHeader(os, "ObjectTemplateInfo");
1887   os << "\n - tag: " << Brief(tag());
1888   os << "\n - serial_number: " << Brief(serial_number());
1889   os << "\n - property_list: " << Brief(property_list());
1890   os << "\n - property_accessors: " << Brief(property_accessors());
1891   os << "\n - constructor: " << Brief(constructor());
1892   os << "\n - embedder_field_count: " << embedder_field_count();
1893   os << "\n - immutable_proto: " << (immutable_proto() ? "true" : "false");
1894   os << "\n";
1895 }
1896 
1897 
AllocationSitePrint(std::ostream & os)1898 void AllocationSite::AllocationSitePrint(std::ostream& os) {  // NOLINT
1899   HeapObject::PrintHeader(os, "AllocationSite");
1900   if (this->HasWeakNext()) os << "\n - weak_next: " << Brief(weak_next());
1901   os << "\n - dependent code: " << Brief(dependent_code());
1902   os << "\n - nested site: " << Brief(nested_site());
1903   os << "\n - memento found count: "
1904      << Brief(Smi::FromInt(memento_found_count()));
1905   os << "\n - memento create count: "
1906      << Brief(Smi::FromInt(memento_create_count()));
1907   os << "\n - pretenure decision: "
1908      << Brief(Smi::FromInt(pretenure_decision()));
1909   os << "\n - transition_info: ";
1910   if (!PointsToLiteral()) {
1911     ElementsKind kind = GetElementsKind();
1912     os << "Array allocation with ElementsKind " << ElementsKindToString(kind);
1913   } else if (boilerplate()->IsJSArray()) {
1914     os << "Array literal with boilerplate " << Brief(boilerplate());
1915   } else {
1916     os << "Object literal with boilerplate " << Brief(boilerplate());
1917   }
1918   os << "\n";
1919 }
1920 
1921 
AllocationMementoPrint(std::ostream & os)1922 void AllocationMemento::AllocationMementoPrint(std::ostream& os) {  // NOLINT
1923   HeapObject::PrintHeader(os, "AllocationMemento");
1924   os << "\n - allocation site: ";
1925   if (IsValid()) {
1926     GetAllocationSite()->AllocationSitePrint(os);
1927   } else {
1928     os << "<invalid>\n";
1929   }
1930 }
1931 
1932 
ScriptPrint(std::ostream & os)1933 void Script::ScriptPrint(std::ostream& os) {  // NOLINT
1934   HeapObject::PrintHeader(os, "Script");
1935   os << "\n - source: " << Brief(source());
1936   os << "\n - name: " << Brief(name());
1937   os << "\n - line_offset: " << line_offset();
1938   os << "\n - column_offset: " << column_offset();
1939   os << "\n - type: " << type();
1940   os << "\n - id: " << id();
1941   os << "\n - context data: " << Brief(context_data());
1942   os << "\n - compilation type: " << compilation_type();
1943   os << "\n - line ends: " << Brief(line_ends());
1944   if (has_eval_from_shared()) {
1945     os << "\n - eval from shared: " << Brief(eval_from_shared());
1946   }
1947   if (is_wrapped()) {
1948     os << "\n - wrapped arguments: " << Brief(wrapped_arguments());
1949   }
1950   os << "\n - eval from position: " << eval_from_position();
1951   os << "\n - shared function infos: " << Brief(shared_function_infos());
1952   os << "\n";
1953 }
1954 
1955 #ifdef V8_INTL_SUPPORT
JSCollatorPrint(std::ostream & os)1956 void JSCollator::JSCollatorPrint(std::ostream& os) {  // NOLINT
1957   JSObjectPrintHeader(os, this, "JSCollator");
1958   os << "\n - usage: " << JSCollator::UsageToString(usage());
1959   os << "\n - icu collator: " << Brief(icu_collator());
1960   os << "\n - bound compare: " << Brief(bound_compare());
1961   os << "\n";
1962 }
1963 
JSListFormatPrint(std::ostream & os)1964 void JSListFormat::JSListFormatPrint(std::ostream& os) {  // NOLINT
1965   JSObjectPrintHeader(os, this, "JSListFormat");
1966   os << "\n - locale: " << Brief(locale());
1967   os << "\n - style: " << StyleAsString();
1968   os << "\n - type: " << TypeAsString();
1969   os << "\n - formatter: " << Brief(formatter());
1970   os << "\n";
1971 }
1972 
JSLocalePrint(std::ostream & os)1973 void JSLocale::JSLocalePrint(std::ostream& os) {  // NOLINT
1974   HeapObject::PrintHeader(os, "JSLocale");
1975   os << "\n - language: " << Brief(language());
1976   os << "\n - script: " << Brief(script());
1977   os << "\n - region: " << Brief(region());
1978   os << "\n - baseName: " << Brief(base_name());
1979   os << "\n - locale: " << Brief(locale());
1980   os << "\n - calendar: " << Brief(calendar());
1981   os << "\n - caseFirst: " << Brief(case_first());
1982   os << "\n - collation: " << Brief(collation());
1983   os << "\n - hourCycle: " << Brief(hour_cycle());
1984   os << "\n - numeric: " << Brief(numeric());
1985   os << "\n - numberingSystem: " << Brief(numbering_system());
1986   os << "\n";
1987 }
1988 
JSPluralRulesPrint(std::ostream & os)1989 void JSPluralRules::JSPluralRulesPrint(std::ostream& os) {  // NOLINT
1990   HeapObject::PrintHeader(os, "JSPluralRules");
1991   JSObjectPrint(os);
1992   os << "\n - locale: " << Brief(locale());
1993   os << "\n - type: " << Brief(type());
1994   os << "\n - icu plural rules: " << Brief(icu_plural_rules());
1995   os << "\n - icu decimal format: " << Brief(icu_decimal_format());
1996   os << "\n";
1997 }
1998 
JSRelativeTimeFormatPrint(std::ostream & os)1999 void JSRelativeTimeFormat::JSRelativeTimeFormatPrint(
2000     std::ostream& os) {  // NOLINT
2001   JSObjectPrintHeader(os, this, "JSRelativeTimeFormat");
2002   os << "\n - locale: " << Brief(locale());
2003   os << "\n - style: " << StyleAsString();
2004   os << "\n - numeric: " << NumericAsString();
2005   os << "\n - formatter: " << Brief(formatter());
2006   os << "\n";
2007 }
2008 #endif  // V8_INTL_SUPPORT
2009 
2010 namespace {
PrintScopeInfoList(ScopeInfo * scope_info,std::ostream & os,const char * list_name,int nof_internal_slots,int start,int length)2011 void PrintScopeInfoList(ScopeInfo* scope_info, std::ostream& os,
2012                         const char* list_name, int nof_internal_slots,
2013                         int start, int length) {
2014   if (length <= 0) return;
2015   int end = start + length;
2016   os << "\n - " << list_name;
2017   if (nof_internal_slots > 0) {
2018     os << " " << start << "-" << end << " [internal slots]";
2019   }
2020   os << " {\n";
2021   for (int i = nof_internal_slots; start < end; ++i, ++start) {
2022     os << "    - " << i << ": ";
2023     String::cast(scope_info->get(start))->ShortPrint(os);
2024     os << "\n";
2025   }
2026   os << "  }";
2027 }
2028 }  // namespace
2029 
ScopeInfoPrint(std::ostream & os)2030 void ScopeInfo::ScopeInfoPrint(std::ostream& os) {  // NOLINT
2031   HeapObject::PrintHeader(os, "ScopeInfo");
2032   if (length() == 0) {
2033     os << "\n - length = 0\n";
2034     return;
2035   }
2036   int flags = Flags();
2037 
2038   os << "\n - parameters: " << ParameterCount();
2039   os << "\n - context locals : " << ContextLocalCount();
2040 
2041   os << "\n - scope type: " << scope_type();
2042   if (CallsSloppyEval()) os << "\n - sloppy eval";
2043   os << "\n - language mode: " << language_mode();
2044   if (is_declaration_scope()) os << "\n - declaration scope";
2045   if (HasReceiver()) {
2046     os << "\n - receiver: " << ReceiverVariableField::decode(flags);
2047   }
2048   if (HasNewTarget()) os << "\n - needs new target";
2049   if (HasFunctionName()) {
2050     os << "\n - function name(" << FunctionVariableField::decode(flags)
2051        << "): ";
2052     FunctionName()->ShortPrint(os);
2053   }
2054   if (IsAsmModule()) os << "\n - asm module";
2055   if (HasSimpleParameters()) os << "\n - simple parameters";
2056   os << "\n - function kind: " << function_kind();
2057   if (HasOuterScopeInfo()) {
2058     os << "\n - outer scope info: " << Brief(OuterScopeInfo());
2059   }
2060   if (HasFunctionName()) {
2061     os << "\n - function name: " << Brief(FunctionName());
2062   }
2063   if (HasInferredFunctionName()) {
2064     os << "\n - inferred function name: " << Brief(InferredFunctionName());
2065   }
2066 
2067   if (HasPositionInfo()) {
2068     os << "\n - start position: " << StartPosition();
2069     os << "\n - end position: " << EndPosition();
2070   }
2071   os << "\n - length: " << length();
2072   if (length() > 0) {
2073     PrintScopeInfoList(this, os, "context slots", Context::MIN_CONTEXT_SLOTS,
2074                        ContextLocalNamesIndex(), ContextLocalCount());
2075     // TODO(neis): Print module stuff if present.
2076   }
2077   os << "\n";
2078 }
2079 
DebugInfoPrint(std::ostream & os)2080 void DebugInfo::DebugInfoPrint(std::ostream& os) {  // NOLINT
2081   HeapObject::PrintHeader(os, "DebugInfo");
2082   os << "\n - flags: " << flags();
2083   os << "\n - debugger_hints: " << debugger_hints();
2084   os << "\n - shared: " << Brief(shared());
2085   os << "\n - script: " << Brief(script());
2086   os << "\n - original bytecode array: " << Brief(original_bytecode_array());
2087   os << "\n - break_points: ";
2088   break_points()->FixedArrayPrint(os);
2089   os << "\n - coverage_info: " << Brief(coverage_info());
2090 }
2091 
2092 
StackFrameInfoPrint(std::ostream & os)2093 void StackFrameInfo::StackFrameInfoPrint(std::ostream& os) {  // NOLINT
2094   HeapObject::PrintHeader(os, "StackFrame");
2095   os << "\n - line_number: " << line_number();
2096   os << "\n - column_number: " << column_number();
2097   os << "\n - script_id: " << script_id();
2098   os << "\n - script_name: " << Brief(script_name());
2099   os << "\n - script_name_or_source_url: "
2100      << Brief(script_name_or_source_url());
2101   os << "\n - function_name: " << Brief(function_name());
2102   os << "\n - is_eval: " << (is_eval() ? "true" : "false");
2103   os << "\n - is_constructor: " << (is_constructor() ? "true" : "false");
2104   os << "\n";
2105 }
2106 
PrintBitMask(std::ostream & os,uint32_t value)2107 static void PrintBitMask(std::ostream& os, uint32_t value) {  // NOLINT
2108   for (int i = 0; i < 32; i++) {
2109     if ((i & 7) == 0) os << " ";
2110     os << (((value & 1) == 0) ? "_" : "x");
2111     value >>= 1;
2112   }
2113 }
2114 
Print()2115 void LayoutDescriptor::Print() {
2116   StdoutStream os;
2117   this->Print(os);
2118   os << std::flush;
2119 }
2120 
ShortPrint(std::ostream & os)2121 void LayoutDescriptor::ShortPrint(std::ostream& os) {
2122   if (IsSmi()) {
2123     os << this;  // Print tagged value for easy use with "jld" gdb macro.
2124   } else {
2125     os << Brief(this);
2126   }
2127 }
2128 
Print(std::ostream & os)2129 void LayoutDescriptor::Print(std::ostream& os) {  // NOLINT
2130   os << "Layout descriptor: ";
2131   if (IsFastPointerLayout()) {
2132     os << "<all tagged>";
2133   } else if (IsSmi()) {
2134     os << "fast";
2135     PrintBitMask(os, static_cast<uint32_t>(Smi::ToInt(this)));
2136   } else if (IsOddball() && IsUninitialized()) {
2137     os << "<uninitialized>";
2138   } else {
2139     os << "slow";
2140     int num_words = number_of_layout_words();
2141     for (int i = 0; i < num_words; i++) {
2142       if (i > 0) os << " |";
2143       PrintBitMask(os, get_layout_word(i));
2144     }
2145   }
2146   os << "\n";
2147 }
2148 
PreParsedScopeDataPrint(std::ostream & os)2149 void PreParsedScopeData::PreParsedScopeDataPrint(std::ostream& os) {  // NOLINT
2150   HeapObject::PrintHeader(os, "PreParsedScopeData");
2151   os << "\n - scope_data: " << Brief(scope_data());
2152   os << "\n - length: " << length();
2153   for (int i = 0; i < length(); ++i) {
2154     os << "\n - [" << i << "]: " << Brief(child_data(i));
2155   }
2156   os << "\n";
2157 }
2158 
2159 void UncompiledDataWithoutPreParsedScope::
UncompiledDataWithoutPreParsedScopePrint(std::ostream & os)2160     UncompiledDataWithoutPreParsedScopePrint(std::ostream& os) {  // NOLINT
2161   HeapObject::PrintHeader(os, "UncompiledDataWithoutPreParsedScope");
2162   os << "\n - start position: " << start_position();
2163   os << "\n - end position: " << end_position();
2164   os << "\n";
2165 }
2166 
UncompiledDataWithPreParsedScopePrint(std::ostream & os)2167 void UncompiledDataWithPreParsedScope::UncompiledDataWithPreParsedScopePrint(
2168     std::ostream& os) {  // NOLINT
2169   HeapObject::PrintHeader(os, "UncompiledDataWithPreParsedScope");
2170   os << "\n - start position: " << start_position();
2171   os << "\n - end position: " << end_position();
2172   os << "\n - pre_parsed_scope_data: " << Brief(pre_parsed_scope_data());
2173   os << "\n";
2174 }
2175 
InterpreterDataPrint(std::ostream & os)2176 void InterpreterData::InterpreterDataPrint(std::ostream& os) {  // NOLINT
2177   HeapObject::PrintHeader(os, "InterpreterData");
2178   os << "\n - bytecode_array: " << Brief(bytecode_array());
2179   os << "\n - interpreter_trampoline: " << Brief(interpreter_trampoline());
2180   os << "\n";
2181 }
2182 
Print()2183 void MaybeObject::Print() {
2184   StdoutStream os;
2185   this->Print(os);
2186   os << std::flush;
2187 }
2188 
Print(std::ostream & os)2189 void MaybeObject::Print(std::ostream& os) {
2190   Smi* smi;
2191   HeapObject* heap_object;
2192   if (ToSmi(&smi)) {
2193     smi->SmiPrint(os);
2194   } else if (IsClearedWeakHeapObject()) {
2195     os << "[cleared]";
2196   } else if (ToWeakHeapObject(&heap_object)) {
2197     os << "[weak] ";
2198     heap_object->HeapObjectPrint(os);
2199   } else if (ToStrongHeapObject(&heap_object)) {
2200     heap_object->HeapObjectPrint(os);
2201   } else {
2202     UNREACHABLE();
2203   }
2204 }
2205 
2206 #endif  // OBJECT_PRINT
2207 
HeapNumberPrint(std::ostream & os)2208 void HeapNumber::HeapNumberPrint(std::ostream& os) { os << value(); }
2209 
MutableHeapNumberPrint(std::ostream & os)2210 void MutableHeapNumber::MutableHeapNumberPrint(std::ostream& os) {
2211   os << value();
2212 }
2213 
2214 // TODO(cbruni): remove once the new maptracer is in place.
NameShortPrint()2215 void Name::NameShortPrint() {
2216   if (this->IsString()) {
2217     PrintF("%s", String::cast(this)->ToCString().get());
2218   } else {
2219     DCHECK(this->IsSymbol());
2220     Symbol* s = Symbol::cast(this);
2221     if (s->name()->IsUndefined()) {
2222       PrintF("#<%s>", s->PrivateSymbolToName());
2223     } else {
2224       PrintF("<%s>", String::cast(s->name())->ToCString().get());
2225     }
2226   }
2227 }
2228 
2229 // TODO(cbruni): remove once the new maptracer is in place.
NameShortPrint(Vector<char> str)2230 int Name::NameShortPrint(Vector<char> str) {
2231   if (this->IsString()) {
2232     return SNPrintF(str, "%s", String::cast(this)->ToCString().get());
2233   } else {
2234     DCHECK(this->IsSymbol());
2235     Symbol* s = Symbol::cast(this);
2236     if (s->name()->IsUndefined()) {
2237       return SNPrintF(str, "#<%s>", s->PrivateSymbolToName());
2238     } else {
2239       return SNPrintF(str, "<%s>", String::cast(s->name())->ToCString().get());
2240     }
2241   }
2242 }
2243 
PrintMapDetails(std::ostream & os)2244 void Map::PrintMapDetails(std::ostream& os) {
2245   DisallowHeapAllocation no_gc;
2246 #ifdef OBJECT_PRINT
2247   this->MapPrint(os);
2248 #else
2249   os << "Map=" << reinterpret_cast<void*>(this);
2250 #endif
2251   os << "\n";
2252   instance_descriptors()->PrintDescriptors(os);
2253 }
2254 
PrintDescriptors(std::ostream & os)2255 void DescriptorArray::PrintDescriptors(std::ostream& os) {
2256   for (int i = 0; i < number_of_descriptors(); i++) {
2257     Name* key = GetKey(i);
2258     os << "\n  [" << i << "]: ";
2259 #ifdef OBJECT_PRINT
2260     key->NamePrint(os);
2261 #else
2262     key->ShortPrint(os);
2263 #endif
2264     os << " ";
2265     PrintDescriptorDetails(os, i, PropertyDetails::kPrintFull);
2266   }
2267   os << "\n";
2268 }
2269 
PrintDescriptorDetails(std::ostream & os,int descriptor,PropertyDetails::PrintMode mode)2270 void DescriptorArray::PrintDescriptorDetails(std::ostream& os, int descriptor,
2271                                              PropertyDetails::PrintMode mode) {
2272   PropertyDetails details = GetDetails(descriptor);
2273   details.PrintAsFastTo(os, mode);
2274   os << " @ ";
2275   switch (details.location()) {
2276     case kField: {
2277       FieldType* field_type = GetFieldType(descriptor);
2278       field_type->PrintTo(os);
2279       break;
2280     }
2281     case kDescriptor:
2282       Object* value = GetStrongValue(descriptor);
2283       os << Brief(value);
2284       if (value->IsAccessorPair()) {
2285         AccessorPair* pair = AccessorPair::cast(value);
2286         os << "(get: " << Brief(pair->getter())
2287            << ", set: " << Brief(pair->setter()) << ")";
2288       }
2289       break;
2290   }
2291 }
2292 
2293 #if defined(DEBUG) || defined(OBJECT_PRINT)
2294 // This method is only meant to be called from gdb for debugging purposes.
2295 // Since the string can also be in two-byte encoding, non-Latin1 characters
2296 // will be ignored in the output.
ToAsciiArray()2297 char* String::ToAsciiArray() {
2298   // Static so that subsequent calls frees previously allocated space.
2299   // This also means that previous results will be overwritten.
2300   static char* buffer = nullptr;
2301   if (buffer != nullptr) delete[] buffer;
2302   buffer = new char[length() + 1];
2303   WriteToFlat(this, reinterpret_cast<uint8_t*>(buffer), 0, length());
2304   buffer[length()] = 0;
2305   return buffer;
2306 }
2307 
2308 // static
PrintOneTransition(std::ostream & os,Name * key,Map * target)2309 void TransitionsAccessor::PrintOneTransition(std::ostream& os, Name* key,
2310                                              Map* target) {
2311   os << "\n     ";
2312 #ifdef OBJECT_PRINT
2313   key->NamePrint(os);
2314 #else
2315   key->ShortPrint(os);
2316 #endif
2317   os << ": ";
2318   ReadOnlyRoots roots = key->GetReadOnlyRoots();
2319   if (key == roots.nonextensible_symbol()) {
2320     os << "(transition to non-extensible)";
2321   } else if (key == roots.sealed_symbol()) {
2322     os << "(transition to sealed)";
2323   } else if (key == roots.frozen_symbol()) {
2324     os << "(transition to frozen)";
2325   } else if (key == roots.elements_transition_symbol()) {
2326     os << "(transition to " << ElementsKindToString(target->elements_kind())
2327        << ")";
2328   } else if (key == roots.strict_function_transition_symbol()) {
2329     os << " (transition to strict function)";
2330   } else {
2331     DCHECK(!IsSpecialTransition(roots, key));
2332     os << "(transition to ";
2333     int descriptor = target->LastAdded();
2334     DescriptorArray* descriptors = target->instance_descriptors();
2335     descriptors->PrintDescriptorDetails(os, descriptor,
2336                                         PropertyDetails::kForTransitions);
2337     os << ")";
2338   }
2339   os << " -> " << Brief(target);
2340 }
2341 
PrintInternal(std::ostream & os)2342 void TransitionArray::PrintInternal(std::ostream& os) {
2343   int num_transitions = number_of_transitions();
2344   os << "Transition array #" << num_transitions << ":";
2345   for (int i = 0; i < num_transitions; i++) {
2346     Name* key = GetKey(i);
2347     Map* target = GetTarget(i);
2348     TransitionsAccessor::PrintOneTransition(os, key, target);
2349   }
2350   os << "\n" << std::flush;
2351 }
2352 
PrintTransitions(std::ostream & os)2353 void TransitionsAccessor::PrintTransitions(std::ostream& os) {  // NOLINT
2354   switch (encoding()) {
2355     case kPrototypeInfo:
2356     case kUninitialized:
2357       return;
2358     case kWeakRef: {
2359       Map* target = Map::cast(raw_transitions_->ToWeakHeapObject());
2360       Name* key = GetSimpleTransitionKey(target);
2361       PrintOneTransition(os, key, target);
2362       break;
2363     }
2364     case kFullTransitionArray:
2365       return transitions()->PrintInternal(os);
2366   }
2367 }
2368 
PrintTransitionTree()2369 void TransitionsAccessor::PrintTransitionTree() {
2370   StdoutStream os;
2371   os << "map= " << Brief(map_);
2372   DisallowHeapAllocation no_gc;
2373   PrintTransitionTree(os, 0, &no_gc);
2374   os << "\n" << std::flush;
2375 }
2376 
PrintTransitionTree(std::ostream & os,int level,DisallowHeapAllocation * no_gc)2377 void TransitionsAccessor::PrintTransitionTree(std::ostream& os, int level,
2378                                               DisallowHeapAllocation* no_gc) {
2379   ReadOnlyRoots roots = ReadOnlyRoots(isolate_);
2380   int num_transitions = NumberOfTransitions();
2381   if (num_transitions == 0) return;
2382   for (int i = 0; i < num_transitions; i++) {
2383     Name* key = GetKey(i);
2384     Map* target = GetTarget(i);
2385     os << std::endl
2386        << "  " << level << "/" << i << ":" << std::setw(level * 2 + 2) << " ";
2387     std::stringstream ss;
2388     ss << Brief(target);
2389     os << std::left << std::setw(50) << ss.str() << ": ";
2390 
2391     if (key == roots.nonextensible_symbol()) {
2392       os << "to non-extensible";
2393     } else if (key == roots.sealed_symbol()) {
2394       os << "to sealed ";
2395     } else if (key == roots.frozen_symbol()) {
2396       os << "to frozen";
2397     } else if (key == roots.elements_transition_symbol()) {
2398       os << "to " << ElementsKindToString(target->elements_kind());
2399     } else if (key == roots.strict_function_transition_symbol()) {
2400       os << "to strict function";
2401     } else {
2402 #ifdef OBJECT_PRINT
2403       key->NamePrint(os);
2404 #else
2405       key->ShortPrint(os);
2406 #endif
2407       os << " ";
2408       DCHECK(!IsSpecialTransition(ReadOnlyRoots(isolate_), key));
2409       os << "to ";
2410       int descriptor = target->LastAdded();
2411       DescriptorArray* descriptors = target->instance_descriptors();
2412       descriptors->PrintDescriptorDetails(os, descriptor,
2413                                           PropertyDetails::kForTransitions);
2414     }
2415     TransitionsAccessor transitions(isolate_, target, no_gc);
2416     transitions.PrintTransitionTree(os, level + 1, no_gc);
2417   }
2418 }
2419 
PrintTransitions(std::ostream & os)2420 void JSObject::PrintTransitions(std::ostream& os) {  // NOLINT
2421   DisallowHeapAllocation no_gc;
2422   TransitionsAccessor ta(GetIsolate(), map(), &no_gc);
2423   if (ta.NumberOfTransitions() == 0) return;
2424   os << "\n - transitions";
2425   ta.PrintTransitions(os);
2426 }
2427 
2428 #endif  // defined(DEBUG) || defined(OBJECT_PRINT)
2429 }  // namespace internal
2430 }  // namespace v8
2431 
2432 //
2433 // The following functions are used by our gdb macros.
2434 //
_v8_internal_Print_Object(void * object)2435 V8_EXPORT_PRIVATE extern void _v8_internal_Print_Object(void* object) {
2436   reinterpret_cast<i::Object*>(object)->Print();
2437 }
2438 
_v8_internal_Print_Code(void * object)2439 V8_EXPORT_PRIVATE extern void _v8_internal_Print_Code(void* object) {
2440   i::Address address = reinterpret_cast<i::Address>(object);
2441   i::Isolate* isolate = i::Isolate::Current();
2442 
2443   i::wasm::WasmCode* wasm_code =
2444       isolate->wasm_engine()->code_manager()->LookupCode(address);
2445   if (wasm_code) {
2446     i::StdoutStream os;
2447     wasm_code->Disassemble(nullptr, os, address);
2448     return;
2449   }
2450 
2451   if (!isolate->heap()->InSpaceSlow(address, i::CODE_SPACE) &&
2452       !isolate->heap()->InSpaceSlow(address, i::LO_SPACE) &&
2453       !i::InstructionStream::PcIsOffHeap(isolate, address)) {
2454     i::PrintF(
2455         "%p is not within the current isolate's large object, code or embedded "
2456         "spaces\n",
2457         object);
2458     return;
2459   }
2460 
2461   i::Code* code = isolate->FindCodeObject(address);
2462   if (!code->IsCode()) {
2463     i::PrintF("No code object found containing %p\n", object);
2464     return;
2465   }
2466 #ifdef ENABLE_DISASSEMBLER
2467   i::StdoutStream os;
2468   code->Disassemble(nullptr, os, address);
2469 #else   // ENABLE_DISASSEMBLER
2470   code->Print();
2471 #endif  // ENABLE_DISASSEMBLER
2472 }
2473 
_v8_internal_Print_LayoutDescriptor(void * object)2474 V8_EXPORT_PRIVATE extern void _v8_internal_Print_LayoutDescriptor(
2475     void* object) {
2476   i::Object* o = reinterpret_cast<i::Object*>(object);
2477   if (!o->IsLayoutDescriptor()) {
2478     printf("Please provide a layout descriptor\n");
2479   } else {
2480     reinterpret_cast<i::LayoutDescriptor*>(object)->Print();
2481   }
2482 }
2483 
_v8_internal_Print_StackTrace()2484 V8_EXPORT_PRIVATE extern void _v8_internal_Print_StackTrace() {
2485   i::Isolate* isolate = i::Isolate::Current();
2486   isolate->PrintStack(stdout);
2487 }
2488 
_v8_internal_Print_TransitionTree(void * object)2489 V8_EXPORT_PRIVATE extern void _v8_internal_Print_TransitionTree(void* object) {
2490   i::Object* o = reinterpret_cast<i::Object*>(object);
2491   if (!o->IsMap()) {
2492     printf("Please provide a valid Map\n");
2493   } else {
2494 #if defined(DEBUG) || defined(OBJECT_PRINT)
2495     i::DisallowHeapAllocation no_gc;
2496     i::Map* map = reinterpret_cast<i::Map*>(object);
2497     i::TransitionsAccessor transitions(i::Isolate::Current(), map, &no_gc);
2498     transitions.PrintTransitionTree();
2499 #endif
2500   }
2501 }
2502