// 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.

#ifndef V8_OBJECTS_VISITING_INL_H_
#define V8_OBJECTS_VISITING_INL_H_

#include "src/heap/array-buffer-tracker.h"
#include "src/heap/mark-compact.h"
#include "src/heap/objects-visiting.h"
#include "src/ic/ic-state.h"
#include "src/macro-assembler.h"
#include "src/objects-body-descriptors-inl.h"

namespace v8 {
namespace internal {


template <typename Callback>
Callback VisitorDispatchTable<Callback>::GetVisitor(Map* map) {
  return reinterpret_cast<Callback>(callbacks_[map->visitor_id()]);
}


template <typename StaticVisitor>
void StaticNewSpaceVisitor<StaticVisitor>::Initialize() {
  table_.Register(
      kVisitShortcutCandidate,
      &FixedBodyVisitor<StaticVisitor, ConsString::BodyDescriptor, int>::Visit);

  table_.Register(
      kVisitConsString,
      &FixedBodyVisitor<StaticVisitor, ConsString::BodyDescriptor, int>::Visit);

  table_.Register(
      kVisitThinString,
      &FixedBodyVisitor<StaticVisitor, ThinString::BodyDescriptor, int>::Visit);

  table_.Register(kVisitSlicedString,
                  &FixedBodyVisitor<StaticVisitor, SlicedString::BodyDescriptor,
                                    int>::Visit);

  table_.Register(
      kVisitSymbol,
      &FixedBodyVisitor<StaticVisitor, Symbol::BodyDescriptor, int>::Visit);

  table_.Register(kVisitFixedArray,
                  &FlexibleBodyVisitor<StaticVisitor,
                                       FixedArray::BodyDescriptor, int>::Visit);

  table_.Register(kVisitFixedDoubleArray, &VisitFixedDoubleArray);
  table_.Register(
      kVisitFixedTypedArrayBase,
      &FlexibleBodyVisitor<StaticVisitor, FixedTypedArrayBase::BodyDescriptor,
                           int>::Visit);

  table_.Register(
      kVisitFixedFloat64Array,
      &FlexibleBodyVisitor<StaticVisitor, FixedTypedArrayBase::BodyDescriptor,
                           int>::Visit);

  table_.Register(
      kVisitNativeContext,
      &FixedBodyVisitor<StaticVisitor, Context::ScavengeBodyDescriptor,
                        int>::Visit);

  table_.Register(kVisitByteArray, &VisitByteArray);

  table_.Register(
      kVisitSharedFunctionInfo,
      &FixedBodyVisitor<StaticVisitor, SharedFunctionInfo::BodyDescriptor,
                        int>::Visit);

  table_.Register(kVisitSeqOneByteString, &VisitSeqOneByteString);

  table_.Register(kVisitSeqTwoByteString, &VisitSeqTwoByteString);

  // Don't visit code entry. We are using this visitor only during scavenges.
  table_.Register(
      kVisitJSFunction,
      &FlexibleBodyVisitor<StaticVisitor, JSFunction::BodyDescriptorWeakCode,
                           int>::Visit);

  table_.Register(
      kVisitJSArrayBuffer,
      &FlexibleBodyVisitor<StaticVisitor, JSArrayBuffer::BodyDescriptor,
                           int>::Visit);

  table_.Register(kVisitFreeSpace, &VisitFreeSpace);

  table_.Register(
      kVisitJSWeakCollection,
      &FlexibleBodyVisitor<StaticVisitor, JSWeakCollection::BodyDescriptor,
                           int>::Visit);

  table_.Register(
      kVisitSmallOrderedHashSet,
      &FlexibleBodyVisitor<StaticVisitor, SmallOrderedHashSet::BodyDescriptor,
                           int>::Visit);

  table_.Register(kVisitJSRegExp, &JSObjectVisitor::Visit);

  table_.Register(kVisitDataObject, &DataObjectVisitor::Visit);

  table_.Register(kVisitJSObjectFast, &JSObjectFastVisitor::Visit);
  table_.Register(kVisitJSObject, &JSObjectVisitor::Visit);

  // Not using specialized Api object visitor for newspace.
  table_.Register(kVisitJSApiObject, &JSObjectVisitor::Visit);

  table_.Register(kVisitStruct, &StructVisitor::Visit);

  table_.Register(kVisitBytecodeArray, &UnreachableVisitor);
  table_.Register(kVisitSharedFunctionInfo, &UnreachableVisitor);
}

template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::Initialize() {
  table_.Register(kVisitShortcutCandidate,
                  &FixedBodyVisitor<StaticVisitor, ConsString::BodyDescriptor,
                                    void>::Visit);

  table_.Register(kVisitConsString,
                  &FixedBodyVisitor<StaticVisitor, ConsString::BodyDescriptor,
                                    void>::Visit);

  table_.Register(kVisitThinString,
                  &FixedBodyVisitor<StaticVisitor, ThinString::BodyDescriptor,
                                    void>::Visit);

  table_.Register(kVisitSlicedString,
                  &FixedBodyVisitor<StaticVisitor, SlicedString::BodyDescriptor,
                                    void>::Visit);

  table_.Register(
      kVisitSymbol,
      &FixedBodyVisitor<StaticVisitor, Symbol::BodyDescriptor, void>::Visit);

  table_.Register(kVisitFixedArray, &FixedArrayVisitor::Visit);

  table_.Register(kVisitFixedDoubleArray, &DataObjectVisitor::Visit);

  table_.Register(
      kVisitFixedTypedArrayBase,
      &FlexibleBodyVisitor<StaticVisitor, FixedTypedArrayBase::BodyDescriptor,
                           void>::Visit);

  table_.Register(
      kVisitFixedFloat64Array,
      &FlexibleBodyVisitor<StaticVisitor, FixedTypedArrayBase::BodyDescriptor,
                           void>::Visit);

  table_.Register(kVisitNativeContext, &VisitNativeContext);

  table_.Register(
      kVisitAllocationSite,
      &FixedBodyVisitor<StaticVisitor, AllocationSite::MarkingBodyDescriptor,
                        void>::Visit);

  table_.Register(kVisitByteArray, &DataObjectVisitor::Visit);

  table_.Register(kVisitBytecodeArray, &VisitBytecodeArray);

  table_.Register(kVisitFreeSpace, &DataObjectVisitor::Visit);

  table_.Register(kVisitSeqOneByteString, &DataObjectVisitor::Visit);

  table_.Register(kVisitSeqTwoByteString, &DataObjectVisitor::Visit);

  table_.Register(kVisitJSWeakCollection, &VisitWeakCollection);

  table_.Register(
      kVisitOddball,
      &FixedBodyVisitor<StaticVisitor, Oddball::BodyDescriptor, void>::Visit);

  table_.Register(kVisitMap, &VisitMap);

  table_.Register(kVisitCode, &VisitCode);

  table_.Register(kVisitSharedFunctionInfo, &VisitSharedFunctionInfo);

  table_.Register(kVisitJSFunction, &VisitJSFunction);

  table_.Register(
      kVisitJSArrayBuffer,
      &FlexibleBodyVisitor<StaticVisitor, JSArrayBuffer::BodyDescriptor,
                           void>::Visit);

  table_.Register(kVisitJSRegExp, &JSObjectVisitor::Visit);

  table_.Register(
      kVisitCell,
      &FixedBodyVisitor<StaticVisitor, Cell::BodyDescriptor, void>::Visit);

  table_.Register(kVisitPropertyCell,
                  &FixedBodyVisitor<StaticVisitor, PropertyCell::BodyDescriptor,
                                    void>::Visit);

  table_.Register(
      kVisitSmallOrderedHashSet,
      &FlexibleBodyVisitor<StaticVisitor, SmallOrderedHashSet::BodyDescriptor,
                           void>::Visit);

  table_.Register(kVisitWeakCell, &VisitWeakCell);

  table_.Register(kVisitTransitionArray, &VisitTransitionArray);

  table_.Register(kVisitDataObject, &DataObjectVisitor::Visit);

  table_.Register(kVisitJSObjectFast, &JSObjectFastVisitor::Visit);
  table_.Register(kVisitJSObject, &JSObjectVisitor::Visit);

  table_.Register(kVisitJSApiObject, &JSApiObjectVisitor::Visit);

  table_.Register(kVisitStruct, &StructObjectVisitor::Visit);
}


template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitCodeEntry(
    Heap* heap, HeapObject* object, Address entry_address) {
  Code* code = Code::cast(Code::GetObjectFromEntryAddress(entry_address));
  heap->mark_compact_collector()->RecordCodeEntrySlot(object, entry_address,
                                                      code);
  StaticVisitor::MarkObject(heap, code);
}


template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitEmbeddedPointer(
    Heap* heap, RelocInfo* rinfo) {
  DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
  HeapObject* object = HeapObject::cast(rinfo->target_object());
  Code* host = rinfo->host();
  heap->mark_compact_collector()->RecordRelocSlot(host, rinfo, object);
  // TODO(ulan): It could be better to record slots only for strongly embedded
  // objects here and record slots for weakly embedded object during clearing
  // of non-live references in mark-compact.
  if (!host->IsWeakObject(object)) {
    StaticVisitor::MarkObject(heap, object);
  }
}


template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitCell(Heap* heap,
                                                    RelocInfo* rinfo) {
  DCHECK(rinfo->rmode() == RelocInfo::CELL);
  Cell* cell = rinfo->target_cell();
  Code* host = rinfo->host();
  heap->mark_compact_collector()->RecordRelocSlot(host, rinfo, cell);
  if (!host->IsWeakObject(cell)) {
    StaticVisitor::MarkObject(heap, cell);
  }
}


template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitDebugTarget(Heap* heap,
                                                           RelocInfo* rinfo) {
  DCHECK(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
         rinfo->IsPatchedDebugBreakSlotSequence());
  Code* target = Code::GetCodeFromTargetAddress(rinfo->debug_call_address());
  Code* host = rinfo->host();
  heap->mark_compact_collector()->RecordRelocSlot(host, rinfo, target);
  StaticVisitor::MarkObject(heap, target);
}


template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget(Heap* heap,
                                                          RelocInfo* rinfo) {
  DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode()));
  Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
  Code* host = rinfo->host();
  heap->mark_compact_collector()->RecordRelocSlot(host, rinfo, target);
  StaticVisitor::MarkObject(heap, target);
}

