// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/objects.h"

#include "src/assembler-inl.h"
#include "src/bootstrapper.h"
#include "src/counters.h"
#include "src/date.h"
#include "src/disasm.h"
#include "src/disassembler.h"
#include "src/elements.h"
#include "src/field-type.h"
#include "src/heap/heap-write-barrier-inl.h"
#include "src/ic/handler-configuration-inl.h"
#include "src/layout-descriptor.h"
#include "src/objects-inl.h"
#include "src/objects/allocation-site-inl.h"
#include "src/objects/arguments-inl.h"
#include "src/objects/bigint.h"
#include "src/objects/cell-inl.h"
#include "src/objects/data-handler-inl.h"
#include "src/objects/debug-objects-inl.h"
#include "src/objects/embedder-data-array-inl.h"
#include "src/objects/embedder-data-slot-inl.h"
#include "src/objects/feedback-cell-inl.h"
#include "src/objects/foreign-inl.h"
#include "src/objects/free-space-inl.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/js-array-inl.h"
#ifdef V8_INTL_SUPPORT
#include "src/objects/js-break-iterator-inl.h"
#include "src/objects/js-collator-inl.h"
#endif  // V8_INTL_SUPPORT
#include "src/objects/js-collection-inl.h"
#ifdef V8_INTL_SUPPORT
#include "src/objects/js-date-time-format-inl.h"
#endif  // V8_INTL_SUPPORT
#include "src/objects/js-generator-inl.h"
#ifdef V8_INTL_SUPPORT
#include "src/objects/js-list-format-inl.h"
#include "src/objects/js-locale-inl.h"
#include "src/objects/js-number-format-inl.h"
#include "src/objects/js-plural-rules-inl.h"
#endif  // V8_INTL_SUPPORT
#include "src/objects/js-regexp-inl.h"
#include "src/objects/js-regexp-string-iterator-inl.h"
#ifdef V8_INTL_SUPPORT
#include "src/objects/js-relative-time-format-inl.h"
#include "src/objects/js-segment-iterator-inl.h"
#include "src/objects/js-segmenter-inl.h"
#endif  // V8_INTL_SUPPORT
#include "src/objects/js-weak-refs-inl.h"
#include "src/objects/literal-objects-inl.h"
#include "src/objects/maybe-object.h"
#include "src/objects/microtask-inl.h"
#include "src/objects/module-inl.h"
#include "src/objects/oddball-inl.h"
#include "src/objects/promise-inl.h"
#include "src/objects/stack-frame-info-inl.h"
#include "src/objects/struct-inl.h"
#include "src/ostreams.h"
#include "src/regexp/jsregexp.h"
#include "src/transitions-inl.h"
#include "src/wasm/wasm-objects-inl.h"

