• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #include "v8.h"
29 
30 #include "disassembler.h"
31 #include "disasm.h"
32 #include "jsregexp.h"
33 #include "objects-visiting.h"
34 
35 namespace v8 {
36 namespace internal {
37 
38 #ifdef OBJECT_PRINT
39 
40 static const char* TypeToString(InstanceType type);
41 
42 
Print(FILE * out)43 void MaybeObject::Print(FILE* out) {
44   Object* this_as_object;
45   if (ToObject(&this_as_object)) {
46     if (this_as_object->IsSmi()) {
47       Smi::cast(this_as_object)->SmiPrint(out);
48     } else {
49       HeapObject::cast(this_as_object)->HeapObjectPrint(out);
50     }
51   } else {
52     Failure::cast(this)->FailurePrint(out);
53   }
54   Flush(out);
55 }
56 
57 
PrintLn(FILE * out)58 void MaybeObject::PrintLn(FILE* out) {
59   Print(out);
60   PrintF(out, "\n");
61 }
62 
63 
PrintHeader(FILE * out,const char * id)64 void HeapObject::PrintHeader(FILE* out, const char* id) {
65   PrintF(out, "%p: [%s]\n", reinterpret_cast<void*>(this), id);
66 }
67 
68 
HeapObjectPrint(FILE * out)69 void HeapObject::HeapObjectPrint(FILE* out) {
70   InstanceType instance_type = map()->instance_type();
71 
72   HandleScope scope;
73   if (instance_type < FIRST_NONSTRING_TYPE) {
74     String::cast(this)->StringPrint(out);
75     return;
76   }
77 
78   switch (instance_type) {
79     case MAP_TYPE:
80       Map::cast(this)->MapPrint(out);
81       break;
82     case HEAP_NUMBER_TYPE:
83       HeapNumber::cast(this)->HeapNumberPrint(out);
84       break;
85     case FIXED_DOUBLE_ARRAY_TYPE:
86       FixedDoubleArray::cast(this)->FixedDoubleArrayPrint(out);
87       break;
88     case FIXED_ARRAY_TYPE:
89       FixedArray::cast(this)->FixedArrayPrint(out);
90       break;
91     case BYTE_ARRAY_TYPE:
92       ByteArray::cast(this)->ByteArrayPrint(out);
93       break;
94     case FREE_SPACE_TYPE:
95       FreeSpace::cast(this)->FreeSpacePrint(out);
96       break;
97     case EXTERNAL_PIXEL_ARRAY_TYPE:
98       ExternalPixelArray::cast(this)->ExternalPixelArrayPrint(out);
99       break;
100     case EXTERNAL_BYTE_ARRAY_TYPE:
101       ExternalByteArray::cast(this)->ExternalByteArrayPrint(out);
102       break;
103     case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
104       ExternalUnsignedByteArray::cast(this)
105           ->ExternalUnsignedByteArrayPrint(out);
106       break;
107     case EXTERNAL_SHORT_ARRAY_TYPE:
108       ExternalShortArray::cast(this)->ExternalShortArrayPrint(out);
109       break;
110     case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
111       ExternalUnsignedShortArray::cast(this)
112           ->ExternalUnsignedShortArrayPrint(out);
113       break;
114     case EXTERNAL_INT_ARRAY_TYPE:
115       ExternalIntArray::cast(this)->ExternalIntArrayPrint(out);
116       break;
117     case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
118       ExternalUnsignedIntArray::cast(this)->ExternalUnsignedIntArrayPrint(out);
119       break;
120     case EXTERNAL_FLOAT_ARRAY_TYPE:
121       ExternalFloatArray::cast(this)->ExternalFloatArrayPrint(out);
122       break;
123     case EXTERNAL_DOUBLE_ARRAY_TYPE:
124       ExternalDoubleArray::cast(this)->ExternalDoubleArrayPrint(out);
125       break;
126     case FILLER_TYPE:
127       PrintF(out, "filler");
128       break;
129     case JS_OBJECT_TYPE:  // fall through
130     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
131     case JS_ARRAY_TYPE:
132     case JS_REGEXP_TYPE:
133       JSObject::cast(this)->JSObjectPrint(out);
134       break;
135     case ODDBALL_TYPE:
136       Oddball::cast(this)->to_string()->Print(out);
137       break;
138     case JS_FUNCTION_TYPE:
139       JSFunction::cast(this)->JSFunctionPrint(out);
140       break;
141     case JS_GLOBAL_PROXY_TYPE:
142       JSGlobalProxy::cast(this)->JSGlobalProxyPrint(out);
143       break;
144     case JS_GLOBAL_OBJECT_TYPE:
145       JSGlobalObject::cast(this)->JSGlobalObjectPrint(out);
146       break;
147     case JS_BUILTINS_OBJECT_TYPE:
148       JSBuiltinsObject::cast(this)->JSBuiltinsObjectPrint(out);
149       break;
150     case JS_VALUE_TYPE:
151       PrintF(out, "Value wrapper around:");
152       JSValue::cast(this)->value()->Print(out);
153       break;
154     case JS_DATE_TYPE:
155       JSDate::cast(this)->value()->Print(out);
156       break;
157     case CODE_TYPE:
158       Code::cast(this)->CodePrint(out);
159       break;
160     case JS_PROXY_TYPE:
161       JSProxy::cast(this)->JSProxyPrint(out);
162       break;
163     case JS_FUNCTION_PROXY_TYPE:
164       JSFunctionProxy::cast(this)->JSFunctionProxyPrint(out);
165       break;
166     case JS_WEAK_MAP_TYPE:
167       JSWeakMap::cast(this)->JSWeakMapPrint(out);
168       break;
169     case FOREIGN_TYPE:
170       Foreign::cast(this)->ForeignPrint(out);
171       break;
172     case SHARED_FUNCTION_INFO_TYPE:
173       SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint(out);
174       break;
175     case JS_MESSAGE_OBJECT_TYPE:
176       JSMessageObject::cast(this)->JSMessageObjectPrint(out);
177       break;
178     case JS_GLOBAL_PROPERTY_CELL_TYPE:
179       JSGlobalPropertyCell::cast(this)->JSGlobalPropertyCellPrint(out);
180       break;
181 #define MAKE_STRUCT_CASE(NAME, Name, name) \
182   case NAME##_TYPE:                        \
183     Name::cast(this)->Name##Print(out);    \
184     break;
185   STRUCT_LIST(MAKE_STRUCT_CASE)
186 #undef MAKE_STRUCT_CASE
187 
188     default:
189       PrintF(out, "UNKNOWN TYPE %d", map()->instance_type());
190       UNREACHABLE();
191       break;
192   }
193 }
194 
195 
ByteArrayPrint(FILE * out)196 void ByteArray::ByteArrayPrint(FILE* out) {
197   PrintF(out, "byte array, data starts at %p", GetDataStartAddress());
198 }
199 
200 
FreeSpacePrint(FILE * out)201 void FreeSpace::FreeSpacePrint(FILE* out) {
202   PrintF(out, "free space, size %d", Size());
203 }
204 
205 
ExternalPixelArrayPrint(FILE * out)206 void ExternalPixelArray::ExternalPixelArrayPrint(FILE* out) {
207   PrintF(out, "external pixel array");
208 }
209 
210 
ExternalByteArrayPrint(FILE * out)211 void ExternalByteArray::ExternalByteArrayPrint(FILE* out) {
212   PrintF(out, "external byte array");
213 }
214 
215 
ExternalUnsignedByteArrayPrint(FILE * out)216 void ExternalUnsignedByteArray::ExternalUnsignedByteArrayPrint(FILE* out) {
217   PrintF(out, "external unsigned byte array");
218 }
219 
220 
ExternalShortArrayPrint(FILE * out)221 void ExternalShortArray::ExternalShortArrayPrint(FILE* out) {
222   PrintF(out, "external short array");
223 }
224 
225 
ExternalUnsignedShortArrayPrint(FILE * out)226 void ExternalUnsignedShortArray::ExternalUnsignedShortArrayPrint(FILE* out) {
227   PrintF(out, "external unsigned short array");
228 }
229 
230 
ExternalIntArrayPrint(FILE * out)231 void ExternalIntArray::ExternalIntArrayPrint(FILE* out) {
232   PrintF(out, "external int array");
233 }
234 
235 
ExternalUnsignedIntArrayPrint(FILE * out)236 void ExternalUnsignedIntArray::ExternalUnsignedIntArrayPrint(FILE* out) {
237   PrintF(out, "external unsigned int array");
238 }
239 
240 
ExternalFloatArrayPrint(FILE * out)241 void ExternalFloatArray::ExternalFloatArrayPrint(FILE* out) {
242   PrintF(out, "external float array");
243 }
244 
245 
ExternalDoubleArrayPrint(FILE * out)246 void ExternalDoubleArray::ExternalDoubleArrayPrint(FILE* out) {
247   PrintF(out, "external double array");
248 }
249 
250 
PrintProperties(FILE * out)251 void JSObject::PrintProperties(FILE* out) {
252   if (HasFastProperties()) {
253     DescriptorArray* descs = map()->instance_descriptors();
254     for (int i = 0; i < descs->number_of_descriptors(); i++) {
255       PrintF(out, "   ");
256       descs->GetKey(i)->StringPrint(out);
257       PrintF(out, ": ");
258       switch (descs->GetType(i)) {
259         case FIELD: {
260           int index = descs->GetFieldIndex(i);
261           FastPropertyAt(index)->ShortPrint(out);
262           PrintF(out, " (field at offset %d)\n", index);
263           break;
264         }
265         case CONSTANT_FUNCTION:
266           descs->GetConstantFunction(i)->ShortPrint(out);
267           PrintF(out, " (constant function)\n");
268           break;
269         case CALLBACKS:
270           descs->GetCallbacksObject(i)->ShortPrint(out);
271           PrintF(out, " (callback)\n");
272           break;
273         case ELEMENTS_TRANSITION: {
274           PrintF(out, "(elements transition to ");
275           Object* descriptor_contents = descs->GetValue(i);
276           if (descriptor_contents->IsMap()) {
277             Map* map = Map::cast(descriptor_contents);
278             PrintElementsKind(out, map->elements_kind());
279           } else {
280             FixedArray* map_array = FixedArray::cast(descriptor_contents);
281             for (int i = 0; i < map_array->length(); ++i) {
282               Map* map = Map::cast(map_array->get(i));
283               if (i != 0) {
284                 PrintF(out, ", ");
285               }
286               PrintElementsKind(out, map->elements_kind());
287             }
288           }
289           PrintF(out, ")\n");
290           break;
291         }
292         case MAP_TRANSITION:
293           PrintF(out, "(map transition)\n");
294           break;
295         case CONSTANT_TRANSITION:
296           PrintF(out, "(constant transition)\n");
297           break;
298         case NULL_DESCRIPTOR:
299           PrintF(out, "(null descriptor)\n");
300           break;
301         case NORMAL:  // only in slow mode
302         case HANDLER:  // only in lookup results, not in descriptors
303         case INTERCEPTOR:  // only in lookup results, not in descriptors
304           UNREACHABLE();
305           break;
306       }
307     }
308   } else {
309     property_dictionary()->Print(out);
310   }
311 }
312 
313 
PrintElements(FILE * out)314 void JSObject::PrintElements(FILE* out) {
315   // Don't call GetElementsKind, its validation code can cause the printer to
316   // fail when debugging.
317   switch (map()->elements_kind()) {
318     case FAST_SMI_ONLY_ELEMENTS:
319     case FAST_ELEMENTS: {
320       // Print in array notation for non-sparse arrays.
321       FixedArray* p = FixedArray::cast(elements());
322       for (int i = 0; i < p->length(); i++) {
323         PrintF(out, "   %d: ", i);
324         p->get(i)->ShortPrint(out);
325         PrintF(out, "\n");
326       }
327       break;
328     }
329     case FAST_DOUBLE_ELEMENTS: {
330       // Print in array notation for non-sparse arrays.
331       if (elements()->length() > 0) {
332         FixedDoubleArray* p = FixedDoubleArray::cast(elements());
333         for (int i = 0; i < p->length(); i++) {
334           if (p->is_the_hole(i)) {
335             PrintF(out, "   %d: <the hole>", i);
336           } else {
337             PrintF(out, "   %d: %g", i, p->get_scalar(i));
338           }
339           PrintF(out, "\n");
340         }
341       }
342       break;
343     }
344     case EXTERNAL_PIXEL_ELEMENTS: {
345       ExternalPixelArray* p = ExternalPixelArray::cast(elements());
346       for (int i = 0; i < p->length(); i++) {
347         PrintF(out, "   %d: %d\n", i, p->get_scalar(i));
348       }
349       break;
350     }
351     case EXTERNAL_BYTE_ELEMENTS: {
352       ExternalByteArray* p = ExternalByteArray::cast(elements());
353       for (int i = 0; i < p->length(); i++) {
354         PrintF(out, "   %d: %d\n", i, static_cast<int>(p->get_scalar(i)));
355       }
356       break;
357     }
358     case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: {
359       ExternalUnsignedByteArray* p =
360           ExternalUnsignedByteArray::cast(elements());
361       for (int i = 0; i < p->length(); i++) {
362         PrintF(out, "   %d: %d\n", i, static_cast<int>(p->get_scalar(i)));
363       }
364       break;
365     }
366     case EXTERNAL_SHORT_ELEMENTS: {
367       ExternalShortArray* p = ExternalShortArray::cast(elements());
368       for (int i = 0; i < p->length(); i++) {
369         PrintF(out, "   %d: %d\n", i, static_cast<int>(p->get_scalar(i)));
370       }
371       break;
372     }
373     case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: {
374       ExternalUnsignedShortArray* p =
375           ExternalUnsignedShortArray::cast(elements());
376       for (int i = 0; i < p->length(); i++) {
377         PrintF(out, "   %d: %d\n", i, static_cast<int>(p->get_scalar(i)));
378       }
379       break;
380     }
381     case EXTERNAL_INT_ELEMENTS: {
382       ExternalIntArray* p = ExternalIntArray::cast(elements());
383       for (int i = 0; i < p->length(); i++) {
384         PrintF(out, "   %d: %d\n", i, static_cast<int>(p->get_scalar(i)));
385       }
386       break;
387     }
388     case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
389       ExternalUnsignedIntArray* p =
390           ExternalUnsignedIntArray::cast(elements());
391       for (int i = 0; i < p->length(); i++) {
392         PrintF(out, "   %d: %d\n", i, static_cast<int>(p->get_scalar(i)));
393       }
394       break;
395     }
396     case EXTERNAL_FLOAT_ELEMENTS: {
397       ExternalFloatArray* p = ExternalFloatArray::cast(elements());
398       for (int i = 0; i < p->length(); i++) {
399         PrintF(out, "   %d: %f\n", i, p->get_scalar(i));
400       }
401       break;
402     }
403     case EXTERNAL_DOUBLE_ELEMENTS: {
404       ExternalDoubleArray* p = ExternalDoubleArray::cast(elements());
405       for (int i = 0; i < p->length(); i++) {
406         PrintF(out, "  %d: %f\n", i, p->get_scalar(i));
407       }
408       break;
409     }
410     case DICTIONARY_ELEMENTS:
411       elements()->Print(out);
412       break;
413     case NON_STRICT_ARGUMENTS_ELEMENTS: {
414       FixedArray* p = FixedArray::cast(elements());
415       for (int i = 2; i < p->length(); i++) {
416         PrintF(out, "   %d: ", i);
417         p->get(i)->ShortPrint(out);
418         PrintF(out, "\n");
419       }
420       break;
421     }
422   }
423 }
424 
425 
JSObjectPrint(FILE * out)426 void JSObject::JSObjectPrint(FILE* out) {
427   PrintF(out, "%p: [JSObject]\n", reinterpret_cast<void*>(this));
428   PrintF(out, " - map = %p [", reinterpret_cast<void*>(map()));
429   // Don't call GetElementsKind, its validation code can cause the printer to
430   // fail when debugging.
431   PrintElementsKind(out, this->map()->elements_kind());
432   PrintF(out,
433          "]\n - prototype = %p\n",
434          reinterpret_cast<void*>(GetPrototype()));
435   PrintF(out, " {\n");
436   PrintProperties(out);
437   PrintElements(out);
438   PrintF(out, " }\n");
439 }
440 
441 
TypeToString(InstanceType type)442 static const char* TypeToString(InstanceType type) {
443   switch (type) {
444     case INVALID_TYPE: return "INVALID";
445     case MAP_TYPE: return "MAP";
446     case HEAP_NUMBER_TYPE: return "HEAP_NUMBER";
447     case SYMBOL_TYPE: return "SYMBOL";
448     case ASCII_SYMBOL_TYPE: return "ASCII_SYMBOL";
449     case CONS_SYMBOL_TYPE: return "CONS_SYMBOL";
450     case CONS_ASCII_SYMBOL_TYPE: return "CONS_ASCII_SYMBOL";
451     case EXTERNAL_ASCII_SYMBOL_TYPE:
452     case EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE:
453     case EXTERNAL_SYMBOL_TYPE: return "EXTERNAL_SYMBOL";
454     case SHORT_EXTERNAL_ASCII_SYMBOL_TYPE:
455     case SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE:
456     case SHORT_EXTERNAL_SYMBOL_TYPE: return "SHORT_EXTERNAL_SYMBOL";
457     case ASCII_STRING_TYPE: return "ASCII_STRING";
458     case STRING_TYPE: return "TWO_BYTE_STRING";
459     case CONS_STRING_TYPE:
460     case CONS_ASCII_STRING_TYPE: return "CONS_STRING";
461     case EXTERNAL_ASCII_STRING_TYPE:
462     case EXTERNAL_STRING_WITH_ASCII_DATA_TYPE:
463     case EXTERNAL_STRING_TYPE: return "EXTERNAL_STRING";
464     case SHORT_EXTERNAL_ASCII_STRING_TYPE:
465     case SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE:
466     case SHORT_EXTERNAL_STRING_TYPE: return "SHORT_EXTERNAL_STRING";
467     case FIXED_ARRAY_TYPE: return "FIXED_ARRAY";
468     case BYTE_ARRAY_TYPE: return "BYTE_ARRAY";
469     case FREE_SPACE_TYPE: return "FREE_SPACE";
470     case EXTERNAL_PIXEL_ARRAY_TYPE: return "EXTERNAL_PIXEL_ARRAY";
471     case EXTERNAL_BYTE_ARRAY_TYPE: return "EXTERNAL_BYTE_ARRAY";
472     case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
473       return "EXTERNAL_UNSIGNED_BYTE_ARRAY";
474     case EXTERNAL_SHORT_ARRAY_TYPE: return "EXTERNAL_SHORT_ARRAY";
475     case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
476       return "EXTERNAL_UNSIGNED_SHORT_ARRAY";
477     case EXTERNAL_INT_ARRAY_TYPE: return "EXTERNAL_INT_ARRAY";
478     case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
479       return "EXTERNAL_UNSIGNED_INT_ARRAY";
480     case EXTERNAL_FLOAT_ARRAY_TYPE: return "EXTERNAL_FLOAT_ARRAY";
481     case EXTERNAL_DOUBLE_ARRAY_TYPE: return "EXTERNAL_DOUBLE_ARRAY";
482     case FILLER_TYPE: return "FILLER";
483     case JS_OBJECT_TYPE: return "JS_OBJECT";
484     case JS_CONTEXT_EXTENSION_OBJECT_TYPE: return "JS_CONTEXT_EXTENSION_OBJECT";
485     case ODDBALL_TYPE: return "ODDBALL";
486     case JS_GLOBAL_PROPERTY_CELL_TYPE: return "JS_GLOBAL_PROPERTY_CELL";
487     case SHARED_FUNCTION_INFO_TYPE: return "SHARED_FUNCTION_INFO";
488     case JS_FUNCTION_TYPE: return "JS_FUNCTION";
489     case CODE_TYPE: return "CODE";
490     case JS_ARRAY_TYPE: return "JS_ARRAY";
491     case JS_PROXY_TYPE: return "JS_PROXY";
492     case JS_WEAK_MAP_TYPE: return "JS_WEAK_MAP";
493     case JS_REGEXP_TYPE: return "JS_REGEXP";
494     case JS_VALUE_TYPE: return "JS_VALUE";
495     case JS_GLOBAL_OBJECT_TYPE: return "JS_GLOBAL_OBJECT";
496     case JS_BUILTINS_OBJECT_TYPE: return "JS_BUILTINS_OBJECT";
497     case JS_GLOBAL_PROXY_TYPE: return "JS_GLOBAL_PROXY";
498     case FOREIGN_TYPE: return "FOREIGN";
499     case JS_MESSAGE_OBJECT_TYPE: return "JS_MESSAGE_OBJECT_TYPE";
500 #define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return #NAME;
501   STRUCT_LIST(MAKE_STRUCT_CASE)
502 #undef MAKE_STRUCT_CASE
503     default: return "UNKNOWN";
504   }
505 }
506 
507 
MapPrint(FILE * out)508 void Map::MapPrint(FILE* out) {
509   HeapObject::PrintHeader(out, "Map");
510   PrintF(out, " - type: %s\n", TypeToString(instance_type()));
511   PrintF(out, " - instance size: %d\n", instance_size());
512   PrintF(out, " - inobject properties: %d\n", inobject_properties());
513   PrintF(out, " - elements kind: ");
514   PrintElementsKind(out, elements_kind());
515   PrintF(out, "\n - pre-allocated property fields: %d\n",
516       pre_allocated_property_fields());
517   PrintF(out, " - unused property fields: %d\n", unused_property_fields());
518   if (is_hidden_prototype()) {
519     PrintF(out, " - hidden_prototype\n");
520   }
521   if (has_named_interceptor()) {
522     PrintF(out, " - named_interceptor\n");
523   }
524   if (has_indexed_interceptor()) {
525     PrintF(out, " - indexed_interceptor\n");
526   }
527   if (is_undetectable()) {
528     PrintF(out, " - undetectable\n");
529   }
530   if (has_instance_call_handler()) {
531     PrintF(out, " - instance_call_handler\n");
532   }
533   if (is_access_check_needed()) {
534     PrintF(out, " - access_check_needed\n");
535   }
536   PrintF(out, " - instance descriptors: ");
537   instance_descriptors()->ShortPrint(out);
538   PrintF(out, "\n - prototype: ");
539   prototype()->ShortPrint(out);
540   PrintF(out, "\n - constructor: ");
541   constructor()->ShortPrint(out);
542   PrintF(out, "\n");
543 }
544 
545 
CodeCachePrint(FILE * out)546 void CodeCache::CodeCachePrint(FILE* out) {
547   HeapObject::PrintHeader(out, "CodeCache");
548   PrintF(out, "\n - default_cache: ");
549   default_cache()->ShortPrint(out);
550   PrintF(out, "\n - normal_type_cache: ");
551   normal_type_cache()->ShortPrint(out);
552 }
553 
554 
PolymorphicCodeCachePrint(FILE * out)555 void PolymorphicCodeCache::PolymorphicCodeCachePrint(FILE* out) {
556   HeapObject::PrintHeader(out, "PolymorphicCodeCache");
557   PrintF(out, "\n - cache: ");
558   cache()->ShortPrint(out);
559 }
560 
561 
TypeFeedbackInfoPrint(FILE * out)562 void TypeFeedbackInfo::TypeFeedbackInfoPrint(FILE* out) {
563   HeapObject::PrintHeader(out, "TypeFeedbackInfo");
564   PrintF(out, "\n - ic_total_count: %d, ic_with_type_info_count: %d",
565          ic_total_count(), ic_with_type_info_count());
566   PrintF(out, "\n - type_feedback_cells: ");
567   type_feedback_cells()->FixedArrayPrint(out);
568 }
569 
570 
AliasedArgumentsEntryPrint(FILE * out)571 void AliasedArgumentsEntry::AliasedArgumentsEntryPrint(FILE* out) {
572   HeapObject::PrintHeader(out, "AliasedArgumentsEntry");
573   PrintF(out, "\n - aliased_context_slot: %d", aliased_context_slot());
574 }
575 
576 
FixedArrayPrint(FILE * out)577 void FixedArray::FixedArrayPrint(FILE* out) {
578   HeapObject::PrintHeader(out, "FixedArray");
579   PrintF(out, " - length: %d", length());
580   for (int i = 0; i < length(); i++) {
581     PrintF(out, "\n  [%d]: ", i);
582     get(i)->ShortPrint(out);
583   }
584   PrintF(out, "\n");
585 }
586 
587 
FixedDoubleArrayPrint(FILE * out)588 void FixedDoubleArray::FixedDoubleArrayPrint(FILE* out) {
589   HeapObject::PrintHeader(out, "FixedDoubleArray");
590   PrintF(out, " - length: %d", length());
591   for (int i = 0; i < length(); i++) {
592     if (is_the_hole(i)) {
593       PrintF(out, "\n  [%d]: <the hole>", i);
594     } else {
595       PrintF(out, "\n  [%d]: %g", i, get_scalar(i));
596     }
597   }
598   PrintF(out, "\n");
599 }
600 
601 
JSValuePrint(FILE * out)602 void JSValue::JSValuePrint(FILE* out) {
603   HeapObject::PrintHeader(out, "ValueObject");
604   value()->Print(out);
605 }
606 
607 
JSMessageObjectPrint(FILE * out)608 void JSMessageObject::JSMessageObjectPrint(FILE* out) {
609   HeapObject::PrintHeader(out, "JSMessageObject");
610   PrintF(out, " - type: ");
611   type()->ShortPrint(out);
612   PrintF(out, "\n - arguments: ");
613   arguments()->ShortPrint(out);
614   PrintF(out, "\n - start_position: %d", start_position());
615   PrintF(out, "\n - end_position: %d", end_position());
616   PrintF(out, "\n - script: ");
617   script()->ShortPrint(out);
618   PrintF(out, "\n - stack_trace: ");
619   stack_trace()->ShortPrint(out);
620   PrintF(out, "\n - stack_frames: ");
621   stack_frames()->ShortPrint(out);
622   PrintF(out, "\n");
623 }
624 
625 
StringPrint(FILE * out)626 void String::StringPrint(FILE* out) {
627   if (StringShape(this).IsSymbol()) {
628     PrintF(out, "#");
629   } else if (StringShape(this).IsCons()) {
630     PrintF(out, "c\"");
631   } else {
632     PrintF(out, "\"");
633   }
634 
635   const char truncated_epilogue[] = "...<truncated>";
636   int len = length();
637   if (!FLAG_use_verbose_printer) {
638     if (len > 100) {
639       len = 100 - sizeof(truncated_epilogue);
640     }
641   }
642   for (int i = 0; i < len; i++) {
643     PrintF(out, "%c", Get(i));
644   }
645   if (len != length()) {
646     PrintF(out, "%s", truncated_epilogue);
647   }
648 
649   if (!StringShape(this).IsSymbol()) PrintF(out, "\"");
650 }
651 
652 
653 // This method is only meant to be called from gdb for debugging purposes.
654 // Since the string can also be in two-byte encoding, non-ASCII characters
655 // will be ignored in the output.
ToAsciiArray()656 char* String::ToAsciiArray() {
657   // Static so that subsequent calls frees previously allocated space.
658   // This also means that previous results will be overwritten.
659   static char* buffer = NULL;
660   if (buffer != NULL) free(buffer);
661   buffer = new char[length()+1];
662   WriteToFlat(this, buffer, 0, length());
663   buffer[length()] = 0;
664   return buffer;
665 }
666 
667 
668 static const char* const weekdays[] = {
669   "???", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
670 };
671 
JSDatePrint(FILE * out)672 void JSDate::JSDatePrint(FILE* out) {
673   HeapObject::PrintHeader(out, "JSDate");
674   PrintF(out, " - map = 0x%p\n", reinterpret_cast<void*>(map()));
675   PrintF(out, " - value = ");
676   value()->Print(out);
677   if (!year()->IsSmi()) {
678     PrintF(out, " - time = NaN\n");
679   } else {
680     PrintF(out, " - time = %s %04d/%02d/%02d %02d:%02d:%02d\n",
681            weekdays[weekday()->IsSmi() ? Smi::cast(weekday())->value() + 1 : 0],
682            year()->IsSmi() ? Smi::cast(year())->value() : -1,
683            month()->IsSmi() ? Smi::cast(month())->value() : -1,
684            day()->IsSmi() ? Smi::cast(day())->value() : -1,
685            hour()->IsSmi() ? Smi::cast(hour())->value() : -1,
686            min()->IsSmi() ? Smi::cast(min())->value() : -1,
687            sec()->IsSmi() ? Smi::cast(sec())->value() : -1);
688   }
689 }
690 
691 
JSProxyPrint(FILE * out)692 void JSProxy::JSProxyPrint(FILE* out) {
693   HeapObject::PrintHeader(out, "JSProxy");
694   PrintF(out, " - map = 0x%p\n", reinterpret_cast<void*>(map()));
695   PrintF(out, " - handler = ");
696   handler()->Print(out);
697   PrintF(out, " - hash = ");
698   hash()->Print(out);
699   PrintF(out, "\n");
700 }
701 
702 
JSFunctionProxyPrint(FILE * out)703 void JSFunctionProxy::JSFunctionProxyPrint(FILE* out) {
704   HeapObject::PrintHeader(out, "JSFunctionProxy");
705   PrintF(out, " - map = 0x%p\n", reinterpret_cast<void*>(map()));
706   PrintF(out, " - handler = ");
707   handler()->Print(out);
708   PrintF(out, " - call_trap = ");
709   call_trap()->Print(out);
710   PrintF(out, " - construct_trap = ");
711   construct_trap()->Print(out);
712   PrintF(out, "\n");
713 }
714 
715 
JSWeakMapPrint(FILE * out)716 void JSWeakMap::JSWeakMapPrint(FILE* out) {
717   HeapObject::PrintHeader(out, "JSWeakMap");
718   PrintF(out, " - map = 0x%p\n", reinterpret_cast<void*>(map()));
719   PrintF(out, " - table = ");
720   table()->ShortPrint(out);
721   PrintF(out, "\n");
722 }
723 
724 
JSFunctionPrint(FILE * out)725 void JSFunction::JSFunctionPrint(FILE* out) {
726   HeapObject::PrintHeader(out, "Function");
727   PrintF(out, " - map = 0x%p\n", reinterpret_cast<void*>(map()));
728   PrintF(out, " - initial_map = ");
729   if (has_initial_map()) {
730     initial_map()->ShortPrint(out);
731   }
732   PrintF(out, "\n - shared_info = ");
733   shared()->ShortPrint(out);
734   PrintF(out, "\n   - name = ");
735   shared()->name()->Print(out);
736   PrintF(out, "\n - context = ");
737   unchecked_context()->ShortPrint(out);
738   PrintF(out, "\n - code = ");
739   code()->ShortPrint(out);
740   PrintF(out, "\n");
741 
742   PrintProperties(out);
743   PrintElements(out);
744 
745   PrintF(out, "\n");
746 }
747 
748 
SharedFunctionInfoPrint(FILE * out)749 void SharedFunctionInfo::SharedFunctionInfoPrint(FILE* out) {
750   HeapObject::PrintHeader(out, "SharedFunctionInfo");
751   PrintF(out, " - name: ");
752   name()->ShortPrint(out);
753   PrintF(out, "\n - expected_nof_properties: %d", expected_nof_properties());
754   PrintF(out, "\n - instance class name = ");
755   instance_class_name()->Print(out);
756   PrintF(out, "\n - code = ");
757   code()->ShortPrint(out);
758   PrintF(out, "\n - source code = ");
759   GetSourceCode()->ShortPrint(out);
760   // Script files are often large, hard to read.
761   // PrintF(out, "\n - script =");
762   // script()->Print(out);
763   PrintF(out, "\n - function token position = %d", function_token_position());
764   PrintF(out, "\n - start position = %d", start_position());
765   PrintF(out, "\n - end position = %d", end_position());
766   PrintF(out, "\n - is expression = %d", is_expression());
767   PrintF(out, "\n - debug info = ");
768   debug_info()->ShortPrint(out);
769   PrintF(out, "\n - length = %d", length());
770   PrintF(out, "\n - has_only_simple_this_property_assignments = %d",
771          has_only_simple_this_property_assignments());
772   PrintF(out, "\n - this_property_assignments = ");
773   this_property_assignments()->ShortPrint(out);
774   PrintF(out, "\n");
775 }
776 
777 
JSGlobalProxyPrint(FILE * out)778 void JSGlobalProxy::JSGlobalProxyPrint(FILE* out) {
779   PrintF(out, "global_proxy");
780   JSObjectPrint(out);
781   PrintF(out, "context : ");
782   context()->ShortPrint(out);
783   PrintF(out, "\n");
784 }
785 
786 
JSGlobalObjectPrint(FILE * out)787 void JSGlobalObject::JSGlobalObjectPrint(FILE* out) {
788   PrintF(out, "global ");
789   JSObjectPrint(out);
790   PrintF(out, "global context : ");
791   global_context()->ShortPrint(out);
792   PrintF(out, "\n");
793 }
794 
795 
JSBuiltinsObjectPrint(FILE * out)796 void JSBuiltinsObject::JSBuiltinsObjectPrint(FILE* out) {
797   PrintF(out, "builtins ");
798   JSObjectPrint(out);
799 }
800 
801 
JSGlobalPropertyCellPrint(FILE * out)802 void JSGlobalPropertyCell::JSGlobalPropertyCellPrint(FILE* out) {
803   HeapObject::PrintHeader(out, "JSGlobalPropertyCell");
804 }
805 
806 
CodePrint(FILE * out)807 void Code::CodePrint(FILE* out) {
808   HeapObject::PrintHeader(out, "Code");
809 #ifdef ENABLE_DISASSEMBLER
810   if (FLAG_use_verbose_printer) {
811     Disassemble(NULL, out);
812   }
813 #endif
814 }
815 
816 
ForeignPrint(FILE * out)817 void Foreign::ForeignPrint(FILE* out) {
818   PrintF(out, "foreign address : %p", foreign_address());
819 }
820 
821 
AccessorInfoPrint(FILE * out)822 void AccessorInfo::AccessorInfoPrint(FILE* out) {
823   HeapObject::PrintHeader(out, "AccessorInfo");
824   PrintF(out, "\n - getter: ");
825   getter()->ShortPrint(out);
826   PrintF(out, "\n - setter: ");
827   setter()->ShortPrint(out);
828   PrintF(out, "\n - name: ");
829   name()->ShortPrint(out);
830   PrintF(out, "\n - data: ");
831   data()->ShortPrint(out);
832   PrintF(out, "\n - flag: ");
833   flag()->ShortPrint(out);
834 }
835 
836 
AccessorPairPrint(FILE * out)837 void AccessorPair::AccessorPairPrint(FILE* out) {
838   HeapObject::PrintHeader(out, "AccessorPair");
839   PrintF(out, "\n - getter: ");
840   getter()->ShortPrint(out);
841   PrintF(out, "\n - setter: ");
842   setter()->ShortPrint(out);
843 }
844 
845 
AccessCheckInfoPrint(FILE * out)846 void AccessCheckInfo::AccessCheckInfoPrint(FILE* out) {
847   HeapObject::PrintHeader(out, "AccessCheckInfo");
848   PrintF(out, "\n - named_callback: ");
849   named_callback()->ShortPrint(out);
850   PrintF(out, "\n - indexed_callback: ");
851   indexed_callback()->ShortPrint(out);
852   PrintF(out, "\n - data: ");
853   data()->ShortPrint(out);
854 }
855 
856 
InterceptorInfoPrint(FILE * out)857 void InterceptorInfo::InterceptorInfoPrint(FILE* out) {
858   HeapObject::PrintHeader(out, "InterceptorInfo");
859   PrintF(out, "\n - getter: ");
860   getter()->ShortPrint(out);
861   PrintF(out, "\n - setter: ");
862   setter()->ShortPrint(out);
863   PrintF(out, "\n - query: ");
864   query()->ShortPrint(out);
865   PrintF(out, "\n - deleter: ");
866   deleter()->ShortPrint(out);
867   PrintF(out, "\n - enumerator: ");
868   enumerator()->ShortPrint(out);
869   PrintF(out, "\n - data: ");
870   data()->ShortPrint(out);
871 }
872 
873 
CallHandlerInfoPrint(FILE * out)874 void CallHandlerInfo::CallHandlerInfoPrint(FILE* out) {
875   HeapObject::PrintHeader(out, "CallHandlerInfo");
876   PrintF(out, "\n - callback: ");
877   callback()->ShortPrint(out);
878   PrintF(out, "\n - data: ");
879   data()->ShortPrint(out);
880   PrintF(out, "\n - call_stub_cache: ");
881 }
882 
883 
FunctionTemplateInfoPrint(FILE * out)884 void FunctionTemplateInfo::FunctionTemplateInfoPrint(FILE* out) {
885   HeapObject::PrintHeader(out, "FunctionTemplateInfo");
886   PrintF(out, "\n - class name: ");
887   class_name()->ShortPrint(out);
888   PrintF(out, "\n - tag: ");
889   tag()->ShortPrint(out);
890   PrintF(out, "\n - property_list: ");
891   property_list()->ShortPrint(out);
892   PrintF(out, "\n - serial_number: ");
893   serial_number()->ShortPrint(out);
894   PrintF(out, "\n - call_code: ");
895   call_code()->ShortPrint(out);
896   PrintF(out, "\n - property_accessors: ");
897   property_accessors()->ShortPrint(out);
898   PrintF(out, "\n - prototype_template: ");
899   prototype_template()->ShortPrint(out);
900   PrintF(out, "\n - parent_template: ");
901   parent_template()->ShortPrint(out);
902   PrintF(out, "\n - named_property_handler: ");
903   named_property_handler()->ShortPrint(out);
904   PrintF(out, "\n - indexed_property_handler: ");
905   indexed_property_handler()->ShortPrint(out);
906   PrintF(out, "\n - instance_template: ");
907   instance_template()->ShortPrint(out);
908   PrintF(out, "\n - signature: ");
909   signature()->ShortPrint(out);
910   PrintF(out, "\n - access_check_info: ");
911   access_check_info()->ShortPrint(out);
912   PrintF(out, "\n - hidden_prototype: %s",
913          hidden_prototype() ? "true" : "false");
914   PrintF(out, "\n - undetectable: %s", undetectable() ? "true" : "false");
915   PrintF(out, "\n - need_access_check: %s",
916          needs_access_check() ? "true" : "false");
917 }
918 
919 
ObjectTemplateInfoPrint(FILE * out)920 void ObjectTemplateInfo::ObjectTemplateInfoPrint(FILE* out) {
921   HeapObject::PrintHeader(out, "ObjectTemplateInfo");
922   PrintF(out, " - tag: ");
923   tag()->ShortPrint(out);
924   PrintF(out, "\n - property_list: ");
925   property_list()->ShortPrint(out);
926   PrintF(out, "\n - constructor: ");
927   constructor()->ShortPrint(out);
928   PrintF(out, "\n - internal_field_count: ");
929   internal_field_count()->ShortPrint(out);
930   PrintF(out, "\n");
931 }
932 
933 
SignatureInfoPrint(FILE * out)934 void SignatureInfo::SignatureInfoPrint(FILE* out) {
935   HeapObject::PrintHeader(out, "SignatureInfo");
936   PrintF(out, "\n - receiver: ");
937   receiver()->ShortPrint(out);
938   PrintF(out, "\n - args: ");
939   args()->ShortPrint(out);
940 }
941 
942 
TypeSwitchInfoPrint(FILE * out)943 void TypeSwitchInfo::TypeSwitchInfoPrint(FILE* out) {
944   HeapObject::PrintHeader(out, "TypeSwitchInfo");
945   PrintF(out, "\n - types: ");
946   types()->ShortPrint(out);
947 }
948 
949 
ScriptPrint(FILE * out)950 void Script::ScriptPrint(FILE* out) {
951   HeapObject::PrintHeader(out, "Script");
952   PrintF(out, "\n - source: ");
953   source()->ShortPrint(out);
954   PrintF(out, "\n - name: ");
955   name()->ShortPrint(out);
956   PrintF(out, "\n - line_offset: ");
957   line_offset()->ShortPrint(out);
958   PrintF(out, "\n - column_offset: ");
959   column_offset()->ShortPrint(out);
960   PrintF(out, "\n - type: ");
961   type()->ShortPrint(out);
962   PrintF(out, "\n - id: ");
963   id()->ShortPrint(out);
964   PrintF(out, "\n - data: ");
965   data()->ShortPrint(out);
966   PrintF(out, "\n - context data: ");
967   context_data()->ShortPrint(out);
968   PrintF(out, "\n - wrapper: ");
969   wrapper()->ShortPrint(out);
970   PrintF(out, "\n - compilation type: ");
971   compilation_type()->ShortPrint(out);
972   PrintF(out, "\n - line ends: ");
973   line_ends()->ShortPrint(out);
974   PrintF(out, "\n - eval from shared: ");
975   eval_from_shared()->ShortPrint(out);
976   PrintF(out, "\n - eval from instructions offset: ");
977   eval_from_instructions_offset()->ShortPrint(out);
978   PrintF(out, "\n");
979 }
980 
981 
982 #ifdef ENABLE_DEBUGGER_SUPPORT
DebugInfoPrint(FILE * out)983 void DebugInfo::DebugInfoPrint(FILE* out) {
984   HeapObject::PrintHeader(out, "DebugInfo");
985   PrintF(out, "\n - shared: ");
986   shared()->ShortPrint(out);
987   PrintF(out, "\n - original_code: ");
988   original_code()->ShortPrint(out);
989   PrintF(out, "\n - code: ");
990   code()->ShortPrint(out);
991   PrintF(out, "\n - break_points: ");
992   break_points()->Print(out);
993 }
994 
995 
BreakPointInfoPrint(FILE * out)996 void BreakPointInfo::BreakPointInfoPrint(FILE* out) {
997   HeapObject::PrintHeader(out, "BreakPointInfo");
998   PrintF(out, "\n - code_position: %d", code_position()->value());
999   PrintF(out, "\n - source_position: %d", source_position()->value());
1000   PrintF(out, "\n - statement_position: %d", statement_position()->value());
1001   PrintF(out, "\n - break_point_objects: ");
1002   break_point_objects()->ShortPrint(out);
1003 }
1004 #endif  // ENABLE_DEBUGGER_SUPPORT
1005 
1006 
PrintDescriptors(FILE * out)1007 void DescriptorArray::PrintDescriptors(FILE* out) {
1008   PrintF(out, "Descriptor array  %d\n", number_of_descriptors());
1009   for (int i = 0; i < number_of_descriptors(); i++) {
1010     PrintF(out, " %d: ", i);
1011     Descriptor desc;
1012     Get(i, &desc);
1013     desc.Print(out);
1014   }
1015   PrintF(out, "\n");
1016 }
1017 
1018 
1019 #endif  // OBJECT_PRINT
1020 
1021 
1022 } }  // namespace v8::internal
1023