template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitCodeAgeSequence(
    Heap* heap, RelocInfo* rinfo) {
  DCHECK(RelocInfo::IsCodeAgeSequence(rinfo->rmode()));
  Code* target = rinfo->code_age_stub();
  DCHECK(target != NULL);
  Code* host = rinfo->host();
  heap->mark_compact_collector()->RecordRelocSlot(host, rinfo, target);
  StaticVisitor::MarkObject(heap, target);
}

template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitBytecodeArray(
    Map* map, HeapObject* object) {
  FixedBodyVisitor<StaticVisitor, BytecodeArray::MarkingBodyDescriptor,
                   void>::Visit(map, object);
  BytecodeArray::cast(object)->MakeOlder();
}

template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitNativeContext(
    Map* map, HeapObject* object) {
  FixedBodyVisitor<StaticVisitor, Context::MarkCompactBodyDescriptor,
                   void>::Visit(map, object);
}


template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitMap(Map* map,
                                                   HeapObject* object) {
  Heap* heap = map->GetHeap();
  Map* map_object = Map::cast(object);

  // Clears the cache of ICs related to this map.
  if (FLAG_cleanup_code_caches_at_gc) {
    map_object->ClearCodeCache(heap);
  }

  // When map collection is enabled we have to mark through map's transitions
  // and back pointers in a special way to make these links weak.
  if (map_object->CanTransition()) {
    MarkMapContents(heap, map_object);
  } else {
    StaticVisitor::VisitPointers(
        heap, object,
        HeapObject::RawField(object, Map::kPointerFieldsBeginOffset),
        HeapObject::RawField(object, Map::kPointerFieldsEndOffset));
  }
}

