// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/raw_object.h"

#include "vm/class_table.h"
#include "vm/dart.h"
#include "vm/heap/become.h"
#include "vm/heap/freelist.h"
#include "vm/isolate.h"
#include "vm/isolate_reload.h"
#include "vm/object.h"
#include "vm/runtime_entry.h"
#include "vm/stack_frame.h"
#include "vm/visitor.h"

namespace dart {

bool UntaggedObject::InVMIsolateHeap() const {
  // All "vm-isolate" objects are pre-marked and in old space
  // (see [Object::FinalizeVMIsolate]).
  if (!IsOldObject() || !IsMarked()) return false;

  auto heap = Dart::vm_isolate_group()->heap();
  ASSERT(heap->UsedInWords(Heap::kNew) == 0);
  return heap->old_space()->ContainsUnsafe(ToAddr(this));
}

void ObjectPtr::Validate(IsolateGroup* isolate_group) const {
  // All Smi values are valid.
  if (!IsHeapObject()) {
    return;
  }
  // Slightly more readable than a segfault.
  if (tagged_pointer_ == kHeapObjectTag) {
    FATAL("RAW_NULL encountered");
  }
  untag()->Validate(isolate_group);
}

void UntaggedObject::Validate(IsolateGroup* isolate_group) const {
  if (static_cast<uword>(Object::void_class_) == kHeapObjectTag) {
    // Validation relies on properly initialized class classes. Skip if the
    // VM is still being initialized.
    return;
  }
  // Validate that the tags_ field is sensible.
  uword tags = tags_;
  if (IsNewObject()) {
    if (!NewOrEvacuationCandidateBit::decode(tags)) {
      FATAL("New object missing kNewBit: %" Px "\n", tags);
    }
    if (OldAndNotRememberedBit::decode(tags)) {
      FATAL("New object has kOldAndNotRememberedBit: %" Px "\n", tags);
    }
  }
  const intptr_t class_id = ClassIdTag::decode(tags);
  if (!isolate_group->class_table()->IsValidIndex(class_id)) {
    FATAL("Invalid class id encountered %" Pd "\n", class_id);
  }
  if (class_id == kNullCid &&
      isolate_group->class_table()->HasValidClassAt(class_id)) {
    // Null class not yet initialized; skip.
    return;
  }
  intptr_t size_from_tags = SizeTag::decode(tags);
  intptr_t size_from_class = HeapSizeFromClass(tags);
  if ((size_from_tags != 0) && (size_from_tags != size_from_class)) {
    FATAL(
        "Inconsistent size encountered "
        "cid: %" Pd ", size_from_tags: %" Pd ", size_from_class: %" Pd "\n",
        class_id, size_from_tags, size_from_class);
  }
}

// Can't look at the class object because it can be called during
// compaction when the class objects are moving. Can use the class
// id in the header and the sizes in the Class Table.
// Cannot deference ptr()->tags_. May dereference other parts of the object.
intptr_t UntaggedObject::HeapSizeFromClass(uword tags) const {
  intptr_t class_id = ClassIdTag::decode(tags);
  intptr_t instance_size = 0;
  switch (class_id) {
    case kCodeCid: {
      const CodePtr raw_code = static_cast<const CodePtr>(this);
      intptr_t pointer_offsets_length =
          Code::PtrOffBits::decode(raw_code->untag()->state_bits_);
      instance_size = Code::InstanceSize(pointer_offsets_length);
      break;
    }
    case kInstructionsCid: {
      const InstructionsPtr raw_instructions =
          static_cast<const InstructionsPtr>(this);
      intptr_t instructions_size = Instructions::Size(raw_instructions);
      instance_size = Instructions::InstanceSize(instructions_size);
      break;
    }
    case kInstructionsSectionCid: {
      const InstructionsSectionPtr raw_section =
          static_cast<const InstructionsSectionPtr>(this);
      intptr_t section_size = InstructionsSection::Size(raw_section);
      instance_size = InstructionsSection::InstanceSize(section_size);
      break;
    }
    case kContextCid: {
      const ContextPtr raw_context = static_cast<const ContextPtr>(this);
      intptr_t num_variables = raw_context->untag()->num_variables_;
      instance_size = Context::InstanceSize(num_variables);
      break;
    }
    case kContextScopeCid: {
      const ContextScopePtr raw_context_scope =
          static_cast<const ContextScopePtr>(this);
      intptr_t num_variables = raw_context_scope->untag()->num_variables_;
      instance_size = ContextScope::InstanceSize(num_variables);
      break;
    }
    case kOneByteStringCid: {
      const OneByteStringPtr raw_string =
          static_cast<const OneByteStringPtr>(this);
      intptr_t string_length = Smi::Value(raw_string->untag()->length());
      instance_size = OneByteString::InstanceSize(string_length);
      break;
    }
    case kTwoByteStringCid: {
      const TwoByteStringPtr raw_string =
          static_cast<const TwoByteStringPtr>(this);
      intptr_t string_length = Smi::Value(raw_string->untag()->length());
      instance_size = TwoByteString::InstanceSize(string_length);
      break;
    }
    case kArrayCid:
    case kImmutableArrayCid: {
      const ArrayPtr raw_array = static_cast<const ArrayPtr>(this);
      intptr_t array_length =
          Smi::Value(raw_array->untag()->length<std::memory_order_acquire>());
      instance_size = Array::InstanceSize(array_length);
      break;
    }
    case kWeakArrayCid: {
      const WeakArrayPtr raw_array = static_cast<const WeakArrayPtr>(this);
      intptr_t array_length = Smi::Value(raw_array->untag()->length());
      instance_size = WeakArray::InstanceSize(array_length);
      break;
    }
    case kObjectPoolCid: {
      const ObjectPoolPtr raw_object_pool =
          static_cast<const ObjectPoolPtr>(this);
      intptr_t len = raw_object_pool->untag()->length_;
      instance_size = ObjectPool::InstanceSize(len);
      break;
    }
    case kRecordCid: {
      const RecordPtr raw_record = static_cast<const RecordPtr>(this);
      intptr_t num_fields =
          RecordShape(raw_record->untag()->shape()).num_fields();
      instance_size = Record::InstanceSize(num_fields);
      break;
    }
#define SIZE_FROM_CLASS(clazz) case kTypedData##clazz##Cid:
      CLASS_LIST_TYPED_DATA(SIZE_FROM_CLASS) {
        const TypedDataPtr raw_obj = static_cast<const TypedDataPtr>(this);
        intptr_t array_len = Smi::Value(raw_obj->untag()->length());
        intptr_t lengthInBytes =
            array_len * TypedData::ElementSizeInBytes(class_id);
        instance_size = TypedData::InstanceSize(lengthInBytes);
        break;
      }
#undef SIZE_FROM_CLASS
    case kPointerCid:
      instance_size = Pointer::InstanceSize();
      break;
    case kSuspendStateCid: {
      const SuspendStatePtr raw_suspend_state =
          static_cast<const SuspendStatePtr>(this);
      intptr_t frame_capacity = raw_suspend_state->untag()->frame_capacity();
      instance_size = SuspendState::InstanceSize(frame_capacity);
      break;
    }
    case kTypeArgumentsCid: {
      const TypeArgumentsPtr raw_array =
          static_cast<const TypeArgumentsPtr>(this);
      intptr_t array_length = Smi::Value(raw_array->untag()->length());
      instance_size = TypeArguments::InstanceSize(array_length);
      break;
    }
    case kPcDescriptorsCid: {
      const PcDescriptorsPtr raw_descriptors =
          static_cast<const PcDescriptorsPtr>(this);
      intptr_t length = raw_descriptors->untag()->length_;
      instance_size = PcDescriptors::InstanceSize(length);
      break;
    }
    case kCodeSourceMapCid: {
      const CodeSourceMapPtr raw_code_source_map =
          static_cast<const CodeSourceMapPtr>(this);
      intptr_t length = raw_code_source_map->untag()->length_;
      instance_size = CodeSourceMap::InstanceSize(length);
      break;
    }
    case kCompressedStackMapsCid: {
      const CompressedStackMapsPtr maps =
          static_cast<const CompressedStackMapsPtr>(this);
      intptr_t length = CompressedStackMaps::PayloadSizeOf(maps);
      instance_size = CompressedStackMaps::InstanceSize(length);
      break;
    }
    case kLocalVarDescriptorsCid: {
      const LocalVarDescriptorsPtr raw_descriptors =
          static_cast<const LocalVarDescriptorsPtr>(this);
      intptr_t num_descriptors = raw_descriptors->untag()->num_entries_;
      instance_size = LocalVarDescriptors::InstanceSize(num_descriptors);
      break;
    }
    case kExceptionHandlersCid: {
      const ExceptionHandlersPtr raw_handlers =
          static_cast<const ExceptionHandlersPtr>(this);
      intptr_t num_handlers = raw_handlers->untag()->num_entries();
      instance_size = ExceptionHandlers::InstanceSize(num_handlers);
      break;
    }
    case kFreeListElement: {
      uword addr = UntaggedObject::ToAddr(this);
      FreeListElement* element = reinterpret_cast<FreeListElement*>(addr);
      instance_size = element->HeapSize(tags);
      break;
    }
    case kForwardingCorpse: {
      uword addr = UntaggedObject::ToAddr(this);
      ForwardingCorpse* element = reinterpret_cast<ForwardingCorpse*>(addr);
      instance_size = element->HeapSize(tags);
      break;
    }
    case kWeakSerializationReferenceCid: {
      instance_size = WeakSerializationReference::InstanceSize();
      break;
    }
    default: {
      // Get the (constant) instance size out of the class object.
      // TODO(koda): Add Size(ClassTable*) interface to allow caching in loops.
      auto isolate_group = IsolateGroup::Current();
#if defined(DEBUG)
      auto class_table = isolate_group->heap_walk_class_table();
      if (!class_table->IsValidIndex(class_id) ||
          !class_table->HasValidClassAt(class_id)) {
        FATAL("Invalid cid: %" Pd ", obj: %p, tags: %x. Corrupt heap?",
              class_id, this, static_cast<uint32_t>(tags));
      }
      ASSERT(class_table->SizeAt(class_id) > 0);
#endif  // DEBUG
      instance_size = isolate_group->heap_walk_class_table()->SizeAt(class_id);
    }
  }
  ASSERT(instance_size != 0);
#if defined(DEBUG)
  intptr_t tags_size = SizeTag::decode(tags);
  if ((class_id == kArrayCid) && (instance_size > tags_size && tags_size > 0)) {
    // TODO(22501): Array::MakeFixedLength could be in the process of shrinking
    // the array (see comment therein), having already updated the tags but not
    // yet set the new length. Wait a millisecond and try again.
    int retries_remaining = 1000;  // ... but not forever.
    do {
      OS::Sleep(1);
      const ArrayPtr raw_array = static_cast<const ArrayPtr>(this);
      intptr_t array_length = Smi::Value(raw_array->untag()->length());
      instance_size = Array::InstanceSize(array_length);
    } while ((instance_size > tags_size) && (--retries_remaining > 0));
  }
  if ((instance_size != tags_size) && (tags_size != 0)) {
    FATAL("Size mismatch: %" Pd " from class vs %" Pd " from tags %" Px "\n",
          instance_size, tags_size, tags);
  }
#endif  // DEBUG
  return instance_size;
}

intptr_t UntaggedObject::VisitPointersPredefined(ObjectPointerVisitor* visitor,
                                                 intptr_t class_id) {
  ASSERT(class_id < kNumPredefinedCids);

  intptr_t size = 0;

  switch (class_id) {
#define RAW_VISITPOINTERS(clazz)                                               \
  case k##clazz##Cid: {                                                        \
    clazz##Ptr raw_obj = static_cast<clazz##Ptr>(this);                        \
    size = Untagged##clazz::Visit##clazz##Pointers(raw_obj, visitor);          \
    break;                                                                     \
  }
    CLASS_LIST_NO_OBJECT(RAW_VISITPOINTERS)
#undef RAW_VISITPOINTERS
#define RAW_VISITPOINTERS(clazz) case kTypedData##clazz##Cid:
    CLASS_LIST_TYPED_DATA(RAW_VISITPOINTERS) {
      TypedDataPtr raw_obj = static_cast<TypedDataPtr>(this);
      size = UntaggedTypedData::VisitTypedDataPointers(raw_obj, visitor);
      break;
    }
#undef RAW_VISITPOINTERS
#define RAW_VISITPOINTERS(clazz) case kExternalTypedData##clazz##Cid:
    CLASS_LIST_TYPED_DATA(RAW_VISITPOINTERS) {
      auto raw_obj = static_cast<ExternalTypedDataPtr>(this);
      size = UntaggedExternalTypedData::VisitExternalTypedDataPointers(raw_obj,
                                                                       visitor);
      break;
    }
#undef RAW_VISITPOINTERS
    case kByteDataViewCid:
    case kUnmodifiableByteDataViewCid:
#define RAW_VISITPOINTERS(clazz)                                               \
  case kTypedData##clazz##ViewCid:                                             \
  case kUnmodifiableTypedData##clazz##ViewCid:
      CLASS_LIST_TYPED_DATA(RAW_VISITPOINTERS) {
        auto raw_obj = static_cast<TypedDataViewPtr>(this);
        size =
            UntaggedTypedDataView::VisitTypedDataViewPointers(raw_obj, visitor);
        break;
      }
#undef RAW_VISITPOINTERS
    case kByteBufferCid: {
      InstancePtr raw_obj = static_cast<InstancePtr>(this);
      size = UntaggedInstance::VisitInstancePointers(raw_obj, visitor);
      break;
    }
#define RAW_VISITPOINTERS(clazz) case kFfi##clazz##Cid:
      CLASS_LIST_FFI_TYPE_MARKER(RAW_VISITPOINTERS) {
        // NativeType do not have any fields or type arguments.
        size = HeapSize();
        break;
      }
#undef RAW_VISITPOINTERS
    case kFreeListElement: {
      uword addr = UntaggedObject::ToAddr(this);
      FreeListElement* element = reinterpret_cast<FreeListElement*>(addr);
      size = element->HeapSize();
      break;
    }
    case kForwardingCorpse: {
      uword addr = UntaggedObject::ToAddr(this);
      ForwardingCorpse* forwarder = reinterpret_cast<ForwardingCorpse*>(addr);
      size = forwarder->HeapSize();
      break;
    }
    case kNullCid:
    case kNeverCid:
      size = HeapSize();
      break;
    default:
      FATAL("Invalid cid: %" Pd ", obj: %p, tags: %x. Corrupt heap?", class_id,
            this, static_cast<uint32_t>(tags_));
      break;
  }

#if defined(DEBUG)
  ASSERT(size != 0);
  const intptr_t expected_size = HeapSize();

  // In general we expect that visitors return exactly the same size that
  // HeapSize would compute. However in case of Arrays we might have a
  // discrepancy when concurrently visiting an array that is being shrunk with
  // Array::MakeFixedLength: the visitor might have visited the full array while
  // here we are observing a smaller HeapSize().
  ASSERT(size == expected_size ||
         (class_id == kArrayCid && size > expected_size));
  return size;  // Prefer larger size.
#else
  return size;
#endif
}

void UntaggedObject::VisitPointersPrecise(ObjectPointerVisitor* visitor) {
  intptr_t class_id = GetClassId();
  if ((class_id != kInstanceCid) && (class_id < kNumPredefinedCids)) {
    VisitPointersPredefined(visitor, class_id);
    return;
  }

  // N.B.: Not using the heap size!
  uword next_field_offset = visitor->class_table()
                                ->At(class_id)
                                ->untag()
                                ->host_next_field_offset_in_words_
                            << kCompressedWordSizeLog2;
  ASSERT(next_field_offset > 0);
  uword obj_addr = UntaggedObject::ToAddr(this);
  uword from = obj_addr + sizeof(UntaggedObject);
  uword to = obj_addr + next_field_offset - kCompressedWordSize;
  const auto first = reinterpret_cast<CompressedObjectPtr*>(from);
  const auto last = reinterpret_cast<CompressedObjectPtr*>(to);

  const auto unboxed_fields_bitmap =
      visitor->class_table()->GetUnboxedFieldsMapAt(class_id);

  if (!unboxed_fields_bitmap.IsEmpty()) {
    intptr_t bit = sizeof(UntaggedObject) / kCompressedWordSize;
    for (CompressedObjectPtr* current = first; current <= last; current++) {
      if (!unboxed_fields_bitmap.Get(bit++)) {
        visitor->VisitCompressedPointers(heap_base(), current, current);
      }
    }
  } else {
    visitor->VisitCompressedPointers(heap_base(), first, last);
  }
}

