@@ -23,13 +23,37 @@ namespace {
23
23
// we'd likely need to have find return an atomic refcount or something similar.
24
24
class CompileCache {
25
25
public:
26
- void add (const void * key, std::unique_ptr<v8::ScriptCompiler::CachedData> cached) const {
27
- cache.lockExclusive ()->upsert (key, kj::mv (cached), [](auto &, auto &&) {});
26
+ class Data {
27
+ public:
28
+ Data (): data(nullptr ), length(0 ), owningPtr(nullptr ) {};
29
+ explicit Data (std::shared_ptr<v8::ScriptCompiler::CachedData> cached_data)
30
+ : data(cached_data->data),
31
+ length(cached_data->length),
32
+ owningPtr(cached_data) {};
33
+
34
+ std::unique_ptr<v8::ScriptCompiler::CachedData> AsCachedData () {
35
+ return std::make_unique<v8::ScriptCompiler::CachedData>(
36
+ data, length, v8::ScriptCompiler::CachedData::BufferNotOwned);
37
+ }
38
+
39
+ const uint8_t * data;
40
+ size_t length;
41
+
42
+ private:
43
+ std::shared_ptr<void > owningPtr;
44
+ };
45
+
46
+ void add (kj::StringPtr key, std::shared_ptr<v8::ScriptCompiler::CachedData> cached) const {
47
+ cache.lockExclusive ()->upsert (kj::str (key), Data (kj::mv (cached)), [](auto &, auto &&) {});
28
48
}
29
49
30
- kj::Maybe<v8::ScriptCompiler::CachedData&> find (const void * key) const {
31
- return cache.lockShared ()->find (key).map (
32
- [](auto & data) -> v8::ScriptCompiler::CachedData& { return *data; });
50
+ kj::Maybe<Data&> find (kj::StringPtr key) const {
51
+ KJ_IF_SOME (value, cache.lockExclusive ()->find (key)) {
52
+ if (value.data != nullptr ) {
53
+ return value;
54
+ }
55
+ }
56
+ return kj::none;
33
57
}
34
58
35
59
static const CompileCache& get () {
@@ -39,7 +63,7 @@ public:
39
63
40
64
private:
41
65
// The key is the address of the static global that was compiled to produce the CachedData.
42
- kj::MutexGuarded<kj::HashMap<const void *, std::unique_ptr<v8::ScriptCompiler::CachedData> >> cache;
66
+ kj::MutexGuarded<kj::HashMap<kj::String, Data >> cache;
43
67
};
44
68
45
69
// Implementation of `v8::Module::ResolveCallback`.
@@ -429,25 +453,19 @@ v8::Local<v8::Module> compileEsmModule(jsg::Lock& js,
429
453
// may need to revisit that to import built-ins as UTF-16 (two-byte).
430
454
contentStr = jsg::newExternalOneByteString (js, content);
431
455
432
- // TODO(bug): The cache is failing under certain conditions. Disabling this logic
433
- // for now until it can be debugged.
434
- // const auto& compileCache = CompileCache::get();
435
- // KJ_IF_SOME(cached, compileCache.find(content.begin())) {
436
- // v8::ScriptCompiler::Source source(contentStr, origin, &cached);
437
- // v8::ScriptCompiler::CompileOptions options = v8::ScriptCompiler::kConsumeCodeCache;
438
- // KJ_DEFER(if (source.GetCachedData()->rejected) {
439
- // KJ_LOG(ERROR, kj::str("Failed to load module '", name ,"' using compile cache"));
440
- // js.throwException(KJ_EXCEPTION(FAILED, "jsg.Error: Internal error"));
441
- // });
442
- // return jsg::check(v8::ScriptCompiler::CompileModule(js.v8Isolate, &source, options));
443
- // }
456
+ const auto & compileCache = CompileCache::get ();
457
+ KJ_IF_SOME (cached, compileCache.find (name)) {
458
+ auto options = v8::ScriptCompiler::kConsumeCodeCache ;
459
+ v8::ScriptCompiler::Source script_source (contentStr, origin, cached.AsCachedData ().release ());
460
+ return jsg::check (v8::ScriptCompiler::CompileModule (js.v8Isolate , &script_source, options));
461
+ }
444
462
445
463
v8::ScriptCompiler::Source source (contentStr, origin);
446
464
auto module = jsg::check (v8::ScriptCompiler::CompileModule (js.v8Isolate , &source));
447
465
448
- auto cachedData = std::unique_ptr <v8::ScriptCompiler::CachedData>(
466
+ auto cachedData = std::shared_ptr <v8::ScriptCompiler::CachedData>(
449
467
v8::ScriptCompiler::CreateCodeCache (module ->GetUnboundModuleScript ()));
450
- // compileCache.add(content.begin() , kj::mv(cachedData));
468
+ compileCache.add (name , kj::mv (cachedData));
451
469
return module ;
452
470
}
453
471
0 commit comments