1. 08 3月, 2016 1 次提交
  2. 26 1月, 2016 1 次提交
  3. 16 10月, 2015 1 次提交
  4. 04 9月, 2015 1 次提交
    • V
      Making stack scheduling optimizations more robust and fixing #4828 · 93b341d0
      vsadov 提交于
      Stack scheduler performs two kinds of transformations -
      1) it turns local slots into ephemeral locals that live on the evaluation stack.
      2) It also tries to Dup previous expressions when the next one is exactly the same and other condittions allow.
      
      The operation # 2 is basically a workaround for cases like
      
         temp = ...
         result = temp + temp;
      
      Since ephemeral locals are modeled as occupying the space "below" the eval values, having temp on eval stack prevents that same temp from being a stack local.
      The self-interference situations like above are fairly common, so the stack scheduler tries to reduce some of the cases by attempting a peephole optimization where value of previous expression could be Dup-ed if the following one is the same. (thus in our example it would look like the second load of the temp does not happen at all).
      
      This # 2 optimization has numerous conditions where it is not applicable and as bug #4828 shows it is still fairly fragile. It relies on the presence of the value produced by the previous expression and that is not always guaranteed to be there if the expression has no sideeffects.
      
      Instead of adding more conditions, I am removing the # 2 entirely.
      
      It appears that it can be removed without any serious regression in # 1 as long as we track not only the depth of the eval stack but also what we have on it. That way we can detect self-interference cases by just examining our best knowledge of the stack and handle definite self-interference cases as not prohibiting.
      
      The result of this change is that many dups have disappeared from the code, but in most cases they were dups of trivial local/parameter loads and as such are not a concern.
      On the other hand most cases where locals slots can be optimized away are still there and in some cases we actually are slightly better.
      
      The most important part is that the whole scheduling got simpler and uses fewer assumptions about what emit might do.
      
      Fixes #4828
      93b341d0
  5. 01 7月, 2015 1 次提交
  6. 18 6月, 2015 1 次提交
  7. 13 5月, 2015 1 次提交
  8. 29 3月, 2015 1 次提交
  9. 24 3月, 2015 1 次提交
  10. 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
  11. 15 1月, 2015 1 次提交
  12. 14 1月, 2015 1 次提交
  13. 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
  14. 07 1月, 2015 2 次提交
  15. 24 12月, 2014 1 次提交
  16. 04 12月, 2014 1 次提交
    • V
      Emitting synthetic ctor and cctor in the same relative order as in Dev12. · 3451b613
      VSadov 提交于
      Changing order causes unnecessary noise in metadata diffing tools. Also we have seen some evidence of existing code taking unintentional dependency on the order of constructors as returned via reflection. That is arguably a bug since the order is not specified nor guaranteed. On the other hand we do not have any serious reasons for moving that cheese, so we will try keeping the emit order of synthetic ctors as it was.
      
      Dev12 C# compiler appears to emit synthetic constructors after all other methods - first ctor, and then cctor, if needed.
       (changeset 1379237)
      3451b613
  17. 07 11月, 2014 1 次提交
  18. 29 10月, 2014 2 次提交
    • A
      DevDiv #623156 Follow-up: No dots in mangled named · 544c369b
      acasey 提交于
      We were cleaning up state machine type names, but not those of lambda methods or auto-prop backing fields.
      
      CR: VSadov; ToMat (changeset 1359718)
      544c369b
    • 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
  19. 06 10月, 2014 1 次提交
  20. 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
  21. 25 9月, 2014 1 次提交
  22. 15 8月, 2014 2 次提交
    • T
      More options cleanup & fix in EE variable enumerator · 556e5b7b
      TomasMatousek 提交于
      Removes UnoptimizedDll/unoptimizedExe and other /optimize & /debug option combinations from tests.
      Fixes bug in C# EE - we have incorrectly treated end offset of a local scope as inclusive. It's exclusive for C#, inclusive for VB. (changeset 1313100)
      556e5b7b
    • T
      Reduce the variety of optimization related compilation option values used in... · f58f5ab8
      TomasMatousek 提交于
      Reduce the variety of optimization related compilation option values used in tests to: Release, DebuggableRelease and Debug.
      
      By default tests should use Release, which enables all optimizations.
      PDB tests should mostly use Debug.
      We should have targeted tests for DebuggableRelease, for optimizations that are selectively disabled to improve debuggability of release builds.
      
         (changeset 1312277)
      f58f5ab8
  23. 18 7月, 2014 1 次提交
    • T
      Adjusting conditional branches for EnC. · b0615ac8
      TomasMatousek 提交于
      For every conditional branch that consumes a value of an expression that might contain calls to user code and that jumps across user code with sequence points, we need to store the value into a synthesized named local, emit stloc and ldloc and place a hidden sequence point on the ldloc instruction. Furthermore, the synthesized local variable has to be associated with the statement syntax whose lowering produces the conditional branch so that EnC infrastructure can map the local variable defined for the branch to the previous generation.
      
      In essence this is what’s going on:
      
      [|if (F())|]
      { … true … }
      else
      { … false … }
      
      IL:
      call F()
      stloc $value
      <-- hidden sequence point -->
      ldloc $value
      brfalse label_false
      <-- sequence point for “{“ of true-block -->
      … true …
      br label_end
      label_false:
      <-- sequence point for “{“of false-block -->
      … false …
      label_end:
      
      When the call to F() returns after an update has been performed on the caller the code execution continues in the old version of the caller body until a special remapping breakpoint is hit. These breakpoints are put on all sequence points of the method. If we didn’t put the hidden sequence point in front of the conditional branch the execution would continue in the old code until another sequence point is hit. Such a sequence point can be arbitrary (suppose e.g. that the else block of the if statement is deleted by an edit). The debugger only knows how to map IP of active statements in the old IL to an IP in the new IL, not arbitrary sequence points. By inserting the hidden sequence point we force the mapping to be performed at well-defined point that we can map to the new method body.
      
      The presence of the hidden sequence point then implies the need of storing the value of the if-statement condition to a long-lived local and reloading it back right after the sequence point. The store will happen before the IP is remapped and the load will happen in the new frame. The synthesized local must be allocated the same slot in the new frame so that its value is transferred from the old frame to the new frame.
      
      Fixes bug 927151: Edit and Continue breaks If statements while inside the conditional method.
      
      This change also includes an update to the test infrastructure to
      1) make it easier to update failing test that checks for an expected IL
      If a VerifyIL fails it synthesizes a temp file containing the unit test source and prints out a link that launches a diff tool (using ROSLYN_DIFFTOOL environment variable).
      2) to be able to directly test correspondence of sequence points to IL.
      VerifyIL has now an optional argument “sequencePoints”. When specified the printed IL will contain marks that designate presence of sequence points at IL offsets. “-“ for regular sequence point, “~” for hidden sequence points.
      I have updated some tests that are supposed to validate correspondence of sequence points to IL instructions to use this new format.  (changeset 1299447)
      b0615ac8
  24. 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
  25. 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
  26. 15 4月, 2014 1 次提交
  27. 19 3月, 2014 1 次提交