Home | History | Annotate | Download | only in src
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/objects.h"
      6 
      7 #include "src/assembler-inl.h"
      8 #include "src/bootstrapper.h"
      9 #include "src/disasm.h"
     10 #include "src/disassembler.h"
     11 #include "src/field-type.h"
     12 #include "src/layout-descriptor.h"
     13 #include "src/macro-assembler.h"
     14 #include "src/objects-inl.h"
     15 #include "src/objects/literal-objects.h"
     16 #include "src/objects/module-info.h"
     17 #include "src/ostreams.h"
     18 #include "src/regexp/jsregexp.h"
     19 #include "src/transitions.h"
     20 
     21 namespace v8 {
     22 namespace internal {
     23 
     24 #ifdef VERIFY_HEAP
     25 
     26 void Object::ObjectVerify() {
     27   if (IsSmi()) {
     28     Smi::cast(this)->SmiVerify();
     29   } else {
     30     HeapObject::cast(this)->HeapObjectVerify();
     31   }
     32   CHECK(!IsConstructor() || IsCallable());
     33 }
     34 
     35 
     36 void Object::VerifyPointer(Object* p) {
     37   if (p->IsHeapObject()) {
     38     HeapObject::VerifyHeapPointer(p);
     39   } else {
     40     CHECK(p->IsSmi());
     41   }
     42 }
     43 
     44 
     45 void Smi::SmiVerify() {
     46   CHECK(IsSmi());
     47   CHECK(!IsCallable());
     48   CHECK(!IsConstructor());
     49 }
     50 
     51 
     52 void HeapObject::HeapObjectVerify() {
     53   VerifyHeapPointer(map());
     54   CHECK(map()->IsMap());
     55   InstanceType instance_type = map()->instance_type();
     56 
     57   if (instance_type < FIRST_NONSTRING_TYPE) {
     58     String::cast(this)->StringVerify();
     59     return;
     60   }
     61 
     62   switch (instance_type) {
     63     case SYMBOL_TYPE:
     64       Symbol::cast(this)->SymbolVerify();
     65       break;
     66     case MAP_TYPE:
     67       Map::cast(this)->MapVerify();
     68       break;
     69     case HEAP_NUMBER_TYPE:
     70     case MUTABLE_HEAP_NUMBER_TYPE:
     71       HeapNumber::cast(this)->HeapNumberVerify();
     72       break;
     73     case FIXED_ARRAY_TYPE:
     74       FixedArray::cast(this)->FixedArrayVerify();
     75       break;
     76     case FIXED_DOUBLE_ARRAY_TYPE:
     77       FixedDoubleArray::cast(this)->FixedDoubleArrayVerify();
     78       break;
     79     case BYTE_ARRAY_TYPE:
     80       ByteArray::cast(this)->ByteArrayVerify();
     81       break;
     82     case BYTECODE_ARRAY_TYPE:
     83       BytecodeArray::cast(this)->BytecodeArrayVerify();
     84       break;
     85     case TRANSITION_ARRAY_TYPE:
     86       TransitionArray::cast(this)->TransitionArrayVerify();
     87       break;
     88     case FREE_SPACE_TYPE:
     89       FreeSpace::cast(this)->FreeSpaceVerify();
     90       break;
     91 
     92 #define VERIFY_TYPED_ARRAY(Type, type, TYPE, ctype, size)                      \
     93     case FIXED_##TYPE##_ARRAY_TYPE:                                            \
     94       Fixed##Type##Array::cast(this)->FixedTypedArrayVerify();                 \
     95       break;
     96 
     97     TYPED_ARRAYS(VERIFY_TYPED_ARRAY)
     98 #undef VERIFY_TYPED_ARRAY
     99 
    100     case CODE_TYPE:
    101       Code::cast(this)->CodeVerify();
    102       break;
    103     case ODDBALL_TYPE:
    104       Oddball::cast(this)->OddballVerify();
    105       break;
    106     case JS_OBJECT_TYPE:
    107     case JS_ERROR_TYPE:
    108     case JS_ARGUMENTS_TYPE:
    109     case JS_API_OBJECT_TYPE:
    110     case JS_SPECIAL_API_OBJECT_TYPE:
    111     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
    112       JSObject::cast(this)->JSObjectVerify();
    113       break;
    114     case JS_GENERATOR_OBJECT_TYPE:
    115       JSGeneratorObject::cast(this)->JSGeneratorObjectVerify();
    116       break;
    117     case JS_VALUE_TYPE:
    118       JSValue::cast(this)->JSValueVerify();
    119       break;
    120     case JS_DATE_TYPE:
    121       JSDate::cast(this)->JSDateVerify();
    122       break;
    123     case JS_BOUND_FUNCTION_TYPE:
    124       JSBoundFunction::cast(this)->JSBoundFunctionVerify();
    125       break;
    126     case JS_FUNCTION_TYPE:
    127       JSFunction::cast(this)->JSFunctionVerify();
    128       break;
    129     case JS_GLOBAL_PROXY_TYPE:
    130       JSGlobalProxy::cast(this)->JSGlobalProxyVerify();
    131       break;
    132     case JS_GLOBAL_OBJECT_TYPE:
    133       JSGlobalObject::cast(this)->JSGlobalObjectVerify();
    134       break;
    135     case CELL_TYPE:
    136       Cell::cast(this)->CellVerify();
    137       break;
    138     case PROPERTY_CELL_TYPE:
    139       PropertyCell::cast(this)->PropertyCellVerify();
    140       break;
    141     case WEAK_CELL_TYPE:
    142       WeakCell::cast(this)->WeakCellVerify();
    143       break;
    144     case JS_ARRAY_TYPE:
    145       JSArray::cast(this)->JSArrayVerify();
    146       break;
    147     case JS_MODULE_NAMESPACE_TYPE:
    148       JSModuleNamespace::cast(this)->JSModuleNamespaceVerify();
    149       break;
    150     case JS_SET_TYPE:
    151       JSSet::cast(this)->JSSetVerify();
    152       break;
    153     case JS_MAP_TYPE:
    154       JSMap::cast(this)->JSMapVerify();
    155       break;
    156     case JS_SET_ITERATOR_TYPE:
    157       JSSetIterator::cast(this)->JSSetIteratorVerify();
    158       break;
    159     case JS_MAP_ITERATOR_TYPE:
    160       JSMapIterator::cast(this)->JSMapIteratorVerify();
    161       break;
    162     case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
    163     case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
    164     case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
    165     case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    166     case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    167     case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    168     case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    169     case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    170     case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    171     case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    172     case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    173     case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    174     case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    175     case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    176     case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    177     case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    178     case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    179     case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    180     case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE:
    181     case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE:
    182     case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE:
    183     case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE:
    184     case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE:
    185     case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE:
    186     case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE:
    187     case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE:
    188     case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE:
    189     case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE:
    190     case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE:
    191     case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE:
    192     case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE:
    193     case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE:
    194     case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
    195     case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
    196     case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE:
    197       JSArrayIterator::cast(this)->JSArrayIteratorVerify();
    198       break;
    199 
    200     case JS_STRING_ITERATOR_TYPE:
    201       JSStringIterator::cast(this)->JSStringIteratorVerify();
    202       break;
    203     case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
    204       JSAsyncFromSyncIterator::cast(this)->JSAsyncFromSyncIteratorVerify();
    205       break;
    206     case JS_WEAK_MAP_TYPE:
    207       JSWeakMap::cast(this)->JSWeakMapVerify();
    208       break;
    209     case JS_WEAK_SET_TYPE:
    210       JSWeakSet::cast(this)->JSWeakSetVerify();
    211       break;
    212     case JS_PROMISE_CAPABILITY_TYPE:
    213       JSPromiseCapability::cast(this)->JSPromiseCapabilityVerify();
    214       break;
    215     case JS_PROMISE_TYPE:
    216       JSPromise::cast(this)->JSPromiseVerify();
    217       break;
    218     case JS_REGEXP_TYPE:
    219       JSRegExp::cast(this)->JSRegExpVerify();
    220       break;
    221     case FILLER_TYPE:
    222       break;
    223     case JS_PROXY_TYPE:
    224       JSProxy::cast(this)->JSProxyVerify();
    225       break;
    226     case FOREIGN_TYPE:
    227       Foreign::cast(this)->ForeignVerify();
    228       break;
    229     case SHARED_FUNCTION_INFO_TYPE:
    230       SharedFunctionInfo::cast(this)->SharedFunctionInfoVerify();
    231       break;
    232     case JS_MESSAGE_OBJECT_TYPE:
    233       JSMessageObject::cast(this)->JSMessageObjectVerify();
    234       break;
    235     case JS_ARRAY_BUFFER_TYPE:
    236       JSArrayBuffer::cast(this)->JSArrayBufferVerify();
    237       break;
    238     case JS_TYPED_ARRAY_TYPE:
    239       JSTypedArray::cast(this)->JSTypedArrayVerify();
    240       break;
    241     case JS_DATA_VIEW_TYPE:
    242       JSDataView::cast(this)->JSDataViewVerify();
    243       break;
    244 
    245 #define MAKE_STRUCT_CASE(NAME, Name, name) \
    246   case NAME##_TYPE:                        \
    247     Name::cast(this)->Name##Verify();      \
    248     break;
    249     STRUCT_LIST(MAKE_STRUCT_CASE)
    250 #undef MAKE_STRUCT_CASE
    251 
    252     default:
    253       UNREACHABLE();
    254       break;
    255   }
    256 }
    257 
    258 
    259 void HeapObject::VerifyHeapPointer(Object* p) {
    260   CHECK(p->IsHeapObject());
    261   HeapObject* ho = HeapObject::cast(p);
    262   CHECK(ho->GetHeap()->Contains(ho));
    263 }
    264 
    265 
    266 void Symbol::SymbolVerify() {
    267   CHECK(IsSymbol());
    268   CHECK(HasHashCode());
    269   CHECK(Hash() > 0u);
    270   CHECK(name()->IsUndefined(GetIsolate()) || name()->IsString());
    271 }
    272 
    273 
    274 void HeapNumber::HeapNumberVerify() {
    275   CHECK(IsHeapNumber() || IsMutableHeapNumber());
    276 }
    277 
    278 void ByteArray::ByteArrayVerify() {
    279   CHECK(IsByteArray());
    280 }
    281 
    282 
    283 void BytecodeArray::BytecodeArrayVerify() {
    284   // TODO(oth): Walk bytecodes and immediate values to validate sanity.
    285   // - All bytecodes are known and well formed.
    286   // - Jumps must go to new instructions starts.
    287   // - No Illegal bytecodes.
    288   // - No consecutive sequences of prefix Wide / ExtraWide.
    289   CHECK(IsBytecodeArray());
    290   CHECK(constant_pool()->IsFixedArray());
    291   VerifyHeapPointer(constant_pool());
    292 }
    293 
    294 
    295 void FreeSpace::FreeSpaceVerify() {
    296   CHECK(IsFreeSpace());
    297 }
    298 
    299 
    300 template <class Traits>
    301 void FixedTypedArray<Traits>::FixedTypedArrayVerify() {
    302   CHECK(IsHeapObject() &&
    303         HeapObject::cast(this)->map()->instance_type() ==
    304             Traits::kInstanceType);
    305   if (base_pointer() == this) {
    306     CHECK(external_pointer() ==
    307           ExternalReference::fixed_typed_array_base_data_offset().address());
    308   } else {
    309     CHECK(base_pointer() == nullptr);
    310   }
    311 }
    312 
    313 
    314 bool JSObject::ElementsAreSafeToExamine() {
    315   // If a GC was caused while constructing this object, the elements
    316   // pointer may point to a one pointer filler map.
    317   return reinterpret_cast<Map*>(elements()) !=
    318       GetHeap()->one_pointer_filler_map();
    319 }
    320 
    321 
    322 void JSObject::JSObjectVerify() {
    323   VerifyHeapPointer(properties());
    324   VerifyHeapPointer(elements());
    325 
    326   if (HasSloppyArgumentsElements()) {
    327     CHECK(this->elements()->IsFixedArray());
    328     CHECK_GE(this->elements()->length(), 2);
    329   }
    330 
    331   if (HasFastProperties()) {
    332     int actual_unused_property_fields = map()->GetInObjectProperties() +
    333                                         properties()->length() -
    334                                         map()->NextFreePropertyIndex();
    335     if (map()->unused_property_fields() != actual_unused_property_fields) {
    336       // This could actually happen in the middle of StoreTransitionStub
    337       // when the new extended backing store is already set into the object and
    338       // the allocation of the MutableHeapNumber triggers GC (in this case map
    339       // is not updated yet).
    340       CHECK_EQ(map()->unused_property_fields(),
    341                actual_unused_property_fields - JSObject::kFieldsAdded);
    342     }
    343     DescriptorArray* descriptors = map()->instance_descriptors();
    344     Isolate* isolate = GetIsolate();
    345     for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) {
    346       PropertyDetails details = descriptors->GetDetails(i);
    347       if (details.location() == kField) {
    348         DCHECK_EQ(kData, details.kind());
    349         Representation r = descriptors->GetDetails(i).representation();
    350         FieldIndex index = FieldIndex::ForDescriptor(map(), i);
    351         if (IsUnboxedDoubleField(index)) {
    352           DCHECK(r.IsDouble());
    353           continue;
    354         }
    355         Object* value = RawFastPropertyAt(index);
    356         if (r.IsDouble()) DCHECK(value->IsMutableHeapNumber());
    357         if (value->IsUninitialized(isolate)) continue;
    358         if (r.IsSmi()) DCHECK(value->IsSmi());
    359         if (r.IsHeapObject()) DCHECK(value->IsHeapObject());
    360         FieldType* field_type = descriptors->GetFieldType(i);
    361         bool type_is_none = field_type->IsNone();
    362         bool type_is_any = field_type->IsAny();
    363         if (r.IsNone()) {
    364           CHECK(type_is_none);
    365         } else if (!type_is_any && !(type_is_none && r.IsHeapObject())) {
    366           // If allocation folding is off then GC could happen during inner
    367           // object literal creation and we will end up having and undefined
    368           // value that does not match the field type.
    369           CHECK(!field_type->NowStable() || field_type->NowContains(value) ||
    370                 (!FLAG_use_allocation_folding && value->IsUndefined(isolate)));
    371         }
    372       }
    373     }
    374   }
    375 
    376   // If a GC was caused while constructing this object, the elements
    377   // pointer may point to a one pointer filler map.
    378   if (ElementsAreSafeToExamine()) {
    379     CHECK_EQ((map()->has_fast_smi_or_object_elements() ||
    380               (elements() == GetHeap()->empty_fixed_array()) ||
    381               HasFastStringWrapperElements()),
    382              (elements()->map() == GetHeap()->fixed_array_map() ||
    383               elements()->map() == GetHeap()->fixed_cow_array_map()));
    384     CHECK(map()->has_fast_object_elements() == HasFastObjectElements());
    385   }
    386 }
    387 
    388 
    389 void Map::MapVerify() {
    390   Heap* heap = GetHeap();
    391   CHECK(!heap->InNewSpace(this));
    392   CHECK(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
    393   CHECK(instance_size() == kVariableSizeSentinel ||
    394         (kPointerSize <= instance_size() &&
    395          static_cast<size_t>(instance_size()) < heap->Capacity()));
    396   CHECK(GetBackPointer()->IsUndefined(heap->isolate()) ||
    397         !Map::cast(GetBackPointer())->is_stable());
    398   VerifyHeapPointer(prototype());
    399   VerifyHeapPointer(instance_descriptors());
    400   SLOW_DCHECK(instance_descriptors()->IsSortedNoDuplicates());
    401   SLOW_DCHECK(TransitionArray::IsSortedNoDuplicates(this));
    402   SLOW_DCHECK(TransitionArray::IsConsistentWithBackPointers(this));
    403   // TODO(ishell): turn it back to SLOW_DCHECK.
    404   CHECK(!FLAG_unbox_double_fields ||
    405         layout_descriptor()->IsConsistentWithMap(this));
    406 }
    407 
    408 
    409 void Map::DictionaryMapVerify() {
    410   MapVerify();
    411   CHECK(is_dictionary_map());
    412   CHECK(instance_descriptors()->IsEmpty());
    413   CHECK_EQ(0, unused_property_fields());
    414   CHECK_EQ(Heap::GetStaticVisitorIdForMap(this), visitor_id());
    415 }
    416 
    417 
    418 void Map::VerifyOmittedMapChecks() {
    419   if (!FLAG_omit_map_checks_for_leaf_maps) return;
    420   if (!is_stable() ||
    421       is_deprecated() ||
    422       is_dictionary_map()) {
    423     CHECK(dependent_code()->IsEmpty(DependentCode::kPrototypeCheckGroup));
    424   }
    425 }
    426 
    427 
    428 void TypeFeedbackInfo::TypeFeedbackInfoVerify() {
    429   VerifyObjectField(kStorage1Offset);
    430   VerifyObjectField(kStorage2Offset);
    431   VerifyObjectField(kStorage3Offset);
    432 }
    433 
    434 
    435 void AliasedArgumentsEntry::AliasedArgumentsEntryVerify() {
    436   VerifySmiField(kAliasedContextSlot);
    437 }
    438 
    439 
    440 void FixedArray::FixedArrayVerify() {
    441   for (int i = 0; i < length(); i++) {
    442     Object* e = get(i);
    443     VerifyPointer(e);
    444   }
    445 }
    446 
    447 
    448 void FixedDoubleArray::FixedDoubleArrayVerify() {
    449   for (int i = 0; i < length(); i++) {
    450     if (!is_the_hole(i)) {
    451       uint64_t value = get_representation(i);
    452       uint64_t unexpected =
    453           bit_cast<uint64_t>(std::numeric_limits<double>::quiet_NaN()) &
    454           V8_UINT64_C(0x7FF8000000000000);
    455       // Create implementation specific sNaN by inverting relevant bit.
    456       unexpected ^= V8_UINT64_C(0x0008000000000000);
    457       CHECK((value & V8_UINT64_C(0x7FF8000000000000)) != unexpected ||
    458             (value & V8_UINT64_C(0x0007FFFFFFFFFFFF)) == V8_UINT64_C(0));
    459     }
    460   }
    461 }
    462 
    463 
    464 void TransitionArray::TransitionArrayVerify() {
    465   for (int i = 0; i < length(); i++) {
    466     Object* e = get(i);
    467     VerifyPointer(e);
    468   }
    469   CHECK_LE(LengthFor(number_of_transitions()), length());
    470   CHECK(next_link()->IsUndefined(GetIsolate()) || next_link()->IsSmi() ||
    471         next_link()->IsTransitionArray());
    472 }
    473 
    474 
    475 void JSGeneratorObject::JSGeneratorObjectVerify() {
    476   // In an expression like "new g()", there can be a point where a generator
    477   // object is allocated but its fields are all undefined, as it hasn't yet been
    478   // initialized by the generator.  Hence these weak checks.
    479   VerifyObjectField(kFunctionOffset);
    480   VerifyObjectField(kContextOffset);
    481   VerifyObjectField(kReceiverOffset);
    482   VerifyObjectField(kRegisterFileOffset);
    483   VerifyObjectField(kContinuationOffset);
    484 }
    485 
    486 
    487 void JSValue::JSValueVerify() {
    488   Object* v = value();
    489   if (v->IsHeapObject()) {
    490     VerifyHeapPointer(v);
    491   }
    492 }
    493 
    494 
    495 void JSDate::JSDateVerify() {
    496   if (value()->IsHeapObject()) {
    497     VerifyHeapPointer(value());
    498   }
    499   Isolate* isolate = GetIsolate();
    500   CHECK(value()->IsUndefined(isolate) || value()->IsSmi() ||
    501         value()->IsHeapNumber());
    502   CHECK(year()->IsUndefined(isolate) || year()->IsSmi() || year()->IsNaN());
    503   CHECK(month()->IsUndefined(isolate) || month()->IsSmi() || month()->IsNaN());
    504   CHECK(day()->IsUndefined(isolate) || day()->IsSmi() || day()->IsNaN());
    505   CHECK(weekday()->IsUndefined(isolate) || weekday()->IsSmi() ||
    506         weekday()->IsNaN());
    507   CHECK(hour()->IsUndefined(isolate) || hour()->IsSmi() || hour()->IsNaN());
    508   CHECK(min()->IsUndefined(isolate) || min()->IsSmi() || min()->IsNaN());
    509   CHECK(sec()->IsUndefined(isolate) || sec()->IsSmi() || sec()->IsNaN());
    510   CHECK(cache_stamp()->IsUndefined(isolate) || cache_stamp()->IsSmi() ||
    511         cache_stamp()->IsNaN());
    512 
    513   if (month()->IsSmi()) {
    514     int month = Smi::cast(this->month())->value();
    515     CHECK(0 <= month && month <= 11);
    516   }
    517   if (day()->IsSmi()) {
    518     int day = Smi::cast(this->day())->value();
    519     CHECK(1 <= day && day <= 31);
    520   }
    521   if (hour()->IsSmi()) {
    522     int hour = Smi::cast(this->hour())->value();
    523     CHECK(0 <= hour && hour <= 23);
    524   }
    525   if (min()->IsSmi()) {
    526     int min = Smi::cast(this->min())->value();
    527     CHECK(0 <= min && min <= 59);
    528   }
    529   if (sec()->IsSmi()) {
    530     int sec = Smi::cast(this->sec())->value();
    531     CHECK(0 <= sec && sec <= 59);
    532   }
    533   if (weekday()->IsSmi()) {
    534     int weekday = Smi::cast(this->weekday())->value();
    535     CHECK(0 <= weekday && weekday <= 6);
    536   }
    537   if (cache_stamp()->IsSmi()) {
    538     CHECK(Smi::cast(cache_stamp())->value() <=
    539           Smi::cast(isolate->date_cache()->stamp())->value());
    540   }
    541 }
    542 
    543 
    544 void JSMessageObject::JSMessageObjectVerify() {
    545   CHECK(IsJSMessageObject());
    546   VerifyObjectField(kStartPositionOffset);
    547   VerifyObjectField(kEndPositionOffset);
    548   VerifyObjectField(kArgumentsOffset);
    549   VerifyObjectField(kScriptOffset);
    550   VerifyObjectField(kStackFramesOffset);
    551 }
    552 
    553 
    554 void String::StringVerify() {
    555   CHECK(IsString());
    556   CHECK(length() >= 0 && length() <= Smi::kMaxValue);
    557   CHECK_IMPLIES(length() == 0, this == GetHeap()->empty_string());
    558   if (IsInternalizedString()) {
    559     CHECK(!GetHeap()->InNewSpace(this));
    560   }
    561   if (IsConsString()) {
    562     ConsString::cast(this)->ConsStringVerify();
    563   } else if (IsSlicedString()) {
    564     SlicedString::cast(this)->SlicedStringVerify();
    565   } else if (IsThinString()) {
    566     ThinString::cast(this)->ThinStringVerify();
    567   }
    568 }
    569 
    570 
    571 void ConsString::ConsStringVerify() {
    572   CHECK(this->first()->IsString());
    573   CHECK(this->second() == GetHeap()->empty_string() ||
    574         this->second()->IsString());
    575   CHECK(this->length() >= ConsString::kMinLength);
    576   CHECK(this->length() == this->first()->length() + this->second()->length());
    577   if (this->IsFlat()) {
    578     // A flat cons can only be created by String::SlowFlatten.
    579     // Afterwards, the first part may be externalized or internalized.
    580     CHECK(this->first()->IsSeqString() || this->first()->IsExternalString() ||
    581           this->first()->IsThinString());
    582   }
    583 }
    584 
    585 void ThinString::ThinStringVerify() {
    586   CHECK(this->actual()->IsInternalizedString());
    587   CHECK(this->actual()->IsSeqString() || this->actual()->IsExternalString());
    588 }
    589 
    590 void SlicedString::SlicedStringVerify() {
    591   CHECK(!this->parent()->IsConsString());
    592   CHECK(!this->parent()->IsSlicedString());
    593   CHECK(this->length() >= SlicedString::kMinLength);
    594 }
    595 
    596 
    597 void JSBoundFunction::JSBoundFunctionVerify() {
    598   CHECK(IsJSBoundFunction());
    599   JSObjectVerify();
    600   VerifyObjectField(kBoundThisOffset);
    601   VerifyObjectField(kBoundTargetFunctionOffset);
    602   VerifyObjectField(kBoundArgumentsOffset);
    603   CHECK(bound_target_function()->IsCallable());
    604   CHECK(IsCallable());
    605   CHECK_EQ(IsConstructor(), bound_target_function()->IsConstructor());
    606 }
    607 
    608 
    609 void JSFunction::JSFunctionVerify() {
    610   CHECK(IsJSFunction());
    611   VerifyObjectField(kPrototypeOrInitialMapOffset);
    612   VerifyObjectField(kNextFunctionLinkOffset);
    613   CHECK(code()->IsCode());
    614   CHECK(next_function_link() == NULL ||
    615         next_function_link()->IsUndefined(GetIsolate()) ||
    616         next_function_link()->IsJSFunction());
    617   CHECK(map()->is_callable());
    618 }
    619 
    620 
    621 void SharedFunctionInfo::SharedFunctionInfoVerify() {
    622   CHECK(IsSharedFunctionInfo());
    623 
    624   VerifyObjectField(kCodeOffset);
    625   VerifyObjectField(kDebugInfoOffset);
    626   VerifyObjectField(kFeedbackMetadataOffset);
    627   VerifyObjectField(kFunctionDataOffset);
    628   VerifyObjectField(kFunctionIdentifierOffset);
    629   VerifyObjectField(kInstanceClassNameOffset);
    630   VerifyObjectField(kNameOffset);
    631   VerifyObjectField(kOptimizedCodeMapOffset);
    632   VerifyObjectField(kOuterScopeInfoOffset);
    633   VerifyObjectField(kScopeInfoOffset);
    634   VerifyObjectField(kScriptOffset);
    635 
    636   CHECK(function_data()->IsUndefined(GetIsolate()) || IsApiFunction() ||
    637         HasBytecodeArray() || HasAsmWasmData());
    638 
    639   CHECK(function_identifier()->IsUndefined(GetIsolate()) ||
    640         HasBuiltinFunctionId() || HasInferredName());
    641 
    642   if (scope_info()->length() > 0) {
    643     CHECK(kind() == scope_info()->function_kind());
    644     CHECK_EQ(kind() == kModule, scope_info()->scope_type() == MODULE_SCOPE);
    645   }
    646 }
    647 
    648 
    649 void JSGlobalProxy::JSGlobalProxyVerify() {
    650   CHECK(IsJSGlobalProxy());
    651   JSObjectVerify();
    652   VerifyObjectField(JSGlobalProxy::kNativeContextOffset);
    653   // Make sure that this object has no properties, elements.
    654   CHECK_EQ(0, properties()->length());
    655   CHECK_EQ(0, FixedArray::cast(elements())->length());
    656 }
    657 
    658 
    659 void JSGlobalObject::JSGlobalObjectVerify() {
    660   CHECK(IsJSGlobalObject());
    661   // Do not check the dummy global object for the builtins.
    662   if (GlobalDictionary::cast(properties())->NumberOfElements() == 0 &&
    663       elements()->length() == 0) {
    664     return;
    665   }
    666   JSObjectVerify();
    667 }
    668 
    669 
    670 void Oddball::OddballVerify() {
    671   CHECK(IsOddball());
    672   Heap* heap = GetHeap();
    673   VerifyHeapPointer(to_string());
    674   Object* number = to_number();
    675   if (number->IsHeapObject()) {
    676     CHECK(number == heap->nan_value() ||
    677           number == heap->hole_nan_value());
    678   } else {
    679     CHECK(number->IsSmi());
    680     int value = Smi::cast(number)->value();
    681     // Hidden oddballs have negative smis.
    682     const int kLeastHiddenOddballNumber = -7;
    683     CHECK_LE(value, 1);
    684     CHECK(value >= kLeastHiddenOddballNumber);
    685   }
    686   if (map() == heap->undefined_map()) {
    687     CHECK(this == heap->undefined_value());
    688   } else if (map() == heap->the_hole_map()) {
    689     CHECK(this == heap->the_hole_value());
    690   } else if (map() == heap->null_map()) {
    691     CHECK(this == heap->null_value());
    692   } else if (map() == heap->boolean_map()) {
    693     CHECK(this == heap->true_value() ||
    694           this == heap->false_value());
    695   } else if (map() == heap->uninitialized_map()) {
    696     CHECK(this == heap->uninitialized_value());
    697   } else if (map() == heap->no_interceptor_result_sentinel_map()) {
    698     CHECK(this == heap->no_interceptor_result_sentinel());
    699   } else if (map() == heap->arguments_marker_map()) {
    700     CHECK(this == heap->arguments_marker());
    701   } else if (map() == heap->termination_exception_map()) {
    702     CHECK(this == heap->termination_exception());
    703   } else if (map() == heap->exception_map()) {
    704     CHECK(this == heap->exception());
    705   } else if (map() == heap->optimized_out_map()) {
    706     CHECK(this == heap->optimized_out());
    707   } else if (map() == heap->stale_register_map()) {
    708     CHECK(this == heap->stale_register());
    709   } else {
    710     UNREACHABLE();
    711   }
    712 }
    713 
    714 
    715 void Cell::CellVerify() {
    716   CHECK(IsCell());
    717   VerifyObjectField(kValueOffset);
    718 }
    719 
    720 
    721 void PropertyCell::PropertyCellVerify() {
    722   CHECK(IsPropertyCell());
    723   VerifyObjectField(kValueOffset);
    724 }
    725 
    726 
    727 void WeakCell::WeakCellVerify() {
    728   CHECK(IsWeakCell());
    729   VerifyObjectField(kValueOffset);
    730   VerifyObjectField(kNextOffset);
    731 }
    732 
    733 
    734 void Code::CodeVerify() {
    735   CHECK(IsAligned(reinterpret_cast<intptr_t>(instruction_start()),
    736                   kCodeAlignment));
    737   relocation_info()->ObjectVerify();
    738   Address last_gc_pc = NULL;
    739   Isolate* isolate = GetIsolate();
    740   for (RelocIterator it(this); !it.done(); it.next()) {
    741     it.rinfo()->Verify(isolate);
    742     // Ensure that GC will not iterate twice over the same pointer.
    743     if (RelocInfo::IsGCRelocMode(it.rinfo()->rmode())) {
    744       CHECK(it.rinfo()->pc() != last_gc_pc);
    745       last_gc_pc = it.rinfo()->pc();
    746     }
    747   }
    748   CHECK(raw_type_feedback_info() == Smi::kZero ||
    749         raw_type_feedback_info()->IsSmi() == IsCodeStubOrIC());
    750 }
    751 
    752 
    753 void Code::VerifyEmbeddedObjectsDependency() {
    754   if (!CanContainWeakObjects()) return;
    755   WeakCell* cell = CachedWeakCell();
    756   DisallowHeapAllocation no_gc;
    757   Isolate* isolate = GetIsolate();
    758   HandleScope scope(isolate);
    759   int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
    760   for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
    761     Object* obj = it.rinfo()->target_object();
    762     if (IsWeakObject(obj)) {
    763       if (obj->IsMap()) {
    764         Map* map = Map::cast(obj);
    765         CHECK(map->dependent_code()->Contains(DependentCode::kWeakCodeGroup,
    766                                               cell));
    767       } else if (obj->IsJSObject()) {
    768         if (isolate->heap()->InNewSpace(obj)) {
    769           ArrayList* list =
    770               GetIsolate()->heap()->weak_new_space_object_to_code_list();
    771           bool found = false;
    772           for (int i = 0; i < list->Length(); i += 2) {
    773             WeakCell* obj_cell = WeakCell::cast(list->Get(i));
    774             if (!obj_cell->cleared() && obj_cell->value() == obj &&
    775                 WeakCell::cast(list->Get(i + 1)) == cell) {
    776               found = true;
    777               break;
    778             }
    779           }
    780           CHECK(found);
    781         } else {
    782           Handle<HeapObject> key_obj(HeapObject::cast(obj), isolate);
    783           DependentCode* dep =
    784               GetIsolate()->heap()->LookupWeakObjectToCodeDependency(key_obj);
    785           dep->Contains(DependentCode::kWeakCodeGroup, cell);
    786         }
    787       }
    788     }
    789   }
    790 }
    791 
    792 
    793 void JSArray::JSArrayVerify() {
    794   JSObjectVerify();
    795   Isolate* isolate = GetIsolate();
    796   CHECK(length()->IsNumber() || length()->IsUndefined(isolate));
    797   // If a GC was caused while constructing this array, the elements
    798   // pointer may point to a one pointer filler map.
    799   if (!ElementsAreSafeToExamine()) return;
    800   if (elements()->IsUndefined(isolate)) return;
    801   CHECK(elements()->IsFixedArray() || elements()->IsFixedDoubleArray());
    802   if (!length()->IsNumber()) return;
    803   // Verify that the length and the elements backing store are in sync.
    804   if (length()->IsSmi() && HasFastElements()) {
    805     int size = Smi::cast(length())->value();
    806     // Holey / Packed backing stores might have slack or might have not been
    807     // properly initialized yet.
    808     CHECK(size <= elements()->length() ||
    809           elements() == isolate->heap()->empty_fixed_array());
    810   } else {
    811     CHECK(HasDictionaryElements());
    812     uint32_t array_length;
    813     CHECK(length()->ToArrayLength(&array_length));
    814     if (array_length == 0xffffffff) {
    815       CHECK(length()->ToArrayLength(&array_length));
    816     }
    817     if (array_length != 0) {
    818       SeededNumberDictionary* dict = SeededNumberDictionary::cast(elements());
    819       // The dictionary can never have more elements than the array length + 1.
    820       // If the backing store grows the verification might be triggered with
    821       // the old length in place.
    822       uint32_t nof_elements = static_cast<uint32_t>(dict->NumberOfElements());
    823       if (nof_elements != 0) nof_elements--;
    824       CHECK_LE(nof_elements, array_length);
    825     }
    826   }
    827 }
    828 
    829 
    830 void JSSet::JSSetVerify() {
    831   CHECK(IsJSSet());
    832   JSObjectVerify();
    833   VerifyHeapPointer(table());
    834   CHECK(table()->IsOrderedHashTable() || table()->IsUndefined(GetIsolate()));
    835   // TODO(arv): Verify OrderedHashTable too.
    836 }
    837 
    838 
    839 void JSMap::JSMapVerify() {
    840   CHECK(IsJSMap());
    841   JSObjectVerify();
    842   VerifyHeapPointer(table());
    843   CHECK(table()->IsOrderedHashTable() || table()->IsUndefined(GetIsolate()));
    844   // TODO(arv): Verify OrderedHashTable too.
    845 }
    846 
    847 
    848 void JSSetIterator::JSSetIteratorVerify() {
    849   CHECK(IsJSSetIterator());
    850   JSObjectVerify();
    851   VerifyHeapPointer(table());
    852   Isolate* isolate = GetIsolate();
    853   CHECK(table()->IsOrderedHashTable() || table()->IsUndefined(isolate));
    854   CHECK(index()->IsSmi() || index()->IsUndefined(isolate));
    855   CHECK(kind()->IsSmi() || kind()->IsUndefined(isolate));
    856 }
    857 
    858 
    859 void JSMapIterator::JSMapIteratorVerify() {
    860   CHECK(IsJSMapIterator());
    861   JSObjectVerify();
    862   VerifyHeapPointer(table());
    863   Isolate* isolate = GetIsolate();
    864   CHECK(table()->IsOrderedHashTable() || table()->IsUndefined(isolate));
    865   CHECK(index()->IsSmi() || index()->IsUndefined(isolate));
    866   CHECK(kind()->IsSmi() || kind()->IsUndefined(isolate));
    867 }
    868 
    869 
    870 void JSWeakMap::JSWeakMapVerify() {
    871   CHECK(IsJSWeakMap());
    872   JSObjectVerify();
    873   VerifyHeapPointer(table());
    874   CHECK(table()->IsHashTable() || table()->IsUndefined(GetIsolate()));
    875 }
    876 
    877 void JSArrayIterator::JSArrayIteratorVerify() {
    878   CHECK(IsJSArrayIterator());
    879   JSObjectVerify();
    880   CHECK(object()->IsJSReceiver() || object()->IsUndefined(GetIsolate()));
    881 
    882   CHECK_GE(index()->Number(), 0);
    883   CHECK_LE(index()->Number(), kMaxSafeInteger);
    884   CHECK(object_map()->IsMap() || object_map()->IsUndefined(GetIsolate()));
    885 }
    886 
    887 void JSStringIterator::JSStringIteratorVerify() {
    888   CHECK(IsJSStringIterator());
    889   JSObjectVerify();
    890   CHECK(string()->IsString());
    891 
    892   CHECK_GE(index(), 0);
    893   CHECK_LE(index(), String::kMaxLength);
    894 }
    895 
    896 void JSAsyncFromSyncIterator::JSAsyncFromSyncIteratorVerify() {
    897   CHECK(IsJSAsyncFromSyncIterator());
    898   JSObjectVerify();
    899   VerifyHeapPointer(sync_iterator());
    900 }
    901 
    902 void JSWeakSet::JSWeakSetVerify() {
    903   CHECK(IsJSWeakSet());
    904   JSObjectVerify();
    905   VerifyHeapPointer(table());
    906   CHECK(table()->IsHashTable() || table()->IsUndefined(GetIsolate()));
    907 }
    908 
    909 void JSPromiseCapability::JSPromiseCapabilityVerify() {
    910   CHECK(IsJSPromiseCapability());
    911   JSObjectVerify();
    912   VerifyPointer(promise());
    913   VerifyPointer(resolve());
    914   VerifyPointer(reject());
    915 }
    916 
    917 void JSPromise::JSPromiseVerify() {
    918   CHECK(IsJSPromise());
    919   JSObjectVerify();
    920   Isolate* isolate = GetIsolate();
    921   VerifySmiField(kStatusOffset);
    922   CHECK(result()->IsUndefined(isolate) || result()->IsObject());
    923   CHECK(deferred_promise()->IsUndefined(isolate) ||
    924         deferred_promise()->IsJSReceiver() ||
    925         deferred_promise()->IsFixedArray());
    926   CHECK(deferred_on_resolve()->IsUndefined(isolate) ||
    927         deferred_on_resolve()->IsCallable() ||
    928         deferred_on_resolve()->IsFixedArray());
    929   CHECK(deferred_on_reject()->IsUndefined(isolate) ||
    930         deferred_on_reject()->IsCallable() ||
    931         deferred_on_reject()->IsFixedArray());
    932   CHECK(fulfill_reactions()->IsUndefined(isolate) ||
    933         fulfill_reactions()->IsCallable() || fulfill_reactions()->IsSymbol() ||
    934         fulfill_reactions()->IsFixedArray());
    935   CHECK(reject_reactions()->IsUndefined(isolate) ||
    936         reject_reactions()->IsSymbol() || reject_reactions()->IsCallable() ||
    937         reject_reactions()->IsFixedArray());
    938 }
    939 
    940 void JSRegExp::JSRegExpVerify() {
    941   JSObjectVerify();
    942   Isolate* isolate = GetIsolate();
    943   CHECK(data()->IsUndefined(isolate) || data()->IsFixedArray());
    944   switch (TypeTag()) {
    945     case JSRegExp::ATOM: {
    946       FixedArray* arr = FixedArray::cast(data());
    947       CHECK(arr->get(JSRegExp::kAtomPatternIndex)->IsString());
    948       break;
    949     }
    950     case JSRegExp::IRREGEXP: {
    951       bool is_native = RegExpImpl::UsesNativeRegExp();
    952 
    953       FixedArray* arr = FixedArray::cast(data());
    954       Object* one_byte_data = arr->get(JSRegExp::kIrregexpLatin1CodeIndex);
    955       // Smi : Not compiled yet (-1) or code prepared for flushing.
    956       // JSObject: Compilation error.
    957       // Code/ByteArray: Compiled code.
    958       CHECK(
    959           one_byte_data->IsSmi() ||
    960           (is_native ? one_byte_data->IsCode() : one_byte_data->IsByteArray()));
    961       Object* uc16_data = arr->get(JSRegExp::kIrregexpUC16CodeIndex);
    962       CHECK(uc16_data->IsSmi() ||
    963              (is_native ? uc16_data->IsCode() : uc16_data->IsByteArray()));
    964 
    965       Object* one_byte_saved =
    966           arr->get(JSRegExp::kIrregexpLatin1CodeSavedIndex);
    967       CHECK(one_byte_saved->IsSmi() || one_byte_saved->IsString() ||
    968             one_byte_saved->IsCode());
    969       Object* uc16_saved = arr->get(JSRegExp::kIrregexpUC16CodeSavedIndex);
    970       CHECK(uc16_saved->IsSmi() || uc16_saved->IsString() ||
    971              uc16_saved->IsCode());
    972 
    973       CHECK(arr->get(JSRegExp::kIrregexpCaptureCountIndex)->IsSmi());
    974       CHECK(arr->get(JSRegExp::kIrregexpMaxRegisterCountIndex)->IsSmi());
    975       break;
    976     }
    977     default:
    978       CHECK_EQ(JSRegExp::NOT_COMPILED, TypeTag());
    979       CHECK(data()->IsUndefined(isolate));
    980       break;
    981   }
    982 }
    983 
    984 void JSProxy::JSProxyVerify() {
    985   CHECK(IsJSProxy());
    986   VerifyPointer(target());
    987   VerifyPointer(handler());
    988   Isolate* isolate = GetIsolate();
    989   CHECK_EQ(target()->IsCallable(), map()->is_callable());
    990   CHECK_EQ(target()->IsConstructor(), map()->is_constructor());
    991   CHECK(hash()->IsSmi() || hash()->IsUndefined(isolate));
    992   CHECK(map()->prototype()->IsNull(isolate));
    993   // There should be no properties on a Proxy.
    994   CHECK_EQ(0, map()->NumberOfOwnDescriptors());
    995 }
    996 
    997 
    998 void JSArrayBuffer::JSArrayBufferVerify() {
    999   CHECK(IsJSArrayBuffer());
   1000   JSObjectVerify();
   1001   VerifyPointer(byte_length());
   1002   CHECK(byte_length()->IsSmi() || byte_length()->IsHeapNumber() ||
   1003         byte_length()->IsUndefined(GetIsolate()));
   1004 }
   1005 
   1006 
   1007 void JSArrayBufferView::JSArrayBufferViewVerify() {
   1008   CHECK(IsJSArrayBufferView());
   1009   JSObjectVerify();
   1010   VerifyPointer(buffer());
   1011   Isolate* isolate = GetIsolate();
   1012   CHECK(buffer()->IsJSArrayBuffer() || buffer()->IsUndefined(isolate) ||
   1013         buffer() == Smi::kZero);
   1014 
   1015   VerifyPointer(raw_byte_offset());
   1016   CHECK(raw_byte_offset()->IsSmi() || raw_byte_offset()->IsHeapNumber() ||
   1017         raw_byte_offset()->IsUndefined(isolate));
   1018 
   1019   VerifyPointer(raw_byte_length());
   1020   CHECK(raw_byte_length()->IsSmi() || raw_byte_length()->IsHeapNumber() ||
   1021         raw_byte_length()->IsUndefined(isolate));
   1022 }
   1023 
   1024 
   1025 void JSTypedArray::JSTypedArrayVerify() {
   1026   CHECK(IsJSTypedArray());
   1027   JSArrayBufferViewVerify();
   1028   VerifyPointer(raw_length());
   1029   CHECK(raw_length()->IsSmi() || raw_length()->IsUndefined(GetIsolate()));
   1030   VerifyPointer(elements());
   1031 }
   1032 
   1033 
   1034 void JSDataView::JSDataViewVerify() {
   1035   CHECK(IsJSDataView());
   1036   JSArrayBufferViewVerify();
   1037 }
   1038 
   1039 
   1040 void Foreign::ForeignVerify() {
   1041   CHECK(IsForeign());
   1042 }
   1043 
   1044 
   1045 void PromiseResolveThenableJobInfo::PromiseResolveThenableJobInfoVerify() {
   1046   CHECK(IsPromiseResolveThenableJobInfo());
   1047   CHECK(thenable()->IsJSReceiver());
   1048   CHECK(then()->IsJSReceiver());
   1049   CHECK(resolve()->IsJSFunction());
   1050   CHECK(reject()->IsJSFunction());
   1051   CHECK(context()->IsContext());
   1052 }
   1053 
   1054 void PromiseReactionJobInfo::PromiseReactionJobInfoVerify() {
   1055   Isolate* isolate = GetIsolate();
   1056   CHECK(IsPromiseReactionJobInfo());
   1057   CHECK(value()->IsObject());
   1058   CHECK(tasks()->IsFixedArray() || tasks()->IsCallable() ||
   1059         tasks()->IsSymbol());
   1060   CHECK(deferred_promise()->IsUndefined(isolate) ||
   1061         deferred_promise()->IsJSReceiver() ||
   1062         deferred_promise()->IsFixedArray());
   1063   CHECK(deferred_on_resolve()->IsUndefined(isolate) ||
   1064         deferred_on_resolve()->IsCallable() ||
   1065         deferred_on_resolve()->IsFixedArray());
   1066   CHECK(deferred_on_reject()->IsUndefined(isolate) ||
   1067         deferred_on_reject()->IsCallable() ||
   1068         deferred_on_reject()->IsFixedArray());
   1069   CHECK(context()->IsContext());
   1070 }
   1071 
   1072 void JSModuleNamespace::JSModuleNamespaceVerify() {
   1073   CHECK(IsJSModuleNamespace());
   1074   VerifyPointer(module());
   1075 }
   1076 
   1077 void ModuleInfoEntry::ModuleInfoEntryVerify() {
   1078   Isolate* isolate = GetIsolate();
   1079   CHECK(IsModuleInfoEntry());
   1080 
   1081   CHECK(export_name()->IsUndefined(isolate) || export_name()->IsString());
   1082   CHECK(local_name()->IsUndefined(isolate) || local_name()->IsString());
   1083   CHECK(import_name()->IsUndefined(isolate) || import_name()->IsString());
   1084 
   1085   VerifySmiField(kModuleRequestOffset);
   1086   VerifySmiField(kCellIndexOffset);
   1087   VerifySmiField(kBegPosOffset);
   1088   VerifySmiField(kEndPosOffset);
   1089 
   1090   CHECK_IMPLIES(import_name()->IsString(), module_request() >= 0);
   1091   CHECK_IMPLIES(export_name()->IsString() && import_name()->IsString(),
   1092                 local_name()->IsUndefined(isolate));
   1093 }
   1094 
   1095 void Module::ModuleVerify() {
   1096   CHECK(IsModule());
   1097 
   1098   VerifyPointer(code());
   1099   VerifyPointer(exports());
   1100   VerifyPointer(module_namespace());
   1101   VerifyPointer(requested_modules());
   1102   VerifySmiField(kHashOffset);
   1103 
   1104   CHECK((!instantiated() && code()->IsSharedFunctionInfo()) ||
   1105         (instantiated() && !evaluated() && code()->IsJSFunction()) ||
   1106         (instantiated() && evaluated() && code()->IsModuleInfo()));
   1107 
   1108   CHECK(module_namespace()->IsUndefined(GetIsolate()) ||
   1109         module_namespace()->IsJSModuleNamespace());
   1110   if (module_namespace()->IsJSModuleNamespace()) {
   1111     CHECK_EQ(JSModuleNamespace::cast(module_namespace())->module(), this);
   1112   }
   1113 
   1114   CHECK_EQ(requested_modules()->length(), info()->module_requests()->length());
   1115 
   1116   CHECK_NE(hash(), 0);
   1117 }
   1118 
   1119 void PrototypeInfo::PrototypeInfoVerify() {
   1120   CHECK(IsPrototypeInfo());
   1121   CHECK(weak_cell()->IsWeakCell() || weak_cell()->IsUndefined(GetIsolate()));
   1122   if (prototype_users()->IsWeakFixedArray()) {
   1123     WeakFixedArray::cast(prototype_users())->FixedArrayVerify();
   1124   } else {
   1125     CHECK(prototype_users()->IsSmi());
   1126   }
   1127   CHECK(validity_cell()->IsCell() || validity_cell()->IsSmi());
   1128 }
   1129 
   1130 void Tuple2::Tuple2Verify() {
   1131   CHECK(IsTuple2());
   1132   VerifyObjectField(kValue1Offset);
   1133   VerifyObjectField(kValue2Offset);
   1134 }
   1135 
   1136 void Tuple3::Tuple3Verify() {
   1137   CHECK(IsTuple3());
   1138   VerifyObjectField(kValue1Offset);
   1139   VerifyObjectField(kValue2Offset);
   1140   VerifyObjectField(kValue3Offset);
   1141 }
   1142 
   1143 void ContextExtension::ContextExtensionVerify() {
   1144   CHECK(IsContextExtension());
   1145   VerifyObjectField(kScopeInfoOffset);
   1146   VerifyObjectField(kExtensionOffset);
   1147 }
   1148 
   1149 void ConstantElementsPair::ConstantElementsPairVerify() {
   1150   CHECK(IsConstantElementsPair());
   1151   VerifySmiField(kElementsKindOffset);
   1152   VerifyObjectField(kConstantValuesOffset);
   1153 }
   1154 
   1155 void AccessorInfo::AccessorInfoVerify() {
   1156   CHECK(IsAccessorInfo());
   1157   VerifyPointer(name());
   1158   VerifyPointer(expected_receiver_type());
   1159   VerifyPointer(getter());
   1160   VerifyPointer(setter());
   1161   VerifyPointer(js_getter());
   1162   VerifyPointer(data());
   1163 }
   1164 
   1165 
   1166 void AccessorPair::AccessorPairVerify() {
   1167   CHECK(IsAccessorPair());
   1168   VerifyPointer(getter());
   1169   VerifyPointer(setter());
   1170 }
   1171 
   1172 
   1173 void AccessCheckInfo::AccessCheckInfoVerify() {
   1174   CHECK(IsAccessCheckInfo());
   1175   VerifyPointer(callback());
   1176   VerifyPointer(named_interceptor());
   1177   VerifyPointer(indexed_interceptor());
   1178   VerifyPointer(data());
   1179 }
   1180 
   1181 
   1182 void InterceptorInfo::InterceptorInfoVerify() {
   1183   CHECK(IsInterceptorInfo());
   1184   VerifyPointer(getter());
   1185   VerifyPointer(setter());
   1186   VerifyPointer(query());
   1187   VerifyPointer(deleter());
   1188   VerifyPointer(enumerator());
   1189   VerifyPointer(data());
   1190   VerifySmiField(kFlagsOffset);
   1191 }
   1192 
   1193 
   1194 void CallHandlerInfo::CallHandlerInfoVerify() {
   1195   CHECK(IsCallHandlerInfo());
   1196   VerifyPointer(callback());
   1197   VerifyPointer(data());
   1198 }
   1199 
   1200 
   1201 void TemplateInfo::TemplateInfoVerify() {
   1202   VerifyPointer(tag());
   1203   VerifyPointer(property_list());
   1204   VerifyPointer(property_accessors());
   1205 }
   1206 
   1207 
   1208 void FunctionTemplateInfo::FunctionTemplateInfoVerify() {
   1209   CHECK(IsFunctionTemplateInfo());
   1210   TemplateInfoVerify();
   1211   VerifyPointer(serial_number());
   1212   VerifyPointer(call_code());
   1213   VerifyPointer(prototype_template());
   1214   VerifyPointer(parent_template());
   1215   VerifyPointer(named_property_handler());
   1216   VerifyPointer(indexed_property_handler());
   1217   VerifyPointer(instance_template());
   1218   VerifyPointer(signature());
   1219   VerifyPointer(access_check_info());
   1220   VerifyPointer(cached_property_name());
   1221 }
   1222 
   1223 
   1224 void ObjectTemplateInfo::ObjectTemplateInfoVerify() {
   1225   CHECK(IsObjectTemplateInfo());
   1226   TemplateInfoVerify();
   1227   VerifyPointer(constructor());
   1228   VerifyPointer(data());
   1229 }
   1230 
   1231 
   1232 void AllocationSite::AllocationSiteVerify() {
   1233   CHECK(IsAllocationSite());
   1234 }
   1235 
   1236 
   1237 void AllocationMemento::AllocationMementoVerify() {
   1238   CHECK(IsAllocationMemento());
   1239   VerifyHeapPointer(allocation_site());
   1240   CHECK(!IsValid() || GetAllocationSite()->IsAllocationSite());
   1241 }
   1242 
   1243 
   1244 void Script::ScriptVerify() {
   1245   CHECK(IsScript());
   1246   VerifyPointer(source());
   1247   VerifyPointer(name());
   1248   VerifyPointer(wrapper());
   1249   VerifyPointer(line_ends());
   1250 }
   1251 
   1252 
   1253 void NormalizedMapCache::NormalizedMapCacheVerify() {
   1254   FixedArray::cast(this)->FixedArrayVerify();
   1255   if (FLAG_enable_slow_asserts) {
   1256     Isolate* isolate = GetIsolate();
   1257     for (int i = 0; i < length(); i++) {
   1258       Object* e = FixedArray::get(i);
   1259       if (e->IsMap()) {
   1260         Map::cast(e)->DictionaryMapVerify();
   1261       } else {
   1262         CHECK(e->IsUndefined(isolate));
   1263       }
   1264     }
   1265   }
   1266 }
   1267 
   1268 
   1269 void DebugInfo::DebugInfoVerify() {
   1270   CHECK(IsDebugInfo());
   1271   VerifyPointer(shared());
   1272   VerifyPointer(debug_bytecode_array());
   1273   VerifyPointer(break_points());
   1274 }
   1275 
   1276 
   1277 void BreakPointInfo::BreakPointInfoVerify() {
   1278   CHECK(IsBreakPointInfo());
   1279   VerifyPointer(break_point_objects());
   1280 }
   1281 #endif  // VERIFY_HEAP
   1282 
   1283 #ifdef DEBUG
   1284 
   1285 void JSObject::IncrementSpillStatistics(SpillInformation* info) {
   1286   info->number_of_objects_++;
   1287   // Named properties
   1288   if (HasFastProperties()) {
   1289     info->number_of_objects_with_fast_properties_++;
   1290     info->number_of_fast_used_fields_   += map()->NextFreePropertyIndex();
   1291     info->number_of_fast_unused_fields_ += map()->unused_property_fields();
   1292   } else if (IsJSGlobalObject()) {
   1293     GlobalDictionary* dict = global_dictionary();
   1294     info->number_of_slow_used_properties_ += dict->NumberOfElements();
   1295     info->number_of_slow_unused_properties_ +=
   1296         dict->Capacity() - dict->NumberOfElements();
   1297   } else {
   1298     NameDictionary* dict = property_dictionary();
   1299     info->number_of_slow_used_properties_ += dict->NumberOfElements();
   1300     info->number_of_slow_unused_properties_ +=
   1301         dict->Capacity() - dict->NumberOfElements();
   1302   }
   1303   // Indexed properties
   1304   switch (GetElementsKind()) {
   1305     case FAST_HOLEY_SMI_ELEMENTS:
   1306     case FAST_SMI_ELEMENTS:
   1307     case FAST_HOLEY_DOUBLE_ELEMENTS:
   1308     case FAST_DOUBLE_ELEMENTS:
   1309     case FAST_HOLEY_ELEMENTS:
   1310     case FAST_ELEMENTS:
   1311     case FAST_STRING_WRAPPER_ELEMENTS: {
   1312       info->number_of_objects_with_fast_elements_++;
   1313       int holes = 0;
   1314       FixedArray* e = FixedArray::cast(elements());
   1315       int len = e->length();
   1316       Isolate* isolate = GetIsolate();
   1317       for (int i = 0; i < len; i++) {
   1318         if (e->get(i)->IsTheHole(isolate)) holes++;
   1319       }
   1320       info->number_of_fast_used_elements_   += len - holes;
   1321       info->number_of_fast_unused_elements_ += holes;
   1322       break;
   1323     }
   1324 
   1325 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                       \
   1326     case TYPE##_ELEMENTS:
   1327 
   1328     TYPED_ARRAYS(TYPED_ARRAY_CASE)
   1329 #undef TYPED_ARRAY_CASE
   1330     { info->number_of_objects_with_fast_elements_++;
   1331       FixedArrayBase* e = FixedArrayBase::cast(elements());
   1332       info->number_of_fast_used_elements_ += e->length();
   1333       break;
   1334     }
   1335     case DICTIONARY_ELEMENTS:
   1336     case SLOW_STRING_WRAPPER_ELEMENTS: {
   1337       SeededNumberDictionary* dict = element_dictionary();
   1338       info->number_of_slow_used_elements_ += dict->NumberOfElements();
   1339       info->number_of_slow_unused_elements_ +=
   1340           dict->Capacity() - dict->NumberOfElements();
   1341       break;
   1342     }
   1343     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
   1344     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
   1345     case NO_ELEMENTS:
   1346       break;
   1347   }
   1348 }
   1349 
   1350 
   1351 void JSObject::SpillInformation::Clear() {
   1352   number_of_objects_ = 0;
   1353   number_of_objects_with_fast_properties_ = 0;
   1354   number_of_objects_with_fast_elements_ = 0;
   1355   number_of_fast_used_fields_ = 0;
   1356   number_of_fast_unused_fields_ = 0;
   1357   number_of_slow_used_properties_ = 0;
   1358   number_of_slow_unused_properties_ = 0;
   1359   number_of_fast_used_elements_ = 0;
   1360   number_of_fast_unused_elements_ = 0;
   1361   number_of_slow_used_elements_ = 0;
   1362   number_of_slow_unused_elements_ = 0;
   1363 }
   1364 
   1365 
   1366 void JSObject::SpillInformation::Print() {
   1367   PrintF("\n  JSObject Spill Statistics (#%d):\n", number_of_objects_);
   1368 
   1369   PrintF("    - fast properties (#%d): %d (used) %d (unused)\n",
   1370          number_of_objects_with_fast_properties_,
   1371          number_of_fast_used_fields_, number_of_fast_unused_fields_);
   1372 
   1373   PrintF("    - slow properties (#%d): %d (used) %d (unused)\n",
   1374          number_of_objects_ - number_of_objects_with_fast_properties_,
   1375          number_of_slow_used_properties_, number_of_slow_unused_properties_);
   1376 
   1377   PrintF("    - fast elements (#%d): %d (used) %d (unused)\n",
   1378          number_of_objects_with_fast_elements_,
   1379          number_of_fast_used_elements_, number_of_fast_unused_elements_);
   1380 
   1381   PrintF("    - slow elements (#%d): %d (used) %d (unused)\n",
   1382          number_of_objects_ - number_of_objects_with_fast_elements_,
   1383          number_of_slow_used_elements_, number_of_slow_unused_elements_);
   1384 
   1385   PrintF("\n");
   1386 }
   1387 
   1388 
   1389 bool DescriptorArray::IsSortedNoDuplicates(int valid_entries) {
   1390   if (valid_entries == -1) valid_entries = number_of_descriptors();
   1391   Name* current_key = NULL;
   1392   uint32_t current = 0;
   1393   for (int i = 0; i < number_of_descriptors(); i++) {
   1394     Name* key = GetSortedKey(i);
   1395     if (key == current_key) {
   1396       Print();
   1397       return false;
   1398     }
   1399     current_key = key;
   1400     uint32_t hash = GetSortedKey(i)->Hash();
   1401     if (hash < current) {
   1402       Print();
   1403       return false;
   1404     }
   1405     current = hash;
   1406   }
   1407   return true;
   1408 }
   1409 
   1410 
   1411 bool TransitionArray::IsSortedNoDuplicates(int valid_entries) {
   1412   DCHECK(valid_entries == -1);
   1413   Name* prev_key = NULL;
   1414   PropertyKind prev_kind = kData;
   1415   PropertyAttributes prev_attributes = NONE;
   1416   uint32_t prev_hash = 0;
   1417   for (int i = 0; i < number_of_transitions(); i++) {
   1418     Name* key = GetSortedKey(i);
   1419     uint32_t hash = key->Hash();
   1420     PropertyKind kind = kData;
   1421     PropertyAttributes attributes = NONE;
   1422     if (!IsSpecialTransition(key)) {
   1423       Map* target = GetTarget(i);
   1424       PropertyDetails details = GetTargetDetails(key, target);
   1425       kind = details.kind();
   1426       attributes = details.attributes();
   1427     } else {
   1428       // Duplicate entries are not allowed for non-property transitions.
   1429       CHECK_NE(prev_key, key);
   1430     }
   1431 
   1432     int cmp = CompareKeys(prev_key, prev_hash, prev_kind, prev_attributes, key,
   1433                           hash, kind, attributes);
   1434     if (cmp >= 0) {
   1435       Print();
   1436       return false;
   1437     }
   1438     prev_key = key;
   1439     prev_hash = hash;
   1440     prev_attributes = attributes;
   1441     prev_kind = kind;
   1442   }
   1443   return true;
   1444 }
   1445 
   1446 
   1447 // static
   1448 bool TransitionArray::IsSortedNoDuplicates(Map* map) {
   1449   Object* raw_transitions = map->raw_transitions();
   1450   if (IsFullTransitionArray(raw_transitions)) {
   1451     return TransitionArray::cast(raw_transitions)->IsSortedNoDuplicates();
   1452   }
   1453   // Simple and non-existent transitions are always sorted.
   1454   return true;
   1455 }
   1456 
   1457 
   1458 static bool CheckOneBackPointer(Map* current_map, Object* target) {
   1459   return !target->IsMap() || Map::cast(target)->GetBackPointer() == current_map;
   1460 }
   1461 
   1462 
   1463 // static
   1464 bool TransitionArray::IsConsistentWithBackPointers(Map* map) {
   1465   Object* transitions = map->raw_transitions();
   1466   for (int i = 0; i < TransitionArray::NumberOfTransitions(transitions); ++i) {
   1467     Map* target = TransitionArray::GetTarget(transitions, i);
   1468     if (!CheckOneBackPointer(map, target)) return false;
   1469   }
   1470   return true;
   1471 }
   1472 
   1473 
   1474 // Estimates if there is a path from the object to a context.
   1475 // This function is not precise, and can return false even if
   1476 // there is a path to a context.
   1477 bool CanLeak(Object* obj, Heap* heap, bool skip_weak_cell) {
   1478   if (!obj->IsHeapObject()) return false;
   1479   if (obj->IsWeakCell()) {
   1480     if (skip_weak_cell) return false;
   1481     return CanLeak(WeakCell::cast(obj)->value(), heap, skip_weak_cell);
   1482   }
   1483   if (obj->IsCell()) {
   1484     return CanLeak(Cell::cast(obj)->value(), heap, skip_weak_cell);
   1485   }
   1486   if (obj->IsPropertyCell()) {
   1487     return CanLeak(PropertyCell::cast(obj)->value(), heap, skip_weak_cell);
   1488   }
   1489   if (obj->IsContext()) return true;
   1490   if (obj->IsMap()) {
   1491     Map* map = Map::cast(obj);
   1492     for (int i = 0; i < Heap::kStrongRootListLength; i++) {
   1493       Heap::RootListIndex root_index = static_cast<Heap::RootListIndex>(i);
   1494       if (map == heap->root(root_index)) return false;
   1495     }
   1496     return true;
   1497   }
   1498   return CanLeak(HeapObject::cast(obj)->map(), heap, skip_weak_cell);
   1499 }
   1500 
   1501 
   1502 void Code::VerifyEmbeddedObjects(VerifyMode mode) {
   1503   if (kind() == OPTIMIZED_FUNCTION) return;
   1504   Heap* heap = GetIsolate()->heap();
   1505   int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
   1506              RelocInfo::ModeMask(RelocInfo::CELL);
   1507   bool skip_weak_cell = (mode == kNoContextSpecificPointers) ? false : true;
   1508   for (RelocIterator it(this, mask); !it.done(); it.next()) {
   1509     Object* target = it.rinfo()->rmode() == RelocInfo::CELL
   1510                          ? it.rinfo()->target_cell()
   1511                          : it.rinfo()->target_object();
   1512     CHECK(!CanLeak(target, heap, skip_weak_cell));
   1513   }
   1514 }
   1515 
   1516 
   1517 // Verify that the debugger can redirect old code to the new code.
   1518 void Code::VerifyRecompiledCode(Code* old_code, Code* new_code) {
   1519   if (old_code->kind() != FUNCTION) return;
   1520   if (new_code->kind() != FUNCTION) return;
   1521   Isolate* isolate = old_code->GetIsolate();
   1522   // Do not verify during bootstrapping. We may replace code using %SetCode.
   1523   if (isolate->bootstrapper()->IsActive()) return;
   1524 
   1525   static const int mask = RelocInfo::kCodeTargetMask;
   1526   RelocIterator old_it(old_code, mask);
   1527   RelocIterator new_it(new_code, mask);
   1528   Code* stack_check = isolate->builtins()->builtin(Builtins::kStackCheck);
   1529 
   1530   while (!old_it.done()) {
   1531     RelocInfo* rinfo = old_it.rinfo();
   1532     Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
   1533     CHECK(!target->is_handler() && !target->is_inline_cache_stub());
   1534     if (target == stack_check) break;
   1535     old_it.next();
   1536   }
   1537 
   1538   while (!new_it.done()) {
   1539     RelocInfo* rinfo = new_it.rinfo();
   1540     Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
   1541     CHECK(!target->is_handler() && !target->is_inline_cache_stub());
   1542     if (target == stack_check) break;
   1543     new_it.next();
   1544   }
   1545 
   1546   // Either both are done because there is no stack check.
   1547   // Or we are past the prologue for both.
   1548   CHECK_EQ(new_it.done(), old_it.done());
   1549 
   1550   // After the prologue, each call in the old code has a corresponding call
   1551   // in the new code.
   1552   while (!old_it.done() && !new_it.done()) {
   1553     Code* old_target =
   1554         Code::GetCodeFromTargetAddress(old_it.rinfo()->target_address());
   1555     Code* new_target =
   1556         Code::GetCodeFromTargetAddress(new_it.rinfo()->target_address());
   1557     CHECK_EQ(old_target->kind(), new_target->kind());
   1558     // Check call target for equality unless it's an IC or an interrupt check.
   1559     // In both cases they may be patched to be something else.
   1560     if (!old_target->is_handler() && !old_target->is_inline_cache_stub() &&
   1561         new_target != isolate->builtins()->builtin(Builtins::kInterruptCheck)) {
   1562       CHECK_EQ(old_target, new_target);
   1563     }
   1564     old_it.next();
   1565     new_it.next();
   1566   }
   1567 
   1568   // Both are done at the same time.
   1569   CHECK_EQ(new_it.done(), old_it.done());
   1570 }
   1571 
   1572 
   1573 #endif  // DEBUG
   1574 
   1575 }  // namespace internal
   1576 }  // namespace v8
   1577