From ca16ec0886701f2acad7140bba7aeef3d652f329 Mon Sep 17 00:00:00 2001 From: Alistair Smith Date: Wed, 28 Jan 2026 12:18:44 -0800 Subject: [PATCH 1/3] some debug logs in CachedTypes to help us understand why misses might happen --- Source/JavaScriptCore/runtime/CachedTypes.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Source/JavaScriptCore/runtime/CachedTypes.cpp b/Source/JavaScriptCore/runtime/CachedTypes.cpp index aafb86346322..e2d506df20bb 100644 --- a/Source/JavaScriptCore/runtime/CachedTypes.cpp +++ b/Source/JavaScriptCore/runtime/CachedTypes.cpp @@ -1543,12 +1543,16 @@ class CachedSourceOrigin : public CachedObject { public: void encode(Encoder& encoder, const SourceOrigin& sourceOrigin) { + dataLogLnIf(Options::verboseDiskCache(), "[Disk Cache] CachedSourceOrigin encode: url='", sourceOrigin.url().string(), "' host='", sourceOrigin.url().host(), "'"); m_string.encode(encoder, sourceOrigin.url().string()); } SourceOrigin decode(Decoder& decoder) const { - return SourceOrigin { URL({ }, m_string.decode(decoder)) }; + String decodedString = m_string.decode(decoder); + URL decodedURL({ }, decodedString); + dataLogLnIf(Options::verboseDiskCache(), "[Disk Cache] CachedSourceOrigin decode: stored='", decodedString, "' decoded_host='", decodedURL.host(), "'"); + return SourceOrigin { WTF::move(decodedURL) }; } private: @@ -2680,8 +2684,13 @@ UnlinkedCodeBlock* decodeCodeBlockImpl(VM& vm, const SourceCodeKey& key, Refdecode(decoder.get(), entry)) return nullptr; } - if (entry.first != key) + if (entry.first != key) { + dataLogLnIf(Options::verboseDiskCache(), "[Disk Cache] key mismatch for ", key.source().provider().sourceURL(), + " hash: ", entry.first.hash(), " vs ", key.hash(), + " length: ", entry.first.length(), " vs ", key.length(), + " host: '", entry.first.host(), "' vs '", key.host(), "'"); return nullptr; + } if (Options::reportBytecodeCacheDecodeTimes()) [[unlikely]] { MonotonicTime after = MonotonicTime::now(); From 9112a156498220d7567d6fbec215c80a2618f5e4 Mon Sep 17 00:00:00 2001 From: Alistair Smith Date: Wed, 28 Jan 2026 12:39:00 -0800 Subject: [PATCH 2/3] Try to always use file:// paths? --- Source/JavaScriptCore/runtime/CachedTypes.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Source/JavaScriptCore/runtime/CachedTypes.cpp b/Source/JavaScriptCore/runtime/CachedTypes.cpp index e2d506df20bb..5c12c3b6ecad 100644 --- a/Source/JavaScriptCore/runtime/CachedTypes.cpp +++ b/Source/JavaScriptCore/runtime/CachedTypes.cpp @@ -1541,18 +1541,23 @@ class CachedMetadataTable : public CachedObject { class CachedSourceOrigin : public CachedObject { public: + // Upstream WebKit stores sourceOrigin.url().string() and re-parses it + // on decode with URL({}, string). In Bun, source origins are always + // file paths constructed via fileURLWithFileSystemPath. On Windows, + // fileURLWithFileSystemPath produces a URL with a different internal + // host() than what re-parsing the same URL's string() gives (drive + // letter "B:" is treated as host). This breaks SourceCodeKey::operator== + // which compares host(). To avoid this, we store the file system path + // directly and reconstruct via fileURLWithFileSystemPath on decode, + // so both encode/decode and runtime use the same construction path. void encode(Encoder& encoder, const SourceOrigin& sourceOrigin) { - dataLogLnIf(Options::verboseDiskCache(), "[Disk Cache] CachedSourceOrigin encode: url='", sourceOrigin.url().string(), "' host='", sourceOrigin.url().host(), "'"); - m_string.encode(encoder, sourceOrigin.url().string()); + m_string.encode(encoder, sourceOrigin.url().fileSystemPath()); } SourceOrigin decode(Decoder& decoder) const { - String decodedString = m_string.decode(decoder); - URL decodedURL({ }, decodedString); - dataLogLnIf(Options::verboseDiskCache(), "[Disk Cache] CachedSourceOrigin decode: stored='", decodedString, "' decoded_host='", decodedURL.host(), "'"); - return SourceOrigin { WTF::move(decodedURL) }; + return SourceOrigin { URL::fileURLWithFileSystemPath(m_string.decode(decoder)) }; } private: From 318bffcd1dbd996c51c7fd864a2e16a01ca37590 Mon Sep 17 00:00:00 2001 From: Alistair Smith Date: Wed, 28 Jan 2026 16:03:35 -0800 Subject: [PATCH 3/3] try to fix bytecode cache miss on Windows standalone executables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Windows, the JSC bytecode cache SourceCodeKey compares host() of the source origin URL. The URLs are constructed via fileURLWithFileSystemPath(), which internally passes the path string to the WHATWG URL parser. The URL parser produces different host() values depending on whether the path uses forward slashes or backslashes: fileURLWithFileSystemPath("B:/BUN/root/app.js") → parser enters FileHost state, sees "B:" as drive letter → windowsQuirk triggers, but host='B' is set internally fileURLWithFileSystemPath("B:\BUN\root\app.js") → parser treats \ as path separator, skips FileHost state → host='' (empty) The bytecode cache stores the source origin via CachedSourceOrigin. Previously, encode stored url().string() and decode re-parsed it. This commit changes encode to store url().fileSystemPath() and decode to reconstruct via fileURLWithFileSystemPath(), ensuring both sides use the same construction path. However, fileSystemPath() on Windows returns backslashes (converting / to \), while the runtime source URL uses forward slashes (e.g. "B:/BUN/root/app.js" from the standalone module graph). This causes fileURLWithFileSystemPath to produce host='' on the cached side but host='B' on the runtime side, failing the SourceCodeKey comparison. The fix normalizes the stored path to use forward slashes, matching the runtime convention used throughout Bun's standalone module graph. --- Source/JavaScriptCore/runtime/CachedTypes.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Source/JavaScriptCore/runtime/CachedTypes.cpp b/Source/JavaScriptCore/runtime/CachedTypes.cpp index 5c12c3b6ecad..d54774d60003 100644 --- a/Source/JavaScriptCore/runtime/CachedTypes.cpp +++ b/Source/JavaScriptCore/runtime/CachedTypes.cpp @@ -1552,7 +1552,15 @@ class CachedSourceOrigin : public CachedObject { // so both encode/decode and runtime use the same construction path. void encode(Encoder& encoder, const SourceOrigin& sourceOrigin) { - m_string.encode(encoder, sourceOrigin.url().fileSystemPath()); + String path = sourceOrigin.url().fileSystemPath(); +#if OS(WINDOWS) + // fileSystemPath() returns backslashes on Windows, but + // fileURLWithFileSystemPath handles forward and back slashes + // differently — forward slashes match how source URLs are + // constructed at runtime (e.g. "B:/BUN/root/app.js"). + path = makeStringByReplacingAll(path, '\\', '/'); +#endif + m_string.encode(encoder, path); } SourceOrigin decode(Decoder& decoder) const