Commit 12bb6c21 authored by Santiago Aboy Solanes's avatar Santiago Aboy Solanes Committed by Commit Bot

[compiler] Mark Map's bit_field set/get as non-atomic or relaxed

Most of Map's bit_field (as in not 2 or 3) accessors are not set after
construction e.g. is_callable. They are also not used as a
synchronization point. From the compiler's point of view, they can be
set as non-atomic. There are two accessors (`prototype_slot` and
`non_instance_prototype`) that have to be atomic for concurrent marker
reasons (relaxed is fine for them).

Bug: v8:7790, chromium:1150811
Change-Id: Ic3c81a59e7895ee9c35a128bb10656040b19dd42
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2752154Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73432}
parent b9ccf865
......@@ -704,7 +704,6 @@ Handle<JSFunction> ApiNatives::CreateApiFunction(
Handle<Map> map = isolate->factory()->NewMap(type, instance_size,
TERMINAL_FAST_ELEMENTS_KIND);
JSFunction::SetInitialMap(result, map, Handle<JSObject>::cast(prototype));
// Mark as undetectable if needed.
if (obj->undetectable()) {
......@@ -740,6 +739,7 @@ Handle<JSFunction> ApiNatives::CreateApiFunction(
if (immutable_proto) map->set_is_immutable_proto(true);
JSFunction::SetInitialMap(result, map, Handle<JSObject>::cast(prototype));
return result;
}
......
......@@ -62,21 +62,26 @@ ACCESSORS_CHECKED(Map, prototype_info, Object,
// is explicitly allowlisted here. The former is never modified after the map
// is setup but it's being read by concurrent marker when pointer compression
// is enabled. The latter bit can be modified on a live objects.
BIT_FIELD_ACCESSORS(Map, bit_field, has_non_instance_prototype,
BIT_FIELD_ACCESSORS(Map, relaxed_bit_field, has_non_instance_prototype,
Map::Bits1::HasNonInstancePrototypeBit)
BIT_FIELD_ACCESSORS(Map, bit_field, is_callable, Map::Bits1::IsCallableBit)
BIT_FIELD_ACCESSORS(Map, bit_field, has_named_interceptor,
BIT_FIELD_ACCESSORS(Map, relaxed_bit_field, has_prototype_slot,
Map::Bits1::HasPrototypeSlotBit)
// These are fine to be written as non-atomic since we don't have data races.
// However, they have to be read atomically from the background since the
// |bit_field| as a whole can mutate when using the above setters.
BIT_FIELD_ACCESSORS2(Map, relaxed_bit_field, bit_field, is_callable,
Map::Bits1::IsCallableBit)
BIT_FIELD_ACCESSORS2(Map, relaxed_bit_field, bit_field, has_named_interceptor,
Map::Bits1::HasNamedInterceptorBit)
BIT_FIELD_ACCESSORS(Map, bit_field, has_indexed_interceptor,
BIT_FIELD_ACCESSORS2(Map, relaxed_bit_field, bit_field, has_indexed_interceptor,
Map::Bits1::HasIndexedInterceptorBit)
BIT_FIELD_ACCESSORS(Map, bit_field, is_undetectable,
BIT_FIELD_ACCESSORS2(Map, relaxed_bit_field, bit_field, is_undetectable,
Map::Bits1::IsUndetectableBit)
BIT_FIELD_ACCESSORS(Map, bit_field, is_access_check_needed,
BIT_FIELD_ACCESSORS2(Map, relaxed_bit_field, bit_field, is_access_check_needed,
Map::Bits1::IsAccessCheckNeededBit)
BIT_FIELD_ACCESSORS(Map, bit_field, is_constructor,
BIT_FIELD_ACCESSORS2(Map, relaxed_bit_field, bit_field, is_constructor,
Map::Bits1::IsConstructorBit)
BIT_FIELD_ACCESSORS(Map, bit_field, has_prototype_slot,
Map::Bits1::HasPrototypeSlotBit)
// |bit_field2| fields.
BIT_FIELD_ACCESSORS(Map, bit_field2, new_target_is_base,
......@@ -437,12 +442,18 @@ void Map::AccountAddedOutOfObjectPropertyField(int unused_in_property_array) {
DCHECK_EQ(unused_in_property_array, UnusedPropertyFields());
}
byte Map::bit_field() const {
return ACQUIRE_READ_BYTE_FIELD(*this, kBitFieldOffset);
}
byte Map::bit_field() const { return ReadField<byte>(kBitFieldOffset); }
void Map::set_bit_field(byte value) {
RELEASE_WRITE_BYTE_FIELD(*this, kBitFieldOffset, value);
WriteField<byte>(kBitFieldOffset, value);
}
byte Map::relaxed_bit_field() const {
return RELAXED_READ_BYTE_FIELD(*this, kBitFieldOffset);
}
void Map::set_relaxed_bit_field(byte value) {
RELAXED_WRITE_BYTE_FIELD(*this, kBitFieldOffset, value);
}
byte Map::bit_field2() const {
......
......@@ -245,6 +245,8 @@ class Map : public HeapObject {
// Bit field.
//
DECL_PRIMITIVE_ACCESSORS(bit_field, byte)
// Atomic accessors, used for allowlisting legitimate concurrent accesses.
DECL_PRIMITIVE_ACCESSORS(relaxed_bit_field, byte)
// Bit positions for |bit_field|.
struct Bits1 {
......
......@@ -11,6 +11,8 @@
#undef OBJECT_CONSTRUCTORS_IMPL_CHECK_SUPER
#undef NEVER_READ_ONLY_SPACE
#undef NEVER_READ_ONLY_SPACE_IMPL
#undef DECL_PRIMITIVE_GETTER
#undef DECL_PRIMITIVE_SETTER
#undef DECL_PRIMITIVE_ACCESSORS
#undef DECL_SYNCHRONIZED_PRIMITIVE_ACCESSORS
#undef DECL_BOOLEAN_ACCESSORS
......@@ -32,6 +34,7 @@
#undef DECL_ACQUIRE_GETTER
#undef DECL_RELEASE_SETTER
#undef DECL_RELEASE_ACQUIRE_ACCESSORS
#undef DECL_RELEASE_ACQUIRE_WEAK_ACCESSORS
#undef DECL_CAST
#undef CAST_ACCESSOR
#undef INT_ACCESSORS
......@@ -53,15 +56,18 @@
#undef WEAK_ACCESSORS_CHECKED2
#undef WEAK_ACCESSORS_CHECKED
#undef WEAK_ACCESSORS
#undef SYNCHRONIZED_WEAK_ACCESSORS_CHECKED2
#undef SYNCHRONIZED_WEAK_ACCESSORS_CHECKED
#undef SYNCHRONIZED_WEAK_ACCESSORS
#undef RELEASE_ACQUIRE_WEAK_ACCESSORS_CHECKED2
#undef RELEASE_ACQUIRE_WEAK_ACCESSORS_CHECKED
#undef RELEASE_ACQUIRE_WEAK_ACCESSORS
#undef SMI_ACCESSORS_CHECKED
#undef SMI_ACCESSORS
#undef SYNCHRONIZED_SMI_ACCESSORS
#undef RELAXED_SMI_ACCESSORS
#undef BOOL_GETTER
#undef BOOL_ACCESSORS
#undef DECL_RELAXED_BOOL_ACCESSORS
#undef RELAXED_BOOL_ACCESSORS
#undef BIT_FIELD_ACCESSORS2
#undef BIT_FIELD_ACCESSORS
#undef INSTANCE_TYPE_CHECKER
#undef TYPE_CHECKER
......@@ -83,6 +89,8 @@
#undef ACQUIRE_READ_INT32_FIELD
#undef RELAXED_WRITE_INT8_FIELD
#undef RELAXED_READ_INT8_FIELD
#undef RELAXED_READ_UINT16_FIELD
#undef RELAXED_WRITE_UINT16_FIELD
#undef RELAXED_READ_INT16_FIELD
#undef RELAXED_WRITE_INT16_FIELD
#undef RELAXED_READ_UINT32_FIELD
......@@ -92,6 +100,10 @@
#undef RELAXED_READ_INT32_FIELD
#undef RELEASE_WRITE_INT32_FIELD
#undef RELAXED_WRITE_INT32_FIELD
#undef RELAXED_READ_INT_FIELD
#undef RELAXED_WRITE_INT_FIELD
#undef RELAXED_READ_UINT_FIELD
#undef RELAXED_WRITE_UINT_FIELD
#undef RELAXED_READ_BYTE_FIELD
#undef ACQUIRE_READ_BYTE_FIELD
#undef RELAXED_WRITE_BYTE_FIELD
......
......@@ -364,14 +364,17 @@
kRelaxedStore); \
}
#define BIT_FIELD_ACCESSORS(holder, field, name, BitField) \
#define BIT_FIELD_ACCESSORS2(holder, get_field, set_field, name, BitField) \
typename BitField::FieldType holder::name() const { \
return BitField::decode(field()); \
return BitField::decode(get_field()); \
} \
void holder::set_##name(typename BitField::FieldType value) { \
set_##field(BitField::update(field(), value)); \
set_##set_field(BitField::update(set_field(), value)); \
}
#define BIT_FIELD_ACCESSORS(holder, field, name, BitField) \
BIT_FIELD_ACCESSORS2(holder, field, field, name, BitField)
#define INSTANCE_TYPE_CHECKER(type, forinstancetype) \
V8_INLINE bool Is##type(InstanceType instance_type) { \
return instance_type == forinstancetype; \
......
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