perf(ivy): avoid repeat LView reads in property instructions (#32681)

Currently all property instructions eventually call into `elementPropertyInternal` which in turn calls to `getLView`, however all of the instructions already have access to the LView. These changes switch to passing in the LView as a parameter.

PR Close #32681
This commit is contained in:
crisbeto 2019-09-14 13:18:37 +02:00 committed by Kara Erickson
parent 4c061271db
commit e6ed4a21e4
5 changed files with 21 additions and 20 deletions

View File

@ -843,7 +843,7 @@ function readUpdateOpCodes(
case I18nUpdateOpCode.Attr: case I18nUpdateOpCode.Attr:
const propName = updateOpCodes[++j] as string; const propName = updateOpCodes[++j] as string;
const sanitizeFn = updateOpCodes[++j] as SanitizerFn | null; const sanitizeFn = updateOpCodes[++j] as SanitizerFn | null;
elementPropertyInternal(nodeIndex, propName, value, sanitizeFn); elementPropertyInternal(viewData, nodeIndex, propName, value, sanitizeFn);
break; break;
case I18nUpdateOpCode.Text: case I18nUpdateOpCode.Text:
textBindingInternal(viewData, nodeIndex, value); textBindingInternal(viewData, nodeIndex, value);

View File

@ -33,7 +33,7 @@ export function ɵɵhostProperty<T>(
const bindingIndex = lView[BINDING_INDEX]++; const bindingIndex = lView[BINDING_INDEX]++;
if (bindingUpdated(lView, bindingIndex, value)) { if (bindingUpdated(lView, bindingIndex, value)) {
const nodeIndex = getSelectedIndex(); const nodeIndex = getSelectedIndex();
elementPropertyInternal(nodeIndex, propName, value, sanitizer, true); elementPropertyInternal(lView, nodeIndex, propName, value, sanitizer, true);
ngDevMode && storePropertyBindingMetadata(lView[TVIEW].data, nodeIndex, propName, bindingIndex); ngDevMode && storePropertyBindingMetadata(lView[TVIEW].data, nodeIndex, propName, bindingIndex);
} }
return ɵɵhostProperty; return ɵɵhostProperty;
@ -67,7 +67,8 @@ export function ɵɵupdateSyntheticHostBinding<T>(
const bindingIndex = lView[BINDING_INDEX]++; const bindingIndex = lView[BINDING_INDEX]++;
if (bindingUpdated(lView, bindingIndex, value)) { if (bindingUpdated(lView, bindingIndex, value)) {
const nodeIndex = getSelectedIndex(); const nodeIndex = getSelectedIndex();
elementPropertyInternal(nodeIndex, propName, value, sanitizer, true, loadComponentRenderer); elementPropertyInternal(
lView, nodeIndex, propName, value, sanitizer, true, loadComponentRenderer);
ngDevMode && storePropertyBindingMetadata(lView[TVIEW].data, nodeIndex, propName, bindingIndex); ngDevMode && storePropertyBindingMetadata(lView[TVIEW].data, nodeIndex, propName, bindingIndex);
} }
return ɵɵupdateSyntheticHostBinding; return ɵɵupdateSyntheticHostBinding;

View File

@ -37,8 +37,8 @@ export function ɵɵproperty<T>(
const bindingIndex = lView[BINDING_INDEX]++; const bindingIndex = lView[BINDING_INDEX]++;
if (bindingUpdated(lView, bindingIndex, value)) { if (bindingUpdated(lView, bindingIndex, value)) {
const nodeIndex = getSelectedIndex(); const nodeIndex = getSelectedIndex();
elementPropertyInternal(nodeIndex, propName, value, sanitizer); elementPropertyInternal(lView, nodeIndex, propName, value, sanitizer);
ngDevMode && storePropertyBindingMetadata(lView[TVIEW].data, nodeIndex, propName, bindingIndex); ngDevMode && storePropertyBindingMetadata(lView[TVIEW].data, nodeIndex, propName, bindingIndex);
} }
return ɵɵproperty; return ɵɵproperty;
} }

View File

@ -85,7 +85,7 @@ export function ɵɵpropertyInterpolate1(
const lView = getLView(); const lView = getLView();
const interpolatedValue = interpolation1(lView, prefix, v0, suffix); const interpolatedValue = interpolation1(lView, prefix, v0, suffix);
if (interpolatedValue !== NO_CHANGE) { if (interpolatedValue !== NO_CHANGE) {
elementPropertyInternal(getSelectedIndex(), propName, interpolatedValue, sanitizer); elementPropertyInternal(lView, getSelectedIndex(), propName, interpolatedValue, sanitizer);
ngDevMode && storePropertyBindingMetadata( ngDevMode && storePropertyBindingMetadata(
lView[TVIEW].data, getSelectedIndex(), propName, lView[BINDING_INDEX] - 1, lView[TVIEW].data, getSelectedIndex(), propName, lView[BINDING_INDEX] - 1,
prefix, suffix); prefix, suffix);
@ -130,7 +130,7 @@ export function ɵɵpropertyInterpolate2(
const interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix); const interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
if (interpolatedValue !== NO_CHANGE) { if (interpolatedValue !== NO_CHANGE) {
const nodeIndex = getSelectedIndex(); const nodeIndex = getSelectedIndex();
elementPropertyInternal(nodeIndex, propName, interpolatedValue, sanitizer); elementPropertyInternal(lView, nodeIndex, propName, interpolatedValue, sanitizer);
ngDevMode && ngDevMode &&
storePropertyBindingMetadata( storePropertyBindingMetadata(
lView[TVIEW].data, nodeIndex, propName, lView[BINDING_INDEX] - 2, prefix, i0, suffix); lView[TVIEW].data, nodeIndex, propName, lView[BINDING_INDEX] - 2, prefix, i0, suffix);
@ -178,7 +178,7 @@ export function ɵɵpropertyInterpolate3(
const interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix); const interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
if (interpolatedValue !== NO_CHANGE) { if (interpolatedValue !== NO_CHANGE) {
const nodeIndex = getSelectedIndex(); const nodeIndex = getSelectedIndex();
elementPropertyInternal(nodeIndex, propName, interpolatedValue, sanitizer); elementPropertyInternal(lView, nodeIndex, propName, interpolatedValue, sanitizer);
ngDevMode && storePropertyBindingMetadata( ngDevMode && storePropertyBindingMetadata(
lView[TVIEW].data, nodeIndex, propName, lView[BINDING_INDEX] - 3, prefix, i0, lView[TVIEW].data, nodeIndex, propName, lView[BINDING_INDEX] - 3, prefix, i0,
i1, suffix); i1, suffix);
@ -228,7 +228,7 @@ export function ɵɵpropertyInterpolate4(
const interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix); const interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
if (interpolatedValue !== NO_CHANGE) { if (interpolatedValue !== NO_CHANGE) {
const nodeIndex = getSelectedIndex(); const nodeIndex = getSelectedIndex();
elementPropertyInternal(nodeIndex, propName, interpolatedValue, sanitizer); elementPropertyInternal(lView, nodeIndex, propName, interpolatedValue, sanitizer);
ngDevMode && storePropertyBindingMetadata( ngDevMode && storePropertyBindingMetadata(
lView[TVIEW].data, nodeIndex, propName, lView[BINDING_INDEX] - 4, prefix, i0, lView[TVIEW].data, nodeIndex, propName, lView[BINDING_INDEX] - 4, prefix, i0,
i1, i2, suffix); i1, i2, suffix);
@ -281,7 +281,7 @@ export function ɵɵpropertyInterpolate5(
interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix); interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
if (interpolatedValue !== NO_CHANGE) { if (interpolatedValue !== NO_CHANGE) {
const nodeIndex = getSelectedIndex(); const nodeIndex = getSelectedIndex();
elementPropertyInternal(nodeIndex, propName, interpolatedValue, sanitizer); elementPropertyInternal(lView, nodeIndex, propName, interpolatedValue, sanitizer);
ngDevMode && storePropertyBindingMetadata( ngDevMode && storePropertyBindingMetadata(
lView[TVIEW].data, nodeIndex, propName, lView[BINDING_INDEX] - 5, prefix, i0, lView[TVIEW].data, nodeIndex, propName, lView[BINDING_INDEX] - 5, prefix, i0,
i1, i2, i3, suffix); i1, i2, i3, suffix);
@ -337,7 +337,7 @@ export function ɵɵpropertyInterpolate6(
interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix); interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
if (interpolatedValue !== NO_CHANGE) { if (interpolatedValue !== NO_CHANGE) {
const nodeIndex = getSelectedIndex(); const nodeIndex = getSelectedIndex();
elementPropertyInternal(nodeIndex, propName, interpolatedValue, sanitizer); elementPropertyInternal(lView, nodeIndex, propName, interpolatedValue, sanitizer);
ngDevMode && storePropertyBindingMetadata( ngDevMode && storePropertyBindingMetadata(
lView[TVIEW].data, nodeIndex, propName, lView[BINDING_INDEX] - 6, prefix, i0, lView[TVIEW].data, nodeIndex, propName, lView[BINDING_INDEX] - 6, prefix, i0,
i1, i2, i3, i4, suffix); i1, i2, i3, i4, suffix);
@ -395,7 +395,7 @@ export function ɵɵpropertyInterpolate7(
interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix); interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
if (interpolatedValue !== NO_CHANGE) { if (interpolatedValue !== NO_CHANGE) {
const nodeIndex = getSelectedIndex(); const nodeIndex = getSelectedIndex();
elementPropertyInternal(nodeIndex, propName, interpolatedValue, sanitizer); elementPropertyInternal(lView, nodeIndex, propName, interpolatedValue, sanitizer);
ngDevMode && storePropertyBindingMetadata( ngDevMode && storePropertyBindingMetadata(
lView[TVIEW].data, nodeIndex, propName, lView[BINDING_INDEX] - 7, prefix, i0, lView[TVIEW].data, nodeIndex, propName, lView[BINDING_INDEX] - 7, prefix, i0,
i1, i2, i3, i4, i5, suffix); i1, i2, i3, i4, i5, suffix);
@ -455,7 +455,7 @@ export function ɵɵpropertyInterpolate8(
lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix); lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
if (interpolatedValue !== NO_CHANGE) { if (interpolatedValue !== NO_CHANGE) {
const nodeIndex = getSelectedIndex(); const nodeIndex = getSelectedIndex();
elementPropertyInternal(nodeIndex, propName, interpolatedValue, sanitizer); elementPropertyInternal(lView, nodeIndex, propName, interpolatedValue, sanitizer);
ngDevMode && storePropertyBindingMetadata( ngDevMode && storePropertyBindingMetadata(
lView[TVIEW].data, nodeIndex, propName, lView[BINDING_INDEX] - 8, prefix, i0, lView[TVIEW].data, nodeIndex, propName, lView[BINDING_INDEX] - 8, prefix, i0,
i1, i2, i3, i4, i5, i6, suffix); i1, i2, i3, i4, i5, i6, suffix);
@ -499,7 +499,7 @@ export function ɵɵpropertyInterpolateV(
const interpolatedValue = interpolationV(lView, values); const interpolatedValue = interpolationV(lView, values);
if (interpolatedValue !== NO_CHANGE) { if (interpolatedValue !== NO_CHANGE) {
const nodeIndex = getSelectedIndex(); const nodeIndex = getSelectedIndex();
elementPropertyInternal(nodeIndex, propName, interpolatedValue, sanitizer); elementPropertyInternal(lView, nodeIndex, propName, interpolatedValue, sanitizer);
if (ngDevMode) { if (ngDevMode) {
const interpolationInBetween = [values[0]]; // prefix const interpolationInBetween = [values[0]]; // prefix
for (let i = 2; i < values.length; i += 2) { for (let i = 2; i < values.length; i += 2) {

View File

@ -30,7 +30,7 @@ import {isComponentDef, isComponentHost, isContentQueryHost, isLContainer, isRoo
import {BINDING_INDEX, CHILD_HEAD, CHILD_TAIL, CLEANUP, CONTEXT, DECLARATION_VIEW, ExpandoInstructions, FLAGS, HEADER_OFFSET, HOST, INJECTOR, InitPhaseState, LView, LViewFlags, NEXT, PARENT, RENDERER, RENDERER_FACTORY, RootContext, RootContextFlags, SANITIZER, TData, TVIEW, TView, T_HOST} from '../interfaces/view'; import {BINDING_INDEX, CHILD_HEAD, CHILD_TAIL, CLEANUP, CONTEXT, DECLARATION_VIEW, ExpandoInstructions, FLAGS, HEADER_OFFSET, HOST, INJECTOR, InitPhaseState, LView, LViewFlags, NEXT, PARENT, RENDERER, RENDERER_FACTORY, RootContext, RootContextFlags, SANITIZER, TData, TVIEW, TView, T_HOST} from '../interfaces/view';
import {assertNodeOfPossibleTypes} from '../node_assert'; import {assertNodeOfPossibleTypes} from '../node_assert';
import {isNodeMatchingSelectorList} from '../node_selector_matcher'; import {isNodeMatchingSelectorList} from '../node_selector_matcher';
import {getBindingsEnabled, getCheckNoChangesMode, getIsParent, getLView, getPreviousOrParentTNode, getSelectedIndex, incrementActiveDirectiveId, namespaceHTMLInternal, selectView, setActiveHostElement, setBindingRoot, setCheckNoChangesMode, setCurrentDirectiveDef, setCurrentQueryIndex, setPreviousOrParentTNode, setSelectedIndex} from '../state'; import {getBindingsEnabled, getCheckNoChangesMode, getIsParent, getPreviousOrParentTNode, getSelectedIndex, incrementActiveDirectiveId, namespaceHTMLInternal, selectView, setActiveHostElement, setBindingRoot, setCheckNoChangesMode, setCurrentDirectiveDef, setCurrentQueryIndex, setPreviousOrParentTNode, setSelectedIndex} from '../state';
import {renderStylingMap} from '../styling_next/bindings'; import {renderStylingMap} from '../styling_next/bindings';
import {NO_CHANGE} from '../tokens'; import {NO_CHANGE} from '../tokens';
import {ANIMATION_PROP_PREFIX, isAnimationProp} from '../util/attrs_utils'; import {ANIMATION_PROP_PREFIX, isAnimationProp} from '../util/attrs_utils';
@ -860,10 +860,10 @@ function mapPropName(name: string): string {
} }
export function elementPropertyInternal<T>( export function elementPropertyInternal<T>(
index: number, propName: string, value: T, sanitizer?: SanitizerFn | null, nativeOnly?: boolean, lView: LView, index: number, propName: string, value: T, sanitizer?: SanitizerFn | null,
nativeOnly?: boolean,
loadRendererFn?: ((tNode: TNode, lView: LView) => Renderer3) | null): void { loadRendererFn?: ((tNode: TNode, lView: LView) => Renderer3) | null): void {
ngDevMode && assertNotSame(value, NO_CHANGE as any, 'Incoming value should never be NO_CHANGE.'); ngDevMode && assertNotSame(value, NO_CHANGE as any, 'Incoming value should never be NO_CHANGE.');
const lView = getLView();
const element = getNativeByIndex(index, lView) as RElement | RComment; const element = getNativeByIndex(index, lView) as RElement | RComment;
const tNode = getTNode(index, lView); const tNode = getTNode(index, lView);
let inputData = tNode.inputs; let inputData = tNode.inputs;
@ -1155,7 +1155,7 @@ function postProcessDirective<T>(
directiveDefIdx: number): void { directiveDefIdx: number): void {
postProcessBaseDirective(lView, hostTNode, directive); postProcessBaseDirective(lView, hostTNode, directive);
if (hostTNode.attrs !== null) { if (hostTNode.attrs !== null) {
setInputsFromAttrs(directiveDefIdx, directive, def, hostTNode); setInputsFromAttrs(lView, directiveDefIdx, directive, def, hostTNode);
} }
if (isComponentDef(def)) { if (isComponentDef(def)) {
@ -1337,13 +1337,14 @@ export function elementAttributeInternal(
/** /**
* Sets initial input properties on directive instances from attribute data * Sets initial input properties on directive instances from attribute data
* *
* @param lView Current LView that is being processed.
* @param directiveIndex Index of the directive in directives array * @param directiveIndex Index of the directive in directives array
* @param instance Instance of the directive on which to set the initial inputs * @param instance Instance of the directive on which to set the initial inputs
* @param def The directive def that contains the list of inputs * @param def The directive def that contains the list of inputs
* @param tNode The static data for this node * @param tNode The static data for this node
*/ */
function setInputsFromAttrs<T>( function setInputsFromAttrs<T>(
directiveIndex: number, instance: T, def: DirectiveDef<T>, tNode: TNode): void { lView: LView, directiveIndex: number, instance: T, def: DirectiveDef<T>, tNode: TNode): void {
let initialInputData = tNode.initialInputs as InitialInputData | undefined; let initialInputData = tNode.initialInputs as InitialInputData | undefined;
if (initialInputData === undefined || directiveIndex >= initialInputData.length) { if (initialInputData === undefined || directiveIndex >= initialInputData.length) {
initialInputData = generateInitialInputs(directiveIndex, def.inputs, tNode); initialInputData = generateInitialInputs(directiveIndex, def.inputs, tNode);
@ -1362,7 +1363,6 @@ function setInputsFromAttrs<T>(
(instance as any)[privateName] = value; (instance as any)[privateName] = value;
} }
if (ngDevMode) { if (ngDevMode) {
const lView = getLView();
const nativeElement = getNativeByTNode(tNode, lView) as RElement; const nativeElement = getNativeByTNode(tNode, lView) as RElement;
setNgReflectProperty(lView, nativeElement, tNode.type, privateName, value); setNgReflectProperty(lView, nativeElement, tNode.type, privateName, value);
} }