namespace v8 {
namespace internal {

// Heap Verification Overview
// --------------------------
// - Each InstanceType has a separate XXXVerify method which checks an object's
//   integrity in isolation.
// - --verify-heap will iterate over all gc spaces and call ObjectVerify() on
//   every encountered tagged pointer.
// - Verification should be pushed down to the specific instance type if its
//   integrity is independent of an outer object.
// - In cases where the InstanceType is too genernic (e.g. FixedArray) the
//   XXXVerify of the outer method has to do recursive verification.
// - If the corresponding objects have inheritence the parent's Verify method
//   is called as well.
// - For any field containing pointes VerifyPointer(...) should be called.
//
// Caveats
// -------
// - Assume that any of the verify methods is incomplete!
// - Some integrity checks are only partially done due to objects being in
//   partially initialized states when a gc happens, for instance when outer
//   objects are allocted before inner ones.
//

#ifdef VERIFY_HEAP

void Object::ObjectVerify(Isolate* isolate) {
  RuntimeCallTimerScope timer(isolate, RuntimeCallCounterId::kObjectVerify);
  if (IsSmi()) {
    Smi::cast(*this)->SmiVerify(isolate);
  } else {
    HeapObject::cast(*this)->HeapObjectVerify(isolate);
  }
  CHECK(!IsConstructor() || IsCallable());
}

void Object::VerifyPointer(Isolate* isolate, Object p) {
  if (p->IsHeapObject()) {
    HeapObject::VerifyHeapPointer(isolate, p);
  } else {
    CHECK(p->IsSmi());
  }
}

void MaybeObject::VerifyMaybeObjectPointer(Isolate* isolate, MaybeObject p) {
  HeapObject heap_object;
  if (p->GetHeapObject(&heap_object)) {
    HeapObject::VerifyHeapPointer(isolate, heap_object);
  } else {
    CHECK(p->IsSmi() || p->IsCleared());
  }
}

namespace {
void VerifyForeignPointer(Isolate* isolate, HeapObject host, Object foreign) {
  host->VerifyPointer(isolate, foreign);
  CHECK(foreign->IsUndefined(isolate) || Foreign::IsNormalized(foreign));
}
}  // namespace

void Smi::SmiVerify(Isolate* isolate) {
  CHECK(IsSmi());
  CHECK(!IsCallable());
  CHECK(!IsConstructor());
}

void HeapObject::HeapObjectVerify(Isolate* isolate) {
  VerifyHeapPointer(isolate, map());
  CHECK(map()->IsMap());

  switch (map()->instance_type()) {
#define STRING_TYPE_CASE(TYPE, size, name, CamelName) case TYPE:
    STRING_TYPE_LIST(STRING_TYPE_CASE)
#undef STRING_TYPE_CASE
    String::cast(*this)->StringVerify(isolate);
    break;
    case SYMBOL_TYPE:
      Symbol::cast(*this)->SymbolVerify(isolate);
      break;
    case MAP_TYPE:
      Map::cast(*this)->MapVerify(isolate);
      break;
    case HEAP_NUMBER_TYPE:
      CHECK(IsHeapNumber());
      break;
    case MUTABLE_HEAP_NUMBER_TYPE:
      CHECK(IsMutableHeapNumber());
      break;
    case BIGINT_TYPE:
      BigInt::cast(*this)->BigIntVerify(isolate);
      break;
    case CALL_HANDLER_INFO_TYPE:
      CallHandlerInfo::cast(*this)->CallHandlerInfoVerify(isolate);
      break;
    case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
      ObjectBoilerplateDescription::cast(*this)
          ->ObjectBoilerplateDescriptionVerify(isolate);
      break;
    case EMBEDDER_DATA_ARRAY_TYPE:
      EmbedderDataArray::cast(*this)->EmbedderDataArrayVerify(isolate);
      break;
    // FixedArray types
    case CLOSURE_FEEDBACK_CELL_ARRAY_TYPE:
    case HASH_TABLE_TYPE:
    case ORDERED_HASH_MAP_TYPE:
    case ORDERED_HASH_SET_TYPE:
    case ORDERED_NAME_DICTIONARY_TYPE:
    case NAME_DICTIONARY_TYPE:
    case GLOBAL_DICTIONARY_TYPE:
    case NUMBER_DICTIONARY_TYPE:
    case SIMPLE_NUMBER_DICTIONARY_TYPE:
    case STRING_TABLE_TYPE:
    case EPHEMERON_HASH_TABLE_TYPE:
    case FIXED_ARRAY_TYPE:
    case SCOPE_INFO_TYPE:
    case SCRIPT_CONTEXT_TABLE_TYPE:
      FixedArray::cast(*this)->FixedArrayVerify(isolate);
      break;
    case AWAIT_CONTEXT_TYPE:
    case BLOCK_CONTEXT_TYPE:
    case CATCH_CONTEXT_TYPE:
    case DEBUG_EVALUATE_CONTEXT_TYPE:
    case EVAL_CONTEXT_TYPE:
    case FUNCTION_CONTEXT_TYPE:
    case MODULE_CONTEXT_TYPE:
    case SCRIPT_CONTEXT_TYPE:
    case WITH_CONTEXT_TYPE:
      Context::cast(*this)->ContextVerify(isolate);
      break;
    case NATIVE_CONTEXT_TYPE:
      NativeContext::cast(*this)->NativeContextVerify(isolate);
      break;
    case WEAK_FIXED_ARRAY_TYPE:
      WeakFixedArray::cast(*this)->WeakFixedArrayVerify(isolate);
      break;
    case WEAK_ARRAY_LIST_TYPE:
      WeakArrayList::cast(*this)->WeakArrayListVerify(isolate);
      break;
    case FIXED_DOUBLE_ARRAY_TYPE:
      FixedDoubleArray::cast(*this)->FixedDoubleArrayVerify(isolate);
      break;
    case FEEDBACK_METADATA_TYPE:
      FeedbackMetadata::cast(*this)->FeedbackMetadataVerify(isolate);
      break;
    case BYTE_ARRAY_TYPE:
      ByteArray::cast(*this)->ByteArrayVerify(isolate);
      break;
    case BYTECODE_ARRAY_TYPE:
      BytecodeArray::cast(*this)->BytecodeArrayVerify(isolate);
      break;
    case DESCRIPTOR_ARRAY_TYPE:
      DescriptorArray::cast(*this)->DescriptorArrayVerify(isolate);
      break;
    case TRANSITION_ARRAY_TYPE:
      TransitionArray::cast(*this)->TransitionArrayVerify(isolate);
      break;
    case PROPERTY_ARRAY_TYPE:
      PropertyArray::cast(*this)->PropertyArrayVerify(isolate);
      break;
    case FREE_SPACE_TYPE:
      FreeSpace::cast(*this)->FreeSpaceVerify(isolate);
      break;
    case FEEDBACK_CELL_TYPE:
      FeedbackCell::cast(*this)->FeedbackCellVerify(isolate);
      break;
    case FEEDBACK_VECTOR_TYPE:
      FeedbackVector::cast(*this)->FeedbackVectorVerify(isolate);
      break;

#define VERIFY_TYPED_ARRAY(Type, type, TYPE, ctype)                  \
  case FIXED_##TYPE##_ARRAY_TYPE:                                    \
    Fixed##Type##Array::cast(*this)->FixedTypedArrayVerify(isolate); \
    break;

      TYPED_ARRAYS(VERIFY_TYPED_ARRAY)
#undef VERIFY_TYPED_ARRAY

    case CODE_TYPE:
      Code::cast(*this)->CodeVerify(isolate);
      break;
    case ODDBALL_TYPE:
      Oddball::cast(*this)->OddballVerify(isolate);
      break;
    case JS_OBJECT_TYPE:
    case JS_ERROR_TYPE:
    case JS_API_OBJECT_TYPE:
    case JS_SPECIAL_API_OBJECT_TYPE:
    case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
    case WASM_EXCEPTION_TYPE:
    case WASM_GLOBAL_TYPE:
    case WASM_MEMORY_TYPE:
    case WASM_TABLE_TYPE:
      JSObject::cast(*this)->JSObjectVerify(isolate);
      break;
    case WASM_MODULE_TYPE:
      WasmModuleObject::cast(*this)->WasmModuleObjectVerify(isolate);
      break;
    case WASM_INSTANCE_TYPE:
      WasmInstanceObject::cast(*this)->WasmInstanceObjectVerify(isolate);
      break;
    case JS_ARGUMENTS_TYPE:
      JSArgumentsObject::cast(*this)->JSArgumentsObjectVerify(isolate);
      break;
    case JS_GENERATOR_OBJECT_TYPE:
      JSGeneratorObject::cast(*this)->JSGeneratorObjectVerify(isolate);
      break;
    case JS_ASYNC_FUNCTION_OBJECT_TYPE:
      JSAsyncFunctionObject::cast(*this)->JSAsyncFunctionObjectVerify(isolate);
      break;
    case JS_ASYNC_GENERATOR_OBJECT_TYPE:
      JSAsyncGeneratorObject::cast(*this)->JSAsyncGeneratorObjectVerify(
          isolate);
      break;
    case JS_VALUE_TYPE:
      JSValue::cast(*this)->JSValueVerify(isolate);
      break;
    case JS_DATE_TYPE:
      JSDate::cast(*this)->JSDateVerify(isolate);
      break;
    case JS_BOUND_FUNCTION_TYPE:
      JSBoundFunction::cast(*this)->JSBoundFunctionVerify(isolate);
      break;
    case JS_FUNCTION_TYPE:
      JSFunction::cast(*this)->JSFunctionVerify(isolate);
      break;
    case JS_GLOBAL_PROXY_TYPE:
      JSGlobalProxy::cast(*this)->JSGlobalProxyVerify(isolate);
      break;
    case JS_GLOBAL_OBJECT_TYPE:
      JSGlobalObject::cast(*this)->JSGlobalObjectVerify(isolate);
      break;
    case CELL_TYPE:
      Cell::cast(*this)->CellVerify(isolate);
      break;
    case PROPERTY_CELL_TYPE:
      PropertyCell::cast(*this)->PropertyCellVerify(isolate);
      break;
    case JS_ARRAY_TYPE:
      JSArray::cast(*this)->JSArrayVerify(isolate);
      break;
    case JS_MODULE_NAMESPACE_TYPE:
      JSModuleNamespace::cast(*this)->JSModuleNamespaceVerify(isolate);
      break;
    case JS_SET_TYPE:
      JSSet::cast(*this)->JSSetVerify(isolate);
      break;
    case JS_MAP_TYPE:
      JSMap::cast(*this)->JSMapVerify(isolate);
      break;
    case JS_SET_KEY_VALUE_ITERATOR_TYPE:
    case JS_SET_VALUE_ITERATOR_TYPE:
      JSSetIterator::cast(*this)->JSSetIteratorVerify(isolate);
      break;
    case JS_MAP_KEY_ITERATOR_TYPE:
    case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
    case JS_MAP_VALUE_ITERATOR_TYPE:
      JSMapIterator::cast(*this)->JSMapIteratorVerify(isolate);
      break;
    case JS_ARRAY_ITERATOR_TYPE:
      JSArrayIterator::cast(*this)->JSArrayIteratorVerify(isolate);
      break;
    case JS_STRING_ITERATOR_TYPE:
      JSStringIterator::cast(*this)->JSStringIteratorVerify(isolate);
      break;
    case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
      JSAsyncFromSyncIterator::cast(*this)->JSAsyncFromSyncIteratorVerify(
          isolate);
      break;
    case WEAK_CELL_TYPE:
      WeakCell::cast(*this)->WeakCellVerify(isolate);
      break;
    case JS_WEAK_REF_TYPE:
      JSWeakRef::cast(*this)->JSWeakRefVerify(isolate);
      break;
    case JS_FINALIZATION_GROUP_TYPE:
      JSFinalizationGroup::cast(*this)->JSFinalizationGroupVerify(isolate);
      break;
    case JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE:
      JSFinalizationGroupCleanupIterator::cast(*this)
          ->JSFinalizationGroupCleanupIteratorVerify(isolate);
      break;
    case JS_WEAK_MAP_TYPE:
      JSWeakMap::cast(*this)->JSWeakMapVerify(isolate);
      break;
    case JS_WEAK_SET_TYPE:
      JSWeakSet::cast(*this)->JSWeakSetVerify(isolate);
      break;
    case JS_PROMISE_TYPE:
      JSPromise::cast(*this)->JSPromiseVerify(isolate);
      break;
    case JS_REGEXP_TYPE:
      JSRegExp::cast(*this)->JSRegExpVerify(isolate);
      break;
    case JS_REGEXP_STRING_ITERATOR_TYPE:
      JSRegExpStringIterator::cast(*this)->JSRegExpStringIteratorVerify(
          isolate);
      break;
    case FILLER_TYPE:
      break;
    case JS_PROXY_TYPE:
      JSProxy::cast(*this)->JSProxyVerify(isolate);
      break;
    case FOREIGN_TYPE:
      Foreign::cast(*this)->ForeignVerify(isolate);
      break;
    case PREPARSE_DATA_TYPE:
      PreparseData::cast(*this)->PreparseDataVerify(isolate);
      break;
    case UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE:
      UncompiledDataWithoutPreparseData::cast(*this)
          ->UncompiledDataWithoutPreparseDataVerify(isolate);
      break;
    case UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE:
      UncompiledDataWithPreparseData::cast(*this)
          ->UncompiledDataWithPreparseDataVerify(isolate);
      break;
    case SHARED_FUNCTION_INFO_TYPE:
      SharedFunctionInfo::cast(*this)->SharedFunctionInfoVerify(isolate);
      break;
    case JS_MESSAGE_OBJECT_TYPE:
      JSMessageObject::cast(*this)->JSMessageObjectVerify(isolate);
      break;
    case JS_ARRAY_BUFFER_TYPE:
      JSArrayBuffer::cast(*this)->JSArrayBufferVerify(isolate);
      break;
    case JS_TYPED_ARRAY_TYPE:
      JSTypedArray::cast(*this)->JSTypedArrayVerify(isolate);
      break;
    case JS_DATA_VIEW_TYPE:
      JSDataView::cast(*this)->JSDataViewVerify(isolate);
      break;
    case SMALL_ORDERED_HASH_SET_TYPE:
      SmallOrderedHashSet::cast(*this)->SmallOrderedHashSetVerify(isolate);
      break;
    case SMALL_ORDERED_HASH_MAP_TYPE:
      SmallOrderedHashMap::cast(*this)->SmallOrderedHashMapVerify(isolate);
      break;
    case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
      SmallOrderedNameDictionary::cast(*this)->SmallOrderedNameDictionaryVerify(
          isolate);
      break;
    case CODE_DATA_CONTAINER_TYPE:
      CodeDataContainer::cast(*this)->CodeDataContainerVerify(isolate);
      break;
#ifdef V8_INTL_SUPPORT
    case JS_INTL_V8_BREAK_ITERATOR_TYPE:
      JSV8BreakIterator::cast(*this)->JSV8BreakIteratorVerify(isolate);
      break;
    case JS_INTL_COLLATOR_TYPE:
      JSCollator::cast(*this)->JSCollatorVerify(isolate);
      break;
    case JS_INTL_DATE_TIME_FORMAT_TYPE:
      JSDateTimeFormat::cast(*this)->JSDateTimeFormatVerify(isolate);
      break;
    case JS_INTL_LIST_FORMAT_TYPE:
      JSListFormat::cast(*this)->JSListFormatVerify(isolate);
      break;
    case JS_INTL_LOCALE_TYPE:
      JSLocale::cast(*this)->JSLocaleVerify(isolate);
      break;
    case JS_INTL_NUMBER_FORMAT_TYPE:
      JSNumberFormat::cast(*this)->JSNumberFormatVerify(isolate);
      break;
    case JS_INTL_PLURAL_RULES_TYPE:
      JSPluralRules::cast(*this)->JSPluralRulesVerify(isolate);
      break;
    case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
      JSRelativeTimeFormat::cast(*this)->JSRelativeTimeFormatVerify(isolate);
      break;
    case JS_INTL_SEGMENT_ITERATOR_TYPE:
      JSSegmentIterator::cast(*this)->JSSegmentIteratorVerify(isolate);
      break;
    case JS_INTL_SEGMENTER_TYPE:
      JSSegmenter::cast(*this)->JSSegmenterVerify(isolate);
      break;
#endif  // V8_INTL_SUPPORT

#define MAKE_STRUCT_CASE(TYPE, Name, name)    \
  case TYPE:                                  \
    Name::cast(*this)->Name##Verify(isolate); \
    break;
      STRUCT_LIST(MAKE_STRUCT_CASE)
#undef MAKE_STRUCT_CASE

    case ALLOCATION_SITE_TYPE:
      AllocationSite::cast(*this)->AllocationSiteVerify(isolate);
      break;

    case LOAD_HANDLER_TYPE:
      LoadHandler::cast(*this)->LoadHandlerVerify(isolate);
      break;

    case STORE_HANDLER_TYPE:
      StoreHandler::cast(*this)->StoreHandlerVerify(isolate);
      break;
  }
}

// static
void HeapObject::VerifyHeapPointer(Isolate* isolate, Object p) {
  CHECK(p->IsHeapObject());
  HeapObject ho = HeapObject::cast(p);
  CHECK(isolate->heap()->Contains(ho));
}

void Symbol::SymbolVerify(Isolate* isolate) {
  CHECK(IsSymbol());
  CHECK(HasHashCode());
  CHECK_GT(Hash(), 0);
  CHECK(name()->IsUndefined(isolate) || name()->IsString());
  CHECK_IMPLIES(IsPrivateName(), IsPrivate());
}

void ByteArray::ByteArrayVerify(Isolate* isolate) { CHECK(IsByteArray()); }

void BytecodeArray::BytecodeArrayVerify(Isolate* isolate) {
  // TODO(oth): Walk bytecodes and immediate values to validate sanity.
  // - All bytecodes are known and well formed.
  // - Jumps must go to new instructions starts.
  // - No Illegal bytecodes.
  // - No consecutive sequences of prefix Wide / ExtraWide.
  CHECK(IsBytecodeArray());
  CHECK(constant_pool()->IsFixedArray());
  VerifyHeapPointer(isolate, constant_pool());
}

void FreeSpace::FreeSpaceVerify(Isolate* isolate) {
  CHECK(IsFreeSpace());
  VerifySmiField(kSizeOffset);
}

void FeedbackCell::FeedbackCellVerify(Isolate* isolate) {
  CHECK(IsFeedbackCell());

  VerifyHeapPointer(isolate, value());
  CHECK(value()->IsUndefined(isolate) || value()->IsFeedbackVector() ||
        value()->IsFixedArray());
}

void FeedbackVector::FeedbackVectorVerify(Isolate* isolate) {
  CHECK(IsFeedbackVector());
  CHECK(closure_feedback_cell_array()->IsFixedArray());
  MaybeObject code = optimized_code_weak_or_smi();
  MaybeObject::VerifyMaybeObjectPointer(isolate, code);
  CHECK(code->IsSmi() || code->IsWeakOrCleared());
}

template <class Traits>
void FixedTypedArray<Traits>::FixedTypedArrayVerify(Isolate* isolate) {
  CHECK(IsHeapObject() && map()->instance_type() == Traits::kInstanceType);
  if (base_pointer()->ptr() == ptr()) {
    CHECK_EQ(reinterpret_cast<Address>(external_pointer()),
             FixedTypedArrayBase::kDataOffset - kHeapObjectTag);
  } else {
    CHECK_EQ(base_pointer(), Smi::kZero);
  }
}

bool JSObject::ElementsAreSafeToExamine() const {
  // If a GC was caused while constructing this object, the elements
  // pointer may point to a one pointer filler map.
  return elements() != GetReadOnlyRoots().one_pointer_filler_map();
}

namespace {
void VerifyJSObjectElements(Isolate* isolate, JSObject object) {
  // Only TypedArrays can have these specialized elements.
  if (object->IsJSTypedArray()) {
    // TODO(cbruni): Fix CreateTypedArray to either not instantiate the object
    // or propertly initialize it on errors during construction.
    /* CHECK(object->HasFixedTypedArrayElements()); */
    /* CHECK(object->elements()->IsFixedTypedArrayBase()); */
    return;
  }
  CHECK(!object->HasFixedTypedArrayElements());
  CHECK(!object->elements()->IsFixedTypedArrayBase());

  if (object->HasDoubleElements()) {
    if (object->elements()->length() > 0) {
      CHECK(object->elements()->IsFixedDoubleArray());
    }
    return;
  }

  FixedArray elements = FixedArray::cast(object->elements());
  if (object->HasSmiElements()) {
    // We might have a partially initialized backing store, in which case we
    // allow the hole + smi values.
    for (int i = 0; i < elements->length(); i++) {
      Object value = elements->get(i);
      CHECK(value->IsSmi() || value->IsTheHole(isolate));
    }
  } else if (object->HasObjectElements()) {
    for (int i = 0; i < elements->length(); i++) {
      Object element = elements->get(i);
      CHECK_IMPLIES(!element->IsSmi(), !HasWeakHeapObjectTag(element));
    }
  }
}
}  // namespace

void JSObject::JSObjectVerify(Isolate* isolate) {
  VerifyPointer(isolate, raw_properties_or_hash());
  VerifyHeapPointer(isolate, elements());

  CHECK_IMPLIES(HasSloppyArgumentsElements(), IsJSArgumentsObject());
  if (HasFastProperties()) {
    int actual_unused_property_fields = map()->GetInObjectProperties() +
                                        property_array()->length() -
                                        map()->NextFreePropertyIndex();
    if (map()->UnusedPropertyFields() != actual_unused_property_fields) {
      // There are two reasons why this can happen:
      // - in the middle of StoreTransitionStub when the new extended backing
      //   store is already set into the object and the allocation of the
      //   MutableHeapNumber triggers GC while the map isn't updated yet.
      // - deletion of the last property can leave additional backing store
      //   capacity behind.
      CHECK_GT(actual_unused_property_fields, map()->UnusedPropertyFields());
      int delta = actual_unused_property_fields - map()->UnusedPropertyFields();
      CHECK_EQ(0, delta % JSObject::kFieldsAdded);
    }
    DescriptorArray descriptors = map()->instance_descriptors();
    bool is_transitionable_fast_elements_kind =
        IsTransitionableFastElementsKind(map()->elements_kind());

    for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) {
      PropertyDetails details = descriptors->GetDetails(i);
      if (details.location() == kField) {
        DCHECK_EQ(kData, details.kind());
        Representation r = details.representation();
        FieldIndex index = FieldIndex::ForDescriptor(map(), i);
        if (IsUnboxedDoubleField(index)) {
          DCHECK(r.IsDouble());
          continue;
        }
        if (COMPRESS_POINTERS_BOOL && index.is_inobject()) {
          VerifyObjectField(isolate, index.offset());
        }
        Object value = RawFastPropertyAt(index);
        if (r.IsDouble()) DCHECK(value->IsMutableHeapNumber());
        if (value->IsUninitialized(isolate)) continue;
        if (r.IsSmi()) DCHECK(value->IsSmi());
        if (r.IsHeapObject()) DCHECK(value->IsHeapObject());
        FieldType field_type = descriptors->GetFieldType(i);
        bool type_is_none = field_type->IsNone();
        bool type_is_any = field_type->IsAny();
        if (r.IsNone()) {
          CHECK(type_is_none);
        } else if (!type_is_any && !(type_is_none && r.IsHeapObject())) {
          CHECK(!field_type->NowStable() || field_type->NowContains(value));
        }
        CHECK_IMPLIES(is_transitionable_fast_elements_kind,
                      Map::IsMostGeneralFieldType(r, field_type));
      }
    }

    if (map()->EnumLength() != kInvalidEnumCacheSentinel) {
      EnumCache enum_cache = descriptors->enum_cache();
      FixedArray keys = enum_cache->keys();
      FixedArray indices = enum_cache->indices();
      CHECK_LE(map()->EnumLength(), keys->length());
      CHECK_IMPLIES(indices != ReadOnlyRoots(isolate).empty_fixed_array(),
                    keys->length() == indices->length());
    }
  }

