Do not spill eeStack after ldtoken opcode. (dotnet/coreclr#10215)
authorSergey Andreenko <seandree@microsoft.com>
Tue, 11 Apr 2017 03:53:38 +0000 (20:53 -0700)
committerGitHub <noreply@github.com>
Tue, 11 Apr 2017 03:53:38 +0000 (20:53 -0700)
Do not spill eeStack if the last opcode was ldtoken.

Commit migrated from https://github.com/dotnet/coreclr/commit/5bc1e42710434cbc6c62a4ed1deb16aa9ecd92f5

src/coreclr/src/jit/compiler.h
src/coreclr/src/jit/importer.cpp

index 482ad49..832ed03 100644 (file)
@@ -3137,6 +3137,11 @@ private:
 
     //---------------- Spilling the importer stack ----------------------------
 
+    // The maximum number of bytes of IL processed without clean stack state.
+    // It allows to limit the maximum tree size and depth.
+    static const unsigned MAX_TREE_SIZE = 200;
+    bool impCanSpillNow(OPCODE prevOpcode);
+
     struct PendingDsc
     {
         PendingDsc*   pdNext;
index 64c6f45..c6f3e10 100644 (file)
@@ -2594,6 +2594,21 @@ inline IL_OFFSETX Compiler::impCurILOffset(IL_OFFSET offs, bool callInstruction)
     }
 }
 
+//------------------------------------------------------------------------
+// impCanSpillNow: check is it possible to spill all values from eeStack to local variables.
+//
+// Arguments:
+//    prevOpcode - last importer opcode
+//
+// Return Value:
+//    true if it is legal, false if it could be a sequence that we do not want to divide.
+bool Compiler::impCanSpillNow(OPCODE prevOpcode)
+{
+    // Don't spill after ldtoken, because it could be a part of the InitializeArray sequence.
+    // Avoid breaking up to guarantee that impInitializeArrayIntrinsic can succeed.
+    return prevOpcode != CEE_LDTOKEN;
+}
+
 /*****************************************************************************
  *
  *  Remember the instr offset for the statements
@@ -9554,7 +9569,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
             /* Has it been a while since we last saw a non-empty stack (which
                guarantees that the tree depth isnt accumulating. */
 
-            if ((opcodeOffs - lastSpillOffs) > 200)
+            if ((opcodeOffs - lastSpillOffs) > MAX_TREE_SIZE && impCanSpillNow(prevOpcode))
             {
                 impSpillStackEnsure();
                 lastSpillOffs = opcodeOffs;