enable builtin-string-stub

desc: enable builtin-string-stub

solu: make FlattenString interface to IR and enable builtin-string-stub

issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I6ZACR
Signed-off-by: wanghuan <wanghuan80@huawei.com>
Change-Id: I31ea1999d94c8ba9a8fc663c8284a00930e957ad
This commit is contained in:
wanghuan 2023-04-27 11:57:07 +08:00 committed by wanghuan2022
parent 22c0a26d0c
commit 62b052937a
6 changed files with 154 additions and 78 deletions

View File

@ -1599,13 +1599,16 @@ void Builtins::InitializeString(const JSHandle<GlobalEnv> &env, const JSHandle<J
stringFunction.GetObject<JSFunction>()->SetFunctionPrototype(thread_, stringFuncInstanceHClass.GetTaggedValue());
// String.prototype method
SetFunction(env, stringFuncPrototype, "charAt", BuiltinsString::CharAt, FunctionLength::ONE);
SetFunction(env, stringFuncPrototype, "charCodeAt", BuiltinsString::CharCodeAt, FunctionLength::ONE);
SetFunction(env, stringFuncPrototype, "charAt", BuiltinsString::CharAt, FunctionLength::ONE,
BUILTINS_STUB_ID(CharAt));
SetFunction(env, stringFuncPrototype, "charCodeAt", BuiltinsString::CharCodeAt, FunctionLength::ONE,
BUILTINS_STUB_ID(CharCodeAt));
SetFunction(env, stringFuncPrototype, "codePointAt", BuiltinsString::CodePointAt, FunctionLength::ONE);
SetFunction(env, stringFuncPrototype, "concat", BuiltinsString::Concat, FunctionLength::ONE);
SetFunction(env, stringFuncPrototype, "endsWith", BuiltinsString::EndsWith, FunctionLength::ONE);
SetFunction(env, stringFuncPrototype, "includes", BuiltinsString::Includes, FunctionLength::ONE);
SetFunction(env, stringFuncPrototype, "indexOf", BuiltinsString::IndexOf, FunctionLength::ONE);
SetFunction(env, stringFuncPrototype, "indexOf", BuiltinsString::IndexOf, FunctionLength::ONE,
BUILTINS_STUB_ID(IndexOf));
SetFunction(env, stringFuncPrototype, "lastIndexOf", BuiltinsString::LastIndexOf, FunctionLength::ONE);
SetFunction(env, stringFuncPrototype, "localeCompare", BuiltinsString::LocaleCompare, FunctionLength::ONE);
SetFunction(env, stringFuncPrototype, "match", BuiltinsString::Match, FunctionLength::ONE);
@ -1620,7 +1623,8 @@ void Builtins::InitializeString(const JSHandle<GlobalEnv> &env, const JSHandle<J
SetFunction(env, stringFuncPrototype, "slice", BuiltinsString::Slice, FunctionLength::TWO);
SetFunction(env, stringFuncPrototype, "split", BuiltinsString::Split, FunctionLength::TWO);
SetFunction(env, stringFuncPrototype, "startsWith", BuiltinsString::StartsWith, FunctionLength::ONE);
SetFunction(env, stringFuncPrototype, "substring", BuiltinsString::Substring, FunctionLength::TWO);
SetFunction(env, stringFuncPrototype, "substring", BuiltinsString::Substring, FunctionLength::TWO,
BUILTINS_STUB_ID(Substring));
SetFunction(env, stringFuncPrototype, "substr", BuiltinsString::SubStr, FunctionLength::TWO);
SetFunction(env, stringFuncPrototype, "toLocaleLowerCase", BuiltinsString::ToLocaleLowerCase, FunctionLength::ZERO);
SetFunction(env, stringFuncPrototype, "toLocaleUpperCase", BuiltinsString::ToLocaleUpperCase, FunctionLength::ZERO);

View File

@ -121,16 +121,20 @@ GateRef BuiltinsStringStubBuilder::CreateFromEcmaString(GateRef glue, GateRef ob
return ret;
}
GateRef BuiltinsStringStubBuilder::FastSubUtf8String(GateRef glue, GateRef thisValue, GateRef from, GateRef len)
GateRef BuiltinsStringStubBuilder::FastSubString(GateRef glue, GateRef thisValue, GateRef from, GateRef len)
{
auto env = GetEnvironment();
Label entry(env);
env->SubCfgEntry(&entry);
DEFVARIABLE(result, VariableType::JS_POINTER(), Undefined());
DEFVARIABLE(result, VariableType::JS_POINTER(), thisValue);
Label exit(env);
Label lenEqualZero(env);
Label lenNotEqualZero(env);
Label fromEqualZero(env);
Label next(env);
Label isUtf8(env);
Label isUtf16(env);
Branch(Int32Equal(len, Int32(0)), &lenEqualZero, &lenNotEqualZero);
Bind(&lenEqualZero);
@ -141,17 +145,51 @@ GateRef BuiltinsStringStubBuilder::FastSubUtf8String(GateRef glue, GateRef thisV
}
Bind(&lenNotEqualZero);
{
NewObjectStubBuilder newBuilder(this);
newBuilder.SetParameters(glue, 0);
Label afterNew(env);
newBuilder.AllocLineStringObject(&result, &afterNew, len, true);
Bind(&afterNew);
Branch(Int32Equal(from, Int32(0)), &fromEqualZero, &next);
Bind(&fromEqualZero);
{
GateRef dst = PtrAdd(*result, IntPtr(LineEcmaString::DATA_OFFSET));
GateRef source = PtrAdd(PtrAdd(thisValue, IntPtr(LineEcmaString::DATA_OFFSET)), ZExtInt32ToPtr(from));
CopyChars(glue, dst, source, len, IntPtr(sizeof(uint8_t)), VariableType::INT8());
Jump(&exit);
GateRef thisLen = GetLengthFromString(thisValue);
Branch(Int32Equal(len, thisLen), &exit, &next);
}
Bind(&next);
{
Branch(IsUtf8String(thisValue), &isUtf8, &isUtf16);
Bind(&isUtf8);
{
result = FastSubUtf8String(glue, thisValue, from, len);
Jump(&exit);
}
Bind(&isUtf16);
{
result = FastSubUtf16String(glue, thisValue, from, len);
Jump(&exit);
}
}
}
Bind(&exit);
auto ret = *result;
env->SubCfgExit();
return ret;
}
GateRef BuiltinsStringStubBuilder::FastSubUtf8String(GateRef glue, GateRef thisValue, GateRef from, GateRef len)
{
auto env = GetEnvironment();
Label entry(env);
env->SubCfgEntry(&entry);
DEFVARIABLE(result, VariableType::JS_POINTER(), Undefined());
Label exit(env);
NewObjectStubBuilder newBuilder(this);
newBuilder.SetParameters(glue, 0);
Label afterNew(env);
newBuilder.AllocLineStringObject(&result, &afterNew, len, true);
Bind(&afterNew);
{
GateRef dst = PtrAdd(*result, IntPtr(LineEcmaString::DATA_OFFSET));
GateRef source = PtrAdd(PtrAdd(thisValue, IntPtr(LineEcmaString::DATA_OFFSET)), ZExtInt32ToPtr(from));
CopyChars(glue, dst, source, len, IntPtr(sizeof(uint8_t)), VariableType::INT8());
Jump(&exit);
}
Bind(&exit);
auto ret = *result;
@ -171,48 +209,36 @@ GateRef BuiltinsStringStubBuilder::FastSubUtf16String(GateRef glue, GateRef this
Label isUtf8(env);
Label isUtf8Next(env);
Label isUtf16Next(env);
Label lenEqualZero(env);
Label lenNotEqualZero(env);
Branch(Int32Equal(len, Int32(0)), &lenEqualZero, &lenNotEqualZero);
Bind(&lenEqualZero);
GateRef fromOffset = PtrMul(ZExtInt32ToPtr(from), IntPtr(sizeof(uint16_t) / sizeof(uint8_t)));
GateRef source = PtrAdd(PtrAdd(thisValue, IntPtr(LineEcmaString::DATA_OFFSET)), fromOffset);
GateRef canBeCompressed = CanBeCompressed(source, len, true);
NewObjectStubBuilder newBuilder(this);
newBuilder.SetParameters(glue, 0);
Label afterNew(env);
Branch(canBeCompressed, &isUtf8, &isUtf16);
Bind(&isUtf8);
{
result = GetGlobalConstantValue(
VariableType::JS_POINTER(), glue, ConstantIndex::EMPTY_STRING_OBJECT_INDEX);
Jump(&exit);
newBuilder.AllocLineStringObject(&result, &afterNew, len, true);
}
Bind(&lenNotEqualZero);
Bind(&isUtf16);
{
GateRef fromOffset = PtrMul(ZExtInt32ToPtr(from), IntPtr(sizeof(uint16_t) / sizeof(uint8_t)));
GateRef source = PtrAdd(PtrAdd(thisValue, IntPtr(LineEcmaString::DATA_OFFSET)), fromOffset);
GateRef canBeCompressed = CanBeCompressed(source, len, true);
NewObjectStubBuilder newBuilder(this);
newBuilder.SetParameters(glue, 0);
Label afterNew(env);
Branch(canBeCompressed, &isUtf8, &isUtf16);
Bind(&isUtf8);
newBuilder.AllocLineStringObject(&result, &afterNew, len, false);
}
Bind(&afterNew);
{
GateRef source1 = PtrAdd(PtrAdd(thisValue, IntPtr(LineEcmaString::DATA_OFFSET)), fromOffset);
GateRef dst = PtrAdd(*result, IntPtr(LineEcmaString::DATA_OFFSET));
Branch(canBeCompressed, &isUtf8Next, &isUtf16Next);
Bind(&isUtf8Next);
{
newBuilder.AllocLineStringObject(&result, &afterNew, len, true);
CopyUtf16AsUtf8(glue, source1, dst, len);
Jump(&exit);
}
Bind(&isUtf16);
Bind(&isUtf16Next);
{
newBuilder.AllocLineStringObject(&result, &afterNew, len, false);
}
Bind(&afterNew);
{
GateRef source1 = PtrAdd(PtrAdd(thisValue, IntPtr(LineEcmaString::DATA_OFFSET)), fromOffset);
GateRef dst = PtrAdd(*result, IntPtr(LineEcmaString::DATA_OFFSET));
Branch(canBeCompressed, &isUtf8Next, &isUtf16Next);
Bind(&isUtf8Next);
{
CopyUtf16AsUtf8(glue, source1, dst, len);
Jump(&exit);
}
Bind(&isUtf16Next);
{
CopyChars(glue, dst, source1, len, IntPtr(sizeof(uint16_t)), VariableType::INT16());
Jump(&exit);
}
CopyChars(glue, dst, source1, len, IntPtr(sizeof(uint16_t)), VariableType::INT16());
Jump(&exit);
}
}
Bind(&exit);
@ -337,7 +363,7 @@ void BuiltinsStringStubBuilder::CopyUtf16AsUtf8(GateRef glue, GateRef src, GateR
return;
}
GateRef BuiltinsStringStubBuilder::GetUtf16Date(GateRef stringData, GateRef index)
GateRef BuiltinsStringStubBuilder::GetUtf16Data(GateRef stringData, GateRef index)
{
return ZExtInt16ToInt32(Load(VariableType::INT16(), PtrAdd(stringData,
PtrMul(ZExtInt32ToPtr(index), IntPtr(sizeof(uint16_t))))));
@ -348,7 +374,7 @@ GateRef BuiltinsStringStubBuilder::IsASCIICharacter(GateRef data)
return Int32LessThan(Int32Sub(data, Int32(1)), Int32(base::utf_helper::UTF8_1B_MAX));
}
GateRef BuiltinsStringStubBuilder::GetUtf8Date(GateRef stringData, GateRef index)
GateRef BuiltinsStringStubBuilder::GetUtf8Data(GateRef stringData, GateRef index)
{
return ZExtInt8ToInt32(Load(VariableType::INT8(), PtrAdd(stringData,
PtrMul(ZExtInt32ToPtr(index), IntPtr(sizeof(uint8_t))))));
@ -391,9 +417,9 @@ GateRef BuiltinsStringStubBuilder::StringIndexOf(GateRef lhsData, bool lhsIsUtf8
Label loopEnd1(env);
GateRef lhsTemp;
if (lhsIsUtf8) {
lhsTemp = GetUtf8Date(lhsData, *i);
lhsTemp = GetUtf8Data(lhsData, *i);
} else {
lhsTemp = GetUtf16Date(lhsData, *i);
lhsTemp = GetUtf16Data(lhsData, *i);
}
Branch(Int32NotEqual(lhsTemp, first), &nextCount1, &nextCount);
Bind(&nextCount1);
@ -408,9 +434,9 @@ GateRef BuiltinsStringStubBuilder::StringIndexOf(GateRef lhsData, bool lhsIsUtf8
{
GateRef lhsTemp1;
if (lhsIsUtf8) {
lhsTemp1 = GetUtf8Date(lhsData, *i);
lhsTemp1 = GetUtf8Data(lhsData, *i);
} else {
lhsTemp1 = GetUtf16Date(lhsData, *i);
lhsTemp1 = GetUtf16Data(lhsData, *i);
}
Branch(Int32NotEqual(lhsTemp1, first), &lhsNotEqualFirst, &nextCount);
Bind(&lhsNotEqualFirst);
@ -440,15 +466,15 @@ GateRef BuiltinsStringStubBuilder::StringIndexOf(GateRef lhsData, bool lhsIsUtf8
{
GateRef lhsTemp2;
if (lhsIsUtf8) {
lhsTemp2 = GetUtf8Date(lhsData, *j);
lhsTemp2 = GetUtf8Data(lhsData, *j);
} else {
lhsTemp2 = GetUtf16Date(lhsData, *j);
lhsTemp2 = GetUtf16Data(lhsData, *j);
}
GateRef rhsTemp;
if (rhsIsUtf8) {
rhsTemp = GetUtf8Date(rhsData, *k);
rhsTemp = GetUtf8Data(rhsData, *k);
} else {
rhsTemp = GetUtf16Date(rhsData, *k);
rhsTemp = GetUtf16Data(rhsData, *k);
}
Branch(Int32Equal(lhsTemp2, rhsTemp), &loopEnd2, &nextCount2);
}
@ -493,6 +519,7 @@ GateRef BuiltinsStringStubBuilder::StringIndexOf(GateRef lhs, GateRef rhs, GateR
Label maxNotLessZero(env);
Label rhsIsUtf8(env);
Label rhsIsUtf16(env);
Label posRMaxNotGreaterLhs(env);
GateRef lhsCount = GetLengthFromString(lhs);
GateRef rhsCount = GetLengthFromString(rhs);
@ -520,6 +547,9 @@ GateRef BuiltinsStringStubBuilder::StringIndexOf(GateRef lhs, GateRef rhs, GateR
Branch(Int32LessThan(max, Int32(0)), &exit, &maxNotLessZero);
Bind(&maxNotLessZero);
{
GateRef posRMax = Int32Add(*posTag, rhsCount);
Branch(Int32GreaterThan(posRMax, lhsCount), &exit, &posRMaxNotGreaterLhs);
Bind(&posRMaxNotGreaterLhs);
GateRef rhsData = PtrAdd(rhs, IntPtr(LineEcmaString::DATA_OFFSET));
GateRef lhsData = PtrAdd(lhs, IntPtr(LineEcmaString::DATA_OFFSET));
Branch(IsUtf8String(rhs), &rhsIsUtf8, &rhsIsUtf16);

View File

@ -28,6 +28,7 @@ public:
void GenerateCircuit() override {}
GateRef StringAt(GateRef obj, GateRef index);
GateRef FastSubString(GateRef glue, GateRef thisValue, GateRef from, GateRef len);
GateRef FastSubUtf8String(GateRef glue, GateRef thisValue, GateRef from, GateRef len);
GateRef FastSubUtf16String(GateRef glue, GateRef thisValue, GateRef from, GateRef len);
void CopyChars(GateRef glue, GateRef dst, GateRef source, GateRef sourceLength, GateRef size, VariableType type);
@ -38,9 +39,9 @@ public:
GateRef CreateFromEcmaString(GateRef glue, GateRef obj, GateRef index);
private:
GateRef CanBeCompressed(GateRef utf16Data, GateRef utf16Len, bool isUtf16);
GateRef GetUtf16Date(GateRef stringData, GateRef index);
GateRef GetUtf16Data(GateRef stringData, GateRef index);
GateRef IsASCIICharacter(GateRef data);
GateRef GetUtf8Date(GateRef stringData, GateRef index);
GateRef GetUtf8Data(GateRef stringData, GateRef index);
};
} // namespace panda::ecmascript::kungfu
#endif // ECMASCRIPT_COMPILER_BUILTINS_STRING_STUB_BUILDER_H

View File

@ -160,6 +160,7 @@ DECLARE_BUILTINS(CharCodeAt)
Label exit(env);
Label posTagIsDouble(env);
Label thisIsHeapobject(env);
Label flattenFastPath(env);
Branch(TaggedIsUndefinedOrNull(thisValue), &slowPath, &objNotUndefinedAndNull);
Bind(&objNotUndefinedAndNull);
@ -169,7 +170,10 @@ DECLARE_BUILTINS(CharCodeAt)
Branch(IsString(thisValue), &isString, &slowPath);
Bind(&isString);
{
GateRef thisLen = GetLengthFromString(thisValue);
DEFVARIABLE(thisFlat, VariableType::JS_POINTER(), thisValue);
FlattenString(thisValue, &thisFlat, &flattenFastPath, &slowPath);
Bind(&flattenFastPath);
GateRef thisLen = GetLengthFromString(*thisFlat);
Branch(Int64GreaterThanOrEqual(IntPtr(0), numArgs), &next, &posTagNotUndefined);
Bind(&posTagNotUndefined);
{
@ -193,7 +197,7 @@ DECLARE_BUILTINS(CharCodeAt)
Bind(&posNotLessZero);
{
BuiltinsStringStubBuilder stringBuilder(this);
res = IntToTaggedPtr(stringBuilder.StringAt(thisValue, *pos));
res = IntToTaggedPtr(stringBuilder.StringAt(*thisFlat, *pos));
Jump(&exit);
}
}
@ -231,6 +235,8 @@ DECLARE_BUILTINS(IndexOf)
Label nextCount(env);
Label posNotLessThanLen(env);
Label thisIsHeapobject(env);
Label flattenFastPath(env);
Label flattenFastPath1(env);
Branch(TaggedIsUndefinedOrNull(thisValue), &slowPath, &objNotUndefinedAndNull);
Bind(&objNotUndefinedAndNull);
@ -282,8 +288,14 @@ DECLARE_BUILTINS(IndexOf)
}
Bind(&nextCount);
{
DEFVARIABLE(thisFlat, VariableType::JS_POINTER(), thisValue);
DEFVARIABLE(searchFlat, VariableType::JS_POINTER(), searchTag);
FlattenString(thisValue, &thisFlat, &flattenFastPath, &slowPath);
Bind(&flattenFastPath);
FlattenString(searchTag, &searchFlat, &flattenFastPath1, &slowPath);
Bind(&flattenFastPath1);
BuiltinsStringStubBuilder stringBuilder(this);
GateRef resPos = stringBuilder.StringIndexOf(thisValue, searchTag, *pos);
GateRef resPos = stringBuilder.StringIndexOf(*thisFlat, *searchFlat, *pos);
Branch(Int32GreaterThanOrEqual(resPos, Int32(0)), &resPosGreaterZero, &exit);
Bind(&resPosGreaterZero);
{
@ -345,6 +357,7 @@ DECLARE_BUILTINS(Substring)
Label startGreatEnd(env);
Label startNotGreatEnd(env);
Label thisIsHeapobject(env);
Label flattenFastPath(env);
Branch(TaggedIsUndefinedOrNull(thisValue), &slowPath, &objNotUndefinedAndNull);
Bind(&objNotUndefinedAndNull);
@ -447,19 +460,13 @@ DECLARE_BUILTINS(Substring)
}
Bind(&countRes);
{
BuiltinsStringStubBuilder stringBuilder(this);
GateRef len = Int32Sub(*to, *from);
Label isUtf8(env);
Label isUtf16(env);
Branch(IsUtf8String(thisValue), &isUtf8, &isUtf16);
Bind(&isUtf8);
DEFVARIABLE(thisFlat, VariableType::JS_POINTER(), thisValue);
FlattenString(thisValue, &thisFlat, &flattenFastPath, &slowPath);
Bind(&flattenFastPath);
{
res = stringBuilder.FastSubUtf8String(glue, thisValue, *from, len);
Jump(&exit);
}
Bind(&isUtf16);
{
res = stringBuilder.FastSubUtf16String(glue, thisValue, *from, len);
BuiltinsStringStubBuilder stringBuilder(this);
res = stringBuilder.FastSubString(glue, *thisFlat, *from, len);
Jump(&exit);
}
}
@ -495,6 +502,7 @@ DECLARE_BUILTINS(CharAt)
Label exit(env);
Label posTagIsDouble(env);
Label thisIsHeapobject(env);
Label flattenFastPath(env);
Branch(TaggedIsUndefinedOrNull(thisValue), &slowPath, &objNotUndefinedAndNull);
Bind(&objNotUndefinedAndNull);
@ -504,7 +512,10 @@ DECLARE_BUILTINS(CharAt)
Branch(IsString(thisValue), &isString, &slowPath);
Bind(&isString);
{
GateRef thisLen = GetLengthFromString(thisValue);
DEFVARIABLE(thisFlat, VariableType::JS_POINTER(), thisValue);
FlattenString(thisValue, &thisFlat, &flattenFastPath, &slowPath);
Bind(&flattenFastPath);
GateRef thisLen = GetLengthFromString(*thisFlat);
Branch(Int64GreaterThanOrEqual(IntPtr(0), numArgs), &next, &posTagNotUndefined);
Bind(&posTagNotUndefined);
{
@ -528,7 +539,7 @@ DECLARE_BUILTINS(CharAt)
Bind(&posNotLessZero);
{
BuiltinsStringStubBuilder stringBuilder(this);
res = stringBuilder.CreateFromEcmaString(glue, thisValue, *pos);
res = stringBuilder.CreateFromEcmaString(glue, *thisFlat, *pos);
Jump(&exit);
}
}

View File

@ -5379,6 +5379,35 @@ GateRef StubBuilder::FlattenString(GateRef glue, GateRef str)
return ret;
}
void StubBuilder::FlattenString(GateRef str, Variable *flatStr, Label *fastPath, Label *slowPath)
{
auto env = GetEnvironment();
Label notLineString(env);
Label exit(env);
DEFVARIABLE(result, VariableType::JS_POINTER(), str);
Branch(IsLineString(str), &exit, &notLineString);
Bind(&notLineString);
{
Label isTreeString(env);
Branch(IsTreeString(str), &isTreeString, &exit);
Bind(&isTreeString);
{
Label isFlat(env);
Branch(TreeStringIsFlat(str), &isFlat, slowPath);
Bind(&isFlat);
{
result = GetFirstFromTreeString(str);
Jump(&exit);
}
}
}
Bind(&exit);
{
flatStr->WriteVariable(*result);
Jump(fastPath);
}
}
GateRef StubBuilder::ToNumber(GateRef glue, GateRef tagged)
{
auto env = GetEnvironment();

View File

@ -619,6 +619,7 @@ public:
void Assert(int messageId, int line, GateRef glue, GateRef condition, Label *nextLabel);
GateRef FlattenString(GateRef glue, GateRef str);
void FlattenString(GateRef str, Variable *flatStr, Label *fastPath, Label *slowPath);
void Comment(GateRef glue, const std::string &str);
GateRef ToNumber(GateRef glue, GateRef tagged);
private: