Skip to content
Permalink
Browse files
[Truffle] Remove some abstractions that don't seem to compile well, a…
…nd fix some other compilation problems.
  • Loading branch information
chrisseaton committed Oct 31, 2014
1 parent eed2a9e commit 6793854970616f219fe618a60b5cf575a8eef0c3
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 134 deletions.
@@ -11,17 +11,9 @@

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.runtime.ModuleOperations;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.UndefinedPlaceholder;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyClass;
import org.jruby.truffle.runtime.core.RubyProc;

import java.math.BigInteger;

@CoreClass(name = "GC")
public abstract class GCNodes {
@@ -59,12 +51,13 @@ public RubyNilClass garbageCollect() {
private RubyNilClass doGC() {
notDesignedForCompilation();

getContext().outsideGlobalLock(new Runnable() {
@Override
public void run() {
System.gc();
}
});
final RubyThread runningThread = getContext().getThreadManager().leaveGlobalLock();

try {
System.gc();
} finally {
getContext().getThreadManager().enterGlobalLock(runningThread);
}

return getContext().getCoreLibrary().getNilObject();
}
@@ -36,6 +36,7 @@
import org.jruby.truffle.runtime.methods.RubyMethod;
import org.jruby.truffle.runtime.subsystems.*;
import org.jruby.truffle.runtime.util.Supplier;
import org.jruby.util.ByteList;

@CoreClass(name = "Kernel")
public abstract class KernelNodes {
@@ -776,19 +777,17 @@ public RubyString gets(VirtualFrame frame) {

final Frame caller = Truffle.getRuntime().getCallerFrame().getFrame(FrameInstance.FrameAccess.READ_WRITE, false);

final ThreadManager threadManager = context.getThreadManager();
final String line;

final String line = getContext().outsideGlobalLock(new Supplier<String>() {
final RubyThread runningThread = getContext().getThreadManager().leaveGlobalLock();

@Override
public String get() {
try {
return gets(context);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
try {
line = gets(context);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
getContext().getThreadManager().enterGlobalLock(runningThread);
}

final RubyString rubyLine = context.makeString(line);

@@ -1073,10 +1072,9 @@ public boolean isA(@SuppressWarnings("unused") RubyBasicObject self, @SuppressWa
return false;
}

@SlowPath
@Specialization
public boolean isA(Object self, RubyClass rubyClass) {
notDesignedForCompilation();

// TODO(CS): fast path
return ModuleOperations.assignableTo(getContext().getCoreLibrary().box(self).getLogicalClass(), rubyClass);
}
@@ -1250,23 +1248,28 @@ public PrintNode(PrintNode prev) {

@Specialization
public RubyNilClass print(final VirtualFrame frame, final Object[] args) {
getContext().outsideGlobalLock(new Runnable() {

@Override
public void run() {
for (Object arg : args) {
try {
getContext().getRuntime().getInstanceConfig().getOutput().write(((RubyString) toS.call(frame, arg, "to_s", null)).getBytes().bytes());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
final RubyThread runningThread = getContext().getThreadManager().leaveGlobalLock();

});
try {
for (Object arg : args) {
write(((RubyString) toS.call(frame, arg, "to_s", null)).getBytes().bytes());
}
} finally {
getContext().getThreadManager().enterGlobalLock(runningThread);
}

return getContext().getCoreLibrary().getNilObject();
}

@SlowPath
private void write(byte[] bytes) {
try{
getContext().getRuntime().getInstanceConfig().getOutput().write(bytes);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

}

@CoreMethod(names = "printf", isModuleFunction = true, argumentsAsArray = true)
@@ -1288,14 +1291,13 @@ public RubyNilClass printf(Object[] args) {
final String format = args[0].toString();
final List<Object> values = Arrays.asList(args).subList(1, args.length);

getContext().outsideGlobalLock(new Runnable() {

@Override
public void run() {
StringFormatter.format(getContext().getRuntime().getInstanceConfig().getOutput(), format, values);
}
final RubyThread runningThread = getContext().getThreadManager().leaveGlobalLock();

});
try {
StringFormatter.format(getContext().getRuntime().getInstanceConfig().getOutput(), format, values);
} finally {
getContext().getThreadManager().enterGlobalLock(runningThread);
}
}

return getContext().getCoreLibrary().getNilObject();
@@ -1724,24 +1726,23 @@ public double sleep(double duration) {

@SlowPath
private double doSleep(final double duration) {
return getContext().outsideGlobalLock(new Supplier<Double>() {
final RubyThread runningThread = getContext().getThreadManager().leaveGlobalLock();

@Override
public Double get() {
final long start = System.nanoTime();

try {
Thread.sleep((long) (duration * 1000));
} catch (InterruptedException e) {
// Ignore interruption
}

final long end = System.nanoTime();
try {
final long start = System.nanoTime();

return (end - start) / 1e9;
try {
Thread.sleep((long) (duration * 1000));
} catch (InterruptedException e) {
// Ignore interruption
}

});
final long end = System.nanoTime();

return (end - start) / 1e9;
} finally {
getContext().getThreadManager().enterGlobalLock(runningThread);
}
}

}
@@ -91,17 +91,15 @@ public boolean equal(@SuppressWarnings("unused") RubyString a, @SuppressWarnings
return false;
}

@CompilerDirectives.SlowPath
@Specialization
public boolean equal(RubyString a, RubyString b) {
notDesignedForCompilation();

return a.equals(b.toString());
}

@CompilerDirectives.SlowPath
@Specialization
public boolean equal(RubyString a, RubySymbol b) {
notDesignedForCompilation();

return equal(a, b.toRubyString());
}
}
@@ -9,10 +9,8 @@
*/
package org.jruby.truffle.nodes.core;

import com.oracle.truffle.api.*;
import com.oracle.truffle.api.source.*;
import com.oracle.truffle.api.dsl.*;
import org.jruby.*;
import org.jruby.RubyThread.Status;
import org.jruby.truffle.runtime.*;
import org.jruby.truffle.runtime.control.RaiseException;
@@ -154,12 +152,13 @@ public PassNode(PassNode prev) {

@Specialization
public RubyNilClass pass() {
getContext().outsideGlobalLock(new Runnable() {
@Override
public void run() {
Thread.yield();
}
});
final RubyThread runningThread = getContext().getThreadManager().leaveGlobalLock();

try {
Thread.yield();
} finally {
getContext().getThreadManager().enterGlobalLock(runningThread);
}

return getContext().getCoreLibrary().getNilObject();
}
@@ -10,11 +10,9 @@
package org.jruby.truffle.runtime;

import java.io.*;
import java.math.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Queue;
import java.util.concurrent.atomic.*;

@@ -38,12 +36,11 @@
import org.jruby.truffle.runtime.core.RubyModule;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.runtime.core.RubySymbol;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyThread;
import org.jruby.truffle.runtime.subsystems.*;
import org.jruby.truffle.runtime.util.Supplier;
import org.jruby.truffle.translator.TranslatorDriver;
import org.jruby.util.ByteList;
import org.jruby.util.cli.Options;

/**
* The global state of a running Ruby system.
@@ -331,14 +328,6 @@ public ThreadManager getThreadManager() {
return threadManager;
}

public void outsideGlobalLock(Runnable runnable) {
threadManager.outsideGlobalLock(runnable);
}

public <T> T outsideGlobalLock(Supplier<T> supplier) {
return threadManager.outsideGlobalLock(supplier);
}

public TranslatorDriver getTranslator() {
return translator;
}
@@ -9,18 +9,15 @@
*/
package org.jruby.truffle.runtime.core;

import java.util.*;
import java.util.concurrent.*;

import org.jruby.*;
import org.jruby.RubyThread.Status;
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.control.ThreadExitException;
import org.jruby.truffle.runtime.subsystems.*;
import org.jruby.util.ByteList;

/**
* Represents the Ruby {@code Thread} class. Implemented using Java threads, but note that there is
@@ -118,21 +115,20 @@ public void run() {
}

public void join() {
getContext().outsideGlobalLock(new Runnable() {
final RubyThread runningThread = getContext().getThreadManager().leaveGlobalLock();

@Override
public void run() {
while (true) {
try {
finished.await();
break;
} catch (InterruptedException e) {
// Await again
}
try {
while (true) {
try {
finished.await();
break;
} catch (InterruptedException e) {
// Await again
}
}

});
} finally {
getContext().getThreadManager().enterGlobalLock(runningThread);
}

if (exception != null) {
throw new RaiseException(exception);
@@ -15,6 +15,7 @@
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.nodes.InvalidAssumptionException;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyThread;
import org.jruby.truffle.runtime.util.Consumer;

import java.util.concurrent.BrokenBarrierException;
@@ -100,20 +101,21 @@ public void pauseAllThreadsAndExecute(final Consumer<Boolean> action) {
}

private void waitOnBarrier() {
context.outsideGlobalLock(new Runnable() {
@Override
public void run() {
while (true) {
try {
barrier.await();
break;
} catch (BrokenBarrierException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
}
final RubyThread runningThread = context.getThreadManager().leaveGlobalLock();

try {
while (true) {
try {
barrier.await();
break;
} catch (BrokenBarrierException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
}
}
});
} finally {
context.getThreadManager().enterGlobalLock(runningThread);
}
}

}

0 comments on commit 6793854

Please sign in to comment.