[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:
parent
72b5d5c00c
commit
9cb2211cb2
@ -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:
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
206
src/objects.cc
206
src/objects.cc
@ -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) {
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user