mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2025-02-25 23:08:22 +00:00
!8153 Workload performance optimization for harmcrest_test
Merge pull request !8153 from xingshunxiang/harmcrest_patch
This commit is contained in:
commit
d394070272
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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_;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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_));
|
||||
|
Loading…
x
Reference in New Issue
Block a user