Skip to content

Commit

Permalink
Showing 33 changed files with 232 additions and 490 deletions.
9 changes: 3 additions & 6 deletions truffle/src/main/java/org/jruby/truffle/cext/CExtNodes.java
Original file line number Diff line number Diff line change
@@ -307,12 +307,9 @@ public abstract static class GetBlockNode extends CoreMethodArrayArgumentsNode {
@TruffleBoundary
@Specialization
public DynamicObject getBlock() {
return Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor<DynamicObject>() {
@Override
public DynamicObject visitFrame(FrameInstance frameInstance) {
Frame frame = frameInstance.getFrame(FrameAccess.READ_ONLY, true);
return RubyArguments.tryGetBlock(frame);
}
return Truffle.getRuntime().iterateFrames(frameInstance -> {
Frame frame = frameInstance.getFrame(FrameAccess.READ_ONLY, true);
return RubyArguments.tryGetBlock(frame);
});
}

Original file line number Diff line number Diff line change
@@ -537,12 +537,7 @@ public Object waitPID(int input_pid, boolean no_hang) {
final int finalOptions = options;

// retry:
pid = getContext().getThreadManager().runUntilResult(this, new ThreadManager.BlockingAction<Integer>() {
@Override
public Integer block() throws InterruptedException {
return posix().waitpid(input_pid, statusReference, finalOptions);
}
});
pid = getContext().getThreadManager().runUntilResult(this, () -> posix().waitpid(input_pid, statusReference, finalOptions));

final int errno = posix().errno();

Original file line number Diff line number Diff line change
@@ -1918,12 +1918,7 @@ public Object sortObjectWithBlock(DynamicObject array, DynamicObject block) {

@TruffleBoundary
private void doSort(Object[] copy, int size, DynamicObject block) {
Arrays.sort(copy, 0, size, new Comparator<Object>() {
@Override
public int compare(Object a, Object b) {
return castSortValue(ProcOperations.rootCall(block, a, b));
}
});
Arrays.sort(copy, 0, size, (a, b) -> castSortValue(ProcOperations.rootCall(block, a, b)));
}

@Specialization(guards = { "!isNullArray(array)", "!isObjectArray(array)" })
Original file line number Diff line number Diff line change
@@ -339,26 +339,23 @@ private DynamicObject buildMethodMissingException(Object self, DynamicObject nam
}

private FrameInstance getRelevantCallerFrame() {
return Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor<FrameInstance>() {
@Override
public FrameInstance visitFrame(FrameInstance frameInstance) {
final Node callNode = frameInstance.getCallNode();
if (callNode == null) {
// skip current frame
return null;
}

final SuperCallNode superCallNode = NodeUtil.findParent(callNode, SuperCallNode.class);
final Frame frame = frameInstance.getFrame(FrameInstance.FrameAccess.READ_ONLY, true);
final String superMethodName = RubyArguments.getMethod(frame).getName();

if (superCallNode != null && superMethodName.equals("method_missing")) {
// skip super calls of method_missing itself
return null;
}

return frameInstance;
return Truffle.getRuntime().iterateFrames(frameInstance -> {
final Node callNode = frameInstance.getCallNode();
if (callNode == null) {
// skip current frame
return null;
}

final SuperCallNode superCallNode = NodeUtil.findParent(callNode, SuperCallNode.class);
final Frame frame = frameInstance.getFrame(FrameInstance.FrameAccess.READ_ONLY, true);
final String superMethodName = RubyArguments.getMethod(frame).getName();

if (superCallNode != null && superMethodName.equals("method_missing")) {
// skip super calls of method_missing itself
return null;
}

return frameInstance;
});
}

Original file line number Diff line number Diff line change
@@ -37,18 +37,13 @@ public DynamicObject ofCaller() {

final Memo<Integer> frameCount = new Memo<>(0);

final MaterializedFrame frame = Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor<MaterializedFrame>() {

@Override
public MaterializedFrame visitFrame(FrameInstance frameInstance) {
if (frameCount.get() == 2) {
return frameInstance.getFrame(FrameInstance.FrameAccess.READ_WRITE, false).materialize();
} else {
frameCount.set(frameCount.get() + 1);
return null;
}
final MaterializedFrame frame = Truffle.getRuntime().iterateFrames(frameInstance -> {
if (frameCount.get() == 2) {
return frameInstance.getFrame(FrameInstance.FrameAccess.READ_WRITE, false).materialize();
} else {
frameCount.set(frameCount.get() + 1);
return null;
}

});

if (frame == null) {
53 changes: 20 additions & 33 deletions truffle/src/main/java/org/jruby/truffle/core/fiber/FiberNodes.java
Original file line number Diff line number Diff line change
@@ -69,12 +69,7 @@ private static DynamicObject createFiber(RubyContext context, DynamicObject thre

public static void initialize(final RubyContext context, final DynamicObject fiber, final DynamicObject block, final Node currentNode) {
final String name = "Ruby Fiber@" + Layouts.PROC.getSharedMethodInfo(block).getSourceSection().getShortDescription();
final Thread thread = new Thread(new Runnable() {
@Override
public void run() {
handleFiberExceptions(context, fiber, block, currentNode);
}
});
final Thread thread = new Thread(() -> handleFiberExceptions(context, fiber, block, currentNode));
thread.setName(name);
thread.start();

@@ -95,29 +90,26 @@ public Boolean block() throws InterruptedException {
}

private static void handleFiberExceptions(final RubyContext context, final DynamicObject fiber, final DynamicObject block, Node currentNode) {
run(context, fiber, currentNode, new Runnable() {
@Override
public void run() {
run(context, fiber, currentNode, () -> {
try {
final Object[] args = waitForResume(context, fiber);
final Object result;
try {
final Object[] args = waitForResume(context, fiber);
final Object result;
try {
result = ProcOperations.rootCall(block, args);
} finally {
// Make sure that other fibers notice we are dead before they gain control back
Layouts.FIBER.setAlive(fiber, false);
}
resume(fiber, Layouts.FIBER.getLastResumedByFiber(fiber), true, result);
} catch (FiberExitException e) {
assert !Layouts.FIBER.getRootFiber(fiber);
// Naturally exit the Java thread on catching this
} catch (BreakException e) {
addToMessageQueue(Layouts.FIBER.getLastResumedByFiber(fiber), new FiberExceptionMessage(context.getCoreExceptions().breakFromProcClosure(null)));
} catch (ReturnException e) {
addToMessageQueue(Layouts.FIBER.getLastResumedByFiber(fiber), new FiberExceptionMessage(context.getCoreExceptions().unexpectedReturn(null)));
} catch (RaiseException e) {
addToMessageQueue(Layouts.FIBER.getLastResumedByFiber(fiber), new FiberExceptionMessage(e.getException()));
result = ProcOperations.rootCall(block, args);
} finally {
// Make sure that other fibers notice we are dead before they gain control back
Layouts.FIBER.setAlive(fiber, false);
}
resume(fiber, Layouts.FIBER.getLastResumedByFiber(fiber), true, result);
} catch (FiberExitException e) {
assert !Layouts.FIBER.getRootFiber(fiber);
// Naturally exit the Java thread on catching this
} catch (BreakException e) {
addToMessageQueue(Layouts.FIBER.getLastResumedByFiber(fiber), new FiberExceptionMessage(context.getCoreExceptions().breakFromProcClosure(null)));
} catch (ReturnException e) {
addToMessageQueue(Layouts.FIBER.getLastResumedByFiber(fiber), new FiberExceptionMessage(context.getCoreExceptions().unexpectedReturn(null)));
} catch (RaiseException e) {
addToMessageQueue(Layouts.FIBER.getLastResumedByFiber(fiber), new FiberExceptionMessage(e.getException()));
}
});
}
@@ -163,12 +155,7 @@ private static void addToMessageQueue(DynamicObject fiber, FiberMessage message)
private static Object[] waitForResume(RubyContext context, final DynamicObject fiber) {
assert RubyGuards.isRubyFiber(fiber);

final FiberMessage message = context.getThreadManager().runUntilResult(null, new BlockingAction<FiberMessage>() {
@Override
public FiberMessage block() throws InterruptedException {
return Layouts.FIBER.getMessageQueue(fiber).take();
}
});
final FiberMessage message = context.getThreadManager().runUntilResult(null, () -> Layouts.FIBER.getMessageQueue(fiber).take());

Layouts.THREAD.getFiberManager(Layouts.FIBER.getRubyThread(fiber)).setCurrentFiber(fiber);

Original file line number Diff line number Diff line change
@@ -234,14 +234,7 @@ public void remove() {
}

public static Iterable<KeyValue> iterableKeyValues(final Entry firstInSequence) {
return new Iterable<KeyValue>() {

@Override
public Iterator<KeyValue> iterator() {
return iterateKeyValues(firstInSequence);
}

};
return () -> iterateKeyValues(firstInSequence);
}

public static void copyInto(RubyContext context, DynamicObject from, DynamicObject to) {
Original file line number Diff line number Diff line change
@@ -122,14 +122,7 @@ public static Iterator<KeyValue> iterateKeyValues(DynamicObject hash) {
public static BoundaryIterable<KeyValue> iterableKeyValues(final DynamicObject hash) {
assert RubyGuards.isRubyHash(hash);

return BoundaryIterable.wrap(new Iterable<KeyValue>() {

@Override
public Iterator<KeyValue> iterator() {
return iterateKeyValues(hash);
}

});
return BoundaryIterable.wrap(() -> iterateKeyValues(hash));
}

}
Original file line number Diff line number Diff line change
@@ -742,12 +742,7 @@ private void exec(RubyContext context, DynamicObject envAsHash, String[] command
}
}

int exitCode = context.getThreadManager().runUntilResult(this, new BlockingAction<Integer>() {
@Override
public Integer block() throws InterruptedException {
return process.waitFor();
}
});
int exitCode = context.getThreadManager().runUntilResult(this, () -> process.waitFor());

/*
* We really do want to just exit here as opposed to throwing a MainExitException and tidying up, as we're
@@ -819,12 +814,7 @@ public DynamicObject gets() {

final BufferedReader reader = new BufferedReader(new InputStreamReader(in, encoding.getCharset()));

final String line = getContext().getThreadManager().runUntilResult(this, new BlockingAction<String>() {
@Override
public String block() throws InterruptedException {
return gets(reader);
}
});
final String line = getContext().getThreadManager().runUntilResult(this, () -> gets(reader));

final DynamicObject rubyLine = createString(StringOperations.encodeRope(line, UTF8Encoding.INSTANCE));

@@ -1666,19 +1656,16 @@ public static long sleepFor(Node currentNode, RubyContext context, final long du

final long start = System.currentTimeMillis();

long slept = context.getThreadManager().runUntilResult(currentNode, new BlockingAction<Long>() {
@Override
public Long block() throws InterruptedException {
long now = System.currentTimeMillis();
long slept = now - start;

if (slept >= durationInMillis || Layouts.THREAD.getWakeUp(thread).getAndSet(false)) {
return slept;
}
Thread.sleep(durationInMillis - slept);
long slept = context.getThreadManager().runUntilResult(currentNode, () -> {
long now = System.currentTimeMillis();
long slept1 = now - start;

return System.currentTimeMillis() - start;
if (slept1 >= durationInMillis || Layouts.THREAD.getWakeUp(thread).getAndSet(false)) {
return slept1;
}
Thread.sleep(durationInMillis - slept1);

return System.currentTimeMillis() - start;
});

return slept / 1000;
Original file line number Diff line number Diff line change
@@ -85,26 +85,14 @@ public void setTraceFunc(final DynamicObject traceFunc) {

instruments = new ArrayList<>();

instruments.add(instrumenter.attachFactory(SourceSectionFilter.newBuilder().tagIs(LineTag.class).build(), new ExecutionEventNodeFactory() {
@Override
public ExecutionEventNode create(EventContext eventContext) {
return new BaseEventEventNode(context, eventContext, traceFunc, context.getCoreStrings().LINE.createInstance());
}
}));
instruments.add(instrumenter.attachFactory(SourceSectionFilter.newBuilder().tagIs(LineTag.class).build(),
eventContext -> new BaseEventEventNode(context, eventContext, traceFunc, context.getCoreStrings().LINE.createInstance())));

instruments.add(instrumenter.attachFactory(SourceSectionFilter.newBuilder().tagIs(CallTag.class).build(), new ExecutionEventNodeFactory() {
@Override
public ExecutionEventNode create(EventContext eventContext) {
return new CallEventEventNode(context, eventContext, traceFunc, context.getCoreStrings().CALL.createInstance());
}
}));
instruments.add(instrumenter.attachFactory(SourceSectionFilter.newBuilder().tagIs(CallTag.class).build(),
eventContext -> new CallEventEventNode(context, eventContext, traceFunc, context.getCoreStrings().CALL.createInstance())));

instruments.add(instrumenter.attachFactory(SourceSectionFilter.newBuilder().tagIs(ClassTag.class).build(), new ExecutionEventNodeFactory() {
@Override
public ExecutionEventNode create(EventContext eventContext) {
return new BaseEventEventNode(context, eventContext, traceFunc, context.getCoreStrings().CLASS.createInstance());
}
}));
instruments.add(instrumenter.attachFactory(SourceSectionFilter.newBuilder().tagIs(ClassTag.class).build(),
eventContext -> new BaseEventEventNode(context, eventContext, traceFunc, context.getCoreStrings().CLASS.createInstance())));

}

Original file line number Diff line number Diff line change
@@ -592,25 +592,17 @@ public DynamicObject getActualModule() {

public Iterable<DynamicObject> ancestors() {
final ModuleChain top = start;
return new Iterable<DynamicObject>() {
@Override
public Iterator<DynamicObject> iterator() {
return new AncestorIterator(top);
}
};
return () -> new AncestorIterator(top);
}

public Iterable<DynamicObject> parentAncestors() {
final ModuleChain top = start;
return new Iterable<DynamicObject>() {
@Override
public Iterator<DynamicObject> iterator() {
final AncestorIterator iterator = new AncestorIterator(top);
if (iterator.hasNext()) {
iterator.next();
}
return iterator;
return () -> {
final AncestorIterator iterator = new AncestorIterator(top);
if (iterator.hasNext()) {
iterator.next();
}
return iterator;
};
}

@@ -620,12 +612,7 @@ public Iterator<DynamicObject> iterator() {
public Iterable<DynamicObject> prependedAndIncludedModules() {
final ModuleChain top = start;
final ModuleFields currentModule = this;
return new Iterable<DynamicObject>() {
@Override
public Iterator<DynamicObject> iterator() {
return new IncludedModulesIterator(top, currentModule);
}
};
return () -> new IncludedModulesIterator(top, currentModule);
}

public Collection<DynamicObject> filterMethods(RubyContext context, boolean includeAncestors, MethodFilter filter) {
Original file line number Diff line number Diff line change
@@ -336,12 +336,9 @@ public static Map<String, Object> getAllClassVariables(DynamicObject module) {

final Map<String, Object> classVariables = new HashMap<>();

classVariableLookup(module, new Function1<Object, DynamicObject>() {
@Override
public Object apply(DynamicObject module) {
classVariables.putAll(Layouts.MODULE.getFields(module).getClassVariables());
return null;
}
classVariableLookup(module, module1 -> {
classVariables.putAll(Layouts.MODULE.getFields(module1).getClassVariables());
return null;
});

return classVariables;
@@ -351,12 +348,7 @@ public Object apply(DynamicObject module) {
public static Object lookupClassVariable(DynamicObject module, final String name) {
assert RubyGuards.isRubyModule(module);

return classVariableLookup(module, new Function1<Object, DynamicObject>() {
@Override
public Object apply(DynamicObject module) {
return Layouts.MODULE.getFields(module).getClassVariables().get(name);
}
});
return classVariableLookup(module, module1 -> Layouts.MODULE.getFields(module1).getClassVariables().get(name));
}

@TruffleBoundary(throwsControlFlowException = true)
@@ -377,15 +369,12 @@ public static void setClassVariable(final RubyContext context, DynamicObject mod
}

private static boolean trySetClassVariable(DynamicObject topModule, final String name, final Object value) {
final DynamicObject found = classVariableLookup(topModule, new Function1<DynamicObject, DynamicObject>() {
@Override
public DynamicObject apply(DynamicObject module) {
final ModuleFields moduleFields = Layouts.MODULE.getFields(module);
if (moduleFields.getClassVariables().replace(name, value) != null) {
return module;
} else {
return null;
}
final DynamicObject found = classVariableLookup(topModule, module -> {
final ModuleFields moduleFields = Layouts.MODULE.getFields(module);
if (moduleFields.getClassVariables().replace(name, value) != null) {
return module;
} else {
return null;
}
});
return found != null;
Original file line number Diff line number Diff line change
@@ -93,12 +93,7 @@ public synchronized void defineFinalizer(DynamicObject object, Object callable)
// TODO(CS): should we be running this in a real Ruby thread?

finalizerThread = ThreadManager.createRubyThread(context);
ThreadManager.initialize(finalizerThread, context, null, "finalizer", new Runnable() {
@Override
public void run() {
runFinalizers();
}
});
ThreadManager.initialize(finalizerThread, context, null, "finalizer", () -> runFinalizers());
}
}

@@ -115,12 +110,7 @@ private void runFinalizers() {

while (true) {
// Wait on the finalizer queue
FinalizerReference finalizerReference = context.getThreadManager().runUntilResult(null, new ThreadManager.BlockingAction<FinalizerReference>() {
@Override
public FinalizerReference block() throws InterruptedException {
return (FinalizerReference) finalizerQueue.remove();
}
});
FinalizerReference finalizerReference = (FinalizerReference) context.getThreadManager().runUntilResult(null, () -> finalizerQueue.remove());

runFinalizers(context, finalizerReference);
}
Original file line number Diff line number Diff line change
@@ -33,12 +33,7 @@ public ProcSignalHandler(RubyContext context, DynamicObject proc) {
@Override
public void handle(Signal signal) {
Thread mainThread = Layouts.FIBER.getThread((Layouts.THREAD.getFiberManager(context.getThreadManager().getRootThread()).getCurrentFiber()));
context.getSafepointManager().pauseThreadAndExecuteLaterFromNonRubyThread(mainThread, new SafepointAction() {
@Override
public void run(DynamicObject thread, Node currentNode) {
ProcOperations.rootCall(proc);
}
});
context.getSafepointManager().pauseThreadAndExecuteLaterFromNonRubyThread(mainThread, (thread, currentNode) -> ProcOperations.rootCall(proc));
}

}
36 changes: 14 additions & 22 deletions truffle/src/main/java/org/jruby/truffle/core/queue/QueueNodes.java
Original file line number Diff line number Diff line change
@@ -96,12 +96,7 @@ public Object popBlocking(DynamicObject self, boolean nonBlocking) {

@TruffleBoundary
private Object doPop(final BlockingQueue<Object> queue) {
return getContext().getThreadManager().runUntilResult(this, new BlockingAction<Object>() {
@Override
public Object block() throws InterruptedException {
return queue.take();
}
});
return getContext().getThreadManager().runUntilResult(this, () -> queue.take());
}

@Specialization(guards = "nonBlocking")
@@ -145,28 +140,25 @@ public Object receiveTimeout(DynamicObject self, double duration) {
final long durationInMillis = (long) (duration * 1000.0);
final long start = System.currentTimeMillis();

return getContext().getThreadManager().runUntilResult(this, new BlockingAction<Object>() {
@Override
public Object block() throws InterruptedException {
long now = System.currentTimeMillis();
long waited = now - start;
if (waited >= durationInMillis) {
// Try again to make sure we at least tried once
final Object result = queue.poll();
if (result == null) {
return false;
} else {
return result;
}
}

final Object result = queue.poll(durationInMillis, TimeUnit.MILLISECONDS);
return getContext().getThreadManager().runUntilResult(this, () -> {
long now = System.currentTimeMillis();
long waited = now - start;
if (waited >= durationInMillis) {
// Try again to make sure we at least tried once
final Object result = queue.poll();
if (result == null) {
return false;
} else {
return result;
}
}

final Object result = queue.poll(durationInMillis, TimeUnit.MILLISECONDS);
if (result == null) {
return false;
} else {
return result;
}
});
}

Original file line number Diff line number Diff line change
@@ -183,12 +183,7 @@ public Object popBlocking(DynamicObject self, boolean nonBlocking) {

@TruffleBoundary
private Object doPop(final BlockingQueue<Object> queue) {
return getContext().getThreadManager().runUntilResult(this, new BlockingAction<Object>() {
@Override
public Object block() throws InterruptedException {
return queue.take();
}
});
return getContext().getThreadManager().runUntilResult(this, () -> queue.take());
}

@Specialization(guards = "nonBlocking")
Original file line number Diff line number Diff line change
@@ -123,12 +123,7 @@ public static DynamicObject matchCommon(RubyContext context, Node currentNode, R

final Rope sourceRope = StringOperations.rope(string);

int match = context.getThreadManager().runUntilResult(currentNode, new BlockingAction<Integer>() {
@Override
public Integer block() throws InterruptedException {
return matcher.searchInterruptible(startPos, range, Option.DEFAULT);
}
});
int match = context.getThreadManager().runUntilResult(currentNode, () -> matcher.searchInterruptible(startPos, range, Option.DEFAULT));

final DynamicObject nil = context.getCoreLibrary().getNilObject();

Original file line number Diff line number Diff line change
@@ -206,15 +206,10 @@ public static byte[] extractRange(Rope rope, int offset, int length) {

final Memo<Integer> resultPosition = new Memo<>(0);

visitBytes(rope, new BytesVisitor() {

@Override
public void accept(byte[] bytes, int offset, int length) {
final int resultPositionValue = resultPosition.get();
System.arraycopy(bytes, offset, result, resultPositionValue, length);
resultPosition.set(resultPositionValue + length);
}

visitBytes(rope, (bytes, offset1, length1) -> {
final int resultPositionValue = resultPosition.get();
System.arraycopy(bytes, offset1, result, resultPositionValue, length1);
resultPosition.set(resultPositionValue + length1);
}, offset, length);

return result;
Original file line number Diff line number Diff line change
@@ -270,12 +270,7 @@ public Object socketRead(DynamicObject io, int length, int flags, int type) {
}

final ByteBuffer buffer = ByteBuffer.allocate(length);
final int bytesRead = getContext().getThreadManager().runUntilResult(this, new ThreadManager.BlockingAction<Integer>() {
@Override
public Integer block() throws InterruptedException {
return ensureSuccessful(nativeSockets().recvfrom(sockfd, buffer, length, flags, PointerPrimitiveNodes.NULL_POINTER, PointerPrimitiveNodes.NULL_POINTER));
}
});
final int bytesRead = getContext().getThreadManager().runUntilResult(this, () -> ensureSuccessful(nativeSockets().recvfrom(sockfd, buffer, length, flags, PointerPrimitiveNodes.NULL_POINTER, PointerPrimitiveNodes.NULL_POINTER)));
buffer.position(bytesRead);

return createString(new ByteList(buffer.array(), buffer.arrayOffset(), buffer.position(), false));
@@ -420,20 +415,15 @@ public int write(DynamicObject file, DynamicObject string) {
return rope.byteLength();
}

RopeOperations.visitBytes(rope, new BytesVisitor() {
RopeOperations.visitBytes(rope, (bytes, offset, length) -> {
final ByteBuffer buffer = ByteBuffer.wrap(bytes, offset, length);

@Override
public void accept(byte[] bytes, int offset, int length) {
final ByteBuffer buffer = ByteBuffer.wrap(bytes, offset, length);
while (buffer.hasRemaining()) {
getContext().getSafepointManager().poll(IOWritePrimitiveNode.this);

while (buffer.hasRemaining()) {
getContext().getSafepointManager().poll(IOWritePrimitiveNode.this);

int written = ensureSuccessful(posix().write(fd, buffer, buffer.remaining()));
buffer.position(buffer.position() + written);
}
int written = ensureSuccessful(posix().write(fd, buffer, buffer.remaining()));
buffer.position(buffer.position() + written);
}

});

return rope.byteLength();
Original file line number Diff line number Diff line change
@@ -92,23 +92,15 @@ public static DynamicObject createThreadLocals(RubyContext context) {

public static void initialize(final DynamicObject thread, RubyContext context, Node currentNode, final Object[] arguments, final DynamicObject block) {
String info = Layouts.PROC.getSharedMethodInfo(block).getSourceSection().getShortDescription();
initialize(thread, context, currentNode, info, new Runnable() {
@Override
public void run() {
final Object value = ProcOperations.rootCall(block, arguments);
Layouts.THREAD.setValue(thread, value);
}
initialize(thread, context, currentNode, info, () -> {
final Object value = ProcOperations.rootCall(block, arguments);
Layouts.THREAD.setValue(thread, value);
});
}

public static void initialize(final DynamicObject thread, final RubyContext context, final Node currentNode, final String info, final Runnable task) {
assert RubyGuards.isRubyThread(thread);
new Thread(new Runnable() {
@Override
public void run() {
ThreadManager.run(thread, context, currentNode, info, task);
}
}).start();
new Thread(() -> run(thread, context, currentNode, info, task)).start();

FiberNodes.waitForInitialization(context, Layouts.THREAD.getFiberManager(thread).getRootFiber(), currentNode);
}
@@ -270,14 +262,7 @@ public <T> ResultOrTimeout<T> runUntilTimeout(Node currentNode, int timeoutMicro
if (timeoutMicros == 0) {
timeoutToUse.setTime(new long[]{0, 0});

return new ResultWithinTime<>(runUntilResult(currentNode, new BlockingAction<T>() {

@Override
public T block() throws InterruptedException {
return action.block(timeoutToUse);
}

}));
return new ResultWithinTime<>(runUntilResult(currentNode, () -> action.block(timeoutToUse)));
} else {
final int pollTime = 500_000_000;
final long requestedTimeoutAt = System.nanoTime() + timeoutMicros * 1_000L;
Original file line number Diff line number Diff line change
@@ -80,14 +80,9 @@ public DynamicObject backtrace(DynamicObject rubyThread) {

final Memo<DynamicObject> result = new Memo<>(null);

getContext().getSafepointManager().pauseThreadAndExecute(thread, this, new SafepointAction() {

@Override
public void run(DynamicObject thread, Node currentNode) {
final Backtrace backtrace = getContext().getCallStack().getBacktrace(currentNode);
result.set(ExceptionOperations.backtraceAsRubyStringArray(getContext(), null, backtrace));
}

getContext().getSafepointManager().pauseThreadAndExecute(thread, this, (thread1, currentNode) -> {
final Backtrace backtrace = getContext().getCallStack().getBacktrace(currentNode);
result.set(ExceptionOperations.backtraceAsRubyStringArray(getContext(), null, backtrace));
});

// If the thread id dead or aborting the SafepointAction will not run
@@ -134,14 +129,7 @@ public DynamicObject kill(final DynamicObject rubyThread) {
return rubyThread;
}

getContext().getSafepointManager().pauseThreadAndExecuteLater(toKill, this, new SafepointAction() {

@Override
public void run(DynamicObject currentThread, Node currentNode) {
ThreadManager.shutdown(getContext(), currentThread, currentNode);
}

});
getContext().getSafepointManager().pauseThreadAndExecuteLater(toKill, this, (currentThread, currentNode) -> ThreadManager.shutdown(getContext(), currentThread, currentNode));

return rubyThread;
}
@@ -279,19 +267,14 @@ public Boolean block() throws InterruptedException {
private boolean doJoinMillis(final DynamicObject thread, final int timeoutInMillis) {
final long start = System.currentTimeMillis();

final boolean joined = getContext().getThreadManager().runUntilResult(this, new ThreadManager.BlockingAction<Boolean>() {

@Override
public Boolean block() throws InterruptedException {
long now = System.currentTimeMillis();
long waited = now - start;
if (waited >= timeoutInMillis) {
// We need to know whether countDown() was called and we do not want to block.
return Layouts.THREAD.getFinishedLatch(thread).getCount() == 0;
}
return Layouts.THREAD.getFinishedLatch(thread).await(timeoutInMillis - waited, TimeUnit.MILLISECONDS);
final boolean joined = getContext().getThreadManager().runUntilResult(this, () -> {
long now = System.currentTimeMillis();
long waited = now - start;
if (waited >= timeoutInMillis) {
// We need to know whether countDown() was called and we do not want to block.
return Layouts.THREAD.getFinishedLatch(thread).getCount() == 0;
}

return Layouts.THREAD.getFinishedLatch(thread).await(timeoutInMillis - waited, TimeUnit.MILLISECONDS);
});

if (joined && Layouts.THREAD.getException(thread) != null) {
@@ -472,15 +455,12 @@ public DynamicObject raise(DynamicObject thread, final DynamicObject exception)
public static void raiseInThread(final RubyContext context, DynamicObject rubyThread, final DynamicObject exception, Node currentNode) {
final Thread javaThread = Layouts.FIBER.getThread((Layouts.THREAD.getFiberManager(rubyThread).getCurrentFiber()));

context.getSafepointManager().pauseThreadAndExecuteLater(javaThread, currentNode, new SafepointAction() {
@Override
public void run(DynamicObject currentThread, Node currentNode) {
if (Layouts.EXCEPTION.getBacktrace(exception) == null) {
Backtrace backtrace = context.getCallStack().getBacktrace(currentNode);
Layouts.EXCEPTION.setBacktrace(exception, backtrace);
}
throw new RaiseException(exception);
context.getSafepointManager().pauseThreadAndExecuteLater(javaThread, currentNode, (currentThread, currentNode1) -> {
if (Layouts.EXCEPTION.getBacktrace(exception) == null) {
Backtrace backtrace = context.getCallStack().getBacktrace(currentNode1);
Layouts.EXCEPTION.setBacktrace(exception, backtrace);
}
throw new RaiseException(exception);
});
}

Original file line number Diff line number Diff line change
@@ -104,12 +104,7 @@ public boolean enable(VirtualFrame frame, DynamicObject tracePoint, DynamicObjec

@TruffleBoundary
public static EventBinding<?> createEventBinding(final RubyContext context, final DynamicObject tracePoint) {
return context.getInstrumenter().attachFactory(SourceSectionFilter.newBuilder().tagIs((Class<?>[]) Layouts.TRACE_POINT.getTags(tracePoint)).build(), new ExecutionEventNodeFactory() {
@Override
public ExecutionEventNode create(EventContext eventContext) {
return new TracePointEventNode(context, tracePoint);
}
});
return context.getInstrumenter().attachFactory(SourceSectionFilter.newBuilder().tagIs((Class<?>[]) Layouts.TRACE_POINT.getTags(tracePoint)).build(), eventContext -> new TracePointEventNode(context, tracePoint));
}

@TruffleBoundary
Original file line number Diff line number Diff line change
@@ -51,13 +51,7 @@ public synchronized EventBinding<?> attach(String file, int line, final DynamicO
.tagIs(LineTag.class)
.build();

return instrumenter.attachFactory(filter, new ExecutionEventNodeFactory() {

public ExecutionEventNode create(EventContext eventContext) {
return new AttachmentEventNode(context, block);
}

});
return instrumenter.attachFactory(filter, eventContext -> new AttachmentEventNode(context, block));
}

private static class AttachmentEventNode extends ExecutionEventNode {
Original file line number Diff line number Diff line change
@@ -93,24 +93,19 @@ public InternalMethod getCallingMethodIgnoringSend() {
public Node getTopMostUserCallNode() {
final Memo<Boolean> firstFrame = new Memo<>(true);

return Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor<Node>() {

@Override
public Node visitFrame(FrameInstance frameInstance) {
if (firstFrame.get()) {
firstFrame.set(false);
return null;
}
return Truffle.getRuntime().iterateFrames(frameInstance -> {
if (firstFrame.get()) {
firstFrame.set(false);
return null;
}

final SourceSection sourceSection = frameInstance.getCallNode().getEncapsulatingSourceSection();
final SourceSection sourceSection = frameInstance.getCallNode().getEncapsulatingSourceSection();

if (sourceSection.getSource() == null) {
return null;
} else {
return frameInstance.getCallNode();
}
if (sourceSection.getSource() == null) {
return null;
} else {
return frameInstance.getCallNode();
}

});
}

Original file line number Diff line number Diff line change
@@ -189,12 +189,9 @@ public void pauseThreadAndExecute(final Thread thread, Node currentNode, final S
final DynamicObject rubyThread = context.getThreadManager().getCurrentThread();
action.run(rubyThread, currentNode);
} else {
pauseAllThreadsAndExecute(currentNode, false, new SafepointAction() {
@Override
public void run(DynamicObject rubyThread, Node currentNode) {
if (Thread.currentThread() == thread) {
action.run(rubyThread, currentNode);
}
pauseAllThreadsAndExecute(currentNode, false, (rubyThread, currentNode1) -> {
if (Thread.currentThread() == thread) {
action.run(rubyThread, currentNode1);
}
});
}
@@ -207,25 +204,19 @@ public void pauseThreadAndExecuteLater(final Thread thread, Node currentNode, fi
final DynamicObject rubyThread = context.getThreadManager().getCurrentThread();
action.run(rubyThread, currentNode);
} else {
pauseAllThreadsAndExecute(currentNode, true, new SafepointAction() {
@Override
public void run(DynamicObject rubyThread, Node currentNode) {
if (Thread.currentThread() == thread) {
action.run(rubyThread, currentNode);
}
pauseAllThreadsAndExecute(currentNode, true, (rubyThread, currentNode1) -> {
if (Thread.currentThread() == thread) {
action.run(rubyThread, currentNode1);
}
});
}
}

@TruffleBoundary
public void pauseThreadAndExecuteLaterFromNonRubyThread(final Thread thread, final SafepointAction action) {
pauseAllThreadsAndExecuteFromNonRubyThread(true, new SafepointAction() {
@Override
public void run(DynamicObject rubyThread, Node currentNode) {
if (Thread.currentThread() == thread) {
action.run(rubyThread, currentNode);
}
pauseAllThreadsAndExecuteFromNonRubyThread(true, (rubyThread, currentNode) -> {
if (Thread.currentThread() == thread) {
action.run(rubyThread, currentNode);
}
});
}
Original file line number Diff line number Diff line change
@@ -162,18 +162,13 @@ public abstract static class SourceOfCallerNode extends CoreMethodArrayArguments
public DynamicObject sourceOfCaller() {
final Memo<Integer> frameCount = new Memo<>(0);

final String source = Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor<String>() {

@Override
public String visitFrame(FrameInstance frameInstance) {
if (frameCount.get() == 2) {
return frameInstance.getCallNode().getEncapsulatingSourceSection().getSource().getName();
} else {
frameCount.set(frameCount.get() + 1);
return null;
}
final String source = Truffle.getRuntime().iterateFrames(frameInstance -> {
if (frameCount.get() == 2) {
return frameInstance.getCallNode().getEncapsulatingSourceSection().getSource().getName();
} else {
frameCount.set(frameCount.get() + 1);
return null;
}

});

if (source == null) {
Original file line number Diff line number Diff line change
@@ -57,42 +57,39 @@ public Object executeDispatch(
((DynamicObject) receiverObject).updateShape();
}

final DispatchNode dispatch = atomic(new Callable<DispatchNode>() {
@Override
public DispatchNode call() throws Exception {
final DispatchNode first = getHeadNode().getFirstDispatchNode();

// First try to see if we did not a miss a specialization added by another thread.

DispatchNode lookupDispatch = first;
while (lookupDispatch != null) {
if (lookupDispatch.guard(methodName, receiverObject)) {
// This one worked, no need to rewrite anything.
return lookupDispatch;
}
lookupDispatch = lookupDispatch.getNext();
final DispatchNode dispatch = atomic(() -> {
final DispatchNode first = getHeadNode().getFirstDispatchNode();

// First try to see if we did not a miss a specialization added by another thread.

DispatchNode lookupDispatch = first;
while (lookupDispatch != null) {
if (lookupDispatch.guard(methodName, receiverObject)) {
// This one worked, no need to rewrite anything.
return lookupDispatch;
}
lookupDispatch = lookupDispatch.getNext();
}

// We need a new node to handle this case.
// We need a new node to handle this case.

final DispatchNode newDispathNode;
final DispatchNode newDispathNode;

if (depth == getContext().getOptions().DISPATCH_CACHE) {
newDispathNode = new UncachedDispatchNode(getContext(), ignoreVisibility, getDispatchAction(), missingBehavior);
if (depth == getContext().getOptions().DISPATCH_CACHE) {
newDispathNode = new UncachedDispatchNode(getContext(), ignoreVisibility, getDispatchAction(), missingBehavior);
} else {
depth++;
if (RubyGuards.isForeignObject(receiverObject)) {
newDispathNode = new CachedForeignDispatchNode(getContext(), first, methodName);
} else if (RubyGuards.isRubyBasicObject(receiverObject)) {
newDispathNode = doDynamicObject(frame, first, receiverObject, methodName, argumentsObjects);
} else {
depth++;
if (RubyGuards.isForeignObject(receiverObject)) {
newDispathNode = new CachedForeignDispatchNode(getContext(), first, methodName);
} else if (RubyGuards.isRubyBasicObject(receiverObject)) {
newDispathNode = doDynamicObject(frame, first, receiverObject, methodName, argumentsObjects);
} else {
newDispathNode = doUnboxedObject(frame, first, receiverObject, methodName);
}
newDispathNode = doUnboxedObject(frame, first, receiverObject, methodName);
}

first.replace(newDispathNode);
return newDispathNode;
}

first.replace(newDispathNode);
return newDispathNode;
});

return dispatch.executeDispatch(frame, receiverObject, methodName, blockObject, argumentsObjects);
Original file line number Diff line number Diff line change
@@ -38,38 +38,30 @@ public static Set<DynamicObject> stopAndGetAllObjects(Node currentNode, final Ru

final Thread stoppingThread = Thread.currentThread();

context.getSafepointManager().pauseAllThreadsAndExecute(currentNode, false, new SafepointAction() {
@Override
public void run(DynamicObject thread, Node currentNode) {
synchronized (visited) {
final Deque<DynamicObject> stack = new ArrayDeque<>();

// Thread.current
stack.add(thread);
// Fiber.current
stack.add(Layouts.THREAD.getFiberManager(thread).getCurrentFiber());

if (Thread.currentThread() == stoppingThread) {
visitContextRoots(context, stack);
}
context.getSafepointManager().pauseAllThreadsAndExecute(currentNode, false, (thread, currentNode1) -> {
synchronized (visited) {
final Deque<DynamicObject> stack = new ArrayDeque<>();

Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor<Object>() {
// Thread.current
stack.add(thread);
// Fiber.current
stack.add(Layouts.THREAD.getFiberManager(thread).getCurrentFiber());

@Override
public Object visitFrame(FrameInstance frameInstance) {
stack.addAll(getObjectsInFrame(frameInstance.getFrame(
FrameInstance.FrameAccess.READ_ONLY, true)));
return null;
}
if (Thread.currentThread() == stoppingThread) {
visitContextRoots(context, stack);
}

});
Truffle.getRuntime().iterateFrames(frameInstance -> {
stack.addAll(getObjectsInFrame(frameInstance.getFrame(
FrameInstance.FrameAccess.READ_ONLY, true)));
return null;
});

while (!stack.isEmpty()) {
final DynamicObject object = stack.pop();
while (!stack.isEmpty()) {
final DynamicObject object = stack.pop();

if (visited.add(object)) {
stack.addAll(ObjectGraph.getAdjacentObjects(object));
}
if (visited.add(object)) {
stack.addAll(ObjectGraph.getAdjacentObjects(object));
}
}
}
@@ -84,14 +76,11 @@ public static Set<DynamicObject> stopAndGetRootObjects(Node currentNode, final R

final Thread stoppingThread = Thread.currentThread();

context.getSafepointManager().pauseAllThreadsAndExecute(currentNode, false, new SafepointAction() {
@Override
public void run(DynamicObject thread, Node currentNode) {
objects.add(thread);
context.getSafepointManager().pauseAllThreadsAndExecute(currentNode, false, (thread, currentNode1) -> {
objects.add(thread);

if (Thread.currentThread() == stoppingThread) {
visitContextRoots(context, objects);
}
if (Thread.currentThread() == stoppingThread) {
visitContextRoots(context, objects);
}
});

Original file line number Diff line number Diff line change
@@ -18,11 +18,8 @@ public interface SignalManager {

Map<String, Integer> SIGNALS_LIST = Collections.unmodifiableMap(RubySignal.list());

SignalHandler IGNORE_HANDLER = new SignalHandler() {
@Override
public void handle(Signal arg0) {
// Just ignore the signal.
}
SignalHandler IGNORE_HANDLER = signal -> {
// Just ignore the signal.
};

Signal createSignal(String name);
Original file line number Diff line number Diff line change
@@ -57,12 +57,7 @@ public void handleDefault(final Signal signal) throws IllegalArgumentException {

private sun.misc.SignalHandler wrapHandler(final Signal signal, final SignalHandler newHandler) {
final SunMiscSignal smSignal = (SunMiscSignal) signal;
return new sun.misc.SignalHandler() {
@Override
public void handle(sun.misc.Signal wrappedSignal) {
newHandler.handle(smSignal);
}
};
return wrappedSignal -> newHandler.handle(smSignal);
}

@Override
Original file line number Diff line number Diff line change
@@ -87,11 +87,7 @@ public synchronized void enable() {

binding = instrumenter.attachFactory(SourceSectionFilter.newBuilder()
.tagIs(LineTag.class)
.build(), new ExecutionEventNodeFactory() {

@Override
public ExecutionEventNode create(final EventContext eventContext) {
return new ExecutionEventNode() {
.build(), eventContext -> new ExecutionEventNode() {

@CompilationFinal private boolean configured;
@CompilationFinal private int lineNumber;
@@ -116,10 +112,7 @@ protected void onEnter(VirtualFrame frame) {
}
}

};
}

});
});

enabled = true;
}
Original file line number Diff line number Diff line change
@@ -105,14 +105,7 @@ public abstract static class UpdateNode extends CoreMethodArrayArgumentsNode {
public DynamicObject update(DynamicObject digestObject, DynamicObject message) {
final MessageDigest digest = Layouts.DIGEST.getDigest(digestObject);

RopeOperations.visitBytes(StringOperations.rope(message), new BytesVisitor() {

@Override
public void accept(byte[] bytes, int offset, int length) {
digest.update(bytes, offset, length);
}

});
RopeOperations.visitBytes(StringOperations.rope(message), (bytes, offset, length) -> digest.update(bytes, offset, length));

return digestObject;
}
Original file line number Diff line number Diff line change
@@ -113,37 +113,25 @@ public void run(DynamicObject thread, Node currentNode) {

});

server.createContext("/break", new HttpHandler() {

@Override
public void handle(HttpExchange httpExchange) {
try {
final Thread mainThread = Layouts.FIBER.getThread(
Layouts.THREAD.getFiberManager(context.getThreadManager().getRootThread())
.getCurrentFiber());

context.getSafepointManager().pauseThreadAndExecuteLaterFromNonRubyThread(mainThread, new SafepointAction() {

@Override
public void run(DynamicObject thread, final Node currentNode) {
new SimpleShell(context).run(Truffle.getRuntime().getCurrentFrame()
.getFrame(FrameInstance.FrameAccess.MATERIALIZE, true).materialize(), currentNode);
}

});

httpExchange.getResponseHeaders().set("Content-Type", "text/plain");
httpExchange.sendResponseHeaders(200, 0);
httpExchange.getResponseBody().close();
} catch (IOException e) {
if (shuttingDown) {
return;
}

e.printStackTrace();
server.createContext("/break", httpExchange -> {
try {
final Thread mainThread = Layouts.FIBER.getThread(
Layouts.THREAD.getFiberManager(context.getThreadManager().getRootThread())
.getCurrentFiber());

context.getSafepointManager().pauseThreadAndExecuteLaterFromNonRubyThread(mainThread, (thread, currentNode) -> new SimpleShell(context).run(Truffle.getRuntime().getCurrentFrame()
.getFrame(FrameInstance.FrameAccess.MATERIALIZE, true).materialize(), currentNode));

httpExchange.getResponseHeaders().set("Content-Type", "text/plain");
httpExchange.sendResponseHeaders(200, 0);
httpExchange.getResponseBody().close();
} catch (IOException e) {
if (shuttingDown) {
return;
}
}

e.printStackTrace();
}
});

server.start();

0 comments on commit 5038049

Please sign in to comment.