Reason:optimize String fromCharcode

Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I8HQ2J

Signed-off-by: wupengyong <wupengyong@huawei.com>
Change-Id: I5217b2acbfa9696c5a167801193bcaa93695bd4e
This commit is contained in:
wupengyong 2023-12-16 18:03:39 +08:00
parent 6d74279c90
commit ee47c801a6
15 changed files with 115 additions and 31 deletions

View File

@ -137,7 +137,7 @@ JSTaggedValue NumberHelper::Int32ToString(JSThread *thread, int32_t number, uint
if (n == 0) {
return thread->GlobalConstants()->GetHandledZeroString().GetTaggedValue();
}
JSHandle<SingleCharTable> singleCharTable(thread->GetEcmaVM()->GetSingleCharTable());
JSHandle<SingleCharTable> singleCharTable(thread, thread->GetSingleCharTable());
return singleCharTable->GetStringFromSingleCharTable(ToCharCode(n));
}
} else {

View File

@ -71,15 +71,9 @@ void BuiltinsStringStubBuilder::FromCharCode(GateRef glue, [[maybe_unused]] Gate
newBuilder.SetParameters(glue, 0);
Bind(&canBeCompress);
{
Label afterNew(env);
newBuilder.AllocLineStringObject(res, &afterNew, Int32(1), true);
Bind(&afterNew);
{
GateRef dst = ChangeStringTaggedPointerToInt64(
PtrAdd(res->ReadVariable(), IntPtr(LineEcmaString::DATA_OFFSET)));
Store(VariableType::INT8(), glue, dst, IntPtr(0), TruncInt16ToInt8(*value));
Jump(exit);
}
GateRef singleCharTable = GetSingleCharTable(glue);
res->WriteVariable(GetValueFromTaggedArray(singleCharTable, ZExtInt16ToInt32(*value)));
Jump(exit);
}
Bind(&canNotBeCompress);
{

View File

@ -2693,6 +2693,12 @@ inline GateRef StubBuilder::GetGlobalConstantValue(VariableType type, GateRef gl
return Load(type, gConstAddr, constantIndex);
}
inline GateRef StubBuilder::GetSingleCharTable(GateRef glue)
{
return Load(VariableType::JS_ANY(), glue,
IntPtr(JSThread::GlueData::GetSingleCharTableOffset(env_->Is32Bit())));
}
inline GateRef StubBuilder::GetGlobalEnvValue(VariableType type, GateRef env, size_t index)
{
auto valueIndex = IntPtr(GlobalEnv::HEADER_SIZE + JSTaggedValue::TaggedTypeSize() * index);

View File

@ -723,6 +723,7 @@ public:
inline GateRef ComputeTaggedArraySize(GateRef length);
inline GateRef GetGlobalConstantValue(
VariableType type, GateRef glue, ConstantIndex index);
inline GateRef GetSingleCharTable(GateRef glue);
inline GateRef GetGlobalEnvValue(VariableType type, GateRef env, size_t index);
GateRef CallGetterHelper(
GateRef glue, GateRef receiver, GateRef holder, GateRef accessor, ProfileOperation callback);

View File

@ -327,17 +327,15 @@ bool EcmaStringTable::CheckStringTableValidity()
return true;
}
JSTaggedValue SingleCharTable::CreateSingleCharTable(const JSThread *thread)
void SingleCharTable::CreateSingleCharTable(JSThread *thread)
{
auto table = static_cast<SingleCharTable*>(
*thread->GetEcmaVM()->GetFactory()->NewTaggedArray(MAX_ONEBYTE_CHARCODE,
JSTaggedValue::Undefined(), MemSpaceType::NON_MOVABLE));
auto table = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(MAX_ONEBYTE_CHARCODE,
JSTaggedValue::Undefined(), MemSpaceType::NON_MOVABLE);
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
table->Set(thread, 0, thread->GlobalConstants()->GetHandledZeroString().GetTaggedValue());
for (uint32_t i = 1; i < MAX_ONEBYTE_CHARCODE; ++i) {
std::string tmp(1, i + 0X00); // 1: size
table->Set(thread, i, factory->NewFromASCIINonMovable(tmp).GetTaggedValue());
}
return JSTaggedValue(table);
thread->SetSingleCharTable((table.GetTaggedValue()));
}
} // namespace panda::ecmascript

View File

@ -82,7 +82,7 @@ public:
{
return reinterpret_cast<SingleCharTable*>(object);
}
static JSTaggedValue CreateSingleCharTable(const JSThread *thread);
static void CreateSingleCharTable(JSThread *thread);
JSTaggedValue GetStringFromSingleCharTable(int32_t ch)
{
return Get(ch);

View File

@ -225,7 +225,7 @@ bool EcmaVM::Initialize()
thread_->SetGlueGlobalEnv(reinterpret_cast<GlobalEnv *>(context->GetGlobalEnv().GetTaggedType()));
thread_->SetGlobalObject(GetGlobalEnv()->GetGlobalObject());
thread_->SetCurrentEcmaContext(context);
SingleCharTable::CreateSingleCharTable(thread_);
GenerateInternalNativeMethods();
quickFixManager_ = new QuickFixManager();
snapshotEnv_ = new SnapshotEnv(this);
@ -233,7 +233,6 @@ bool EcmaVM::Initialize()
thread_->GetCurrentEcmaContext()->LoadStubFile();
}
singleCharTable_ = SingleCharTable::CreateSingleCharTable(thread_);
callTimer_ = new FunctionCallTimer();
strategy_ = new ThroughputJSObjectResizingStrategy();
@ -527,7 +526,6 @@ void EcmaVM::Iterate(const RootVisitor &v, const RootRangeVisitor &rv)
{
rv(Root::ROOT_VM, ObjectSlot(ToUintPtr(&internalNativeMethods_.front())),
ObjectSlot(ToUintPtr(&internalNativeMethods_.back()) + JSTaggedValue::TaggedTypeSize()));
v(Root::ROOT_VM, ObjectSlot(ToUintPtr(&singleCharTable_)));
if (!WIN_OR_MAC_OR_IOS_PLATFORM) {
snapshotEnv_->Iterate(v);
}

View File

@ -55,7 +55,6 @@ enum class PromiseRejectionEvent : uint8_t;
class JSPandaFileManager;
class JSPandaFile;
class EcmaStringTable;
class SingleCharTable;
class SnapshotEnv;
class SnapshotSerialize;
class SnapshotProcessor;
@ -507,12 +506,6 @@ public:
return stringTable_;
}
JSHandle<JSTaggedValue> GetSingleCharTable() const
{
ASSERT(singleCharTable_ != JSTaggedValue::Hole());
return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(&singleCharTable_));
}
void IncreaseCallDepth()
{
callDepth_++;
@ -578,7 +571,6 @@ private:
bool initialized_ {false};
GCStats *gcStats_ {nullptr};
EcmaStringTable *stringTable_;
JSTaggedValue singleCharTable_ {JSTaggedValue::Hole()};
// VM memory management.
std::unique_ptr<NativeAreaAllocator> nativeAreaAllocator_;

View File

@ -222,7 +222,7 @@ void JSThread::Iterate(const RootVisitor &visitor, const RootRangeVisitor &range
if (!glueData_.exception_.IsHole()) {
visitor(Root::ROOT_VM, ObjectSlot(ToUintPtr(&glueData_.exception_)));
}
visitor(Root::ROOT_VM, ObjectSlot(ToUintPtr(&glueData_.singleCharTable_)));
rangeVisitor(
Root::ROOT_VM, ObjectSlot(glueData_.builtinEntries_.Begin()), ObjectSlot(glueData_.builtinEntries_.End()));

View File

@ -40,6 +40,7 @@ class PropertiesCache;
template<typename T>
class EcmaGlobalStorage;
class Node;
class SingleCharTable;
class DebugNode;
class VmThreadControl;
using WeakClearCallback = void (*)(void *);
@ -726,7 +727,8 @@ public:
base::AlignedUint32,
JSTaggedValue,
base::AlignedPointer,
BuiltinEntries> {
BuiltinEntries,
JSTaggedValue> {
enum class Index : size_t {
BCStubEntriesIndex = 0,
ExceptionIndex,
@ -757,6 +759,7 @@ public:
EntryFrameDroppedStateIndex,
CurrentContextIndex,
BuiltinEntriesIndex,
SingleCharTableIndex,
NumOfMembers
};
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
@ -911,6 +914,11 @@ public:
return GetOffset<static_cast<size_t>(Index::BuiltinEntriesIndex)>(isArch32);
}
static size_t GetSingleCharTableOffset(bool isArch32)
{
return GetOffset<static_cast<size_t>(Index::SingleCharTableIndex)>(isArch32);
}
alignas(EAS) BCStubEntries bcStubEntries_;
alignas(EAS) JSTaggedValue exception_ {JSTaggedValue::Hole()};
alignas(EAS) JSTaggedValue globalObject_ {JSTaggedValue::Hole()};
@ -940,6 +948,7 @@ public:
alignas(EAS) uint64_t entryFrameDroppedState_ {FrameDroppedState::StateFalse};
alignas(EAS) EcmaContext *currentContext_ {nullptr};
alignas(EAS) BuiltinEntries builtinEntries_;
alignas(EAS) JSTaggedValue singleCharTable_ {JSTaggedValue::Hole()};
};
STATIC_ASSERT_EQ_ARCH(sizeof(GlueData), GlueData::SizeArch32, GlueData::SizeArch64);
@ -950,6 +959,18 @@ public:
{
return glueData_.currentContext_;
}
JSTaggedValue GetSingleCharTable() const
{
ASSERT(glueData_.singleCharTable_ != JSTaggedValue::Hole());
return glueData_.singleCharTable_;
}
void SetSingleCharTable(JSTaggedValue singleCharTable)
{
glueData_.singleCharTable_ = singleCharTable;
}
void SwitchCurrentContext(EcmaContext *currentContext, bool isInIterate = false);
CVector<EcmaContext *> GetEcmaContexts()

View File

@ -640,7 +640,7 @@ DEF_RUNTIME_STUBS(CallGetPrototype)
DEF_RUNTIME_STUBS(RegularJSObjDeletePrototype)
{
RUNTIME_STUBS_HEADER(CallJSObjDeletePrototype);
RUNTIME_STUBS_HEADER(RegularJSObjDeletePrototype);
JSHandle<JSObject> tagged = GetHArg<JSObject>(argv, argc, 0); // 0: means the zeroth parameter
JSTaggedValue value = GetArg(argv, argc, 1);
uint32_t index = 0;

View File

@ -128,6 +128,7 @@ group("ark_js_moduletest") {
"storeicbyname",
"storeicbyvalue",
"string",
"stringfromcharcode",
"stringreplace",
"stubbuilder",
"throwdyn",

View File

@ -0,0 +1,18 @@
# Copyright (c) 2023 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_moduletest_action("stringfromcharcode") {
deps = []
}

View File

@ -0,0 +1,19 @@
# Copyright (c) 2023 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.
8
Z
q
jjj1
jjj2
jjj3

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2023 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.
*/
/*
* @tc.name:fromCharCode
* @tc.desc:test String.fromCharCode
* @tc.type: FUNC
* @tc.require: issueI5NO8G
*/
var str = String.fromCharCode(0);
var str1 = String.fromCharCode(56);
var str2 = String.fromCharCode(90);
var str3 = String.fromCharCode(113);
print(str1);
print(str2);
print(str3);
var obj = {};
obj[str1] = 'jjj1';
obj[str2] = 'jjj2';
obj[str3] = 'jjj3';
print(obj[8]);
print(obj.Z);
print(obj.q);