Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 2ee74f485eb3
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: a923c816fbad
Choose a head ref
  • 2 commits
  • 13 files changed
  • 1 contributor

Commits on Oct 18, 2014

  1. Revert "[Truffle] Abstract the safepoint mechanism so other features …

    …can re-use it."
    
    This reverts commit 9951841.
    mkristian committed Oct 18, 2014
    Copy the full SHA
    3fb763a View commit details
  2. Copy the full SHA
    a923c81 View commit details
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -50,7 +50,6 @@ matrix:
allow_failures:
- env: TARGET='-Pcomplete'
- env: TARGET='-Prake -Dtask=spec:compiler'
- env: TARGET='-Posgi'

branches:
only:
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@ public InitializeNode(InitializeNode prev) {
public RubyNilClass initialize(RubyThread thread, RubyProc block) {
notDesignedForCompilation();

thread.initialize(getContext(), this, block);
thread.initialize(this, block);
return getContext().getCoreLibrary().getNilObject();
}

Original file line number Diff line number Diff line change
@@ -14,17 +14,17 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import org.jruby.truffle.runtime.RubyContext;

public class SafepointInstrument extends Instrument {
public class ObjectSpaceSafepointInstrument extends Instrument {

private final RubyContext context;

public SafepointInstrument(RubyContext context) {
public ObjectSpaceSafepointInstrument(RubyContext context) {
this.context = context;
}

@Override
public void enter(Node node, VirtualFrame frame) {
context.getSafepointManager().poll();
context.getObjectSpaceManager().checkSafepoint();
}

}
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@
import com.oracle.truffle.api.nodes.Node;
import org.jruby.truffle.nodes.RubyNode;

public class SafepointProber implements RubyNodeProber {
public class ObjectSpaceSafepointProber implements RubyNodeProber {

@Override
public RubyNode probeAsStatement(RubyNode node) {
@@ -32,7 +32,7 @@ public RubyNode probeAsPeriodic(RubyNode node) {
}

wrapper.tagAs(StandardSyntaxTag.PERIODIC);
wrapper.getProbe().addInstrument(new SafepointInstrument(node.getContext()));
wrapper.getProbe().addInstrument(new ObjectSpaceSafepointInstrument(node.getContext()));

return wrapper;
}
658 changes: 0 additions & 658 deletions core/src/main/java/org/jruby/truffle/nodes/debug/ProxyNode.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@
import com.oracle.truffle.api.instrument.ASTProber;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.util.cli.Options;

import java.util.ArrayList;
import java.util.List;
@@ -27,7 +28,7 @@ public RubyASTProber() {
}

if (RubyContext.OBJECTSPACE) {
probers.add(new SafepointProber());
probers.add(new ObjectSpaceSafepointProber());
}
}

607 changes: 589 additions & 18 deletions core/src/main/java/org/jruby/truffle/nodes/debug/RubyWrapper.java

Large diffs are not rendered by default.

8 changes: 2 additions & 6 deletions core/src/main/java/org/jruby/truffle/runtime/RubyContext.java
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@

import java.io.*;
import java.math.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayDeque;
@@ -24,6 +25,7 @@
import com.oracle.truffle.api.*;
import com.oracle.truffle.api.source.*;
import com.oracle.truffle.api.frame.*;
import com.oracle.truffle.api.nodes.*;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.truffle.TruffleHooks;
import org.jruby.truffle.nodes.RubyNode;
@@ -73,7 +75,6 @@ public class RubyContext extends ExecutionContext {
private final AtExitManager atExitManager;
private final RubySymbol.SymbolTable symbolTable = new RubySymbol.SymbolTable(this);
private final Warnings warnings;
private final SafepointManager safepointManager;

private SourceCallback sourceCallback = null;

@@ -91,8 +92,6 @@ protected Queue<Object> initialValue() {
public RubyContext(Ruby runtime) {
assert runtime != null;

safepointManager = new SafepointManager(this);

this.runtime = runtime;
translator = new TranslatorDriver(this);
astProber = new RubyASTProber();
@@ -409,7 +408,4 @@ public Queue<Object> getThrowTags() {
return throwTags.get();
}

public SafepointManager getSafepointManager() {
return safepointManager;
}
}
Original file line number Diff line number Diff line change
@@ -13,10 +13,10 @@
import java.util.concurrent.*;

import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.control.ReturnException;
import org.jruby.truffle.runtime.subsystems.*;
import org.jruby.truffle.runtime.util.Supplier;

/**
* Represents the Ruby {@code Thread} class. Implemented using Java threads, but note that there is
@@ -55,10 +55,10 @@ public RubyThread(RubyClass rubyClass, ThreadManager manager) {
this.manager = manager;
}

public void initialize(RubyContext context, RubyNode currentNode, RubyProc block) {
public void initialize(final RubyNode currentNode, RubyProc block) {
final RubyProc finalBlock = block;

initialize(context, currentNode, new Runnable() {
initialize(currentNode, new Runnable() {

@Override
public void run() {
@@ -68,7 +68,7 @@ public void run() {
});
}

public void initialize(final RubyContext context, final RubyNode currentNode, Runnable runnable) {
public void initialize(final RubyNode currentNode, Runnable runnable) {
final RubyThread finalThread = this;
final Runnable finalRunnable = runnable;

@@ -78,7 +78,6 @@ public void initialize(final RubyContext context, final RubyNode currentNode, Ru
public void run() {
finalThread.manager.registerThread(finalThread);
finalThread.manager.enterGlobalLock(finalThread);
context.getSafepointManager().enterThread();

try {
finalRunnable.run();
@@ -90,7 +89,6 @@ public void run() {
finalThread.manager.leaveGlobalLock();
finalThread.manager.unregisterThread(finalThread);
finalThread.finished.countDown();
context.getSafepointManager().leaveThread();
}
}

Original file line number Diff line number Diff line change
@@ -13,15 +13,17 @@
import java.util.*;
import java.util.concurrent.*;

import com.oracle.truffle.api.Assumption;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.frame.Frame;
import com.oracle.truffle.api.frame.FrameInstance;
import com.oracle.truffle.api.frame.FrameInstanceVisitor;
import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.nodes.InvalidAssumptionException;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.*;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.util.Consumer;

/**
* Supports the Ruby {@code ObjectSpace} module. Object IDs are lazily allocated {@code long}
@@ -92,7 +94,7 @@ public void defineFinalizer(RubyBasicObject object, RubyProc proc) {

finalizerThread = new RubyThread(context.getCoreLibrary().getThreadClass(), context.getThreadManager());

finalizerThread.initialize(context, null, new Runnable() {
finalizerThread.initialize(null, new Runnable() {

@Override
public void run() {
@@ -205,37 +207,101 @@ public static interface ObjectGraphVisitor {
private Map<Long, RubyBasicObject> liveObjects;
private ObjectGraphVisitor visitor;

@CompilerDirectives.CompilationFinal private Assumption notStoppingAssumption = Truffle.getRuntime().createAssumption();
private CyclicBarrier stoppedBarrier;
private CyclicBarrier markedBarrier;

public void checkSafepoint() {
try {
notStoppingAssumption.check();
} catch (InvalidAssumptionException e) {
context.outsideGlobalLock(new Runnable() {

@Override
public void run() {
while (true) {
try {
stoppedBarrier.await();
break;
} catch (InterruptedException | BrokenBarrierException e2) {
}
}

synchronized (liveObjects) {
visitCallStack(visitor);
}

while (true) {
try {
markedBarrier.await();
break;
} catch (InterruptedException | BrokenBarrierException e2) {
}
}

// TODO(CS): error recovery
}

});
}
}

public Map<Long, RubyBasicObject> collectLiveObjects() {
RubyNode.notDesignedForCompilation();

// TODO(CS): probably a race condition here if multiple threads try to collect at the same time
synchronized (context.getThreadManager()) {
context.outsideGlobalLock(new Runnable() {

liveObjects = new HashMap<>();
@Override
public void run() {
liveObjects = new HashMap<>();

visitor = new ObjectGraphVisitor() {
visitor = new ObjectGraphVisitor() {

@Override
public boolean visit(RubyBasicObject object) {
return liveObjects.put(object.getObjectID(), object) == null;
}
@Override
public boolean visit(RubyBasicObject object) {
return liveObjects.put(object.getObjectID(), object) == null;
}

};
};

context.getSafepointManager().pauseAllThreadsAndExecute(new Consumer<Boolean>() {
stoppedBarrier = new CyclicBarrier(2);
markedBarrier = new CyclicBarrier(2);

@Override
public void accept(Boolean pausingThread) {
synchronized (liveObjects) {
context.getCoreLibrary().getGlobalVariablesObject().visitObjectGraph(visitor);
context.getCoreLibrary().getMainObject().visitObjectGraph(visitor);
context.getCoreLibrary().getObjectClass().visitObjectGraph(visitor);
visitCallStack(visitor);
notStoppingAssumption.invalidate();

while (true) {
try {
stoppedBarrier.await();
break;
} catch (InterruptedException | BrokenBarrierException e) {
}
}

synchronized (liveObjects) {
context.getCoreLibrary().getGlobalVariablesObject().visitObjectGraph(visitor);
context.getCoreLibrary().getMainObject().visitObjectGraph(visitor);
context.getCoreLibrary().getObjectClass().visitObjectGraph(visitor);
visitCallStack(visitor);
}

notStoppingAssumption = Truffle.getRuntime().createAssumption();

while (true) {
try {
markedBarrier.await();
break;
} catch (InterruptedException | BrokenBarrierException e) {
}
}

// TODO(CS): error recovery
}
}

});
});

return Collections.unmodifiableMap(liveObjects);
return Collections.unmodifiableMap(liveObjects);
}
}

public void visitCallStack(final ObjectGraphVisitor visitor) {

This file was deleted.

16 changes: 0 additions & 16 deletions core/src/main/java/org/jruby/truffle/runtime/util/Consumer.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@
import org.jruby.truffle.nodes.control.*;
import org.jruby.truffle.nodes.control.AndNode;
import org.jruby.truffle.nodes.control.IfNode;
import org.jruby.truffle.nodes.debug.ObjectSpaceSafepointInstrument;
import org.jruby.truffle.nodes.literal.ObjectLiteralNode;
import org.jruby.truffle.nodes.methods.*;
import org.jruby.truffle.nodes.methods.arguments.*;