// Most objects are visited with this function. It calls the from() and to()
// methods on the raw object to get the first and last cells that need
// visiting.
#define REGULAR_VISITOR(Type)                                                  \
  intptr_t Untagged##Type::Visit##Type##Pointers(                              \
      Type##Ptr raw_obj, ObjectPointerVisitor* visitor) {                      \
    /* Make sure that we got here with the tagged pointer as this. */          \
    ASSERT(raw_obj->IsHeapObject());                                           \
    ASSERT_UNCOMPRESSED(Type);                                                 \
    visitor->VisitPointers(raw_obj->untag()->from(), raw_obj->untag()->to());  \
    return Type::InstanceSize();                                               \
  }

#if !defined(DART_COMPRESSED_POINTERS)
#define COMPRESSED_VISITOR(Type) REGULAR_VISITOR(Type)
#else
#define COMPRESSED_VISITOR(Type)                                               \
  intptr_t Untagged##Type::Visit##Type##Pointers(                              \
      Type##Ptr raw_obj, ObjectPointerVisitor* visitor) {                      \
    /* Make sure that we got here with the tagged pointer as this. */          \
    ASSERT(raw_obj->IsHeapObject());                                           \
    ASSERT_COMPRESSED(Type);                                                   \
    visitor->VisitCompressedPointers(raw_obj->heap_base(),                     \
                                     raw_obj->untag()->from(),                 \
                                     raw_obj->untag()->to());                  \
    return Type::InstanceSize();                                               \
  }
