!8153 Workload performance optimization for harmcrest_test

Merge pull request !8153 from xingshunxiang/harmcrest_patch
This commit is contained in:
openharmony_ci 2024-07-18 06:30:04 +00:00 committed by Gitee
commit d394070272
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
9 changed files with 118 additions and 28 deletions

View File

@ -180,16 +180,22 @@ void BytecodeInfoCollector::CollectMethodPcsFromBC(const uint32_t insSz, const u
bool noGC = true;
bool debuggerStmt = false;
uint32_t newtargetIndex = method->GetNewTargetVregIndex();
bool canTypedCall = true;
while (bcIns.GetAddress() != bcInsLast.GetAddress()) {
curPc = bcIns.GetAddress();
auto metaData = bytecodes_.GetBytecodeMetaData(curPc);
bool opcodeSupprotFastCall = true;
CollectMethodInfoFromBC(bcIns, method, bcIndex, recordNamePtr, classConstructIndexes, &opcodeSupprotFastCall);
bool opcodeSupportTypeByteCall = true;
CollectMethodInfoFromBC(bcIns, method, bcIndex, recordNamePtr, classConstructIndexes,
&opcodeSupprotFastCall, &opcodeSupportTypeByteCall);
bool vregSupportFastCall = !IsVRegUsed(bcIns, metaData, newtargetIndex);
if (!opcodeSupprotFastCall || !vregSupportFastCall) {
canFastCall = false;
}
if (!opcodeSupportTypeByteCall) {
canTypedCall = false;
}
if (snapshotCPData_ != nullptr) {
snapshotCPData_->Record(bcIns, bcIndex, *recordNamePtr, method);
}
@ -209,6 +215,7 @@ void BytecodeInfoCollector::CollectMethodPcsFromBC(const uint32_t insSz, const u
method->SetIsFastCall(canFastCall);
method->SetNoGCBit(noGC);
method->SetHasDebuggerStmtBit(debuggerStmt);
method->SetCanTypedCall(canTypedCall);
}
// static
@ -281,7 +288,7 @@ void BytecodeInfoCollector::CollectInnerMethodsFromNewLiteral(panda_file::File::
void BytecodeInfoCollector::CollectMethodInfoFromBC(const BytecodeInstruction &bcIns, const MethodLiteral *method,
int32_t bcIndex, const std::shared_ptr<CString> recordNamePtr,
std::vector<panda_file::File::EntityId> &classConstructIndexes,
bool *canFastCall)
bool *canFastCall, bool *canTypedCall)
{
if (!(bcIns.HasFlag(BytecodeInstruction::Flags::STRING_ID) &&
BytecodeInstruction::HasId(BytecodeInstruction::GetFormat(bcIns.GetOpcode()), 0))) {
@ -342,13 +349,17 @@ void BytecodeInfoCollector::CollectMethodInfoFromBC(const BytecodeInstruction &b
case EcmaOpcode::SUPERCALLTHISRANGE_IMM8_IMM8_V8:
case EcmaOpcode::WIDE_SUPERCALLTHISRANGE_PREF_IMM16_V8:
case EcmaOpcode::SUPERCALLARROWRANGE_IMM8_IMM8_V8:
case EcmaOpcode::WIDE_SUPERCALLARROWRANGE_PREF_IMM16_V8:
case EcmaOpcode::WIDE_SUPERCALLARROWRANGE_PREF_IMM16_V8: {
*canFastCall = false;
break;
}
case EcmaOpcode::SUPERCALLSPREAD_IMM8_V8:
case EcmaOpcode::GETUNMAPPEDARGS:
case EcmaOpcode::COPYRESTARGS_IMM8:
case EcmaOpcode::WIDE_COPYRESTARGS_PREF_IMM16: {
*canFastCall = false;
return;
*canTypedCall = false;
break;
}
default:
break;

View File

@ -382,7 +382,8 @@ private:
const std::shared_ptr<CString> recordNamePtr);
void CollectMethodInfoFromBC(const BytecodeInstruction &bcIns, const MethodLiteral *method, int32_t bcIndex,
const std::shared_ptr<CString> recordNamePtr,
std::vector<panda_file::File::EntityId> &classConstructIndexes, bool *canFastCall);
std::vector<panda_file::File::EntityId> &classConstructIndexes, bool *canFastCall,
bool *canTypedCall);
void IterateLiteral(const MethodLiteral *method, std::vector<uint32_t> &classOffsetVector);
void StoreClassTypeOffset(const uint32_t typeOffset, std::vector<uint32_t> &classOffsetVector);
void CollectClassLiteralInfo(const MethodLiteral *method, const std::vector<std::string> &classNameVec);

View File

@ -292,20 +292,19 @@ void NewLexicalEnvStubBuilder::GenerateCircuit()
void CopyRestArgsStubBuilder::GenerateCircuit()
{
DEFVARIABLE(argumentsList, VariableType::JS_ANY(), Undefined());
DEFVARIABLE(arrayObj, VariableType::JS_ANY(), Undefined());
DEFVARIABLE(actualRestNum, VariableType::INT32(), Int32(0));
DEFVARIABLE(argv, VariableType::NATIVE_POINTER(), PtrArgument(1));
DEFVARIABLE(i, VariableType::INT32(), Int32(0));
DEFVARIABLE(actualRestNum, VariableType::INT32(), Int32(0));
auto env = GetEnvironment();
GateRef glue = PtrArgument(0);
GateRef startIdx = Int32Argument(2); /* 2 : 3rd parameter is index */
GateRef numArgs = Int32Argument(3); /* 3 : 4th parameter is index */
Label afterArgumentsList(env);
Label newArgumentsObj(env);
Label numArgsGreater(env);
Label numArgsNotGreater(env);
Label calcArgv(env);
Label hasArgv(env);
Label afterCreateArrayObj(env);
BRANCH(Equal(*argv, IntPtr(0)), &calcArgv, &hasArgv);
Bind(&calcArgv);
argv = CallNGCRuntime(glue, RTSTUB_ID(GetActualArgvNoGC), { glue });
@ -321,23 +320,14 @@ void CopyRestArgsStubBuilder::GenerateCircuit()
Jump(&numArgsNotGreater);
}
Bind(&numArgsNotGreater);
// 2. Construct arguments list.
// 2. Construct RestArguments object.
NewObjectStubBuilder newBuilder(this);
newBuilder.SetParameters(glue, 0);
newBuilder.NewArgumentsList(&argumentsList, &afterArgumentsList, args, startIdx, *actualRestNum);
Bind(&afterArgumentsList);
// 3. Construct rest array.
GateRef glueGlobalEnvOffset = IntPtr(JSThread::GlueData::GetGlueGlobalEnvOffset(env->Is32Bit()));
GateRef glueGlobalEnv = Load(VariableType::NATIVE_POINTER(), glue, glueGlobalEnvOffset);
GateRef arrayFunc = GetGlobalEnvValue(VariableType::JS_ANY(), glueGlobalEnv, GlobalEnv::ARRAY_FUNCTION_INDEX);
GateRef hclass = Load(VariableType::JS_POINTER(), arrayFunc, IntPtr(JSFunction::PROTO_OR_DYNCLASS_OFFSET));
arrayObj = newBuilder.NewJSArrayWithSize(hclass, *actualRestNum);
GateRef lengthOffset = IntPtr(JSArray::LENGTH_OFFSET);
Store(VariableType::INT32(), glue, *arrayObj, lengthOffset, *actualRestNum);
GateRef accessor = GetGlobalConstantValue(VariableType::JS_ANY(), glue, ConstantIndex::ARRAY_LENGTH_ACCESSOR);
SetPropertyInlinedProps(glue, *arrayObj, hclass, accessor, Int32(JSArray::LENGTH_INLINE_PROPERTY_INDEX));
SetExtensibleToBitfield(glue, *arrayObj, true);
SetElementsArray(VariableType::JS_POINTER(), glue, *arrayObj, *argumentsList);
GateRef intialHClass = GetGlobalConstantValue(VariableType::JS_ANY(), glue,
ConstantIndex::ELEMENT_HOLE_TAGGED_HCLASS_INDEX);
arrayObj = newBuilder.NewJSArrayWithSize(intialHClass, *actualRestNum);
newBuilder.AssignRestArg(&arrayObj, &afterCreateArrayObj, args, startIdx, *actualRestNum, intialHClass);
Bind(&afterCreateArrayObj);
Return(*arrayObj);
}

View File

@ -1312,6 +1312,36 @@ void NewObjectStubBuilder::NewArgumentsObj(Variable *result, Label *exit,
Jump(exit);
}
void NewObjectStubBuilder::AssignRestArg(Variable *result, Label *exit,
GateRef sp, GateRef startIdx, GateRef numArgs, GateRef intialHClass)
{
auto env = GetEnvironment();
DEFVARIABLE(i, VariableType::INT32(), Int32(0));
GateRef lengthOffset = IntPtr(JSArray::LENGTH_OFFSET);
Store(VariableType::INT32(), glue_, result->ReadVariable(), lengthOffset, TruncInt64ToInt32(numArgs));
GateRef accessor = GetGlobalConstantValue(VariableType::JS_ANY(), glue_, ConstantIndex::ARRAY_LENGTH_ACCESSOR);
SetPropertyInlinedProps(glue_, result->ReadVariable(), intialHClass, accessor,
Int32(JSArray::LENGTH_INLINE_PROPERTY_INDEX));
SetExtensibleToBitfield(glue_, result->ReadVariable(), true);
Label setArgumentsBegin(env);
Label setArgumentsAgain(env);
Label setArgumentsEnd(env);
GateRef elements = GetElementsArray(result->ReadVariable());
BRANCH(Int32UnsignedLessThan(*i, numArgs), &setArgumentsBegin, &setArgumentsEnd);
LoopBegin(&setArgumentsBegin);
{
GateRef idx = ZExtInt32ToPtr(Int32Add(startIdx, *i));
GateRef receiver = Load(VariableType::JS_ANY(), sp, PtrMul(IntPtr(sizeof(JSTaggedType)), idx));
SetValueToTaggedArray(VariableType::JS_ANY(), glue_, elements, *i, receiver);
i = Int32Add(*i, Int32(1));
BRANCH(Int32UnsignedLessThan(*i, numArgs), &setArgumentsAgain, &setArgumentsEnd);
Bind(&setArgumentsAgain);
}
LoopEnd(&setArgumentsBegin);
Bind(&setArgumentsEnd);
Jump(exit);
}
void NewObjectStubBuilder::NewJSArrayLiteral(Variable *result, Label *exit, RegionSpaceFlag spaceType, GateRef obj,
GateRef hclass, GateRef trackInfo, bool isEmptyArray)
{

View File

@ -81,6 +81,8 @@ public:
GateRef EnumerateObjectProperties(GateRef glue, GateRef obj);
void NewArgumentsList(Variable *result, Label *exit, GateRef sp, GateRef startIdx, GateRef numArgs);
void NewArgumentsObj(Variable *result, Label *exit, GateRef argumentsList, GateRef numArgs);
void AssignRestArg(Variable *result, Label *exit, GateRef sp, GateRef startIdx, GateRef numArgs,
GateRef intialHClass);
void AllocLineStringObject(Variable *result, Label *exit, GateRef length, bool compressed);
void AllocSlicedStringObject(Variable *result, Label *exit, GateRef from, GateRef length,
FlatStringStubBuilder *flatString);

View File

@ -333,8 +333,10 @@ bool TypeOfTypeInfoAccessor::IsIllegalType() const
return true;
}
SuperCallTypeInfoAccessor::SuperCallTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate)
: TypeInfoAccessor(env, circuit, gate)
SuperCallTypeInfoAccessor::SuperCallTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate,
const JSPandaFile *jsPandaFile,
const CallMethodFlagMap *callMethodFlagMap)
: TypeInfoAccessor(env, circuit, gate), jsPandaFile_(jsPandaFile), callMethodFlagMap_(callMethodFlagMap)
{
ctor_ = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC);
}

