Skip to content

Commit

Permalink
Cache block bodies, since they should contain no mutable state.
Browse files Browse the repository at this point in the history
For #2442.
  • Loading branch information
headius committed Jan 8, 2015
1 parent 2d95d47 commit 35be34a
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 10 deletions.
28 changes: 28 additions & 0 deletions core/src/main/java/org/jruby/ir/targets/IRBytecodeAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,18 @@
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.compiler.impl.SkinnyMethodAdapter;
import org.jruby.ir.IRScope;
import org.jruby.ir.operands.UndefinedValue;
import org.jruby.ir.runtime.IRRuntimeHelpers;
import org.jruby.runtime.CompiledIRBlockBody;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
import org.jruby.util.RegexpOptions;
import org.objectweb.asm.Handle;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.Method;

Expand Down Expand Up @@ -184,6 +188,30 @@ public org.objectweb.asm.Label newLabel() {
return new org.objectweb.asm.Label();
}

public void pushBlockBody(Handle handle, int arity, String className) {
// FIXME: too much bytecode
String cacheField = "blockBody" + getClassData().callSiteCount.getAndIncrement();
Label done = new Label();
adapter.getClassVisitor().visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC, cacheField, ci(CompiledIRBlockBody.class), null, null).visitEnd();
adapter.getstatic(getClassData().clsName, cacheField, ci(CompiledIRBlockBody.class));
adapter.dup();
adapter.ifnonnull(done);
{
adapter.pop();
adapter.newobj(p(CompiledIRBlockBody.class));
adapter.dup();

adapter.ldc(handle);
adapter.getstatic(className, handle.getName() + "_IRScope", ci(IRScope.class));
adapter.ldc(arity);

adapter.invokespecial(p(CompiledIRBlockBody.class), "<init>", sig(void.class, java.lang.invoke.MethodHandle.class, IRScope.class, int.class));
adapter.dup();
adapter.putstatic(getClassData().clsName, cacheField, ci(CompiledIRBlockBody.class));
}
adapter.label(done);
}

/**
* Stack required: none
*
Expand Down
11 changes: 1 addition & 10 deletions core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -2208,16 +2208,7 @@ public void WrappedIRClosure(WrappedIRClosure wrappedirclosure) {
jvmAdapter().newobj(p(Block.class));
jvmAdapter().dup();

{ // FIXME: block body should be cached
jvmAdapter().newobj(p(CompiledIRBlockBody.class));
jvmAdapter().dup();

jvmAdapter().ldc(closure.getHandle());
jvmAdapter().getstatic(jvm.clsData().clsName, closure.getHandle().getName() + "_IRScope", ci(IRScope.class));
jvmAdapter().ldc(closure.getArity().getValue());

jvmAdapter().invokespecial(p(CompiledIRBlockBody.class), "<init>", sig(void.class, java.lang.invoke.MethodHandle.class, IRScope.class, int.class));
}
jvmMethod().pushBlockBody(closure.getHandle(), closure.getArity().getValue(), jvm.clsData().clsName);

{ // prepare binding
jvmMethod().loadContext();
Expand Down

0 comments on commit 35be34a

Please sign in to comment.