Compare commits

...

2 Commits

Author SHA1 Message Date
Jarred Sumner
57441cbc2a Update exports.zig 2025-01-01 01:49:32 -08:00
Jarred Sumner
697d9c19ff Report memory cost of sourcemaps 2025-01-01 01:31:43 -08:00
9 changed files with 45 additions and 4 deletions

View File

@@ -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)

View File

@@ -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)});

View File

@@ -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);

View File

@@ -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<JSC::Exception> exception;
evaluateCommonJSModuleOnce(vm, globalObject, this, this->m_dirname.get(), this->m_filename.get(), exception);
@@ -1189,6 +1197,7 @@ std::optional<JSC::SourceCode> createCommonJSModule(
}
moduleObject->ignoreESModuleAnnotation = ignoreESModuleAnnotation;
moduleObject->source_map_memory_cost = source.source_map_memory_cost;
return JSC::SourceCode(
JSC::SyntheticSourceProvider::create(

View File

@@ -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);

View File

@@ -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<JSC::CachedBytecode> cachedBytecode() const final
{

View File

@@ -222,6 +222,7 @@ pub const ResolvedSource = extern struct {
already_bundled: bool = false,
bytecode_cache: ?[*]u8 = null,
bytecode_cache_size: usize = 0,
source_map_memory_cost: usize = 0,
pub const Tag = @import("ResolvedSourceTag").ResolvedSourceTag;
};

View File

@@ -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 {

View File

@@ -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