template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitWeakCell(Map* map,
                                                        HeapObject* object) {
  Heap* heap = map->GetHeap();
  WeakCell* weak_cell = reinterpret_cast<WeakCell*>(object);
  // Enqueue weak cell in linked list of encountered weak collections.
  // We can ignore weak cells with cleared values because they will always
  // contain smi zero.
  if (weak_cell->next_cleared() && !weak_cell->cleared()) {
    HeapObject* value = HeapObject::cast(weak_cell->value());
    if (ObjectMarking::IsBlackOrGrey(value, MarkingState::Internal(value))) {
      // Weak cells with live values are directly processed here to reduce
      // the processing time of weak cells during the main GC pause.
      Object** slot = HeapObject::RawField(weak_cell, WeakCell::kValueOffset);
      map->GetHeap()->mark_compact_collector()->RecordSlot(weak_cell, slot,
                                                           *slot);
    } else {
      // If we do not know about liveness of values of weak cells, we have to
      // process them when we know the liveness of the whole transitive
      // closure.
      weak_cell->set_next(heap->encountered_weak_cells(),
                          UPDATE_WEAK_WRITE_BARRIER);
      heap->set_encountered_weak_cells(weak_cell);
    }
  }
}


template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitTransitionArray(
    Map* map, HeapObject* object) {
  TransitionArray* array = TransitionArray::cast(object);
  Heap* heap = array->GetHeap();
  // Visit strong references.
  if (array->HasPrototypeTransitions()) {
    StaticVisitor::VisitPointer(heap, array,
                                array->GetPrototypeTransitionsSlot());
  }
  int num_transitions = TransitionArray::NumberOfTransitions(array);
  for (int i = 0; i < num_transitions; ++i) {
    StaticVisitor::VisitPointer(heap, array, array->GetKeySlot(i));
  }
  // Enqueue the array in linked list of encountered transition arrays if it is
  // not already in the list.
  if (array->next_link()->IsUndefined(heap->isolate())) {
    Heap* heap = map->GetHeap();
    array->set_next_link(heap->encountered_transition_arrays(),
                         UPDATE_WEAK_WRITE_BARRIER);
    heap->set_encountered_transition_arrays(array);
  }
}

