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/v8.h"
6 
7 #include "src/disasm.h"
8 #include "src/disassembler.h"
9 #include "src/heap/objects-visiting.h"
10 #include "src/jsregexp.h"
11 #include "src/ostreams.h"
12 
13 namespace v8 {
14 namespace internal {
15 
16 #ifdef OBJECT_PRINT
17 
Print()18 void Object::Print() {
19   OFStream os(stdout);
20   this->Print(os);
21   os << flush;
22 }
23 
24 
Print(OStream & os)25 void Object::Print(OStream& os) {  // NOLINT
26   if (IsSmi()) {
27     Smi::cast(this)->SmiPrint(os);
28   } else {
29     HeapObject::cast(this)->HeapObjectPrint(os);
30   }
31 }
32 
33 
PrintHeader(OStream & os,const char * id)34 void HeapObject::PrintHeader(OStream& os, const char* id) {  // NOLINT
35   os << "" << reinterpret_cast<void*>(this) << ": [" << id << "]\n";
36 }
37 
38 
HeapObjectPrint(OStream & os)39 void HeapObject::HeapObjectPrint(OStream& os) {  // NOLINT
40   InstanceType instance_type = map()->instance_type();
41 
42   HandleScope scope(GetIsolate());
43   if (instance_type < FIRST_NONSTRING_TYPE) {
44     String::cast(this)->StringPrint(os);
45     return;
46   }
47 
48   switch (instance_type) {
49     case SYMBOL_TYPE:
50       Symbol::cast(this)->SymbolPrint(os);
51       break;
52     case MAP_TYPE:
53       Map::cast(this)->MapPrint(os);
54       break;
55     case HEAP_NUMBER_TYPE:
56       HeapNumber::cast(this)->HeapNumberPrint(os);
57       break;
58     case MUTABLE_HEAP_NUMBER_TYPE:
59       os << "<mutable ";
60       HeapNumber::cast(this)->HeapNumberPrint(os);
61       os << ">";
62       break;
63     case FIXED_DOUBLE_ARRAY_TYPE:
64       FixedDoubleArray::cast(this)->FixedDoubleArrayPrint(os);
65       break;
66     case CONSTANT_POOL_ARRAY_TYPE:
67       ConstantPoolArray::cast(this)->ConstantPoolArrayPrint(os);
68       break;
69     case FIXED_ARRAY_TYPE:
70       FixedArray::cast(this)->FixedArrayPrint(os);
71       break;
72     case BYTE_ARRAY_TYPE:
73       ByteArray::cast(this)->ByteArrayPrint(os);
74       break;
75     case FREE_SPACE_TYPE:
76       FreeSpace::cast(this)->FreeSpacePrint(os);
77       break;
78 
79 #define PRINT_EXTERNAL_ARRAY(Type, type, TYPE, ctype, size)            \
80   case EXTERNAL_##TYPE##_ARRAY_TYPE:                                   \
81     External##Type##Array::cast(this)->External##Type##ArrayPrint(os); \
82     break;
83 
84      TYPED_ARRAYS(PRINT_EXTERNAL_ARRAY)
85 #undef PRINT_EXTERNAL_ARRAY
86 
87 #define PRINT_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype, size) \
88   case Fixed##Type##Array::kInstanceType:                      \
89     Fixed##Type##Array::cast(this)->FixedTypedArrayPrint(os);  \
90     break;
91 
92     TYPED_ARRAYS(PRINT_FIXED_TYPED_ARRAY)
93 #undef PRINT_FIXED_TYPED_ARRAY
94 
95     case FILLER_TYPE:
96       os << "filler";
97       break;
98     case JS_OBJECT_TYPE:  // fall through
99     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
100     case JS_ARRAY_TYPE:
101     case JS_GENERATOR_OBJECT_TYPE:
102     case JS_REGEXP_TYPE:
103       JSObject::cast(this)->JSObjectPrint(os);
104       break;
105     case ODDBALL_TYPE:
106       Oddball::cast(this)->to_string()->Print(os);
107       break;
108     case JS_MODULE_TYPE:
109       JSModule::cast(this)->JSModulePrint(os);
110       break;
111     case JS_FUNCTION_TYPE:
112       JSFunction::cast(this)->JSFunctionPrint(os);
113       break;
114     case JS_GLOBAL_PROXY_TYPE:
115       JSGlobalProxy::cast(this)->JSGlobalProxyPrint(os);
116       break;
117     case JS_GLOBAL_OBJECT_TYPE:
118       JSGlobalObject::cast(this)->JSGlobalObjectPrint(os);
119       break;
120     case JS_BUILTINS_OBJECT_TYPE:
121       JSBuiltinsObject::cast(this)->JSBuiltinsObjectPrint(os);
122       break;
123     case JS_VALUE_TYPE:
124       os << "Value wrapper around:";
125       JSValue::cast(this)->value()->Print(os);
126       break;
127     case JS_DATE_TYPE:
128       JSDate::cast(this)->JSDatePrint(os);
129       break;
130     case CODE_TYPE:
131       Code::cast(this)->CodePrint(os);
132       break;
133     case JS_PROXY_TYPE:
134       JSProxy::cast(this)->JSProxyPrint(os);
135       break;
136     case JS_FUNCTION_PROXY_TYPE:
137       JSFunctionProxy::cast(this)->JSFunctionProxyPrint(os);
138       break;
139     case JS_SET_TYPE:
140       JSSet::cast(this)->JSSetPrint(os);
141       break;
142     case JS_MAP_TYPE:
143       JSMap::cast(this)->JSMapPrint(os);
144       break;
145     case JS_SET_ITERATOR_TYPE:
146       JSSetIterator::cast(this)->JSSetIteratorPrint(os);
147       break;
148     case JS_MAP_ITERATOR_TYPE:
149       JSMapIterator::cast(this)->JSMapIteratorPrint(os);
150       break;
151     case JS_WEAK_MAP_TYPE:
152       JSWeakMap::cast(this)->JSWeakMapPrint(os);
153       break;
154     case JS_WEAK_SET_TYPE:
155       JSWeakSet::cast(this)->JSWeakSetPrint(os);
156       break;
157     case FOREIGN_TYPE:
158       Foreign::cast(this)->ForeignPrint(os);
159       break;
160     case SHARED_FUNCTION_INFO_TYPE:
161       SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint(os);
162       break;
163     case JS_MESSAGE_OBJECT_TYPE:
164       JSMessageObject::cast(this)->JSMessageObjectPrint(os);
165       break;
166     case CELL_TYPE:
167       Cell::cast(this)->CellPrint(os);
168       break;
169     case PROPERTY_CELL_TYPE:
170       PropertyCell::cast(this)->PropertyCellPrint(os);
171       break;
172     case JS_ARRAY_BUFFER_TYPE:
173       JSArrayBuffer::cast(this)->JSArrayBufferPrint(os);
174       break;
175     case JS_TYPED_ARRAY_TYPE:
176       JSTypedArray::cast(this)->JSTypedArrayPrint(os);
177       break;
178     case JS_DATA_VIEW_TYPE:
179       JSDataView::cast(this)->JSDataViewPrint(os);
180       break;
181 #define MAKE_STRUCT_CASE(NAME, Name, name) \
182   case NAME##_TYPE:                        \
183     Name::cast(this)->Name##Print(os);     \
184     break;
185   STRUCT_LIST(MAKE_STRUCT_CASE)
186 #undef MAKE_STRUCT_CASE
187 
188     default:
189       os << "UNKNOWN TYPE " << map()->instance_type();
190       UNREACHABLE();
191       break;
192   }
193 }
194 
195 
ByteArrayPrint(OStream & os)196 void ByteArray::ByteArrayPrint(OStream& os) {  // NOLINT
197   os << "byte array, data starts at " << GetDataStartAddress();
198 }
199 
200 
FreeSpacePrint(OStream & os)201 void FreeSpace::FreeSpacePrint(OStream& os) {  // NOLINT
202   os << "free space, size " << Size();
203 }
204 
205 
206 #define EXTERNAL_ARRAY_PRINTER(Type, type, TYPE, ctype, size)           \
207   void External##Type##Array::External##Type##ArrayPrint(OStream& os) { \
208     os << "external " #type " array";                                   \
209   }
210 
TYPED_ARRAYS(EXTERNAL_ARRAY_PRINTER)211 TYPED_ARRAYS(EXTERNAL_ARRAY_PRINTER)
212 
213 #undef EXTERNAL_ARRAY_PRINTER
214 
215 
216 template <class Traits>
217 void FixedTypedArray<Traits>::FixedTypedArrayPrint(OStream& os) {  // NOLINT
218   os << "fixed " << Traits::Designator();
219 }
220 
221 
PrintProperties(OStream & os)222 void JSObject::PrintProperties(OStream& os) {  // NOLINT
223   if (HasFastProperties()) {
224     DescriptorArray* descs = map()->instance_descriptors();
225     for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) {
226       os << "   ";
227       descs->GetKey(i)->NamePrint(os);
228       os << ": ";
229       switch (descs->GetType(i)) {
230         case FIELD: {
231           FieldIndex index = FieldIndex::ForDescriptor(map(), i);
232           os << Brief(RawFastPropertyAt(index)) << " (field at offset "
233              << index.property_index() << ")\n";
234           break;
235         }
236         case CONSTANT:
237           os << Brief(descs->GetConstant(i)) << " (constant)\n";
238           break;
239         case CALLBACKS:
240           os << Brief(descs->GetCallbacksObject(i)) << " (callback)\n";
241           break;
242         case NORMAL:  // only in slow mode
243           UNREACHABLE();
244           break;
245       }
246     }
247   } else {
248     property_dictionary()->Print(os);
249   }
250 }
251 
252 
253 template <class T>
DoPrintElements(OStream & os,Object * object)254 static void DoPrintElements(OStream& os, Object* object) {  // NOLINT
255   T* p = T::cast(object);
256   for (int i = 0; i < p->length(); i++) {
257     os << "   " << i << ": " << p->get_scalar(i) << "\n";
258   }
259 }
260 
261 
PrintElements(OStream & os)262 void JSObject::PrintElements(OStream& os) {  // NOLINT
263   // Don't call GetElementsKind, its validation code can cause the printer to
264   // fail when debugging.
265   switch (map()->elements_kind()) {
266     case FAST_HOLEY_SMI_ELEMENTS:
267     case FAST_SMI_ELEMENTS:
268     case FAST_HOLEY_ELEMENTS:
269     case FAST_ELEMENTS: {
270       // Print in array notation for non-sparse arrays.
271       FixedArray* p = FixedArray::cast(elements());
272       for (int i = 0; i < p->length(); i++) {
273         os << "   " << i << ": " << Brief(p->get(i)) << "\n";
274       }
275       break;
276     }
277     case FAST_HOLEY_DOUBLE_ELEMENTS:
278     case FAST_DOUBLE_ELEMENTS: {
279       // Print in array notation for non-sparse arrays.
280       if (elements()->length() > 0) {
281         FixedDoubleArray* p = FixedDoubleArray::cast(elements());
282         for (int i = 0; i < p->length(); i++) {
283           os << "   " << i << ": ";
284           if (p->is_the_hole(i)) {
285             os << "<the hole>";
286           } else {
287             os << p->get_scalar(i);
288           }
289           os << "\n";
290         }
291       }
292       break;
293     }
294 
295 
296 #define PRINT_ELEMENTS(Kind, Type)         \
297   case Kind: {                             \
298     DoPrintElements<Type>(os, elements()); \
299     break;                                 \
300   }
301 
302     PRINT_ELEMENTS(EXTERNAL_UINT8_CLAMPED_ELEMENTS, ExternalUint8ClampedArray)
303     PRINT_ELEMENTS(EXTERNAL_INT8_ELEMENTS, ExternalInt8Array)
304     PRINT_ELEMENTS(EXTERNAL_UINT8_ELEMENTS,
305         ExternalUint8Array)
306     PRINT_ELEMENTS(EXTERNAL_INT16_ELEMENTS, ExternalInt16Array)
307     PRINT_ELEMENTS(EXTERNAL_UINT16_ELEMENTS,
308         ExternalUint16Array)
309     PRINT_ELEMENTS(EXTERNAL_INT32_ELEMENTS, ExternalInt32Array)
310     PRINT_ELEMENTS(EXTERNAL_UINT32_ELEMENTS,
311         ExternalUint32Array)
312     PRINT_ELEMENTS(EXTERNAL_FLOAT32_ELEMENTS, ExternalFloat32Array)
313     PRINT_ELEMENTS(EXTERNAL_FLOAT64_ELEMENTS, ExternalFloat64Array)
314 
315     PRINT_ELEMENTS(UINT8_ELEMENTS, FixedUint8Array)
316     PRINT_ELEMENTS(UINT8_CLAMPED_ELEMENTS, FixedUint8ClampedArray)
317     PRINT_ELEMENTS(INT8_ELEMENTS, FixedInt8Array)
318     PRINT_ELEMENTS(UINT16_ELEMENTS, FixedUint16Array)
319     PRINT_ELEMENTS(INT16_ELEMENTS, FixedInt16Array)
320     PRINT_ELEMENTS(UINT32_ELEMENTS, FixedUint32Array)
321     PRINT_ELEMENTS(INT32_ELEMENTS, FixedInt32Array)
322     PRINT_ELEMENTS(FLOAT32_ELEMENTS, FixedFloat32Array)
323     PRINT_ELEMENTS(FLOAT64_ELEMENTS, FixedFloat64Array)
324 
325 #undef PRINT_ELEMENTS
326 
327     case DICTIONARY_ELEMENTS:
328       elements()->Print(os);
329       break;
330     case SLOPPY_ARGUMENTS_ELEMENTS: {
331       FixedArray* p = FixedArray::cast(elements());
332       os << "   parameter map:";
333       for (int i = 2; i < p->length(); i++) {
334         os << " " << (i - 2) << ":" << Brief(p->get(i));
335       }
336       os << "\n   context: " << Brief(p->get(0))
337          << "\n   arguments: " << Brief(p->get(1)) << "\n";
338       break;
339     }
340   }
341 }
342 
343 
PrintTransitions(OStream & os)344 void JSObject::PrintTransitions(OStream& os) {  // NOLINT
345   if (!map()->HasTransitionArray()) return;
346   TransitionArray* transitions = map()->transitions();
347   for (int i = 0; i < transitions->number_of_transitions(); i++) {
348     Name* key = transitions->GetKey(i);
349     os << "   ";
350     key->NamePrint(os);
351     os << ": ";
352     if (key == GetHeap()->frozen_symbol()) {
353       os << " (transition to frozen)\n";
354     } else if (key == GetHeap()->elements_transition_symbol()) {
355       os << " (transition to "
356          << ElementsKindToString(transitions->GetTarget(i)->elements_kind())
357          << ")\n";
358     } else if (key == GetHeap()->observed_symbol()) {
359       os << " (transition to Object.observe)\n";
360     } else {
361       switch (transitions->GetTargetDetails(i).type()) {
362         case FIELD: {
363           os << " (transition to field)\n";
364           break;
365         }
366         case CONSTANT:
367           os << " (transition to constant)\n";
368           break;
369         case CALLBACKS:
370           os << " (transition to callback)\n";
371           break;
372         // Values below are never in the target descriptor array.
373         case NORMAL:
374           UNREACHABLE();
375           break;
376       }
377     }
378   }
379 }
380 
381 
JSObjectPrint(OStream & os)382 void JSObject::JSObjectPrint(OStream& os) {  // NOLINT
383   HeapObject::PrintHeader(os, "JSObject");
384   // Don't call GetElementsKind, its validation code can cause the printer to
385   // fail when debugging.
386   PrototypeIterator iter(GetIsolate(), this);
387   os << " - map = " << reinterpret_cast<void*>(map()) << " ["
388      << ElementsKindToString(this->map()->elements_kind())
389      << "]\n - prototype = " << reinterpret_cast<void*>(iter.GetCurrent())
390      << "\n {\n";
391   PrintProperties(os);
392   PrintTransitions(os);
393   PrintElements(os);
394   os << " }\n";
395 }
396 
397 
JSModulePrint(OStream & os)398 void JSModule::JSModulePrint(OStream& os) {  // NOLINT
399   HeapObject::PrintHeader(os, "JSModule");
400   os << " - map = " << reinterpret_cast<void*>(map()) << "\n"
401      << " - context = ";
402   context()->Print(os);
403   os << " - scope_info = " << Brief(scope_info())
404      << ElementsKindToString(this->map()->elements_kind()) << " {\n";
405   PrintProperties(os);
406   PrintElements(os);
407   os << " }\n";
408 }
409 
410 
TypeToString(InstanceType type)411 static const char* TypeToString(InstanceType type) {
412   switch (type) {
413 #define TYPE_TO_STRING(TYPE) case TYPE: return #TYPE;
414   INSTANCE_TYPE_LIST(TYPE_TO_STRING)
415 #undef TYPE_TO_STRING
416   }
417   UNREACHABLE();
418   return "UNKNOWN";  // Keep the compiler happy.
419 }
420 
421 
SymbolPrint(OStream & os)422 void Symbol::SymbolPrint(OStream& os) {  // NOLINT
423   HeapObject::PrintHeader(os, "Symbol");
424   os << " - hash: " << Hash();
425   os << "\n - name: " << Brief(name());
426   os << "\n - private: " << is_private();
427   os << "\n - own: " << is_own();
428   os << "\n";
429 }
430 
431 
MapPrint(OStream & os)432 void Map::MapPrint(OStream& os) {  // NOLINT
433   HeapObject::PrintHeader(os, "Map");
434   os << " - type: " << TypeToString(instance_type()) << "\n";
435   os << " - instance size: " << instance_size() << "\n";
436   os << " - inobject properties: " << inobject_properties() << "\n";
437   os << " - elements kind: " << ElementsKindToString(elements_kind());
438   os << "\n - pre-allocated property fields: "
439      << pre_allocated_property_fields() << "\n";
440   os << " - unused property fields: " << unused_property_fields() << "\n";
441   if (is_hidden_prototype()) os << " - hidden_prototype\n";
442   if (has_named_interceptor()) os << " - named_interceptor\n";
443   if (has_indexed_interceptor()) os << " - indexed_interceptor\n";
444   if (is_undetectable()) os << " - undetectable\n";
445   if (has_instance_call_handler()) os << " - instance_call_handler\n";
446   if (is_access_check_needed()) os << " - access_check_needed\n";
447   if (is_frozen()) {
448     os << " - frozen\n";
449   } else if (!is_extensible()) {
450     os << " - sealed\n";
451   }
452   os << " - back pointer: " << Brief(GetBackPointer());
453   os << "\n - instance descriptors " << (owns_descriptors() ? "(own) " : "")
454      << "#" << NumberOfOwnDescriptors() << ": "
455      << Brief(instance_descriptors());
456   if (HasTransitionArray()) {
457     os << "\n - transitions: " << Brief(transitions());
458   }
459   os << "\n - prototype: " << Brief(prototype());
460   os << "\n - constructor: " << Brief(constructor());
461   os << "\n - code cache: " << Brief(code_cache());
462   os << "\n - dependent code: " << Brief(dependent_code());
463   os << "\n";
464 }
465 
466 
CodeCachePrint(OStream & os)467 void CodeCache::CodeCachePrint(OStream& os) {  // NOLINT
468   HeapObject::PrintHeader(os, "CodeCache");
469   os << "\n - default_cache: " << Brief(default_cache());
470   os << "\n - normal_type_cache: " << Brief(normal_type_cache());
471 }
472 
473 
PolymorphicCodeCachePrint(OStream & os)474 void PolymorphicCodeCache::PolymorphicCodeCachePrint(OStream& os) {  // NOLINT
475   HeapObject::PrintHeader(os, "PolymorphicCodeCache");
476   os << "\n - cache: " << Brief(cache());
477 }
478 
479 
TypeFeedbackInfoPrint(OStream & os)480 void TypeFeedbackInfo::TypeFeedbackInfoPrint(OStream& os) {  // NOLINT
481   HeapObject::PrintHeader(os, "TypeFeedbackInfo");
482   os << " - ic_total_count: " << ic_total_count()
483      << ", ic_with_type_info_count: " << ic_with_type_info_count()
484      << ", ic_generic_count: " << ic_generic_count() << "\n";
485 }
486 
487 
AliasedArgumentsEntryPrint(OStream & os)488 void AliasedArgumentsEntry::AliasedArgumentsEntryPrint(OStream& os) {  // NOLINT
489   HeapObject::PrintHeader(os, "AliasedArgumentsEntry");
490   os << "\n - aliased_context_slot: " << aliased_context_slot();
491 }
492 
493 
FixedArrayPrint(OStream & os)494 void FixedArray::FixedArrayPrint(OStream& os) {  // NOLINT
495   HeapObject::PrintHeader(os, "FixedArray");
496   os << " - length: " << length();
497   for (int i = 0; i < length(); i++) {
498     os << "\n  [" << i << "]: " << Brief(get(i));
499   }
500   os << "\n";
501 }
502 
503 
FixedDoubleArrayPrint(OStream & os)504 void FixedDoubleArray::FixedDoubleArrayPrint(OStream& os) {  // NOLINT
505   HeapObject::PrintHeader(os, "FixedDoubleArray");
506   os << " - length: " << length();
507   for (int i = 0; i < length(); i++) {
508     os << "\n  [" << i << "]: ";
509     if (is_the_hole(i)) {
510       os << "<the hole>";
511     } else {
512       os << get_scalar(i);
513     }
514   }
515   os << "\n";
516 }
517 
518 
ConstantPoolArrayPrint(OStream & os)519 void ConstantPoolArray::ConstantPoolArrayPrint(OStream& os) {  // NOLINT
520   HeapObject::PrintHeader(os, "ConstantPoolArray");
521   os << " - length: " << length();
522   for (int i = 0; i <= last_index(INT32, SMALL_SECTION); i++) {
523     if (i < last_index(INT64, SMALL_SECTION)) {
524       os << "\n  [" << i << "]: double: " << get_int64_entry_as_double(i);
525     } else if (i <= last_index(CODE_PTR, SMALL_SECTION)) {
526       os << "\n  [" << i << "]: code target pointer: "
527          << reinterpret_cast<void*>(get_code_ptr_entry(i));
528     } else if (i <= last_index(HEAP_PTR, SMALL_SECTION)) {
529       os << "\n  [" << i << "]: heap pointer: "
530          << reinterpret_cast<void*>(get_heap_ptr_entry(i));
531     } else if (i <= last_index(INT32, SMALL_SECTION)) {
532       os << "\n  [" << i << "]: int32: " << get_int32_entry(i);
533     }
534   }
535   if (is_extended_layout()) {
536     os << "\n  Extended section:";
537     for (int i = first_extended_section_index();
538          i <= last_index(INT32, EXTENDED_SECTION); i++) {
539       if (i < last_index(INT64, EXTENDED_SECTION)) {
540         os << "\n  [" << i << "]: double: " << get_int64_entry_as_double(i);
541       } else if (i <= last_index(CODE_PTR, EXTENDED_SECTION)) {
542         os << "\n  [" << i << "]: code target pointer: "
543            << reinterpret_cast<void*>(get_code_ptr_entry(i));
544       } else if (i <= last_index(HEAP_PTR, EXTENDED_SECTION)) {
545         os << "\n  [" << i << "]: heap pointer: "
546            << reinterpret_cast<void*>(get_heap_ptr_entry(i));
547       } else if (i <= last_index(INT32, EXTENDED_SECTION)) {
548         os << "\n  [" << i << "]: int32: " << get_int32_entry(i);
549       }
550     }
551   }
552   os << "\n";
553 }
554 
555 
JSValuePrint(OStream & os)556 void JSValue::JSValuePrint(OStream& os) {  // NOLINT
557   HeapObject::PrintHeader(os, "ValueObject");
558   value()->Print(os);
559 }
560 
561 
JSMessageObjectPrint(OStream & os)562 void JSMessageObject::JSMessageObjectPrint(OStream& os) {  // NOLINT
563   HeapObject::PrintHeader(os, "JSMessageObject");
564   os << " - type: " << Brief(type());
565   os << "\n - arguments: " << Brief(arguments());
566   os << "\n - start_position: " << start_position();
567   os << "\n - end_position: " << end_position();
568   os << "\n - script: " << Brief(script());
569   os << "\n - stack_frames: " << Brief(stack_frames());
570   os << "\n";
571 }
572 
573 
StringPrint(OStream & os)574 void String::StringPrint(OStream& os) {  // NOLINT
575   if (StringShape(this).IsInternalized()) {
576     os << "#";
577   } else if (StringShape(this).IsCons()) {
578     os << "c\"";
579   } else {
580     os << "\"";
581   }
582 
583   const char truncated_epilogue[] = "...<truncated>";
584   int len = length();
585   if (!FLAG_use_verbose_printer) {
586     if (len > 100) {
587       len = 100 - sizeof(truncated_epilogue);
588     }
589   }
590   for (int i = 0; i < len; i++) {
591     os << AsUC16(Get(i));
592   }
593   if (len != length()) {
594     os << truncated_epilogue;
595   }
596 
597   if (!StringShape(this).IsInternalized()) os << "\"";
598 }
599 
600 
NamePrint(OStream & os)601 void Name::NamePrint(OStream& os) {  // NOLINT
602   if (IsString())
603     String::cast(this)->StringPrint(os);
604   else
605     os << Brief(this);
606 }
607 
608 
609 // This method is only meant to be called from gdb for debugging purposes.
610 // Since the string can also be in two-byte encoding, non-Latin1 characters
611 // will be ignored in the output.
ToAsciiArray()612 char* String::ToAsciiArray() {
613   // Static so that subsequent calls frees previously allocated space.
614   // This also means that previous results will be overwritten.
615   static char* buffer = NULL;
616   if (buffer != NULL) free(buffer);
617   buffer = new char[length()+1];
618   WriteToFlat(this, reinterpret_cast<uint8_t*>(buffer), 0, length());
619   buffer[length()] = 0;
620   return buffer;
621 }
622 
623 
624 static const char* const weekdays[] = {
625   "???", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
626 };
627 
628 
JSDatePrint(OStream & os)629 void JSDate::JSDatePrint(OStream& os) {  // NOLINT
630   HeapObject::PrintHeader(os, "JSDate");
631   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
632   os << " - value = ";
633   value()->Print(os);
634   if (!year()->IsSmi()) {
635     os << " - time = NaN\n";
636   } else {
637     // TODO(svenpanne) Add some basic formatting to our streams.
638     Vector<char> buf = Vector<char>::New(100);
639     SNPrintF(
640         buf, " - time = %s %04d/%02d/%02d %02d:%02d:%02d\n",
641         weekdays[weekday()->IsSmi() ? Smi::cast(weekday())->value() + 1 : 0],
642         year()->IsSmi() ? Smi::cast(year())->value() : -1,
643         month()->IsSmi() ? Smi::cast(month())->value() : -1,
644         day()->IsSmi() ? Smi::cast(day())->value() : -1,
645         hour()->IsSmi() ? Smi::cast(hour())->value() : -1,
646         min()->IsSmi() ? Smi::cast(min())->value() : -1,
647         sec()->IsSmi() ? Smi::cast(sec())->value() : -1);
648     os << buf.start();
649   }
650 }
651 
652 
JSProxyPrint(OStream & os)653 void JSProxy::JSProxyPrint(OStream& os) {  // NOLINT
654   HeapObject::PrintHeader(os, "JSProxy");
655   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
656   os << " - handler = ";
657   handler()->Print(os);
658   os << "\n - hash = ";
659   hash()->Print(os);
660   os << "\n";
661 }
662 
663 
JSFunctionProxyPrint(OStream & os)664 void JSFunctionProxy::JSFunctionProxyPrint(OStream& os) {  // NOLINT
665   HeapObject::PrintHeader(os, "JSFunctionProxy");
666   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
667   os << " - handler = ";
668   handler()->Print(os);
669   os << "\n - call_trap = ";
670   call_trap()->Print(os);
671   os << "\n - construct_trap = ";
672   construct_trap()->Print(os);
673   os << "\n";
674 }
675 
676 
JSSetPrint(OStream & os)677 void JSSet::JSSetPrint(OStream& os) {  // NOLINT
678   HeapObject::PrintHeader(os, "JSSet");
679   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
680   os << " - table = " << Brief(table());
681   os << "\n";
682 }
683 
684 
JSMapPrint(OStream & os)685 void JSMap::JSMapPrint(OStream& os) {  // NOLINT
686   HeapObject::PrintHeader(os, "JSMap");
687   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
688   os << " - table = " << Brief(table());
689   os << "\n";
690 }
691 
692 
693 template <class Derived, class TableType>
694 void OrderedHashTableIterator<
OrderedHashTableIteratorPrint(OStream & os)695     Derived, TableType>::OrderedHashTableIteratorPrint(OStream& os) {  // NOLINT
696   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
697   os << " - table = " << Brief(table());
698   os << "\n - index = " << Brief(index());
699   os << "\n - kind = " << Brief(kind());
700   os << "\n";
701 }
702 
703 
704 template void OrderedHashTableIterator<
705     JSSetIterator,
706     OrderedHashSet>::OrderedHashTableIteratorPrint(OStream& os);  // NOLINT
707 
708 
709 template void OrderedHashTableIterator<
710     JSMapIterator,
711     OrderedHashMap>::OrderedHashTableIteratorPrint(OStream& os);  // NOLINT
712 
713 
JSSetIteratorPrint(OStream & os)714 void JSSetIterator::JSSetIteratorPrint(OStream& os) {  // NOLINT
715   HeapObject::PrintHeader(os, "JSSetIterator");
716   OrderedHashTableIteratorPrint(os);
717 }
718 
719 
JSMapIteratorPrint(OStream & os)720 void JSMapIterator::JSMapIteratorPrint(OStream& os) {  // NOLINT
721   HeapObject::PrintHeader(os, "JSMapIterator");
722   OrderedHashTableIteratorPrint(os);
723 }
724 
725 
JSWeakMapPrint(OStream & os)726 void JSWeakMap::JSWeakMapPrint(OStream& os) {  // NOLINT
727   HeapObject::PrintHeader(os, "JSWeakMap");
728   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
729   os << " - table = " << Brief(table());
730   os << "\n";
731 }
732 
733 
JSWeakSetPrint(OStream & os)734 void JSWeakSet::JSWeakSetPrint(OStream& os) {  // NOLINT
735   HeapObject::PrintHeader(os, "JSWeakSet");
736   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
737   os << " - table = " << Brief(table());
738   os << "\n";
739 }
740 
741 
JSArrayBufferPrint(OStream & os)742 void JSArrayBuffer::JSArrayBufferPrint(OStream& os) {  // NOLINT
743   HeapObject::PrintHeader(os, "JSArrayBuffer");
744   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
745   os << " - backing_store = " << backing_store() << "\n";
746   os << " - byte_length = " << Brief(byte_length());
747   os << "\n";
748 }
749 
750 
JSTypedArrayPrint(OStream & os)751 void JSTypedArray::JSTypedArrayPrint(OStream& os) {  // NOLINT
752   HeapObject::PrintHeader(os, "JSTypedArray");
753   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
754   os << " - buffer = " << Brief(buffer());
755   os << "\n - byte_offset = " << Brief(byte_offset());
756   os << "\n - byte_length = " << Brief(byte_length());
757   os << "\n - length = " << Brief(length());
758   os << "\n";
759   PrintElements(os);
760 }
761 
762 
JSDataViewPrint(OStream & os)763 void JSDataView::JSDataViewPrint(OStream& os) {  // NOLINT
764   HeapObject::PrintHeader(os, "JSDataView");
765   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
766   os << " - buffer =" << Brief(buffer());
767   os << "\n - byte_offset = " << Brief(byte_offset());
768   os << "\n - byte_length = " << Brief(byte_length());
769   os << "\n";
770 }
771 
772 
JSFunctionPrint(OStream & os)773 void JSFunction::JSFunctionPrint(OStream& os) {  // NOLINT
774   HeapObject::PrintHeader(os, "Function");
775   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
776   os << " - initial_map = ";
777   if (has_initial_map()) os << Brief(initial_map());
778   os << "\n - shared_info = " << Brief(shared());
779   os << "\n   - name = " << Brief(shared()->name());
780   os << "\n - context = " << Brief(context());
781   if (shared()->bound()) {
782     os << "\n - bindings = " << Brief(function_bindings());
783   } else {
784     os << "\n - literals = " << Brief(literals());
785   }
786   os << "\n - code = " << Brief(code());
787   os << "\n";
788   PrintProperties(os);
789   PrintElements(os);
790   os << "\n";
791 }
792 
793 
SharedFunctionInfoPrint(OStream & os)794 void SharedFunctionInfo::SharedFunctionInfoPrint(OStream& os) {  // NOLINT
795   HeapObject::PrintHeader(os, "SharedFunctionInfo");
796   os << " - name: " << Brief(name());
797   os << "\n - expected_nof_properties: " << expected_nof_properties();
798   os << "\n - ast_node_count: " << ast_node_count();
799   os << "\n - instance class name = ";
800   instance_class_name()->Print(os);
801   os << "\n - code = " << Brief(code());
802   if (HasSourceCode()) {
803     os << "\n - source code = ";
804     String* source = String::cast(Script::cast(script())->source());
805     int start = start_position();
806     int length = end_position() - start;
807     SmartArrayPointer<char> source_string =
808         source->ToCString(DISALLOW_NULLS,
809                           FAST_STRING_TRAVERSAL,
810                           start, length, NULL);
811     os << source_string.get();
812   }
813   // Script files are often large, hard to read.
814   // os << "\n - script =";
815   // script()->Print(os);
816   os << "\n - function token position = " << function_token_position();
817   os << "\n - start position = " << start_position();
818   os << "\n - end position = " << end_position();
819   os << "\n - is expression = " << is_expression();
820   os << "\n - debug info = " << Brief(debug_info());
821   os << "\n - length = " << length();
822   os << "\n - optimized_code_map = " << Brief(optimized_code_map());
823   os << "\n - feedback_vector = ";
824   feedback_vector()->FixedArrayPrint(os);
825   os << "\n";
826 }
827 
828 
JSGlobalProxyPrint(OStream & os)829 void JSGlobalProxy::JSGlobalProxyPrint(OStream& os) {  // NOLINT
830   os << "global_proxy ";
831   JSObjectPrint(os);
832   os << "native context : " << Brief(native_context());
833   os << "\n";
834 }
835 
836 
JSGlobalObjectPrint(OStream & os)837 void JSGlobalObject::JSGlobalObjectPrint(OStream& os) {  // NOLINT
838   os << "global ";
839   JSObjectPrint(os);
840   os << "native context : " << Brief(native_context());
841   os << "\n";
842 }
843 
844 
JSBuiltinsObjectPrint(OStream & os)845 void JSBuiltinsObject::JSBuiltinsObjectPrint(OStream& os) {  // NOLINT
846   os << "builtins ";
847   JSObjectPrint(os);
848 }
849 
850 
CellPrint(OStream & os)851 void Cell::CellPrint(OStream& os) {  // NOLINT
852   HeapObject::PrintHeader(os, "Cell");
853 }
854 
855 
PropertyCellPrint(OStream & os)856 void PropertyCell::PropertyCellPrint(OStream& os) {  // NOLINT
857   HeapObject::PrintHeader(os, "PropertyCell");
858 }
859 
860 
CodePrint(OStream & os)861 void Code::CodePrint(OStream& os) {  // NOLINT
862   HeapObject::PrintHeader(os, "Code");
863 #ifdef ENABLE_DISASSEMBLER
864   if (FLAG_use_verbose_printer) {
865     Disassemble(NULL, os);
866   }
867 #endif
868 }
869 
870 
ForeignPrint(OStream & os)871 void Foreign::ForeignPrint(OStream& os) {  // NOLINT
872   os << "foreign address : " << foreign_address();
873 }
874 
875 
ExecutableAccessorInfoPrint(OStream & os)876 void ExecutableAccessorInfo::ExecutableAccessorInfoPrint(
877     OStream& os) {  // NOLINT
878   HeapObject::PrintHeader(os, "ExecutableAccessorInfo");
879   os << "\n - name: " << Brief(name());
880   os << "\n - flag: " << Brief(flag());
881   os << "\n - getter: " << Brief(getter());
882   os << "\n - setter: " << Brief(setter());
883   os << "\n - data: " << Brief(data());
884   os << "\n";
885 }
886 
887 
DeclaredAccessorInfoPrint(OStream & os)888 void DeclaredAccessorInfo::DeclaredAccessorInfoPrint(OStream& os) {  // NOLINT
889   HeapObject::PrintHeader(os, "DeclaredAccessorInfo");
890   os << "\n - name: " << Brief(name());
891   os << "\n - flag: " << Brief(flag());
892   os << "\n - descriptor: " << Brief(descriptor());
893   os << "\n";
894 }
895 
896 
DeclaredAccessorDescriptorPrint(OStream & os)897 void DeclaredAccessorDescriptor::DeclaredAccessorDescriptorPrint(
898     OStream& os) {  // NOLINT
899   HeapObject::PrintHeader(os, "DeclaredAccessorDescriptor");
900   os << "\n - internal field: " << Brief(serialized_data());
901   os << "\n";
902 }
903 
904 
BoxPrint(OStream & os)905 void Box::BoxPrint(OStream& os) {  // NOLINT
906   HeapObject::PrintHeader(os, "Box");
907   os << "\n - value: " << Brief(value());
908   os << "\n";
909 }
910 
911 
AccessorPairPrint(OStream & os)912 void AccessorPair::AccessorPairPrint(OStream& os) {  // NOLINT
913   HeapObject::PrintHeader(os, "AccessorPair");
914   os << "\n - getter: " << Brief(getter());
915   os << "\n - setter: " << Brief(setter());
916   os << "\n";
917 }
918 
919 
AccessCheckInfoPrint(OStream & os)920 void AccessCheckInfo::AccessCheckInfoPrint(OStream& os) {  // NOLINT
921   HeapObject::PrintHeader(os, "AccessCheckInfo");
922   os << "\n - named_callback: " << Brief(named_callback());
923   os << "\n - indexed_callback: " << Brief(indexed_callback());
924   os << "\n - data: " << Brief(data());
925   os << "\n";
926 }
927 
928 
InterceptorInfoPrint(OStream & os)929 void InterceptorInfo::InterceptorInfoPrint(OStream& os) {  // NOLINT
930   HeapObject::PrintHeader(os, "InterceptorInfo");
931   os << "\n - getter: " << Brief(getter());
932   os << "\n - setter: " << Brief(setter());
933   os << "\n - query: " << Brief(query());
934   os << "\n - deleter: " << Brief(deleter());
935   os << "\n - enumerator: " << Brief(enumerator());
936   os << "\n - data: " << Brief(data());
937   os << "\n";
938 }
939 
940 
CallHandlerInfoPrint(OStream & os)941 void CallHandlerInfo::CallHandlerInfoPrint(OStream& os) {  // NOLINT
942   HeapObject::PrintHeader(os, "CallHandlerInfo");
943   os << "\n - callback: " << Brief(callback());
944   os << "\n - data: " << Brief(data());
945   os << "\n";
946 }
947 
948 
FunctionTemplateInfoPrint(OStream & os)949 void FunctionTemplateInfo::FunctionTemplateInfoPrint(OStream& os) {  // NOLINT
950   HeapObject::PrintHeader(os, "FunctionTemplateInfo");
951   os << "\n - class name: " << Brief(class_name());
952   os << "\n - tag: " << Brief(tag());
953   os << "\n - property_list: " << Brief(property_list());
954   os << "\n - serial_number: " << Brief(serial_number());
955   os << "\n - call_code: " << Brief(call_code());
956   os << "\n - property_accessors: " << Brief(property_accessors());
957   os << "\n - prototype_template: " << Brief(prototype_template());
958   os << "\n - parent_template: " << Brief(parent_template());
959   os << "\n - named_property_handler: " << Brief(named_property_handler());
960   os << "\n - indexed_property_handler: " << Brief(indexed_property_handler());
961   os << "\n - instance_template: " << Brief(instance_template());
962   os << "\n - signature: " << Brief(signature());
963   os << "\n - access_check_info: " << Brief(access_check_info());
964   os << "\n - hidden_prototype: " << (hidden_prototype() ? "true" : "false");
965   os << "\n - undetectable: " << (undetectable() ? "true" : "false");
966   os << "\n - need_access_check: " << (needs_access_check() ? "true" : "false");
967   os << "\n";
968 }
969 
970 
ObjectTemplateInfoPrint(OStream & os)971 void ObjectTemplateInfo::ObjectTemplateInfoPrint(OStream& os) {  // NOLINT
972   HeapObject::PrintHeader(os, "ObjectTemplateInfo");
973   os << " - tag: " << Brief(tag());
974   os << "\n - property_list: " << Brief(property_list());
975   os << "\n - property_accessors: " << Brief(property_accessors());
976   os << "\n - constructor: " << Brief(constructor());
977   os << "\n - internal_field_count: " << Brief(internal_field_count());
978   os << "\n";
979 }
980 
981 
SignatureInfoPrint(OStream & os)982 void SignatureInfo::SignatureInfoPrint(OStream& os) {  // NOLINT
983   HeapObject::PrintHeader(os, "SignatureInfo");
984   os << "\n - receiver: " << Brief(receiver());
985   os << "\n - args: " << Brief(args());
986   os << "\n";
987 }
988 
989 
TypeSwitchInfoPrint(OStream & os)990 void TypeSwitchInfo::TypeSwitchInfoPrint(OStream& os) {  // NOLINT
991   HeapObject::PrintHeader(os, "TypeSwitchInfo");
992   os << "\n - types: " << Brief(types());
993   os << "\n";
994 }
995 
996 
AllocationSitePrint(OStream & os)997 void AllocationSite::AllocationSitePrint(OStream& os) {  // NOLINT
998   HeapObject::PrintHeader(os, "AllocationSite");
999   os << " - weak_next: " << Brief(weak_next());
1000   os << "\n - dependent code: " << Brief(dependent_code());
1001   os << "\n - nested site: " << Brief(nested_site());
1002   os << "\n - memento found count: "
1003      << Brief(Smi::FromInt(memento_found_count()));
1004   os << "\n - memento create count: "
1005      << Brief(Smi::FromInt(memento_create_count()));
1006   os << "\n - pretenure decision: "
1007      << Brief(Smi::FromInt(pretenure_decision()));
1008   os << "\n - transition_info: ";
1009   if (transition_info()->IsSmi()) {
1010     ElementsKind kind = GetElementsKind();
1011     os << "Array allocation with ElementsKind " << ElementsKindToString(kind);
1012   } else if (transition_info()->IsJSArray()) {
1013     os << "Array literal " << Brief(transition_info());
1014   } else {
1015     os << "unknown transition_info" << Brief(transition_info());
1016   }
1017   os << "\n";
1018 }
1019 
1020 
AllocationMementoPrint(OStream & os)1021 void AllocationMemento::AllocationMementoPrint(OStream& os) {  // NOLINT
1022   HeapObject::PrintHeader(os, "AllocationMemento");
1023   os << " - allocation site: ";
1024   if (IsValid()) {
1025     GetAllocationSite()->Print(os);
1026   } else {
1027     os << "<invalid>\n";
1028   }
1029 }
1030 
1031 
ScriptPrint(OStream & os)1032 void Script::ScriptPrint(OStream& os) {  // NOLINT
1033   HeapObject::PrintHeader(os, "Script");
1034   os << "\n - source: " << Brief(source());
1035   os << "\n - name: " << Brief(name());
1036   os << "\n - line_offset: " << Brief(line_offset());
1037   os << "\n - column_offset: " << Brief(column_offset());
1038   os << "\n - type: " << Brief(type());
1039   os << "\n - id: " << Brief(id());
1040   os << "\n - context data: " << Brief(context_data());
1041   os << "\n - wrapper: " << Brief(wrapper());
1042   os << "\n - compilation type: " << compilation_type();
1043   os << "\n - line ends: " << Brief(line_ends());
1044   os << "\n - eval from shared: " << Brief(eval_from_shared());
1045   os << "\n - eval from instructions offset: "
1046      << Brief(eval_from_instructions_offset());
1047   os << "\n";
1048 }
1049 
1050 
DebugInfoPrint(OStream & os)1051 void DebugInfo::DebugInfoPrint(OStream& os) {  // NOLINT
1052   HeapObject::PrintHeader(os, "DebugInfo");
1053   os << "\n - shared: " << Brief(shared());
1054   os << "\n - original_code: " << Brief(original_code());
1055   os << "\n - code: " << Brief(code());
1056   os << "\n - break_points: ";
1057   break_points()->Print(os);
1058 }
1059 
1060 
BreakPointInfoPrint(OStream & os)1061 void BreakPointInfo::BreakPointInfoPrint(OStream& os) {  // NOLINT
1062   HeapObject::PrintHeader(os, "BreakPointInfo");
1063   os << "\n - code_position: " << code_position()->value();
1064   os << "\n - source_position: " << source_position()->value();
1065   os << "\n - statement_position: " << statement_position()->value();
1066   os << "\n - break_point_objects: " << Brief(break_point_objects());
1067   os << "\n";
1068 }
1069 
1070 
PrintDescriptors(OStream & os)1071 void DescriptorArray::PrintDescriptors(OStream& os) {  // NOLINT
1072   os << "Descriptor array  " << number_of_descriptors() << "\n";
1073   for (int i = 0; i < number_of_descriptors(); i++) {
1074     Descriptor desc;
1075     Get(i, &desc);
1076     os << " " << i << ": " << desc;
1077   }
1078   os << "\n";
1079 }
1080 
1081 
PrintTransitions(OStream & os)1082 void TransitionArray::PrintTransitions(OStream& os) {  // NOLINT
1083   os << "Transition array  %d\n", number_of_transitions();
1084   for (int i = 0; i < number_of_transitions(); i++) {
1085     os << " " << i << ": ";
1086     GetKey(i)->NamePrint(os);
1087     os << ": ";
1088     switch (GetTargetDetails(i).type()) {
1089       case FIELD: {
1090         os << " (transition to field)\n";
1091         break;
1092       }
1093       case CONSTANT:
1094         os << " (transition to constant)\n";
1095         break;
1096       case CALLBACKS:
1097         os << " (transition to callback)\n";
1098         break;
1099       // Values below are never in the target descriptor array.
1100       case NORMAL:
1101         UNREACHABLE();
1102         break;
1103     }
1104   }
1105   os << "\n";
1106 }
1107 
1108 
1109 #endif  // OBJECT_PRINT
1110 
1111 
1112 } }  // namespace v8::internal
1113