public void VisitNode(JSResultReferenceExpression rre) { var invocation = (rre.Referent as JSInvocationExpression); // When passing a packed array element directly to a function, use a proxy instead. // This allows hoisting to operate when the call is inside a loop, and it reduces GC pressure (since we basically make the struct unpack occur on-demand). if ( (ParentNode is JSInvocationExpression) && (invocation != null) && (invocation.JSMethod != null) && invocation.JSMethod.Reference.FullName.Contains("JSIL.Runtime.IPackedArray") && invocation.JSMethod.Reference.FullName.Contains("get_Item(") && Configuration.CodeGenerator.AggressivelyUseElementProxies.GetValueOrDefault(false) ) { var elementType = invocation.GetActualType(TypeSystem); var replacement = new JSNewPackedArrayElementProxy( invocation.ThisReference, invocation.Arguments.First(), elementType ); ParentNode.ReplaceChild(rre, replacement); VisitReplacement(replacement); return; } VisitChildren(rre); }
public void VisitNode(JSNewPackedArrayElementProxy npaep) { var isInsideLoop = (Stack.Any((node) => node is JSLoopStatement)); var parentInvocation = Stack.OfType <JSInvocationExpression>().FirstOrDefault(); var doesValueEscape = (parentInvocation != null) && DoesValueEscapeFromInvocation(parentInvocation, npaep, true); if ( isInsideLoop && ( (parentInvocation == null) || !doesValueEscape ) ) { var replacement = CreateHoistedVariable( (hoistedVariable) => new JSRetargetPackedArrayElementProxy( hoistedVariable, npaep.Array, npaep.Index ), npaep.GetActualType(TypeSystem), npaep.Array, npaep.Index, npaep.MakeUntargeted() ); ParentNode.ReplaceChild(npaep, replacement); VisitReplacement(replacement); } VisitChildren(npaep); }
public void VisitNode (JSResultReferenceExpression rre) { var invocation = (rre.Referent as JSInvocationExpression); // When passing a packed array element directly to a function, use a proxy instead. // This allows hoisting to operate when the call is inside a loop, and it reduces GC pressure (since we basically make the struct unpack occur on-demand). if ( (ParentNode is JSInvocationExpression) && (invocation != null) && (invocation.JSMethod != null) && invocation.JSMethod.Reference.FullName.Contains("JSIL.Runtime.IPackedArray") && invocation.JSMethod.Reference.FullName.Contains("get_Item(") && Configuration.CodeGenerator.AggressivelyUseElementProxies.GetValueOrDefault(false) ) { var elementType = invocation.GetActualType(TypeSystem); var replacement = new JSNewPackedArrayElementProxy( invocation.ThisReference, invocation.Arguments.First(), elementType ); ParentNode.ReplaceChild(rre, replacement); VisitReplacement(replacement); return; } VisitChildren(rre); }
public void VisitNode (JSNewPackedArrayElementProxy npaep) { var isInsideLoop = (Stack.Any((node) => node is JSLoopStatement)); var parentInvocation = Stack.OfType<JSInvocationExpression>().FirstOrDefault(); var doesValueEscape = (parentInvocation != null) && DoesValueEscapeFromInvocation(parentInvocation, npaep, true); if ( isInsideLoop && ( (parentInvocation == null) || !doesValueEscape ) ) { var replacement = CreateHoistedVariable( (hoistedVariable) => new JSRetargetPackedArrayElementProxy( hoistedVariable, npaep.Array, npaep.Index ), npaep.GetActualType(TypeSystem), npaep.Array, npaep.Index, npaep.MakeUntargeted() ); ParentNode.ReplaceChild(npaep, replacement); VisitReplacement(replacement); } VisitChildren(npaep); }