mirror of
https://github.com/Samsung/escargot.git
synced 2026-06-22 10:01:50 +00:00
Implement experimental code cache of function
Signed-off-by: Seonghyun Kim <sh8281.kim@samsung.com>
This commit is contained in:
parent
195039d901
commit
fcc35d22bf
7 changed files with 182 additions and 46 deletions
|
|
@ -154,6 +154,10 @@ ENDIF()
|
|||
|
||||
IF (ESCARGOT_TEST)
|
||||
SET (ESCARGOT_DEFINITIONS ${ESCARGOT_DEFINITIONS} -DESCARGOT_ENABLE_TEST)
|
||||
IF (ESCARGOT_CODE_CACHE)
|
||||
SET (ESCARGOT_DEFINITIONS ${ESCARGOT_DEFINITIONS} -DCODE_CACHE_MIN_SOURCE_LENGTH=1024)
|
||||
SET (ESCARGOT_DEFINITIONS ${ESCARGOT_DEFINITIONS} -DCODE_CACHE_MAX_CACHE_NUM=128)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
#######################################################
|
||||
|
|
|
|||
|
|
@ -3054,7 +3054,7 @@ void ContextRef::setSecurityPolicyCheckCallback(SecurityPolicyCheckCallback cb)
|
|||
|
||||
StackOverflowDisabler::StackOverflowDisabler(ExecutionStateRef* es)
|
||||
: m_executionState(es)
|
||||
, m_originStackLimit(toImpl(es)->stackLimit())
|
||||
, m_originStackLimit(ThreadLocal::stackLimit())
|
||||
{
|
||||
#ifdef STACK_GROWS_DOWN
|
||||
size_t newStackLimit = 0;
|
||||
|
|
|
|||
|
|
@ -299,19 +299,20 @@ void CodeCache::reset()
|
|||
|
||||
void CodeCache::setCacheEntry(const CodeCacheEntryChunk& entryChunk)
|
||||
{
|
||||
CodeCacheItem item(entryChunk.m_srcHash, entryChunk.m_functionSourceIndex);
|
||||
#ifndef NDEBUG
|
||||
auto iter = m_cacheList.find(entryChunk.m_srcHash);
|
||||
auto iter = m_cacheList.find(item);
|
||||
ASSERT(iter == m_cacheList.end());
|
||||
#endif
|
||||
m_cacheList.insert(std::make_pair(entryChunk.m_srcHash, entryChunk.m_entry));
|
||||
m_cacheList.insert(std::make_pair(item, entryChunk.m_entry));
|
||||
}
|
||||
|
||||
bool CodeCache::addCacheEntry(size_t hash, const CodeCacheEntry& entry)
|
||||
bool CodeCache::addCacheEntry(size_t hash, Optional<size_t> functionSourceIndex, const CodeCacheEntry& entry)
|
||||
{
|
||||
ASSERT(m_enabled);
|
||||
|
||||
#ifndef NDEBUG
|
||||
auto iter = m_cacheList.find(hash);
|
||||
auto iter = m_cacheList.find(CodeCacheItem(hash, functionSourceIndex));
|
||||
ASSERT(iter == m_cacheList.end());
|
||||
#endif
|
||||
if (m_cacheList.size() == CODE_CACHE_MAX_CACHE_NUM) {
|
||||
|
|
@ -320,7 +321,7 @@ bool CodeCache::addCacheEntry(size_t hash, const CodeCacheEntry& entry)
|
|||
}
|
||||
}
|
||||
|
||||
m_cacheList.insert(std::make_pair(hash, entry));
|
||||
m_cacheList.insert(std::make_pair(CodeCacheItem(hash, functionSourceIndex), entry));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -332,7 +333,7 @@ bool CodeCache::removeLRUCacheEntry()
|
|||
#ifndef NDEBUG
|
||||
uint64_t currentTimeStamp = fastTickCount();
|
||||
#endif
|
||||
size_t lruHash = 0;
|
||||
CodeCacheItem lruItem(0, Optional<size_t>());
|
||||
uint64_t lruTimeStamp = std::numeric_limits<uint64_t>::max();
|
||||
for (auto iter = m_cacheList.begin(); iter != m_cacheList.end(); iter++) {
|
||||
uint64_t timeStamp = iter->second.m_lastWrittenTimeStamp;
|
||||
|
|
@ -340,27 +341,30 @@ bool CodeCache::removeLRUCacheEntry()
|
|||
ASSERT(timeStamp <= currentTimeStamp);
|
||||
#endif
|
||||
if (lruTimeStamp > timeStamp) {
|
||||
lruHash = iter->first;
|
||||
lruItem = iter->first;
|
||||
lruTimeStamp = timeStamp;
|
||||
}
|
||||
}
|
||||
|
||||
if (UNLIKELY(!removeCacheFile(lruHash))) {
|
||||
if (UNLIKELY(!removeCacheFile(lruItem.m_srcHash, lruItem.m_functionSourceIndex))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t eraseReturn = m_cacheList.erase(lruHash);
|
||||
size_t eraseReturn = m_cacheList.erase(lruItem);
|
||||
ASSERT(eraseReturn == 1 && m_cacheList.size() == CODE_CACHE_MAX_CACHE_NUM - 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CodeCache::removeCacheFile(size_t hash)
|
||||
bool CodeCache::removeCacheFile(size_t hash, Optional<size_t> functionSourceIndex)
|
||||
{
|
||||
ASSERT(m_enabled);
|
||||
ASSERT(m_cacheDirPath.length());
|
||||
|
||||
std::string filePath = m_cacheDirPath + std::to_string(hash);
|
||||
if (functionSourceIndex) {
|
||||
filePath += "." + std::to_string(functionSourceIndex.value());
|
||||
}
|
||||
|
||||
if (remove(filePath.data()) != 0) {
|
||||
ESCARGOT_LOG_ERROR("[CodeCache] can`t remove a cache file %s\n", filePath.data());
|
||||
|
|
@ -370,14 +374,14 @@ bool CodeCache::removeCacheFile(size_t hash)
|
|||
return true;
|
||||
}
|
||||
|
||||
std::pair<bool, CodeCacheEntry> CodeCache::searchCache(size_t srcHash)
|
||||
std::pair<bool, CodeCacheEntry> CodeCache::searchCache(size_t srcHash, Optional<size_t> functionSourceIndex)
|
||||
{
|
||||
ASSERT(m_enabled);
|
||||
|
||||
CodeCacheEntry entry;
|
||||
bool cacheHit = false;
|
||||
|
||||
auto iter = m_cacheList.find(srcHash);
|
||||
auto iter = m_cacheList.find(CodeCacheItem(srcHash, functionSourceIndex));
|
||||
if (iter != m_cacheList.end()) {
|
||||
cacheHit = true;
|
||||
entry = iter->second;
|
||||
|
|
@ -386,7 +390,7 @@ std::pair<bool, CodeCacheEntry> CodeCache::searchCache(size_t srcHash)
|
|||
return std::make_pair(cacheHit, entry);
|
||||
}
|
||||
|
||||
void CodeCache::prepareCacheLoading(Context* context, size_t srcHash, const CodeCacheEntry& entry)
|
||||
void CodeCache::prepareCacheLoading(Context* context, size_t srcHash, Optional<size_t> functionSourceIndex, const CodeCacheEntry& entry)
|
||||
{
|
||||
ASSERT(m_enabled && m_status == Status::READY);
|
||||
ASSERT(m_cacheDirPath.length());
|
||||
|
|
@ -396,11 +400,14 @@ void CodeCache::prepareCacheLoading(Context* context, size_t srcHash, const Code
|
|||
m_status = Status::IN_PROGRESS;
|
||||
|
||||
m_currentContext.m_cacheFilePath = m_cacheDirPath + std::to_string(srcHash);
|
||||
if (functionSourceIndex) {
|
||||
m_currentContext.m_cacheFilePath += "." + std::to_string(functionSourceIndex.value());
|
||||
}
|
||||
m_currentContext.m_cacheEntry = entry;
|
||||
m_currentContext.m_cacheStringTable = loadCacheStringTable(context);
|
||||
}
|
||||
|
||||
void CodeCache::prepareCacheWriting(size_t srcHash)
|
||||
void CodeCache::prepareCacheWriting(size_t srcHash, Optional<size_t> functionSourceIndex)
|
||||
{
|
||||
ASSERT(m_enabled && m_status == Status::READY);
|
||||
ASSERT(m_cacheDirPath.length());
|
||||
|
|
@ -410,6 +417,9 @@ void CodeCache::prepareCacheWriting(size_t srcHash)
|
|||
m_status = Status::IN_PROGRESS;
|
||||
|
||||
m_currentContext.m_cacheFilePath = m_cacheDirPath + std::to_string(srcHash);
|
||||
if (functionSourceIndex) {
|
||||
m_currentContext.m_cacheFilePath += "." + std::to_string(functionSourceIndex.value());
|
||||
}
|
||||
m_currentContext.m_cacheStringTable = new CacheStringTable();
|
||||
}
|
||||
|
||||
|
|
@ -430,7 +440,7 @@ bool CodeCache::postCacheLoading()
|
|||
return false;
|
||||
}
|
||||
|
||||
void CodeCache::postCacheWriting(size_t srcHash)
|
||||
void CodeCache::postCacheWriting(size_t srcHash, Optional<size_t> functionSourceIndex)
|
||||
{
|
||||
ASSERT(m_enabled);
|
||||
|
||||
|
|
@ -441,7 +451,7 @@ void CodeCache::postCacheWriting(size_t srcHash)
|
|||
// write time stamp
|
||||
entry.m_lastWrittenTimeStamp = fastTickCount();
|
||||
|
||||
if (addCacheEntry(srcHash, m_currentContext.m_cacheEntry)) {
|
||||
if (addCacheEntry(srcHash, functionSourceIndex, m_currentContext.m_cacheEntry)) {
|
||||
if (writeCacheList()) {
|
||||
reset();
|
||||
m_status = Status::READY;
|
||||
|
|
@ -694,7 +704,7 @@ bool CodeCache::writeCacheList()
|
|||
while (entryCount < listSize) {
|
||||
ASSERT(iter != m_cacheList.end());
|
||||
|
||||
CodeCacheEntryChunk entryChunk(iter->first, iter->second);
|
||||
CodeCacheEntryChunk entryChunk(iter->first.m_srcHash, iter->first.m_functionSourceIndex, iter->second);
|
||||
if (UNLIKELY(fwrite(&entryChunk, sizeof(CodeCacheEntryChunk), 1, listFile) != 1)) {
|
||||
ESCARGOT_LOG_ERROR("[CodeCache] fwrite of %s failed\n", cacheListFilePath.data());
|
||||
fclose(listFile);
|
||||
|
|
|
|||
|
|
@ -26,12 +26,12 @@
|
|||
#error "Code Cache does not support OS other than POSIX"
|
||||
#endif
|
||||
|
||||
#if defined(ESCARGOT_ENABLE_TEST)
|
||||
#define CODE_CACHE_MIN_SOURCE_LENGTH 1024
|
||||
#define CODE_CACHE_MAX_CACHE_NUM 128
|
||||
#else
|
||||
#define CODE_CACHE_MIN_SOURCE_LENGTH 1024 * 4
|
||||
#define CODE_CACHE_MAX_CACHE_NUM 32
|
||||
#ifndef CODE_CACHE_MIN_SOURCE_LENGTH
|
||||
#define CODE_CACHE_MIN_SOURCE_LENGTH 1024 * 32
|
||||
#endif
|
||||
|
||||
#ifndef CODE_CACHE_MAX_CACHE_NUM
|
||||
#define CODE_CACHE_MAX_CACHE_NUM 256
|
||||
#endif
|
||||
|
||||
namespace Escargot {
|
||||
|
|
@ -85,6 +85,43 @@ struct CodeCacheMetaInfo {
|
|||
size_t dataSize;
|
||||
};
|
||||
|
||||
struct CodeCacheItem {
|
||||
size_t m_srcHash;
|
||||
Optional<size_t> m_functionSourceIndex;
|
||||
CodeCacheItem(size_t srcHash, Optional<size_t> functionSourceIndex)
|
||||
: m_srcHash(srcHash)
|
||||
, m_functionSourceIndex(functionSourceIndex)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==(const CodeCacheItem& src) const
|
||||
{
|
||||
return m_srcHash == src.m_srcHash && m_functionSourceIndex == src.m_functionSourceIndex;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Escargot
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<Escargot::CodeCacheItem> {
|
||||
size_t operator()(Escargot::CodeCacheItem const& x) const
|
||||
{
|
||||
return x.m_srcHash;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct equal_to<Escargot::CodeCacheItem> {
|
||||
bool operator()(Escargot::CodeCacheItem const& a, Escargot::CodeCacheItem const& b) const
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
namespace Escargot {
|
||||
|
||||
struct CodeCacheEntry {
|
||||
CodeCacheEntry()
|
||||
: m_lastWrittenTimeStamp(0)
|
||||
|
|
@ -134,13 +171,15 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
CodeCacheEntryChunk(size_t srcHash, const CodeCacheEntry& entry)
|
||||
CodeCacheEntryChunk(size_t srcHash, Optional<size_t> functionSourceIndex, const CodeCacheEntry& entry)
|
||||
: m_srcHash(srcHash)
|
||||
, m_functionSourceIndex(functionSourceIndex)
|
||||
, m_entry(entry)
|
||||
{
|
||||
}
|
||||
|
||||
size_t m_srcHash;
|
||||
Optional<size_t> m_functionSourceIndex;
|
||||
CodeCacheEntry m_entry;
|
||||
};
|
||||
|
||||
|
|
@ -148,12 +187,12 @@ public:
|
|||
~CodeCache();
|
||||
|
||||
bool enabled() const { return m_enabled; }
|
||||
std::pair<bool, CodeCacheEntry> searchCache(size_t srcHash);
|
||||
std::pair<bool, CodeCacheEntry> searchCache(size_t srcHash, Optional<size_t> functionSourceIndex);
|
||||
|
||||
void prepareCacheLoading(Context* context, size_t srcHash, const CodeCacheEntry& entry);
|
||||
void prepareCacheWriting(size_t srcHash);
|
||||
void prepareCacheLoading(Context* context, size_t srcHash, Optional<size_t> functionSourceIndex, const CodeCacheEntry& entry);
|
||||
void prepareCacheWriting(size_t srcHash, Optional<size_t> functionSourceIndex);
|
||||
bool postCacheLoading();
|
||||
void postCacheWriting(size_t srcHash);
|
||||
void postCacheWriting(size_t srcHash, Optional<size_t> functionSourceIndex);
|
||||
|
||||
void storeStringTable();
|
||||
void storeCodeBlockTree(InterpretedCodeBlock* topCodeBlock, CodeBlockCacheInfo* codeBlockCacheInfo);
|
||||
|
|
@ -170,7 +209,7 @@ private:
|
|||
|
||||
CodeCacheContext m_currentContext; // current CodeCache infos
|
||||
|
||||
typedef std::unordered_map<size_t, CodeCacheEntry, std::hash<size_t>, std::equal_to<size_t>, std::allocator<std::pair<size_t const, CodeCacheEntry>>> CodeCacheListMap;
|
||||
typedef std::unordered_map<CodeCacheItem, CodeCacheEntry, std::hash<CodeCacheItem>, std::equal_to<CodeCacheItem>, std::allocator<std::pair<CodeCacheItem const, CodeCacheEntry>>> CodeCacheListMap;
|
||||
CodeCacheListMap m_cacheList;
|
||||
|
||||
CodeCacheWriter* m_cacheWriter;
|
||||
|
|
@ -190,10 +229,10 @@ private:
|
|||
void clearAll();
|
||||
void reset();
|
||||
void setCacheEntry(const CodeCacheEntryChunk& entryChunk);
|
||||
bool addCacheEntry(size_t hash, const CodeCacheEntry& entry);
|
||||
bool addCacheEntry(size_t hash, Optional<size_t> functionSourceIndex, const CodeCacheEntry& entry);
|
||||
|
||||
bool removeLRUCacheEntry();
|
||||
bool removeCacheFile(size_t hash);
|
||||
bool removeCacheFile(size_t hash, Optional<size_t> functionSourceIndex);
|
||||
|
||||
void storeCodeBlockTreeNode(InterpretedCodeBlock* codeBlock, size_t& nodeCount);
|
||||
InterpretedCodeBlock* loadCodeBlockTreeNode(Script* script);
|
||||
|
|
|
|||
|
|
@ -161,8 +161,17 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
Script(String* srcName, String* sourceCode, ModuleData* moduleData, bool canExecuteAgain, size_t originLineOffset)
|
||||
Script(String* srcName, String* sourceCode, ModuleData* moduleData, size_t originLineOffset, bool canExecuteAgain
|
||||
#if defined(ENABLE_CODE_CACHE)
|
||||
,
|
||||
bool isCacheable
|
||||
#endif
|
||||
)
|
||||
: m_canExecuteAgain(canExecuteAgain && !moduleData)
|
||||
#if defined(ENABLE_CODE_CACHE)
|
||||
, m_isCacheable(isCacheable)
|
||||
, m_sourceCodeHashValue(0)
|
||||
#endif
|
||||
, m_srcName(srcName)
|
||||
, m_sourceCode(sourceCode)
|
||||
, m_topCodeBlock(nullptr)
|
||||
|
|
@ -204,6 +213,18 @@ public:
|
|||
return m_moduleData;
|
||||
}
|
||||
|
||||
#if defined(ENABLE_CODE_CACHE)
|
||||
bool isCacheable()
|
||||
{
|
||||
return m_isCacheable;
|
||||
}
|
||||
|
||||
size_t sourceCodeHashValue()
|
||||
{
|
||||
return m_sourceCodeHashValue;
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t moduleRequestsLength();
|
||||
String* moduleRequest(size_t i);
|
||||
|
||||
|
|
@ -297,6 +318,10 @@ private:
|
|||
static Value asyncModuleRejectedFunction(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget);
|
||||
|
||||
bool m_canExecuteAgain;
|
||||
#if defined(ENABLE_CODE_CACHE)
|
||||
bool m_isCacheable;
|
||||
size_t m_sourceCodeHashValue;
|
||||
#endif
|
||||
String* m_srcName;
|
||||
String* m_sourceCode;
|
||||
InterpretedCodeBlock* m_topCodeBlock;
|
||||
|
|
|
|||
|
|
@ -308,14 +308,14 @@ ScriptParser::InitializeScriptResult ScriptParser::initializeScript(String* orig
|
|||
if (cacheable) {
|
||||
ASSERT(!parentCodeBlock);
|
||||
srcHash = source->hashValue();
|
||||
auto result = codeCache->searchCache(srcHash);
|
||||
auto result = codeCache->searchCache(srcHash, Optional<size_t>());
|
||||
if (result.first) {
|
||||
GC_disable();
|
||||
|
||||
Script* script = new Script(srcName, source, nullptr, false, originLineOffset);
|
||||
Script* script = new Script(srcName, source, nullptr, originLineOffset, false, cacheable);
|
||||
CodeCacheEntry& entry = result.second;
|
||||
|
||||
codeCache->prepareCacheLoading(m_context, srcHash, entry);
|
||||
codeCache->prepareCacheLoading(m_context, srcHash, Optional<size_t>(), entry);
|
||||
// load CodeBlockTree
|
||||
InterpretedCodeBlock* topCodeBlock = codeCache->loadCodeBlockTree(m_context, script);
|
||||
// load global ByteCodeBlock
|
||||
|
|
@ -368,7 +368,12 @@ ScriptParser::InitializeScriptResult ScriptParser::initializeScript(String* orig
|
|||
programNode = esprima::parseProgram(m_context, sourceView, outerClassInfo,
|
||||
isModule, strictFromOutside, inWith, allowSC, allowSP, allowNewTarget, allowArguments);
|
||||
|
||||
script = new Script(srcName, source, programNode->moduleData(), !parentCodeBlock, originLineOffset);
|
||||
script = new Script(srcName, source, programNode->moduleData(), originLineOffset, !parentCodeBlock
|
||||
#if defined(ENABLE_CODE_CACHE)
|
||||
,
|
||||
cacheable
|
||||
#endif
|
||||
);
|
||||
if (parentCodeBlock) {
|
||||
programNode->scopeContext()->m_hasEval = parentCodeBlock->hasEval();
|
||||
programNode->scopeContext()->m_hasWith = parentCodeBlock->hasWith();
|
||||
|
|
@ -421,7 +426,7 @@ ScriptParser::InitializeScriptResult ScriptParser::initializeScript(String* orig
|
|||
#if defined(ENABLE_CODE_CACHE)
|
||||
// Store cache
|
||||
if (cacheable) {
|
||||
codeCache->prepareCacheWriting(srcHash);
|
||||
codeCache->prepareCacheWriting(srcHash, Optional<size_t>());
|
||||
|
||||
// For storing cache, CodeBlockTree is firstly saved
|
||||
codeCache->storeCodeBlockTree(topCodeBlock, m_codeBlockCacheInfo);
|
||||
|
|
@ -429,9 +434,11 @@ ScriptParser::InitializeScriptResult ScriptParser::initializeScript(String* orig
|
|||
// After CodeBlockTree, ByteCode and StringTable are stored sequentially
|
||||
topCodeBlock->m_byteCodeBlock = ByteCodeGenerator::generateByteCode(m_context, topCodeBlock, programNode, inWith, true);
|
||||
|
||||
codeCache->postCacheWriting(srcHash);
|
||||
codeCache->postCacheWriting(srcHash, Optional<size_t>());
|
||||
deleteCodeBlockCacheInfo();
|
||||
|
||||
script->m_sourceCodeHashValue = srcHash;
|
||||
|
||||
ESCARGOT_LOG_INFO("[CodeCache] Store CodeCache Done (%s)\n", srcName->toUTF8StringData().data());
|
||||
} else {
|
||||
topCodeBlock->m_byteCodeBlock = ByteCodeGenerator::generateByteCode(m_context, topCodeBlock, programNode, inWith, false);
|
||||
|
|
@ -469,6 +476,36 @@ void ScriptParser::generateFunctionByteCode(ExecutionState& state, InterpretedCo
|
|||
ASSERT(!m_context->debuggerEnabled() || !m_context->inDebuggingCodeMode());
|
||||
#endif /* ESCARGOT_DEBUGGER */
|
||||
|
||||
#if defined(ENABLE_CODE_CACHE)
|
||||
CodeCache* codeCache = m_context->vmInstance()->codeCache();
|
||||
bool cacheable = codeBlock->script()->isCacheable() && codeBlock->src().length() > CODE_CACHE_MIN_SOURCE_LENGTH;
|
||||
// Lode code from cache
|
||||
size_t srcHash = codeBlock->script()->sourceCodeHashValue();
|
||||
|
||||
// Load cache
|
||||
if (cacheable) {
|
||||
auto result = codeCache->searchCache(srcHash, codeBlock->functionStart().index);
|
||||
if (result.first) {
|
||||
GC_disable();
|
||||
CodeCacheEntry& entry = result.second;
|
||||
|
||||
codeCache->prepareCacheLoading(m_context, srcHash, codeBlock->functionStart().index, entry);
|
||||
// load ByteCodeBlock
|
||||
codeBlock->m_byteCodeBlock = codeCache->loadByteCodeBlock(m_context, codeBlock);
|
||||
bool loadingDone = codeCache->postCacheLoading();
|
||||
cacheable = loadingDone;
|
||||
GC_enable();
|
||||
|
||||
if (LIKELY(loadingDone)) {
|
||||
ESCARGOT_LOG_INFO("[CodeCache] Load CodeCache Done (%s: index %zu size %zu)\n", codeBlock->script()->srcName()->toNonGCUTF8StringData().data(),
|
||||
codeBlock->functionStart().index, codeBlock->src().length());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
GC_disable();
|
||||
|
||||
FunctionNode* functionNode;
|
||||
|
|
@ -489,7 +526,23 @@ void ScriptParser::generateFunctionByteCode(ExecutionState& state, InterpretedCo
|
|||
|
||||
// Generate ByteCode
|
||||
try {
|
||||
#if defined(ENABLE_CODE_CACHE)
|
||||
// Store cache
|
||||
if (cacheable) {
|
||||
codeCache->prepareCacheWriting(srcHash, codeBlock->functionStart().index);
|
||||
// After CodeBlockTree, ByteCode and StringTable are stored sequentially
|
||||
codeBlock->m_byteCodeBlock = ByteCodeGenerator::generateByteCode(state.context(), codeBlock, functionNode, false, true);
|
||||
codeCache->postCacheWriting(srcHash, codeBlock->functionStart().index);
|
||||
ESCARGOT_LOG_INFO("[CodeCache] Store CodeCache Done (%s: index %zu size %zu)\n", codeBlock->script()->srcName()->toNonGCUTF8StringData().data(),
|
||||
codeBlock->functionStart().index, codeBlock->src().length());
|
||||
} else {
|
||||
codeBlock->m_byteCodeBlock = ByteCodeGenerator::generateByteCode(state.context(), codeBlock, functionNode);
|
||||
}
|
||||
#else
|
||||
codeBlock->m_byteCodeBlock = ByteCodeGenerator::generateByteCode(state.context(), codeBlock, functionNode);
|
||||
#endif
|
||||
|
||||
|
||||
} catch (const char* message) {
|
||||
// reset ASTAllocator
|
||||
m_context->astAllocator().reset();
|
||||
|
|
@ -513,7 +566,12 @@ Script* ScriptParser::initializeJSONModule(String* source, String* srcName)
|
|||
|
||||
moduleData->m_localExportEntries.push_back(entry);
|
||||
|
||||
Script* script = new Script(srcName, source, moduleData, false, 0);
|
||||
Script* script = new Script(srcName, source, moduleData, 0, false
|
||||
#if defined(ENABLE_CODE_CACHE)
|
||||
,
|
||||
false
|
||||
#endif
|
||||
);
|
||||
|
||||
ModuleEnvironmentRecord* moduleRecord = new ModuleEnvironmentRecord(script);
|
||||
moduleData->m_moduleRecord = moduleRecord;
|
||||
|
|
@ -575,7 +633,12 @@ ScriptParser::InitializeScriptResult ScriptParser::initializeScriptWithDebugger(
|
|||
|
||||
programNode = esprima::parseProgram(m_context, sourceView, outerClassInfo, isModule, strictFromOutside, inWith, allowSC, allowSP, allowNewTarget, allowArguments);
|
||||
|
||||
script = new Script(srcName, source, programNode->moduleData(), !parentCodeBlock, originLineOffset);
|
||||
script = new Script(srcName, source, programNode->moduleData(), originLineOffset, !parentCodeBlock
|
||||
#if defined(ENABLE_CODE_CACHE)
|
||||
,
|
||||
false
|
||||
#endif
|
||||
);
|
||||
if (parentCodeBlock) {
|
||||
programNode->scopeContext()->m_hasEval = parentCodeBlock->hasEval();
|
||||
programNode->scopeContext()->m_hasWith = parentCodeBlock->hasWith();
|
||||
|
|
|
|||
|
|
@ -186,11 +186,6 @@ public:
|
|||
m_inStrictMode = inStrictMode;
|
||||
}
|
||||
|
||||
size_t stackLimit()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void throwException(const Value& e);
|
||||
|
||||
bool hasRareData()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue