Skip to content

Commit

Permalink
Move remaining logical chunks out of Bootstrap
Browse files Browse the repository at this point in the history
  • Loading branch information
headius committed Oct 26, 2023
1 parent f21f7d5 commit ea35485
Show file tree
Hide file tree
Showing 16 changed files with 468 additions and 327 deletions.
6 changes: 5 additions & 1 deletion core/src/main/java/org/jruby/RubyModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -5108,6 +5108,10 @@ private RaiseException cannotRemoveError(String id) {
return getRuntime().newNameError(str(runtime, "cannot remove ", ids(runtime, id), " for ", types(runtime, this)), id);
}

public static boolean testModuleMatch(ThreadContext context, IRubyObject arg0, int id) {
return arg0 instanceof RubyModule && ((RubyModule) arg0).id == id;
}


//
////////////////// INTERNAL MODULE VARIABLE API METHODS ////////////////
Expand Down Expand Up @@ -6159,5 +6163,5 @@ public synchronized void defineAliases(List<String> aliases, String oldId) {
*/
private static final MethodHandle testModuleMatch = Binder
.from(boolean.class, ThreadContext.class, IRubyObject.class, int.class)
.invokeStaticQuiet(LOOKUP, Bootstrap.class, "testModuleMatch");
.invokeStaticQuiet(LOOKUP, RubyModule.class, "testModuleMatch");
}
8 changes: 4 additions & 4 deletions core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,16 @@
import org.jruby.ir.representations.BasicBlock;
import org.jruby.ir.runtime.IRRuntimeHelpers;
import org.jruby.ir.targets.IRBytecodeAdapter.BlockPassType;
import org.jruby.ir.targets.indy.Bootstrap;
import org.jruby.ir.targets.indy.CallTraceSite;
import org.jruby.ir.targets.indy.CoverageSite;
import org.jruby.ir.targets.indy.MetaClassBootstrap;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.ArgumentDescriptor;
import org.jruby.runtime.Block;
import org.jruby.runtime.CallType;
import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.Frame;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.RubyEvent;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
Expand Down Expand Up @@ -1515,7 +1515,7 @@ public void DefineMetaClassInstr(DefineMetaClassInstr definemetaclassinstr) {
jvmAdapter().invokedynamic(
"openMetaClass",
sig(DynamicMethod.class, ThreadContext.class, IRubyObject.class, String.class, StaticScope.class),
Bootstrap.OPEN_META_CLASS,
MetaClassBootstrap.OPEN_META_CLASS,
bodyHandle,
scopeHandle,
setScopeHandle,
Expand Down Expand Up @@ -1738,7 +1738,7 @@ public void LineNumberInstr(LineNumberInstr linenumberinstr) {
jvmAdapter().invokedynamic(
"coverLine",
sig(void.class, ThreadContext.class),
Bootstrap.coverLineHandle(),
CoverageSite.COVER_LINE_BOOTSTRAP,
jvm.methodData().scope.getFile(),
linenumberinstr.getLineNumber(),
linenumberinstr.oneshot ? 1 : 0);
Expand Down
315 changes: 4 additions & 311 deletions core/src/main/java/org/jruby/ir/targets/indy/Bootstrap.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.jruby.ir.targets.indy;

import org.jruby.ir.runtime.IRRuntimeHelpers;
import org.jruby.runtime.ThreadContext;
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 java.lang.invoke.MethodHandles.insertArguments;
import static java.lang.invoke.MethodType.methodType;
import static org.jruby.util.CodegenUtils.p;

public class CallInfoBootstrap {
public static final Handle CALL_INFO_BOOTSTRAP = new Handle(
Opcodes.H_INVOKESTATIC,
p(CallInfoBootstrap.class),
"callInfoBootstrap",
Bootstrap.BOOTSTRAP_INT_SIG,
false);

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);
}
}
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(CallSiteCacheBootstrap.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");
}
}
}
60 changes: 60 additions & 0 deletions core/src/main/java/org/jruby/ir/targets/indy/CheckpointSite.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
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 org.objectweb.asm.Opcodes;

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;
import static org.jruby.util.CodegenUtils.p;

public class CheckpointSite extends MutableCallSite {
public static final Handle CHECKPOINT_BOOTSTRAP = new Handle(
Opcodes.H_INVOKESTATIC,
p(CheckpointSite.class),
"checkpointBootstrap",
Bootstrap.BOOTSTRAP_BARE_SIG,
false);

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().findVirtual(CheckpointSite.class, "checkpointFallback", methodType(void.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();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
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, ConstructBlockBootstrap.class, "selfBinding");
private static final MethodHandle SCOPE_BINDING = BINDING_MAKER_BINDER.invokeStaticQuiet(LOOKUP, ConstructBlockBootstrap.class, "scopeBinding");
private static final MethodHandle FRAME_BINDING = BINDING_MAKER_BINDER.invokeStaticQuiet(LOOKUP, ConstructBlockBootstrap.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, ConstructBlockBootstrap.class, "constructBlock");
public static final Handle PREPARE_BLOCK_BOOTSTRAP = new Handle(
Opcodes.H_INVOKESTATIC,
p(ConstructBlockBootstrap.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);
}
}
44 changes: 44 additions & 0 deletions core/src/main/java/org/jruby/ir/targets/indy/CoverageSite.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
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 org.objectweb.asm.Opcodes;

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.p;
import static org.jruby.util.CodegenUtils.sig;

public class CoverageSite {
public static final Handle COVER_LINE_BOOTSTRAP = new Handle(
Opcodes.H_INVOKESTATIC,
p(CoverageSite.class),
"coverLineBootstrap",
sig(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, String.class, int.class, int.class),
false);

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(CoverageSite.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());
}
}
Loading

0 comments on commit ea35485

Please sign in to comment.