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
- PrefixQName.cs
- DecoratedNameAttribute.cs
- ConnectionInterfaceCollection.cs
- BufferModesCollection.cs
- ResourceDisplayNameAttribute.cs
- ReverseInheritProperty.cs
- SchemaTableOptionalColumn.cs
- CapabilitiesAssignment.cs
- SerialPort.cs
- UITypeEditors.cs
- ColumnClickEvent.cs
- CodeArrayIndexerExpression.cs
- HtmlToClrEventProxy.cs
- CompModSwitches.cs
- SoapAttributeOverrides.cs
- TypeBrowser.xaml.cs
- AdapterUtil.cs
- Switch.cs
- MessageDroppedTraceRecord.cs
- Options.cs
- BasicViewGenerator.cs
- SqlDataSourceSelectingEventArgs.cs
- ServiceModelSecurityTokenRequirement.cs
- ChangeTracker.cs
- AttachedAnnotationChangedEventArgs.cs
- TreeIterator.cs
- EpmTargetTree.cs
- ClientProtocol.cs
- GenericArgumentsUpdater.cs
- InstancePersistenceEvent.cs
- InProcStateClientManager.cs
- BitmapEffect.cs
- IUnknownConstantAttribute.cs
- IResourceProvider.cs
- EndEvent.cs
- PageThemeParser.cs
- WmlListAdapter.cs
- DbConnectionOptions.cs
- DetailsViewInsertEventArgs.cs
- SQLDecimalStorage.cs
- EtwTrace.cs
- RowToFieldTransformer.cs
- DesignTimeTemplateParser.cs
- DocumentScope.cs
- ScrollProperties.cs
- WebServiceHandlerFactory.cs
- activationcontext.cs
- TableCellAutomationPeer.cs
- SystemFonts.cs
- SystemPens.cs
- ADMembershipProvider.cs
- RegexNode.cs
- RightsManagementUser.cs
- SecurityRuntime.cs
- InputManager.cs
- SqlTopReducer.cs
- ObjectConverter.cs
- RelationalExpressions.cs
- InlinedAggregationOperator.cs
- ReliableOutputConnection.cs
- StrongBox.cs
- XhtmlBasicValidatorAdapter.cs
- ComplusTypeValidator.cs
- TextDecorationLocationValidation.cs
- ObjectHandle.cs
- DesignerSerializationOptionsAttribute.cs
- EmptyEnumerator.cs
- WmlObjectListAdapter.cs
- IfJoinedCondition.cs
- AppLevelCompilationSectionCache.cs
- SelectionItemPattern.cs
- Transactions.cs
- DLinqColumnProvider.cs
- X509UI.cs
- DecoderBestFitFallback.cs
- EntryPointNotFoundException.cs
- brushes.cs
- WorkflowServiceHostFactory.cs
- CompoundFileStorageReference.cs
- PermissionAttributes.cs
- DbConnectionInternal.cs
- handlecollector.cs
- Rotation3DAnimationBase.cs
- SessionPageStateSection.cs
- CollaborationHelperFunctions.cs
- util.cs
- GridItem.cs
- HtmlInputReset.cs
- SqlDataSourceSelectingEventArgs.cs
- RequiredFieldValidator.cs
- BevelBitmapEffect.cs
- DataGridItemCollection.cs
- indexingfiltermarshaler.cs
- XsdValidatingReader.cs
- SID.cs
- DateBoldEvent.cs
- _ReceiveMessageOverlappedAsyncResult.cs
- PriorityChain.cs
- FormsAuthenticationModule.cs
- IArgumentProvider.cs