Remove Compiler::impSmallStack
authorMike Danes <onemihaid@hotmail.com>
Sat, 16 Jun 2018 20:07:49 +0000 (23:07 +0300)
committerMike Danes <onemihaid@hotmail.com>
Sat, 30 Jun 2018 19:34:10 +0000 (22:34 +0300)
Memory allocation via ArenaAllocator is cheap so it's not worth having this inline array that ends up wasting 384 bytes when a larger stack is needed.

Care needs to be taken when inlining to avoid allocating a new stack every time - just steal the stack of the inliner compiler (after ensuring that it is large enough).

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

index 0a51e1f..efbf0a5 100644 (file)
@@ -3004,8 +3004,6 @@ protected:
 
 #define SMALL_STACK_SIZE 16 // number of elements in impSmallStack
 
-    StackEntry impSmallStack[SMALL_STACK_SIZE]; // Use this array if possible
-
     struct SavedStack // used to save/restore stack contents.
     {
         unsigned    ssDepth; // number of values on stack
index 8ec9303..0fafa77 100644 (file)
@@ -17438,26 +17438,39 @@ void Compiler::impImport(BasicBlock* method)
     }
 #endif
 
-    /* Allocate the stack contents */
+    Compiler* inlineRoot = impInlineRoot();
 
-    if (info.compMaxStack <= _countof(impSmallStack))
+    if (info.compMaxStack <= SMALL_STACK_SIZE)
     {
-        /* Use local variable, don't waste time allocating on the heap */
-
-        impStkSize              = _countof(impSmallStack);
-        verCurrentState.esStack = impSmallStack;
+        impStkSize = SMALL_STACK_SIZE;
     }
     else
     {
-        impStkSize              = info.compMaxStack;
+        impStkSize = info.compMaxStack;
+    }
+
+    if (this == inlineRoot)
+    {
+        // Allocate the stack contents
         verCurrentState.esStack = new (this, CMK_ImpStack) StackEntry[impStkSize];
     }
+    else
+    {
+        // This is the inlinee compiler, steal the stack from the inliner compiler
+        // (after ensuring that it is large enough).
+        if (inlineRoot->impStkSize < impStkSize)
+        {
+            inlineRoot->impStkSize              = impStkSize;
+            inlineRoot->verCurrentState.esStack = new (this, CMK_ImpStack) StackEntry[impStkSize];
+        }
+
+        verCurrentState.esStack = inlineRoot->verCurrentState.esStack;
+    }
 
     // initialize the entry state at start of method
     verInitCurrentState();
 
     // Initialize stuff related to figuring "spill cliques" (see spec comment for impGetSpillTmpBase).
-    Compiler* inlineRoot = impInlineRoot();
     if (this == inlineRoot) // These are only used on the root of the inlining tree.
     {
         // We have initialized these previously, but to size 0.  Make them larger.