!9417 [JIT] Fixed string table when create jshandle

Merge pull request !9417 from xiaoweidong/fix_string_table
This commit is contained in:
openharmony_ci 2024-09-23 03:14:17 +00:00 committed by Gitee
commit 68ebc6984a
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
9 changed files with 124 additions and 1 deletions

View File

@ -482,6 +482,31 @@ EcmaString *EcmaStringTable::GetOrInternStringWithSpaceType(EcmaVM *vm, const ui
return str; return str;
} }
// used in jit thread, which unsupport create jshandle
EcmaString *EcmaStringTable::GetOrInternStringWithSpaceTypeWithoutJSHandle(EcmaVM *vm, const uint8_t *utf8Data,
uint32_t utf16Len, MemSpaceType type)
{
ASSERT(IsSMemSpace(type));
type = (type == MemSpaceType::SHARED_NON_MOVABLE) ? type : MemSpaceType::SHARED_OLD_SPACE;
CVector<uint16_t> u16Buffer(utf16Len);
utf::ConvertRegionMUtf8ToUtf16(utf8Data, u16Buffer.data(), utf::Mutf8Size(utf8Data), utf16Len, 0);
auto hashcode = EcmaStringAccessor::ComputeHashcodeUtf16(u16Buffer.data(), utf16Len);
RuntimeLockHolder locker(vm->GetJSThread(), stringTable_[GetTableId(hashcode)].mutex_);
#if ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT
if (vm->IsCollectingScopeLockStats()) {
vm->IncreaseStringTableLockCount();
}
#endif
auto result = GetStringThreadUnsafe(u16Buffer.data(), utf16Len, hashcode);
if (result.first != nullptr) {
return result.first;
}
EcmaString *str = EcmaStringAccessor::CreateFromUtf16(vm, u16Buffer.data(), utf16Len, false, type);
str->SetMixHashcode(hashcode);
InternStringThreadUnsafe(str, hashcode);
return str;
}
void EcmaStringTable::SweepWeakRef(const WeakRootVisitor &visitor) void EcmaStringTable::SweepWeakRef(const WeakRootVisitor &visitor)
{ {
// No need lock here, only shared gc will sweep string table, meanwhile other threads are suspended. // No need lock here, only shared gc will sweep string table, meanwhile other threads are suspended.

View File

@ -128,6 +128,8 @@ public:
bool canBeCompress, MemSpaceType type, bool isConstantString, uint32_t idOffset); bool canBeCompress, MemSpaceType type, bool isConstantString, uint32_t idOffset);
EcmaString *GetOrInternStringWithSpaceType(EcmaVM *vm, const uint8_t *utf8Data, uint32_t utf16Len, EcmaString *GetOrInternStringWithSpaceType(EcmaVM *vm, const uint8_t *utf8Data, uint32_t utf16Len,
MemSpaceType type); MemSpaceType type);
EcmaString *GetOrInternStringWithSpaceTypeWithoutJSHandle(EcmaVM *vm, const uint8_t *utf8Data, uint32_t utf16Len,
MemSpaceType type);
EcmaString *TryGetInternString(JSThread *thread, const JSHandle<EcmaString> &string); EcmaString *TryGetInternString(JSThread *thread, const JSHandle<EcmaString> &string);
void InsertStringToTableWithHashThreadUnsafe(EcmaString* string, uint32_t hashcode); void InsertStringToTableWithHashThreadUnsafe(EcmaString* string, uint32_t hashcode);
EcmaString *InsertStringToTable(EcmaVM *vm, const JSHandle<EcmaString> &strHandle); EcmaString *InsertStringToTable(EcmaVM *vm, const JSHandle<EcmaString> &strHandle);

View File