#endif

// It calls the from() and to() methods on the raw object to get the first and
// last cells that need visiting.
//
// Though as opposed to Similar to [REGULAR_VISITOR] this visitor will call the
// specialized VisitTypedDataViewPointers
#define TYPED_DATA_VIEW_VISITOR(Type)                                          \
  intptr_t Untagged##Type::Visit##Type##Pointers(                              \
      Type##Ptr raw_obj, ObjectPointerVisitor* visitor) {                      \
    /* Make sure that we got here with the tagged pointer as this. */          \
    ASSERT(raw_obj->IsHeapObject());                                           \
    ASSERT_COMPRESSED(Type);                                                   \
    visitor->VisitTypedDataViewPointers(raw_obj, raw_obj->untag()->from(),     \
                                        raw_obj->untag()->to());               \
    return Type::InstanceSize();                                               \
  }

// For variable length objects. get_length is a code snippet that gets the
// length of the object, which is passed to InstanceSize and the to() method.
#define VARIABLE_VISITOR(Type, get_length)                                     \
  intptr_t Untagged##Type::Visit##Type##Pointers(                              \
      Type##Ptr raw_obj, ObjectPointerVisitor* visitor) {                      \
    /* Make sure that we got here with the tagged pointer as this. */          \
    ASSERT(raw_obj->IsHeapObject());                                           \
    intptr_t length = get_length;                                              \
    visitor->VisitPointers(raw_obj->untag()->from(),                           \
                           raw_obj->untag()->to(length));                      \
    return Type::InstanceSize(length);                                         \
  }

