Home | History | Annotate | Download | only in src
      1 // Copyright 2006-2008 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 
     34 namespace v8 {
     35 namespace internal {
     36 
     37 #ifdef DEBUG
     38 
     39 static const char* TypeToString(InstanceType type);
     40 
     41 
     42 void Object::Print() {
     43   if (IsSmi()) {
     44     Smi::cast(this)->SmiPrint();
     45   } else if (IsFailure()) {
     46     Failure::cast(this)->FailurePrint();
     47   } else {
     48     HeapObject::cast(this)->HeapObjectPrint();
     49   }
     50   Flush();
     51 }
     52 
     53 
     54 void Object::PrintLn() {
     55   Print();
     56   PrintF("\n");
     57 }
     58 
     59 
     60 void Object::Verify() {
     61   if (IsSmi()) {
     62     Smi::cast(this)->SmiVerify();
     63   } else if (IsFailure()) {
     64     Failure::cast(this)->FailureVerify();
     65   } else {
     66     HeapObject::cast(this)->HeapObjectVerify();
     67   }
     68 }
     69 
     70 
     71 void Object::VerifyPointer(Object* p) {
     72   if (p->IsHeapObject()) {
     73     HeapObject::VerifyHeapPointer(p);
     74   } else {
     75     ASSERT(p->IsSmi());
     76   }
     77 }
     78 
     79 
     80 void Smi::SmiVerify() {
     81   ASSERT(IsSmi());
     82 }
     83 
     84 
     85 void Failure::FailureVerify() {
     86   ASSERT(IsFailure());
     87 }
     88 
     89 
     90 void HeapObject::PrintHeader(const char* id) {
     91   PrintF("%p: [%s]\n", this, id);
     92 }
     93 
     94 
     95 void HeapObject::HeapObjectPrint() {
     96   InstanceType instance_type = map()->instance_type();
     97 
     98   HandleScope scope;
     99   if (instance_type < FIRST_NONSTRING_TYPE) {
    100     String::cast(this)->StringPrint();
    101     return;
    102   }
    103 
    104   switch (instance_type) {
    105     case MAP_TYPE:
    106       Map::cast(this)->MapPrint();
    107       break;
    108     case HEAP_NUMBER_TYPE:
    109       HeapNumber::cast(this)->HeapNumberPrint();
    110       break;
    111     case FIXED_ARRAY_TYPE:
    112       FixedArray::cast(this)->FixedArrayPrint();
    113       break;
    114     case BYTE_ARRAY_TYPE:
    115       ByteArray::cast(this)->ByteArrayPrint();
    116       break;
    117     case PIXEL_ARRAY_TYPE:
    118       PixelArray::cast(this)->PixelArrayPrint();
    119       break;
    120     case EXTERNAL_BYTE_ARRAY_TYPE:
    121       ExternalByteArray::cast(this)->ExternalByteArrayPrint();
    122       break;
    123     case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
    124       ExternalUnsignedByteArray::cast(this)->ExternalUnsignedByteArrayPrint();
    125       break;
    126     case EXTERNAL_SHORT_ARRAY_TYPE:
    127       ExternalShortArray::cast(this)->ExternalShortArrayPrint();
    128       break;
    129     case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
    130       ExternalUnsignedShortArray::cast(this)->ExternalUnsignedShortArrayPrint();
    131       break;
    132     case EXTERNAL_INT_ARRAY_TYPE:
    133       ExternalIntArray::cast(this)->ExternalIntArrayPrint();
    134       break;
    135     case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
    136       ExternalUnsignedIntArray::cast(this)->ExternalUnsignedIntArrayPrint();
    137       break;
    138     case EXTERNAL_FLOAT_ARRAY_TYPE:
    139       ExternalFloatArray::cast(this)->ExternalFloatArrayPrint();
    140       break;
    141     case FILLER_TYPE:
    142       PrintF("filler");
    143       break;
    144     case JS_OBJECT_TYPE:  // fall through
    145     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
    146     case JS_ARRAY_TYPE:
    147     case JS_REGEXP_TYPE:
    148       JSObject::cast(this)->JSObjectPrint();
    149       break;
    150     case ODDBALL_TYPE:
    151       Oddball::cast(this)->to_string()->Print();
    152       break;
    153     case JS_FUNCTION_TYPE:
    154       JSFunction::cast(this)->JSFunctionPrint();
    155       break;
    156     case JS_GLOBAL_PROXY_TYPE:
    157       JSGlobalProxy::cast(this)->JSGlobalProxyPrint();
    158       break;
    159     case JS_GLOBAL_OBJECT_TYPE:
    160       JSGlobalObject::cast(this)->JSGlobalObjectPrint();
    161       break;
    162     case JS_BUILTINS_OBJECT_TYPE:
    163       JSBuiltinsObject::cast(this)->JSBuiltinsObjectPrint();
    164       break;
    165     case JS_VALUE_TYPE:
    166       PrintF("Value wrapper around:");
    167       JSValue::cast(this)->value()->Print();
    168       break;
    169     case CODE_TYPE:
    170       Code::cast(this)->CodePrint();
    171       break;
    172     case PROXY_TYPE:
    173       Proxy::cast(this)->ProxyPrint();
    174       break;
    175     case SHARED_FUNCTION_INFO_TYPE:
    176       SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint();
    177       break;
    178     case JS_GLOBAL_PROPERTY_CELL_TYPE:
    179       JSGlobalPropertyCell::cast(this)->JSGlobalPropertyCellPrint();
    180       break;
    181 #define MAKE_STRUCT_CASE(NAME, Name, name) \
    182   case NAME##_TYPE:                        \
    183     Name::cast(this)->Name##Print();       \
    184     break;
    185   STRUCT_LIST(MAKE_STRUCT_CASE)
    186 #undef MAKE_STRUCT_CASE
    187 
    188     default:
    189       PrintF("UNKNOWN TYPE %d", map()->instance_type());
    190       UNREACHABLE();
    191       break;
    192   }
    193 }
    194 
    195 
    196 void HeapObject::HeapObjectVerify() {
    197   InstanceType instance_type = map()->instance_type();
    198 
    199   if (instance_type < FIRST_NONSTRING_TYPE) {
    200     String::cast(this)->StringVerify();
    201     return;
    202   }
    203 
    204   switch (instance_type) {
    205     case MAP_TYPE:
    206       Map::cast(this)->MapVerify();
    207       break;
    208     case HEAP_NUMBER_TYPE:
    209       HeapNumber::cast(this)->HeapNumberVerify();
    210       break;
    211     case FIXED_ARRAY_TYPE:
    212       FixedArray::cast(this)->FixedArrayVerify();
    213       break;
    214     case BYTE_ARRAY_TYPE:
    215       ByteArray::cast(this)->ByteArrayVerify();
    216       break;
    217     case PIXEL_ARRAY_TYPE:
    218       PixelArray::cast(this)->PixelArrayVerify();
    219       break;
    220     case EXTERNAL_BYTE_ARRAY_TYPE:
    221       ExternalByteArray::cast(this)->ExternalByteArrayVerify();
    222       break;
    223     case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
    224       ExternalUnsignedByteArray::cast(this)->ExternalUnsignedByteArrayVerify();
    225       break;
    226     case EXTERNAL_SHORT_ARRAY_TYPE:
    227       ExternalShortArray::cast(this)->ExternalShortArrayVerify();
    228       break;
    229     case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
    230       ExternalUnsignedShortArray::cast(this)->
    231           ExternalUnsignedShortArrayVerify();
    232       break;
    233     case EXTERNAL_INT_ARRAY_TYPE:
    234       ExternalIntArray::cast(this)->ExternalIntArrayVerify();
    235       break;
    236     case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
    237       ExternalUnsignedIntArray::cast(this)->ExternalUnsignedIntArrayVerify();
    238       break;
    239     case EXTERNAL_FLOAT_ARRAY_TYPE:
    240       ExternalFloatArray::cast(this)->ExternalFloatArrayVerify();
    241       break;
    242     case CODE_TYPE:
    243       Code::cast(this)->CodeVerify();
    244       break;
    245     case ODDBALL_TYPE:
    246       Oddball::cast(this)->OddballVerify();
    247       break;
    248     case JS_OBJECT_TYPE:
    249     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
    250       JSObject::cast(this)->JSObjectVerify();
    251       break;
    252     case JS_VALUE_TYPE:
    253       JSValue::cast(this)->JSValueVerify();
    254       break;
    255     case JS_FUNCTION_TYPE:
    256       JSFunction::cast(this)->JSFunctionVerify();
    257       break;
    258     case JS_GLOBAL_PROXY_TYPE:
    259       JSGlobalProxy::cast(this)->JSGlobalProxyVerify();
    260       break;
    261     case JS_GLOBAL_OBJECT_TYPE:
    262       JSGlobalObject::cast(this)->JSGlobalObjectVerify();
    263       break;
    264     case JS_BUILTINS_OBJECT_TYPE:
    265       JSBuiltinsObject::cast(this)->JSBuiltinsObjectVerify();
    266       break;
    267     case JS_GLOBAL_PROPERTY_CELL_TYPE:
    268       JSGlobalPropertyCell::cast(this)->JSGlobalPropertyCellVerify();
    269       break;
    270     case JS_ARRAY_TYPE:
    271       JSArray::cast(this)->JSArrayVerify();
    272       break;
    273     case JS_REGEXP_TYPE:
    274       JSRegExp::cast(this)->JSRegExpVerify();
    275       break;
    276     case FILLER_TYPE:
    277       break;
    278     case PROXY_TYPE:
    279       Proxy::cast(this)->ProxyVerify();
    280       break;
    281     case SHARED_FUNCTION_INFO_TYPE:
    282       SharedFunctionInfo::cast(this)->SharedFunctionInfoVerify();
    283       break;
    284 
    285 #define MAKE_STRUCT_CASE(NAME, Name, name) \
    286   case NAME##_TYPE:                        \
    287     Name::cast(this)->Name##Verify();      \
    288     break;
    289     STRUCT_LIST(MAKE_STRUCT_CASE)
    290 #undef MAKE_STRUCT_CASE
    291 
    292     default:
    293       UNREACHABLE();
    294       break;
    295   }
    296 }
    297 
    298 
    299 void HeapObject::VerifyHeapPointer(Object* p) {
    300   ASSERT(p->IsHeapObject());
    301   ASSERT(Heap::Contains(HeapObject::cast(p)));
    302 }
    303 
    304 
    305 void HeapNumber::HeapNumberVerify() {
    306   ASSERT(IsHeapNumber());
    307 }
    308 
    309 
    310 void ByteArray::ByteArrayPrint() {
    311   PrintF("byte array, data starts at %p", GetDataStartAddress());
    312 }
    313 
    314 
    315 void PixelArray::PixelArrayPrint() {
    316   PrintF("pixel array");
    317 }
    318 
    319 
    320 void ExternalByteArray::ExternalByteArrayPrint() {
    321   PrintF("external byte array");
    322 }
    323 
    324 
    325 void ExternalUnsignedByteArray::ExternalUnsignedByteArrayPrint() {
    326   PrintF("external unsigned byte array");
    327 }
    328 
    329 
    330 void ExternalShortArray::ExternalShortArrayPrint() {
    331   PrintF("external short array");
    332 }
    333 
    334 
    335 void ExternalUnsignedShortArray::ExternalUnsignedShortArrayPrint() {
    336   PrintF("external unsigned short array");
    337 }
    338 
    339 
    340 void ExternalIntArray::ExternalIntArrayPrint() {
    341   PrintF("external int array");
    342 }
    343 
    344 
    345 void ExternalUnsignedIntArray::ExternalUnsignedIntArrayPrint() {
    346   PrintF("external unsigned int array");
    347 }
    348 
    349 
    350 void ExternalFloatArray::ExternalFloatArrayPrint() {
    351   PrintF("external float array");
    352 }
    353 
    354 
    355 void ByteArray::ByteArrayVerify() {
    356   ASSERT(IsByteArray());
    357 }
    358 
    359 
    360 void PixelArray::PixelArrayVerify() {
    361   ASSERT(IsPixelArray());
    362 }
    363 
    364 
    365 void ExternalByteArray::ExternalByteArrayVerify() {
    366   ASSERT(IsExternalByteArray());
    367 }
    368 
    369 
    370 void ExternalUnsignedByteArray::ExternalUnsignedByteArrayVerify() {
    371   ASSERT(IsExternalUnsignedByteArray());
    372 }
    373 
    374 
    375 void ExternalShortArray::ExternalShortArrayVerify() {
    376   ASSERT(IsExternalShortArray());
    377 }
    378 
    379 
    380 void ExternalUnsignedShortArray::ExternalUnsignedShortArrayVerify() {
    381   ASSERT(IsExternalUnsignedShortArray());
    382 }
    383 
    384 
    385 void ExternalIntArray::ExternalIntArrayVerify() {
    386   ASSERT(IsExternalIntArray());
    387 }
    388 
    389 
    390 void ExternalUnsignedIntArray::ExternalUnsignedIntArrayVerify() {
    391   ASSERT(IsExternalUnsignedIntArray());
    392 }
    393 
    394 
    395 void ExternalFloatArray::ExternalFloatArrayVerify() {
    396   ASSERT(IsExternalFloatArray());
    397 }
    398 
    399 
    400 void JSObject::PrintProperties() {
    401   if (HasFastProperties()) {
    402     DescriptorArray* descs = map()->instance_descriptors();
    403     for (int i = 0; i < descs->number_of_descriptors(); i++) {
    404       PrintF("   ");
    405       descs->GetKey(i)->StringPrint();
    406       PrintF(": ");
    407       switch (descs->GetType(i)) {
    408         case FIELD: {
    409           int index = descs->GetFieldIndex(i);
    410           FastPropertyAt(index)->ShortPrint();
    411           PrintF(" (field at offset %d)\n", index);
    412           break;
    413         }
    414         case CONSTANT_FUNCTION:
    415           descs->GetConstantFunction(i)->ShortPrint();
    416           PrintF(" (constant function)\n");
    417           break;
    418         case CALLBACKS:
    419           descs->GetCallbacksObject(i)->ShortPrint();
    420           PrintF(" (callback)\n");
    421           break;
    422         case MAP_TRANSITION:
    423           PrintF(" (map transition)\n");
    424           break;
    425         case CONSTANT_TRANSITION:
    426           PrintF(" (constant transition)\n");
    427           break;
    428         case NULL_DESCRIPTOR:
    429           PrintF(" (null descriptor)\n");
    430           break;
    431         default:
    432           UNREACHABLE();
    433           break;
    434       }
    435     }
    436   } else {
    437     property_dictionary()->Print();
    438   }
    439 }
    440 
    441 
    442 void JSObject::PrintElements() {
    443   switch (GetElementsKind()) {
    444     case FAST_ELEMENTS: {
    445       // Print in array notation for non-sparse arrays.
    446       FixedArray* p = FixedArray::cast(elements());
    447       for (int i = 0; i < p->length(); i++) {
    448         PrintF("   %d: ", i);
    449         p->get(i)->ShortPrint();
    450         PrintF("\n");
    451       }
    452       break;
    453     }
    454     case PIXEL_ELEMENTS: {
    455       PixelArray* p = PixelArray::cast(elements());
    456       for (int i = 0; i < p->length(); i++) {
    457         PrintF("   %d: %d\n", i, p->get(i));
    458       }
    459       break;
    460     }
    461     case EXTERNAL_BYTE_ELEMENTS: {
    462       ExternalByteArray* p = ExternalByteArray::cast(elements());
    463       for (int i = 0; i < p->length(); i++) {
    464         PrintF("   %d: %d\n", i, static_cast<int>(p->get(i)));
    465       }
    466       break;
    467     }
    468     case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: {
    469       ExternalUnsignedByteArray* p =
    470           ExternalUnsignedByteArray::cast(elements());
    471       for (int i = 0; i < p->length(); i++) {
    472         PrintF("   %d: %d\n", i, static_cast<int>(p->get(i)));
    473       }
    474       break;
    475     }
    476     case EXTERNAL_SHORT_ELEMENTS: {
    477       ExternalShortArray* p = ExternalShortArray::cast(elements());
    478       for (int i = 0; i < p->length(); i++) {
    479         PrintF("   %d: %d\n", i, static_cast<int>(p->get(i)));
    480       }
    481       break;
    482     }
    483     case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: {
    484       ExternalUnsignedShortArray* p =
    485           ExternalUnsignedShortArray::cast(elements());
    486       for (int i = 0; i < p->length(); i++) {
    487         PrintF("   %d: %d\n", i, static_cast<int>(p->get(i)));
    488       }
    489       break;
    490     }
    491     case EXTERNAL_INT_ELEMENTS: {
    492       ExternalIntArray* p = ExternalIntArray::cast(elements());
    493       for (int i = 0; i < p->length(); i++) {
    494         PrintF("   %d: %d\n", i, static_cast<int>(p->get(i)));
    495       }
    496       break;
    497     }
    498     case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
    499       ExternalUnsignedIntArray* p =
    500           ExternalUnsignedIntArray::cast(elements());
    501       for (int i = 0; i < p->length(); i++) {
    502         PrintF("   %d: %d\n", i, static_cast<int>(p->get(i)));
    503       }
    504       break;
    505     }
    506     case EXTERNAL_FLOAT_ELEMENTS: {
    507       ExternalFloatArray* p = ExternalFloatArray::cast(elements());
    508       for (int i = 0; i < p->length(); i++) {
    509         PrintF("   %d: %f\n", i, p->get(i));
    510       }
    511       break;
    512     }
    513     case DICTIONARY_ELEMENTS:
    514       elements()->Print();
    515       break;
    516     default:
    517       UNREACHABLE();
    518       break;
    519   }
    520 }
    521 
    522 
    523 void JSObject::JSObjectPrint() {
    524   PrintF("%p: [JSObject]\n", this);
    525   PrintF(" - map = %p\n", map());
    526   PrintF(" - prototype = %p\n", GetPrototype());
    527   PrintF(" {\n");
    528   PrintProperties();
    529   PrintElements();
    530   PrintF(" }\n");
    531 }
    532 
    533 
    534 void JSObject::JSObjectVerify() {
    535   VerifyHeapPointer(properties());
    536   VerifyHeapPointer(elements());
    537   if (HasFastProperties()) {
    538     CHECK_EQ(map()->unused_property_fields(),
    539              (map()->inobject_properties() + properties()->length() -
    540               map()->NextFreePropertyIndex()));
    541   }
    542 }
    543 
    544 
    545 static const char* TypeToString(InstanceType type) {
    546   switch (type) {
    547     case INVALID_TYPE: return "INVALID";
    548     case MAP_TYPE: return "MAP";
    549     case HEAP_NUMBER_TYPE: return "HEAP_NUMBER";
    550     case SYMBOL_TYPE: return "SYMBOL";
    551     case ASCII_SYMBOL_TYPE: return "ASCII_SYMBOL";
    552     case CONS_SYMBOL_TYPE: return "CONS_SYMBOL";
    553     case CONS_ASCII_SYMBOL_TYPE: return "CONS_ASCII_SYMBOL";
    554     case EXTERNAL_ASCII_SYMBOL_TYPE:
    555     case EXTERNAL_SYMBOL_TYPE: return "EXTERNAL_SYMBOL";
    556     case ASCII_STRING_TYPE: return "ASCII_STRING";
    557     case STRING_TYPE: return "TWO_BYTE_STRING";
    558     case CONS_STRING_TYPE:
    559     case CONS_ASCII_STRING_TYPE: return "CONS_STRING";
    560     case EXTERNAL_ASCII_STRING_TYPE:
    561     case EXTERNAL_STRING_TYPE: return "EXTERNAL_STRING";
    562     case FIXED_ARRAY_TYPE: return "FIXED_ARRAY";
    563     case BYTE_ARRAY_TYPE: return "BYTE_ARRAY";
    564     case PIXEL_ARRAY_TYPE: return "PIXEL_ARRAY";
    565     case EXTERNAL_BYTE_ARRAY_TYPE: return "EXTERNAL_BYTE_ARRAY";
    566     case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
    567       return "EXTERNAL_UNSIGNED_BYTE_ARRAY";
    568     case EXTERNAL_SHORT_ARRAY_TYPE: return "EXTERNAL_SHORT_ARRAY";
    569     case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
    570       return "EXTERNAL_UNSIGNED_SHORT_ARRAY";
    571     case EXTERNAL_INT_ARRAY_TYPE: return "EXTERNAL_INT_ARRAY";
    572     case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
    573       return "EXTERNAL_UNSIGNED_INT_ARRAY";
    574     case EXTERNAL_FLOAT_ARRAY_TYPE: return "EXTERNAL_FLOAT_ARRAY";
    575     case FILLER_TYPE: return "FILLER";
    576     case JS_OBJECT_TYPE: return "JS_OBJECT";
    577     case JS_CONTEXT_EXTENSION_OBJECT_TYPE: return "JS_CONTEXT_EXTENSION_OBJECT";
    578     case ODDBALL_TYPE: return "ODDBALL";
    579     case JS_GLOBAL_PROPERTY_CELL_TYPE: return "JS_GLOBAL_PROPERTY_CELL";
    580     case SHARED_FUNCTION_INFO_TYPE: return "SHARED_FUNCTION_INFO";
    581     case JS_FUNCTION_TYPE: return "JS_FUNCTION";
    582     case CODE_TYPE: return "CODE";
    583     case JS_ARRAY_TYPE: return "JS_ARRAY";
    584     case JS_REGEXP_TYPE: return "JS_REGEXP";
    585     case JS_VALUE_TYPE: return "JS_VALUE";
    586     case JS_GLOBAL_OBJECT_TYPE: return "JS_GLOBAL_OBJECT";
    587     case JS_BUILTINS_OBJECT_TYPE: return "JS_BUILTINS_OBJECT";
    588     case JS_GLOBAL_PROXY_TYPE: return "JS_GLOBAL_PROXY";
    589     case PROXY_TYPE: return "PROXY";
    590 #define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return #NAME;
    591   STRUCT_LIST(MAKE_STRUCT_CASE)
    592 #undef MAKE_STRUCT_CASE
    593   }
    594   return "UNKNOWN";
    595 }
    596 
    597 
    598 void Map::MapPrint() {
    599   HeapObject::PrintHeader("Map");
    600   PrintF(" - type: %s\n", TypeToString(instance_type()));
    601   PrintF(" - instance size: %d\n", instance_size());
    602   PrintF(" - inobject properties: %d\n", inobject_properties());
    603   PrintF(" - pre-allocated property fields: %d\n",
    604       pre_allocated_property_fields());
    605   PrintF(" - unused property fields: %d\n", unused_property_fields());
    606   if (is_hidden_prototype()) {
    607     PrintF(" - hidden_prototype\n");
    608   }
    609   if (has_named_interceptor()) {
    610     PrintF(" - named_interceptor\n");
    611   }
    612   if (has_indexed_interceptor()) {
    613     PrintF(" - indexed_interceptor\n");
    614   }
    615   if (is_undetectable()) {
    616     PrintF(" - undetectable\n");
    617   }
    618   if (has_instance_call_handler()) {
    619     PrintF(" - instance_call_handler\n");
    620   }
    621   if (is_access_check_needed()) {
    622     PrintF(" - access_check_needed\n");
    623   }
    624   PrintF(" - instance descriptors: ");
    625   instance_descriptors()->ShortPrint();
    626   PrintF("\n - prototype: ");
    627   prototype()->ShortPrint();
    628   PrintF("\n - constructor: ");
    629   constructor()->ShortPrint();
    630   PrintF("\n");
    631 }
    632 
    633 
    634 void Map::MapVerify() {
    635   ASSERT(!Heap::InNewSpace(this));
    636   ASSERT(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
    637   ASSERT(kPointerSize <= instance_size()
    638          && instance_size() < Heap::Capacity());
    639   VerifyHeapPointer(prototype());
    640   VerifyHeapPointer(instance_descriptors());
    641 }
    642 
    643 
    644 void FixedArray::FixedArrayPrint() {
    645   HeapObject::PrintHeader("FixedArray");
    646   PrintF(" - length: %d", length());
    647   for (int i = 0; i < length(); i++) {
    648     PrintF("\n  [%d]: ", i);
    649     get(i)->ShortPrint();
    650   }
    651   PrintF("\n");
    652 }
    653 
    654 
    655 void FixedArray::FixedArrayVerify() {
    656   for (int i = 0; i < length(); i++) {
    657     Object* e = get(i);
    658     if (e->IsHeapObject()) {
    659       VerifyHeapPointer(e);
    660     } else {
    661       e->Verify();
    662     }
    663   }
    664 }
    665 
    666 
    667 void JSValue::JSValuePrint() {
    668   HeapObject::PrintHeader("ValueObject");
    669   value()->Print();
    670 }
    671 
    672 
    673 void JSValue::JSValueVerify() {
    674   Object* v = value();
    675   if (v->IsHeapObject()) {
    676     VerifyHeapPointer(v);
    677   }
    678 }
    679 
    680 
    681 void String::StringPrint() {
    682   if (StringShape(this).IsSymbol()) {
    683     PrintF("#");
    684   } else if (StringShape(this).IsCons()) {
    685     PrintF("c\"");
    686   } else {
    687     PrintF("\"");
    688   }
    689 
    690   for (int i = 0; i < length(); i++) {
    691     PrintF("%c", Get(i));
    692   }
    693 
    694   if (!StringShape(this).IsSymbol()) PrintF("\"");
    695 }
    696 
    697 
    698 void String::StringVerify() {
    699   CHECK(IsString());
    700   CHECK(length() >= 0 && length() <= Smi::kMaxValue);
    701   if (IsSymbol()) {
    702     CHECK(!Heap::InNewSpace(this));
    703   }
    704 }
    705 
    706 
    707 void JSFunction::JSFunctionPrint() {
    708   HeapObject::PrintHeader("Function");
    709   PrintF(" - map = 0x%p\n", map());
    710   PrintF(" - is boilerplate: %s\n", IsBoilerplate() ? "yes" : "no");
    711   PrintF(" - initial_map = ");
    712   if (has_initial_map()) {
    713     initial_map()->ShortPrint();
    714   }
    715   PrintF("\n - shared_info = ");
    716   shared()->ShortPrint();
    717   PrintF("\n   - name = ");
    718   shared()->name()->Print();
    719   PrintF("\n - context = ");
    720   unchecked_context()->ShortPrint();
    721   PrintF("\n - code = ");
    722   code()->ShortPrint();
    723   PrintF("\n");
    724 
    725   PrintProperties();
    726   PrintElements();
    727 
    728   PrintF("\n");
    729 }
    730 
    731 
    732 void JSFunction::JSFunctionVerify() {
    733   CHECK(IsJSFunction());
    734   VerifyObjectField(kPrototypeOrInitialMapOffset);
    735 }
    736 
    737 
    738 void SharedFunctionInfo::SharedFunctionInfoPrint() {
    739   HeapObject::PrintHeader("SharedFunctionInfo");
    740   PrintF(" - name: ");
    741   name()->ShortPrint();
    742   PrintF("\n - expected_nof_properties: %d", expected_nof_properties());
    743   PrintF("\n - instance class name = ");
    744   instance_class_name()->Print();
    745   PrintF("\n - code = ");
    746   code()->ShortPrint();
    747   PrintF("\n - source code = ");
    748   GetSourceCode()->ShortPrint();
    749   // Script files are often large, hard to read.
    750   // PrintF("\n - script =");
    751   // script()->Print();
    752   PrintF("\n - function token position = %d", function_token_position());
    753   PrintF("\n - start position = %d", start_position());
    754   PrintF("\n - end position = %d", end_position());
    755   PrintF("\n - is expression = %d", is_expression());
    756   PrintF("\n - debug info = ");
    757   debug_info()->ShortPrint();
    758   PrintF("\n - length = %d", length());
    759   PrintF("\n - has_only_simple_this_property_assignments = %d",
    760          has_only_simple_this_property_assignments());
    761   PrintF("\n - this_property_assignments = ");
    762   this_property_assignments()->ShortPrint();
    763   PrintF("\n");
    764 }
    765 
    766 void SharedFunctionInfo::SharedFunctionInfoVerify() {
    767   CHECK(IsSharedFunctionInfo());
    768   VerifyObjectField(kNameOffset);
    769   VerifyObjectField(kCodeOffset);
    770   VerifyObjectField(kInstanceClassNameOffset);
    771   VerifyObjectField(kExternalReferenceDataOffset);
    772   VerifyObjectField(kScriptOffset);
    773   VerifyObjectField(kDebugInfoOffset);
    774 }
    775 
    776 
    777 void JSGlobalProxy::JSGlobalProxyPrint() {
    778   PrintF("global_proxy");
    779   JSObjectPrint();
    780   PrintF("context : ");
    781   context()->ShortPrint();
    782   PrintF("\n");
    783 }
    784 
    785 
    786 void JSGlobalProxy::JSGlobalProxyVerify() {
    787   CHECK(IsJSGlobalProxy());
    788   JSObjectVerify();
    789   VerifyObjectField(JSGlobalProxy::kContextOffset);
    790   // Make sure that this object has no properties, elements.
    791   CHECK_EQ(0, properties()->length());
    792   CHECK_EQ(0, elements()->length());
    793 }
    794 
    795 
    796 void JSGlobalObject::JSGlobalObjectPrint() {
    797   PrintF("global ");
    798   JSObjectPrint();
    799   PrintF("global context : ");
    800   global_context()->ShortPrint();
    801   PrintF("\n");
    802 }
    803 
    804 
    805 void JSGlobalObject::JSGlobalObjectVerify() {
    806   CHECK(IsJSGlobalObject());
    807   JSObjectVerify();
    808   for (int i = GlobalObject::kBuiltinsOffset;
    809        i < JSGlobalObject::kSize;
    810        i += kPointerSize) {
    811     VerifyObjectField(i);
    812   }
    813 }
    814 
    815 
    816 void JSBuiltinsObject::JSBuiltinsObjectPrint() {
    817   PrintF("builtins ");
    818   JSObjectPrint();
    819 }
    820 
    821 
    822 void JSBuiltinsObject::JSBuiltinsObjectVerify() {
    823   CHECK(IsJSBuiltinsObject());
    824   JSObjectVerify();
    825   for (int i = GlobalObject::kBuiltinsOffset;
    826        i < JSBuiltinsObject::kSize;
    827        i += kPointerSize) {
    828     VerifyObjectField(i);
    829   }
    830 }
    831 
    832 
    833 void Oddball::OddballVerify() {
    834   CHECK(IsOddball());
    835   VerifyHeapPointer(to_string());
    836   Object* number = to_number();
    837   if (number->IsHeapObject()) {
    838     ASSERT(number == Heap::nan_value());
    839   } else {
    840     ASSERT(number->IsSmi());
    841     int value = Smi::cast(number)->value();
    842     ASSERT(value == 0 || value == 1 || value == -1 ||
    843            value == -2 || value == -3);
    844   }
    845 }
    846 
    847 
    848 void JSGlobalPropertyCell::JSGlobalPropertyCellVerify() {
    849   CHECK(IsJSGlobalPropertyCell());
    850   VerifyObjectField(kValueOffset);
    851 }
    852 
    853 
    854 void JSGlobalPropertyCell::JSGlobalPropertyCellPrint() {
    855   HeapObject::PrintHeader("JSGlobalPropertyCell");
    856 }
    857 
    858 
    859 void Code::CodePrint() {
    860   HeapObject::PrintHeader("Code");
    861 #ifdef ENABLE_DISASSEMBLER
    862   Disassemble(NULL);
    863 #endif
    864 }
    865 
    866 
    867 void Code::CodeVerify() {
    868   CHECK(IsAligned(reinterpret_cast<intptr_t>(instruction_start()),
    869                   static_cast<intptr_t>(kCodeAlignment)));
    870   Address last_gc_pc = NULL;
    871   for (RelocIterator it(this); !it.done(); it.next()) {
    872     it.rinfo()->Verify();
    873     // Ensure that GC will not iterate twice over the same pointer.
    874     if (RelocInfo::IsGCRelocMode(it.rinfo()->rmode())) {
    875       CHECK(it.rinfo()->pc() != last_gc_pc);
    876       last_gc_pc = it.rinfo()->pc();
    877     }
    878   }
    879 }
    880 
    881 
    882 void JSArray::JSArrayVerify() {
    883   JSObjectVerify();
    884   ASSERT(length()->IsNumber() || length()->IsUndefined());
    885   ASSERT(elements()->IsUndefined() || elements()->IsFixedArray());
    886 }
    887 
    888 
    889 void JSRegExp::JSRegExpVerify() {
    890   JSObjectVerify();
    891   ASSERT(data()->IsUndefined() || data()->IsFixedArray());
    892   switch (TypeTag()) {
    893     case JSRegExp::ATOM: {
    894       FixedArray* arr = FixedArray::cast(data());
    895       ASSERT(arr->get(JSRegExp::kAtomPatternIndex)->IsString());
    896       break;
    897     }
    898     case JSRegExp::IRREGEXP: {
    899       bool is_native = RegExpImpl::UsesNativeRegExp();
    900 
    901       FixedArray* arr = FixedArray::cast(data());
    902       Object* ascii_data = arr->get(JSRegExp::kIrregexpASCIICodeIndex);
    903       // TheHole : Not compiled yet.
    904       // JSObject: Compilation error.
    905       // Code/ByteArray: Compiled code.
    906       ASSERT(ascii_data->IsTheHole() || ascii_data->IsJSObject() ||
    907           (is_native ? ascii_data->IsCode() : ascii_data->IsByteArray()));
    908       Object* uc16_data = arr->get(JSRegExp::kIrregexpUC16CodeIndex);
    909       ASSERT(uc16_data->IsTheHole() || ascii_data->IsJSObject() ||
    910           (is_native ? uc16_data->IsCode() : uc16_data->IsByteArray()));
    911       ASSERT(arr->get(JSRegExp::kIrregexpCaptureCountIndex)->IsSmi());
    912       ASSERT(arr->get(JSRegExp::kIrregexpMaxRegisterCountIndex)->IsSmi());
    913       break;
    914     }
    915     default:
    916       ASSERT_EQ(JSRegExp::NOT_COMPILED, TypeTag());
    917       ASSERT(data()->IsUndefined());
    918       break;
    919   }
    920 }
    921 
    922 
    923 void Proxy::ProxyPrint() {
    924   PrintF("proxy to %p", proxy());
    925 }
    926 
    927 
    928 void Proxy::ProxyVerify() {
    929   ASSERT(IsProxy());
    930 }
    931 
    932 
    933 void AccessorInfo::AccessorInfoVerify() {
    934   CHECK(IsAccessorInfo());
    935   VerifyPointer(getter());
    936   VerifyPointer(setter());
    937   VerifyPointer(name());
    938   VerifyPointer(data());
    939   VerifyPointer(flag());
    940   VerifyPointer(load_stub_cache());
    941 }
    942 
    943 void AccessorInfo::AccessorInfoPrint() {
    944   HeapObject::PrintHeader("AccessorInfo");
    945   PrintF("\n - getter: ");
    946   getter()->ShortPrint();
    947   PrintF("\n - setter: ");
    948   setter()->ShortPrint();
    949   PrintF("\n - name: ");
    950   name()->ShortPrint();
    951   PrintF("\n - data: ");
    952   data()->ShortPrint();
    953   PrintF("\n - flag: ");
    954   flag()->ShortPrint();
    955 }
    956 
    957 void AccessCheckInfo::AccessCheckInfoVerify() {
    958   CHECK(IsAccessCheckInfo());
    959   VerifyPointer(named_callback());
    960   VerifyPointer(indexed_callback());
    961   VerifyPointer(data());
    962 }
    963 
    964 void AccessCheckInfo::AccessCheckInfoPrint() {
    965   HeapObject::PrintHeader("AccessCheckInfo");
    966   PrintF("\n - named_callback: ");
    967   named_callback()->ShortPrint();
    968   PrintF("\n - indexed_callback: ");
    969   indexed_callback()->ShortPrint();
    970   PrintF("\n - data: ");
    971   data()->ShortPrint();
    972 }
    973 
    974 void InterceptorInfo::InterceptorInfoVerify() {
    975   CHECK(IsInterceptorInfo());
    976   VerifyPointer(getter());
    977   VerifyPointer(setter());
    978   VerifyPointer(query());
    979   VerifyPointer(deleter());
    980   VerifyPointer(enumerator());
    981   VerifyPointer(data());
    982 }
    983 
    984 void InterceptorInfo::InterceptorInfoPrint() {
    985   HeapObject::PrintHeader("InterceptorInfo");
    986   PrintF("\n - getter: ");
    987   getter()->ShortPrint();
    988   PrintF("\n - setter: ");
    989   setter()->ShortPrint();
    990   PrintF("\n - query: ");
    991   query()->ShortPrint();
    992   PrintF("\n - deleter: ");
    993   deleter()->ShortPrint();
    994   PrintF("\n - enumerator: ");
    995   enumerator()->ShortPrint();
    996   PrintF("\n - data: ");
    997   data()->ShortPrint();
    998 }
    999 
   1000 void CallHandlerInfo::CallHandlerInfoVerify() {
   1001   CHECK(IsCallHandlerInfo());
   1002   VerifyPointer(callback());
   1003   VerifyPointer(data());
   1004 }
   1005 
   1006 void CallHandlerInfo::CallHandlerInfoPrint() {
   1007   HeapObject::PrintHeader("CallHandlerInfo");
   1008   PrintF("\n - callback: ");
   1009   callback()->ShortPrint();
   1010   PrintF("\n - data: ");
   1011   data()->ShortPrint();
   1012 }
   1013 
   1014 void TemplateInfo::TemplateInfoVerify() {
   1015   VerifyPointer(tag());
   1016   VerifyPointer(property_list());
   1017 }
   1018 
   1019 void FunctionTemplateInfo::FunctionTemplateInfoVerify() {
   1020   CHECK(IsFunctionTemplateInfo());
   1021   TemplateInfoVerify();
   1022   VerifyPointer(serial_number());
   1023   VerifyPointer(call_code());
   1024   VerifyPointer(property_accessors());
   1025   VerifyPointer(prototype_template());
   1026   VerifyPointer(parent_template());
   1027   VerifyPointer(named_property_handler());
   1028   VerifyPointer(indexed_property_handler());
   1029   VerifyPointer(instance_template());
   1030   VerifyPointer(signature());
   1031   VerifyPointer(access_check_info());
   1032 }
   1033 
   1034 void FunctionTemplateInfo::FunctionTemplateInfoPrint() {
   1035   HeapObject::PrintHeader("FunctionTemplateInfo");
   1036   PrintF("\n - class name: ");
   1037   class_name()->ShortPrint();
   1038   PrintF("\n - tag: ");
   1039   tag()->ShortPrint();
   1040   PrintF("\n - property_list: ");
   1041   property_list()->ShortPrint();
   1042   PrintF("\n - serial_number: ");
   1043   serial_number()->ShortPrint();
   1044   PrintF("\n - call_code: ");
   1045   call_code()->ShortPrint();
   1046   PrintF("\n - property_accessors: ");
   1047   property_accessors()->ShortPrint();
   1048   PrintF("\n - prototype_template: ");
   1049   prototype_template()->ShortPrint();
   1050   PrintF("\n - parent_template: ");
   1051   parent_template()->ShortPrint();
   1052   PrintF("\n - named_property_handler: ");
   1053   named_property_handler()->ShortPrint();
   1054   PrintF("\n - indexed_property_handler: ");
   1055   indexed_property_handler()->ShortPrint();
   1056   PrintF("\n - instance_template: ");
   1057   instance_template()->ShortPrint();
   1058   PrintF("\n - signature: ");
   1059   signature()->ShortPrint();
   1060   PrintF("\n - access_check_info: ");
   1061   access_check_info()->ShortPrint();
   1062   PrintF("\n - hidden_prototype: %s", hidden_prototype() ? "true" : "false");
   1063   PrintF("\n - undetectable: %s", undetectable() ? "true" : "false");
   1064   PrintF("\n - need_access_check: %s", needs_access_check() ? "true" : "false");
   1065 }
   1066 
   1067 void ObjectTemplateInfo::ObjectTemplateInfoVerify() {
   1068   CHECK(IsObjectTemplateInfo());
   1069   TemplateInfoVerify();
   1070   VerifyPointer(constructor());
   1071   VerifyPointer(internal_field_count());
   1072 }
   1073 
   1074 void ObjectTemplateInfo::ObjectTemplateInfoPrint() {
   1075   HeapObject::PrintHeader("ObjectTemplateInfo");
   1076   PrintF("\n - constructor: ");
   1077   constructor()->ShortPrint();
   1078   PrintF("\n - internal_field_count: ");
   1079   internal_field_count()->ShortPrint();
   1080 }
   1081 
   1082 void SignatureInfo::SignatureInfoVerify() {
   1083   CHECK(IsSignatureInfo());
   1084   VerifyPointer(receiver());
   1085   VerifyPointer(args());
   1086 }
   1087 
   1088 void SignatureInfo::SignatureInfoPrint() {
   1089   HeapObject::PrintHeader("SignatureInfo");
   1090   PrintF("\n - receiver: ");
   1091   receiver()->ShortPrint();
   1092   PrintF("\n - args: ");
   1093   args()->ShortPrint();
   1094 }
   1095 
   1096 void TypeSwitchInfo::TypeSwitchInfoVerify() {
   1097   CHECK(IsTypeSwitchInfo());
   1098   VerifyPointer(types());
   1099 }
   1100 
   1101 void TypeSwitchInfo::TypeSwitchInfoPrint() {
   1102   HeapObject::PrintHeader("TypeSwitchInfo");
   1103   PrintF("\n - types: ");
   1104   types()->ShortPrint();
   1105 }
   1106 
   1107 
   1108 void Script::ScriptVerify() {
   1109   CHECK(IsScript());
   1110   VerifyPointer(source());
   1111   VerifyPointer(name());
   1112   line_offset()->SmiVerify();
   1113   column_offset()->SmiVerify();
   1114   VerifyPointer(data());
   1115   VerifyPointer(wrapper());
   1116   type()->SmiVerify();
   1117   VerifyPointer(line_ends());
   1118   VerifyPointer(id());
   1119 }
   1120 
   1121 
   1122 void Script::ScriptPrint() {
   1123   HeapObject::PrintHeader("Script");
   1124   PrintF("\n - source: ");
   1125   source()->ShortPrint();
   1126   PrintF("\n - name: ");
   1127   name()->ShortPrint();
   1128   PrintF("\n - line_offset: ");
   1129   line_offset()->ShortPrint();
   1130   PrintF("\n - column_offset: ");
   1131   column_offset()->ShortPrint();
   1132   PrintF("\n - type: ");
   1133   type()->ShortPrint();
   1134   PrintF("\n - id: ");
   1135   id()->ShortPrint();
   1136   PrintF("\n - data: ");
   1137   data()->ShortPrint();
   1138   PrintF("\n - context data: ");
   1139   context_data()->ShortPrint();
   1140   PrintF("\n - wrapper: ");
   1141   wrapper()->ShortPrint();
   1142   PrintF("\n - compilation type: ");
   1143   compilation_type()->ShortPrint();
   1144   PrintF("\n - line ends: ");
   1145   line_ends()->ShortPrint();
   1146   PrintF("\n - eval from shared: ");
   1147   eval_from_shared()->ShortPrint();
   1148   PrintF("\n - eval from instructions offset: ");
   1149   eval_from_instructions_offset()->ShortPrint();
   1150   PrintF("\n");
   1151 }
   1152 
   1153 
   1154 #ifdef ENABLE_DEBUGGER_SUPPORT
   1155 void DebugInfo::DebugInfoVerify() {
   1156   CHECK(IsDebugInfo());
   1157   VerifyPointer(shared());
   1158   VerifyPointer(original_code());
   1159   VerifyPointer(code());
   1160   VerifyPointer(break_points());
   1161 }
   1162 
   1163 
   1164 void DebugInfo::DebugInfoPrint() {
   1165   HeapObject::PrintHeader("DebugInfo");
   1166   PrintF("\n - shared: ");
   1167   shared()->ShortPrint();
   1168   PrintF("\n - original_code: ");
   1169   original_code()->ShortPrint();
   1170   PrintF("\n - code: ");
   1171   code()->ShortPrint();
   1172   PrintF("\n - break_points: ");
   1173   break_points()->Print();
   1174 }
   1175 
   1176 
   1177 void BreakPointInfo::BreakPointInfoVerify() {
   1178   CHECK(IsBreakPointInfo());
   1179   code_position()->SmiVerify();
   1180   source_position()->SmiVerify();
   1181   statement_position()->SmiVerify();
   1182   VerifyPointer(break_point_objects());
   1183 }
   1184 
   1185 
   1186 void BreakPointInfo::BreakPointInfoPrint() {
   1187   HeapObject::PrintHeader("BreakPointInfo");
   1188   PrintF("\n - code_position: %d", code_position());
   1189   PrintF("\n - source_position: %d", source_position());
   1190   PrintF("\n - statement_position: %d", statement_position());
   1191   PrintF("\n - break_point_objects: ");
   1192   break_point_objects()->ShortPrint();
   1193 }
   1194 #endif
   1195 
   1196 
   1197 void JSObject::IncrementSpillStatistics(SpillInformation* info) {
   1198   info->number_of_objects_++;
   1199   // Named properties
   1200   if (HasFastProperties()) {
   1201     info->number_of_objects_with_fast_properties_++;
   1202     info->number_of_fast_used_fields_   += map()->NextFreePropertyIndex();
   1203     info->number_of_fast_unused_fields_ += map()->unused_property_fields();
   1204   } else {
   1205     StringDictionary* dict = property_dictionary();
   1206     info->number_of_slow_used_properties_ += dict->NumberOfElements();
   1207     info->number_of_slow_unused_properties_ +=
   1208         dict->Capacity() - dict->NumberOfElements();
   1209   }
   1210   // Indexed properties
   1211   switch (GetElementsKind()) {
   1212     case FAST_ELEMENTS: {
   1213       info->number_of_objects_with_fast_elements_++;
   1214       int holes = 0;
   1215       FixedArray* e = FixedArray::cast(elements());
   1216       int len = e->length();
   1217       for (int i = 0; i < len; i++) {
   1218         if (e->get(i) == Heap::the_hole_value()) holes++;
   1219       }
   1220       info->number_of_fast_used_elements_   += len - holes;
   1221       info->number_of_fast_unused_elements_ += holes;
   1222       break;
   1223     }
   1224     case PIXEL_ELEMENTS: {
   1225       info->number_of_objects_with_fast_elements_++;
   1226       PixelArray* e = PixelArray::cast(elements());
   1227       info->number_of_fast_used_elements_ += e->length();
   1228       break;
   1229     }
   1230     case DICTIONARY_ELEMENTS: {
   1231       NumberDictionary* dict = element_dictionary();
   1232       info->number_of_slow_used_elements_ += dict->NumberOfElements();
   1233       info->number_of_slow_unused_elements_ +=
   1234           dict->Capacity() - dict->NumberOfElements();
   1235       break;
   1236     }
   1237     default:
   1238       UNREACHABLE();
   1239       break;
   1240   }
   1241 }
   1242 
   1243 
   1244 void JSObject::SpillInformation::Clear() {
   1245   number_of_objects_ = 0;
   1246   number_of_objects_with_fast_properties_ = 0;
   1247   number_of_objects_with_fast_elements_ = 0;
   1248   number_of_fast_used_fields_ = 0;
   1249   number_of_fast_unused_fields_ = 0;
   1250   number_of_slow_used_properties_ = 0;
   1251   number_of_slow_unused_properties_ = 0;
   1252   number_of_fast_used_elements_ = 0;
   1253   number_of_fast_unused_elements_ = 0;
   1254   number_of_slow_used_elements_ = 0;
   1255   number_of_slow_unused_elements_ = 0;
   1256 }
   1257 
   1258 void JSObject::SpillInformation::Print() {
   1259   PrintF("\n  JSObject Spill Statistics (#%d):\n", number_of_objects_);
   1260 
   1261   PrintF("    - fast properties (#%d): %d (used) %d (unused)\n",
   1262          number_of_objects_with_fast_properties_,
   1263          number_of_fast_used_fields_, number_of_fast_unused_fields_);
   1264 
   1265   PrintF("    - slow properties (#%d): %d (used) %d (unused)\n",
   1266          number_of_objects_ - number_of_objects_with_fast_properties_,
   1267          number_of_slow_used_properties_, number_of_slow_unused_properties_);
   1268 
   1269   PrintF("    - fast elements (#%d): %d (used) %d (unused)\n",
   1270          number_of_objects_with_fast_elements_,
   1271          number_of_fast_used_elements_, number_of_fast_unused_elements_);
   1272 
   1273   PrintF("    - slow elements (#%d): %d (used) %d (unused)\n",
   1274          number_of_objects_ - number_of_objects_with_fast_elements_,
   1275          number_of_slow_used_elements_, number_of_slow_unused_elements_);
   1276 
   1277   PrintF("\n");
   1278 }
   1279 
   1280 
   1281 void DescriptorArray::PrintDescriptors() {
   1282   PrintF("Descriptor array  %d\n", number_of_descriptors());
   1283   for (int i = 0; i < number_of_descriptors(); i++) {
   1284     PrintF(" %d: ", i);
   1285     Descriptor desc;
   1286     Get(i, &desc);
   1287     desc.Print();
   1288   }
   1289   PrintF("\n");
   1290 }
   1291 
   1292 
   1293 bool DescriptorArray::IsSortedNoDuplicates() {
   1294   String* current_key = NULL;
   1295   uint32_t current = 0;
   1296   for (int i = 0; i < number_of_descriptors(); i++) {
   1297     String* key = GetKey(i);
   1298     if (key == current_key) {
   1299       PrintDescriptors();
   1300       return false;
   1301     }
   1302     current_key = key;
   1303     uint32_t hash = GetKey(i)->Hash();
   1304     if (hash < current) {
   1305       PrintDescriptors();
   1306       return false;
   1307     }
   1308     current = hash;
   1309   }
   1310   return true;
   1311 }
   1312 
   1313 
   1314 #endif  // DEBUG
   1315 
   1316 } }  // namespace v8::internal
   1317