diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bun.js/module_loader.zig | 38 | ||||
-rw-r--r-- | src/cli/test_command.zig | 13 | ||||
-rw-r--r-- | src/install/install.zig | 22 | ||||
-rw-r--r-- | src/resolver/resolver.zig | 10 |
4 files changed, 56 insertions, 27 deletions
diff --git a/src/bun.js/module_loader.zig b/src/bun.js/module_loader.zig index bee5fa1a1..ae415b65b 100644 --- a/src/bun.js/module_loader.zig +++ b/src/bun.js/module_loader.zig @@ -188,6 +188,7 @@ pub const ModuleLoader = struct { // This is the specific state for making it async poll_ref: JSC.PollRef = .{}, + any_task: JSC.AnyTask = undefined, pub const Id = u32; const debug = Output.scoped(.ModuleLoader, false); @@ -208,6 +209,7 @@ pub const ModuleLoader = struct { pub const Queue = struct { map: Map = .{}, + scheduled: u32 = 0, concurrent_task_count: std.atomic.Atomic(u32) = std.atomic.Atomic(u32).init(0), const DeferredDependencyError = struct { @@ -273,9 +275,11 @@ pub const ModuleLoader = struct { var pm = this.vm().packageManager(); this.runTasks(); + _ = pm.scheduleNetworkTasks(); + this.runTasks(); + this.pollModules(); _ = pm.flushDependencyQueue(); - _ = pm.scheduleNetworkTasks(); } pub fn runTasks(this: *Queue) void { @@ -414,8 +418,11 @@ pub const ModuleLoader = struct { pub fn pollModules(this: *Queue) void { var pm = this.vm().packageManager(); - var modules = this.map.items; + if (pm.pending_tasks > 0) return; + + var modules: []AsyncModule = this.map.items; var i: usize = 0; + for (modules) |mod| { var module = mod; var tags = module.parse_result.pending_imports.items(.tag); @@ -459,8 +466,14 @@ pub const ModuleLoader = struct { switch (pm.determinePreinstallState(package, pm.lockfile)) { .done => { - done_count += 1; - tags[tag_i] = .done; + // we are only truly done if all the dependencies are done. + const current_tasks = pm.total_tasks; + // so if enqueuing all the dependencies produces no new tasks, we are done. + pm.enqueueDependencyList(package.dependencies, false); + if (current_tasks == pm.total_tasks) { + tags[tag_i] = .done; + done_count += 1; + } }, .extracting => { // we are extracting the package @@ -473,9 +486,6 @@ pub const ModuleLoader = struct { } if (done_count == tags.len) { - if (i + 1 >= modules.len) { - this.vm().packageManager().endProgressBar(); - } module.done(this.vm()); } else { modules[i] = module; @@ -529,6 +539,19 @@ pub const ModuleLoader = struct { } pub fn done(this: *AsyncModule, jsc_vm: *JSC.VirtualMachine) void { + var clone = jsc_vm.allocator.create(AsyncModule) catch unreachable; + clone.* = this.*; + jsc_vm.modules.scheduled += 1; + clone.any_task = JSC.AnyTask.New(AsyncModule, onDone).init(clone); + jsc_vm.enqueueTask(JSC.Task.init(&clone.any_task)); + } + + pub fn onDone(this: *AsyncModule) void { + var jsc_vm = this.globalThis.bunVM(); + jsc_vm.modules.scheduled -= 1; + if (jsc_vm.modules.scheduled == 0) { + jsc_vm.packageManager().endProgressBar(); + } var log = logger.Log.init(jsc_vm.allocator); defer log.deinit(); var errorable: ErrorableResolvedSource = undefined; @@ -556,6 +579,7 @@ pub const ModuleLoader = struct { &ref, ); this.deinit(); + jsc_vm.allocator.destroy(this); } pub fn resolveError(this: *AsyncModule, vm: *JSC.VirtualMachine, import_record_id: u32, result: PackageResolveError) !void { diff --git a/src/cli/test_command.zig b/src/cli/test_command.zig index 7b5c88947..ac210dfe2 100644 --- a/src/cli/test_command.zig +++ b/src/cli/test_command.zig @@ -480,6 +480,18 @@ pub const TestCommand = struct { else => {}, } + { + vm.global.vm().drainMicrotasks(); + var count = vm.unhandled_error_counter; + vm.global.handleRejectedPromises(); + while (vm.unhandled_error_counter > count) { + count = vm.unhandled_error_counter; + vm.global.vm().drainMicrotasks(); + vm.global.handleRejectedPromises(); + } + vm.global.vm().doWork(); + } + var modules: []*Jest.DescribeScope = reporter.jest.files.items(.module_scope)[file_start..]; for (modules) |module| { vm.onUnhandledRejectionCtx = null; @@ -501,5 +513,6 @@ pub const TestCommand = struct { _ = vm.global.vm().runGC(false); } vm.global.vm().clearMicrotaskCallback(); + vm.global.handleRejectedPromises(); } }; diff --git a/src/install/install.zig b/src/install/install.zig index a30fdb139..81db2128d 100644 --- a/src/install/install.zig +++ b/src/install/install.zig @@ -2791,8 +2791,6 @@ pub const PackageManager = struct { var lockfile = this.lockfile; var dependency_queue = &lockfile.scratch.dependency_list_queue; - this.flushNetworkQueue(); - while (dependency_queue.readItem()) |dependencies_list| { var i: u32 = dependencies_list.off; const end = dependencies_list.off + dependencies_list.len; @@ -2804,16 +2802,19 @@ pub const PackageManager = struct { false, ) catch {}; } - - this.flushNetworkQueue(); } + + this.flushNetworkQueue(); } pub fn flushDependencyQueue(this: *PackageManager) void { - this.flushNetworkQueue(); - this.doFlushDependencyQueue(); - this.doFlushDependencyQueue(); - this.doFlushDependencyQueue(); - this.flushNetworkQueue(); + var last_count = this.total_tasks; + while (true) : (last_count = this.total_tasks) { + this.flushNetworkQueue(); + this.doFlushDependencyQueue(); + this.flushNetworkQueue(); + + if (this.total_tasks == last_count) break; + } } pub fn scheduleNetworkTasks(manager: *PackageManager) usize { @@ -2987,7 +2988,7 @@ pub const PackageManager = struct { if (manager.dynamic_root_dependencies) |*root_deps| { var deps: []Dependency.Pair = root_deps.items; for (deps) |*dep| { - if (strings.eql(manager.lockfile.str(dep.dependency.name), name.slice())) { + if (strings.eqlLong(manager.lockfile.str(dep.dependency.name), name.slice(), true)) { dep.failed = dep.failed orelse err; } } @@ -3153,7 +3154,6 @@ pub const PackageManager = struct { try manager.processDependencyList(dependency_list, ExtractCompletionContext, extract_ctx, callbacks); - manager.flushDependencyQueue(); continue; } } diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig index b959445dc..309707dde 100644 --- a/src/resolver/resolver.zig +++ b/src/resolver/resolver.zig @@ -1543,22 +1543,14 @@ pub const Resolver = struct { string_buf = package_json.dependencies.source_buf; } - var hash: u64 = std.math.maxInt(u64); - for (dependencies_list) |dependency, dependency_id| { const dep_name_ = &dependency.name; const dep_name = dep_name_.slice(string_buf); if (dep_name.len == esm.name.len) { - if (hash == std.math.maxInt(u64)) { - hash = bun.hash(dep_name); - } - - if (hash != dependency.name_hash) { + if (!strings.eqlLong(dep_name, esm.name, false)) { continue; } - std.debug.assert(strings.eql(dep_name, esm.name)); - dependency_version = dependency.version; dependency_behavior = dependency.behavior; |