[runtime] Cleanup Map class definition.
.. by using macros for defining field offsets. Bug: v8:5799 Change-Id: Id76e81bedb8f348b2efaa1d553bebac0ff90b474 Reviewed-on: https://chromium-review.googlesource.com/768382 Reviewed-by: Camillo Bruni <cbruni@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Commit-Queue: Igor Sheludko <ishell@chromium.org> Cr-Commit-Position: refs/heads/master@{#49351}
This commit is contained in:
parent
e634740bf9
commit
68f1dcf9e7
@ -131,7 +131,8 @@ inline constexpr unsigned CountTrailingZeros64(uint64_t value) {
|
||||
|
||||
// Returns true iff |value| is a power of 2.
|
||||
template <typename T,
|
||||
typename = typename std::enable_if<std::is_integral<T>::value>::type>
|
||||
typename = typename std::enable_if<std::is_integral<T>::value ||
|
||||
std::is_enum<T>::value>::type>
|
||||
constexpr inline bool IsPowerOfTwo(T value) {
|
||||
return value > 0 && (value & (value - 1)) == 0;
|
||||
}
|
||||
|
@ -1372,7 +1372,6 @@ TNode<IntPtrT> CodeStubAssembler::LoadMapInobjectProperties(
|
||||
SloppyTNode<Map> map) {
|
||||
CSA_SLOW_ASSERT(this, IsMap(map));
|
||||
// See Map::GetInObjectProperties() for details.
|
||||
STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
|
||||
CSA_ASSERT(this, IsJSObjectMap(map));
|
||||
return ChangeInt32ToIntPtr(LoadObjectField(
|
||||
map, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset,
|
||||
@ -1383,9 +1382,7 @@ TNode<IntPtrT> CodeStubAssembler::LoadMapConstructorFunctionIndex(
|
||||
SloppyTNode<Map> map) {
|
||||
CSA_SLOW_ASSERT(this, IsMap(map));
|
||||
// See Map::GetConstructorFunctionIndex() for details.
|
||||
STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE);
|
||||
CSA_ASSERT(this, Int32LessThanOrEqual(LoadMapInstanceType(map),
|
||||
Int32Constant(LAST_PRIMITIVE_TYPE)));
|
||||
CSA_ASSERT(this, IsPrimitiveInstanceType(LoadMapInstanceType(map)));
|
||||
return ChangeInt32ToIntPtr(LoadObjectField(
|
||||
map, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset,
|
||||
MachineType::Uint8()));
|
||||
|
@ -148,6 +148,7 @@ const int kMinUInt16 = 0;
|
||||
const uint32_t kMaxUInt32 = 0xFFFFFFFFu;
|
||||
const int kMinUInt32 = 0;
|
||||
|
||||
const int kUInt8Size = sizeof(uint8_t);
|
||||
const int kCharSize = sizeof(char);
|
||||
const int kShortSize = sizeof(short); // NOLINT
|
||||
const int kIntSize = sizeof(int);
|
||||
|
@ -31,7 +31,7 @@ template <typename ResultType, typename ConcreteVisitor>
|
||||
ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit(Map* map,
|
||||
HeapObject* object) {
|
||||
ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
|
||||
switch (static_cast<VisitorId>(map->visitor_id())) {
|
||||
switch (map->visitor_id()) {
|
||||
#define CASE(type) \
|
||||
case kVisit##type: \
|
||||
return visitor->Visit##type(map, \
|
||||
|
@ -116,7 +116,7 @@ bool Scavenger::PromoteObject(Map* map, HeapObject** slot, HeapObject* object,
|
||||
}
|
||||
*slot = target;
|
||||
|
||||
if (!ContainsOnlyData(static_cast<VisitorId>(map->visitor_id()))) {
|
||||
if (!ContainsOnlyData(map->visitor_id())) {
|
||||
promotion_list_.Push(ObjectAndSize(target, object_size));
|
||||
}
|
||||
promoted_size_ += object_size;
|
||||
@ -206,7 +206,7 @@ void Scavenger::EvacuateObject(HeapObject** slot, Map* map,
|
||||
int size = source->SizeFromMap(map);
|
||||
// Cannot use ::cast() below because that would add checks in debug mode
|
||||
// that require re-reading the map.
|
||||
switch (static_cast<VisitorId>(map->visitor_id())) {
|
||||
switch (map->visitor_id()) {
|
||||
case kVisitThinString:
|
||||
EvacuateThinString(map, slot, reinterpret_cast<ThinString*>(source),
|
||||
size);
|
||||
|
@ -2968,9 +2968,11 @@ Handle<Object> Float64ArrayTraits::ToHandle(Isolate* isolate, double scalar) {
|
||||
return isolate->factory()->NewNumber(scalar);
|
||||
}
|
||||
|
||||
int Map::visitor_id() const { return READ_BYTE_FIELD(this, kVisitorIdOffset); }
|
||||
VisitorId Map::visitor_id() const {
|
||||
return static_cast<VisitorId>(READ_BYTE_FIELD(this, kVisitorIdOffset));
|
||||
}
|
||||
|
||||
void Map::set_visitor_id(int id) {
|
||||
void Map::set_visitor_id(VisitorId id) {
|
||||
DCHECK_LE(0, id);
|
||||
DCHECK_LT(id, 256);
|
||||
WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
|
||||
@ -3573,12 +3575,14 @@ void Map::set_prototype(Object* value, WriteBarrierMode mode) {
|
||||
}
|
||||
|
||||
LayoutDescriptor* Map::layout_descriptor_gc_safe() const {
|
||||
DCHECK(FLAG_unbox_double_fields);
|
||||
Object* layout_desc = RELAXED_READ_FIELD(this, kLayoutDescriptorOffset);
|
||||
return LayoutDescriptor::cast_gc_safe(layout_desc);
|
||||
}
|
||||
|
||||
|
||||
bool Map::HasFastPointerLayout() const {
|
||||
DCHECK(FLAG_unbox_double_fields);
|
||||
Object* layout_desc = RELAXED_READ_FIELD(this, kLayoutDescriptorOffset);
|
||||
return LayoutDescriptor::IsFastPointerLayout(layout_desc);
|
||||
}
|
||||
@ -3595,7 +3599,7 @@ 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() == Map::GetVisitorId(this));
|
||||
CHECK_EQ(Map::GetVisitorId(this), visitor_id());
|
||||
}
|
||||
#else
|
||||
SLOW_DCHECK(layout_descriptor()->IsConsistentWithMap(this));
|
||||
@ -3627,7 +3631,8 @@ void Map::InitializeDescriptors(DescriptorArray* descriptors,
|
||||
|
||||
|
||||
ACCESSORS(Map, instance_descriptors, DescriptorArray, kDescriptorsOffset)
|
||||
ACCESSORS(Map, layout_descriptor, LayoutDescriptor, kLayoutDescriptorOffset)
|
||||
ACCESSORS_CHECKED(Map, layout_descriptor, LayoutDescriptor,
|
||||
kLayoutDescriptorOffset, FLAG_unbox_double_fields)
|
||||
|
||||
void Map::set_bit_field3(uint32_t bits) {
|
||||
if (kInt32Size != kPointerSize) {
|
||||
|
@ -151,7 +151,9 @@ typedef std::vector<Handle<Map>> MapHandles;
|
||||
// | TaggedPointer | [instance_descriptors] |
|
||||
// +*************************************************************+
|
||||
// ! TaggedPointer ! [layout_descriptors] !
|
||||
// ! ! Field is only present on 64 bit arch !
|
||||
// ! ! Field is only present if compile-time flag !
|
||||
// ! ! FLAG_unbox_double_fields is enabled !
|
||||
// ! ! (basically on 64 bit architectures) !
|
||||
// +*************************************************************+
|
||||
// | TaggedPointer | [dependent_code] |
|
||||
// +---------------+---------------------------------------------+
|
||||
@ -163,14 +165,13 @@ class Map : public HeapObject {
|
||||
// Instance size.
|
||||
// Size in bytes or kVariableSizeSentinel if instances do not have
|
||||
// a fixed size.
|
||||
inline int instance_size() const;
|
||||
inline void set_instance_size(int value);
|
||||
DECL_INT_ACCESSORS(instance_size)
|
||||
|
||||
// [inobject_properties_or_constructor_function_index]: Provides access
|
||||
// to the inobject properties in case of JSObject maps, or the constructor
|
||||
// function index in case of primitive maps.
|
||||
inline int inobject_properties_or_constructor_function_index() const;
|
||||
inline void set_inobject_properties_or_constructor_function_index(int value);
|
||||
DECL_INT_ACCESSORS(inobject_properties_or_constructor_function_index)
|
||||
|
||||
// Count of properties allocated in the object (JSObject only).
|
||||
inline int GetInObjectProperties() const;
|
||||
inline void SetInObjectProperties(int value);
|
||||
@ -206,8 +207,7 @@ class Map : public HeapObject {
|
||||
// - there is no slack in the object.
|
||||
// - the property array has value slack slots.
|
||||
// Note that this encoding requires that H = JSObject::kFieldsAdded.
|
||||
inline int used_instance_size_in_words() const;
|
||||
inline void set_used_instance_size_in_words(int value);
|
||||
DECL_INT_ACCESSORS(used_instance_size_in_words)
|
||||
inline int UsedInstanceSize() const;
|
||||
|
||||
inline int UnusedPropertyFields() const;
|
||||
@ -320,21 +320,18 @@ class Map : public HeapObject {
|
||||
|
||||
// Tells whether the instance has a [[Construct]] internal method.
|
||||
// This property is implemented according to ES6, section 7.2.4.
|
||||
inline void set_is_constructor(bool value);
|
||||
inline bool is_constructor() const;
|
||||
DECL_BOOLEAN_ACCESSORS(is_constructor)
|
||||
|
||||
// Tells whether the instance with this map may have properties for
|
||||
// interesting symbols on it.
|
||||
// An "interesting symbol" is one for which Name::IsInterestingSymbol()
|
||||
// returns true, i.e. a well-known symbol like @@toStringTag.
|
||||
inline void set_may_have_interesting_symbols(bool value);
|
||||
inline bool may_have_interesting_symbols() const;
|
||||
DECL_BOOLEAN_ACCESSORS(may_have_interesting_symbols)
|
||||
|
||||
DECL_BOOLEAN_ACCESSORS(has_prototype_slot)
|
||||
|
||||
// Tells whether the instance with this map has a hidden prototype.
|
||||
inline void set_has_hidden_prototype(bool value);
|
||||
inline bool has_hidden_prototype() const;
|
||||
DECL_BOOLEAN_ACCESSORS(has_hidden_prototype)
|
||||
|
||||
// Records and queries whether the instance has a named interceptor.
|
||||
inline void set_has_named_interceptor();
|
||||
@ -358,12 +355,9 @@ class Map : public HeapObject {
|
||||
inline void set_is_callable();
|
||||
inline bool is_callable() const;
|
||||
|
||||
inline void set_new_target_is_base(bool value);
|
||||
inline bool new_target_is_base() const;
|
||||
inline void set_is_extensible(bool value);
|
||||
inline bool is_extensible() const;
|
||||
inline void set_is_prototype_map(bool value);
|
||||
inline bool is_prototype_map() const;
|
||||
DECL_BOOLEAN_ACCESSORS(new_target_is_base)
|
||||
DECL_BOOLEAN_ACCESSORS(is_extensible)
|
||||
DECL_BOOLEAN_ACCESSORS(is_prototype_map)
|
||||
inline bool is_abandoned_prototype_map() const;
|
||||
|
||||
inline void set_elements_kind(ElementsKind elements_kind);
|
||||
@ -571,16 +565,14 @@ class Map : public HeapObject {
|
||||
inline int EnumLength() const;
|
||||
inline void SetEnumLength(int length);
|
||||
|
||||
inline bool owns_descriptors() const;
|
||||
inline void set_owns_descriptors(bool owns_descriptors);
|
||||
DECL_BOOLEAN_ACCESSORS(owns_descriptors)
|
||||
inline void mark_unstable();
|
||||
inline bool is_stable() const;
|
||||
inline void set_migration_target(bool value);
|
||||
inline bool is_migration_target() const;
|
||||
inline void set_immutable_proto(bool value);
|
||||
inline bool is_immutable_proto() const;
|
||||
inline void set_construction_counter(int value);
|
||||
inline int construction_counter() const;
|
||||
DECL_INT_ACCESSORS(construction_counter)
|
||||
inline void deprecate();
|
||||
inline bool is_deprecated() const;
|
||||
inline bool CanBeDeprecated() const;
|
||||
@ -725,8 +717,7 @@ class Map : public HeapObject {
|
||||
void DictionaryMapVerify();
|
||||
#endif
|
||||
|
||||
inline int visitor_id() const;
|
||||
inline void set_visitor_id(int visitor_id);
|
||||
DECL_PRIMITIVE_ACCESSORS(visitor_id, VisitorId)
|
||||
|
||||
static Handle<Map> TransitionToPrototype(Handle<Map> map,
|
||||
Handle<Object> prototype);
|
||||
@ -736,46 +727,29 @@ class Map : public HeapObject {
|
||||
static const int kMaxPreAllocatedPropertyFields = 255;
|
||||
|
||||
// Layout description.
|
||||
static const int kInstanceSizesOffset = HeapObject::kHeaderSize;
|
||||
static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize;
|
||||
static const int kBitField3Offset = kInstanceAttributesOffset + kIntSize;
|
||||
static const int kPrototypeOffset = kBitField3Offset + kPointerSize;
|
||||
static const int kConstructorOrBackPointerOffset =
|
||||
kPrototypeOffset + kPointerSize;
|
||||
// When there is only one transition, it is stored directly in this field;
|
||||
// otherwise a transition array is used.
|
||||
// For prototype maps, this slot is used to store this map's PrototypeInfo
|
||||
// struct.
|
||||
static const int kTransitionsOrPrototypeInfoOffset =
|
||||
kConstructorOrBackPointerOffset + kPointerSize;
|
||||
static const int kDescriptorsOffset =
|
||||
kTransitionsOrPrototypeInfoOffset + kPointerSize;
|
||||
#if V8_DOUBLE_FIELDS_UNBOXING
|
||||
static const int kLayoutDescriptorOffset = kDescriptorsOffset + kPointerSize;
|
||||
static const int kDependentCodeOffset =
|
||||
kLayoutDescriptorOffset + kPointerSize;
|
||||
#else
|
||||
static const int kLayoutDescriptorOffset = 1; // Must not be ever accessed.
|
||||
static const int kDependentCodeOffset = kDescriptorsOffset + kPointerSize;
|
||||
#endif
|
||||
static const int kWeakCellCacheOffset = kDependentCodeOffset + kPointerSize;
|
||||
static const int kSize = kWeakCellCacheOffset + kPointerSize;
|
||||
#define MAP_FIELDS(V) \
|
||||
/* Raw data fields. */ \
|
||||
V(kInstanceSizeOffset, kUInt8Size) \
|
||||
V(kInObjectPropertiesOrConstructorFunctionIndexOffset, kUInt8Size) \
|
||||
V(kUsedInstanceSizeInWordsOffset, kUInt8Size) \
|
||||
V(kVisitorIdOffset, kUInt8Size) \
|
||||
V(kInstanceAttributesOffset, kInt32Size) \
|
||||
V(kBitField3Offset, kPointerSize) \
|
||||
/* Pointer fields. */ \
|
||||
V(kPointerFieldsBeginOffset, 0) \
|
||||
V(kPrototypeOffset, kPointerSize) \
|
||||
V(kConstructorOrBackPointerOffset, kPointerSize) \
|
||||
V(kTransitionsOrPrototypeInfoOffset, kPointerSize) \
|
||||
V(kDescriptorsOffset, kPointerSize) \
|
||||
V(kLayoutDescriptorOffset, (FLAG_unbox_double_fields ? kPointerSize : 0)) \
|
||||
V(kDependentCodeOffset, kPointerSize) \
|
||||
V(kWeakCellCacheOffset, kPointerSize) \
|
||||
V(kPointerFieldsEndOffset, 0) \
|
||||
/* Total size. */ \
|
||||
V(kSize, 0)
|
||||
|
||||
// Layout of pointer fields. Heap iteration code relies on them
|
||||
// being continuously allocated.
|
||||
static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset;
|
||||
static const int kPointerFieldsEndOffset = kSize;
|
||||
|
||||
// Byte offsets within kInstanceSizesOffset.
|
||||
static const int kInstanceSizeOffset = kInstanceSizesOffset + 0;
|
||||
static const int kInObjectPropertiesOrConstructorFunctionIndexByte = 1;
|
||||
static const int kInObjectPropertiesOrConstructorFunctionIndexOffset =
|
||||
kInstanceSizesOffset + kInObjectPropertiesOrConstructorFunctionIndexByte;
|
||||
static const int kUsedInstanceSizeInWordsByte = 2;
|
||||
static const int kUsedInstanceSizeInWordsOffset =
|
||||
kInstanceSizesOffset + kUsedInstanceSizeInWordsByte;
|
||||
static const int kVisitorIdByte = 3;
|
||||
static const int kVisitorIdOffset = kInstanceSizesOffset + kVisitorIdByte;
|
||||
DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, MAP_FIELDS)
|
||||
#undef MAP_FIELDS
|
||||
|
||||
// Byte offsets within kInstanceAttributesOffset attributes.
|
||||
#if V8_TARGET_LITTLE_ENDIAN
|
||||
@ -814,24 +788,6 @@ class Map : public HeapObject {
|
||||
class IsPrototypeMapBits : public BitField<bool, 2, 1> {};
|
||||
class ElementsKindBits : public BitField<ElementsKind, 3, 5> {};
|
||||
|
||||
// Derived values from bit field 2
|
||||
static const int8_t kMaximumBitField2FastElementValue =
|
||||
static_cast<int8_t>((PACKED_ELEMENTS + 1)
|
||||
<< Map::ElementsKindBits::kShift) -
|
||||
1;
|
||||
static const int8_t kMaximumBitField2FastSmiElementValue =
|
||||
static_cast<int8_t>((PACKED_SMI_ELEMENTS + 1)
|
||||
<< Map::ElementsKindBits::kShift) -
|
||||
1;
|
||||
static const int8_t kMaximumBitField2FastHoleyElementValue =
|
||||
static_cast<int8_t>((HOLEY_ELEMENTS + 1)
|
||||
<< Map::ElementsKindBits::kShift) -
|
||||
1;
|
||||
static const int8_t kMaximumBitField2FastHoleySmiElementValue =
|
||||
static_cast<int8_t>((HOLEY_SMI_ELEMENTS + 1)
|
||||
<< Map::ElementsKindBits::kShift) -
|
||||
1;
|
||||
|
||||
typedef FixedBodyDescriptor<kPointerFieldsBeginOffset,
|
||||
kPointerFieldsEndOffset, kSize>
|
||||
BodyDescriptor;
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#undef DECL_PRIMITIVE_ACCESSORS
|
||||
#undef DECL_BOOLEAN_ACCESSORS
|
||||
#undef DECL_INT_ACCESSORS
|
||||
#undef DECL_ACCESSORS
|
||||
@ -17,6 +18,7 @@
|
||||
#undef RELAXED_SMI_ACCESSORS
|
||||
#undef BOOL_GETTER
|
||||
#undef BOOL_ACCESSORS
|
||||
#undef BIT_FIELD_ACCESSORS
|
||||
#undef TYPE_CHECKER
|
||||
#undef FIELD_ADDR
|
||||
#undef FIELD_ADDR_CONST
|
||||
|
@ -12,17 +12,15 @@
|
||||
// for fields that can be written to and read from multiple threads at the same
|
||||
// time. See comments in src/base/atomicops.h for the memory ordering sematics.
|
||||
|
||||
#define DECL_BOOLEAN_ACCESSORS(name) \
|
||||
inline bool name() const; \
|
||||
inline void set_##name(bool value);
|
||||
#define DECL_PRIMITIVE_ACCESSORS(name, type) \
|
||||
inline type name() const; \
|
||||
inline void set_##name(type value);
|
||||
|
||||
#define DECL_INT_ACCESSORS(name) \
|
||||
inline int name() const; \
|
||||
inline void set_##name(int value);
|
||||
#define DECL_BOOLEAN_ACCESSORS(name) DECL_PRIMITIVE_ACCESSORS(name, bool)
|
||||
|
||||
#define DECL_INT32_ACCESSORS(name) \
|
||||
inline int32_t name() const; \
|
||||
inline void set_##name(int32_t value);
|
||||
#define DECL_INT_ACCESSORS(name) DECL_PRIMITIVE_ACCESSORS(name, int)
|
||||
|
||||
#define DECL_INT32_ACCESSORS(name) DECL_PRIMITIVE_ACCESSORS(name, int32_t)
|
||||
|
||||
#define DECL_ACCESSORS(name, type) \
|
||||
inline type* name() const; \
|
||||
|
@ -1097,13 +1097,11 @@ void V8HeapExplorer::ExtractMapReferences(int entry, Map* map) {
|
||||
Map::kDescriptorsOffset);
|
||||
SetInternalReference(map, entry, "prototype", map->prototype(),
|
||||
Map::kPrototypeOffset);
|
||||
#if V8_DOUBLE_FIELDS_UNBOXING
|
||||
if (FLAG_unbox_double_fields) {
|
||||
SetInternalReference(map, entry, "layout_descriptor",
|
||||
map->layout_descriptor(),
|
||||
Map::kLayoutDescriptorOffset);
|
||||
}
|
||||
#endif
|
||||
Object* constructor_or_backpointer = map->constructor_or_backpointer();
|
||||
if (constructor_or_backpointer->IsMap()) {
|
||||
TagObject(constructor_or_backpointer, "(back pointer)");
|
||||
|
Loading…
Reference in New Issue
Block a user