template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitWeakCollection(
    Map* map, HeapObject* object) {
  typedef FlexibleBodyVisitor<StaticVisitor,
                              JSWeakCollection::BodyDescriptorWeak,
                              void> JSWeakCollectionBodyVisitor;
  Heap* heap = map->GetHeap();
  JSWeakCollection* weak_collection =
      reinterpret_cast<JSWeakCollection*>(object);

  // Enqueue weak collection in linked list of encountered weak collections.
  if (weak_collection->next() == heap->undefined_value()) {
    weak_collection->set_next(heap->encountered_weak_collections());
    heap->set_encountered_weak_collections(weak_collection);
  }

  // Skip visiting the backing hash table containing the mappings and the
  // pointer to the other enqueued weak collections, both are post-processed.
  JSWeakCollectionBodyVisitor::Visit(map, object);

  // Partially initialized weak collection is enqueued, but table is ignored.
  if (!weak_collection->table()->IsHashTable()) return;

  // Mark the backing hash table without pushing it on the marking stack.
  Object** slot = HeapObject::RawField(object, JSWeakCollection::kTableOffset);
  HeapObject* obj = HeapObject::cast(*slot);
  heap->mark_compact_collector()->RecordSlot(object, slot, obj);
  StaticVisitor::MarkObjectWithoutPush(heap, obj);
}


template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitCode(Map* map,
                                                    HeapObject* object) {
  typedef FlexibleBodyVisitor<StaticVisitor, Code::BodyDescriptor, void>
      CodeBodyVisitor;
  Heap* heap = map->GetHeap();
  Code* code = Code::cast(object);
  if (FLAG_age_code && !heap->isolate()->serializer_enabled()) {
    code->MakeOlder();
  }
  CodeBodyVisitor::Visit(map, object);
}