View File

@ -353,7 +353,9 @@ class SuperCallTypeInfoAccessor final : public TypeInfoAccessor {
public:
SuperCallTypeInfoAccessor(const CompilationEnv *env,
Circuit *circuit,
GateRef gate);
GateRef gate,
const JSPandaFile *jsPandaFile = nullptr,
const CallMethodFlagMap *callMethodFlagMap = nullptr);
NO_COPY_SEMANTIC(SuperCallTypeInfoAccessor);
NO_MOVE_SEMANTIC(SuperCallTypeInfoAccessor);
@ -362,11 +364,27 @@ public:
return pgoType_.IsValidCallMethodId();
}
uint32_t GetMethodId() const
{
if (jsPandaFile_ == nullptr || callMethodFlagMap_ == nullptr) {
return 0;
}
auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType();
if (!profileType->IsNone()) {
return profileType->GetProfileType().GetId();
}
return 0;
}
GateRef GetCtor() const
{
return ctor_;
}
protected:
const JSPandaFile *jsPandaFile_;
const CallMethodFlagMap *callMethodFlagMap_;
private:
GateRef ctor_;
};

View File

@ -1549,7 +1549,16 @@ bool TypedBytecodeLowering::TryLowerNewBuiltinConstructor(GateRef gate)
void TypedBytecodeLowering::LowerTypedSuperCall(GateRef gate)
{
SuperCallTypeInfoAccessor tacc(compilationEnv_, circuit_, gate);
SuperCallTypeInfoAccessor tacc(compilationEnv_, circuit_, gate, GetCalleePandaFile(gate), callMethodFlagMap_);
auto methodId = tacc.GetMethodId();
if (methodId == 0) {
return;
}
auto *methodLiteral = ctx_->GetJSPandaFile()->FindMethodLiteral(methodId);
if (!methodLiteral->IsTypedCall()) {
return;
}
if (!tacc.IsValidCallMethodId()) {
return;
}
@ -1740,6 +1749,14 @@ void TypedBytecodeLowering::LowerTypedCall(const TypeAccessor &tacc)
if (!tacc.IsHotnessFunc()) {
return;
}
auto methodId = tacc.GetMethodId();
if (methodId == 0) {
return;
}
auto *methodLiteral = ctx_->GetJSPandaFile()->FindMethodLiteral(methodId);
if (!methodLiteral->IsTypedCall()) {
return;
}
uint32_t argc = tacc.GetArgc();
GateRef gate = tacc.GetGate();
GateRef actualArgc = Circuit::NullGate();
@ -1898,6 +1915,14 @@ bool TypedBytecodeLowering::IsLoadVtable(GateRef func)
template<EcmaOpcode Op, class TypeAccessor>
void TypedBytecodeLowering::LowerTypedThisCall(const TypeAccessor &tacc)
{
auto methodId = tacc.GetMethodId();
if (methodId == 0) {
return;
}
auto *methodLiteral = ctx_->GetJSPandaFile()->FindMethodLiteral(methodId);
if (!methodLiteral->IsTypedCall()) {
return;
}
if (!tacc.IsHotnessFunc()) {
return;
}

View File

@ -225,6 +225,7 @@ public:
using HasDebuggerStmtBit = IsNoGCBit::NextFlag; // offset 13
using EmptyBit = HasDebuggerStmtBit::NextField<uint8_t, EMPTY_BITS>; // offset 14-29
using IsSharedBit = EmptyBit::NextFlag; // offset 30
using CanTypedCall = IsSharedBit::NextFlag; // offset 31
inline NO_THREAD_SANITIZE void SetHotnessCounter(int16_t counter)
{
@ -292,6 +293,16 @@ public:
return IsSharedBit::Decode(extraLiteralInfo_);
}
void SetCanTypedCall(bool isTypedCall)
{
extraLiteralInfo_ = CanTypedCall::Update(extraLiteralInfo_, isTypedCall);
}
bool IsTypedCall() const
{
return CanTypedCall::Decode(extraLiteralInfo_);
}
FunctionKind GetFunctionKind() const
{
return static_cast<FunctionKind>(FunctionKindBits::Decode(extraLiteralInfo_));