Code:
/ 4.0 / 4.0 / 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. /* **************************************************************************** * * 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
- Matrix3DValueSerializer.cs
- Utils.cs
- SQLResource.cs
- WebResponse.cs
- PictureBoxDesigner.cs
- MultipleViewPattern.cs
- PhotoPrintingIntent.cs
- ElementInit.cs
- SmiGettersStream.cs
- ValueConversionAttribute.cs
- BindingExpressionUncommonField.cs
- WebPartChrome.cs
- OpenFileDialog.cs
- IPGlobalProperties.cs
- DataMisalignedException.cs
- HyperLink.cs
- PersonalizationEntry.cs
- CompModHelpers.cs
- PropertyEmitterBase.cs
- SHA512Managed.cs
- UshortList2.cs
- webclient.cs
- UserNameSecurityTokenParameters.cs
- InternalSafeNativeMethods.cs
- _SslSessionsCache.cs
- CallbackCorrelationInitializer.cs
- NotFiniteNumberException.cs
- SendMailErrorEventArgs.cs
- DSASignatureDeformatter.cs
- TimeEnumHelper.cs
- FusionWrap.cs
- MediaElementAutomationPeer.cs
- PageAsyncTask.cs
- DefaultEvaluationContext.cs
- InvokeHandlers.cs
- Positioning.cs
- SqlLiftIndependentRowExpressions.cs
- Privilege.cs
- DataColumnCollection.cs
- MachineKeySection.cs
- SineEase.cs
- RemotingConfigParser.cs
- HttpRequestCacheValidator.cs
- DirectoryInfo.cs
- NonSerializedAttribute.cs
- TextTreeExtractElementUndoUnit.cs
- RowCache.cs
- TabControlDesigner.cs
- ThreadAbortException.cs
- SubclassTypeValidator.cs
- OleDbWrapper.cs
- SecurityState.cs
- ContextStack.cs
- DataMisalignedException.cs
- PropertyTab.cs
- dsa.cs
- TemplateLookupAction.cs
- Query.cs
- SafeCryptoHandles.cs
- CorrelationManager.cs
- HierarchicalDataBoundControlAdapter.cs
- WebPartEventArgs.cs
- PageOutputColor.cs
- TextEndOfParagraph.cs
- Exception.cs
- Double.cs
- IOException.cs
- CopyAction.cs
- ModelVisual3D.cs
- DES.cs
- SegmentInfo.cs
- DataGridViewHitTestInfo.cs
- InvokeProviderWrapper.cs
- DataGridPageChangedEventArgs.cs
- SafeCryptoHandles.cs
- RegexFCD.cs
- SiteMapProvider.cs
- ZoneLinkButton.cs
- BindingList.cs
- PlaceHolder.cs
- TreeViewEvent.cs
- DBConnectionString.cs
- StrongNameKeyPair.cs
- IntegrationExceptionEventArgs.cs
- TableLayoutCellPaintEventArgs.cs
- Point3DCollection.cs
- FaultDesigner.cs
- EmissiveMaterial.cs
- ToolZone.cs
- StorageMappingFragment.cs
- SystemDropShadowChrome.cs
- HttpRequestWrapper.cs
- DictionaryEntry.cs
- ByteStack.cs
- SpecialTypeDataContract.cs
- DataSourceCache.cs
- AssemblyBuilder.cs
- TreeViewImageIndexConverter.cs
- DemultiplexingClientMessageFormatter.cs
- BaseValidator.cs