template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitSharedFunctionInfo(
    Map* map, HeapObject* object) {
  Heap* heap = map->GetHeap();
  SharedFunctionInfo* shared = SharedFunctionInfo::cast(object);
  if (shared->ic_age() != heap->global_ic_age()) {
    shared->ResetForNewContext(heap->global_ic_age());
  }
  FixedBodyVisitor<StaticVisitor, SharedFunctionInfo::BodyDescriptor,
                   void>::Visit(map, object);
}


template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::VisitJSFunction(Map* map,
                                                          HeapObject* object) {
  FlexibleBodyVisitor<StaticVisitor, JSFunction::BodyDescriptorStrongCode,
                      void>::Visit(map, object);
}

template <typename StaticVisitor>
void StaticMarkingVisitor<StaticVisitor>::MarkMapContents(Heap* heap,
                                                          Map* map) {
  // Since descriptor arrays are potentially shared, ensure that only the
  // descriptors that belong to this map are marked. The first time a non-empty
  // descriptor array is marked, its header is also visited. The slot holding
  // the descriptor array will be implicitly recorded when the pointer fields of
  // this map are visited.  Prototype maps don't keep track of transitions, so
  // just mark the entire descriptor array.
  if (!map->is_prototype_map()) {
    DescriptorArray* descriptors = map->instance_descriptors();
    if (StaticVisitor::MarkObjectWithoutPush(heap, descriptors) &&
        descriptors->length() > 0) {
      StaticVisitor::VisitPointers(heap, descriptors,
                                   descriptors->GetFirstElementAddress(),
                                   descriptors->GetDescriptorEndSlot(0));
    }
    int start = 0;
    int end = map->NumberOfOwnDescriptors();
    if (start < end) {
      StaticVisitor::VisitPointers(heap, descriptors,
                                   descriptors->GetDescriptorStartSlot(start),
                                   descriptors->GetDescriptorEndSlot(end));
    }
  }

  // Mark the pointer fields of the Map. Since the transitions array has
  // been marked already, it is fine that one of these fields contains a
  // pointer to it.
  StaticVisitor::VisitPointers(
      heap, map, HeapObject::RawField(map, Map::kPointerFieldsBeginOffset),
      HeapObject::RawField(map, Map::kPointerFieldsEndOffset));
}


inline static bool HasSourceCode(Heap* heap, SharedFunctionInfo* info) {
  Object* undefined = heap->undefined_value();
  return (info->script() != undefined) &&
         (reinterpret_cast<Script*>(info->script())->source() != undefined);
}

template <typename ResultType, typename ConcreteVisitor>
ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit(HeapObject* object) {
  Map* map = object->map();
  ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
  switch (static_cast<VisitorId>(map->visitor_id())) {
#define CASE(type)   \
  case kVisit##type: \
    return visitor->Visit##type(map, type::cast(object));
    TYPED_VISITOR_ID_LIST(CASE)
#undef CASE
    case kVisitShortcutCandidate:
      return visitor->VisitShortcutCandidate(map, ConsString::cast(object));
    case kVisitNativeContext:
      return visitor->VisitNativeContext(map, Context::cast(object));
    case kVisitDataObject:
      return visitor->VisitDataObject(map, HeapObject::cast(object));
    case kVisitJSObjectFast:
      return visitor->VisitJSObjectFast(map, JSObject::cast(object));
    case kVisitJSApiObject:
      return visitor->VisitJSApiObject(map, JSObject::cast(object));
    case kVisitStruct:
      return visitor->VisitStruct(map, HeapObject::cast(object));
    case kVisitFreeSpace:
      return visitor->VisitFreeSpace(map, FreeSpace::cast(object));
    case kVisitorIdCount:
      UNREACHABLE();
  }
  UNREACHABLE();
  // Make the compiler happy.
  return ResultType();
}

template <typename ResultType, typename ConcreteVisitor>
void HeapVisitor<ResultType, ConcreteVisitor>::VisitMapPointer(
    HeapObject* host, HeapObject** map) {
  static_cast<ConcreteVisitor*>(this)->VisitPointer(
      host, reinterpret_cast<Object**>(map));
}

