mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 16:13:49 +00:00
fixed for Set/GetPropertyByValue & test262 case verify
Signed-off-by: getingke <getingke@huawei.com> Change-Id: I06214f39ebff93754edb3d275be4d4d76c1dba0c
This commit is contained in:
parent
121c45d6ab
commit
b35952f22a
@ -735,13 +735,13 @@ void GetPropertyByIndexStub::GenerateCircuit()
|
||||
StubDescriptor *callAccessorGetter = GET_STUBDESCRIPTOR(AccessorGetter);
|
||||
Return(CallRuntime(callAccessorGetter, thread,
|
||||
GetWord64Constant(FAST_STUB_ID(AccessorGetter)),
|
||||
{thread, *holder, value}));
|
||||
{thread, value, *holder}));
|
||||
}
|
||||
Bind(¬Internal);
|
||||
{
|
||||
StubDescriptor *callGetter = GET_STUBDESCRIPTOR(CallGetter);
|
||||
Return(CallRuntime(callGetter, thread, GetWord64Constant(FAST_STUB_ID(CallGetter)),
|
||||
{thread, receiver, value}));
|
||||
{thread, value, receiver}));
|
||||
}
|
||||
}
|
||||
Bind(¬Accessor);
|
||||
@ -891,7 +891,7 @@ void GetPropertyByNameStub::GenerateCircuit()
|
||||
Label isDicMode(env);
|
||||
Label notDicMode(env);
|
||||
// if branch condition : LIKELY(!hclass->IsDictionaryMode())
|
||||
Branch(IsDictionaryElement(hClass), &isDicMode, ¬DicMode);
|
||||
Branch(IsDictionaryModeByHClass(hClass), &isDicMode, ¬DicMode);
|
||||
Bind(¬DicMode);
|
||||
{
|
||||
// LayoutInfo *layoutInfo = LayoutInfo::Cast(hclass->GetAttributes().GetTaggedObject())
|
||||
@ -918,6 +918,7 @@ void GetPropertyByNameStub::GenerateCircuit()
|
||||
Label notAccessor(env);
|
||||
Branch(IsAccessor(attr), &isAccessor, ¬Accessor);
|
||||
Bind(&isAccessor);
|
||||
|
||||
{
|
||||
Label isInternal(env);
|
||||
Label notInternal(env);
|
||||
@ -927,13 +928,13 @@ void GetPropertyByNameStub::GenerateCircuit()
|
||||
StubDescriptor *callAccessorGetter = GET_STUBDESCRIPTOR(AccessorGetter);
|
||||
Return(CallRuntime(callAccessorGetter, thread,
|
||||
GetWord64Constant(FAST_STUB_ID(AccessorGetter)),
|
||||
{thread, *holder, value}));
|
||||
{thread, value, *holder}));
|
||||
}
|
||||
Bind(¬Internal);
|
||||
{
|
||||
StubDescriptor *callGetter = GET_STUBDESCRIPTOR(CallGetter);
|
||||
Return(CallRuntime(callGetter, thread, GetWord64Constant(FAST_STUB_ID(CallGetter)),
|
||||
{thread, receiver, value}));
|
||||
{thread, value, receiver}));
|
||||
}
|
||||
}
|
||||
Bind(¬Accessor);
|
||||
@ -976,13 +977,13 @@ void GetPropertyByNameStub::GenerateCircuit()
|
||||
StubDescriptor *callAccessorGetter1 = GET_STUBDESCRIPTOR(AccessorGetter);
|
||||
Return(CallRuntime(callAccessorGetter1, thread,
|
||||
GetWord64Constant(FAST_STUB_ID(AccessorGetter)),
|
||||
{thread, *holder, value}));
|
||||
{thread, value, *holder}));
|
||||
}
|
||||
Bind(¬Internal1);
|
||||
{
|
||||
StubDescriptor *callGetter1 = GET_STUBDESCRIPTOR(CallGetter);
|
||||
Return(CallRuntime(callGetter1, thread, GetWord64Constant(FAST_STUB_ID(CallGetter)),
|
||||
{thread, receiver, value}));
|
||||
{thread, value, receiver,}));
|
||||
}
|
||||
}
|
||||
Bind(¬Accessor1);
|
||||
@ -1314,4 +1315,159 @@ void FunctionCallInternalStub::GenerateCircuit()
|
||||
Return(CallRuntime(execute, thread, GetWord64Constant(FAST_STUB_ID(Execute)),
|
||||
{thread, func, thisArg, argc, argv}));
|
||||
}
|
||||
|
||||
void GetPropertyByValueStub::GenerateCircuit()
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
AddrShift thread = PtrArgument(0);
|
||||
AddrShift receiver = PtrArgument(1);
|
||||
DEFVARIABLE(key, TAGGED_TYPE, PtrArgument(2)); /* 2 : 3rd parameter is key */
|
||||
|
||||
Label isNumberOrStringSymbol(env);
|
||||
Label notNumber(env);
|
||||
Label isStringOrSymbol(env);
|
||||
Label notStringOrSymbol(env);
|
||||
Label exit(env);
|
||||
|
||||
Branch(TaggedIsNumber(*key), &isNumberOrStringSymbol, ¬Number);
|
||||
Bind(¬Number);
|
||||
{
|
||||
Branch(TaggedIsStringOrSymbol(*key), &isNumberOrStringSymbol, ¬StringOrSymbol);
|
||||
Bind(¬StringOrSymbol);
|
||||
{
|
||||
Return(GetHoleConstant());
|
||||
}
|
||||
}
|
||||
Bind(&isNumberOrStringSymbol);
|
||||
{
|
||||
AddrShift index = TryToElementsIndex(*key);
|
||||
Label validIndex(env);
|
||||
Label notValidIndex(env);
|
||||
Branch(Int32GreaterThanOrEqual(index, GetInteger32Constant(0)), &validIndex, ¬ValidIndex);
|
||||
Bind(&validIndex);
|
||||
{
|
||||
auto getPropertyByIndex = GET_STUBDESCRIPTOR(GetPropertyByIndex);
|
||||
Return(CallStub(getPropertyByIndex, GetWord64Constant(FAST_STUB_ID(GetPropertyByIndex)),
|
||||
{thread, receiver, index}));
|
||||
}
|
||||
Bind(¬ValidIndex);
|
||||
{
|
||||
Label notNumber(env);
|
||||
Label getByName(env);
|
||||
Branch(TaggedIsNumber(*key), &exit, ¬Number);
|
||||
Bind(¬Number);
|
||||
{
|
||||
Label isString(env);
|
||||
Label notString(env);
|
||||
Label isInternalString(env);
|
||||
Label notIntenalString(env);
|
||||
Branch(TaggedIsString(*key), &isString, ¬String);
|
||||
Bind(&isString);
|
||||
{
|
||||
Branch(IsInternalString(*key), &isInternalString, ¬IntenalString);
|
||||
Bind(&isInternalString);
|
||||
Jump(&getByName);
|
||||
Bind(¬IntenalString);
|
||||
{
|
||||
StubDescriptor *newInternalString = GET_STUBDESCRIPTOR(NewInternalString);
|
||||
key = CallRuntime(newInternalString, thread,
|
||||
GetWord64Constant(FAST_STUB_ID(NewInternalString)),
|
||||
{thread, *key});
|
||||
Jump(&getByName);
|
||||
}
|
||||
}
|
||||
Bind(¬String);
|
||||
{
|
||||
Jump(&getByName);
|
||||
}
|
||||
}
|
||||
Bind(&getByName);
|
||||
{
|
||||
auto getPropertyByName = GET_STUBDESCRIPTOR(GetPropertyByName);
|
||||
Return(CallStub(getPropertyByName, GetWord64Constant(FAST_STUB_ID(GetPropertyByName)),
|
||||
{thread, receiver, *key}));
|
||||
}
|
||||
}
|
||||
}
|
||||
Bind(&exit);
|
||||
Return(GetHoleConstant());
|
||||
}
|
||||
|
||||
void SetPropertyByValueStub::GenerateCircuit()
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
AddrShift thread = PtrArgument(0);
|
||||
AddrShift receiver = PtrArgument(1);
|
||||
DEFVARIABLE(key, TAGGED_TYPE, PtrArgument(2)); /* 2 : 3rd parameter is key */
|
||||
AddrShift value = Int64Argument(3); /* 3 : 4th parameter is value */
|
||||
|
||||
Label isNumberOrStringSymbol(env);
|
||||
Label notNumber(env);
|
||||
Label isStringOrSymbol(env);
|
||||
Label notStringOrSymbol(env);
|
||||
Label exit(env);
|
||||
|
||||
Branch(TaggedIsNumber(*key), &isNumberOrStringSymbol, ¬Number);
|
||||
Bind(¬Number);
|
||||
{
|
||||
Branch(TaggedIsStringOrSymbol(*key), &isNumberOrStringSymbol, ¬StringOrSymbol);
|
||||
Bind(¬StringOrSymbol);
|
||||
{
|
||||
Return(GetHoleConstant());
|
||||
}
|
||||
}
|
||||
Bind(&isNumberOrStringSymbol);
|
||||
{
|
||||
AddrShift index = TryToElementsIndex(*key);
|
||||
Label validIndex(env);
|
||||
Label notValidIndex(env);
|
||||
Branch(Int32GreaterThanOrEqual(index, GetInteger32Constant(0)), &validIndex, ¬ValidIndex);
|
||||
Bind(&validIndex);
|
||||
{
|
||||
auto setPropertyByIndex = GET_STUBDESCRIPTOR(SetPropertyByIndex);
|
||||
Return(CallStub(setPropertyByIndex, GetWord64Constant(FAST_STUB_ID(SetPropertyByIndex)),
|
||||
{thread, receiver, index, value}));
|
||||
}
|
||||
Bind(¬ValidIndex);
|
||||
{
|
||||
Label notNumber(env);
|
||||
Label getByName(env);
|
||||
Branch(TaggedIsNumber(*key), &exit, ¬Number);
|
||||
Bind(¬Number);
|
||||
{
|
||||
Label isString(env);
|
||||
Label notString(env);
|
||||
Label isInternalString(env);
|
||||
Label notIntenalString(env);
|
||||
Branch(TaggedIsString(*key), &isString, ¬String);
|
||||
Bind(&isString);
|
||||
{
|
||||
Branch(IsInternalString(*key), &isInternalString, ¬IntenalString);
|
||||
Bind(&isInternalString);
|
||||
Jump(&getByName);
|
||||
Bind(¬IntenalString);
|
||||
{
|
||||
StubDescriptor *newInternalString = GET_STUBDESCRIPTOR(NewInternalString);
|
||||
key = CallRuntime(newInternalString, thread,
|
||||
GetWord64Constant(FAST_STUB_ID(NewInternalString)),
|
||||
{thread, *key});
|
||||
Jump(&getByName);
|
||||
}
|
||||
}
|
||||
Bind(¬String);
|
||||
{
|
||||
Jump(&getByName);
|
||||
}
|
||||
}
|
||||
Bind(&getByName);
|
||||
{
|
||||
auto setPropertyByName = GET_STUBDESCRIPTOR(SetPropertyByName);
|
||||
Return(CallStub(setPropertyByName, GetWord64Constant(FAST_STUB_ID(SetPropertyByName)),
|
||||
{thread, receiver, *key, value}));
|
||||
}
|
||||
}
|
||||
}
|
||||
Bind(&exit);
|
||||
Return(GetHoleConstant());
|
||||
}
|
||||
} // namespace kungfu
|
@ -83,7 +83,10 @@ public:
|
||||
class GetElementStub : public Stub {
|
||||
public:
|
||||
// 3 : 3 means argument counts
|
||||
explicit GetElementStub(Circuit *circuit) : Stub("GetElement", 3, circuit) {}
|
||||
explicit GetElementStub(Circuit *circuit) : Stub("GetElement", 3, circuit)
|
||||
{
|
||||
circuit->SetFrameType(panda::ecmascript::FrameType::OPTIMIZED_ENTRY_FRAME);
|
||||
}
|
||||
~GetElementStub() = default;
|
||||
NO_MOVE_SEMANTIC(GetElementStub);
|
||||
NO_COPY_SEMANTIC(GetElementStub);
|
||||
@ -113,7 +116,10 @@ public:
|
||||
class GetPropertyByIndexStub : public Stub {
|
||||
public:
|
||||
// 3 : 3 means argument counts
|
||||
explicit GetPropertyByIndexStub(Circuit *circuit) : Stub("GetPropertyByIndex", 3, circuit) {}
|
||||
explicit GetPropertyByIndexStub(Circuit *circuit) : Stub("GetPropertyByIndex", 3, circuit)
|
||||
{
|
||||
circuit->SetFrameType(panda::ecmascript::FrameType::OPTIMIZED_ENTRY_FRAME);
|
||||
}
|
||||
~GetPropertyByIndexStub() = default;
|
||||
NO_MOVE_SEMANTIC(GetPropertyByIndexStub);
|
||||
NO_COPY_SEMANTIC(GetPropertyByIndexStub);
|
||||
@ -123,7 +129,10 @@ public:
|
||||
class SetPropertyByIndexStub : public Stub {
|
||||
public:
|
||||
// 4 : 4 means argument counts
|
||||
explicit SetPropertyByIndexStub(Circuit *circuit) : Stub("SetPropertyByIndex", 4, circuit) {}
|
||||
explicit SetPropertyByIndexStub(Circuit *circuit) : Stub("SetPropertyByIndex", 4, circuit)
|
||||
{
|
||||
circuit->SetFrameType(panda::ecmascript::FrameType::OPTIMIZED_ENTRY_FRAME);
|
||||
}
|
||||
~SetPropertyByIndexStub() = default;
|
||||
NO_MOVE_SEMANTIC(SetPropertyByIndexStub);
|
||||
NO_COPY_SEMANTIC(SetPropertyByIndexStub);
|
||||
@ -133,7 +142,10 @@ public:
|
||||
class GetPropertyByNameStub : public Stub {
|
||||
public:
|
||||
// 3 : 3 means argument counts
|
||||
explicit GetPropertyByNameStub(Circuit *circuit) : Stub("GetPropertyByName", 3, circuit) {}
|
||||
explicit GetPropertyByNameStub(Circuit *circuit) : Stub("GetPropertyByName", 3, circuit)
|
||||
{
|
||||
circuit->SetFrameType(panda::ecmascript::FrameType::OPTIMIZED_ENTRY_FRAME);
|
||||
}
|
||||
~GetPropertyByNameStub() = default;
|
||||
NO_MOVE_SEMANTIC(GetPropertyByNameStub);
|
||||
NO_COPY_SEMANTIC(GetPropertyByNameStub);
|
||||
@ -172,5 +184,31 @@ public:
|
||||
NO_COPY_SEMANTIC(FunctionCallInternalStub);
|
||||
void GenerateCircuit() override;
|
||||
};
|
||||
|
||||
class GetPropertyByValueStub : public Stub {
|
||||
public:
|
||||
// 3 : 3 means argument counts
|
||||
explicit GetPropertyByValueStub(Circuit *circuit) : Stub("FastGetPropertyByValue", 3, circuit)
|
||||
{
|
||||
circuit->SetFrameType(panda::ecmascript::FrameType::OPTIMIZED_ENTRY_FRAME);
|
||||
}
|
||||
~GetPropertyByValueStub() = default;
|
||||
NO_MOVE_SEMANTIC(GetPropertyByValueStub);
|
||||
NO_COPY_SEMANTIC(GetPropertyByValueStub);
|
||||
void GenerateCircuit() override;
|
||||
};
|
||||
|
||||
class SetPropertyByValueStub : public Stub {
|
||||
public:
|
||||
// 4 : 4 means argument counts
|
||||
explicit SetPropertyByValueStub(Circuit *circuit) : Stub("FastSetPropertyByValue", 4, circuit)
|
||||
{
|
||||
circuit->SetFrameType(panda::ecmascript::FrameType::OPTIMIZED_ENTRY_FRAME);
|
||||
}
|
||||
~SetPropertyByValueStub() = default;
|
||||
NO_MOVE_SEMANTIC(SetPropertyByValueStub);
|
||||
NO_COPY_SEMANTIC(SetPropertyByValueStub);
|
||||
void GenerateCircuit() override;
|
||||
};
|
||||
} // namespace kungfu
|
||||
#endif // ECMASCRIPT_COMPILER_FASTPATH_STUB_H
|
@ -29,7 +29,8 @@ namespace kungfu {
|
||||
V(FindElementWithCache, 4) \
|
||||
V(Execute, 5) \
|
||||
V(StringGetHashCode, 1) \
|
||||
V(FloatMod, 2)
|
||||
V(FloatMod, 2) \
|
||||
V(NewInternalString, 2)
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define FAST_RUNTIME_STUB_LIST(V) \
|
||||
@ -60,7 +61,9 @@ namespace kungfu {
|
||||
V(FindOwnElement2, 6) \
|
||||
V(GetPropertyByIndex, 3) \
|
||||
V(FunctionCallInternal, 5) \
|
||||
V(SetPropertyByIndex, 4)
|
||||
V(SetPropertyByIndex, 4) \
|
||||
V(GetPropertyByValue, 3) \
|
||||
V(SetPropertyByValue, 4)
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define TEST_FUNC_LIST(V) \
|
||||
|
@ -185,12 +185,20 @@ Properties OpCode::GetProperties() const
|
||||
return {INT64, NO_STATE, NO_DEPEND, VALUE(INT32), NO_ROOT};
|
||||
case ZEXT_INT1_TO_INT32:
|
||||
return {INT32, NO_STATE, NO_DEPEND, VALUE(INT1), NO_ROOT};
|
||||
case ZEXT_INT8_TO_INT32:
|
||||
return {INT32, NO_STATE, NO_DEPEND, VALUE(INT8), NO_ROOT};
|
||||
case ZEXT_INT16_TO_INT32:
|
||||
return {INT32, NO_STATE, NO_DEPEND, VALUE(INT16), NO_ROOT};
|
||||
case ZEXT_INT1_TO_INT64:
|
||||
return {INT64, NO_STATE, NO_DEPEND, VALUE(INT1), NO_ROOT};
|
||||
case SEXT_INT32_TO_INT64:
|
||||
return {INT64, NO_STATE, NO_DEPEND, VALUE(INT32), NO_ROOT};
|
||||
case SEXT_INT1_TO_INT32:
|
||||
return {INT32, NO_STATE, NO_DEPEND, VALUE(INT1), NO_ROOT};
|
||||
case SEXT_INT8_TO_INT32:
|
||||
return {INT32, NO_STATE, NO_DEPEND, VALUE(INT8), NO_ROOT};
|
||||
case SEXT_INT16_TO_INT32:
|
||||
return {INT32, NO_STATE, NO_DEPEND, VALUE(INT8), NO_ROOT};
|
||||
case SEXT_INT1_TO_INT64:
|
||||
return {INT64, NO_STATE, NO_DEPEND, VALUE(INT1), NO_ROOT};
|
||||
case TRUNC_INT64_TO_INT32:
|
||||
@ -400,9 +408,13 @@ std::string OpCode::Str() const
|
||||
{FLOAT64_CONSTANT, "FLOAT64_CONSTANT"},
|
||||
{ZEXT_INT32_TO_INT64, "ZEXT_INT32_TO_INT64"},
|
||||
{ZEXT_INT1_TO_INT32, "ZEXT_INT1_TO_INT32"},
|
||||
{ZEXT_INT8_TO_INT32, "ZEXT_INT8_TO_INT32"},
|
||||
{ZEXT_INT16_TO_INT32, "ZEXT_INT16_TO_INT32"},
|
||||
{ZEXT_INT1_TO_INT64, "ZEXT_INT1_TO_INT64"},
|
||||
{SEXT_INT32_TO_INT64, "SEXT_INT32_TO_INT64"},
|
||||
{SEXT_INT1_TO_INT32, "SEXT_INT1_TO_INT32"},
|
||||
{SEXT_INT8_TO_INT32, "SEXT_INT8_TO_INT32"},
|
||||
{SEXT_INT16_TO_INT32, "SEXT_INT16_TO_INT32"},
|
||||
{SEXT_INT1_TO_INT64, "SEXT_INT1_TO_INT64"},
|
||||
{TRUNC_INT64_TO_INT32, "TRUNC_INT64_TO_INT32"},
|
||||
{TRUNC_INT64_TO_INT1, "TRUNC_INT64_TO_INT1"},
|
||||
@ -1305,4 +1317,9 @@ bool OpCode::IsLoopHead() const
|
||||
{
|
||||
return (this->op == OpCode::LOOP_BEGIN);
|
||||
}
|
||||
|
||||
bool OpCode::IsNop() const
|
||||
{
|
||||
return (this->op == OpCode::NOP);
|
||||
}
|
||||
} // namespace kungfu
|
@ -147,9 +147,13 @@ public:
|
||||
FLOAT64_CONSTANT,
|
||||
ZEXT_INT32_TO_INT64,
|
||||
ZEXT_INT1_TO_INT32,
|
||||
ZEXT_INT8_TO_INT32,
|
||||
ZEXT_INT16_TO_INT32,
|
||||
ZEXT_INT1_TO_INT64,
|
||||
SEXT_INT32_TO_INT64,
|
||||
SEXT_INT1_TO_INT32,
|
||||
SEXT_INT8_TO_INT32,
|
||||
SEXT_INT16_TO_INT32,
|
||||
SEXT_INT1_TO_INT64,
|
||||
TRUNC_INT64_TO_INT32,
|
||||
TRUNC_INT64_TO_INT1,
|
||||
@ -253,6 +257,7 @@ public:
|
||||
[[nodiscard]] bool IsCFGMerge() const;
|
||||
[[nodiscard]] bool IsControlCase() const;
|
||||
[[nodiscard]] bool IsLoopHead() const;
|
||||
[[nodiscard]] bool IsNop() const;
|
||||
~OpCode() = default;
|
||||
|
||||
private:
|
||||
|
@ -92,6 +92,8 @@ void LLVMIRBuilder::AssignHandleMap()
|
||||
{OpCode::INT64_CONSTANT, &LLVMIRBuilder::HandleInt64Constant},
|
||||
{OpCode::FLOAT64_CONSTANT, &LLVMIRBuilder::HandleFloat64Constant},
|
||||
{OpCode::ZEXT_INT1_TO_INT32, &LLVMIRBuilder::HandleZExtInt},
|
||||
{OpCode::ZEXT_INT8_TO_INT32, &LLVMIRBuilder::HandleZExtInt},
|
||||
{OpCode::ZEXT_INT16_TO_INT32, &LLVMIRBuilder::HandleZExtInt},
|
||||
{OpCode::ZEXT_INT32_TO_INT64, &LLVMIRBuilder::HandleZExtInt},
|
||||
{OpCode::ZEXT_INT1_TO_INT64, &LLVMIRBuilder::HandleZExtInt},
|
||||
{OpCode::SEXT_INT1_TO_INT32, &LLVMIRBuilder::HandleSExtInt},
|
||||
@ -134,6 +136,8 @@ void LLVMIRBuilder::AssignHandleMap()
|
||||
{OpCode::FLOAT64_EQ, &LLVMIRBuilder::HandleFloatOrDoubleCmp},
|
||||
{OpCode::INT32_NE, &LLVMIRBuilder::HandleIntOrUintCmp},
|
||||
{OpCode::INT64_NE, &LLVMIRBuilder::HandleIntOrUintCmp},
|
||||
{OpCode::INT8_LOAD, &LLVMIRBuilder::HandleLoad},
|
||||
{OpCode::INT16_LOAD, &LLVMIRBuilder::HandleLoad},
|
||||
{OpCode::INT32_LOAD, &LLVMIRBuilder::HandleLoad},
|
||||
{OpCode::INT64_LOAD, &LLVMIRBuilder::HandleLoad},
|
||||
{OpCode::INT32_STORE, &LLVMIRBuilder::HandleStore},
|
||||
@ -186,7 +190,6 @@ void LLVMIRBuilder::Build()
|
||||
AddrShift gate = (*schedule_)[bbIdx][instIdx - 1];
|
||||
std::vector<AddrShift> ins = circuit_->GetInVector(gate);
|
||||
std::vector<AddrShift> outs = circuit_->GetOutVector(gate);
|
||||
std::cout << "instIdx :" << instIdx << std::endl;
|
||||
circuit_->Print(gate);
|
||||
auto found = opCodeHandleMap_.find(circuit_->GetOpCode(gate));
|
||||
if (found != opCodeHandleMap_.end()) {
|
||||
@ -362,6 +365,9 @@ LLVMTypeRef LLVMIRBuilder::GetMachineRepType(MachineRep rep) const
|
||||
case MachineRep::K_WORD8:
|
||||
dstType = LLVMInt8TypeInContext(context_);
|
||||
break;
|
||||
case MachineRep::K_WORD16:
|
||||
dstType = LLVMInt16TypeInContext(context_);
|
||||
break;
|
||||
case MachineRep::K_WORD32:
|
||||
dstType = LLVMInt32TypeInContext(context_);
|
||||
break;
|
||||
@ -626,6 +632,8 @@ void LLVMIRBuilder::HandleZExtInt(AddrShift gate)
|
||||
{
|
||||
std::vector<AddrShift> ins = circuit_->GetInVector(gate);
|
||||
switch (circuit_->GetOpCode(gate)) {
|
||||
case OpCode::ZEXT_INT8_TO_INT32: // no break, fall through
|
||||
case OpCode::ZEXT_INT16_TO_INT32:
|
||||
case OpCode::ZEXT_INT1_TO_INT32: {
|
||||
VisitZExtInt(gate, ins[0], MachineRep::K_WORD32);
|
||||
break;
|
||||
@ -1041,6 +1049,16 @@ void LLVMIRBuilder::HandleLoad(AddrShift gate)
|
||||
std::vector<AddrShift> ins = circuit_->GetInVector(gate);
|
||||
std::vector<AddrShift> outs = circuit_->GetOutVector(gate);
|
||||
switch (circuit_->GetOpCode(gate)) {
|
||||
case OpCode::INT8_LOAD: {
|
||||
AddrShift base = ins[1];
|
||||
VisitLoad(gate, MachineRep::K_WORD8, base);
|
||||
break;
|
||||
}
|
||||
case OpCode::INT16_LOAD: {
|
||||
AddrShift base = ins[1];
|
||||
VisitLoad(gate, MachineRep::K_WORD16, base);
|
||||
break;
|
||||
}
|
||||
case OpCode::INT32_LOAD: {
|
||||
AddrShift base = ins[1];
|
||||
VisitLoad(gate, MachineRep::K_WORD32, base);
|
||||
|
@ -104,7 +104,7 @@ void LLVMAssembler::BuildAndRunPasses() const
|
||||
LOG_ECMA(INFO) << "BuildAndRunPasses - ";
|
||||
LLVMPassManagerRef pass = LLVMCreatePassManager();
|
||||
LLVMAddConstantPropagationPass(pass);
|
||||
LLVMAddInstructionCombiningPass(pass);
|
||||
//LLVMAddInstructionCombiningPass(pass);
|
||||
llvm::unwrap(pass)->add(llvm::createRewriteStatepointsForGCLegacyPass());
|
||||
char *info = LLVMPrintModuleToString(module_);
|
||||
LOG_ECMA(INFO) << "Current Module: " << info;
|
||||
|
@ -34,10 +34,11 @@ AddrShift Stub::Variable::AddPhiOperand(AddrShift val)
|
||||
Label label = env_->GetLabelFromSelector(val);
|
||||
size_t idx = 0;
|
||||
for (auto pred : label.GetPredecessors()) {
|
||||
auto preVal = pred.ReadVariable(this);
|
||||
ASSERT(!env_->GetCircuit()->GetOpCode(preVal).IsNop());
|
||||
idx++;
|
||||
val = AddOperandToSelector(val, idx, pred.ReadVariable(this));
|
||||
val = AddOperandToSelector(val, idx, preVal);
|
||||
}
|
||||
|
||||
return TryRemoveTrivialPhi(val);
|
||||
}
|
||||
|
||||
@ -66,6 +67,7 @@ AddrShift Stub::Variable::TryRemoveTrivialPhi(AddrShift phiVal)
|
||||
// the phi is unreachable or in the start block
|
||||
same = env_->GetCircuit()->LoadGatePtr(env_->GetCircuitBuilder().UndefineConstant());
|
||||
}
|
||||
auto same_addr_shift = env_->GetCircuit()->SaveGatePtr(same);
|
||||
|
||||
// remove the trivial phi
|
||||
// get all users of phi except self
|
||||
@ -92,10 +94,15 @@ AddrShift Stub::Variable::TryRemoveTrivialPhi(AddrShift phiVal)
|
||||
for (auto out : outs) {
|
||||
if (IsSelector(out->GetGate())) {
|
||||
auto out_addr_shift = env_->GetCircuit()->SaveGatePtr(out->GetGate());
|
||||
TryRemoveTrivialPhi(out_addr_shift);
|
||||
auto result = TryRemoveTrivialPhi(out_addr_shift);
|
||||
if (same_addr_shift == out_addr_shift)
|
||||
{
|
||||
same_addr_shift = result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return env_->GetCircuit()->SaveGatePtr(same);
|
||||
return same_addr_shift;
|
||||
}
|
||||
|
||||
void Stub::Variable::RerouteOuts(const std::vector<Out *> &outs, Gate *newGate)
|
||||
@ -123,7 +130,10 @@ void LabelImpl::WriteVariable(Variable *var, AddrShift value)
|
||||
AddrShift LabelImpl::ReadVariable(Variable *var)
|
||||
{
|
||||
if (valueMap_.find(var) != valueMap_.end()) {
|
||||
return valueMap_.at(var);
|
||||
auto result = valueMap_.at(var);
|
||||
if (!env_->GetCircuit()->GetOpCode(result).IsNop()) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return ReadVariableRecursive(var);
|
||||
}
|
||||
@ -423,7 +433,7 @@ AddrShift Stub::FindElementFromNumberDictionary(AddrShift thread, AddrShift elem
|
||||
Bind(¬Match);
|
||||
Jump(&loopEnd);
|
||||
Bind(&loopEnd);
|
||||
entry = Word32And(Int32Add(*entry, *count), Int32Sub(capacity, GetInteger32Constant(1)));
|
||||
entry = GetNextPositionForHash(*entry, *count, capacity);
|
||||
count = Int32Add(*count, GetInteger32Constant(1));
|
||||
LoopEnd(&loopHead);
|
||||
Bind(&exit);
|
||||
@ -594,7 +604,7 @@ AddrShift Stub::FindEntryFromNameDictionary(AddrShift thread, AddrShift elements
|
||||
}
|
||||
Bind(&loopEnd);
|
||||
{
|
||||
entry = Word32And(Int32Add(*entry, *count), Int32Sub(capacity, GetInteger32Constant(1)));
|
||||
entry = GetNextPositionForHash(*entry, *count, capacity);
|
||||
count = Int32Add(*count, GetInteger32Constant(1));
|
||||
LoopEnd(&loopHead);
|
||||
}
|
||||
@ -626,7 +636,7 @@ AddrShift Stub::JSObjectGetProperty(AddrShift obj, AddrShift hClass, AddrShift a
|
||||
Int32Mul(Int32Sub(
|
||||
GetInteger32Constant(panda::ecmascript::JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS), attrOffset),
|
||||
GetInteger32Constant(panda::ecmascript::JSTaggedValue::TaggedTypeSize())));
|
||||
result = Int64BuildTagged(Load(UINT64_TYPE, obj, ZExtInt32ToInt64(propOffset)));
|
||||
result = Load(UINT64_TYPE, obj, ZExtInt32ToInt64(propOffset));
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(¬InlinedProp);
|
||||
@ -646,10 +656,9 @@ AddrShift Stub::JSObjectGetProperty(AddrShift obj, AddrShift hClass, AddrShift a
|
||||
|
||||
void Stub::ThrowTypeAndReturn(AddrShift thread, int messageId, AddrShift val)
|
||||
{
|
||||
AddrShift taggedId = GetInteger32Constant(messageId);
|
||||
StubDescriptor *throwTypeError = GET_STUBDESCRIPTOR(ThrowTypeError);
|
||||
CallRuntime(throwTypeError, thread, GetWord64Constant(FAST_STUB_ID(ThrowTypeError)),
|
||||
{thread, taggedId});
|
||||
AddrShift msgIntId = GetInteger32Constant(messageId);
|
||||
CallRuntime(throwTypeError, thread, GetWord64Constant(FAST_STUB_ID(ThrowTypeError)), {thread, msgIntId});
|
||||
Return(val);
|
||||
}
|
||||
|
||||
@ -793,4 +802,248 @@ void Stub::UpdateAndStoreRepresention(AddrShift hclass, AddrShift value)
|
||||
AddrShift newRep = UpdateRepresention(GetElementRepresentation(hclass), value);
|
||||
SetElementRepresentation(hclass, newRep);
|
||||
}
|
||||
|
||||
AddrShift Stub::TaggedIsString(AddrShift obj)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label entry(env);
|
||||
[[maybe_unused]] SubCircuitScope subCircuit(env, &entry);
|
||||
Label exit(env);
|
||||
DEFVARIABLE(result, BOOL_TYPE, FalseConstant());
|
||||
Label isHeapObject(env);
|
||||
Branch(TaggedIsHeapObject(obj), &isHeapObject, &exit);
|
||||
Bind(&isHeapObject);
|
||||
{
|
||||
result = Word32Equal(GetObjectType(LoadHClass(obj)),
|
||||
GetInteger32Constant(static_cast<int32_t>(panda::ecmascript::JSType::STRING)));
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(&exit);
|
||||
return *result;
|
||||
}
|
||||
|
||||
AddrShift Stub::TaggedIsStringOrSymbol(AddrShift obj)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label entry(env);
|
||||
[[maybe_unused]] SubCircuitScope subCircuit(env, &entry);
|
||||
Label exit(env);
|
||||
DEFVARIABLE(result, BOOL_TYPE, FalseConstant());
|
||||
Label isHeapObject(env);
|
||||
Branch(TaggedIsHeapObject(obj), &isHeapObject, &exit);
|
||||
Bind(&isHeapObject);
|
||||
{
|
||||
AddrShift objType = GetObjectType(LoadHClass(obj));
|
||||
result = Word32Equal(objType,
|
||||
GetInteger32Constant(static_cast<int32_t>(panda::ecmascript::JSType::STRING)));
|
||||
Label isString(env);
|
||||
Label notString(env);
|
||||
Branch(*result, &exit, ¬String);
|
||||
Bind(¬String);
|
||||
{
|
||||
result = Word32Equal(objType,
|
||||
GetInteger32Constant(static_cast<int32_t>(panda::ecmascript::JSType::SYMBOL)));
|
||||
Jump(&exit);
|
||||
}
|
||||
}
|
||||
Bind(&exit);
|
||||
return *result;
|
||||
}
|
||||
|
||||
AddrShift Stub::IsUtf16String(AddrShift string)
|
||||
{
|
||||
// compressedStringsEnabled fixed to true constant
|
||||
AddrShift len = Load(MachineType::UINT32_TYPE, string,
|
||||
GetPtrConstant(panda::ecmascript::EcmaString::GetLengthOffset()));
|
||||
return Word32Equal(
|
||||
Word32And(len, GetInteger32Constant(panda::ecmascript::EcmaString::STRING_COMPRESSED_BIT)),
|
||||
GetInteger32Constant(panda::ecmascript::EcmaString::STRING_UNCOMPRESSED));
|
||||
}
|
||||
|
||||
AddrShift Stub::IsUtf8String(AddrShift string)
|
||||
{
|
||||
// compressedStringsEnabled fixed to true constant
|
||||
AddrShift len = Load(MachineType::UINT32_TYPE, string,
|
||||
GetPtrConstant(panda::ecmascript::EcmaString::GetLengthOffset()));
|
||||
return Word32Equal(
|
||||
Word32And(len, GetInteger32Constant(panda::ecmascript::EcmaString::STRING_COMPRESSED_BIT)),
|
||||
GetInteger32Constant(panda::ecmascript::EcmaString::STRING_COMPRESSED));
|
||||
}
|
||||
|
||||
AddrShift Stub::IsInternalString(AddrShift string)
|
||||
{
|
||||
// compressedStringsEnabled fixed to true constant
|
||||
AddrShift len = Load(MachineType::UINT32_TYPE, string,
|
||||
GetPtrConstant(panda::ecmascript::EcmaString::GetLengthOffset()));
|
||||
return Word32NotEqual(
|
||||
Word32And(len, GetInteger32Constant(panda::ecmascript::EcmaString::STRING_INTERN_BIT)),
|
||||
GetInteger32Constant(0));
|
||||
}
|
||||
|
||||
AddrShift Stub::IsDigit(AddrShift ch)
|
||||
{
|
||||
return TruncInt32ToInt1(
|
||||
Word32And(SExtInt1ToInt32(Int32LessThanOrEqual(ch, GetInteger32Constant('9'))),
|
||||
SExtInt1ToInt32(Int32GreaterThanOrEqual(ch, GetInteger32Constant('0')))));
|
||||
}
|
||||
|
||||
AddrShift Stub::StringToElementIndex(AddrShift string)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label entry(env);
|
||||
[[maybe_unused]] SubCircuitScope subCircuit(env, &entry);
|
||||
Label exit(env);
|
||||
DEFVARIABLE(result, INT32_TYPE, GetInteger32Constant(-1));
|
||||
Label greatThanZero(env);
|
||||
Label inRange(env);
|
||||
AddrShift len = Load(MachineType::UINT32_TYPE, string,
|
||||
GetPtrConstant(panda::ecmascript::EcmaString::GetLengthOffset()));
|
||||
len = Word32LSR(len, GetInteger32Constant(2));
|
||||
Branch(Word32Equal(len, GetInteger32Constant(0)), &exit, &greatThanZero);
|
||||
Bind(&greatThanZero);
|
||||
Branch(Int32GreaterThan(len, GetInteger32Constant(panda::ecmascript::MAX_INDEX_LEN)), &exit, &inRange);
|
||||
Bind(&inRange);
|
||||
{
|
||||
AddrShift dataUtf16 = PtrAdd(string, GetPtrConstant(panda::ecmascript::EcmaString::GetDataOffset()));
|
||||
DEFVARIABLE(c, UINT32_TYPE, GetInteger32Constant(0));
|
||||
Label isUtf16(env);
|
||||
Label isUtf8(env);
|
||||
Label getChar1(env);
|
||||
AddrShift isUtf16String = IsUtf16String(string);
|
||||
Branch(isUtf16String, &isUtf16, &isUtf8);
|
||||
Bind(&isUtf16);
|
||||
{
|
||||
c = ZExtInt16ToInt32(Load(INT16_TYPE, dataUtf16));
|
||||
Jump(&getChar1);
|
||||
}
|
||||
Bind(&isUtf8);
|
||||
{
|
||||
c = ZExtInt8ToInt32(Load(INT8_TYPE, dataUtf16));
|
||||
Jump(&getChar1);
|
||||
}
|
||||
Bind(&getChar1);
|
||||
{
|
||||
Label isDigitZero(env);
|
||||
Label notDigitZero(env);
|
||||
Branch(Word32Equal(*c, GetInteger32Constant('0')), &isDigitZero, ¬DigitZero);
|
||||
Bind(&isDigitZero);
|
||||
{
|
||||
Label lengthIsOne(env);
|
||||
Branch(Word32Equal(len, GetInteger32Constant(1)), &lengthIsOne, &exit);
|
||||
Bind(&lengthIsOne);
|
||||
{
|
||||
result = GetInteger32Constant(0);
|
||||
Jump(&exit);
|
||||
}
|
||||
}
|
||||
Bind(¬DigitZero);
|
||||
{
|
||||
Label isDigit(env);
|
||||
DEFVARIABLE(i, UINT32_TYPE, GetInteger32Constant(1));
|
||||
DEFVARIABLE(n, UINT32_TYPE, Int32Sub(*c, GetInteger32Constant('0')));
|
||||
Branch(IsDigit(*c), &isDigit, &exit);
|
||||
Label loopHead(env);
|
||||
Label loopEnd(env);
|
||||
Label afterLoop(env);
|
||||
Bind(&isDigit);
|
||||
Branch(Int32LessThan(*i, len), &loopHead, &exit);
|
||||
LoopBegin(&loopHead);
|
||||
{
|
||||
Label isUtf16(env);
|
||||
Label notUtf16(env);
|
||||
Label getChar2(env);
|
||||
Branch(isUtf16String, &isUtf16, ¬Utf16);
|
||||
Bind(&isUtf16);
|
||||
{
|
||||
c = ZExtInt16ToInt32(Load(INT16_TYPE, dataUtf16, PtrMul(*i, GetPtrConstant(2))));
|
||||
Jump(&getChar2);
|
||||
}
|
||||
Bind(¬Utf16);
|
||||
{
|
||||
c = ZExtInt8ToInt32(Load(INT8_TYPE, dataUtf16, *i));
|
||||
Jump(&getChar2);
|
||||
}
|
||||
Bind(&getChar2);
|
||||
{
|
||||
Label isDigit2(env);
|
||||
Label notDigit2(env);
|
||||
Branch(IsDigit(*c), &isDigit2, ¬Digit2);
|
||||
Bind(&isDigit2);
|
||||
{
|
||||
n = Int32Add(Int32Mul(*n, GetInteger32Constant(10)),
|
||||
Int32Sub(*c, GetInteger32Constant('0')));
|
||||
i = Int32Add(*i, GetInteger32Constant(1));
|
||||
Branch(Int32LessThan(*i, len), &loopEnd, &afterLoop);
|
||||
}
|
||||
Bind(¬Digit2);
|
||||
Jump(&exit);
|
||||
}
|
||||
}
|
||||
Bind(&loopEnd);
|
||||
LoopEnd(&loopHead);
|
||||
Bind(&afterLoop);
|
||||
{
|
||||
Label lessThanMaxIndex(env);
|
||||
Branch(Word32LessThan(*n, GetInteger32Constant(panda::ecmascript::JSObject::MAX_ELEMENT_INDEX)),
|
||||
&lessThanMaxIndex, &exit);
|
||||
Bind(&lessThanMaxIndex);
|
||||
{
|
||||
result = *n;
|
||||
Jump(&exit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Bind(&exit);
|
||||
return *result;
|
||||
}
|
||||
|
||||
AddrShift Stub::TryToElementsIndex(AddrShift key)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label entry(env);
|
||||
[[maybe_unused]] SubCircuitScope subCircuit(env, &entry);
|
||||
Label exit(env);
|
||||
Label isKeyInt(env);
|
||||
Label notKeyInt(env);
|
||||
|
||||
DEFVARIABLE(resultKey, INT32_TYPE, GetInteger32Constant(0));
|
||||
Branch(TaggedIsInt(key), &isKeyInt, ¬KeyInt);
|
||||
Bind(&isKeyInt);
|
||||
{
|
||||
resultKey = TaggedCastToInt32(key);
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(¬KeyInt);
|
||||
{
|
||||
Label isString(env);
|
||||
Label notString(env);
|
||||
Branch(TaggedIsString(key), &isString, ¬String);
|
||||
Bind(&isString);
|
||||
{
|
||||
resultKey = StringToElementIndex(key);
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(¬String);
|
||||
{
|
||||
Label isDouble(env);
|
||||
Branch(TaggedIsDouble(key), &isDouble, &exit);
|
||||
Bind(&isDouble);
|
||||
{
|
||||
AddrShift number = TaggedCastToDouble(key);
|
||||
AddrShift integer = ChangeInt64ToInt32(CastDoubleToInt64(number));
|
||||
Label isEqual(env);
|
||||
Branch(DoubleEqual(number, CastInt64ToFloat64(SExtInt32ToInt64(integer))), &isEqual, &exit);
|
||||
Bind(&isEqual);
|
||||
{
|
||||
resultKey = integer;
|
||||
Jump(&exit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Bind(&exit);
|
||||
return *resultKey;
|
||||
}
|
||||
} // namespace kungfu
|
@ -699,7 +699,16 @@ public:
|
||||
{
|
||||
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::FLOAT64_DIV), x, y);
|
||||
}
|
||||
AddrShift Int32Div(AddrShift x, AddrShift y);
|
||||
AddrShift Int32Div(AddrShift x, AddrShift y)
|
||||
{
|
||||
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_SDIV), x, y);
|
||||
}
|
||||
|
||||
AddrShift Word32Div(AddrShift x, AddrShift y)
|
||||
{
|
||||
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_UDIV), x, y);
|
||||
}
|
||||
|
||||
AddrShift Int64Div(AddrShift x, AddrShift y);
|
||||
|
||||
AddrShift Int32Mod(AddrShift x, AddrShift y)
|
||||
@ -761,11 +770,6 @@ public:
|
||||
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_AND), x, y);
|
||||
}
|
||||
|
||||
AddrShift WordLogicNot(AddrShift x)
|
||||
{
|
||||
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_REV), x);
|
||||
}
|
||||
|
||||
AddrShift Word32LSL(AddrShift x, AddrShift y)
|
||||
{
|
||||
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_LSL), x, y);
|
||||
@ -828,15 +832,27 @@ public:
|
||||
SExtInt1ToInt32(
|
||||
Word64Equal(Word64And(x, GetWord64Constant(~panda::ecmascript::JSTaggedValue::TAG_SPECIAL_MASK)),
|
||||
GetWord64Constant(0))),
|
||||
Word32Or(SExtInt1ToInt32(Word64NotEqual(
|
||||
Word64And(x, GetWord64Constant(panda::ecmascript::JSTaggedValue::TAG_SPECIAL_MASK)),
|
||||
WordLogicOr(SExtInt1ToInt32(Word64NotEqual(
|
||||
Word64And(x, GetWord64Constant(panda::ecmascript::JSTaggedValue::TAG_SPECIAL_VALUE)),
|
||||
GetWord64Constant(0))), SExtInt1ToInt32(TaggedIsHole(x)))));
|
||||
}
|
||||
|
||||
AddrShift TaggedIsHeapObject(AddrShift x)
|
||||
{
|
||||
return TruncInt32ToInt1(
|
||||
Word32And(SExtInt1ToInt32(TaggedIsObject(x)), Word32Not(SExtInt1ToInt32(TaggedIsSpecial(x)))));
|
||||
WordLogicAnd(SExtInt1ToInt32(TaggedIsObject(x)),
|
||||
SExtInt1ToInt32(Word32Equal(SExtInt1ToInt32(TaggedIsSpecial(x)), GetInteger32Constant(0)))));
|
||||
}
|
||||
|
||||
AddrShift TaggedIsString(AddrShift obj);
|
||||
|
||||
AddrShift TaggedIsStringOrSymbol(AddrShift obj);
|
||||
|
||||
AddrShift GetNextPositionForHash(AddrShift last, AddrShift count, AddrShift size)
|
||||
{
|
||||
auto nextOffset = Word32LSR(Int32Mul(count, Int32Add(count, GetInteger32Constant(1))),
|
||||
GetInteger32Constant(2));
|
||||
return Word32And(Int32Add(last, nextOffset), Int32Sub(size, GetInteger32Constant(1)));
|
||||
}
|
||||
|
||||
AddrShift DoubleIsNAN(AddrShift x)
|
||||
@ -1062,6 +1078,17 @@ public:
|
||||
GetInteger32Constant(0));
|
||||
}
|
||||
|
||||
AddrShift IsDictionaryModeByHClass(AddrShift hClass)
|
||||
{
|
||||
AddrShift bitfieldOffset = GetPtrConstant(panda::ecmascript::JSHClass::BIT_FIELD_OFFSET);
|
||||
AddrShift bitfield = Load(INT64_TYPE, hClass, bitfieldOffset);
|
||||
return Word64NotEqual(
|
||||
Word64And(
|
||||
Word64LSR(bitfield, GetWord64Constant(panda::ecmascript::JSHClass::IsDictionaryBit::START_BIT)),
|
||||
GetWord64Constant((1LLU << panda::ecmascript::JSHClass::IsDictionaryBit::SIZE) - 1)),
|
||||
GetWord64Constant(0));
|
||||
}
|
||||
|
||||
AddrShift IsDictionaryElement(AddrShift hclass)
|
||||
{
|
||||
AddrShift bitfieldOffset = GetPtrConstant(panda::ecmascript::JSHClass::BIT_FIELD_OFFSET);
|
||||
@ -1309,6 +1336,18 @@ public:
|
||||
|
||||
AddrShift JSObjectGetProperty(AddrShift obj, AddrShift hClass, AddrShift propAttr);
|
||||
|
||||
AddrShift IsUtf16String(AddrShift string);
|
||||
|
||||
AddrShift IsUtf8String(AddrShift string);
|
||||
|
||||
AddrShift IsInternalString(AddrShift string);
|
||||
|
||||
AddrShift IsDigit(AddrShift ch);
|
||||
|
||||
AddrShift StringToElementIndex(AddrShift string);
|
||||
|
||||
AddrShift TryToElementsIndex(AddrShift key);
|
||||
|
||||
AddrShift TaggedCastToInt64(AddrShift x)
|
||||
{
|
||||
return Word64And(x, GetWord64Constant(~panda::ecmascript::JSTaggedValue::TAG_MASK));
|
||||
@ -1365,6 +1404,16 @@ public:
|
||||
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::ZEXT_INT1_TO_INT32), x);
|
||||
}
|
||||
|
||||
AddrShift ZExtInt8ToInt32(AddrShift x)
|
||||
{
|
||||
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::ZEXT_INT8_TO_INT32), x);
|
||||
}
|
||||
|
||||
AddrShift ZExtInt16ToInt32(AddrShift x)
|
||||
{
|
||||
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::ZEXT_INT16_TO_INT32), x);
|
||||
}
|
||||
|
||||
AddrShift TruncInt64ToInt32(AddrShift x)
|
||||
{
|
||||
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::TRUNC_INT64_TO_INT32), x);
|
||||
|
@ -161,7 +161,8 @@ void StubAotCompiler::BuildStubModuleAndSave(const char *triple, panda::ecmascri
|
||||
SET_STUB_TO_MODULE(module, GetPropertyByIndex) \
|
||||
SET_STUB_TO_MODULE(module, SetPropertyByIndex) \
|
||||
SET_STUB_TO_MODULE(module, FunctionCallInternal) \
|
||||
SET_STUB_TO_MODULE(module, GetPropertyByName)
|
||||
SET_STUB_TO_MODULE(module, GetPropertyByName) \
|
||||
SET_STUB_TO_MODULE(module, GetPropertyByValue)
|
||||
|
||||
int main(const int argc, const char **argv)
|
||||
{
|
||||
|
@ -39,6 +39,7 @@ public:
|
||||
}
|
||||
void BuildStubModuleAndSave(const char *triple, panda::ecmascript::StubModule *module,
|
||||
const std::string &filename);
|
||||
void SetAllStubToModule();
|
||||
void SetStub(int index, Stub *optimizer)
|
||||
{
|
||||
stubs_[index] = optimizer;
|
||||
|
@ -28,4 +28,4 @@ options:
|
||||
- x86_64-unknown-linux-gnu
|
||||
- arm-unknown-linux-gnu
|
||||
- aarch64-unknown-linux-gnu
|
||||
description: stub aot compiler target triple
|
||||
description: stub aot compiler target triple
|
||||
|
@ -245,6 +245,36 @@ CALL_STUB_INIT_DESCRIPTOR(SetPropertyByIndex)
|
||||
descriptor->SetParameters(params.data());
|
||||
}
|
||||
|
||||
CALL_STUB_INIT_DESCRIPTOR(GetPropertyByValue)
|
||||
{
|
||||
// 3 : 3 input parameters
|
||||
static StubDescriptor getPropertyByValue("GetPropertyByValue", 0, 3, ArgumentsOrder::DEFAULT_ORDER, UINT64_TYPE);
|
||||
*descriptor = getPropertyByValue;
|
||||
// 3 : 3 input parameters
|
||||
std::array<MachineType, 3> params = {
|
||||
MachineType::UINT64_TYPE,
|
||||
MachineType::UINT64_TYPE,
|
||||
MachineType::UINT64_TYPE,
|
||||
};
|
||||
descriptor->SetParameters(params.data());
|
||||
}
|
||||
|
||||
CALL_STUB_INIT_DESCRIPTOR(SetPropertyByValue)
|
||||
{
|
||||
// // 4 : 4 input parameters
|
||||
// static StubDescriptor setPropertyByValue("SetPropertyByValue", 0, 4, ArgumentsOrder::DEFAULT_ORDER, UINT64_TYPE);
|
||||
// *descriptor = setPropertyByValue;
|
||||
// // 4 : 4 input parameters
|
||||
// std::array<MachineType, 4> params = {
|
||||
// MachineType::UINT64_TYPE,
|
||||
// MachineType::UINT64_TYPE,
|
||||
// MachineType::UINT64_TYPE,
|
||||
// MachineType::UINT64_TYPE,
|
||||
// };
|
||||
// descriptor->SetParameters(params.data());
|
||||
}
|
||||
|
||||
|
||||
CALL_STUB_INIT_DESCRIPTOR(AddElementInternal)
|
||||
{
|
||||
// 5 : 5 input parameters
|
||||
@ -404,6 +434,20 @@ CALL_STUB_INIT_DESCRIPTOR(StringGetHashCode)
|
||||
descriptor->SetStubKind(StubDescriptor::CallStubKind::RUNTIME_STUB);
|
||||
}
|
||||
|
||||
CALL_STUB_INIT_DESCRIPTOR(NewInternalString)
|
||||
{
|
||||
// 2 : 2 input parameters
|
||||
static StubDescriptor stringGetHashCode("NewInternalString", 0, 2, ArgumentsOrder::DEFAULT_ORDER, UINT64_TYPE);
|
||||
*descriptor = stringGetHashCode;
|
||||
// 2 : 2 input parameters
|
||||
std::array<MachineType, 2> params = {
|
||||
MachineType::UINT64_TYPE,
|
||||
MachineType::UINT64_TYPE,
|
||||
};
|
||||
descriptor->SetParameters(params.data());
|
||||
descriptor->SetStubKind(StubDescriptor::CallStubKind::RUNTIME_STUB);
|
||||
}
|
||||
|
||||
CALL_STUB_INIT_DESCRIPTOR(FastLoadElement)
|
||||
{
|
||||
// 2 : 2 input parameters
|
||||
|
@ -1185,6 +1185,91 @@ HWTEST_F_L0(StubTest, GetPropertyByNameStub)
|
||||
EXPECT_EQ(resVal.GetNumber(), y);
|
||||
}
|
||||
|
||||
HWTEST_F_L0(StubTest, FastGetPropertyByValueStub)
|
||||
{
|
||||
auto module = stubModule.GetModule();
|
||||
LLVMValueRef getPropertyByIndexfunction = LLVMGetNamedFunction(module, "GetPropertyByIndex");
|
||||
Circuit netOfGates2;
|
||||
GetPropertyByIndexStub getPropertyByIndexStub(&netOfGates2);
|
||||
getPropertyByIndexStub.GenerateCircuit();
|
||||
netOfGates2.PrintAllGates();
|
||||
auto cfg2 = Scheduler::Run(&netOfGates2);
|
||||
LLVMIRBuilder llvmBuilder2(&cfg2, &netOfGates2, &stubModule, getPropertyByIndexfunction);
|
||||
llvmBuilder2.Build();
|
||||
|
||||
LLVMValueRef getPropertyByNamefunction = LLVMGetNamedFunction(module, "GetPropertyByName");
|
||||
Circuit netOfGates1;
|
||||
GetPropertyByNameStub getPropertyByNameStub(&netOfGates1);
|
||||
getPropertyByNameStub.GenerateCircuit();
|
||||
bool result = Verifier::Run(&netOfGates1);
|
||||
ASSERT_TRUE(result);
|
||||
auto cfg1 = Scheduler::Run(&netOfGates1);
|
||||
LLVMIRBuilder llvmBuilder1(&cfg1, &netOfGates1, &stubModule, getPropertyByNamefunction);
|
||||
llvmBuilder1.Build();
|
||||
|
||||
LLVMValueRef function = LLVMGetNamedFunction(module, "GetPropertyByValue");
|
||||
Circuit netOfGates;
|
||||
GetPropertyByValueStub optimizer(&netOfGates);
|
||||
optimizer.GenerateCircuit();
|
||||
netOfGates.PrintAllGates();
|
||||
result = Verifier::Run(&netOfGates);
|
||||
ASSERT_TRUE(result);
|
||||
auto cfg = Scheduler::Run(&netOfGates);
|
||||
for (size_t bbIdx = 0; bbIdx < cfg.size(); bbIdx++) {
|
||||
std::cout << (netOfGates.GetOpCode(cfg[bbIdx].front()).IsCFGMerge() ? "MERGE_" : "BB_") << bbIdx << ":"
|
||||
<< std::endl;
|
||||
for (size_t instIdx = cfg[bbIdx].size(); instIdx > 0; instIdx--) {
|
||||
netOfGates.Print(cfg[bbIdx][instIdx - 1]);
|
||||
}
|
||||
}
|
||||
LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, &stubModule, function);
|
||||
llvmBuilder.Build();
|
||||
LLVMAssembler assembler(module, "x86_64-unknown-linux-gnu");
|
||||
assembler.Run();
|
||||
auto engine = assembler.GetEngine();
|
||||
auto *getPropertyByValuePtr = reinterpret_cast<JSTaggedValue (*)(JSThread *, uint64_t, uint64_t)>(
|
||||
reinterpret_cast<uintptr_t>(LLVMGetPointerToGlobal(engine, function)));
|
||||
auto *getPropertyByNamePtr = reinterpret_cast<JSTaggedValue (*)(JSThread *, uint64_t, uint64_t)>(
|
||||
reinterpret_cast<uintptr_t>(LLVMGetPointerToGlobal(engine, getPropertyByNamefunction)));
|
||||
auto *getpropertyByIndexPtr = reinterpret_cast<JSTaggedValue (*)(JSThread *, JSTaggedValue, uint32_t)>(
|
||||
reinterpret_cast<uintptr_t>(LLVMGetPointerToGlobal(engine, getPropertyByIndexfunction)));
|
||||
auto *factory = JSThread::Cast(thread)->GetEcmaVM()->GetFactory();
|
||||
JSHandle<JSObject> obj = factory->NewEmptyJSObject();
|
||||
int x = 213;
|
||||
int y = 10;
|
||||
|
||||
FastRuntimeStub::SetOwnElement(thread, obj.GetTaggedValue(), 1, JSTaggedValue(x));
|
||||
FastRuntimeStub::SetOwnElement(thread, obj.GetTaggedValue(), 10250, JSTaggedValue(y));
|
||||
|
||||
JSHandle<JSTaggedValue> strA(factory->NewFromCanBeCompressString("a"));
|
||||
JSHandle<JSTaggedValue> strBig(factory->NewFromCanBeCompressString("biggest"));
|
||||
JSHandle<JSTaggedValue> strDigit(factory->NewFromCanBeCompressString("10250"));
|
||||
|
||||
FastRuntimeStub::SetPropertyByName(thread, obj.GetTaggedValue(), strA.GetTaggedValue(), JSTaggedValue(x));
|
||||
FastRuntimeStub::SetPropertyByName(thread, obj.GetTaggedValue(), strBig.GetTaggedValue(), JSTaggedValue(y));
|
||||
assembler.Disassemble();
|
||||
|
||||
JSTaggedValue resVal1 = getPropertyByNamePtr(thread, obj.GetTaggedValue().GetRawData(),
|
||||
strA.GetTaggedValue().GetRawData());
|
||||
EXPECT_EQ(resVal1.GetNumber(), x);
|
||||
JSTaggedValue resVal = getPropertyByValuePtr(thread, obj.GetTaggedValue().GetRawData(),
|
||||
strA.GetTaggedValue().GetRawData());
|
||||
EXPECT_EQ(resVal.GetNumber(), x);
|
||||
resVal = getPropertyByValuePtr(thread, obj.GetTaggedValue().GetRawData(), strBig.GetTaggedValue().GetRawData());
|
||||
EXPECT_EQ(resVal.GetNumber(), y);
|
||||
resVal = getpropertyByIndexPtr(thread, obj.GetTaggedValue(), 1);
|
||||
EXPECT_EQ(resVal.GetNumber(), x);
|
||||
resVal = getPropertyByValuePtr(thread, obj.GetTaggedValue().GetRawData(), JSTaggedValue(10250).GetRawData());
|
||||
EXPECT_EQ(resVal.GetNumber(), y);
|
||||
resVal = getPropertyByValuePtr(thread, obj.GetTaggedValue().GetRawData(), strDigit.GetTaggedValue().GetRawData());
|
||||
EXPECT_EQ(resVal.GetNumber(), y);
|
||||
|
||||
JSHandle<JSTaggedValue> strHello(factory->NewFromCanBeCompressString("hello world"));
|
||||
double key = 4.29497e+09;
|
||||
resVal = getPropertyByValuePtr(thread, strHello.GetTaggedValue().GetRawData(), JSTaggedValue(key).GetRawData());
|
||||
EXPECT_EQ(resVal.GetRawData(), 0);
|
||||
}
|
||||
|
||||
HWTEST_F_L0(StubTest, FastTypeOfTest)
|
||||
{
|
||||
auto module = stubModule.GetModule();
|
||||
|
@ -45,6 +45,13 @@ public:
|
||||
static EcmaString *FastSubString(const JSHandle<EcmaString> &src, uint32_t start, uint32_t utf16Len,
|
||||
const EcmaVM *vm);
|
||||
|
||||
static constexpr uint32_t STRING_COMPRESSED_BIT = 0x1;
|
||||
static constexpr uint32_t STRING_INTERN_BIT = 0x2;
|
||||
enum CompressedStatus {
|
||||
STRING_COMPRESSED,
|
||||
STRING_UNCOMPRESSED,
|
||||
};
|
||||
|
||||
template<bool verify = true>
|
||||
uint16_t At(int32_t index) const;
|
||||
|
||||
@ -285,12 +292,6 @@ private:
|
||||
static void CopyUtf16AsUtf8(const uint16_t *utf16From, uint8_t *utf8To, uint32_t utf16Len);
|
||||
|
||||
static bool compressedStringsEnabled;
|
||||
static constexpr uint32_t STRING_COMPRESSED_BIT = 0x1;
|
||||
static constexpr uint32_t STRING_INTERN_BIT = 0x2;
|
||||
enum CompressedStatus {
|
||||
STRING_COMPRESSED,
|
||||
STRING_UNCOMPRESSED,
|
||||
};
|
||||
|
||||
static bool IsASCIICharacter(uint16_t data)
|
||||
{
|
||||
|
@ -168,6 +168,9 @@ bool EcmaVM::Initialize()
|
||||
globalEnv->SetTemplateMap(thread_, JSTaggedValue(TemplateMap::Create(thread_)));
|
||||
globalEnv->SetRegisterSymbols(GetJSThread(), JSTaggedValue(SymbolTable::Create(GetJSThread())));
|
||||
|
||||
std::string moduleFile = options_.GetStubModuleFile();
|
||||
thread_->LoadFastStubModule(moduleFile.c_str());
|
||||
|
||||
SetupRegExpResultCache();
|
||||
microJobQueue_ = factory_->NewMicroJobQueue().GetTaggedValue();
|
||||
|
||||
|
@ -622,7 +622,10 @@ bool FastRuntimeStub::FastSetPropertyByIndex(JSThread *thread, JSTaggedValue rec
|
||||
JSTaggedValue value)
|
||||
{
|
||||
INTERPRETER_TRACE(thread, FastSetPropertyByIndex);
|
||||
JSTaggedValue result = FastRuntimeStub::SetPropertyByIndex(thread, receiver, index, value);
|
||||
auto *setPropertyByIndex = \
|
||||
reinterpret_cast<JSTaggedValue (*)(JSThread *, JSTaggedValue, uint32_t, JSTaggedValue)> \
|
||||
(reinterpret_cast<uintptr_t>(thread->GetFastStubEntry(FAST_STUB_ID(SetPropertyByIndex))));
|
||||
JSTaggedValue result = setPropertyByIndex(thread, receiver, index, value);
|
||||
if (!result.IsHole()) {
|
||||
return result != JSTaggedValue::Exception();
|
||||
}
|
||||
@ -654,7 +657,9 @@ JSTaggedValue FastRuntimeStub::FastGetPropertyByName(JSThread *thread, JSTaggedV
|
||||
// Maybe moved by GC
|
||||
receiver = receiverHandler.GetTaggedValue();
|
||||
}
|
||||
JSTaggedValue result = FastRuntimeStub::GetPropertyByName(thread, receiver, key);
|
||||
auto *getPropertyByNamePtr = reinterpret_cast<JSTaggedValue (*)(JSThread *, JSTaggedValue, JSTaggedValue)>(
|
||||
thread->GetFastStubEntry(FAST_STUB_ID(GetPropertyByName)));
|
||||
JSTaggedValue result = getPropertyByNamePtr(thread, receiver, key);
|
||||
if (result.IsHole()) {
|
||||
return JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>(thread, receiver),
|
||||
JSHandle<JSTaggedValue>(thread, key))
|
||||
@ -681,7 +686,10 @@ template<bool UseHole> // UseHole is only for Array::Sort() which requires Hole
|
||||
JSTaggedValue FastRuntimeStub::FastGetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index)
|
||||
{
|
||||
INTERPRETER_TRACE(thread, FastGetPropertyByIndex);
|
||||
JSTaggedValue result = GetPropertyByIndex(thread, receiver, index);
|
||||
auto getPropertyByIndex = reinterpret_cast<JSTaggedValue (*)(JSThread *, JSTaggedValue, uint32_t)>(
|
||||
thread->GetFastStubEntry(FAST_STUB_ID(GetPropertyByIndex)));
|
||||
|
||||
JSTaggedValue result = getPropertyByIndex(thread, receiver, index);
|
||||
if (result.IsHole() && !UseHole) {
|
||||
return JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>(thread, receiver), index)
|
||||
.GetValue()
|
||||
|
@ -16,6 +16,7 @@
|
||||
#ifndef ECMASCRIPT_INTERPRETER_FAST_RUNTIME_STUB_H
|
||||
#define ECMASCRIPT_INTERPRETER_FAST_RUNTIME_STUB_H
|
||||
|
||||
#include <memory>
|
||||
#include "ecmascript/js_tagged_value.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
@ -24,6 +25,7 @@ class PropertyAttributes;
|
||||
|
||||
class FastRuntimeStub {
|
||||
public:
|
||||
using Address = uintptr_t;
|
||||
/* -------------- Common API Begin, Don't change those interface!!! ----------------- */
|
||||
static inline JSTaggedValue FastAdd(JSTaggedValue left, JSTaggedValue right);
|
||||
static inline JSTaggedValue FastSub(JSTaggedValue left, JSTaggedValue right);
|
||||
|
@ -2439,7 +2439,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool
|
||||
JSTaggedValue receiver = GET_VREG_VALUE(v0);
|
||||
// fast path
|
||||
if (LIKELY(receiver.IsHeapObject())) {
|
||||
JSTaggedValue res = FastRuntimeStub::GetPropertyByIndex(thread, receiver, idx);
|
||||
auto getPropertyByIndex = reinterpret_cast<JSTaggedValue (*)(JSThread *, JSTaggedValue, uint32_t)>(
|
||||
thread->GetFastStubEntry(FAST_STUB_ID(GetPropertyByIndex)));
|
||||
JSTaggedValue res = getPropertyByIndex(thread, receiver, idx);
|
||||
if (!res.IsHole()) {
|
||||
INTERPRETER_RETURN_IF_ABRUPT(res);
|
||||
SET_ACC(res);
|
||||
@ -2464,7 +2466,10 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool
|
||||
SAVE_ACC();
|
||||
JSTaggedValue value = GET_ACC();
|
||||
// fast path
|
||||
JSTaggedValue res = FastRuntimeStub::SetPropertyByIndex(thread, receiver, index, value);
|
||||
auto *setPropertyByIndex = \
|
||||
reinterpret_cast<JSTaggedValue (*)(JSThread *, JSTaggedValue, uint32_t, JSTaggedValue)> \
|
||||
(reinterpret_cast<uintptr_t>(thread->GetFastStubEntry(FAST_STUB_ID(SetPropertyByIndex))));
|
||||
JSTaggedValue res = setPropertyByIndex(thread, receiver, index, value);
|
||||
if (!res.IsHole()) {
|
||||
INTERPRETER_RETURN_IF_ABRUPT(res);
|
||||
RESTORE_ACC();
|
||||
@ -2887,7 +2892,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool
|
||||
|
||||
if (LIKELY(receiver.IsHeapObject())) {
|
||||
// fast path
|
||||
JSTaggedValue res = FastRuntimeStub::GetPropertyByName(thread, receiver, propKey);
|
||||
auto *getPropertyByNamePtr = reinterpret_cast<JSTaggedValue (*)(JSThread *, JSTaggedValue, JSTaggedValue)>(
|
||||
thread->GetFastStubEntry(FAST_STUB_ID(GetPropertyByName)));
|
||||
JSTaggedValue res = getPropertyByNamePtr(thread, receiver, propKey);
|
||||
if (!res.IsHole()) {
|
||||
ASSERT(!res.IsAccessor());
|
||||
INTERPRETER_RETURN_IF_ABRUPT(res);
|
||||
|
@ -170,6 +170,14 @@ public:
|
||||
return fastStubEntires_[id];
|
||||
}
|
||||
|
||||
void SetFastStubEntry(uint32_t id, Address entry)
|
||||
{
|
||||
ASSERT(id < kungfu::FAST_STUB_MAXCOUNT);
|
||||
fastStubEntires_[id] = entry;
|
||||
}
|
||||
|
||||
void InitializeFastRuntimeStubs();
|
||||
|
||||
void LoadFastStubModule(const char *moduleFile);
|
||||
|
||||
static uint32_t GetRuntimeFunctionsOffset()
|
||||
|
@ -149,4 +149,11 @@ double RuntimeTrampolines::FloatMod(double left, double right)
|
||||
{
|
||||
return std::fmod(left, right);
|
||||
}
|
||||
|
||||
uint64_t RuntimeTrampolines::NewInternalString(uint64_t argThread, uint64_t argKey)
|
||||
{
|
||||
auto thread = reinterpret_cast<JSThread *>(argThread);
|
||||
JSHandle<JSTaggedValue> keyHandle(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(argKey)));
|
||||
return JSTaggedValue(thread->GetEcmaVM()->GetFactory()->InternString(keyHandle)).GetRawData();
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -50,6 +50,7 @@ public:
|
||||
static uint32_t StringGetHashCode(uint64_t ecmaString);
|
||||
static uint64_t Execute(uint64_t argThread, uint64_t argFunc, uint64_t thisArg, uint32_t argc, uint64_t argArgv);
|
||||
static double FloatMod(double left, double right);
|
||||
static uint64_t NewInternalString(uint64_t argThread, uint64_t argKey);
|
||||
};
|
||||
|
||||
class CallRuntimeTrampolinesScope {
|
||||
|
Loading…
Reference in New Issue
Block a user