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 "macro-assembler.h"
     34 #include "objects-visiting.h"
     35 
     36 namespace v8 {
     37 namespace internal {
     38 
     39 #ifdef VERIFY_HEAP
     40 
     41 void MaybeObject::Verify() {
     42   Object* this_as_object;
     43   if (ToObject(&this_as_object)) {
     44     if (this_as_object->IsSmi()) {
     45       Smi::cast(this_as_object)->SmiVerify();
     46     } else {
     47       HeapObject::cast(this_as_object)->HeapObjectVerify();
     48     }
     49   } else {
     50     Failure::cast(this)->FailureVerify();
     51   }
     52 }
     53 
     54 
     55 void Object::VerifyPointer(Object* p) {
     56   if (p->IsHeapObject()) {
     57     HeapObject::VerifyHeapPointer(p);
     58   } else {
     59     CHECK(p->IsSmi());
     60   }
     61 }
     62 
     63 
     64 void Smi::SmiVerify() {
     65   CHECK(IsSmi());
     66 }
     67 
     68 
     69 void Failure::FailureVerify() {
     70   CHECK(IsFailure());
     71 }
     72 
     73 
     74 void HeapObject::HeapObjectVerify() {
     75   InstanceType instance_type = map()->instance_type();
     76 
     77   if (instance_type < FIRST_NONSTRING_TYPE) {
     78     String::cast(this)->StringVerify();
     79     return;
     80   }
     81 
     82   switch (instance_type) {
     83     case SYMBOL_TYPE:
     84       Symbol::cast(this)->SymbolVerify();
     85       break;
     86     case MAP_TYPE:
     87       Map::cast(this)->MapVerify();
     88       break;
     89     case HEAP_NUMBER_TYPE:
     90       HeapNumber::cast(this)->HeapNumberVerify();
     91       break;
     92     case FIXED_ARRAY_TYPE:
     93       FixedArray::cast(this)->FixedArrayVerify();
     94       break;
     95     case FIXED_DOUBLE_ARRAY_TYPE:
     96       FixedDoubleArray::cast(this)->FixedDoubleArrayVerify();
     97       break;
     98     case BYTE_ARRAY_TYPE:
     99       ByteArray::cast(this)->ByteArrayVerify();
    100       break;
    101     case FREE_SPACE_TYPE:
    102       FreeSpace::cast(this)->FreeSpaceVerify();
    103       break;
    104     case EXTERNAL_PIXEL_ARRAY_TYPE:
    105       ExternalPixelArray::cast(this)->ExternalPixelArrayVerify();
    106       break;
    107     case EXTERNAL_BYTE_ARRAY_TYPE:
    108       ExternalByteArray::cast(this)->ExternalByteArrayVerify();
    109       break;
    110     case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
    111       ExternalUnsignedByteArray::cast(this)->ExternalUnsignedByteArrayVerify();
    112       break;
    113     case EXTERNAL_SHORT_ARRAY_TYPE:
    114       ExternalShortArray::cast(this)->ExternalShortArrayVerify();
    115       break;
    116     case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
    117       ExternalUnsignedShortArray::cast(this)->
    118           ExternalUnsignedShortArrayVerify();
    119       break;
    120     case EXTERNAL_INT_ARRAY_TYPE:
    121       ExternalIntArray::cast(this)->ExternalIntArrayVerify();
    122       break;
    123     case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
    124       ExternalUnsignedIntArray::cast(this)->ExternalUnsignedIntArrayVerify();
    125       break;
    126     case EXTERNAL_FLOAT_ARRAY_TYPE:
    127       ExternalFloatArray::cast(this)->ExternalFloatArrayVerify();
    128       break;
    129     case EXTERNAL_DOUBLE_ARRAY_TYPE:
    130       ExternalDoubleArray::cast(this)->ExternalDoubleArrayVerify();
    131       break;
    132     case CODE_TYPE:
    133       Code::cast(this)->CodeVerify();
    134       break;
    135     case ODDBALL_TYPE:
    136       Oddball::cast(this)->OddballVerify();
    137       break;
    138     case JS_OBJECT_TYPE:
    139     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
    140       JSObject::cast(this)->JSObjectVerify();
    141       break;
    142     case JS_GENERATOR_OBJECT_TYPE:
    143       JSGeneratorObject::cast(this)->JSGeneratorObjectVerify();
    144       break;
    145     case JS_MODULE_TYPE:
    146       JSModule::cast(this)->JSModuleVerify();
    147       break;
    148     case JS_VALUE_TYPE:
    149       JSValue::cast(this)->JSValueVerify();
    150       break;
    151     case JS_DATE_TYPE:
    152       JSDate::cast(this)->JSDateVerify();
    153       break;
    154     case JS_FUNCTION_TYPE:
    155       JSFunction::cast(this)->JSFunctionVerify();
    156       break;
    157     case JS_GLOBAL_PROXY_TYPE:
    158       JSGlobalProxy::cast(this)->JSGlobalProxyVerify();
    159       break;
    160     case JS_GLOBAL_OBJECT_TYPE:
    161       JSGlobalObject::cast(this)->JSGlobalObjectVerify();
    162       break;
    163     case JS_BUILTINS_OBJECT_TYPE:
    164       JSBuiltinsObject::cast(this)->JSBuiltinsObjectVerify();
    165       break;
    166     case CELL_TYPE:
    167       Cell::cast(this)->CellVerify();
    168       break;
    169     case PROPERTY_CELL_TYPE:
    170       PropertyCell::cast(this)->PropertyCellVerify();
    171       break;
    172     case JS_ARRAY_TYPE:
    173       JSArray::cast(this)->JSArrayVerify();
    174       break;
    175     case JS_SET_TYPE:
    176       JSSet::cast(this)->JSSetVerify();
    177       break;
    178     case JS_MAP_TYPE:
    179       JSMap::cast(this)->JSMapVerify();
    180       break;
    181     case JS_WEAK_MAP_TYPE:
    182       JSWeakMap::cast(this)->JSWeakMapVerify();
    183       break;
    184     case JS_WEAK_SET_TYPE:
    185       JSWeakSet::cast(this)->JSWeakSetVerify();
    186       break;
    187     case JS_REGEXP_TYPE:
    188       JSRegExp::cast(this)->JSRegExpVerify();
    189       break;
    190     case FILLER_TYPE:
    191       break;
    192     case JS_PROXY_TYPE:
    193       JSProxy::cast(this)->JSProxyVerify();
    194       break;
    195     case JS_FUNCTION_PROXY_TYPE:
    196       JSFunctionProxy::cast(this)->JSFunctionProxyVerify();
    197       break;
    198     case FOREIGN_TYPE:
    199       Foreign::cast(this)->ForeignVerify();
    200       break;
    201     case SHARED_FUNCTION_INFO_TYPE:
    202       SharedFunctionInfo::cast(this)->SharedFunctionInfoVerify();
    203       break;
    204     case JS_MESSAGE_OBJECT_TYPE:
    205       JSMessageObject::cast(this)->JSMessageObjectVerify();
    206       break;
    207     case JS_ARRAY_BUFFER_TYPE:
    208       JSArrayBuffer::cast(this)->JSArrayBufferVerify();
    209       break;
    210     case JS_TYPED_ARRAY_TYPE:
    211       JSTypedArray::cast(this)->JSTypedArrayVerify();
    212       break;
    213     case JS_DATA_VIEW_TYPE:
    214       JSDataView::cast(this)->JSDataViewVerify();
    215       break;
    216 
    217 #define MAKE_STRUCT_CASE(NAME, Name, name) \
    218   case NAME##_TYPE:                        \
    219     Name::cast(this)->Name##Verify();      \
    220     break;
    221     STRUCT_LIST(MAKE_STRUCT_CASE)
    222 #undef MAKE_STRUCT_CASE
    223 
    224     default:
    225       UNREACHABLE();
    226       break;
    227   }
    228 }
    229 
    230 
    231 void HeapObject::VerifyHeapPointer(Object* p) {
    232   CHECK(p->IsHeapObject());
    233   CHECK(HEAP->Contains(HeapObject::cast(p)));
    234 }
    235 
    236 
    237 void Symbol::SymbolVerify() {
    238   CHECK(IsSymbol());
    239   CHECK(HasHashCode());
    240   CHECK_GT(Hash(), 0);
    241   CHECK(name()->IsUndefined() || name()->IsString());
    242 }
    243 
    244 
    245 void HeapNumber::HeapNumberVerify() {
    246   CHECK(IsHeapNumber());
    247 }
    248 
    249 
    250 void ByteArray::ByteArrayVerify() {
    251   CHECK(IsByteArray());
    252 }
    253 
    254 
    255 void FreeSpace::FreeSpaceVerify() {
    256   CHECK(IsFreeSpace());
    257 }
    258 
    259 
    260 void ExternalPixelArray::ExternalPixelArrayVerify() {
    261   CHECK(IsExternalPixelArray());
    262 }
    263 
    264 
    265 void ExternalByteArray::ExternalByteArrayVerify() {
    266   CHECK(IsExternalByteArray());
    267 }
    268 
    269 
    270 void ExternalUnsignedByteArray::ExternalUnsignedByteArrayVerify() {
    271   CHECK(IsExternalUnsignedByteArray());
    272 }
    273 
    274 
    275 void ExternalShortArray::ExternalShortArrayVerify() {
    276   CHECK(IsExternalShortArray());
    277 }
    278 
    279 
    280 void ExternalUnsignedShortArray::ExternalUnsignedShortArrayVerify() {
    281   CHECK(IsExternalUnsignedShortArray());
    282 }
    283 
    284 
    285 void ExternalIntArray::ExternalIntArrayVerify() {
    286   CHECK(IsExternalIntArray());
    287 }
    288 
    289 
    290 void ExternalUnsignedIntArray::ExternalUnsignedIntArrayVerify() {
    291   CHECK(IsExternalUnsignedIntArray());
    292 }
    293 
    294 
    295 void ExternalFloatArray::ExternalFloatArrayVerify() {
    296   CHECK(IsExternalFloatArray());
    297 }
    298 
    299 
    300 void ExternalDoubleArray::ExternalDoubleArrayVerify() {
    301   CHECK(IsExternalDoubleArray());
    302 }
    303 
    304 
    305 void JSObject::JSObjectVerify() {
    306   VerifyHeapPointer(properties());
    307   VerifyHeapPointer(elements());
    308 
    309   if (GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS) {
    310     CHECK(this->elements()->IsFixedArray());
    311     CHECK_GE(this->elements()->length(), 2);
    312   }
    313 
    314   if (HasFastProperties()) {
    315     CHECK_EQ(map()->unused_property_fields(),
    316              (map()->inobject_properties() + properties()->length() -
    317               map()->NextFreePropertyIndex()));
    318     DescriptorArray* descriptors = map()->instance_descriptors();
    319     for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) {
    320       if (descriptors->GetDetails(i).type() == FIELD) {
    321         Representation r = descriptors->GetDetails(i).representation();
    322         int field = descriptors->GetFieldIndex(i);
    323         Object* value = RawFastPropertyAt(field);
    324         if (r.IsDouble()) ASSERT(value->IsHeapNumber());
    325         if (value->IsUninitialized()) continue;
    326         if (r.IsSmi()) ASSERT(value->IsSmi());
    327         if (r.IsHeapObject()) ASSERT(value->IsHeapObject());
    328       }
    329     }
    330   }
    331   CHECK_EQ((map()->has_fast_smi_or_object_elements() ||
    332              (elements() == GetHeap()->empty_fixed_array())),
    333             (elements()->map() == GetHeap()->fixed_array_map() ||
    334              elements()->map() == GetHeap()->fixed_cow_array_map()));
    335   CHECK(map()->has_fast_object_elements() == HasFastObjectElements());
    336 }
    337 
    338 
    339 void Map::MapVerify() {
    340   CHECK(!HEAP->InNewSpace(this));
    341   CHECK(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
    342   CHECK(instance_size() == kVariableSizeSentinel ||
    343          (kPointerSize <= instance_size() &&
    344           instance_size() < HEAP->Capacity()));
    345   VerifyHeapPointer(prototype());
    346   VerifyHeapPointer(instance_descriptors());
    347   SLOW_ASSERT(instance_descriptors()->IsSortedNoDuplicates());
    348   if (HasTransitionArray()) {
    349     SLOW_ASSERT(transitions()->IsSortedNoDuplicates());
    350     SLOW_ASSERT(transitions()->IsConsistentWithBackPointers(this));
    351   }
    352   ASSERT(!is_observed() || instance_type() < FIRST_JS_OBJECT_TYPE ||
    353          instance_type() > LAST_JS_OBJECT_TYPE ||
    354          has_slow_elements_kind() || has_external_array_elements());
    355 }
    356 
    357 
    358 void Map::SharedMapVerify() {
    359   MapVerify();
    360   CHECK(is_shared());
    361   CHECK(instance_descriptors()->IsEmpty());
    362   CHECK_EQ(0, pre_allocated_property_fields());
    363   CHECK_EQ(0, unused_property_fields());
    364   CHECK_EQ(StaticVisitorBase::GetVisitorId(instance_type(), instance_size()),
    365       visitor_id());
    366 }
    367 
    368 
    369 void Map::VerifyOmittedMapChecks() {
    370   if (!FLAG_omit_map_checks_for_leaf_maps) return;
    371   if (!is_stable() ||
    372       is_deprecated() ||
    373       HasTransitionArray() ||
    374       is_dictionary_map()) {
    375     CHECK_EQ(0, dependent_code()->number_of_entries(
    376         DependentCode::kPrototypeCheckGroup));
    377   }
    378 }
    379 
    380 
    381 void CodeCache::CodeCacheVerify() {
    382   VerifyHeapPointer(default_cache());
    383   VerifyHeapPointer(normal_type_cache());
    384   CHECK(default_cache()->IsFixedArray());
    385   CHECK(normal_type_cache()->IsUndefined()
    386          || normal_type_cache()->IsCodeCacheHashTable());
    387 }
    388 
    389 
    390 void PolymorphicCodeCache::PolymorphicCodeCacheVerify() {
    391   VerifyHeapPointer(cache());
    392   CHECK(cache()->IsUndefined() || cache()->IsPolymorphicCodeCacheHashTable());
    393 }
    394 
    395 
    396 void TypeFeedbackInfo::TypeFeedbackInfoVerify() {
    397   VerifyObjectField(kStorage1Offset);
    398   VerifyObjectField(kStorage2Offset);
    399   VerifyHeapPointer(type_feedback_cells());
    400 }
    401 
    402 
    403 void AliasedArgumentsEntry::AliasedArgumentsEntryVerify() {
    404   VerifySmiField(kAliasedContextSlot);
    405 }
    406 
    407 
    408 void FixedArray::FixedArrayVerify() {
    409   for (int i = 0; i < length(); i++) {
    410     Object* e = get(i);
    411     if (e->IsHeapObject()) {
    412       VerifyHeapPointer(e);
    413     } else {
    414       e->Verify();
    415     }
    416   }
    417 }
    418 
    419 
    420 void FixedDoubleArray::FixedDoubleArrayVerify() {
    421   for (int i = 0; i < length(); i++) {
    422     if (!is_the_hole(i)) {
    423       double value = get_scalar(i);
    424       CHECK(!std::isnan(value) ||
    425              (BitCast<uint64_t>(value) ==
    426               BitCast<uint64_t>(canonical_not_the_hole_nan_as_double())) ||
    427              ((BitCast<uint64_t>(value) & Double::kSignMask) != 0));
    428     }
    429   }
    430 }
    431 
    432 
    433 void JSGeneratorObject::JSGeneratorObjectVerify() {
    434   // In an expression like "new g()", there can be a point where a generator
    435   // object is allocated but its fields are all undefined, as it hasn't yet been
    436   // initialized by the generator.  Hence these weak checks.
    437   VerifyObjectField(kFunctionOffset);
    438   VerifyObjectField(kContextOffset);
    439   VerifyObjectField(kReceiverOffset);
    440   VerifyObjectField(kOperandStackOffset);
    441   VerifyObjectField(kContinuationOffset);
    442   VerifyObjectField(kStackHandlerIndexOffset);
    443 }
    444 
    445 
    446 void JSModule::JSModuleVerify() {
    447   VerifyObjectField(kContextOffset);
    448   VerifyObjectField(kScopeInfoOffset);
    449   CHECK(context()->IsUndefined() ||
    450         Context::cast(context())->IsModuleContext());
    451 }
    452 
    453 
    454 void JSValue::JSValueVerify() {
    455   Object* v = value();
    456   if (v->IsHeapObject()) {
    457     VerifyHeapPointer(v);
    458   }
    459 }
    460 
    461 
    462 void JSDate::JSDateVerify() {
    463   if (value()->IsHeapObject()) {
    464     VerifyHeapPointer(value());
    465   }
    466   CHECK(value()->IsUndefined() || value()->IsSmi() || value()->IsHeapNumber());
    467   CHECK(year()->IsUndefined() || year()->IsSmi() || year()->IsNaN());
    468   CHECK(month()->IsUndefined() || month()->IsSmi() || month()->IsNaN());
    469   CHECK(day()->IsUndefined() || day()->IsSmi() || day()->IsNaN());
    470   CHECK(weekday()->IsUndefined() || weekday()->IsSmi() || weekday()->IsNaN());
    471   CHECK(hour()->IsUndefined() || hour()->IsSmi() || hour()->IsNaN());
    472   CHECK(min()->IsUndefined() || min()->IsSmi() || min()->IsNaN());
    473   CHECK(sec()->IsUndefined() || sec()->IsSmi() || sec()->IsNaN());
    474   CHECK(cache_stamp()->IsUndefined() ||
    475         cache_stamp()->IsSmi() ||
    476         cache_stamp()->IsNaN());
    477 
    478   if (month()->IsSmi()) {
    479     int month = Smi::cast(this->month())->value();
    480     CHECK(0 <= month && month <= 11);
    481   }
    482   if (day()->IsSmi()) {
    483     int day = Smi::cast(this->day())->value();
    484     CHECK(1 <= day && day <= 31);
    485   }
    486   if (hour()->IsSmi()) {
    487     int hour = Smi::cast(this->hour())->value();
    488     CHECK(0 <= hour && hour <= 23);
    489   }
    490   if (min()->IsSmi()) {
    491     int min = Smi::cast(this->min())->value();
    492     CHECK(0 <= min && min <= 59);
    493   }
    494   if (sec()->IsSmi()) {
    495     int sec = Smi::cast(this->sec())->value();
    496     CHECK(0 <= sec && sec <= 59);
    497   }
    498   if (weekday()->IsSmi()) {
    499     int weekday = Smi::cast(this->weekday())->value();
    500     CHECK(0 <= weekday && weekday <= 6);
    501   }
    502   if (cache_stamp()->IsSmi()) {
    503     CHECK(Smi::cast(cache_stamp())->value() <=
    504           Smi::cast(Isolate::Current()->date_cache()->stamp())->value());
    505   }
    506 }
    507 
    508 
    509 void JSMessageObject::JSMessageObjectVerify() {
    510   CHECK(IsJSMessageObject());
    511   CHECK(type()->IsString());
    512   CHECK(arguments()->IsJSArray());
    513   VerifyObjectField(kStartPositionOffset);
    514   VerifyObjectField(kEndPositionOffset);
    515   VerifyObjectField(kArgumentsOffset);
    516   VerifyObjectField(kScriptOffset);
    517   VerifyObjectField(kStackTraceOffset);
    518   VerifyObjectField(kStackFramesOffset);
    519 }
    520 
    521 
    522 void String::StringVerify() {
    523   CHECK(IsString());
    524   CHECK(length() >= 0 && length() <= Smi::kMaxValue);
    525   if (IsInternalizedString()) {
    526     CHECK(!HEAP->InNewSpace(this));
    527   }
    528   if (IsConsString()) {
    529     ConsString::cast(this)->ConsStringVerify();
    530   } else if (IsSlicedString()) {
    531     SlicedString::cast(this)->SlicedStringVerify();
    532   }
    533 }
    534 
    535 
    536 void ConsString::ConsStringVerify() {
    537   CHECK(this->first()->IsString());
    538   CHECK(this->second() == GetHeap()->empty_string() ||
    539         this->second()->IsString());
    540   CHECK(this->length() >= ConsString::kMinLength);
    541   if (this->IsFlat()) {
    542     // A flat cons can only be created by String::SlowTryFlatten.
    543     // Afterwards, the first part may be externalized.
    544     CHECK(this->first()->IsSeqString() || this->first()->IsExternalString());
    545   }
    546 }
    547 
    548 
    549 void SlicedString::SlicedStringVerify() {
    550   CHECK(!this->parent()->IsConsString());
    551   CHECK(!this->parent()->IsSlicedString());
    552   CHECK(this->length() >= SlicedString::kMinLength);
    553 }
    554 
    555 
    556 void JSFunction::JSFunctionVerify() {
    557   CHECK(IsJSFunction());
    558   VerifyObjectField(kPrototypeOrInitialMapOffset);
    559   VerifyObjectField(kNextFunctionLinkOffset);
    560   CHECK(code()->IsCode());
    561   CHECK(next_function_link() == NULL ||
    562         next_function_link()->IsUndefined() ||
    563         next_function_link()->IsJSFunction());
    564 }
    565 
    566 
    567 void SharedFunctionInfo::SharedFunctionInfoVerify() {
    568   CHECK(IsSharedFunctionInfo());
    569   VerifyObjectField(kNameOffset);
    570   VerifyObjectField(kCodeOffset);
    571   VerifyObjectField(kOptimizedCodeMapOffset);
    572   VerifyObjectField(kScopeInfoOffset);
    573   VerifyObjectField(kInstanceClassNameOffset);
    574   VerifyObjectField(kFunctionDataOffset);
    575   VerifyObjectField(kScriptOffset);
    576   VerifyObjectField(kDebugInfoOffset);
    577 }
    578 
    579 
    580 void JSGlobalProxy::JSGlobalProxyVerify() {
    581   CHECK(IsJSGlobalProxy());
    582   JSObjectVerify();
    583   VerifyObjectField(JSGlobalProxy::kNativeContextOffset);
    584   // Make sure that this object has no properties, elements.
    585   CHECK_EQ(0, properties()->length());
    586   CHECK(HasFastObjectElements());
    587   CHECK_EQ(0, FixedArray::cast(elements())->length());
    588 }
    589 
    590 
    591 void JSGlobalObject::JSGlobalObjectVerify() {
    592   CHECK(IsJSGlobalObject());
    593   JSObjectVerify();
    594   for (int i = GlobalObject::kBuiltinsOffset;
    595        i < JSGlobalObject::kSize;
    596        i += kPointerSize) {
    597     VerifyObjectField(i);
    598   }
    599 }
    600 
    601 
    602 void JSBuiltinsObject::JSBuiltinsObjectVerify() {
    603   CHECK(IsJSBuiltinsObject());
    604   JSObjectVerify();
    605   for (int i = GlobalObject::kBuiltinsOffset;
    606        i < JSBuiltinsObject::kSize;
    607        i += kPointerSize) {
    608     VerifyObjectField(i);
    609   }
    610 }
    611 
    612 
    613 void Oddball::OddballVerify() {
    614   CHECK(IsOddball());
    615   VerifyHeapPointer(to_string());
    616   Object* number = to_number();
    617   if (number->IsHeapObject()) {
    618     CHECK(number == HEAP->nan_value());
    619   } else {
    620     CHECK(number->IsSmi());
    621     int value = Smi::cast(number)->value();
    622     // Hidden oddballs have negative smis.
    623     const int kLeastHiddenOddballNumber = -4;
    624     CHECK_LE(value, 1);
    625     CHECK(value >= kLeastHiddenOddballNumber);
    626   }
    627 }
    628 
    629 
    630 void Cell::CellVerify() {
    631   CHECK(IsCell());
    632   VerifyObjectField(kValueOffset);
    633 }
    634 
    635 
    636 void PropertyCell::PropertyCellVerify() {
    637   CHECK(IsPropertyCell());
    638   VerifyObjectField(kValueOffset);
    639   VerifyObjectField(kTypeOffset);
    640 }
    641 
    642 
    643 void Code::CodeVerify() {
    644   CHECK(IsAligned(reinterpret_cast<intptr_t>(instruction_start()),
    645                   kCodeAlignment));
    646   relocation_info()->Verify();
    647   Address last_gc_pc = NULL;
    648   for (RelocIterator it(this); !it.done(); it.next()) {
    649     it.rinfo()->Verify();
    650     // Ensure that GC will not iterate twice over the same pointer.
    651     if (RelocInfo::IsGCRelocMode(it.rinfo()->rmode())) {
    652       CHECK(it.rinfo()->pc() != last_gc_pc);
    653       last_gc_pc = it.rinfo()->pc();
    654     }
    655   }
    656 }
    657 
    658 
    659 void Code::VerifyEmbeddedMapsDependency() {
    660   int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
    661   for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
    662     RelocInfo::Mode mode = it.rinfo()->rmode();
    663     if (mode == RelocInfo::EMBEDDED_OBJECT &&
    664       it.rinfo()->target_object()->IsMap()) {
    665       Map* map = Map::cast(it.rinfo()->target_object());
    666       if (map->CanTransition()) {
    667         CHECK(map->dependent_code()->Contains(
    668             DependentCode::kWeaklyEmbeddedGroup, this));
    669       }
    670     }
    671   }
    672 }
    673 
    674 
    675 void JSArray::JSArrayVerify() {
    676   JSObjectVerify();
    677   CHECK(length()->IsNumber() || length()->IsUndefined());
    678   CHECK(elements()->IsUndefined() ||
    679          elements()->IsFixedArray() ||
    680          elements()->IsFixedDoubleArray());
    681 }
    682 
    683 
    684 void JSSet::JSSetVerify() {
    685   CHECK(IsJSSet());
    686   JSObjectVerify();
    687   VerifyHeapPointer(table());
    688   CHECK(table()->IsHashTable() || table()->IsUndefined());
    689 }
    690 
    691 
    692 void JSMap::JSMapVerify() {
    693   CHECK(IsJSMap());
    694   JSObjectVerify();
    695   VerifyHeapPointer(table());
    696   CHECK(table()->IsHashTable() || table()->IsUndefined());
    697 }
    698 
    699 
    700 void JSWeakMap::JSWeakMapVerify() {
    701   CHECK(IsJSWeakMap());
    702   JSObjectVerify();
    703   VerifyHeapPointer(table());
    704   CHECK(table()->IsHashTable() || table()->IsUndefined());
    705 }
    706 
    707 
    708 void JSWeakSet::JSWeakSetVerify() {
    709   CHECK(IsJSWeakSet());
    710   JSObjectVerify();
    711   VerifyHeapPointer(table());
    712   CHECK(table()->IsHashTable() || table()->IsUndefined());
    713 }
    714 
    715 
    716 void JSRegExp::JSRegExpVerify() {
    717   JSObjectVerify();
    718   CHECK(data()->IsUndefined() || data()->IsFixedArray());
    719   switch (TypeTag()) {
    720     case JSRegExp::ATOM: {
    721       FixedArray* arr = FixedArray::cast(data());
    722       CHECK(arr->get(JSRegExp::kAtomPatternIndex)->IsString());
    723       break;
    724     }
    725     case JSRegExp::IRREGEXP: {
    726       bool is_native = RegExpImpl::UsesNativeRegExp();
    727 
    728       FixedArray* arr = FixedArray::cast(data());
    729       Object* ascii_data = arr->get(JSRegExp::kIrregexpASCIICodeIndex);
    730       // Smi : Not compiled yet (-1) or code prepared for flushing.
    731       // JSObject: Compilation error.
    732       // Code/ByteArray: Compiled code.
    733       CHECK(ascii_data->IsSmi() ||
    734              (is_native ? ascii_data->IsCode() : ascii_data->IsByteArray()));
    735       Object* uc16_data = arr->get(JSRegExp::kIrregexpUC16CodeIndex);
    736       CHECK(uc16_data->IsSmi() ||
    737              (is_native ? uc16_data->IsCode() : uc16_data->IsByteArray()));
    738 
    739       Object* ascii_saved = arr->get(JSRegExp::kIrregexpASCIICodeSavedIndex);
    740       CHECK(ascii_saved->IsSmi() || ascii_saved->IsString() ||
    741              ascii_saved->IsCode());
    742       Object* uc16_saved = arr->get(JSRegExp::kIrregexpUC16CodeSavedIndex);
    743       CHECK(uc16_saved->IsSmi() || uc16_saved->IsString() ||
    744              uc16_saved->IsCode());
    745 
    746       CHECK(arr->get(JSRegExp::kIrregexpCaptureCountIndex)->IsSmi());
    747       CHECK(arr->get(JSRegExp::kIrregexpMaxRegisterCountIndex)->IsSmi());
    748       break;
    749     }
    750     default:
    751       CHECK_EQ(JSRegExp::NOT_COMPILED, TypeTag());
    752       CHECK(data()->IsUndefined());
    753       break;
    754   }
    755 }
    756 
    757 
    758 void JSProxy::JSProxyVerify() {
    759   CHECK(IsJSProxy());
    760   VerifyPointer(handler());
    761   CHECK(hash()->IsSmi() || hash()->IsUndefined());
    762 }
    763 
    764 
    765 void JSFunctionProxy::JSFunctionProxyVerify() {
    766   CHECK(IsJSFunctionProxy());
    767   JSProxyVerify();
    768   VerifyPointer(call_trap());
    769   VerifyPointer(construct_trap());
    770 }
    771 
    772 
    773 void JSArrayBuffer::JSArrayBufferVerify() {
    774   CHECK(IsJSArrayBuffer());
    775   JSObjectVerify();
    776   VerifyPointer(byte_length());
    777   CHECK(byte_length()->IsSmi() || byte_length()->IsHeapNumber()
    778         || byte_length()->IsUndefined());
    779 }
    780 
    781 
    782 void JSArrayBufferView::JSArrayBufferViewVerify() {
    783   CHECK(IsJSArrayBufferView());
    784   JSObjectVerify();
    785   VerifyPointer(buffer());
    786   CHECK(buffer()->IsJSArrayBuffer() || buffer()->IsUndefined());
    787 
    788   VerifyPointer(byte_offset());
    789   CHECK(byte_offset()->IsSmi() || byte_offset()->IsHeapNumber()
    790         || byte_offset()->IsUndefined());
    791 
    792   VerifyPointer(byte_length());
    793   CHECK(byte_length()->IsSmi() || byte_length()->IsHeapNumber()
    794         || byte_length()->IsUndefined());
    795 }
    796 
    797 
    798 void JSTypedArray::JSTypedArrayVerify() {
    799   CHECK(IsJSTypedArray());
    800   JSArrayBufferViewVerify();
    801   VerifyPointer(length());
    802   CHECK(length()->IsSmi() || length()->IsHeapNumber()
    803         || length()->IsUndefined());
    804 
    805   VerifyPointer(elements());
    806 }
    807 
    808 
    809 void JSDataView::JSDataViewVerify() {
    810   CHECK(IsJSDataView());
    811   JSArrayBufferViewVerify();
    812 }
    813 
    814 
    815 void Foreign::ForeignVerify() {
    816   CHECK(IsForeign());
    817 }
    818 
    819 
    820 void Box::BoxVerify() {
    821   CHECK(IsBox());
    822   value()->Verify();
    823 }
    824 
    825 
    826 void AccessorInfo::AccessorInfoVerify() {
    827   VerifyPointer(name());
    828   VerifyPointer(flag());
    829   VerifyPointer(expected_receiver_type());
    830 }
    831 
    832 
    833 void ExecutableAccessorInfo::ExecutableAccessorInfoVerify() {
    834   CHECK(IsExecutableAccessorInfo());
    835   AccessorInfoVerify();
    836   VerifyPointer(getter());
    837   VerifyPointer(setter());
    838   VerifyPointer(data());
    839 }
    840 
    841 
    842 void DeclaredAccessorDescriptor::DeclaredAccessorDescriptorVerify() {
    843   CHECK(IsDeclaredAccessorDescriptor());
    844   VerifyPointer(serialized_data());
    845 }
    846 
    847 
    848 void DeclaredAccessorInfo::DeclaredAccessorInfoVerify() {
    849   CHECK(IsDeclaredAccessorInfo());
    850   AccessorInfoVerify();
    851   VerifyPointer(descriptor());
    852 }
    853 
    854 
    855 void AccessorPair::AccessorPairVerify() {
    856   CHECK(IsAccessorPair());
    857   VerifyPointer(getter());
    858   VerifyPointer(setter());
    859 }
    860 
    861 
    862 void AccessCheckInfo::AccessCheckInfoVerify() {
    863   CHECK(IsAccessCheckInfo());
    864   VerifyPointer(named_callback());
    865   VerifyPointer(indexed_callback());
    866   VerifyPointer(data());
    867 }
    868 
    869 
    870 void InterceptorInfo::InterceptorInfoVerify() {
    871   CHECK(IsInterceptorInfo());
    872   VerifyPointer(getter());
    873   VerifyPointer(setter());
    874   VerifyPointer(query());
    875   VerifyPointer(deleter());
    876   VerifyPointer(enumerator());
    877   VerifyPointer(data());
    878 }
    879 
    880 
    881 void CallHandlerInfo::CallHandlerInfoVerify() {
    882   CHECK(IsCallHandlerInfo());
    883   VerifyPointer(callback());
    884   VerifyPointer(data());
    885 }
    886 
    887 
    888 void TemplateInfo::TemplateInfoVerify() {
    889   VerifyPointer(tag());
    890   VerifyPointer(property_list());
    891 }
    892 
    893 
    894 void FunctionTemplateInfo::FunctionTemplateInfoVerify() {
    895   CHECK(IsFunctionTemplateInfo());
    896   TemplateInfoVerify();
    897   VerifyPointer(serial_number());
    898   VerifyPointer(call_code());
    899   VerifyPointer(property_accessors());
    900   VerifyPointer(prototype_template());
    901   VerifyPointer(parent_template());
    902   VerifyPointer(named_property_handler());
    903   VerifyPointer(indexed_property_handler());
    904   VerifyPointer(instance_template());
    905   VerifyPointer(signature());
    906   VerifyPointer(access_check_info());
    907 }
    908 
    909 
    910 void ObjectTemplateInfo::ObjectTemplateInfoVerify() {
    911   CHECK(IsObjectTemplateInfo());
    912   TemplateInfoVerify();
    913   VerifyPointer(constructor());
    914   VerifyPointer(internal_field_count());
    915 }
    916 
    917 
    918 void SignatureInfo::SignatureInfoVerify() {
    919   CHECK(IsSignatureInfo());
    920   VerifyPointer(receiver());
    921   VerifyPointer(args());
    922 }
    923 
    924 
    925 void TypeSwitchInfo::TypeSwitchInfoVerify() {
    926   CHECK(IsTypeSwitchInfo());
    927   VerifyPointer(types());
    928 }
    929 
    930 
    931 void AllocationSite::AllocationSiteVerify() {
    932   CHECK(IsAllocationSite());
    933 }
    934 
    935 
    936 void AllocationMemento::AllocationMementoVerify() {
    937   CHECK(IsAllocationMemento());
    938   VerifyHeapPointer(allocation_site());
    939   CHECK(!IsValid() || GetAllocationSite()->IsAllocationSite());
    940 }
    941 
    942 
    943 void Script::ScriptVerify() {
    944   CHECK(IsScript());
    945   VerifyPointer(source());
    946   VerifyPointer(name());
    947   line_offset()->SmiVerify();
    948   column_offset()->SmiVerify();
    949   VerifyPointer(data());
    950   VerifyPointer(wrapper());
    951   type()->SmiVerify();
    952   VerifyPointer(line_ends());
    953   VerifyPointer(id());
    954 }
    955 
    956 
    957 void JSFunctionResultCache::JSFunctionResultCacheVerify() {
    958   JSFunction::cast(get(kFactoryIndex))->Verify();
    959 
    960   int size = Smi::cast(get(kCacheSizeIndex))->value();
    961   CHECK(kEntriesIndex <= size);
    962   CHECK(size <= length());
    963   CHECK_EQ(0, size % kEntrySize);
    964 
    965   int finger = Smi::cast(get(kFingerIndex))->value();
    966   CHECK(kEntriesIndex <= finger);
    967   CHECK((finger < size) || (finger == kEntriesIndex && finger == size));
    968   CHECK_EQ(0, finger % kEntrySize);
    969 
    970   if (FLAG_enable_slow_asserts) {
    971     for (int i = kEntriesIndex; i < size; i++) {
    972       CHECK(!get(i)->IsTheHole());
    973       get(i)->Verify();
    974     }
    975     for (int i = size; i < length(); i++) {
    976       CHECK(get(i)->IsTheHole());
    977       get(i)->Verify();
    978     }
    979   }
    980 }
    981 
    982 
    983 void NormalizedMapCache::NormalizedMapCacheVerify() {
    984   FixedArray::cast(this)->Verify();
    985   if (FLAG_enable_slow_asserts) {
    986     for (int i = 0; i < length(); i++) {
    987       Object* e = get(i);
    988       if (e->IsMap()) {
    989         Map::cast(e)->SharedMapVerify();
    990       } else {
    991         CHECK(e->IsUndefined());
    992       }
    993     }
    994   }
    995 }
    996 
    997 
    998 #ifdef ENABLE_DEBUGGER_SUPPORT
    999 void DebugInfo::DebugInfoVerify() {
   1000   CHECK(IsDebugInfo());
   1001   VerifyPointer(shared());
   1002   VerifyPointer(original_code());
   1003   VerifyPointer(code());
   1004   VerifyPointer(break_points());
   1005 }
   1006 
   1007 
   1008 void BreakPointInfo::BreakPointInfoVerify() {
   1009   CHECK(IsBreakPointInfo());
   1010   code_position()->SmiVerify();
   1011   source_position()->SmiVerify();
   1012   statement_position()->SmiVerify();
   1013   VerifyPointer(break_point_objects());
   1014 }
   1015 #endif  // ENABLE_DEBUGGER_SUPPORT
   1016 #endif  // VERIFY_HEAP
   1017 
   1018 #ifdef DEBUG
   1019 
   1020 void JSObject::IncrementSpillStatistics(SpillInformation* info) {
   1021   info->number_of_objects_++;
   1022   // Named properties
   1023   if (HasFastProperties()) {
   1024     info->number_of_objects_with_fast_properties_++;
   1025     info->number_of_fast_used_fields_   += map()->NextFreePropertyIndex();
   1026     info->number_of_fast_unused_fields_ += map()->unused_property_fields();
   1027   } else {
   1028     NameDictionary* dict = property_dictionary();
   1029     info->number_of_slow_used_properties_ += dict->NumberOfElements();
   1030     info->number_of_slow_unused_properties_ +=
   1031         dict->Capacity() - dict->NumberOfElements();
   1032   }
   1033   // Indexed properties
   1034   switch (GetElementsKind()) {
   1035     case FAST_HOLEY_SMI_ELEMENTS:
   1036     case FAST_SMI_ELEMENTS:
   1037     case FAST_HOLEY_DOUBLE_ELEMENTS:
   1038     case FAST_DOUBLE_ELEMENTS:
   1039     case FAST_HOLEY_ELEMENTS:
   1040     case FAST_ELEMENTS: {
   1041       info->number_of_objects_with_fast_elements_++;
   1042       int holes = 0;
   1043       FixedArray* e = FixedArray::cast(elements());
   1044       int len = e->length();
   1045       Heap* heap = HEAP;
   1046       for (int i = 0; i < len; i++) {
   1047         if (e->get(i) == heap->the_hole_value()) holes++;
   1048       }
   1049       info->number_of_fast_used_elements_   += len - holes;
   1050       info->number_of_fast_unused_elements_ += holes;
   1051       break;
   1052     }
   1053     case EXTERNAL_BYTE_ELEMENTS:
   1054     case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
   1055     case EXTERNAL_SHORT_ELEMENTS:
   1056     case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
   1057     case EXTERNAL_INT_ELEMENTS:
   1058     case EXTERNAL_UNSIGNED_INT_ELEMENTS:
   1059     case EXTERNAL_FLOAT_ELEMENTS:
   1060     case EXTERNAL_DOUBLE_ELEMENTS:
   1061     case EXTERNAL_PIXEL_ELEMENTS: {
   1062       info->number_of_objects_with_fast_elements_++;
   1063       ExternalPixelArray* e = ExternalPixelArray::cast(elements());
   1064       info->number_of_fast_used_elements_ += e->length();
   1065       break;
   1066     }
   1067     case DICTIONARY_ELEMENTS: {
   1068       SeededNumberDictionary* dict = element_dictionary();
   1069       info->number_of_slow_used_elements_ += dict->NumberOfElements();
   1070       info->number_of_slow_unused_elements_ +=
   1071           dict->Capacity() - dict->NumberOfElements();
   1072       break;
   1073     }
   1074     case NON_STRICT_ARGUMENTS_ELEMENTS:
   1075       break;
   1076   }
   1077 }
   1078 
   1079 
   1080 void JSObject::SpillInformation::Clear() {
   1081   number_of_objects_ = 0;
   1082   number_of_objects_with_fast_properties_ = 0;
   1083   number_of_objects_with_fast_elements_ = 0;
   1084   number_of_fast_used_fields_ = 0;
   1085   number_of_fast_unused_fields_ = 0;
   1086   number_of_slow_used_properties_ = 0;
   1087   number_of_slow_unused_properties_ = 0;
   1088   number_of_fast_used_elements_ = 0;
   1089   number_of_fast_unused_elements_ = 0;
   1090   number_of_slow_used_elements_ = 0;
   1091   number_of_slow_unused_elements_ = 0;
   1092 }
   1093 
   1094 
   1095 void JSObject::SpillInformation::Print() {
   1096   PrintF("\n  JSObject Spill Statistics (#%d):\n", number_of_objects_);
   1097 
   1098   PrintF("    - fast properties (#%d): %d (used) %d (unused)\n",
   1099          number_of_objects_with_fast_properties_,
   1100          number_of_fast_used_fields_, number_of_fast_unused_fields_);
   1101 
   1102   PrintF("    - slow properties (#%d): %d (used) %d (unused)\n",
   1103          number_of_objects_ - number_of_objects_with_fast_properties_,
   1104          number_of_slow_used_properties_, number_of_slow_unused_properties_);
   1105 
   1106   PrintF("    - fast elements (#%d): %d (used) %d (unused)\n",
   1107          number_of_objects_with_fast_elements_,
   1108          number_of_fast_used_elements_, number_of_fast_unused_elements_);
   1109 
   1110   PrintF("    - slow elements (#%d): %d (used) %d (unused)\n",
   1111          number_of_objects_ - number_of_objects_with_fast_elements_,
   1112          number_of_slow_used_elements_, number_of_slow_unused_elements_);
   1113 
   1114   PrintF("\n");
   1115 }
   1116 
   1117 
   1118 bool DescriptorArray::IsSortedNoDuplicates(int valid_entries) {
   1119   if (valid_entries == -1) valid_entries = number_of_descriptors();
   1120   Name* current_key = NULL;
   1121   uint32_t current = 0;
   1122   for (int i = 0; i < number_of_descriptors(); i++) {
   1123     Name* key = GetSortedKey(i);
   1124     if (key == current_key) {
   1125       PrintDescriptors();
   1126       return false;
   1127     }
   1128     current_key = key;
   1129     uint32_t hash = GetSortedKey(i)->Hash();
   1130     if (hash < current) {
   1131       PrintDescriptors();
   1132       return false;
   1133     }
   1134     current = hash;
   1135   }
   1136   return true;
   1137 }
   1138 
   1139 
   1140 bool TransitionArray::IsSortedNoDuplicates(int valid_entries) {
   1141   ASSERT(valid_entries == -1);
   1142   Name* current_key = NULL;
   1143   uint32_t current = 0;
   1144   for (int i = 0; i < number_of_transitions(); i++) {
   1145     Name* key = GetSortedKey(i);
   1146     if (key == current_key) {
   1147       PrintTransitions();
   1148       return false;
   1149     }
   1150     current_key = key;
   1151     uint32_t hash = GetSortedKey(i)->Hash();
   1152     if (hash < current) {
   1153       PrintTransitions();
   1154       return false;
   1155     }
   1156     current = hash;
   1157   }
   1158   return true;
   1159 }
   1160 
   1161 
   1162 static bool CheckOneBackPointer(Map* current_map, Object* target) {
   1163   return !target->IsMap() || Map::cast(target)->GetBackPointer() == current_map;
   1164 }
   1165 
   1166 
   1167 bool TransitionArray::IsConsistentWithBackPointers(Map* current_map) {
   1168   for (int i = 0; i < number_of_transitions(); ++i) {
   1169     if (!CheckOneBackPointer(current_map, GetTarget(i))) return false;
   1170   }
   1171   return true;
   1172 }
   1173 
   1174 
   1175 #endif  // DEBUG
   1176 
   1177 } }  // namespace v8::internal
   1178