Skip to content

Commit 8083f9d

Browse files
perf(serialization): restore rolled back references without a journal
Recording every replaced position allocated two slots and retained the item for the whole serialize call, and `HarmonyExportImportedSpecifierDependency` calls `setCircularReference` on every instance, so re-export heavy graphs paid for thousands of entries. Positions only ever grow, so a rollback can find the markers a `setCircularReference` replaced by scanning the cycle stack for a position at or past the snapshot's, which allocates nothing while serializing.
1 parent 44e274c commit 8083f9d

2 files changed

Lines changed: 8 additions & 26 deletions

File tree

‎lib/serialization/ObjectMiddleware.js‎

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ Technically any value can be used.
5757
* @property {number} length
5858
* @property {number} cycleStackSize
5959
* @property {number} referenceableSize
60-
* @property {number} overwrittenReferencesLength
6160
* @property {number} currentPos
6261
* @property {number} objectTypeLookupSize
6362
* @property {number} currentPosTypeLookup
@@ -375,22 +374,11 @@ class ObjectMiddleware extends SerializerMiddleware {
375374
let currentPos = 0;
376375
/** @type {Map<ReferenceableItem, number>} */
377376
let referenceable = new Map();
378-
/**
379-
* Item and prior position, in pairs, for the positions `addReferenceable` replaced.
380-
* @type {(ReferenceableItem | number)[]}
381-
*/
382-
const overwrittenReferences = [];
383377
/**
384378
* Adds referenceable.
385379
* @param {ReferenceableItem} item referenceable item
386380
*/
387381
const addReferenceable = (item) => {
388-
const previous = referenceable.get(item);
389-
// `setMapSize` can only drop keys added since a snapshot, so an
390-
// overwritten position has to be recorded to be undone
391-
if (previous !== undefined) {
392-
overwrittenReferences.push(item, previous);
393-
}
394382
referenceable.set(item, currentPos++);
395383
};
396384
/** @type {Map<number, Buffer | [Buffer, Buffer] | Map<string, Buffer>>} */
@@ -747,7 +735,6 @@ class ObjectMiddleware extends SerializerMiddleware {
747735
length: result.length,
748736
cycleStackSize: cycleStack.length,
749737
referenceableSize: referenceable.size,
750-
overwrittenReferencesLength: overwrittenReferences.length,
751738
currentPos,
752739
objectTypeLookupSize: objectTypeLookup.size,
753740
currentPosTypeLookup
@@ -756,19 +743,15 @@ class ObjectMiddleware extends SerializerMiddleware {
756743
rollback(snapshot) {
757744
result.length = snapshot.length;
758745
cycleStack.length = snapshot.cycleStackSize;
759-
// newest first, so the oldest recorded position is the one kept,
760-
// and before the truncation that drops the keys added since
761-
for (
762-
let i = overwrittenReferences.length - 2;
763-
i >= snapshot.overwrittenReferencesLength;
764-
i -= 2
765-
) {
766-
referenceable.set(
767-
/** @type {ReferenceableItem} */ (overwrittenReferences[i]),
768-
/** @type {number} */ (overwrittenReferences[i + 1])
769-
);
746+
// a `setCircularReference` since the snapshot replaced a marker on an
747+
// item already keyed here, which `setMapSize` cannot undo
748+
for (let i = 0; i < cycleStack.length; i++) {
749+
const item = /** @type {ReferenceableItem} */ (cycleStack[i]);
750+
const ref = referenceable.get(item);
751+
if (ref !== undefined && ref >= snapshot.currentPos) {
752+
referenceable.set(item, IN_PROGRESS);
753+
}
770754
}
771-
overwrittenReferences.length = snapshot.overwrittenReferencesLength;
772755
setMapSize(referenceable, snapshot.referenceableSize);
773756
currentPos = snapshot.currentPos;
774757
setMapSize(objectTypeLookup, snapshot.objectTypeLookupSize);

‎types.d.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20030,7 +20030,6 @@ declare interface ObjectSerializerSnapshot {
2003020030
length: number;
2003120031
cycleStackSize: number;
2003220032
referenceableSize: number;
20033-
overwrittenReferencesLength: number;
2003420033
currentPos: number;
2003520034
objectTypeLookupSize: number;
2003620035
currentPosTypeLookup: number;

0 commit comments

Comments
 (0)