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