v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
objects-printer.cc
Go to the documentation of this file.
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 <iomanip>
6#include <memory>
7#include <optional>
8
12#include "src/common/globals.h"
17#include "src/heap/heap-inl.h" // For InOldSpace.
19#include "src/heap/heap-write-barrier-inl.h" // For GetIsolateFromWritableObj.
30#include "src/objects/struct.h"
31#include "src/regexp/regexp.h"
32#include "src/sandbox/isolate.h"
36#include "src/utils/ostreams.h"
37#include "third_party/fp16/src/include/fp16.h"
38
39#if V8_ENABLE_WEBASSEMBLY
45#endif // V8_ENABLE_WEBASSEMBLY
46
47namespace v8::internal {
48
49namespace {
50constexpr char kUnavailableString[] = "unavailable";
51} // namespace
52
53#ifdef OBJECT_PRINT
54
55void Print(Tagged<Object> obj) {
56 // Output into debugger's command window if a debugger is attached.
57 DbgStdoutStream dbg_os;
58 Print(obj, dbg_os);
59 dbg_os << std::flush;
60
61 StdoutStream os;
62 Print(obj, os);
63 os << std::flush;
64}
65
66void Print(Tagged<Object> obj, std::ostream& os) {
67 if (IsSmi(obj)) {
68 os << "Smi: " << std::hex << "0x" << Smi::ToInt(obj);
69 os << std::dec << " (" << Smi::ToInt(obj) << ")\n";
70 } else {
71 Cast<HeapObject>(obj)->HeapObjectPrint(os);
72 }
73}
74
75namespace {
76
77#define AS_PTR(x) reinterpret_cast<void*>(x)
78#define AS_OBJ(x) Brief(Tagged<Object>(x))
79
80void PrintFunctionCallbackInfo(Address* implicit_args, Address* js_args,
81 Address length, std::ostream& os) {
82 using FCA = FunctionCallbackArguments;
83
84 static_assert(FCA::kArgsLength == 6);
85 os << "FunctionCallbackInfo: " //
86 << "\n - isolate: " << AS_PTR(implicit_args[FCA::kIsolateIndex])
87 << "\n - return_value: " << AS_OBJ(implicit_args[FCA::kReturnValueIndex])
88 << "\n - target: " << AS_OBJ(implicit_args[FCA::kTargetIndex])
89 << "\n - new_target: " << AS_OBJ(implicit_args[FCA::kNewTargetIndex])
90
91 << "\n - argc: " << length //
92 << "\n - receiver: " << AS_OBJ(js_args[0]);
93
94 constexpr int kMaxArgs = 4;
95 for (int i = 0; i < std::min(static_cast<int>(length), kMaxArgs); i++) {
96 os << "\n - arg[" << i << "]: " << AS_OBJ(js_args[i]);
97 }
98 os << "\n";
99}
100
101void PrintPropertyCallbackInfo(Address* args, std::ostream& os) {
102 using PCA = internal::PropertyCallbackArguments;
103
104 static_assert(PCA::kArgsLength == 8);
105 os << "PropertyCallbackInfo: " //
106 << "\n - isolate: " << AS_PTR(args[PCA::kIsolateIndex])
107 << "\n - return_value: " << AS_OBJ(args[PCA::kReturnValueIndex])
108 << "\n - should_throw: " << AS_OBJ(args[PCA::kShouldThrowOnErrorIndex])
109 << "\n - holder: " << AS_OBJ(args[PCA::kHolderIndex])
110 << "\n - holderV2: " << AS_OBJ(args[PCA::kHolderV2Index])
111 << "\n - data: " << AS_OBJ(args[PCA::kDataIndex]) //
112 << "\n - property_key: " << AS_OBJ(args[PCA::kPropertyKeyIndex])
113 << "\n - receiver: " << AS_OBJ(args[PCA::kThisIndex]);
114
115 // In case it's a setter call there will be additional |value| parameter,
116 // print it as a raw pointer to avoid crashing.
117 os << "\n - value?: " << AS_PTR(args[PCA::kArgsLength]);
118 os << "\n";
119}
120
121#undef AS_PTR
122#undef AS_OBJ
123
124} // namespace
125
126void PrintFunctionCallbackInfo(void* function_callback_info) {
128 FCI& info = *reinterpret_cast<FCI*>(function_callback_info);
129
130 // |values| points to the first argument after the receiver.
131 Address* js_args = info.values_ - 1;
132
133 // Output into debugger's command window if a debugger is attached.
134 DbgStdoutStream dbg_os;
135 PrintFunctionCallbackInfo(info.implicit_args_, js_args, info.length_, dbg_os);
136 dbg_os << std::flush;
137
138 StdoutStream os;
139 PrintFunctionCallbackInfo(info.implicit_args_, js_args, info.length_, os);
140 os << std::flush;
141}
142
143void PrintPropertyCallbackInfo(void* property_callback_info) {
145 PCI& info = *reinterpret_cast<PCI*>(property_callback_info);
146
147 // Output into debugger's command window if a debugger is attached.
148 DbgStdoutStream dbg_os;
149 PrintPropertyCallbackInfo(info.args_, dbg_os);
150 dbg_os << std::flush;
151
152 StdoutStream os;
153 PrintPropertyCallbackInfo(info.args_, os);
154 os << std::flush;
155}
156
157namespace {
158
159void PrintHeapObjectHeaderWithoutMap(Tagged<HeapObject> object,
160 std::ostream& os, const char* id) {
161 PtrComprCageBase cage_base = GetPtrComprCageBase();
162 os << reinterpret_cast<void*>(object.ptr()) << ": [";
163 if (id != nullptr) {
164 os << id;
165 } else {
166 os << object->map(cage_base)->instance_type();
167 }
168 os << "]";
169 if (ReadOnlyHeap::Contains(object)) {
170 os << " in ReadOnlySpace";
171 }
172}
173
174template <typename T>
175void PrintDictionaryContents(std::ostream& os, Tagged<T> dict) {
177 ReadOnlyRoots roots = GetReadOnlyRoots();
178
179 if (dict->Capacity() == 0) {
180 return;
181 }
182
183#ifdef V8_ENABLE_SWISS_NAME_DICTIONARY
184 Isolate* isolate = GetIsolateFromWritableObject(dict);
185 // IterateEntries for SwissNameDictionary needs to create a handle.
186 HandleScope scope(isolate);
187#endif
188 for (InternalIndex i : dict->IterateEntries()) {
190 if (!dict->ToKey(roots, i, &k)) continue;
191 os << "\n ";
192 if (IsString(k)) {
193 Cast<String>(k)->PrintUC16(os);
194 } else {
195 os << Brief(k);
196 }
197 os << ": " << Brief(dict->ValueAt(i)) << " ";
198 dict->DetailsAt(i).PrintAsSlowTo(os, !T::kIsOrderedDictionaryType);
199 }
200}
201} // namespace
202
203void HeapObjectLayout::PrintHeader(std::ostream& os, const char* id) {
204 Tagged<HeapObject>(this)->PrintHeader(os, id);
205}
206
207void HeapObject::PrintHeader(std::ostream& os, const char* id) {
208 PrintHeapObjectHeaderWithoutMap(*this, os, id);
209 PtrComprCageBase cage_base = GetPtrComprCageBase();
210 if (!SafeEquals(GetReadOnlyRoots().meta_map())) {
211 os << "\n - map: " << Brief(map(cage_base));
212 }
213}
214
215void HeapObject::HeapObjectPrint(std::ostream& os) {
216 PtrComprCageBase cage_base = GetPtrComprCageBase();
217
218 InstanceType instance_type = map(cage_base)->instance_type();
219
220 if (instance_type < FIRST_NONSTRING_TYPE) {
221 Cast<String>(*this)->StringPrint(os);
222 os << "\n";
223 return;
224 }
225
226 // Skip invalid trusted objects. Technically it'd be fine to still handle
227 // them below since we only print the objects, but such an object will
228 // quickly lead to out-of-sandbox segfaults and so fuzzers will complain.
229 if (InstanceTypeChecker::IsTrustedObject(instance_type) &&
231 os << "<Invalid TrustedObject (outside trusted space)>\n";
232 return;
233 }
234
235 switch (instance_type) {
236 case AWAIT_CONTEXT_TYPE:
237 case BLOCK_CONTEXT_TYPE:
238 case CATCH_CONTEXT_TYPE:
239 case DEBUG_EVALUATE_CONTEXT_TYPE:
240 case EVAL_CONTEXT_TYPE:
241 case FUNCTION_CONTEXT_TYPE:
242 case MODULE_CONTEXT_TYPE:
243 case SCRIPT_CONTEXT_TYPE:
244 case WITH_CONTEXT_TYPE:
245 Cast<Context>(*this)->ContextPrint(os);
246 break;
247 case NATIVE_CONTEXT_TYPE:
248 Cast<NativeContext>(*this)->NativeContextPrint(os);
249 break;
250 case HASH_TABLE_TYPE:
251 Cast<ObjectHashTable>(*this)->ObjectHashTablePrint(os);
252 break;
253 case NAME_TO_INDEX_HASH_TABLE_TYPE:
254 Cast<NameToIndexHashTable>(*this)->NameToIndexHashTablePrint(os);
255 break;
256 case REGISTERED_SYMBOL_TABLE_TYPE:
257 Cast<RegisteredSymbolTable>(*this)->RegisteredSymbolTablePrint(os);
258 break;
259 case ORDERED_HASH_MAP_TYPE:
260 Cast<OrderedHashMap>(*this)->OrderedHashMapPrint(os);
261 break;
262 case ORDERED_HASH_SET_TYPE:
263 Cast<OrderedHashSet>(*this)->OrderedHashSetPrint(os);
264 break;
265 case ORDERED_NAME_DICTIONARY_TYPE:
266 Cast<OrderedNameDictionary>(*this)->OrderedNameDictionaryPrint(os);
267 break;
268 case NAME_DICTIONARY_TYPE:
269 Cast<NameDictionary>(*this)->NameDictionaryPrint(os);
270 break;
271 case GLOBAL_DICTIONARY_TYPE:
272 Cast<GlobalDictionary>(*this)->GlobalDictionaryPrint(os);
273 break;
274 case SIMPLE_NUMBER_DICTIONARY_TYPE:
275 Cast<FixedArray>(*this)->FixedArrayPrint(os);
276 break;
277 case NUMBER_DICTIONARY_TYPE:
278 Cast<NumberDictionary>(*this)->NumberDictionaryPrint(os);
279 break;
280 case EPHEMERON_HASH_TABLE_TYPE:
281 Cast<EphemeronHashTable>(*this)->EphemeronHashTablePrint(os);
282 break;
283 case TRANSITION_ARRAY_TYPE:
284 Cast<TransitionArray>(*this)->TransitionArrayPrint(os);
285 break;
286 case FILLER_TYPE:
287 os << "filler";
288 break;
289 case JS_API_OBJECT_TYPE:
290 case JS_ARRAY_ITERATOR_PROTOTYPE_TYPE:
291 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
292 case JS_ERROR_TYPE:
293 case JS_ITERATOR_PROTOTYPE_TYPE:
294 case JS_MAP_ITERATOR_PROTOTYPE_TYPE:
295 case JS_OBJECT_PROTOTYPE_TYPE:
296 case JS_PROMISE_PROTOTYPE_TYPE:
297 case JS_REG_EXP_PROTOTYPE_TYPE:
298 case JS_SET_ITERATOR_PROTOTYPE_TYPE:
299 case JS_SET_PROTOTYPE_TYPE:
300 case JS_SPECIAL_API_OBJECT_TYPE:
301 case JS_STRING_ITERATOR_PROTOTYPE_TYPE:
302 case JS_TYPED_ARRAY_PROTOTYPE_TYPE:
303 Cast<JSObject>(*this)->JSObjectPrint(os);
304 break;
305#if V8_ENABLE_WEBASSEMBLY
306 case WASM_TRUSTED_INSTANCE_DATA_TYPE:
307 Cast<WasmTrustedInstanceData>(*this)->WasmTrustedInstanceDataPrint(os);
308 break;
309 case WASM_DISPATCH_TABLE_TYPE:
310 Cast<WasmDispatchTable>(*this)->WasmDispatchTablePrint(os);
311 break;
312 case WASM_VALUE_OBJECT_TYPE:
313 Cast<WasmValueObject>(*this)->WasmValueObjectPrint(os);
314 break;
315 case WASM_EXCEPTION_PACKAGE_TYPE:
316 Cast<WasmExceptionPackage>(*this)->WasmExceptionPackagePrint(os);
317 break;
318#endif // V8_ENABLE_WEBASSEMBLY
319 case INSTRUCTION_STREAM_TYPE:
320 Cast<InstructionStream>(*this)->InstructionStreamPrint(os);
321 break;
322 case CODE_TYPE:
323 Cast<Code>(*this)->CodePrint(os);
324 break;
325 case CODE_WRAPPER_TYPE:
326 Cast<CodeWrapper>(*this)->CodeWrapperPrint(os);
327 break;
328 case JS_SET_KEY_VALUE_ITERATOR_TYPE:
329 case JS_SET_VALUE_ITERATOR_TYPE:
330 Cast<JSSetIterator>(*this)->JSSetIteratorPrint(os);
331 break;
332 case JS_MAP_KEY_ITERATOR_TYPE:
333 case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
334 case JS_MAP_VALUE_ITERATOR_TYPE:
335 Cast<JSMapIterator>(*this)->JSMapIteratorPrint(os);
336 break;
337#define MAKE_TORQUE_CASE(Name, TYPE) \
338 case TYPE: \
339 Cast<Name>(*this)->Name##Print(os); \
340 break;
341 // Every class that has its fields defined in a .tq file and corresponds
342 // to exactly one InstanceType value is included in the following list.
343 TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(MAKE_TORQUE_CASE)
344 TORQUE_INSTANCE_CHECKERS_MULTIPLE_FULLY_DEFINED(MAKE_TORQUE_CASE)
345#undef MAKE_TORQUE_CASE
346
347 case TUPLE2_TYPE:
348 Cast<Tuple2>(*this)->Tuple2Print(os);
349 break;
350 case CLASS_POSITIONS_TYPE:
351 Cast<ClassPositions>(*this)->ClassPositionsPrint(os);
352 break;
353 case ACCESSOR_PAIR_TYPE:
354 Cast<AccessorPair>(*this)->AccessorPairPrint(os);
355 break;
356 case ALLOCATION_SITE_TYPE:
357 Cast<AllocationSite>(*this)->AllocationSitePrint(os);
358 break;
359 case LOAD_HANDLER_TYPE:
360 Cast<LoadHandler>(*this)->LoadHandlerPrint(os);
361 break;
362 case STORE_HANDLER_TYPE:
363 Cast<StoreHandler>(*this)->StoreHandlerPrint(os);
364 break;
365 case FEEDBACK_METADATA_TYPE:
366 Cast<FeedbackMetadata>(*this)->FeedbackMetadataPrint(os);
367 break;
368 case BIG_INT_BASE_TYPE:
369 Cast<BigIntBase>(*this)->BigIntBasePrint(os);
370 break;
371 case JS_CLASS_CONSTRUCTOR_TYPE:
372 case JS_PROMISE_CONSTRUCTOR_TYPE:
373 case JS_REG_EXP_CONSTRUCTOR_TYPE:
374 case JS_ARRAY_CONSTRUCTOR_TYPE:
375#define TYPED_ARRAY_CONSTRUCTORS_SWITCH(Type, type, TYPE, Ctype) \
376 case TYPE##_TYPED_ARRAY_CONSTRUCTOR_TYPE:
378#undef TYPED_ARRAY_CONSTRUCTORS_SWITCH
379 Cast<JSFunction>(*this)->JSFunctionPrint(os);
380 break;
405 case JS_LAST_DUMMY_API_OBJECT_TYPE:
406 // TODO(all): Handle these types too.
407 os << "UNKNOWN TYPE " << map()->instance_type();
408 UNREACHABLE();
409 }
410}
411
412template <typename T>
413void PrintByteArrayElements(std::ostream& os, const T* array) {
414 int length = array->length();
415 int i = 0;
416 while (i < length) {
417 os << " 0x" << std::setfill('0') << std::setw(4) << std::hex << i << ":";
418 int line_end = std::min(i + 16, length);
419 for (; i < line_end; ++i) {
420 os << " " << std::setfill('0') << std::setw(2) << std::hex
421 << static_cast<int>(array->get(i));
422 }
423 os << "\n";
424 }
425}
426
427void ByteArray::ByteArrayPrint(std::ostream& os) {
428 PrintHeader(os, "ByteArray");
429 os << "\n - length: " << length()
430 << "\n - begin: " << static_cast<void*>(begin()) << "\n";
431 PrintByteArrayElements(os, this);
432}
433
434void TrustedByteArray::TrustedByteArrayPrint(std::ostream& os) {
435 PrintHeader(os, "TrustedByteArray");
436 os << "\n - length: " << length()
437 << "\n - begin: " << static_cast<void*>(begin()) << "\n";
438 PrintByteArrayElements(os, this);
439}
440
441void BytecodeArray::BytecodeArrayPrint(std::ostream& os) {
442 PrintHeader(os, "BytecodeArray");
443 os << "\n";
444 Disassemble(os);
445}
446
447void BytecodeWrapper::BytecodeWrapperPrint(std::ostream& os) {
448 PrintHeader(os, "BytecodeWrapper");
449 IsolateForSandbox isolate = GetIsolateForSandbox(*this);
450 os << "\n bytecode: " << Brief(bytecode(isolate));
451}
452
453void FreeSpace::FreeSpacePrint(std::ostream& os) {
454 os << "free space, size " << Size() << "\n";
455}
456
457bool JSObject::PrintProperties(std::ostream& os) {
458 if (HasFastProperties()) {
459 Tagged<DescriptorArray> descs = map()->instance_descriptors(GetIsolate());
460 int nof_inobject_properties = map()->GetInObjectProperties();
461 for (InternalIndex i : map()->IterateOwnDescriptors()) {
462 os << "\n ";
463 descs->GetKey(i)->NamePrint(os);
464 os << ": ";
465 PropertyDetails details = descs->GetDetails(i);
466 switch (details.location()) {
468 FieldIndex field_index = FieldIndex::ForDetails(map(), details);
469 os << Brief(RawFastPropertyAt(field_index));
470 break;
471 }
473 os << Brief(descs->GetStrongValue(i));
474 break;
475 }
476 os << " ";
477 details.PrintAsFastTo(os, PropertyDetails::kForProperties);
478 if (details.location() == PropertyLocation::kField) {
479 os << " @ ";
480 FieldType::PrintTo(descs->GetFieldType(i), os);
481 int field_index = details.field_index();
482 if (field_index < nof_inobject_properties) {
483 os << ", location: in-object";
484 } else {
485 field_index -= nof_inobject_properties;
486 os << ", location: properties[" << field_index << "]";
487 }
488 } else {
489 os << ", location: descriptor";
490 }
491 }
492 return map()->NumberOfOwnDescriptors() > 0;
493 } else if (IsJSGlobalObject(*this)) {
494 PrintDictionaryContents(
495 os, Cast<JSGlobalObject>(*this)->global_dictionary(kAcquireLoad));
496 } else if constexpr (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
497 PrintDictionaryContents(os, property_dictionary_swiss());
498 } else {
499 PrintDictionaryContents(os, property_dictionary());
500 }
501 return true;
502}
503
504namespace {
505
506template <class T>
507bool IsTheHoleAt(Tagged<T> array, int index) {
508 return false;
509}
510
511template <>
512bool IsTheHoleAt(Tagged<FixedDoubleArray> array, int index) {
513 return array->is_the_hole(index);
514}
515
516#ifdef V8_ENABLE_EXPERIMENTAL_UNDEFINED_DOUBLE
517template <class T>
518bool IsUndefinedAt(Tagged<T> array, int index) {
519 return false;
520}
521
522template <>
523bool IsUndefinedAt(Tagged<FixedDoubleArray> array, int index) {
524 return array->is_undefined(index);
525}
526#endif // V8_ENABLE_EXPERIMENTAL_UNDEFINED_DOUBLE
527
528template <class T>
529double GetScalarElement(Tagged<T> array, int index) {
530 if (IsTheHoleAt(array, index)) {
531 return std::numeric_limits<double>::quiet_NaN();
532 }
533 return array->get_scalar(index);
534}
535
536template <class T>
537void DoPrintElements(std::ostream& os, Tagged<Object> object, int length) {
538 const bool print_the_hole = std::is_same_v<T, FixedDoubleArray>;
539 Tagged<T> array = Cast<T>(object);
540 if (length == 0) return;
541 int previous_index = 0;
542 uint64_t previous_representation = array->get_representation(0);
543 uint64_t representation = 0;
544 int i;
545 for (i = 1; i <= length; i++) {
546 if (i < length) {
547 representation = array->get_representation(i);
548 if (previous_representation == representation) continue;
549 }
550 os << "\n";
551 std::stringstream ss;
552 ss << previous_index;
553 if (previous_index != i - 1) {
554 ss << '-' << (i - 1);
555 }
556 os << std::setw(12) << ss.str() << ": ";
557 if (print_the_hole && IsTheHoleAt(array, i - 1)) {
558 os << "<the_hole>";
559#ifdef V8_ENABLE_EXPERIMENTAL_UNDEFINED_DOUBLE
560 } else if (IsUndefinedAt(array, i - 1)) {
561 os << "undefined";
562#endif // V8_ENABLE_EXPERIMENTAL_UNDEFINED_DOUBLE
563 } else {
564 os << GetScalarElement(array, i - 1);
565 }
566 previous_index = i;
567 previous_representation = representation;
568 }
569}
570
571struct Fp16Printer {
572 uint16_t val;
573 explicit Fp16Printer(float f) : val(fp16_ieee_from_fp32_value(f)) {}
574 operator float() const { return fp16_ieee_to_fp32_value(val); }
575};
576
577template <typename ElementType>
578void PrintTypedArrayElements(std::ostream& os, const ElementType* data_ptr,
579 size_t length, bool is_on_heap) {
580 if (length == 0) return;
581 size_t previous_index = 0;
582 if (i::v8_flags.mock_arraybuffer_allocator && !is_on_heap) {
583 // Don't try to print data that's not actually allocated.
584 os << "\n 0-" << length << ": <mocked array buffer bytes>";
585 return;
586 }
587
588 ElementType previous_value = data_ptr[0];
589 ElementType value{0};
590 for (size_t i = 1; i <= length; i++) {
591 if (i < length) value = data_ptr[i];
592 if (i != length && previous_value == value) {
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() << ": " << +previous_value;
602 previous_index = i;
603 previous_value = value;
604 }
605}
606
607template <typename T>
608void PrintFixedArrayElements(std::ostream& os, Tagged<T> array, int capacity,
609 Tagged<Object> (*get)(Tagged<T>, int)) {
610 // Print in array notation for non-sparse arrays.
611 if (capacity == 0) return;
612 Tagged<Object> previous_value = get(array, 0);
614 int previous_index = 0;
615 int i;
616 for (i = 1; i <= capacity; i++) {
617 if (i < capacity) value = get(array, i);
618 if (previous_value == value && i != capacity) {
619 continue;
620 }
621 os << "\n";
622 std::stringstream ss;
623 ss << previous_index;
624 if (previous_index != i - 1) {
625 ss << '-' << (i - 1);
626 }
627 os << std::setw(12) << ss.str() << ": " << Brief(previous_value);
628 previous_index = i;
629 previous_value = value;
630 }
631}
632
633template <typename T>
634void PrintFixedArrayElements(std::ostream& os, Tagged<T> array) {
635 PrintFixedArrayElements<T>(
636 os, array, array->length(),
637 [](Tagged<T> xs, int i) { return Cast<Object>(xs->get(i)); });
638}
639
640void PrintDictionaryElements(std::ostream& os,
641 Tagged<FixedArrayBase> elements) {
642 // Print some internal fields
644 if (dict->requires_slow_elements()) {
645 os << "\n - requires_slow_elements";
646 } else {
647 os << "\n - max_number_key: " << dict->max_number_key();
648 }
649 PrintDictionaryContents(os, dict);
650}
651
652void PrintSloppyArgumentElements(std::ostream& os, ElementsKind kind,
654 Tagged<FixedArray> arguments_store = elements->arguments();
655 os << "\n 0: context: " << Brief(elements->context())
656 << "\n 1: arguments_store: " << Brief(arguments_store)
657 << "\n parameter to context slot map:";
658 for (int i = 0; i < elements->length(); i++) {
659 Tagged<Object> mapped_entry = elements->mapped_entries(i, kRelaxedLoad);
660 os << "\n " << i << ": param(" << i << "): " << Brief(mapped_entry);
661 if (IsTheHole(mapped_entry)) {
662 os << " in the arguments_store[" << i << "]";
663 } else {
664 os << " in the context";
665 }
666 }
667 if (arguments_store->length() == 0) return;
668 os << "\n }"
669 << "\n - arguments_store: " << Brief(arguments_store) << " "
670 << ElementsKindToString(arguments_store->map()->elements_kind()) << " {";
672 PrintFixedArrayElements(os, arguments_store);
673 } else {
675 PrintDictionaryElements(os, arguments_store);
676 }
677}
678
679void PrintEmbedderData(IsolateForSandbox isolate, std::ostream& os,
680 EmbedderDataSlot slot) {
682 Tagged<Object> value = slot.load_tagged();
683 os << Brief(value);
684 void* raw_pointer;
685 if (slot.ToAlignedPointer(isolate, &raw_pointer)) {
686 os << ", aligned pointer: " << raw_pointer;
687 }
688}
689
690} // namespace
691
692void JSObject::PrintElements(std::ostream& os) {
693 // Don't call GetElementsKind, its validation code can cause the printer to
694 // fail when debugging.
695 os << " - elements: " << Brief(elements()) << " {";
696 switch (map()->elements_kind()) {
699 case HOLEY_ELEMENTS:
703 case PACKED_ELEMENTS:
709 PrintFixedArrayElements(os, Cast<FixedArray>(elements()));
710 break;
711 }
714 DoPrintElements<FixedDoubleArray>(os, elements(), elements()->length());
715 break;
716 }
717
718#define PRINT_ELEMENTS(Type, type, TYPE, elementType) \
719 case TYPE##_ELEMENTS: { \
720 size_t length = Cast<JSTypedArray>(*this)->GetLength(); \
721 bool is_on_heap = Cast<JSTypedArray>(*this)->is_on_heap(); \
722 const elementType* data_ptr = \
723 static_cast<const elementType*>(Cast<JSTypedArray>(*this)->DataPtr()); \
724 PrintTypedArrayElements<elementType>(os, data_ptr, length, is_on_heap); \
725 break; \
726 }
727 TYPED_ARRAYS(PRINT_ELEMENTS)
728 RAB_GSAB_TYPED_ARRAYS(PRINT_ELEMENTS)
729#undef PRINT_ELEMENTS
730
733 PrintDictionaryElements(os, elements());
734 break;
737 PrintSloppyArgumentElements(os, map()->elements_kind(),
739 break;
741 // WasmArrayPrint() should be called instead.
742 UNREACHABLE();
743 case NO_ELEMENTS:
744 break;
745 }
746 os << "\n }\n";
747}
748
749namespace {
750
751void JSObjectPrintHeader(std::ostream& os, Tagged<JSObject> obj,
752 const char* id) {
753 Isolate* isolate = obj->GetIsolate();
754 obj->PrintHeader(os, id);
755 // Don't call GetElementsKind, its validation code can cause the printer to
756 // fail when debugging.
757 os << " [";
758 if (obj->HasFastProperties()) {
759 os << "FastProperties";
760 } else {
761 os << "DictionaryProperties";
762 }
763 PrototypeIterator iter(isolate, obj);
764 os << "]\n - prototype: " << Brief(iter.GetCurrent());
765 os << "\n - elements: " << Brief(obj->elements()) << " ["
766 << ElementsKindToString(obj->map()->elements_kind());
767 if (obj->elements()->IsCowArray()) os << " (COW)";
768 os << "]";
770 if (IsSmi(hash)) {
771 os << "\n - hash: " << Brief(hash);
772 }
773 if (obj->GetEmbedderFieldCount() > 0) {
774 os << "\n - embedder fields: " << obj->GetEmbedderFieldCount();
775 }
776}
777
778void JSAPIObjectWithEmbedderSlotsPrintHeader(std::ostream& os,
780 const char* id = nullptr) {
781 JSObjectPrintHeader(os, obj, id);
782 os << "\n - cpp_heap_wrappable: "
783 << obj->ReadField<uint32_t>(
784 JSAPIObjectWithEmbedderSlots::kCppHeapWrappableOffset);
785}
786
787void JSObjectPrintBody(std::ostream& os, Tagged<JSObject> obj,
788 bool print_elements = true) {
789 os << "\n - properties: ";
790 Tagged<Object> properties_or_hash = obj->raw_properties_or_hash(kRelaxedLoad);
791 if (!IsSmi(properties_or_hash)) {
792 os << Brief(properties_or_hash);
793 }
794 os << "\n - All own properties (excluding elements): {";
795 if (obj->PrintProperties(os)) os << "\n ";
796 os << "}\n";
797
798 if (print_elements) {
799 size_t length = IsJSTypedArray(obj) ? Cast<JSTypedArray>(obj)->GetLength()
800 : obj->elements()->length();
801 if (length > 0) obj->PrintElements(os);
802 }
803 int embedder_fields = obj->GetEmbedderFieldCount();
804 if (embedder_fields > 0) {
805 IsolateForSandbox isolate = GetIsolateForSandbox(obj);
806 os << " - embedder fields = {";
807 for (int i = 0; i < embedder_fields; i++) {
808 os << "\n ";
809 PrintEmbedderData(isolate, os, EmbedderDataSlot(obj, i));
810 }
811 os << "\n }\n";
812 }
813}
814
815} // namespace
816
817void JSObject::JSObjectPrint(std::ostream& os) {
818 JSObjectPrintHeader(os, *this, nullptr);
819 JSObjectPrintBody(os, *this);
820}
821
822void JSExternalObject::JSExternalObjectPrint(std::ostream& os) {
823 JSObjectPrintHeader(os, *this, nullptr);
824 os << "\n - external value: " << value();
825 JSObjectPrintBody(os, *this);
826}
827
828void JSGeneratorObject::JSGeneratorObjectPrint(std::ostream& os) {
829 JSObjectPrintHeader(os, *this, "JSGeneratorObject");
830 os << "\n - function: " << Brief(function());
831 os << "\n - context: " << Brief(context());
832 os << "\n - receiver: " << Brief(receiver());
833 if (is_executing() || is_closed()) {
834 os << "\n - input: " << Brief(input_or_debug_pos());
835 } else {
837 os << "\n - debug pos: " << Brief(input_or_debug_pos());
838 }
839 const char* mode = "(invalid)";
840 switch (resume_mode()) {
841 case kNext:
842 mode = ".next()";
843 break;
844 case kReturn:
845 mode = ".return()";
846 break;
847 case kThrow:
848 mode = ".throw()";
849 break;
850 }
851 os << "\n - resume mode: " << mode;
852 os << "\n - continuation: " << continuation();
853 if (is_closed()) os << " (closed)";
854 if (is_executing()) os << " (executing)";
855 if (is_suspended()) os << " (suspended)";
856 if (is_suspended()) {
858 Tagged<SharedFunctionInfo> fun_info = function()->shared();
859 if (fun_info->HasSourceCode()) {
860 Tagged<Script> script = Cast<Script>(fun_info->script());
861 Tagged<String> script_name = IsString(script->name())
862 ? Cast<String>(script->name())
863 : GetReadOnlyRoots().empty_string();
864
865 os << "\n - source position: ";
866 // Can't collect source positions here if not available as that would
867 // allocate memory.
868 Isolate* isolate = GetIsolate();
869 if (fun_info->HasBytecodeArray() &&
870 fun_info->GetBytecodeArray(isolate)->HasSourcePositionTable()) {
871 os << source_position();
872 os << " (";
873 script_name->PrintUC16(os);
874 Script::PositionInfo info;
875 script->GetPositionInfo(source_position(), &info);
876 os << ", line " << info.line + 1;
877 os << ", column " << info.column + 1;
878 } else {
879 os << kUnavailableString;
880 }
881 os << ")";
882 }
883 }
884 os << "\n - register file: " << Brief(parameters_and_registers());
885 JSObjectPrintBody(os, *this);
886}
887
888void JSArray::JSArrayPrint(std::ostream& os) {
889 JSObjectPrintHeader(os, *this, "JSArray");
890 os << "\n - length: " << Brief(this->length());
891 JSObjectPrintBody(os, *this);
892}
893
894void JSPromise::JSPromisePrint(std::ostream& os) {
895 JSObjectPrintHeader(os, *this, "JSPromise");
896 os << "\n - status: " << JSPromise::Status(status());
897 if (status() == Promise::kPending) {
898 os << "\n - reactions: " << Brief(reactions());
899 } else {
900 os << "\n - result: " << Brief(result());
901 }
902 os << "\n - has_handler: " << has_handler();
903 os << "\n - is_silent: " << is_silent();
904 JSObjectPrintBody(os, *this);
905}
906
907void JSRegExp::JSRegExpPrint(std::ostream& os) {
908 JSObjectPrintHeader(os, *this, "JSRegExp");
909 IsolateForSandbox isolate = GetIsolateForSandbox(*this);
910 os << "\n - data: " << Brief(data(isolate));
911 os << "\n - source: " << Brief(source());
912 FlagsBuffer buffer;
913 os << "\n - flags: " << JSRegExp::FlagsToString(flags(), &buffer);
914 JSObjectPrintBody(os, *this);
915}
916
917void RegExpData::RegExpDataPrint(std::ostream& os) {
918 switch (type_tag()) {
920 PrintHeader(os, "AtomRegExpData");
921 break;
923 PrintHeader(os, "IrRegExpData");
924 break;
926 PrintHeader(os, "IrRegExpData");
927 break;
928 default:
929 UNREACHABLE();
930 }
931 os << "\n - source: " << source();
933 os << "\n - flags: " << JSRegExp::FlagsToString(flags(), &buffer);
934}
935
936void AtomRegExpData::AtomRegExpDataPrint(std::ostream& os) {
937 RegExpDataPrint(os);
938 os << "\n - pattern: " << pattern();
939 os << "\n";
940}
941
942void IrRegExpData::IrRegExpDataPrint(std::ostream& os) {
943 IsolateForSandbox isolate = GetIsolateForSandbox(*this);
944 RegExpDataPrint(os);
945 if (has_latin1_bytecode()) {
946 os << "\n - latin1_bytecode: " << Brief(latin1_bytecode());
947 }
948 if (has_uc16_bytecode()) {
949 os << "\n - uc16_bytecode: " << Brief(uc16_bytecode());
950 }
951 if (has_latin1_code()) {
952 os << "\n - latin1_code: " << Brief(latin1_code(isolate));
953 }
954 if (has_uc16_code()) {
955 os << "\n - uc16_code: " << Brief(uc16_code(isolate));
956 }
957 os << "\n - capture_name_map: " << Brief(capture_name_map());
958 os << "\n - max_register_count: " << max_register_count();
959 os << "\n - capture_count: " << max_register_count();
960 os << "\n - ticks_until_tier_up: " << max_register_count();
961 os << "\n - backtrack_limit: " << max_register_count();
962 os << "\n";
963}
964
965void RegExpDataWrapper::RegExpDataWrapperPrint(std::ostream& os) {
966 PrintHeader(os, "RegExpDataWrapper");
967 IsolateForSandbox isolate = GetIsolateForSandbox(*this);
968 os << "\n data: " << Brief(data(isolate));
969 os << "\n";
970}
971
972void JSRegExpStringIterator::JSRegExpStringIteratorPrint(std::ostream& os) {
973 JSObjectPrintHeader(os, *this, "JSRegExpStringIterator");
974 os << "\n - regex: " << Brief(iterating_reg_exp());
975 os << "\n - string: " << Brief(iterated_string());
976 os << "\n - done: " << done();
977 os << "\n - global: " << global();
978 os << "\n - unicode: " << unicode();
979 JSObjectPrintBody(os, *this);
980}
981
982void Symbol::SymbolPrint(std::ostream& os) {
983 PrintHeader(os, "Symbol");
984 os << "\n - hash: " << hash();
985 os << "\n - description: " << Brief(description());
986 if (IsUndefined(description())) {
987 os << " (" << PrivateSymbolToName() << ")";
988 }
989 os << "\n - private: " << is_private();
990 os << "\n - private_name: " << is_private_name();
991 os << "\n - private_brand: " << is_private_brand();
992 os << "\n - is_interesting_symbol: " << is_interesting_symbol();
993 os << "\n - is_well_known_symbol: " << is_well_known_symbol();
994 os << "\n";
995}
996
997void DescriptorArray::DescriptorArrayPrint(std::ostream& os) {
998 PrintHeader(os, "DescriptorArray");
999 os << "\n - enum_cache: ";
1000 if (enum_cache()->keys()->length() == 0) {
1001 os << "empty";
1002 } else {
1003 os << enum_cache()->keys()->length();
1004 os << "\n - keys: " << Brief(enum_cache()->keys());
1005 os << "\n - indices: " << Brief(enum_cache()->indices());
1006 }
1007 os << "\n - nof slack descriptors: " << number_of_slack_descriptors();
1008 os << "\n - nof descriptors: " << number_of_descriptors();
1009 const auto raw = raw_gc_state(kRelaxedLoad);
1010 os << "\n - raw gc state: mc epoch "
1011 << DescriptorArrayMarkingState::Epoch::decode(raw) << ", marked "
1012 << DescriptorArrayMarkingState::Marked::decode(raw) << ", delta "
1013 << DescriptorArrayMarkingState::Delta::decode(raw);
1014 PrintDescriptors(os);
1015}
1016
1017namespace {
1018template <typename T>
1019void PrintFixedArrayWithHeader(std::ostream& os, T* array, const char* type) {
1020 array->PrintHeader(os, type);
1021 os << "\n - length: " << array->length();
1022 PrintFixedArrayElements(os, Tagged(array));
1023 os << "\n";
1024}
1025
1026template <typename T>
1027void PrintWeakArrayElements(std::ostream& os, T* array) {
1028 // Print in array notation for non-sparse arrays.
1029 Tagged<MaybeObject> previous_value =
1030 array->length() > 0 ? array->get(0) : Tagged<MaybeObject>(kNullAddress);
1032 int previous_index = 0;
1033 int i;
1034 for (i = 1; i <= array->length(); i++) {
1035 if (i < array->length()) value = array->get(i);
1036 if (previous_value == value && i != array->length()) {
1037 continue;
1038 }
1039 os << "\n";
1040 std::stringstream ss;
1041 ss << previous_index;
1042 if (previous_index != i - 1) {
1043 ss << '-' << (i - 1);
1044 }
1045 os << std::setw(12) << ss.str() << ": " << Brief(previous_value);
1046 previous_index = i;
1047 previous_value = value;
1048 }
1049}
1050
1051} // namespace
1052
1053void ObjectBoilerplateDescription::ObjectBoilerplateDescriptionPrint(
1054 std::ostream& os) {
1055 PrintHeader(os, "ObjectBoilerplateDescription");
1056 os << "\n - capacity: " << capacity();
1057 os << "\n - backing_store_size: " << backing_store_size();
1058 os << "\n - flags: " << flags();
1059 os << "\n - elements:";
1060 PrintFixedArrayElements<ObjectBoilerplateDescription>(
1061 os, this, capacity(), [](Tagged<ObjectBoilerplateDescription> xs, int i) {
1062 return xs->get(i);
1063 });
1064 os << "\n";
1065}
1066
1067void ClassBoilerplate::ClassBoilerplatePrint(std::ostream& os) {
1068 PrintHeader(os, "ClassBoilerplate");
1069 os << "\n - arguments_count: " << arguments_count();
1070 os << "\n - static_properties_template: " << static_properties_template();
1071 os << "\n - static_elements_template: " << static_elements_template();
1072 os << "\n - static_computed_properties: " << static_computed_properties();
1073 os << "\n - instance_properties_template: " << instance_properties_template();
1074 os << "\n - instance_elements_template: " << instance_elements_template();
1075 os << "\n - instance_computed_properties: " << instance_computed_properties();
1076 os << "\n";
1077}
1078
1079void RegExpBoilerplateDescription::RegExpBoilerplateDescriptionPrint(
1080 std::ostream& os) {
1081 IsolateForSandbox isolate = GetIsolateForSandbox(*this);
1082 PrintHeader(os, "RegExpBoilerplate");
1083 os << "\n - data: " << Brief(data(isolate));
1084 os << "\n - source: " << source();
1085 os << "\n - flags: " << flags();
1086 os << "\n";
1087}
1088
1089void EmbedderDataArray::EmbedderDataArrayPrint(std::ostream& os) {
1090 IsolateForSandbox isolate = GetIsolateForSandbox(*this);
1091 PrintHeader(os, "EmbedderDataArray");
1092 os << "\n - length: " << length();
1093 EmbedderDataSlot start(*this, 0);
1094 EmbedderDataSlot end(*this, length());
1095 for (EmbedderDataSlot slot = start; slot < end; ++slot) {
1096 os << "\n ";
1097 PrintEmbedderData(isolate, os, slot);
1098 }
1099 os << "\n";
1100}
1101
1102void FixedArray::FixedArrayPrint(std::ostream& os) {
1103 PrintFixedArrayWithHeader(os, this, "FixedArray");
1104}
1105
1106void TrustedFixedArray::TrustedFixedArrayPrint(std::ostream& os) {
1107 PrintFixedArrayWithHeader(os, this, "TrustedFixedArray");
1108}
1109
1110void ProtectedFixedArray::ProtectedFixedArrayPrint(std::ostream& os) {
1111 PrintFixedArrayWithHeader(os, this, "ProtectedFixedArray");
1112}
1113
1114void ArrayList::ArrayListPrint(std::ostream& os) {
1115 PrintHeader(os, "ArrayList");
1116 os << "\n - capacity: " << capacity();
1117 os << "\n - length: " << length();
1118 os << "\n - elements:";
1119 PrintFixedArrayElements<ArrayList>(
1120 os, this, length(),
1121 [](Tagged<ArrayList> xs, int i) { return xs->get(i); });
1122 os << "\n";
1123}
1124
1125void ScriptContextTable::ScriptContextTablePrint(std::ostream& os) {
1126 PrintHeader(os, "ScriptContextTable");
1127 os << "\n - capacity: " << capacity();
1128 os << "\n - length: " << length(kAcquireLoad);
1129 os << "\n - names_to_context_index: " << names_to_context_index();
1130 os << "\n - elements:";
1131 PrintFixedArrayElements<ScriptContextTable>(
1132 os, this, length(kAcquireLoad), [](Tagged<ScriptContextTable> xs, int i) {
1133 return Cast<Object>(xs->get(i));
1134 });
1135 os << "\n";
1136}
1137
1138void RegExpMatchInfo::RegExpMatchInfoPrint(std::ostream& os) {
1139 PrintHeader(os, "RegExpMatchInfo");
1140 os << "\n - capacity: " << capacity();
1141 os << "\n - number_of_capture_registers: " << number_of_capture_registers();
1142 os << "\n - last_subject: " << last_subject();
1143 os << "\n - last_input: " << last_input();
1144 os << "\n - captures:";
1145 PrintFixedArrayElements<RegExpMatchInfo>(
1146 os, this, capacity(), [](Tagged<RegExpMatchInfo> xs, int i) {
1147 return Cast<Object>(xs->get(i));
1148 });
1149 os << "\n";
1150}
1151
1152void SloppyArgumentsElements::SloppyArgumentsElementsPrint(std::ostream& os) {
1153 PrintHeader(os, "SloppyArgumentsElements");
1154 os << "\n - length: " << length();
1155 os << "\n - context: " << Brief(context());
1156 os << "\n - arguments: " << Brief(arguments());
1157 os << "\n - mapped_entries:";
1158 PrintFixedArrayElements<SloppyArgumentsElements>(
1159 os, this, length(), [](Tagged<SloppyArgumentsElements> xs, int i) {
1160 return Cast<Object>(xs->mapped_entries(i, kRelaxedLoad));
1161 });
1162 os << '\n';
1163}
1164
1165namespace {
1166const char* SideEffectType2String(SideEffectType type) {
1167 switch (type) {
1169 return "kHasSideEffect";
1171 return "kHasNoSideEffect";
1173 return "kHasSideEffectToReceiver";
1174 }
1175}
1176} // namespace
1177
1178#define AS_PTR(x) reinterpret_cast<void*>(x)
1179
1180void AccessorInfo::AccessorInfoPrint(std::ostream& os) {
1181 TorqueGeneratedAccessorInfo<AccessorInfo, HeapObject>::AccessorInfoPrint(os);
1182 os << " - is_sloppy: " << is_sloppy();
1183 os << "\n - replace_on_access: " << replace_on_access();
1184 os << "\n - getter_side_effect_type: "
1185 << SideEffectType2String(getter_side_effect_type());
1186 os << "\n - setter_side_effect_type: "
1187 << SideEffectType2String(setter_side_effect_type());
1188 os << "\n - initial_attributes: " << initial_property_attributes();
1189 Isolate* isolate;
1190 if (GetIsolateFromHeapObject(*this, &isolate)) {
1191 os << "\n - getter: " << AS_PTR(getter(isolate));
1192 if (USE_SIMULATOR_BOOL) {
1193 os << "\n - maybe_redirected_getter: "
1194 << AS_PTR(maybe_redirected_getter(isolate));
1195 }
1196 os << "\n - setter: " << AS_PTR(setter(isolate));
1197 } else {
1198 os << "\n - getter: " << kUnavailableString;
1199 os << "\n - maybe_redirected_getter: " << kUnavailableString;
1200 os << "\n - setter: " << kUnavailableString;
1201 }
1202 os << '\n';
1203}
1204
1205void InterceptorInfo::InterceptorInfoPrint(std::ostream& os) {
1206 TorqueGeneratedInterceptorInfo<InterceptorInfo,
1207 HeapObject>::InterceptorInfoPrint(os);
1208 IsolateForSandbox isolate = GetCurrentIsolateForSandbox();
1209 if (is_named()) {
1210 os << " - getter: " << AS_PTR(named_getter(isolate));
1211 os << "\n - setter: " << AS_PTR(named_setter(isolate));
1212 os << "\n - query: " << AS_PTR(named_query(isolate));
1213 os << "\n - descriptor: " << AS_PTR(named_descriptor(isolate));
1214 os << "\n - deleter: " << AS_PTR(named_deleter(isolate));
1215 os << "\n - enumerator: " << AS_PTR(named_enumerator(isolate));
1216 os << "\n - definer: " << AS_PTR(named_definer(isolate));
1217 } else {
1218 os << " - getter: " << AS_PTR(indexed_getter(isolate));
1219 os << "\n - setter: " << AS_PTR(indexed_setter(isolate));
1220 os << "\n - query: " << AS_PTR(indexed_query(isolate));
1221 os << "\n - descriptor: " << AS_PTR(indexed_descriptor(isolate));
1222 os << "\n - deleter: " << AS_PTR(indexed_deleter(isolate));
1223 os << "\n - enumerator: " << AS_PTR(indexed_enumerator(isolate));
1224 os << "\n - definer: " << AS_PTR(indexed_definer(isolate));
1225 }
1226
1227 os << "\n --- flags: ";
1228 if (can_intercept_symbols()) os << "\n - can_intercept_symbols";
1229 if (non_masking()) os << "\n - non_masking";
1230 if (is_named()) os << "\n - is_named";
1231 if (has_no_side_effect()) os << "\n - has_no_side_effect";
1232 os << '\n';
1233}
1234
1235#undef AS_PTR
1236
1237void FunctionTemplateInfo::FunctionTemplateInfoPrint(std::ostream& os) {
1238 TorqueGeneratedFunctionTemplateInfo<
1239 FunctionTemplateInfo,
1240 TemplateInfoWithProperties>::FunctionTemplateInfoPrint(os);
1241
1242 Isolate* isolate;
1243 if (GetIsolateFromHeapObject(*this, &isolate)) {
1244 os << " - callback: " << reinterpret_cast<void*>(callback(isolate));
1245 if (USE_SIMULATOR_BOOL) {
1246 os << "\n - maybe_redirected_callback: "
1247 << reinterpret_cast<void*>(maybe_redirected_callback(isolate));
1248 }
1249 } else {
1250 os << "\n - callback: " << kUnavailableString;
1251 os << "\n - maybe_redirected_callback: " << kUnavailableString;
1252 }
1253
1254 os << "\n - serial_number: ";
1255 if (serial_number() == kUninitializedSerialNumber) {
1256 os << "n/a";
1257 } else {
1258 os << serial_number();
1259 }
1260 os << "\n --- flags: ";
1261 if (is_cacheable()) os << "\n - is_cacheable";
1262 if (should_promote_to_read_only()) os << "\n - should_promote_to_read_only";
1263 if (is_object_template_call_handler()) {
1264 os << "\n - is_object_template_call_handler";
1265 }
1266 if (has_side_effects()) os << "\n - has_side_effects";
1267
1268 if (undetectable()) os << "\n - undetectable";
1269 if (needs_access_check()) os << "\n - needs_access_check";
1270 if (read_only_prototype()) os << "\n - read_only_prototype";
1271 if (remove_prototype()) os << "\n - remove_prototype";
1272 if (accept_any_receiver()) os << "\n - accept_any_receiver";
1273 if (published()) os << "\n - published";
1274
1275 if (allowed_receiver_instance_type_range_start() ||
1277 os << "\n - allowed_receiver_instance_type_range: ["
1278 << allowed_receiver_instance_type_range_start() << ", "
1280 }
1281 os << '\n';
1282}
1283
1284namespace {
1285void PrintContextWithHeader(std::ostream& os, Tagged<Context> context,
1286 const char* type) {
1287 context->PrintHeader(os, type);
1288 os << "\n - type: " << context->map()->instance_type();
1289 os << "\n - scope_info: " << Brief(context->scope_info());
1290 os << "\n - previous: " << Brief(context->unchecked_previous());
1291 os << "\n - native_context: " << Brief(context->native_context());
1292 if (context->scope_info()->HasContextExtensionSlot()) {
1293 os << "\n - extension: " << context->extension();
1294 }
1295 os << "\n - length: " << context->length();
1296 os << "\n - elements:";
1297 PrintFixedArrayElements(os, context);
1298 os << "\n";
1299}
1300} // namespace
1301
1302void Context::ContextPrint(std::ostream& os) {
1303 PrintContextWithHeader(os, *this, "Context");
1304}
1305
1306void NativeContext::NativeContextPrint(std::ostream& os) {
1307 PrintContextWithHeader(os, *this, "NativeContext");
1308 os << " - microtask_queue: " << microtask_queue() << "\n";
1309}
1310
1311namespace {
1312using DataPrinter = std::function<void(InternalIndex)>;
1313
1314// Prints the data associated with each key (but no headers or other meta
1315// data) in a hash table. Works on different hash table types, like the
1316// subtypes of HashTable and OrderedHashTable. |print_data_at| is given an
1317// index into the table (where a valid key resides) and prints the data at
1318// that index, like just the value (in case of a hash map), or value and
1319// property details (in case of a property dictionary). No leading space
1320// required or trailing newline required. It can be null/non-callable
1321// std::function to indicate that there is no associated data to be printed
1322// (for example in case of a hash set).
1323template <typename T>
1324void PrintTableContentsGeneric(std::ostream& os, T* dict,
1325 DataPrinter print_data_at) {
1327 ReadOnlyRoots roots = GetReadOnlyRoots();
1328
1329 for (InternalIndex i : dict->IterateEntries()) {
1331 if (!dict->ToKey(roots, i, &k)) continue;
1332 os << "\n " << std::setw(12) << i.as_int() << ": ";
1333 if (IsString(k)) {
1334 Cast<String>(k)->PrintUC16(os);
1335 } else {
1336 os << Brief(k);
1337 }
1338 if (print_data_at) {
1339 os << " -> ";
1340 print_data_at(i);
1341 }
1342 }
1343}
1344
1345void PrintNameDictionaryFlags(std::ostream& os, Tagged<NameDictionary> dict) {
1346 if (dict->may_have_interesting_properties()) {
1347 os << "\n - may_have_interesting_properties";
1348 }
1349}
1350
1351// Used for ordered and unordered dictionaries.
1352template <typename T>
1353void PrintDictionaryContentsFull(std::ostream& os, T* dict) {
1354 os << "\n - elements: {";
1355 auto print_value_and_property_details = [&](InternalIndex i) {
1356 os << Brief(dict->ValueAt(i)) << " ";
1357 dict->DetailsAt(i).PrintAsSlowTo(os, !T::kIsOrderedDictionaryType);
1358 };
1359 PrintTableContentsGeneric(os, dict, print_value_and_property_details);
1360 os << "\n }\n";
1361}
1362
1363// Used for ordered and unordered hash maps.
1364template <typename T>
1365void PrintHashMapContentsFull(std::ostream& os, T* dict) {
1366 os << "\n - elements: {";
1367 auto print_value = [&](InternalIndex i) { os << Brief(dict->ValueAt(i)); };
1368 PrintTableContentsGeneric(os, dict, print_value);
1369 os << "\n }\n";
1370}
1371
1372// Used for ordered and unordered hash sets.
1373template <typename T>
1374void PrintHashSetContentsFull(std::ostream& os, T* dict) {
1375 os << "\n - elements: {";
1376 // Passing non-callable std::function as there are no values to print.
1377 PrintTableContentsGeneric(os, dict, nullptr);
1378 os << "\n }\n";
1379}
1380
1381// Used for subtypes of OrderedHashTable.
1382template <typename T>
1383void PrintOrderedHashTableHeaderAndBuckets(std::ostream& os, T* table,
1384 const char* type) {
1386
1387 PrintHeapObjectHeaderWithoutMap(table, os, type);
1388 os << "\n - FixedArray length: " << table->length();
1389 os << "\n - elements: " << table->NumberOfElements();
1390 os << "\n - deleted: " << table->NumberOfDeletedElements();
1391 os << "\n - buckets: " << table->NumberOfBuckets();
1392 os << "\n - capacity: " << table->Capacity();
1393
1394 os << "\n - buckets: {";
1395 for (int bucket = 0; bucket < table->NumberOfBuckets(); bucket++) {
1396 Tagged<Object> entry = table->get(T::HashTableStartIndex() + bucket);
1397 DCHECK(IsSmi(entry));
1398 os << "\n " << std::setw(12) << bucket << ": " << Brief(entry);
1399 }
1400 os << "\n }";
1401}
1402
1403// Used for subtypes of HashTable.
1404template <typename T>
1405void PrintHashTableHeader(std::ostream& os, T* table, const char* type) {
1406 PrintHeapObjectHeaderWithoutMap(table, os, type);
1407 os << "\n - FixedArray length: " << table->length();
1408 os << "\n - elements: " << table->NumberOfElements();
1409 os << "\n - deleted: " << table->NumberOfDeletedElements();
1410 os << "\n - capacity: " << table->Capacity();
1411}
1412} // namespace
1413
1414void ObjectHashTable::ObjectHashTablePrint(std::ostream& os) {
1415 PrintHashTableHeader(os, this, "ObjectHashTable");
1416 PrintHashMapContentsFull(os, this);
1417}
1418
1419void NameToIndexHashTable::NameToIndexHashTablePrint(std::ostream& os) {
1420 PrintHashTableHeader(os, this, "NameToIndexHashTable");
1421 PrintHashMapContentsFull(os, this);
1422}
1423
1424void RegisteredSymbolTable::RegisteredSymbolTablePrint(std::ostream& os) {
1425 PrintHashTableHeader(os, this, "RegisteredSymbolTable");
1426 PrintHashMapContentsFull(os, this);
1427}
1428
1429void NumberDictionary::NumberDictionaryPrint(std::ostream& os) {
1430 PrintHashTableHeader(os, this, "NumberDictionary");
1431 PrintDictionaryContentsFull(os, this);
1432}
1433
1434void EphemeronHashTable::EphemeronHashTablePrint(std::ostream& os) {
1435 PrintHashTableHeader(os, this, "EphemeronHashTable");
1436 PrintHashMapContentsFull(os, this);
1437}
1438
1439void NameDictionary::NameDictionaryPrint(std::ostream& os) {
1440 PrintHashTableHeader(os, this, "NameDictionary");
1441 PrintNameDictionaryFlags(os, this);
1442 PrintDictionaryContentsFull(os, this);
1443}
1444
1445void GlobalDictionary::GlobalDictionaryPrint(std::ostream& os) {
1446 PrintHashTableHeader(os, this, "GlobalDictionary");
1447 PrintDictionaryContentsFull(os, this);
1448}
1449
1450void SmallOrderedHashSet::SmallOrderedHashSetPrint(std::ostream& os) {
1451 PrintHeader(os, "SmallOrderedHashSet");
1452 // TODO(turbofan): Print all fields.
1453}
1454
1455void SmallOrderedHashMap::SmallOrderedHashMapPrint(std::ostream& os) {
1456 PrintHeader(os, "SmallOrderedHashMap");
1457 // TODO(turbofan): Print all fields.
1458}
1459
1460void SmallOrderedNameDictionary::SmallOrderedNameDictionaryPrint(
1461 std::ostream& os) {
1462 PrintHeader(os, "SmallOrderedNameDictionary");
1463 // TODO(turbofan): Print all fields.
1464}
1465
1466void OrderedHashSet::OrderedHashSetPrint(std::ostream& os) {
1467 PrintOrderedHashTableHeaderAndBuckets(os, this, "OrderedHashSet");
1468 PrintHashSetContentsFull(os, this);
1469}
1470
1471void OrderedHashMap::OrderedHashMapPrint(std::ostream& os) {
1472 PrintOrderedHashTableHeaderAndBuckets(os, this, "OrderedHashMap");
1473 PrintHashMapContentsFull(os, this);
1474}
1475
1476void OrderedNameDictionary::OrderedNameDictionaryPrint(std::ostream& os) {
1477 PrintOrderedHashTableHeaderAndBuckets(os, this, "OrderedNameDictionary");
1478 PrintDictionaryContentsFull(os, this);
1479}
1480
1481void print_hex_byte(std::ostream& os, int value) {
1482 os << "0x" << std::setfill('0') << std::setw(2) << std::right << std::hex
1483 << (value & 0xff) << std::setfill(' ');
1484}
1485
1486void SwissNameDictionary::SwissNameDictionaryPrint(std::ostream& os) {
1487 this->PrintHeader(os, "SwissNameDictionary");
1488 os << "\n - meta table ByteArray: "
1489 << reinterpret_cast<void*>(this->meta_table().ptr());
1490 os << "\n - capacity: " << this->Capacity();
1491 os << "\n - elements: " << this->NumberOfElements();
1492 os << "\n - deleted: " << this->NumberOfDeletedElements();
1493
1494 std::ios_base::fmtflags sav_flags = os.flags();
1495 os << "\n - ctrl table (omitting buckets where key is hole value): {";
1496 for (int i = 0; i < this->Capacity() + kGroupWidth; i++) {
1497 ctrl_t ctrl = CtrlTable()[i];
1498
1499 if (ctrl == Ctrl::kEmpty) continue;
1500
1501 os << "\n " << std::setw(12) << std::dec << i << ": ";
1502 switch (ctrl) {
1503 case Ctrl::kEmpty:
1504 UNREACHABLE();
1505 case Ctrl::kDeleted:
1506 print_hex_byte(os, ctrl);
1507 os << " (= kDeleted)";
1508 break;
1509 case Ctrl::kSentinel:
1510 print_hex_byte(os, ctrl);
1511 os << " (= kSentinel)";
1512 break;
1513 default:
1514 print_hex_byte(os, ctrl);
1515 os << " (= H2 of a key)";
1516 break;
1517 }
1518 }
1519 os << "\n }";
1520
1521 os << "\n - enumeration table: {";
1522 for (int enum_index = 0; enum_index < this->UsedCapacity(); enum_index++) {
1523 int entry = EntryForEnumerationIndex(enum_index);
1524 os << "\n " << std::setw(12) << std::dec << enum_index << ": " << entry;
1525 }
1526 os << "\n }";
1527
1528 os << "\n - data table (omitting slots where key is the hole): {";
1529 for (int bucket = 0; bucket < this->Capacity(); ++bucket) {
1531 if (!this->ToKey(GetReadOnlyRoots(), bucket, &k)) continue;
1532
1533 Tagged<Object> value = this->ValueAtRaw(bucket);
1534 PropertyDetails details = this->DetailsAt(bucket);
1535 os << "\n " << std::setw(12) << std::dec << bucket << ": ";
1536 if (IsString(k)) {
1537 Cast<String>(k)->PrintUC16(os);
1538 } else {
1539 os << Brief(k);
1540 }
1541 os << " -> " << Brief(value);
1542 details.PrintAsSlowTo(os, false);
1543 }
1544 os << "\n }\n";
1545 os.flags(sav_flags);
1546}
1547
1548void PropertyArray::PropertyArrayPrint(std::ostream& os) {
1549 PrintHeader(os, "PropertyArray");
1550 os << "\n - length: " << length();
1551 os << "\n - hash: " << Hash();
1552 PrintFixedArrayElements(os, Tagged(*this));
1553 os << "\n";
1554}
1555
1556void FixedDoubleArray::FixedDoubleArrayPrint(std::ostream& os) {
1557 PrintHeader(os, "FixedDoubleArray");
1558 os << "\n - length: " << length();
1559 DoPrintElements<FixedDoubleArray>(os, this, length());
1560 os << "\n";
1561}
1562
1563void WeakFixedArray::WeakFixedArrayPrint(std::ostream& os) {
1564 PrintHeader(os, "WeakFixedArray");
1565 os << "\n - length: " << length();
1566 PrintWeakArrayElements(os, this);
1567 os << "\n";
1568}
1569
1570void TrustedWeakFixedArray::TrustedWeakFixedArrayPrint(std::ostream& os) {
1571 PrintHeader(os, "TrustedWeakFixedArray");
1572 os << "\n - length: " << length();
1573 PrintWeakArrayElements(os, this);
1574 os << "\n";
1575}
1576
1577void ProtectedWeakFixedArray::ProtectedWeakFixedArrayPrint(std::ostream& os) {
1578 PrintHeader(os, "ProtectedWeakFixedArray");
1579 os << "\n - length: " << length();
1580 PrintWeakArrayElements(os, this);
1581 os << "\n";
1582}
1583
1584void WeakArrayList::WeakArrayListPrint(std::ostream& os) {
1585 PrintHeader(os, "WeakArrayList");
1586 os << "\n - capacity: " << capacity();
1587 os << "\n - length: " << length();
1588 PrintWeakArrayElements(os, this);
1589 os << "\n";
1590}
1591
1592void TransitionArray::TransitionArrayPrint(std::ostream& os) {
1593 PrintHeader(os, "TransitionArray");
1594 PrintInternal(os);
1595 os << "\n";
1596}
1597
1598void FeedbackCell::FeedbackCellPrint(std::ostream& os) {
1599 PrintHeader(os, "FeedbackCell");
1600 ReadOnlyRoots roots = GetReadOnlyRoots();
1601 if (map() == roots.no_closures_cell_map()) {
1602 os << "\n - no closures";
1603 } else if (map() == roots.one_closure_cell_map()) {
1604 os << "\n - one closure";
1605 } else if (map() == roots.many_closures_cell_map()) {
1606 os << "\n - many closures";
1607 } else {
1608 os << "\n - Invalid FeedbackCell map";
1609 }
1610 os << "\n - value: " << Brief(value());
1611 os << "\n - interrupt_budget: " << interrupt_budget();
1612#ifdef V8_ENABLE_LEAPTIERING
1613 os << "\n - dispatch_handle: 0x" << std::hex << dispatch_handle() << std::dec;
1614 JSDispatchTable* jdt = IsolateGroup::current()->js_dispatch_table();
1615 if (dispatch_handle() != kNullJSDispatchHandle &&
1616 jdt->IsTieringRequested(dispatch_handle())) {
1617 os << "\n - tiering request ";
1618 if (Tagged<FeedbackVector> fbv;
1619 TryCast(value(), &fbv) && fbv->tiering_in_progress()) {
1620 os << "in_progress ";
1621 }
1622 jdt->PrintCurrentTieringRequest(dispatch_handle(),
1623 GetIsolateFromWritableObject(*this), os);
1624 }
1625
1626#endif // V8_ENABLE_LEAPTIERING
1627 os << "\n";
1628}
1629
1630void FeedbackVectorSpec::Print() {
1631 StdoutStream os;
1632
1633 FeedbackVectorSpecPrint(os);
1634
1635 os << std::flush;
1636}
1637
1638void FeedbackVectorSpec::FeedbackVectorSpecPrint(std::ostream& os) {
1639 os << " - slot_count: " << slot_count();
1640 if (slot_count() == 0) {
1641 os << " (empty)\n";
1642 return;
1643 }
1644
1645 for (int slot = 0; slot < slot_count();) {
1646 FeedbackSlotKind kind = GetKind(FeedbackSlot(slot));
1647 int entry_size = FeedbackMetadata::GetSlotSize(kind);
1648 DCHECK_LT(0, entry_size);
1649 os << "\n Slot #" << slot << " " << kind;
1650 slot += entry_size;
1651 }
1652 os << "\n";
1653}
1654
1655void FeedbackMetadata::FeedbackMetadataPrint(std::ostream& os) {
1656 PrintHeader(os, "FeedbackMetadata");
1657 os << "\n - slot_count: " << slot_count();
1658 os << "\n - create_closure_slot_count: " << create_closure_slot_count();
1659
1660 FeedbackMetadataIterator iter(*this);
1661 while (iter.HasNext()) {
1662 FeedbackSlot slot = iter.Next();
1663 FeedbackSlotKind kind = iter.kind();
1664 os << "\n Slot " << slot << " " << kind;
1665 }
1666 os << "\n";
1667}
1668
1669void ClosureFeedbackCellArray::ClosureFeedbackCellArrayPrint(std::ostream& os) {
1670 PrintHeader(os, "ClosureFeedbackCellArray");
1671 os << "\n - length: " << length();
1672 os << "\n - elements:";
1673 PrintFixedArrayElements<ClosureFeedbackCellArray>(os, this);
1674 os << "\n";
1675}
1676
1677void FeedbackVector::FeedbackVectorPrint(std::ostream& os) {
1678 PrintHeader(os, "FeedbackVector");
1679 os << "\n - length: " << length();
1680 if (length() == 0) {
1681 os << " (empty)\n";
1682 return;
1683 }
1684
1685 os << "\n - shared function info: " << Brief(shared_function_info());
1686#ifdef V8_ENABLE_LEAPTIERING
1687 os << "\n - tiering_in_progress: " << tiering_in_progress();
1688#else
1689 os << "\n - tiering state: " << tiering_state();
1690 if (has_optimized_code()) {
1691 os << "\n - optimized code: "
1692 << Brief(optimized_code(GetIsolateForSandbox(*this)));
1693 } else {
1694 os << "\n - no optimized code";
1695 }
1696 os << "\n - maybe has maglev code: " << maybe_has_maglev_code();
1697 os << "\n - maybe has turbofan code: " << maybe_has_turbofan_code();
1698#endif // !V8_ENABLE_LEAPTIERING
1699 os << "\n - osr_tiering_in_progress: " << osr_tiering_in_progress();
1700 os << "\n - invocation count: " << invocation_count();
1701 os << "\n - closure feedback cell array: ";
1702 closure_feedback_cell_array()->ClosureFeedbackCellArrayPrint(os);
1703
1704 FeedbackMetadataIterator iter(metadata());
1705 while (iter.HasNext()) {
1706 FeedbackSlot slot = iter.Next();
1707 FeedbackSlotKind kind = iter.kind();
1708
1709 os << "\n - slot " << slot << " " << kind << " ";
1710 FeedbackSlotPrint(os, slot);
1711
1712 int entry_size = iter.entry_size();
1713 if (entry_size > 0) os << " {";
1714 for (int i = 0; i < entry_size; i++) {
1715 FeedbackSlot slot_with_offset = slot.WithOffset(i);
1716 os << "\n [" << slot_with_offset.ToInt()
1717 << "]: " << Brief(Get(slot_with_offset));
1718 }
1719 if (entry_size > 0) os << "\n }";
1720 }
1721 os << "\n";
1722}
1723
1724void FeedbackVector::FeedbackSlotPrint(std::ostream& os, FeedbackSlot slot) {
1725 FeedbackNexus nexus(GetIsolate(), *this, slot);
1726 nexus.Print(os);
1727}
1728
1729void FeedbackNexus::Print(std::ostream& os) {
1730 auto slot_kind = kind();
1731 switch (slot_kind) {
1740 break;
1741 }
1748 os << "\n ";
1749 if (GetFeedback().IsCleared()) {
1750 // Handler mode: feedback is the cleared value, extra is the handler.
1751 if (IsLoadGlobalICKind(slot_kind)) {
1752 LoadHandler::PrintHandler(GetFeedbackExtra().GetHeapObjectOrSmi(),
1753 os);
1754 } else {
1755 StoreHandler::PrintHandler(GetFeedbackExtra().GetHeapObjectOrSmi(),
1756 os);
1757 }
1758 } else if (IsPropertyCell(GetFeedback().GetHeapObjectOrSmi())) {
1759 os << Brief(GetFeedback());
1760 } else {
1761 // Lexical variable mode: the variable location is encoded in the SMI.
1762 int handler = GetFeedback().GetHeapObjectOrSmi().ToSmi().value();
1763 os << (IsLoadGlobalICKind(slot_kind) ? "Load" : "Store");
1764 os << "Handler(Lexical variable mode)(context ix = "
1765 << FeedbackNexus::ContextIndexBits::decode(handler)
1766 << ", slot ix = " << FeedbackNexus::SlotIndexBits::decode(handler)
1767 << ")";
1768 }
1769 }
1770 break;
1771 }
1776 os << "\n " << Brief(GetFeedback()) << ": ";
1777 if (GetFeedbackExtra().IsCleared()) {
1778 os << " <cleared>\n";
1779 break;
1780 }
1781 Tagged<Object> handler = GetFeedbackExtra().GetHeapObjectOrSmi();
1782 if (IsWeakFixedArray(handler) &&
1783 !Cast<WeakFixedArray>(handler)->get(0).IsCleared()) {
1784 handler = Cast<WeakFixedArray>(handler)->get(0).GetHeapObjectOrSmi();
1785 }
1786 LoadHandler::PrintHandler(handler, os);
1787 } else if (ic_state() == InlineCacheState::POLYMORPHIC) {
1788 Tagged<HeapObject> feedback = GetFeedback().GetHeapObject();
1790 if (IsName(feedback)) {
1791 os << " with name " << Brief(feedback);
1792 array = Cast<WeakFixedArray>(GetFeedbackExtra().GetHeapObject());
1793 } else {
1794 array = Cast<WeakFixedArray>(feedback);
1795 }
1796 for (int i = 0; i < array->length(); i += 2) {
1797 os << "\n " << Brief(array->get(i)) << ": ";
1798 LoadHandler::PrintHandler(array->get(i + 1).GetHeapObjectOrSmi(), os);
1799 }
1800 }
1801 break;
1802 }
1810 if (GetFeedback().IsCleared()) {
1811 os << "\n [cleared]";
1812 break;
1813 }
1815 Tagged<HeapObject> feedback = GetFeedback().GetHeapObject();
1816 if (GetFeedbackExtra().IsCleared()) {
1817 os << " [cleared]\n";
1818 break;
1819 }
1820 if (IsName(feedback)) {
1821 os << " with name " << Brief(feedback);
1823 Cast<WeakFixedArray>(GetFeedbackExtra().GetHeapObject());
1824 os << "\n " << Brief(array->get(0)) << ": ";
1825 if (array->get(1).IsCleared()) {
1826 os << "[cleared]\n";
1827 } else {
1828 Tagged<Object> handler = array->get(1).GetHeapObjectOrSmi();
1829 StoreHandler::PrintHandler(handler, os);
1830 }
1831 } else {
1832 os << "\n " << Brief(feedback) << ": ";
1833 StoreHandler::PrintHandler(GetFeedbackExtra().GetHeapObjectOrSmi(),
1834 os);
1835 }
1836 } else if (ic_state() == InlineCacheState::POLYMORPHIC) {
1837 Tagged<HeapObject> feedback = GetFeedback().GetHeapObject();
1839 if (IsName(feedback)) {
1840 os << " with name " << Brief(feedback);
1841 array = Cast<WeakFixedArray>(GetFeedbackExtra().GetHeapObject());
1842 } else {
1843 array = Cast<WeakFixedArray>(feedback);
1844 }
1845 for (int i = 0; i < array->length(); i += 2) {
1846 os << "\n " << Brief(array->get(i)) << ": ";
1847 if (!array->get(i + 1).IsCleared()) {
1848 StoreHandler::PrintHandler(array->get(i + 1).GetHeapObjectOrSmi(),
1849 os);
1850 }
1851 }
1852 }
1853 break;
1854 }
1856 os << "BinaryOp:" << GetBinaryOperationFeedback();
1857 break;
1858 }
1860 os << "CompareOp:" << GetCompareOperationFeedback();
1861 break;
1862 }
1864 os << "ForIn:" << GetForInFeedback();
1865 break;
1866 }
1868 break;
1870 os << "JumpLoop";
1871 break;
1873 UNREACHABLE();
1874 }
1875}
1876
1877void Oddball::OddballPrint(std::ostream& os) {
1878 PrintHeapObjectHeaderWithoutMap(Tagged<HeapObject>(this), os, "Oddball");
1879 os << ": ";
1881 os << s->PrefixForDebugPrint();
1882 s->PrintUC16(os);
1883 os << s->SuffixForDebugPrint();
1884 os << std::endl;
1885}
1886
1887void Hole::HolePrint(std::ostream& os) {
1888 PrintHeapObjectHeaderWithoutMap(*this, os, "Hole");
1889 ReadOnlyRoots roots = GetReadOnlyRoots();
1890#define PRINT_SPECIFIC_HOLE(type, name, CamelName) \
1891 if (*this == roots.name()) { \
1892 os << "\n <" #name ">"; \
1893 }
1894 HOLE_LIST(PRINT_SPECIFIC_HOLE);
1895#undef PRINT_SPECIFIC_HOLE
1896
1897 os << std::endl;
1898}
1899
1900void JSAsyncFunctionObject::JSAsyncFunctionObjectPrint(std::ostream& os) {
1901 JSGeneratorObjectPrint(os);
1902}
1903
1904void JSAsyncGeneratorObject::JSAsyncGeneratorObjectPrint(std::ostream& os) {
1905 JSGeneratorObjectPrint(os);
1906}
1907
1908void JSArgumentsObject::JSArgumentsObjectPrint(std::ostream& os) {
1909 JSObjectPrint(os);
1910}
1911
1912void JSStringIterator::JSStringIteratorPrint(std::ostream& os) {
1913 JSObjectPrintHeader(os, *this, "JSStringIterator");
1914 os << "\n - string: " << Brief(string());
1915 os << "\n - index: " << index();
1916 JSObjectPrintBody(os, *this);
1917}
1918
1919void JSAsyncFromSyncIterator::JSAsyncFromSyncIteratorPrint(std::ostream& os) {
1920 JSObjectPrintHeader(os, *this, "JSAsyncFromSyncIterator");
1921 os << "\n - sync_iterator: " << Brief(sync_iterator());
1922 os << "\n - next: " << Brief(next());
1923 JSObjectPrintBody(os, *this);
1924}
1925
1926void JSValidIteratorWrapper::JSValidIteratorWrapperPrint(std::ostream& os) {
1927 JSObjectPrintHeader(os, *this, "JSValidIteratorWrapper");
1928 os << "\n - underlying.object: " << Brief(underlying_object());
1929 os << "\n - underlying.next: " << Brief(underlying_next());
1930 JSObjectPrintBody(os, *this);
1931}
1932
1933void JSPrimitiveWrapper::JSPrimitiveWrapperPrint(std::ostream& os) {
1934 JSObjectPrintHeader(os, *this, "JSPrimitiveWrapper");
1935 os << "\n - value: " << Brief(value());
1936 JSObjectPrintBody(os, *this);
1937}
1938
1939void JSMessageObject::JSMessageObjectPrint(std::ostream& os) {
1940 JSObjectPrintHeader(os, *this, "JSMessageObject");
1941 os << "\n - type: " << static_cast<int>(type());
1942 os << "\n - arguments: " << Brief(argument());
1943 os << "\n - script: " << Brief(script());
1944 os << "\n - stack_trace: " << Brief(stack_trace());
1945 os << "\n - shared_info: " << Brief(shared_info());
1946 if (shared_info() == Smi::zero()) {
1947 os << " (cleared after calculating line ends)";
1948 } else if (shared_info() == Smi::FromInt(-1)) {
1949 os << "(no line ends needed)";
1950 }
1951 os << "\n - bytecode_offset: " << bytecode_offset();
1952 os << "\n - start_position: " << start_position();
1953 os << "\n - end_position: " << end_position();
1954 os << "\n - error_level: " << error_level();
1955 JSObjectPrintBody(os, *this);
1956}
1957
1958void String::StringPrint(std::ostream& os) {
1959 PrintHeapObjectHeaderWithoutMap(this, os, "String");
1960 os << ": ";
1961 os << PrefixForDebugPrint();
1962 PrintUC16(os, 0, length());
1963 os << SuffixForDebugPrint();
1964}
1965
1966void Name::NamePrint(std::ostream& os) {
1967 if (IsString(this)) {
1968 Cast<String>(this)->StringPrint(os);
1969 } else {
1970 os << Brief(this);
1971 }
1972}
1973
1974static const char* const weekdays[] = {"???", "Sun", "Mon", "Tue",
1975 "Wed", "Thu", "Fri", "Sat"};
1976
1977void JSDate::JSDatePrint(std::ostream& os) {
1978 JSObjectPrintHeader(os, *this, "JSDate");
1979 os << "\n - value: " << value();
1980 if (!IsSmi(year())) {
1981 os << "\n - time = NaN\n";
1982 } else {
1983 // TODO(svenpanne) Add some basic formatting to our streams.
1984 base::ScopedVector<char> buf(100);
1985 SNPrintF(buf, "\n - time = %s %04d/%02d/%02d %02d:%02d:%02d\n",
1986 weekdays[IsSmi(weekday()) ? Smi::ToInt(weekday()) + 1 : 0],
1987 IsSmi(year()) ? Smi::ToInt(year()) : -1,
1988 IsSmi(month()) ? Smi::ToInt(month()) : -1,
1989 IsSmi(day()) ? Smi::ToInt(day()) : -1,
1990 IsSmi(hour()) ? Smi::ToInt(hour()) : -1,
1991 IsSmi(min()) ? Smi::ToInt(min()) : -1,
1992 IsSmi(sec()) ? Smi::ToInt(sec()) : -1);
1993 os << buf.begin();
1994 }
1995 JSObjectPrintBody(os, *this);
1996}
1997
1998void JSSet::JSSetPrint(std::ostream& os) {
1999 JSObjectPrintHeader(os, *this, "JSSet");
2000 os << "\n - table: " << Brief(table());
2001 JSObjectPrintBody(os, *this);
2002}
2003
2004void JSMap::JSMapPrint(std::ostream& os) {
2005 JSObjectPrintHeader(os, *this, "JSMap");
2006 os << "\n - table: " << Brief(table());
2007 JSObjectPrintBody(os, *this);
2008}
2009
2011 const char* name) {
2012 JSObjectPrintHeader(os, *this, name);
2013 os << "\n - table: " << Brief(table());
2014 os << "\n - index: " << Brief(index());
2015 JSObjectPrintBody(os, *this);
2016}
2017
2018void JSSetIterator::JSSetIteratorPrint(std::ostream& os) {
2019 JSCollectionIteratorPrint(os, "JSSetIterator");
2020}
2021
2022void JSMapIterator::JSMapIteratorPrint(std::ostream& os) {
2023 JSCollectionIteratorPrint(os, "JSMapIterator");
2024}
2025
2026void JSWeakRef::JSWeakRefPrint(std::ostream& os) {
2027 JSObjectPrintHeader(os, *this, "JSWeakRef");
2028 os << "\n - target: " << Brief(target());
2029 JSObjectPrintBody(os, *this);
2030}
2031
2032void JSShadowRealm::JSShadowRealmPrint(std::ostream& os) {
2033 JSObjectPrintHeader(os, *this, "JSShadowRealm");
2034 os << "\n - native_context: " << Brief(native_context());
2035 JSObjectPrintBody(os, *this);
2036}
2037
2038void JSWrappedFunction::JSWrappedFunctionPrint(std::ostream& os) {
2039 JSObjectPrintHeader(os, *this, "JSWrappedFunction");
2040 os << "\n - wrapped_target_function: " << Brief(wrapped_target_function());
2041 JSObjectPrintBody(os, *this);
2042}
2043
2044void JSFinalizationRegistry::JSFinalizationRegistryPrint(std::ostream& os) {
2045 JSObjectPrintHeader(os, *this, "JSFinalizationRegistry");
2046 os << "\n - native_context: " << Brief(native_context());
2047 os << "\n - cleanup: " << Brief(cleanup());
2048 os << "\n - active_cells: " << Brief(active_cells());
2049 Tagged<Object> active_cell = active_cells();
2050 while (IsWeakCell(active_cell)) {
2051 os << "\n - " << Brief(active_cell);
2052 active_cell = Cast<WeakCell>(active_cell)->next();
2053 }
2054 os << "\n - cleared_cells: " << Brief(cleared_cells());
2055 Tagged<Object> cleared_cell = cleared_cells();
2056 while (IsWeakCell(cleared_cell)) {
2057 os << "\n - " << Brief(cleared_cell);
2058 cleared_cell = Cast<WeakCell>(cleared_cell)->next();
2059 }
2060 os << "\n - key_map: " << Brief(key_map());
2061 JSObjectPrintBody(os, *this);
2062}
2063
2064void JSSharedArray::JSSharedArrayPrint(std::ostream& os) {
2065 JSObjectPrintHeader(os, *this, "JSSharedArray");
2066 Isolate* isolate = GetIsolateFromWritableObject(*this);
2067 os << "\n - isolate: " << isolate;
2068 if (HeapLayout::InWritableSharedSpace(*this)) os << " (shared)";
2069 JSObjectPrintBody(os, *this);
2070}
2071
2072void JSSharedStruct::JSSharedStructPrint(std::ostream& os) {
2073 JSObjectPrintHeader(os, *this, "JSSharedStruct");
2074 Isolate* isolate = GetIsolateFromWritableObject(*this);
2075 os << "\n - isolate: " << isolate;
2076 if (HeapLayout::InWritableSharedSpace(*this)) os << " (shared)";
2077 JSObjectPrintBody(os, *this);
2078}
2079
2080void JSAtomicsMutex::JSAtomicsMutexPrint(std::ostream& os) {
2081 JSObjectPrintHeader(os, *this, "JSAtomicsMutex");
2082 Isolate* isolate = GetIsolateFromWritableObject(*this);
2083 os << "\n - isolate: " << isolate;
2084 if (HeapLayout::InWritableSharedSpace(*this)) os << " (shared)";
2085 os << "\n - state: " << this->state();
2086 os << "\n - owner_thread_id: " << this->owner_thread_id();
2087 JSObjectPrintBody(os, *this);
2088}
2089
2090void JSAtomicsCondition::JSAtomicsConditionPrint(std::ostream& os) {
2091 JSObjectPrintHeader(os, *this, "JSAtomicsCondition");
2092 Isolate* isolate = GetIsolateFromWritableObject(*this);
2093 os << "\n - isolate: " << isolate;
2094 if (HeapLayout::InWritableSharedSpace(*this)) os << " (shared)";
2095 os << "\n - state: " << this->state();
2096 JSObjectPrintBody(os, *this);
2097}
2098
2099std::ostream& operator<<(std::ostream& os, DisposableStackState state) {
2100 switch (state) {
2102 return os << "Pending";
2104 return os << "Disposed";
2105 }
2106 UNREACHABLE();
2107}
2108
2109void JSDisposableStackBase::JSDisposableStackBasePrint(std::ostream& os) {
2110 JSObjectPrintHeader(os, *this, "JSDisposableStack");
2111 os << "\n - stack: " << Brief(stack());
2112 os << "\n - length: " << length();
2113 os << "\n - state: " << state();
2114 os << "\n - needs_await: " << needs_await();
2115 os << "\n - has_awaited: " << has_awaited();
2116 os << "\n - suppressed_error_created: " << suppressed_error_created();
2117 os << "\n - error: " << error();
2118 os << "\n - error_message: " << error_message();
2119 JSObjectPrintBody(os, *this);
2120}
2121
2122void JSAsyncDisposableStack::JSAsyncDisposableStackPrint(std::ostream& os) {
2123 JSObjectPrintHeader(os, *this, "JSAsyncDisposableStack");
2124 os << "\n - stack: " << Brief(stack());
2125 os << "\n - length: " << length();
2126 os << "\n - state: " << state();
2127 os << "\n - needs_await: " << needs_await();
2128 os << "\n - has_awaited: " << has_awaited();
2129 os << "\n - suppressed_error_created: " << suppressed_error_created();
2130 os << "\n - error: " << error();
2131 os << "\n - error_message: " << error_message();
2132 JSObjectPrintBody(os, *this);
2133}
2134
2136 const char* helper_name) {
2137 JSObjectPrintHeader(os, *this, helper_name);
2138 os << "\n - underlying.object: " << Brief(underlying_object());
2139 os << "\n - underlying.next: " << Brief(underlying_next());
2140}
2141
2142void JSIteratorMapHelper::JSIteratorMapHelperPrint(std::ostream& os) {
2143 JSIteratorHelperPrintHeader(os, "JSIteratorMapHelper");
2144 os << "\n - mapper: " << Brief(mapper());
2145 os << "\n - counter: " << counter();
2146 JSObjectPrintBody(os, *this);
2147}
2148
2149void JSIteratorFilterHelper::JSIteratorFilterHelperPrint(std::ostream& os) {
2150 JSIteratorHelperPrintHeader(os, "JSIteratorFilterHelper");
2151 os << "\n - predicate: " << Brief(predicate());
2152 os << "\n - counter: " << counter();
2153 JSObjectPrintBody(os, *this);
2154}
2155
2156void JSIteratorTakeHelper::JSIteratorTakeHelperPrint(std::ostream& os) {
2157 JSIteratorHelperPrintHeader(os, "JSIteratorTakeHelper");
2158 os << "\n - remaining: " << remaining();
2159 JSObjectPrintBody(os, *this);
2160}
2161
2162void JSIteratorDropHelper::JSIteratorDropHelperPrint(std::ostream& os) {
2163 JSIteratorHelperPrintHeader(os, "JSIteratorDropHelper");
2164 os << "\n - remaining: " << remaining();
2165 JSObjectPrintBody(os, *this);
2166}
2167
2168void JSIteratorFlatMapHelper::JSIteratorFlatMapHelperPrint(std::ostream& os) {
2169 JSIteratorHelperPrintHeader(os, "JSIteratorFlatMapHelper");
2170 os << "\n - mapper: " << Brief(mapper());
2171 os << "\n - counter: " << counter();
2172 os << "\n - innerIterator.object" << Brief(innerIterator_object());
2173 os << "\n - innerIterator.next" << Brief(innerIterator_next());
2174 os << "\n - innerAlive" << innerAlive();
2175 JSObjectPrintBody(os, *this);
2176}
2177
2178void JSWeakMap::JSWeakMapPrint(std::ostream& os) {
2179 JSObjectPrintHeader(os, *this, "JSWeakMap");
2180 os << "\n - table: " << Brief(table());
2181 JSObjectPrintBody(os, *this);
2182}
2183
2184void JSWeakSet::JSWeakSetPrint(std::ostream& os) {
2185 JSObjectPrintHeader(os, *this, "JSWeakSet");
2186 os << "\n - table: " << Brief(table());
2187 JSObjectPrintBody(os, *this);
2188}
2189
2190void JSArrayBuffer::JSArrayBufferPrint(std::ostream& os) {
2191 JSAPIObjectWithEmbedderSlotsPrintHeader(os, *this, "JSArrayBuffer");
2192 os << "\n - backing_store: " << backing_store();
2193 os << "\n - byte_length: " << byte_length();
2194 os << "\n - max_byte_length: " << max_byte_length();
2195 os << "\n - detach key: " << detach_key();
2196 if (is_external()) os << "\n - external";
2197 if (is_detachable()) os << "\n - detachable";
2198 if (was_detached()) os << "\n - detached";
2199 if (is_shared()) os << "\n - shared";
2200 if (is_resizable_by_js()) os << "\n - resizable_by_js";
2201 JSObjectPrintBody(os, *this, !was_detached());
2202}
2203
2204void JSTypedArray::JSTypedArrayPrint(std::ostream& os) {
2205 JSAPIObjectWithEmbedderSlotsPrintHeader(os, *this, "JSTypedArray");
2206 os << "\n - buffer: " << Brief(buffer());
2207 os << "\n - byte_offset: " << byte_offset();
2208 os << "\n - byte_length: " << byte_length();
2209 os << "\n - length: " << GetLength();
2210 os << "\n - data_ptr: " << DataPtr();
2211 Tagged_t base_ptr = static_cast<Tagged_t>(base_pointer().ptr());
2212 os << "\n - base_pointer: "
2213 << reinterpret_cast<void*>(static_cast<Address>(base_ptr));
2214 os << "\n - external_pointer: "
2215 << reinterpret_cast<void*>(external_pointer());
2216 if (!IsJSArrayBuffer(buffer())) {
2217 os << "\n <invalid buffer>\n";
2218 return;
2219 }
2220 if (WasDetached()) os << "\n - detached";
2221 if (is_length_tracking()) os << "\n - length-tracking";
2222 if (is_backed_by_rab()) os << "\n - backed-by-rab";
2223 JSObjectPrintBody(os, *this, !WasDetached());
2224}
2225
2226void JSArrayIterator::JSArrayIteratorPrint(std::ostream& os) { // NOLING
2227 JSObjectPrintHeader(os, *this, "JSArrayIterator");
2228 os << "\n - iterated_object: " << Brief(iterated_object());
2229 os << "\n - next_index: " << Brief(next_index());
2230 os << "\n - kind: " << kind();
2231 JSObjectPrintBody(os, *this);
2232}
2233
2234void JSDataView::JSDataViewPrint(std::ostream& os) {
2235 JSObjectPrintHeader(os, *this, "JSDataView");
2236 os << "\n - buffer =" << Brief(buffer());
2237 os << "\n - byte_offset: " << byte_offset();
2238 os << "\n - byte_length: " << byte_length();
2239 if (!IsJSArrayBuffer(buffer())) {
2240 os << "\n <invalid buffer>";
2241 return;
2242 }
2243 if (WasDetached()) os << "\n - detached";
2244 JSObjectPrintBody(os, *this, !WasDetached());
2245}
2246
2247void JSRabGsabDataView::JSRabGsabDataViewPrint(std::ostream& os) {
2248 JSObjectPrintHeader(os, *this, "JSRabGsabDataView");
2249 os << "\n - buffer =" << Brief(buffer());
2250 os << "\n - byte_offset: " << byte_offset();
2251 os << "\n - byte_length: " << byte_length();
2252 if (is_length_tracking()) os << "\n - length-tracking";
2253 if (is_backed_by_rab()) os << "\n - backed-by-rab";
2254 if (!IsJSArrayBuffer(buffer())) {
2255 os << "\n <invalid buffer>";
2256 return;
2257 }
2258 if (WasDetached()) os << "\n - detached";
2259 JSObjectPrintBody(os, *this, !WasDetached());
2260}
2261
2262void JSBoundFunction::JSBoundFunctionPrint(std::ostream& os) {
2263 JSObjectPrintHeader(os, *this, "JSBoundFunction");
2264 os << "\n - bound_target_function: " << Brief(bound_target_function());
2265 os << "\n - bound_this: " << Brief(bound_this());
2266 os << "\n - bound_arguments: " << Brief(bound_arguments());
2267 JSObjectPrintBody(os, *this);
2268}
2269
2270void JSFunction::JSFunctionPrint(std::ostream& os) {
2271 Isolate* isolate = GetIsolate();
2272 JSObjectPrintHeader(os, *this, "Function");
2273 os << "\n - function prototype: ";
2274 if (has_prototype_slot()) {
2275 if (has_prototype()) {
2276 os << Brief(prototype());
2277 if (map()->has_non_instance_prototype()) {
2278 os << " (non-instance prototype)";
2279 }
2280 }
2281 os << "\n - initial_map: ";
2282 if (has_initial_map()) os << Brief(initial_map());
2283 } else {
2284 os << "<no-prototype-slot>";
2285 }
2286 os << "\n - shared_info: " << Brief(shared());
2287 os << "\n - name: " << Brief(shared()->Name());
2288
2289 // Print Builtin name for builtin functions
2290 Builtin builtin = code(isolate)->builtin_id();
2291 if (Builtins::IsBuiltinId(builtin)) {
2292 os << "\n - builtin: " << isolate->builtins()->name(builtin);
2293 }
2294
2295 os << "\n - formal_parameter_count: ";
2296 int formal_parameter_count =
2297 shared()->internal_formal_parameter_count_with_receiver();
2298 if (formal_parameter_count == kDontAdaptArgumentsSentinel) {
2299 os << "kDontAdaptArgumentsSentinel";
2300 } else {
2301 os << formal_parameter_count;
2302 }
2303 os << "\n - kind: " << shared()->kind();
2304 os << "\n - context: " << Brief(context());
2305 os << "\n - code: " << Brief(code(isolate));
2306#ifdef V8_ENABLE_LEAPTIERING
2307 os << "\n - dispatch_handle: 0x" << std::hex << dispatch_handle() << std::dec;
2308 if (has_feedback_vector() &&
2309 raw_feedback_cell()->dispatch_handle() != dispatch_handle()) {
2310 os << "\n - canonical feedback cell dispatch_handle: 0x" << std::hex
2311 << raw_feedback_cell()->dispatch_handle() << std::dec;
2312 }
2314 os << "\n - tiering request ";
2315 if (tiering_in_progress()) {
2316 os << "in_progress ";
2317 }
2318 IsolateGroup::current()->js_dispatch_table()->PrintCurrentTieringRequest(
2319 dispatch_handle(), GetIsolate(), os);
2320 }
2321
2322#endif // V8_ENABLE_LEAPTIERING
2323 if (code(isolate)->kind() == CodeKind::FOR_TESTING) {
2324 os << "\n - FOR_TESTING";
2325 } else if (ActiveTierIsIgnition(isolate)) {
2326 os << "\n - interpreted";
2327 if (shared()->HasBytecodeArray()) {
2328 os << "\n - bytecode: " << shared()->GetBytecodeArray(isolate);
2329 }
2330 }
2331#if V8_ENABLE_WEBASSEMBLY
2335 function->shared()->wasm_exported_function_data();
2336 os << "\n - Wasm instance data: " << Brief(data->instance_data());
2337 os << "\n - Wasm function index: " << data->function_index();
2338 }
2341 os << "\n - Wasm wrapper around: "
2342 << Brief(function->shared()->wasm_js_function_data()->GetCallable());
2343 }
2344#endif // V8_ENABLE_WEBASSEMBLY
2345 shared()->PrintSourceCode(os);
2346 JSObjectPrintBody(os, *this);
2347 os << " - feedback vector: ";
2348 if (!shared()->HasFeedbackMetadata()) {
2349 os << "feedback metadata is not available in SFI\n";
2350 } else if (has_feedback_vector()) {
2351 feedback_vector()->FeedbackVectorPrint(os);
2352 } else if (has_closure_feedback_cell_array()) {
2353 os << "No feedback vector, but we have a closure feedback cell array\n";
2354 closure_feedback_cell_array()->ClosureFeedbackCellArrayPrint(os);
2355 } else {
2356 os << "not available\n";
2357 }
2358}
2359
2360void SharedFunctionInfo::PrintSourceCode(std::ostream& os) {
2361 if (HasSourceCode()) {
2362 os << "\n - source code: ";
2364 int start = StartPosition();
2365 int length = EndPosition() - start;
2366 std::unique_ptr<char[]> source_string = source->ToCString(start, length);
2367 os << source_string.get();
2368 }
2369}
2370
2371void SharedFunctionInfo::SharedFunctionInfoPrint(std::ostream& os) {
2372 PrintHeader(os, "SharedFunctionInfo");
2373 os << "\n - name: ";
2374 if (HasSharedName()) {
2375 os << Brief(Name());
2376 } else {
2377 os << "<no-shared-name>";
2378 }
2379 if (HasInferredName()) {
2380 os << "\n - inferred name: " << Brief(inferred_name());
2381 }
2382 if (class_scope_has_private_brand()) {
2383 os << "\n - class_scope_has_private_brand";
2384 }
2386 os << "\n - has_static_private_methods_or_accessors";
2387 }
2388 if (private_name_lookup_skips_outer_class()) {
2389 os << "\n - private_name_lookup_skips_outer_class";
2390 }
2391 os << "\n - kind: " << kind();
2392 os << "\n - syntax kind: " << syntax_kind();
2393 os << "\n - function_map_index: " << function_map_index();
2394 os << "\n - formal_parameter_count: ";
2395 int formal_parameter_count = internal_formal_parameter_count_with_receiver();
2396 if (formal_parameter_count == kDontAdaptArgumentsSentinel) {
2397 os << "kDontAdaptArgumentsSentinel";
2398 } else {
2399 os << formal_parameter_count;
2400 }
2401 os << "\n - expected_nof_properties: "
2402 << static_cast<int>(expected_nof_properties());
2403 os << "\n - language_mode: " << language_mode();
2404 if (HasTrustedData()) {
2405 os << "\n - trusted_function_data: "
2406 << Brief(GetTrustedData(GetIsolateForSandbox(*this)));
2407 } else {
2408 os << "\n - trusted_function_data: <empty>";
2409 }
2410 os << "\n - untrusted_function_data: " << Brief(GetUntrustedData());
2411 os << "\n - code (from function_data): ";
2412 Isolate* isolate;
2413 if (GetIsolateFromHeapObject(*this, &isolate)) {
2414 os << Brief(GetCode(isolate));
2415 } else {
2416 os << kUnavailableString;
2417 }
2418 PrintSourceCode(os);
2419 // Script files are often large, thus only print their {Brief} representation.
2420 os << "\n - script: " << Brief(script());
2421 os << "\n - function token position: " << function_token_position();
2422 os << "\n - start position: " << StartPosition();
2423 os << "\n - end position: " << EndPosition();
2424 os << "\n - scope info: " << Brief(scope_info());
2425 if (HasOuterScopeInfo()) {
2426 os << "\n - outer scope info: " << Brief(GetOuterScopeInfo());
2427 }
2428 os << "\n - length: " << length();
2429 os << "\n - feedback_metadata: ";
2430 if (HasFeedbackMetadata()) {
2431 feedback_metadata()->FeedbackMetadataPrint(os);
2432 } else {
2433 os << "<none>";
2434 }
2435 os << "\n - function_literal_id: " << function_literal_id();
2436 os << "\n - unique_id: " << unique_id();
2437 os << "\n - age: " << age();
2438 os << "\n";
2439}
2440
2441void SharedFunctionInfoWrapper::SharedFunctionInfoWrapperPrint(
2442 std::ostream& os) {
2443 PrintHeader(os, "SharedFunctionInfoWrapper");
2444 os << "\n sfi: " << Brief(shared_info());
2445}
2446
2447void JSGlobalProxy::JSGlobalProxyPrint(std::ostream& os) {
2448 JSAPIObjectWithEmbedderSlotsPrintHeader(os, *this, "JSGlobalProxy");
2449 JSObjectPrintBody(os, *this);
2450}
2451
2452void JSGlobalObject::JSGlobalObjectPrint(std::ostream& os) {
2453 JSAPIObjectWithEmbedderSlotsPrintHeader(os, *this, "JSGlobalObject");
2454 os << "\n - global proxy: " << Brief(global_proxy());
2455 JSObjectPrintBody(os, *this);
2456}
2457
2458void PropertyCell::PropertyCellPrint(std::ostream& os) {
2459 PrintHeader(os, "PropertyCell");
2460 os << "\n - name: ";
2461 name()->NamePrint(os);
2462 os << "\n - value: " << Brief(value(kAcquireLoad));
2463 os << "\n - details: ";
2464 PropertyDetails details = property_details(kAcquireLoad);
2465 details.PrintAsSlowTo(os, true);
2466 os << "\n - cell_type: " << details.cell_type();
2467 os << "\n - dependent code: " << dependent_code();
2468 os << "\n";
2469}
2470
2471void ContextSidePropertyCell::ContextSidePropertyCellPrint(std::ostream& os) {
2472 PrintHeader(os, "ContextSidePropertyCell");
2473 os << "\n - dependent code: " << dependent_code();
2474 os << "\n - cell_type: " << context_side_property_raw(kAcquireLoad);
2475 os << "\n";
2476}
2477
2478void InstructionStream::InstructionStreamPrint(std::ostream& os) {
2479 code(kAcquireLoad)->CodePrint(os);
2480}
2481
2482void Code::CodePrint(std::ostream& os, const char* name, Address current_pc) {
2483 // This prints the entire {Code,InstructionStream} composite object.
2484 //
2485 // First, Code:
2486 PrintHeader(os, "Code");
2487 os << "\n - kind: " << CodeKindToString(kind());
2488 if (is_builtin()) {
2489 os << "\n - builtin_id: " << Builtins::name(builtin_id());
2490 }
2491 os << "\n - deoptimization_data_or_interpreter_data: "
2493 os << "\n - position_table: " << Brief(raw_position_table());
2494 os << "\n - parameter_count: " << parameter_count();
2495 os << "\n - instruction_stream: " << Brief(raw_instruction_stream());
2496 os << "\n - instruction_start: "
2497 << reinterpret_cast<void*>(instruction_start());
2498 os << "\n - is_turbofanned: " << is_turbofanned();
2499 os << "\n - stack_slots: " << stack_slots();
2500 os << "\n - marked_for_deoptimization: " << marked_for_deoptimization();
2501 os << "\n - embedded_objects_cleared: " << embedded_objects_cleared();
2502 os << "\n - can_have_weak_objects: " << can_have_weak_objects();
2503 os << "\n - instruction_size: " << instruction_size();
2504 os << "\n - metadata_size: " << metadata_size();
2505
2506 if (kind() != CodeKind::WASM_TO_JS_FUNCTION) {
2507 os << "\n - inlined_bytecode_size: " << inlined_bytecode_size();
2508 } else {
2509 os << "\n - wasm_js_tagged_parameter_count: "
2510 << wasm_js_tagged_parameter_count();
2511 os << "\n - wasm_js_first_tagged_parameter: "
2512 << wasm_js_first_tagged_parameter();
2513 }
2514 os << "\n - osr_offset: " << osr_offset();
2515 os << "\n - handler_table_offset: " << handler_table_offset();
2516 os << "\n - unwinding_info_offset: " << unwinding_info_offset();
2518 os << "\n - constant_pool_offset: " << constant_pool_offset();
2519 }
2520 os << "\n - code_comments_offset: " << code_comments_offset();
2521
2522 // Then, InstructionStream:
2523 if (has_instruction_stream()) {
2524 Tagged<InstructionStream> istream = instruction_stream();
2525 os << "\n - instruction_stream.relocation_info: "
2526 << Brief(istream->relocation_info());
2527 os << "\n - instruction_stream.body_size: " << istream->body_size();
2528 }
2529 os << "\n";
2530
2531 // Finally, the disassembly:
2532#ifdef ENABLE_DISASSEMBLER
2533 os << "\n--- Disassembly: ---\n";
2534 Disassemble(name, os, Isolate::Current(), current_pc);
2535#endif
2536}
2537
2538void CodeWrapper::CodeWrapperPrint(std::ostream& os) {
2539 PrintHeader(os, "CodeWrapper");
2540 os << "\n - code: " << Brief(code(Isolate::Current()));
2541 os << "\n";
2542}
2543
2544void Foreign::ForeignPrint(std::ostream& os) {
2545 PrintHeader(os, "Foreign");
2546 os << "\n - foreign address: "
2547 << reinterpret_cast<void*>(foreign_address_unchecked());
2548 os << "\n";
2549}
2550
2551void TrustedForeign::TrustedForeignPrint(std::ostream& os) {
2552 PrintHeader(os, "TrustedForeign");
2553 os << "\n - foreign address: " << reinterpret_cast<void*>(foreign_address());
2554 os << "\n";
2555}
2556
2557void AsyncGeneratorRequest::AsyncGeneratorRequestPrint(std::ostream& os) {
2558 PrintHeader(os, "AsyncGeneratorRequest");
2559 const char* mode = "Invalid!";
2560 switch (resume_mode()) {
2562 mode = ".next()";
2563 break;
2565 mode = ".return()";
2566 break;
2568 mode = ".throw()";
2569 break;
2570 }
2571 os << "\n - resume mode: " << mode;
2572 os << "\n - value: " << Brief(value());
2573 os << "\n - next: " << Brief(next());
2574 os << "\n";
2575}
2576
2577static void PrintModuleFields(Tagged<Module> module, std::ostream& os) {
2578 os << "\n - exports: " << Brief(module->exports());
2579 os << "\n - status: " << module->status();
2580 os << "\n - exception: " << Brief(module->exception());
2581}
2582
2583void Module::ModulePrint(std::ostream& os) {
2584 if (IsSourceTextModule(*this)) {
2585 Cast<SourceTextModule>(*this)->SourceTextModulePrint(os);
2586 } else if (IsSyntheticModule(*this)) {
2587 Cast<SyntheticModule>(*this)->SyntheticModulePrint(os);
2588 } else {
2589 UNREACHABLE();
2590 }
2591}
2592
2593void SourceTextModule::SourceTextModulePrint(std::ostream& os) {
2594 PrintHeader(os, "SourceTextModule");
2595 PrintModuleFields(*this, os);
2596 os << "\n - sfi/code/info: " << Brief(code());
2597 Tagged<Script> script = GetScript();
2598 os << "\n - script: " << Brief(script);
2599 os << "\n - origin: " << Brief(script->GetNameOrSourceURL());
2600 os << "\n - requested_modules: " << Brief(requested_modules());
2601 os << "\n - import_meta: " << Brief(import_meta(kAcquireLoad));
2602 os << "\n - cycle_root: " << Brief(cycle_root());
2603 os << "\n - has_toplevel_await: " << has_toplevel_await();
2604 os << "\n - async_evaluation_ordinal: " << async_evaluation_ordinal();
2605 os << "\n";
2606}
2607
2608void JSModuleNamespace::JSModuleNamespacePrint(std::ostream& os) {
2609 JSObjectPrintHeader(os, *this, "JSModuleNamespace");
2610 os << "\n - module: " << Brief(module());
2611 JSObjectPrintBody(os, *this);
2612}
2613
2614void PrototypeInfo::PrototypeInfoPrint(std::ostream& os) {
2615 PrintHeader(os, "PrototypeInfo");
2616 os << "\n - module namespace: " << Brief(module_namespace());
2617 os << "\n - prototype users: " << Brief(prototype_users());
2618 os << "\n - registry slot: " << registry_slot();
2619 os << "\n - derived maps: " << Brief(derived_maps());
2620 os << "\n - should_be_fast_map: " << should_be_fast_map();
2621 os << "\n";
2622}
2623
2624void ArrayBoilerplateDescription::ArrayBoilerplateDescriptionPrint(
2625 std::ostream& os) {
2626 PrintHeader(os, "ArrayBoilerplateDescription");
2627 os << "\n - elements kind: " << ElementsKindToString(elements_kind());
2628 os << "\n - constant elements: " << Brief(constant_elements());
2629 os << "\n";
2630}
2631
2632#if V8_ENABLE_WEBASSEMBLY
2633void AsmWasmData::AsmWasmDataPrint(std::ostream& os) {
2634 PrintHeader(os, "AsmWasmData");
2635 os << "\n - native module: " << Brief(managed_native_module());
2636 os << "\n - uses bitset: " << uses_bitset()->value();
2637 os << "\n";
2638}
2639
2640void WasmTypeInfo::WasmTypeInfoPrint(std::ostream& os) {
2641 PrintHeader(os, "WasmTypeInfo");
2642 os << "\n - canonical type: " << type().name();
2643 os << "\n - element type: " << element_type().name();
2644 os << "\n - supertypes: ";
2645 for (int i = 0; i < supertypes_length(); i++) {
2646 os << "\n - " << Brief(supertypes(i));
2647 }
2648 os << "\n";
2649}
2650
2651void WasmStruct::WasmStructPrint(std::ostream& os) {
2652 PrintHeader(os, "WasmStruct");
2653 const wasm::CanonicalStructType* struct_type =
2655 map()->wasm_type_info()->type_index());
2656 if (struct_type->is_descriptor()) {
2657 os << "\n - describes RTT: " << Brief(get_described_rtt());
2658 }
2659 os << "\n - fields (" << struct_type->field_count() << "):";
2660 for (uint32_t i = 0; i < struct_type->field_count(); i++) {
2661 wasm::CanonicalValueType field = struct_type->field(i);
2662 os << "\n - " << field.short_name() << ": ";
2663 uint32_t field_offset = struct_type->field_offset(i);
2664 Address field_address = RawFieldAddress(field_offset);
2665 switch (field.kind()) {
2666 case wasm::kI32:
2667 os << base::ReadUnalignedValue<int32_t>(field_address);
2668 break;
2669 case wasm::kI64:
2670 os << base::ReadUnalignedValue<int64_t>(field_address);
2671 break;
2672 case wasm::kF16:
2673 os << fp16_ieee_to_fp32_value(
2674 base::ReadUnalignedValue<uint16_t>(field_address));
2675 break;
2676 case wasm::kF32:
2677 os << base::ReadUnalignedValue<float>(field_address);
2678 break;
2679 case wasm::kF64:
2680 os << base::ReadUnalignedValue<double>(field_address);
2681 break;
2682 case wasm::kI8:
2683 os << base::ReadUnalignedValue<int8_t>(field_address);
2684 break;
2685 case wasm::kI16:
2686 os << base::ReadUnalignedValue<int16_t>(field_address);
2687 break;
2688 case wasm::kRef:
2689 case wasm::kRefNull: {
2690 Tagged_t raw = base::ReadUnalignedValue<Tagged_t>(field_address);
2691#if V8_COMPRESS_POINTERS
2693#else
2694 Address obj = raw;
2695#endif
2696 os << Brief(Tagged<Object>(obj));
2697 break;
2698 }
2699 case wasm::kS128:
2700 os << "0x" << std::hex << std::setfill('0');
2701#ifdef V8_TARGET_BIG_ENDIAN
2702 for (int j = 0; j < kSimd128Size; j++) {
2703#else
2704 for (int j = kSimd128Size - 1; j >= 0; j--) {
2705#endif
2706 os << std::setw(2)
2707 << static_cast<int>(reinterpret_cast<uint8_t*>(field_address)[j]);
2708 }
2709 os << std::dec << std::setfill(' ');
2710 break;
2711 case wasm::kTop:
2712 case wasm::kBottom:
2713 case wasm::kVoid:
2714 UNREACHABLE();
2715 }
2716 }
2717 os << "\n";
2718}
2719
2720void WasmArray::WasmArrayPrint(std::ostream& os) {
2721 PrintHeader(os, "WasmArray");
2722 const wasm::CanonicalValueType element_type =
2723 map()->wasm_type_info()->element_type();
2724 uint32_t len = length();
2725 os << "\n - element type: " << element_type.name();
2726 os << "\n - length: " << len;
2727 Address data_ptr = ptr() + WasmArray::kHeaderSize - kHeapObjectTag;
2728 switch (element_type.kind()) {
2729 case wasm::kI32:
2730 PrintTypedArrayElements(os, reinterpret_cast<int32_t*>(data_ptr), len,
2731 true);
2732 break;
2733 case wasm::kI64:
2734 PrintTypedArrayElements(os, reinterpret_cast<int64_t*>(data_ptr), len,
2735 true);
2736 break;
2737 case wasm::kF16:
2738 PrintTypedArrayElements(os, reinterpret_cast<Fp16Printer*>(data_ptr), len,
2739 true);
2740 break;
2741 case wasm::kF32:
2742 PrintTypedArrayElements(os, reinterpret_cast<float*>(data_ptr), len,
2743 true);
2744 break;
2745 case wasm::kF64:
2746 PrintTypedArrayElements(os, reinterpret_cast<double*>(data_ptr), len,
2747 true);
2748 break;
2749 case wasm::kI8:
2750 PrintTypedArrayElements(os, reinterpret_cast<int8_t*>(data_ptr), len,
2751 true);
2752 break;
2753 case wasm::kI16:
2754 PrintTypedArrayElements(os, reinterpret_cast<int16_t*>(data_ptr), len,
2755 true);
2756 break;
2757 case wasm::kRef:
2758 case wasm::kRefNull: {
2759 os << "\n - elements:";
2760 constexpr uint32_t kWasmArrayMaximumPrintedElements = 5;
2761 for (uint32_t i = 0;
2762 i < std::min(this->length(), kWasmArrayMaximumPrintedElements);
2763 i++) {
2764 os << "\n " << static_cast<int>(i) << " - "
2765 << Brief(TaggedField<Object>::load(*this, this->element_offset(i)));
2766 }
2767 if (this->length() > kWasmArrayMaximumPrintedElements) os << "\n ...";
2768 break;
2769 }
2770 case wasm::kS128: {
2771 os << "\n - elements:";
2772 constexpr uint32_t kWasmArrayMaximumPrintedElements = 5;
2773 for (uint32_t i = 0;
2774 i < std::min(this->length(), kWasmArrayMaximumPrintedElements);
2775 i++) {
2776 os << "\n " << static_cast<int>(i) << " - 0x" << std::hex
2777 << std::setfill('0');
2778#ifdef V8_TARGET_BIG_ENDIAN
2779 for (int j = 0; j < kSimd128Size; j++) {
2780#else
2781 for (int j = kSimd128Size - 1; j >= 0; j--) {
2782#endif
2783 os << std::setw(2)
2784 << static_cast<int>(
2785 reinterpret_cast<uint8_t*>(this->ElementAddress(i))[j]);
2786 }
2787 os << std::dec << std::setfill(' ');
2788 }
2789 if (this->length() > kWasmArrayMaximumPrintedElements) os << "\n ...";
2790 break;
2791 }
2792 case wasm::kTop:
2793 case wasm::kBottom:
2794 case wasm::kVoid:
2795 UNREACHABLE();
2796 }
2797 os << "\n";
2798}
2799
2800void WasmSuspenderObject::WasmSuspenderObjectPrint(std::ostream& os) {
2801 PrintHeader(os, "WasmSuspenderObject");
2802 os << "\n - stack: " << (stack() == nullptr ? -1 : stack()->id());
2803 os << "\n - parent: " << parent();
2804 os << "\n - promise: " << promise();
2805 os << "\n - resume: " << resume();
2806 os << "\n - reject: " << reject();
2807 os << "\n";
2808}
2809
2810void WasmSuspendingObject::WasmSuspendingObjectPrint(std::ostream& os) {
2811 PrintHeader(os, "WasmSuspendingObject");
2812 os << "\n - callable: " << callable();
2813 os << "\n";
2814}
2815
2816void WasmInstanceObject::WasmInstanceObjectPrint(std::ostream& os) {
2817 IsolateForSandbox isolate = GetIsolateForSandbox(*this);
2818 JSObjectPrintHeader(os, *this, "WasmInstanceObject");
2819 os << "\n - trusted_data: " << Brief(trusted_data(isolate));
2820 os << "\n - module_object: " << Brief(module_object());
2821 os << "\n - exports_object: " << Brief(exports_object());
2822 JSObjectPrintBody(os, *this);
2823 os << "\n";
2824}
2825
2826void WasmTrustedInstanceData::WasmTrustedInstanceDataPrint(std::ostream& os) {
2827#define PRINT_WASM_INSTANCE_FIELD(name, convert) \
2828 os << "\n - " #name ": " << convert(name());
2829#define PRINT_OPTIONAL_WASM_INSTANCE_FIELD(name, convert) \
2830 if (has_##name()) os << "\n - " #name ": " << convert(name());
2831
2832 auto to_void_ptr = [](auto value) {
2833 static_assert(sizeof(value) == kSystemPointerSize);
2834 return reinterpret_cast<void*>(value);
2835 };
2836
2837 PrintHeader(os, "WasmTrustedInstanceData");
2838 PRINT_OPTIONAL_WASM_INSTANCE_FIELD(instance_object, Brief);
2839 PRINT_WASM_INSTANCE_FIELD(native_context, Brief);
2840 PRINT_WASM_INSTANCE_FIELD(shared_part, Brief);
2841 PRINT_WASM_INSTANCE_FIELD(memory_objects, Brief);
2842 PRINT_OPTIONAL_WASM_INSTANCE_FIELD(untagged_globals_buffer, Brief);
2843 PRINT_OPTIONAL_WASM_INSTANCE_FIELD(tagged_globals_buffer, Brief);
2844 PRINT_OPTIONAL_WASM_INSTANCE_FIELD(imported_mutable_globals_buffers, Brief);
2845#if V8_ENABLE_DRUMBRAKE
2846 PRINT_OPTIONAL_WASM_INSTANCE_FIELD(interpreter_object, Brief);
2847#endif // V8_ENABLE_DRUMBRAKE
2848 PRINT_OPTIONAL_WASM_INSTANCE_FIELD(tables, Brief);
2849 PRINT_WASM_INSTANCE_FIELD(dispatch_table0, Brief);
2850 PRINT_WASM_INSTANCE_FIELD(dispatch_tables, Brief);
2851 PRINT_WASM_INSTANCE_FIELD(dispatch_table_for_imports, Brief);
2852 PRINT_OPTIONAL_WASM_INSTANCE_FIELD(tags_table, Brief);
2853 PRINT_WASM_INSTANCE_FIELD(func_refs, Brief);
2854 PRINT_WASM_INSTANCE_FIELD(managed_object_maps, Brief);
2855 PRINT_WASM_INSTANCE_FIELD(feedback_vectors, Brief);
2856 PRINT_WASM_INSTANCE_FIELD(well_known_imports, Brief);
2857 PRINT_WASM_INSTANCE_FIELD(memory0_start, to_void_ptr);
2858 PRINT_WASM_INSTANCE_FIELD(memory0_size, +);
2859 PRINT_WASM_INSTANCE_FIELD(new_allocation_limit_address, to_void_ptr);
2860 PRINT_WASM_INSTANCE_FIELD(new_allocation_top_address, to_void_ptr);
2861 PRINT_WASM_INSTANCE_FIELD(old_allocation_limit_address, to_void_ptr);
2862 PRINT_WASM_INSTANCE_FIELD(old_allocation_top_address, to_void_ptr);
2863#if V8_ENABLE_DRUMBRAKE
2864 PRINT_WASM_INSTANCE_FIELD(imported_function_indices, Brief);
2865#endif // V8_ENABLE_DRUMBRAKE
2866 PRINT_WASM_INSTANCE_FIELD(globals_start, to_void_ptr);
2867 PRINT_WASM_INSTANCE_FIELD(imported_mutable_globals, Brief);
2868 PRINT_WASM_INSTANCE_FIELD(jump_table_start, to_void_ptr);
2869 PRINT_WASM_INSTANCE_FIELD(data_segment_starts, Brief);
2870 PRINT_WASM_INSTANCE_FIELD(data_segment_sizes, Brief);
2871 PRINT_WASM_INSTANCE_FIELD(element_segments, Brief);
2872 PRINT_WASM_INSTANCE_FIELD(hook_on_function_call_address, to_void_ptr);
2873 PRINT_WASM_INSTANCE_FIELD(tiering_budget_array, to_void_ptr);
2874 PRINT_WASM_INSTANCE_FIELD(memory_bases_and_sizes, Brief);
2875 PRINT_WASM_INSTANCE_FIELD(break_on_entry, static_cast<int>);
2876 os << "\n";
2877
2878#undef PRINT_OPTIONAL_WASM_INSTANCE_FIELD
2879#undef PRINT_WASM_INSTANCE_FIELD
2880}
2881
2882void WasmDispatchTable::WasmDispatchTablePrint(std::ostream& os) {
2883 PrintHeader(os, "WasmDispatchTable");
2884 int len = length();
2885 os << "\n - length: " << len;
2886 os << "\n - capacity: " << capacity();
2887 Tagged<ProtectedWeakFixedArray> uses = protected_uses();
2888 os << "\n - uses: " << Brief(uses);
2889 os << "\n - table type: " << table_type().name();
2890 // Only print up to 55 elements; otherwise print the first 50 and "[...]".
2891 int printed = len > 55 ? 50 : len;
2892 for (int i = 0; i < printed; ++i) {
2893 os << "\n " << std::setw(8) << i << ": sig: " << sig(i)
2894 << "; target: " << AsHex::Address(target(i).value())
2895 << "; implicit_arg: " << Brief(implicit_arg(i));
2896 }
2897 if (printed != len) os << "\n [...]";
2898 os << "\n";
2899}
2900
2901// Never called directly, as WasmFunctionData is an "abstract" class.
2902void WasmFunctionData::WasmFunctionDataPrint(std::ostream& os) {
2903 IsolateForSandbox isolate = GetIsolateForSandbox(*this);
2904 os << "\n - func_ref: " << Brief(func_ref());
2905 os << "\n - internal: " << Brief(internal());
2906 os << "\n - wrapper_code: " << Brief(wrapper_code(isolate));
2907 os << "\n - js_promise_flags: " << js_promise_flags();
2908 // No newline here; the caller prints it after printing additional fields.
2909}
2910
2911void WasmExportedFunctionData::WasmExportedFunctionDataPrint(std::ostream& os) {
2912 PrintHeader(os, "WasmExportedFunctionData");
2913 WasmFunctionDataPrint(os);
2914 os << "\n - instance_data: " << Brief(instance_data());
2915 os << "\n - function_index: " << function_index();
2916 os << "\n - signature: " << reinterpret_cast<const void*>(sig());
2917 os << "\n - wrapper_budget: " << wrapper_budget()->value();
2918 os << "\n";
2919}
2920
2921void WasmJSFunctionData::WasmJSFunctionDataPrint(std::ostream& os) {
2922 PrintHeader(os, "WasmJSFunctionData");
2923 WasmFunctionDataPrint(os);
2924 os << "\n - canonical_sig_index: " << canonical_sig_index();
2925 os << "\n";
2926}
2927
2928void WasmResumeData::WasmResumeDataPrint(std::ostream& os) {
2929 PrintHeader(os, "WasmResumeData");
2930 os << "\n - suspender: " << Brief(suspender());
2931 os << '\n';
2932}
2933
2934void WasmImportData::WasmImportDataPrint(std::ostream& os) {
2935 PrintHeader(os, "WasmImportData");
2936 os << "\n - native_context: " << Brief(native_context());
2937 os << "\n - callable: " << Brief(callable());
2938 os << "\n - instance_data: ";
2939 if (has_instance_data()) {
2940 os << Brief(instance_data());
2941 } else {
2942 os << "<empty>";
2943 }
2944 os << "\n - suspend: " << static_cast<int>(suspend());
2945 os << "\n - wrapper_budget: " << wrapper_budget();
2946 if (has_call_origin()) {
2947 os << "\n - call_origin: " << Brief(call_origin());
2948 }
2949 os << "\n - sig: " << sig() << " (" << sig()->parameter_count() << " params, "
2950 << sig()->return_count() << " returns)";
2951 os << "\n";
2952}
2953
2954void WasmInternalFunction::WasmInternalFunctionPrint(std::ostream& os) {
2955 PrintHeader(os, "WasmInternalFunction");
2956 os << "\n - call target: "
2958 ->GetEntrypointWithoutSignatureCheck(call_target());
2959 os << "\n - implicit arg: " << Brief(implicit_arg());
2960 os << "\n - external: " << Brief(external());
2961 os << "\n";
2962}
2963
2964void WasmFuncRef::WasmFuncRefPrint(std::ostream& os) {
2965 PrintHeader(os, "WasmFuncRef");
2966 IsolateForSandbox isolate = GetIsolateForSandbox(*this);
2967 os << "\n - internal: " << Brief(internal(isolate));
2968 os << "\n";
2969}
2970
2971void WasmCapiFunctionData::WasmCapiFunctionDataPrint(std::ostream& os) {
2972 PrintHeader(os, "WasmCapiFunctionData");
2973 WasmFunctionDataPrint(os);
2974 os << "\n - canonical_sig_index: " << canonical_sig_index();
2975 os << "\n - embedder_data: " << Brief(embedder_data());
2976 os << "\n - sig: " << sig();
2977 os << "\n";
2978}
2979
2980void WasmExceptionPackage::WasmExceptionPackagePrint(std::ostream& os) {
2981 PrintHeader(os, "WasmExceptionPackage");
2982 os << "\n";
2983}
2984
2985void WasmModuleObject::WasmModuleObjectPrint(std::ostream& os) {
2986 PrintHeader(os, "WasmModuleObject");
2987 os << "\n - module: " << module();
2988 os << "\n - native module: " << native_module();
2989 os << "\n - script: " << Brief(script());
2990 os << "\n";
2991}
2992
2993void WasmGlobalObject::WasmGlobalObjectPrint(std::ostream& os) {
2994 PrintHeader(os, "WasmGlobalObject");
2995 if (type().is_reference()) {
2996 os << "\n - tagged_buffer: " << Brief(tagged_buffer());
2997 } else {
2998 os << "\n - untagged_buffer: " << Brief(untagged_buffer());
2999 }
3000 os << "\n - offset: " << offset();
3001 os << "\n - raw_type: " << raw_type();
3002 os << "\n - is_mutable: " << is_mutable();
3003 os << "\n - type: " << type();
3004 os << "\n - is_mutable: " << is_mutable();
3005 os << "\n";
3006}
3007
3008void WasmValueObject::WasmValueObjectPrint(std::ostream& os) {
3009 PrintHeader(os, "WasmValueObject");
3010 os << "\n - value: " << Brief(value());
3011 os << "\n";
3012}
3013#endif // V8_ENABLE_WEBASSEMBLY
3014
3015void Tuple2::Tuple2Print(std::ostream& os) {
3016 this->PrintHeader(os, "Tuple2");
3017 os << "\n - value1: " << Brief(this->value1());
3018 os << "\n - value2: " << Brief(this->value2());
3019 os << '\n';
3020}
3021
3022void AccessorPair::AccessorPairPrint(std::ostream& os) {
3023 this->PrintHeader(os, "AccessorPair");
3024 os << "\n - getter: " << Brief(this->getter());
3025 os << "\n - setter: " << Brief(this->setter());
3026 os << '\n';
3027}
3028
3029void ClassPositions::ClassPositionsPrint(std::ostream& os) {
3030 this->PrintHeader(os, "ClassPositions");
3031 os << "\n - start: " << this->start();
3032 os << "\n - end: " << this->end();
3033 os << '\n';
3034}
3035
3036void LoadHandler::LoadHandlerPrint(std::ostream& os) {
3037 PrintHeader(os, "LoadHandler");
3038 // TODO(ishell): implement printing based on handler kind
3039 os << "\n - handler: " << Brief(smi_handler());
3040 os << "\n - validity_cell: " << Brief(validity_cell());
3041 int data_count = data_field_count();
3042 if (data_count >= 1) {
3043 os << "\n - data1: " << Brief(data1());
3044 }
3045 if (data_count >= 2) {
3046 os << "\n - data2: " << Brief(data2());
3047 }
3048 if (data_count >= 3) {
3049 os << "\n - data3: " << Brief(data3());
3050 }
3051 os << "\n";
3052}
3053
3054void StoreHandler::StoreHandlerPrint(std::ostream& os) {
3055 PrintHeader(os, "StoreHandler");
3056 // TODO(ishell): implement printing based on handler kind
3057 os << "\n - handler: " << Brief(smi_handler());
3058 os << "\n - validity_cell: " << Brief(validity_cell());
3059 int data_count = data_field_count();
3060 if (data_count >= 1) {
3061 os << "\n - data1: " << Brief(data1());
3062 }
3063 if (data_count >= 2) {
3064 os << "\n - data2: " << Brief(data2());
3065 }
3066 if (data_count >= 3) {
3067 os << "\n - data3: " << Brief(data3());
3068 }
3069 os << "\n";
3070}
3071
3072void AllocationSite::AllocationSitePrint(std::ostream& os) {
3073 PrintHeader(os, "AllocationSite");
3074 if (this->HasWeakNext())
3075 os << "\n - weak_next: "
3076 << Brief(Cast<AllocationSiteWithWeakNext>(this)->weak_next());
3077 os << "\n - dependent code: " << Brief(dependent_code());
3078 os << "\n - nested site: " << Brief(nested_site());
3079 os << "\n - memento found count: "
3080 << Brief(Smi::FromInt(memento_found_count()));
3081 os << "\n - memento create count: "
3082 << Brief(Smi::FromInt(memento_create_count()));
3083 os << "\n - pretenure decision: "
3084 << Brief(Smi::FromInt(pretenure_decision()));
3085 os << "\n - transition_info: ";
3086 if (!PointsToLiteral()) {
3087 ElementsKind kind = GetElementsKind();
3088 os << "Array allocation with ElementsKind " << ElementsKindToString(kind);
3089 } else if (IsJSArray(boilerplate())) {
3090 os << "Array literal with boilerplate " << Brief(boilerplate());
3091 } else {
3092 os << "Object literal with boilerplate " << Brief(boilerplate());
3093 }
3094 os << "\n";
3095}
3096
3097void AllocationMemento::AllocationMementoPrint(std::ostream& os) {
3098 PrintHeader(os, "AllocationMemento");
3099 os << "\n - allocation site: ";
3100 if (IsValid()) {
3101 GetAllocationSite()->AllocationSitePrint(os);
3102 } else {
3103 os << "<invalid>\n";
3104 }
3105}
3106
3107void ScriptOrModule::ScriptOrModulePrint(std::ostream& os) {
3108 PrintHeader(os, "ScriptOrModule");
3109 os << "\n - host_defined_options: " << Brief(host_defined_options());
3110 os << "\n - resource_name: " << Brief(resource_name());
3111}
3112
3113void Script::ScriptPrint(std::ostream& os) {
3114 PrintHeader(os, "Script");
3115 os << "\n - source: " << Brief(source());
3116 os << "\n - name: " << Brief(name());
3117 os << "\n - line_offset: " << line_offset();
3118 os << "\n - column_offset: " << column_offset();
3119 os << "\n - context data: " << Brief(context_data());
3120 os << "\n - type: " << static_cast<int>(type());
3121 os << "\n - line ends: " << Brief(line_ends());
3122 if (!has_line_ends()) os << " (not set)";
3123 os << "\n - id: " << id();
3124 os << "\n - source_url: " << Brief(source_url());
3125 os << "\n - source_mapping_url: " << Brief(source_mapping_url());
3126 os << "\n - host_defined_options: " << Brief(host_defined_options());
3127 os << "\n - compilation type: " << static_cast<int>(compilation_type());
3128 os << "\n - compiled lazy function positions: "
3129 << compiled_lazy_function_positions();
3130 bool is_wasm = false;
3131#if V8_ENABLE_WEBASSEMBLY
3132 if ((is_wasm = (type() == Type::kWasm))) {
3133 if (has_wasm_breakpoint_infos()) {
3134 os << "\n - wasm_breakpoint_infos: " << Brief(wasm_breakpoint_infos());
3135 }
3136 }
3137#endif // V8_ENABLE_WEBASSEMBLY
3138 if (!is_wasm) {
3139 if (has_eval_from_shared()) {
3140 os << "\n - eval from shared: " << Brief(eval_from_shared());
3141 } else if (is_wrapped()) {
3142 os << "\n - wrapped arguments: " << Brief(wrapped_arguments());
3143 }
3144 os << "\n - eval from position: " << eval_from_position();
3145 }
3146 os << "\n - infos: " << Brief(infos());
3147 os << "\n";
3148}
3149
3150void JSTemporalPlainDate::JSTemporalPlainDatePrint(std::ostream& os) {
3151 JSObjectPrintHeader(os, *this, "JSTemporalPlainDate");
3152 JSObjectPrintBody(os, *this);
3153}
3154
3155void JSTemporalPlainTime::JSTemporalPlainTimePrint(std::ostream& os) {
3156 JSObjectPrintHeader(os, *this, "JSTemporalPlainTime");
3157 JSObjectPrintBody(os, *this);
3158}
3159
3160void JSTemporalPlainDateTime::JSTemporalPlainDateTimePrint(std::ostream& os) {
3161 JSObjectPrintHeader(os, *this, "JSTemporalPlainDateTime");
3162 JSObjectPrintBody(os, *this);
3163}
3164
3165void JSTemporalZonedDateTime::JSTemporalZonedDateTimePrint(std::ostream& os) {
3166 JSObjectPrintHeader(os, *this, "JSTemporalZonedDateTime");
3167 JSObjectPrintBody(os, *this);
3168}
3169
3170void JSTemporalDuration::JSTemporalDurationPrint(std::ostream& os) {
3171 JSObjectPrintHeader(os, *this, "JSTemporalDuration");
3172 JSObjectPrintBody(os, *this);
3173}
3174
3175void JSTemporalInstant::JSTemporalInstantPrint(std::ostream& os) {
3176 JSObjectPrintHeader(os, *this, "JSTemporalInstant");
3177 JSObjectPrintBody(os, *this);
3178}
3179
3180void JSTemporalPlainYearMonth::JSTemporalPlainYearMonthPrint(std::ostream& os) {
3181 JSObjectPrintHeader(os, *this, "JSTemporalPlainYearMonth");
3182 JSObjectPrintBody(os, *this);
3183}
3184
3185void JSTemporalPlainMonthDay::JSTemporalPlainMonthDayPrint(std::ostream& os) {
3186 JSObjectPrintHeader(os, *this, "JSTemporalPlainMonthDay");
3187 JSObjectPrintBody(os, *this);
3188}
3189
3190void JSTemporalTimeZone::JSTemporalTimeZonePrint(std::ostream& os) {
3191 JSObjectPrintHeader(os, *this, "JSTemporalTimeZone");
3192 JSObjectPrintBody(os, *this);
3193}
3194
3195void JSTemporalCalendar::JSTemporalCalendarPrint(std::ostream& os) {
3196 JSObjectPrintHeader(os, *this, "JSTemporalCalendar");
3197 JSObjectPrintBody(os, *this);
3198}
3199
3200void JSRawJson::JSRawJsonPrint(std::ostream& os) {
3201 JSObjectPrintHeader(os, *this, "JSRawJson");
3202 JSObjectPrintBody(os, *this);
3203}
3204
3205#ifdef V8_INTL_SUPPORT
3206void JSV8BreakIterator::JSV8BreakIteratorPrint(std::ostream& os) {
3207 JSObjectPrintHeader(os, *this, "JSV8BreakIterator");
3208 os << "\n - locale: " << Brief(locale());
3209 os << "\n - break iterator: " << Brief(break_iterator());
3210 os << "\n - unicode string: " << Brief(unicode_string());
3211 os << "\n - bound adopt text: " << Brief(bound_adopt_text());
3212 os << "\n - bound first: " << Brief(bound_first());
3213 os << "\n - bound next: " << Brief(bound_next());
3214 os << "\n - bound current: " << Brief(bound_current());
3215 os << "\n - bound break type: " << Brief(bound_break_type());
3216 os << "\n";
3217}
3218
3219void JSCollator::JSCollatorPrint(std::ostream& os) {
3220 JSObjectPrintHeader(os, *this, "JSCollator");
3221 os << "\n - icu collator: " << Brief(icu_collator());
3222 os << "\n - bound compare: " << Brief(bound_compare());
3223 JSObjectPrintBody(os, *this);
3224}
3225
3226void JSDateTimeFormat::JSDateTimeFormatPrint(std::ostream& os) {
3227 JSObjectPrintHeader(os, *this, "JSDateTimeFormat");
3228 os << "\n - locale: " << Brief(locale());
3229 os << "\n - icu locale: " << Brief(icu_locale());
3230 os << "\n - icu simple date format: " << Brief(icu_simple_date_format());
3231 os << "\n - icu date interval format: " << Brief(icu_date_interval_format());
3232 os << "\n - bound format: " << Brief(bound_format());
3233 os << "\n - hour cycle: " << HourCycleAsString(GetIsolate());
3234 JSObjectPrintBody(os, *this);
3235}
3236
3237void JSDisplayNames::JSDisplayNamesPrint(std::ostream& os) {
3238 JSObjectPrintHeader(os, *this, "JSDisplayNames");
3239 os << "\n - internal: " << Brief(internal());
3240 os << "\n - style: " << StyleAsString(GetIsolate());
3241 os << "\n - fallback: " << FallbackAsString(GetIsolate());
3242 JSObjectPrintBody(os, *this);
3243}
3244
3245void JSDurationFormat::JSDurationFormatPrint(std::ostream& os) {
3246 JSObjectPrintHeader(os, *this, "JSDurationFormat");
3247 os << "\n - style_flags: " << style_flags();
3248 os << "\n - display_flags: " << display_flags();
3249 os << "\n - icu locale: " << Brief(icu_locale());
3250 os << "\n - icu number formatter: " << Brief(icu_number_formatter());
3251 JSObjectPrintBody(os, *this);
3252}
3253
3254void JSListFormat::JSListFormatPrint(std::ostream& os) {
3255 JSObjectPrintHeader(os, *this, "JSListFormat");
3256 os << "\n - locale: " << Brief(locale());
3257 os << "\n - style: " << StyleAsString(GetIsolate());
3258 os << "\n - type: " << TypeAsString(GetIsolate());
3259 os << "\n - icu formatter: " << Brief(icu_formatter());
3260 JSObjectPrintBody(os, *this);
3261}
3262
3263void JSLocale::JSLocalePrint(std::ostream& os) {
3264 JSObjectPrintHeader(os, *this, "JSLocale");
3265 os << "\n - icu locale: " << Brief(icu_locale());
3266 JSObjectPrintBody(os, *this);
3267}
3268
3269void JSNumberFormat::JSNumberFormatPrint(std::ostream& os) {
3270 JSObjectPrintHeader(os, *this, "JSNumberFormat");
3271 os << "\n - locale: " << Brief(locale());
3272 os << "\n - icu_number_formatter: " << Brief(icu_number_formatter());
3273 os << "\n - bound_format: " << Brief(bound_format());
3274 JSObjectPrintBody(os, *this);
3275}
3276
3277void JSPluralRules::JSPluralRulesPrint(std::ostream& os) {
3278 JSObjectPrintHeader(os, *this, "JSPluralRules");
3279 os << "\n - locale: " << Brief(locale());
3280 os << "\n - type: " << TypeAsString(GetIsolate());
3281 os << "\n - icu plural rules: " << Brief(icu_plural_rules());
3282 os << "\n - icu_number_formatter: " << Brief(icu_number_formatter());
3283 JSObjectPrintBody(os, *this);
3284}
3285
3286void JSRelativeTimeFormat::JSRelativeTimeFormatPrint(std::ostream& os) {
3287 JSObjectPrintHeader(os, *this, "JSRelativeTimeFormat");
3288 os << "\n - locale: " << Brief(locale());
3289 os << "\n - numberingSystem: " << Brief(numberingSystem());
3290 os << "\n - numeric: " << NumericAsString(GetIsolate());
3291 os << "\n - icu formatter: " << Brief(icu_formatter());
3292 os << "\n";
3293}
3294
3295void JSSegmentIterator::JSSegmentIteratorPrint(std::ostream& os) {
3296 JSObjectPrintHeader(os, *this, "JSSegmentIterator");
3297 os << "\n - icu break iterator: " << Brief(icu_break_iterator());
3298 os << "\n - granularity: " << GranularityAsString(GetIsolate());
3299 os << "\n";
3300}
3301
3302void JSSegmenter::JSSegmenterPrint(std::ostream& os) {
3303 JSObjectPrintHeader(os, *this, "JSSegmenter");
3304 os << "\n - locale: " << Brief(locale());
3305 os << "\n - granularity: " << GranularityAsString(GetIsolate());
3306 os << "\n - icu break iterator: " << Brief(icu_break_iterator());
3307 JSObjectPrintBody(os, *this);
3308}
3309
3310void JSSegments::JSSegmentsPrint(std::ostream& os) {
3311 JSObjectPrintHeader(os, *this, "JSSegments");
3312 os << "\n - icu break iterator: " << Brief(icu_break_iterator());
3313 os << "\n - unicode string: " << Brief(unicode_string());
3314 os << "\n - granularity: " << GranularityAsString(GetIsolate());
3315 JSObjectPrintBody(os, *this);
3316}
3317#endif // V8_INTL_SUPPORT
3318
3319namespace {
3320void PrintScopeInfoList(Tagged<ScopeInfo> scope_info, std::ostream& os,
3321 const char* list_name, int length) {
3323 if (length <= 0) return;
3324 os << "\n - " << list_name;
3325 os << " {\n";
3326 for (auto it : ScopeInfo::IterateLocalNames(scope_info, no_gc)) {
3327 os << " - " << it->index() << ": " << it->name() << "\n";
3328 }
3329 os << " }";
3330}
3331} // namespace
3332
3333void ScopeInfo::ScopeInfoPrint(std::ostream& os) {
3334 PrintHeader(os, "ScopeInfo");
3335 if (this->IsEmpty()) {
3336 os << "\n - empty\n";
3337 return;
3338 }
3339 int flags = Flags();
3340
3341 os << "\n - parameters: " << ParameterCount();
3342 os << "\n - context locals : " << ContextLocalCount();
3343 if (HasInlinedLocalNames()) {
3344 os << "\n - inlined local names";
3345 } else {
3346 os << "\n - local names in a hashtable: "
3347 << Brief(context_local_names_hashtable());
3348 }
3349
3350 os << "\n - scope type: " << scope_type();
3351 if (SloppyEvalCanExtendVars()) {
3352 os << "\n - sloppy eval";
3353 os << "\n - dependent code: " << Brief(dependent_code());
3354 }
3355 os << "\n - language mode: " << language_mode();
3356 if (is_declaration_scope()) os << "\n - declaration scope";
3357 if (HasReceiver()) {
3358 os << "\n - receiver: " << ReceiverVariableBits::decode(flags);
3359 }
3360 if (ClassScopeHasPrivateBrand()) os << "\n - class scope has private brand";
3361 if (HasSavedClassVariable()) os << "\n - has saved class variable";
3362 if (HasNewTarget()) os << "\n - needs new target";
3363 if (HasFunctionName()) {
3364 os << "\n - function name(" << FunctionVariableBits::decode(flags) << "): ";
3365 ShortPrint(FunctionName(), os);
3366 }
3367 if (IsAsmModule()) os << "\n - asm module";
3368 if (HasSimpleParameters()) os << "\n - simple parameters";
3369 if (PrivateNameLookupSkipsOuterClass())
3370 os << "\n - private name lookup skips outer class";
3371 os << "\n - function kind: " << function_kind();
3372 if (HasOuterScopeInfo()) {
3373 os << "\n - outer scope info: " << Brief(OuterScopeInfo());
3374 }
3375 if (HasFunctionName()) {
3376 os << "\n - function name: " << Brief(FunctionName());
3377 }
3378 if (HasInferredFunctionName()) {
3379 os << "\n - inferred function name: " << Brief(InferredFunctionName());
3380 }
3381 if (HasContextExtensionSlot()) {
3382 os << "\n - has context extension slot";
3383 }
3384
3385 if (HasPositionInfo()) {
3386 os << "\n - start position: " << StartPosition();
3387 os << "\n - end position: " << EndPosition();
3388 }
3389 os << "\n - length: " << length();
3390 if (length() > 0) {
3391 PrintScopeInfoList(*this, os, "context slots", ContextLocalCount());
3392 // TODO(neis): Print module stuff if present.
3393 }
3394 os << "\n";
3395}
3396
3397void PreparseData::PreparseDataPrint(std::ostream& os) {
3398 PrintHeader(os, "PreparseData");
3399 os << "\n - data_length: " << data_length();
3400 os << "\n - children_length: " << children_length();
3401 if (data_length() > 0) {
3402 os << "\n - data-start: " << (address() + kDataStartOffset);
3403 }
3404 if (children_length() > 0) {
3405 os << "\n - children-start: " << inner_start_offset();
3406 }
3407 for (int i = 0; i < children_length(); ++i) {
3408 os << "\n - [" << i << "]: " << Brief(get_child(i));
3409 }
3410 os << "\n";
3411}
3412
3413void HeapNumber::HeapNumberPrint(std::ostream& os) {
3414 PrintHeader(os, "HeapNumber");
3415 os << "\n - value: ";
3416 HeapNumberShortPrint(os);
3417 os << "\n";
3418}
3419
3420#endif // OBJECT_PRINT
3421
3422void HeapObject::Print() { Print(*this); }
3423
3424// static
3426
3427// static
3428void HeapObject::Print(Tagged<Object> obj, std::ostream& os) {
3429 v8::internal::Print(obj, os);
3430}
3431
3432void HeapObject::HeapObjectShortPrint(std::ostream& os) {
3434 os << AsHex::Address(this->ptr()) << " ";
3435
3436 if (IsString(*this, cage_base)) {
3437 HeapStringAllocator allocator;
3438 StringStream accumulator(&allocator);
3439 Cast<String>(*this)->StringShortPrint(&accumulator);
3440 os << accumulator.ToCString().get();
3441 return;
3442 }
3443 if (IsJSObject(*this, cage_base)) {
3444 HeapStringAllocator allocator;
3445 StringStream accumulator(&allocator);
3446 Cast<JSObject>(*this)->JSObjectShortPrint(&accumulator);
3447 os << accumulator.ToCString().get();
3448 return;
3449 }
3450
3451 InstanceType instance_type = map(cage_base)->instance_type();
3452
3453 // Skip invalid trusted objects. Technically it'd be fine to still handle
3454 // them below since we only print the objects, but such an object will
3455 // quickly lead to out-of-sandbox segfaults and so fuzzers will complain.
3456 if (InstanceTypeChecker::IsTrustedObject(instance_type) &&
3458 os << "<Invalid TrustedObject (outside trusted space)>\n";
3459 return;
3460 }
3461
3462 switch (instance_type) {
3463 case MAP_TYPE: {
3464 Tagged<Map> map = Cast<Map>(*this);
3465 if (map->instance_type() == MAP_TYPE) {
3466 // This is one of the meta maps, print only relevant fields.
3467 os << "<MetaMap (" << Brief(map->native_context_or_null()) << ")>";
3468 } else {
3469 os << "<Map";
3470 if (map->instance_size() != kVariableSizeSentinel) {
3471 os << "[" << map->instance_size() << "]";
3472 }
3473 os << "(";
3474 if (IsJSObjectMap(map)) {
3475 os << ElementsKindToString(map->elements_kind());
3476 } else {
3477 os << map->instance_type();
3478 }
3479 os << ")>";
3480 }
3481 } break;
3482 case AWAIT_CONTEXT_TYPE: {
3483 os << "<AwaitContext generator= ";
3484 HeapStringAllocator allocator;
3485 StringStream accumulator(&allocator);
3486 ShortPrint(Cast<Context>(*this)->extension(), &accumulator);
3487 os << accumulator.ToCString().get();
3488 os << '>';
3489 break;
3490 }
3491 case BLOCK_CONTEXT_TYPE:
3492 os << "<BlockContext[" << Cast<Context>(*this)->length() << "]>";
3493 break;
3494 case CATCH_CONTEXT_TYPE:
3495 os << "<CatchContext[" << Cast<Context>(*this)->length() << "]>";
3496 break;
3497 case DEBUG_EVALUATE_CONTEXT_TYPE:
3498 os << "<DebugEvaluateContext[" << Cast<Context>(*this)->length() << "]>";
3499 break;
3500 case EVAL_CONTEXT_TYPE:
3501 os << "<EvalContext[" << Cast<Context>(*this)->length() << "]>";
3502 break;
3503 case FUNCTION_CONTEXT_TYPE:
3504 os << "<FunctionContext[" << Cast<Context>(*this)->length() << "]>";
3505 break;
3506 case MODULE_CONTEXT_TYPE:
3507 os << "<ModuleContext[" << Cast<Context>(*this)->length() << "]>";
3508 break;
3509 case NATIVE_CONTEXT_TYPE:
3510 os << "<NativeContext[" << Cast<Context>(*this)->length() << "]>";
3511 break;
3512 case SCRIPT_CONTEXT_TYPE:
3513 os << "<ScriptContext[" << Cast<Context>(*this)->length() << "]>";
3514 break;
3515 case WITH_CONTEXT_TYPE:
3516 os << "<WithContext[" << Cast<Context>(*this)->length() << "]>";
3517 break;
3518 case SCRIPT_CONTEXT_TABLE_TYPE:
3519 os << "<ScriptContextTable["
3520 << Cast<ScriptContextTable>(*this)->capacity() << "]>";
3521 break;
3522 case HASH_TABLE_TYPE:
3523 os << "<HashTable[" << Cast<FixedArray>(*this)->length() << "]>";
3524 break;
3525 case ORDERED_HASH_MAP_TYPE:
3526 os << "<OrderedHashMap[" << Cast<FixedArray>(*this)->length() << "]>";
3527 break;
3528 case ORDERED_HASH_SET_TYPE:
3529 os << "<OrderedHashSet[" << Cast<FixedArray>(*this)->length() << "]>";
3530 break;
3531 case ORDERED_NAME_DICTIONARY_TYPE:
3532 os << "<OrderedNameDictionary[" << Cast<FixedArray>(*this)->length()
3533 << "]>";
3534 break;
3535 case NAME_DICTIONARY_TYPE:
3536 os << "<NameDictionary[" << Cast<FixedArray>(*this)->length() << "]>";
3537 break;
3538 case SWISS_NAME_DICTIONARY_TYPE:
3539 os << "<SwissNameDictionary["
3540 << Cast<SwissNameDictionary>(*this)->Capacity() << "]>";
3541 break;
3542 case GLOBAL_DICTIONARY_TYPE:
3543 os << "<GlobalDictionary[" << Cast<FixedArray>(*this)->length() << "]>";
3544 break;
3545 case NUMBER_DICTIONARY_TYPE:
3546 os << "<NumberDictionary[" << Cast<FixedArray>(*this)->length() << "]>";
3547 break;
3548 case SIMPLE_NUMBER_DICTIONARY_TYPE:
3549 os << "<SimpleNumberDictionary[" << Cast<FixedArray>(*this)->length()
3550 << "]>";
3551 break;
3552 case FIXED_ARRAY_TYPE:
3553 os << "<FixedArray[" << Cast<FixedArray>(*this)->length() << "]>";
3554 break;
3555 case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
3556 os << "<ObjectBoilerplateDescription["
3557 << Cast<ObjectBoilerplateDescription>(*this)->capacity() << "]>";
3558 break;
3559 case FIXED_DOUBLE_ARRAY_TYPE:
3560 os << "<FixedDoubleArray[" << Cast<FixedDoubleArray>(*this)->length()
3561 << "]>";
3562 break;
3563 case BYTE_ARRAY_TYPE:
3564 os << "<ByteArray[" << Cast<ByteArray>(*this)->length() << "]>";
3565 break;
3566 case BYTECODE_ARRAY_TYPE:
3567 os << "<BytecodeArray[" << Cast<BytecodeArray>(*this)->length() << "]>";
3568 break;
3569 case DESCRIPTOR_ARRAY_TYPE:
3570 os << "<DescriptorArray["
3571 << Cast<DescriptorArray>(*this)->number_of_descriptors() << "]>";
3572 break;
3573 case WEAK_FIXED_ARRAY_TYPE:
3574 os << "<WeakFixedArray[" << Cast<WeakFixedArray>(*this)->length() << "]>";
3575 break;
3576 case TRUSTED_FIXED_ARRAY_TYPE:
3577 os << "<TrustedFixedArray[" << Cast<TrustedFixedArray>(*this)->length()
3578 << "]>";
3579 break;
3580 case TRUSTED_WEAK_FIXED_ARRAY_TYPE:
3581 os << "<TrustedWeakFixedArray["
3582 << Cast<TrustedWeakFixedArray>(*this)->length() << "]>";
3583 break;
3584 case PROTECTED_FIXED_ARRAY_TYPE:
3585 os << "<ProtectedFixedArray["
3586 << Cast<ProtectedFixedArray>(*this)->length() << "]>";
3587 break;
3588 case PROTECTED_WEAK_FIXED_ARRAY_TYPE:
3589 os << "<ProtectedWeakFixedArray["
3590 << Cast<ProtectedWeakFixedArray>(*this)->length() << "]>";
3591 break;
3592 case TRANSITION_ARRAY_TYPE:
3593 os << "<TransitionArray[" << Cast<TransitionArray>(*this)->length()
3594 << "]>";
3595 break;
3596 case PROPERTY_ARRAY_TYPE:
3597 os << "<PropertyArray[" << Cast<PropertyArray>(*this)->length() << "]>";
3598 break;
3599 case FEEDBACK_CELL_TYPE: {
3600 {
3602 os << "<FeedbackCell[";
3603 if (map() == roots.no_closures_cell_map()) {
3604 os << "no feedback";
3605 } else if (map() == roots.one_closure_cell_map()) {
3606 os << "one closure";
3607 } else if (map() == roots.many_closures_cell_map()) {
3608 os << "many closures";
3609 } else {
3610 os << "!!!INVALID MAP!!!";
3611 }
3612 os << "]>";
3613 }
3614 break;
3615 }
3616 case CLOSURE_FEEDBACK_CELL_ARRAY_TYPE:
3617 os << "<ClosureFeedbackCellArray["
3618 << Cast<ClosureFeedbackCellArray>(*this)->length() << "]>";
3619 break;
3620 case FEEDBACK_VECTOR_TYPE:
3621 os << "<FeedbackVector[" << Cast<FeedbackVector>(*this)->length() << "]>";
3622 break;
3623 case FREE_SPACE_TYPE:
3624 os << "<FreeSpace[" << Cast<FreeSpace>(*this)->size(kRelaxedLoad) << "]>";
3625 break;
3626
3627 case PREPARSE_DATA_TYPE: {
3629 os << "<PreparseData[data=" << data->data_length()
3630 << " children=" << data->children_length() << "]>";
3631 break;
3632 }
3633
3634 case UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE: {
3637 os << "<UncompiledDataWithoutPreparseData (" << data->start_position()
3638 << ", " << data->end_position() << ")]>";
3639 break;
3640 }
3641
3642 case UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE: {
3645 os << "<UncompiledDataWithPreparseData (" << data->start_position()
3646 << ", " << data->end_position()
3647 << ") preparsed=" << Brief(data->preparse_data()) << ">";
3648 break;
3649 }
3650
3651 case SHARED_FUNCTION_INFO_TYPE: {
3653 std::unique_ptr<char[]> debug_name = shared->DebugNameCStr();
3654 if (debug_name[0] != '\0') {
3655 os << "<SharedFunctionInfo " << debug_name.get() << ">";
3656 } else {
3657 os << "<SharedFunctionInfo>";
3658 }
3659 break;
3660 }
3661 case JS_MESSAGE_OBJECT_TYPE:
3662 os << "<JSMessageObject>";
3663 break;
3664#define MAKE_STRUCT_CASE(TYPE, Name, name) \
3665 case TYPE: \
3666 os << "<" #Name; \
3667 Cast<Name>(*this)->BriefPrintDetails(os); \
3668 os << ">"; \
3669 break;
3671#undef MAKE_STRUCT_CASE
3672 case ALLOCATION_SITE_TYPE: {
3673 os << "<AllocationSite>";
3674 break;
3675 }
3676 case SCOPE_INFO_TYPE: {
3677 Tagged<ScopeInfo> scope = Cast<ScopeInfo>(*this);
3678 os << "<ScopeInfo";
3679 if (!scope->IsEmpty()) os << " " << scope->scope_type();
3680 os << ">";
3681 break;
3682 }
3683 case CODE_TYPE: {
3684 Tagged<Code> code = Cast<Code>(*this);
3685 os << "<Code " << CodeKindToString(code->kind());
3686 if (code->is_builtin()) {
3687 os << " " << Builtins::name(code->builtin_id());
3688 }
3689 os << ">";
3690 break;
3691 }
3692 case HOLE_TYPE: {
3693#define PRINT_HOLE(Type, Value, _) \
3694 if (Is##Type(*this)) { \
3695 os << "<" #Value ">"; \
3696 break; \
3697 }
3699#undef PRINT_HOLE
3700 UNREACHABLE();
3701 }
3702 case INSTRUCTION_STREAM_TYPE: {
3704 Tagged<Code> code = istream->code(kAcquireLoad);
3705 os << "<InstructionStream " << CodeKindToString(code->kind());
3706 if (code->is_builtin()) {
3707 os << " " << Builtins::name(code->builtin_id());
3708 }
3709 os << ">";
3710 break;
3711 }
3712 case ODDBALL_TYPE: {
3713 if (IsUndefined(*this)) {
3714 os << "<undefined>";
3715 } else if (IsNull(*this)) {
3716 os << "<null>";
3717 } else if (IsTrue(*this)) {
3718 os << "<true>";
3719 } else if (IsFalse(*this)) {
3720 os << "<false>";
3721 } else {
3722 os << "<Odd Oddball: ";
3723 os << Cast<Oddball>(*this)->to_string()->ToCString().get();
3724 os << ">";
3725 }
3726 break;
3727 }
3728 case SYMBOL_TYPE: {
3729 Tagged<Symbol> symbol = Cast<Symbol>(*this);
3730 symbol->SymbolShortPrint(os);
3731 break;
3732 }
3733 case HEAP_NUMBER_TYPE: {
3734 os << "<HeapNumber ";
3735 Cast<HeapNumber>(*this)->HeapNumberShortPrint(os);
3736 os << ">";
3737 break;
3738 }
3739 case BIGINT_TYPE: {
3740 os << "<BigInt ";
3741 Cast<BigInt>(*this)->BigIntShortPrint(os);
3742 os << ">";
3743 break;
3744 }
3745 case JS_PROXY_TYPE:
3746 os << "<JSProxy>";
3747 break;
3748 case FOREIGN_TYPE:
3749 os << "<Foreign>";
3750 break;
3751 case CELL_TYPE: {
3752 os << "<Cell value= ";
3753 HeapStringAllocator allocator;
3754 StringStream accumulator(&allocator);
3755 ShortPrint(Cast<Cell>(*this)->value(), &accumulator);
3756 os << accumulator.ToCString().get();
3757 os << '>';
3758 break;
3759 }
3760 case PROPERTY_CELL_TYPE: {
3762 os << "<PropertyCell name=";
3763 ShortPrint(cell->name(), os);
3764 os << " value=";
3765 HeapStringAllocator allocator;
3766 StringStream accumulator(&allocator);
3767 ShortPrint(cell->value(kAcquireLoad), &accumulator);
3768 os << accumulator.ToCString().get();
3769 os << '>';
3770 break;
3771 }
3772 case CONTEXT_SIDE_PROPERTY_CELL_TYPE: {
3773 os << "<ContextSidePropertyCell>";
3774 break;
3775 }
3776 case ACCESSOR_INFO_TYPE: {
3778 os << "<AccessorInfo ";
3779 os << "name= " << Brief(info->name());
3780 os << ", data= " << Brief(info->data());
3781 os << ">";
3782 break;
3783 }
3784 case FUNCTION_TEMPLATE_INFO_TYPE: {
3786 os << "<FunctionTemplateInfo ";
3788 if (GetIsolateFromHeapObject(*this, &isolate)) {
3789 os << "callback= " << reinterpret_cast<void*>(info->callback(isolate));
3790 } else {
3791 os << "callback= " << kUnavailableString;
3792 }
3793 os << ", data= " << Brief(info->callback_data(kAcquireLoad));
3794 os << ", has_side_effects= ";
3795 if (info->has_side_effects()) {
3796 os << "true>";
3797 } else {
3798 os << "false>";
3799 }
3800 break;
3801 }
3802#if V8_ENABLE_WEBASSEMBLY
3803 case WASM_DISPATCH_TABLE_TYPE:
3804 os << "<WasmDispatchTable[" << Cast<WasmDispatchTable>(*this)->length()
3805 << "]>";
3806 break;
3807#endif // V8_ENABLE_WEBASSEMBLY
3808 default:
3809 os << "<Other heap object (" << map()->instance_type() << ")>";
3810 break;
3811 }
3812}
3813
3814void HeapNumber::HeapNumberShortPrint(std::ostream& os) {
3815 double val = value();
3816 if (i::IsMinusZero(val)) {
3817 os << "-0.0";
3818 } else if (val == DoubleToInteger(val) && val >= kMinSafeInteger &&
3819 val <= kMaxSafeInteger) {
3820 // Print integer HeapNumbers in safe integer range with max precision: as
3821 // 9007199254740991.0 instead of 9.0072e+15
3822 int64_t i = static_cast<int64_t>(val);
3823 os << i << ".0";
3824 } else {
3825 os << val;
3826 }
3827}
3828
3829// TODO(cbruni): remove once the new maptracer is in place.
3831 if (IsString(this)) {
3832 PrintF("%s", Cast<String>(this)->ToCString().get());
3833 } else {
3834 DCHECK(IsSymbol(this));
3835 Tagged<Symbol> s = Cast<Symbol>(this);
3836 if (IsUndefined(s->description())) {
3837 PrintF("#<%s>", s->PrivateSymbolToName());
3838 } else {
3839 PrintF("<%s>", Cast<String>(s->description())->ToCString().get());
3840 }
3841 }
3842}
3843
3844// TODO(cbruni): remove once the new maptracer is in place.
3846 if (IsString(this)) {
3847 return SNPrintF(str, "%s", Cast<String>(this)->ToCString().get());
3848 } else {
3849 DCHECK(IsSymbol(this));
3850 Tagged<Symbol> s = Cast<Symbol>(this);
3851 if (IsUndefined(s->description())) {
3852 return SNPrintF(str, "#<%s>", s->PrivateSymbolToName());
3853 } else {
3854 return SNPrintF(str, "<%s>",
3855 Cast<String>(s->description())->ToCString().get());
3856 }
3857 }
3858}
3859
3860void Symbol::SymbolShortPrint(std::ostream& os) {
3861 os << "<Symbol:";
3862 if (!IsUndefined(description())) {
3863 os << " ";
3864 Tagged<String> description_as_string = Cast<String>(description());
3865 description_as_string->PrintUC16(os, 0, description_as_string->length());
3866 } else {
3867 os << " (" << PrivateSymbolToName() << ")";
3868 }
3869 os << ">";
3870}
3871
3872void Map::PrintMapDetails(std::ostream& os) {
3874 this->MapPrint(os);
3875 instance_descriptors()->PrintDescriptors(os);
3876}
3877
3878void Map::MapPrint(std::ostream& os) {
3879 bool is_meta_map = instance_type() == MAP_TYPE;
3880#ifdef OBJECT_PRINT
3881 PrintHeader(os, is_meta_map ? "MetaMap" : "Map");
3882#else
3883 os << (is_meta_map ? "MetaMap=" : "Map=") << reinterpret_cast<void*>(ptr());
3884#endif
3885 os << "\n - type: " << instance_type();
3886 os << "\n - instance size: ";
3887 if (instance_size() == kVariableSizeSentinel) {
3888 os << "variable";
3889 } else {
3890 os << instance_size();
3891 }
3892 if (is_meta_map) {
3893 // This is one of the meta maps, print only relevant fields.
3894 os << "\n - native_context: " << Brief(native_context_or_null());
3895 os << "\n";
3896 return;
3897 }
3898
3899 if (IsJSObjectMap(*this)) {
3900 os << "\n - inobject properties: " << GetInObjectProperties();
3901 os << "\n - unused property fields: " << UnusedPropertyFields();
3902 }
3903 os << "\n - elements kind: " << ElementsKindToString(elements_kind());
3904 os << "\n - enum length: ";
3905 if (EnumLength() == kInvalidEnumCacheSentinel) {
3906 os << "invalid";
3907 } else {
3908 os << EnumLength();
3909 }
3910 if (is_deprecated()) os << "\n - deprecated_map";
3911 if (is_stable()) os << "\n - stable_map";
3912 if (is_migration_target()) os << "\n - migration_target";
3913 if (is_dictionary_map()) os << "\n - dictionary_map";
3914 if (has_named_interceptor()) os << "\n - named_interceptor";
3915 if (has_indexed_interceptor()) os << "\n - indexed_interceptor";
3916 if (may_have_interesting_properties())
3917 os << "\n - may_have_interesting_properties";
3918 if (is_undetectable()) os << "\n - undetectable";
3919 if (is_callable()) os << "\n - callable";
3920 if (is_constructor()) os << "\n - constructor";
3921 if (has_prototype_slot()) {
3922 os << "\n - has_prototype_slot";
3923 if (has_non_instance_prototype()) os << " (non-instance prototype)";
3924 }
3925 if (is_access_check_needed()) os << "\n - access_check_needed";
3926 if (!is_extensible()) os << "\n - non-extensible";
3927 if (IsContextMap(*this)) {
3928 os << "\n - native context: " << Brief(native_context());
3929 } else if (is_prototype_map()) {
3930 os << "\n - prototype_map";
3931 os << "\n - prototype info: " << Brief(prototype_info());
3932 } else {
3933 os << "\n - back pointer: " << Brief(GetBackPointer());
3934 }
3935 os << "\n - prototype_validity cell: "
3936 << Brief(prototype_validity_cell(kRelaxedLoad));
3937 os << "\n - instance descriptors " << (owns_descriptors() ? "(own) " : "")
3938 << "#" << NumberOfOwnDescriptors() << ": "
3940
3941 // Read-only maps can't have transitions, which is fortunate because we need
3942 // the isolate to iterate over the transitions.
3943 if (!HeapLayout::InReadOnlySpace(*this)) {
3944 Isolate* isolate = GetIsolateFromWritableObject(*this);
3945 TransitionsAccessor transitions(isolate, *this);
3946 int nof_transitions = transitions.NumberOfTransitions();
3947 if (nof_transitions > 0 || transitions.HasPrototypeTransitions() ||
3948 transitions.HasSideStepTransitions()) {
3949 os << "\n - transitions #" << nof_transitions << ": ";
3950 Tagged<HeapObject> heap_object;
3951 Tagged<Smi> smi;
3952 if (raw_transitions().ToSmi(&smi)) {
3953 os << Brief(smi);
3954 } else if (raw_transitions().GetHeapObject(&heap_object)) {
3955 os << Brief(heap_object);
3956 }
3957#ifdef OBJECT_PRINT
3958 transitions.PrintTransitions(os);
3959#endif // OBJECT_PRINT
3960 }
3961 }
3962 os << "\n - prototype: " << Brief(prototype());
3963 if (has_non_instance_prototype()) {
3964 os << "\n - non-instance prototype: " << Brief(GetNonInstancePrototype());
3965 }
3966 if (!IsContextMap(*this)) {
3967 os << "\n - constructor: " << Brief(GetConstructor());
3968 }
3969 os << "\n - dependent code: " << Brief(dependent_code());
3970 os << "\n - construction counter: " << construction_counter();
3971 os << "\n";
3972}
3973
3976 Tagged<Name> key = GetKey(i);
3977 os << "\n [" << i.as_int() << "]: ";
3978#ifdef OBJECT_PRINT
3979 key->NamePrint(os);
3980#else
3981 ShortPrint(key, os);
3982#endif
3983 os << " ";
3984 PrintDescriptorDetails(os, i, PropertyDetails::kPrintFull);
3985 }
3986 os << "\n";
3987}
3988
3990 InternalIndex descriptor,
3992 PropertyDetails details = GetDetails(descriptor);
3993 details.PrintAsFastTo(os, mode);
3994 os << " @ ";
3995 switch (details.location()) {
3997 Tagged<FieldType> field_type = GetFieldType(descriptor);
3998 FieldType::PrintTo(field_type, os);
3999 break;
4000 }
4002 Tagged<Object> value = GetStrongValue(descriptor);
4003 os << Brief(value);
4004 if (IsAccessorPair(value)) {
4006 os << "(get: " << Brief(pair->getter())
4007 << ", set: " << Brief(pair->setter()) << ")";
4008 }
4009 break;
4010 }
4011}
4012
4013#if defined(DEBUG) || defined(OBJECT_PRINT)
4014// This method is only meant to be called from gdb for debugging purposes.
4015// Since the string can also be in two-byte encoding, non-Latin1 characters
4016// will be ignored in the output.
4017char* String::ToAsciiArray() {
4018 // Static so that subsequent calls frees previously allocated space.
4019 // This also means that previous results will be overwritten.
4020 static char* buffer = nullptr;
4021 if (buffer != nullptr) delete[] buffer;
4022 buffer = new char[length() + 1];
4023 WriteToFlat(this, reinterpret_cast<uint8_t*>(buffer), 0, length());
4024 buffer[length()] = 0;
4025 return buffer;
4026}
4027
4028// static
4029void TransitionsAccessor::PrintOneTransition(std::ostream& os, Tagged<Name> key,
4030 Tagged<Map> target) {
4031 os << "\n ";
4032#ifdef OBJECT_PRINT
4033 key->NamePrint(os);
4034#else
4035 ShortPrint(key, os);
4036#endif
4037 os << ": ";
4038 ReadOnlyRoots roots = GetReadOnlyRoots();
4039 if (key == roots.nonextensible_symbol()) {
4040 os << "(transition to non-extensible)";
4041 } else if (key == roots.sealed_symbol()) {
4042 os << "(transition to sealed)";
4043 } else if (key == roots.frozen_symbol()) {
4044 os << "(transition to frozen)";
4045 } else if (key == roots.elements_transition_symbol()) {
4046 os << "(transition to " << ElementsKindToString(target->elements_kind())
4047 << ")";
4048 } else if (key == roots.strict_function_transition_symbol()) {
4049 os << " (transition to strict function)";
4050 } else {
4051 DCHECK(!IsSpecialTransition(roots, key));
4052 os << "(transition to ";
4053 InternalIndex descriptor = target->LastAdded();
4054 Tagged<DescriptorArray> descriptors = target->instance_descriptors();
4055 descriptors->PrintDescriptorDetails(os, descriptor,
4057 os << ")";
4058 }
4059 os << " -> " << Brief(target);
4060}
4061
4062void TransitionArray::PrintInternal(std::ostream& os) {
4063 {
4064 int num_transitions = number_of_transitions();
4065 os << "\n Transitions #" << num_transitions << ":";
4066 for (int i = 0; i < num_transitions; i++) {
4067 Tagged<Name> key = GetKey(i);
4068 Tagged<Map> target;
4069 GetTargetIfExists(i, GetIsolateFromWritableObject(*this), &target);
4070 TransitionsAccessor::PrintOneTransition(os, key, target);
4071 }
4072 }
4073
4074 if (HasPrototypeTransitions()) {
4075 auto prototype_transitions = GetPrototypeTransitions();
4076 int num_transitions = NumberOfPrototypeTransitions(prototype_transitions);
4077 os << "\n Prototype transitions #" << num_transitions << ": "
4078 << Brief(prototype_transitions);
4079 for (int i = 0; i < num_transitions; i++) {
4080 auto maybe = prototype_transitions->get(
4083 if (maybe.GetHeapObjectIfWeak(&target)) {
4084 auto map = Cast<Map>(target);
4085 os << "\n " << Brief(map->prototype()) << " -> "
4086 << Brief(Cast<Map>(target));
4087 }
4088 }
4089 }
4090
4091 if (HasSideStepTransitions()) {
4092 auto sidestep_transitions = GetSideStepTransitions();
4093 int num_transitions = sidestep_transitions->length();
4094 os << "\n Sidestep transitions #" << num_transitions << ": "
4095 << Brief(sidestep_transitions);
4096 for (int i = 0; i < num_transitions; i++) {
4098 auto maybe_target = sidestep_transitions->get(i);
4099 os << "\n " << kind << " -> " << Brief(maybe_target);
4100 }
4101 }
4102}
4103
4104void TransitionsAccessor::PrintTransitions(std::ostream& os) {
4105 switch (encoding()) {
4106 case kPrototypeInfo:
4107 case kUninitialized:
4108 case kMigrationTarget:
4109 return;
4110 case kWeakRef: {
4111 Tagged<Map> target =
4112 Cast<Map>(raw_transitions_.GetHeapObjectAssumeWeak());
4113 Tagged<Name> key = GetSimpleTransitionKey(target);
4114 PrintOneTransition(os, key, target);
4115 break;
4116 }
4117 case kFullTransitionArray:
4118 return transitions()->PrintInternal(os);
4119 }
4120}
4121
4122void TransitionsAccessor::PrintTransitionTree() {
4123 StdoutStream os;
4124 os << (IsUndefined(map_->GetBackPointer()) ? "root_" : "")
4125 << "map= " << Brief(map_);
4127 PrintTransitionTree(os, 0, &no_gc);
4128 os << "\n" << std::flush;
4129}
4130
4131void TransitionsAccessor::PrintTransitionTree(
4132 std::ostream& os, int level, DisallowGarbageCollection* no_gc) {
4133 ReadOnlyRoots roots = ReadOnlyRoots(isolate_);
4134 int pos = 0;
4135 int proto_pos = 0;
4136 ForEachTransitionWithKey(
4137 no_gc,
4138 [&](Tagged<Name> key, Tagged<Map> target) {
4139 os << std::endl
4140 << " " << level << "/" << pos << ":" << std::setw(level * 2 + 2)
4141 << " ";
4142 pos++;
4143 std::stringstream ss;
4144 ss << Brief(target);
4145 os << std::left << std::setw(50) << ss.str() << ": ";
4146
4147 if (key == roots.nonextensible_symbol()) {
4148 os << "to non-extensible";
4149 } else if (key == roots.sealed_symbol()) {
4150 os << "to sealed ";
4151 } else if (key == roots.frozen_symbol()) {
4152 os << "to frozen";
4153 } else if (key == roots.elements_transition_symbol()) {
4154 os << "to " << ElementsKindToString(target->elements_kind());
4155 } else if (key == roots.strict_function_transition_symbol()) {
4156 os << "to strict function";
4157 } else {
4158#ifdef OBJECT_PRINT
4159 key->NamePrint(os);
4160#else
4161 ShortPrint(key, os);
4162#endif
4163 os << " ";
4164 DCHECK(!IsSpecialTransition(ReadOnlyRoots(isolate_), key));
4165 os << "to ";
4166 InternalIndex descriptor = target->LastAdded();
4167 Tagged<DescriptorArray> descriptors =
4168 target->instance_descriptors(isolate_);
4169 descriptors->PrintDescriptorDetails(os, descriptor,
4171 }
4172 TransitionsAccessor transitions(isolate_, target);
4173 transitions.PrintTransitionTree(os, level + 1, no_gc);
4174 },
4175 [&](Tagged<Map> target) {
4176 os << std::endl
4177 << " " << level << "/p" << proto_pos << ":"
4178 << std::setw(level * 2 + 2) << " ";
4179 proto_pos++;
4180 std::stringstream ss;
4181 ss << Brief(target);
4182 os << std::left << std::setw(50) << ss.str() << ": to proto ";
4183 ShortPrint(target->prototype(), os);
4184 TransitionsAccessor transitions(isolate_, target);
4185 transitions.PrintTransitionTree(os, level + 1, no_gc);
4186 },
4188 os << std::endl
4189 << " " << level << "/s:" << std::setw(level * 2 + 2) << " ";
4190 std::stringstream ss;
4191 ss << Brief(side_step);
4192 os << std::left << std::setw(50) << ss.str() << ": sidestep " << kind;
4193 });
4194}
4195
4196void JSObject::PrintTransitions(std::ostream& os) {
4197 TransitionsAccessor ta(GetIsolate(), map());
4198 if (ta.NumberOfTransitions() != 0 || ta.HasPrototypeTransitions()) {
4199 os << "\n - transitions";
4200 ta.PrintTransitions(os);
4201 }
4202}
4203
4204#endif // defined(DEBUG) || defined(OBJECT_PRINT)
4205} // namespace v8::internal
4206
4207namespace {
4208
4209inline i::Tagged<i::Object> GetObjectFromRaw(void* object) {
4210 i::Address object_ptr = reinterpret_cast<i::Address>(object);
4211#ifdef V8_COMPRESS_POINTERS
4213 // Try to decompress pointer.
4214 i::Isolate* isolate = i::Isolate::TryGetCurrent();
4215 if (isolate != nullptr) {
4216 object_ptr = i::V8HeapCompressionScheme::DecompressTagged(
4217 isolate, static_cast<i::Tagged_t>(object_ptr));
4218 } else {
4220 object_ptr = i::V8HeapCompressionScheme::DecompressTagged(
4221 cage_base, static_cast<i::Tagged_t>(object_ptr));
4222 }
4223 }
4224#endif
4225 return i::Tagged<i::Object>(object_ptr);
4226}
4227
4228} // namespace
4229
4230//
4231// The following functions are used by our gdb macros.
4232//
4234 void* object) {
4235 return GetObjectFromRaw(object);
4236}
4237
4238// Defines _As_XXX functions which are useful for inspecting object properties
4239// in debugger:
4240//
4241// (gdb) p _As_ScopeInfo(0xead)->IsEmpty()
4242// $1 = 0x1
4243// (gdb) p _As_ScopeInfo(0x0e830009d555)->scope_type()
4244// $2 = v8::internal::FUNCTION_SCOPE
4245// (gdb) p _As_Undefined(0x11)->kind()
4246// $3 = 0x4
4247// (gdb) job _As_Oddball(0x2d)->to_string()
4248// 0xe8300005309: [String] in ReadOnlySpace: #null
4249//
4250#define AS_HELPER_DEF(Type, ...) \
4251 V8_DEBUGGING_EXPORT auto& _As_##Type(i::Address ptr) { \
4252 i::Tagged<i::Type> tagged = UncheckedCast<i::Type>( \
4253 GetObjectFromRaw(reinterpret_cast<void*>(ptr))); \
4254 /* _As_XXX(..) functions provide storage for TaggedOperatorArrowRef<T> */ \
4255 /* temporary object and return a reference as a measure against gdb */ \
4256 /* error "Attempt to take address of value not located in memory." */ \
4257 static auto result = tagged.operator->(); /* There's no default ctor. */ \
4258 result = tagged.operator->(); \
4259 return result; \
4260 } \
4261 V8_DEBUGGING_EXPORT auto& _As_##Type(i::Tagged<i::HeapObject>& obj) { \
4262 return _As_##Type(obj.ptr()); \
4263 }
4264
4268#undef AS_HELPER_DEF
4269
4270V8_DEBUGGING_EXPORT extern "C" void _v8_internal_Print_Object(void* object) {
4271 i::AllowHandleDereference allow_deref;
4272 i::AllowHandleUsageOnAllThreads allow_deref_all_threads;
4273 i::Print(GetObjectFromRaw(object));
4274}
4275
4276// Used by lldb_visualizers.py to create a representation of a V8 object.
4278 void* object) {
4279 std::stringstream strm;
4280 i::Print(GetObjectFromRaw(object), strm);
4281 return strm.str();
4282}
4283
4285 void* object) {
4286#ifdef OBJECT_PRINT
4287 i::StdoutStream os;
4288 i::LoadHandler::PrintHandler(GetObjectFromRaw(object), os);
4289 os << std::endl << std::flush;
4290#endif
4291}
4292
4294 void* object) {
4295#ifdef OBJECT_PRINT
4296 i::StdoutStream os;
4297 i::StoreHandler::PrintHandler(GetObjectFromRaw(object), os);
4298 os << std::flush;
4299#endif
4300}
4301
4302V8_DEBUGGING_EXPORT extern "C" void _v8_internal_Print_Code(void* object) {
4303 i::Address address = reinterpret_cast<i::Address>(object);
4304 i::Isolate* isolate = i::Isolate::Current();
4305
4306#if V8_ENABLE_WEBASSEMBLY
4307 {
4308 if (auto* wasm_code =
4309 i::wasm::GetWasmCodeManager()->LookupCode(isolate, address)) {
4310 i::StdoutStream os;
4311 wasm_code->Disassemble(nullptr, os, address);
4312 return;
4313 }
4314 }
4315#endif // V8_ENABLE_WEBASSEMBLY
4316
4317 std::optional<i::Tagged<i::Code>> lookup_result =
4318 isolate->heap()->TryFindCodeForInnerPointerForPrinting(address);
4319 if (!lookup_result.has_value()) {
4320 i::PrintF(
4321 "%p is not within the current isolate's code or embedded spaces\n",
4322 object);
4323 return;
4324 }
4325
4326#if defined(OBJECT_PRINT)
4327 i::StdoutStream os;
4328 lookup_result.value()->CodePrint(os, nullptr, address);
4329#elif defined(ENABLE_DISASSEMBLER)
4330 i::StdoutStream os;
4331 lookup_result.value()->Disassemble(nullptr, os, isolate, address);
4332#else
4333 i::Print(lookup_result.value());
4334#endif
4335}
4336
4337#ifdef V8_ENABLE_LEAPTIERING
4338V8_DEBUGGING_EXPORT extern "C" void _v8_internal_Print_Dispatch_Handle(
4339 uint32_t handle) {
4340 i::IsolateGroup::current()->js_dispatch_table()->PrintEntry(
4342}
4343#endif // V8_ENABLE_LEAPTIERING
4344
4346 void* object, size_t range_limit) {
4347 i::Address address = reinterpret_cast<i::Address>(object);
4348 i::Isolate* isolate = i::Isolate::Current();
4349
4350#if V8_ENABLE_WEBASSEMBLY
4351 {
4352 if (i::wasm::GetWasmCodeManager()->LookupCode(isolate, address)) {
4353 i::PrintF("Not supported on wasm code");
4354 return;
4355 }
4356 }
4357#endif // V8_ENABLE_WEBASSEMBLY
4358
4359 std::optional<i::Tagged<i::Code>> lookup_result =
4360 isolate->heap()->TryFindCodeForInnerPointerForPrinting(address);
4361 if (!lookup_result.has_value()) {
4362 i::PrintF(
4363 "%p is not within the current isolate's code or embedded spaces\n",
4364 object);
4365 return;
4366 }
4367
4368#if defined(ENABLE_DISASSEMBLER)
4369 i::StdoutStream os;
4370 lookup_result.value()->DisassembleOnlyCode(nullptr, os, isolate, address,
4371 range_limit);
4372#endif
4373}
4374
4376 i::Isolate* isolate = i::Isolate::Current();
4377 isolate->PrintStack(stdout);
4378}
4379
4381// This class is easy to navigate in a GUI debugger and not intended for
4382// use elsewhere.
4384 i::StackFrame::Type type;
4385 std::string summary;
4386 std::vector<i::Tagged<i::SharedFunctionInfo>> functions;
4387 std::vector<i::Tagged<i::Object>> expressions;
4388};
4389} // namespace _v8_internal_debugonly
4390
4391// Used by lldb_visualizers.py to create a representation of the V8 stack.
4392V8_DEBUGGING_EXPORT extern std::vector<
4395 std::vector<_v8_internal_debugonly::StackTraceDebugDetails> stack;
4397 int frame_index = 0;
4398
4399 for (i::StackFrameIterator it(isolate); !it.done(); it.Advance()) {
4400 i::CommonFrame* frame = i::CommonFrame::cast(it.frame());
4402 details.type = frame->type();
4403
4404 if (frame->is_javascript()) {
4405 i::JavaScriptFrame::cast(frame)->GetFunctions(&details.functions);
4406 if (!frame->is_optimized_js()) {
4407 int exprcount = frame->ComputeExpressionsCount();
4408 for (int i = 0; i < exprcount; i++) {
4409 details.expressions.push_back(frame->GetExpression(i));
4410 }
4411 }
4412 }
4413
4414 i::HandleScope scope(isolate);
4415 i::StringStream::ClearMentionedObjectCache(isolate);
4416 i::HeapStringAllocator allocator;
4417 i::StringStream accumulator(&allocator);
4418 frame->Print(&accumulator, i::StackFrame::OVERVIEW, frame_index++);
4419 std::unique_ptr<char[]> overview = accumulator.ToCString();
4420 details.summary = overview.get();
4421 stack.push_back(std::move(details));
4422 }
4423 return stack;
4424}
4425
4427 void* object, bool start_at_root = false) {
4428 i::Tagged<i::Object> o(GetObjectFromRaw(object));
4429 if (!IsMap(o)) {
4430 printf("Please provide a valid Map\n");
4431 } else {
4432#if defined(DEBUG) || defined(OBJECT_PRINT)
4434 i::TransitionsAccessor transitions(
4435 i::Isolate::Current(),
4436 start_at_root ? map->FindRootMap(GetPtrComprCageBase(map)) : map);
4437 transitions.PrintTransitionTree();
4438#endif
4439 }
4440}
4441
4443 void* object) {
4444#ifdef OBJECT_PRINT
4445 const auto mark_bit =
4446 v8::internal::MarkBit::From(reinterpret_cast<i::Address>(object));
4447 i::StdoutStream os;
4448 os << "Object " << object << " is "
4449 << (mark_bit.Get() ? "marked" : "unmarked") << std::endl;
4450 os << " mark-bit cell: " << mark_bit.CellAddress()
4451 << ", mask: " << mark_bit.Mask() << std::endl;
4452#endif
4453}
4454
4456 void* function_callback_info) {
4457#ifdef OBJECT_PRINT
4458 i::PrintFunctionCallbackInfo(function_callback_info);
4459#endif
4460}
4461
4463 void* property_callback_info) {
4464#ifdef OBJECT_PRINT
4465 i::PrintPropertyCallbackInfo(property_callback_info);
4466#endif
4467}
Isolate * isolate_
int16_t parameter_count
Definition builtins.cc:67
interpreter::Bytecode bytecode
Definition builtins.cc:43
union v8::internal::@341::BuiltinMetadata::KindSpecificData data
Builtins::Kind kind
Definition builtins.cc:40
PropertyT * getter
SourcePosition pos
uint32_t GetHash()
Definition api.cc:4282
PropertyAttributes initial_property_attributes() const
SideEffectType setter_side_effect_type() const
SideEffectType getter_side_effect_type() const
static constexpr bool IsBuiltinId(Builtin builtin)
Definition builtins.h:128
static V8_EXPORT_PRIVATE const char * name(Builtin builtin)
Definition builtins.cc:226
V8_EXPORT_PRIVATE void Disassemble(std::ostream &os)
uint32_t stack_slots() const
Definition code-inl.h:491
bool is_turbofanned() const
Definition code-inl.h:437
Tagged< Object > raw_deoptimization_data_or_interpreter_data() const
Definition code.cc:25
CodeKind kind() const
Definition code-inl.h:332
bool is_builtin() const
Definition code-inl.h:914
bool embedded_objects_cleared() const
Definition code-inl.h:574
Tagged< Object > raw_position_table() const
Definition code.cc:30
Builtin builtin_id() const
Definition code-inl.h:904
bool has_instruction_stream() const
Definition code-inl.h:739
int ComputeExpressionsCount() const
Definition frames.cc:1481
Tagged< Object > GetExpression(int index) const
Definition frames-inl.h:242
void PrintDescriptors(std::ostream &os)
void PrintDescriptorDetails(std::ostream &os, InternalIndex descriptor, PropertyDetails::PrintMode mode)
int32_t slot_count(AcquireLoadTag) const
int32_t create_closure_slot_count(AcquireLoadTag) const
static int GetSlotSize(FeedbackSlotKind kind)
CompareOperationHint GetCompareOperationFeedback() const
Tagged< MaybeObject > GetFeedbackExtra() const
FeedbackSlotKind kind() const
void Print(std::ostream &os)
Tagged< MaybeObject > GetFeedback() const
InlineCacheState ic_state() const
BinaryOperationHint GetBinaryOperationFeedback() const
FeedbackSlotKind GetKind(FeedbackSlot slot) const
Tagged< MaybeObject > Get(FeedbackSlot slot) const
Tagged< Code > optimized_code(IsolateForSandbox isolate) const
void FeedbackSlotPrint(std::ostream &os, FeedbackSlot slot)
static FieldIndex ForDetails(Tagged< Map > map, PropertyDetails details)
static V8_EXPORT_PRIVATE void PrintTo(Tagged< FieldType > type, std::ostream &os)
Definition field-type.cc:94
Address foreign_address_unchecked() const
Definition foreign-inl.h:51
static V8_INLINE bool InWritableSharedSpace(Tagged< HeapObject > object)
static V8_INLINE bool InReadOnlySpace(Tagged< HeapObject > object)
V8_EXPORT_PRIVATE void HeapNumberShortPrint(std::ostream &os)
void HeapObjectShortPrint(std::ostream &os)
static IsolateGroup * current()
static V8_INLINE Isolate * Current()
Definition isolate-inl.h:35
IterationKind kind() const
void JSCollectionIteratorPrint(std::ostream &os, const char *name)
DisposableStackState state() const
Tagged< Context > context()
bool has_closure_feedback_cell_array() const
Tagged< ClosureFeedbackCellArray > closure_feedback_cell_array() const
bool IsTieringRequestedOrInProgress() const
V8_EXPORT_PRIVATE bool ActiveTierIsIgnition(IsolateForSandbox isolate) const
void JSIteratorHelperPrintHeader(std::ostream &os, const char *helper_name)
MessageTemplate type() const
Tagged< JSAny > RawFastPropertyAt(FieldIndex index) const
Tagged< FixedArrayBase > elements(PtrComprCageBase cage_base, AcquireLoadTag tag) const =delete
Tagged< Object > reactions() const
static const char * Status(Promise::PromiseState status)
Definition objects.cc:5005
Tagged< Object > result() const
V8_EXPORT_PRIVATE Promise::PromiseState status() const
Definition objects.cc:4993
static const char * FlagsToString(Flags flags, FlagsBuffer *out_buffer)
Tagged< String > source() const
base::EmbeddedVector< char, kFlagCount+1 > FlagsBuffer
Definition js-regexp.h:145
void MapPrint(std::ostream &os)
void PrintMapDetails(std::ostream &os)
static V8_ALLOW_UNUSED MarkBit From(Address)
uint32_t hash() const
Definition name-inl.h:228
Tagged< String > to_string() const
Definition oddball-inl.h:32
PropertyDetails property_details() const
PropertyLocation location() const
void PrintAsFastTo(std::ostream &out, PrintMode mode=kPrintFull)
Definition property.cc:139
static V8_EXPORT_PRIVATE bool Contains(Address address)
JSRegExp::Flags flags() const
Tagged< Object > last_input() const
Tagged< String > last_subject() const
static LocalNamesRange< DirectHandle< ScopeInfo > > IterateLocalNames(DirectHandle< ScopeInfo > scope_info)
Tagged< NameToIndexHashTable > names_to_context_index() const
uint16_t internal_formal_parameter_count_with_receiver() const
Tagged< HeapObject > script() const
Tagged< ScopeInfo > GetOuterScopeInfo() const
V8_EXPORT_PRIVATE int StartPosition() const
V8_EXPORT_PRIVATE int EndPosition() const
V8_EXPORT_PRIVATE Tagged< Code > GetCode(Isolate *isolate) const
Tagged< Context > context() const
Tagged< UnionOf< FixedArray, NumberDictionary > > arguments() const
static constexpr int ToInt(const Tagged< Object > object)
Definition smi.h:33
static constexpr Tagged< Smi > FromInt(int value)
Definition smi.h:38
static constexpr Tagged< Smi > zero()
Definition smi.h:99
Tagged< Script > GetScript() const
virtual Type type() const =0
bool is_javascript() const
Definition frames.h:290
virtual void Print(StringStream *accumulator, PrintMode mode, int index) const
Definition frames.cc:1386
bool is_optimized_js() const
Definition frames.h:233
std::unique_ptr< char[]> ToCString() const
const char * PrefixForDebugPrint() const
Definition string.cc:568
uint32_t length() const
Definition string-inl.h:127
const char * SuffixForDebugPrint() const
Definition string.cc:598
void PrintUC16(std::ostream &os, int start=0, int end=-1)
Definition string.cc:621
int EntryForEnumerationIndex(int enumeration_index)
bool ToKey(ReadOnlyRoots roots, InternalIndex entry, Tagged< Object > *out_key)
PropertyDetails DetailsAt(InternalIndex entry)
bool is_private() const
bool is_interesting_symbol() const
Tagged< PrimitiveHeapObject > description() const
Definition name-inl.h:25
bool is_private_name() const
Definition name-inl.h:54
void SymbolShortPrint(std::ostream &os)
const char * PrivateSymbolToName() const
Definition objects.cc:4984
bool is_well_known_symbol() const
bool is_private_brand() const
static PtrType load(Tagged< HeapObject > host, int offset=0)
constexpr bool SafeEquals(TaggedImpl< kOtherRefType, Address > other) const
Definition tagged-impl.h:93
void PrintInternal(std::ostream &os)
static const int kProtoTransitionHeaderSize
static V8_INLINE Address DecompressTagged(TOnHeapAddress on_heap_addr, Tagged_t raw_value)
static V8_EXPORT_PRIVATE bool IsWasmExportedFunction(Tagged< Object > object)
static bool IsWasmJSFunction(Tagged< Object > object)
Address RawFieldAddress(int raw_offset)
Tagged< Map > get_described_rtt() const
wasm::CanonicalValueType type() const
wasm::CanonicalValueType element_type() const
V8_EXPORT_PRIVATE const CanonicalStructType * LookupStruct(CanonicalTypeIndex index) const
V8_EXPORT_PRIVATE std::string name() const
Address GetEntrypointWithoutSignatureCheck(WasmCodePointer index) const
Handle< Code > code
#define V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL
Definition globals.h:242
#define V8_EMBEDDED_CONSTANT_POOL_BOOL
Definition globals.h:81
#define USE_SIMULATOR_BOOL
Definition globals.h:73
const MapRef map_
int start
Handle< SharedFunctionInfo > info
int end
#define RAB_GSAB_TYPED_ARRAYS(V)
#define TYPED_ARRAYS(V)
MicrotaskQueue * microtask_queue
Definition execution.cc:77
base::Vector< const DirectHandle< Object > > args
Definition execution.cc:74
DirectHandle< FixedArray > capture_name_map
Isolate * isolate
#define MAKE_TORQUE_CASE(Name, TYPE)
int32_t offset
TNode< Context > context
TNode< Object > target
TNode< Object > receiver
SharedFunctionInfoRef shared
TNode< Object > callback
std::map< const std::string, const std::string > map
std::string pattern
double hour
ZoneStack< RpoNumber > & stack
MovableLabel continuation
LiftoffAssembler::CacheState state
InstructionOperand source
int int32_t
Definition unicode.cc:40
unsigned short uint16_t
Definition unicode.cc:39
signed short int16_t
Definition unicode.cc:38
static V ReadUnalignedValue(Address p)
Definition memory.h:28
int SNPrintF(Vector< char > str, const char *format,...)
Definition strings.cc:20
FunctionCallbackArguments FCA
Definition frames.cc:1271
V8_EXPORT_PRIVATE WasmCodePointerTable * GetProcessWideWasmCodePointerTable()
TypeCanonicalizer * GetTypeCanonicalizer()
void Disassemble(const WasmModule *module, ModuleWireBytes wire_bytes, NamesProvider *names, v8::debug::DisassemblyCollector *collector, std::vector< int > *function_body_offsets)
constexpr bool is_reference(ValueKind kind)
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset kElementSegmentsOffset kInstanceObjectOffset kMemoryObjectsOffset kTaggedGlobalsBufferOffset kTablesOffset kProtectedDispatchTable0Offset kProtectedDispatchTableForImportsOffset kFuncRefsOffset feedback_vectors
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
Definition handles-inl.h:72
V8_EXPORT_PRIVATE base::Vector< Flag > Flags()
Definition flags.cc:300
bool TryCast(Tagged< From > value, Tagged< To > *out)
Definition casting.h:77
HasSideEffectsBit::kShift NeedsAccessCheckBit::kShift remove_prototype
kStaticElementsTemplateOffset kInstancePropertiesTemplateOffset instance_computed_properties
constexpr double kMaxSafeInteger
Definition globals.h:1985
constexpr int kSimd128Size
Definition globals.h:706
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset kElementSegmentsOffset kInstanceObjectOffset kMemoryObjectsOffset kTaggedGlobalsBufferOffset kTablesOffset kProtectedDispatchTable0Offset dispatch_table_for_imports
PerThreadAssertScopeDebugOnly< false, SAFEPOINTS_ASSERT, HEAP_ALLOCATION_ASSERT > DisallowGarbageCollection
bool is_sloppy(LanguageMode language_mode)
Definition globals.h:773
kMemory0SizeOffset new_allocation_limit_address
ReadOnlyRoots GetReadOnlyRoots()
Definition roots-inl.h:86
void PrintF(const char *format,...)
Definition utils.cc:39
Map::Bits1::HasPrototypeSlotBit Map::Bits1::HasNamedInterceptorBit Map::Bits1::IsUndetectableBit Map::Bits1::IsConstructorBit Map::Bits2::IsImmutablePrototypeBit Map::Bits3::IsDeprecatedBit is_prototype_map
Definition map-inl.h:133
void PrintPropertyCallbackInfo(void *property_callback_info)
const char * CodeKindToString(CodeKind kind)
Definition code-kind.cc:10
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset tiering_budget_array
Tagged< DescriptorArray >
Definition map-inl.h:52
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset old_allocation_limit_address
SharedFunctionInfo::HasStaticPrivateMethodsOrAccessorsBit SharedFunctionInfo::MaglevCompilationFailedBit syntax_kind
Tagged(T object) -> Tagged< T >
V8_INLINE IsolateForSandbox GetCurrentIsolateForSandbox()
Definition isolate.h:78
double DoubleToInteger(double x)
kWasmInternalFunctionIndirectPointerTag instance_data
V8_INLINE Isolate * GetIsolateFromWritableObject(Tagged< HeapObject > object)
V8_INLINE bool GetIsolateFromHeapObject(Tagged< HeapObject > object, Isolate **isolate)
V8_INLINE constexpr bool IsSmi(TaggedImpl< kRefType, StorageType > obj)
Definition objects.h:665
constexpr uint16_t kDontAdaptArgumentsSentinel
Definition globals.h:2779
kInterpreterTrampolineOffset Tagged< HeapObject >
const char * InlineCacheState2String(InlineCacheState state)
Definition globals.h:1692
kStaticElementsTemplateOffset kInstancePropertiesTemplateOffset Tagged< FixedArray >
Address Tagged_t
Definition globals.h:547
@ HOLEY_NONEXTENSIBLE_ELEMENTS
@ SLOW_STRING_WRAPPER_ELEMENTS
@ PACKED_NONEXTENSIBLE_ELEMENTS
@ SLOW_SLOPPY_ARGUMENTS_ELEMENTS
@ FAST_SLOPPY_ARGUMENTS_ELEMENTS
@ FAST_STRING_WRAPPER_ELEMENTS
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in name
Definition flags.cc:2086
kWasmInternalFunctionIndirectPointerTag kProtectedInstanceDataOffset sig
Flag flags[]
Definition flags.cc:3797
Map::Bits1::HasPrototypeSlotBit Map::Bits1::HasNamedInterceptorBit Map::Bits1::IsUndetectableBit Map::Bits1::IsConstructorBit Map::Bits2::IsImmutablePrototypeBit Map::Bits3::IsDeprecatedBit Map::Bits3::IsPrototypeMapBit Map::Bits3::IsExtensibleBit construction_counter
Definition map-inl.h:141
Map::Bits1::HasPrototypeSlotBit Map::Bits1::HasNamedInterceptorBit is_undetectable
Definition map-inl.h:113
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in allocation gc speed threshold for starting incremental marking via a task in percent of available threshold for starting incremental marking immediately in percent of available Use a single schedule for determining a marking schedule between JS and C objects schedules the minor GC task with kUserVisible priority max worker number of concurrent for NumberOfWorkerThreads start background threads that allocate memory concurrent_array_buffer_sweeping use parallel threads to clear weak refs in the atomic pause trace progress of the incremental marking trace object counts and memory usage report a tick only when allocated zone memory changes by this amount TracingFlags::gc_stats TracingFlags::gc_stats track native contexts that are expected to be garbage collected verify heap pointers before and after GC memory reducer runs GC with ReduceMemoryFootprint flag Maximum number of memory reducer GCs scheduled Old gen GC speed is computed directly from gc tracer counters Perform compaction on full GCs based on V8 s default heuristics Perform compaction on every full GC Perform code space compaction when finalizing a full GC with stack Stress GC compaction to flush out bugs with moving objects flush of baseline code when it has not been executed recently Use time base code flushing instead of age Use a progress bar to scan large objects in increments when incremental marking is active force incremental marking for small heaps and run it more often force marking at random points between and force scavenge at random points between and reclaim otherwise unreachable unmodified wrapper objects when possible less compaction in non memory reducing mode use high priority threads for concurrent Marking Test mode only flag It allows an unit test to select evacuation candidates use incremental marking for CppHeap cppheap_concurrent_marking c value for membalancer A special constant to balance between memory and space tradeoff The smaller the more memory it uses enable use of SSE4 instructions if available enable use of AVX VNNI instructions if available enable use of POPCNT instruction if available force all emitted branches to be in long mode(MIPS/PPC only)") DEFINE_BOOL(partial_constant_pool
return Cast< NumberDictionary >(elements(cage_base))
const char * ElementsKindToString(ElementsKind kind)
std::ostream & operator<<(std::ostream &os, AtomicMemoryOrder order)
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset globals_start
const int kVariableSizeSentinel
Definition objects.h:84
V8_INLINE IsolateForSandbox GetIsolateForSandbox(Tagged< HeapObject >)
Definition isolate.h:75
HasSideEffectsBit::kShift needs_access_check
void Print(Tagged< Object > obj)
Definition objects.h:774
Handle< To > UncheckedCast(Handle< From > value)
Definition handles-inl.h:55
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset kElementSegmentsOffset kInstanceObjectOffset memory_objects
constexpr int kSystemPointerSize
Definition globals.h:410
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset jump_table_start
V8_INLINE bool OutsideSandboxOrInReadonlySpace(Tagged< HeapObject > obj)
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset kElementSegmentsOffset kInstanceObjectOffset kMemoryObjectsOffset kTaggedGlobalsBufferOffset tables
V8_INLINE PtrComprCageBase GetPtrComprCageBase()
static const int kInvalidEnumCacheSentinel
Map::Bits1::HasPrototypeSlotBit has_named_interceptor
Definition map-inl.h:109
constexpr JSDispatchHandle kNullJSDispatchHandle(0)
instance_descriptors
Definition map-inl.h:52
DONT_OVERRIDE DISABLE_ALLOCATION_SITES HOLEY_ELEMENTS
kInstanceDescriptorsOffset raw_transitions
Definition map-inl.h:61
Map::Bits1::HasPrototypeSlotBit Map::Bits1::HasNamedInterceptorBit Map::Bits1::IsUndetectableBit Map::Bits1::IsConstructorBit Map::Bits2::IsImmutablePrototypeBit is_deprecated
Definition map-inl.h:129
void ShortPrint(Tagged< Object > obj, FILE *out)
Definition objects.cc:1865
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset data_segment_starts
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset kElementSegmentsOffset kInstanceObjectOffset kMemoryObjectsOffset kTaggedGlobalsBufferOffset kTablesOffset kProtectedDispatchTable0Offset kProtectedDispatchTableForImportsOffset func_refs
JSDisposableStackBase::NeedsAwaitBit suppressed_error_created
@ UNCACHED_EXTERNAL_INTERNALIZED_ONE_BYTE_STRING_TYPE
@ SHARED_SEQ_ONE_BYTE_STRING_TYPE
@ SHARED_SEQ_TWO_BYTE_STRING_TYPE
@ UNCACHED_EXTERNAL_TWO_BYTE_STRING_TYPE
@ SHARED_EXTERNAL_TWO_BYTE_STRING_TYPE
@ UNCACHED_EXTERNAL_INTERNALIZED_TWO_BYTE_STRING_TYPE
@ SLICED_TWO_BYTE_STRING_TYPE
@ UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE
@ SHARED_UNCACHED_EXTERNAL_TWO_BYTE_STRING_TYPE
@ SLICED_ONE_BYTE_STRING_TYPE
@ EXTERNAL_TWO_BYTE_STRING_TYPE
@ SHARED_UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE
@ EXTERNAL_INTERNALIZED_TWO_BYTE_STRING_TYPE
@ SHARED_EXTERNAL_ONE_BYTE_STRING_TYPE
@ EXTERNAL_INTERNALIZED_ONE_BYTE_STRING_TYPE
@ EXTERNAL_ONE_BYTE_STRING_TYPE
@ INTERNALIZED_ONE_BYTE_STRING_TYPE
@ INTERNALIZED_TWO_BYTE_STRING_TYPE
DONT_OVERRIDE DISABLE_ALLOCATION_SITES DISABLE_ALLOCATION_SITES HOLEY_DOUBLE_ELEMENTS
const int kHeapObjectTag
Definition v8-internal.h:72
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset element_segments
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset kElementSegmentsOffset kInstanceObjectOffset kMemoryObjectsOffset tagged_globals_buffer
V8_EXPORT_PRIVATE FlagValues v8_flags
kStaticElementsTemplateOffset instance_properties_template
void PrintFunctionCallbackInfo(void *function_callback_info)
return value
Definition map-inl.h:893
static bool IsMinusZero(double value)
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset kElementSegmentsOffset kInstanceObjectOffset kMemoryObjectsOffset kTaggedGlobalsBufferOffset kTablesOffset dispatch_table0
bool IsLoadGlobalICKind(FeedbackSlotKind kind)
static constexpr Address kNullAddress
Definition v8-internal.h:53
constexpr double kMinSafeInteger
Definition globals.h:1987
JSArrayBuffer::IsDetachableBit is_shared
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset kElementSegmentsOffset instance_object
Map::Bits1::HasPrototypeSlotBit Map::Bits1::HasNamedInterceptorBit Map::Bits1::IsUndetectableBit Map::Bits1::IsConstructorBit Map::Bits2::IsImmutablePrototypeBit Map::Bits3::IsDeprecatedBit Map::Bits3::IsPrototypeMapBit is_extensible
Definition map-inl.h:137
kInstanceDescriptorsOffset kTransitionsOrPrototypeInfoOffset IsNull(value)||IsJSProxy(value)||IsWasmObject(value)||(IsJSObject(value) &&(HeapLayout
Definition map-inl.h:70
kInstanceDescriptorsOffset kTransitionsOrPrototypeInfoOffset prototype
Definition map-inl.h:69
kInterpreterTrampolineOffset script
allowed_receiver_instance_type_range_end
!IsContextMap !IsContextMap native_context
Definition map-inl.h:877
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
SideEffectType
Definition v8-object.h:198
static constexpr RelaxedLoadTag kRelaxedLoad
Definition globals.h:2909
static constexpr AcquireLoadTag kAcquireLoad
Definition globals.h:2908
#define HEAP_OBJECT_TRUSTED_TYPE_LIST(V)
#define HOLE_LIST(V)
#define ODDBALL_LIST(V)
#define HEAP_OBJECT_ORDINARY_TYPE_LIST(V)
#define STRUCT_LIST(V)
V8_DEBUGGING_EXPORT C void _v8_internal_Print_PropertyCallbackInfo(void *property_callback_info)
#define MAKE_STRUCT_CASE(TYPE, Name, name)
V8_DEBUGGING_EXPORT C void _v8_internal_Print_OnlyCode(void *object, size_t range_limit)
V8_DEBUGGING_EXPORT C void _v8_internal_Print_Object_MarkBit(void *object)
V8_DEBUGGING_EXPORT C void _v8_internal_Print_Code(void *object)
V8_DEBUGGING_EXPORT C void _v8_internal_Print_Object(void *object)
V8_DEBUGGING_EXPORT C void _v8_internal_Print_StoreHandler(void *object)
#define AS_HELPER_DEF(Type,...)
V8_DEBUGGING_EXPORT C void _v8_internal_Print_StackTrace()
V8_DEBUGGING_EXPORT std::vector< _v8_internal_debugonly::StackTraceDebugDetails > _v8_internal_Expand_StackTrace(i::Isolate *isolate)
V8_DEBUGGING_EXPORT i::Tagged< i::Object > _v8_internal_Get_Object(void *object)
#define PRINT_HOLE(Type, Value, _)
V8_DEBUGGING_EXPORT C void _v8_internal_Print_TransitionTree(void *object, bool start_at_root=false)
V8_DEBUGGING_EXPORT C void _v8_internal_Print_LoadHandler(void *object)
V8_DEBUGGING_EXPORT C void _v8_internal_Print_FunctionCallbackInfo(void *function_callback_info)
V8_DEBUGGING_EXPORT std::string _v8_internal_Print_Object_To_String(void *object)
#define V8_DEBUGGING_EXPORT
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
constexpr T RoundDown(T x, intptr_t m)
Definition macros.h:371
std::vector< i::Tagged< i::Object > > expressions
std::vector< i::Tagged< i::SharedFunctionInfo > > functions
static AsHex Address(Address a)
Definition ostreams.h:142
#define TYPED_ARRAY_CONSTRUCTORS_SWITCH(Type, type, TYPE, Ctype)
wasm::ValueType type