#if !defined(DART_COMPRESSED_POINTERS)
#define VARIABLE_COMPRESSED_VISITOR(Type, get_length)                          \
  VARIABLE_VISITOR(Type, get_length)
#else
#define VARIABLE_COMPRESSED_VISITOR(Type, get_length)                          \
  intptr_t Untagged##Type::Visit##Type##Pointers(                              \
      Type##Ptr raw_obj, ObjectPointerVisitor* visitor) {                      \
    /* Make sure that we got here with the tagged pointer as this. */          \
    ASSERT(raw_obj->IsHeapObject());                                           \
    intptr_t length = get_length;                                              \
    visitor->VisitCompressedPointers(raw_obj->heap_base(),                     \
                                     raw_obj->untag()->from(),                 \
                                     raw_obj->untag()->to(length));            \
    return Type::InstanceSize(length);                                         \
  }
#endif

// For fixed-length objects that don't have any pointers that need visiting.
#define NULL_VISITOR(Type)                                                     \
  intptr_t Untagged##Type::Visit##Type##Pointers(                              \
      Type##Ptr raw_obj, ObjectPointerVisitor* visitor) {                      \
    /* Make sure that we got here with the tagged pointer as this. */          \
    ASSERT(raw_obj->IsHeapObject());                                           \
    ASSERT_NOTHING_TO_VISIT(Type);                                             \
    return Type::InstanceSize();                                               \
  }

// For objects that don't have any pointers that need visiting, but have a
// variable length.
#define VARIABLE_NULL_VISITOR(Type, get_length)                                \
  intptr_t Untagged##Type::Visit##Type##Pointers(                              \
      Type##Ptr raw_obj, ObjectPointerVisitor* visitor) {                      \
    /* Make sure that we got here with the tagged pointer as this. */          \
    ASSERT(raw_obj->IsHeapObject());                                           \
    ASSERT_NOTHING_TO_VISIT(Type);                                             \
    intptr_t length = get_length;                                              \
    return Type::InstanceSize(length);                                         \
  }

// For objects that are never instantiated on the heap.
#define UNREACHABLE_VISITOR(Type)                                              \
  intptr_t Untagged##Type::Visit##Type##Pointers(                              \
      Type##Ptr raw_obj, ObjectPointerVisitor* visitor) {                      \
    UNREACHABLE();                                                             \
    return 0;                                                                  \
  }

