!8205 [JIT]Fix dead lock in access profiletype

Merge pull request !8205 from xiaoweidong/fix_dead_lock
This commit is contained in:
openharmony_ci 2024-07-23 03:51:49 +00:00 committed by Gitee
commit 45a8bcf6b7
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
2 changed files with 39 additions and 37 deletions

View File

@ -22,20 +22,19 @@
namespace panda::ecmascript { namespace panda::ecmascript {
void ProfileTypeAccessor::AddElementHandler(JSHandle<JSTaggedValue> hclass, JSHandle<JSTaggedValue> handler) const void ProfileTypeAccessor::AddElementHandler(JSHandle<JSTaggedValue> hclass, JSHandle<JSTaggedValue> handler) const
{ {
ProfileTypeAccessorLockScope accessorLockScope(thread_);
ALLOW_LOCAL_TO_SHARE_WEAK_REF_HANDLE; ALLOW_LOCAL_TO_SHARE_WEAK_REF_HANDLE;
auto profileData = profileTypeInfo_->GetIcSlot(slotId_); auto profileData = profileTypeInfo_->GetIcSlot(slotId_);
ASSERT(!profileData.IsHole()); ASSERT(!profileData.IsHole());
auto index = slotId_; auto index = slotId_;
if (profileData.IsUndefined()) { if (profileData.IsUndefined()) {
profileTypeInfo_->SetIcSlot(thread_, index, GetWeakRef(hclass.GetTaggedValue())); profileTypeInfo_->SetMultiIcSlotLocked(thread_, index, GetWeakRef(hclass.GetTaggedValue()),
profileTypeInfo_->SetIcSlot(thread_, index + 1, handler.GetTaggedValue()); index + 1, handler.GetTaggedValue());
return; return;
} }
// clear key ic // clear key ic
if (!profileData.IsWeak() && (profileData.IsString() || profileData.IsSymbol())) { if (!profileData.IsWeak() && (profileData.IsString() || profileData.IsSymbol())) {
profileTypeInfo_->SetIcSlot(thread_, index, GetWeakRef(hclass.GetTaggedValue())); profileTypeInfo_->SetMultiIcSlotLocked(thread_, index, GetWeakRef(hclass.GetTaggedValue()),
profileTypeInfo_->SetIcSlot(thread_, index + 1, handler.GetTaggedValue()); index + 1, handler.GetTaggedValue());
return; return;
} }
AddHandlerWithoutKey(hclass, handler); AddHandlerWithoutKey(hclass, handler);
@ -49,8 +48,7 @@ void ProfileTypeAccessor::AddWithoutKeyPoly(JSHandle<JSTaggedValue> hclass, JSHa
const uint32_t step = 2; const uint32_t step = 2;
uint32_t newLen = arr->GetLength() + step; uint32_t newLen = arr->GetLength() + step;
if (newLen > CACHE_MAX_LEN) { if (newLen > CACHE_MAX_LEN) {
profileTypeInfo_->SetIcSlot(thread_, index, JSTaggedValue::Hole()); profileTypeInfo_->SetMultiIcSlotLocked(thread_, index, JSTaggedValue::Hole(), index + 1, JSTaggedValue::Hole());
profileTypeInfo_->SetIcSlot(thread_, index + 1, JSTaggedValue::Hole());
return; return;
} }
auto factory = thread_->GetEcmaVM()->GetFactory(); auto factory = thread_->GetEcmaVM()->GetFactory();
@ -62,13 +60,11 @@ void ProfileTypeAccessor::AddWithoutKeyPoly(JSHandle<JSTaggedValue> hclass, JSHa
} }
newArr->Set(thread_, i, GetWeakRef(hclass.GetTaggedValue())); newArr->Set(thread_, i, GetWeakRef(hclass.GetTaggedValue()));
newArr->Set(thread_, i + 1, handler.GetTaggedValue()); newArr->Set(thread_, i + 1, handler.GetTaggedValue());
profileTypeInfo_->SetIcSlot(thread_, index, newArr.GetTaggedValue()); profileTypeInfo_->SetMultiIcSlotLocked(thread_, index, newArr.GetTaggedValue(), index + 1, JSTaggedValue::Hole());
profileTypeInfo_->SetIcSlot(thread_, index + 1, JSTaggedValue::Hole());
} }
void ProfileTypeAccessor::AddHandlerWithoutKey(JSHandle<JSTaggedValue> hclass, JSHandle<JSTaggedValue> handler) const void ProfileTypeAccessor::AddHandlerWithoutKey(JSHandle<JSTaggedValue> hclass, JSHandle<JSTaggedValue> handler) const
{ {
ProfileTypeAccessorLockScope accessorLockScope(thread_);
ALLOW_LOCAL_TO_SHARE_WEAK_REF_HANDLE; ALLOW_LOCAL_TO_SHARE_WEAK_REF_HANDLE;
auto index = slotId_; auto index = slotId_;
if (IsNamedGlobalIC(GetKind())) { if (IsNamedGlobalIC(GetKind())) {
@ -78,8 +74,8 @@ void ProfileTypeAccessor::AddHandlerWithoutKey(JSHandle<JSTaggedValue> hclass, J
auto profileData = profileTypeInfo_->GetIcSlot(slotId_); auto profileData = profileTypeInfo_->GetIcSlot(slotId_);
ASSERT(!profileData.IsHole()); ASSERT(!profileData.IsHole());
if (profileData.IsUndefined()) { if (profileData.IsUndefined()) {
profileTypeInfo_->SetIcSlot(thread_, index, GetWeakRef(hclass.GetTaggedValue())); profileTypeInfo_->SetMultiIcSlotLocked(thread_, index, GetWeakRef(hclass.GetTaggedValue()),
profileTypeInfo_->SetIcSlot(thread_, index + 1, handler.GetTaggedValue()); index + 1, handler.GetTaggedValue());
return; return;
} }
if (!profileData.IsWeak() && profileData.IsTaggedArray()) { // POLY if (!profileData.IsWeak() && profileData.IsTaggedArray()) { // POLY
@ -95,14 +91,12 @@ void ProfileTypeAccessor::AddHandlerWithoutKey(JSHandle<JSTaggedValue> hclass, J
newArr->Set(thread_, arrIndex++, GetWeakRef(hclass.GetTaggedValue())); newArr->Set(thread_, arrIndex++, GetWeakRef(hclass.GetTaggedValue()));
newArr->Set(thread_, arrIndex, handler.GetTaggedValue()); newArr->Set(thread_, arrIndex, handler.GetTaggedValue());
profileTypeInfo_->SetIcSlot(thread_, index, newArr.GetTaggedValue()); profileTypeInfo_->SetMultiIcSlotLocked(thread_, index, newArr.GetTaggedValue(), index + 1, JSTaggedValue::Hole());
profileTypeInfo_->SetIcSlot(thread_, index + 1, JSTaggedValue::Hole());
} }
void ProfileTypeAccessor::AddHandlerWithKey(JSHandle<JSTaggedValue> key, JSHandle<JSTaggedValue> hclass, void ProfileTypeAccessor::AddHandlerWithKey(JSHandle<JSTaggedValue> key, JSHandle<JSTaggedValue> hclass,
JSHandle<JSTaggedValue> handler) const JSHandle<JSTaggedValue> handler) const
{ {
ProfileTypeAccessorLockScope accessorLockScope(thread_);
ALLOW_LOCAL_TO_SHARE_WEAK_REF_HANDLE; ALLOW_LOCAL_TO_SHARE_WEAK_REF_HANDLE;
if (IsValueGlobalIC(GetKind())) { if (IsValueGlobalIC(GetKind())) {
AddGlobalHandlerKey(key, handler); AddGlobalHandlerKey(key, handler);
@ -112,18 +106,17 @@ void ProfileTypeAccessor::AddHandlerWithKey(JSHandle<JSTaggedValue> key, JSHandl
ASSERT(!profileData.IsHole()); ASSERT(!profileData.IsHole());
auto index = slotId_; auto index = slotId_;
if (profileData.IsUndefined()) { if (profileData.IsUndefined()) {
profileTypeInfo_->SetIcSlot(thread_, index, key.GetTaggedValue());
const int arrayLength = 2; const int arrayLength = 2;
JSHandle<TaggedArray> newArr = thread_->GetEcmaVM()->GetFactory()->NewTaggedArray(arrayLength); JSHandle<TaggedArray> newArr = thread_->GetEcmaVM()->GetFactory()->NewTaggedArray(arrayLength);
newArr->Set(thread_, 0, GetWeakRef(hclass.GetTaggedValue())); newArr->Set(thread_, 0, GetWeakRef(hclass.GetTaggedValue()));
newArr->Set(thread_, 1, handler.GetTaggedValue()); newArr->Set(thread_, 1, handler.GetTaggedValue());
profileTypeInfo_->SetIcSlot(thread_, index + 1, newArr.GetTaggedValue()); profileTypeInfo_->SetMultiIcSlotLocked(thread_, index,
key.GetTaggedValue(), index + 1, newArr.GetTaggedValue());
return; return;
} }
// for element ic, profileData may hclass or tagged array // for element ic, profileData may hclass or tagged array
if (key.GetTaggedValue() != profileData) { if (key.GetTaggedValue() != profileData) {
profileTypeInfo_->SetIcSlot(thread_, index, JSTaggedValue::Hole()); profileTypeInfo_->SetMultiIcSlotLocked(thread_, index, JSTaggedValue::Hole(), index + 1, JSTaggedValue::Hole());
profileTypeInfo_->SetIcSlot(thread_, index + 1, JSTaggedValue::Hole());
return; return;
} }
JSTaggedValue patchValue = profileTypeInfo_->GetIcSlot(index + 1); JSTaggedValue patchValue = profileTypeInfo_->GetIcSlot(index + 1);
@ -133,8 +126,8 @@ void ProfileTypeAccessor::AddHandlerWithKey(JSHandle<JSTaggedValue> key, JSHandl
if (arr->GetLength() > step) { // POLY if (arr->GetLength() > step) { // POLY
uint32_t newLen = arr->GetLength() + step; uint32_t newLen = arr->GetLength() + step;
if (newLen > CACHE_MAX_LEN) { if (newLen > CACHE_MAX_LEN) {
profileTypeInfo_->SetIcSlot(thread_, index, JSTaggedValue::Hole()); profileTypeInfo_->SetMultiIcSlotLocked(thread_, index,
profileTypeInfo_->SetIcSlot(thread_, index + 1, JSTaggedValue::Hole()); JSTaggedValue::Hole(), index + 1, JSTaggedValue::Hole());
return; return;
} }
auto factory = thread_->GetEcmaVM()->GetFactory(); auto factory = thread_->GetEcmaVM()->GetFactory();
@ -162,7 +155,6 @@ void ProfileTypeAccessor::AddHandlerWithKey(JSHandle<JSTaggedValue> key, JSHandl
void ProfileTypeAccessor::AddGlobalHandlerKey(JSHandle<JSTaggedValue> key, JSHandle<JSTaggedValue> handler) const void ProfileTypeAccessor::AddGlobalHandlerKey(JSHandle<JSTaggedValue> key, JSHandle<JSTaggedValue> handler) const
{ {
ProfileTypeAccessorLockScope accessorLockScope(thread_);
ALLOW_LOCAL_TO_SHARE_WEAK_REF_HANDLE; ALLOW_LOCAL_TO_SHARE_WEAK_REF_HANDLE;
auto index = slotId_; auto index = slotId_;
const uint8_t step = 2; // key and value pair const uint8_t step = 2; // key and value pair
@ -205,8 +197,8 @@ void ProfileTypeAccessor::SetAsMega() const
if (IsGlobalIC(kind_)) { if (IsGlobalIC(kind_)) {
profileTypeInfo_->SetIcSlot(thread_, slotId_, JSTaggedValue::Hole()); profileTypeInfo_->SetIcSlot(thread_, slotId_, JSTaggedValue::Hole());
} else { } else {
profileTypeInfo_->SetIcSlot(thread_, slotId_, JSTaggedValue::Hole()); profileTypeInfo_->SetMultiIcSlotLocked(thread_, slotId_,
profileTypeInfo_->SetIcSlot(thread_, slotId_ + 1, JSTaggedValue::Hole()); JSTaggedValue::Hole(), slotId_ + 1, JSTaggedValue::Hole());
} }
} }

View File

@ -83,6 +83,19 @@ static inline bool IsGlobalIC(ICKind kind)
std::string ICKindToString(ICKind kind); std::string ICKindToString(ICKind kind);
class ProfileTypeAccessorLockScope {
public:
ProfileTypeAccessorLockScope(JSThread *thread)
{
if (thread->GetEcmaVM()->IsEnableFastJit() || thread->GetEcmaVM()->IsEnableBaselineJit()) {
lockHolder_.emplace(thread->GetProfileTypeAccessorLock());
}
}
private:
std::optional<LockHolder> lockHolder_;
};
/** /**
* ProfileTypeInfo * ProfileTypeInfo
* +--------------------------------+ * +--------------------------------+
@ -285,6 +298,16 @@ public:
TaggedArray::Set(thread, idx, value); TaggedArray::Set(thread, idx, value);
} }
inline void SetMultiIcSlotLocked(JSThread* thread, uint32_t firstIdx, const JSTaggedValue& firstValue,
uint32_t secondIdx, const JSTaggedValue& secondValue)
{
ProfileTypeAccessorLockScope accessorLockScope(thread);
ASSERT(firstIdx < GetIcSlotLength());
ASSERT(secondIdx < GetIcSlotLength());
TaggedArray::Set(thread, firstIdx, firstValue);
TaggedArray::Set(thread, secondIdx, secondValue);
}
DECL_VISIT_ARRAY(DATA_OFFSET, GetIcSlotAndOsrLength(), GetIcSlotAndOsrLength()); DECL_VISIT_ARRAY(DATA_OFFSET, GetIcSlotAndOsrLength(), GetIcSlotAndOsrLength());
DECL_DUMP() DECL_DUMP()
@ -345,19 +368,6 @@ private:
} }
}; };
class ProfileTypeAccessorLockScope {
public:
ProfileTypeAccessorLockScope(JSThread *thread)
{
if (thread->GetEcmaVM()->IsEnableFastJit() || thread->GetEcmaVM()->IsEnableBaselineJit()) {
lockHolder_.emplace(thread->GetProfileTypeAccessorLock());
}
}
private:
std::optional<LockHolder> lockHolder_;
};
class ProfileTypeAccessor { class ProfileTypeAccessor {
public: public:
static constexpr size_t CACHE_MAX_LEN = 8; static constexpr size_t CACHE_MAX_LEN = 8;