Fix TSAN Warning

Avoid data hazard in multi-thread cases

Issue: IAVDMU

Signed-off-by: zbx <zhangboxiao1@huawei.com>
Change-Id: I3210def0df57e3d75234c59e5c2d2380b88fae77
This commit is contained in:
zbx 2024-10-10 09:30:21 +08:00
parent 00e623a192
commit eb1c1456b3
4 changed files with 28 additions and 9 deletions

View File

@ -184,6 +184,24 @@
Set##bitFieldName(name##Bits::Update(Get##bitFieldName(), t)); \ Set##bitFieldName(name##Bits::Update(Get##bitFieldName(), t)); \
} }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define ACCESSORS_PRIMITIVE_FIELD_ATOMIC(name, type, offset) \
inline void AtomicSet##name(type value) \
{ \
volatile auto *atomicField = reinterpret_cast<volatile std::atomic<type> *>(ToUintPtr(this) + (offset)); \
atomicField->store(value, std::memory_order_release); \
} \
inline type AtomicGet##name() const \
{ \
volatile auto *atomicField = reinterpret_cast<volatile std::atomic<type> *>(ToUintPtr(this) + (offset)); \
return atomicField->load(std::memory_order_acquire); \
}
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define ACCESSORS_PRIMITIVE_FIELD_HAS_ATOMIC_INTERFACE(name, type, offset, endOffset) \
ACCESSORS_PRIMITIVE_FIELD(name, type, offset, endOffset) \
ACCESSORS_PRIMITIVE_FIELD_ATOMIC(name, type, offset)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define FIRST_BIT_FIELD(bitFieldName, name, type, bits) \ #define FIRST_BIT_FIELD(bitFieldName, name, type, bits) \
using name##Bits = BitField<type, 0, bits>; \ using name##Bits = BitField<type, 0, bits>; \

View File

@ -28,7 +28,6 @@ uintptr_t WorkSpaceChunk::NewArea(size_t size)
LOG_ECMA_MEM(FATAL) << "OOM WorkSpaceChunk : NewArea area is nullptr"; LOG_ECMA_MEM(FATAL) << "OOM WorkSpaceChunk : NewArea area is nullptr";
UNREACHABLE(); UNREACHABLE();
} }
allocator_->IncreaseNativeSizeStats(size, NativeFlag::CHUNK_MEM);
areaList_.emplace(area, area); areaList_.emplace(area, area);
return area; return area;
} }

View File

