mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Separate mode to validate preserving manual memoization
Adds a new mode which validates that existing manual memoization is preserved _without_ using information from the manual memoization to affect compilation. This gives us a way to try out the more aggressive version of Forget — ignoring manual memoization — first and see how much code bails out and what patterns cause this. We can then proceed to enable the mode to actually _preserve_ existing memo guarantees only where necessary.
This commit is contained in:
@@ -349,7 +349,10 @@ function* runWithEnvironment(
|
||||
validateMemoizedEffectDependencies(reactiveFunction);
|
||||
}
|
||||
|
||||
if (env.config.enablePreserveExistingMemoizationGuarantees) {
|
||||
if (
|
||||
env.config.enablePreserveExistingMemoizationGuarantees ||
|
||||
env.config.validatePreserveExistingMemoizationGuarantees
|
||||
) {
|
||||
validatePreservedManualMemoization(reactiveFunction);
|
||||
}
|
||||
|
||||
|
||||
@@ -126,6 +126,21 @@ const EnvironmentConfigSchema = z.object({
|
||||
*/
|
||||
enablePreserveExistingMemoizationGuarantees: z.boolean().default(false),
|
||||
|
||||
/**
|
||||
* Validates that all useMemo/useCallback values are also memoized by Forget. This mode can be
|
||||
* used with or without @enablePreserveExistingMemoizationGuarantees.
|
||||
*
|
||||
* With enablePreserveExistingMemoizationGuarantees, this validation enables automatically and
|
||||
* verifies that Forget was able to preserve manual memoization semantics under that mode's
|
||||
* additional assumptions about the input.
|
||||
*
|
||||
* With enablePreserveExistingMemoizationGuarantees off, this validation ignores manual memoization
|
||||
* when determining program behavior, and only uses information from useMemo/useCallback to check
|
||||
* that the memoization was preserved. This can be useful for determining where referential equalities
|
||||
* may change under Forget.
|
||||
*/
|
||||
validatePreserveExistingMemoizationGuarantees: z.boolean().default(false),
|
||||
|
||||
// 🌲
|
||||
enableForest: z.boolean().default(false),
|
||||
// <🌲>
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
SpreadPattern,
|
||||
makeInstructionId,
|
||||
} from "../HIR";
|
||||
import { createTemporaryPlace } from "../HIR/HIRBuilder";
|
||||
import { createTemporaryPlace, markInstructionIds } from "../HIR/HIRBuilder";
|
||||
import { HookKind } from "../HIR/ObjectShape";
|
||||
import { eachInstructionValueOperand } from "../HIR/visitors";
|
||||
|
||||
@@ -114,7 +114,8 @@ export function dropManualMemoization(func: HIRFunction): void {
|
||||
};
|
||||
|
||||
if (
|
||||
func.env.config.enablePreserveExistingMemoizationGuarantees
|
||||
func.env.config.enablePreserveExistingMemoizationGuarantees ||
|
||||
func.env.config.validatePreserveExistingMemoizationGuarantees
|
||||
) {
|
||||
/**
|
||||
* When this flag is enabled we also compile in a 'Memoize' instruction
|
||||
@@ -215,7 +216,8 @@ export function dropManualMemoization(func: HIRFunction): void {
|
||||
loc: instr.value.loc,
|
||||
};
|
||||
if (
|
||||
func.env.config.enablePreserveExistingMemoizationGuarantees
|
||||
func.env.config.enablePreserveExistingMemoizationGuarantees ||
|
||||
func.env.config.validatePreserveExistingMemoizationGuarantees
|
||||
) {
|
||||
nextInstructions =
|
||||
nextInstructions ?? block.instructions.slice(0, i);
|
||||
@@ -295,6 +297,6 @@ export function dropManualMemoization(func: HIRFunction): void {
|
||||
}
|
||||
}
|
||||
if (hasChanges) {
|
||||
// markInstructionIds(func.body);
|
||||
markInstructionIds(func.body);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1163,7 +1163,11 @@ function inferBlock(
|
||||
continue;
|
||||
}
|
||||
case "Memoize": {
|
||||
state.reference(instrValue.value, Effect.Freeze, ValueReason.Other);
|
||||
if (env.config.enablePreserveExistingMemoizationGuarantees) {
|
||||
state.reference(instrValue.value, Effect.Freeze, ValueReason.Other);
|
||||
} else {
|
||||
state.reference(instrValue.value, Effect.Read, ValueReason.Other);
|
||||
}
|
||||
const lvalue = instr.lvalue;
|
||||
lvalue.effect = Effect.ConditionallyMutate;
|
||||
state.initialize(instrValue, {
|
||||
|
||||
Reference in New Issue
Block a user