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 DEBUG
     39 
     40 void MaybeObject::Verify() {
     41   Object* this_as_object;
     42   if (ToObject(&this_as_object)) {
     43     if (this_as_object->IsSmi()) {
     44       Smi::cast(this_as_object)->SmiVerify();
     45     } else {
     46       HeapObject::cast(this_as_object)->HeapObjectVerify();
     47     }
     48   } else {
     49     Failure::cast(this)->FailureVerify();
     50   }
     51 }
     52 
     53 
     54 void Object::VerifyPointer(Object* p) {
     55   if (p->IsHeapObject()) {
     56     HeapObject::VerifyHeapPointer(p);
     57   } else {
     58     ASSERT(p->IsSmi());
     59   }
     60 }
     61 
     62 
     63 void Smi::SmiVerify() {
     64   ASSERT(IsSmi());
     65 }
     66 
     67 
     68 void Failure::FailureVerify() {
     69   ASSERT(IsFailure());
     70 }
     71 
     72 
     73 void HeapObject::HeapObjectVerify() {
     74   InstanceType instance_type = map()->instance_type();
     75 
     76   if (instance_type < FIRST_NONSTRING_TYPE) {
     77     String::cast(this)->StringVerify();
     78     return;
     79   }
     80 
     81   switch (instance_type) {
     82     case MAP_TYPE:
     83       Map::cast(this)->MapVerify();
     84       break;
     85     case HEAP_NUMBER_TYPE:
     86       HeapNumber::cast(this)->HeapNumberVerify();
     87       break;
     88     case FIXED_ARRAY_TYPE:
     89       FixedArray::cast(this)->FixedArrayVerify();
     90       break;
     91     case FIXED_DOUBLE_ARRAY_TYPE:
     92       FixedDoubleArray::cast(this)->FixedDoubleArrayVerify();
     93       break;
     94     case BYTE_ARRAY_TYPE:
     95       ByteArray::cast(this)->ByteArrayVerify();
     96       break;
     97     case FREE_SPACE_TYPE:
     98       FreeSpace::cast(this)->FreeSpaceVerify();
     99       break;
    100     case EXTERNAL_PIXEL_ARRAY_TYPE:
    101       ExternalPixelArray::cast(this)->ExternalPixelArrayVerify();
    102       break;
    103     case EXTERNAL_BYTE_ARRAY_TYPE:
    104       ExternalByteArray::cast(this)->ExternalByteArrayVerify();
    105       break;
    106     case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
    107       ExternalUnsignedByteArray::cast(this)->ExternalUnsignedByteArrayVerify();
    108       break;
    109     case EXTERNAL_SHORT_ARRAY_TYPE:
    110       ExternalShortArray::cast(this)->ExternalShortArrayVerify();
    111       break;
    112     case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
    113       ExternalUnsignedShortArray::cast(this)->
    114           ExternalUnsignedShortArrayVerify();
    115       break;
    116     case EXTERNAL_INT_ARRAY_TYPE:
    117       ExternalIntArray::cast(this)->ExternalIntArrayVerify();
    118       break;
    119     case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
    120       ExternalUnsignedIntArray::cast(this)->ExternalUnsignedIntArrayVerify();
    121       break;
    122     case EXTERNAL_FLOAT_ARRAY_TYPE:
    123       ExternalFloatArray::cast(this)->ExternalFloatArrayVerify();
    124       break;
    125     case EXTERNAL_DOUBLE_ARRAY_TYPE:
    126       ExternalDoubleArray::cast(this)->ExternalDoubleArrayVerify();
    127       break;
    128     case CODE_TYPE:
    129       Code::cast(this)->CodeVerify();
    130       break;
    131     case ODDBALL_TYPE:
    132       Oddball::cast(this)->OddballVerify();
    133       break;
    134     case JS_OBJECT_TYPE:
    135     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
    136       JSObject::cast(this)->JSObjectVerify();
    137       break;
    138     case JS_VALUE_TYPE:
    139       JSValue::cast(this)->JSValueVerify();
    140       break;
    141     case JS_DATE_TYPE:
    142       JSDate::cast(this)->JSDateVerify();
    143       break;
    144     case JS_FUNCTION_TYPE:
    145       JSFunction::cast(this)->JSFunctionVerify();
    146       break;
    147     case JS_GLOBAL_PROXY_TYPE:
    148       JSGlobalProxy::cast(this)->JSGlobalProxyVerify();
    149       break;
    150     case JS_GLOBAL_OBJECT_TYPE:
    151       JSGlobalObject::cast(this)->JSGlobalObjectVerify();
    152       break;
    153     case JS_BUILTINS_OBJECT_TYPE:
    154       JSBuiltinsObject::cast(this)->JSBuiltinsObjectVerify();
    155       break;
    156     case JS_GLOBAL_PROPERTY_CELL_TYPE:
    157       JSGlobalPropertyCell::cast(this)->JSGlobalPropertyCellVerify();
    158       break;
    159     case JS_ARRAY_TYPE:
    160       JSArray::cast(this)->JSArrayVerify();
    161       break;
    162     case JS_SET_TYPE:
    163       JSSet::cast(this)->JSSetVerify();
    164       break;
    165     case JS_MAP_TYPE:
    166       JSMap::cast(this)->JSMapVerify();
    167       break;
    168     case JS_WEAK_MAP_TYPE:
    169       JSWeakMap::cast(this)->JSWeakMapVerify();
    170       break;
    171     case JS_REGEXP_TYPE:
    172       JSRegExp::cast(this)->JSRegExpVerify();
    173       break;
    174     case FILLER_TYPE:
    175       break;
    176     case JS_PROXY_TYPE:
    177       JSProxy::cast(this)->JSProxyVerify();
    178       break;
    179     case JS_FUNCTION_PROXY_TYPE:
    180       JSFunctionProxy::cast(this)->JSFunctionProxyVerify();
    181       break;
    182     case FOREIGN_TYPE:
    183       Foreign::cast(this)->ForeignVerify();
    184       break;
    185     case SHARED_FUNCTION_INFO_TYPE:
    186       SharedFunctionInfo::cast(this)->SharedFunctionInfoVerify();
    187       break;
    188     case JS_MESSAGE_OBJECT_TYPE:
    189       JSMessageObject::cast(this)->JSMessageObjectVerify();
    190       break;
    191 
    192 #define MAKE_STRUCT_CASE(NAME, Name, name) \
    193   case NAME##_TYPE:                        \
    194     Name::cast(this)->Name##Verify();      \
    195     break;
    196     STRUCT_LIST(MAKE_STRUCT_CASE)
    197 #undef MAKE_STRUCT_CASE
    198 
    199     default:
    200       UNREACHABLE();
    201       break;
    202   }
    203 }
    204 
    205 
    206 void HeapObject::VerifyHeapPointer(Object* p) {
    207   ASSERT(p->IsHeapObject());
    208   ASSERT(HEAP->Contains(HeapObject::cast(p)));
    209 }
    210 
    211 
    212 void HeapNumber::HeapNumberVerify() {
    213   ASSERT(IsHeapNumber());
    214 }
    215 
    216 
    217 void ByteArray::ByteArrayVerify() {
    218   ASSERT(IsByteArray());
    219 }
    220 
    221 
    222 void FreeSpace::FreeSpaceVerify() {
    223   ASSERT(IsFreeSpace());
    224 }
    225 
    226 
    227 void ExternalPixelArray::ExternalPixelArrayVerify() {
    228   ASSERT(IsExternalPixelArray());
    229 }
    230 
    231 
    232 void ExternalByteArray::ExternalByteArrayVerify() {
    233   ASSERT(IsExternalByteArray());
    234 }
    235 
    236 
    237 void ExternalUnsignedByteArray::ExternalUnsignedByteArrayVerify() {
    238   ASSERT(IsExternalUnsignedByteArray());
    239 }
    240 
    241 
    242 void ExternalShortArray::ExternalShortArrayVerify() {
    243   ASSERT(IsExternalShortArray());
    244 }
    245 
    246 
    247 void ExternalUnsignedShortArray::ExternalUnsignedShortArrayVerify() {
    248   ASSERT(IsExternalUnsignedShortArray());
    249 }
    250 
    251 
    252 void ExternalIntArray::ExternalIntArrayVerify() {
    253   ASSERT(IsExternalIntArray());
    254 }
    255 
    256 
    257 void ExternalUnsignedIntArray::ExternalUnsignedIntArrayVerify() {
    258   ASSERT(IsExternalUnsignedIntArray());
    259 }
    260 
    261 
    262 void ExternalFloatArray::ExternalFloatArrayVerify() {
    263   ASSERT(IsExternalFloatArray());
    264 }
    265 
    266 
    267 void ExternalDoubleArray::ExternalDoubleArrayVerify() {
    268   ASSERT(IsExternalDoubleArray());
    269 }
    270 
    271 
    272 void JSObject::JSObjectVerify() {
    273   VerifyHeapPointer(properties());
    274   VerifyHeapPointer(elements());
    275 
    276   if (GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS) {
    277     ASSERT(this->elements()->IsFixedArray());
    278     ASSERT(this->elements()->length() >= 2);
    279   }
    280 
    281   if (HasFastProperties()) {
    282     CHECK_EQ(map()->unused_property_fields(),
    283              (map()->inobject_properties() + properties()->length() -
    284               map()->NextFreePropertyIndex()));
    285   }
    286   ASSERT_EQ((map()->has_fast_elements() ||
    287              map()->has_fast_smi_only_elements() ||
    288              (elements() == GetHeap()->empty_fixed_array())),
    289             (elements()->map() == GetHeap()->fixed_array_map() ||
    290              elements()->map() == GetHeap()->fixed_cow_array_map()));
    291   ASSERT(map()->has_fast_elements() == HasFastElements());
    292 }
    293 
    294 
    295 void Map::MapVerify() {
    296   ASSERT(!HEAP->InNewSpace(this));
    297   ASSERT(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
    298   ASSERT(instance_size() == kVariableSizeSentinel ||
    299          (kPointerSize <= instance_size() &&
    300           instance_size() < HEAP->Capacity()));
    301   VerifyHeapPointer(prototype());
    302   VerifyHeapPointer(instance_descriptors());
    303 }
    304 
    305 
    306 void Map::SharedMapVerify() {
    307   MapVerify();
    308   ASSERT(is_shared());
    309   ASSERT(instance_descriptors()->IsEmpty());
    310   ASSERT_EQ(0, pre_allocated_property_fields());
    311   ASSERT_EQ(0, unused_property_fields());
    312   ASSERT_EQ(StaticVisitorBase::GetVisitorId(instance_type(), instance_size()),
    313       visitor_id());
    314 }
    315 
    316 
    317 void CodeCache::CodeCacheVerify() {
    318   VerifyHeapPointer(default_cache());
    319   VerifyHeapPointer(normal_type_cache());
    320   ASSERT(default_cache()->IsFixedArray());
    321   ASSERT(normal_type_cache()->IsUndefined()
    322          || normal_type_cache()->IsCodeCacheHashTable());
    323 }
    324 
    325 
    326 void PolymorphicCodeCache::PolymorphicCodeCacheVerify() {
    327   VerifyHeapPointer(cache());
    328   ASSERT(cache()->IsUndefined() || cache()->IsPolymorphicCodeCacheHashTable());
    329 }
    330 
    331 
    332 void TypeFeedbackInfo::TypeFeedbackInfoVerify() {
    333   VerifyObjectField(kIcTotalCountOffset);
    334   VerifyObjectField(kIcWithTypeinfoCountOffset);
    335   VerifyHeapPointer(type_feedback_cells());
    336 }
    337 
    338 
    339 void AliasedArgumentsEntry::AliasedArgumentsEntryVerify() {
    340   VerifySmiField(kAliasedContextSlot);
    341 }
    342 
    343 
    344 void FixedArray::FixedArrayVerify() {
    345   for (int i = 0; i < length(); i++) {
    346     Object* e = get(i);
    347     if (e->IsHeapObject()) {
    348       VerifyHeapPointer(e);
    349     } else {
    350       e->Verify();
    351     }
    352   }
    353 }
    354 
    355 
    356 void FixedDoubleArray::FixedDoubleArrayVerify() {
    357   for (int i = 0; i < length(); i++) {
    358     if (!is_the_hole(i)) {
    359       double value = get_scalar(i);
    360       ASSERT(!isnan(value) ||
    361              (BitCast<uint64_t>(value) ==
    362               BitCast<uint64_t>(canonical_not_the_hole_nan_as_double())) ||
    363              ((BitCast<uint64_t>(value) & Double::kSignMask) != 0));
    364     }
    365   }
    366 }
    367 
    368 
    369 void JSValue::JSValueVerify() {
    370   Object* v = value();
    371   if (v->IsHeapObject()) {
    372     VerifyHeapPointer(v);
    373   }
    374 }
    375 
    376 
    377 void JSDate::JSDateVerify() {
    378   if (value()->IsHeapObject()) {
    379     VerifyHeapPointer(value());
    380   }
    381   CHECK(value()->IsUndefined() || value()->IsSmi() || value()->IsHeapNumber());
    382   CHECK(year()->IsUndefined() || year()->IsSmi() || year()->IsNaN());
    383   CHECK(month()->IsUndefined() || month()->IsSmi() || month()->IsNaN());
    384   CHECK(day()->IsUndefined() || day()->IsSmi() || day()->IsNaN());
    385   CHECK(weekday()->IsUndefined() || weekday()->IsSmi() || weekday()->IsNaN());
    386   CHECK(hour()->IsUndefined() || hour()->IsSmi() || hour()->IsNaN());
    387   CHECK(min()->IsUndefined() || min()->IsSmi() || min()->IsNaN());
    388   CHECK(sec()->IsUndefined() || sec()->IsSmi() || sec()->IsNaN());
    389   CHECK(cache_stamp()->IsUndefined() ||
    390         cache_stamp()->IsSmi() ||
    391         cache_stamp()->IsNaN());
    392 
    393   if (month()->IsSmi()) {
    394     int month = Smi::cast(this->month())->value();
    395     CHECK(0 <= month && month <= 11);
    396   }
    397   if (day()->IsSmi()) {
    398     int day = Smi::cast(this->day())->value();
    399     CHECK(1 <= day && day <= 31);
    400   }
    401   if (hour()->IsSmi()) {
    402     int hour = Smi::cast(this->hour())->value();
    403     CHECK(0 <= hour && hour <= 23);
    404   }
    405   if (min()->IsSmi()) {
    406     int min = Smi::cast(this->min())->value();
    407     CHECK(0 <= min && min <= 59);
    408   }
    409   if (sec()->IsSmi()) {
    410     int sec = Smi::cast(this->sec())->value();
    411     CHECK(0 <= sec && sec <= 59);
    412   }
    413   if (weekday()->IsSmi()) {
    414     int weekday = Smi::cast(this->weekday())->value();
    415     CHECK(0 <= weekday && weekday <= 6);
    416   }
    417   if (cache_stamp()->IsSmi()) {
    418     CHECK(Smi::cast(cache_stamp())->value() <=
    419           Smi::cast(Isolate::Current()->date_cache()->stamp())->value());
    420   }
    421 }
    422 
    423 
    424 void JSMessageObject::JSMessageObjectVerify() {
    425   CHECK(IsJSMessageObject());
    426   CHECK(type()->IsString());
    427   CHECK(arguments()->IsJSArray());
    428   VerifyObjectField(kStartPositionOffset);
    429   VerifyObjectField(kEndPositionOffset);
    430   VerifyObjectField(kArgumentsOffset);
    431   VerifyObjectField(kScriptOffset);
    432   VerifyObjectField(kStackTraceOffset);
    433   VerifyObjectField(kStackFramesOffset);
    434 }
    435 
    436 
    437 void String::StringVerify() {
    438   CHECK(IsString());
    439   CHECK(length() >= 0 && length() <= Smi::kMaxValue);
    440   if (IsSymbol()) {
    441     CHECK(!HEAP->InNewSpace(this));
    442   }
    443   if (IsConsString()) {
    444     ConsString::cast(this)->ConsStringVerify();
    445   } else if (IsSlicedString()) {
    446     SlicedString::cast(this)->SlicedStringVerify();
    447   }
    448 }
    449 
    450 
    451 void ConsString::ConsStringVerify() {
    452   CHECK(this->first()->IsString());
    453   CHECK(this->second() == GetHeap()->empty_string() ||
    454         this->second()->IsString());
    455   CHECK(this->length() >= ConsString::kMinLength);
    456   if (this->IsFlat()) {
    457     // A flat cons can only be created by String::SlowTryFlatten.
    458     // Afterwards, the first part may be externalized.
    459     CHECK(this->first()->IsSeqString() || this->first()->IsExternalString());
    460   }
    461 }
    462 
    463 
    464 void SlicedString::SlicedStringVerify() {
    465   CHECK(!this->parent()->IsConsString());
    466   CHECK(!this->parent()->IsSlicedString());
    467   CHECK(this->length() >= SlicedString::kMinLength);
    468 }
    469 
    470 
    471 void JSFunction::JSFunctionVerify() {
    472   CHECK(IsJSFunction());
    473   VerifyObjectField(kPrototypeOrInitialMapOffset);
    474   VerifyObjectField(kNextFunctionLinkOffset);
    475   CHECK(code()->IsCode());
    476   CHECK(next_function_link()->IsUndefined() ||
    477         next_function_link()->IsJSFunction());
    478 }
    479 
    480 
    481 void SharedFunctionInfo::SharedFunctionInfoVerify() {
    482   CHECK(IsSharedFunctionInfo());
    483   VerifyObjectField(kNameOffset);
    484   VerifyObjectField(kCodeOffset);
    485   VerifyObjectField(kScopeInfoOffset);
    486   VerifyObjectField(kInstanceClassNameOffset);
    487   VerifyObjectField(kFunctionDataOffset);
    488   VerifyObjectField(kScriptOffset);
    489   VerifyObjectField(kDebugInfoOffset);
    490 }
    491 
    492 
    493 void JSGlobalProxy::JSGlobalProxyVerify() {
    494   CHECK(IsJSGlobalProxy());
    495   JSObjectVerify();
    496   VerifyObjectField(JSGlobalProxy::kContextOffset);
    497   // Make sure that this object has no properties, elements.
    498   CHECK_EQ(0, properties()->length());
    499   CHECK(HasFastElements());
    500   CHECK_EQ(0, FixedArray::cast(elements())->length());
    501 }
    502 
    503 
    504 void JSGlobalObject::JSGlobalObjectVerify() {
    505   CHECK(IsJSGlobalObject());
    506   JSObjectVerify();
    507   for (int i = GlobalObject::kBuiltinsOffset;
    508        i < JSGlobalObject::kSize;
    509        i += kPointerSize) {
    510     VerifyObjectField(i);
    511   }
    512 }
    513 
    514 
    515 void JSBuiltinsObject::JSBuiltinsObjectVerify() {
    516   CHECK(IsJSBuiltinsObject());
    517   JSObjectVerify();
    518   for (int i = GlobalObject::kBuiltinsOffset;
    519        i < JSBuiltinsObject::kSize;
    520        i += kPointerSize) {
    521     VerifyObjectField(i);
    522   }
    523 }
    524 
    525 
    526 void Oddball::OddballVerify() {
    527   CHECK(IsOddball());
    528   VerifyHeapPointer(to_string());
    529   Object* number = to_number();
    530   if (number->IsHeapObject()) {
    531     ASSERT(number == HEAP->nan_value());
    532   } else {
    533     ASSERT(number->IsSmi());
    534     int value = Smi::cast(number)->value();
    535     // Hidden oddballs have negative smis.
    536     const int kLeastHiddenOddballNumber = -4;
    537     ASSERT(value <= 1);
    538     ASSERT(value >= kLeastHiddenOddballNumber);
    539   }
    540 }
    541 
    542 
    543 void JSGlobalPropertyCell::JSGlobalPropertyCellVerify() {
    544   CHECK(IsJSGlobalPropertyCell());
    545   VerifyObjectField(kValueOffset);
    546 }
    547 
    548 
    549 void Code::CodeVerify() {
    550   CHECK(IsAligned(reinterpret_cast<intptr_t>(instruction_start()),
    551                   kCodeAlignment));
    552   relocation_info()->Verify();
    553   Address last_gc_pc = NULL;
    554   for (RelocIterator it(this); !it.done(); it.next()) {
    555     it.rinfo()->Verify();
    556     // Ensure that GC will not iterate twice over the same pointer.
    557     if (RelocInfo::IsGCRelocMode(it.rinfo()->rmode())) {
    558       CHECK(it.rinfo()->pc() != last_gc_pc);
    559       last_gc_pc = it.rinfo()->pc();
    560     }
    561   }
    562 }
    563 
    564 
    565 void JSArray::JSArrayVerify() {
    566   JSObjectVerify();
    567   ASSERT(length()->IsNumber() || length()->IsUndefined());
    568   ASSERT(elements()->IsUndefined() ||
    569          elements()->IsFixedArray() ||
    570          elements()->IsFixedDoubleArray());
    571 }
    572 
    573 
    574 void JSSet::JSSetVerify() {
    575   CHECK(IsJSSet());
    576   JSObjectVerify();
    577   VerifyHeapPointer(table());
    578   ASSERT(table()->IsHashTable() || table()->IsUndefined());
    579 }
    580 
    581 
    582 void JSMap::JSMapVerify() {
    583   CHECK(IsJSMap());
    584   JSObjectVerify();
    585   VerifyHeapPointer(table());
    586   ASSERT(table()->IsHashTable() || table()->IsUndefined());
    587 }
    588 
    589 
    590 void JSWeakMap::JSWeakMapVerify() {
    591   CHECK(IsJSWeakMap());
    592   JSObjectVerify();
    593   VerifyHeapPointer(table());
    594   ASSERT(table()->IsHashTable() || table()->IsUndefined());
    595 }
    596 
    597 
    598 void JSRegExp::JSRegExpVerify() {
    599   JSObjectVerify();
    600   ASSERT(data()->IsUndefined() || data()->IsFixedArray());
    601   switch (TypeTag()) {
    602     case JSRegExp::ATOM: {
    603       FixedArray* arr = FixedArray::cast(data());
    604       ASSERT(arr->get(JSRegExp::kAtomPatternIndex)->IsString());
    605       break;
    606     }
    607     case JSRegExp::IRREGEXP: {
    608       bool is_native = RegExpImpl::UsesNativeRegExp();
    609 
    610       FixedArray* arr = FixedArray::cast(data());
    611       Object* ascii_data = arr->get(JSRegExp::kIrregexpASCIICodeIndex);
    612       // Smi : Not compiled yet (-1) or code prepared for flushing.
    613       // JSObject: Compilation error.
    614       // Code/ByteArray: Compiled code.
    615       ASSERT(ascii_data->IsSmi() ||
    616              (is_native ? ascii_data->IsCode() : ascii_data->IsByteArray()));
    617       Object* uc16_data = arr->get(JSRegExp::kIrregexpUC16CodeIndex);
    618       ASSERT(uc16_data->IsSmi() ||
    619              (is_native ? uc16_data->IsCode() : uc16_data->IsByteArray()));
    620 
    621       Object* ascii_saved = arr->get(JSRegExp::kIrregexpASCIICodeSavedIndex);
    622       ASSERT(ascii_saved->IsSmi() || ascii_saved->IsString() ||
    623              ascii_saved->IsCode());
    624       Object* uc16_saved = arr->get(JSRegExp::kIrregexpUC16CodeSavedIndex);
    625       ASSERT(uc16_saved->IsSmi() || uc16_saved->IsString() ||
    626              uc16_saved->IsCode());
    627 
    628       ASSERT(arr->get(JSRegExp::kIrregexpCaptureCountIndex)->IsSmi());
    629       ASSERT(arr->get(JSRegExp::kIrregexpMaxRegisterCountIndex)->IsSmi());
    630       break;
    631     }
    632     default:
    633       ASSERT_EQ(JSRegExp::NOT_COMPILED, TypeTag());
    634       ASSERT(data()->IsUndefined());
    635       break;
    636   }
    637 }
    638 
    639 
    640 void JSProxy::JSProxyVerify() {
    641   CHECK(IsJSProxy());
    642   VerifyPointer(handler());
    643   ASSERT(hash()->IsSmi() || hash()->IsUndefined());
    644 }
    645 
    646 
    647 void JSFunctionProxy::JSFunctionProxyVerify() {
    648   CHECK(IsJSFunctionProxy());
    649   JSProxyVerify();
    650   VerifyPointer(call_trap());
    651   VerifyPointer(construct_trap());
    652 }
    653 
    654 
    655 void Foreign::ForeignVerify() {
    656   ASSERT(IsForeign());
    657 }
    658 
    659 
    660 void AccessorInfo::AccessorInfoVerify() {
    661   CHECK(IsAccessorInfo());
    662   VerifyPointer(getter());
    663   VerifyPointer(setter());
    664   VerifyPointer(name());
    665   VerifyPointer(data());
    666   VerifyPointer(flag());
    667 }
    668 
    669 
    670 void AccessorPair::AccessorPairVerify() {
    671   CHECK(IsAccessorPair());
    672   VerifyPointer(getter());
    673   VerifyPointer(setter());
    674 }
    675 
    676 
    677 void AccessCheckInfo::AccessCheckInfoVerify() {
    678   CHECK(IsAccessCheckInfo());
    679   VerifyPointer(named_callback());
    680   VerifyPointer(indexed_callback());
    681   VerifyPointer(data());
    682 }
    683 
    684 
    685 void InterceptorInfo::InterceptorInfoVerify() {
    686   CHECK(IsInterceptorInfo());
    687   VerifyPointer(getter());
    688   VerifyPointer(setter());
    689   VerifyPointer(query());
    690   VerifyPointer(deleter());
    691   VerifyPointer(enumerator());
    692   VerifyPointer(data());
    693 }
    694 
    695 
    696 void CallHandlerInfo::CallHandlerInfoVerify() {
    697   CHECK(IsCallHandlerInfo());
    698   VerifyPointer(callback());
    699   VerifyPointer(data());
    700 }
    701 
    702 
    703 void TemplateInfo::TemplateInfoVerify() {
    704   VerifyPointer(tag());
    705   VerifyPointer(property_list());
    706 }
    707 
    708 void FunctionTemplateInfo::FunctionTemplateInfoVerify() {
    709   CHECK(IsFunctionTemplateInfo());
    710   TemplateInfoVerify();
    711   VerifyPointer(serial_number());
    712   VerifyPointer(call_code());
    713   VerifyPointer(property_accessors());
    714   VerifyPointer(prototype_template());
    715   VerifyPointer(parent_template());
    716   VerifyPointer(named_property_handler());
    717   VerifyPointer(indexed_property_handler());
    718   VerifyPointer(instance_template());
    719   VerifyPointer(signature());
    720   VerifyPointer(access_check_info());
    721 }
    722 
    723 
    724 void ObjectTemplateInfo::ObjectTemplateInfoVerify() {
    725   CHECK(IsObjectTemplateInfo());
    726   TemplateInfoVerify();
    727   VerifyPointer(constructor());
    728   VerifyPointer(internal_field_count());
    729 }
    730 
    731 
    732 void SignatureInfo::SignatureInfoVerify() {
    733   CHECK(IsSignatureInfo());
    734   VerifyPointer(receiver());
    735   VerifyPointer(args());
    736 }
    737 
    738 
    739 void TypeSwitchInfo::TypeSwitchInfoVerify() {
    740   CHECK(IsTypeSwitchInfo());
    741   VerifyPointer(types());
    742 }
    743 
    744 
    745 void Script::ScriptVerify() {
    746   CHECK(IsScript());
    747   VerifyPointer(source());
    748   VerifyPointer(name());
    749   line_offset()->SmiVerify();
    750   column_offset()->SmiVerify();
    751   VerifyPointer(data());
    752   VerifyPointer(wrapper());
    753   type()->SmiVerify();
    754   VerifyPointer(line_ends());
    755   VerifyPointer(id());
    756 }
    757 
    758 
    759 #ifdef ENABLE_DEBUGGER_SUPPORT
    760 void DebugInfo::DebugInfoVerify() {
    761   CHECK(IsDebugInfo());
    762   VerifyPointer(shared());
    763   VerifyPointer(original_code());
    764   VerifyPointer(code());
    765   VerifyPointer(break_points());
    766 }
    767 
    768 
    769 void BreakPointInfo::BreakPointInfoVerify() {
    770   CHECK(IsBreakPointInfo());
    771   code_position()->SmiVerify();
    772   source_position()->SmiVerify();
    773   statement_position()->SmiVerify();
    774   VerifyPointer(break_point_objects());
    775 }
    776 #endif  // ENABLE_DEBUGGER_SUPPORT
    777 
    778 
    779 void JSObject::IncrementSpillStatistics(SpillInformation* info) {
    780   info->number_of_objects_++;
    781   // Named properties
    782   if (HasFastProperties()) {
    783     info->number_of_objects_with_fast_properties_++;
    784     info->number_of_fast_used_fields_   += map()->NextFreePropertyIndex();
    785     info->number_of_fast_unused_fields_ += map()->unused_property_fields();
    786   } else {
    787     StringDictionary* dict = property_dictionary();
    788     info->number_of_slow_used_properties_ += dict->NumberOfElements();
    789     info->number_of_slow_unused_properties_ +=
    790         dict->Capacity() - dict->NumberOfElements();
    791   }
    792   // Indexed properties
    793   switch (GetElementsKind()) {
    794     case FAST_ELEMENTS: {
    795       info->number_of_objects_with_fast_elements_++;
    796       int holes = 0;
    797       FixedArray* e = FixedArray::cast(elements());
    798       int len = e->length();
    799       Heap* heap = HEAP;
    800       for (int i = 0; i < len; i++) {
    801         if (e->get(i) == heap->the_hole_value()) holes++;
    802       }
    803       info->number_of_fast_used_elements_   += len - holes;
    804       info->number_of_fast_unused_elements_ += holes;
    805       break;
    806     }
    807     case EXTERNAL_PIXEL_ELEMENTS: {
    808       info->number_of_objects_with_fast_elements_++;
    809       ExternalPixelArray* e = ExternalPixelArray::cast(elements());
    810       info->number_of_fast_used_elements_ += e->length();
    811       break;
    812     }
    813     case DICTIONARY_ELEMENTS: {
    814       SeededNumberDictionary* dict = element_dictionary();
    815       info->number_of_slow_used_elements_ += dict->NumberOfElements();
    816       info->number_of_slow_unused_elements_ +=
    817           dict->Capacity() - dict->NumberOfElements();
    818       break;
    819     }
    820     default:
    821       UNREACHABLE();
    822       break;
    823   }
    824 }
    825 
    826 
    827 void JSObject::SpillInformation::Clear() {
    828   number_of_objects_ = 0;
    829   number_of_objects_with_fast_properties_ = 0;
    830   number_of_objects_with_fast_elements_ = 0;
    831   number_of_fast_used_fields_ = 0;
    832   number_of_fast_unused_fields_ = 0;
    833   number_of_slow_used_properties_ = 0;
    834   number_of_slow_unused_properties_ = 0;
    835   number_of_fast_used_elements_ = 0;
    836   number_of_fast_unused_elements_ = 0;
    837   number_of_slow_used_elements_ = 0;
    838   number_of_slow_unused_elements_ = 0;
    839 }
    840 
    841 void JSObject::SpillInformation::Print() {
    842   PrintF("\n  JSObject Spill Statistics (#%d):\n", number_of_objects_);
    843 
    844   PrintF("    - fast properties (#%d): %d (used) %d (unused)\n",
    845          number_of_objects_with_fast_properties_,
    846          number_of_fast_used_fields_, number_of_fast_unused_fields_);
    847 
    848   PrintF("    - slow properties (#%d): %d (used) %d (unused)\n",
    849          number_of_objects_ - number_of_objects_with_fast_properties_,
    850          number_of_slow_used_properties_, number_of_slow_unused_properties_);
    851 
    852   PrintF("    - fast elements (#%d): %d (used) %d (unused)\n",
    853          number_of_objects_with_fast_elements_,
    854          number_of_fast_used_elements_, number_of_fast_unused_elements_);
    855 
    856   PrintF("    - slow elements (#%d): %d (used) %d (unused)\n",
    857          number_of_objects_ - number_of_objects_with_fast_elements_,
    858          number_of_slow_used_elements_, number_of_slow_unused_elements_);
    859 
    860   PrintF("\n");
    861 }
    862 
    863 
    864 bool DescriptorArray::IsSortedNoDuplicates() {
    865   String* current_key = NULL;
    866   uint32_t current = 0;
    867   for (int i = 0; i < number_of_descriptors(); i++) {
    868     String* key = GetKey(i);
    869     if (key == current_key) {
    870       PrintDescriptors();
    871       return false;
    872     }
    873     current_key = key;
    874     uint32_t hash = GetKey(i)->Hash();
    875     if (hash < current) {
    876       PrintDescriptors();
    877       return false;
    878     }
    879     current = hash;
    880   }
    881   return true;
    882 }
    883 
    884 
    885 void JSFunctionResultCache::JSFunctionResultCacheVerify() {
    886   JSFunction::cast(get(kFactoryIndex))->Verify();
    887 
    888   int size = Smi::cast(get(kCacheSizeIndex))->value();
    889   ASSERT(kEntriesIndex <= size);
    890   ASSERT(size <= length());
    891   ASSERT_EQ(0, size % kEntrySize);
    892 
    893   int finger = Smi::cast(get(kFingerIndex))->value();
    894   ASSERT(kEntriesIndex <= finger);
    895   ASSERT((finger < size) || (finger == kEntriesIndex && finger == size));
    896   ASSERT_EQ(0, finger % kEntrySize);
    897 
    898   if (FLAG_enable_slow_asserts) {
    899     for (int i = kEntriesIndex; i < size; i++) {
    900       ASSERT(!get(i)->IsTheHole());
    901       get(i)->Verify();
    902     }
    903     for (int i = size; i < length(); i++) {
    904       ASSERT(get(i)->IsTheHole());
    905       get(i)->Verify();
    906     }
    907   }
    908 }
    909 
    910 
    911 void NormalizedMapCache::NormalizedMapCacheVerify() {
    912   FixedArray::cast(this)->Verify();
    913   if (FLAG_enable_slow_asserts) {
    914     for (int i = 0; i < length(); i++) {
    915       Object* e = get(i);
    916       if (e->IsMap()) {
    917         Map::cast(e)->SharedMapVerify();
    918       } else {
    919         ASSERT(e->IsUndefined());
    920       }
    921     }
    922   }
    923 }
    924 
    925 
    926 #endif  // DEBUG
    927 
    928 } }  // namespace v8::internal
    929