Skip to content

Commit

Permalink
Use string length with hash for identify source code in CodeCache
Browse files Browse the repository at this point in the history
Signed-off-by: Seonghyun Kim <[email protected]>
  • Loading branch information
ksh8281 authored and clover2123 committed Nov 30, 2023
1 parent 4120672 commit 184295c
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 51 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/es-actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ jobs:
- name: Handle error cases
run: |
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/codecache/x64/escargot" sunspider-js
rm $HOME/Escargot-cache/3217641879501852439
rm $HOME/Escargot-cache/3217641879501852439_17149
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/codecache/x64/escargot" sunspider-js
ls -1q $HOME/Escargot-cache/ | wc -l
$RUNNER --arch=x86_64 --engine="$GITHUB_WORKSPACE/out/codecache/x64/escargot" sunspider-js
Expand Down
49 changes: 29 additions & 20 deletions src/codecache/CodeCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@

namespace Escargot {

static std::string makeCacheFilePath(const std::string& cacheDirPath, const CodeCacheScriptIdentifier& id)
{
std::stringstream ss;
ss << cacheDirPath;
id.makeCacheFilePath(ss);
return ss.str();
}

void CodeCache::CodeCacheContext::reset()
{
m_cacheFilePath.clear();
Expand Down Expand Up @@ -304,20 +312,20 @@ void CodeCache::reset()

void CodeCache::setCacheEntry(const CodeCacheEntryChunk& entryChunk)
{
CodeCacheItem item(entryChunk.m_srcHash, entryChunk.m_functionSourceIndex);
CodeCacheItem item(entryChunk.m_scriptIdentifier, entryChunk.m_functionSourceIndex);
#ifndef NDEBUG
auto iter = m_cacheList.find(item);
ASSERT(iter == m_cacheList.end());
#endif
m_cacheList.insert(std::make_pair(item, entryChunk.m_entry));
}

bool CodeCache::addCacheEntry(size_t hash, Optional<size_t> functionSourceIndex, const CodeCacheEntry& entry)
bool CodeCache::addCacheEntry(const CodeCacheScriptIdentifier& scriptIdentifier, Optional<size_t> functionSourceIndex, const CodeCacheEntry& entry)
{
ASSERT(m_enabled);

#ifndef NDEBUG
auto iter = m_cacheList.find(CodeCacheItem(hash, functionSourceIndex));
auto iter = m_cacheList.find(CodeCacheItem(scriptIdentifier, functionSourceIndex));
ASSERT(iter == m_cacheList.end());
#endif
if (m_cacheLRUList.size() == m_maxCacheCount) {
Expand All @@ -326,7 +334,7 @@ bool CodeCache::addCacheEntry(size_t hash, Optional<size_t> functionSourceIndex,
}
}

m_cacheList.insert(std::make_pair(CodeCacheItem(hash, functionSourceIndex), entry));
m_cacheList.insert(std::make_pair(CodeCacheItem(scriptIdentifier, functionSourceIndex), entry));
return true;
}

Expand All @@ -338,7 +346,7 @@ bool CodeCache::removeLRUCacheEntry()
#ifndef NDEBUG
uint64_t currentTimeStamp = fastTickCount();
#endif
size_t lruItem = 0;
CodeCacheScriptIdentifier lruItem(0, 0);
uint64_t lruTimeStamp = std::numeric_limits<uint64_t>::max();
for (auto iter = m_cacheLRUList.begin(); iter != m_cacheLRUList.end(); iter++) {
uint64_t timeStamp = iter->second;
Expand All @@ -359,26 +367,26 @@ bool CodeCache::removeLRUCacheEntry()
ASSERT(eraseReturn == 1 && m_cacheLRUList.size() == m_maxCacheCount - 1);

for (auto iter = m_cacheList.begin(); iter != m_cacheList.end();) {
if (iter->first.m_srcHash == lruItem) {
if (iter->first.m_scriptIdentifier == lruItem) {
iter = m_cacheList.erase(iter);
} else {
iter++;
}
}

#ifndef NDEBUG
ESCARGOT_LOG_INFO("[CodeCache] removeLRUCacheEntry %zu done\n", lruItem);
ESCARGOT_LOG_INFO("[CodeCache] removeLRUCacheEntry %zu_%zu done\n", lruItem.m_srcHash, lruItem.m_sourceCodeLength);
#endif

return true;
}

bool CodeCache::removeCacheFile(size_t hash)
bool CodeCache::removeCacheFile(const CodeCacheScriptIdentifier& scriptIdentifier)
{
ASSERT(m_enabled);
ASSERT(m_cacheDirPath.length());

std::string filePath = m_cacheDirPath + std::to_string(hash);
std::string filePath = makeCacheFilePath(m_cacheDirPath, scriptIdentifier);
if (remove(filePath.data()) != 0) {
ESCARGOT_LOG_ERROR("[CodeCache] can`t remove a cache file %s\n", filePath.data());
return false;
Expand All @@ -387,14 +395,14 @@ bool CodeCache::removeCacheFile(size_t hash)
return true;
}

std::pair<bool, CodeCacheEntry> CodeCache::searchCache(size_t srcHash, Optional<size_t> functionSourceIndex)
std::pair<bool, CodeCacheEntry> CodeCache::searchCache(const CodeCacheScriptIdentifier& scriptIdentifier, Optional<size_t> functionSourceIndex)
{
ASSERT(m_enabled);

CodeCacheEntry entry;
bool cacheHit = false;

auto iter = m_cacheList.find(CodeCacheItem(srcHash, functionSourceIndex));
auto iter = m_cacheList.find(CodeCacheItem(scriptIdentifier, functionSourceIndex));
if (iter != m_cacheList.end()) {
cacheHit = true;
entry = iter->second;
Expand All @@ -403,7 +411,7 @@ std::pair<bool, CodeCacheEntry> CodeCache::searchCache(size_t srcHash, Optional<
return std::make_pair(cacheHit, entry);
}

void CodeCache::prepareCacheLoading(Context* context, size_t srcHash, Optional<size_t> functionSourceIndex, const CodeCacheEntry& entry)
void CodeCache::prepareCacheLoading(Context* context, const CodeCacheScriptIdentifier& scriptIdentifier, Optional<size_t> functionSourceIndex, const CodeCacheEntry& entry)
{
ASSERT(m_enabled && m_status == Status::READY);
ASSERT(m_cacheDirPath.length());
Expand All @@ -412,12 +420,12 @@ void CodeCache::prepareCacheLoading(Context* context, size_t srcHash, Optional<s

m_status = Status::IN_PROGRESS;

m_currentContext.m_cacheFilePath = m_cacheDirPath + std::to_string(srcHash);
m_currentContext.m_cacheFilePath = makeCacheFilePath(m_cacheDirPath, scriptIdentifier);
m_currentContext.m_cacheEntry = entry;
m_currentContext.m_cacheStringTable = loadCacheStringTable(context);
}

void CodeCache::prepareCacheWriting(size_t srcHash, Optional<size_t> functionSourceIndex)
void CodeCache::prepareCacheWriting(const CodeCacheScriptIdentifier& scriptIdentifier, Optional<size_t> functionSourceIndex)
{
ASSERT(m_enabled && m_status == Status::READY);
ASSERT(m_cacheDirPath.length());
Expand All @@ -426,7 +434,7 @@ void CodeCache::prepareCacheWriting(size_t srcHash, Optional<size_t> functionSou

m_status = Status::IN_PROGRESS;

m_currentContext.m_cacheFilePath = m_cacheDirPath + std::to_string(srcHash);
m_currentContext.m_cacheFilePath = makeCacheFilePath(m_cacheDirPath, scriptIdentifier);
m_currentContext.m_cacheStringTable = new CacheStringTable();
}

Expand All @@ -447,15 +455,15 @@ bool CodeCache::postCacheLoading()
return false;
}

void CodeCache::postCacheWriting(size_t srcHash, Optional<size_t> functionSourceIndex)
void CodeCache::postCacheWriting(const CodeCacheScriptIdentifier& scriptIdentifier, Optional<size_t> functionSourceIndex)
{
ASSERT(m_enabled);

if (LIKELY(m_status == Status::FINISH)) {
// write time stamp
m_cacheLRUList[srcHash] = fastTickCount();
m_cacheLRUList[scriptIdentifier] = fastTickCount();

if (addCacheEntry(srcHash, functionSourceIndex, m_currentContext.m_cacheEntry)) {
if (addCacheEntry(scriptIdentifier, functionSourceIndex, m_currentContext.m_cacheEntry)) {
if (writeCacheList()) {
reset();
m_status = Status::READY;
Expand Down Expand Up @@ -633,10 +641,11 @@ InterpretedCodeBlock* CodeCache::loadCodeBlockTree(Context* context, Script* scr
// load bytecode of functions
if (m_shouldLoadFunctionOnScriptLoading) {
FILE* dataFile = nullptr;
CodeCacheScriptIdentifier scriptIdentifier(script->sourceCodeHashValue(), script->sourceCode()->length());
size_t loadedFunctionCount = 0;
for (size_t i = 0; i < tempCodeBlockVector.size(); i++) {
InterpretedCodeBlock* codeBlock = tempCodeBlockVector[i];
auto result = searchCache(script->sourceCodeHashValue(), codeBlock->functionStart().index);
auto result = searchCache(scriptIdentifier, codeBlock->functionStart().index);
if (result.first) {
if (!dataFile) {
dataFile = fopen(m_currentContext.m_cacheFilePath.data(), "rb");
Expand Down Expand Up @@ -778,7 +787,7 @@ bool CodeCache::writeCacheList()
while (entryCount < listSize) {
ASSERT(iter != m_cacheList.end());

CodeCacheEntryChunk entryChunk(iter->first.m_srcHash, iter->first.m_functionSourceIndex, iter->second);
CodeCacheEntryChunk entryChunk(iter->first.m_scriptIdentifier, 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);
Expand Down
71 changes: 55 additions & 16 deletions src/codecache/CodeCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,41 @@ struct CodeCacheMetaInfo {
size_t dataSize;
};

struct CodeCacheItem {
struct CodeCacheScriptIdentifier {
size_t m_srcHash;
Optional<size_t> m_functionSourceIndex;
CodeCacheItem(size_t srcHash, Optional<size_t> functionSourceIndex)
size_t m_sourceCodeLength;

CodeCacheScriptIdentifier(size_t srcHash, size_t sourceCodeLength)
: m_srcHash(srcHash)
, m_sourceCodeLength(sourceCodeLength)
{
}

void makeCacheFilePath(std::stringstream& ss) const
{
ss << m_srcHash;
ss << '_';
ss << m_sourceCodeLength;
}

bool operator==(const CodeCacheScriptIdentifier& src) const
{
return m_srcHash == src.m_srcHash && m_sourceCodeLength == src.m_sourceCodeLength;
}
};

struct CodeCacheItem {
CodeCacheScriptIdentifier m_scriptIdentifier;
Optional<size_t> m_functionSourceIndex;
CodeCacheItem(CodeCacheScriptIdentifier scriptIdentifier, Optional<size_t> functionSourceIndex)
: m_scriptIdentifier(scriptIdentifier)
, m_functionSourceIndex(functionSourceIndex)
{
}

bool operator==(const CodeCacheItem& src) const
{
return m_srcHash == src.m_srcHash && m_functionSourceIndex == src.m_functionSourceIndex;
return m_scriptIdentifier == src.m_scriptIdentifier && m_functionSourceIndex == src.m_functionSourceIndex;
}
};

Expand All @@ -111,7 +134,7 @@ template <>
struct hash<Escargot::CodeCacheItem> {
size_t operator()(Escargot::CodeCacheItem const& x) const
{
return x.m_srcHash + (x.m_functionSourceIndex ? x.m_functionSourceIndex.value() : 0);
return x.m_scriptIdentifier.m_srcHash + (x.m_functionSourceIndex ? x.m_functionSourceIndex.value() : 0);
}
};

Expand All @@ -122,6 +145,22 @@ struct equal_to<Escargot::CodeCacheItem> {
return a == b;
}
};

template <>
struct hash<Escargot::CodeCacheScriptIdentifier> {
size_t operator()(Escargot::CodeCacheScriptIdentifier const& x) const
{
return x.m_srcHash;
}
};

template <>
struct equal_to<Escargot::CodeCacheScriptIdentifier> {
bool operator()(Escargot::CodeCacheScriptIdentifier const& a, Escargot::CodeCacheScriptIdentifier const& b) const
{
return a == b;
}
};
} // namespace std

namespace Escargot {
Expand Down Expand Up @@ -167,18 +206,18 @@ class CodeCache {

struct CodeCacheEntryChunk {
CodeCacheEntryChunk()
: m_srcHash(0)
: m_scriptIdentifier(0, 0)
{
}

CodeCacheEntryChunk(size_t srcHash, Optional<size_t> functionSourceIndex, const CodeCacheEntry& entry)
: m_srcHash(srcHash)
CodeCacheEntryChunk(const CodeCacheScriptIdentifier& scriptIdentifier, Optional<size_t> functionSourceIndex, const CodeCacheEntry& entry)
: m_scriptIdentifier(scriptIdentifier)
, m_functionSourceIndex(functionSourceIndex)
, m_entry(entry)
{
}

size_t m_srcHash;
CodeCacheScriptIdentifier m_scriptIdentifier;
Optional<size_t> m_functionSourceIndex;
CodeCacheEntry m_entry;
};
Expand All @@ -187,12 +226,12 @@ class CodeCache {
~CodeCache();

bool enabled() const { return m_enabled; }
std::pair<bool, CodeCacheEntry> searchCache(size_t srcHash, Optional<size_t> functionSourceIndex);
std::pair<bool, CodeCacheEntry> searchCache(const CodeCacheScriptIdentifier& scriptIdentifier, Optional<size_t> functionSourceIndex);

void prepareCacheLoading(Context* context, size_t srcHash, Optional<size_t> functionSourceIndex, const CodeCacheEntry& entry);
void prepareCacheWriting(size_t srcHash, Optional<size_t> functionSourceIndex);
void prepareCacheLoading(Context* context, const CodeCacheScriptIdentifier& scriptIdentifier, Optional<size_t> functionSourceIndex, const CodeCacheEntry& entry);
void prepareCacheWriting(const CodeCacheScriptIdentifier& scriptIdentifier, Optional<size_t> functionSourceIndex);
bool postCacheLoading();
void postCacheWriting(size_t srcHash, Optional<size_t> functionSourceIndex);
void postCacheWriting(const CodeCacheScriptIdentifier& scriptIdentifier, Optional<size_t> functionSourceIndex);

void storeStringTable();
void storeCodeBlockTree(InterpretedCodeBlock* topCodeBlock, CodeBlockCacheInfo* codeBlockCacheInfo);
Expand All @@ -218,7 +257,7 @@ class CodeCache {

typedef std::unordered_map<CodeCacheItem, CodeCacheEntry, std::hash<CodeCacheItem>, std::equal_to<CodeCacheItem>, std::allocator<std::pair<CodeCacheItem const, CodeCacheEntry>>> CodeCacheListMap;
CodeCacheListMap m_cacheList;
typedef std::unordered_map<size_t, uint64_t> CodeCacheLRUList; /* <Hash, TimeStamp> */
typedef std::unordered_map<CodeCacheScriptIdentifier, uint64_t> CodeCacheLRUList; /* <Hash, TimeStamp> */
CodeCacheLRUList m_cacheLRUList;

CodeCacheWriter* m_cacheWriter;
Expand All @@ -241,10 +280,10 @@ class CodeCache {
void clearAll();
void reset();
void setCacheEntry(const CodeCacheEntryChunk& entryChunk);
bool addCacheEntry(size_t hash, Optional<size_t> functionSourceIndex, const CodeCacheEntry& entry);
bool addCacheEntry(const CodeCacheScriptIdentifier& scriptIdentifier, Optional<size_t> functionSourceIndex, const CodeCacheEntry& entry);

bool removeLRUCacheEntry();
bool removeCacheFile(size_t hash);
bool removeCacheFile(const CodeCacheScriptIdentifier& scriptIdentifier);

void storeCodeBlockTreeNode(InterpretedCodeBlock* codeBlock, size_t& nodeCount);
InterpretedCodeBlock* loadCodeBlockTreeNode(Script* script);
Expand Down
Loading

0 comments on commit 184295c

Please sign in to comment.