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