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