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:
weng-xi 2022-10-19 09:53:32 +08:00
parent 99e26a230c
commit 74b83ecb36
14 changed files with 190 additions and 129 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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