@ -130,9 +130,9 @@ public:
void SetAotCodeBit(bool isCompiled) void SetAotCodeBit(bool isCompiled)
{ {
uint64_t callField = GetCallField(); uint64_t callField = AtomicGetCallField();
uint64_t newValue = SetAotCodeBit(callField, isCompiled); uint64_t newValue = SetAotCodeBit(callField, isCompiled);
SetCallField(newValue); AtomicSetCallField(newValue);
} }
void SetFastBuiltinBit(bool isFastBuiltin) void SetFastBuiltinBit(bool isFastBuiltin)
@ -174,7 +174,7 @@ public:
bool IsAotWithCallField() const bool IsAotWithCallField() const
{ {
uint64_t callField = GetCallField(); uint64_t callField = AtomicGetCallField();
return MethodLiteral::IsAotWithCallField(callField); return MethodLiteral::IsAotWithCallField(callField);
} }
@ -320,14 +320,14 @@ public:
void SetFunctionKind(FunctionKind kind) void SetFunctionKind(FunctionKind kind)
{ {
uint64_t extraLiteralInfo = GetExtraLiteralInfo(); uint64_t extraLiteralInfo = AtomicGetExtraLiteralInfo();
uint64_t newValue = SetFunctionKind(extraLiteralInfo, kind); uint64_t newValue = SetFunctionKind(extraLiteralInfo, kind);
SetExtraLiteralInfo(newValue); AtomicSetExtraLiteralInfo(newValue);
} }
FunctionKind GetFunctionKind() const FunctionKind GetFunctionKind() const
{ {
uint64_t extraLiteralInfo = GetExtraLiteralInfo(); uint64_t extraLiteralInfo = AtomicGetExtraLiteralInfo();
return GetFunctionKind(extraLiteralInfo); return GetFunctionKind(extraLiteralInfo);
} }
@ -484,14 +484,15 @@ public:
static constexpr size_t CONSTANT_POOL_OFFSET = TaggedObjectSize(); static constexpr size_t CONSTANT_POOL_OFFSET = TaggedObjectSize();
ACCESSORS(ConstantPool, CONSTANT_POOL_OFFSET, CALL_FIELD_OFFSET) ACCESSORS(ConstantPool, CONSTANT_POOL_OFFSET, CALL_FIELD_OFFSET)
ACCESSORS_PRIMITIVE_FIELD(CallField, uint64_t, CALL_FIELD_OFFSET, NATIVE_POINTER_OR_BYTECODE_ARRAY_OFFSET) ACCESSORS_PRIMITIVE_FIELD_HAS_ATOMIC_INTERFACE(CallField, uint64_t, CALL_FIELD_OFFSET,
NATIVE_POINTER_OR_BYTECODE_ARRAY_OFFSET)
// Native method decides this filed is NativePointer or BytecodeArray pointer. // Native method decides this filed is NativePointer or BytecodeArray pointer.
ACCESSORS_NATIVE_FIELD( ACCESSORS_NATIVE_FIELD(
NativePointerOrBytecodeArray, void, NATIVE_POINTER_OR_BYTECODE_ARRAY_OFFSET, CODEENTRY_LITERAL_OFFSET) NativePointerOrBytecodeArray, void, NATIVE_POINTER_OR_BYTECODE_ARRAY_OFFSET, CODEENTRY_LITERAL_OFFSET)
ACCESSORS_PRIMITIVE_FIELD(CodeEntryOrLiteral, uintptr_t, CODEENTRY_LITERAL_OFFSET, LITERAL_INFO_OFFSET) ACCESSORS_PRIMITIVE_FIELD(CodeEntryOrLiteral, uintptr_t, CODEENTRY_LITERAL_OFFSET, LITERAL_INFO_OFFSET)
// hotness counter is encoded in a js method field, the first uint16_t in a uint64_t. // hotness counter is encoded in a js method field, the first uint16_t in a uint64_t.
ACCESSORS_PRIMITIVE_FIELD(LiteralInfo, uint64_t, LITERAL_INFO_OFFSET, EXTRA_LITERAL_INFO_OFFSET) ACCESSORS_PRIMITIVE_FIELD(LiteralInfo, uint64_t, LITERAL_INFO_OFFSET, EXTRA_LITERAL_INFO_OFFSET)
ACCESSORS_PRIMITIVE_FIELD(ExtraLiteralInfo, uint64_t, EXTRA_LITERAL_INFO_OFFSET, LAST_OFFSET) ACCESSORS_PRIMITIVE_FIELD_HAS_ATOMIC_INTERFACE(ExtraLiteralInfo, uint64_t, EXTRA_LITERAL_INFO_OFFSET, LAST_OFFSET)
DEFINE_ALIGN_SIZE(LAST_OFFSET); DEFINE_ALIGN_SIZE(LAST_OFFSET);
DECL_VISIT_OBJECT(CONSTANT_POOL_OFFSET, CALL_FIELD_OFFSET); DECL_VISIT_OBJECT(CONSTANT_POOL_OFFSET, CALL_FIELD_OFFSET);

View File

@ -4246,6 +4246,7 @@ void JSNApi::SetEnv(EcmaVM *vm, void *env)
void JSNApi::SynchronizVMInfo(EcmaVM *vm, const EcmaVM *hostVM) void JSNApi::SynchronizVMInfo(EcmaVM *vm, const EcmaVM *hostVM)
{ {
std::atomic_thread_fence(std::memory_order_seq_cst);
vm->SetBundleName(hostVM->GetBundleName()); vm->SetBundleName(hostVM->GetBundleName());
vm->SetModuleName(hostVM->GetModuleName()); vm->SetModuleName(hostVM->GetModuleName());
vm->SetAssetPath(hostVM->GetAssetPath()); vm->SetAssetPath(hostVM->GetAssetPath());