[heap] Remove StaticVisitorBase; Introduce Map::GetVisitorId

Bug: chromium:738368
Change-Id: I749517391f9d5dd0827f3d37f975f6c61542d1ff
Reviewed-on: https://chromium-review.googlesource.com/558914
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46391}
This commit is contained in:
Michael Lippautz 2017-07-03 16:11:30 +02:00 committed by Commit Bot
parent 72b5d5c00c
commit 9cb2211cb2
10 changed files with 288 additions and 313 deletions

View File

@ -2187,29 +2187,28 @@ AllocationResult Heap::AllocatePartialMap(InstanceType instance_type,
AllocationResult allocation = AllocateRaw(Map::kSize, MAP_SPACE);
if (!allocation.To(&result)) return allocation;
// Map::cast cannot be used due to uninitialized map field.
reinterpret_cast<Map*>(result)->set_map_after_allocation(
reinterpret_cast<Map*>(root(kMetaMapRootIndex)), SKIP_WRITE_BARRIER);
reinterpret_cast<Map*>(result)->set_instance_type(instance_type);
reinterpret_cast<Map*>(result)->set_instance_size(instance_size);
Map* map = reinterpret_cast<Map*>(result);
map->set_map_after_allocation(reinterpret_cast<Map*>(root(kMetaMapRootIndex)),
SKIP_WRITE_BARRIER);
map->set_instance_type(instance_type);
map->set_instance_size(instance_size);
// Initialize to only containing tagged fields.
reinterpret_cast<Map*>(result)->set_visitor_id(
StaticVisitorBase::GetVisitorId(instance_type, instance_size, false));
if (FLAG_unbox_double_fields) {
reinterpret_cast<Map*>(result)
->set_layout_descriptor(LayoutDescriptor::FastPointerLayout());
map->set_layout_descriptor(LayoutDescriptor::FastPointerLayout());
}
reinterpret_cast<Map*>(result)->clear_unused();
reinterpret_cast<Map*>(result)
->set_inobject_properties_or_constructor_function_index(0);
reinterpret_cast<Map*>(result)->set_unused_property_fields(0);
reinterpret_cast<Map*>(result)->set_bit_field(0);
reinterpret_cast<Map*>(result)->set_bit_field2(0);
// GetVisitorId requires a properly initialized LayoutDescriptor.
map->set_visitor_id(Map::GetVisitorId(map));
map->clear_unused();
map->set_inobject_properties_or_constructor_function_index(0);
map->set_unused_property_fields(0);
map->set_bit_field(0);
map->set_bit_field2(0);
int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) |
Map::OwnsDescriptors::encode(true) |
Map::ConstructionCounter::encode(Map::kNoSlackTracking);
reinterpret_cast<Map*>(result)->set_bit_field3(bit_field3);
reinterpret_cast<Map*>(result)->set_weak_cell_cache(Smi::kZero);
return result;
map->set_bit_field3(bit_field3);
map->set_weak_cell_cache(Smi::kZero);
return map;
}
@ -2241,7 +2240,7 @@ AllocationResult Heap::AllocateMap(InstanceType instance_type,
}
// Must be called only after |instance_type|, |instance_size| and
// |layout_descriptor| are set.
map->set_visitor_id(Heap::GetStaticVisitorIdForMap(map));
map->set_visitor_id(Map::GetVisitorId(map));
map->set_bit_field(0);
map->set_bit_field2(1 << Map::kIsExtensible);
int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) |
@ -6692,12 +6691,6 @@ bool Heap::GetObjectTypeName(size_t index, const char** object_type,
return false;
}
// static
int Heap::GetStaticVisitorIdForMap(Map* map) {
return StaticVisitorBase::GetVisitorId(map);
}
const char* AllocationSpaceName(AllocationSpace space) {
switch (space) {
case NEW_SPACE:

View File

@ -728,10 +728,6 @@ class Heap {
// by pointer size.
static inline void CopyBlock(Address dst, Address src, int byte_size);
// Determines a static visitor id based on the given {map} that can then be
// stored on the map to facilitate fast dispatch for {StaticVisitorBase}.
static int GetStaticVisitorIdForMap(Map* map);
// Notifies the heap that is ok to start marking or other activities that
// should not happen during deserialization.
void NotifyDeserializationComplete();

View File

@ -17,205 +17,6 @@
namespace v8 {
namespace internal {
VisitorId StaticVisitorBase::GetVisitorId(Map* map) {
return GetVisitorId(map->instance_type(), map->instance_size(),
FLAG_unbox_double_fields && !map->HasFastPointerLayout());
}
VisitorId StaticVisitorBase::GetVisitorId(int instance_type, int instance_size,
bool has_unboxed_fields) {
if (instance_type < FIRST_NONSTRING_TYPE) {
switch (instance_type & kStringRepresentationMask) {
case kSeqStringTag:
if ((instance_type & kStringEncodingMask) == kOneByteStringTag) {
return kVisitSeqOneByteString;
} else {
return kVisitSeqTwoByteString;
}
case kConsStringTag:
if (IsShortcutCandidate(instance_type)) {
return kVisitShortcutCandidate;
} else {
return kVisitConsString;
}
case kSlicedStringTag:
return kVisitSlicedString;
case kExternalStringTag:
return kVisitDataObject;
case kThinStringTag:
return kVisitThinString;
}
UNREACHABLE();
}
switch (instance_type) {
case BYTE_ARRAY_TYPE:
return kVisitByteArray;
case BYTECODE_ARRAY_TYPE:
return kVisitBytecodeArray;
case FREE_SPACE_TYPE:
return kVisitFreeSpace;
case FIXED_ARRAY_TYPE:
return kVisitFixedArray;
case FIXED_DOUBLE_ARRAY_TYPE:
return kVisitFixedDoubleArray;
case ODDBALL_TYPE:
return kVisitOddball;
case MAP_TYPE:
return kVisitMap;
case CODE_TYPE:
return kVisitCode;
case CELL_TYPE:
return kVisitCell;
case PROPERTY_CELL_TYPE:
return kVisitPropertyCell;
case WEAK_CELL_TYPE:
return kVisitWeakCell;
case TRANSITION_ARRAY_TYPE:
return kVisitTransitionArray;
case JS_WEAK_MAP_TYPE:
case JS_WEAK_SET_TYPE:
return kVisitJSWeakCollection;
case JS_REGEXP_TYPE:
return kVisitJSRegExp;
case SHARED_FUNCTION_INFO_TYPE:
return kVisitSharedFunctionInfo;
case JS_PROXY_TYPE:
return kVisitStruct;
case SYMBOL_TYPE:
return kVisitSymbol;
case JS_ARRAY_BUFFER_TYPE:
return kVisitJSArrayBuffer;
case SMALL_ORDERED_HASH_MAP_TYPE:
return kVisitSmallOrderedHashMap;
case SMALL_ORDERED_HASH_SET_TYPE:
return kVisitSmallOrderedHashSet;
case JS_OBJECT_TYPE:
case JS_ERROR_TYPE:
case JS_ARGUMENTS_TYPE:
case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
case JS_GENERATOR_OBJECT_TYPE:
case JS_ASYNC_GENERATOR_OBJECT_TYPE:
case JS_MODULE_NAMESPACE_TYPE:
case JS_VALUE_TYPE:
case JS_DATE_TYPE:
case JS_ARRAY_TYPE:
case JS_GLOBAL_PROXY_TYPE:
case JS_GLOBAL_OBJECT_TYPE:
case JS_MESSAGE_OBJECT_TYPE:
case JS_TYPED_ARRAY_TYPE:
case JS_DATA_VIEW_TYPE:
case JS_SET_TYPE:
case JS_MAP_TYPE:
case JS_SET_ITERATOR_TYPE:
case JS_MAP_ITERATOR_TYPE:
case JS_STRING_ITERATOR_TYPE:
case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE:
case JS_PROMISE_CAPABILITY_TYPE:
case JS_PROMISE_TYPE:
case JS_BOUND_FUNCTION_TYPE:
return has_unboxed_fields ? kVisitJSObject : kVisitJSObjectFast;
case JS_API_OBJECT_TYPE:
case JS_SPECIAL_API_OBJECT_TYPE:
return kVisitJSApiObject;
case JS_FUNCTION_TYPE:
return kVisitJSFunction;
case FILLER_TYPE:
case FOREIGN_TYPE:
case HEAP_NUMBER_TYPE:
case MUTABLE_HEAP_NUMBER_TYPE:
return kVisitDataObject;
case FIXED_UINT8_ARRAY_TYPE:
case FIXED_INT8_ARRAY_TYPE:
case FIXED_UINT16_ARRAY_TYPE:
case FIXED_INT16_ARRAY_TYPE:
case FIXED_UINT32_ARRAY_TYPE:
case FIXED_INT32_ARRAY_TYPE:
case FIXED_FLOAT32_ARRAY_TYPE:
case FIXED_UINT8_CLAMPED_ARRAY_TYPE:
return kVisitFixedTypedArrayBase;
case FIXED_FLOAT64_ARRAY_TYPE:
return kVisitFixedFloat64Array;
#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE:
STRUCT_LIST(MAKE_STRUCT_CASE)
#undef MAKE_STRUCT_CASE
if (instance_type == ALLOCATION_SITE_TYPE) {
return kVisitAllocationSite;
}
return kVisitStruct;
default:
UNREACHABLE();
}
}
template <typename ResultType, typename ConcreteVisitor>
ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit(HeapObject* object) {
return Visit(object->map(), object);

View File

@ -14,74 +14,6 @@
namespace v8 {
namespace internal {
#define VISITOR_ID_LIST(V) \
V(AllocationSite) \
V(ByteArray) \
V(BytecodeArray) \
V(Cell) \
V(Code) \
V(ConsString) \
V(DataObject) \
V(FixedArray) \
V(FixedDoubleArray) \
V(FixedFloat64Array) \
V(FixedTypedArrayBase) \
V(FreeSpace) \
V(JSApiObject) \
V(JSArrayBuffer) \
V(JSFunction) \
V(JSObject) \
V(JSObjectFast) \
V(JSRegExp) \
V(JSWeakCollection) \
V(Map) \
V(NativeContext) \
V(Oddball) \
V(PropertyCell) \
V(SeqOneByteString) \
V(SeqTwoByteString) \
V(SharedFunctionInfo) \
V(ShortcutCandidate) \
V(SlicedString) \
V(SmallOrderedHashMap) \
V(SmallOrderedHashSet) \
V(Struct) \
V(Symbol) \
V(ThinString) \
V(TransitionArray) \
V(WeakCell)
// For data objects, JS objects and structs along with generic visitor which
// can visit object of any size we provide visitors specialized by
// object size in words.
// Ids of specialized visitors are declared in a linear order (without
// holes) starting from the id of visitor specialized for 2 words objects
// (base visitor id) and ending with the id of generic visitor.
// Method GetVisitorIdForSize depends on this ordering to calculate visitor
// id of specialized visitor from given instance size, base visitor id and
// generic visitor's id.
enum VisitorId {
#define VISITOR_ID_ENUM_DECL(id) kVisit##id,
VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL)
#undef VISITOR_ID_ENUM_DECL
kVisitorIdCount
};
// Base class for all static visitors.
class StaticVisitorBase : public AllStatic {
public:
// Visitor ID should fit in one byte.
STATIC_ASSERT(kVisitorIdCount <= 256);
// Determine which specialized visitor should be used for given instance type
// and instance type.
static inline VisitorId GetVisitorId(int instance_type, int instance_size,
bool has_unboxed_fields);
// Determine which specialized visitor should be used for given map.
static inline VisitorId GetVisitorId(Map* map);
};
#define TYPED_VISITOR_ID_LIST(V) \
V(AllocationSite) \
V(ByteArray) \
@ -112,10 +44,9 @@ class StaticVisitorBase : public AllStatic {
V(TransitionArray) \
V(WeakCell)
// The base class for visitors that need to dispatch on object type. It is
// similar to StaticVisitor except it uses virtual dispatch instead of static
// dispatch table. The default behavior of all visit functions is to iterate
// body of the given object using the BodyDescriptor of the object.
// The base class for visitors that need to dispatch on object type. The default
// behavior of all visit functions is to iterate body of the given object using
// the BodyDescriptor of the object.
//
// The visit functions return the size of the object cast to ResultType.
//
@ -124,8 +55,6 @@ class StaticVisitorBase : public AllStatic {
// class SomeVisitor : public HeapVisitor<ResultType, SomeVisitor> {
// ...
// }
//
// TODO(ulan): replace static visitors with the HeapVisitor.
template <typename ResultType, typename ConcreteVisitor>
class HeapVisitor : public ObjectVisitor {
public:

View File

@ -6,11 +6,15 @@
#define V8_HEAP_SCAVENGER_INL_H_
#include "src/heap/scavenger.h"
#include "src/objects/map.h"
namespace v8 {
namespace internal {
bool Scavenger::ContainsOnlyData(VisitorId visitor_id) {
namespace {
// White list for objects that for sure only contain data.
bool ContainsOnlyData(VisitorId visitor_id) {
switch (visitor_id) {
case kVisitSeqOneByteString:
return true;
@ -28,6 +32,8 @@ bool Scavenger::ContainsOnlyData(VisitorId visitor_id) {
return false;
}
} // namespace
// Helper function used by CopyObject to copy a source object to an
// allocated target object and update the forwarding pointer in the source
// object. Returns the target object.

View File

@ -32,9 +32,6 @@ class Scavenger {
inline Heap* heap() { return heap_; }
private:
// White list for objects that for sure only contain data.
V8_INLINE static bool ContainsOnlyData(VisitorId visitor_id);
V8_INLINE HeapObject* MigrateObject(HeapObject* source, HeapObject* target,
int size);

View File

@ -425,7 +425,7 @@ void Map::DictionaryMapVerify() {
CHECK(is_dictionary_map());
CHECK(instance_descriptors()->IsEmpty());
CHECK_EQ(0, unused_property_fields());
CHECK_EQ(Heap::GetStaticVisitorIdForMap(this), visitor_id());
CHECK_EQ(Map::GetVisitorId(this), visitor_id());
}

View File

@ -4273,11 +4273,11 @@ void Map::UpdateDescriptors(DescriptorArray* descriptors,
// TODO(ishell): remove these checks from VERIFY_HEAP mode.
if (FLAG_verify_heap) {
CHECK(layout_descriptor()->IsConsistentWithMap(this));
CHECK(visitor_id() == Heap::GetStaticVisitorIdForMap(this));
CHECK(visitor_id() == Map::GetVisitorId(this));
}
#else
SLOW_DCHECK(layout_descriptor()->IsConsistentWithMap(this));
DCHECK(visitor_id() == Heap::GetStaticVisitorIdForMap(this));
DCHECK(visitor_id() == Map::GetVisitorId(this));
#endif
}
}
@ -4299,7 +4299,7 @@ void Map::InitializeDescriptors(DescriptorArray* descriptors,
#else
SLOW_DCHECK(layout_descriptor()->IsConsistentWithMap(this));
#endif
set_visitor_id(Heap::GetStaticVisitorIdForMap(this));
set_visitor_id(Map::GetVisitorId(this));
}
}

View File

@ -2855,6 +2855,204 @@ void Map::PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind,
os << "]\n";
}
VisitorId Map::GetVisitorId(Map* map) {
STATIC_ASSERT(kVisitorIdCount <= 256);
const int instance_type = map->instance_type();
const bool has_unboxed_fields =
FLAG_unbox_double_fields && !map->HasFastPointerLayout();
if (instance_type < FIRST_NONSTRING_TYPE) {
switch (instance_type & kStringRepresentationMask) {
case kSeqStringTag:
if ((instance_type & kStringEncodingMask) == kOneByteStringTag) {
return kVisitSeqOneByteString;
} else {
return kVisitSeqTwoByteString;
}
case kConsStringTag:
if (IsShortcutCandidate(instance_type)) {
return kVisitShortcutCandidate;
} else {
return kVisitConsString;
}
case kSlicedStringTag:
return kVisitSlicedString;
case kExternalStringTag:
return kVisitDataObject;
case kThinStringTag:
return kVisitThinString;
}
UNREACHABLE();
}
switch (instance_type) {
case BYTE_ARRAY_TYPE:
return kVisitByteArray;
case BYTECODE_ARRAY_TYPE:
return kVisitBytecodeArray;
case FREE_SPACE_TYPE:
return kVisitFreeSpace;
case FIXED_ARRAY_TYPE:
return kVisitFixedArray;
case FIXED_DOUBLE_ARRAY_TYPE:
return kVisitFixedDoubleArray;
case ODDBALL_TYPE:
return kVisitOddball;
case MAP_TYPE:
return kVisitMap;
case CODE_TYPE:
return kVisitCode;
case CELL_TYPE:
return kVisitCell;
case PROPERTY_CELL_TYPE:
return kVisitPropertyCell;
case WEAK_CELL_TYPE:
return kVisitWeakCell;
case TRANSITION_ARRAY_TYPE:
return kVisitTransitionArray;
case JS_WEAK_MAP_TYPE:
case JS_WEAK_SET_TYPE:
return kVisitJSWeakCollection;
case JS_REGEXP_TYPE:
return kVisitJSRegExp;
case SHARED_FUNCTION_INFO_TYPE:
return kVisitSharedFunctionInfo;
case JS_PROXY_TYPE:
return kVisitStruct;
case SYMBOL_TYPE:
return kVisitSymbol;
case JS_ARRAY_BUFFER_TYPE:
return kVisitJSArrayBuffer;
case SMALL_ORDERED_HASH_MAP_TYPE:
return kVisitSmallOrderedHashMap;
case SMALL_ORDERED_HASH_SET_TYPE:
return kVisitSmallOrderedHashSet;
case JS_OBJECT_TYPE:
case JS_ERROR_TYPE:
case JS_ARGUMENTS_TYPE:
case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
case JS_GENERATOR_OBJECT_TYPE:
case JS_ASYNC_GENERATOR_OBJECT_TYPE:
case JS_MODULE_NAMESPACE_TYPE:
case JS_VALUE_TYPE:
case JS_DATE_TYPE:
case JS_ARRAY_TYPE:
case JS_GLOBAL_PROXY_TYPE:
case JS_GLOBAL_OBJECT_TYPE:
case JS_MESSAGE_OBJECT_TYPE:
case JS_TYPED_ARRAY_TYPE:
case JS_DATA_VIEW_TYPE:
case JS_SET_TYPE:
case JS_MAP_TYPE:
case JS_SET_ITERATOR_TYPE:
case JS_MAP_ITERATOR_TYPE:
case JS_STRING_ITERATOR_TYPE:
case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE:
case JS_PROMISE_CAPABILITY_TYPE:
case JS_PROMISE_TYPE:
case JS_BOUND_FUNCTION_TYPE:
return has_unboxed_fields ? kVisitJSObject : kVisitJSObjectFast;
case JS_API_OBJECT_TYPE:
case JS_SPECIAL_API_OBJECT_TYPE:
return kVisitJSApiObject;
case JS_FUNCTION_TYPE:
return kVisitJSFunction;
case FILLER_TYPE:
case FOREIGN_TYPE:
case HEAP_NUMBER_TYPE:
case MUTABLE_HEAP_NUMBER_TYPE:
return kVisitDataObject;
case FIXED_UINT8_ARRAY_TYPE:
case FIXED_INT8_ARRAY_TYPE:
case FIXED_UINT16_ARRAY_TYPE:
case FIXED_INT16_ARRAY_TYPE:
case FIXED_UINT32_ARRAY_TYPE:
case FIXED_INT32_ARRAY_TYPE:
case FIXED_FLOAT32_ARRAY_TYPE:
case FIXED_UINT8_CLAMPED_ARRAY_TYPE:
return kVisitFixedTypedArrayBase;
case FIXED_FLOAT64_ARRAY_TYPE:
return kVisitFixedFloat64Array;
#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE:
STRUCT_LIST(MAKE_STRUCT_CASE)
#undef MAKE_STRUCT_CASE
if (instance_type == ALLOCATION_SITE_TYPE) {
return kVisitAllocationSite;
}
return kVisitStruct;
default:
UNREACHABLE();
}
}
void Map::PrintGeneralization(
FILE* file, const char* reason, int modify_index, int split,
int descriptors, bool descriptor_to_field,
@ -8819,7 +9017,7 @@ void Map::InstallDescriptors(Handle<Map> parent, Handle<Map> child,
#else
SLOW_DCHECK(child->layout_descriptor()->IsConsistentWithMap(*child));
#endif
child->set_visitor_id(Heap::GetStaticVisitorIdForMap(*child));
child->set_visitor_id(Map::GetVisitorId(*child));
}
Handle<Name> name = handle(descriptors->GetKey(new_descriptor));
@ -8970,7 +9168,7 @@ Handle<Map> Map::Create(Isolate* isolate, int inobject_properties) {
copy->SetInObjectProperties(inobject_properties);
copy->set_unused_property_fields(inobject_properties);
copy->set_instance_size(new_instance_size);
copy->set_visitor_id(Heap::GetStaticVisitorIdForMap(*copy));
copy->set_visitor_id(Map::GetVisitorId(*copy));
return copy;
}
@ -11909,7 +12107,7 @@ static void GetMinInobjectSlack(Map* map, void* data) {
static void ShrinkInstanceSize(Map* map, void* data) {
#ifdef DEBUG
int old_visitor_id = Heap::GetStaticVisitorIdForMap(map);
int old_visitor_id = Map::GetVisitorId(map);
#endif
int slack = *reinterpret_cast<int*>(data);
DCHECK_GE(slack, 0);
@ -11917,7 +12115,7 @@ static void ShrinkInstanceSize(Map* map, void* data) {
map->set_unused_property_fields(map->unused_property_fields() - slack);
map->set_instance_size(map->instance_size() - slack * kPointerSize);
map->set_construction_counter(Map::kNoSlackTracking);
DCHECK_EQ(old_visitor_id, Heap::GetStaticVisitorIdForMap(map));
DCHECK_EQ(old_visitor_id, Map::GetVisitorId(map));
}
static void StopSlackTracking(Map* map, void* data) {

View File

@ -15,6 +15,59 @@
namespace v8 {
namespace internal {
#define VISITOR_ID_LIST(V) \
V(AllocationSite) \
V(ByteArray) \
V(BytecodeArray) \
V(Cell) \
V(Code) \
V(ConsString) \
V(DataObject) \
V(FixedArray) \
V(FixedDoubleArray) \
V(FixedFloat64Array) \
V(FixedTypedArrayBase) \
V(FreeSpace) \
V(JSApiObject) \
V(JSArrayBuffer) \
V(JSFunction) \
V(JSObject) \
V(JSObjectFast) \
V(JSRegExp) \
V(JSWeakCollection) \
V(Map) \
V(NativeContext) \
V(Oddball) \
V(PropertyCell) \
V(SeqOneByteString) \
V(SeqTwoByteString) \
V(SharedFunctionInfo) \
V(ShortcutCandidate) \
V(SlicedString) \
V(SmallOrderedHashMap) \
V(SmallOrderedHashSet) \
V(Struct) \
V(Symbol) \
V(ThinString) \
V(TransitionArray) \
V(WeakCell)
// For data objects, JS objects and structs along with generic visitor which
// can visit object of any size we provide visitors specialized by
// object size in words.
// Ids of specialized visitors are declared in a linear order (without
// holes) starting from the id of visitor specialized for 2 words objects
// (base visitor id) and ending with the id of generic visitor.
// Method GetVisitorIdForSize depends on this ordering to calculate visitor
// id of specialized visitor from given instance size, base visitor id and
// generic visitor's id.
enum VisitorId {
#define VISITOR_ID_ENUM_DECL(id) kVisit##id,
VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL)
#undef VISITOR_ID_ENUM_DECL
kVisitorIdCount
};
typedef std::vector<Handle<Map>> MapHandles;
// All heap objects have a Map that describes their structure.
@ -694,6 +747,8 @@ class Map : public HeapObject {
// the descriptor array.
inline void NotifyLeafMapLayoutChange();
static VisitorId GetVisitorId(Map* map);
private:
// Returns the map that this (root) map transitions to if its elements_kind
// is changed to |elements_kind|, or |nullptr| if no such map is cached yet.