1. 06 3月, 2015 1 次提交
  2. 01 2月, 2015 1 次提交
    • B
      Complete the style update to the rest of Open\src directory · 995eb372
      beep boop 提交于
           Background:
      
           As discussed in the dev team all hands all code under the GitHub dotnet foundation is using a single process for contribution, API review, infrastructure and coding style. The idea is to present a unified view to our customer and give them a single story for contributing to any project under the dotnet foundation.
      
           https://github.com/dotnet/corefx/wiki/Contributing#c-coding-style
      
           The coding style transition is automated using a Roslyn based rewrite tool:
      
           https://github.com/dotnet/codeformatter
      
           This will be applied in stages across our developer tree. Right now the focus is on the Open directory as this is what is being presented on github. Code owners will be contacted before the transition happens.
      
           Note: this is a soft style requirement. There are no build errors that come from this change.
       (changeset 1408227)
      995eb372
  3. 31 1月, 2015 1 次提交
    • T
      EnC support for lambdas & closures in C# compiler · ebc795d4
      TomasMatousek 提交于
      1) Change MethdCompiler.BindMethodBody to associate correct syntax with BoundBlocks it creates when binding constructor with constructor initializer call (two bound blocks are created – outer one defines a closure scope for constructor parameters, the inner one defines a closure scope for variables in the body).
      2) Introduce MethodDebugId – a method ordinal and generation ordinal pair
      3) Introduce LamdbaDebugInfo and ClosureDebugInfo to represent information (syntax offset) we use to figure out how to map lambdas and closures to the previous generation.
      4) Adds a new PDB CDI record (#7) to store lambda and closure debug info.
      5) Generalizes CalculateLocalSyntaxOffset to handle positions in field/property initializers and constructor initializers. Use it to calculate syntax offsets of lambdas and closure scopes. (TODO: rename CalculateLocalSyntaxOffset to CalculateSyntaxOffset).
      6) Replace lambda and scope ordinal dispenser integers with array builders that collect LambdaDebugInfo and ClosureDebugInfo.
      7) Use TryGet- pattern for all VariableSlotAllocator APIs.
      8) Implements mapping of lambda method and display class names to previous generation via VariableSlotAllocator.
       (changeset 1407240)
      ebc795d4
  4. 28 1月, 2015 1 次提交
    • T
      The compiler emits catch-all handler to all async methods. In case of async... · b564f8c4
      TomasMatousek 提交于
      The compiler emits catch-all handler to all async methods. In case of async void methods we also emit the offset of the catch handler to PDB, so that the debugger can pretend that exceptions thrown by the async method are unhandled. Otherwise they are lost. Currently the compiler emits wrong offset, so the debugger is completely confused and displays "no source location" when such exception occurs.
      
           The fix is to remove a synthesized "nop" instruction that was incorrectly used to track the catch handler IL offset. Instead mark the synthesized BoundCatchHandler node by a flag and create the IL marker in the CodeGen when emitting instructions for such bound node.
      
           Affects both C# and VB.
      
           Fixes bug 1114809. (changeset 1405564)
      b564f8c4
  5. 15 1月, 2015 1 次提交
  6. 14 1月, 2015 2 次提交
    • R
      e315208f
    • T
      Synthesized VB names · e7a20119
      TomasMatousek 提交于
      1) Assigns each member a "member ordinal" - the index in the members array of the containing type. The ordinal is propagated thru lowering rewriters which uses it to make generated names unique.
           2) We no longer calculate "overload ordinal" for names of state machine types, we use the member ordinal of the async/iterator method instead.
           3) Removes GenerateTempNumber from TypeCompilationState. Combination of method ordinal and other indices is used to make generated names unique:
           - Display classes use ordinal of the method containing the lambda and closure scope ordinal (unique within a method). Static display class is shared across all non-generic methods of a containing class and thus doesn't need a unique number in name.
           - Lambda methods include containing method ordinal (unless emitted to a display class whose name already includes it) and lambda ordinal (unique within a method).
           - The same for fields caching lambdas.
           - Delegate relaxation stubs and their closures have a separate numbering and are distinguished from regular lambdas/closures, since they are immutable and EnC doesn't need to map them across generations.
           - Late-bound AddressOf operator oddly creates real closure and is thus not considered a delegate relaxation for the purposes of synthesized naming.
           - Properties generated to override inherited WithEvent properties are assigned ids in the source order of Handles clauses.
      
           In order to guarantee uniqueness of the names added during EnC include generation ordinal in synthesized names  wherever we use method ordinal. Generation ordinal 0 (regular build) is omitted - the additional number is only added to names of synthesized members created during EnC compilation. (changeset 1395267)
      e7a20119
  7. 09 1月, 2015 3 次提交
    • T
      Currently we include a method ordinal to the name of a synthesized member... · 74142c4f
      TomasMatousek 提交于
      Currently we include a method ordinal to the name of a synthesized member produced during lowering of the method. When a method is added during EnC in the middle of existing members the ordinal is not enough to avoid name conflicts with the previously emitted synthesized members.
           In order to guarantee uniqueness of the names we now include generation ordinal in synthesized names as well, wherever we use method ordinal. Generation ordinal 0 (regular build) is omitted - the additional number is only added to names of synthesized members created during EnC compilation.
      
           An alternative would be to find the highest existing ordinal and start indexing EnC members from there. Such approach would probably work but including the generation number is much simpler and imposes less constraints on the EnC compilation.
      
           In addition to including the generic ordinal this changeset also fixes a couple of bugs that were previously masked or we haven't had coverage of the scenarios:
           - the EnC changeset calculation was not properly handling additions of synthesized members into existing synthesized classes.
           - SymbolMatcher didn't map local variable types forward correctly for variables of synthesized types.
           - SymbolMatcher didn't handle generic static lambda display classes with generic. Currently we create generic parameters for these classes via alpha renaming of the type parameters of the top-level generic method. VB is constructing fresh generic parameters, which seems a better approach. I'll leave changing this to a follow-up changeset.
      
           As a byproduct of this change we can now enable editing of methods containing dynamic operations. It just works now! Each update of such method creates a new set of dynamic sites. We don't attempt to reuse existing sites. It's little bit wasteful but it also avoids the need of invalidating the call-site caches. (changeset 1393184)
      74142c4f
    • T
      Static lambdas in generic methods are emitted on per-method display class.... · 9c7ab597
      TomasMatousek 提交于
      Static lambdas in generic methods are emitted on per-method display class. Include method ordinal into its name to make it unique.
      
           The previous change to synthesized name numbering introduced a regression - if two generic methods of the same arity contained static lambdas the resulting assembly had duplicate type names. This change addresses that case.
       (changeset 1391470)
      9c7ab597
    • T
      Implements a new approach to generating unique synthesized member names (see... · 94711411
      TomasMatousek 提交于
      Implements a new approach to generating unique synthesized member names (see also the attached email).
      
           1) Assigns each member a "member ordinal" - the index in the members array of the containing type. The ordinal is propagated thru lowering rewriters which uses it to make generated names unique.
           2) We no longer calculate "overload ordinal" for names of state machine types, we use the member ordinal of the async/iterator method instead.
           3) Removes GenerateTempNumber from TypeCompiationState. Combination of method ordinal and other indices is used to make generated names unique:
           - Display classes use ordinal of the method containing the lambda and closure scope ordinal (unique within a method). Static display class is shared across all non-generic methods of a containing class and thus doesn't need a unique number in name (it;'s simple named "c<>").
           - Lambda methods include containing method ordinal (unless emitted to a display class whose name already includes it) and lambda ordinal (unique within a method).
           - The same for fields caching lambdas.
           - Dynamic site containers - no longer include method name in the type name, instead method ordinal is used.
      
           4) Expression compiler - rename generated type to "<>x" to avoid confusion with "<>c" static display class.
           5) Avoid replacing "." with "_" in member names, other than type names. While displaying stack frames the EE extracts method name from synthesized lambdas method names and displays it. Thus we were displaying "I_F" instead of "I.F" for explicitly implemented methods.
            In type names replace "." with "-". Replacing with "_" lead to duplicate type names in emitted assembly (2 iterator methods with names "I_F" and "I.F" - explicitly implemented iface method). (changeset 1390962)
      94711411
  8. 07 1月, 2015 3 次提交
  9. 24 12月, 2014 1 次提交
    • P
      MultiDictionary API changes. · d87c7faf
      pgavlin 提交于
      Many uses of MultiDictionary incur unnecessary overhead due to double-lookup or key enumeration and value lookup patterns and unnecessary allocations. This change enables single-lookup patterns, removes a number of allocations from typical uses of MultiDictionary, and cuts the surface area down to what it actually used by the product.
      ***NO_CI***
       (changeset 1384052)
      d87c7faf
  10. 29 10月, 2014 1 次提交
    • V
      Making lambda codegen to always emit instance delegates. · 3de67f36
      VSadov 提交于
      This way we can have better performance of invocations while keeping parameter list of delegate.Method backwards compatible.
      
      The approach is basically always to emit backing methods into a display class, just that in a case of lambdas not capturing anything, the display classes will not have any fields.
      Also, when display classes do not have any fields, lambdas of all nongeneric methods in a given class can share the same display class and in fact can share the same singleton instance.
      
      ***NO_CI***
       (changeset 1359290)
      3de67f36
  11. 04 10月, 2014 1 次提交
    • T
      EnC: Local variable mapping rewrite. · 916b9efa
      TomasMatousek 提交于
      Current approach and issues
      
           When emitting method body of a method updated during EnC the compiler needs to assign local variables the same slots they had before the edit, so that state stored in those locals gets preserved.
           To implement this slot mapping we used to encode information into synthesized variable names that identified the syntax node that produced the variable and ultimately allowed us to calculate the slot mapping.
           For user variables we identified the slot by name. In both cases we relied on an assumption that the compiler assigns slots in syntax order. This assumption is false in some cases. We could make it true but the requirement would be fragile and hard to enforce when new features are implemented in the compiler since the entire lowering pipeline would need to preserve the assumption.
      
           New approach
           In the new approach we calculate a "syntax offset" for each user-defined and long-lived synthesized variable. Every such variable symbol has to be associated with a syntax node (its declarator). In usual cases this is the textual distance of the declarator from the start of the method body. It gets a bit complicated when the containing method body is not contiguous (constructors). If the variable is in the body of the constructor the definition of syntax offset is the same. If the variable is defined in a constructor  initializer or in a member initializer (this is only possible when declaration expressions or closures in primary constructors are involved) then the distance is a negative sum of the widths of all the initializers that succeed the declarator of the variable in the emitted constructor body plus the relative offset of the declarator from the start of the containing initializer.
      
           If a single node is a declarator for multiple variables of the same synthesized kind (it can only happen for synthesized variables) we calculate additional number "ordinal" for such variable. We assign the ordinals to the synthesized variables with the same kind and syntax offset in the order as they appear in the lowered bound tree. It is important that a valid EnC edit can't change the ordinal of a synthesized variable. If it could it would need to be assigned a different kind or associated with a different declarator node.
      
           To support EnC of async method we will assign another number "subordinal" to certain synthesized locals (produced by spilling by-ref variables) to simplify the mapping. Assigning of such number is not yet implemented in this change.
      
           Together (syntax offset, ordinal, subordinal) form a LocalDebugId of a variable. Since this id needs to be stored in PDB for both user-defined and long-lived synthesized variables we can’t encode it in the name of the variable (the names of user-defined variables have to be their user specified names). Therefore this change introduces a new custom debug info record that is associated with a method. The record encodes the kind and id for each local slot of the method.
      
           As a consequence we no longer emit names for synthesized long-lived variables (“CS$...”) unless it’s necessary for backward comp with Dev12 EE (only display class local names need to be emitted for this reason). (changeset 1348066)
      916b9efa
  12. 02 10月, 2014 1 次提交
  13. 15 8月, 2014 3 次提交
    • T
      Preparation for hoisting more locals in Debug builds. I noticed we can use... · ad2bd29c
      TomasMatousek 提交于
      Preparation for hoisting more locals in Debug builds. I noticed we can use less maps while rewriting a method to a class.
      
           MethodToClassRewriter:
           - parameterMap could be moved up to LambdaRewriter since it's only needed when rewriting lambdas.
           - variablesCaptured is replaced by a virtual NeedsProxy method which is implemented on LambdaRewriter and StateMachineRewriter using existing maps (so we can save another HashSet).
              We can also distinguish between "captured" variables and variables we create proxy field for. The former are deduced from syntax. A variable may be captured but not lifted into a field (e.g. expression tree lambda parameter). Or a variable can be lifted to field but not captured (in Debug builds we are going to lift user defined variables that are not captured to allow their later capture during EnC).
      
           LambdaRewriter:
           - variablesCaptured encodes the same information as keys of captured syntax multi-dictionary.
           - declaredInsideExpressionLambda is not needed either. When visiting ET lambdas we used to add their parameters to both variableBlock and declaredInsideExpressionLambda maps. Since ET lambda parameters are never lifted to closure we can avoid adding them to variableBlock map instead of excluding them later via declaredInsideExpressionLambda lookup.
      
           Adds internal IReadOnlySet similar to IReadOnlyList and IReadOnlyDictionary so that we can specify an intent of not mutating a set. (changeset 1317999)
      ad2bd29c
    • T
      Replaces CompilationOptions.Optimize and... · 9fbe1432
      TomasMatousek 提交于
      Replaces CompilationOptions.Optimize and CompilationOptions.DebugInformationKind with a single enum OptimizationLevel that has two values: Release and Debug.
      Removes dependency in IL generation on whether PDB stream is passed to Emit or not. IL shall only differ between Release and Debug.
      
      Command line arguments /optimize, /debug and /pdb remain the same, their values map to either Release or Debug. The value of /optimize is mapped to Release or Debug. /debug+, /debug:full and /debug:pdbonly have all the same effect - enable generating PDB file. They don't influence the generated IL.
      
      Debug information/instrumentation (sequence points, dead stores, nops, etc.) doesn't need to be emitted for synthesized methods that don't contain user code (property GenerateDebugInfo on a symbol returns true).
      
      During lowering always create bound sequence nodes. In some scenarios (PDB stream is not passed, we are emitting helper that contains no user code) these nodes are not used. However, in mainstream scenarios we always emit PDBs, so optimizing the bound nodes away is optimizing for uncommon case and just increases test matrix. Lambda, iterator and async lowering have to handle presence of bound sequence point nodes. We get more test coverage if they are always present.
      
      Another reason why to always create bound sequence points is to avoid complexity and ambiguity when checking if a symbol needs debug information. Some symbols might need debug information during some lowering phases but not other. For example, the generated body of a method symbol that represents an async kick-off method doesn't need debug information since it doesn't contain any user code. However, all source code contained in an async method should have debug information emitted. Bound tree for such code is lowered in the context of the async method symbol, so the value of GenerateDebugInfo for the async method symbol would need to differ depending on which phase of compilation are we in.
      
      Finally, IL body deduplication can always be enabled (in Release and Debug), even in EnC scenarios. Removing another compiler knob further simplifies testing.
       (changeset 1316430)
      9fbe1432
    • T
      Initial refactoring to support reuse and clearing of state machine field slots... · d5d8190c
      TomasMatousek 提交于
      Initial refactoring to support reuse and clearing of state machine field slots associated with all kinds of captured locals (synthesized or user defined). (changeset 1312733)
      d5d8190c
  14. 12 7月, 2014 1 次提交
    • T
      To support EnC well the compiler needs to carefully distinguish between... · d4b0a867
      TomasMatousek 提交于
      To support EnC well the compiler needs to carefully distinguish between long-lived and short-lived synthesized variables. Long-lived variables may cross sequence points and thus need to be mapped the the corresponding variables in the previous generation when emitting EnC deltas. Short-lived local variables shall never cross sequence points.
      
      This change revisits helpers that create synthesized variables and assigns each synthesized variable a SynthesizedLocalKind. Negative kind values are reserved for short-lived variables, positive values for long-lived variables.
      
      The change removed the option to give a synthesized variable an explicit name. The names of the variables are assigned at code-gen time based on their SynthesizedLocalKind. This is to enforce that the names of long-lived variables follow a naming pattern that allows use to reverse-engineer the SynthesizedLocalKind value from the variable name.
      
      Also renames DebugInformationKind.PDBOnly to DebugInformationKind.PdbOnly to follow .NET naming guidelines.
       (changeset 1293017)
      d4b0a867
  15. 02 7月, 2014 1 次提交
  16. 25 6月, 2014 1 次提交
    • V
      Changes emit for synthetic methods backing lambda expressions to include dummy... · 1cd6a42f
      VSadov 提交于
      Changes emit for synthetic methods backing lambda expressions to include dummy "this" parameter to match the number of parameters in delegate "Invoke" method.
      
      When implementing static lambdas (those that do not have closures) C# has a choice of emitting an open or a closed delegate. In the latter case we can just enclose null and not use it in the method.
      It appears that in a case of closed delegate, Invoke dispatch is considerably cheaper - no need to left-shift the arguments to adjust for missing "this".
      
      == Example:
      
      Consider code like the following
      
      Func<int, int, int> adder = (x, y) => x + y;
      
      Since the lambda does not need to enclose anything, we can implement it in two ways.
      
      • Open delegate implementation (current)
      
              public static int Add(int x, int y)
              {
                  return x + y;
              }
      
              Func<int, int, int> adderOpen = cls1.Add;
      
      • Closed delegate implementation (also works and seems better)
      
              // does not really need to be an extension when in synthetic code
              public static int Add(this object dummy, int x, int y)
              {
                  return x + y;
              }
      
              // enclose null
              Func<int, int, int> adderClosed = ((object)null).Add;
      
      Crude experiments confirm that invoking adderClosed indeed costs noticeably less than adderOpen. (about 30% less in common scenarios like adding two ints)
      
      This change adjusts codegen for static lambdas to use closed delegates.
      
       (changeset 1285058)
      1cd6a42f
  17. 20 6月, 2014 1 次提交
    • T
      Splits Microsoft.CodeAnalysis, Microsoft.CodeAnalysis.CSharp and... · fc3b332f
      TomasMatousek 提交于
      Splits Microsoft.CodeAnalysis, Microsoft.CodeAnalysis.CSharp and Microsoft.CodeAnalysis.VisualBasic into portable and desktop assemblies.
      
      Existing Core\Source, CSharp\Source and VisualBasic\Source directories are renamed to Core\Portable, CSharp\Portable and VisualBasic\Portable.
      New sibling Desktop folders are added and non-portable source is moved there.
      "System.Runtime" references has to be removed in order for the portable project system magic to automatically add facade references.
       (changeset 1281686)
      fc3b332f
  18. 04 6月, 2014 1 次提交
  19. 06 5月, 2014 2 次提交
  20. 05 5月, 2014 1 次提交
  21. 03 5月, 2014 1 次提交
  22. 01 5月, 2014 2 次提交
    • T
      We need to be more conscious about producing synthesized symbols during... · 211b47ed
      TomasMatousek 提交于
      We need to be more conscious about producing synthesized symbols during lowering in order to enable EnC of method bodies whose lowering produce such symbols (e.g. lambdas, iterators, dynamic sites, etc.).
      
           This change refactors synthesized symbols in C# so that all symbols produced during lowering phase implement an interface (ISynthesizedMethodBodyImplementationSymbol) that can be used in the emit phase to retrieve information necessary for updating the corresponding metadata entities should they enter EnC.
      
           I also attempted to somewhat improve and increase consistency of the naming of synthesized symbols involved in this change.
      
           No new functionality is added by this change. (changeset 1247789)
      211b47ed
    • C
  23. 30 4月, 2014 1 次提交
  24. 22 4月, 2014 1 次提交
    • T
      MethodCompiler refactorings: · a90eb5d9
      TomasMatousek 提交于
           - We mix "CompilerGenerated" and "Synthesized", but they mean the same - renames the former to the latter. The latter is less ambiguous since we also name "generated" the result of CodeGen phase.
           - Merges Compiler.cs into MethodCompiler.cs, CSharpCompilation.cs and Binder_Initializers.cs -- to match VB.
           - Renames misc members/types so that those that serve the same purpose in C# and VB are called the same. (changeset 1235392)
      a90eb5d9
  25. 12 4月, 2014 1 次提交
  26. 28 3月, 2014 1 次提交
  27. 23 3月, 2014 1 次提交
  28. 19 3月, 2014 1 次提交