[compiler] Perform Map::bit_field_3 non-release/acquire if possible
We have to have special rules for bit_fields since we multiple accesors touch the same field. I used: * If the accessor is set at map initalization time only and: * only the main thread accesses it: non-atomic write/read * bg accesses it too: non-atomic write, relaxed read (read has to be relaxed due to the whole bit_field being modified concurrently via other bit_field3 accessors) * If the accessor is set after map initialization: * but it is not necessary for synchronization: relaxed write/read * If the accessor is needed for synchronization: release/acquire As a note, Map::NumberOfOwnDescriptors are the bits accessed by the concurrent marker. For concurrent marker reasons it can be relaxed, but we would like it to be release/acquire for the compiler since that's where we synchronize Maps with adding descriptors to the descriptor array. Bug: v8:7790, chromium:1150811 Change-Id: I0ba7d2f8cb81d65a487970b4ea0bfa2a4cb3a975 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2773286 Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org> Cr-Commit-Position: refs/heads/master@{#73911}
This commit is contained in:
parent
e101c057af
commit
f2b4272dae
@ -1340,7 +1340,8 @@ MapData::MapData(JSHeapBroker* broker, ObjectData** storage, Handle<Map> object,
|
||||
// is set to false when it was already false).
|
||||
bit_field_(object->relaxed_bit_field()),
|
||||
bit_field2_(object->bit_field2()),
|
||||
bit_field3_(object->bit_field3()),
|
||||
// Similar to the bit_field comment above.
|
||||
bit_field3_(object->relaxed_bit_field3()),
|
||||
can_be_deprecated_(object->NumberOfOwnDescriptors() > 0
|
||||
? object->CanBeDeprecated()
|
||||
: false),
|
||||
|
@ -90,19 +90,21 @@ BIT_FIELD_ACCESSORS(Map, bit_field2, is_immutable_proto,
|
||||
Map::Bits2::IsImmutablePrototypeBit)
|
||||
|
||||
// |bit_field3| fields.
|
||||
BIT_FIELD_ACCESSORS(Map, bit_field3, owns_descriptors,
|
||||
BIT_FIELD_ACCESSORS(Map, relaxed_bit_field3, owns_descriptors,
|
||||
Map::Bits3::OwnsDescriptorsBit)
|
||||
BIT_FIELD_ACCESSORS(Map, bit_field3, is_deprecated, Map::Bits3::IsDeprecatedBit)
|
||||
BIT_FIELD_ACCESSORS(Map, bit_field3, is_in_retained_map_list,
|
||||
BIT_FIELD_ACCESSORS(Map, release_acquire_bit_field3, is_deprecated,
|
||||
Map::Bits3::IsDeprecatedBit)
|
||||
BIT_FIELD_ACCESSORS(Map, relaxed_bit_field3, is_in_retained_map_list,
|
||||
Map::Bits3::IsInRetainedMapListBit)
|
||||
BIT_FIELD_ACCESSORS(Map, bit_field3, is_prototype_map,
|
||||
BIT_FIELD_ACCESSORS(Map, release_acquire_bit_field3, is_prototype_map,
|
||||
Map::Bits3::IsPrototypeMapBit)
|
||||
BIT_FIELD_ACCESSORS(Map, bit_field3, is_migration_target,
|
||||
BIT_FIELD_ACCESSORS(Map, relaxed_bit_field3, is_migration_target,
|
||||
Map::Bits3::IsMigrationTargetBit)
|
||||
BIT_FIELD_ACCESSORS(Map, bit_field3, is_extensible, Map::Bits3::IsExtensibleBit)
|
||||
BIT_FIELD_ACCESSORS(Map, relaxed_bit_field3, is_extensible,
|
||||
Map::Bits3::IsExtensibleBit)
|
||||
BIT_FIELD_ACCESSORS(Map, bit_field3, may_have_interesting_symbols,
|
||||
Map::Bits3::MayHaveInterestingSymbolsBit)
|
||||
BIT_FIELD_ACCESSORS(Map, bit_field3, construction_counter,
|
||||
BIT_FIELD_ACCESSORS(Map, relaxed_bit_field3, construction_counter,
|
||||
Map::Bits3::ConstructionCounterBits)
|
||||
|
||||
DEF_GETTER(Map, GetNamedInterceptor, InterceptorInfo) {
|
||||
@ -199,14 +201,15 @@ InternalIndex Map::LastAdded() const {
|
||||
}
|
||||
|
||||
int Map::NumberOfOwnDescriptors() const {
|
||||
return Bits3::NumberOfOwnDescriptorsBits::decode(bit_field3());
|
||||
return Bits3::NumberOfOwnDescriptorsBits::decode(
|
||||
release_acquire_bit_field3());
|
||||
}
|
||||
|
||||
void Map::SetNumberOfOwnDescriptors(int number) {
|
||||
DCHECK_LE(number, instance_descriptors().number_of_descriptors());
|
||||
CHECK_LE(static_cast<unsigned>(number),
|
||||
static_cast<unsigned>(kMaxNumberOfDescriptors));
|
||||
set_bit_field3(
|
||||
set_release_acquire_bit_field3(
|
||||
Bits3::NumberOfOwnDescriptorsBits::update(bit_field3(), number));
|
||||
}
|
||||
|
||||
@ -224,7 +227,7 @@ void Map::SetEnumLength(int length) {
|
||||
CHECK_LE(static_cast<unsigned>(length),
|
||||
static_cast<unsigned>(kMaxNumberOfDescriptors));
|
||||
}
|
||||
set_bit_field3(Bits3::EnumLengthBits::update(bit_field3(), length));
|
||||
set_relaxed_bit_field3(Bits3::EnumLengthBits::update(bit_field3(), length));
|
||||
}
|
||||
|
||||
FixedArrayBase Map::GetInitialElements() const {
|
||||
@ -471,6 +474,30 @@ void Map::set_bit_field2(byte value) {
|
||||
WriteField<byte>(kBitField2Offset, value);
|
||||
}
|
||||
|
||||
uint32_t Map::bit_field3() const {
|
||||
return ReadField<uint32_t>(kBitField3Offset);
|
||||
}
|
||||
|
||||
void Map::set_bit_field3(uint32_t value) {
|
||||
WriteField<uint32_t>(kBitField3Offset, value);
|
||||
}
|
||||
|
||||
uint32_t Map::relaxed_bit_field3() const {
|
||||
return RELAXED_READ_UINT32_FIELD(*this, kBitField3Offset);
|
||||
}
|
||||
|
||||
void Map::set_relaxed_bit_field3(uint32_t value) {
|
||||
RELAXED_WRITE_UINT32_FIELD(*this, kBitField3Offset, value);
|
||||
}
|
||||
|
||||
uint32_t Map::release_acquire_bit_field3() const {
|
||||
return ACQUIRE_READ_UINT32_FIELD(*this, kBitField3Offset);
|
||||
}
|
||||
|
||||
void Map::set_release_acquire_bit_field3(uint32_t value) {
|
||||
RELEASE_WRITE_UINT32_FIELD(*this, kBitField3Offset, value);
|
||||
}
|
||||
|
||||
bool Map::is_abandoned_prototype_map() const {
|
||||
return is_prototype_map() && !owns_descriptors();
|
||||
}
|
||||
@ -554,15 +581,16 @@ void Map::set_is_dictionary_map(bool value) {
|
||||
}
|
||||
|
||||
bool Map::is_dictionary_map() const {
|
||||
return Bits3::IsDictionaryMapBit::decode(bit_field3());
|
||||
return Bits3::IsDictionaryMapBit::decode(relaxed_bit_field3());
|
||||
}
|
||||
|
||||
void Map::mark_unstable() {
|
||||
set_bit_field3(Bits3::IsUnstableBit::update(bit_field3(), true));
|
||||
set_release_acquire_bit_field3(
|
||||
Bits3::IsUnstableBit::update(bit_field3(), true));
|
||||
}
|
||||
|
||||
bool Map::is_stable() const {
|
||||
return !Bits3::IsUnstableBit::decode(bit_field3());
|
||||
return !Bits3::IsUnstableBit::decode(release_acquire_bit_field3());
|
||||
}
|
||||
|
||||
bool Map::CanBeDeprecated() const {
|
||||
@ -619,14 +647,6 @@ void Map::InitializeDescriptors(Isolate* isolate, DescriptorArray descriptors) {
|
||||
descriptors.number_of_descriptors());
|
||||
}
|
||||
|
||||
void Map::set_bit_field3(uint32_t bits) {
|
||||
RELEASE_WRITE_UINT32_FIELD(*this, kBitField3Offset, bits);
|
||||
}
|
||||
|
||||
uint32_t Map::bit_field3() const {
|
||||
return ACQUIRE_READ_UINT32_FIELD(*this, kBitField3Offset);
|
||||
}
|
||||
|
||||
void Map::clear_padding() {
|
||||
if (FIELD_SIZE(kOptionalPaddingOffset) == 0) return;
|
||||
DCHECK_EQ(4, FIELD_SIZE(kOptionalPaddingOffset));
|
||||
|
@ -1224,7 +1224,8 @@ Handle<Map> Map::RawCopy(Isolate* isolate, Handle<Map> map, int instance_size,
|
||||
if (!map->is_dictionary_map()) {
|
||||
new_bit_field3 = Bits3::IsUnstableBit::update(new_bit_field3, false);
|
||||
}
|
||||
result->set_bit_field3(new_bit_field3);
|
||||
// Same as bit_field comment above.
|
||||
result->set_relaxed_bit_field3(new_bit_field3);
|
||||
result->clear_padding();
|
||||
return result;
|
||||
}
|
||||
|
@ -267,6 +267,8 @@ class Map : public HeapObject {
|
||||
// Bit field 3.
|
||||
//
|
||||
DECL_PRIMITIVE_ACCESSORS(bit_field3, uint32_t)
|
||||
DECL_PRIMITIVE_ACCESSORS(relaxed_bit_field3, uint32_t)
|
||||
DECL_PRIMITIVE_ACCESSORS(release_acquire_bit_field3, uint32_t)
|
||||
|
||||
// Clear uninitialized padding space. This ensures that the snapshot content
|
||||
// is deterministic. Depending on the V8 build mode there could be no padding.
|
||||
|
Loading…
Reference in New Issue
Block a user