// 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/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 (!NewBit::decode(tags)) {
      FATAL1("New object missing kNewBit: %" Px "\n", tags);
    }
    if (OldBit::decode(tags)) {
      FATAL1("New object has kOldBit: %" Px "\n", tags);
    }
    if (OldAndNotMarkedBit::decode(tags)) {
      FATAL1("New object has kOldAndNotMarkedBit: %" Px "\n", tags);
    }
    if (OldAndNotRememberedBit::decode(tags)) {
      FATAL1("New object has kOldAndNotRememberedBit: %" Px "\n", tags);
    }
  } else {
    if (NewBit::decode(tags)) {
      FATAL1("Old object has kNewBit: %" Px "\n", tags);
    }
    if (!OldBit::decode(tags)) {
      FATAL1("Old object missing kOldBit: %" Px "\n", tags);
    }
  }
  const intptr_t class_id = ClassIdTag::decode(tags);
  if (!isolate_group->shared_class_table()->IsValidIndex(class_id)) {
    FATAL1("Invalid class id encountered %" Pd "\n", class_id);
  }
  if (class_id == kNullCid &&
      isolate_group->shared_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)) {
    FATAL3(
        "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 kInstructionsTableCid: {
      const InstructionsTablePtr raw_instructions_table =
          static_cast<const InstructionsTablePtr>(this);
      intptr_t length = raw_instructions_table->untag()->length_;
      instance_size = InstructionsTable::InstanceSize(length);
      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 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;
    }
#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 kFfiPointerCid:
      instance_size = Pointer::InstanceSize();
      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();
      break;
    }
    case kForwardingCorpse: {
      uword addr = UntaggedObject::ToAddr(this);
      ForwardingCorpse* element = reinterpret_cast<ForwardingCorpse*>(addr);
      instance_size = element->HeapSize();
      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)
#if !defined(DART_PRECOMPILED_RUNTIME)
      auto reload_context = isolate_group->reload_context();
      const bool use_saved_class_table =
          reload_context != nullptr ? reload_context->UseSavedSizeTableForGC()
                                    : false;
#else
      const bool use_saved_class_table = false;
#endif

      auto class_table = isolate_group->shared_class_table();
      ASSERT(use_saved_class_table || class_table->SizeAt(class_id) > 0);
      if (!class_table->IsValidIndex(class_id) ||
          (!class_table->HasValidClassAt(class_id) && !use_saved_class_table)) {
        FATAL3("Invalid cid: %" Pd ", obj: %p, tags: %x. Corrupt heap?",
               class_id, this, static_cast<uint32_t>(tags));
      }
#endif  // DEBUG
      instance_size = isolate_group->GetClassSizeForHeapWalkAt(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)) {
    FATAL3("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:
#define RAW_VISITPOINTERS(clazz) case kTypedData##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;
    }
    case kFfiPointerCid: {
      PointerPtr raw_obj = static_cast<PointerPtr>(this);
      size = UntaggedPointer::VisitPointerPointers(raw_obj, visitor);
      break;
    }
    case kFfiDynamicLibraryCid: {
      DynamicLibraryPtr raw_obj = static_cast<DynamicLibraryPtr>(this);
      size =
          UntaggedDynamicLibrary::VisitDynamicLibraryPointers(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:
      FATAL3("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(IsolateGroup* isolate_group,
                                          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 = isolate_group->GetClassForHeapWalkAt(class_id)
                                ->untag()
                                ->host_next_field_offset_in_words_
                            << kWordSizeLog2;
  ASSERT(next_field_offset > 0);
  uword obj_addr = UntaggedObject::ToAddr(this);
  uword from = obj_addr + sizeof(UntaggedObject);
  uword to = obj_addr + next_field_offset - kWordSize;
  const auto first = reinterpret_cast<ObjectPtr*>(from);
  const auto last = reinterpret_cast<ObjectPtr*>(to);

#if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
  const auto unboxed_fields_bitmap =
      visitor->shared_class_table()->GetUnboxedFieldsMapAt(class_id);

  if (!unboxed_fields_bitmap.IsEmpty()) {
    intptr_t bit = sizeof(UntaggedObject) / kWordSize;
    for (ObjectPtr* current = first; current <= last; current++) {
      if (!unboxed_fields_bitmap.Get(bit++)) {
        visitor->VisitPointer(current);
      }
    }
  } else {
    visitor->VisitPointers(first, last);
  }
#else
  visitor->VisitPointers(first, last);
#endif  // defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
}

bool UntaggedObject::FindObject(FindObjectVisitor* visitor) {
  ASSERT(visitor != NULL);
  return visitor->FindObject(static_cast<ObjectPtr>(this));
}

// 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
// specializd 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)
COMPRESSED_VISITOR(Type)
COMPRESSED_VISITOR(FunctionType)
COMPRESSED_VISITOR(TypeRef)
COMPRESSED_VISITOR(TypeParameter)
COMPRESSED_VISITOR(Function)
REGULAR_VISITOR(Closure)
COMPRESSED_VISITOR(LibraryPrefix)
REGULAR_VISITOR(SingleTargetCache)
REGULAR_VISITOR(UnlinkedCall)
REGULAR_VISITOR(MonomorphicSmiableCall)
REGULAR_VISITOR(ICData)
REGULAR_VISITOR(MegamorphicCache)
COMPRESSED_VISITOR(ApiError)
COMPRESSED_VISITOR(LanguageError)
COMPRESSED_VISITOR(UnhandledException)
COMPRESSED_VISITOR(UnwindError)
COMPRESSED_VISITOR(ExternalOneByteString)
COMPRESSED_VISITOR(ExternalTwoByteString)
REGULAR_VISITOR(GrowableObjectArray)
REGULAR_VISITOR(LinkedHashMap)
COMPRESSED_VISITOR(ExternalTypedData)
TYPED_DATA_VIEW_VISITOR(TypedDataView)
COMPRESSED_VISITOR(ReceivePort)
COMPRESSED_VISITOR(StackTrace)
COMPRESSED_VISITOR(RegExp)
REGULAR_VISITOR(WeakProperty)
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_VISITOR(Context, raw_obj->untag()->num_variables_)
VARIABLE_VISITOR(Array, Smi::Value(raw_obj->untag()->length()))
VARIABLE_COMPRESSED_VISITOR(
    TypedData,
    TypedData::ElementSizeInBytes(raw_obj->GetClassId()) *
        Smi::Value(raw_obj->untag()->length()))
VARIABLE_COMPRESSED_VISITOR(ContextScope, raw_obj->untag()->num_variables_)
NULL_VISITOR(Sentinel)
VARIABLE_VISITOR(InstructionsTable, raw_obj->untag()->length_)
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(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();
}

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
}

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->isolate_group()->GetClassSizeForHeapWalkAt(
        raw_obj->GetClassId());
  }

  // 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 - kWordSize;
  visitor->VisitPointers(reinterpret_cast<ObjectPtr*>(from),
                         reinterpret_cast<ObjectPtr*>(to));
  return instance_size;
}

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

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

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

DEFINE_LEAF_RUNTIME_ENTRY(void,
                          RememberCard,
                          2,
                          uword /*ObjectPtr*/ object_in,
                          ObjectPtr* slot) {
  ObjectPtr object = static_cast<ObjectPtr>(object_in);
  ASSERT(object->IsOldObject());
  ASSERT(object->untag()->IsCardRemembered());
  OldPage::Of(object)->RememberCard(slot);
}
END_LEAF_RUNTIME_ENTRY

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
