Support deserializing constpool from etso file

1. AOT will get strings directly from constant pool instead of relying on tsmanager
2. Fixed incorrect deserialization of non-heap objects in snapshot
3. Remove code for slowpathlowering and IRbuilder that are no longer needed

Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I5O7T7

Signed-off-by: weng-xi <wengxi1@huawei.com>
Change-Id: Ide0b8ffff04d0230ced2b6670a18980c9eeb135d
This commit is contained in:
weng-xi 2022-08-28 00:23:14 +08:00
parent d347e9b87f
commit 00caad2ebf
24 changed files with 298 additions and 227 deletions

View File

@ -449,6 +449,7 @@ ecma_source = [
"ecmascript/jspandafile/js_pandafile_executor.cpp",
"ecmascript/jspandafile/scope_info_extractor.cpp",
"ecmascript/jspandafile/method_literal.cpp",
"ecmascript/jspandafile/program_object.cpp",
"ecmascript/js_api/js_api_arraylist.cpp",
"ecmascript/js_api/js_api_arraylist_iterator.cpp",
"ecmascript/js_api/js_api_deque.cpp",

View File

@ -98,6 +98,8 @@ int Main(const int argc, const char **argv)
CompilerLog log(logOption, isEnableBcTrace);
AotMethodLogList logList(logMethodsList);
AOTFileGenerator generator(&log, &logList, vm);
generator.InitializeConstantPoolInfos(pandaFileNames);
vm->GetTSManager()->SetConstantPoolInfo(generator.GetCpProcessor().GetInfos());
PassManager passManager(vm, entry, triple, optLevel, relocMode, &log, &logList, maxAotMethodSize);
for (const auto &fileName : pandaFileNames) {
LOG_COMPILER(INFO) << "AOT start to execute ark file: " << fileName;

View File

@ -2057,8 +2057,8 @@ std::vector<GateRef> BytecodeCircuitBuilder::CreateGateInList(const BytecodeInfo
{Circuit::GetCircuitRoot(OpCode(OpCode::CONSTANT_LIST))},
GateType::NJSValue());
} else if (std::holds_alternative<StringId>(input)) {
size_t index = tsManager_->GetStringIdx(constantPool_, std::get<StringId>(input).GetId());
inList[i + length] = circuit_.NewGate(OpCode(OpCode::CONSTANT), MachineType::I32, index,
inList[i + length] = circuit_.NewGate(OpCode(OpCode::CONSTANT), MachineType::I32,
std::get<StringId>(input).GetId(),
{Circuit::GetCircuitRoot(OpCode(OpCode::CONSTANT_LIST))},
GateType::NJSValue());
} else if (std::holds_alternative<Immediate>(input)) {

View File

@ -449,9 +449,8 @@ public:
const MethodLiteral *methodLiteral,
BytecodeInfoCollector::MethodPcInfo &methodPCInfo,
TSManager *tsManager, bool enableLog)
: tsManager_(tsManager), file_(jsPandaFile), pf_(jsPandaFile->GetPandaFile()),
method_(methodLiteral), constantPool_(constantPool), gateAcc_(&circuit_),
argAcc_(&circuit_, method_, jsPandaFile),
: file_(jsPandaFile), pf_(jsPandaFile->GetPandaFile()), method_(methodLiteral), constantPool_(constantPool),
gateAcc_(&circuit_), argAcc_(&circuit_, method_, jsPandaFile),
typeRecorder_(jsPandaFile, method_, tsManager), hasTypes_(file_->HasTSTypes()),
enableLog_(enableLog), pcToBCOffset_(methodPCInfo.pcToBCOffset),
byteCodeCurPrePc_(methodPCInfo.byteCodeCurPrePc), bytecodeBlockInfos_(methodPCInfo.bytecodeBlockInfos)
@ -542,6 +541,11 @@ public:
}
}
JSHandle<JSTaggedValue> GetConstantPool() const
{
return constantPool_;
}
private:
void CollectTryCatchBlockInfo(std::map<std::pair<uint8_t *, uint8_t *>, std::vector<uint8_t *>> &Exception);
void CompleteBytecodeBlockInfo();
@ -587,7 +591,6 @@ private:
std::map<kungfu::GateRef, std::pair<size_t, const uint8_t *>> jsgateToBytecode_;
std::map<const uint8_t *, kungfu::GateRef> byteCodeToJSGate_;
BytecodeGraph graph_;
TSManager *tsManager_ {nullptr};
const JSPandaFile *file_ {nullptr};
const panda_file::File *pf_ {nullptr};
const MethodLiteral *method_ {nullptr};

View File

@ -127,14 +127,8 @@ void AOTFileGenerator::SaveAOTFile(const std::string &filename)
void AOTFileGenerator::SaveSnapshotFile()
{
TSManager *tsManager = vm_->GetTSManager();
Snapshot snapshot(vm_);
CVector<JSTaggedType> constStringTable = tsManager->GetConstStringTable();
CVector<JSTaggedType> staticHClassTable = tsManager->GetStaticHClassTable();
CVector<JSTaggedType> tsManagerSerializeTable(constStringTable);
tsManagerSerializeTable.insert(tsManagerSerializeTable.end(), staticHClassTable.begin(), staticHClassTable.end());
const CString snapshotPath(vm_->GetJSOptions().GetAOTOutputFile().c_str());
snapshot.Serialize(reinterpret_cast<uintptr_t>(tsManagerSerializeTable.data()), tsManagerSerializeTable.size(),
snapshotPath + ".etso");
snapshot.Serialize(snapshotPath + ".etso");
}
} // namespace panda::ecmascript::kungfu

View File

@ -22,8 +22,11 @@
#include "ecmascript/compiler/compiler_log.h"
#include "ecmascript/compiler/llvm_codegen.h"
#include "ecmascript/compiler/llvm_ir_builder.h"
#include "ecmascript/compiler/bytecode_info_collector.h"
#include "ecmascript/compiler/bytecode_circuit_builder.h"
#include "ecmascript/file_loader.h"
#include "ecmascript/jspandafile/js_pandafile.h"
#include "ecmascript/snapshot/mem/snapshot_processor.h"
namespace panda::ecmascript::kungfu {
class Module {
@ -206,23 +209,40 @@ protected:
class AOTFileGenerator : public FileGenerator {
public:
AOTFileGenerator(const CompilerLog *log, const MethodLogList *logList,
EcmaVM* vm) : FileGenerator(log, logList), vm_(vm) {};
EcmaVM* vm) : FileGenerator(log, logList), vm_(vm), cpProcessor_(vm) {};
~AOTFileGenerator() override = default;
void AddModule(LLVMModule *llvmModule, LLVMAssembler *assembler, const JSPandaFile *jsPandaFile)
void InitializeConstantPoolInfos(const arg_list_t pandaFileNames)
{
cpProcessor_.InitializeConstantPoolInfos(pandaFileNames.size());
}
void AddModule(LLVMModule *llvmModule, LLVMAssembler *assembler, const BytecodeInfoCollector::BCInfo &bytecodeInfo)
{
modulePackage_.emplace_back(Module(llvmModule, assembler));
auto hash = jsPandaFile->GetFileUniqId();
auto hash = bytecodeInfo.jsPandaFile->GetFileUniqId();
aotfileHashs_.emplace_back(hash);
CollectConstantPoolInfo(bytecodeInfo.jsPandaFile, bytecodeInfo.constantPool);
}
ConstantPoolProcessor& GetCpProcessor()
{
return cpProcessor_;
}
// save function for aot files containing normal func translated from JS/TS
void SaveAOTFile(const std::string &filename);
void SaveSnapshotFile();
private:
void CollectConstantPoolInfo(const JSPandaFile* pf, const JSHandle<JSTaggedValue> constantPool)
{
cpProcessor_.CollectConstantPoolInfo(pf, constantPool);
}
AOTModulePackInfo aotInfo_;
std::vector<uint32_t> aotfileHashs_ {};
EcmaVM* vm_;
ConstantPoolProcessor cpProcessor_;
// collect aot component info
void CollectCodeInfo();

View File

@ -77,7 +77,7 @@ bool PassManager::Compile(const std::string &fileName, AOTFileGenerator &generat
}
});
LOG_COMPILER(INFO) << skipMethodNum << " large methods in '" << fileName << "' have been skipped";
generator.AddModule(aotModule, aotModuleAssembler, bytecodeInfo.jsPandaFile);
generator.AddModule(aotModule, aotModuleAssembler, bytecodeInfo);
return true;
}

