mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Dont memoize calls that produce primitive values
Teaches InferReactiveScopeVariables that calls can produce primitives that don't need a scope.
This commit is contained in:
@@ -1013,7 +1013,7 @@ function hasContextRefOperand(
|
||||
return false;
|
||||
}
|
||||
|
||||
function getFunctionCallSignature(
|
||||
export function getFunctionCallSignature(
|
||||
env: Environment,
|
||||
type: Type
|
||||
): FunctionSignature | null {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import { Environment } from "../HIR";
|
||||
import {
|
||||
HIRFunction,
|
||||
Identifier,
|
||||
@@ -20,6 +21,7 @@ import {
|
||||
eachInstructionOperand,
|
||||
eachPatternOperand,
|
||||
} from "../HIR/visitors";
|
||||
import { getFunctionCallSignature } from "../Inference/InferReferenceEffects";
|
||||
import DisjointSet from "../Utils/DisjointSet";
|
||||
import { assertExhaustive } from "../Utils/utils";
|
||||
|
||||
@@ -103,7 +105,7 @@ export function inferReactiveScopeVariables(fn: HIRFunction): void {
|
||||
for (const instr of block.instructions) {
|
||||
const operands: Array<Identifier> = [];
|
||||
const range = instr.lvalue.identifier.mutableRange;
|
||||
if (range.end > range.start + 1 || mayAllocate(instr.value)) {
|
||||
if (range.end > range.start + 1 || mayAllocate(fn.env, instr.value)) {
|
||||
operands.push(instr.lvalue!.identifier);
|
||||
}
|
||||
if (
|
||||
@@ -217,7 +219,7 @@ function isMutable({ id }: Instruction, place: Place): boolean {
|
||||
return id >= range.start && id < range.end;
|
||||
}
|
||||
|
||||
function mayAllocate(value: InstructionValue): boolean {
|
||||
function mayAllocate(env: Environment, value: InstructionValue): boolean {
|
||||
switch (value.kind) {
|
||||
case "Destructure": {
|
||||
return doesPatternContainSpreadElement(value.lvalue.pattern);
|
||||
@@ -245,12 +247,30 @@ function mayAllocate(value: InstructionValue): boolean {
|
||||
case "Debugger": {
|
||||
return false;
|
||||
}
|
||||
case "CallExpression": {
|
||||
const signature = getFunctionCallSignature(
|
||||
env,
|
||||
value.callee.identifier.type
|
||||
);
|
||||
if (signature !== null) {
|
||||
return signature.returnType.kind !== "Primitive";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case "MethodCall": {
|
||||
const signature = getFunctionCallSignature(
|
||||
env,
|
||||
value.receiver.identifier.type
|
||||
);
|
||||
if (signature !== null) {
|
||||
return signature.returnType.kind !== "Primitive";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case "RegExpLiteral":
|
||||
case "MethodCall":
|
||||
case "PropertyStore":
|
||||
case "ComputedStore":
|
||||
case "ArrayExpression":
|
||||
case "CallExpression":
|
||||
case "JsxExpression":
|
||||
case "JsxFragment":
|
||||
case "NewExpression":
|
||||
|
||||
@@ -15,7 +15,7 @@ function Component(props) {
|
||||
```javascript
|
||||
import { unstable_useMemoCache as useMemoCache } from "react";
|
||||
function Component(props) {
|
||||
const $ = useMemoCache(3);
|
||||
const $ = useMemoCache(2);
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = {};
|
||||
@@ -24,22 +24,15 @@ function Component(props) {
|
||||
t0 = $[0];
|
||||
}
|
||||
const x = t0;
|
||||
const y = Boolean(x);
|
||||
let t1;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = Boolean(x);
|
||||
t1 = [x, y];
|
||||
$[1] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
}
|
||||
const y = t1;
|
||||
let t2;
|
||||
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t2 = [x, y];
|
||||
$[2] = t2;
|
||||
} else {
|
||||
t2 = $[2];
|
||||
}
|
||||
return t2;
|
||||
return t1;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
@@ -15,7 +15,7 @@ function Component(props) {
|
||||
```javascript
|
||||
import { unstable_useMemoCache as useMemoCache } from "react";
|
||||
function Component(props) {
|
||||
const $ = useMemoCache(3);
|
||||
const $ = useMemoCache(2);
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = {};
|
||||
@@ -24,22 +24,15 @@ function Component(props) {
|
||||
t0 = $[0];
|
||||
}
|
||||
const x = t0;
|
||||
const y = Number(x);
|
||||
let t1;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = Number(x);
|
||||
t1 = [x, y];
|
||||
$[1] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
}
|
||||
const y = t1;
|
||||
let t2;
|
||||
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t2 = [x, y];
|
||||
$[2] = t2;
|
||||
} else {
|
||||
t2 = $[2];
|
||||
}
|
||||
return t2;
|
||||
return t1;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
@@ -15,7 +15,7 @@ function Component(props) {
|
||||
```javascript
|
||||
import { unstable_useMemoCache as useMemoCache } from "react";
|
||||
function Component(props) {
|
||||
const $ = useMemoCache(3);
|
||||
const $ = useMemoCache(2);
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = {};
|
||||
@@ -24,22 +24,15 @@ function Component(props) {
|
||||
t0 = $[0];
|
||||
}
|
||||
const x = t0;
|
||||
const y = String(x);
|
||||
let t1;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = String(x);
|
||||
t1 = [x, y];
|
||||
$[1] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
}
|
||||
const y = t1;
|
||||
let t2;
|
||||
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t2 = [x, y];
|
||||
$[2] = t2;
|
||||
} else {
|
||||
t2 = $[2];
|
||||
}
|
||||
return t2;
|
||||
return t1;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user