Commit ea5ba5db authored by Mike Stanton's avatar Mike Stanton Committed by Commit Bot

[TurboFan] Code object needs some relaxed load/stores

We got a TSAN
warning because of the non-atomic store of the code pointer in
a JSFunction in the interpreter builtin (when the pointer is
discovered in the FeedbackVector). However, we know this store is
safe because we guarantee a release store into the
FeedbackVector. However, TSAN can't recognize this interesting
triple relation. Therefore, we mark the fields we need to read
from TurboFan as relaxed.

Bug: v8:11501, v8:7790
Change-Id: I20652216294db540bf9c20e5067a6362fea07dc3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2721762Reviewed-by: 's avatarMichael Stanton <mvstanton@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Commit-Queue: Michael Stanton <mvstanton@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73098}
parent 2ea82355
...@@ -327,7 +327,8 @@ int Code::CodeSize() const { return SizeFor(raw_body_size()); } ...@@ -327,7 +327,8 @@ int Code::CodeSize() const { return SizeFor(raw_body_size()); }
CodeKind Code::kind() const { CodeKind Code::kind() const {
STATIC_ASSERT(FIELD_SIZE(kFlagsOffset) == kInt32Size); STATIC_ASSERT(FIELD_SIZE(kFlagsOffset) == kInt32Size);
return KindField::decode(ReadField<uint32_t>(kFlagsOffset)); const uint32_t flags = RELAXED_READ_UINT32_FIELD(*this, kFlagsOffset);
return KindField::decode(flags);
} }
int Code::GetBytecodeOffsetForBaselinePC(Address baseline_pc) { int Code::GetBytecodeOffsetForBaselinePC(Address baseline_pc) {
...@@ -386,7 +387,7 @@ void Code::initialize_flags(CodeKind kind, bool is_turbofanned, int stack_slots, ...@@ -386,7 +387,7 @@ void Code::initialize_flags(CodeKind kind, bool is_turbofanned, int stack_slots,
StackSlotsField::encode(stack_slots) | StackSlotsField::encode(stack_slots) |
IsOffHeapTrampoline::encode(is_off_heap_trampoline); IsOffHeapTrampoline::encode(is_off_heap_trampoline);
STATIC_ASSERT(FIELD_SIZE(kFlagsOffset) == kInt32Size); STATIC_ASSERT(FIELD_SIZE(kFlagsOffset) == kInt32Size);
WriteField<uint32_t>(kFlagsOffset, flags); RELAXED_WRITE_UINT32_FIELD(*this, kFlagsOffset, flags);
DCHECK_IMPLIES(stack_slots != 0, has_safepoint_info()); DCHECK_IMPLIES(stack_slots != 0, has_safepoint_info());
} }
...@@ -423,7 +424,8 @@ inline bool Code::has_tagged_outgoing_params() const { ...@@ -423,7 +424,8 @@ inline bool Code::has_tagged_outgoing_params() const {
} }
inline bool Code::is_turbofanned() const { inline bool Code::is_turbofanned() const {
return IsTurbofannedField::decode(ReadField<uint32_t>(kFlagsOffset)); const uint32_t flags = RELAXED_READ_UINT32_FIELD(*this, kFlagsOffset);
return IsTurbofannedField::decode(flags);
} }
inline bool Code::can_have_weak_objects() const { inline bool Code::can_have_weak_objects() const {
...@@ -469,7 +471,8 @@ inline void Code::set_is_exception_caught(bool value) { ...@@ -469,7 +471,8 @@ inline void Code::set_is_exception_caught(bool value) {
} }
inline bool Code::is_off_heap_trampoline() const { inline bool Code::is_off_heap_trampoline() const {
return IsOffHeapTrampoline::decode(ReadField<uint32_t>(kFlagsOffset)); const uint32_t flags = RELAXED_READ_UINT32_FIELD(*this, kFlagsOffset);
return IsOffHeapTrampoline::decode(flags);
} }
inline HandlerTable::CatchPrediction Code::GetBuiltinCatchPrediction() { inline HandlerTable::CatchPrediction Code::GetBuiltinCatchPrediction() {
...@@ -494,14 +497,14 @@ bool Code::is_builtin() const { ...@@ -494,14 +497,14 @@ bool Code::is_builtin() const {
} }
unsigned Code::inlined_bytecode_size() const { unsigned Code::inlined_bytecode_size() const {
DCHECK(CodeKindIsOptimizedJSFunction(kind()) || unsigned size = RELAXED_READ_UINT_FIELD(*this, kInlinedBytecodeSizeOffset);
ReadField<unsigned>(kInlinedBytecodeSizeOffset) == 0); DCHECK(CodeKindIsOptimizedJSFunction(kind()) || size == 0);
return ReadField<unsigned>(kInlinedBytecodeSizeOffset); return size;
} }
void Code::set_inlined_bytecode_size(unsigned size) { void Code::set_inlined_bytecode_size(unsigned size) {
DCHECK(CodeKindIsOptimizedJSFunction(kind()) || size == 0); DCHECK(CodeKindIsOptimizedJSFunction(kind()) || size == 0);
WriteField<unsigned>(kInlinedBytecodeSizeOffset, size); RELAXED_WRITE_UINT_FIELD(*this, kInlinedBytecodeSizeOffset, size);
} }
bool Code::has_safepoint_info() const { bool Code::has_safepoint_info() const {
...@@ -510,7 +513,8 @@ bool Code::has_safepoint_info() const { ...@@ -510,7 +513,8 @@ bool Code::has_safepoint_info() const {
int Code::stack_slots() const { int Code::stack_slots() const {
DCHECK(has_safepoint_info()); DCHECK(has_safepoint_info());
return StackSlotsField::decode(ReadField<uint32_t>(kFlagsOffset)); const uint32_t flags = RELAXED_READ_UINT32_FIELD(*this, kFlagsOffset);
return StackSlotsField::decode(flags);
} }
bool Code::marked_for_deoptimization() const { bool Code::marked_for_deoptimization() const {
......
...@@ -563,6 +563,14 @@ static_assert(sizeof(int) == sizeof(int32_t), ...@@ -563,6 +563,14 @@ static_assert(sizeof(int) == sizeof(int32_t),
#define RELAXED_WRITE_INT_FIELD(p, offset, value) \ #define RELAXED_WRITE_INT_FIELD(p, offset, value) \
RELAXED_WRITE_INT32_FIELD(p, offset, value) RELAXED_WRITE_INT32_FIELD(p, offset, value)
static_assert(sizeof(unsigned) == sizeof(uint32_t),
"sizeof unsigned must match sizeof uint32_t");
#define RELAXED_READ_UINT_FIELD(p, offset) RELAXED_READ_UINT32_FIELD(p, offset)
#define RELAXED_WRITE_UINT_FIELD(p, offset, value) \
RELAXED_WRITE_UINT32_FIELD(p, offset, value)
#define RELAXED_READ_BYTE_FIELD(p, offset) \ #define RELAXED_READ_BYTE_FIELD(p, offset) \
static_cast<byte>(base::Relaxed_Load( \ static_cast<byte>(base::Relaxed_Load( \
reinterpret_cast<const base::Atomic8*>(FIELD_ADDR(p, offset)))) reinterpret_cast<const base::Atomic8*>(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