View File

@ -261,15 +261,6 @@ GateRef SlowPathLowering::GetHomeObjectFromJSFunction(GateRef jsFunc)
return builder_.Load(VariableType::JS_ANY(), jsFunc, offset);
}
GateRef SlowPathLowering::GetValueFromConstStringTable(GateRef glue, GateRef gate, uint32_t inIndex)
{
GateRef target = builder_.IntPtr(RTSTUB_ID(LoadValueFromConstantStringTable));
auto idGate = builder_.TaggedTypeNGC(builder_.ZExtInt32ToInt64(acc_.GetValueIn(gate, inIndex)));
GateRef dependGate = acc_.GetDep(gate);
const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(CallRuntime));
return builder_.Call(cs, glue, target, dependGate, {idGate});
}
void SlowPathLowering::Lower(GateRef gate)
{
GateRef glue = argAcc_.GetCommonArgGate(CommonArgIdx::GLUE);
@ -283,7 +274,7 @@ void SlowPathLowering::Lower(GateRef gate)
Environment env(gate, circuit_, &builder_);
switch (op) {
case LDA_STR_ID32:
LowerLoadStr(gate, glue);
LowerLoadStr(gate, glue, jsFunc);
break;
case CALLARG0DYN_PREF_V8:
LowerCallArg0Dyn(gate, glue);
@ -385,10 +376,10 @@ void SlowPathLowering::Lower(GateRef gate)
LowerAsyncFunctionReject(gate, glue);
break;
case TRYLDGLOBALBYNAME_PREF_ID32:
LowerTryLdGlobalByName(gate, glue);
LowerTryLdGlobalByName(gate, glue, jsFunc);
break;
case STGLOBALVAR_PREF_ID32:
LowerStGlobalVar(gate, glue);
LowerStGlobalVar(gate, glue, jsFunc);
break;
case GETITERATOR_PREF:
LowerGetIterator(gate, glue);
@ -505,7 +496,7 @@ void SlowPathLowering::Lower(GateRef gate)
LowerSetObjectWithProto(gate, glue);
break;
case LDBIGINT_PREF_ID32:
LowerLdBigInt(gate, glue);
LowerLdBigInt(gate, glue, jsFunc);
break;
case TONUMERIC_PREF_V8:
LowerToNumeric(gate, glue);
@ -552,7 +543,7 @@ void SlowPathLowering::Lower(GateRef gate)
LowerCreateObjectWithExcludedKeys(gate, glue);
break;
case CREATEREGEXPWITHLITERAL_PREF_ID32_IMM8:
LowerCreateRegExpWithLiteral(gate, glue);
LowerCreateRegExpWithLiteral(gate, glue, jsFunc);
break;
case STOWNBYVALUE_PREF_V8_V8:
LowerStOwnByValue(gate, glue);
@ -561,7 +552,7 @@ void SlowPathLowering::Lower(GateRef gate)
LowerStOwnByIndex(gate, glue);
break;
case STOWNBYNAME_PREF_ID32_V8:
LowerStOwnByName(gate, glue);
LowerStOwnByName(gate, glue, jsFunc);
break;
case DEFINEGENERATORFUNC_PREF_ID16_IMM16_V8:
LowerDefineGeneratorFunc(gate, glue, jsFunc);
@ -588,31 +579,31 @@ void SlowPathLowering::Lower(GateRef gate)
LowerStSuperByValue(gate, glue, jsFunc);
break;
case TRYSTGLOBALBYNAME_PREF_ID32:
LowerTryStGlobalByName(gate, glue);
LowerTryStGlobalByName(gate, glue, jsFunc);
break;
case STCONSTTOGLOBALRECORD_PREF_ID32:
LowerStConstToGlobalRecord(gate, glue);
LowerStConstToGlobalRecord(gate, glue, jsFunc);
break;
case STLETTOGLOBALRECORD_PREF_ID32:
LowerStLetToGlobalRecord(gate, glue);
LowerStLetToGlobalRecord(gate, glue, jsFunc);
break;
case STCLASSTOGLOBALRECORD_PREF_ID32:
LowerStClassToGlobalRecord(gate, glue);
LowerStClassToGlobalRecord(gate, glue, jsFunc);
break;
case STOWNBYVALUEWITHNAMESET_PREF_V8_V8:
LowerStOwnByValueWithNameSet(gate, glue);
break;
case STOWNBYNAMEWITHNAMESET_PREF_ID32_V8:
LowerStOwnByNameWithNameSet(gate, glue);
LowerStOwnByNameWithNameSet(gate, glue, jsFunc);
break;
case LDGLOBALVAR_PREF_ID32:
LowerLdGlobalVar(gate, glue);
LowerLdGlobalVar(gate, glue, jsFunc);
break;
case LDOBJBYNAME_PREF_ID32_V8:
LowerLdObjByName(gate, glue);
LowerLdObjByName(gate, glue, jsFunc);
break;
case STOBJBYNAME_PREF_ID32_V8:
LowerStObjByName(gate, glue);
LowerStObjByName(gate, glue, jsFunc);
break;
case DEFINEGETTERSETTERBYVALUE_PREF_V8_V8_V8_V8:
LowerDefineGetterSetterByValue(gate, glue);
@ -828,11 +819,13 @@ void SlowPathLowering::LowerAsyncFunctionReject(GateRef gate, GateRef glue)
ReplaceHirToCall(gate, newGate);
}
void SlowPathLowering::LowerLoadStr(GateRef gate, GateRef glue)
void SlowPathLowering::LowerLoadStr(GateRef gate, GateRef glue, GateRef jsFunc)
{
DebugPrintBC(gate, glue, builder_.Int32(GET_MESSAGE_STRING_ID(HandleLdaStrId32)));
GateRef newGate = GetValueFromConstStringTable(glue, gate, 0);
ReplaceHirToCall(gate, newGate);
GateRef newGate = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
std::vector<GateRef> successControl {builder_.GetState(), builder_.GetDepend()};
std::vector<GateRef> failControl {Circuit::NullGate(), Circuit::NullGate()};
ReplaceHirToSubCfg(gate, newGate, successControl, failControl, true);
}
void SlowPathLowering::LowerLexicalEnv(GateRef gate, GateRef glue)
@ -843,12 +836,11 @@ void SlowPathLowering::LowerLexicalEnv(GateRef gate, GateRef glue)
ReplaceHirToCall(gate, newGate, true);
}
void SlowPathLowering::LowerTryLdGlobalByName(GateRef gate, GateRef glue)
void SlowPathLowering::LowerTryLdGlobalByName(GateRef gate, GateRef glue, GateRef jsFunc)
{
DebugPrintBC(gate, glue, builder_.Int32(GET_MESSAGE_STRING_ID(HandleTryLdGlobalByNamePrefId32)));
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), acc_.GetValueIn(gate, 0));
GateRef stringId = builder_.TaggedTypeNGC(builder_.ZExtInt32ToInt64(acc_.GetValueIn(gate, 0)));
GateRef prop = LowerCallRuntime(glue, RTSTUB_ID(LoadValueFromConstantStringTable), { stringId }, true);
GateRef prop = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
GateRef recordResult = LowerCallRuntime(glue, RTSTUB_ID(LdGlobalRecord), {prop}, true);
Label isFound(&builder_);
Label isNotFound(&builder_);
@ -882,15 +874,18 @@ void SlowPathLowering::LowerTryLdGlobalByName(GateRef gate, GateRef glue)
ReplaceHirToSubCfg(gate, value, successControl, failControl);
}
void SlowPathLowering::LowerStGlobalVar(GateRef gate, GateRef glue)
void SlowPathLowering::LowerStGlobalVar(GateRef gate, GateRef glue, GateRef jsFunc)
{
DebugPrintBC(gate, glue, builder_.Int32(GET_MESSAGE_STRING_ID(HandleStGlobalVarPrefId32)));
GateRef prop = GetValueFromConstStringTable(glue, gate, 0);
acc_.SetDep(gate, prop);
Label successExit(&builder_);
Label exceptionExit(&builder_);
GateRef prop = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
const int id = RTSTUB_ID(StGlobalVar);
ASSERT(acc_.GetNumValueIn(gate) == 2); // 2: number of value inputs
GateRef newGate = LowerCallRuntime(glue, id, {prop, acc_.GetValueIn(gate, 1)});
ReplaceHirToCall(gate, newGate);
builder_.Branch(builder_.IsSpecial(newGate, JSTaggedValue::VALUE_EXCEPTION), &exceptionExit, &successExit);
CREATE_DOUBLE_EXIT(successExit, exceptionExit)
ReplaceHirToSubCfg(gate, newGate, successControl, failControl);
}
void SlowPathLowering::LowerGetIterator(GateRef gate, GateRef glue)
@ -1564,8 +1559,7 @@ void SlowPathLowering::LowerStModuleVar(GateRef gate, GateRef glue, GateRef jsFu
std::vector<GateRef> failControl;
// 2: number of value inputs
ASSERT(acc_.GetNumValueIn(gate) == 2);
GateRef stringId = builder_.TaggedTypeNGC(builder_.ZExtInt32ToInt64(acc_.GetValueIn(gate, 0)));
GateRef prop = LowerCallRuntime(glue, RTSTUB_ID(LoadValueFromConstantStringTable), { stringId }, true);
GateRef prop = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
GateRef result = LowerCallRuntime(glue, RTSTUB_ID(StModuleVarOnJSFunc),
{ prop, acc_.GetValueIn(gate, 1), jsFunc }, true);
successControl.emplace_back(builder_.GetState());
@ -1599,15 +1593,14 @@ void SlowPathLowering::LowerSetObjectWithProto(GateRef gate, GateRef glue)
ReplaceHirToCall(gate, newGate);
}
void SlowPathLowering::LowerLdBigInt(GateRef gate, GateRef glue)
void SlowPathLowering::LowerLdBigInt(GateRef gate, GateRef glue, GateRef jsFunc)
{
DebugPrintBC(gate, glue, builder_.Int32(GET_MESSAGE_STRING_ID(HandleLdBigIntPrefId32)));
Label successExit(&builder_);
Label exceptionExit(&builder_);
// 1: number of value inputs
ASSERT(acc_.GetNumValueIn(gate) == 1);
GateRef stringId = builder_.TaggedTypeNGC(builder_.ZExtInt32ToInt64(acc_.GetValueIn(gate, 0)));
GateRef numberBigInt = LowerCallRuntime(glue, RTSTUB_ID(LoadValueFromConstantStringTable), { stringId }, true);
GateRef numberBigInt = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
GateRef result = LowerCallRuntime(glue, RTSTUB_ID(LdBigInt), {numberBigInt}, true);
builder_.Branch(builder_.IsSpecial(result, JSTaggedValue::VALUE_EXCEPTION),
&exceptionExit, &successExit);
@ -1632,8 +1625,7 @@ void SlowPathLowering::LowerLdModuleVar(GateRef gate, GateRef glue, GateRef jsFu
std::vector<GateRef> failControl;
// 2: number of value inputs
ASSERT(acc_.GetNumValueIn(gate) == 2);
GateRef stringId = builder_.TaggedTypeNGC(builder_.ZExtInt32ToInt64(acc_.GetValueIn(gate, 0)));
GateRef key = LowerCallRuntime(glue, RTSTUB_ID(LoadValueFromConstantStringTable), { stringId }, true);
GateRef key = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
GateRef inner = builder_.TaggedTypeNGC(acc_.GetValueIn(gate, 1));
GateRef result = LowerCallRuntime(glue, RTSTUB_ID(LdModuleVarOnJSFunc), {key, inner, jsFunc}, true);
successControl.emplace_back(builder_.GetState());
@ -1650,8 +1642,7 @@ void SlowPathLowering::LowerGetModuleNamespace(GateRef gate, GateRef glue, GateR
std::vector<GateRef> failControl;
// 1: number of value inputs
ASSERT(acc_.GetNumValueIn(gate) == 1);
GateRef stringId = builder_.TaggedTypeNGC(builder_.ZExtInt32ToInt64(acc_.GetValueIn(gate, 0)));
GateRef localName = LowerCallRuntime(glue, RTSTUB_ID(LoadValueFromConstantStringTable), { stringId }, true);
GateRef localName = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
GateRef result = LowerCallRuntime(glue, RTSTUB_ID(GetModuleNamespaceOnJSFunc), { localName, jsFunc }, true);
successControl.emplace_back(builder_.GetState());
successControl.emplace_back(builder_.GetDepend());
@ -1852,16 +1843,20 @@ void SlowPathLowering::LowerCreateObjectWithExcludedKeys(GateRef gate, GateRef g
ReplaceHirToCall(gate, newGate);
}
void SlowPathLowering::LowerCreateRegExpWithLiteral(GateRef gate, GateRef glue)
void SlowPathLowering::LowerCreateRegExpWithLiteral(GateRef gate, GateRef glue, GateRef jsFunc)
{
DebugPrintBC(gate, glue, builder_.Int32(GET_MESSAGE_STRING_ID(HandleCreateRegExpWithLiteralPrefId32Imm8)));
Label successExit(&builder_);
Label exceptionExit(&builder_);
const int id = RTSTUB_ID(CreateRegExpWithLiteral);
// 2: number of value inputs
ASSERT(acc_.GetNumValueIn(gate) == 2);
GateRef pattern = GetValueFromConstStringTable(glue, gate, 0);
GateRef pattern = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
GateRef flags = acc_.GetValueIn(gate, 1);
GateRef newGate = LowerCallRuntime(glue, id, { pattern, builder_.TaggedTypeNGC(flags) });
ReplaceHirToCall(gate, newGate);
builder_.Branch(builder_.IsSpecial(newGate, JSTaggedValue::VALUE_EXCEPTION), &exceptionExit, &successExit);
CREATE_DOUBLE_EXIT(successExit, exceptionExit)
ReplaceHirToSubCfg(gate, newGate, successControl, failControl);
}
void SlowPathLowering::LowerStOwnByValue(GateRef gate, GateRef glue)
@ -1949,13 +1944,12 @@ void SlowPathLowering::LowerStOwnByIndex(GateRef gate, GateRef glue)
ReplaceHirToSubCfg(gate, Circuit::NullGate(), successControl, failControl);
}
void SlowPathLowering::LowerStOwnByName(GateRef gate, GateRef glue)
void SlowPathLowering::LowerStOwnByName(GateRef gate, GateRef glue, GateRef jsFunc)
{
DebugPrintBC(gate, glue, builder_.Int32(GET_MESSAGE_STRING_ID(HandleStOwnByNamePrefId32V8)));
// 3: number of value inputs
ASSERT(acc_.GetNumValueIn(gate) == 3);
auto args = { builder_.TaggedTypeNGC(builder_.ZExtInt32ToInt64(acc_.GetValueIn(gate, 0))) };
GateRef propKey = LowerCallRuntime(glue, RTSTUB_ID(LoadValueFromConstantStringTable), args, true);
GateRef propKey = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
GateRef receiver = acc_.GetValueIn(gate, 1);
GateRef accValue = acc_.GetValueIn(gate, 2);
// we do not need to merge outValueGate, so using GateRef directly instead of using Variable
@ -2209,15 +2203,14 @@ void SlowPathLowering::LowerStSuperByValue(GateRef gate, GateRef glue, GateRef j
ReplaceHirToCall(gate, newGate);
}
void SlowPathLowering::LowerTryStGlobalByName(GateRef gate, GateRef glue)
void SlowPathLowering::LowerTryStGlobalByName(GateRef gate, GateRef glue, GateRef jsFunc)
{
DebugPrintBC(gate, glue, builder_.Int32(GET_MESSAGE_STRING_ID(HandleTryStGlobalByNamePrefId32)));
// order: 1. global record 2. global object
DEFVAlUE(res, (&builder_), VariableType::JS_ANY(), builder_.Int64(JSTaggedValue::VALUE_HOLE));
// 2 : number of value inputs
ASSERT(acc_.GetNumValueIn(gate) == 2);
GateRef stringId = builder_.TaggedTypeNGC(builder_.ZExtInt32ToInt64(acc_.GetValueIn(gate, 0)));
GateRef propKey = LowerCallRuntime(glue, RTSTUB_ID(LoadValueFromConstantStringTable), { stringId }, true);
GateRef propKey = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
Label isUndefined(&builder_);
Label notUndefined(&builder_);
Label successExit(&builder_);
@ -2257,10 +2250,12 @@ void SlowPathLowering::LowerTryStGlobalByName(GateRef gate, GateRef glue)
ReplaceHirToSubCfg(gate, Circuit::NullGate(), successControl, failControl);
}
void SlowPathLowering::LowerStConstToGlobalRecord(GateRef gate, GateRef glue)
void SlowPathLowering::LowerStConstToGlobalRecord(GateRef gate, GateRef glue, GateRef jsFunc)
{
DebugPrintBC(gate, glue, builder_.Int32(GET_MESSAGE_STRING_ID(HandleStConstToGlobalRecordPrefId32)));
GateRef propKey = GetValueFromConstStringTable(glue, gate, 0);
Label successExit(&builder_);
Label exceptionExit(&builder_);
GateRef propKey = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
acc_.SetDep(gate, propKey);
// 2 : number of value inputs
ASSERT(acc_.GetNumValueIn(gate) == 2);
@ -2268,18 +2263,19 @@ void SlowPathLowering::LowerStConstToGlobalRecord(GateRef gate, GateRef glue)
GateRef value = acc_.GetValueIn(gate, 1);
GateRef isConst = builder_.TaggedTrue();
GateRef newGate = LowerCallRuntime(glue, id, { propKey, value, isConst });
ReplaceHirToCall(gate, newGate);
builder_.Branch(builder_.IsSpecial(newGate, JSTaggedValue::VALUE_EXCEPTION), &exceptionExit, &successExit);
CREATE_DOUBLE_EXIT(successExit, exceptionExit)
ReplaceHirToSubCfg(gate, newGate, successControl, failControl);
}
void SlowPathLowering::LowerStLetToGlobalRecord(GateRef gate, GateRef glue)
void SlowPathLowering::LowerStLetToGlobalRecord(GateRef gate, GateRef glue, GateRef jsFunc)
{
DebugPrintBC(gate, glue, builder_.Int32(GET_MESSAGE_STRING_ID(HandleStLetToGlobalRecordPrefId32)));
Label successExit(&builder_);
Label exceptionExit(&builder_);
// 2: number of value inputs
ASSERT(acc_.GetNumValueIn(gate) == 2);
GateRef stringId = builder_.TaggedTypeNGC(builder_.ZExtInt32ToInt64(acc_.GetValueIn(gate, 0)));
GateRef prop = LowerCallRuntime(glue, RTSTUB_ID(LoadValueFromConstantStringTable), { stringId }, true);
GateRef prop = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
GateRef taggedFalse = builder_.TaggedFalse();
GateRef result = LowerCallRuntime(glue, RTSTUB_ID(StGlobalRecord),
{prop, acc_.GetValueIn(gate, 1), taggedFalse}, true);
@ -2289,15 +2285,14 @@ void SlowPathLowering::LowerStLetToGlobalRecord(GateRef gate, GateRef glue)
ReplaceHirToSubCfg(gate, Circuit::NullGate(), successControl, failControl);
}
void SlowPathLowering::LowerStClassToGlobalRecord(GateRef gate, GateRef glue)
void SlowPathLowering::LowerStClassToGlobalRecord(GateRef gate, GateRef glue, GateRef jsFunc)
{
DebugPrintBC(gate, glue, builder_.Int32(GET_MESSAGE_STRING_ID(HandleStClassToGlobalRecordPrefId32)));
Label successExit(&builder_);
Label exceptionExit(&builder_);
// 2: number of value inputs
ASSERT(acc_.GetNumValueIn(gate) == 2);
GateRef stringId = builder_.TaggedTypeNGC(builder_.ZExtInt32ToInt64(acc_.GetValueIn(gate, 0)));
GateRef prop = LowerCallRuntime(glue, RTSTUB_ID(LoadValueFromConstantStringTable), { stringId }, true);
GateRef prop = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
GateRef taggedFalse = builder_.TaggedFalse();
GateRef result = LowerCallRuntime(glue, RTSTUB_ID(StGlobalRecord),
{prop, acc_.GetValueIn(gate, 1), taggedFalse}, true);
@ -2358,13 +2353,12 @@ void SlowPathLowering::LowerStOwnByValueWithNameSet(GateRef gate, GateRef glue)
ReplaceHirToSubCfg(gate, Circuit::NullGate(), successControl, failControl);
}
void SlowPathLowering::LowerStOwnByNameWithNameSet(GateRef gate, GateRef glue)
void SlowPathLowering::LowerStOwnByNameWithNameSet(GateRef gate, GateRef glue, GateRef jsFunc)
{
DebugPrintBC(gate, glue, builder_.Int32(GET_MESSAGE_STRING_ID(HandleStOwnByNameWithNameSetPrefId32V8)));
// 3: number of value inputs
ASSERT(acc_.GetNumValueIn(gate) == 3);
GateRef stringId = builder_.TaggedTypeNGC(builder_.ZExtInt32ToInt64(acc_.GetValueIn(gate, 0)));
GateRef propKey = LowerCallRuntime(glue, RTSTUB_ID(LoadValueFromConstantStringTable), { stringId }, true);
GateRef propKey = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
GateRef receiver = acc_.GetValueIn(gate, 1);
GateRef accValue = acc_.GetValueIn(gate, 2);
GateRef result;
@ -2410,7 +2404,7 @@ void SlowPathLowering::LowerStOwnByNameWithNameSet(GateRef gate, GateRef glue)
ReplaceHirToSubCfg(gate, Circuit::NullGate(), successControl, failControl);
}
void SlowPathLowering::LowerLdGlobalVar(GateRef gate, GateRef glue)
void SlowPathLowering::LowerLdGlobalVar(GateRef gate, GateRef glue, GateRef jsFunc)
{
DebugPrintBC(gate, glue, builder_.Int32(GET_MESSAGE_STRING_ID(HandleLdGlobalVarPrefId32)));
std::vector<GateRef> successControl;
@ -2421,8 +2415,7 @@ void SlowPathLowering::LowerLdGlobalVar(GateRef gate, GateRef glue)
GateRef ret;
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.Undefined());
ASSERT(acc_.GetNumValueIn(gate) == 1);
GateRef stringId = builder_.TaggedTypeNGC(builder_.ZExtInt32ToInt64(acc_.GetValueIn(gate, 0)));
GateRef propKey = LowerCallRuntime(glue, RTSTUB_ID(LoadValueFromConstantStringTable), { stringId }, true);
GateRef propKey = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
GateRef globalObject = builder_.GetGlobalObject(glue);
result = LowerCallRuntime(glue, RTSTUB_ID(GetGlobalOwnProperty), { propKey }, true);
builder_.Branch(builder_.IsSpecial(*result, JSTaggedValue::VALUE_HOLE),
@ -2447,7 +2440,7 @@ void SlowPathLowering::LowerLdGlobalVar(GateRef gate, GateRef glue)
ReplaceHirToSubCfg(gate, ret, successControl, failControl);
}
void SlowPathLowering::LowerLdObjByName(GateRef gate, GateRef glue)
void SlowPathLowering::LowerLdObjByName(GateRef gate, GateRef glue, GateRef jsFunc)
{
DebugPrintBC(gate, glue, builder_.Int32(GET_MESSAGE_STRING_ID(HandleLdObjByNamePrefId32V8)));
std::vector<GateRef> successControl;
@ -2462,8 +2455,7 @@ void SlowPathLowering::LowerLdObjByName(GateRef gate, GateRef glue)
// 2: number of value inputs
ASSERT(acc_.GetNumValueIn(gate) == 2);
GateRef receiver = acc_.GetValueIn(gate, 1);
GateRef stringId = builder_.TaggedTypeNGC(builder_.ZExtInt32ToInt64(acc_.GetValueIn(gate, 0)));
GateRef prop = LowerCallRuntime(glue, RTSTUB_ID(LoadValueFromConstantStringTable), {stringId}, true);
GateRef prop = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
builder_.Branch(builder_.TaggedIsHeapObject(receiver), &receiverIsHeapObject, &slowPath);
builder_.Bind(&receiverIsHeapObject);
{
@ -2497,7 +2489,7 @@ void SlowPathLowering::LowerLdObjByName(GateRef gate, GateRef glue)
ReplaceHirToSubCfg(gate, result, successControl, failControl);
}
void SlowPathLowering::LowerStObjByName(GateRef gate, GateRef glue)
void SlowPathLowering::LowerStObjByName(GateRef gate, GateRef glue, GateRef jsFunc)
{
DebugPrintBC(gate, glue, builder_.Int32(GET_MESSAGE_STRING_ID(HandleStObjByNamePrefId32V8)));
Label receiverIsHeapObject(&builder_);
@ -2506,8 +2498,7 @@ void SlowPathLowering::LowerStObjByName(GateRef gate, GateRef glue)
Label exceptionExit(&builder_);
// 3: number of value inputs
ASSERT(acc_.GetNumValueIn(gate) == 3);
GateRef stringId = builder_.TaggedTypeNGC(builder_.ZExtInt32ToInt64(acc_.GetValueIn(gate, 0)));
GateRef prop = LowerCallRuntime(glue, RTSTUB_ID(LoadValueFromConstantStringTable), {stringId}, true);
GateRef prop = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
GateRef receiver = acc_.GetValueIn(gate, 1);
GateRef result;
builder_.Branch(builder_.TaggedIsHeapObject(receiver), &receiverIsHeapObject, &slowPath);
@ -2727,8 +2718,7 @@ void SlowPathLowering::LowerLdSuperByName(GateRef gate, GateRef glue, GateRef js
Label exceptionExit(&builder_);
// 2: number of value inputs
ASSERT(acc_.GetNumValueIn(gate) == 2);
auto args1 = { builder_.TaggedTypeNGC(builder_.ZExtInt32ToInt64(acc_.GetValueIn(gate, 0))) };
GateRef prop = LowerCallRuntime(glue, RTSTUB_ID(LoadValueFromConstantStringTable), args1, true);
GateRef prop = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
GateRef result =
LowerCallRuntime(glue, RTSTUB_ID(OptLdSuperByValue), {acc_.GetValueIn(gate, 1), prop, jsFunc}, true);
builder_.Branch(builder_.IsSpecial(result, JSTaggedValue::VALUE_EXCEPTION),
@ -2744,8 +2734,7 @@ void SlowPathLowering::LowerStSuperByName(GateRef gate, GateRef glue, GateRef js
Label exceptionExit(&builder_);
// 3: number of value inputs
ASSERT(acc_.GetNumValueIn(gate) == 3);
auto args1 = { builder_.TaggedTypeNGC(builder_.ZExtInt32ToInt64(acc_.GetValueIn(gate, 0))) };
GateRef prop = LowerCallRuntime(glue, RTSTUB_ID(LoadValueFromConstantStringTable), args1, true);
GateRef prop = GetObjectFromConstPool(jsFunc, acc_.GetValueIn(gate, 0));
auto args2 = { acc_.GetValueIn(gate, 1), prop, acc_.GetValueIn(gate, 2), jsFunc };
GateRef result = LowerCallRuntime(glue, RTSTUB_ID(OptStSuperByValue), args2, true);
builder_.Branch(builder_.IsSpecial(result, JSTaggedValue::VALUE_EXCEPTION),

View File

@ -149,7 +149,6 @@ private:
GateRef GetObjectFromConstPool(GateRef jsFunc, GateRef index);
// environment must be initialized
GateRef GetHomeObjectFromJSFunction(GateRef jsFunc);
GateRef GetValueFromConstStringTable(GateRef glue, GateRef gate, uint32_t inIndex);
void Lower(GateRef gate);
void LowerAdd2Dyn(GateRef gate, GateRef glue);
void LowerCreateIterResultObj(GateRef gate, GateRef glue);
@ -158,10 +157,10 @@ private:
void LowerAsyncFunctionAwaitUncaught(GateRef gate, GateRef glue);
void LowerAsyncFunctionResolve(GateRef gate, GateRef glue);
void LowerAsyncFunctionReject(GateRef gate, GateRef glue);
void LowerLoadStr(GateRef gate, GateRef glue);
void LowerLoadStr(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerLexicalEnv(GateRef gate, GateRef glue);
void LowerStGlobalVar(GateRef gate, GateRef glue);
void LowerTryLdGlobalByName(GateRef gate, GateRef glue);
void LowerStGlobalVar(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerTryLdGlobalByName(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerGetIterator(GateRef gate, GateRef glue);
void LowerToJSCall(GateRef gate, GateRef glue, const std::vector<GateRef> &args);
void LowerCallArg0Dyn(GateRef gate, GateRef glue);
@ -219,7 +218,7 @@ private:
void LowerStModuleVar(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerGetTemplateObject(GateRef gate, GateRef glue);
void LowerSetObjectWithProto(GateRef gate, GateRef glue);
void LowerLdBigInt(GateRef gate, GateRef glue);
void LowerLdBigInt(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerToNumeric(GateRef gate, GateRef glue);
void LowerLdModuleVar(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerGetModuleNamespace(GateRef gate, GateRef glue, GateRef jsFunc);
@ -232,10 +231,10 @@ private:
void LowerGetNextPropName(GateRef gate, GateRef glue);
void LowerCopyDataProperties(GateRef gate, GateRef glue);
void LowerCreateObjectWithExcludedKeys(GateRef gate, GateRef glue);
void LowerCreateRegExpWithLiteral(GateRef gate, GateRef glue);
void LowerCreateRegExpWithLiteral(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerStOwnByValue(GateRef gate, GateRef glue);
void LowerStOwnByIndex(GateRef gate, GateRef glue);
void LowerStOwnByName(GateRef gate, GateRef glue);
void LowerStOwnByName(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerDefineFuncDyn(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerDefineGeneratorFunc(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerDefineAsyncGeneratorFunc(GateRef gate, GateRef glue, GateRef jsFunc);
@ -245,15 +244,15 @@ private:
void LowerPopLexicalEnv(GateRef gate, GateRef glue);
void LowerLdSuperByValue(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerStSuperByValue(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerTryStGlobalByName(GateRef gate, GateRef glue);
void LowerStConstToGlobalRecord(GateRef gate, GateRef glue);
void LowerStLetToGlobalRecord(GateRef gate, GateRef glue);
void LowerStClassToGlobalRecord(GateRef gate, GateRef glue);
void LowerTryStGlobalByName(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerStConstToGlobalRecord(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerStLetToGlobalRecord(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerStClassToGlobalRecord(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerStOwnByValueWithNameSet(GateRef gate, GateRef glue);
void LowerStOwnByNameWithNameSet(GateRef gate, GateRef glue);
void LowerLdGlobalVar(GateRef gate, GateRef glue);
void LowerLdObjByName(GateRef gate, GateRef glue);
void LowerStObjByName(GateRef gate, GateRef glue);
void LowerStOwnByNameWithNameSet(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerLdGlobalVar(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerLdObjByName(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerStObjByName(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerLdSuperByName(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerStSuperByName(GateRef gate, GateRef glue, GateRef jsFunc);
void LowerDefineGetterSetterByValue(GateRef gate, GateRef glue);

View File

@ -15,6 +15,7 @@
#include "ecmascript/compiler/type_inference/type_infer.h"
#include "ecmascript/jspandafile/js_pandafile_manager.h"
#include "ecmascript/jspandafile/program_object.h"
namespace panda::ecmascript::kungfu {
void TypeInfer::TraverseCircuit()
@ -364,8 +365,9 @@ bool TypeInfer::InferLdObjByName(GateRef gate)
if (objType.IsTSType()) {
// If this object has no gt type, we cannot get its internal property type
if (IsObjectOrClass(objType)) {
auto constantPool = builder_->GetConstantPool().GetObject<ConstantPool>();
auto index = gateAccessor_.GetBitField(gateAccessor_.GetValueIn(gate, 0));
auto name = tsManager_->GetStringById(index);
auto name = constantPool->GetObjectFromCache(index);
auto type = GetPropType(objType, name);
return UpdateType(gate, type);
}
@ -496,9 +498,10 @@ void TypeInfer::TypeCheck(GateRef gate) const
return;
}
auto funcName = gateAccessor_.GetValueIn(func, 0);
if (tsManager_->GetStdStringById(gateAccessor_.GetBitField(funcName)) == "AssertType") {
auto constantPool = builder_->GetConstantPool().GetObject<ConstantPool>();
if (constantPool->GetStdStringByIdx(gateAccessor_.GetBitField(funcName)) == "AssertType") {
GateRef expectedGate = gateAccessor_.GetValueIn(gateAccessor_.GetValueIn(gate, 2), 0);
auto expectedTypeStr = tsManager_->GetStdStringById(gateAccessor_.GetBitField(expectedGate));
auto expectedTypeStr = constantPool->GetStdStringByIdx(gateAccessor_.GetBitField(expectedGate));
GateRef valueGate = gateAccessor_.GetValueIn(gate, 1);
auto type = gateAccessor_.GetGateType(valueGate);
if (expectedTypeStr != tsManager_->GetTypeStr(type)) {

View File

@ -73,7 +73,7 @@ private:
bool InferSuperCall(GateRef gate);
bool InferTryLdGlobalByName(GateRef gate);
inline GlobalTSTypeRef GetPropType(const GateType &type, const JSHandle<EcmaString> propertyName) const
inline GlobalTSTypeRef GetPropType(const GateType &type, const JSTaggedValue propertyName) const
{
return tsManager_->GetPropType(type, propertyName);
}

View File

@ -314,7 +314,7 @@ void FileLoader::LoadSnapshotFile()
CString snapshotPath = snapshotArg + ".etso";
Snapshot snapshot(vm_);
#if !defined(PANDA_TARGET_WINDOWS) && !defined(PANDA_TARGET_MACOS)
snapshot.Deserialize(SnapshotType::TS_LOADER, snapshotPath);
snapshot.Deserialize(SnapshotType::ETSO, snapshotPath);
#endif
}

View File

@ -29,6 +29,7 @@
#include "ecmascript/tagged_array.h"
#include "ecmascript/ts_types/ts_manager.h"
#include "ecmascript/ts_types/ts_type_table.h"
#include "ecmascript/snapshot/mem/snapshot_processor.h"
#include "libpandabase/utils/utf.h"
#include "libpandafile/bytecode_instruction-inl.h"
#include "libpandafile/class_data_accessor-inl.h"
@ -143,9 +144,22 @@ JSTaggedValue PandaFileTranslator::ParseConstPool(EcmaVM *vm, const JSPandaFile
const CUnorderedMap<uint32_t, uint64_t> &constpoolMap = jsPandaFile->GetConstpoolMap();
const bool isLoadedAOT = jsPandaFile->IsLoadedAOT();
auto fileLoader = vm->GetFileLoader();
#if !defined(PANDA_TARGET_WINDOWS) && !defined(PANDA_TARGET_MACOS)
if (isLoadedAOT) {
JSTaggedValue constPoolInfo = vm->GetTSManager()->GetConstantPoolInfo();
ConstantPoolProcessor::RestoreConstantPoolInfo(vm->GetJSThread(), constPoolInfo, jsPandaFile, constpool);
}
#endif
for (const auto &it : constpoolMap) {
ConstPoolValue value(it.second);
if (value.GetConstpoolType() == ConstPoolType::STRING) {
#if !defined(PANDA_TARGET_WINDOWS) && !defined(PANDA_TARGET_MACOS)
if (isLoadedAOT) {
continue;
}
#endif
panda_file::File::EntityId id(it.first);
auto foundStr = pf->GetStringData(id);
auto string = factory->GetRawStringFromStringTable(foundStr.data, foundStr.utf16_length, foundStr.is_ascii,

View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecmascript/jspandafile/program_object.h"
namespace panda::ecmascript {
std::string ConstantPool::GetStdStringByIdx(size_t index) const
{
JSTaggedType str = GetObjectFromCache(index).GetRawData();
return JSHandle<EcmaString>(reinterpret_cast<uintptr_t>(&str))->GetCString().get();
}
}

View File

@ -48,6 +48,8 @@ public:
return Get(index);
}
std::string PUBLIC_API GetStdStringByIdx(size_t index) const;
DECL_DUMP()
};
} // namespace ecmascript

View File

@ -26,6 +26,7 @@
#include "ecmascript/jspandafile/program_object.h"
#include "ecmascript/js_hclass.h"
#include "ecmascript/js_thread.h"
#include "ecmascript/file_loader.h"
#include "ecmascript/jspandafile/js_pandafile_manager.h"
#include "ecmascript/mem/c_containers.h"
#include "ecmascript/mem/heap.h"
@ -34,6 +35,21 @@
#include "ecmascript/ts_types/ts_manager.h"
namespace panda::ecmascript {
void Snapshot::Serialize(const CString &fileName)
{
JSThread *thread = vm_->GetJSThread();
TSManager *tsManager = vm_->GetTSManager();
CVector<JSTaggedType> staticHClassTable = tsManager->GetStaticHClassTable();
uint32_t staticHClassTableLen = staticHClassTable.size();
JSHandle<TaggedArray> root = vm_->GetFactory()->NewTaggedArray(staticHClassTableLen + 1);
root->Set(thread, 0, tsManager->GetConstantPoolInfo());
for (uint32_t i = 0; i < staticHClassTableLen; ++i) {
root->Set(thread, i + 1, JSTaggedValue(staticHClassTable[i]));
}
Serialize(root.GetTaggedValue().GetTaggedObject(), nullptr, fileName);
}
void Snapshot::Serialize(TaggedObject *objectHeader, const panda_file::File *pf, const CString &fileName)
{
std::pair<bool, CString> filePath = VerifyFilePath(fileName, true);
@ -156,13 +172,6 @@ const JSPandaFile *Snapshot::Deserialize(SnapshotType type, const CString &snaps
uintptr_t stringEnd = stringBegin + hdr.stringSize;
processor.DeserializeString(stringBegin, stringEnd);
if (type == SnapshotType::TS_LOADER) {
auto stringVector = processor.GetStringVector();
for (uint32_t i = 0; i < stringVector.size(); ++i) {
JSTaggedValue result(reinterpret_cast<EcmaString *>(stringVector[i]));
vm_->GetTSManager()->AddConstString(result);
}
}
munmap(ToNativePtr<void>(readFile), hdr.pandaFileBegin);
const JSPandaFile *jsPandaFile = nullptr;
if (static_cast<uint32_t>(file_size) > hdr.pandaFileBegin) {

View File

@ -34,6 +34,7 @@ public:
explicit Snapshot(EcmaVM *vm) : vm_(vm) {}
~Snapshot() = default;
void Serialize(const CString &fileName = "./snapshot");
void Serialize(TaggedObject *objectHeader, const panda_file::File *pf, const CString &fileName = "./snapshot");
void Serialize(uintptr_t startAddr, size_t size, const CString &fileName = "./snapshot");
void SerializeBuiltins(const CString &fileName = "./snapshot");

View File

@ -1254,10 +1254,21 @@ void SnapshotProcessor::HandleRootObject(SnapshotType type, uintptr_t rootObject
constSpecialIndex++;
break;
}
case SnapshotType::TS_LOADER: {
if (JSType(objType) == JSType::HCLASS) {
case SnapshotType::ETSO: {
JSTaggedValue item = JSTaggedValue(rootObjectAddr);
if (item.IsTaggedArray()) {
JSHandle<TaggedArray> root(vm_->GetJSThread(), item);
TSManager *tsManager = vm_->GetTSManager();
tsManager->AddStaticHClassInRuntimePhase(JSTaggedValue(rootObjectAddr));
// Get ConstPoolInfo
JSTaggedValue constPoolInfo = root->Get(0);
tsManager->SetConstantPoolInfo(constPoolInfo);
// Get StaticHClass
uint32_t len = root->GetLength();
for (uint32_t i = 1; i < len; ++i) {
tsManager->AddStaticHClassInRuntimePhase(root->Get(i));
}
}
break;
}
@ -1428,6 +1439,11 @@ void SnapshotProcessor::DeserializeTaggedField(uint64_t *value)
*value = vm_->GetSnapshotEnv()->FindEnvObjectByIndex(index);
return;
}
if (!encodeBit.IsReference()) {
return;
}
if (encodeBit.IsReference() && !encodeBit.IsSpecial()) {
uintptr_t taggedObjectAddr = TaggedObjectEncodeBitToAddr(encodeBit);
*value = taggedObjectAddr;
@ -1656,4 +1672,57 @@ size_t SnapshotProcessor::GetNativeTableSize() const
{
return sizeof(g_nativeTable) / sizeof(g_nativeTable[0]);
}
void ConstantPoolProcessor::InitializeConstantPoolInfos(size_t nums)
{
ObjectFactory *factory = vm_->GetFactory();
infos_ = factory->NewTaggedArray(nums * ITEM_SIZE).GetTaggedValue();
}
void ConstantPoolProcessor::CollectConstantPoolInfo(const JSPandaFile* pf, const JSHandle<JSTaggedValue> constantPool)
{
JSThread *thread = vm_->GetJSThread();
JSHandle<TaggedArray> array(thread, infos_);
ASSERT(index_ < array->GetLength());
JSHandle<ConstantPool> cp(thread, constantPool.GetTaggedValue());
array->Set(thread, index_++, JSTaggedValue(pf->GetFileUniqId()));
array->Set(thread, index_++, GenerateConstantPoolInfo(cp));
}
JSTaggedValue ConstantPoolProcessor::GenerateConstantPoolInfo(const JSHandle<ConstantPool> constantPool)
{
ObjectFactory *factory = vm_->GetFactory();
JSThread *thread = vm_->GetJSThread();
uint32_t len = constantPool->GetLength();
JSHandle<TaggedArray> valueArray = factory->NewTaggedArray(len * ITEM_SIZE);
int index = 0;
for (uint32_t i = 0; i < len; ++i) {
JSTaggedValue item = constantPool->GetObjectFromCache(i);
if (item.GetTaggedObject()->GetClass()->IsString()) {
valueArray->Set(thread, index++, JSTaggedValue(i));
valueArray->Set(thread, index++, item);
}
}
valueArray = TaggedArray::SetCapacity(thread, valueArray, index);
return valueArray.GetTaggedValue();
}
void ConstantPoolProcessor::RestoreConstantPoolInfo(JSThread *thread, JSTaggedValue constPoolInfo,
const JSPandaFile* pf, JSHandle<ConstantPool> constPool)
{
JSTaggedValue fileUniqID(pf->GetFileUniqId());
JSHandle<TaggedArray> array(thread, constPoolInfo);
auto index = array->GetIdx(fileUniqID);
JSHandle<TaggedArray> valueArray(thread, array->Get(index + 1));
uint32_t len = valueArray->GetLength();
for (uint32_t i = 0; i < len; i += ITEM_SIZE) {
uint32_t valueIndex = valueArray->Get(i).GetInt();
JSTaggedValue value = valueArray->Get(i + 1);
constPool->Set(thread, valueIndex, value);
}
}
} // namespace panda::ecmascript

View File

@ -34,7 +34,7 @@ class JSPandaFile;
enum class SnapshotType {
VM_ROOT,
BUILTINS,
TS_LOADER
ETSO
};
using ObjectEncode = std::pair<uint64_t, ecmascript::EncodeBit>;
@ -130,6 +130,31 @@ private:
NO_COPY_SEMANTIC(SnapshotProcessor);
NO_MOVE_SEMANTIC(SnapshotProcessor);
};
class PUBLIC_API ConstantPoolProcessor {
public:
ConstantPoolProcessor(EcmaVM *vm) : vm_(vm), index_(0) {}
void InitializeConstantPoolInfos(size_t nums);
void CollectConstantPoolInfo(const JSPandaFile* pf, const JSHandle<JSTaggedValue> constantPool);
static void RestoreConstantPoolInfo(JSThread *thread, JSTaggedValue constPoolInfo,
const JSPandaFile* pf, JSHandle<ConstantPool> constPool);
JSTaggedValue GetInfos() const
{
return infos_;
}
private:
JSTaggedValue GenerateConstantPoolInfo(const JSHandle<ConstantPool> constantPool);
JSTaggedValue infos_ {JSTaggedValue::Hole()};
EcmaVM *vm_ {nullptr};
size_t index_ {0};
static const int ITEM_SIZE = 2;
};
} // namespace panda::ecmascript
#endif // ECMASCRIPT_SNAPSHOT_MEM_SNAPSHOT_PROCESSOR_H

View File

@ -64,42 +64,6 @@ public:
JSThread *thread {nullptr};
};
HWTEST_F_L0(SnapshotTest, SerializeConstStringTable)
{
auto factory = ecmaVm->GetFactory();
auto tsManager = ecmaVm->GetTSManager();
JSHandle<EcmaString> str1 = factory->NewFromASCII("str1");
JSHandle<EcmaString> str2 = factory->NewFromASCII("str2");
JSHandle<EcmaString> str3 = factory->NewFromASCII("str3");
JSHandle<EcmaString> str4 = factory->NewFromASCII("str4");
tsManager->AddConstString(str1.GetTaggedValue());
tsManager->AddConstString(str2.GetTaggedValue());
tsManager->AddConstString(str3.GetTaggedValue());
tsManager->AddConstString(str4.GetTaggedValue());
CString fileName = "snapshot";
Snapshot snapshotSerialize(ecmaVm);
// serialize
CVector<JSTaggedType> constStringTable = tsManager->GetConstStringTable();
snapshotSerialize.Serialize(reinterpret_cast<uintptr_t>(constStringTable.data()),
constStringTable.size(), fileName);
tsManager->ClearConstStringTable();
Snapshot snapshotDeserialize(ecmaVm);
// deserialize
snapshotDeserialize.Deserialize(SnapshotType::TS_LOADER, fileName);
CVector<JSTaggedType> constStringTable1 = tsManager->GetConstStringTable();
ASSERT_EQ(constStringTable1.size(), 4U);
EcmaString *str11 = reinterpret_cast<EcmaString *>(constStringTable1[0]);
EcmaString *str22 = reinterpret_cast<EcmaString *>(constStringTable1[1]);
EcmaString *str33 = reinterpret_cast<EcmaString *>(constStringTable1[2]);
EcmaString *str44 = reinterpret_cast<EcmaString *>(constStringTable1[3]);
ASSERT_EQ(std::strcmp(str11->GetCString().get(), "str1"), 0);
ASSERT_EQ(std::strcmp(str22->GetCString().get(), "str2"), 0);
ASSERT_EQ(std::strcmp(str33->GetCString().get(), "str3"), 0);
ASSERT_EQ(std::strcmp(str44->GetCString().get(), "str4"), 0);
ecmaVm->GetHeap()->GetSnapshotSpace()->ReclaimRegions();
std::remove(fileName.c_str());
}
HWTEST_F_L0(SnapshotTest, SerializeConstPool)
{
auto factory = ecmaVm->GetFactory();

View File

@ -1280,14 +1280,6 @@ DEF_RUNTIME_STUBS(Mod2Dyn)
return RuntimeMod2Dyn(thread, left, right).GetRawData();
}
DEF_RUNTIME_STUBS(LoadValueFromConstantStringTable)
{
RUNTIME_STUBS_HEADER(LoadValueFromConstantStringTable);
JSTaggedValue id = GetArg(argv, argc, 0); // 0: means the zeroth parameter
auto tsManager = thread->GetEcmaVM()->GetTSManager();
return tsManager->GetStringById(id.GetInt()).GetTaggedValue().GetRawData();
}
DEF_RUNTIME_STUBS(JumpToCInterpreter)
{
RUNTIME_STUBS_HEADER(JumpToCInterpreter);

View File

@ -197,7 +197,6 @@ using JSFunctionEntryType = JSTaggedValue (*)(uintptr_t glue, uintptr_t prevFp,
V(Mul2Dyn) \
V(Div2Dyn) \
V(Mod2Dyn) \
V(LoadValueFromConstantStringTable) \
V(CreateEmptyObject) \
V(CreateEmptyArray) \
V(GetSymbolFunction) \

View File

@ -331,10 +331,7 @@ GlobalTSTypeRef TSManager::GetOrCreateUnionType(CVector<GlobalTSTypeRef> unionTy
void TSManager::Iterate(const RootVisitor &v)
{
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&globalModuleTable_)));
uint64_t length = constantStringTable_.size();
for (uint64_t i = 0; i < length; i++) {
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&(constantStringTable_.data()[i]))));
}
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&constantPoolInfo_)));
uint64_t hclassTableLength = staticHClassTable_.size();
for (uint64_t i = 0; i < hclassTableLength; i++) {
@ -429,31 +426,6 @@ GlobalTSTypeRef TSManager::GetArrayParameterTypeGT(GlobalTSTypeRef gt) const
return arrayType->GetElementGT();
}
size_t TSManager::AddConstString(JSTaggedValue string)
{
auto it = std::find(constantStringTable_.begin(), constantStringTable_.end(), string.GetRawData());
if (it != constantStringTable_.end()) {
return it - constantStringTable_.begin();
} else {
constantStringTable_.emplace_back(string.GetRawData());
return constantStringTable_.size() - 1;
}
}
// add string to constantstringtable and get its index
size_t TSManager::GetStringIdx(JSHandle<JSTaggedValue> constPool, const uint16_t id)
{
JSHandle<ConstantPool> newConstPool(thread_, constPool.GetTaggedValue());
auto str = newConstPool->GetObjectFromCache(id);
return AddConstString(str);
}
std::string TSManager::GetStdStringById(size_t index) const
{
std::string str = GetStringById(index)->GetCString().get();
return str;
}
void TSManager::GenerateStaticHClass(JSHandle<TSTypeTable> tsTypeTable)
{
JSMutableHandle<TSObjectType> instanceType(thread_, JSTaggedValue::Undefined());

View File

@ -115,16 +115,6 @@ public:
return JSHandle<TSModuleTable>(reinterpret_cast<uintptr_t>(&globalModuleTable_));
}
CVector<JSTaggedType> GetConstStringTable() const
{
return constantStringTable_;
}
void ClearConstStringTable()
{
constantStringTable_.clear();
}
void SetTSModuleTable(JSHandle<TSModuleTable> table)
{
globalModuleTable_ = table.GetTaggedValue();
@ -146,6 +136,11 @@ public:
GlobalTSTypeRef PUBLIC_API GetImportTypeTargetGT(GlobalTSTypeRef gt) const;
inline GlobalTSTypeRef PUBLIC_API GetPropType(kungfu::GateType gateType, JSTaggedValue propertyName) const
{
return GetPropType(gateType, JSHandle<EcmaString>(vm_->GetJSThread(), propertyName));
}
inline GlobalTSTypeRef PUBLIC_API GetPropType(kungfu::GateType gateType, JSHandle<EcmaString> propertyName) const
{
GlobalTSTypeRef gt = GlobalTSTypeRef(gateType.GetType());
@ -197,8 +192,6 @@ public:
GlobalTSTypeRef PUBLIC_API GetArrayParameterTypeGT(GlobalTSTypeRef gt) const;
size_t PUBLIC_API AddConstString(JSTaggedValue string);
bool PUBLIC_API AssertTypes() const
{
return assertTypes_;
@ -220,22 +213,6 @@ public:
return CString(fileName);
}
// add string to constantstringtable and get its index
size_t PUBLIC_API GetStringIdx(JSHandle<JSTaggedValue> constPool, const uint16_t id);
/*
* Before using this method for type infer, you need to wait until all the
* string objects of the panda_file are collected, otherwise an error will
* be generated, and it will be optimized later.
*/
JSHandle<EcmaString> PUBLIC_API GetStringById(size_t index) const
{
ASSERT(index < constantStringTable_.size());
return JSHandle<EcmaString>(reinterpret_cast<uintptr_t>(&(constantStringTable_.at(index))));
}
std::string PUBLIC_API GetStdStringById(size_t index) const;
CVector<JSTaggedType> GetStaticHClassTable() const
{
return staticHClassTable_;
@ -263,6 +240,18 @@ public:
std::string PUBLIC_API GetTypeStr(kungfu::GateType gateType) const;
void PUBLIC_API CollectConstantPoolInfo(const JSPandaFile* pf, const JSHandle<JSTaggedValue> constantPool);
JSTaggedValue PUBLIC_API GetConstantPoolInfo() const
{
return constantPoolInfo_;
}
void PUBLIC_API SetConstantPoolInfo(JSTaggedValue constantPoolInfo)
{
constantPoolInfo_ = constantPoolInfo;
}
#define IS_TSTYPEKIND_METHOD_LIST(V) \
V(Primitive, TSTypeKind::PRIMITIVE) \
V(Class, TSTypeKind::CLASS) \
@ -310,8 +299,8 @@ private:
EcmaVM *vm_ {nullptr};
JSThread *thread_ {nullptr};
ObjectFactory *factory_ {nullptr};
JSTaggedValue constantPoolInfo_ {JSTaggedValue::Hole()};
JSTaggedValue globalModuleTable_ {JSTaggedValue::Hole()};
CVector<JSTaggedType> constantStringTable_ {};
CVector<JSTaggedType> staticHClassTable_ {}; // store hclass which produced from static type info
std::map<GlobalTSTypeRef, uint32_t> gtHClassIndexMap_ {}; // record gt and static hclass index mapping relation
bool assertTypes_ {false};