COMPRESSED_VISITOR(Class)
COMPRESSED_VISITOR(PatchClass)
COMPRESSED_VISITOR(ClosureData)
COMPRESSED_VISITOR(FfiTrampolineData)
COMPRESSED_VISITOR(Script)
COMPRESSED_VISITOR(Library)
COMPRESSED_VISITOR(Namespace)
COMPRESSED_VISITOR(KernelProgramInfo)
COMPRESSED_VISITOR(WeakSerializationReference)
VARIABLE_COMPRESSED_VISITOR(WeakArray, Smi::Value(raw_obj->untag()->length()))
COMPRESSED_VISITOR(Type)
COMPRESSED_VISITOR(FunctionType)
COMPRESSED_VISITOR(RecordType)
COMPRESSED_VISITOR(TypeParameter)
COMPRESSED_VISITOR(Function)
COMPRESSED_VISITOR(Closure)
COMPRESSED_VISITOR(LibraryPrefix)
COMPRESSED_VISITOR(Bytecode)
REGULAR_VISITOR(SingleTargetCache)
REGULAR_VISITOR(UnlinkedCall)
NULL_VISITOR(MonomorphicSmiableCall)
REGULAR_VISITOR(ICData)
REGULAR_VISITOR(MegamorphicCache)
COMPRESSED_VISITOR(ApiError)
COMPRESSED_VISITOR(LanguageError)
COMPRESSED_VISITOR(UnhandledException)
COMPRESSED_VISITOR(UnwindError)
COMPRESSED_VISITOR(GrowableObjectArray)
COMPRESSED_VISITOR(Map)
COMPRESSED_VISITOR(Set)
COMPRESSED_VISITOR(ExternalTypedData)
TYPED_DATA_VIEW_VISITOR(TypedDataView)
COMPRESSED_VISITOR(ReceivePort)
COMPRESSED_VISITOR(StackTrace)
COMPRESSED_VISITOR(RegExp)
COMPRESSED_VISITOR(WeakProperty)
COMPRESSED_VISITOR(WeakReference)
COMPRESSED_VISITOR(Finalizer)
COMPRESSED_VISITOR(FinalizerEntry)
COMPRESSED_VISITOR(NativeFinalizer)
COMPRESSED_VISITOR(MirrorReference)
COMPRESSED_VISITOR(UserTag)
REGULAR_VISITOR(SubtypeTestCache)
COMPRESSED_VISITOR(LoadingUnit)
COMPRESSED_VISITOR(TypeParameters)
VARIABLE_COMPRESSED_VISITOR(TypeArguments,
                            Smi::Value(raw_obj->untag()->length()))
VARIABLE_COMPRESSED_VISITOR(LocalVarDescriptors, raw_obj->untag()->num_entries_)
VARIABLE_COMPRESSED_VISITOR(ExceptionHandlers, raw_obj->untag()->num_entries())
VARIABLE_COMPRESSED_VISITOR(Context, raw_obj->untag()->num_variables_)
VARIABLE_COMPRESSED_VISITOR(Array, Smi::Value(raw_obj->untag()->length()))
VARIABLE_COMPRESSED_VISITOR(
    TypedData,
    TypedData::ElementSizeInBytes(raw_obj->GetClassIdOfHeapObject()) *
        Smi::Value(raw_obj->untag()->length()))
VARIABLE_COMPRESSED_VISITOR(ContextScope, raw_obj->untag()->num_variables_)
VARIABLE_COMPRESSED_VISITOR(Record,
                            RecordShape(raw_obj->untag()->shape()).num_fields())
NULL_VISITOR(Sentinel)
REGULAR_VISITOR(InstructionsTable)
NULL_VISITOR(Mint)
NULL_VISITOR(Double)
NULL_VISITOR(Float32x4)
NULL_VISITOR(Int32x4)
NULL_VISITOR(Float64x2)
NULL_VISITOR(Bool)
NULL_VISITOR(Capability)
NULL_VISITOR(SendPort)
NULL_VISITOR(TransferableTypedData)
COMPRESSED_VISITOR(Pointer)
NULL_VISITOR(DynamicLibrary)
VARIABLE_NULL_VISITOR(Instructions, Instructions::Size(raw_obj))
VARIABLE_NULL_VISITOR(InstructionsSection, InstructionsSection::Size(raw_obj))
VARIABLE_NULL_VISITOR(PcDescriptors, raw_obj->untag()->length_)
VARIABLE_NULL_VISITOR(CodeSourceMap, raw_obj->untag()->length_)
VARIABLE_NULL_VISITOR(CompressedStackMaps,
                      CompressedStackMaps::PayloadSizeOf(raw_obj))
VARIABLE_NULL_VISITOR(OneByteString, Smi::Value(raw_obj->untag()->length()))
VARIABLE_NULL_VISITOR(TwoByteString, Smi::Value(raw_obj->untag()->length()))
// Abstract types don't have their visitor called.
UNREACHABLE_VISITOR(AbstractType)
UNREACHABLE_VISITOR(CallSiteData)
UNREACHABLE_VISITOR(TypedDataBase)
UNREACHABLE_VISITOR(Error)
UNREACHABLE_VISITOR(FinalizerBase)
UNREACHABLE_VISITOR(Number)
UNREACHABLE_VISITOR(Integer)
UNREACHABLE_VISITOR(String)
UNREACHABLE_VISITOR(FutureOr)
// Smi has no heap representation.
UNREACHABLE_VISITOR(Smi)

intptr_t UntaggedField::VisitFieldPointers(FieldPtr raw_obj,
                                           ObjectPointerVisitor* visitor) {
  ASSERT(raw_obj->IsHeapObject());
  ASSERT_COMPRESSED(Field);
  visitor->VisitCompressedPointers(
      raw_obj->heap_base(), raw_obj->untag()->from(), raw_obj->untag()->to());

  if (visitor->trace_values_through_fields()) {
    if (Field::StaticBit::decode(raw_obj->untag()->kind_bits_)) {
      visitor->isolate_group()->ForEachIsolate(
          [&](Isolate* isolate) {
            intptr_t index =
                Smi::Value(raw_obj->untag()->host_offset_or_field_id());
            visitor->VisitPointer(&isolate->field_table()->table()[index]);
          },
          /*at_safepoint=*/true);
    }
  }
  return Field::InstanceSize();
}

intptr_t UntaggedSuspendState::VisitSuspendStatePointers(
    SuspendStatePtr raw_obj,
    ObjectPointerVisitor* visitor) {
  ASSERT(raw_obj->IsHeapObject());
  ASSERT_COMPRESSED(SuspendState);

  if (visitor->CanVisitSuspendStatePointers(raw_obj)) {
    visitor->VisitCompressedPointers(
        raw_obj->heap_base(), raw_obj->untag()->from(), raw_obj->untag()->to());

    const uword pc = raw_obj->untag()->pc_;
    if (pc != 0) {
      Thread* thread = Thread::Current();
      ASSERT(thread != nullptr);
      ASSERT(thread->isolate_group() == visitor->isolate_group());
      const uword sp = reinterpret_cast<uword>(raw_obj->untag()->payload());
      StackFrame frame(thread);
      frame.pc_ = pc;
      frame.sp_ = sp;
      frame.fp_ = sp + raw_obj->untag()->frame_size_;
      frame.VisitObjectPointers(visitor);
    }
  }

  return SuspendState::InstanceSize(raw_obj->untag()->frame_capacity());
}

bool UntaggedCode::ContainsPC(const ObjectPtr raw_obj, uword pc) {
  if (!raw_obj->IsCode()) return false;
  auto const raw_code = static_cast<const CodePtr>(raw_obj);
  const uword start = Code::PayloadStartOf(raw_code);
  const uword size = Code::PayloadSizeOf(raw_code);
  return (pc - start) <= size;  // pc may point just past last instruction.
}

intptr_t UntaggedCode::VisitCodePointers(CodePtr raw_obj,
                                         ObjectPointerVisitor* visitor) {
  visitor->VisitPointers(raw_obj->untag()->from(), raw_obj->untag()->to());

  UntaggedCode* obj = raw_obj->untag();
  intptr_t length = Code::PtrOffBits::decode(obj->state_bits_);
#if defined(TARGET_ARCH_IA32)
  // On IA32 only we embed pointers to objects directly in the generated
  // instructions. The variable portion of a Code object describes where to
  // find those pointers for tracing.
  if (Code::AliveBit::decode(obj->state_bits_)) {
    uword entry_point = Code::PayloadStartOf(raw_obj);
    for (intptr_t i = 0; i < length; i++) {
      int32_t offset = obj->data()[i];
      visitor->VisitPointer(reinterpret_cast<ObjectPtr*>(entry_point + offset));
    }
  }
  return Code::InstanceSize(length);
#else
  // On all other architectures, objects are referenced indirectly through
  // either an ObjectPool or Thread.
  ASSERT(length == 0);
  return Code::InstanceSize(0);
#endif
}

