Commit f39a3b99 authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

Make code_data_container and kind_specific_flags accessors atomic.

The concurrent marker needs to access the kind_specific_flags to decide
whether an embedded object reference is weak or not.

This patch turns the Code::code_data_container() into an acquire/release
atomic accessor and makes CodeDataContainer::kind_specific_flags a
relaxed atomic accessor.

Bug: v8:8459
Change-Id: I5251fed4e7b3315f8e229dfcfe2c23f611f4b333
Reviewed-on: https://chromium-review.googlesource.com/c/1337746Reviewed-by: 's avatarHannes Payer <hpayer@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57638}
parent aded96db
......@@ -187,10 +187,15 @@ INT_ACCESSORS(Code, raw_instruction_size, kInstructionSizeOffset)
INT_ACCESSORS(Code, handler_table_offset, kHandlerTableOffsetOffset)
#define CODE_ACCESSORS(name, type, offset) \
ACCESSORS_CHECKED2(Code, name, type, offset, true, !Heap::InNewSpace(value))
#define SYNCHRONIZED_CODE_ACCESSORS(name, type, offset) \
SYNCHRONIZED_ACCESSORS_CHECKED2(Code, name, type, offset, true, \
!Heap::InNewSpace(value))
CODE_ACCESSORS(relocation_info, ByteArray, kRelocationInfoOffset)
CODE_ACCESSORS(deoptimization_data, FixedArray, kDeoptimizationDataOffset)
CODE_ACCESSORS(source_position_table, Object, kSourcePositionTableOffset)
CODE_ACCESSORS(code_data_container, CodeDataContainer, kCodeDataContainerOffset)
// Concurrent marker needs to access kind specific flags in code data container.
SYNCHRONIZED_CODE_ACCESSORS(code_data_container, CodeDataContainer,
kCodeDataContainerOffset)
#undef CODE_ACCESSORS
void Code::WipeOutHeader() {
......@@ -404,53 +409,53 @@ inline bool Code::is_turbofanned() const {
inline bool Code::can_have_weak_objects() const {
DCHECK(kind() == OPTIMIZED_FUNCTION);
int flags = code_data_container()->kind_specific_flags();
int32_t flags = code_data_container()->kind_specific_flags();
return CanHaveWeakObjectsField::decode(flags);
}
inline void Code::set_can_have_weak_objects(bool value) {
DCHECK(kind() == OPTIMIZED_FUNCTION);
int previous = code_data_container()->kind_specific_flags();
int updated = CanHaveWeakObjectsField::update(previous, value);
int32_t previous = code_data_container()->kind_specific_flags();
int32_t updated = CanHaveWeakObjectsField::update(previous, value);
code_data_container()->set_kind_specific_flags(updated);
}
inline bool Code::is_construct_stub() const {
DCHECK(kind() == BUILTIN);
int flags = code_data_container()->kind_specific_flags();
int32_t flags = code_data_container()->kind_specific_flags();
return IsConstructStubField::decode(flags);
}
inline void Code::set_is_construct_stub(bool value) {
DCHECK(kind() == BUILTIN);
int previous = code_data_container()->kind_specific_flags();
int updated = IsConstructStubField::update(previous, value);
int32_t previous = code_data_container()->kind_specific_flags();
int32_t updated = IsConstructStubField::update(previous, value);
code_data_container()->set_kind_specific_flags(updated);
}
inline bool Code::is_promise_rejection() const {
DCHECK(kind() == BUILTIN);
int flags = code_data_container()->kind_specific_flags();
int32_t flags = code_data_container()->kind_specific_flags();
return IsPromiseRejectionField::decode(flags);
}
inline void Code::set_is_promise_rejection(bool value) {
DCHECK(kind() == BUILTIN);
int previous = code_data_container()->kind_specific_flags();
int updated = IsPromiseRejectionField::update(previous, value);
int32_t previous = code_data_container()->kind_specific_flags();
int32_t updated = IsPromiseRejectionField::update(previous, value);
code_data_container()->set_kind_specific_flags(updated);
}
inline bool Code::is_exception_caught() const {
DCHECK(kind() == BUILTIN);
int flags = code_data_container()->kind_specific_flags();
int32_t flags = code_data_container()->kind_specific_flags();
return IsExceptionCaughtField::decode(flags);
}
inline void Code::set_is_exception_caught(bool value) {
DCHECK(kind() == BUILTIN);
int previous = code_data_container()->kind_specific_flags();
int updated = IsExceptionCaughtField::update(previous, value);
int32_t previous = code_data_container()->kind_specific_flags();
int32_t updated = IsExceptionCaughtField::update(previous, value);
code_data_container()->set_kind_specific_flags(updated);
}
......@@ -500,43 +505,43 @@ void Code::set_safepoint_table_offset(int offset) {
bool Code::marked_for_deoptimization() const {
DCHECK(kind() == OPTIMIZED_FUNCTION);
int flags = code_data_container()->kind_specific_flags();
int32_t flags = code_data_container()->kind_specific_flags();
return MarkedForDeoptimizationField::decode(flags);
}
void Code::set_marked_for_deoptimization(bool flag) {
DCHECK(kind() == OPTIMIZED_FUNCTION);
DCHECK_IMPLIES(flag, AllowDeoptimization::IsAllowed(GetIsolate()));
int previous = code_data_container()->kind_specific_flags();
int updated = MarkedForDeoptimizationField::update(previous, flag);
int32_t previous = code_data_container()->kind_specific_flags();
int32_t updated = MarkedForDeoptimizationField::update(previous, flag);
code_data_container()->set_kind_specific_flags(updated);
}
bool Code::embedded_objects_cleared() const {
DCHECK(kind() == OPTIMIZED_FUNCTION);
int flags = code_data_container()->kind_specific_flags();
int32_t flags = code_data_container()->kind_specific_flags();
return EmbeddedObjectsClearedField::decode(flags);
}
void Code::set_embedded_objects_cleared(bool flag) {
DCHECK(kind() == OPTIMIZED_FUNCTION);
DCHECK_IMPLIES(flag, marked_for_deoptimization());
int previous = code_data_container()->kind_specific_flags();
int updated = EmbeddedObjectsClearedField::update(previous, flag);
int32_t previous = code_data_container()->kind_specific_flags();
int32_t updated = EmbeddedObjectsClearedField::update(previous, flag);
code_data_container()->set_kind_specific_flags(updated);
}
bool Code::deopt_already_counted() const {
DCHECK(kind() == OPTIMIZED_FUNCTION);
int flags = code_data_container()->kind_specific_flags();
int32_t flags = code_data_container()->kind_specific_flags();
return DeoptAlreadyCountedField::decode(flags);
}
void Code::set_deopt_already_counted(bool flag) {
DCHECK(kind() == OPTIMIZED_FUNCTION);
DCHECK_IMPLIES(flag, AllowDeoptimization::IsAllowed(GetIsolate()));
int previous = code_data_container()->kind_specific_flags();
int updated = DeoptAlreadyCountedField::update(previous, flag);
int32_t previous = code_data_container()->kind_specific_flags();
int32_t updated = DeoptAlreadyCountedField::update(previous, flag);
code_data_container()->set_kind_specific_flags(updated);
}
......@@ -606,7 +611,10 @@ bool Code::IsWeakObjectInOptimizedCode(HeapObject* object) {
InstanceTypeChecker::IsContext(instance_type);
}
INT_ACCESSORS(CodeDataContainer, kind_specific_flags, kKindSpecificFlagsOffset)
// This field has to have relaxed atomic accessors because it is accessed in the
// concurrent marker.
RELAXED_INT32_ACCESSORS(CodeDataContainer, kind_specific_flags,
kKindSpecificFlagsOffset)
ACCESSORS(CodeDataContainer, next_code_link, Object, kNextCodeLinkOffset)
void CodeDataContainer::clear_padding() {
......
......@@ -118,6 +118,14 @@
WRITE_INT32_FIELD(this, offset, value); \
}
#define RELAXED_INT32_ACCESSORS(holder, name, offset) \
int32_t holder::name() const { \
return RELAXED_READ_INT32_FIELD(this, offset); \
} \
void holder::set_##name(int32_t value) { \
RELAXED_WRITE_INT32_FIELD(this, offset, value); \
}
#define UINT16_ACCESSORS(holder, name, offset) \
uint16_t holder::name() const { return READ_UINT16_FIELD(this, offset); } \
void holder::set_##name(int value) { \
......@@ -425,9 +433,18 @@
#define READ_INT32_FIELD(p, offset) \
(*reinterpret_cast<const int32_t*>(FIELD_ADDR(p, offset)))
#define RELAXED_READ_INT32_FIELD(p, offset) \
static_cast<int32_t>(base::Relaxed_Load( \
reinterpret_cast<const base::Atomic32*>(FIELD_ADDR(p, offset))))
#define WRITE_INT32_FIELD(p, offset, value) \
(*reinterpret_cast<int32_t*>(FIELD_ADDR(p, offset)) = value)
#define RELAXED_WRITE_INT32_FIELD(p, offset, value) \
base::Relaxed_Store( \
reinterpret_cast<base::Atomic32*>(FIELD_ADDR(p, offset)), \
static_cast<base::Atomic32>(value));
#define READ_FLOAT_FIELD(p, offset) \
(*reinterpret_cast<const float*>(FIELD_ADDR(p, offset)))
......
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