@ -86,7 +86,7 @@ JSTaggedValue ConstantPool::GetStringFromCacheForJit(JSThread *thread, JSTaggedV
auto foundStr = jsPandaFile->GetStringData(id); auto foundStr = jsPandaFile->GetStringData(id);
EcmaVM *vm = thread->GetEcmaVM(); EcmaVM *vm = thread->GetEcmaVM();
ObjectFactory *factory = vm->GetFactory(); ObjectFactory *factory = vm->GetFactory();
auto string = factory->GetRawStringFromStringTable(foundStr, MemSpaceType::SHARED_OLD_SPACE, auto string = factory->GetRawStringFromStringTableWithoutJSHandle(foundStr, MemSpaceType::SHARED_OLD_SPACE,
jsPandaFile->IsFirstMergedAbc(), id.GetOffset()); jsPandaFile->IsFirstMergedAbc(), id.GetOffset());
val = JSTaggedValue(string); val = JSTaggedValue(string);
} }

View File

@ -3275,6 +3275,26 @@ EcmaString *ObjectFactory::GetRawStringFromStringTable(StringData sd, MemSpaceTy
return vm_->GetEcmaStringTable()->GetOrInternStringWithSpaceType(vm_, mutf8Data, utf16Len, type); return vm_->GetEcmaStringTable()->GetOrInternStringWithSpaceType(vm_, mutf8Data, utf16Len, type);
} }
// used in jit thread, which unsupport create jshandle
EcmaString *ObjectFactory::GetRawStringFromStringTableWithoutJSHandle(StringData sd, MemSpaceType type,
bool isConstantString, uint32_t idOffset) const
{
NewObjectHook();
uint32_t utf16Len = sd.utf16_length;
if (UNLIKELY(utf16Len == 0)) {
return *GetEmptyString();
}
bool canBeCompressed = sd.is_ascii;
const uint8_t *mutf8Data = sd.data;
if (canBeCompressed) {
// This branch will use constant string, which has a pointer at the string in the pandafile.
return vm_->GetEcmaStringTable()->GetOrInternStringWithSpaceType(vm_, mutf8Data, utf16Len, true, type,
isConstantString, idOffset);
}
return vm_->GetEcmaStringTable()->GetOrInternStringWithSpaceTypeWithoutJSHandle(vm_, mutf8Data, utf16Len, type);
}
JSHandle<PropertyBox> ObjectFactory::NewPropertyBox(const JSHandle<JSTaggedValue> &value) JSHandle<PropertyBox> ObjectFactory::NewPropertyBox(const JSHandle<JSTaggedValue> &value)
{ {
NewObjectHook(); NewObjectHook();

View File

@ -954,6 +954,10 @@ private:
EcmaString *PUBLIC_API GetRawStringFromStringTable(StringData sd, EcmaString *PUBLIC_API GetRawStringFromStringTable(StringData sd,
MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE, MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE,
bool isConstantString = false, uint32_t idOffset = 0) const; bool isConstantString = false, uint32_t idOffset = 0) const;
EcmaString *GetRawStringFromStringTableWithoutJSHandle(StringData sd,
MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE,
bool isConstantString = false,
uint32_t idOffset = 0) const;
JSHandle<EcmaString> GetStringFromStringTable(const uint16_t *utf16Data, uint32_t utf16Len, JSHandle<EcmaString> GetStringFromStringTable(const uint16_t *utf16Data, uint32_t utf16Len,
bool canBeCompress) const; bool canBeCompress) const;

View File

@ -33,6 +33,7 @@ group("ark_jit_ts_test") {
"ts_inline", "ts_inline",
"proxy_fast_call", "proxy_fast_call",
"fuzz_exception", "fuzz_exception",
"utf16key",
"throw_error", "throw_error",
"compiler_inline", "compiler_inline",
"uint32_array", "uint32_array",

View File

@ -0,0 +1,18 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_jit_test_action("utf16key") {
deps = []
}

View File

@ -0,0 +1,14 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
true

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class Utf16key {
constructor() {
this.鸿 = '鸿蒙'
}
}
function LoadValueByName(o) {
return o.鸿;
}
const o = new Utf16key();
for (let i = 0; i < 3; i++) {
LoadValueByName(o)
}
ArkTools.jitCompileAsync(LoadValueByName);
let res = ArkTools.waitJitCompileFinish(LoadValueByName);
print(res);
try {
LoadValueByName(o)
} catch(err) {
print("catch")
}