  // If a GC was caused while constructing this object, the elements
  // pointer may point to a one pointer filler map.
  if (ElementsAreSafeToExamine()) {
    CHECK_EQ((map()->has_fast_smi_or_object_elements() ||
              (elements() == GetReadOnlyRoots().empty_fixed_array()) ||
              HasFastStringWrapperElements()),
             (elements()->map() == GetReadOnlyRoots().fixed_array_map() ||
              elements()->map() == GetReadOnlyRoots().fixed_cow_array_map()));
    CHECK_EQ(map()->has_fast_object_elements(), HasObjectElements());
    VerifyJSObjectElements(isolate, *this);
  }
}

void Map::MapVerify(Isolate* isolate) {
  Heap* heap = isolate->heap();
  CHECK(!ObjectInYoungGeneration(*this));
  CHECK(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
  CHECK(instance_size() == kVariableSizeSentinel ||
        (kTaggedSize <= instance_size() &&
         static_cast<size_t>(instance_size()) < heap->Capacity()));
  CHECK(GetBackPointer()->IsUndefined(isolate) ||
        !Map::cast(GetBackPointer())->is_stable());
  HeapObject::VerifyHeapPointer(isolate, prototype());
  HeapObject::VerifyHeapPointer(isolate, instance_descriptors());
  SLOW_DCHECK(instance_descriptors()->IsSortedNoDuplicates());
  DisallowHeapAllocation no_gc;
  SLOW_DCHECK(
      TransitionsAccessor(isolate, *this, &no_gc).IsSortedNoDuplicates());
  SLOW_DCHECK(TransitionsAccessor(isolate, *this, &no_gc)
                  .IsConsistentWithBackPointers());
  SLOW_DCHECK(!FLAG_unbox_double_fields ||
              layout_descriptor()->IsConsistentWithMap(*this));
  if (!may_have_interesting_symbols()) {
    CHECK(!has_named_interceptor());
    CHECK(!is_dictionary_map());
    CHECK(!is_access_check_needed());
    DescriptorArray const descriptors = instance_descriptors();
    for (int i = 0; i < NumberOfOwnDescriptors(); ++i) {
      CHECK(!descriptors->GetKey(i)->IsInterestingSymbol());
    }
  }
  CHECK_IMPLIES(has_named_interceptor(), may_have_interesting_symbols());
  CHECK_IMPLIES(is_dictionary_map(), may_have_interesting_symbols());
  CHECK_IMPLIES(is_access_check_needed(), may_have_interesting_symbols());
  CHECK_IMPLIES(IsJSObjectMap() && !CanHaveFastTransitionableElementsKind(),
                IsDictionaryElementsKind(elements_kind()) ||
                    IsTerminalElementsKind(elements_kind()));
  CHECK_IMPLIES(is_deprecated(), !is_stable());
  if (is_prototype_map()) {
    DCHECK(prototype_info() == Smi::kZero ||
           prototype_info()->IsPrototypeInfo());
  }
  CHECK(prototype_validity_cell()->IsSmi() ||
        prototype_validity_cell()->IsCell());
}

void Map::DictionaryMapVerify(Isolate* isolate) {
  MapVerify(isolate);
  CHECK(is_dictionary_map());
  CHECK_EQ(kInvalidEnumCacheSentinel, EnumLength());
  CHECK_EQ(ReadOnlyRoots(isolate).empty_descriptor_array(),
           instance_descriptors());
  CHECK_EQ(0, UnusedPropertyFields());
  CHECK_EQ(Map::GetVisitorId(*this), visitor_id());
}

void AliasedArgumentsEntry::AliasedArgumentsEntryVerify(Isolate* isolate) {
  VerifySmiField(kAliasedContextSlotOffset);
}

void EmbedderDataArray::EmbedderDataArrayVerify(Isolate* isolate) {
  EmbedderDataSlot start(*this, 0);
  EmbedderDataSlot end(*this, length());
  for (EmbedderDataSlot slot = start; slot < end; ++slot) {
    Object e = slot.load_tagged();
    Object::VerifyPointer(isolate, e);
  }
  VerifySmiField(kLengthOffset);
}

void FixedArray::FixedArrayVerify(Isolate* isolate) {
  for (int i = 0; i < length(); i++) {
    Object e = get(i);
    VerifyPointer(isolate, e);
  }
}

void WeakFixedArray::WeakFixedArrayVerify(Isolate* isolate) {
  for (int i = 0; i < length(); i++) {
    MaybeObject::VerifyMaybeObjectPointer(isolate, Get(i));
  }
}

void WeakArrayList::WeakArrayListVerify(Isolate* isolate) {
  for (int i = 0; i < length(); i++) {
    MaybeObject::VerifyMaybeObjectPointer(isolate, Get(i));
  }
}

void PropertyArray::PropertyArrayVerify(Isolate* isolate) {
  if (length() == 0) {
    CHECK_EQ(*this, ReadOnlyRoots(isolate).empty_property_array());
    return;
  }
  // There are no empty PropertyArrays.
  CHECK_LT(0, length());
  for (int i = 0; i < length(); i++) {
    Object e = get(i);
    Object::VerifyPointer(isolate, e);
  }
  VerifySmiField(kLengthAndHashOffset);
}

void FixedDoubleArray::FixedDoubleArrayVerify(Isolate* isolate) {
  for (int i = 0; i < length(); i++) {
    if (!is_the_hole(i)) {
      uint64_t value = get_representation(i);
      uint64_t unexpected =
          bit_cast<uint64_t>(std::numeric_limits<double>::quiet_NaN()) &
          uint64_t{0x7FF8000000000000};
      // Create implementation specific sNaN by inverting relevant bit.
      unexpected ^= uint64_t{0x0008000000000000};
      CHECK((value & uint64_t{0x7FF8000000000000}) != unexpected ||
            (value & uint64_t{0x0007FFFFFFFFFFFF}) == uint64_t{0});
    }
  }
}

void Context::ContextVerify(Isolate* isolate) {
  VerifySmiField(kLengthOffset);
  VerifyObjectField(isolate, kScopeInfoOffset);
  VerifyObjectField(isolate, kPreviousOffset);
  VerifyObjectField(isolate, kExtensionOffset);
  VerifyObjectField(isolate, kNativeContextOffset);
  for (int i = 0; i < length(); i++) {
    VerifyObjectField(isolate, OffsetOfElementAt(i));
  }
}

void NativeContext::NativeContextVerify(Isolate* isolate) {
  ContextVerify(isolate);
  CHECK_EQ(length(), NativeContext::NATIVE_CONTEXT_SLOTS);
  CHECK_EQ(kSize, map()->instance_size());
}

void FeedbackMetadata::FeedbackMetadataVerify(Isolate* isolate) {
  if (slot_count() == 0 && closure_feedback_cell_count() == 0) {
    CHECK_EQ(ReadOnlyRoots(isolate).empty_feedback_metadata(), *this);
  } else {
    FeedbackMetadataIterator iter(*this);
    while (iter.HasNext()) {
      iter.Next();
      FeedbackSlotKind kind = iter.kind();
      CHECK_NE(FeedbackSlotKind::kInvalid, kind);
      CHECK_GT(FeedbackSlotKind::kKindsNumber, kind);
    }
  }
}

void DescriptorArray::DescriptorArrayVerify(Isolate* isolate) {
  for (int i = 0; i < number_of_all_descriptors(); i++) {
    MaybeObject::VerifyMaybeObjectPointer(isolate, get(ToKeyIndex(i)));
    MaybeObject::VerifyMaybeObjectPointer(isolate, get(ToDetailsIndex(i)));
    MaybeObject::VerifyMaybeObjectPointer(isolate, get(ToValueIndex(i)));
  }
  if (number_of_all_descriptors() == 0) {
    Heap* heap = isolate->heap();
    CHECK_EQ(ReadOnlyRoots(heap).empty_descriptor_array(), *this);
    CHECK_EQ(0, number_of_all_descriptors());
    CHECK_EQ(0, number_of_descriptors());
    CHECK_EQ(ReadOnlyRoots(heap).empty_enum_cache(), enum_cache());
  } else {
    CHECK_LT(0, number_of_all_descriptors());
    CHECK_LE(number_of_descriptors(), number_of_all_descriptors());

    // Check that properties with private symbols names are non-enumerable.
    for (int descriptor = 0; descriptor < number_of_descriptors();
         descriptor++) {
      Object key = get(ToKeyIndex(descriptor))->cast<Object>();
      // number_of_descriptors() may be out of sync with the actual descriptors
      // written during descriptor array construction.
      if (key->IsUndefined(isolate)) continue;
      PropertyDetails details = GetDetails(descriptor);
      if (Name::cast(key)->IsPrivate()) {
        CHECK_NE(details.attributes() & DONT_ENUM, 0);
      }
      MaybeObject value = get(ToValueIndex(descriptor));
      HeapObject heap_object;
      if (details.location() == kField) {
        CHECK(
            value == MaybeObject::FromObject(FieldType::None()) ||
            value == MaybeObject::FromObject(FieldType::Any()) ||
            value->IsCleared() ||
            (value->GetHeapObjectIfWeak(&heap_object) && heap_object->IsMap()));
      } else {
        CHECK(!value->IsWeakOrCleared());
        CHECK(!value->cast<Object>()->IsMap());
      }
    }
  }
}

void TransitionArray::TransitionArrayVerify(Isolate* isolate) {
  WeakFixedArrayVerify(isolate);
  CHECK_LE(LengthFor(number_of_transitions()), length());
}

void JSArgumentsObject::JSArgumentsObjectVerify(Isolate* isolate) {
  if (IsSloppyArgumentsElementsKind(GetElementsKind())) {
    SloppyArgumentsElements::cast(elements())
        ->SloppyArgumentsElementsVerify(isolate, *this);
  }
  if (isolate->IsInAnyContext(map(), Context::SLOPPY_ARGUMENTS_MAP_INDEX) ||
      isolate->IsInAnyContext(map(),
                              Context::SLOW_ALIASED_ARGUMENTS_MAP_INDEX) ||
      isolate->IsInAnyContext(map(),
                              Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX)) {
    VerifyObjectField(isolate, JSSloppyArgumentsObject::kLengthOffset);
    VerifyObjectField(isolate, JSSloppyArgumentsObject::kCalleeOffset);
  } else if (isolate->IsInAnyContext(map(),
                                     Context::STRICT_ARGUMENTS_MAP_INDEX)) {
    VerifyObjectField(isolate, JSStrictArgumentsObject::kLengthOffset);
  }
  JSObjectVerify(isolate);
}

void SloppyArgumentsElements::SloppyArgumentsElementsVerify(Isolate* isolate,
                                                            JSObject holder) {
  FixedArrayVerify(isolate);
  // Abort verification if only partially initialized (can't use arguments()
  // getter because it does FixedArray::cast()).
  if (get(kArgumentsIndex)->IsUndefined(isolate)) return;

  ElementsKind kind = holder->GetElementsKind();
  bool is_fast = kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS;
  CHECK(IsFixedArray());
  CHECK_GE(length(), 2);
  CHECK_EQ(map(), ReadOnlyRoots(isolate).sloppy_arguments_elements_map());
  Context context_object = context();
  FixedArray arg_elements = FixedArray::cast(arguments());
  if (arg_elements->length() == 0) {
    CHECK(arg_elements == ReadOnlyRoots(isolate).empty_fixed_array());
    return;
  }
  ElementsAccessor* accessor;
  if (is_fast) {
    accessor = ElementsAccessor::ForKind(HOLEY_ELEMENTS);
  } else {
    accessor = ElementsAccessor::ForKind(DICTIONARY_ELEMENTS);
  }
  int nofMappedParameters = 0;
  int maxMappedIndex = 0;
  for (int i = 0; i < nofMappedParameters; i++) {
    // Verify that each context-mapped argument is either the hole or a valid
    // Smi within context length range.
    Object mapped = get_mapped_entry(i);
    if (mapped->IsTheHole(isolate)) {
      // Slow sloppy arguments can be holey.
      if (!is_fast) continue;
      // Fast sloppy arguments elements are never holey. Either the element is
      // context-mapped or present in the arguments elements.
      CHECK(accessor->HasElement(holder, i, arg_elements));
      continue;
    }
    int mappedIndex = Smi::ToInt(mapped);
    nofMappedParameters++;
    CHECK_LE(maxMappedIndex, mappedIndex);
    maxMappedIndex = mappedIndex;
    Object value = context_object->get(mappedIndex);
    CHECK(value->IsObject());
    // None of the context-mapped entries should exist in the arguments
    // elements.
    CHECK(!accessor->HasElement(holder, i, arg_elements));
  }
  CHECK_LE(nofMappedParameters, context_object->length());
  CHECK_LE(nofMappedParameters, arg_elements->length());
  CHECK_LE(maxMappedIndex, context_object->length());
  CHECK_LE(maxMappedIndex, arg_elements->length());
}

void JSGeneratorObject::JSGeneratorObjectVerify(Isolate* isolate) {
  // In an expression like "new g()", there can be a point where a generator
  // object is allocated but its fields are all undefined, as it hasn't yet been
  // initialized by the generator.  Hence these weak checks.
  VerifyObjectField(isolate, kFunctionOffset);
  VerifyObjectField(isolate, kContextOffset);
  VerifyObjectField(isolate, kReceiverOffset);
  VerifyObjectField(isolate, kParametersAndRegistersOffset);
  VerifyObjectField(isolate, kContinuationOffset);
}

void JSAsyncFunctionObject::JSAsyncFunctionObjectVerify(Isolate* isolate) {
  // Check inherited fields
  JSGeneratorObjectVerify(isolate);
  VerifyObjectField(isolate, kPromiseOffset);
  promise()->HeapObjectVerify(isolate);
}

void JSAsyncGeneratorObject::JSAsyncGeneratorObjectVerify(Isolate* isolate) {
  // Check inherited fields
  JSGeneratorObjectVerify(isolate);
  VerifyObjectField(isolate, kQueueOffset);
  queue()->HeapObjectVerify(isolate);
}

void JSValue::JSValueVerify(Isolate* isolate) {
  Object v = value();
  if (v->IsHeapObject()) {
    VerifyHeapPointer(isolate, v);
  }
}

void JSDate::JSDateVerify(Isolate* isolate) {
  if (value()->IsHeapObject()) {
    VerifyHeapPointer(isolate, value());
  }
  CHECK(value()->IsUndefined(isolate) || value()->IsSmi() ||
        value()->IsHeapNumber());
  CHECK(year()->IsUndefined(isolate) || year()->IsSmi() || year()->IsNaN());
  CHECK(month()->IsUndefined(isolate) || month()->IsSmi() || month()->IsNaN());
  CHECK(day()->IsUndefined(isolate) || day()->IsSmi() || day()->IsNaN());
  CHECK(weekday()->IsUndefined(isolate) || weekday()->IsSmi() ||
        weekday()->IsNaN());
  CHECK(hour()->IsUndefined(isolate) || hour()->IsSmi() || hour()->IsNaN());
  CHECK(min()->IsUndefined(isolate) || min()->IsSmi() || min()->IsNaN());
  CHECK(sec()->IsUndefined(isolate) || sec()->IsSmi() || sec()->IsNaN());
  CHECK(cache_stamp()->IsUndefined(isolate) || cache_stamp()->IsSmi() ||
        cache_stamp()->IsNaN());

  if (month()->IsSmi()) {
    int month = Smi::ToInt(this->month());
    CHECK(0 <= month && month <= 11);
  }
  if (day()->IsSmi()) {
    int day = Smi::ToInt(this->day());
    CHECK(1 <= day && day <= 31);
  }
  if (hour()->IsSmi()) {
    int hour = Smi::ToInt(this->hour());
    CHECK(0 <= hour && hour <= 23);
  }
  if (min()->IsSmi()) {
    int min = Smi::ToInt(this->min());
    CHECK(0 <= min && min <= 59);
  }
  if (sec()->IsSmi()) {
    int sec = Smi::ToInt(this->sec());
    CHECK(0 <= sec && sec <= 59);
  }
  if (weekday()->IsSmi()) {
    int weekday = Smi::ToInt(this->weekday());
    CHECK(0 <= weekday && weekday <= 6);
  }
  if (cache_stamp()->IsSmi()) {
    CHECK(Smi::ToInt(cache_stamp()) <=
          Smi::ToInt(isolate->date_cache()->stamp()));
  }
}

void JSMessageObject::JSMessageObjectVerify(Isolate* isolate) {
  CHECK(IsJSMessageObject());
  VerifyObjectField(isolate, kStartPositionOffset);
  VerifyObjectField(isolate, kEndPositionOffset);
  VerifyObjectField(isolate, kArgumentsOffset);
  VerifyObjectField(isolate, kScriptOffset);
  VerifyObjectField(isolate, kStackFramesOffset);
  VerifySmiField(kMessageTypeOffset);
  VerifySmiField(kStartPositionOffset);
  VerifySmiField(kEndPositionOffset);
  VerifySmiField(kErrorLevelOffset);
}

void String::StringVerify(Isolate* isolate) {
  CHECK(IsString());
  CHECK(length() >= 0 && length() <= Smi::kMaxValue);
  CHECK_IMPLIES(length() == 0, *this == ReadOnlyRoots(isolate).empty_string());
  CHECK_EQ(*this == ReadOnlyRoots(isolate).empty_string(),
           map() == ReadOnlyRoots(isolate).empty_string_map());
  if (IsInternalizedString()) {
    CHECK(!ObjectInYoungGeneration(*this));
  }
  if (IsConsString()) {
    ConsString::cast(*this)->ConsStringVerify(isolate);
  } else if (IsSlicedString()) {
    SlicedString::cast(*this)->SlicedStringVerify(isolate);
  } else if (IsThinString()) {
    ThinString::cast(*this)->ThinStringVerify(isolate);
  }
}

void ConsString::ConsStringVerify(Isolate* isolate) {
  CHECK(this->first()->IsString());
  CHECK(this->second()->IsString());
  CHECK_GT(this->first()->length(), 0);
  CHECK_GE(this->length(), ConsString::kMinLength);
  CHECK(this->length() == this->first()->length() + this->second()->length());
  if (this->IsFlat()) {
    // A flat cons can only be created by String::SlowFlatten.
    // Afterwards, the first part may be externalized or internalized.
    CHECK(this->first()->IsSeqString() || this->first()->IsExternalString() ||
          this->first()->IsThinString());
  }
}

void ThinString::ThinStringVerify(Isolate* isolate) {
  CHECK(this->actual()->IsInternalizedString());
  CHECK(this->actual()->IsSeqString() || this->actual()->IsExternalString());
}

void SlicedString::SlicedStringVerify(Isolate* isolate) {
  CHECK(!this->parent()->IsConsString());
  CHECK(!this->parent()->IsSlicedString());
  CHECK_GE(this->length(), SlicedString::kMinLength);
}

void JSBoundFunction::JSBoundFunctionVerify(Isolate* isolate) {
  CHECK(IsJSBoundFunction());
  JSObjectVerify(isolate);
  VerifyObjectField(isolate, kBoundThisOffset);
  VerifyObjectField(isolate, kBoundTargetFunctionOffset);
  VerifyObjectField(isolate, kBoundArgumentsOffset);
  CHECK(IsCallable());

  if (!raw_bound_target_function()->IsUndefined(isolate)) {
    CHECK(bound_target_function()->IsCallable());
    CHECK_EQ(IsConstructor(), bound_target_function()->IsConstructor());
  }
}

void JSFunction::JSFunctionVerify(Isolate* isolate) {
  CHECK(IsJSFunction());
  JSObjectVerify(isolate);
  VerifyHeapPointer(isolate, raw_feedback_cell());
  CHECK(raw_feedback_cell()->IsFeedbackCell());
  CHECK(code()->IsCode());
  CHECK(map()->is_callable());
  Handle<JSFunction> function(*this, isolate);
  LookupIterator it(isolate, function, isolate->factory()->prototype_string(),
                    LookupIterator::OWN_SKIP_INTERCEPTOR);
  if (has_prototype_slot()) {
    VerifyObjectField(isolate, kPrototypeOrInitialMapOffset);
  }

  if (has_prototype_property()) {
    CHECK(it.IsFound());
    CHECK_EQ(LookupIterator::ACCESSOR, it.state());
    CHECK(it.GetAccessors()->IsAccessorInfo());
  } else {
    CHECK(!it.IsFound() || it.state() != LookupIterator::ACCESSOR ||
          !it.GetAccessors()->IsAccessorInfo());
  }
}

void SharedFunctionInfo::SharedFunctionInfoVerify(Isolate* isolate) {
  CHECK(IsSharedFunctionInfo());

  VerifyObjectField(isolate, kFunctionDataOffset);
  VerifyObjectField(isolate, kOuterScopeInfoOrFeedbackMetadataOffset);
  VerifyObjectField(isolate, kScriptOrDebugInfoOffset);
  VerifyObjectField(isolate, kNameOrScopeInfoOffset);

  Object value = name_or_scope_info();
  CHECK(value == kNoSharedNameSentinel || value->IsString() ||
        value->IsScopeInfo());
  if (value->IsScopeInfo()) {
    CHECK_LT(0, ScopeInfo::cast(value)->length());
    CHECK_NE(value, ReadOnlyRoots(isolate).empty_scope_info());
  }

  CHECK(HasWasmExportedFunctionData() || IsApiFunction() ||
        HasBytecodeArray() || HasAsmWasmData() || HasBuiltinId() ||
        HasUncompiledDataWithPreparseData() ||
        HasUncompiledDataWithoutPreparseData());

  CHECK(script_or_debug_info()->IsUndefined(isolate) ||
        script_or_debug_info()->IsScript() || HasDebugInfo());

  if (!is_compiled()) {
    CHECK(!HasFeedbackMetadata());
    CHECK(outer_scope_info()->IsScopeInfo() ||
          outer_scope_info()->IsTheHole(isolate));
  } else if (HasBytecodeArray() && HasFeedbackMetadata()) {
    CHECK(feedback_metadata()->IsFeedbackMetadata());
  }

  int expected_map_index = Context::FunctionMapIndex(
      language_mode(), kind(), HasSharedName(), needs_home_object());
  CHECK_EQ(expected_map_index, function_map_index());

  if (scope_info()->length() > 0) {
    ScopeInfo info = scope_info();
    CHECK(kind() == info->function_kind());
    CHECK_EQ(kind() == kModule, info->scope_type() == MODULE_SCOPE);
  }

  if (IsApiFunction()) {
    CHECK(construct_as_builtin());
  } else if (!HasBuiltinId()) {
    CHECK(!construct_as_builtin());
  } else {
    int id = builtin_id();
    if (id != Builtins::kCompileLazy && id != Builtins::kEmptyFunction) {
      CHECK(construct_as_builtin());
    } else {
      CHECK(!construct_as_builtin());
    }
  }

  // At this point we only support skipping arguments adaptor frames
  // for strict mode functions (see https://crbug.com/v8/8895).
  CHECK_IMPLIES(is_safe_to_skip_arguments_adaptor(),
                language_mode() == LanguageMode::kStrict);
}

void JSGlobalProxy::JSGlobalProxyVerify(Isolate* isolate) {
  CHECK(IsJSGlobalProxy());
  JSObjectVerify(isolate);
  VerifyObjectField(isolate, JSGlobalProxy::kNativeContextOffset);
  CHECK(map()->is_access_check_needed());
  // Make sure that this object has no properties, elements.
  CHECK_EQ(0, FixedArray::cast(elements())->length());
}

void JSGlobalObject::JSGlobalObjectVerify(Isolate* isolate) {
  CHECK(IsJSGlobalObject());
  // Do not check the dummy global object for the builtins.
  if (global_dictionary()->NumberOfElements() == 0 &&
      elements()->length() == 0) {
    return;
  }
  JSObjectVerify(isolate);
}

void Oddball::OddballVerify(Isolate* isolate) {
  CHECK(IsOddball());
  Heap* heap = isolate->heap();
  VerifyHeapPointer(isolate, to_string());
  Object number = to_number();
  if (number->IsHeapObject()) {
    CHECK(number == ReadOnlyRoots(heap).nan_value() ||
          number == ReadOnlyRoots(heap).hole_nan_value());
  } else {
    CHECK(number->IsSmi());
    int value = Smi::ToInt(number);
    // Hidden oddballs have negative smis.
    const int kLeastHiddenOddballNumber = -7;
    CHECK_LE(value, 1);
    CHECK_GE(value, kLeastHiddenOddballNumber);
  }

  ReadOnlyRoots roots(heap);
  if (map() == roots.undefined_map()) {
    CHECK(*this == roots.undefined_value());
  } else if (map() == roots.the_hole_map()) {
    CHECK(*this == roots.the_hole_value());
  } else if (map() == roots.null_map()) {
    CHECK(*this == roots.null_value());
  } else if (map() == roots.boolean_map()) {
    CHECK(*this == roots.true_value() || *this == roots.false_value());
  } else if (map() == roots.uninitialized_map()) {
    CHECK(*this == roots.uninitialized_value());
  } else if (map() == roots.arguments_marker_map()) {
    CHECK(*this == roots.arguments_marker());
  } else if (map() == roots.termination_exception_map()) {
    CHECK(*this == roots.termination_exception());
  } else if (map() == roots.exception_map()) {
    CHECK(*this == roots.exception());
  } else if (map() == roots.optimized_out_map()) {
    CHECK(*this == roots.optimized_out());
  } else if (map() == roots.stale_register_map()) {
    CHECK(*this == roots.stale_register());
  } else if (map() == roots.self_reference_marker_map()) {
    // Multiple instances of this oddball may exist at once.
    CHECK_EQ(kind(), Oddball::kSelfReferenceMarker);
  } else {
    UNREACHABLE();
  }
  CHECK(to_string()->IsString());
  CHECK(type_of()->IsString());
}

void Cell::CellVerify(Isolate* isolate) {
  CHECK(IsCell());
  VerifyObjectField(isolate, kValueOffset);
}

void PropertyCell::PropertyCellVerify(Isolate* isolate) {
  CHECK(IsPropertyCell());
  VerifyObjectField(isolate, kValueOffset);
}

void CodeDataContainer::CodeDataContainerVerify(Isolate* isolate) {
  CHECK(IsCodeDataContainer());
  VerifyObjectField(isolate, kNextCodeLinkOffset);
  CHECK(next_code_link()->IsCode() || next_code_link()->IsUndefined(isolate));
}

void Code::CodeVerify(Isolate* isolate) {
  CHECK_IMPLIES(
      has_safepoint_table(),
      IsAligned(safepoint_table_offset(), static_cast<unsigned>(kIntSize)));
  CHECK_LE(safepoint_table_offset(), handler_table_offset());
  CHECK_LE(handler_table_offset(), constant_pool_offset());
  CHECK_LE(constant_pool_offset(), code_comments_offset());
  CHECK_LE(code_comments_offset(), InstructionSize());
  CHECK(IsAligned(raw_instruction_start(), kCodeAlignment));
  relocation_info()->ObjectVerify(isolate);
  CHECK(Code::SizeFor(body_size()) <= kMaxRegularHeapObjectSize ||
        isolate->heap()->InSpace(*this, CODE_LO_SPACE));
  Address last_gc_pc = kNullAddress;

  for (RelocIterator it(*this); !it.done(); it.next()) {
    it.rinfo()->Verify(isolate);
    // Ensure that GC will not iterate twice over the same pointer.
    if (RelocInfo::IsGCRelocMode(it.rinfo()->rmode())) {
      CHECK(it.rinfo()->pc() != last_gc_pc);
      last_gc_pc = it.rinfo()->pc();
    }
  }
}

void JSArray::JSArrayVerify(Isolate* isolate) {
  JSObjectVerify(isolate);
  CHECK(length()->IsNumber() || length()->IsUndefined(isolate));
  // If a GC was caused while constructing this array, the elements
  // pointer may point to a one pointer filler map.
  if (!ElementsAreSafeToExamine()) return;
  if (elements()->IsUndefined(isolate)) return;
  CHECK(elements()->IsFixedArray() || elements()->IsFixedDoubleArray());
  if (elements()->length() == 0) {
    CHECK_EQ(elements(), ReadOnlyRoots(isolate).empty_fixed_array());
  }
  if (!length()->IsNumber()) return;
  // Verify that the length and the elements backing store are in sync.
  if (length()->IsSmi() && HasFastElements()) {
    if (elements()->length() > 0) {
      CHECK_IMPLIES(HasDoubleElements(), elements()->IsFixedDoubleArray());
      CHECK_IMPLIES(HasSmiOrObjectElements(), elements()->IsFixedArray());
    }
    int size = Smi::ToInt(length());
    // Holey / Packed backing stores might have slack or might have not been
    // properly initialized yet.
    CHECK(size <= elements()->length() ||
          elements() == ReadOnlyRoots(isolate).empty_fixed_array());
  } else {
    CHECK(HasDictionaryElements());
    uint32_t array_length;
    CHECK(length()->ToArrayLength(&array_length));
    if (array_length == 0xFFFFFFFF) {
      CHECK(length()->ToArrayLength(&array_length));
    }
    if (array_length != 0) {
      NumberDictionary dict = NumberDictionary::cast(elements());
      // The dictionary can never have more elements than the array length + 1.
      // If the backing store grows the verification might be triggered with
      // the old length in place.
      uint32_t nof_elements = static_cast<uint32_t>(dict->NumberOfElements());
      if (nof_elements != 0) nof_elements--;
      CHECK_LE(nof_elements, array_length);
    }
  }
}

void JSSet::JSSetVerify(Isolate* isolate) {
  CHECK(IsJSSet());
  JSObjectVerify(isolate);
  VerifyHeapPointer(isolate, table());
  CHECK(table()->IsOrderedHashSet() || table()->IsUndefined(isolate));
  // TODO(arv): Verify OrderedHashTable too.
}

void JSMap::JSMapVerify(Isolate* isolate) {
  CHECK(IsJSMap());
  JSObjectVerify(isolate);
  VerifyHeapPointer(isolate, table());
  CHECK(table()->IsOrderedHashMap() || table()->IsUndefined(isolate));
  // TODO(arv): Verify OrderedHashTable too.
}

void JSSetIterator::JSSetIteratorVerify(Isolate* isolate) {
  CHECK(IsJSSetIterator());
  JSObjectVerify(isolate);
  VerifyHeapPointer(isolate, table());
  CHECK(table()->IsOrderedHashSet());
  CHECK(index()->IsSmi());
}

void JSMapIterator::JSMapIteratorVerify(Isolate* isolate) {
  CHECK(IsJSMapIterator());
  JSObjectVerify(isolate);
  VerifyHeapPointer(isolate, table());
  CHECK(table()->IsOrderedHashMap());
  CHECK(index()->IsSmi());
}

void WeakCell::WeakCellVerify(Isolate* isolate) {
  CHECK(IsWeakCell());

  CHECK(target()->IsJSReceiver() || target()->IsUndefined(isolate));

  CHECK(prev()->IsWeakCell() || prev()->IsUndefined(isolate));
  if (prev()->IsWeakCell()) {
    CHECK_EQ(WeakCell::cast(prev())->next(), *this);
  }

  CHECK(next()->IsWeakCell() || next()->IsUndefined(isolate));
  if (next()->IsWeakCell()) {
    CHECK_EQ(WeakCell::cast(next())->prev(), *this);
  }

  CHECK_IMPLIES(key()->IsUndefined(isolate),
                key_list_prev()->IsUndefined(isolate));
  CHECK_IMPLIES(key()->IsUndefined(isolate),
                key_list_next()->IsUndefined(isolate));

  CHECK(key_list_prev()->IsWeakCell() || key_list_prev()->IsUndefined(isolate));
  if (key_list_prev()->IsWeakCell()) {
    CHECK_EQ(WeakCell::cast(key_list_prev())->key_list_next(), *this);
  }

  CHECK(key_list_next()->IsWeakCell() || key_list_next()->IsUndefined(isolate));
  if (key_list_next()->IsWeakCell()) {
    CHECK_EQ(WeakCell::cast(key_list_next())->key_list_prev(), *this);
  }

  CHECK(finalization_group()->IsUndefined(isolate) ||
        finalization_group()->IsJSFinalizationGroup());
}

void JSWeakRef::JSWeakRefVerify(Isolate* isolate) {
  CHECK(IsJSWeakRef());
  JSObjectVerify(isolate);
  CHECK(target()->IsUndefined(isolate) || target()->IsJSReceiver());
}

void JSFinalizationGroup::JSFinalizationGroupVerify(Isolate* isolate) {
  CHECK(IsJSFinalizationGroup());
  JSObjectVerify(isolate);
  VerifyHeapPointer(isolate, cleanup());
  CHECK(active_cells()->IsUndefined(isolate) || active_cells()->IsWeakCell());
  if (active_cells()->IsWeakCell()) {
    CHECK(WeakCell::cast(active_cells())->prev()->IsUndefined(isolate));
  }
  CHECK(cleared_cells()->IsUndefined(isolate) || cleared_cells()->IsWeakCell());
  if (cleared_cells()->IsWeakCell()) {
    CHECK(WeakCell::cast(cleared_cells())->prev()->IsUndefined(isolate));
  }
}

void JSFinalizationGroupCleanupIterator::
    JSFinalizationGroupCleanupIteratorVerify(Isolate* isolate) {
  CHECK(IsJSFinalizationGroupCleanupIterator());
  JSObjectVerify(isolate);
  VerifyHeapPointer(isolate, finalization_group());
}

void FinalizationGroupCleanupJobTask::FinalizationGroupCleanupJobTaskVerify(
    Isolate* isolate) {
  CHECK(IsFinalizationGroupCleanupJobTask());
  CHECK(finalization_group()->IsJSFinalizationGroup());
}

void JSWeakMap::JSWeakMapVerify(Isolate* isolate) {
  CHECK(IsJSWeakMap());
  JSObjectVerify(isolate);
  VerifyHeapPointer(isolate, table());
  CHECK(table()->IsEphemeronHashTable() || table()->IsUndefined(isolate));
}

void JSArrayIterator::JSArrayIteratorVerify(Isolate* isolate) {
  CHECK(IsJSArrayIterator());
  JSObjectVerify(isolate);
  CHECK(iterated_object()->IsJSReceiver());

  CHECK_GE(next_index()->Number(), 0);
  CHECK_LE(next_index()->Number(), kMaxSafeInteger);

  if (iterated_object()->IsJSTypedArray()) {
    // JSTypedArray::length is limited to Smi range.
    CHECK(next_index()->IsSmi());
    CHECK_LE(next_index()->Number(), Smi::kMaxValue);
  } else if (iterated_object()->IsJSArray()) {
    // JSArray::length is limited to Uint32 range.
    CHECK_LE(next_index()->Number(), kMaxUInt32);
  }
}

void JSStringIterator::JSStringIteratorVerify(Isolate* isolate) {
  CHECK(IsJSStringIterator());
  JSObjectVerify(isolate);
  CHECK(string()->IsString());

  CHECK_GE(index(), 0);
  CHECK_LE(index(), String::kMaxLength);
}

void JSAsyncFromSyncIterator::JSAsyncFromSyncIteratorVerify(Isolate* isolate) {
  CHECK(IsJSAsyncFromSyncIterator());
  JSObjectVerify(isolate);
  VerifyHeapPointer(isolate, sync_iterator());
}

void JSWeakSet::JSWeakSetVerify(Isolate* isolate) {
  CHECK(IsJSWeakSet());
  JSObjectVerify(isolate);
  VerifyHeapPointer(isolate, table());
  CHECK(table()->IsEphemeronHashTable() || table()->IsUndefined(isolate));
}

void Microtask::MicrotaskVerify(Isolate* isolate) { CHECK(IsMicrotask()); }

void CallableTask::CallableTaskVerify(Isolate* isolate) {
  CHECK(IsCallableTask());
  MicrotaskVerify(isolate);
  VerifyHeapPointer(isolate, callable());
  CHECK(callable()->IsCallable());
  VerifyHeapPointer(isolate, context());
  CHECK(context()->IsContext());
}

void CallbackTask::CallbackTaskVerify(Isolate* isolate) {
  CHECK(IsCallbackTask());
  MicrotaskVerify(isolate);
  VerifyHeapPointer(isolate, callback());
  VerifyHeapPointer(isolate, data());
}

void PromiseReactionJobTask::PromiseReactionJobTaskVerify(Isolate* isolate) {
  CHECK(IsPromiseReactionJobTask());
  MicrotaskVerify(isolate);
  VerifyPointer(isolate, argument());
  VerifyHeapPointer(isolate, context());
  CHECK(context()->IsContext());
  VerifyHeapPointer(isolate, handler());
  CHECK(handler()->IsUndefined(isolate) || handler()->IsCallable());
  VerifyHeapPointer(isolate, promise_or_capability());
  CHECK(promise_or_capability()->IsJSPromise() ||
        promise_or_capability()->IsPromiseCapability() ||
        promise_or_capability()->IsUndefined(isolate));
}

void PromiseFulfillReactionJobTask::PromiseFulfillReactionJobTaskVerify(
    Isolate* isolate) {
  CHECK(IsPromiseFulfillReactionJobTask());
  PromiseReactionJobTaskVerify(isolate);
}

void PromiseRejectReactionJobTask::PromiseRejectReactionJobTaskVerify(
    Isolate* isolate) {
  CHECK(IsPromiseRejectReactionJobTask());
  PromiseReactionJobTaskVerify(isolate);
}

void PromiseResolveThenableJobTask::PromiseResolveThenableJobTaskVerify(
    Isolate* isolate) {
  CHECK(IsPromiseResolveThenableJobTask());
  MicrotaskVerify(isolate);
  VerifyHeapPointer(isolate, context());
  CHECK(context()->IsContext());
  VerifyHeapPointer(isolate, promise_to_resolve());
  CHECK(promise_to_resolve()->IsJSPromise());
  VerifyHeapPointer(isolate, then());
  CHECK(then()->IsCallable());
  CHECK(then()->IsJSReceiver());
  VerifyHeapPointer(isolate, thenable());
  CHECK(thenable()->IsJSReceiver());
}

void PromiseCapability::PromiseCapabilityVerify(Isolate* isolate) {
  CHECK(IsPromiseCapability());

  VerifyHeapPointer(isolate, promise());
  CHECK(promise()->IsJSReceiver() || promise()->IsUndefined(isolate));
  VerifyPointer(isolate, resolve());
  VerifyPointer(isolate, reject());
}

void PromiseReaction::PromiseReactionVerify(Isolate* isolate) {
  CHECK(IsPromiseReaction());

  VerifyPointer(isolate, next());
  CHECK(next()->IsSmi() || next()->IsPromiseReaction());
  VerifyHeapPointer(isolate, reject_handler());
  CHECK(reject_handler()->IsUndefined(isolate) ||
        reject_handler()->IsCallable());
  VerifyHeapPointer(isolate, fulfill_handler());
  CHECK(fulfill_handler()->IsUndefined(isolate) ||
        fulfill_handler()->IsCallable());
  VerifyHeapPointer(isolate, promise_or_capability());
  CHECK(promise_or_capability()->IsJSPromise() ||
        promise_or_capability()->IsPromiseCapability() ||
        promise_or_capability()->IsUndefined(isolate));
}

void JSPromise::JSPromiseVerify(Isolate* isolate) {
  CHECK(IsJSPromise());
  JSObjectVerify(isolate);
  VerifyPointer(isolate, reactions_or_result());
  VerifySmiField(kFlagsOffset);
  if (status() == Promise::kPending) {
    CHECK(reactions()->IsSmi() || reactions()->IsPromiseReaction());
  }
}

template <typename Derived>
void SmallOrderedHashTable<Derived>::SmallOrderedHashTableVerify(
    Isolate* isolate) {
  CHECK(IsSmallOrderedHashTable());

  int capacity = Capacity();
  CHECK_GE(capacity, kMinCapacity);
  CHECK_LE(capacity, kMaxCapacity);

  for (int entry = 0; entry < NumberOfBuckets(); entry++) {
    int bucket = GetFirstEntry(entry);
    if (bucket == kNotFound) continue;
    CHECK_GE(bucket, 0);
    CHECK_LE(bucket, capacity);
  }

  for (int entry = 0; entry < NumberOfElements(); entry++) {
    int chain = GetNextEntry(entry);
    if (chain == kNotFound) continue;
    CHECK_GE(chain, 0);
    CHECK_LE(chain, capacity);
  }

  for (int entry = 0; entry < NumberOfElements(); entry++) {
    for (int offset = 0; offset < Derived::kEntrySize; offset++) {
      Object val = GetDataEntry(entry, offset);
      VerifyPointer(isolate, val);
    }
  }

  for (int entry = NumberOfElements() + NumberOfDeletedElements();
       entry < Capacity(); entry++) {
    for (int offset = 0; offset < Derived::kEntrySize; offset++) {
      Object val = GetDataEntry(entry, offset);
      CHECK(val->IsTheHole(isolate));
    }
  }
}
void SmallOrderedHashMap::SmallOrderedHashMapVerify(Isolate* isolate) {
  SmallOrderedHashTable<SmallOrderedHashMap>::SmallOrderedHashTableVerify(
      isolate);
  for (int entry = NumberOfElements(); entry < NumberOfDeletedElements();
       entry++) {
    for (int offset = 0; offset < kEntrySize; offset++) {
      Object val = GetDataEntry(entry, offset);
      CHECK(val->IsTheHole(isolate));
    }
  }
}

void SmallOrderedHashSet::SmallOrderedHashSetVerify(Isolate* isolate) {
  SmallOrderedHashTable<SmallOrderedHashSet>::SmallOrderedHashTableVerify(
      isolate);
  for (int entry = NumberOfElements(); entry < NumberOfDeletedElements();
       entry++) {
    for (int offset = 0; offset < kEntrySize; offset++) {
      Object val = GetDataEntry(entry, offset);
      CHECK(val->IsTheHole(isolate));
    }
  }
}

void SmallOrderedNameDictionary::SmallOrderedNameDictionaryVerify(
    Isolate* isolate) {
  SmallOrderedHashTable<
      SmallOrderedNameDictionary>::SmallOrderedHashTableVerify(isolate);
  for (int entry = NumberOfElements(); entry < NumberOfDeletedElements();
       entry++) {
    for (int offset = 0; offset < kEntrySize; offset++) {
      Object val = GetDataEntry(entry, offset);
      CHECK(val->IsTheHole(isolate) ||
            (PropertyDetails::Empty().AsSmi() == Smi::cast(val)));
    }
  }
}

void JSRegExp::JSRegExpVerify(Isolate* isolate) {
  JSObjectVerify(isolate);
  CHECK(data()->IsUndefined(isolate) || data()->IsFixedArray());
  CHECK(source()->IsUndefined(isolate) || source()->IsString());
  CHECK(flags()->IsUndefined() || flags()->IsSmi());
  switch (TypeTag()) {
    case JSRegExp::ATOM: {
      FixedArray arr = FixedArray::cast(data());
      CHECK(arr->get(JSRegExp::kAtomPatternIndex)->IsString());
      break;
    }
    case JSRegExp::IRREGEXP: {
      bool is_native = RegExpImpl::UsesNativeRegExp();

      FixedArray arr = FixedArray::cast(data());
      Object one_byte_data = arr->get(JSRegExp::kIrregexpLatin1CodeIndex);
      // Smi : Not compiled yet (-1).
      // Code/ByteArray: Compiled code.
      CHECK(
          (one_byte_data->IsSmi() &&
           Smi::ToInt(one_byte_data) == JSRegExp::kUninitializedValue) ||
          (is_native ? one_byte_data->IsCode() : one_byte_data->IsByteArray()));
      Object uc16_data = arr->get(JSRegExp::kIrregexpUC16CodeIndex);
      CHECK((uc16_data->IsSmi() &&
             Smi::ToInt(uc16_data) == JSRegExp::kUninitializedValue) ||
            (is_native ? uc16_data->IsCode() : uc16_data->IsByteArray()));

      CHECK(arr->get(JSRegExp::kIrregexpCaptureCountIndex)->IsSmi());
      CHECK(arr->get(JSRegExp::kIrregexpMaxRegisterCountIndex)->IsSmi());
      break;
    }
    default:
      CHECK_EQ(JSRegExp::NOT_COMPILED, TypeTag());
      CHECK(data()->IsUndefined(isolate));
      break;
  }
}

void JSRegExpStringIterator::JSRegExpStringIteratorVerify(Isolate* isolate) {
  CHECK(IsJSRegExpStringIterator());
  JSObjectVerify(isolate);
  CHECK(iterating_string()->IsString());
  CHECK(iterating_regexp()->IsObject());
  VerifySmiField(kFlagsOffset);
}

void JSProxy::JSProxyVerify(Isolate* isolate) {
  CHECK(IsJSProxy());
  CHECK(map()->GetConstructor()->IsJSFunction());
  VerifyPointer(isolate, target());
  VerifyPointer(isolate, handler());
  if (!IsRevoked()) {
    CHECK_EQ(target()->IsCallable(), map()->is_callable());
    CHECK_EQ(target()->IsConstructor(), map()->is_constructor());
  }
  CHECK(map()->prototype()->IsNull(isolate));
  // There should be no properties on a Proxy.
  CHECK_EQ(0, map()->NumberOfOwnDescriptors());
}

void JSArrayBuffer::JSArrayBufferVerify(Isolate* isolate) {
  CHECK(IsJSArrayBuffer());
  if (FIELD_SIZE(kOptionalPaddingOffset) != 0) {
    CHECK_EQ(4, FIELD_SIZE(kOptionalPaddingOffset));
    CHECK_EQ(0,
             *reinterpret_cast<uint32_t*>(address() + kOptionalPaddingOffset));
  }
  JSObjectVerify(isolate);
}

void JSArrayBufferView::JSArrayBufferViewVerify(Isolate* isolate) {
  CHECK(IsJSArrayBufferView());
  JSObjectVerify(isolate);
  VerifyPointer(isolate, buffer());
  CHECK(buffer()->IsJSArrayBuffer() || buffer()->IsUndefined(isolate) ||
        buffer() == Smi::kZero);
  CHECK_LE(byte_length(), JSArrayBuffer::kMaxByteLength);
  CHECK_LE(byte_offset(), JSArrayBuffer::kMaxByteLength);
}

void JSTypedArray::JSTypedArrayVerify(Isolate* isolate) {
  CHECK(IsJSTypedArray());
  JSArrayBufferViewVerify(isolate);
  VerifyPointer(isolate, raw_length());
  CHECK(raw_length()->IsSmi() || raw_length()->IsUndefined(isolate));
  VerifyPointer(isolate, elements());
}

void JSDataView::JSDataViewVerify(Isolate* isolate) {
  CHECK(IsJSDataView());
  JSArrayBufferViewVerify(isolate);
}

void Foreign::ForeignVerify(Isolate* isolate) { CHECK(IsForeign()); }

void AsyncGeneratorRequest::AsyncGeneratorRequestVerify(Isolate* isolate) {
  CHECK(IsAsyncGeneratorRequest());
  VerifySmiField(kResumeModeOffset);
  CHECK_GE(resume_mode(), JSGeneratorObject::kNext);
  CHECK_LE(resume_mode(), JSGeneratorObject::kThrow);
  CHECK(promise()->IsJSPromise());
  VerifyPointer(isolate, value());
  VerifyPointer(isolate, next());
  next()->ObjectVerify(isolate);
}

void BigInt::BigIntVerify(Isolate* isolate) {
  CHECK(IsBigInt());
  CHECK_GE(length(), 0);
  CHECK_IMPLIES(is_zero(), !sign());  // There is no -0n.
}

void JSModuleNamespace::JSModuleNamespaceVerify(Isolate* isolate) {
  CHECK(IsJSModuleNamespace());
  VerifyPointer(isolate, module());
}

void ModuleInfoEntry::ModuleInfoEntryVerify(Isolate* isolate) {
  CHECK(IsModuleInfoEntry());

  CHECK(export_name()->IsUndefined(isolate) || export_name()->IsString());
  CHECK(local_name()->IsUndefined(isolate) || local_name()->IsString());
  CHECK(import_name()->IsUndefined(isolate) || import_name()->IsString());

  VerifySmiField(kModuleRequestOffset);
  VerifySmiField(kCellIndexOffset);
  VerifySmiField(kBegPosOffset);
  VerifySmiField(kEndPosOffset);

  CHECK_IMPLIES(import_name()->IsString(), module_request() >= 0);
  CHECK_IMPLIES(export_name()->IsString() && import_name()->IsString(),
                local_name()->IsUndefined(isolate));
}

void Module::ModuleVerify(Isolate* isolate) {
  CHECK(IsModule());

  VerifyPointer(isolate, code());
  VerifyPointer(isolate, exports());
  VerifyPointer(isolate, module_namespace());
  VerifyPointer(isolate, requested_modules());
  VerifyPointer(isolate, script());
  VerifyPointer(isolate, import_meta());
  VerifyPointer(isolate, exception());
  VerifySmiField(kHashOffset);
  VerifySmiField(kStatusOffset);

  CHECK((status() >= kEvaluating && code()->IsModuleInfo()) ||
        (status() == kInstantiated && code()->IsJSGeneratorObject()) ||
        (status() == kInstantiating && code()->IsJSFunction()) ||
        (code()->IsSharedFunctionInfo()));

  CHECK_EQ(status() == kErrored, !exception()->IsTheHole(isolate));

  CHECK(module_namespace()->IsUndefined(isolate) ||
        module_namespace()->IsJSModuleNamespace());
  if (module_namespace()->IsJSModuleNamespace()) {
    CHECK_LE(kInstantiating, status());
    CHECK_EQ(JSModuleNamespace::cast(module_namespace())->module(), *this);
  }

  CHECK_EQ(requested_modules()->length(), info()->module_requests()->length());

  CHECK(import_meta()->IsTheHole(isolate) || import_meta()->IsJSObject());

  CHECK_NE(hash(), 0);
}

void PrototypeInfo::PrototypeInfoVerify(Isolate* isolate) {
  CHECK(IsPrototypeInfo());
  Object module_ns = module_namespace();
  CHECK(module_ns->IsJSModuleNamespace() || module_ns->IsUndefined(isolate));
  if (prototype_users()->IsWeakArrayList()) {
    PrototypeUsers::Verify(WeakArrayList::cast(prototype_users()));
  } else {
    CHECK(prototype_users()->IsSmi());
  }
}

void PrototypeUsers::Verify(WeakArrayList array) {
  if (array->length() == 0) {
    // Allow empty & uninitialized lists.
    return;
  }
  // Verify empty slot chain.
  int empty_slot = Smi::ToInt(empty_slot_index(array));
  int empty_slots_count = 0;
  while (empty_slot != kNoEmptySlotsMarker) {
    CHECK_GT(empty_slot, 0);
    CHECK_LT(empty_slot, array->length());
    empty_slot = array->Get(empty_slot).ToSmi().value();
    ++empty_slots_count;
  }

  // Verify that all elements are either weak pointers or SMIs marking empty
  // slots.
  int weak_maps_count = 0;
  for (int i = kFirstIndex; i < array->length(); ++i) {
    HeapObject heap_object;
    MaybeObject object = array->Get(i);
    if ((object->GetHeapObjectIfWeak(&heap_object) && heap_object->IsMap()) ||
        object->IsCleared()) {
      ++weak_maps_count;
    } else {
      CHECK(object->IsSmi());
    }
  }

  CHECK_EQ(weak_maps_count + empty_slots_count + 1, array->length());
}

void Tuple2::Tuple2Verify(Isolate* isolate) {
  CHECK(IsTuple2());
  Heap* heap = isolate->heap();
  if (*this == ReadOnlyRoots(heap).empty_enum_cache()) {
    CHECK_EQ(ReadOnlyRoots(heap).empty_fixed_array(),
             EnumCache::cast(*this)->keys());
    CHECK_EQ(ReadOnlyRoots(heap).empty_fixed_array(),
             EnumCache::cast(*this)->indices());
  } else {
    VerifyObjectField(isolate, kValue1Offset);
    VerifyObjectField(isolate, kValue2Offset);
  }
}

void Tuple3::Tuple3Verify(Isolate* isolate) {
  CHECK(IsTuple3());
  VerifyObjectField(isolate, kValue1Offset);
  VerifyObjectField(isolate, kValue2Offset);
  VerifyObjectField(isolate, kValue3Offset);
}

void ClassPositions::ClassPositionsVerify(Isolate* isolate) {
  CHECK(IsClassPositions());
  VerifySmiField(kStartOffset);
  VerifySmiField(kEndOffset);
}

void ObjectBoilerplateDescription::ObjectBoilerplateDescriptionVerify(
    Isolate* isolate) {
  CHECK(IsObjectBoilerplateDescription());
  CHECK_GE(this->length(),
           ObjectBoilerplateDescription::kDescriptionStartIndex);
  this->FixedArrayVerify(isolate);
}

void ArrayBoilerplateDescription::ArrayBoilerplateDescriptionVerify(
    Isolate* isolate) {
  CHECK(IsArrayBoilerplateDescription());
  CHECK(constant_elements()->IsFixedArrayBase());
  VerifyObjectField(isolate, kConstantElementsOffset);
}

void AsmWasmData::AsmWasmDataVerify(Isolate* isolate) {
  CHECK(IsAsmWasmData());
  VerifyObjectField(isolate, kManagedNativeModuleOffset);
  VerifyObjectField(isolate, kExportWrappersOffset);
  VerifyObjectField(isolate, kAsmJsOffsetTableOffset);
  CHECK(uses_bitset()->IsHeapNumber());
  VerifyObjectField(isolate, kUsesBitsetOffset);
}

void WasmDebugInfo::WasmDebugInfoVerify(Isolate* isolate) {
  CHECK(IsWasmDebugInfo());
  VerifyObjectField(isolate, kInstanceOffset);
  CHECK(wasm_instance()->IsWasmInstanceObject());
  VerifyObjectField(isolate, kInterpreterHandleOffset);
  CHECK(interpreter_handle()->IsUndefined(isolate) ||
        interpreter_handle()->IsForeign());
  VerifyObjectField(isolate, kInterpretedFunctionsOffset);
  VerifyObjectField(isolate, kLocalsNamesOffset);
  VerifyObjectField(isolate, kCWasmEntriesOffset);
  VerifyObjectField(isolate, kCWasmEntryMapOffset);
}

void WasmExceptionTag::WasmExceptionTagVerify(Isolate* isolate) {
  CHECK(IsWasmExceptionTag());
  VerifySmiField(kIndexOffset);
}

void WasmInstanceObject::WasmInstanceObjectVerify(Isolate* isolate) {
  JSObjectVerify(isolate);
  CHECK(IsWasmInstanceObject());

  // Just generically check all tagged fields. Don't check the untagged fields,
  // as some of them might still contain the "undefined" value if the
  // WasmInstanceObject is not fully set up yet.
  for (int offset = kHeaderSize; offset < kEndOfTaggedFieldsOffset;
       offset += kTaggedSize) {
    VerifyObjectField(isolate, offset);
  }
}

void WasmExportedFunctionData::WasmExportedFunctionDataVerify(
    Isolate* isolate) {
  CHECK(IsWasmExportedFunctionData());
  VerifyObjectField(isolate, kWrapperCodeOffset);
  CHECK(wrapper_code()->kind() == Code::JS_TO_WASM_FUNCTION ||
        wrapper_code()->kind() == Code::C_WASM_ENTRY);
  VerifyObjectField(isolate, kInstanceOffset);
  VerifySmiField(kJumpTableOffsetOffset);
  VerifySmiField(kFunctionIndexOffset);
}

void WasmModuleObject::WasmModuleObjectVerify(Isolate* isolate) {
  CHECK(IsWasmModuleObject());
  VerifyObjectField(isolate, kNativeModuleOffset);
  CHECK(managed_native_module()->IsForeign());
  VerifyObjectField(isolate, kExportWrappersOffset);
  CHECK(export_wrappers()->IsFixedArray());
  VerifyObjectField(isolate, kScriptOffset);
  VerifyObjectField(isolate, kAsmJsOffsetTableOffset);
  VerifyObjectField(isolate, kBreakPointInfosOffset);
}

void DataHandler::DataHandlerVerify(Isolate* isolate) {
  CHECK(IsDataHandler());
  CHECK_IMPLIES(!smi_handler()->IsSmi(),
                smi_handler()->IsCode() && IsStoreHandler());
  CHECK(validity_cell()->IsSmi() || validity_cell()->IsCell());
  int data_count = data_field_count();
  if (data_count >= 1) {
    VerifyMaybeObjectField(isolate, kData1Offset);
  }
  if (data_count >= 2) {
    VerifyMaybeObjectField(isolate, kData2Offset);
  }
  if (data_count >= 3) {
    VerifyMaybeObjectField(isolate, kData3Offset);
  }
}

void LoadHandler::LoadHandlerVerify(Isolate* isolate) {
  DataHandler::DataHandlerVerify(isolate);
  // TODO(ishell): check handler integrity
}

void StoreHandler::StoreHandlerVerify(Isolate* isolate) {
  DataHandler::DataHandlerVerify(isolate);
  // TODO(ishell): check handler integrity
}

void AccessorInfo::AccessorInfoVerify(Isolate* isolate) {
  CHECK(IsAccessorInfo());
  VerifyPointer(isolate, name());
  VerifyPointer(isolate, expected_receiver_type());
  VerifyForeignPointer(isolate, *this, getter());
  VerifyForeignPointer(isolate, *this, setter());
  VerifyForeignPointer(isolate, *this, js_getter());
  VerifyPointer(isolate, data());
}

void AccessorPair::AccessorPairVerify(Isolate* isolate) {
  CHECK(IsAccessorPair());
  VerifyPointer(isolate, getter());
  VerifyPointer(isolate, setter());
}

void AccessCheckInfo::AccessCheckInfoVerify(Isolate* isolate) {
  CHECK(IsAccessCheckInfo());
  VerifyPointer(isolate, callback());
  VerifyPointer(isolate, named_interceptor());
  VerifyPointer(isolate, indexed_interceptor());
  VerifyPointer(isolate, data());
}

void CallHandlerInfo::CallHandlerInfoVerify(Isolate* isolate) {
  CHECK(IsCallHandlerInfo());
  CHECK(map() == ReadOnlyRoots(isolate).side_effect_call_handler_info_map() ||
        map() ==
            ReadOnlyRoots(isolate).side_effect_free_call_handler_info_map() ||
        map() == ReadOnlyRoots(isolate)
                     .next_call_side_effect_free_call_handler_info_map());
  VerifyPointer(isolate, callback());
  VerifyPointer(isolate, js_callback());
  VerifyPointer(isolate, data());
}

void InterceptorInfo::InterceptorInfoVerify(Isolate* isolate) {
  CHECK(IsInterceptorInfo());
  VerifyForeignPointer(isolate, *this, getter());
  VerifyForeignPointer(isolate, *this, setter());
  VerifyForeignPointer(isolate, *this, query());
  VerifyForeignPointer(isolate, *this, deleter());
  VerifyForeignPointer(isolate, *this, enumerator());
  VerifyPointer(isolate, data());
  VerifySmiField(kFlagsOffset);
}

void TemplateInfo::TemplateInfoVerify(Isolate* isolate) {
  VerifyPointer(isolate, tag());
  VerifyPointer(isolate, property_list());
  VerifyPointer(isolate, property_accessors());
}

void FunctionTemplateInfo::FunctionTemplateInfoVerify(Isolate* isolate) {
  CHECK(IsFunctionTemplateInfo());
  TemplateInfoVerify(isolate);
  VerifyPointer(isolate, serial_number());
  VerifyPointer(isolate, call_code());
  VerifyPointer(isolate, signature());
  VerifyPointer(isolate, cached_property_name());
  VerifyPointer(isolate, rare_data());
}

void FunctionTemplateRareData::FunctionTemplateRareDataVerify(
    Isolate* isolate) {
  CHECK(IsFunctionTemplateRareData());
  VerifyPointer(isolate, prototype_template());
  VerifyPointer(isolate, parent_template());
  VerifyPointer(isolate, named_property_handler());
  VerifyPointer(isolate, indexed_property_handler());
  VerifyPointer(isolate, instance_template());
  VerifyPointer(isolate, access_check_info());
}

void ObjectTemplateInfo::ObjectTemplateInfoVerify(Isolate* isolate) {
  CHECK(IsObjectTemplateInfo());
  TemplateInfoVerify(isolate);
  VerifyPointer(isolate, constructor());
  VerifyPointer(isolate, data());
}

void AllocationSite::AllocationSiteVerify(Isolate* isolate) {
  CHECK(IsAllocationSite());
}

void AllocationMemento::AllocationMementoVerify(Isolate* isolate) {
  CHECK(IsAllocationMemento());
  VerifyHeapPointer(isolate, allocation_site());
  CHECK(!IsValid() || GetAllocationSite()->IsAllocationSite());
}

void Script::ScriptVerify(Isolate* isolate) {
  CHECK(IsScript());
  VerifyPointer(isolate, source());
  VerifyPointer(isolate, name());
  VerifyPointer(isolate, line_ends());
  for (int i = 0; i < shared_function_infos()->length(); ++i) {
    MaybeObject maybe_object = shared_function_infos()->Get(i);
    HeapObject heap_object;
    CHECK(maybe_object->IsWeak() || maybe_object->IsCleared() ||
          (maybe_object->GetHeapObjectIfStrong(&heap_object) &&
           heap_object->IsUndefined(isolate)));
  }
  VerifySmiField(kIdOffset);
  VerifySmiField(kLineOffsetOffset);
  VerifySmiField(kColumnOffsetOffset);
  VerifySmiField(kScriptTypeOffset);
  VerifySmiField(kEvalFromPositionOffset);
  VerifySmiField(kFlagsOffset);
}

void NormalizedMapCache::NormalizedMapCacheVerify(Isolate* isolate) {
  WeakFixedArray::cast(*this)->WeakFixedArrayVerify(isolate);
  if (FLAG_enable_slow_asserts) {
    for (int i = 0; i < length(); i++) {
      MaybeObject e = WeakFixedArray::Get(i);
      HeapObject heap_object;
      if (e->GetHeapObjectIfWeak(&heap_object)) {
        Map::cast(heap_object)->DictionaryMapVerify(isolate);
      } else {
        CHECK(e->IsCleared() || (e->GetHeapObjectIfStrong(&heap_object) &&
                                 heap_object->IsUndefined(isolate)));
      }
    }
  }
}

void DebugInfo::DebugInfoVerify(Isolate* isolate) {
  CHECK(IsDebugInfo());
  VerifyPointer(isolate, shared());
  VerifyPointer(isolate, script());
  VerifyPointer(isolate, original_bytecode_array());
  VerifyPointer(isolate, break_points());
}

void StackTraceFrame::StackTraceFrameVerify(Isolate* isolate) {
  CHECK(IsStackTraceFrame());
  VerifySmiField(kFrameIndexOffset);
  VerifySmiField(kIdOffset);
  VerifyPointer(isolate, frame_array());
  VerifyPointer(isolate, frame_info());
}

void StackFrameInfo::StackFrameInfoVerify(Isolate* isolate) {
  CHECK(IsStackFrameInfo());
  VerifyPointer(isolate, script_name());
  VerifyPointer(isolate, script_name_or_source_url());
  VerifyPointer(isolate, function_name());
}

void PreparseData::PreparseDataVerify(Isolate* isolate) {
  CHECK(IsPreparseData());
  CHECK_LE(0, data_length());
  CHECK_LE(0, children_length());

  for (int i = 0; i < children_length(); ++i) {
    Object child = get_child_raw(i);
    CHECK(child->IsNull() || child->IsPreparseData());
    VerifyPointer(isolate, child);
  }
}

void UncompiledDataWithPreparseData::UncompiledDataWithPreparseDataVerify(
    Isolate* isolate) {
  CHECK(IsUncompiledDataWithPreparseData());
  VerifyPointer(isolate, inferred_name());
  VerifyPointer(isolate, preparse_data());
}

void UncompiledDataWithoutPreparseData::UncompiledDataWithoutPreparseDataVerify(
    Isolate* isolate) {
  CHECK(IsUncompiledDataWithoutPreparseData());
  VerifyPointer(isolate, inferred_name());
}

void InterpreterData::InterpreterDataVerify(Isolate* isolate) {
  CHECK(IsInterpreterData());
  CHECK(bytecode_array()->IsBytecodeArray());
  CHECK(interpreter_trampoline()->IsCode());
}

#ifdef V8_INTL_SUPPORT
void JSV8BreakIterator::JSV8BreakIteratorVerify(Isolate* isolate) {
  JSObjectVerify(isolate);
  VerifyObjectField(isolate, kLocaleOffset);
  VerifyObjectField(isolate, kTypeOffset);
  VerifyObjectField(isolate, kBreakIteratorOffset);
  VerifyObjectField(isolate, kUnicodeStringOffset);
  VerifyObjectField(isolate, kBoundAdoptTextOffset);
  VerifyObjectField(isolate, kBoundFirstOffset);
  VerifyObjectField(isolate, kBoundNextOffset);
  VerifyObjectField(isolate, kBoundCurrentOffset);
  VerifyObjectField(isolate, kBoundBreakTypeOffset);
}

void JSCollator::JSCollatorVerify(Isolate* isolate) {
  CHECK(IsJSCollator());
  JSObjectVerify(isolate);
  VerifyObjectField(isolate, kICUCollatorOffset);
  VerifyObjectField(isolate, kBoundCompareOffset);
}

void JSDateTimeFormat::JSDateTimeFormatVerify(Isolate* isolate) {
  JSObjectVerify(isolate);
  VerifyObjectField(isolate, kICULocaleOffset);
  VerifyObjectField(isolate, kICUSimpleDateFormatOffset);
  VerifyObjectField(isolate, kICUDateIntervalFormatOffset);
  VerifyObjectField(isolate, kBoundFormatOffset);
  VerifyObjectField(isolate, kFlagsOffset);
}

void JSListFormat::JSListFormatVerify(Isolate* isolate) {
  JSObjectVerify(isolate);
  VerifyObjectField(isolate, kLocaleOffset);
  VerifyObjectField(isolate, kICUFormatterOffset);
  VerifyObjectField(isolate, kFlagsOffset);
}

void JSLocale::JSLocaleVerify(Isolate* isolate) {
  JSObjectVerify(isolate);
  VerifyObjectField(isolate, kICULocaleOffset);
}

void JSNumberFormat::JSNumberFormatVerify(Isolate* isolate) {
  CHECK(IsJSNumberFormat());
  JSObjectVerify(isolate);
  VerifyObjectField(isolate, kLocaleOffset);
  VerifyObjectField(isolate, kICUNumberFormatOffset);
  VerifyObjectField(isolate, kBoundFormatOffset);
  VerifyObjectField(isolate, kFlagsOffset);
}

void JSPluralRules::JSPluralRulesVerify(Isolate* isolate) {
  CHECK(IsJSPluralRules());
  JSObjectVerify(isolate);
  VerifyObjectField(isolate, kLocaleOffset);
  VerifyObjectField(isolate, kFlagsOffset);
  VerifyObjectField(isolate, kICUPluralRulesOffset);
  VerifyObjectField(isolate, kICUDecimalFormatOffset);
}

void JSRelativeTimeFormat::JSRelativeTimeFormatVerify(Isolate* isolate) {
  JSObjectVerify(isolate);
  VerifyObjectField(isolate, kLocaleOffset);
  VerifyObjectField(isolate, kICUFormatterOffset);
  VerifyObjectField(isolate, kFlagsOffset);
}

void JSSegmentIterator::JSSegmentIteratorVerify(Isolate* isolate) {
  JSObjectVerify(isolate);
  VerifyObjectField(isolate, kICUBreakIteratorOffset);
  VerifyObjectField(isolate, kUnicodeStringOffset);
  VerifyObjectField(isolate, kFlagsOffset);
}

void JSSegmenter::JSSegmenterVerify(Isolate* isolate) {
  JSObjectVerify(isolate);
  VerifyObjectField(isolate, kLocaleOffset);
  VerifyObjectField(isolate, kICUBreakIteratorOffset);
  VerifyObjectField(isolate, kFlagsOffset);
}
#endif  // V8_INTL_SUPPORT

#endif  // VERIFY_HEAP

#ifdef DEBUG

void JSObject::IncrementSpillStatistics(Isolate* isolate,
                                        SpillInformation* info) {
  info->number_of_objects_++;
  // Named properties
  if (HasFastProperties()) {
    info->number_of_objects_with_fast_properties_++;
    info->number_of_fast_used_fields_   += map()->NextFreePropertyIndex();
    info->number_of_fast_unused_fields_ += map()->UnusedPropertyFields();
  } else if (IsJSGlobalObject()) {
    GlobalDictionary dict = JSGlobalObject::cast(*this)->global_dictionary();
    info->number_of_slow_used_properties_ += dict->NumberOfElements();
    info->number_of_slow_unused_properties_ +=
        dict->Capacity() - dict->NumberOfElements();
  } else {
    NameDictionary dict = property_dictionary();
    info->number_of_slow_used_properties_ += dict->NumberOfElements();
    info->number_of_slow_unused_properties_ +=
        dict->Capacity() - dict->NumberOfElements();
  }
  // Indexed properties
  switch (GetElementsKind()) {
    case HOLEY_SMI_ELEMENTS:
    case PACKED_SMI_ELEMENTS:
    case HOLEY_DOUBLE_ELEMENTS:
    case PACKED_DOUBLE_ELEMENTS:
    case HOLEY_ELEMENTS:
    case PACKED_ELEMENTS:
    case FAST_STRING_WRAPPER_ELEMENTS: {
      info->number_of_objects_with_fast_elements_++;
      int holes = 0;
      FixedArray e = FixedArray::cast(elements());
      int len = e->length();
      for (int i = 0; i < len; i++) {
        if (e->get(i)->IsTheHole(isolate)) holes++;
      }
      info->number_of_fast_used_elements_   += len - holes;
      info->number_of_fast_unused_elements_ += holes;
      break;
    }

#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) case TYPE##_ELEMENTS:

      TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
      {
        info->number_of_objects_with_fast_elements_++;
        FixedArrayBase e = FixedArrayBase::cast(elements());
        info->number_of_fast_used_elements_ += e->length();
        break;
      }
    case DICTIONARY_ELEMENTS:
    case SLOW_STRING_WRAPPER_ELEMENTS: {
      NumberDictionary dict = element_dictionary();
      info->number_of_slow_used_elements_ += dict->NumberOfElements();
      info->number_of_slow_unused_elements_ +=
          dict->Capacity() - dict->NumberOfElements();
      break;
    }
    case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
    case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
    case NO_ELEMENTS:
      break;
  }
}


void JSObject::SpillInformation::Clear() {
  number_of_objects_ = 0;
  number_of_objects_with_fast_properties_ = 0;
  number_of_objects_with_fast_elements_ = 0;
  number_of_fast_used_fields_ = 0;
  number_of_fast_unused_fields_ = 0;
  number_of_slow_used_properties_ = 0;
  number_of_slow_unused_properties_ = 0;
  number_of_fast_used_elements_ = 0;
  number_of_fast_unused_elements_ = 0;
  number_of_slow_used_elements_ = 0;
  number_of_slow_unused_elements_ = 0;
}


void JSObject::SpillInformation::Print() {
  PrintF("\n  JSObject Spill Statistics (#%d):\n", number_of_objects_);

  PrintF("    - fast properties (#%d): %d (used) %d (unused)\n",
         number_of_objects_with_fast_properties_,
         number_of_fast_used_fields_, number_of_fast_unused_fields_);

  PrintF("    - slow properties (#%d): %d (used) %d (unused)\n",
         number_of_objects_ - number_of_objects_with_fast_properties_,
         number_of_slow_used_properties_, number_of_slow_unused_properties_);

  PrintF("    - fast elements (#%d): %d (used) %d (unused)\n",
         number_of_objects_with_fast_elements_,
         number_of_fast_used_elements_, number_of_fast_unused_elements_);

  PrintF("    - slow elements (#%d): %d (used) %d (unused)\n",
         number_of_objects_ - number_of_objects_with_fast_elements_,
         number_of_slow_used_elements_, number_of_slow_unused_elements_);

  PrintF("\n");
}

bool DescriptorArray::IsSortedNoDuplicates(int valid_entries) {
  if (valid_entries == -1) valid_entries = number_of_descriptors();
  Name current_key;
  uint32_t current = 0;
  for (int i = 0; i < number_of_descriptors(); i++) {
    Name key = GetSortedKey(i);
    if (key == current_key) {
      Print();
      return false;
    }
    current_key = key;
    uint32_t hash = GetSortedKey(i)->Hash();
    if (hash < current) {
      Print();
      return false;
    }
    current = hash;
  }
  return true;
}

bool TransitionArray::IsSortedNoDuplicates(int valid_entries) {
  DCHECK_EQ(valid_entries, -1);
  Name prev_key;
  PropertyKind prev_kind = kData;
  PropertyAttributes prev_attributes = NONE;
  uint32_t prev_hash = 0;

  for (int i = 0; i < number_of_transitions(); i++) {
    Name key = GetSortedKey(i);
    uint32_t hash = key->Hash();
    PropertyKind kind = kData;
    PropertyAttributes attributes = NONE;
    if (!TransitionsAccessor::IsSpecialTransition(key->GetReadOnlyRoots(),
                                                  key)) {
      Map target = GetTarget(i);
      PropertyDetails details =
          TransitionsAccessor::GetTargetDetails(key, target);
      kind = details.kind();
      attributes = details.attributes();
    } else {
      // Duplicate entries are not allowed for non-property transitions.
      DCHECK_NE(prev_key, key);
    }

    int cmp = CompareKeys(prev_key, prev_hash, prev_kind, prev_attributes, key,
                          hash, kind, attributes);
    if (cmp >= 0) {
      Print();
      return false;
    }
    prev_key = key;
    prev_hash = hash;
    prev_attributes = attributes;
    prev_kind = kind;
  }
  return true;
}

bool TransitionsAccessor::IsSortedNoDuplicates() {
  // Simple and non-existent transitions are always sorted.
  if (encoding() != kFullTransitionArray) return true;
  return transitions()->IsSortedNoDuplicates();
}

static bool CheckOneBackPointer(Map current_map, Object target) {
  return !target->IsMap() || Map::cast(target)->GetBackPointer() == current_map;
}

bool TransitionsAccessor::IsConsistentWithBackPointers() {
  int num_transitions = NumberOfTransitions();
  for (int i = 0; i < num_transitions; i++) {
    Map target = GetTarget(i);
    if (!CheckOneBackPointer(map_, target)) return false;
  }
  return true;
}

#endif  // DEBUG

}  // namespace internal
}  // namespace v8
