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,
// Disallow pushing onto prototypes. It might be the JSArray prototype.
// Disallow pushing onto non-extensible objects.
Comment("Disallow pushing onto prototypes");
Node* bit_field2 = LoadMapBitField2(map);
int mask = Map::IsPrototypeMapBit::kMask | Map::IsExtensibleBit::kMask;
Node* test = Word32And(bit_field2, Int32Constant(mask));
GotoIf(Word32NotEqual(test, Int32Constant(Map::IsExtensibleBit::kMask)),
bailout);
GotoIfNot(IsExtensibleNonPrototypeMap(map), bailout);
EnsureArrayLengthWritable(map, bailout);
TNode<Uint32T> kind = DecodeWord32<Map::ElementsKindBits>(bit_field2);
TNode<Uint32T> kind =
DecodeWord32<Map::ElementsKindBits>(LoadMapBitField2(map));
return Signed(kind);
}
......@@ -6010,13 +6007,12 @@ TNode<BoolT> CodeStubAssembler::InstanceTypeEqual(
TNode<BoolT> CodeStubAssembler::IsDictionaryMap(SloppyTNode<Map> map) {
CSA_SLOW_ASSERT(this, IsMap(map));
Node* bit_field3 = LoadMapBitField3(map);
return IsSetWord32<Map::IsDictionaryMapBit>(bit_field3);
return IsSetWord32<Map::IsDictionaryMapBit>(LoadMapBitField3(map));
}
TNode<BoolT> CodeStubAssembler::IsExtensibleMap(SloppyTNode<Map> map) {
CSA_ASSERT(this, IsMap(map));
return IsSetWord32<Map::IsExtensibleBit>(LoadMapBitField2(map));
return IsSetWord32<Map::IsExtensibleBit>(LoadMapBitField3(map));
}
TNode<BoolT> CodeStubAssembler::IsFrozenOrSealedElementsKindMap(
......@@ -6029,7 +6025,7 @@ TNode<BoolT> CodeStubAssembler::IsFrozenOrSealedElementsKindMap(
TNode<BoolT> CodeStubAssembler::IsExtensibleNonPrototypeMap(TNode<Map> map) {
int kMask = Map::IsExtensibleBit::kMask | Map::IsPrototypeMapBit::kMask;
int kExpected = Map::IsExtensibleBit::kMask;
return Word32Equal(Word32And(LoadMapBitField2(map), Int32Constant(kMask)),
return Word32Equal(Word32And(LoadMapBitField3(map), Int32Constant(kMask)),
Int32Constant(kExpected));
}
......
......@@ -2633,13 +2633,13 @@ BIMODAL_ACCESSOR_C(JSTypedArray, size_t, length)
BIMODAL_ACCESSOR(JSTypedArray, HeapObject, buffer)
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_deprecated, Map::IsDeprecatedBit)
BIMODAL_ACCESSOR_B(Map, bit_field3, NumberOfOwnDescriptors,
Map::NumberOfOwnDescriptorsBits)
BIMODAL_ACCESSOR_B(Map, bit_field3, is_migration_target,
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, is_access_check_needed,
Map::IsAccessCheckNeededBit)
......
......@@ -1977,15 +1977,15 @@ Map Factory::InitializeMap(Map map, InstanceType type, int instance_size,
// |layout_descriptor| are set.
map.set_visitor_id(Map::GetVisitorId(map));
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) |
Map::OwnsDescriptorsBit::encode(true) |
Map::ConstructionCounterBits::encode(Map::kNoSlackTracking);
Map::ConstructionCounterBits::encode(Map::kNoSlackTracking) |
Map::IsExtensibleBit::encode(true);
map.set_bit_field3(bit_field3);
DCHECK(!map.is_in_retained_map_list());
map.clear_padding();
map.set_elements_kind(elements_kind);
map.set_new_target_is_base(true);
isolate()->counters()->maps_created()->Increment();
if (FLAG_trace_maps) LOG(isolate(), MapCreate(map));
return map;
......
......@@ -150,11 +150,11 @@ AllocationResult Heap::AllocatePartialMap(InstanceType instance_type,
map.SetInObjectUnusedPropertyFields(0);
map.set_bit_field(0);
map.set_bit_field2(0);
DCHECK(!map.is_in_retained_map_list());
int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) |
Map::OwnsDescriptorsBit::encode(true) |
Map::ConstructionCounterBits::encode(Map::kNoSlackTracking);
map.set_bit_field3(bit_field3);
DCHECK(!map.is_in_retained_map_list());
map.clear_padding();
map.set_elements_kind(TERMINAL_FAST_ELEMENTS_KIND);
return map;
......
......@@ -2087,13 +2087,13 @@ void AccessorAssembler::NameDictionaryNegativeLookup(Node* object,
}
void AccessorAssembler::InvalidateValidityCellIfPrototype(Node* map,
Node* bitfield2) {
Node* bitfield3) {
Label is_prototype(this), cont(this);
if (bitfield2 == nullptr) {
bitfield2 = LoadMapBitField2(map);
if (bitfield3 == nullptr) {
bitfield3 = LoadMapBitField3(map);
}
Branch(IsSetWord32(bitfield2, Map::IsPrototypeMapBit::kMask), &is_prototype,
Branch(IsSetWord32(bitfield3, Map::IsPrototypeMapBit::kMask), &is_prototype,
&cont);
BIND(&is_prototype);
......
......@@ -127,7 +127,7 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler {
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,
Node* descriptors,
......
......@@ -869,9 +869,9 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
{
CheckForAssociatedProtector(p->name, slow);
Label extensible(this);
Node* bitfield2 = LoadMapBitField2(receiver_map);
Node* bitfield3 = LoadMapBitField3(receiver_map);
GotoIf(IsPrivateSymbol(p->name), &extensible);
Branch(IsSetWord32<Map::IsExtensibleBit>(bitfield2), &extensible, slow);
Branch(IsSetWord32<Map::IsExtensibleBit>(bitfield3), &extensible, slow);
BIND(&extensible);
if (ShouldCheckPrototype()) {
......@@ -882,7 +882,7 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
ShouldReconfigureExisting() ? nullptr : &readonly, slow);
}
Label add_dictionary_property_slow(this);
InvalidateValidityCellIfPrototype(receiver_map, bitfield2);
InvalidateValidityCellIfPrototype(receiver_map, bitfield3);
Add<NameDictionary>(properties, CAST(p->name), p->value,
&add_dictionary_property_slow);
exit_point->Return(p->value);
......
......@@ -74,20 +74,20 @@ BIT_FIELD_ACCESSORS(Map, relaxed_bit_field, has_prototype_slot,
Map::HasPrototypeSlotBit)
// |bit_field2| fields.
BIT_FIELD_ACCESSORS(Map, bit_field2, is_extensible, Map::IsExtensibleBit)
BIT_FIELD_ACCESSORS(Map, bit_field2, is_prototype_map, Map::IsPrototypeMapBit)
BIT_FIELD_ACCESSORS(Map, bit_field2, new_target_is_base,
Map::NewTargetIsBaseBit)
BIT_FIELD_ACCESSORS(Map, bit_field2, is_immutable_proto,
Map::IsImmutablePrototypeBit)
// |bit_field3| fields.
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_in_retained_map_list,
Map::IsInRetainedMapListBit)
BIT_FIELD_ACCESSORS(Map, bit_field3, is_prototype_map, Map::IsPrototypeMapBit)
BIT_FIELD_ACCESSORS(Map, bit_field3, is_migration_target,
Map::IsMigrationTargetBit)
BIT_FIELD_ACCESSORS(Map, bit_field3, is_immutable_proto,
Map::IsImmutablePrototypeBit)
BIT_FIELD_ACCESSORS(Map, bit_field3, new_target_is_base,
Map::NewTargetIsBaseBit)
BIT_FIELD_ACCESSORS(Map, bit_field3, is_extensible, Map::IsExtensibleBit)
BIT_FIELD_ACCESSORS(Map, bit_field3, may_have_interesting_symbols,
Map::MayHaveInterestingSymbolsBit)
BIT_FIELD_ACCESSORS(Map, bit_field3, construction_counter,
......
......@@ -138,22 +138,22 @@ using MapHandles = std::vector<Handle<Map>>;
// | | - has_prototype_slot (bit 7) |
// +----------+---------------------------------------------+
// | Byte | [bit_field2] |
// | | - is_extensible (bit 0) |
// | | - is_prototype_map (bit 1) |
// | | - new_target_is_base (bit 0) |
// | | - is_immutable_proto (bit 1) |
// | | - unused bit (bit 2) |
// | | - elements_kind (bits 3..7) |
// +----+----------+---------------------------------------------+
// | Int | [bit_field3] |
// | | - enum_length (bit 0..9) |
// | | - number_of_own_descriptors (bit 10..19) |
// | | - is_dictionary_map (bit 20) |
// | | - owns_descriptors (bit 21) |
// | | - is_in_retained_map_list (bit 22) |
// | | - is_deprecated (bit 23) |
// | | - is_unstable (bit 24) |
// | | - is_migration_target (bit 25) |
// | | - is_immutable_proto (bit 26) |
// | | - new_target_is_base (bit 27) |
// | | - is_prototype_map (bit 20) |
// | | - is_dictionary_map (bit 21) |
// | | - owns_descriptors (bit 22) |
// | | - is_in_retained_map_list (bit 23) |
// | | - is_deprecated (bit 24) |
// | | - is_unstable (bit 25) |
// | | - is_migration_target (bit 26) |
// | | - is_extensible (bit 28) |
// | | - may_have_interesting_symbols (bit 28) |
// | | - construction_counter (bit 29..31) |
// | | |
......@@ -265,10 +265,10 @@ class Map : public HeapObject {
DECL_PRIMITIVE_ACCESSORS(bit_field2, byte)
// Bit positions for |bit_field2|.
#define MAP_BIT_FIELD2_FIELDS(V, _) \
V(IsExtensibleBit, bool, 1, _) \
V(IsPrototypeMapBit, bool, 1, _) \
V(UnusedBit, bool, 1, _) \
#define MAP_BIT_FIELD2_FIELDS(V, _) \
V(NewTargetIsBaseBit, bool, 1, _) \
V(IsImmutablePrototypeBit, bool, 1, _) \
V(UnusedBit, bool, 1, _) \
V(ElementsKindBits, ElementsKind, 5, _)
DEFINE_BIT_FIELDS(MAP_BIT_FIELD2_FIELDS)
......@@ -287,14 +287,14 @@ class Map : public HeapObject {
#define MAP_BIT_FIELD3_FIELDS(V, _) \
V(EnumLengthBits, int, kDescriptorIndexBitCount, _) \
V(NumberOfOwnDescriptorsBits, int, kDescriptorIndexBitCount, _) \
V(IsPrototypeMapBit, bool, 1, _) \
V(IsDictionaryMapBit, bool, 1, _) \
V(OwnsDescriptorsBit, bool, 1, _) \
V(IsInRetainedMapListBit, bool, 1, _) \
V(IsDeprecatedBit, bool, 1, _) \
V(IsUnstableBit, bool, 1, _) \
V(IsMigrationTargetBit, bool, 1, _) \
V(IsImmutablePrototypeBit, bool, 1, _) \
V(NewTargetIsBaseBit, bool, 1, _) \
V(IsExtensibleBit, bool, 1, _) \
V(MayHaveInterestingSymbolsBit, bool, 1, _) \
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