Home | History | Annotate | Download | only in src
      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 
     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 
     58 void MaybeObject::PrintLn(FILE* out) {
     59   Print(out);
     60   PrintF(out, "\n");
     61 }
     62 
     63 
     64 void HeapObject::PrintHeader(FILE* out, const char* id) {
     65   PrintF(out, "%p: [%s]\n", reinterpret_cast<void*>(this), id);
     66 }
     67 
     68 
     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 
    196 void ByteArray::ByteArrayPrint(FILE* out) {
    197   PrintF(out, "byte array, data starts at %p", GetDataStartAddress());
    198 }
    199 
    200 
    201 void FreeSpace::FreeSpacePrint(FILE* out) {
    202   PrintF(out, "free space, size %d", Size());
    203 }
    204 
    205 
    206 void ExternalPixelArray::ExternalPixelArrayPrint(FILE* out) {
    207   PrintF(out, "external pixel array");
    208 }
    209 
    210 
    211 void ExternalByteArray::ExternalByteArrayPrint(FILE* out) {
    212   PrintF(out, "external byte array");
    213 }
    214 
    215 
    216 void ExternalUnsignedByteArray::ExternalUnsignedByteArrayPrint(FILE* out) {
    217   PrintF(out, "external unsigned byte array");
    218 }
    219 
    220 
    221 void ExternalShortArray::ExternalShortArrayPrint(FILE* out) {
    222   PrintF(out, "external short array");
    223 }
    224 
    225 
    226 void ExternalUnsignedShortArray::ExternalUnsignedShortArrayPrint(FILE* out) {
    227   PrintF(out, "external unsigned short array");
    228 }
    229 
    230 
    231 void ExternalIntArray::ExternalIntArrayPrint(FILE* out) {
    232   PrintF(out, "external int array");
    233 }
    234 
    235 
    236 void ExternalUnsignedIntArray::ExternalUnsignedIntArrayPrint(FILE* out) {
    237   PrintF(out, "external unsigned int array");
    238 }
    239 
    240 
    241 void ExternalFloatArray::ExternalFloatArrayPrint(FILE* out) {
    242   PrintF(out, "external float array");
    243 }
    244 
    245 
    246 void ExternalDoubleArray::ExternalDoubleArrayPrint(FILE* out) {
    247   PrintF(out, "external double array");
    248 }
    249 
    250 
    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 
    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 
    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 
    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 
    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 
    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 
    555 void PolymorphicCodeCache::PolymorphicCodeCachePrint(FILE* out) {
    556   HeapObject::PrintHeader(out, "PolymorphicCodeCache");
    557   PrintF(out, "\n - cache: ");
    558   cache()->ShortPrint(out);
    559 }
    560 
    561 
    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 
    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 
    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 
    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 
    602 void JSValue::JSValuePrint(FILE* out) {
    603   HeapObject::PrintHeader(out, "ValueObject");
    604   value()->Print(out);
    605 }
    606 
    607 
    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 
    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.
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    796 void JSBuiltinsObject::JSBuiltinsObjectPrint(FILE* out) {
    797   PrintF(out, "builtins ");
    798   JSObjectPrint(out);
    799 }
    800 
    801 
    802 void JSGlobalPropertyCell::JSGlobalPropertyCellPrint(FILE* out) {
    803   HeapObject::PrintHeader(out, "JSGlobalPropertyCell");
    804 }
    805 
    806 
    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 
    817 void Foreign::ForeignPrint(FILE* out) {
    818   PrintF(out, "foreign address : %p", foreign_address());
    819 }
    820 
    821 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    943 void TypeSwitchInfo::TypeSwitchInfoPrint(FILE* out) {
    944   HeapObject::PrintHeader(out, "TypeSwitchInfo");
    945   PrintF(out, "\n - types: ");
    946   types()->ShortPrint(out);
    947 }
    948 
    949 
    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
    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 
    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 
   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