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