Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / Microsoft / Scripting / Compiler / StackSpiller.Temps.cs / 1305376 / StackSpiller.Temps.cs
/* **************************************************************************** * * Copyright (c) Microsoft Corporation. * * This source code is subject to terms and conditions of the Microsoft Public License. A * copy of the license can be found in the License.html file at the root of this distribution. If * you cannot locate the Microsoft Public License, please send an email to * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound * by the terms of the Microsoft Public License. * * You must not remove this notice, or any other, from this software. * * * ***************************************************************************/ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Dynamic.Utils; namespace System.Linq.Expressions.Compiler { internal partial class StackSpiller { private class TempMaker { ////// Current temporary variable /// private int _temp; ////// List of free temporary variables. These can be recycled for new temps. /// private List_freeTemps; /// /// Stack of currently active temporary variables. /// private Stack_usedTemps; /// /// List of all temps created by stackspiller for this rule/lambda /// private List_temps = new List (); internal List Temps { get { return _temps; } } internal ParameterExpression Temp(Type type) { ParameterExpression temp; if (_freeTemps != null) { // Recycle from the free-list if possible. for (int i = _freeTemps.Count - 1; i >= 0; i--) { temp = _freeTemps[i]; if (temp.Type == type) { _freeTemps.RemoveAt(i); return UseTemp(temp); } } } // Not on the free-list, create a brand new one. temp = Expression.Variable(type, "$temp$" + _temp++); _temps.Add(temp); return UseTemp(temp); } private ParameterExpression UseTemp(ParameterExpression temp) { Debug.Assert(_freeTemps == null || !_freeTemps.Contains(temp)); Debug.Assert(_usedTemps == null || !_usedTemps.Contains(temp)); if (_usedTemps == null) { _usedTemps = new Stack (); } _usedTemps.Push(temp); return temp; } private void FreeTemp(ParameterExpression temp) { Debug.Assert(_freeTemps == null || !_freeTemps.Contains(temp)); if (_freeTemps == null) { _freeTemps = new List (); } _freeTemps.Add(temp); } internal int Mark() { return _usedTemps != null ? _usedTemps.Count : 0; } // Free temporaries created since the last marking. // This is a performance optimization to lower the overall number of tempories needed. internal void Free(int mark) { // (_usedTemps != null) ==> (mark <= _usedTemps.Count) Debug.Assert(_usedTemps == null || mark <= _usedTemps.Count); // (_usedTemps == null) ==> (mark == 0) Debug.Assert(mark == 0 || _usedTemps != null); if (_usedTemps != null) { while (mark < _usedTemps.Count) { FreeTemp(_usedTemps.Pop()); } } } [Conditional("DEBUG")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")] internal void VerifyTemps() { Debug.Assert(_usedTemps == null || _usedTemps.Count == 0); } } /// /// Rewrites child expressions, spilling them into temps if needed. The /// stack starts in the inital state, and after the first subexpression /// is added it is change to non-empty. This behavior can be overridden /// by setting the stack manually between adds. /// /// When all children have been added, the caller should rewrite the /// node if Rewrite is true. Then, it should call Finish with etiher /// the orignal expression or the rewritten expression. Finish will call /// Expression.Comma if necessary and return a new Result. /// private class ChildRewriter { private readonly StackSpiller _self; private readonly Expression[] _expressions; private int _expressionsCount; private List_comma; private RewriteAction _action; private Stack _stack; private bool _done; internal ChildRewriter(StackSpiller self, Stack stack, int count) { _self = self; _stack = stack; _expressions = new Expression[count]; } internal void Add(Expression node) { Debug.Assert(!_done); if (node == null) { _expressions[_expressionsCount++] = null; return; } Result exp = _self.RewriteExpression(node, _stack); _action |= exp.Action; _stack = Stack.NonEmpty; // track items in case we need to copy or spill stack _expressions[_expressionsCount++] = exp.Node; } internal void Add(IList expressions) { for (int i = 0, count = expressions.Count; i < count; i++) { Add(expressions[i]); } } internal void AddArguments(IArgumentProvider expressions) { for (int i = 0, count = expressions.ArgumentCount; i < count; i++) { Add(expressions.GetArgument(i)); } } private void EnsureDone() { // done adding arguments, build the comma if necessary if (!_done) { _done = true; if (_action == RewriteAction.SpillStack) { Expression[] clone = _expressions; int count = clone.Length; List comma = new List (count + 1); for (int i = 0; i < count; i++) { if (clone[i] != null) { Expression temp; clone[i] = _self.ToTemp(clone[i], out temp); comma.Add(temp); } } comma.Capacity = comma.Count + 1; _comma = comma; } } } internal bool Rewrite { get { return _action != RewriteAction.None; } } internal RewriteAction Action { get { return _action; } } internal Result Finish(Expression expr) { EnsureDone(); if (_action == RewriteAction.SpillStack) { Debug.Assert(_comma.Capacity == _comma.Count + 1); _comma.Add(expr); expr = MakeBlock(_comma); } return new Result(_action, expr); } internal Expression this[int index] { get { EnsureDone(); if (index < 0) { index += _expressions.Length; } return _expressions[index]; } } internal Expression[] this[int first, int last] { get { EnsureDone(); if (last < 0) { last += _expressions.Length; } int count = last - first + 1; ContractUtils.RequiresArrayRange(_expressions, first, count, "first", "last"); if (count == _expressions.Length) { Debug.Assert(first == 0); // if the entire array is requested just return it so we don't make a new array return _expressions; } Expression[] clone = new Expression[count]; Array.Copy(_expressions, first, clone, 0, count); return clone; } } } private ParameterExpression MakeTemp(Type type) { return _tm.Temp(type); } private int Mark() { return _tm.Mark(); } private void Free(int mark) { _tm.Free(mark); } [Conditional("DEBUG")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")] private void VerifyTemps() { _tm.VerifyTemps(); } /// /// Will perform: /// save: temp = expression /// return value: temp /// private ParameterExpression ToTemp(Expression expression, out Expression save) { ParameterExpression temp = MakeTemp(expression.Type); save = Expression.Assign(temp, expression); return temp; } ////// Creates a special block that is marked as not allowing jumps in. /// This should not be used for rewriting BlockExpression itself, or /// anything else that supports jumping. /// private static Expression MakeBlock(params Expression[] expressions) { return MakeBlock((IList)expressions); } /// /// Creates a special block that is marked as not allowing jumps in. /// This should not be used for rewriting BlockExpression itself, or /// anything else that supports jumping. /// private static Expression MakeBlock(IListexpressions) { return new SpilledExpressionBlock(expressions); } } /// /// A special subtype of BlockExpression that indicates to the compiler /// that this block is a spilled expression and should not allow jumps in. /// internal sealed class SpilledExpressionBlock : BlockN { internal SpilledExpressionBlock(IListexpressions) : base(expressions) { } internal override BlockExpression Rewrite(ReadOnlyCollection variables, Expression[] args) { throw ContractUtils.Unreachable; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ViewGenResults.cs
- ActiveXHost.cs
- AxHost.cs
- HttpRuntimeSection.cs
- SecurityManager.cs
- SafeEventLogWriteHandle.cs
- QualificationDataAttribute.cs
- CodeExporter.cs
- WebPartsSection.cs
- AssociativeAggregationOperator.cs
- GridItemCollection.cs
- _SpnDictionary.cs
- ArraySegment.cs
- VisualStyleRenderer.cs
- FaultDesigner.cs
- ServiceSecurityAuditBehavior.cs
- VarRefManager.cs
- InlineObject.cs
- KeyBinding.cs
- ConstructorExpr.cs
- SmtpSpecifiedPickupDirectoryElement.cs
- ProfileEventArgs.cs
- StoreItemCollection.cs
- _SSPIWrapper.cs
- SafeProcessHandle.cs
- TaskFormBase.cs
- CredentialSelector.cs
- cache.cs
- SessionStateItemCollection.cs
- AnimationTimeline.cs
- AnnotationMap.cs
- TextTreeObjectNode.cs
- ApplicationInfo.cs
- DataListItemEventArgs.cs
- InvalidOleVariantTypeException.cs
- CFStream.cs
- PointLight.cs
- CodeCatchClause.cs
- RoleService.cs
- OrderedEnumerableRowCollection.cs
- GridViewRowCollection.cs
- XmlName.cs
- TreeNodeConverter.cs
- MatrixCamera.cs
- SHA384Managed.cs
- PanelStyle.cs
- XmlUtil.cs
- PointConverter.cs
- PolyQuadraticBezierSegment.cs
- PolyQuadraticBezierSegment.cs
- ExpanderAutomationPeer.cs
- StringValidatorAttribute.cs
- RuleSetCollection.cs
- WindowsTooltip.cs
- ToolStripComboBox.cs
- InlineCollection.cs
- CodeSnippetStatement.cs
- SecurityTokenProvider.cs
- InvalidFilterCriteriaException.cs
- Environment.cs
- LockRecursionException.cs
- Wildcard.cs
- XpsFontSerializationService.cs
- ListViewDeletedEventArgs.cs
- TextFormatterImp.cs
- MetadataArtifactLoaderCompositeResource.cs
- _ConnectOverlappedAsyncResult.cs
- GCHandleCookieTable.cs
- KernelTypeValidation.cs
- TraceInternal.cs
- AccessViolationException.cs
- ObfuscateAssemblyAttribute.cs
- BaseHashHelper.cs
- Int32AnimationUsingKeyFrames.cs
- InstanceKeyView.cs
- WinInet.cs
- DocumentEventArgs.cs
- HandlerBase.cs
- DbConnectionFactory.cs
- NestedContainer.cs
- PropertyBuilder.cs
- MissingMemberException.cs
- HitTestParameters.cs
- ConnectionProviderAttribute.cs
- EntityDataSourceConfigureObjectContext.cs
- DiscreteKeyFrames.cs
- DotExpr.cs
- DatePicker.cs
- CommonObjectSecurity.cs
- NullableDecimalAverageAggregationOperator.cs
- WindowsIdentity.cs
- BitmapImage.cs
- MenuAdapter.cs
- RuleInfoComparer.cs
- Point.cs
- ControlOperationInvoker.cs
- WorkflowDesignerMessageFilter.cs
- FormsAuthenticationCredentials.cs
- TimeZone.cs
- ObjectHandle.cs