%PDF- <> %âãÏÓ endobj 2 0 obj <> endobj 3 0 obj <>/ExtGState<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI] >>/Annots[ 28 0 R 29 0 R] /MediaBox[ 0 0 595.5 842.25] /Contents 4 0 R/Group<>/Tabs/S>> endobj ºaâÚÎΞ-ÌE1ÍØÄ÷{òò2ÿ ÛÖ^ÔÀá TÎ{¦?§®¥kuµùÕ5sLOšuY>endobj 2 0 obj<>endobj 2 0 obj<>endobj 2 0 obj<>endobj 2 0 obj<> endobj 2 0 obj<>endobj 2 0 obj<>es 3 0 R>> endobj 2 0 obj<> ox[ 0.000000 0.000000 609.600000 935.600000]/Fi endobj 3 0 obj<> endobj 7 1 obj<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI]>>/Subtype/Form>> stream
#include "cache_builder.h" #include "debug_utils-inl.h" #include "node_native_module.h" #include "util.h" #include <iostream> #include <map> #include <sstream> #include <vector> #include <cstdlib> namespace node { namespace native_module { using v8::Context; using v8::Local; using v8::ScriptCompiler; static std::string GetDefName(const std::string& id) { char buf[64] = {0}; size_t size = id.size(); CHECK_LT(size, sizeof(buf)); for (size_t i = 0; i < size; ++i) { char ch = id[i]; buf[i] = (ch == '-' || ch == '/') ? '_' : ch; } return buf; } static std::string FormatSize(size_t size) { char buf[64] = {0}; if (size < 1024) { snprintf(buf, sizeof(buf), "%.2fB", static_cast<double>(size)); } else if (size < 1024 * 1024) { snprintf(buf, sizeof(buf), "%.2fKB", static_cast<double>(size / 1024)); } else { snprintf( buf, sizeof(buf), "%.2fMB", static_cast<double>(size / 1024 / 1024)); } return buf; } static std::string GetDefinition(const std::string& id, size_t size, const uint8_t* data) { std::stringstream ss; ss << "static const uint8_t " << GetDefName(id) << "[] = {\n"; for (size_t i = 0; i < size; ++i) { uint8_t ch = data[i]; ss << std::to_string(ch) << (i == size - 1 ? '\n' : ','); } ss << "};"; return ss.str(); } static void GetInitializer(const std::string& id, std::stringstream& ss) { std::string def_name = GetDefName(id); ss << " code_cache.emplace(\n"; ss << " \"" << id << "\",\n"; ss << " std::make_unique<v8::ScriptCompiler::CachedData>(\n"; ss << " " << def_name << ",\n"; ss << " static_cast<int>(arraysize(" << def_name << ")), policy\n"; ss << " )\n"; ss << " );"; } static std::string GenerateCodeCache( const std::map<std::string, ScriptCompiler::CachedData*>& data) { std::stringstream ss; ss << R"(#include <cinttypes> #include "node_native_module_env.h" // This file is generated by mkcodecache (tools/code_cache/mkcodecache.cc) namespace node { namespace native_module { const bool has_code_cache = true; )"; size_t total = 0; for (const auto& x : data) { const std::string& id = x.first; ScriptCompiler::CachedData* cached_data = x.second; total += cached_data->length; std::string def = GetDefinition(id, cached_data->length, cached_data->data); ss << def << "\n\n"; std::string size_str = FormatSize(cached_data->length); std::string total_str = FormatSize(total); per_process::Debug(DebugCategory::CODE_CACHE, "Generated cache for %s, size = %s, total = %s\n", id.c_str(), size_str.c_str(), total_str.c_str()); } ss << R"(void NativeModuleEnv::InitializeCodeCache() { NativeModuleCacheMap& code_cache = *NativeModuleLoader::GetInstance()->code_cache(); CHECK(code_cache.empty()); auto policy = v8::ScriptCompiler::CachedData::BufferPolicy::BufferNotOwned; )"; for (const auto& x : data) { GetInitializer(x.first, ss); ss << "\n\n"; } ss << R"( } } // namespace native_module } // namespace node )"; return ss.str(); } std::string CodeCacheBuilder::Generate(Local<Context> context) { NativeModuleLoader* loader = NativeModuleLoader::GetInstance(); std::vector<std::string> ids = loader->GetModuleIds(); std::map<std::string, ScriptCompiler::CachedData*> data; for (const auto& id : ids) { // TODO(joyeecheung): we can only compile the modules that can be // required here because the parameters for other types of builtins // are still very flexible. We should look into auto-generating // the parameters from the source somehow. if (loader->CanBeRequired(id.c_str())) { NativeModuleLoader::Result result; USE(loader->CompileAsModule(context, id.c_str(), &result)); ScriptCompiler::CachedData* cached_data = loader->GetCodeCache(id.c_str()); if (cached_data == nullptr) { // TODO(joyeecheung): display syntax errors std::cerr << "Failed to compile " << id << "\n"; } else { data.emplace(id, cached_data); } } } return GenerateCodeCache(data); } } // namespace native_module } // namespace node