mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
Serialize/deserialize Aot FuncEntry
Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I5WCWJ Signed-off-by: weng-xi <wengxi1@huawei.com> Change-Id: I5e780c0dff1515906bc1649f495b1a63a0742ef5
This commit is contained in:
parent
99e26a230c
commit
74b83ecb36
@ -454,6 +454,21 @@ void AOTFileManager::SetAOTFuncEntry(const JSPandaFile *jsPandaFile, Method *met
|
||||
method->SetCodeEntryAndMarkAOT(codeEntry);
|
||||
}
|
||||
|
||||
void AOTFileManager::SetAOTFuncEntry(const JSPandaFile *jsPandaFile, Method *method, uint32_t entryIndex)
|
||||
{
|
||||
uint32_t aotPackInfoIndex = jsPandaFile->GetAOTPackInfoIndex();
|
||||
const AOTModulePackInfo &aotPackInfo = aotPackInfos_[aotPackInfoIndex];
|
||||
const ModulePackInfo::FuncEntryDes &entry = aotPackInfo.GetStubDes(entryIndex);
|
||||
uint64_t codeEntry = entry.codeAddr_;
|
||||
#ifndef NDEBUG
|
||||
PrintAOTEntry(jsPandaFile, method, codeEntry);
|
||||
#endif
|
||||
if (!codeEntry) {
|
||||
return;
|
||||
}
|
||||
method->SetCodeEntryAndMarkAOT(codeEntry);
|
||||
}
|
||||
|
||||
void AOTFileManager::SetAOTFuncEntryForLiteral(const JSPandaFile *jsPandaFile, const JSHandle<TaggedArray> &obj)
|
||||
{
|
||||
JSThread *thread = vm_->GetJSThread();
|
||||
|
@ -408,6 +408,7 @@ public:
|
||||
void UpdateJSMethods(JSHandle<JSFunction> mainFunc, const JSPandaFile *jsPandaFile);
|
||||
bool hasLoaded(const JSPandaFile *jsPandaFile);
|
||||
void SetAOTFuncEntry(const JSPandaFile *jsPandaFile, Method *method);
|
||||
void SetAOTFuncEntry(const JSPandaFile *jsPandaFile, Method *method, uint32_t entryIndex);
|
||||
void SetAOTFuncEntryForLiteral(const JSPandaFile *jsPandaFile, const JSHandle<TaggedArray> &obj);
|
||||
void LoadSnapshotFile([[maybe_unused]]const std::string& filename);
|
||||
kungfu::ArkStackMapParser* GetStackMapParser() const;
|
||||
|
@ -860,28 +860,28 @@ BytecodeInfo BytecodeCircuitBuilder::GetBytecodeInfo(const uint8_t *pc)
|
||||
case EcmaOpcode::DEFINEFUNC_IMM8_ID16_IMM8: {
|
||||
uint16_t methodId = READ_INST_16_1();
|
||||
uint16_t length = READ_INST_8_3();
|
||||
info.inputs.emplace_back(Immediate(methodId));
|
||||
info.inputs.emplace_back(ConstDataId(ConstDataIDType::MethodIDType, methodId));
|
||||
info.inputs.emplace_back(Immediate(length));
|
||||
break;
|
||||
}
|
||||
case EcmaOpcode::DEFINEFUNC_IMM16_ID16_IMM8: {
|
||||
uint16_t methodId = READ_INST_16_2();
|
||||
uint16_t length = READ_INST_8_4();
|
||||
info.inputs.emplace_back(Immediate(methodId));
|
||||
info.inputs.emplace_back(ConstDataId(ConstDataIDType::MethodIDType, methodId));
|
||||
info.inputs.emplace_back(Immediate(length));
|
||||
break;
|
||||
}
|
||||
case EcmaOpcode::DEFINEMETHOD_IMM8_ID16_IMM8: {
|
||||
uint16_t methodId = READ_INST_16_1();
|
||||
uint16_t length = READ_INST_8_3();
|
||||
info.inputs.emplace_back(Immediate(methodId));
|
||||
info.inputs.emplace_back(ConstDataId(ConstDataIDType::MethodIDType, methodId));
|
||||
info.inputs.emplace_back(Immediate(length));
|
||||
break;
|
||||
}
|
||||
case EcmaOpcode::DEFINEMETHOD_IMM16_ID16_IMM8: {
|
||||
uint16_t methodId = READ_INST_16_2();
|
||||
uint16_t length = READ_INST_8_4();
|
||||
info.inputs.emplace_back(Immediate(methodId));
|
||||
info.inputs.emplace_back(ConstDataId(ConstDataIDType::MethodIDType, methodId));
|
||||
info.inputs.emplace_back(Immediate(length));
|
||||
break;
|
||||
}
|
||||
@ -1493,7 +1493,7 @@ BytecodeInfo BytecodeCircuitBuilder::GetBytecodeInfo(const uint8_t *pc)
|
||||
uint16_t literaId = READ_INST_16_3();
|
||||
uint16_t length = READ_INST_16_5();
|
||||
uint16_t v0 = READ_INST_8_7();
|
||||
info.inputs.emplace_back(Immediate(methodId));
|
||||
info.inputs.emplace_back(ConstDataId(ConstDataIDType::MethodIDType, methodId));
|
||||
info.inputs.emplace_back(Immediate(literaId));
|
||||
info.inputs.emplace_back(Immediate(length));
|
||||
info.inputs.emplace_back(VirtualRegister(v0));
|
||||
@ -1504,7 +1504,7 @@ BytecodeInfo BytecodeCircuitBuilder::GetBytecodeInfo(const uint8_t *pc)
|
||||
uint16_t literaId = READ_INST_16_4();
|
||||
uint16_t length = READ_INST_16_6();
|
||||
uint16_t v0 = READ_INST_8_8();
|
||||
info.inputs.emplace_back(Immediate(methodId));
|
||||
info.inputs.emplace_back(ConstDataId(ConstDataIDType::MethodIDType, methodId));
|
||||
info.inputs.emplace_back(Immediate(literaId));
|
||||
info.inputs.emplace_back(Immediate(length));
|
||||
info.inputs.emplace_back(VirtualRegister(v0));
|
||||
@ -1901,9 +1901,14 @@ std::vector<GateRef> BytecodeCircuitBuilder::CreateGateInList(const BytecodeInfo
|
||||
if (std::holds_alternative<ConstDataId>(input)) {
|
||||
if (std::get<ConstDataId>(input).IsStringId()) {
|
||||
tsManager_->AddStringIndex(std::get<ConstDataId>(input).GetId());
|
||||
}
|
||||
inList[i + length] = circuit_.GetConstantDataGate(std::get<ConstDataId>(input).CaculateBitField(),
|
||||
GateType::StringType());
|
||||
} else if (std::get<ConstDataId>(input).IsMethodId()) {
|
||||
tsManager_->AddMethodIndex(std::get<ConstDataId>(input).GetId());
|
||||
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(),
|
||||
|
@ -118,6 +118,7 @@ void AOTFileGenerator::SaveAOTFile(const std::string &filename)
|
||||
{
|
||||
RunLLVMAssembler();
|
||||
CollectCodeInfo();
|
||||
GenerateMethodToEntryIndexMap();
|
||||
aotInfo_.Save(filename);
|
||||
DestoryModule();
|
||||
}
|
||||
@ -126,6 +127,7 @@ void AOTFileGenerator::SaveSnapshotFile()
|
||||
{
|
||||
Snapshot snapshot(vm_);
|
||||
const CString snapshotPath(vm_->GetJSOptions().GetAOTOutputFile().c_str());
|
||||
vm_->GetTSManager()->ResolveConstantPoolInfo(methodToEntryIndexMap_);
|
||||
snapshot.Serialize(snapshotPath + ".etso");
|
||||
}
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
|
@ -233,6 +233,16 @@ public:
|
||||
vm_->GetTSManager()->ClearCaches();
|
||||
}
|
||||
|
||||
void GenerateMethodToEntryIndexMap()
|
||||
{
|
||||
const std::vector<ModulePackInfo::FuncEntryDes> &entries = aotInfo_.GetStubs();
|
||||
uint32_t entriesSize = entries.size();
|
||||
for (uint32_t i = 0; i < entriesSize; ++i) {
|
||||
const ModulePackInfo::FuncEntryDes &entry = entries[i];
|
||||
methodToEntryIndexMap_[std::make_pair(entry.moduleIndex_, entry.indexInKind_)] = i;
|
||||
}
|
||||
}
|
||||
|
||||
// save function for aot files containing normal func translated from JS/TS
|
||||
void SaveAOTFile(const std::string &filename);
|
||||
void SaveSnapshotFile();
|
||||
@ -240,6 +250,8 @@ private:
|
||||
AOTModulePackInfo aotInfo_;
|
||||
std::vector<uint32_t> aotfileHashs_ {};
|
||||
EcmaVM* vm_;
|
||||
// (moduleIndex, MethodID)->EntryIndex
|
||||
std::map<std::pair<uint32_t, uint32_t>, uint32_t> methodToEntryIndexMap_ {};
|
||||
|
||||
// collect aot component info
|
||||
void CollectCodeInfo();
|
||||
|
@ -265,12 +265,13 @@ GateRef SlowPathLowering::GetObjectFromConstPool(GateRef glue, GateRef jsFunc, G
|
||||
env->SubCfgEntry(&entry);
|
||||
Label exit(&builder_);
|
||||
Label cacheMiss(&builder_);
|
||||
Label cache(&builder_);
|
||||
|
||||
GateRef constPool = GetConstPool(jsFunc);
|
||||
GateRef module = builder_.GetModuleFromFunction(jsFunc);
|
||||
auto cacheValue = builder_.GetValueFromTaggedArray(constPool, index);
|
||||
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), cacheValue);
|
||||
builder_.Branch(builder_.TaggedIsHole(cacheValue), &cacheMiss, &exit);
|
||||
builder_.Branch(builder_.TaggedIsHole(cacheValue), &cacheMiss, &cache);
|
||||
builder_.Bind(&cacheMiss);
|
||||
{
|
||||
if (type == ConstPoolType::STRING) {
|
||||
@ -288,7 +289,19 @@ GateRef SlowPathLowering::GetObjectFromConstPool(GateRef glue, GateRef jsFunc, G
|
||||
}
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
|
||||
builder_.Bind(&cache);
|
||||
{
|
||||
Label isNumber(&builder_);
|
||||
builder_.Branch(builder_.TaggedIsNumber(cacheValue), &isNumber, &exit);
|
||||
builder_.Bind(&isNumber);
|
||||
{
|
||||
if (type == ConstPoolType::METHOD) {
|
||||
result = LowerCallRuntime(glue, RTSTUB_ID(GetMethodFromCache),
|
||||
{ constPool, builder_.Int32ToTaggedInt(index) }, true);
|
||||
}
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
}
|
||||
builder_.Bind(&exit);
|
||||
auto ret = *result;
|
||||
env->SubCfgExit();
|
||||
|
@ -245,6 +245,28 @@ public:
|
||||
// For local merge abc, get record name from file name.
|
||||
static CString PUBLIC_API ParseRecordName(const CString &fileName);
|
||||
|
||||
bool IsSystemLib() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t GetAOTPackInfoIndex() const
|
||||
{
|
||||
return aotPackInfoIndex_;
|
||||
}
|
||||
|
||||
// If the system library is loaded, packinfos has two elements
|
||||
// 0: system library, 1: application
|
||||
// Note: There is no system library currently, so the aotPackInfoIndex_ is 0
|
||||
void SetAOTPackInfoIndex()
|
||||
{
|
||||
if (IsSystemLib()) {
|
||||
aotPackInfoIndex_ = 0;
|
||||
} else {
|
||||
aotPackInfoIndex_ = 1;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void InitializeUnMergedPF();
|
||||
void InitializeMergedPF();
|
||||
@ -261,6 +283,7 @@ private:
|
||||
CString desc_;
|
||||
bool hasTSTypes_ {false};
|
||||
bool isLoadedAOT_ {false};
|
||||
uint32_t aotPackInfoIndex_ {0};
|
||||
uint32_t typeSummaryOffset_ {0};
|
||||
bool isNewVersion_ {false};
|
||||
|
||||
|
@ -467,7 +467,7 @@ JSHandle<ConstantPool> PandaFileTranslator::AllocateConstPool(EcmaVM *vm, const
|
||||
#if !defined(PANDA_TARGET_WINDOWS) && !defined(PANDA_TARGET_MACOS)
|
||||
const bool isLoadedAOT = jsPandaFile->IsLoadedAOT();
|
||||
if (isLoadedAOT) {
|
||||
constpool = vm->GetTSManager()->RestoreConstantPool(jsPandaFile, constpoolIndex);
|
||||
constpool = vm->GetTSManager()->RestoreConstantPool(jsPandaFile);
|
||||
} else {
|
||||
constpool = factory->NewConstantPool(constpoolIndex);
|
||||
}
|
||||
|
@ -24,9 +24,8 @@ std::string ConstantPool::GetStdStringByIdx(size_t index) const
|
||||
return EcmaStringAccessor(str).ToStdString(StringConvertedUsage::LOGICOPERATION);
|
||||
}
|
||||
|
||||
JSHandle<ConstantPool> ConstantPool::RestoreConstantPool(EcmaVM *vm, const JSPandaFile *jsPandaFile,
|
||||
uint32_t constpoolSize)
|
||||
JSHandle<ConstantPool> ConstantPool::RestoreConstantPool(EcmaVM *vm, const JSPandaFile *jsPandaFile)
|
||||
{
|
||||
return vm->GetTSManager()->RestoreConstantPool(jsPandaFile, constpoolSize);
|
||||
return vm->GetTSManager()->RestoreConstantPool(jsPandaFile);
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@
|
||||
#include "ecmascript/ecma_macros.h"
|
||||
#include "ecmascript/global_env.h"
|
||||
#include "ecmascript/js_tagged_value-inl.h"
|
||||
#include "ecmascript/aot_file_manager.h"
|
||||
#include "ecmascript/jspandafile/class_info_extractor.h"
|
||||
#include "ecmascript/jspandafile/constpool_value.h"
|
||||
#include "ecmascript/jspandafile/js_pandafile_manager.h"
|
||||
@ -79,7 +80,7 @@ public:
|
||||
bool isLoadedAOT = jsPandaFile->IsLoadedAOT();
|
||||
if (isLoadedAOT) {
|
||||
#if !defined(PANDA_TARGET_WINDOWS) && !defined(PANDA_TARGET_MACOS)
|
||||
constpool = RestoreConstantPool(vm, jsPandaFile, constpoolSize);
|
||||
constpool = RestoreConstantPool(vm, jsPandaFile);
|
||||
#else
|
||||
LOG_FULL(FATAL) << "Aot don't support Windows and MacOS platform";
|
||||
UNREACHABLE();
|
||||
@ -151,12 +152,20 @@ 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;
|
||||
|
||||
if (isLoadedAOT && val.IsInt()) {
|
||||
entryIndex = val.GetInt();
|
||||
val = JSTaggedValue::Hole();
|
||||
}
|
||||
|
||||
if (val.IsHole()) {
|
||||
JSHandle<ConstantPool> constpoolHandle(thread, constpool);
|
||||
EcmaVM *vm = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = vm->GetFactory();
|
||||
|
||||
JSPandaFile *jsPandaFile = taggedPool->GetJSPandaFile();
|
||||
panda_file::File::IndexHeader *indexHeader = taggedPool->GetIndexHeader();
|
||||
auto pf = jsPandaFile->GetPandaFile();
|
||||
Span<const panda_file::File::EntityId> indexs = pf->GetMethodIndex(indexHeader);
|
||||
@ -176,6 +185,9 @@ public:
|
||||
vm->AddConstpool(jsPandaFile, newConstpool, constpoolIndex);
|
||||
}
|
||||
method->SetConstantPool(thread, newConstpool);
|
||||
if (isLoadedAOT) {
|
||||
vm->GetAOTFileManager()->SetAOTFuncEntry(jsPandaFile, *method, entryIndex);
|
||||
}
|
||||
|
||||
val = method.GetTaggedValue();
|
||||
constpoolHandle->Set(thread, index, val);
|
||||
@ -188,11 +200,19 @@ public:
|
||||
uint32_t index)
|
||||
{
|
||||
auto val = constpool->Get(index);
|
||||
JSPandaFile *jsPandaFile = constpool->GetJSPandaFile();
|
||||
bool isLoadedAOT = jsPandaFile->IsLoadedAOT();
|
||||
uint32_t entryIndex = 0;
|
||||
|
||||
if (isLoadedAOT && val.IsInt()) {
|
||||
entryIndex = val.GetInt();
|
||||
val = JSTaggedValue::Hole();
|
||||
}
|
||||
|
||||
if (val.IsHole()) {
|
||||
EcmaVM *vm = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = vm->GetFactory();
|
||||
|
||||
JSPandaFile *jsPandaFile = constpool->GetJSPandaFile();
|
||||
panda_file::File::IndexHeader *indexHeader = constpool->GetIndexHeader();
|
||||
auto pf = jsPandaFile->GetPandaFile();
|
||||
Span<const panda_file::File::EntityId> indexs = pf->GetMethodIndex(indexHeader);
|
||||
@ -210,6 +230,9 @@ public:
|
||||
vm->AddConstpool(jsPandaFile, newConstpool, constpoolIndex);
|
||||
}
|
||||
method->SetConstantPool(thread, newConstpool);
|
||||
if (isLoadedAOT) {
|
||||
vm->GetAOTFileManager()->SetAOTFuncEntry(jsPandaFile, *method, entryIndex);
|
||||
}
|
||||
|
||||
val = method.GetTaggedValue();
|
||||
constpool->Set(thread, index, val);
|
||||
@ -369,8 +392,7 @@ private:
|
||||
return JSTaggedValue::TaggedTypeSize() * GetLength() + DATA_OFFSET;
|
||||
}
|
||||
|
||||
static JSHandle<ConstantPool> RestoreConstantPool(EcmaVM *vm, const JSPandaFile *jsPandaFile,
|
||||
uint32_t constpoolSize);
|
||||
static JSHandle<ConstantPool> RestoreConstantPool(EcmaVM *vm, const JSPandaFile *jsPandaFile);
|
||||
};
|
||||
} // namespace ecmascript
|
||||
} // namespace panda
|
||||
|
@ -726,20 +726,6 @@ JSTaggedValue RuntimeStubs::RuntimeCloneClassFromTemplate(JSThread *thread, cons
|
||||
return cloneClass.GetTaggedValue();
|
||||
}
|
||||
|
||||
void RuntimeStubs::RuntimeUpdateAotStatus(JSThread *thread,
|
||||
const JSTaggedValue constpoolValue,
|
||||
const JSTaggedValue methodValue)
|
||||
{
|
||||
auto constpool = ConstantPool::Cast(constpoolValue.GetTaggedObject());
|
||||
auto method = Method::Cast(methodValue.GetTaggedObject());
|
||||
// JSPandaFile is in the first index of constpool.
|
||||
auto jsPandaFile = constpool->GetJSPandaFile();
|
||||
AOTFileManager *aotFileManager = thread->GetEcmaVM()->GetAOTFileManager();
|
||||
if (jsPandaFile->IsLoadedAOT()) {
|
||||
aotFileManager->SetAOTFuncEntry(jsPandaFile, method);
|
||||
}
|
||||
}
|
||||
|
||||
// clone class may need re-set inheritance relationship due to extends may be a variable.
|
||||
JSTaggedValue RuntimeStubs::RuntimeCreateClassWithBuffer(JSThread *thread,
|
||||
const JSHandle<JSTaggedValue> &base,
|
||||
@ -763,7 +749,6 @@ JSTaggedValue RuntimeStubs::RuntimeCreateClassWithBuffer(JSThread *thread,
|
||||
JSHandle<JSFunction> cls = ClassHelper::DefineClassFromExtractor(thread, base, extractor, constpool, lexenv);
|
||||
|
||||
RuntimeSetClassInheritanceRelationship(thread, JSHandle<JSTaggedValue>(cls), base);
|
||||
RuntimeUpdateAotStatus(thread, constpool.GetTaggedValue(), method.GetTaggedValue());
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
return cls.GetTaggedValue();
|
||||
}
|
||||
@ -795,7 +780,6 @@ JSTaggedValue RuntimeStubs::RuntimeCreateClassWithIHClass(JSThread *thread,
|
||||
JSHandle<JSFunction> cls = ClassHelper::DefineClassWithIHClass(thread, base, extractor, constpool, lexenv, ihclass);
|
||||
|
||||
RuntimeSetClassInheritanceRelationship(thread, JSHandle<JSTaggedValue>(cls), base);
|
||||
RuntimeUpdateAotStatus(thread, constpool.GetTaggedValue(), method.GetTaggedValue());
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
|
||||
return cls.GetTaggedValue();
|
||||
@ -1828,7 +1812,6 @@ JSTaggedValue RuntimeStubs::RuntimeDefinefunc(JSThread *thread, const JSHandle<M
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
RuntimeUpdateAotStatus(thread, methodHandle->GetConstantPool(), methodHandle.GetTaggedValue());
|
||||
ASSERT_NO_ABRUPT_COMPLETION(thread);
|
||||
return jsFunc.GetTaggedValue();
|
||||
}
|
||||
@ -1925,7 +1908,6 @@ JSTaggedValue RuntimeStubs::RuntimeDefineMethod(JSThread *thread, const JSHandle
|
||||
JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutProto());
|
||||
JSHandle<JSFunction> jsFunc = factory->NewJSFunctionByHClass(methodHandle, hclass);
|
||||
jsFunc->SetHomeObject(thread, homeObject);
|
||||
RuntimeUpdateAotStatus(thread, methodHandle->GetConstantPool(), methodHandle.GetTaggedValue());
|
||||
ASSERT_NO_ABRUPT_COMPLETION(thread);
|
||||
return jsFunc.GetTaggedValue();
|
||||
}
|
||||
|
@ -617,9 +617,6 @@ private:
|
||||
static inline JSTaggedValue RuntimeOptGenerateScopeInfo(JSThread *thread, uint16_t scopeId, JSTaggedValue func);
|
||||
static inline JSTaggedType *GetActualArgv(JSThread *thread);
|
||||
static inline OptimizedJSFunctionFrame *GetOptimizedJSFunctionFrame(JSThread *thread);
|
||||
static inline void RuntimeUpdateAotStatus(JSThread *thread,
|
||||
const JSTaggedValue constpool,
|
||||
const JSTaggedValue method);
|
||||
|
||||
static JSTaggedValue NewObject(EcmaRuntimeCallInfo *info);
|
||||
static void SaveFrameToContext(JSThread *thread, JSHandle<GeneratorContext> context);
|
||||
|
@ -324,7 +324,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 = GetHClassCacheSize();
|
||||
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]))));
|
||||
}
|
||||
@ -564,36 +564,51 @@ JSTaggedValue TSManager::GenerateConstantPoolInfo(const JSPandaFile* jsPandaFile
|
||||
ObjectFactory *factory = vm_->GetFactory();
|
||||
JSThread *thread = vm_->GetJSThread();
|
||||
JSHandle<ConstantPool> constantPool(thread, vm_->FindConstpool(jsPandaFile, 0));
|
||||
JSHandle<TaggedArray> constantPoolInfo = factory->NewTaggedArray(ComputeSizeOfConstantPoolInfo());
|
||||
constantPoolInfo->Set(thread, NUM_OF_ORIGINAL_CONSTANTPOOL_DATA_INDEX,
|
||||
JSTaggedValue(GetConstDataCacheSize() * ORIGINAL_CONSTANTPOOL_DATA_SIZE));
|
||||
constantPoolInfo->Set(thread, NUM_OF_HCLASS_INDEX, JSTaggedValue(GetHClassCacheSize()));
|
||||
uint32_t index = CONSTANTPOOL_INFO_DATA_OFFSET;
|
||||
IterateConstDataCaches([thread, constantPool, &index, constantPoolInfo] (ConstPoolType type, uint32_t constIndex) {
|
||||
switch (type) {
|
||||
case ConstPoolType::STRING: {
|
||||
auto string = ConstantPool::GetStringFromCache(thread, constantPool.GetTaggedValue(), constIndex);
|
||||
constantPoolInfo->Set(thread, index++, JSTaggedValue(constIndex));
|
||||
constantPoolInfo->Set(thread, index++, string);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
uint32_t constantPoolSize = constantPool->GetCacheLength();
|
||||
uint32_t hclassCacheSize = hclassCache_.size();
|
||||
JSHandle<ConstantPool> constantPoolInfo = factory->NewConstantPool(constantPoolSize + hclassCacheSize);
|
||||
recordMethodInfos_.emplace_back(std::vector<std::pair<uint32_t, uint32_t>>{});
|
||||
|
||||
IterateConstantPoolCache(CacheType::STRING, [thread, constantPool, constantPoolInfo] (uint32_t index) {
|
||||
auto string = ConstantPool::GetStringFromCache(thread, constantPool.GetTaggedValue(), index);
|
||||
constantPoolInfo->SetObjectToCache(thread, index, string);
|
||||
});
|
||||
|
||||
IterateHClassCaches([thread, &index, &constantPoolInfo]
|
||||
(JSTaggedType hclass) {
|
||||
constantPoolInfo->Set(thread, index++, JSTaggedValue(hclass));
|
||||
IterateConstantPoolCache(CacheType::METHOD, [this, constantPool, jsPandaFile] (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];
|
||||
recordMethodInfos_.back().emplace_back(std::make_pair(methodID.GetOffset(), index));
|
||||
});
|
||||
|
||||
if (ComputeSizeOfConstantPoolInfo() != index) {
|
||||
LOG_FULL(FATAL) << "constantpool info size incorrect";
|
||||
}
|
||||
IterateHClassCaches([thread, constantPoolSize, constantPoolInfo] (JSTaggedType hclass, uint32_t index) {
|
||||
constantPoolInfo->SetObjectToCache(thread, constantPoolSize + index, JSTaggedValue(hclass));
|
||||
});
|
||||
|
||||
return constantPoolInfo.GetTaggedValue();
|
||||
}
|
||||
|
||||
void TSManager::ResolveConstantPoolInfo(const std::map<std::pair<uint32_t, uint32_t>, uint32_t> &methodToEntryIndexMap)
|
||||
{
|
||||
JSHandle<TaggedArray> constantPoolInfosHandle(thread_, constantPoolInfos_);
|
||||
JSMutableHandle<ConstantPool> currentCPInfo(thread_, JSTaggedValue::Undefined());
|
||||
uint32_t size = recordMethodInfos_.size();
|
||||
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) {
|
||||
uint32_t moduleIndex = i;
|
||||
uint32_t methodID = item.first;
|
||||
uint32_t constantPoolIndex = item.second;
|
||||
uint32_t entryIndex = methodToEntryIndexMap.at(std::make_pair(moduleIndex, methodID));
|
||||
currentCPInfo->SetObjectToCache(thread_, constantPoolIndex, JSTaggedValue(entryIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TSManager::SortConstantPoolInfos()
|
||||
{
|
||||
JSHandle<TaggedArray> constantPoolInfos = GetConstantPoolInfos();
|
||||
@ -637,7 +652,7 @@ void TSManager::SortConstantPoolInfos()
|
||||
}
|
||||
}
|
||||
|
||||
JSHandle<ConstantPool> TSManager::RestoreConstantPool(const JSPandaFile* pf, uint32_t oldConstantPoolLen)
|
||||
JSHandle<ConstantPool> TSManager::RestoreConstantPool(const JSPandaFile* pf)
|
||||
{
|
||||
JSThread *thread = vm_->GetJSThread();
|
||||
JSHandle<TaggedArray> constantPoolInfos = GetConstantPoolInfos();
|
||||
@ -650,34 +665,19 @@ JSHandle<ConstantPool> TSManager::RestoreConstantPool(const JSPandaFile* pf, uin
|
||||
LOG_FULL(FATAL) << "restore constant pool fail";
|
||||
}
|
||||
|
||||
JSMutableHandle<TaggedArray> valueArray(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<ConstantPool> constantPool(thread, JSTaggedValue::Undefined());
|
||||
while (leftBound <= rightBound) {
|
||||
uint32_t currentKeyIndex = static_cast<uint32_t>(leftBound) * CONSTANTPOOL_INFOS_ITEM_SIZE;
|
||||
EcmaString *nowStr = EcmaString::Cast(constantPoolInfos->Get(currentKeyIndex).GetTaggedObject());
|
||||
if (EcmaStringAccessor::StringsAreEqual(nowStr, *key)) {
|
||||
valueArray.Update(constantPoolInfos->Get(currentKeyIndex + 1));
|
||||
constantPool.Update(constantPoolInfos->Get(currentKeyIndex + 1));
|
||||
break;
|
||||
}
|
||||
leftBound++;
|
||||
}
|
||||
|
||||
uint32_t originalConstantPoolDataStart = CONSTANTPOOL_INFO_DATA_OFFSET;
|
||||
uint32_t originalConstantPoolDataLen = static_cast<uint32_t>(valueArray->
|
||||
Get(NUM_OF_ORIGINAL_CONSTANTPOOL_DATA_INDEX).GetInt());
|
||||
uint32_t hclassStart = originalConstantPoolDataStart + originalConstantPoolDataLen;
|
||||
uint32_t hclassLen = static_cast<uint32_t>(valueArray->Get(NUM_OF_HCLASS_INDEX).GetInt());
|
||||
|
||||
JSHandle<ConstantPool> constantPool = vm_->GetFactory()->NewConstantPool(oldConstantPoolLen + hclassLen);
|
||||
|
||||
for (uint32_t i = 0; i < originalConstantPoolDataLen; i += ORIGINAL_CONSTANTPOOL_DATA_SIZE) {
|
||||
uint32_t currentIndex = originalConstantPoolDataStart + i;
|
||||
uint32_t constantPoolIndex = static_cast<uint32_t>(valueArray->Get(currentIndex).GetInt());
|
||||
JSTaggedValue constantPoolValue = valueArray->Get(currentIndex + 1);
|
||||
constantPool->SetObjectToCache(thread, constantPoolIndex, constantPoolValue);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < hclassLen; ++i) {
|
||||
JSTaggedValue value = valueArray->Get(hclassStart + i);
|
||||
constantPool->SetObjectToCache(thread, oldConstantPoolLen + i, value);
|
||||
if (leftBound > rightBound) {
|
||||
LOG_FULL(FATAL) << "restore constantpool: can not find the constantpool";
|
||||
}
|
||||
|
||||
return constantPool;
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
#include "ecmascript/mem/c_string.h"
|
||||
#include "ecmascript/js_handle.h"
|
||||
#include "ecmascript/jspandafile/constpool_value.h"
|
||||
#include "ecmascript/js_tagged_value-inl.h"
|
||||
#include "ecmascript/ts_types/global_ts_type_ref.h"
|
||||
|
||||
@ -30,9 +29,9 @@ enum class MTableIdx : uint8_t {
|
||||
NUM_OF_DEFAULT_TABLES,
|
||||
};
|
||||
|
||||
enum class CacheKind: uint8_t {
|
||||
CONST_DATA_INDEX = 0,
|
||||
HCLASS,
|
||||
enum class CacheType : uint8_t {
|
||||
STRING = 0,
|
||||
METHOD,
|
||||
};
|
||||
|
||||
class TSModuleTable : public TaggedArray {
|
||||
@ -238,6 +237,9 @@ public:
|
||||
|
||||
void PUBLIC_API CollectConstantPoolInfo(const JSPandaFile* jsPandaFile);
|
||||
|
||||
void PUBLIC_API ResolveConstantPoolInfo(const std::map<std::pair<uint32_t, uint32_t>, uint32_t>
|
||||
&methodToEntryIndexMap);
|
||||
|
||||
JSHandle<TaggedArray> PUBLIC_API GetConstantPoolInfos() const
|
||||
{
|
||||
return JSHandle<TaggedArray>(uintptr_t(&constantPoolInfos_));
|
||||
@ -250,36 +252,29 @@ public:
|
||||
|
||||
void PUBLIC_API SortConstantPoolInfos();
|
||||
|
||||
JSHandle<ConstantPool> PUBLIC_API RestoreConstantPool(const JSPandaFile* pf, uint32_t constantPool);
|
||||
JSHandle<ConstantPool> PUBLIC_API RestoreConstantPool(const JSPandaFile* pf);
|
||||
|
||||
void ClearCaches()
|
||||
{
|
||||
constIndexCache_.clear();
|
||||
stringIndexCache_.clear();
|
||||
methodIndexCache_.clear();
|
||||
hclassCache_.clear();
|
||||
}
|
||||
|
||||
void AddStringIndex(uint32_t index)
|
||||
{
|
||||
if (constIndexCache_.find({ConstPoolType::STRING, index}) != constIndexCache_.end()) {
|
||||
if (stringIndexCache_.find(index) != stringIndexCache_.end()) {
|
||||
return;
|
||||
}
|
||||
constIndexCache_.insert({ConstPoolType::STRING, index});
|
||||
stringIndexCache_.insert(index);
|
||||
}
|
||||
|
||||
void AddMethodIndex(uint32_t index)
|
||||
{
|
||||
if (constIndexCache_.find({ConstPoolType::METHOD, index}) != constIndexCache_.end()) {
|
||||
if (methodIndexCache_.find(index) != methodIndexCache_.end()) {
|
||||
return;
|
||||
}
|
||||
constIndexCache_.insert({ConstPoolType::METHOD, index});
|
||||
}
|
||||
|
||||
void AddClassLiteraIndex(uint32_t index)
|
||||
{
|
||||
if (constIndexCache_.find({ConstPoolType::CLASS_LITERAL, index}) != constIndexCache_.end()) {
|
||||
return;
|
||||
}
|
||||
constIndexCache_.insert({ConstPoolType::CLASS_LITERAL, index});
|
||||
methodIndexCache_.insert(index);
|
||||
}
|
||||
|
||||
EcmaVM *GetEcmaVM() const
|
||||
@ -346,11 +341,7 @@ public:
|
||||
|
||||
private:
|
||||
// constantpoolInfos
|
||||
static constexpr uint32_t CONSTANTPOOL_INFO_DATA_OFFSET = 2;
|
||||
static constexpr uint32_t CONSTANTPOOL_INFOS_ITEM_SIZE = 2;
|
||||
static constexpr uint32_t NUM_OF_ORIGINAL_CONSTANTPOOL_DATA_INDEX = 0;
|
||||
static constexpr uint32_t ORIGINAL_CONSTANTPOOL_DATA_SIZE = 2;
|
||||
static constexpr uint32_t NUM_OF_HCLASS_INDEX = 1;
|
||||
|
||||
NO_COPY_SEMANTIC(TSManager);
|
||||
NO_MOVE_SEMANTIC(TSManager);
|
||||
@ -377,22 +368,6 @@ private:
|
||||
|
||||
int BinarySearch(uint32_t target, uint32_t itemSize, bool findLeftBound = true);
|
||||
|
||||
uint32_t ComputeSizeOfConstantPoolInfo() const
|
||||
{
|
||||
return CONSTANTPOOL_INFO_DATA_OFFSET + ORIGINAL_CONSTANTPOOL_DATA_SIZE *
|
||||
GetConstDataCacheSize() + GetHClassCacheSize();
|
||||
}
|
||||
|
||||
uint32_t GetHClassCacheSize() const
|
||||
{
|
||||
return hclassCache_.size();
|
||||
}
|
||||
|
||||
uint32_t GetConstDataCacheSize() const
|
||||
{
|
||||
return constIndexCache_.size();
|
||||
}
|
||||
|
||||
void AddHClassInCompilePhase(GlobalTSTypeRef gt, JSTaggedValue hclass, uint32_t constantPoolLen)
|
||||
{
|
||||
hclassCache_.emplace_back(hclass.GetRawData());
|
||||
@ -400,18 +375,31 @@ private:
|
||||
}
|
||||
|
||||
template <class Callback>
|
||||
void IterateConstDataCaches(const Callback &cb)
|
||||
void IterateConstantPoolCache(CacheType type, const Callback &cb)
|
||||
{
|
||||
for (auto item: constIndexCache_) {
|
||||
cb(std::get<0>(item), std::get<1>(item));
|
||||
switch (type) {
|
||||
case CacheType::STRING: {
|
||||
for (auto item: stringIndexCache_) {
|
||||
cb(item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CacheType::METHOD: {
|
||||
for (auto item: methodIndexCache_) {
|
||||
cb(item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
template <class Callback>
|
||||
void IterateHClassCaches(const Callback &cb)
|
||||
{
|
||||
for (JSTaggedType item: hclassCache_) {
|
||||
cb(item);
|
||||
for (uint32_t i = 0; i < hclassCache_.size(); ++i) {
|
||||
cb(hclassCache_[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
@ -420,6 +408,7 @@ private:
|
||||
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_ {};
|
||||
@ -427,8 +416,9 @@ private:
|
||||
bool printAnyTypes_ {false};
|
||||
friend class EcmaVM;
|
||||
|
||||
// recode the index of String in each constpool
|
||||
std::set<std::tuple<ConstPoolType, int>>constIndexCache_ {};
|
||||
// records the index in constantpool of the data that aot needs to serialize
|
||||
std::set<int> stringIndexCache_ {};
|
||||
std::set<int> methodIndexCache_ {};
|
||||
// store hclass of each abc which produced from static type info
|
||||
CVector<JSTaggedType> hclassCache_ {};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user