Cache loaded source signatures safely

This commit is contained in:
udo
2026-07-13 08:07:37 +00:00
parent 02ed75fc85
commit ada01e34f4
2 changed files with 58 additions and 6 deletions
+45 -3
View File
@@ -6,7 +6,9 @@
#include <cctype>
#include <filesystem>
#include <fcntl.h>
#include <mutex>
#include <sys/file.h>
#include <sys/stat.h>
#include <unistd.h>
namespace {
@@ -43,6 +45,19 @@ struct SharedUnitCompileCheck
bool needs_compile = false;
};
struct UnitSourceSignatureEntry
{
u64 modified_ns = 0;
u64 changed_ns = 0;
u64 size = 0;
String content_hash;
StringList loaded_paths;
};
const u64 UCE_UNIT_SOURCE_SIGNATURE_CACHE_MAX = 4096;
std::mutex unit_source_signature_cache_mutex;
std::map<String, UnitSourceSignatureEntry> unit_source_signature_cache;
bool compiler_jit_compile_on_request_enabled(Request* context)
{
if(!context || !context->server)
@@ -113,6 +128,33 @@ StringList compiler_unit_load_paths(String file_name, String content)
return(paths);
}
UnitSourceSignatureEntry compiler_unit_source_entry(String file_name)
{
struct stat info;
UnitSourceSignatureEntry entry;
if(stat(file_name.c_str(), &info) != 0)
return(entry);
entry.modified_ns = (u64)info.st_mtim.tv_sec * 1000000000ull + (u64)info.st_mtim.tv_nsec;
entry.changed_ns = (u64)info.st_ctim.tv_sec * 1000000000ull + (u64)info.st_ctim.tv_nsec;
entry.size = (u64)info.st_size;
{
std::lock_guard<std::mutex> lock(unit_source_signature_cache_mutex);
auto cached = unit_source_signature_cache.find(file_name);
if(cached != unit_source_signature_cache.end() && cached->second.modified_ns == entry.modified_ns && cached->second.changed_ns == entry.changed_ns && cached->second.size == entry.size)
return(cached->second);
}
String content = file_get_contents(file_name);
entry.content_hash = gen_sha1(content);
entry.loaded_paths = compiler_unit_load_paths(file_name, content);
{
std::lock_guard<std::mutex> lock(unit_source_signature_cache_mutex);
if(unit_source_signature_cache.size() >= UCE_UNIT_SOURCE_SIGNATURE_CACHE_MAX)
unit_source_signature_cache.clear();
unit_source_signature_cache[file_name] = entry;
}
return(entry);
}
void compiler_append_unit_source_signature(String file_name, std::set<String>& visited, String& signature)
{
String normalized = path_real(file_name);
@@ -122,9 +164,9 @@ void compiler_append_unit_source_signature(String file_name, std::set<String>& v
return;
visited.insert(normalized);
String content = file_get_contents(file_name);
signature += normalized + ":" + gen_sha1(content) + "\n";
for(String loaded : compiler_unit_load_paths(file_name, content))
UnitSourceSignatureEntry entry = compiler_unit_source_entry(normalized);
signature += normalized + ":" + entry.content_hash + "\n";
for(String loaded : entry.loaded_paths)
compiler_append_unit_source_signature(loaded, visited, signature);
}