Commit 1ff4a0c4 authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[runtime] Make bitfield2 immutable across named property transitions

Swap bits between bitfield2 and bitfield3 so that bitfield2 doesn't change
across named property transitions. This will allow us to share bf1/bf2 through
the descriptor array.

Change-Id: I3579ae89189ae0729cd492db1afb29cf90981f6a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1657908Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62134}
parent 44b5a524
...@@ -2928,15 +2928,12 @@ TNode<Int32T> CodeStubAssembler::EnsureArrayPushable(TNode<Map> map, ...@@ -2928,15 +2928,12 @@ TNode<Int32T> CodeStubAssembler::EnsureArrayPushable(TNode<Map> map,
// Disallow pushing onto prototypes. It might be the JSArray prototype. // Disallow pushing onto prototypes. It might be the JSArray prototype.
// Disallow pushing onto non-extensible objects. // Disallow pushing onto non-extensible objects.
Comment("Disallow pushing onto prototypes"); Comment("Disallow pushing onto prototypes");
Node* bit_field2 = LoadMapBitField2(map); GotoIfNot(IsExtensibleNonPrototypeMap(map), bailout);
int mask = Map::IsPrototypeMapBit::kMask | Map::IsExtensibleBit::kMask;
Node* test = Word32And(bit_field2, Int32Constant(mask));
GotoIf(Word32NotEqual(test, Int32Constant(Map::IsExtensibleBit::kMask)),
bailout);
EnsureArrayLengthWritable(map, bailout); EnsureArrayLengthWritable(map, bailout);
TNode<Uint32T> kind = DecodeWord32<Map::ElementsKindBits>(bit_field2); TNode<Uint32T> kind =
DecodeWord32<Map::ElementsKindBits>(LoadMapBitField2(map));
return Signed(kind); return Signed(kind);
} }
...@@ -6010,13 +6007,12 @@ TNode<BoolT> CodeStubAssembler::InstanceTypeEqual( ...@@ -6010,13 +6007,12 @@ TNode<BoolT> CodeStubAssembler::InstanceTypeEqual(
TNode<BoolT> CodeStubAssembler::IsDictionaryMap(SloppyTNode<Map> map) { TNode<BoolT> CodeStubAssembler::IsDictionaryMap(SloppyTNode<Map> map) {
CSA_SLOW_ASSERT(this, IsMap(map)); CSA_SLOW_ASSERT(this, IsMap(map));
Node* bit_field3 = LoadMapBitField3(map); return IsSetWord32<Map::IsDictionaryMapBit>(LoadMapBitField3(map));
return IsSetWord32<Map::IsDictionaryMapBit>(bit_field3);
} }
TNode<BoolT> CodeStubAssembler::IsExtensibleMap(SloppyTNode<Map> map) { TNode<BoolT> CodeStubAssembler::IsExtensibleMap(SloppyTNode<Map> map) {
CSA_ASSERT(this, IsMap(map)); CSA_ASSERT(this, IsMap(map));
return IsSetWord32<Map::IsExtensibleBit>(LoadMapBitField2(map)); return IsSetWord32<Map::IsExtensibleBit>(LoadMapBitField3(map));
} }
TNode<BoolT> CodeStubAssembler::IsFrozenOrSealedElementsKindMap( TNode<BoolT> CodeStubAssembler::IsFrozenOrSealedElementsKindMap(
...@@ -6029,7 +6025,7 @@ TNode<BoolT> CodeStubAssembler::IsFrozenOrSealedElementsKindMap( ...@@ -6029,7 +6025,7 @@ TNode<BoolT> CodeStubAssembler::IsFrozenOrSealedElementsKindMap(
TNode<BoolT> CodeStubAssembler::IsExtensibleNonPrototypeMap(TNode<Map> map) { TNode<BoolT> CodeStubAssembler::IsExtensibleNonPrototypeMap(TNode<Map> map) {
int kMask = Map::IsExtensibleBit::kMask | Map::IsPrototypeMapBit::kMask; int kMask = Map::IsExtensibleBit::kMask | Map::IsPrototypeMapBit::kMask;
int kExpected = Map::IsExtensibleBit::kMask; int kExpected = Map::IsExtensibleBit::kMask;
return Word32Equal(Word32And(LoadMapBitField2(map), Int32Constant(kMask)), return Word32Equal(Word32And(LoadMapBitField3(map), Int32Constant(kMask)),
Int32Constant(kExpected)); Int32Constant(kExpected));
} }
......
...@@ -2633,13 +2633,13 @@ BIMODAL_ACCESSOR_C(JSTypedArray, size_t, length) ...@@ -2633,13 +2633,13 @@ BIMODAL_ACCESSOR_C(JSTypedArray, size_t, length)
BIMODAL_ACCESSOR(JSTypedArray, HeapObject, buffer) BIMODAL_ACCESSOR(JSTypedArray, HeapObject, buffer)
BIMODAL_ACCESSOR_B(Map, bit_field2, elements_kind, Map::ElementsKindBits) BIMODAL_ACCESSOR_B(Map, bit_field2, elements_kind, Map::ElementsKindBits)
BIMODAL_ACCESSOR_B(Map, bit_field2, is_extensible, Map::IsExtensibleBit)
BIMODAL_ACCESSOR_B(Map, bit_field3, is_deprecated, Map::IsDeprecatedBit)
BIMODAL_ACCESSOR_B(Map, bit_field3, is_dictionary_map, Map::IsDictionaryMapBit) BIMODAL_ACCESSOR_B(Map, bit_field3, is_dictionary_map, Map::IsDictionaryMapBit)
BIMODAL_ACCESSOR_B(Map, bit_field3, is_deprecated, Map::IsDeprecatedBit)
BIMODAL_ACCESSOR_B(Map, bit_field3, NumberOfOwnDescriptors, BIMODAL_ACCESSOR_B(Map, bit_field3, NumberOfOwnDescriptors,
Map::NumberOfOwnDescriptorsBits) Map::NumberOfOwnDescriptorsBits)
BIMODAL_ACCESSOR_B(Map, bit_field3, is_migration_target, BIMODAL_ACCESSOR_B(Map, bit_field3, is_migration_target,
Map::IsMigrationTargetBit) Map::IsMigrationTargetBit)
BIMODAL_ACCESSOR_B(Map, bit_field3, is_extensible, Map::IsExtensibleBit)
BIMODAL_ACCESSOR_B(Map, bit_field, has_prototype_slot, Map::HasPrototypeSlotBit) BIMODAL_ACCESSOR_B(Map, bit_field, has_prototype_slot, Map::HasPrototypeSlotBit)
BIMODAL_ACCESSOR_B(Map, bit_field, is_access_check_needed, BIMODAL_ACCESSOR_B(Map, bit_field, is_access_check_needed,
Map::IsAccessCheckNeededBit) Map::IsAccessCheckNeededBit)
......
...@@ -1977,15 +1977,15 @@ Map Factory::InitializeMap(Map map, InstanceType type, int instance_size, ...@@ -1977,15 +1977,15 @@ Map Factory::InitializeMap(Map map, InstanceType type, int instance_size,
// |layout_descriptor| are set. // |layout_descriptor| are set.
map.set_visitor_id(Map::GetVisitorId(map)); map.set_visitor_id(Map::GetVisitorId(map));
map.set_bit_field(0); map.set_bit_field(0);
map.set_bit_field2(Map::IsExtensibleBit::kMask); map.set_bit_field2(Map::NewTargetIsBaseBit::encode(true));
int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) | int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) |
Map::OwnsDescriptorsBit::encode(true) | Map::OwnsDescriptorsBit::encode(true) |
Map::ConstructionCounterBits::encode(Map::kNoSlackTracking); Map::ConstructionCounterBits::encode(Map::kNoSlackTracking) |
Map::IsExtensibleBit::encode(true);
map.set_bit_field3(bit_field3); map.set_bit_field3(bit_field3);
DCHECK(!map.is_in_retained_map_list()); DCHECK(!map.is_in_retained_map_list());
map.clear_padding(); map.clear_padding();
map.set_elements_kind(elements_kind); map.set_elements_kind(elements_kind);
map.set_new_target_is_base(true);
isolate()->counters()->maps_created()->Increment(); isolate()->counters()->maps_created()->Increment();
if (FLAG_trace_maps) LOG(isolate(), MapCreate(map)); if (FLAG_trace_maps) LOG(isolate(), MapCreate(map));
return map; return map;
......
...@@ -150,11 +150,11 @@ AllocationResult Heap::AllocatePartialMap(InstanceType instance_type, ...@@ -150,11 +150,11 @@ AllocationResult Heap::AllocatePartialMap(InstanceType instance_type,
map.SetInObjectUnusedPropertyFields(0); map.SetInObjectUnusedPropertyFields(0);
map.set_bit_field(0); map.set_bit_field(0);
map.set_bit_field2(0); map.set_bit_field2(0);
DCHECK(!map.is_in_retained_map_list());
int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) | int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) |
Map::OwnsDescriptorsBit::encode(true) | Map::OwnsDescriptorsBit::encode(true) |
Map::ConstructionCounterBits::encode(Map::kNoSlackTracking); Map::ConstructionCounterBits::encode(Map::kNoSlackTracking);
map.set_bit_field3(bit_field3); map.set_bit_field3(bit_field3);
DCHECK(!map.is_in_retained_map_list());
map.clear_padding(); map.clear_padding();
map.set_elements_kind(TERMINAL_FAST_ELEMENTS_KIND); map.set_elements_kind(TERMINAL_FAST_ELEMENTS_KIND);
return map; return map;
......
...@@ -2087,13 +2087,13 @@ void AccessorAssembler::NameDictionaryNegativeLookup(Node* object, ...@@ -2087,13 +2087,13 @@ void AccessorAssembler::NameDictionaryNegativeLookup(Node* object,
} }
void AccessorAssembler::InvalidateValidityCellIfPrototype(Node* map, void AccessorAssembler::InvalidateValidityCellIfPrototype(Node* map,
Node* bitfield2) { Node* bitfield3) {
Label is_prototype(this), cont(this); Label is_prototype(this), cont(this);
if (bitfield2 == nullptr) { if (bitfield3 == nullptr) {
bitfield2 = LoadMapBitField2(map); bitfield3 = LoadMapBitField3(map);
} }
Branch(IsSetWord32(bitfield2, Map::IsPrototypeMapBit::kMask), &is_prototype, Branch(IsSetWord32(bitfield3, Map::IsPrototypeMapBit::kMask), &is_prototype,
&cont); &cont);
BIND(&is_prototype); BIND(&is_prototype);
......
...@@ -127,7 +127,7 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { ...@@ -127,7 +127,7 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler {
void JumpIfDataProperty(Node* details, Label* writable, Label* readonly); void JumpIfDataProperty(Node* details, Label* writable, Label* readonly);
void InvalidateValidityCellIfPrototype(Node* map, Node* bitfield2 = nullptr); void InvalidateValidityCellIfPrototype(Node* map, Node* bitfield3 = nullptr);
void OverwriteExistingFastDataProperty(Node* object, Node* object_map, void OverwriteExistingFastDataProperty(Node* object, Node* object_map,
Node* descriptors, Node* descriptors,
......
...@@ -869,9 +869,9 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( ...@@ -869,9 +869,9 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
{ {
CheckForAssociatedProtector(p->name, slow); CheckForAssociatedProtector(p->name, slow);
Label extensible(this); Label extensible(this);
Node* bitfield2 = LoadMapBitField2(receiver_map); Node* bitfield3 = LoadMapBitField3(receiver_map);
GotoIf(IsPrivateSymbol(p->name), &extensible); GotoIf(IsPrivateSymbol(p->name), &extensible);
Branch(IsSetWord32<Map::IsExtensibleBit>(bitfield2), &extensible, slow); Branch(IsSetWord32<Map::IsExtensibleBit>(bitfield3), &extensible, slow);
BIND(&extensible); BIND(&extensible);
if (ShouldCheckPrototype()) { if (ShouldCheckPrototype()) {
...@@ -882,7 +882,7 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( ...@@ -882,7 +882,7 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
ShouldReconfigureExisting() ? nullptr : &readonly, slow); ShouldReconfigureExisting() ? nullptr : &readonly, slow);
} }
Label add_dictionary_property_slow(this); Label add_dictionary_property_slow(this);
InvalidateValidityCellIfPrototype(receiver_map, bitfield2); InvalidateValidityCellIfPrototype(receiver_map, bitfield3);
Add<NameDictionary>(properties, CAST(p->name), p->value, Add<NameDictionary>(properties, CAST(p->name), p->value,
&add_dictionary_property_slow); &add_dictionary_property_slow);
exit_point->Return(p->value); exit_point->Return(p->value);
......
...@@ -74,20 +74,20 @@ BIT_FIELD_ACCESSORS(Map, relaxed_bit_field, has_prototype_slot, ...@@ -74,20 +74,20 @@ BIT_FIELD_ACCESSORS(Map, relaxed_bit_field, has_prototype_slot,
Map::HasPrototypeSlotBit) Map::HasPrototypeSlotBit)
// |bit_field2| fields. // |bit_field2| fields.
BIT_FIELD_ACCESSORS(Map, bit_field2, is_extensible, Map::IsExtensibleBit) BIT_FIELD_ACCESSORS(Map, bit_field2, new_target_is_base,
BIT_FIELD_ACCESSORS(Map, bit_field2, is_prototype_map, Map::IsPrototypeMapBit) Map::NewTargetIsBaseBit)
BIT_FIELD_ACCESSORS(Map, bit_field2, is_immutable_proto,
Map::IsImmutablePrototypeBit)
// |bit_field3| fields. // |bit_field3| fields.
BIT_FIELD_ACCESSORS(Map, bit_field3, owns_descriptors, Map::OwnsDescriptorsBit) BIT_FIELD_ACCESSORS(Map, bit_field3, owns_descriptors, Map::OwnsDescriptorsBit)
BIT_FIELD_ACCESSORS(Map, bit_field3, is_deprecated, Map::IsDeprecatedBit) BIT_FIELD_ACCESSORS(Map, bit_field3, is_deprecated, Map::IsDeprecatedBit)
BIT_FIELD_ACCESSORS(Map, bit_field3, is_in_retained_map_list, BIT_FIELD_ACCESSORS(Map, bit_field3, is_in_retained_map_list,
Map::IsInRetainedMapListBit) Map::IsInRetainedMapListBit)
BIT_FIELD_ACCESSORS(Map, bit_field3, is_prototype_map, Map::IsPrototypeMapBit)
BIT_FIELD_ACCESSORS(Map, bit_field3, is_migration_target, BIT_FIELD_ACCESSORS(Map, bit_field3, is_migration_target,
Map::IsMigrationTargetBit) Map::IsMigrationTargetBit)
BIT_FIELD_ACCESSORS(Map, bit_field3, is_immutable_proto, BIT_FIELD_ACCESSORS(Map, bit_field3, is_extensible, Map::IsExtensibleBit)
Map::IsImmutablePrototypeBit)
BIT_FIELD_ACCESSORS(Map, bit_field3, new_target_is_base,
Map::NewTargetIsBaseBit)
BIT_FIELD_ACCESSORS(Map, bit_field3, may_have_interesting_symbols, BIT_FIELD_ACCESSORS(Map, bit_field3, may_have_interesting_symbols,
Map::MayHaveInterestingSymbolsBit) Map::MayHaveInterestingSymbolsBit)
BIT_FIELD_ACCESSORS(Map, bit_field3, construction_counter, BIT_FIELD_ACCESSORS(Map, bit_field3, construction_counter,
......
...@@ -138,22 +138,22 @@ using MapHandles = std::vector<Handle<Map>>; ...@@ -138,22 +138,22 @@ using MapHandles = std::vector<Handle<Map>>;
// | | - has_prototype_slot (bit 7) | // | | - has_prototype_slot (bit 7) |
// +----------+---------------------------------------------+ // +----------+---------------------------------------------+
// | Byte | [bit_field2] | // | Byte | [bit_field2] |
// | | - is_extensible (bit 0) | // | | - new_target_is_base (bit 0) |
// | | - is_prototype_map (bit 1) | // | | - is_immutable_proto (bit 1) |
// | | - unused bit (bit 2) | // | | - unused bit (bit 2) |
// | | - elements_kind (bits 3..7) | // | | - elements_kind (bits 3..7) |
// +----+----------+---------------------------------------------+ // +----+----------+---------------------------------------------+
// | Int | [bit_field3] | // | Int | [bit_field3] |
// | | - enum_length (bit 0..9) | // | | - enum_length (bit 0..9) |
// | | - number_of_own_descriptors (bit 10..19) | // | | - number_of_own_descriptors (bit 10..19) |
// | | - is_dictionary_map (bit 20) | // | | - is_prototype_map (bit 20) |
// | | - owns_descriptors (bit 21) | // | | - is_dictionary_map (bit 21) |
// | | - is_in_retained_map_list (bit 22) | // | | - owns_descriptors (bit 22) |
// | | - is_deprecated (bit 23) | // | | - is_in_retained_map_list (bit 23) |
// | | - is_unstable (bit 24) | // | | - is_deprecated (bit 24) |
// | | - is_migration_target (bit 25) | // | | - is_unstable (bit 25) |
// | | - is_immutable_proto (bit 26) | // | | - is_migration_target (bit 26) |
// | | - new_target_is_base (bit 27) | // | | - is_extensible (bit 28) |
// | | - may_have_interesting_symbols (bit 28) | // | | - may_have_interesting_symbols (bit 28) |
// | | - construction_counter (bit 29..31) | // | | - construction_counter (bit 29..31) |
// | | | // | | |
...@@ -265,10 +265,10 @@ class Map : public HeapObject { ...@@ -265,10 +265,10 @@ class Map : public HeapObject {
DECL_PRIMITIVE_ACCESSORS(bit_field2, byte) DECL_PRIMITIVE_ACCESSORS(bit_field2, byte)
// Bit positions for |bit_field2|. // Bit positions for |bit_field2|.
#define MAP_BIT_FIELD2_FIELDS(V, _) \ #define MAP_BIT_FIELD2_FIELDS(V, _) \
V(IsExtensibleBit, bool, 1, _) \ V(NewTargetIsBaseBit, bool, 1, _) \
V(IsPrototypeMapBit, bool, 1, _) \ V(IsImmutablePrototypeBit, bool, 1, _) \
V(UnusedBit, bool, 1, _) \ V(UnusedBit, bool, 1, _) \
V(ElementsKindBits, ElementsKind, 5, _) V(ElementsKindBits, ElementsKind, 5, _)
DEFINE_BIT_FIELDS(MAP_BIT_FIELD2_FIELDS) DEFINE_BIT_FIELDS(MAP_BIT_FIELD2_FIELDS)
...@@ -287,14 +287,14 @@ class Map : public HeapObject { ...@@ -287,14 +287,14 @@ class Map : public HeapObject {
#define MAP_BIT_FIELD3_FIELDS(V, _) \ #define MAP_BIT_FIELD3_FIELDS(V, _) \
V(EnumLengthBits, int, kDescriptorIndexBitCount, _) \ V(EnumLengthBits, int, kDescriptorIndexBitCount, _) \
V(NumberOfOwnDescriptorsBits, int, kDescriptorIndexBitCount, _) \ V(NumberOfOwnDescriptorsBits, int, kDescriptorIndexBitCount, _) \
V(IsPrototypeMapBit, bool, 1, _) \
V(IsDictionaryMapBit, bool, 1, _) \ V(IsDictionaryMapBit, bool, 1, _) \
V(OwnsDescriptorsBit, bool, 1, _) \ V(OwnsDescriptorsBit, bool, 1, _) \
V(IsInRetainedMapListBit, bool, 1, _) \ V(IsInRetainedMapListBit, bool, 1, _) \
V(IsDeprecatedBit, bool, 1, _) \ V(IsDeprecatedBit, bool, 1, _) \
V(IsUnstableBit, bool, 1, _) \ V(IsUnstableBit, bool, 1, _) \
V(IsMigrationTargetBit, bool, 1, _) \ V(IsMigrationTargetBit, bool, 1, _) \
V(IsImmutablePrototypeBit, bool, 1, _) \ V(IsExtensibleBit, bool, 1, _) \
V(NewTargetIsBaseBit, bool, 1, _) \
V(MayHaveInterestingSymbolsBit, bool, 1, _) \ V(MayHaveInterestingSymbolsBit, bool, 1, _) \
V(ConstructionCounterBits, int, 3, _) V(ConstructionCounterBits, int, 3, _)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment