Skip to content

Commit

Permalink
Make global TemporaryVariableCache to dramatically reduce allocation …
Browse files Browse the repository at this point in the history
…of this highly repetitive immutable object
  • Loading branch information
enebo committed Dec 18, 2014
1 parent 69212f8 commit 61f745e
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
35 changes: 35 additions & 0 deletions core/src/main/java/org/jruby/ir/IRManager.java
Expand Up @@ -4,6 +4,7 @@
import org.jruby.ir.listeners.IRScopeListener;
import org.jruby.ir.listeners.InstructionsListener;
import org.jruby.ir.operands.Nil;
import org.jruby.ir.operands.TemporaryLocalVariable;
import org.jruby.ir.passes.BasicCompilerPassListener;
import org.jruby.ir.passes.CompilerPass;
import org.jruby.ir.passes.CompilerPassListener;
Expand Down Expand Up @@ -167,4 +168,38 @@ public void removeListener(IRScopeListener listener) {
public String getMetaClassName() {
return "<DUMMY_MC:" + dummyMetaClassCount++ + ">";
}

private TemporaryLocalVariable[] temporaryLocalVariables = new TemporaryLocalVariable[1600];

protected TemporaryLocalVariable[] growTemporaryVariablePool(int index) {
int newLength = index * 2;
TemporaryLocalVariable[] newPool = new TemporaryLocalVariable[newLength];

System.arraycopy(temporaryLocalVariables, 0, newPool, 0, temporaryLocalVariables.length);
temporaryLocalVariables = newPool;
return newPool;
}

// FIXME: Consider IRBuilder not using so many temporary variables for literal initialization. This is the
// vast majority of high index temp variables.
/**
* Temporary local variables are immutable and always start from a low index value and increment up
* to a higher index value per scope. So we can share these and store the ones in a simple list. If
* hard pinning is ever an issue we can periodically evict the list and start over at the cost of more
* live objects but this list cache reduces a simple empty Rails app console from over 140K instances
* to about 1200 instances.
*
*/
public TemporaryLocalVariable newTemporaryLocalVariable(int index) {
if (index >= temporaryLocalVariables.length-1) growTemporaryVariablePool(index);

TemporaryLocalVariable tempVar = temporaryLocalVariables[index];

if (tempVar == null) {
tempVar = new TemporaryLocalVariable(index);
temporaryLocalVariables[index] = tempVar;
}

return tempVar;
}
}
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/ir/IRScope.java
Expand Up @@ -887,7 +887,7 @@ public TemporaryLocalVariable getNewTemporaryVariable(TemporaryVariableType type
}
case LOCAL: {
temporaryVariableIndex++;
return new TemporaryLocalVariable(temporaryVariableIndex);
return manager.newTemporaryLocalVariable(temporaryVariableIndex);
}
}

Expand Down

0 comments on commit 61f745e

Please sign in to comment.