mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-27 04:00:37 +00:00
commit
24bb369d9f
@ -131,7 +131,8 @@ int Main(const int argc, const char **argv)
|
||||
cOptions.isEnableCollectLiteralInfo_,
|
||||
cOptions.isEnableOptConstantFolding_,
|
||||
cOptions.isEnableLexenvSpecialization_,
|
||||
cOptions.isEnableNativeInline_);
|
||||
cOptions.isEnableNativeInline_,
|
||||
cOptions.isEnableFastModule_);
|
||||
|
||||
PassManager passManager(vm,
|
||||
cOptions.triple_,
|
||||
|
@ -59,6 +59,7 @@ CompilationOptions::CompilationOptions(EcmaVM *vm, JSRuntimeOptions &runtimeOpti
|
||||
isEnableCollectLiteralInfo_ = false;
|
||||
isEnableLexenvSpecialization_ = runtimeOptions.IsEnableLexenvSpecialization();
|
||||
isEnableNativeInline_ = runtimeOptions.IsEnableNativeInline();
|
||||
isEnableFastModule_ = runtimeOptions.IsEnableFastModule();
|
||||
}
|
||||
|
||||
bool AotCompilerPreprocessor::HandleTargetCompilerMode(CompilationOptions &cOptions)
|
||||
|
@ -64,6 +64,7 @@ struct CompilationOptions {
|
||||
bool isEnableLexenvSpecialization_;
|
||||
bool isEnableNativeInline_;
|
||||
bool isEnablePGOHCRLowering_;
|
||||
bool isEnableFastModule_;
|
||||
};
|
||||
|
||||
class AotCompilerPreprocessor {
|
||||
|
@ -327,6 +327,9 @@ public:
|
||||
GateRef TypedCallNative(GateRef hirGate, GateRef thisObj, GateRef funcId);
|
||||
GateRef IsBase(GateRef ctor);
|
||||
GateRef ToLength(GateRef receiver);
|
||||
GateRef StoreModuleVar(GateRef jsFunc, GateRef index, GateRef value);
|
||||
GateRef LdLocalModuleVar(GateRef jsFunc, GateRef index);
|
||||
GateRef BuiltinConstructor(BuiltinTypeId id, GateRef gate);
|
||||
|
||||
inline GateRef GetMethodId(GateRef func);
|
||||
inline GateRef IsAOTLiteralInfo(GateRef x);
|
||||
@ -397,6 +400,7 @@ public:
|
||||
inline void StoreHClass(GateRef glue, GateRef object, GateRef hClass);
|
||||
GateRef IsStabelArray(GateRef glue, GateRef obj);
|
||||
inline void StorePrototype(GateRef glue, GateRef hclass, GateRef prototype);
|
||||
void SetExtensibleToBitfield(GateRef glue, GateRef obj, bool isExtensible);
|
||||
|
||||
// WeakRef
|
||||
inline GateRef CreateWeakRef(GateRef x);
|
||||
@ -456,6 +460,7 @@ public:
|
||||
GateRef InsertStableArrayCheck(GateRef array);
|
||||
GateRef InsertLoadArrayLength(GateRef array, bool isTypedArray);
|
||||
GateRef InsertTypedArrayCheck(GateType type, GateRef array);
|
||||
GateRef ArrayConstructorCheck(GateRef gate);
|
||||
GateRef InsertTypedBinaryop(GateRef left, GateRef right, GateType leftType, GateType rightType,
|
||||
GateType gateType, PGOTypeRef pgoType, TypedBinOp op);
|
||||
GateRef InsertRangeCheckPredicate(GateRef left, TypedBinOp cond, GateRef right);
|
||||
|
@ -87,6 +87,7 @@ GateRef EarlyElimination::VisitGate(GateRef gate)
|
||||
case OpCode::ECMA_STRING_CHECK:
|
||||
case OpCode::BUILTIN_PROTOTYPE_HCLASS_CHECK:
|
||||
case OpCode::TYPE_OF_CHECK:
|
||||
case OpCode::ARRAY_CONSTRUCTOR_CHECK:
|
||||
return TryEliminateGate(gate);
|
||||
case OpCode::STATE_SPLIT:
|
||||
return TryEliminateFrameState(gate);
|
||||
@ -364,6 +365,10 @@ bool EarlyElimination::CheckReplacement(GateRef lhs, GateRef rhs)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OpCode::ARRAY_CONSTRUCTOR_CHECK:
|
||||
if (acc_.GetValueIn(lhs) != acc_.GetValueIn(rhs)) {
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -457,4 +457,70 @@ GateRef CircuitBuilder::IsStabelArray(GateRef glue, GateRef obj)
|
||||
env_->SubCfgExit();
|
||||
return res;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::StoreModuleVar(GateRef jsFunc, GateRef index, GateRef value)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
auto currentControl = currentLabel->GetControl();
|
||||
auto currentDepend = currentLabel->GetDepend();
|
||||
GateRef newGate = GetCircuit()->NewGate(circuit_->StoreModuleVar(), MachineType::I64,
|
||||
{ currentControl, currentDepend, jsFunc, index, value }, GateType::TaggedValue());
|
||||
currentLabel->SetControl(newGate);
|
||||
currentLabel->SetDepend(newGate);
|
||||
return newGate;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::LdLocalModuleVar(GateRef jsFunc, GateRef index)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
auto currentControl = currentLabel->GetControl();
|
||||
auto currentDepend = currentLabel->GetDepend();
|
||||
GateRef newGate = GetCircuit()->NewGate(circuit_->LdLocalModuleVar(), MachineType::I64,
|
||||
{ currentControl, currentDepend, jsFunc, index}, GateType::TaggedValue());
|
||||
currentLabel->SetControl(newGate);
|
||||
currentLabel->SetDepend(newGate);
|
||||
return newGate;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::BuiltinConstructor(BuiltinTypeId id, GateRef gate)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
auto currentControl = currentLabel->GetControl();
|
||||
auto currentDepend = currentLabel->GetDepend();
|
||||
GateRef newGate = Circuit::NullGate();
|
||||
switch (id) {
|
||||
case BuiltinTypeId::ARRAY: {
|
||||
if (acc_.GetNumValueIn(gate) == 1) {
|
||||
newGate = GetCircuit()->NewGate(circuit_->ArrayConstructor(1), MachineType::I64,
|
||||
{ currentControl, currentDepend, acc_.GetValueIn(gate, 0)},
|
||||
GateType::TaggedValue());
|
||||
} else {
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 2); // 2: num value in
|
||||
newGate = GetCircuit()->NewGate(circuit_->ArrayConstructor(2), MachineType::I64,
|
||||
{ currentControl, currentDepend, acc_.GetValueIn(gate, 0), acc_.GetValueIn(gate, 1)},
|
||||
GateType::TaggedValue());
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG_ECMA(FATAL) << "this branch is unreachable";
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
currentLabel->SetControl(newGate);
|
||||
currentLabel->SetDepend(newGate);
|
||||
return newGate;
|
||||
}
|
||||
|
||||
void CircuitBuilder::SetExtensibleToBitfield(GateRef glue, GateRef obj, bool isExtensible)
|
||||
{
|
||||
GateRef jsHclass = LoadHClass(obj);
|
||||
GateRef bitfield = Load(VariableType::INT32(), jsHclass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
|
||||
GateRef boolVal = Boolean(isExtensible);
|
||||
GateRef boolToInt32 = ZExtInt1ToInt32(boolVal);
|
||||
GateRef encodeValue = Int32LSL(boolToInt32, Int32(JSHClass::ExtensibleBit::START_BIT));
|
||||
GateRef mask = Int32(((1LU << JSHClass::ExtensibleBit::SIZE) - 1) << JSHClass::ExtensibleBit::START_BIT);
|
||||
bitfield = Int32Or(Int32And(bitfield, Int32Not(mask)), encodeValue);
|
||||
Store(VariableType::INT32(), glue, jsHclass, IntPtr(JSHClass::BIT_FIELD_OFFSET), bitfield);
|
||||
}
|
||||
}
|
@ -19,7 +19,10 @@
|
||||
namespace panda::ecmascript::kungfu {
|
||||
|
||||
#define HCR_IMMUTABLE_META_DATA_CACHE_LIST(V) \
|
||||
V(ToLength, TO_LENGTH, GateFlags::NONE_FLAG, 1, 1, 1)
|
||||
V(ToLength, TO_LENGTH, GateFlags::NONE_FLAG, 1, 1, 1) \
|
||||
V(StoreModuleVar, STORE_MODULE_VAR, GateFlags::NONE_FLAG, 1, 1, 3) \
|
||||
V(LdLocalModuleVar, LD_LOCAL_MODULE_VAR, GateFlags::NONE_FLAG, 1, 1, 2)
|
||||
|
||||
|
||||
#define HCR_GATE_META_DATA_LIST_WITH_VALUE_IN(V) \
|
||||
V(Call, CALL, GateFlags::NONE_FLAG, 0, 1, value) \
|
||||
@ -30,7 +33,8 @@ namespace panda::ecmascript::kungfu {
|
||||
V(BuiltinsCall, BUILTINS_CALL, GateFlags::NONE_FLAG, 0, 1, value) \
|
||||
V(RuntimeCall, RUNTIME_CALL, GateFlags::NONE_FLAG, 0, 1, value) \
|
||||
V(RuntimeCallWithArgv, RUNTIME_CALL_WITH_ARGV, GateFlags::NONE_FLAG, 0, 1, value) \
|
||||
V(SaveRegister, SAVE_REGISTER, GateFlags::NONE_FLAG, 0, 1, value)
|
||||
V(SaveRegister, SAVE_REGISTER, GateFlags::NONE_FLAG, 0, 1, value) \
|
||||
V(ArrayConstructor, ARRAY_CONSTRUCTOR, GateFlags::NONE_FLAG, 1, 1, value)
|
||||
|
||||
#define HCR_GATE_META_DATA_LIST_WITH_PC_OFFSET(V) \
|
||||
V(Construct, CONSTRUCT, GateFlags::HAS_FRAME_STATE, 1, 1, value)
|
||||
|
@ -1198,4 +1198,17 @@ GateRef CircuitBuilder::NeedCheckProperty(GateRef receiver)
|
||||
SubCfgExit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::ArrayConstructorCheck(GateRef gate)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
auto currentControl = currentLabel->GetControl();
|
||||
auto currentDepend = currentLabel->GetDepend();
|
||||
auto frameState = acc_.FindNearestFrameState(currentDepend);
|
||||
GateRef ret = GetCircuit()->NewGate(circuit_->ArrayConstructorCheck(),
|
||||
MachineType::I64, {currentControl, currentDepend, gate, frameState}, GateType::IntType());
|
||||
currentLabel->SetControl(ret);
|
||||
currentLabel->SetDepend(ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ namespace panda::ecmascript::kungfu {
|
||||
V(TypedNewAllocateThis, TYPED_NEW_ALLOCATE_THIS, GateFlags::CHECKABLE, 1, 1, 2) \
|
||||
V(TypedSuperAllocateThis, TYPED_SUPER_ALLOCATE_THIS, GateFlags::CHECKABLE, 1, 1, 2) \
|
||||
V(InlineAccessorCheck, INLINE_ACCESSOR_CHECK, GateFlags::CHECKABLE, 1, 1, 2) \
|
||||
V(ArrayConstructorCheck, ARRAY_CONSTRUCTOR_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
MCR_BINARY_GATE_META_DATA_CACHE_LIST(V)
|
||||
|
||||
#define MCR_GATE_META_DATA_LIST_WITH_PC_OFFSET(V) \
|
||||
|
@ -75,6 +75,14 @@ void NTypeBytecodeLowering::Lower(GateRef gate)
|
||||
case EcmaOpcode::WIDE_STLEXVAR_PREF_IMM16_IMM16:
|
||||
LowerStLexVar(gate);
|
||||
break;
|
||||
case EcmaOpcode::LDLOCALMODULEVAR_IMM8:
|
||||
case EcmaOpcode::WIDE_LDLOCALMODULEVAR_PREF_IMM16:
|
||||
LowerLdLocalMoudleVar(gate);
|
||||
break;
|
||||
case EcmaOpcode::STMODULEVAR_IMM8:
|
||||
case EcmaOpcode::WIDE_STMODULEVAR_PREF_IMM16:
|
||||
LowerStModuleVar(gate);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -82,6 +90,7 @@ void NTypeBytecodeLowering::Lower(GateRef gate)
|
||||
|
||||
void NTypeBytecodeLowering::LowerThrowUndefinedIfHoleWithName(GateRef gate)
|
||||
{
|
||||
AddProfiling(gate);
|
||||
GateRef value = acc_.GetValueIn(gate, 1); // 1: the second parameter
|
||||
builder_.LexVarIsHoleCheck(value);
|
||||
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), Circuit::NullGate());
|
||||
@ -233,4 +242,29 @@ void NTypeBytecodeLowering::AddProfiling(GateRef gate)
|
||||
builder_.SetDepend(acc_.GetDep(gate)); // set gate depend: profiling or STATE_SPLIT
|
||||
}
|
||||
}
|
||||
|
||||
void NTypeBytecodeLowering::LowerLdLocalMoudleVar(GateRef gate)
|
||||
{
|
||||
if (!IsFastModule()) {
|
||||
return;
|
||||
}
|
||||
AddProfiling(gate);
|
||||
GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC);
|
||||
GateRef index = acc_.GetValueIn(gate, 0);
|
||||
GateRef result = builder_.LdLocalModuleVar(jsFunc, index);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
}
|
||||
|
||||
void NTypeBytecodeLowering::LowerStModuleVar(GateRef gate)
|
||||
{
|
||||
if (!IsFastModule()) {
|
||||
return;
|
||||
}
|
||||
AddProfiling(gate);
|
||||
GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC);
|
||||
GateRef index = acc_.GetValueIn(gate, 0);
|
||||
GateRef value = acc_.GetValueIn(gate, 1);
|
||||
builder_.StoreModuleVar(jsFunc, index, value);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate());
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ namespace panda::ecmascript::kungfu {
|
||||
class NTypeBytecodeLowering {
|
||||
public:
|
||||
NTypeBytecodeLowering(Circuit *circuit, PassContext *ctx, TSManager *tsManager,
|
||||
bool enableLog, const std::string& name)
|
||||
bool enableLog, const std::string& name, bool fastModule)
|
||||
: circuit_(circuit),
|
||||
acc_(circuit),
|
||||
builder_(circuit, ctx->GetCompilerConfig()),
|
||||
@ -37,7 +37,9 @@ public:
|
||||
profiling_(ctx->GetCompilerConfig()->IsProfiling()),
|
||||
traceBc_(ctx->GetCompilerConfig()->IsTraceBC()),
|
||||
methodName_(name),
|
||||
glue_(acc_.GetGlueFromArgList()) {}
|
||||
glue_(acc_.GetGlueFromArgList()),
|
||||
argAcc_(circuit),
|
||||
fastModule_(fastModule) {}
|
||||
|
||||
~NTypeBytecodeLowering() = default;
|
||||
|
||||
@ -50,6 +52,8 @@ private:
|
||||
void LowerLdLexVar(GateRef gate);
|
||||
void LowerStLexVar(GateRef gate);
|
||||
void LowerThrowUndefinedIfHoleWithName(GateRef gate);
|
||||
void LowerLdLocalMoudleVar(GateRef gate);
|
||||
void LowerStModuleVar(GateRef gate);
|
||||
|
||||
bool IsLogEnabled() const
|
||||
{
|
||||
@ -66,6 +70,11 @@ private:
|
||||
return traceBc_;
|
||||
}
|
||||
|
||||
bool IsFastModule() const
|
||||
{
|
||||
return fastModule_;
|
||||
}
|
||||
|
||||
const std::string& GetMethodName() const
|
||||
{
|
||||
return methodName_;
|
||||
@ -83,6 +92,8 @@ private:
|
||||
bool traceBc_ {false};
|
||||
std::string methodName_;
|
||||
GateRef glue_ {Circuit::NullGate()};
|
||||
ArgumentAccessor argAcc_;
|
||||
bool fastModule_;
|
||||
};
|
||||
} // panda::ecmascript::kungfu
|
||||
#endif // ECMASCRIPT_COMPILER_NTYPE_BYTECODE_LOWERING_H
|
||||
|
@ -30,6 +30,12 @@ GateRef NTypeHCRLowering::VisitGate(GateRef gate)
|
||||
case OpCode::CREATE_ARRAY_WITH_BUFFER:
|
||||
LowerCreateArrayWithBuffer(gate, glue);
|
||||
break;
|
||||
case OpCode::STORE_MODULE_VAR:
|
||||
LowerStoreModuleVar(gate, glue);
|
||||
break;
|
||||
case OpCode::LD_LOCAL_MODULE_VAR:
|
||||
LowerLdLocalModuleVar(gate);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -199,4 +205,126 @@ GateRef NTypeHCRLowering::LowerCallRuntime(GateRef glue, GateRef hirGate, int in
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
void NTypeHCRLowering::LowerStoreModuleVar(GateRef gate, GateRef glue)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
GateRef jsFunc = acc_.GetValueIn(gate, 0);
|
||||
GateRef index = acc_.GetValueIn(gate, 1);
|
||||
GateRef value = acc_.GetValueIn(gate, 2);
|
||||
GateRef method = builder_.GetMethodFromFunction(jsFunc);
|
||||
GateRef moduleOffset = builder_.IntPtr(Method::ECMA_MODULE_OFFSET);
|
||||
GateRef module = builder_.Load(VariableType::JS_ANY(), method, moduleOffset);
|
||||
GateRef localExportEntriesOffset = builder_.IntPtr(SourceTextModule::LOCAL_EXPORT_ENTTRIES_OFFSET);
|
||||
GateRef localExportEntries = builder_.Load(VariableType::JS_ANY(), module, localExportEntriesOffset);
|
||||
GateRef nameDictionaryOffset = builder_.IntPtr(SourceTextModule::NAME_DICTIONARY_OFFSET);
|
||||
GateRef data = builder_.Load(VariableType::JS_ANY(), module, nameDictionaryOffset);
|
||||
DEFVALUE(array, (&builder_), VariableType::JS_ANY(), data);
|
||||
|
||||
Label dataIsUndefined(&builder_);
|
||||
Label exit(&builder_);
|
||||
builder_.Branch(builder_.TaggedIsUndefined(data), &dataIsUndefined, &exit);
|
||||
builder_.Bind(&dataIsUndefined);
|
||||
{
|
||||
GateRef size = builder_.GetLengthOfTaggedArray(localExportEntries);
|
||||
Label fastpath(&builder_);
|
||||
Label slowPath(&builder_);
|
||||
Label finishNew(&builder_);
|
||||
builder_.Branch(builder_.Int32LessThan(size, builder_.Int32(MAX_TAGGED_ARRAY_LENGTH)), &fastpath, &slowPath);
|
||||
builder_.Bind(&fastpath);
|
||||
{
|
||||
array = NewTaggedArray(size);
|
||||
builder_.Jump(&finishNew);
|
||||
}
|
||||
builder_.Bind(&slowPath);
|
||||
{
|
||||
array = LowerCallRuntime(glue, gate, RTSTUB_ID(NewTaggedArray), { builder_.Int32ToTaggedInt(size) }, true);
|
||||
builder_.Jump(&finishNew);
|
||||
}
|
||||
builder_.Bind(&finishNew);
|
||||
{
|
||||
builder_.StoreConstOffset(VariableType::JS_ANY(), module, SourceTextModule::NAME_DICTIONARY_OFFSET, *array);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
}
|
||||
builder_.Bind(&exit);
|
||||
GateRef dataOffset = builder_.Int32(TaggedArray::DATA_OFFSET);
|
||||
GateRef indexOffset = builder_.Int32Mul(index, builder_.Int32(JSTaggedValue::TaggedTypeSize()));
|
||||
GateRef offset = builder_.Int32Add(indexOffset, dataOffset);
|
||||
builder_.Store(VariableType::JS_ANY(), glue_, *array, offset, value);
|
||||
ReplaceGateWithPendingException(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate());
|
||||
}
|
||||
|
||||
GateRef NTypeHCRLowering::NewTaggedArray(GateRef length)
|
||||
{
|
||||
Label subentry(&builder_);
|
||||
builder_.SubCfgEntry(&subentry);
|
||||
Label exit(&builder_);
|
||||
DEFVALUE(array, (&builder_), VariableType::JS_ANY(), builder_.Undefined());
|
||||
GateRef hclass = builder_.GetGlobalConstantValue(ConstantIndex::ARRAY_CLASS_INDEX);
|
||||
GateRef size = builder_.ComputeTaggedArraySize(builder_.ZExtInt32ToPtr(length));
|
||||
builder_.StartAllocate();
|
||||
array = builder_.HeapAlloc(size, GateType::TaggedValue(), RegionSpaceFlag::IN_YOUNG_SPACE);
|
||||
builder_.StoreConstOffset(VariableType::JS_POINTER(), *array, 0, hclass);
|
||||
builder_.StoreConstOffset(VariableType::JS_ANY(), *array, TaggedArray::LENGTH_OFFSET,
|
||||
builder_.Int32ToTaggedInt(length));
|
||||
GateRef dataOffset = builder_.Int32(TaggedArray::DATA_OFFSET);
|
||||
GateRef offset = builder_.Int32Mul(length, builder_.Int32(JSTaggedValue::TaggedTypeSize()));
|
||||
GateRef endOffset = builder_.Int32Add(offset, builder_.Int32(TaggedArray::DATA_OFFSET));
|
||||
Label loopHead(&builder_);
|
||||
Label loopEnd(&builder_);
|
||||
DEFVALUE(startOffset, (&builder_), VariableType::INT32(), dataOffset);
|
||||
builder_.Branch(builder_.Int32UnsignedLessThan(*startOffset, endOffset), &loopHead, &exit);
|
||||
builder_.LoopBegin(&loopHead);
|
||||
builder_.Store(VariableType::INT64(), glue_, *array, *startOffset, builder_.Hole());
|
||||
startOffset = builder_.Int32Add(*startOffset, builder_.Int32(JSTaggedValue::TaggedTypeSize()));
|
||||
builder_.Branch(builder_.Int32UnsignedLessThan(*startOffset, endOffset), &loopEnd, &exit);
|
||||
builder_.Bind(&loopEnd);
|
||||
builder_.LoopEnd(&loopHead);
|
||||
builder_.Bind(&exit);
|
||||
builder_.FinishAllocate();
|
||||
auto ret = *array;
|
||||
builder_.SubCfgExit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void NTypeHCRLowering::LowerLdLocalModuleVar(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
GateRef jsFunc = acc_.GetValueIn(gate, 0);
|
||||
GateRef index = acc_.GetValueIn(gate, 1);
|
||||
GateRef method = builder_.GetMethodFromFunction(jsFunc);
|
||||
GateRef moduleOffset = builder_.IntPtr(Method::ECMA_MODULE_OFFSET);
|
||||
GateRef module = builder_.Load(VariableType::JS_ANY(), method, moduleOffset);
|
||||
GateRef nameDictionaryOffset = builder_.IntPtr(SourceTextModule::NAME_DICTIONARY_OFFSET);
|
||||
GateRef dictionary = builder_.Load(VariableType::JS_ANY(), module, nameDictionaryOffset);
|
||||
DEFVALUE(result, (&builder_), VariableType::JS_ANY(), builder_.Hole());
|
||||
Label dataIsNotUndefined(&builder_);
|
||||
Label exit(&builder_);
|
||||
builder_.Branch(builder_.TaggedIsUndefined(dictionary), &exit, &dataIsNotUndefined);
|
||||
builder_.Bind(&dataIsNotUndefined);
|
||||
{
|
||||
GateRef dataOffset = builder_.Int32(TaggedArray::DATA_OFFSET);
|
||||
GateRef indexOffset = builder_.Int32Mul(index, builder_.Int32(JSTaggedValue::TaggedTypeSize()));
|
||||
GateRef offset = builder_.Int32Add(indexOffset, dataOffset);
|
||||
result = builder_.Load(VariableType::JS_ANY(), dictionary, offset);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
builder_.Bind(&exit);
|
||||
ReplaceGateWithPendingException(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void NTypeHCRLowering::ReplaceGateWithPendingException(GateRef gate, GateRef state, GateRef depend, GateRef value)
|
||||
{
|
||||
auto condition = builder_.HasPendingException(glue_);
|
||||
GateRef ifBranch = builder_.Branch(state, condition);
|
||||
GateRef ifTrue = builder_.IfTrue(ifBranch);
|
||||
GateRef ifFalse = builder_.IfFalse(ifBranch);
|
||||
GateRef eDepend = builder_.DependRelay(ifTrue, depend);
|
||||
GateRef sDepend = builder_.DependRelay(ifFalse, depend);
|
||||
|
||||
StateDepend success(ifFalse, sDepend);
|
||||
StateDepend exception(ifTrue, eDepend);
|
||||
acc_.ReplaceHirWithIfBranch(gate, success, exception, value);
|
||||
}
|
||||
}
|
||||
|
@ -46,15 +46,17 @@ private:
|
||||
void LowerCreateArrayWithBuffer(GateRef gate, GateRef glue);
|
||||
void LowerCreateEmptyArray(GateRef gate);
|
||||
void LowerCreateArrayWithOwn(GateRef gate, GateRef glue);
|
||||
void LowerStLexVar(GateRef gate);
|
||||
void LowerLdLexVar(GateRef gate);
|
||||
void LowerStoreModuleVar(GateRef gate, GateRef glue);
|
||||
void LowerLdLocalModuleVar(GateRef gate);
|
||||
|
||||
GateRef LoadFromConstPool(GateRef jsFunc, size_t index, size_t valVecType);
|
||||
GateRef NewJSArrayLiteral(GateRef gate, GateRef elements, GateRef length);
|
||||
GateRef NewTaggedArray(size_t length);
|
||||
GateRef NewTaggedArray(GateRef length);
|
||||
GateRef CreateElementsWithLength(GateRef gate, GateRef glue, size_t arrayLength);
|
||||
GateRef LowerCallRuntime(GateRef glue, GateRef hirGate, int index, const std::vector<GateRef> &args,
|
||||
bool useLabel = false);
|
||||
void ReplaceGateWithPendingException(GateRef gate, GateRef state, GateRef depend, GateRef value);
|
||||
|
||||
GateRef GetFrameState(GateRef gate) const
|
||||
{
|
||||
|
@ -143,6 +143,8 @@ GateRef NumberSpeculativeRetype::VisitGate(GateRef gate)
|
||||
case OpCode::STORE_CONST_OFFSET:
|
||||
case OpCode::LEX_VAR_IS_HOLE_CHECK:
|
||||
case OpCode::TYPE_OF_CHECK:
|
||||
// case OpCode::ARRAY_CONSTRUCTOR:
|
||||
case OpCode::LD_LOCAL_MODULE_VAR:
|
||||
return VisitOthers(gate);
|
||||
default:
|
||||
return Circuit::NullGate();
|
||||
|
@ -299,7 +299,7 @@ public:
|
||||
bool enableLog = data->GetLog()->EnableMethodCIRLog();
|
||||
bool enableTypeLog = data->GetLog()->GetEnableMethodLog() && data->GetLog()->OutputType();
|
||||
TypeBytecodeLowering lowering(data->GetCircuit(), data->GetPassContext(),
|
||||
enableLog, enableTypeLog, data->GetMethodName());
|
||||
enableLog, enableTypeLog, data->GetMethodName(), passOptions->EnableFastModule());
|
||||
bool success = lowering.RunTypeBytecodeLowering();
|
||||
if (!success) {
|
||||
data->MarkAsTypeAbort();
|
||||
@ -329,7 +329,7 @@ public:
|
||||
TimeScope timescope("NTypeBytecodeLoweringPass", data->GetMethodName(), data->GetMethodOffset(), data->GetLog());
|
||||
bool enableLog = data->GetLog()->EnableMethodCIRLog();
|
||||
NTypeBytecodeLowering lowering(data->GetCircuit(), data->GetPassContext(), data->GetTSManager(),
|
||||
enableLog, data->GetMethodName());
|
||||
enableLog, data->GetMethodName(), passOptions->EnableFastModule());
|
||||
lowering.RunNTypeBytecodeLowering();
|
||||
Chunk chunk(data->GetNativeAreaAllocator());
|
||||
CombinedPassVisitor visitor(data->GetCircuit(), enableLog, data->GetMethodName(), &chunk);
|
||||
|
@ -135,7 +135,8 @@ public:
|
||||
bool enableLaterElimination, bool enableValueNumbering, bool enableTypeInfer,
|
||||
bool enableOptInlining, bool enableOptPGOType, bool enableOptTrackField, bool enableOptLoopPeeling,
|
||||
bool enableOptOnHeapCheck, bool enableOptLoopInvariantCodeMotion, bool enableCollectLiteralInfo,
|
||||
bool enableOptConstantFolding, bool enableLexenvSpecialization, bool enableInlineNative)
|
||||
bool enableOptConstantFolding, bool enableLexenvSpecialization, bool enableInlineNative,
|
||||
bool enableFastModule)
|
||||
: enableArrayBoundsCheckElimination_(enableArrayBoundsCheckElimination),
|
||||
enableTypeLowering_(enableTypeLowering),
|
||||
enableEarlyElimination_(enableEarlyElimination),
|
||||
@ -151,7 +152,8 @@ public:
|
||||
enableCollectLiteralInfo_(enableCollectLiteralInfo),
|
||||
enableOptConstantFolding_(enableOptConstantFolding),
|
||||
enableLexenvSpecialization_(enableLexenvSpecialization),
|
||||
enableInlineNative_(enableInlineNative)
|
||||
enableInlineNative_(enableInlineNative),
|
||||
enableFastModule_(enableFastModule)
|
||||
{
|
||||
}
|
||||
|
||||
@ -173,7 +175,8 @@ public:
|
||||
V(CollectLiteralInfo, false) \
|
||||
V(OptConstantFolding, true) \
|
||||
V(LexenvSpecialization, false) \
|
||||
V(InlineNative, false)
|
||||
V(InlineNative, false) \
|
||||
V(FastModule, false)
|
||||
|
||||
#define DECL_OPTION(NAME, DEFAULT) \
|
||||
public: \
|
||||
|
@ -72,6 +72,7 @@ enum class TypedCallTargetCheckOp : uint8_t;
|
||||
V(IteratorFunctionDisMactch, ITERATORFUNCTIONDISMATCH) \
|
||||
V(NativeCallTargetDisMatch, NATIVECALLTARGETDISMATCH) \
|
||||
V(ProtoTypeChanged, PROTOTYPECHANGED) \
|
||||
V(NewBuiltinCtorFail, NEWBUILTINCTORFAIL) \
|
||||
|
||||
enum class DeoptType : uint8_t {
|
||||
NOTCHECK = 0,
|
||||
|
@ -200,7 +200,7 @@ inline GateRef StubBuilder::CallRuntime(GateRef glue, int index, const std::init
|
||||
SavePcIfNeeded(glue);
|
||||
const std::string name = RuntimeStubCSigns::GetRTName(index);
|
||||
GateRef result = env_->GetBuilder()->CallRuntime(glue, index, Gate::InvalidGateRef, args,
|
||||
Circuit::NullGate(), name.c_str());
|
||||
glue, name.c_str());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -283,6 +283,7 @@ void TypeBytecodeLowering::Lower(GateRef gate)
|
||||
case EcmaOpcode::NEWOBJRANGE_IMM8_IMM8_V8:
|
||||
case EcmaOpcode::NEWOBJRANGE_IMM16_IMM8_V8:
|
||||
case EcmaOpcode::WIDE_NEWOBJRANGE_PREF_IMM16_V8:
|
||||
LowerTypedNewObjRange(gate);
|
||||
break;
|
||||
case EcmaOpcode::SUPERCALLTHISRANGE_IMM8_IMM8_V8:
|
||||
case EcmaOpcode::WIDE_SUPERCALLTHISRANGE_PREF_IMM16_V8:
|
||||
@ -1472,27 +1473,33 @@ void TypeBytecodeLowering::LowerTypedNewObjRange(GateRef gate)
|
||||
{
|
||||
GateRef ctor = acc_.GetValueIn(gate, 0);
|
||||
GateType ctorType = acc_.GetGateType(ctor);
|
||||
if (!tsManager_->IsClassTypeKind(ctorType)) {
|
||||
GlobalTSTypeRef ctorGT = ctorType.GetGTRef();
|
||||
if (ctorGT.IsBuiltinModule()) {
|
||||
if (TryLowerNewBuiltinConstructor(gate)) {
|
||||
return;
|
||||
}
|
||||
|
||||
AddProfiling(gate);
|
||||
|
||||
int hclassIndex = tsManager_->GetHClassIndexByClassGateType(ctorType);
|
||||
GateRef stateSplit = acc_.GetDep(gate);
|
||||
|
||||
GateRef frameState = acc_.FindNearestFrameState(stateSplit);
|
||||
GateRef thisObj = builder_.TypedNewAllocateThis(ctor, builder_.IntPtr(hclassIndex), frameState);
|
||||
|
||||
// call constructor
|
||||
size_t range = acc_.GetNumValueIn(gate);
|
||||
GateRef actualArgc = builder_.Int64(BytecodeCallArgc::ComputeCallArgc(range, EcmaOpcode::NEWOBJRANGE_IMM8_IMM8_V8));
|
||||
std::vector<GateRef> args { glue_, actualArgc, ctor, ctor, thisObj };
|
||||
for (size_t i = 1; i < range; ++i) { // 1:skip ctor
|
||||
args.emplace_back(acc_.GetValueIn(gate, i));
|
||||
}
|
||||
GateRef constructGate = builder_.Construct(gate, args);
|
||||
}
|
||||
|
||||
bool TypeBytecodeLowering::TryLowerNewBuiltinConstructor(GateRef gate)
|
||||
{
|
||||
GateRef ctor = acc_.GetValueIn(gate, 0);
|
||||
GateType ctorType = acc_.GetGateType(ctor);
|
||||
GlobalTSTypeRef ctorGT = ctorType.GetGTRef();
|
||||
GateRef constructGate = Circuit::NullGate();
|
||||
if (tsManager_->IsBuiltinConstructor(BuiltinTypeId::ARRAY, ctorGT) && enableNewArrayInline_) {
|
||||
if (acc_.GetNumValueIn(gate) <= 2) { // 2: ctor and first arg
|
||||
if (!Uncheck()) {
|
||||
builder_.ArrayConstructorCheck(ctor);
|
||||
}
|
||||
constructGate = builder_.BuiltinConstructor(BuiltinTypeId::ARRAY, gate);
|
||||
}
|
||||
}
|
||||
if (constructGate == Circuit::NullGate()) {
|
||||
return false;
|
||||
}
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), constructGate);
|
||||
return true;
|
||||
}
|
||||
|
||||
void TypeBytecodeLowering::LowerTypedSuperCall(GateRef gate)
|
||||
|
@ -29,7 +29,7 @@ class TypeBytecodeLowering {
|
||||
public:
|
||||
TypeBytecodeLowering(Circuit *circuit, PassContext *ctx,
|
||||
bool enableLog, bool enableTypeLog,
|
||||
const std::string& name)
|
||||
const std::string& name, bool enableNewArrayInline)
|
||||
: circuit_(circuit),
|
||||
acc_(circuit),
|
||||
builder_(circuit, ctx->GetCompilerConfig()),
|
||||
@ -45,7 +45,8 @@ public:
|
||||
argAcc_(circuit),
|
||||
pgoTypeLog_(circuit),
|
||||
noCheck_(ctx->GetEcmaVM()->GetJSOptions().IsCompilerNoCheck()),
|
||||
thread_(ctx->GetEcmaVM()->GetJSThread()) {}
|
||||
thread_(ctx->GetEcmaVM()->GetJSThread()),
|
||||
enableNewArrayInline_(enableNewArrayInline) {}
|
||||
|
||||
~TypeBytecodeLowering() = default;
|
||||
|
||||
@ -172,6 +173,7 @@ private:
|
||||
BuiltinsStubCSigns::ID GetBuiltinId(BuiltinTypeId id, GateRef func);
|
||||
BuiltinsStubCSigns::ID GetPGOBuiltinId(GateRef gate);
|
||||
void DeleteConstDataIfNoUser(GateRef gate);
|
||||
bool TryLowerNewBuiltinConstructor(GateRef gate);
|
||||
|
||||
void AddProfiling(GateRef gate);
|
||||
|
||||
@ -202,6 +204,7 @@ private:
|
||||
std::unordered_map<EcmaOpcode, uint32_t> bytecodeHitTimeMap_;
|
||||
bool noCheck_ {false};
|
||||
const JSThread *thread_ {nullptr};
|
||||
bool enableNewArrayInline_ {false};
|
||||
};
|
||||
} // panda::ecmascript::kungfu
|
||||
#endif // ECMASCRIPT_COMPILER_TYPE_BYTECODE_LOWERING_H
|
||||
|
@ -138,6 +138,12 @@ GateRef TypeHCRLowering::VisitGate(GateRef gate)
|
||||
case OpCode::TYPE_OF:
|
||||
LowerTypeOf(gate, glue);
|
||||
break;
|
||||
case OpCode::ARRAY_CONSTRUCTOR_CHECK:
|
||||
LowerArrayConstructorCheck(gate, glue);
|
||||
break;
|
||||
case OpCode::ARRAY_CONSTRUCTOR:
|
||||
LowerArrayConstructor(gate, glue);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1801,4 +1807,164 @@ void TypeHCRLowering::LowerTypeOf(GateRef gate, GateRef glue)
|
||||
GateRef result = builder_.Load(VariableType::JS_POINTER(), gConstAddr, builder_.GetGlobalConstantOffset(index));
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
}
|
||||
|
||||
void TypeHCRLowering::LowerArrayConstructorCheck(GateRef gate, GateRef glue)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
GateRef frameState = GetFrameState(gate);
|
||||
GateRef newTarget = acc_.GetValueIn(gate, 0);
|
||||
Label isHeapObject(&builder_);
|
||||
Label exit(&builder_);
|
||||
DEFVALUE(check, (&builder_), VariableType::BOOL(), builder_.True());
|
||||
check = builder_.TaggedIsHeapObject(newTarget);
|
||||
builder_.Branch(*check, &isHeapObject, &exit);
|
||||
builder_.Bind(&isHeapObject);
|
||||
{
|
||||
Label isJSFunction(&builder_);
|
||||
check = builder_.IsJSFunction(newTarget);
|
||||
builder_.Branch(*check, &isJSFunction, &exit);
|
||||
builder_.Bind(&isJSFunction);
|
||||
{
|
||||
Label getHclass(&builder_);
|
||||
GateRef glueGlobalEnvOffset = builder_.IntPtr(
|
||||
JSThread::GlueData::GetGlueGlobalEnvOffset(builder_.GetCurrentEnvironment()->Is32Bit()));
|
||||
GateRef glueGlobalEnv = builder_.Load(VariableType::NATIVE_POINTER(), glue, glueGlobalEnvOffset);
|
||||
GateRef arrayFunc =
|
||||
builder_.GetGlobalEnvValue(VariableType::JS_ANY(), glueGlobalEnv, GlobalEnv::ARRAY_FUNCTION_INDEX);
|
||||
check = builder_.Equal(arrayFunc, newTarget);
|
||||
builder_.Branch(*check, &getHclass, &exit);
|
||||
builder_.Bind(&getHclass);
|
||||
{
|
||||
GateRef intialHClass = builder_.Load(VariableType::JS_ANY(), newTarget,
|
||||
builder_.IntPtr(JSFunction::PROTO_OR_DYNCLASS_OFFSET));
|
||||
check = builder_.IsJSHClass(intialHClass);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
}
|
||||
}
|
||||
builder_.Bind(&exit);
|
||||
builder_.DeoptCheck(*check, frameState, DeoptType::NEWBUILTINCTORFAIL);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate());
|
||||
}
|
||||
|
||||
void TypeHCRLowering::LowerArrayConstructor(GateRef gate, GateRef glue)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
if (acc_.GetNumValueIn(gate) == 1) {
|
||||
NewArrayConstructorWithNoArgs(gate, glue);
|
||||
return;
|
||||
}
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 2); // 2: new target and arg0
|
||||
DEFVALUE(res, (&builder_), VariableType::JS_ANY(), builder_.Undefined());
|
||||
Label slowPath(&builder_);
|
||||
Label exit(&builder_);
|
||||
GateRef newTarget = acc_.GetValueIn(gate, 0);
|
||||
GateRef arg0 = acc_.GetValueIn(gate, 1);
|
||||
GateRef intialHClass =
|
||||
builder_.Load(VariableType::JS_ANY(), newTarget, builder_.IntPtr(JSFunction::PROTO_OR_DYNCLASS_OFFSET));
|
||||
DEFVALUE(arrayLength, (&builder_), VariableType::INT64(), builder_.Int64(0));
|
||||
Label argIsNumber(&builder_);
|
||||
Label arrayCreate(&builder_);
|
||||
builder_.Branch(builder_.TaggedIsNumber(arg0), &argIsNumber, &slowPath);
|
||||
builder_.Bind(&argIsNumber);
|
||||
{
|
||||
Label argIsInt(&builder_);
|
||||
Label argIsDouble(&builder_);
|
||||
builder_.Branch(builder_.TaggedIsInt(arg0), &argIsInt, &argIsDouble);
|
||||
builder_.Bind(&argIsInt);
|
||||
{
|
||||
Label validIntLength(&builder_);
|
||||
GateRef intLen = builder_.GetInt64OfTInt(arg0);
|
||||
GateRef isGEZero = builder_.Int64GreaterThanOrEqual(intLen, builder_.Int64(0));
|
||||
GateRef isLEMaxLen = builder_.Int64LessThanOrEqual(intLen, builder_.Int64(JSArray::MAX_ARRAY_INDEX));
|
||||
builder_.Branch(builder_.BoolAnd(isGEZero, isLEMaxLen), &validIntLength, &slowPath);
|
||||
builder_.Bind(&validIntLength);
|
||||
{
|
||||
arrayLength = intLen;
|
||||
builder_.Jump(&arrayCreate);
|
||||
}
|
||||
}
|
||||
builder_.Bind(&argIsDouble);
|
||||
{
|
||||
Label validDoubleLength(&builder_);
|
||||
Label GetDoubleToIntValue(&builder_);
|
||||
GateRef doubleLength = builder_.GetDoubleOfTDouble(arg0);
|
||||
GateRef doubleToInt = builder_.DoubleToInt(doubleLength, &GetDoubleToIntValue);
|
||||
GateRef intToDouble = builder_.CastInt64ToFloat64(builder_.SExtInt32ToInt64(doubleToInt));
|
||||
GateRef doubleEqual = builder_.DoubleEqual(doubleLength, intToDouble);
|
||||
GateRef doubleLEMaxLen =
|
||||
builder_.DoubleLessThanOrEqual(doubleLength, builder_.Double(JSArray::MAX_ARRAY_INDEX));
|
||||
builder_.Branch(builder_.BoolAnd(doubleEqual, doubleLEMaxLen), &validDoubleLength, &slowPath);
|
||||
builder_.Bind(&validDoubleLength);
|
||||
{
|
||||
arrayLength = builder_.SExtInt32ToInt64(doubleToInt);
|
||||
builder_.Jump(&arrayCreate);
|
||||
}
|
||||
}
|
||||
}
|
||||
builder_.Bind(&arrayCreate);
|
||||
{
|
||||
Label lengthValid(&builder_);
|
||||
builder_.Branch(
|
||||
builder_.Int64GreaterThan(*arrayLength, builder_.Int64(JSObject::MAX_GAP)), &slowPath, &lengthValid);
|
||||
builder_.Bind(&lengthValid);
|
||||
{
|
||||
NewObjectStubBuilder newBuilder(builder_.GetCurrentEnvironment());
|
||||
newBuilder.SetParameters(glue, 0);
|
||||
res = newBuilder.NewJSArrayWithSize(intialHClass, *arrayLength);
|
||||
GateRef lengthOffset = builder_.IntPtr(JSArray::LENGTH_OFFSET);
|
||||
builder_.Store(VariableType::INT32(), glue, *res, lengthOffset, builder_.TruncInt64ToInt32(*arrayLength));
|
||||
GateRef accessor = builder_.GetGlobalConstantValue(ConstantIndex::ARRAY_LENGTH_ACCESSOR);
|
||||
builder_.SetPropertyInlinedProps(glue, *res, intialHClass, accessor,
|
||||
builder_.Int32(JSArray::LENGTH_INLINE_PROPERTY_INDEX), VariableType::JS_ANY());
|
||||
builder_.SetExtensibleToBitfield(glue, *res, true);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
}
|
||||
builder_.Bind(&slowPath);
|
||||
{
|
||||
size_t range = acc_.GetNumValueIn(gate);
|
||||
std::vector<GateRef> args(range);
|
||||
for (size_t i = 0; i < range; ++i) {
|
||||
args[i] = acc_.GetValueIn(gate, i);
|
||||
}
|
||||
res = LowerCallRuntime(glue, gate, RTSTUB_ID(OptNewObjRange), args, true);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
builder_.Bind(&exit);
|
||||
ReplaceGateWithPendingException(glue, gate, builder_.GetState(), builder_.GetDepend(), *res);
|
||||
}
|
||||
|
||||
void TypeHCRLowering::NewArrayConstructorWithNoArgs(GateRef gate, GateRef glue)
|
||||
{
|
||||
GateRef newTarget = acc_.GetValueIn(gate, 0);
|
||||
GateRef intialHClass =
|
||||
builder_.Load(VariableType::JS_ANY(), newTarget, builder_.IntPtr(JSFunction::PROTO_OR_DYNCLASS_OFFSET));
|
||||
GateRef arrayLength = builder_.Int64(0);
|
||||
NewObjectStubBuilder newBuilder(builder_.GetCurrentEnvironment());
|
||||
newBuilder.SetParameters(glue, 0);
|
||||
GateRef res = newBuilder.NewJSArrayWithSize(intialHClass, arrayLength);
|
||||
GateRef lengthOffset = builder_.IntPtr(JSArray::LENGTH_OFFSET);
|
||||
builder_.Store(VariableType::INT32(), glue, res, lengthOffset, builder_.TruncInt64ToInt32(arrayLength));
|
||||
GateRef accessor = builder_.GetGlobalConstantValue(ConstantIndex::ARRAY_LENGTH_ACCESSOR);
|
||||
builder_.SetPropertyInlinedProps(glue, res, intialHClass, accessor,
|
||||
builder_.Int32(JSArray::LENGTH_INLINE_PROPERTY_INDEX), VariableType::JS_ANY());
|
||||
builder_.SetExtensibleToBitfield(glue, res, true);
|
||||
ReplaceGateWithPendingException(glue, gate, builder_.GetState(), builder_.GetDepend(), res);
|
||||
}
|
||||
|
||||
void TypeHCRLowering::ReplaceGateWithPendingException(GateRef glue, GateRef gate, GateRef state, GateRef depend,
|
||||
GateRef value)
|
||||
{
|
||||
auto condition = builder_.HasPendingException(glue);
|
||||
GateRef ifBranch = builder_.Branch(state, condition);
|
||||
GateRef ifTrue = builder_.IfTrue(ifBranch);
|
||||
GateRef ifFalse = builder_.IfFalse(ifBranch);
|
||||
GateRef eDepend = builder_.DependRelay(ifTrue, depend);
|
||||
GateRef sDepend = builder_.DependRelay(ifFalse, depend);
|
||||
|
||||
StateDepend success(ifFalse, sDepend);
|
||||
StateDepend exception(ifTrue, eDepend);
|
||||
acc_.ReplaceHirWithIfBranch(gate, success, exception, value);
|
||||
}
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
|
@ -188,6 +188,10 @@ private:
|
||||
void LowerStringAdd(GateRef gate, GateRef glue);
|
||||
void LowerTypeOfCheck(GateRef gate);
|
||||
void LowerTypeOf(GateRef gate, GateRef glue);
|
||||
void LowerArrayConstructorCheck(GateRef gate, GateRef glue);
|
||||
void NewArrayConstructorWithNoArgs(GateRef gate, GateRef glue);
|
||||
void LowerArrayConstructor(GateRef gate, GateRef glue);
|
||||
void ReplaceGateWithPendingException(GateRef glue, GateRef gate, GateRef state, GateRef depend, GateRef value);
|
||||
|
||||
GateRef LowerCallRuntime(GateRef glue, GateRef hirGate, int index, const std::vector<GateRef> &args,
|
||||
bool useLabel = false);
|
||||
|
@ -154,6 +154,7 @@ const std::string PUBLIC_API HELP_OPTION_MSG =
|
||||
"--compiler-enable-external-pkg Enable compile with external package for ark aot compiler\n"
|
||||
"--compiler-enable-lexenv-specialization: Enable replace ldlexvar with specific values: Default: 'true'\n"
|
||||
"--compiler-enable-native-inline: Enable inline native function: Default: 'false'\n"
|
||||
"--compiler-enable-fast-module: Enable fast module bytecode: Default: 'false'\n"
|
||||
"--compiler-opt-array-onheap-check: Enable TypedArray on heap check for aot compiler: Default: 'false'\n\n";
|
||||
|
||||
bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
|
||||
@ -246,7 +247,8 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
|
||||
{"compiler-enable-external-pkg", required_argument, nullptr, OPTION_COMPILER_ENABLE_EXTERNAL_PKG},
|
||||
{"compiler-enable-lexenv-specialization", required_argument, nullptr,
|
||||
OPTION_COMPILER_ENABLE_LEXENV_SPECIALIZATION},
|
||||
{"compiler-enable-native-inline", required_argument, nullptr, OPTION_COMPILER_ENBALE_NATIVE_INLINE},
|
||||
{"compiler-enable-native-inline", required_argument, nullptr, OPTION_COMPILER_ENABLE_NATIVE_INLINE},
|
||||
{"compiler-enable-fast-module", required_argument, nullptr, OPTION_COMPILER_ENABLE_FAST_MODULE},
|
||||
{nullptr, 0, nullptr, 0},
|
||||
};
|
||||
|
||||
@ -840,7 +842,7 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case OPTION_COMPILER_ENBALE_NATIVE_INLINE:
|
||||
case OPTION_COMPILER_ENABLE_NATIVE_INLINE:
|
||||
ret = ParseBoolParam(&argBool);
|
||||
if (ret) {
|
||||
SetEnableNativeInline(argBool);
|
||||
@ -848,6 +850,15 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case OPTION_COMPILER_ENABLE_FAST_MODULE:
|
||||
ret = ParseBoolParam(&argBool);
|
||||
if (ret) {
|
||||
SetEnableFastModule(argBool);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_ECMA(ERROR) << "Invalid option\n";
|
||||
return false;
|
||||
|
@ -150,7 +150,8 @@ enum CommandValues {
|
||||
OPTION_COMPILER_TRACE_VALUE_NUMBERING,
|
||||
OPTION_COMPILER_OPT_INSTRUCTIONE_COMBINE,
|
||||
OPTION_COMPILER_OPT_NEW_VALUE_NUMBERING,
|
||||
OPTION_COMPILER_ENBALE_NATIVE_INLINE,
|
||||
OPTION_COMPILER_ENABLE_NATIVE_INLINE,
|
||||
OPTION_COMPILER_ENABLE_FAST_MODULE
|
||||
};
|
||||
|
||||
class PUBLIC_API JSRuntimeOptions {
|
||||
@ -1323,6 +1324,16 @@ public:
|
||||
enableNativeInline_ = value;
|
||||
}
|
||||
|
||||
bool IsEnableFastModule() const
|
||||
{
|
||||
return enableFastModule_;
|
||||
}
|
||||
|
||||
void SetEnableFastModule(bool value)
|
||||
{
|
||||
enableFastModule_ = value;
|
||||
}
|
||||
|
||||
private:
|
||||
static bool StartsWith(const std::string &haystack, const std::string &needle)
|
||||
{
|
||||
@ -1431,6 +1442,7 @@ private:
|
||||
bool enableOptLoopInvariantCodeMotion_ {false};
|
||||
bool enableLexenvSpecialization_ {true};
|
||||
bool enableNativeInline_ {false};
|
||||
bool enableFastModule_ {false};
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
|
||||
|
@ -1434,4 +1434,22 @@ int TSModuleTable::GetGlobalModuleID(JSThread *thread, JSHandle<EcmaString> amiP
|
||||
}
|
||||
return NOT_FOUND;
|
||||
}
|
||||
|
||||
bool TSManager::IsBuiltinConstructor(BuiltinTypeId id, GlobalTSTypeRef ctorGT) const
|
||||
{
|
||||
ASSERT(ctorGT.IsBuiltinModule());
|
||||
if (IsBuiltinsDTSEnabled()) {
|
||||
uint32_t idx = static_cast<uint32_t>(id);
|
||||
const JSPandaFile *builtinPandaFile = GetBuiltinPandaFile();
|
||||
uint32_t builtinOffset = GetBuiltinOffset(idx);
|
||||
GlobalTypeID gId(builtinPandaFile, builtinOffset);
|
||||
bool hasCreatedGT = HasCreatedGT(gId);
|
||||
if (hasCreatedGT) {
|
||||
auto gt = GetGTByGlobalTypeID(gId);
|
||||
return ctorGT == gt;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -509,6 +509,7 @@ public:
|
||||
}
|
||||
|
||||
bool PUBLIC_API IsBuiltinObjectMethod(BuiltinTypeId id, kungfu::GateType funcType) const;
|
||||
bool PUBLIC_API IsBuiltinConstructor(BuiltinTypeId id, GlobalTSTypeRef ctorType) const;
|
||||
|
||||
inline const JSPandaFile *GetBuiltinPandaFile() const
|
||||
{
|
||||
|
@ -158,6 +158,7 @@ group("ark_aot_ts_test") {
|
||||
"lexenv_specialization",
|
||||
"lexenv_specialization",
|
||||
"lexenv_specialization_noopt",
|
||||
"load_local_module_var",
|
||||
"logic_op",
|
||||
"loop_peeling",
|
||||
"loop_phi",
|
||||
|
18
test/aottest/load_local_module_var/BUILD.gn
Normal file
18
test/aottest/load_local_module_var/BUILD.gn
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_test_action("load_local_module_var") {
|
||||
deps = []
|
||||
}
|
14
test/aottest/load_local_module_var/expect_output.txt
Normal file
14
test/aottest/load_local_module_var/expect_output.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
2
|
25
test/aottest/load_local_module_var/load_local_module_var.ts
Normal file
25
test/aottest/load_local_module_var/load_local_module_var.ts
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
declare function print(arg:any) : string;
|
||||
|
||||
export function RunNormalCall():number {
|
||||
let res : number = 1;
|
||||
res++;
|
||||
return res
|
||||
|
||||
}
|
||||
let num = RunNormalCall()
|
||||
print(num)
|
Loading…
Reference in New Issue
Block a user