forked from jruby/jruby
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move remaining logical chunks out of Bootstrap
- Loading branch information
Showing
16 changed files
with
425 additions
and
326 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
315 changes: 4 additions & 311 deletions
315
core/src/main/java/org/jruby/ir/targets/indy/Bootstrap.java
Large diffs are not rendered by default.
Oops, something went wrong.
30 changes: 30 additions & 0 deletions
30
core/src/main/java/org/jruby/ir/targets/indy/CallInfoBootstrap.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package org.jruby.ir.targets.indy; | ||
|
||
import org.jruby.ir.runtime.IRRuntimeHelpers; | ||
import org.jruby.runtime.ThreadContext; | ||
import org.objectweb.asm.Handle; | ||
|
||
import java.lang.invoke.CallSite; | ||
import java.lang.invoke.ConstantCallSite; | ||
import java.lang.invoke.MethodHandle; | ||
import java.lang.invoke.MethodHandles; | ||
import java.lang.invoke.MethodType; | ||
|
||
import static java.lang.invoke.MethodHandles.insertArguments; | ||
import static java.lang.invoke.MethodType.methodType; | ||
|
||
public class CallInfoBootstrap { | ||
public static final Handle CALL_INFO_BOOTSTRAP = Bootstrap.getBootstrapHandle("callInfoBootstrap", Bootstrap.BOOTSTRAP_INT_SIG); | ||
|
||
public static CallSite callInfoBootstrap(MethodHandles.Lookup lookup, String name, MethodType type, int callInfo) throws Throwable { | ||
MethodHandle handle; | ||
if (callInfo == 0) { | ||
handle = lookup.findVirtual(ThreadContext.class, "clearCallInfo", methodType(void.class)); | ||
} else { | ||
handle = lookup.findStatic(IRRuntimeHelpers.class, "setCallInfo", methodType(void.class, ThreadContext.class, int.class)); | ||
handle = insertArguments(handle, 1, callInfo); | ||
} | ||
|
||
return new ConstantCallSite(handle); | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
core/src/main/java/org/jruby/ir/targets/indy/CallSiteCacheBootstrap.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package org.jruby.ir.targets.indy; | ||
|
||
import org.jruby.runtime.CallType; | ||
import org.jruby.runtime.callsite.CachingCallSite; | ||
import org.jruby.runtime.callsite.FunctionalCachingCallSite; | ||
import org.jruby.runtime.callsite.MonomorphicCallSite; | ||
import org.jruby.runtime.callsite.VariableCachingCallSite; | ||
import org.objectweb.asm.Handle; | ||
import org.objectweb.asm.Opcodes; | ||
|
||
import java.lang.invoke.CallSite; | ||
import java.lang.invoke.ConstantCallSite; | ||
import java.lang.invoke.MethodHandles; | ||
import java.lang.invoke.MethodType; | ||
|
||
import static java.lang.invoke.MethodHandles.constant; | ||
import static org.jruby.util.CodegenUtils.p; | ||
import static org.jruby.util.CodegenUtils.sig; | ||
|
||
public class CallSiteCacheBootstrap { | ||
public static final Handle CALLSITE = new Handle( | ||
Opcodes.H_INVOKESTATIC, | ||
p(Bootstrap.class), | ||
"callSite", | ||
sig(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, String.class, int.class), | ||
false); | ||
|
||
public static CallSite callSite(MethodHandles.Lookup lookup, String name, MethodType type, String id, int callType) { | ||
return new ConstantCallSite(constant(CachingCallSite.class, callSite(id, callType))); | ||
} | ||
|
||
private static CachingCallSite callSite(String id, int callType) { | ||
switch (CallType.fromOrdinal(callType)) { | ||
case NORMAL: | ||
return new MonomorphicCallSite(id); | ||
case FUNCTIONAL: | ||
return new FunctionalCachingCallSite(id); | ||
case VARIABLE: | ||
return new VariableCachingCallSite(id); | ||
default: | ||
throw new RuntimeException("BUG: Unexpected call type " + callType + " in JVM6 invoke logic"); | ||
} | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
core/src/main/java/org/jruby/ir/targets/indy/CheckpointSite.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package org.jruby.ir.targets.indy; | ||
|
||
import com.headius.invokebinder.Binder; | ||
import org.jruby.Ruby; | ||
import org.jruby.runtime.ThreadContext; | ||
import org.jruby.runtime.opto.Invalidator; | ||
import org.objectweb.asm.Handle; | ||
|
||
import java.lang.invoke.CallSite; | ||
import java.lang.invoke.MethodHandle; | ||
import java.lang.invoke.MethodHandles; | ||
import java.lang.invoke.MethodType; | ||
import java.lang.invoke.MutableCallSite; | ||
import java.lang.invoke.SwitchPoint; | ||
|
||
import static java.lang.invoke.MethodHandles.lookup; | ||
import static java.lang.invoke.MethodType.methodType; | ||
|
||
public class CheckpointSite extends MutableCallSite { | ||
public static final Handle CHECKPOINT_BOOTSTRAP = Bootstrap.getBootstrapHandle("checkpointBootstrap", Bootstrap.BOOTSTRAP_BARE_SIG); | ||
|
||
public CheckpointSite(MethodType type) { | ||
super(type); | ||
} | ||
|
||
public static CallSite checkpointBootstrap(MethodHandles.Lookup lookup, String name, MethodType type) throws Throwable { | ||
CheckpointSite site = new CheckpointSite(type); | ||
MethodHandle handle = lookup.findVirtual(CheckpointSite.class, "checkpointFallback", methodType(void.class, ThreadContext.class)); | ||
|
||
handle = handle.bindTo(site); | ||
site.setTarget(handle); | ||
|
||
return site; | ||
} | ||
|
||
public void checkpointFallback(ThreadContext context) throws Throwable { | ||
Ruby runtime = context.runtime; | ||
Invalidator invalidator = runtime.getCheckpointInvalidator(); | ||
|
||
MethodHandle target = Binder | ||
.from(void.class, ThreadContext.class) | ||
.nop(); | ||
MethodHandle fallback = lookup().findStatic(Bootstrap.class, "checkpointFallback", methodType(void.class, MutableCallSite.class, ThreadContext.class)); | ||
fallback = fallback.bindTo(this); | ||
|
||
target = ((SwitchPoint)invalidator.getData()).guardWithTest(target, fallback); | ||
|
||
this.setTarget(target); | ||
|
||
// poll for events once since we've ended up back in fallback | ||
context.pollThreadEvents(); | ||
} | ||
} |
107 changes: 107 additions & 0 deletions
107
core/src/main/java/org/jruby/ir/targets/indy/ConstructBlockBootstrap.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
package org.jruby.ir.targets.indy; | ||
|
||
import com.headius.invokebinder.Binder; | ||
import org.jruby.ir.runtime.IRRuntimeHelpers; | ||
import org.jruby.parser.StaticScope; | ||
import org.jruby.runtime.Binding; | ||
import org.jruby.runtime.Block; | ||
import org.jruby.runtime.CompiledIRBlockBody; | ||
import org.jruby.runtime.DynamicScope; | ||
import org.jruby.runtime.Frame; | ||
import org.jruby.runtime.Helpers; | ||
import org.jruby.runtime.ThreadContext; | ||
import org.jruby.runtime.builtin.IRubyObject; | ||
import org.objectweb.asm.Handle; | ||
import org.objectweb.asm.Opcodes; | ||
|
||
import java.lang.invoke.CallSite; | ||
import java.lang.invoke.ConstantCallSite; | ||
import java.lang.invoke.MethodHandle; | ||
import java.lang.invoke.MethodHandles; | ||
import java.lang.invoke.MethodType; | ||
|
||
import static org.jruby.util.CodegenUtils.p; | ||
import static org.jruby.util.CodegenUtils.sig; | ||
|
||
public class ConstructBlockBootstrap { | ||
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup(); | ||
private static final Binder BINDING_MAKER_BINDER = Binder.from(Binding.class, ThreadContext.class, IRubyObject.class, DynamicScope.class); | ||
private static final MethodHandle SELF_BINDING = BINDING_MAKER_BINDER.invokeStaticQuiet(LOOKUP, Bootstrap.class, "selfBinding"); | ||
private static final MethodHandle SCOPE_BINDING = BINDING_MAKER_BINDER.invokeStaticQuiet(LOOKUP, Bootstrap.class, "scopeBinding"); | ||
private static final MethodHandle FRAME_BINDING = BINDING_MAKER_BINDER.invokeStaticQuiet(LOOKUP, Bootstrap.class, "frameBinding"); | ||
private static final MethodHandle FRAME_SCOPE_BINDING = BINDING_MAKER_BINDER.invokeStaticQuiet(LOOKUP, IRRuntimeHelpers.class, "newFrameScopeBinding"); | ||
private static final MethodHandle CONSTRUCT_BLOCK = Binder.from(Block.class, Binding.class, CompiledIRBlockBody.class).invokeStaticQuiet(LOOKUP, Bootstrap.class, "constructBlock"); | ||
|
||
public static Handle prepareBlock() { | ||
return new Handle( | ||
Opcodes.H_INVOKESTATIC, | ||
p(Bootstrap.class), | ||
"prepareBlock", | ||
sig(CallSite.class, MethodHandles.Lookup.class, String.class, | ||
MethodType.class, MethodHandle.class, MethodHandle.class, MethodHandle.class, MethodHandle.class, String.class, long.class, | ||
String.class, int.class, String.class), | ||
false); | ||
} | ||
|
||
public static CallSite prepareBlock(MethodHandles.Lookup lookup, String name, MethodType type, | ||
MethodHandle bodyHandle, MethodHandle scopeHandle, MethodHandle setScopeHandle, MethodHandle parentHandle, String scopeDescriptor, long encodedSignature, | ||
String file, int line, String encodedArgumentDescriptors | ||
) throws Throwable { | ||
StaticScope staticScope = (StaticScope) scopeHandle.invokeExact(); | ||
|
||
if (staticScope == null) { | ||
staticScope = Helpers.restoreScope(scopeDescriptor, (StaticScope) parentHandle.invokeExact()); | ||
setScopeHandle.invokeExact(staticScope); | ||
} | ||
|
||
CompiledIRBlockBody body = new CompiledIRBlockBody(bodyHandle, staticScope, file, line, encodedArgumentDescriptors, encodedSignature); | ||
|
||
Binder binder = Binder.from(type); | ||
|
||
binder = binder.fold(FRAME_SCOPE_BINDING); | ||
|
||
// This optimization can't happen until we can see into the method we're calling to know if it reifies the block | ||
if (false) { | ||
/* | ||
if (needsBinding) { | ||
if (needsFrame) { | ||
FullInterpreterContext fic = scope.getExecutionContext(); | ||
if (fic.needsBinding()) { | ||
if (fic.needsFrame()) { | ||
binder = binder.fold(FRAME_SCOPE_BINDING); | ||
} else { | ||
binder = binder.fold(SCOPE_BINDING); | ||
} | ||
} else { | ||
if (needsFrame) { | ||
binder = binder.fold(FRAME_BINDING); | ||
} else { | ||
binder = binder.fold(SELF_BINDING); | ||
} | ||
}*/ | ||
} | ||
|
||
MethodHandle blockMaker = binder.drop(1, 3) | ||
.append(body) | ||
.invoke(CONSTRUCT_BLOCK); | ||
|
||
return new ConstantCallSite(blockMaker); | ||
} | ||
|
||
public static Binding frameBinding(ThreadContext context, IRubyObject self, DynamicScope scope) { | ||
Frame frame = context.getCurrentFrame().capture(); | ||
return new Binding(self, frame, frame.getVisibility()); | ||
} | ||
|
||
public static Binding scopeBinding(ThreadContext context, IRubyObject self, DynamicScope scope) { | ||
return new Binding(self, scope); | ||
} | ||
|
||
public static Binding selfBinding(ThreadContext context, IRubyObject self, DynamicScope scope) { | ||
return new Binding(self); | ||
} | ||
|
||
public static Block constructBlock(Binding binding, CompiledIRBlockBody body) throws Throwable { | ||
return new Block(body, binding); | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
core/src/main/java/org/jruby/ir/targets/indy/CoverageSite.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package org.jruby.ir.targets.indy; | ||
|
||
import com.headius.invokebinder.Binder; | ||
import org.jruby.ir.runtime.IRRuntimeHelpers; | ||
import org.jruby.runtime.ThreadContext; | ||
import org.objectweb.asm.Handle; | ||
|
||
import java.lang.invoke.CallSite; | ||
import java.lang.invoke.MethodHandle; | ||
import java.lang.invoke.MethodHandles; | ||
import java.lang.invoke.MethodType; | ||
import java.lang.invoke.MutableCallSite; | ||
|
||
import static java.lang.invoke.MethodHandles.insertArguments; | ||
import static java.lang.invoke.MethodType.methodType; | ||
import static org.jruby.util.CodegenUtils.sig; | ||
|
||
public class CoverageSite { | ||
public static final Handle COVER_LINE_BOOTSTRAP = Bootstrap.getBootstrapHandle("coverLineBootstrap", sig(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, String.class, int.class, int.class)); | ||
|
||
public static CallSite coverLineBootstrap(MethodHandles.Lookup lookup, String name, MethodType type, String filename, int line, int oneshot) throws Throwable { | ||
MutableCallSite site = new MutableCallSite(type); | ||
MethodHandle handle = lookup.findStatic(Bootstrap.class, "coverLineFallback", methodType(void.class, MutableCallSite.class, ThreadContext.class, String.class, int.class, boolean.class)); | ||
|
||
handle = handle.bindTo(site); | ||
handle = insertArguments(handle, 1, filename, line, oneshot != 0); | ||
site.setTarget(handle); | ||
|
||
return site; | ||
} | ||
|
||
public static void coverLineFallback(MutableCallSite site, ThreadContext context, String filename, int line, boolean oneshot) throws Throwable { | ||
IRRuntimeHelpers.updateCoverage(context, filename, line); | ||
|
||
if (oneshot) site.setTarget(Binder.from(void.class, ThreadContext.class).dropAll().nop()); | ||
} | ||
} |
72 changes: 72 additions & 0 deletions
72
core/src/main/java/org/jruby/ir/targets/indy/HeapVariableBootstrap.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package org.jruby.ir.targets.indy; | ||
|
||
import com.headius.invokebinder.Binder; | ||
import org.jruby.runtime.ThreadContext; | ||
import org.jruby.runtime.builtin.IRubyObject; | ||
import org.jruby.runtime.scope.DynamicScopeGenerator; | ||
import org.objectweb.asm.Handle; | ||
|
||
import java.lang.invoke.CallSite; | ||
import java.lang.invoke.ConstantCallSite; | ||
import java.lang.invoke.MethodHandle; | ||
import java.lang.invoke.MethodHandles; | ||
import java.lang.invoke.MethodType; | ||
|
||
import static java.lang.invoke.MethodType.methodType; | ||
import static org.jruby.runtime.Helpers.arrayOf; | ||
|
||
public class HeapVariableBootstrap { | ||
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup(); | ||
public static final Handle GET_HEAP_LOCAL_OR_NIL_BOOTSTRAP = Bootstrap.getBootstrapHandle("getHeapLocalOrNilBootstrap", Bootstrap.BOOTSTRAP_INT_INT_SIG); | ||
public static final Handle GET_HEAP_LOCAL_BOOTSTRAP = Bootstrap.getBootstrapHandle("getHeapLocalBootstrap", Bootstrap.BOOTSTRAP_INT_INT_SIG); | ||
|
||
public static CallSite getHeapLocalBootstrap(MethodHandles.Lookup lookup, String name, MethodType type, int depth, int location) throws Throwable { | ||
// no null checking needed for method bodies | ||
MethodHandle getter; | ||
Binder binder = Binder | ||
.from(type); | ||
|
||
if (depth == 0) { | ||
if (location < DynamicScopeGenerator.SPECIALIZED_GETS.size()) { | ||
getter = binder.invokeVirtualQuiet(LOOKUP, DynamicScopeGenerator.SPECIALIZED_GETS.get(location)); | ||
} else { | ||
getter = binder | ||
.insert(1, location) | ||
.invokeVirtualQuiet(LOOKUP, "getValueDepthZero"); | ||
} | ||
} else { | ||
getter = binder | ||
.insert(1, arrayOf(int.class, int.class), location, depth) | ||
.invokeVirtualQuiet(LOOKUP, "getValue"); | ||
} | ||
|
||
ConstantCallSite site = new ConstantCallSite(getter); | ||
|
||
return site; | ||
} | ||
|
||
public static CallSite getHeapLocalOrNilBootstrap(MethodHandles.Lookup lookup, String name, MethodType type, int depth, int location) throws Throwable { | ||
MethodHandle getter; | ||
Binder binder = Binder | ||
.from(type) | ||
.filter(1, LiteralValueBootstrap.contextValue(lookup, "nil", methodType(IRubyObject.class, ThreadContext.class)).dynamicInvoker()); | ||
|
||
if (depth == 0) { | ||
if (location < DynamicScopeGenerator.SPECIALIZED_GETS_OR_NIL.size()) { | ||
getter = binder.invokeVirtualQuiet(LOOKUP, DynamicScopeGenerator.SPECIALIZED_GETS_OR_NIL.get(location)); | ||
} else { | ||
getter = binder | ||
.insert(1, location) | ||
.invokeVirtualQuiet(LOOKUP, "getValueDepthZeroOrNil"); | ||
} | ||
} else { | ||
getter = binder | ||
.insert(1, arrayOf(int.class, int.class), location, depth) | ||
.invokeVirtualQuiet(LOOKUP, "getValueOrNil"); | ||
} | ||
|
||
ConstantCallSite site = new ConstantCallSite(getter); | ||
|
||
return site; | ||
} | ||
} |
Oops, something went wrong.