bool UntaggedBytecode::ContainsPC(ObjectPtr raw_obj, uword pc) {
  if (raw_obj->IsBytecode()) {
    BytecodePtr raw_bytecode = static_cast<BytecodePtr>(raw_obj);
    uword start = raw_bytecode->untag()->instructions_;
    uword size = raw_bytecode->untag()->instructions_size_;
    return (pc - start) <= size;  // pc may point past last instruction.
  }
  return false;
}

intptr_t UntaggedObjectPool::VisitObjectPoolPointers(
    ObjectPoolPtr raw_obj,
    ObjectPointerVisitor* visitor) {
  const intptr_t length = raw_obj->untag()->length_;
  UntaggedObjectPool::Entry* entries = raw_obj->untag()->data();
  uint8_t* entry_bits = raw_obj->untag()->entry_bits();
  for (intptr_t i = 0; i < length; ++i) {
    ObjectPool::EntryType entry_type =
        ObjectPool::TypeBits::decode(entry_bits[i]);
    if (entry_type == ObjectPool::EntryType::kTaggedObject) {
      visitor->VisitPointer(&entries[i].raw_obj_);
    }
  }
  return ObjectPool::InstanceSize(length);
}

bool UntaggedInstructions::ContainsPC(const InstructionsPtr raw_instr,
                                      uword pc) {
  const uword start = Instructions::PayloadStart(raw_instr);
  const uword size = Instructions::Size(raw_instr);
  // We use <= instead of < here because the saved-pc can be outside the
  // instruction stream if the last instruction is a call we don't expect to
  // return (e.g. because it throws an exception).
  return (pc - start) <= size;
}

intptr_t UntaggedInstance::VisitInstancePointers(
    InstancePtr raw_obj,
    ObjectPointerVisitor* visitor) {
  // Make sure that we got here with the tagged pointer as this.
  ASSERT(raw_obj->IsHeapObject());
  uword tags = raw_obj->untag()->tags_;
  intptr_t instance_size = SizeTag::decode(tags);
  if (instance_size == 0) {
    instance_size =
        visitor->class_table()->SizeAt(raw_obj->GetClassIdOfHeapObject());
  }

  // Calculate the first and last raw object pointer fields.
  uword obj_addr = UntaggedObject::ToAddr(raw_obj);
  uword from = obj_addr + sizeof(UntaggedObject);
  uword to = obj_addr + instance_size - kCompressedWordSize;
  visitor->VisitCompressedPointers(raw_obj->heap_base(),
                                   reinterpret_cast<CompressedObjectPtr*>(from),
                                   reinterpret_cast<CompressedObjectPtr*>(to));
  return instance_size;
}

intptr_t UntaggedImmutableArray::VisitImmutableArrayPointers(
    ImmutableArrayPtr raw_obj,
    ObjectPointerVisitor* visitor) {
  return UntaggedArray::VisitArrayPointers(raw_obj, visitor);
}

intptr_t UntaggedConstMap::VisitConstMapPointers(
    ConstMapPtr raw_obj,
    ObjectPointerVisitor* visitor) {
  return UntaggedMap::VisitMapPointers(raw_obj, visitor);
}

intptr_t UntaggedConstSet::VisitConstSetPointers(
    ConstSetPtr raw_obj,
    ObjectPointerVisitor* visitor) {
  return UntaggedSet::VisitSetPointers(raw_obj, visitor);
}

void UntaggedObject::RememberCard(ObjectPtr const* slot) {
  Page::Of(static_cast<ObjectPtr>(this))->RememberCard(slot);
}

#if defined(DART_COMPRESSED_POINTERS)
void UntaggedObject::RememberCard(CompressedObjectPtr const* slot) {
  Page::Of(static_cast<ObjectPtr>(this))->RememberCard(slot);
}
#endif

const char* UntaggedPcDescriptors::KindToCString(Kind k) {
  switch (k) {
#define ENUM_CASE(name, init)                                                  \
  case Kind::k##name:                                                          \
    return #name;
    FOR_EACH_RAW_PC_DESCRIPTOR(ENUM_CASE)
#undef ENUM_CASE
    default:
      return nullptr;
  }
}

bool UntaggedPcDescriptors::ParseKind(const char* cstr, Kind* out) {
  ASSERT(cstr != nullptr && out != nullptr);
#define ENUM_CASE(name, init)                                                  \
  if (strcmp(#name, cstr) == 0) {                                              \
    *out = Kind::k##name;                                                      \
    return true;                                                               \
  }
  FOR_EACH_RAW_PC_DESCRIPTOR(ENUM_CASE)
#undef ENUM_CASE
  return false;
}
#undef PREFIXED_NAME

}  // namespace dart