template <typename ResultType, typename ConcreteVisitor>
bool HeapVisitor<ResultType, ConcreteVisitor>::ShouldVisit(HeapObject* object) {
  return true;
}

#define VISIT(type)                                                 \
  template <typename ResultType, typename ConcreteVisitor>          \
  ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit##type( \
      Map* map, type* object) {                                     \
    ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this); \
    if (!visitor->ShouldVisit(object)) return ResultType();         \
    int size = type::BodyDescriptor::SizeOf(map, object);           \
    visitor->VisitMapPointer(object, object->map_slot());           \
    type::BodyDescriptor::IterateBody(object, size, visitor);       \
    return static_cast<ResultType>(size);                           \
  }
TYPED_VISITOR_ID_LIST(VISIT)
#undef VISIT

template <typename ResultType, typename ConcreteVisitor>
ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitShortcutCandidate(
    Map* map, ConsString* object) {
  ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
  if (!visitor->ShouldVisit(object)) return ResultType();
  int size = ConsString::BodyDescriptor::SizeOf(map, object);
  visitor->VisitMapPointer(object, object->map_slot());
  ConsString::BodyDescriptor::IterateBody(object, size,
                                          static_cast<ConcreteVisitor*>(this));
  return static_cast<ResultType>(size);
}

template <typename ResultType, typename ConcreteVisitor>
ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitNativeContext(
    Map* map, Context* object) {
  ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
  if (!visitor->ShouldVisit(object)) return ResultType();
  int size = Context::BodyDescriptor::SizeOf(map, object);
  visitor->VisitMapPointer(object, object->map_slot());
  Context::BodyDescriptor::IterateBody(object, size,
                                       static_cast<ConcreteVisitor*>(this));
  return static_cast<ResultType>(size);
}

template <typename ResultType, typename ConcreteVisitor>
ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitDataObject(
    Map* map, HeapObject* object) {
  ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
  if (!visitor->ShouldVisit(object)) return ResultType();
  int size = map->instance_size();
  visitor->VisitMapPointer(object, object->map_slot());
  return static_cast<ResultType>(size);
}

template <typename ResultType, typename ConcreteVisitor>
ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitJSObjectFast(
    Map* map, JSObject* object) {
  ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
  if (!visitor->ShouldVisit(object)) return ResultType();
  int size = JSObject::FastBodyDescriptor::SizeOf(map, object);
  visitor->VisitMapPointer(object, object->map_slot());
  JSObject::FastBodyDescriptor::IterateBody(
      object, size, static_cast<ConcreteVisitor*>(this));
  return static_cast<ResultType>(size);
}
template <typename ResultType, typename ConcreteVisitor>
ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitJSApiObject(
    Map* map, JSObject* object) {
  ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
  if (!visitor->ShouldVisit(object)) return ResultType();
  int size = JSObject::BodyDescriptor::SizeOf(map, object);
  visitor->VisitMapPointer(object, object->map_slot());
  JSObject::BodyDescriptor::IterateBody(object, size,
                                        static_cast<ConcreteVisitor*>(this));
  return static_cast<ResultType>(size);
}
template <typename ResultType, typename ConcreteVisitor>
ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitStruct(
    Map* map, HeapObject* object) {
  ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
  if (!visitor->ShouldVisit(object)) return ResultType();
  int size = map->instance_size();
  visitor->VisitMapPointer(object, object->map_slot());
  StructBodyDescriptor::IterateBody(object, size,
                                    static_cast<ConcreteVisitor*>(this));
  return static_cast<ResultType>(size);
}
template <typename ResultType, typename ConcreteVisitor>
ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitFreeSpace(
    Map* map, FreeSpace* object) {
  ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
  if (!visitor->ShouldVisit(object)) return ResultType();
  visitor->VisitMapPointer(object, object->map_slot());
  return static_cast<ResultType>(FreeSpace::cast(object)->size());
}

}  // namespace internal
}  // namespace v8

#endif  // V8_OBJECTS_VISITING_INL_H_
