mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
!2699 Set AOT code entry for literal object
Merge pull request !2699 from weng-xi/add_code_entry_for_literal
This commit is contained in:
commit
c2d7f33998
@ -459,6 +459,27 @@ void AOTFileManager::SetAOTFuncEntry(const JSPandaFile *jsPandaFile, Method *met
|
||||
method->SetCodeEntryAndMarkAOT(codeEntry);
|
||||
}
|
||||
|
||||
void AOTFileManager::SetAOTFuncEntryForLiteral(const JSPandaFile *jsPandaFile, const TaggedArray *literal,
|
||||
const AOTLiteralInfo *entryIndexes)
|
||||
{
|
||||
size_t elementsLen = literal->GetLength();
|
||||
JSTaggedValue value = JSTaggedValue::Undefined();
|
||||
int pos = 0;
|
||||
for (size_t i = 0; i < elementsLen; i++) {
|
||||
value = literal->Get(i);
|
||||
if (value.IsJSFunction()) {
|
||||
JSTaggedValue index = entryIndexes->Get(pos++);
|
||||
int entryIndex = index.GetInt();
|
||||
// -1 : this jsfunction is a large function
|
||||
if (entryIndex == -1) {
|
||||
continue;
|
||||
}
|
||||
SetAOTFuncEntry(jsPandaFile, JSFunction::Cast(value)->GetCallTarget(),
|
||||
static_cast<uint32_t>(entryIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
kungfu::ArkStackMapParser* AOTFileManager::GetStackMapParser() const
|
||||
{
|
||||
return arkStackMapParser_;
|
||||
|
@ -149,7 +149,7 @@ public:
|
||||
struct FuncEntryDes {
|
||||
uint64_t codeAddr_;
|
||||
CallSignature::TargetKind kind_;
|
||||
bool isMainFunc_;
|
||||
bool isMainFunc_;
|
||||
uint32_t indexInKindOrMethodId_;
|
||||
uint32_t moduleIndex_;
|
||||
int fpDeltaPrevFrameSp_;
|
||||
@ -392,6 +392,15 @@ private:
|
||||
std::vector<int> asmStubTempHolder_ {};
|
||||
};
|
||||
|
||||
class AOTLiteralInfo : public TaggedArray {
|
||||
public:
|
||||
static AOTLiteralInfo *Cast(TaggedObject *object)
|
||||
{
|
||||
ASSERT(JSTaggedValue(object).IsTaggedArray());
|
||||
return static_cast<AOTLiteralInfo *>(object);
|
||||
}
|
||||
};
|
||||
|
||||
class AOTFileManager {
|
||||
public:
|
||||
explicit AOTFileManager(EcmaVM *vm);
|
||||
@ -420,6 +429,8 @@ public:
|
||||
void UpdateJSMethods(JSHandle<JSFunction> mainFunc, const JSPandaFile *jsPandaFile, std::string_view entryPoint);
|
||||
bool HasLoaded(const JSPandaFile *jsPandaFile) const;
|
||||
void SetAOTFuncEntry(const JSPandaFile *jsPandaFile, Method *method, uint32_t entryIndex);
|
||||
void SetAOTFuncEntryForLiteral(const JSPandaFile *jsPandaFile, const TaggedArray *literal,
|
||||
const AOTLiteralInfo *entryIndexes);
|
||||
void LoadSnapshotFile([[maybe_unused]]const std::string& filename);
|
||||
kungfu::ArkStackMapParser* GetStackMapParser() const;
|
||||
static JSTaggedValue GetAbsolutePath(JSThread *thread, JSTaggedValue relativePathVal);
|
||||
|
@ -1054,12 +1054,12 @@ BytecodeInfo BytecodeCircuitBuilder::GetBytecodeInfo(const uint8_t *pc)
|
||||
}
|
||||
case EcmaOpcode::CREATEOBJECTWITHBUFFER_IMM8_ID16: {
|
||||
uint16_t imm = READ_INST_16_1();
|
||||
info.inputs.emplace_back(Immediate(imm));
|
||||
info.inputs.emplace_back(ConstDataId(ConstDataIDType::ObjectLiteralIDType, imm));
|
||||
break;
|
||||
}
|
||||
case EcmaOpcode::CREATEOBJECTWITHBUFFER_IMM16_ID16: {
|
||||
uint16_t imm = READ_INST_16_2();
|
||||
info.inputs.emplace_back(Immediate(imm));
|
||||
info.inputs.emplace_back(ConstDataId(ConstDataIDType::ObjectLiteralIDType, imm));
|
||||
break;
|
||||
}
|
||||
case EcmaOpcode::SETOBJECTWITHPROTO_IMM8_V8: {
|
||||
@ -1074,12 +1074,12 @@ BytecodeInfo BytecodeCircuitBuilder::GetBytecodeInfo(const uint8_t *pc)
|
||||
}
|
||||
case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM8_ID16: {
|
||||
uint16_t imm = READ_INST_16_1();
|
||||
info.inputs.emplace_back(Immediate(imm));
|
||||
info.inputs.emplace_back(ConstDataId(ConstDataIDType::ArrayLiteralIDType, imm));
|
||||
break;
|
||||
}
|
||||
case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM16_ID16: {
|
||||
uint16_t imm = READ_INST_16_2();
|
||||
info.inputs.emplace_back(Immediate(imm));
|
||||
info.inputs.emplace_back(ConstDataId(ConstDataIDType::ArrayLiteralIDType, imm));
|
||||
break;
|
||||
}
|
||||
case EcmaOpcode::GETMODULENAMESPACE_IMM8: {
|
||||
@ -1542,7 +1542,7 @@ BytecodeInfo BytecodeCircuitBuilder::GetBytecodeInfo(const uint8_t *pc)
|
||||
uint16_t length = READ_INST_16_5();
|
||||
uint16_t v0 = READ_INST_8_7();
|
||||
info.inputs.emplace_back(ConstDataId(ConstDataIDType::MethodIDType, methodId));
|
||||
info.inputs.emplace_back(Immediate(literaId));
|
||||
info.inputs.emplace_back(ConstDataId(ConstDataIDType::ClassLiteralIDType, literaId));
|
||||
info.inputs.emplace_back(Immediate(length));
|
||||
info.inputs.emplace_back(VirtualRegister(v0));
|
||||
break;
|
||||
@ -1553,7 +1553,7 @@ BytecodeInfo BytecodeCircuitBuilder::GetBytecodeInfo(const uint8_t *pc)
|
||||
uint16_t length = READ_INST_16_6();
|
||||
uint16_t v0 = READ_INST_8_8();
|
||||
info.inputs.emplace_back(ConstDataId(ConstDataIDType::MethodIDType, methodId));
|
||||
info.inputs.emplace_back(Immediate(literaId));
|
||||
info.inputs.emplace_back(ConstDataId(ConstDataIDType::ClassLiteralIDType, literaId));
|
||||
info.inputs.emplace_back(Immediate(length));
|
||||
info.inputs.emplace_back(VirtualRegister(v0));
|
||||
break;
|
||||
@ -1956,15 +1956,27 @@ std::vector<GateRef> BytecodeCircuitBuilder::CreateGateInList(const BytecodeInfo
|
||||
const auto &input = info.inputs[i];
|
||||
if (std::holds_alternative<ConstDataId>(input)) {
|
||||
if (std::get<ConstDataId>(input).IsStringId()) {
|
||||
tsManager_->AddStringIndex(std::get<ConstDataId>(input).GetId());
|
||||
tsManager_->AddIndexOrSkippedMethodID(CacheType::STRING,
|
||||
std::get<ConstDataId>(input).GetId());
|
||||
inList[i + length] = circuit_.GetConstantDataGate(std::get<ConstDataId>(input).CaculateBitField(),
|
||||
GateType::StringType());
|
||||
continue;
|
||||
} else if (std::get<ConstDataId>(input).IsMethodId()) {
|
||||
tsManager_->AddMethodIndex(std::get<ConstDataId>(input).GetId());
|
||||
inList[i + length] = circuit_.GetConstantGate(MachineType::I64,
|
||||
tsManager_->AddIndexOrSkippedMethodID(CacheType::METHOD,
|
||||
std::get<ConstDataId>(input).GetId());
|
||||
} else if (std::get<ConstDataId>(input).IsClassLiteraId()) {
|
||||
tsManager_->AddIndexOrSkippedMethodID(CacheType::CLASS_LITERAL,
|
||||
std::get<ConstDataId>(input).GetId(), recordName_);
|
||||
} else if (std::get<ConstDataId>(input).IsObjectLiteralID()) {
|
||||
tsManager_->AddIndexOrSkippedMethodID(CacheType::OBJECT_LITERAL,
|
||||
std::get<ConstDataId>(input).GetId(), recordName_);
|
||||
} else if (std::get<ConstDataId>(input).IsArrayLiteralID()) {
|
||||
tsManager_->AddIndexOrSkippedMethodID(CacheType::ARRAY_LITERAL,
|
||||
std::get<ConstDataId>(input).GetId(), recordName_);
|
||||
}
|
||||
inList[i + length] = circuit_.GetConstantGate(MachineType::I64,
|
||||
std::get<ConstDataId>(input).GetId(),
|
||||
GateType::NJSValue());
|
||||
}
|
||||
} else if (std::holds_alternative<Immediate>(input)) {
|
||||
inList[i + length] = circuit_.GetConstantGate(MachineType::I64,
|
||||
std::get<Immediate>(input).GetValue(),
|
||||
@ -2066,7 +2078,7 @@ GateRef BytecodeCircuitBuilder::NewConst(const BytecodeInfo &info)
|
||||
case EcmaOpcode::LDA_STR_ID16: {
|
||||
auto input = std::get<ConstDataId>(info.inputs.at(0));
|
||||
if (input.IsStringId()) {
|
||||
tsManager_->AddStringIndex(input.GetId());
|
||||
tsManager_->AddIndexOrSkippedMethodID(CacheType::STRING, input.GetId());
|
||||
}
|
||||
gate = circuit_.GetConstantDataGate(input.CaculateBitField(), GateType::StringType());
|
||||
break;
|
||||
|
@ -170,6 +170,16 @@ public:
|
||||
return type_ == ConstDataIDType::ClassLiteralIDType;
|
||||
}
|
||||
|
||||
bool IsObjectLiteralID() const
|
||||
{
|
||||
return type_ == ConstDataIDType::ObjectLiteralIDType;
|
||||
}
|
||||
|
||||
bool IsArrayLiteralID() const
|
||||
{
|
||||
return type_ == ConstDataIDType::ArrayLiteralIDType;
|
||||
}
|
||||
|
||||
BitField CaculateBitField() const
|
||||
{
|
||||
return (static_cast<uint8_t>(type_) << TYPE_SHIFT) | id_;
|
||||
@ -515,13 +525,14 @@ public:
|
||||
const CompilationConfig* cconfig,
|
||||
bool hasTypes,
|
||||
bool enableLog,
|
||||
std::string name)
|
||||
std::string name,
|
||||
const CString &recordName)
|
||||
: tsManager_(tsManager), circuit_(cconfig->Is64Bit()), file_(jsPandaFile), pf_(jsPandaFile->GetPandaFile()),
|
||||
method_(methodLiteral), gateAcc_(&circuit_), argAcc_(&circuit_, method_, jsPandaFile),
|
||||
typeRecorder_(jsPandaFile, method_, tsManager), hasTypes_(hasTypes),
|
||||
enableLog_(enableLog), pcToBCOffset_(methodPCInfo.pcToBCOffset),
|
||||
byteCodeCurPrePc_(methodPCInfo.byteCodeCurPrePc), bytecodeBlockInfos_(methodPCInfo.bytecodeBlockInfos),
|
||||
frameStateBuilder_(this, &circuit_, methodLiteral), methodName_(name)
|
||||
frameStateBuilder_(this, &circuit_, methodLiteral), methodName_(name), recordName_(recordName)
|
||||
{
|
||||
}
|
||||
~BytecodeCircuitBuilder() = default;
|
||||
@ -704,6 +715,7 @@ private:
|
||||
std::map<std::pair<kungfu::GateRef, uint16_t>, kungfu::GateRef> resumeRegToRestore_;
|
||||
FrameStateBuilder frameStateBuilder_;
|
||||
std::string methodName_;
|
||||
const CString &recordName_;
|
||||
};
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
#endif // ECMASCRIPT_CLASS_LINKER_BYTECODE_CIRCUIT_IR_BUILDER_H
|
||||
|
@ -322,6 +322,15 @@ GateRef CircuitBuilder::TaggedIsBoolean(GateRef x)
|
||||
return BoolOr(TaggedIsFalse(x), TaggedIsTrue(x));
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::IsAOTLiteralInfo(GateRef x)
|
||||
{
|
||||
GateRef isHeapObj = TaggedIsHeapObject(x);
|
||||
GateRef objType = GetObjectType(LoadHClass(x));
|
||||
GateRef isAOTLiteralInfoObj = Equal(objType,
|
||||
Int32(static_cast<int32_t>(JSType::AOT_LITERAL_INFO)));
|
||||
return LogicAnd(isHeapObj, isAOTLiteralInfoObj);
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::TaggedGetInt(GateRef x)
|
||||
{
|
||||
x = ChangeTaggedPointerToInt64(x);
|
||||
|
@ -346,6 +346,7 @@ public:
|
||||
inline GateRef TaggedIsFalse(GateRef x);
|
||||
inline GateRef TaggedIsNull(GateRef x);
|
||||
inline GateRef TaggedIsBoolean(GateRef x);
|
||||
inline GateRef IsAOTLiteralInfo(GateRef x);
|
||||
inline GateRef TaggedGetInt(GateRef x);
|
||||
inline GateRef ToTaggedInt(GateRef x);
|
||||
inline GateRef ToTaggedIntPtr(GateRef x);
|
||||
|
@ -57,7 +57,7 @@ bool PassManager::Compile(const std::string &fileName, AOTFileGenerator &generat
|
||||
const std::string methodName(MethodLiteral::GetMethodName(jsPandaFile, method->GetMethodId()));
|
||||
if (FilterMethod(jsPandaFile, recordName, method, methodOffset, methodPCInfo)) {
|
||||
++skippedMethodNum;
|
||||
tsManager->AddSkippedMethodID(method->GetMethodId().GetOffset());
|
||||
tsManager->AddIndexOrSkippedMethodID(CacheType::SKIPPED_METHOD, method->GetMethodId().GetOffset());
|
||||
LOG_COMPILER(INFO) << " method " << methodName << " has been skipped";
|
||||
return;
|
||||
}
|
||||
@ -73,7 +73,7 @@ bool PassManager::Compile(const std::string &fileName, AOTFileGenerator &generat
|
||||
|
||||
bool hasTyps = jsPandaFile->HasTSTypes(recordName);
|
||||
BytecodeCircuitBuilder builder(jsPandaFile, method, methodPCInfo, tsManager,
|
||||
&cmpCfg, hasTyps, enableMethodLog && log_->OutputCIR(), fullName);
|
||||
&cmpCfg, hasTyps, enableMethodLog && log_->OutputCIR(), fullName, recordName);
|
||||
builder.BytecodeToCircuit();
|
||||
PassData data(builder.GetCircuit(), log_, enableMethodLog, fullName);
|
||||
PassRunner<PassData> pipeline(&data);
|
||||
|
@ -298,14 +298,34 @@ GateRef SlowPathLowering::GetObjectFromConstPool(GateRef glue, GateRef jsFunc, G
|
||||
}
|
||||
builder_.Bind(&cache);
|
||||
{
|
||||
Label isNumber(&builder_);
|
||||
builder_.Branch(builder_.TaggedIsNumber(cacheValue), &isNumber, &exit);
|
||||
builder_.Bind(&isNumber);
|
||||
{
|
||||
if (type == ConstPoolType::METHOD) {
|
||||
if (type == ConstPoolType::METHOD) {
|
||||
Label isNumber(&builder_);
|
||||
builder_.Branch(builder_.TaggedIsNumber(cacheValue), &isNumber, &exit);
|
||||
builder_.Bind(&isNumber);
|
||||
{
|
||||
result = LowerCallRuntime(glue, RTSTUB_ID(GetMethodFromCache),
|
||||
{ constPool, builder_.Int32ToTaggedInt(index) }, true);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
} else if (type == ConstPoolType::ARRAY_LITERAL) {
|
||||
Label isAOTLiteralInfo(&builder_);
|
||||
builder_.Branch(builder_.IsAOTLiteralInfo(*result), &isAOTLiteralInfo, &exit);
|
||||
builder_.Bind(&isAOTLiteralInfo);
|
||||
{
|
||||
result = LowerCallRuntime(glue, RTSTUB_ID(GetArrayLiteralFromCache),
|
||||
{ constPool, builder_.Int32ToTaggedInt(index), module }, true);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
} else if (type == ConstPoolType::OBJECT_LITERAL) {
|
||||
Label isAOTLiteralInfo(&builder_);
|
||||
builder_.Branch(builder_.IsAOTLiteralInfo(*result), &isAOTLiteralInfo, &exit);
|
||||
builder_.Bind(&isAOTLiteralInfo);
|
||||
{
|
||||
result = LowerCallRuntime(glue, RTSTUB_ID(GetObjectLiteralFromCache),
|
||||
{ constPool, builder_.Int32ToTaggedInt(index), module }, true);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
} else {
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
}
|
||||
|
@ -213,6 +213,8 @@ CString *HeapSnapshot::GenerateNodeName(TaggedObject *entry)
|
||||
return GetArrayString(TaggedArray::Cast(entry), "ConstantPool[");
|
||||
case JSType::TAGGED_DICTIONARY:
|
||||
return GetArrayString(TaggedArray::Cast(entry), "TaggedDict[");
|
||||
case JSType::AOT_LITERAL_INFO:
|
||||
return GetArrayString(TaggedArray::Cast(entry), "AOTLiteralInfo[");
|
||||
case JSType::HCLASS:
|
||||
return GetString("HiddenClass");
|
||||
case JSType::STRING:
|
||||
|
@ -422,6 +422,8 @@ CString JSHClass::DumpJSType(JSType type)
|
||||
return "CommonJSRequire";
|
||||
case JSType::METHOD:
|
||||
return "Method";
|
||||
case JSType::AOT_LITERAL_INFO:
|
||||
return "AOTLiteralInfo";
|
||||
default: {
|
||||
CString ret = "unknown type ";
|
||||
return ret + static_cast<char>(type);
|
||||
|
@ -96,6 +96,8 @@ void GlobalEnvConstants::InitRootsClass([[maybe_unused]] JSThread *thread, JSHCl
|
||||
factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::TAGGED_ARRAY));
|
||||
SetConstant(ConstantIndex::CONSTANT_POOL_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::CONSTANT_POOL));
|
||||
SetConstant(ConstantIndex::AOT_LITERAL_INFO_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::AOT_LITERAL_INFO));
|
||||
InitGlobalConstantSpecial(thread);
|
||||
SetConstant(ConstantIndex::DICTIONARY_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::TAGGED_DICTIONARY));
|
||||
|
@ -112,6 +112,7 @@ class JSThread;
|
||||
V(JSTaggedValue, MethodClass, JS_METHOD_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, ClassPrototypeClass, CLASS_PROTOTYPE_HCLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, ClassConstructorClass, CLASS_CONSTRUCTOR_HCLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, AOTLiteralInfoClass, AOT_LITERAL_INFO_CLASS_INDEX, ecma_roots_class) \
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define GLOBAL_ENV_CONSTANT_SPECIAL(V) \
|
||||
|
@ -178,6 +178,7 @@ inline size_t JSHClass::SizeFromJSHClass(TaggedObject *header)
|
||||
case JSType::TAGGED_DICTIONARY:
|
||||
case JSType::LEXICAL_ENV:
|
||||
case JSType::CONSTANT_POOL:
|
||||
case JSType::AOT_LITERAL_INFO:
|
||||
size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(),
|
||||
reinterpret_cast<TaggedArray *>(header)->GetLength());
|
||||
break;
|
||||
|
@ -235,7 +235,9 @@ class ProtoChangeDetails;
|
||||
TS_CLASS_INSTANCE_TYPE, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
TS_INTERFACE_TYPE, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
TS_ITERATOR_INSTANCE_TYPE, /* //////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
TYPE_LAST = TS_ITERATOR_INSTANCE_TYPE, /* /////////////////////////////////////////////////////////-PADDING */ \
|
||||
\
|
||||
AOT_LITERAL_INFO, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
TYPE_LAST = AOT_LITERAL_INFO, /* //////////////////////////////////////////////////////////////////-PADDING */ \
|
||||
\
|
||||
JS_FUNCTION_FIRST = JS_FUNCTION, /* ///////////////////////////////////////////////////////////////-PADDING */ \
|
||||
JS_FUNCTION_LAST = JS_ASYNC_AWAIT_STATUS_FUNCTION, /* //////////////////////////////////////////////-PADDING */\
|
||||
@ -470,6 +472,7 @@ public:
|
||||
case JSType::TAGGED_DICTIONARY:
|
||||
case JSType::LEXICAL_ENV:
|
||||
case JSType::CONSTANT_POOL:
|
||||
case JSType::AOT_LITERAL_INFO:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@ -1260,6 +1263,11 @@ public:
|
||||
return GetObjectType() == JSType::TS_ITERATOR_INSTANCE_TYPE;
|
||||
}
|
||||
|
||||
inline bool IsAOTLiteralInfo() const
|
||||
{
|
||||
return GetObjectType() == JSType::AOT_LITERAL_INFO;
|
||||
}
|
||||
|
||||
inline bool IsModuleRecord() const
|
||||
{
|
||||
JSType jsType = GetObjectType();
|
||||
|
@ -468,6 +468,11 @@ inline bool JSTaggedValue::IsConstantPool() const
|
||||
return IsHeapObject() && GetTaggedObject()->GetClass()->IsConstantPool();
|
||||
}
|
||||
|
||||
inline bool JSTaggedValue::IsAOTLiteralInfo() const
|
||||
{
|
||||
return IsHeapObject() && GetTaggedObject()->GetClass()->IsAOTLiteralInfo();
|
||||
}
|
||||
|
||||
inline bool JSTaggedValue::IsLinkedNode() const
|
||||
{
|
||||
return IsHeapObject() && GetTaggedObject()->GetClass()->IsLinkedNode();
|
||||
|
@ -493,6 +493,7 @@ public:
|
||||
bool IsStringOrSymbol() const;
|
||||
bool IsTaggedArray() const;
|
||||
bool IsConstantPool() const;
|
||||
bool IsAOTLiteralInfo() const;
|
||||
bool IsLinkedNode() const;
|
||||
bool IsRBTreeNode() const;
|
||||
bool IsNativePointer() const;
|
||||
|
@ -201,7 +201,7 @@ JSHandle<ConstantPool> PandaFileTranslator::ParseConstPool(EcmaVM *vm, const JSP
|
||||
auto string = factory->GetRawStringFromStringTable(foundStr.data, foundStr.utf16_length, foundStr.is_ascii,
|
||||
MemSpaceType::OLD_SPACE);
|
||||
constpool->SetObjectToCache(thread, value.GetConstpoolIndex(), JSTaggedValue(string));
|
||||
vm->GetTSManager()->AddStringIndex(value.GetConstpoolIndex());
|
||||
vm->GetTSManager()->AddIndexOrSkippedMethodID(CacheType::STRING, value.GetConstpoolIndex());
|
||||
} else if (value.GetConstpoolType() == ConstPoolType::BASE_FUNCTION) {
|
||||
MethodLiteral *methodLiteral = jsPandaFile->FindMethodLiteral(it.first);
|
||||
ASSERT(methodLiteral != nullptr);
|
||||
|
@ -164,11 +164,14 @@ public:
|
||||
const ConstantPool *taggedPool = ConstantPool::Cast(constpool.GetTaggedObject());
|
||||
auto val = taggedPool->Get(index);
|
||||
JSPandaFile *jsPandaFile = taggedPool->GetJSPandaFile();
|
||||
bool isLoadedAOT = jsPandaFile->IsLoadedAOT();
|
||||
uint32_t entryIndex = 0;
|
||||
|
||||
// For AOT
|
||||
bool isLoadedAOT = jsPandaFile->IsLoadedAOT();
|
||||
bool hasEntryIndex = false;
|
||||
uint32_t entryIndex = 0;
|
||||
if (isLoadedAOT && val.IsInt()) {
|
||||
entryIndex = static_cast<uint32_t>(val.GetInt());
|
||||
hasEntryIndex = true;
|
||||
val = JSTaggedValue::Hole();
|
||||
}
|
||||
|
||||
@ -186,7 +189,7 @@ public:
|
||||
|
||||
JSHandle<ConstantPool> newConstpool = vm->FindOrCreateConstPool(jsPandaFile, id);
|
||||
method->SetConstantPool(thread, newConstpool);
|
||||
if (isLoadedAOT) {
|
||||
if (isLoadedAOT && hasEntryIndex) {
|
||||
vm->GetAOTFileManager()->SetAOTFuncEntry(jsPandaFile, *method, entryIndex);
|
||||
}
|
||||
|
||||
@ -202,11 +205,14 @@ public:
|
||||
{
|
||||
auto val = constpool->Get(index);
|
||||
JSPandaFile *jsPandaFile = constpool->GetJSPandaFile();
|
||||
bool isLoadedAOT = jsPandaFile->IsLoadedAOT();
|
||||
uint32_t entryIndex = 0;
|
||||
|
||||
// For AOT
|
||||
bool isLoadedAOT = jsPandaFile->IsLoadedAOT();
|
||||
bool hasEntryIndex = false;
|
||||
uint32_t entryIndex = 0;
|
||||
if (isLoadedAOT && val.IsInt()) {
|
||||
entryIndex = static_cast<uint32_t>(val.GetInt());
|
||||
hasEntryIndex = true;
|
||||
val = JSTaggedValue::Hole();
|
||||
}
|
||||
|
||||
@ -223,7 +229,7 @@ public:
|
||||
|
||||
JSHandle<ConstantPool> newConstpool = vm->FindOrCreateConstPool(jsPandaFile, id);
|
||||
method->SetConstantPool(thread, newConstpool);
|
||||
if (isLoadedAOT) {
|
||||
if (isLoadedAOT && hasEntryIndex) {
|
||||
vm->GetAOTFileManager()->SetAOTFuncEntry(jsPandaFile, *method, entryIndex);
|
||||
}
|
||||
|
||||
@ -238,15 +244,27 @@ public:
|
||||
static JSTaggedValue GetClassLiteralFromCache(JSThread *thread, JSHandle<ConstantPool> constpool,
|
||||
uint32_t literal, CString entry)
|
||||
{
|
||||
EcmaHandleScope handleScope(thread);
|
||||
auto val = constpool->Get(literal);
|
||||
if (val.IsHole()) {
|
||||
EcmaHandleScope handleScope(thread);
|
||||
JSPandaFile *jsPandaFile = constpool->GetJSPandaFile();
|
||||
|
||||
JSPandaFile *jsPandaFile = constpool->GetJSPandaFile();
|
||||
// For AOT
|
||||
bool isLoadedAOT = jsPandaFile->IsLoadedAOT();
|
||||
JSHandle<AOTLiteralInfo> entryIndexes(thread, JSTaggedValue::Undefined());
|
||||
if (isLoadedAOT && val.IsAOTLiteralInfo()) {
|
||||
entryIndexes = JSHandle<AOTLiteralInfo>(thread, val);
|
||||
val = JSTaggedValue::Hole();
|
||||
}
|
||||
|
||||
if (val.IsHole()) {
|
||||
EcmaVM *vm = thread->GetEcmaVM();
|
||||
ASSERT(jsPandaFile->IsNewVersion());
|
||||
panda_file::File::EntityId literalId = constpool->GetEntityId(literal);
|
||||
JSHandle<TaggedArray> literalArray = LiteralDataExtractor::GetDatasIgnoreType(
|
||||
thread, jsPandaFile, literalId, JSHandle<JSTaggedValue>(constpool), entry);
|
||||
if (isLoadedAOT && !entryIndexes.GetTaggedValue().IsUndefined()) {
|
||||
vm->GetAOTFileManager()->SetAOTFuncEntryForLiteral(jsPandaFile, *literalArray, *entryIndexes);
|
||||
}
|
||||
|
||||
val = literalArray.GetTaggedValue();
|
||||
constpool->Set(thread, literal, val);
|
||||
@ -260,14 +278,23 @@ public:
|
||||
static JSTaggedValue GetLiteralFromCache(JSThread *thread, JSTaggedValue constpool, uint32_t index, CString entry)
|
||||
{
|
||||
static_assert(type == ConstPoolType::OBJECT_LITERAL || type == ConstPoolType::ARRAY_LITERAL);
|
||||
EcmaHandleScope handleScope(thread);
|
||||
const ConstantPool *taggedPool = ConstantPool::Cast(constpool.GetTaggedObject());
|
||||
|
||||
auto val = taggedPool->Get(index);
|
||||
if (val.IsHole()) {
|
||||
EcmaHandleScope handleScope(thread);
|
||||
JSPandaFile *jsPandaFile = taggedPool->GetJSPandaFile();
|
||||
|
||||
// For AOT
|
||||
bool isLoadedAOT = jsPandaFile->IsLoadedAOT();
|
||||
JSHandle<AOTLiteralInfo> entryIndexes(thread, JSTaggedValue::Undefined());
|
||||
if (isLoadedAOT && val.IsAOTLiteralInfo()) {
|
||||
entryIndexes = JSHandle<AOTLiteralInfo>(thread, val);
|
||||
val = JSTaggedValue::Hole();
|
||||
}
|
||||
|
||||
if (val.IsHole()) {
|
||||
EcmaVM *vm = thread->GetEcmaVM();
|
||||
JSHandle<ConstantPool> constpoolHandle(thread, constpool);
|
||||
JSPandaFile *jsPandaFile = taggedPool->GetJSPandaFile();
|
||||
|
||||
ASSERT(jsPandaFile->IsNewVersion());
|
||||
panda_file::File::EntityId id = taggedPool->GetEntityId(index);
|
||||
|
||||
@ -291,6 +318,9 @@ public:
|
||||
valueHandle.Update(elements->Get(i + 1));
|
||||
JSObject::DefinePropertyByLiteral(thread, obj, key, valueHandle);
|
||||
}
|
||||
if (isLoadedAOT && !entryIndexes.GetTaggedValue().IsUndefined()) {
|
||||
vm->GetAOTFileManager()->SetAOTFuncEntryForLiteral(jsPandaFile, *properties, *entryIndexes);
|
||||
}
|
||||
val = obj.GetTaggedValue();
|
||||
break;
|
||||
}
|
||||
@ -300,6 +330,9 @@ public:
|
||||
uint32_t length = literal->GetLength();
|
||||
JSHandle<JSArray> arr(JSArray::ArrayCreate(thread, JSTaggedNumber(length)));
|
||||
arr->SetElements(thread, literal);
|
||||
if (isLoadedAOT && !entryIndexes.GetTaggedValue().IsUndefined()) {
|
||||
vm->GetAOTFileManager()->SetAOTFuncEntryForLiteral(jsPandaFile, *literal, *entryIndexes);
|
||||
}
|
||||
val = arr.GetTaggedValue();
|
||||
break;
|
||||
}
|
||||
|
@ -330,6 +330,7 @@ public:
|
||||
case JSType::TAGGED_DICTIONARY:
|
||||
case JSType::TEMPLATE_MAP:
|
||||
case JSType::LEXICAL_ENV:
|
||||
case JSType::AOT_LITERAL_INFO:
|
||||
TaggedArray::Cast(object)->VisitRangeSlot(visitor);
|
||||
break;
|
||||
case JSType::CONSTANT_POOL:
|
||||
|
@ -122,6 +122,7 @@
|
||||
#include "ecmascript/ts_types/ts_obj_layout_info.h"
|
||||
#include "ecmascript/ts_types/ts_type.h"
|
||||
#include "ecmascript/ts_types/ts_type_table.h"
|
||||
#include "ecmascript/aot_file_manager.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
using Error = builtins::BuiltinsError;
|
||||
@ -3782,4 +3783,16 @@ JSHandle<AsyncGeneratorRequest> ObjectFactory::NewAsyncGeneratorRequest()
|
||||
obj->SetCapability(thread_, JSTaggedValue::Undefined());
|
||||
return obj;
|
||||
}
|
||||
|
||||
JSHandle<AOTLiteralInfo> ObjectFactory::NewAOTLiteralInfo(uint32_t length, JSTaggedValue initVal)
|
||||
{
|
||||
NewObjectHook();
|
||||
size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
|
||||
auto header = heap_->AllocateYoungOrHugeObject(
|
||||
JSHClass::Cast(thread_->GlobalConstants()->GetAOTLiteralInfoClass().GetTaggedObject()), size);
|
||||
|
||||
JSHandle<AOTLiteralInfo> aotLiteralInfo(thread_, header);
|
||||
aotLiteralInfo->InitializeWithSpecialValue(initVal, length);
|
||||
return aotLiteralInfo;
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -164,6 +164,7 @@ class ProtoChangeDetails;
|
||||
class ProfileTypeInfo;
|
||||
class MachineCode;
|
||||
class ClassInfoExtractor;
|
||||
class AOTLiteralInfo;
|
||||
|
||||
enum class CompletionRecordType : uint8_t;
|
||||
enum class PrimitiveType : uint8_t;
|
||||
@ -559,6 +560,9 @@ public:
|
||||
// ---------------------------------New objects used internally--------------------------------------
|
||||
JSHandle<JSArray> NewJSStableArrayWithElements(const JSHandle<TaggedArray> &elements);
|
||||
|
||||
// ---------------------------------AOT snapshot-----------------------------------------------------
|
||||
JSHandle<AOTLiteralInfo> NewAOTLiteralInfo(uint32_t length, JSTaggedValue initVal = JSTaggedValue::Hole());
|
||||
|
||||
private:
|
||||
friend class GlobalEnv;
|
||||
friend class GlobalEnvConstants;
|
||||
|
@ -787,7 +787,8 @@ HWTEST_F_L0(EcmaDumpTest, HeapProfileDump)
|
||||
break;
|
||||
}
|
||||
case JSType::TAGGED_ARRAY:
|
||||
case JSType::LEXICAL_ENV: {
|
||||
case JSType::LEXICAL_ENV:
|
||||
case JSType::AOT_LITERAL_INFO: {
|
||||
JSHandle<TaggedArray> taggedArray = factory->NewTaggedArray(4);
|
||||
DUMP_FOR_HANDLE(taggedArray)
|
||||
break;
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "ecmascript/ts_types/ts_type_table.h"
|
||||
#include "libpandafile/file-inl.h"
|
||||
#include "libpandafile/method_data_accessor-inl.h"
|
||||
#include "ecmascript/aot_file_manager.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
void TSManager::DecodeTSTypes(const JSPandaFile *jsPandaFile)
|
||||
@ -381,11 +382,7 @@ void TSManager::Iterate(const RootVisitor &v)
|
||||
{
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&globalModuleTable_)));
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&constantPoolInfos_)));
|
||||
|
||||
uint64_t hclassCacheSize = hclassCache_.size();
|
||||
for (uint64_t i = 0; i < hclassCacheSize; i++) {
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&(hclassCache_.data()[i]))));
|
||||
}
|
||||
currentABCInfo_.Iterate(v);
|
||||
}
|
||||
|
||||
GlobalTSTypeRef TSManager::GetImportTypeTargetGT(GlobalTSTypeRef gt) const
|
||||
@ -622,76 +619,149 @@ std::string TSManager::GetPrimitiveStr(const GlobalTSTypeRef >) const
|
||||
|
||||
void TSManager::CreateConstantPoolInfos(size_t size)
|
||||
{
|
||||
ObjectFactory *factory = vm_->GetFactory();
|
||||
constantPoolInfosSize_ = 0;
|
||||
constantPoolInfos_ = factory->NewTaggedArray(size * CONSTANTPOOL_INFOS_ITEM_SIZE).GetTaggedValue();
|
||||
constantPoolInfos_ = factory_->NewTaggedArray(size * CONSTANTPOOL_INFOS_ITEM_SIZE).GetTaggedValue();
|
||||
}
|
||||
|
||||
void TSManager::CollectConstantPoolInfo(const JSPandaFile* jsPandaFile)
|
||||
{
|
||||
JSThread *thread = vm_->GetJSThread();
|
||||
JSHandle<TaggedArray> constantPoolInfos = GetConstantPoolInfos();
|
||||
ASSERT(constantPoolInfosSize_ < constantPoolInfos->GetLength());
|
||||
|
||||
std::string keyStr = std::to_string(jsPandaFile->GetFileUniqId());
|
||||
JSHandle<EcmaString> key = vm_->GetFactory()->NewFromStdString(keyStr);
|
||||
constantPoolInfos->Set(thread, constantPoolInfosSize_++, key);
|
||||
constantPoolInfos->Set(thread_, constantPoolInfosSize_++, key);
|
||||
auto value = GenerateConstantPoolInfo(jsPandaFile);
|
||||
constantPoolInfos->Set(thread, constantPoolInfosSize_++, value);
|
||||
constantPoolInfos->Set(thread_, constantPoolInfosSize_++, value);
|
||||
}
|
||||
|
||||
JSTaggedValue TSManager::GenerateConstantPoolInfo(const JSPandaFile* jsPandaFile)
|
||||
{
|
||||
ObjectFactory *factory = vm_->GetFactory();
|
||||
JSThread *thread = vm_->GetJSThread();
|
||||
JSHandle<ConstantPool> constantPool(thread, vm_->FindConstpool(jsPandaFile, 0));
|
||||
|
||||
JSHandle<ConstantPool> constantPool(thread_, vm_->FindConstpool(jsPandaFile, 0));
|
||||
uint32_t constantPoolSize = constantPool->GetCacheLength();
|
||||
uint32_t hclassCacheSize = hclassCache_.size();
|
||||
JSHandle<ConstantPool> constantPoolInfo = factory->NewConstantPool(constantPoolSize + hclassCacheSize);
|
||||
uint32_t hclassCacheSize = currentABCInfo_.GetHClassCacheSize();
|
||||
JSHandle<ConstantPool> constantPoolInfo = factory_->NewConstantPool(constantPoolSize + hclassCacheSize);
|
||||
LOG_COMPILER(INFO) << "snapshot: constantPoolSize: " << constantPoolSize;
|
||||
LOG_COMPILER(INFO) << "snapshot: hclassCacheSize: " << hclassCacheSize;
|
||||
recordMethodInfos_.emplace_back(std::vector<std::pair<uint32_t, uint32_t>>{});
|
||||
snapshotRecordInfo_.InitNewRecordInfo();
|
||||
auto &recordMethodInfo = snapshotRecordInfo_.GetRecordMethodInfos().back();
|
||||
auto &recordLiteralInfo = snapshotRecordInfo_.GetRecordLiteralInfos().back();
|
||||
|
||||
IterateConstantPoolCache(CacheType::STRING, [thread, constantPool, constantPoolInfo] (uint32_t index) {
|
||||
auto string = ConstantPool::GetStringFromCache(thread, constantPool.GetTaggedValue(), index);
|
||||
constantPoolInfo->SetObjectToCache(thread, index, string);
|
||||
IterateConstantPoolCache(CacheType::STRING, [this, constantPool, constantPoolInfo] (uint32_t index) {
|
||||
auto string = ConstantPool::GetStringFromCache(thread_, constantPool.GetTaggedValue(), index);
|
||||
constantPoolInfo->SetObjectToCache(thread_, index, string);
|
||||
});
|
||||
|
||||
IterateConstantPoolCache(CacheType::METHOD, [this, constantPool, jsPandaFile] (uint32_t index) {
|
||||
IterateConstantPoolCache(CacheType::METHOD, [this, constantPool, jsPandaFile, &recordMethodInfo] (uint32_t index) {
|
||||
panda_file::File::IndexHeader *indexHeader = constantPool->GetIndexHeader();
|
||||
auto pf = jsPandaFile->GetPandaFile();
|
||||
Span<const panda_file::File::EntityId> indexs = pf->GetMethodIndex(indexHeader);
|
||||
panda_file::File::EntityId methodID = indexs[index];
|
||||
if (skippedMethodIDCache_.find(methodID.GetOffset()) == skippedMethodIDCache_.end()) {
|
||||
recordMethodInfos_.back().emplace_back(std::make_pair(methodID.GetOffset(), index));
|
||||
if (!currentABCInfo_.IsSkippedMethod(methodID.GetOffset())) {
|
||||
auto &methodInfos = recordMethodInfo.methodInfos_;
|
||||
methodInfos.emplace_back(std::make_pair(index, methodID.GetOffset()));
|
||||
}
|
||||
});
|
||||
|
||||
IterateHClassCaches([thread, constantPoolSize, constantPoolInfo] (JSTaggedType hclass, uint32_t index) {
|
||||
constantPoolInfo->SetObjectToCache(thread, constantPoolSize + index, JSTaggedValue(hclass));
|
||||
IterateLiteralCaches(CacheType::CLASS_LITERAL, [this, constantPool, &recordLiteralInfo]
|
||||
(std::pair<CString, uint32_t> item) {
|
||||
const CString &recordName = item.first;
|
||||
uint32_t index = item.second;
|
||||
auto literalObj = ConstantPool::GetClassLiteralFromCache(thread_, constantPool, index, recordName);
|
||||
JSHandle<TaggedArray> literalHandle(thread_, literalObj);
|
||||
CollectLiteralInfo(literalHandle, index, recordLiteralInfo);
|
||||
});
|
||||
|
||||
IterateLiteralCaches(CacheType::OBJECT_LITERAL, [this, jsPandaFile, constantPool, &recordLiteralInfo]
|
||||
(std::pair<CString, uint32_t> item) {
|
||||
const CString &recordName = item.first;
|
||||
uint32_t index = item.second;
|
||||
panda_file::File::EntityId id = constantPool->GetEntityId(index);
|
||||
JSMutableHandle<TaggedArray> elements(thread_, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<TaggedArray> properties(thread_, JSTaggedValue::Undefined());
|
||||
LiteralDataExtractor::ExtractObjectDatas(
|
||||
thread_, jsPandaFile, id, elements, properties, JSHandle<JSTaggedValue>(constantPool), recordName);
|
||||
CollectLiteralInfo(properties, index, recordLiteralInfo);
|
||||
});
|
||||
|
||||
IterateLiteralCaches(CacheType::ARRAY_LITERAL, [this, jsPandaFile, constantPool, &recordLiteralInfo]
|
||||
(std::pair<CString, uint32_t> item) {
|
||||
const CString &recordName = item.first;
|
||||
uint32_t index = item.second;
|
||||
panda_file::File::EntityId id = constantPool->GetEntityId(index);
|
||||
JSHandle<TaggedArray> literal = LiteralDataExtractor::GetDatasIgnoreType(
|
||||
thread_, jsPandaFile, id, JSHandle<JSTaggedValue>(constantPool), recordName);
|
||||
CollectLiteralInfo(literal, index, recordLiteralInfo);
|
||||
});
|
||||
|
||||
IterateHClassCaches([this, constantPoolSize, constantPoolInfo] (JSTaggedType hclass, uint32_t index) {
|
||||
constantPoolInfo->SetObjectToCache(thread_, constantPoolSize + index, JSTaggedValue(hclass));
|
||||
});
|
||||
|
||||
return constantPoolInfo.GetTaggedValue();
|
||||
}
|
||||
|
||||
void TSManager::CollectLiteralInfo(JSHandle<TaggedArray> array, uint32_t constantPoolIndex,
|
||||
SnapshotRecordInfo::RecordLiteralInfo &recordLiteralInfo)
|
||||
{
|
||||
JSMutableHandle<JSTaggedValue> valueHandle(thread_, JSTaggedValue::Undefined());
|
||||
uint32_t len = array->GetLength();
|
||||
SnapshotRecordInfo::RecordLiteralInfo::LiteralMethods methodIDs;
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
valueHandle.Update(array->Get(i));
|
||||
if (valueHandle->IsJSFunction()) {
|
||||
auto methodID = JSHandle<JSFunction>(valueHandle)->GetCallTarget()->GetMethodId().GetOffset();
|
||||
if (currentABCInfo_.IsSkippedMethod(methodID)) {
|
||||
methodIDs.emplace_back(std::make_pair(true, methodID));
|
||||
} else {
|
||||
methodIDs.emplace_back(std::make_pair(false, methodID));
|
||||
}
|
||||
}
|
||||
}
|
||||
recordLiteralInfo.literalInfos_.emplace_back(std::make_pair(constantPoolIndex, methodIDs));
|
||||
}
|
||||
|
||||
void TSManager::ResolveConstantPoolInfo(const std::map<std::pair<uint32_t, uint32_t>, uint32_t> &methodToEntryIndexMap)
|
||||
{
|
||||
ObjectFactory *factory = vm_->GetFactory();
|
||||
JSHandle<TaggedArray> constantPoolInfosHandle(thread_, constantPoolInfos_);
|
||||
JSMutableHandle<ConstantPool> currentCPInfo(thread_, JSTaggedValue::Undefined());
|
||||
uint32_t size = recordMethodInfos_.size();
|
||||
uint32_t size = snapshotRecordInfo_.GetSize();
|
||||
const auto &recordMethodInfos = snapshotRecordInfo_.GetRecordMethodInfos();
|
||||
const auto &recordLiteralInfos = snapshotRecordInfo_.GetRecordLiteralInfos();
|
||||
|
||||
for (uint32_t i = 0; i < size; ++i) {
|
||||
JSTaggedValue constantPoolInfo = constantPoolInfosHandle->Get(i * CONSTANTPOOL_INFOS_ITEM_SIZE + 1);
|
||||
currentCPInfo.Update(constantPoolInfo);
|
||||
const std::vector<std::pair<uint32_t, uint32_t>> &methodInfo = recordMethodInfos_[i];
|
||||
for (auto item: methodInfo) {
|
||||
const SnapshotRecordInfo::RecordMethodInfo &recordMethodInfo = recordMethodInfos[i];
|
||||
for (auto item: recordMethodInfo.methodInfos_) {
|
||||
uint32_t moduleIndex = i;
|
||||
uint32_t methodID = item.first;
|
||||
uint32_t constantPoolIndex = item.second;
|
||||
uint32_t constantPoolIndex = item.first;
|
||||
uint32_t methodID = item.second;
|
||||
LOG_COMPILER(INFO) << "snapshot: resolve function method ID: " << methodID;
|
||||
uint32_t entryIndex = methodToEntryIndexMap.at(std::make_pair(moduleIndex, methodID));
|
||||
currentCPInfo->SetObjectToCache(thread_, constantPoolIndex, JSTaggedValue(entryIndex));
|
||||
}
|
||||
const SnapshotRecordInfo::RecordLiteralInfo &recordLiteralInfo = recordLiteralInfos[i];
|
||||
for (auto item: recordLiteralInfo.literalInfos_) {
|
||||
uint32_t moduleIndex = i;
|
||||
uint32_t constantPoolIndex = item.first;
|
||||
const SnapshotRecordInfo::RecordLiteralInfo::LiteralMethods &methodIDs = item.second;
|
||||
uint32_t len = methodIDs.size();
|
||||
JSHandle<AOTLiteralInfo> aotLiteralInfo = factory->NewAOTLiteralInfo(len);
|
||||
for (uint32_t pos = 0; pos < len; ++pos) {
|
||||
bool isSkipped = methodIDs[pos].first;
|
||||
uint32_t methodID = methodIDs[pos].second;
|
||||
if (isSkipped) {
|
||||
aotLiteralInfo->Set(thread_, pos, JSTaggedValue(-1));
|
||||
} else {
|
||||
LOG_COMPILER(INFO) << "snapshot: resolve function method ID: " << methodID;
|
||||
uint32_t entryIndex = methodToEntryIndexMap.at(std::make_pair(moduleIndex, methodID));
|
||||
aotLiteralInfo->Set(thread_, pos, JSTaggedValue(entryIndex));
|
||||
}
|
||||
}
|
||||
currentCPInfo->SetObjectToCache(thread_, constantPoolIndex, aotLiteralInfo.GetTaggedValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -969,4 +1039,127 @@ JSHandle<TSTypeTable> TSModuleTable::GenerateBuiltinsTypeTable(JSThread *thread)
|
||||
TSTypeTable::GenerateTypeTable(thread, jsPandaFile, builtinsRecordName, BUILTINS_TABLE_ID, vec);
|
||||
return builtinsTypeTable;
|
||||
}
|
||||
|
||||
void ABCInfo::Iterate(const RootVisitor &v)
|
||||
{
|
||||
uint64_t hclassCacheSize = hclassCache_.size();
|
||||
for (uint64_t i = 0; i < hclassCacheSize; i++) {
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&(hclassCache_.data()[i]))));
|
||||
}
|
||||
}
|
||||
|
||||
void ABCInfo::AddStringIndex(uint32_t index)
|
||||
{
|
||||
if (stringIndexCache_.find(index) != stringIndexCache_.end()) {
|
||||
return;
|
||||
}
|
||||
stringIndexCache_.insert(index);
|
||||
}
|
||||
|
||||
void ABCInfo::AddMethodIndex(uint32_t index)
|
||||
{
|
||||
if (methodIndexCache_.find(index) != methodIndexCache_.end()) {
|
||||
return;
|
||||
}
|
||||
methodIndexCache_.insert(index);
|
||||
}
|
||||
|
||||
void ABCInfo::AddSkippedMethodID(uint32_t methodID)
|
||||
{
|
||||
if (skippedMethodIDCache_.find(methodID) != skippedMethodIDCache_.end()) {
|
||||
return;
|
||||
}
|
||||
skippedMethodIDCache_.insert(methodID);
|
||||
}
|
||||
|
||||
void ABCInfo::AddClassLiteralIndex(const CString &recordName, uint32_t index)
|
||||
{
|
||||
auto item = std::make_pair(recordName, index);
|
||||
if (classLiteralCache_.find(item) != classLiteralCache_.end()) {
|
||||
return;
|
||||
}
|
||||
classLiteralCache_.insert(item);
|
||||
}
|
||||
|
||||
void ABCInfo::AddObjectLiteralIndex(const CString &recordName, uint32_t index)
|
||||
{
|
||||
auto item = std::make_pair(recordName, index);
|
||||
if (objectLiteralCache_.find(item) != objectLiteralCache_.end()) {
|
||||
return;
|
||||
}
|
||||
objectLiteralCache_.insert(item);
|
||||
}
|
||||
|
||||
void ABCInfo::AddArrayLiteralIndex(const CString &recordName, uint32_t index)
|
||||
{
|
||||
auto item = std::make_pair(recordName, index);
|
||||
if (arrayLiteralCache_.find(item) != arrayLiteralCache_.end()) {
|
||||
return;
|
||||
}
|
||||
arrayLiteralCache_.insert(item);
|
||||
}
|
||||
|
||||
void ABCInfo::AddIndexOrSkippedMethodID(CacheType type, uint32_t index, const CString &recordName)
|
||||
{
|
||||
switch (type) {
|
||||
case CacheType::STRING: {
|
||||
AddStringIndex(index);
|
||||
break;
|
||||
}
|
||||
case CacheType::METHOD: {
|
||||
AddMethodIndex(index);
|
||||
break;
|
||||
}
|
||||
case CacheType::SKIPPED_METHOD: {
|
||||
AddSkippedMethodID(index);
|
||||
break;
|
||||
}
|
||||
case CacheType::CLASS_LITERAL: {
|
||||
AddClassLiteralIndex(recordName, index);
|
||||
break;
|
||||
}
|
||||
case CacheType::OBJECT_LITERAL: {
|
||||
AddObjectLiteralIndex(recordName, index);
|
||||
break;
|
||||
}
|
||||
case CacheType::ARRAY_LITERAL: {
|
||||
AddArrayLiteralIndex(recordName, index);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
const std::set<uint32_t>& ABCInfo::GetStringOrMethodCache(CacheType type) const
|
||||
{
|
||||
switch (type) {
|
||||
case CacheType::STRING: {
|
||||
return stringIndexCache_;
|
||||
}
|
||||
case CacheType::METHOD: {
|
||||
return methodIndexCache_;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
const std::set<std::pair<CString, uint32_t>>& ABCInfo::GetLiteralCache(CacheType type) const
|
||||
{
|
||||
switch (type) {
|
||||
case CacheType::CLASS_LITERAL: {
|
||||
return classLiteralCache_;
|
||||
}
|
||||
case CacheType::OBJECT_LITERAL: {
|
||||
return objectLiteralCache_;
|
||||
}
|
||||
case CacheType::ARRAY_LITERAL: {
|
||||
return arrayLiteralCache_;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -32,6 +32,120 @@ enum class MTableIdx : uint8_t {
|
||||
enum class CacheType : uint8_t {
|
||||
STRING = 0,
|
||||
METHOD,
|
||||
SKIPPED_METHOD,
|
||||
CLASS_LITERAL,
|
||||
OBJECT_LITERAL,
|
||||
ARRAY_LITERAL,
|
||||
};
|
||||
|
||||
class ABCInfo {
|
||||
public:
|
||||
void PUBLIC_API AddIndexOrSkippedMethodID(CacheType type, uint32_t index, const CString &recordName);
|
||||
|
||||
const std::set<uint32_t>& GetStringOrMethodCache(CacheType type) const;
|
||||
|
||||
const std::set<std::pair<CString, uint32_t>>& GetLiteralCache(CacheType type) const;
|
||||
|
||||
void Iterate(const RootVisitor &v);
|
||||
|
||||
CVector<JSTaggedType>& GetHClassCache()
|
||||
{
|
||||
return hclassCache_;
|
||||
}
|
||||
|
||||
void AddHClass(JSTaggedType hclass)
|
||||
{
|
||||
hclassCache_.emplace_back(hclass);
|
||||
}
|
||||
|
||||
bool IsSkippedMethod(uint32_t methodID)
|
||||
{
|
||||
if (skippedMethodIDCache_.find(methodID) == skippedMethodIDCache_.end()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t GetHClassCacheSize()
|
||||
{
|
||||
return hclassCache_.size();
|
||||
}
|
||||
|
||||
void ClearCaches()
|
||||
{
|
||||
stringIndexCache_.clear();
|
||||
methodIndexCache_.clear();
|
||||
skippedMethodIDCache_.clear();
|
||||
classLiteralCache_.clear();
|
||||
objectLiteralCache_.clear();
|
||||
arrayLiteralCache_.clear();
|
||||
hclassCache_.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
void AddStringIndex(uint32_t index);
|
||||
|
||||
void AddMethodIndex(uint32_t index);
|
||||
|
||||
void AddSkippedMethodID(uint32_t methodID);
|
||||
|
||||
void AddClassLiteralIndex(const CString &recordName, uint32_t index);
|
||||
|
||||
void AddObjectLiteralIndex(const CString &recordName, uint32_t index);
|
||||
|
||||
void AddArrayLiteralIndex(const CString &recordName, uint32_t index);
|
||||
|
||||
// constantpool index
|
||||
std::set<uint32_t> stringIndexCache_ {};
|
||||
std::set<uint32_t> methodIndexCache_ {};
|
||||
std::set<uint32_t> skippedMethodIDCache_ {};
|
||||
|
||||
// (recordName, constantpool index)
|
||||
std::set<std::pair<CString, uint32_t>> classLiteralCache_ {};
|
||||
std::set<std::pair<CString, uint32_t>> objectLiteralCache_ {};
|
||||
std::set<std::pair<CString, uint32_t>> arrayLiteralCache_ {};
|
||||
|
||||
// store hclass of each abc which produced from static type info
|
||||
CVector<JSTaggedType> hclassCache_ {};
|
||||
};
|
||||
|
||||
class SnapshotRecordInfo {
|
||||
public:
|
||||
struct RecordLiteralInfo {
|
||||
using LiteralMethods = std::vector<std::pair<bool, uint32_t>>;
|
||||
using LiteralInfo = std::pair<uint32_t, LiteralMethods>;
|
||||
std::vector<LiteralInfo> literalInfos_;
|
||||
};
|
||||
|
||||
struct RecordMethodInfo {
|
||||
std::vector<std::pair<uint32_t, uint32_t>> methodInfos_;
|
||||
};
|
||||
|
||||
void InitNewRecordInfo()
|
||||
{
|
||||
recordMethodInfos_.emplace_back(RecordMethodInfo{});
|
||||
recordLiteralInfos_.emplace_back(RecordLiteralInfo{});
|
||||
++size_;
|
||||
}
|
||||
|
||||
uint32_t GetSize()
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
std::vector<RecordMethodInfo>& GetRecordMethodInfos()
|
||||
{
|
||||
return recordMethodInfos_;
|
||||
}
|
||||
std::vector<RecordLiteralInfo>& GetRecordLiteralInfos()
|
||||
{
|
||||
return recordLiteralInfos_;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t size_ = 0;
|
||||
std::vector<RecordMethodInfo> recordMethodInfos_ {};
|
||||
std::vector<RecordLiteralInfo> recordLiteralInfos_ {};
|
||||
};
|
||||
|
||||
class TSModuleTable : public TaggedArray {
|
||||
@ -186,7 +300,7 @@ public:
|
||||
GlobalTSTypeRef PUBLIC_API GetOrCreateUnionType(CVector<GlobalTSTypeRef> unionTypeVec);
|
||||
|
||||
uint32_t PUBLIC_API GetFunctionTypeLength(GlobalTSTypeRef gt) const;
|
||||
|
||||
|
||||
GlobalTSTypeRef PUBLIC_API GetOrCreateTSIteratorInstanceType(TSRuntimeType runtimeType, GlobalTSTypeRef elementGt);
|
||||
|
||||
GlobalTSTypeRef PUBLIC_API GetIteratorInstanceElementGt(GlobalTSTypeRef gt) const;
|
||||
@ -274,36 +388,14 @@ public:
|
||||
|
||||
JSHandle<ConstantPool> PUBLIC_API RestoreConstantPool(const JSPandaFile* pf);
|
||||
|
||||
void PUBLIC_API AddIndexOrSkippedMethodID(CacheType type, uint32_t index, const CString &recordName="")
|
||||
{
|
||||
currentABCInfo_.AddIndexOrSkippedMethodID(type, index, recordName);
|
||||
}
|
||||
|
||||
void ClearCaches()
|
||||
{
|
||||
stringIndexCache_.clear();
|
||||
methodIndexCache_.clear();
|
||||
skippedMethodIDCache_.clear();
|
||||
hclassCache_.clear();
|
||||
}
|
||||
|
||||
void AddStringIndex(uint32_t index)
|
||||
{
|
||||
if (stringIndexCache_.find(index) != stringIndexCache_.end()) {
|
||||
return;
|
||||
}
|
||||
stringIndexCache_.insert(index);
|
||||
}
|
||||
|
||||
void AddMethodIndex(uint32_t index)
|
||||
{
|
||||
if (methodIndexCache_.find(index) != methodIndexCache_.end()) {
|
||||
return;
|
||||
}
|
||||
methodIndexCache_.insert(index);
|
||||
}
|
||||
|
||||
void AddSkippedMethodID(uint32_t methodID)
|
||||
{
|
||||
if (skippedMethodIDCache_.find(methodID) != skippedMethodIDCache_.end()) {
|
||||
return;
|
||||
}
|
||||
skippedMethodIDCache_.insert(methodID);
|
||||
currentABCInfo_.ClearCaches();
|
||||
}
|
||||
|
||||
EcmaVM *GetEcmaVM() const
|
||||
@ -412,10 +504,14 @@ private:
|
||||
|
||||
JSTaggedValue GenerateConstantPoolInfo(const JSPandaFile* jsPandaFile);
|
||||
|
||||
void CollectLiteralInfo(JSHandle<TaggedArray> array, uint32_t constantPoolIndex,
|
||||
SnapshotRecordInfo::RecordLiteralInfo &recordLiteralInfo);
|
||||
|
||||
int BinarySearch(uint32_t target, uint32_t itemSize, bool findLeftBound = true);
|
||||
|
||||
void AddHClassInCompilePhase(GlobalTSTypeRef gt, JSTaggedValue hclass, uint32_t constantPoolLen)
|
||||
{
|
||||
CVector<JSTaggedType> &hclassCache_ = currentABCInfo_.GetHClassCache();
|
||||
hclassCache_.emplace_back(hclass.GetRawData());
|
||||
classTypeIhcIndexMap_[gt] = constantPoolLen + hclassCache_.size() - 1;
|
||||
}
|
||||
@ -423,29 +519,27 @@ private:
|
||||
template <class Callback>
|
||||
void IterateConstantPoolCache(CacheType type, const Callback &cb)
|
||||
{
|
||||
switch (type) {
|
||||
case CacheType::STRING: {
|
||||
for (auto item: stringIndexCache_) {
|
||||
cb(item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CacheType::METHOD: {
|
||||
for (auto item: methodIndexCache_) {
|
||||
cb(item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
const std::set<uint32_t> &cache = currentABCInfo_.GetStringOrMethodCache(type);
|
||||
for (auto item: cache) {
|
||||
cb(item);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Callback>
|
||||
void IterateLiteralCaches(CacheType type, const Callback &cb)
|
||||
{
|
||||
const std::set<std::pair<CString, uint32_t>> &cache = currentABCInfo_.GetLiteralCache(type);
|
||||
for (auto item: cache) {
|
||||
cb(item);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Callback>
|
||||
void IterateHClassCaches(const Callback &cb)
|
||||
{
|
||||
for (uint32_t i = 0; i < hclassCache_.size(); ++i) {
|
||||
cb(hclassCache_[i], i);
|
||||
const auto &hclassCache = currentABCInfo_.GetHClassCache();
|
||||
for (uint32_t i = 0; i < hclassCache.size(); ++i) {
|
||||
cb(hclassCache[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
@ -453,21 +547,17 @@ private:
|
||||
JSThread *thread_ {nullptr};
|
||||
ObjectFactory *factory_ {nullptr};
|
||||
JSTaggedValue globalModuleTable_ {JSTaggedValue::Hole()};
|
||||
JSTaggedValue constantPoolInfos_ {JSTaggedValue::Hole()};
|
||||
std::vector<std::vector<std::pair<uint32_t, uint32_t>>> recordMethodInfos_ {};
|
||||
size_t constantPoolInfosSize_ {0};
|
||||
// record the mapping relationship between classType and instance hclass index in the constant pool
|
||||
std::map<GlobalTSTypeRef, uint32_t> classTypeIhcIndexMap_ {};
|
||||
bool assertTypes_ {false};
|
||||
bool printAnyTypes_ {false};
|
||||
friend class EcmaVM;
|
||||
|
||||
// records the index in constantpool of the data that aot needs to serialize
|
||||
std::set<uint32_t> stringIndexCache_ {};
|
||||
std::set<uint32_t> methodIndexCache_ {};
|
||||
std::set<uint32_t> skippedMethodIDCache_ {};
|
||||
// store hclass of each abc which produced from static type info
|
||||
CVector<JSTaggedType> hclassCache_ {};
|
||||
// For snapshot
|
||||
size_t constantPoolInfosSize_ {0};
|
||||
JSTaggedValue constantPoolInfos_ {JSTaggedValue::Hole()};
|
||||
ABCInfo currentABCInfo_ {};
|
||||
SnapshotRecordInfo snapshotRecordInfo_ {};
|
||||
|
||||
std::map<std::pair<const JSPandaFile *, panda_file::File::EntityId>, GlobalTSTypeRef> literalOffsetGTMap_ {};
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user