refactor(ivy): remove calls into other instructions from pipe instructions (#33714)
A while ago we made a pass through all instructions to make sure that none of them call directly into other instructions, however it seems like missed the `pipeBind*` since they still call into the pure functions. The result is that we have some unnecessary duplicated accesses of global state like `getLView` which are called twice in a row with nothing changing. These changes move the common functionality into a shared file and make the pipe instructions call into them with the global state instead. PR Close #33714
This commit is contained in:
parent
794dcb58d3
commit
b1eb84c57e
|
@ -13,8 +13,8 @@ import {getFactoryDef} from './definition';
|
|||
import {store} from './instructions/all';
|
||||
import {PipeDef, PipeDefList} from './interfaces/definition';
|
||||
import {HEADER_OFFSET, LView, TVIEW} from './interfaces/view';
|
||||
import {ɵɵpureFunction1, ɵɵpureFunction2, ɵɵpureFunction3, ɵɵpureFunction4, ɵɵpureFunctionV} from './pure_function';
|
||||
import {getBindingIndex, getLView} from './state';
|
||||
import {pureFunction1Internal, pureFunction2Internal, pureFunction3Internal, pureFunction4Internal, pureFunctionVInternal} from './pure_function';
|
||||
import {getBindingIndex, getBindingRoot, getLView} from './state';
|
||||
import {NO_CHANGE} from './tokens';
|
||||
import {load} from './util/view_utils';
|
||||
|
||||
|
@ -89,7 +89,8 @@ export function ɵɵpipeBind1(index: number, slotOffset: number, v1: any): any {
|
|||
const pipeInstance = load<PipeTransform>(lView, index);
|
||||
return unwrapValue(
|
||||
lView, isPure(lView, index) ?
|
||||
ɵɵpureFunction1(slotOffset, pipeInstance.transform, v1, pipeInstance) :
|
||||
pureFunction1Internal(
|
||||
lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, pipeInstance) :
|
||||
pipeInstance.transform(v1));
|
||||
}
|
||||
|
||||
|
@ -111,7 +112,8 @@ export function ɵɵpipeBind2(index: number, slotOffset: number, v1: any, v2: an
|
|||
const pipeInstance = load<PipeTransform>(lView, index);
|
||||
return unwrapValue(
|
||||
lView, isPure(lView, index) ?
|
||||
ɵɵpureFunction2(slotOffset, pipeInstance.transform, v1, v2, pipeInstance) :
|
||||
pureFunction2Internal(
|
||||
lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, v2, pipeInstance) :
|
||||
pipeInstance.transform(v1, v2));
|
||||
}
|
||||
|
||||
|
@ -133,9 +135,10 @@ export function ɵɵpipeBind3(index: number, slotOffset: number, v1: any, v2: an
|
|||
const lView = getLView();
|
||||
const pipeInstance = load<PipeTransform>(lView, index);
|
||||
return unwrapValue(
|
||||
lView, isPure(lView, index) ?
|
||||
ɵɵpureFunction3(slotOffset, pipeInstance.transform, v1, v2, v3, pipeInstance) :
|
||||
pipeInstance.transform(v1, v2, v3));
|
||||
lView, isPure(lView, index) ? pureFunction3Internal(
|
||||
lView, getBindingRoot(), slotOffset, pipeInstance.transform,
|
||||
v1, v2, v3, pipeInstance) :
|
||||
pipeInstance.transform(v1, v2, v3));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -158,9 +161,10 @@ export function ɵɵpipeBind4(
|
|||
const lView = getLView();
|
||||
const pipeInstance = load<PipeTransform>(lView, index);
|
||||
return unwrapValue(
|
||||
lView, isPure(lView, index) ?
|
||||
ɵɵpureFunction4(slotOffset, pipeInstance.transform, v1, v2, v3, v4, pipeInstance) :
|
||||
pipeInstance.transform(v1, v2, v3, v4));
|
||||
lView, isPure(lView, index) ? pureFunction4Internal(
|
||||
lView, getBindingRoot(), slotOffset, pipeInstance.transform,
|
||||
v1, v2, v3, v4, pipeInstance) :
|
||||
pipeInstance.transform(v1, v2, v3, v4));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -180,7 +184,8 @@ export function ɵɵpipeBindV(index: number, slotOffset: number, values: [any, .
|
|||
const pipeInstance = load<PipeTransform>(lView, index);
|
||||
return unwrapValue(
|
||||
lView, isPure(lView, index) ?
|
||||
ɵɵpureFunctionV(slotOffset, pipeInstance.transform, values, pipeInstance) :
|
||||
pureFunctionVInternal(
|
||||
lView, getBindingRoot(), slotOffset, pipeInstance.transform, values, pipeInstance) :
|
||||
pipeInstance.transform.apply(pipeInstance, values));
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
import {bindingUpdated, bindingUpdated2, bindingUpdated3, bindingUpdated4, getBinding, updateBinding} from './bindings';
|
||||
import {LView} from './interfaces/view';
|
||||
import {getBindingRoot, getLView} from './state';
|
||||
import {NO_CHANGE} from './tokens';
|
||||
|
||||
|
@ -41,7 +42,6 @@ import {NO_CHANGE} from './tokens';
|
|||
* @codeGenApi
|
||||
*/
|
||||
export function ɵɵpureFunction0<T>(slotOffset: number, pureFn: () => T, thisArg?: any): T {
|
||||
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
|
||||
const bindingIndex = getBindingRoot() + slotOffset;
|
||||
const lView = getLView();
|
||||
return lView[bindingIndex] === NO_CHANGE ?
|
||||
|
@ -63,12 +63,7 @@ export function ɵɵpureFunction0<T>(slotOffset: number, pureFn: () => T, thisAr
|
|||
*/
|
||||
export function ɵɵpureFunction1(
|
||||
slotOffset: number, pureFn: (v: any) => any, exp: any, thisArg?: any): any {
|
||||
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
|
||||
const lView = getLView();
|
||||
const bindingIndex = getBindingRoot() + slotOffset;
|
||||
return bindingUpdated(lView, bindingIndex, exp) ?
|
||||
updateBinding(lView, bindingIndex + 1, thisArg ? pureFn.call(thisArg, exp) : pureFn(exp)) :
|
||||
getBinding(lView, bindingIndex + 1);
|
||||
return pureFunction1Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp, thisArg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,14 +82,8 @@ export function ɵɵpureFunction1(
|
|||
export function ɵɵpureFunction2(
|
||||
slotOffset: number, pureFn: (v1: any, v2: any) => any, exp1: any, exp2: any,
|
||||
thisArg?: any): any {
|
||||
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
|
||||
const bindingIndex = getBindingRoot() + slotOffset;
|
||||
const lView = getLView();
|
||||
return bindingUpdated2(lView, bindingIndex, exp1, exp2) ?
|
||||
updateBinding(
|
||||
lView, bindingIndex + 2,
|
||||
thisArg ? pureFn.call(thisArg, exp1, exp2) : pureFn(exp1, exp2)) :
|
||||
getBinding(lView, bindingIndex + 2);
|
||||
return pureFunction2Internal(
|
||||
getLView(), getBindingRoot(), slotOffset, pureFn, exp1, exp2, thisArg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -114,14 +103,8 @@ export function ɵɵpureFunction2(
|
|||
export function ɵɵpureFunction3(
|
||||
slotOffset: number, pureFn: (v1: any, v2: any, v3: any) => any, exp1: any, exp2: any, exp3: any,
|
||||
thisArg?: any): any {
|
||||
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
|
||||
const bindingIndex = getBindingRoot() + slotOffset;
|
||||
const lView = getLView();
|
||||
return bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) ?
|
||||
updateBinding(
|
||||
lView, bindingIndex + 3,
|
||||
thisArg ? pureFn.call(thisArg, exp1, exp2, exp3) : pureFn(exp1, exp2, exp3)) :
|
||||
getBinding(lView, bindingIndex + 3);
|
||||
return pureFunction3Internal(
|
||||
getLView(), getBindingRoot(), slotOffset, pureFn, exp1, exp2, exp3, thisArg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -142,14 +125,8 @@ export function ɵɵpureFunction3(
|
|||
export function ɵɵpureFunction4(
|
||||
slotOffset: number, pureFn: (v1: any, v2: any, v3: any, v4: any) => any, exp1: any, exp2: any,
|
||||
exp3: any, exp4: any, thisArg?: any): any {
|
||||
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
|
||||
const bindingIndex = getBindingRoot() + slotOffset;
|
||||
const lView = getLView();
|
||||
return bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) ?
|
||||
updateBinding(
|
||||
lView, bindingIndex + 4,
|
||||
thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4) : pureFn(exp1, exp2, exp3, exp4)) :
|
||||
getBinding(lView, bindingIndex + 4);
|
||||
return pureFunction4Internal(
|
||||
getLView(), getBindingRoot(), slotOffset, pureFn, exp1, exp2, exp3, exp4, thisArg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -171,7 +148,6 @@ export function ɵɵpureFunction4(
|
|||
export function ɵɵpureFunction5(
|
||||
slotOffset: number, pureFn: (v1: any, v2: any, v3: any, v4: any, v5: any) => any, exp1: any,
|
||||
exp2: any, exp3: any, exp4: any, exp5: any, thisArg?: any): any {
|
||||
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
|
||||
const bindingIndex = getBindingRoot() + slotOffset;
|
||||
const lView = getLView();
|
||||
const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
|
||||
|
@ -202,7 +178,6 @@ export function ɵɵpureFunction5(
|
|||
export function ɵɵpureFunction6(
|
||||
slotOffset: number, pureFn: (v1: any, v2: any, v3: any, v4: any, v5: any, v6: any) => any,
|
||||
exp1: any, exp2: any, exp3: any, exp4: any, exp5: any, exp6: any, thisArg?: any): any {
|
||||
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
|
||||
const bindingIndex = getBindingRoot() + slotOffset;
|
||||
const lView = getLView();
|
||||
const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
|
||||
|
@ -236,7 +211,6 @@ export function ɵɵpureFunction7(
|
|||
slotOffset: number,
|
||||
pureFn: (v1: any, v2: any, v3: any, v4: any, v5: any, v6: any, v7: any) => any, exp1: any,
|
||||
exp2: any, exp3: any, exp4: any, exp5: any, exp6: any, exp7: any, thisArg?: any): any {
|
||||
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
|
||||
const bindingIndex = getBindingRoot() + slotOffset;
|
||||
const lView = getLView();
|
||||
let different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
|
||||
|
@ -272,7 +246,6 @@ export function ɵɵpureFunction8(
|
|||
pureFn: (v1: any, v2: any, v3: any, v4: any, v5: any, v6: any, v7: any, v8: any) => any,
|
||||
exp1: any, exp2: any, exp3: any, exp4: any, exp5: any, exp6: any, exp7: any, exp8: any,
|
||||
thisArg?: any): any {
|
||||
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
|
||||
const bindingIndex = getBindingRoot() + slotOffset;
|
||||
const lView = getLView();
|
||||
const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
|
||||
|
@ -301,10 +274,131 @@ export function ɵɵpureFunction8(
|
|||
*/
|
||||
export function ɵɵpureFunctionV(
|
||||
slotOffset: number, pureFn: (...v: any[]) => any, exps: any[], thisArg?: any): any {
|
||||
// TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
|
||||
let bindingIndex = getBindingRoot() + slotOffset;
|
||||
return pureFunctionVInternal(getLView(), getBindingRoot(), slotOffset, pureFn, exps, thisArg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If the value of the provided exp has changed, calls the pure function to return
|
||||
* an updated value. Or if the value has not changed, returns cached value.
|
||||
*
|
||||
* @param lView LView in which the function is being executed.
|
||||
* @param bindingRoot Binding root index.
|
||||
* @param slotOffset the offset from binding root to the reserved slot
|
||||
* @param pureFn Function that returns an updated value
|
||||
* @param exp Updated expression value
|
||||
* @param thisArg Optional calling context of pureFn
|
||||
* @returns Updated or cached value
|
||||
*/
|
||||
export function pureFunction1Internal(
|
||||
lView: LView, bindingRoot: number, slotOffset: number, pureFn: (v: any) => any, exp: any,
|
||||
thisArg?: any): any {
|
||||
const bindingIndex = bindingRoot + slotOffset;
|
||||
return bindingUpdated(lView, bindingIndex, exp) ?
|
||||
updateBinding(lView, bindingIndex + 1, thisArg ? pureFn.call(thisArg, exp) : pureFn(exp)) :
|
||||
getBinding(lView, bindingIndex + 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If the value of any provided exp has changed, calls the pure function to return
|
||||
* an updated value. Or if no values have changed, returns cached value.
|
||||
*
|
||||
* @param lView LView in which the function is being executed.
|
||||
* @param bindingRoot Binding root index.
|
||||
* @param slotOffset the offset from binding root to the reserved slot
|
||||
* @param pureFn
|
||||
* @param exp1
|
||||
* @param exp2
|
||||
* @param thisArg Optional calling context of pureFn
|
||||
* @returns Updated or cached value
|
||||
*/
|
||||
export function pureFunction2Internal(
|
||||
lView: LView, bindingRoot: number, slotOffset: number, pureFn: (v1: any, v2: any) => any,
|
||||
exp1: any, exp2: any, thisArg?: any): any {
|
||||
const bindingIndex = bindingRoot + slotOffset;
|
||||
return bindingUpdated2(lView, bindingIndex, exp1, exp2) ?
|
||||
updateBinding(
|
||||
lView, bindingIndex + 2,
|
||||
thisArg ? pureFn.call(thisArg, exp1, exp2) : pureFn(exp1, exp2)) :
|
||||
getBinding(lView, bindingIndex + 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the value of any provided exp has changed, calls the pure function to return
|
||||
* an updated value. Or if no values have changed, returns cached value.
|
||||
*
|
||||
* @param lView LView in which the function is being executed.
|
||||
* @param bindingRoot Binding root index.
|
||||
* @param slotOffset the offset from binding root to the reserved slot
|
||||
* @param pureFn
|
||||
* @param exp1
|
||||
* @param exp2
|
||||
* @param exp3
|
||||
* @param thisArg Optional calling context of pureFn
|
||||
* @returns Updated or cached value
|
||||
*/
|
||||
export function pureFunction3Internal(
|
||||
lView: LView, bindingRoot: number, slotOffset: number,
|
||||
pureFn: (v1: any, v2: any, v3: any) => any, exp1: any, exp2: any, exp3: any,
|
||||
thisArg?: any): any {
|
||||
const bindingIndex = bindingRoot + slotOffset;
|
||||
return bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) ?
|
||||
updateBinding(
|
||||
lView, bindingIndex + 3,
|
||||
thisArg ? pureFn.call(thisArg, exp1, exp2, exp3) : pureFn(exp1, exp2, exp3)) :
|
||||
getBinding(lView, bindingIndex + 3);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If the value of any provided exp has changed, calls the pure function to return
|
||||
* an updated value. Or if no values have changed, returns cached value.
|
||||
*
|
||||
* @param lView LView in which the function is being executed.
|
||||
* @param bindingRoot Binding root index.
|
||||
* @param slotOffset the offset from binding root to the reserved slot
|
||||
* @param pureFn
|
||||
* @param exp1
|
||||
* @param exp2
|
||||
* @param exp3
|
||||
* @param exp4
|
||||
* @param thisArg Optional calling context of pureFn
|
||||
* @returns Updated or cached value
|
||||
*
|
||||
*/
|
||||
export function pureFunction4Internal(
|
||||
lView: LView, bindingRoot: number, slotOffset: number,
|
||||
pureFn: (v1: any, v2: any, v3: any, v4: any) => any, exp1: any, exp2: any, exp3: any, exp4: any,
|
||||
thisArg?: any): any {
|
||||
const bindingIndex = bindingRoot + slotOffset;
|
||||
return bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) ?
|
||||
updateBinding(
|
||||
lView, bindingIndex + 4,
|
||||
thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4) : pureFn(exp1, exp2, exp3, exp4)) :
|
||||
getBinding(lView, bindingIndex + 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* pureFunction instruction that can support any number of bindings.
|
||||
*
|
||||
* If the value of any provided exp has changed, calls the pure function to return
|
||||
* an updated value. Or if no values have changed, returns cached value.
|
||||
*
|
||||
* @param lView LView in which the function is being executed.
|
||||
* @param bindingRoot Binding root index.
|
||||
* @param slotOffset the offset from binding root to the reserved slot
|
||||
* @param pureFn A pure function that takes binding values and builds an object or array
|
||||
* containing those values.
|
||||
* @param exps An array of binding values
|
||||
* @param thisArg Optional calling context of pureFn
|
||||
* @returns Updated or cached value
|
||||
*/
|
||||
export function pureFunctionVInternal(
|
||||
lView: LView, bindingRoot: number, slotOffset: number, pureFn: (...v: any[]) => any,
|
||||
exps: any[], thisArg?: any): any {
|
||||
let bindingIndex = bindingRoot + slotOffset;
|
||||
let different = false;
|
||||
const lView = getLView();
|
||||
for (let i = 0; i < exps.length; i++) {
|
||||
bindingUpdated(lView, bindingIndex++, exps[i]) && (different = true);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue