!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:
openharmony_ci 2022-10-26 01:46:28 +00:00 committed by Gitee
commit c2d7f33998
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
24 changed files with 565 additions and 122 deletions

View File

@ -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_;

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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:

View File

@ -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);

View File

@ -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));

View File

@ -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) \

View File

@ -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;

View File

@ -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();

View File

@ -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();

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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:

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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 &gt) 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

View File

@ -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_ {};
};