mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-23 18:20:04 +00:00
!849 Add STLETTOGLOBALRECORD slow path
Merge pull request !849 from taohong/DevLowering
This commit is contained in:
commit
ac88a6ad3f
@ -389,7 +389,7 @@ DEF_CALL_SIGNATURE(SetValueWithBarrier)
|
||||
|
||||
std::array<VariableType, 4> params = { // 4 : 4 input parameters
|
||||
VariableType::POINTER(),
|
||||
VariableType::POINTER(),
|
||||
VariableType::JS_POINTER(),
|
||||
VariableType::POINTER(),
|
||||
VariableType::JS_ANY()
|
||||
};
|
||||
|
@ -479,7 +479,7 @@ void SetValueWithBarrierStub::GenerateCircuit(const CompilationConfig *cfg)
|
||||
{
|
||||
Stub::GenerateCircuit(cfg);
|
||||
GateRef glue = PtrArgument(0);
|
||||
GateRef obj = PtrArgument(1);
|
||||
GateRef obj = TaggedArgument(1);
|
||||
GateRef offset = PtrArgument(2); // 2 : 3rd para
|
||||
GateRef value = TaggedArgument(3); // 3 : 4th para
|
||||
SetValueWithBarrier(glue, obj, offset, value);
|
||||
|
@ -1288,6 +1288,20 @@ void LLVMIRBuilder::HandleAdd(GateRef gate)
|
||||
VisitAdd(gate, g0, g1);
|
||||
}
|
||||
|
||||
bool IsAddIntergerType(MachineType machineType)
|
||||
{
|
||||
switch (machineType) {
|
||||
case MachineType::I8:
|
||||
case MachineType::I16:
|
||||
case MachineType::I32:
|
||||
case MachineType::I64:
|
||||
case MachineType::ARCH:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void LLVMIRBuilder::VisitAdd(GateRef gate, GateRef e1, GateRef e2)
|
||||
{
|
||||
COMPILER_LOG(DEBUG) << "add gate:" << gate;
|
||||
@ -1302,8 +1316,7 @@ void LLVMIRBuilder::VisitAdd(GateRef gate, GateRef e1, GateRef e2)
|
||||
LLVMTypeRef returnType = ConvertLLVMTypeFromGate(gate);
|
||||
|
||||
auto machineType = circuit_->LoadGatePtrConst(gate)->GetMachineType();
|
||||
if (machineType == MachineType::I32 || machineType == MachineType::I64 ||
|
||||
machineType == MachineType::I8 || machineType == MachineType::I16) {
|
||||
if (IsAddIntergerType(machineType)) {
|
||||
auto e1Type = LLVMGetTypeKind(ConvertLLVMTypeFromGate(e1));
|
||||
if (e1Type == LLVMVectorTypeKind) {
|
||||
result = VectorAdd(e1Value, e2Value, returnType);
|
||||
@ -1361,6 +1374,18 @@ void LLVMIRBuilder::HandleMul(GateRef gate)
|
||||
VisitMul(gate, g0, g1);
|
||||
}
|
||||
|
||||
bool IsMulIntergerType(MachineType machineType)
|
||||
{
|
||||
switch (machineType) {
|
||||
case MachineType::I32:
|
||||
case MachineType::I64:
|
||||
case MachineType::ARCH:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void LLVMIRBuilder::VisitMul(GateRef gate, GateRef e1, GateRef e2)
|
||||
{
|
||||
COMPILER_LOG(DEBUG) << "mul gate:" << gate;
|
||||
@ -1370,7 +1395,7 @@ void LLVMIRBuilder::VisitMul(GateRef gate, GateRef e1, GateRef e2)
|
||||
COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
|
||||
LLVMValueRef result = nullptr;
|
||||
auto machineType = circuit_->LoadGatePtrConst(gate)->GetMachineType();
|
||||
if (machineType == MachineType::I32 || machineType == MachineType::I64) {
|
||||
if (IsMulIntergerType(machineType)) {
|
||||
result = LLVMBuildMul(builder_, e1Value, e2Value, "");
|
||||
} else if (machineType == MachineType::F64) {
|
||||
result = LLVMBuildFMul(builder_, e1Value, e2Value, "");
|
||||
|
@ -531,6 +531,39 @@ void SlowPathLowering::Lower(GateRef gate, EcmaOpcode op)
|
||||
case STCONSTTOGLOBALRECORD_PREF_ID32:
|
||||
LowerStConstToGlobalRecord(gate, glue);
|
||||
break;
|
||||
case STLETTOGLOBALRECORD_PREF_ID32:
|
||||
LowerStLetToGlobalRecord(gate, glue, jsFunc);
|
||||
break;
|
||||
case STCLASSTOGLOBALRECORD_PREF_ID32:
|
||||
LowerStClassToGlobalRecord(gate, glue, jsFunc);
|
||||
break;
|
||||
case STOWNBYVALUEWITHNAMESET_PREF_V8_V8:
|
||||
LowerStOwnByValueWithNameSet(gate, glue);
|
||||
break;
|
||||
case STOWNBYNAMEWITHNAMESET_PREF_ID32_V8:
|
||||
LowerStOwnByNameWithNameSet(gate, glue, jsFunc);
|
||||
break;
|
||||
case LDGLOBALVAR_PREF_ID32:
|
||||
LowerLdGlobalVar(gate, glue);
|
||||
break;
|
||||
case LDOBJBYNAME_PREF_ID32_V8:
|
||||
LowerLdObjByName(gate, glue, jsFunc);
|
||||
break;
|
||||
case STOBJBYNAME_PREF_ID32_V8:
|
||||
LowerStObjByName(gate, glue, jsFunc);
|
||||
break;
|
||||
case LDSUPERBYNAME_PREF_ID32_V8:
|
||||
LowerLdSuperByName(gate, glue, jsFunc);
|
||||
break;
|
||||
case STSUPERBYNAME_PREF_ID32_V8:
|
||||
LowerStSuperByName(gate, glue, jsFunc);
|
||||
break;
|
||||
case CREATEGENERATOROBJ_PREF_V8:
|
||||
LowerCreateGeneratorObj(gate, glue);
|
||||
break;
|
||||
case STARRAYSPREAD_PREF_V8_V8:
|
||||
LowerStArraySpread(gate, glue);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1904,4 +1937,237 @@ void SlowPathLowering::LowerStConstToGlobalRecord(GateRef gate, GateRef glue)
|
||||
{ propKey, value, isConst });
|
||||
LowerHirToCall(gate, newGate);
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerStLetToGlobalRecord(GateRef gate, GateRef glue, GateRef jsFunc)
|
||||
{
|
||||
builder_.NewLabelManager(gate);
|
||||
Label successExit(&builder_);
|
||||
Label exceptionExit(&builder_);
|
||||
// 2: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 2);
|
||||
GateRef prop = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
|
||||
GateRef falseConst = builder_.Boolean(false);
|
||||
GateRef result = builder_.CallRuntime(glue, RTSTUB_ID(StGlobalRecord),
|
||||
{prop, acc_.GetValueIn(gate, 1), falseConst});
|
||||
builder_.Branch(builder_.TaggedSpecialValueChecker(result, JSTaggedValue::VALUE_EXCEPTION),
|
||||
&exceptionExit, &successExit);
|
||||
CREATE_DOUBLE_EXIT(successExit, exceptionExit)
|
||||
builder_.MergeMirCircuit(gate, Circuit::NullGate(), successControl, failControl);
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerStClassToGlobalRecord(GateRef gate, GateRef glue, GateRef jsFunc)
|
||||
{
|
||||
builder_.NewLabelManager(gate);
|
||||
Label successExit(&builder_);
|
||||
Label exceptionExit(&builder_);
|
||||
// 2: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 2);
|
||||
GateRef prop = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
|
||||
GateRef falseConst = builder_.Boolean(false);
|
||||
GateRef result = builder_.CallRuntime(glue, RTSTUB_ID(StGlobalRecord),
|
||||
{prop, acc_.GetValueIn(gate, 1), falseConst});
|
||||
builder_.Branch(builder_.TaggedSpecialValueChecker(result, JSTaggedValue::VALUE_EXCEPTION),
|
||||
&exceptionExit, &successExit);
|
||||
CREATE_DOUBLE_EXIT(successExit, exceptionExit)
|
||||
builder_.MergeMirCircuit(gate, Circuit::NullGate(), successControl, failControl);
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerStOwnByValueWithNameSet(GateRef gate, GateRef glue)
|
||||
{
|
||||
builder_.NewLabelManager(gate);
|
||||
// 3: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 3);
|
||||
GateRef receiver = acc_.GetValueIn(gate, 0);
|
||||
GateRef propKey = acc_.GetValueIn(gate, 1);
|
||||
GateRef accValue = acc_.GetValueIn(gate, 2);
|
||||
Label isHeapObject(&builder_);
|
||||
Label slowPath(&builder_);
|
||||
Label notClassConstructor(&builder_);
|
||||
Label notClassPrototype(&builder_);
|
||||
Label notHole(&builder_);
|
||||
Label successExit(&builder_);
|
||||
Label exceptionExit(&builder_);
|
||||
GateRef res;
|
||||
builder_.Branch(builder_.TaggedIsHeapObject(receiver), &isHeapObject, &slowPath);
|
||||
builder_.Bind(&isHeapObject);
|
||||
{
|
||||
builder_.Branch(builder_.IsClassConstructor(receiver), &slowPath, ¬ClassConstructor);
|
||||
builder_.Bind(¬ClassConstructor);
|
||||
{
|
||||
builder_.Branch(builder_.IsClassPrototype(receiver), &slowPath, ¬ClassPrototype);
|
||||
builder_.Bind(¬ClassPrototype);
|
||||
{
|
||||
res = builder_.CallStub(glue, CommonStubCSigns::SetPropertyByValue,
|
||||
{ glue, receiver, propKey, accValue });
|
||||
builder_.Branch(builder_.TaggedSpecialValueChecker(res, JSTaggedValue::VALUE_HOLE),
|
||||
&slowPath, ¬Hole);
|
||||
builder_.Bind(¬Hole);
|
||||
{
|
||||
Label notexception(&builder_);
|
||||
builder_.Branch(builder_.TaggedSpecialValueChecker(res, JSTaggedValue::VALUE_EXCEPTION),
|
||||
&exceptionExit, ¬exception);
|
||||
builder_.Bind(¬exception);
|
||||
res = builder_.CallRuntime(glue, RTSTUB_ID(SetFunctionNameNoPrefix),
|
||||
{ accValue, propKey });
|
||||
builder_.Branch(builder_.TaggedSpecialValueChecker(res, JSTaggedValue::VALUE_EXCEPTION),
|
||||
&exceptionExit, &successExit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
builder_.Bind(&slowPath);
|
||||
{
|
||||
res = builder_.CallRuntime(glue, RTSTUB_ID(StOwnByValueWithNameSet), { receiver, propKey, accValue });
|
||||
builder_.Branch(builder_.TaggedSpecialValueChecker(res, JSTaggedValue::VALUE_EXCEPTION),
|
||||
&exceptionExit, &successExit);
|
||||
}
|
||||
CREATE_DOUBLE_EXIT(successExit, exceptionExit)
|
||||
builder_.MergeMirCircuit(gate, Circuit::NullGate(), successControl, failControl);
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerStOwnByNameWithNameSet(GateRef gate, GateRef glue, GateRef jsFunc)
|
||||
{
|
||||
builder_.NewLabelManager(gate);
|
||||
// 3: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 3);
|
||||
GateRef propKey = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
|
||||
GateRef receiver = acc_.GetValueIn(gate, 1);
|
||||
GateRef accValue = acc_.GetValueIn(gate, 2);
|
||||
GateRef result;
|
||||
Label isJsObject(&builder_);
|
||||
Label notJSObject(&builder_);
|
||||
Label notClassConstructor(&builder_);
|
||||
Label notClassPrototype(&builder_);
|
||||
Label notHole(&builder_);
|
||||
Label successExit(&builder_);
|
||||
Label exceptionExit(&builder_);
|
||||
builder_.Branch(builder_.IsJsObject(receiver), &isJsObject, ¬JSObject);
|
||||
builder_.Bind(&isJsObject);
|
||||
{
|
||||
builder_.Branch(builder_.IsClassConstructor(receiver), ¬JSObject, ¬ClassConstructor);
|
||||
builder_.Bind(¬ClassConstructor);
|
||||
{
|
||||
builder_.Branch(builder_.IsClassPrototype(receiver), ¬JSObject, ¬ClassPrototype);
|
||||
builder_.Bind(¬ClassPrototype);
|
||||
{
|
||||
result = builder_.CallStub(glue, CommonStubCSigns::SetPropertyByNameWithOwn,
|
||||
{ glue, receiver, propKey, accValue });
|
||||
builder_.Branch(builder_.TaggedSpecialValueChecker(result, JSTaggedValue::VALUE_HOLE),
|
||||
¬JSObject, ¬Hole);
|
||||
builder_.Bind(¬Hole);
|
||||
{
|
||||
Label notException(&builder_);
|
||||
builder_.Branch(builder_.TaggedSpecialValueChecker(result, JSTaggedValue::VALUE_EXCEPTION),
|
||||
&exceptionExit, ¬Exception);
|
||||
builder_.Bind(¬Exception);
|
||||
result = builder_.CallRuntime(glue, RTSTUB_ID(SetFunctionNameNoPrefix), {accValue, propKey});
|
||||
builder_.Branch(builder_.TaggedSpecialValueChecker(result, JSTaggedValue::VALUE_EXCEPTION),
|
||||
&exceptionExit, &successExit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
builder_.Bind(¬JSObject);
|
||||
{
|
||||
result = builder_.CallRuntime(glue, RTSTUB_ID(StOwnByNameWithNameSet), { receiver, propKey, accValue });
|
||||
builder_.Branch(builder_.TaggedSpecialValueChecker(result, JSTaggedValue::VALUE_EXCEPTION),
|
||||
&exceptionExit, &successExit);
|
||||
}
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerLdGlobalVar(GateRef gate, GateRef glue)
|
||||
{
|
||||
GateRef prop = GetValueFromConstStringTable(glue, gate, 0);
|
||||
GateRef id = builder_.Int64(RTSTUB_ID(TryLdGlobalByName));
|
||||
// 1: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 1);
|
||||
GateRef newGate =
|
||||
builder_.RuntimeCall(glue, id, Circuit::GetCircuitRoot(OpCode(OpCode::DEPEND_ENTRY)), {prop});
|
||||
LowerHirToCall(gate, newGate);
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerLdObjByName(GateRef gate, GateRef glue, GateRef jsFunc)
|
||||
{
|
||||
builder_.NewLabelManager(gate);
|
||||
Label successExit(&builder_);
|
||||
Label exceptionExit(&builder_);
|
||||
// 2: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 2);
|
||||
GateRef prop = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
|
||||
GateRef undefined = builder_.Int64(JSTaggedValue::VALUE_UNDEFINED);
|
||||
GateRef result = builder_.CallRuntime(glue, RTSTUB_ID(LoadICByName), {undefined,
|
||||
acc_.GetValueIn(gate, 1), prop, builder_.IntBuildTaggedTypeWithNoGC(undefined)});
|
||||
builder_.Branch(builder_.TaggedSpecialValueChecker(result, JSTaggedValue::VALUE_EXCEPTION),
|
||||
&exceptionExit, &successExit);
|
||||
CREATE_DOUBLE_EXIT(successExit, exceptionExit)
|
||||
builder_.MergeMirCircuit(gate, result, successControl, failControl);
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerStObjByName(GateRef gate, GateRef glue, GateRef jsFunc)
|
||||
{
|
||||
builder_.NewLabelManager(gate);
|
||||
Label successExit(&builder_);
|
||||
Label exceptionExit(&builder_);
|
||||
// 3: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 3);
|
||||
GateRef prop = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
|
||||
GateRef undefined = builder_.Int64(JSTaggedValue::VALUE_UNDEFINED);
|
||||
GateRef result = builder_.CallRuntime(glue, RTSTUB_ID(StoreICByName), {undefined,
|
||||
acc_.GetValueIn(gate, 1), prop, acc_.GetValueIn(gate, 2), builder_.IntBuildTaggedTypeWithNoGC(undefined)});
|
||||
builder_.Branch(builder_.TaggedSpecialValueChecker(result, JSTaggedValue::VALUE_EXCEPTION),
|
||||
&exceptionExit, &successExit);
|
||||
CREATE_DOUBLE_EXIT(successExit, exceptionExit)
|
||||
builder_.MergeMirCircuit(gate, Circuit::NullGate(), successControl, failControl);
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerLdSuperByName(GateRef gate, GateRef glue, GateRef jsFunc)
|
||||
{
|
||||
builder_.NewLabelManager(gate);
|
||||
Label successExit(&builder_);
|
||||
Label exceptionExit(&builder_);
|
||||
// 2: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 2);
|
||||
GateRef prop = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
|
||||
GateRef result = builder_.CallRuntime(glue, RTSTUB_ID(LdSuperByValue), {prop, acc_.GetValueIn(gate, 1)});
|
||||
builder_.Branch(builder_.TaggedSpecialValueChecker(result, JSTaggedValue::VALUE_EXCEPTION),
|
||||
&exceptionExit, &successExit);
|
||||
CREATE_DOUBLE_EXIT(successExit, exceptionExit)
|
||||
builder_.MergeMirCircuit(gate, result, successControl, failControl);
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerStSuperByName(GateRef gate, GateRef glue, GateRef jsFunc)
|
||||
{
|
||||
builder_.NewLabelManager(gate);
|
||||
Label successExit(&builder_);
|
||||
Label exceptionExit(&builder_);
|
||||
// 2: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 3);
|
||||
GateRef prop = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
|
||||
GateRef result = builder_.CallRuntime(glue, RTSTUB_ID(StSuperByValue), {prop, acc_.GetValueIn(gate, 1),
|
||||
acc_.GetValueIn(gate, 2)});
|
||||
builder_.Branch(builder_.TaggedSpecialValueChecker(result, JSTaggedValue::VALUE_EXCEPTION),
|
||||
&exceptionExit, &successExit);
|
||||
CREATE_DOUBLE_EXIT(successExit, exceptionExit)
|
||||
builder_.MergeMirCircuit(gate, Circuit::NullGate(), successControl, failControl);
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerCreateGeneratorObj(GateRef gate, GateRef glue)
|
||||
{
|
||||
GateRef id = builder_.Int64(RTSTUB_ID(CreateGeneratorObj));
|
||||
// 1: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 1);
|
||||
GateRef newGate = builder_.RuntimeCall(glue, id, Circuit::GetCircuitRoot(OpCode(OpCode::DEPEND_ENTRY)),
|
||||
{acc_.GetValueIn(gate, 0)});
|
||||
LowerHirToCall(gate, newGate);
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerStArraySpread(GateRef gate, GateRef glue)
|
||||
{
|
||||
GateRef id = builder_.Int64(RTSTUB_ID(StArraySpread));
|
||||
// 3: number of value inputs
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 3);
|
||||
GateRef newGate = builder_.RuntimeCall(glue, id, Circuit::GetCircuitRoot(OpCode(OpCode::DEPEND_ENTRY)),
|
||||
{acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1), acc_.GetValueIn(gate, 2)});
|
||||
LowerHirToCall(gate, newGate);
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -225,6 +225,17 @@ private:
|
||||
void LowerStSuperByValue(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerTryStGlobalByName(GateRef gate, GateRef glue);
|
||||
void LowerStConstToGlobalRecord(GateRef gate, GateRef glue);
|
||||
void LowerStLetToGlobalRecord(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerStClassToGlobalRecord(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerStOwnByValueWithNameSet(GateRef gate, GateRef glue);
|
||||
void LowerStOwnByNameWithNameSet(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerLdGlobalVar(GateRef gate, GateRef glue);
|
||||
void LowerLdObjByName(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerStObjByName(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerLdSuperByName(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerStSuperByName(GateRef gate, GateRef glue, GateRef jsFunc);
|
||||
void LowerCreateGeneratorObj(GateRef gate, GateRef glue);
|
||||
void LowerStArraySpread(GateRef gate, GateRef glue);
|
||||
|
||||
BytecodeCircuitBuilder *bcBuilder_;
|
||||
Circuit *circuit_;
|
||||
|
Loading…
Reference in New Issue
Block a user