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