diff --git a/cmake/tools/SetupWebKit.cmake b/cmake/tools/SetupWebKit.cmake index 7ff6ffca0d..3e040a2500 100644 --- a/cmake/tools/SetupWebKit.cmake +++ b/cmake/tools/SetupWebKit.cmake @@ -2,7 +2,7 @@ option(WEBKIT_VERSION "The version of WebKit to use") option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of downloading") if(NOT WEBKIT_VERSION) - set(WEBKIT_VERSION 30046aef5ec6590c74c6a696e4f01683f962a6a2) + set(WEBKIT_VERSION b3d72e752901e40629990469fe5035787230fbc5) endif() if(WEBKIT_LOCAL) diff --git a/src/bun.js/RuntimeTranspilerCache.zig b/src/bun.js/RuntimeTranspilerCache.zig index ad40bc7399..c080ebf033 100644 --- a/src/bun.js/RuntimeTranspilerCache.zig +++ b/src/bun.js/RuntimeTranspilerCache.zig @@ -29,6 +29,7 @@ pub const RuntimeTranspilerCache = struct { exports_kind: bun.JSAst.ExportsKind = .none, output_code: ?bun.String = null, entry: ?Entry = null, + source_map_memory_cost: usize = 0, sourcemap_allocator: std.mem.Allocator, output_code_allocator: std.mem.Allocator, @@ -369,6 +370,14 @@ pub const RuntimeTranspilerCache = struct { return printed.len; } + pub fn memoryCost(this: *const RuntimeTranspilerCache) usize { + if (this.entry) |*entry| { + return entry.metadata.sourcemap_byte_length; + } + + return this.source_map_memory_cost; + } + pub fn getCacheFilePath( buf: *bun.PathBuffer, input_hash: u64, @@ -603,6 +612,7 @@ pub const RuntimeTranspilerCache = struct { debug("get(\"{s}\") = {s}", .{ source.path.text, @errorName(err) }); return false; }; + if (comptime bun.Environment.isDebug) { if (bun_debug_restore_from_cache) { debug("get(\"{s}\") = {d} bytes, restored", .{ source.path.text, this.entry.?.output_code.byteSlice().len }); @@ -634,6 +644,7 @@ pub const RuntimeTranspilerCache = struct { bun.assert(this.entry == null); const output_code = bun.String.createLatin1(output_code_bytes); this.output_code = output_code; + this.source_map_memory_cost = sourcemap.len; toFile(this.input_byte_length.?, this.input_hash.?, this.features_hash.?, sourcemap, output_code, this.exports_kind) catch |err| { debug("put() = {s}", .{@errorName(err)}); diff --git a/src/bun.js/bindings/BunString.cpp b/src/bun.js/bindings/BunString.cpp index 3190415941..535558456e 100644 --- a/src/bun.js/bindings/BunString.cpp +++ b/src/bun.js/bindings/BunString.cpp @@ -56,6 +56,15 @@ extern "C" void Bun__WTFStringImpl__ref(WTF::StringImpl* impl) impl->ref(); } +size_t BunString::memoryCost() const +{ + if (tag == BunStringTag::WTFStringImpl) { + return impl.wtf->sizeInBytes(); + } + + return 0; +} + extern "C" bool BunString__fromJS(JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue encodedValue, BunString* bunString) { JSC::JSValue value = JSC::JSValue::decode(encodedValue); diff --git a/src/bun.js/bindings/CommonJSModuleRecord.cpp b/src/bun.js/bindings/CommonJSModuleRecord.cpp index 9573cfa46a..d95bdd051d 100644 --- a/src/bun.js/bindings/CommonJSModuleRecord.cpp +++ b/src/bun.js/bindings/CommonJSModuleRecord.cpp @@ -156,6 +156,11 @@ static bool evaluateCommonJSModuleOnce(JSC::VM& vm, Zig::GlobalObject* globalObj return true; } + // Report the cost of the sourcemap + if (moduleObject->source_map_memory_cost > 0) { + vm.heap.reportExtraMemoryAllocated(moduleObject, moduleObject->source_map_memory_cost); + } + // This will return 0 if there was a syntax error or an allocation failure JSValue fnValue = JSC::evaluate(globalObject, code, jsUndefined(), exception); @@ -757,6 +762,7 @@ size_t JSCommonJSModule::estimatedSize(JSC::JSCell* cell, JSC::VM& vm) additionalSize *= 2; } } + additionalSize += thisObject->source_map_memory_cost; return Base::estimatedSize(cell, vm) + additionalSize; } @@ -1021,6 +1027,8 @@ void JSCommonJSModule::visitChildrenImpl(JSCell* cell, Visitor& visitor) visitor.append(thisObject->m_dirname); visitor.append(thisObject->m_paths); visitor.append(thisObject->m_overridenParent); + + visitor.reportExtraMemoryVisited(thisObject->source_map_memory_cost); } DEFINE_VISIT_CHILDREN(JSCommonJSModule); @@ -1124,7 +1132,7 @@ bool JSCommonJSModule::evaluate( return true; this->sourceCode = JSC::SourceCode(WTFMove(sourceProvider)); - + this->source_map_memory_cost = source.source_map_memory_cost; WTF::NakedPtr exception; evaluateCommonJSModuleOnce(vm, globalObject, this, this->m_dirname.get(), this->m_filename.get(), exception); @@ -1189,6 +1197,7 @@ std::optional createCommonJSModule( } moduleObject->ignoreESModuleAnnotation = ignoreESModuleAnnotation; + moduleObject->source_map_memory_cost = source.source_map_memory_cost; return JSC::SourceCode( JSC::SyntheticSourceProvider::create( diff --git a/src/bun.js/bindings/CommonJSModuleRecord.h b/src/bun.js/bindings/CommonJSModuleRecord.h index e663dd7460..2bad6c98d9 100644 --- a/src/bun.js/bindings/CommonJSModuleRecord.h +++ b/src/bun.js/bindings/CommonJSModuleRecord.h @@ -56,6 +56,9 @@ public: bool ignoreESModuleAnnotation { false }; JSC::SourceCode sourceCode = JSC::SourceCode(); + // Stored separately from SourceCode since we try to free SourceCode sooner. + size_t source_map_memory_cost = 0; + static size_t estimatedSize(JSC::JSCell* cell, JSC::VM& vm); void setSourceCode(JSC::SourceCode&& sourceCode); diff --git a/src/bun.js/bindings/ZigSourceProvider.h b/src/bun.js/bindings/ZigSourceProvider.h index eddb638665..3b449173bb 100644 --- a/src/bun.js/bindings/ZigSourceProvider.h +++ b/src/bun.js/bindings/ZigSourceProvider.h @@ -44,6 +44,7 @@ public: ~SourceProvider(); unsigned hash() const override; StringView source() const override; + size_t memoryCost() const override { return m_resolvedSource.source_map_memory_cost + m_resolvedSource.source_code.memoryCost(); } RefPtr cachedBytecode() const final { diff --git a/src/bun.js/bindings/headers-handwritten.h b/src/bun.js/bindings/headers-handwritten.h index 8c7b6802a5..94c3d54276 100644 --- a/src/bun.js/bindings/headers-handwritten.h +++ b/src/bun.js/bindings/headers-handwritten.h @@ -72,6 +72,8 @@ typedef struct BunString { // This one usually will clone the raw bytes. WTF::String toWTFString() const; + size_t memoryCost() const; + } BunString; typedef struct ZigErrorType { @@ -107,6 +109,7 @@ typedef struct ResolvedSource { bool already_bundled; uint8_t* bytecode_cache; size_t bytecode_cache_size; + size_t source_map_memory_cost; } ResolvedSource; static const uint32_t ResolvedSourceTagPackageJSONTypeModule = 1; typedef union ErrorableResolvedSourceResult { diff --git a/src/bun.js/module_loader.zig b/src/bun.js/module_loader.zig index b316a1d764..16fa7ad171 100644 --- a/src/bun.js/module_loader.zig +++ b/src/bun.js/module_loader.zig @@ -588,6 +588,7 @@ pub const RuntimeTranspilerStore = struct { .bytecode_cache = if (bytecode_slice.len > 0) bytecode_slice.ptr else null, .bytecode_cache_size = bytecode_slice.len, .is_commonjs_module = parse_result.already_bundled.isCommonJS(), + .source_map_memory_cost = if (parse_result.runtime_transpiler_cache) |transpiler_cache| transpiler_cache.memoryCost() else 0, }; this.resolved_source.source_code.ensureHash(); return; @@ -689,6 +690,7 @@ pub const RuntimeTranspilerStore = struct { .source_url = duped.createIfDifferent(path.text), .is_commonjs_module = parse_result.ast.has_commonjs_export_names or parse_result.ast.exports_kind == .cjs, .hash = 0, + .source_map_memory_cost = if (parse_result.runtime_transpiler_cache) |transpiler_cache| transpiler_cache.memoryCost() else 0, }; } }; @@ -1451,7 +1453,7 @@ pub const ModuleLoader = struct { .specifier = String.init(specifier), .source_url = String.init(path.text), .is_commonjs_module = parse_result.ast.has_commonjs_export_names or parse_result.ast.exports_kind == .cjs, - + .source_map_memory_cost = if (parse_result.runtime_transpiler_cache) |transpiler_cache| transpiler_cache.memoryCost() else 0, .hash = 0, }; } @@ -1802,6 +1804,7 @@ pub const ModuleLoader = struct { } if (cache.entry) |*entry| { + const source_map_memory_cost = entry.sourcemap.len; jsc_vm.source_mappings.putMappings(parse_result.source, .{ .list = .{ .items = @constCast(entry.sourcemap), .capacity = entry.sourcemap.len }, .allocator = bun.default_allocator, @@ -1843,6 +1846,7 @@ pub const ModuleLoader = struct { break :brk ResolvedSource.Tag.javascript; }, + .source_map_memory_cost = source_map_memory_cost, }; } @@ -1899,7 +1903,6 @@ pub const ModuleLoader = struct { defer source_code_printer.* = printer; _ = brk: { var mapper = jsc_vm.sourceMapHandler(&printer); - break :brk try jsc_vm.transpiler.printWithSourceMap( parse_result, @TypeOf(&printer), @@ -1961,6 +1964,7 @@ pub const ModuleLoader = struct { .is_commonjs_module = parse_result.ast.has_commonjs_export_names or parse_result.ast.exports_kind == .cjs, .hash = 0, .tag = tag, + .source_map_memory_cost = if (parse_result.runtime_transpiler_cache) |transpiler_cache| transpiler_cache.memoryCost() else 0, }; }, // provideFetch() should be called