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