From 1818b104185169c89a91fbc6b1ccb4d091b2f135 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Wed, 21 Jan 2026 09:35:26 +0100 Subject: [PATCH 1/3] Update deterministic-build assertion (#88820) --- .../deterministic-build/deployment-id.test.ts | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/test/production/deterministic-build/deployment-id.test.ts b/test/production/deterministic-build/deployment-id.test.ts index a2d13f0249182..721a599b93560 100644 --- a/test/production/deterministic-build/deployment-id.test.ts +++ b/test/production/deterministic-build/deployment-id.test.ts @@ -27,30 +27,18 @@ async function readFiles(next: NextInstance) { ) } -// TODO static/* browser chunks are content hashed and have the deployment id inlined -const IGNORE_NAME = /^static\/chunks\// const IGNORE_CONTENT = new RegExp( [ - // TODO These contain content-hashed browser chunk urls (and/or the deployment id query param) - 'page_client-reference-manifest\\.js', - 'build-manifest\\.json', - // TODO This contains - // - content-hashed browser chunk urls (and/or the deployment id query param) - // - browser chunk urls inside of a folder named after the build id - 'middleware-build-manifest\\.js', // TODO this contains "env": { "__NEXT_BUILD_ID": "taBOOu8Znzobe4G7wEG_i", 'middleware-manifest\\.json', // TODO this contains the build id 'BUILD_ID', // TODO this contains the build id: "/pages-static-gsp": { "dataRoute": "/_next/data/V7oVUAlS1LiV5CqrtpkAL/pages-static-gsp.json", 'prerender-manifest\\.json', - // TODO These contain (but are not deployed to the serverless function itself) - // - content-hashed browser chunk urls - // - the build id + // TODO These contain the build id (but are not deployed to the serverless function itself) '.*\\.html', '.*\\.rsc', // These are not critical, as they aren't deployed to the serverless function itself - '_buildManifest\\.js', 'client-build-manifest\\.json', 'fallback-build-manifest\\.json', 'routes-manifest\\.json', @@ -98,9 +86,6 @@ const IGNORE_CONTENT = new RegExp( await next.build() let run2 = await readFiles(next) - run1 = run1.filter(([f, _]) => !IGNORE_NAME.test(f)) - run2 = run2.filter(([f, _]) => !IGNORE_NAME.test(f)) - // First, compare file names let run1FileNames = run1.map(([f, _]) => f) let run2FileNames = run2.map(([f, _]) => f) From 1bdb2e20052281c614a8bfef08a6ebb66a546129 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 21 Jan 2026 10:36:24 +0100 Subject: [PATCH 2/3] Turbopack: shrink amortized (#88619) ### What? Use amortized shrinking. Capacity should always be a power of 2. We shrink when len is capacity / 3. Assuming the capacity was `2^x` we shrink to `2^(x-1)` which is `capacity / 2`. Therefore capacity is still larger than len, which avoids direct reallocation when items are added again. --- .../crates/turbo-tasks-auto-hash-map/src/map.rs | 5 ++++- .../turbo-tasks-backend/src/backend/mod.rs | 4 ++++ .../crates/turbo-tasks/src/priority_runner.rs | 17 +++++++++++------ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/turbopack/crates/turbo-tasks-auto-hash-map/src/map.rs b/turbopack/crates/turbo-tasks-auto-hash-map/src/map.rs index 92d599b459235..8821cfcf93630 100644 --- a/turbopack/crates/turbo-tasks-auto-hash-map/src/map.rs +++ b/turbopack/crates/turbo-tasks-auto-hash-map/src/map.rs @@ -271,7 +271,9 @@ impl AutoMap { if list.capacity() > list.len() * 3 { - list.shrink_to_fit(); + // You need to call "grow" to shrink a SmallVec to a specific capacity + // There is no Vec::shrink_to() equivalent for SmallVec + list.grow(list.len().next_power_of_two()); } } AutoMap::Map(map) => { @@ -280,6 +282,7 @@ impl AutoMap map.len() * 3 { + // HashMaps will always have a capacity that is a power of two map.shrink_to_fit(); } } diff --git a/turbopack/crates/turbo-tasks-backend/src/backend/mod.rs b/turbopack/crates/turbo-tasks-backend/src/backend/mod.rs index 6a83bbea783f8..ed44f3ef298a7 100644 --- a/turbopack/crates/turbo-tasks-backend/src/backend/mod.rs +++ b/turbopack/crates/turbo-tasks-backend/src/backend/mod.rs @@ -2580,6 +2580,10 @@ impl TurboTasksBackendInner { task.shrink_to_fit(CachedDataItemType::CellDependency); task.shrink_to_fit(CachedDataItemType::OutputDependency); task.shrink_to_fit(CachedDataItemType::CollectiblesDependency); + task.shrink_to_fit(CachedDataItemType::OutdatedOutputDependency); + task.shrink_to_fit(CachedDataItemType::OutdatedCellDependency); + task.shrink_to_fit(CachedDataItemType::OutdatedCollectiblesDependency); + task.shrink_to_fit(CachedDataItemType::OutdatedCollectible); drop(task); } diff --git a/turbopack/crates/turbo-tasks/src/priority_runner.rs b/turbopack/crates/turbo-tasks/src/priority_runner.rs index 484a63c70fec0..ce4eed37397cb 100644 --- a/turbopack/crates/turbo-tasks/src/priority_runner.rs +++ b/turbopack/crates/turbo-tasks/src/priority_runner.rs @@ -176,9 +176,7 @@ impl< ) -> Option<(E::Future, Option>)> { let mut queue = self.queue.lock(); if let Some(heap_item) = queue.pop() { - if queue.len() * 2 + 16 < queue.capacity() { - queue.shrink_to_fit(); - } + shrink_amortized(&mut queue); drop(queue); let tx = heap_item.tx; Some(( @@ -198,9 +196,7 @@ impl< ) -> bool { let mut queue = self.queue.lock(); if let Some(heap_item) = queue.pop() { - if queue.len() * 2 + 16 < queue.capacity() { - queue.shrink_to_fit(); - } + shrink_amortized(&mut queue); drop(queue); let tx = heap_item.tx; let new_future = @@ -218,6 +214,15 @@ impl< } } +fn shrink_amortized(queue: &mut BinaryHeap>) { + // Amortized shrinking of the queue, but with a lower threshold to avoid + // frequent reallocations when the queue is small. + if queue.capacity() > queue.len() * 3 && queue.capacity() > 128 { + let new_capacity = queue.len().next_power_of_two().max(128); + queue.shrink_to(new_capacity); + } +} + #[derive(Debug)] enum WorkerState { UnfinishedFuture, From d5d760540d2ff2630d5275a30577e51cac8f2620 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Wed, 21 Jan 2026 12:29:36 +0100 Subject: [PATCH 3/3] Fix deployment test due to data-dpl-id attribute (#88846) --- test/e2e/favicon-short-circuit/favicon-short-circuit.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/e2e/favicon-short-circuit/favicon-short-circuit.test.ts b/test/e2e/favicon-short-circuit/favicon-short-circuit.test.ts index 049e9d6f5c3dd..f252b88d4890f 100644 --- a/test/e2e/favicon-short-circuit/favicon-short-circuit.test.ts +++ b/test/e2e/favicon-short-circuit/favicon-short-circuit.test.ts @@ -28,9 +28,9 @@ describe('favicon-short-circuit', () => { expect(res.status).toBe(404) expect(res.headers.get('content-type')).toBe('text/html; charset=utf-8') - // Expect we got the right body. + // Expect we got HTML as text (with a non-empty body unlike in dev) and also not binary data const html = await res.text() - expect(html).toContain('') + expect(html).toContain('