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: 8c5a24d02cb5
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 39a810dccb56
Choose a head ref
  • 12 commits
  • 17 files changed
  • 1 contributor

Commits on Feb 20, 2015

  1. [Truffle] Fix ruby warning.

    eregon committed Feb 20, 2015
    Copy the full SHA
    7a3930d View commit details
  2. Copy the full SHA
    5350a54 View commit details
  3. Copy the full SHA
    629410e View commit details
  4. [Truffle] Add missing TruffleBoundary for the SymbolTable!

    * Also, only give a view for listing the values.
    eregon committed Feb 20, 2015
    Copy the full SHA
    e3e71a4 View commit details
  5. Copy the full SHA
    5160480 View commit details
  6. Copy the full SHA
    c924fb9 View commit details
  7. Copy the full SHA
    073b933 View commit details
  8. Copy the full SHA
    7149ae2 View commit details
  9. Copy the full SHA
    c6e566d View commit details
  10. Copy the full SHA
    7fa2de7 View commit details
  11. Copy the full SHA
    2b508b1 View commit details
  12. [Truffle] Use an explicit lock in SafepointManager.

    * We need to handle the case when multiple threads are calling pauseAllThreadsAndExecute().
    * Allows to check for reentrency.
    eregon committed Feb 20, 2015
    Copy the full SHA
    39a810d View commit details
3 changes: 3 additions & 0 deletions spec/truffle/tags/core/encoding/default_internal_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
windows:Encoding.default_internal with command line options returns Encoding::UTF_8 if ruby was invoked with -U
windows:Encoding.default_internal with command line options uses the encoding specified when ruby is invoked with an '-E :internal' argument
windows:Encoding.default_internal with command line options uses the encoding specified when ruby is invoked with an '-E external:internal' argument
slow:Encoding.default_internal with command line options returns Encoding::UTF_8 if ruby was invoked with -U
slow:Encoding.default_internal with command line options uses the encoding specified when ruby is invoked with an '-E :internal' argument
slow:Encoding.default_internal with command line options uses the encoding specified when ruby is invoked with an '-E external:internal' argument
3 changes: 3 additions & 0 deletions spec/truffle/tags/core/signal/trap_tags.txt
Original file line number Diff line number Diff line change
@@ -16,3 +16,6 @@ windows:Signal.trap accepts 'DEFAULT' in place of a proc
windows:Signal.trap accepts 'SIG_IGN' in place of a proc
windows:Signal.trap accepts 'IGNORE' in place of a proc
windows:Signal.trap the special EXIT signal code can unset the handler
slow:Signal.trap the special EXIT signal code accepts the EXIT code
slow:Signal.trap the special EXIT signal code runs the proc before at_exit handlers
slow:Signal.trap the special EXIT signal code can unset the handler
Original file line number Diff line number Diff line change
@@ -754,6 +754,7 @@ public ToSNode(ToSNode prev) {
super(prev);
}

@TruffleBoundary
@Specialization
public RubyString toS(RubyBignum value) {
return getContext().makeString(value.bigIntegerValue().toString());
Original file line number Diff line number Diff line change
@@ -232,7 +232,6 @@ public RubyString concat(RubyString string, RubyString other) {
} catch (org.jruby.exceptions.RaiseException e) {
if (e.getException().getMetaClass().equals(getContext().getRuntime().getEncodingCompatibilityError())) {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(getContext().getCoreLibrary().encodingCompatibilityError(e.getException().message.asJavaString(), this));
}

@@ -950,6 +949,7 @@ public InspectNode(InspectNode prev) {
super(prev);
}

@TruffleBoundary
@Specialization
public RubyString inspect(RubyString string) {
notDesignedForCompilation();
Original file line number Diff line number Diff line change
@@ -107,7 +107,7 @@ public RubyArray allSymbols() {

final RubyArray array = new RubyArray(getContext().getCoreLibrary().getArrayClass());

for (RubySymbol s : getContext().getSymbolTable().getSymbolsTable().values()){
for (RubySymbol s : getContext().getSymbolTable().allSymbols()) {
array.slowPush(s);
}
return array;
Original file line number Diff line number Diff line change
@@ -38,8 +38,7 @@ public Object execute(VirtualFrame frame) {

final Object rhsValue = rhs.execute(frame);

moduleObject.checkFrozen(this);
ModuleOperations.setClassVariable(moduleObject, name, rhsValue);
ModuleOperations.setClassVariable(moduleObject, name, rhsValue, this);

return rhsValue;
}
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@
*/
public class RubiniusPrimitiveManager {

private final Map<String, RubiniusPrimitiveConstructor> primitives;
private final Map<String, RubiniusPrimitiveConstructor> primitives; // Initialized once by create().

private RubiniusPrimitiveManager(Map<String, RubiniusPrimitiveConstructor> primitives) {
this.primitives = primitives;
Original file line number Diff line number Diff line change
@@ -248,28 +248,28 @@ public static Object lookupClassVariable(RubyModule module, String name) {
}

@TruffleBoundary
public static void setClassVariable(RubyModule module, String name, Object value) {
public static void setClassVariable(RubyModule module, String name, Object value, RubyNode currentNode) {
CompilerAsserts.neverPartOfCompilation();

// Look in the current module

if (module.getClassVariables().containsKey(name)) {
module.getClassVariables().put(name, value);
module.setClassVariable(currentNode, name, value);
return;
}

// Look in ancestors

for (RubyModule ancestor : module.parentAncestors()) {
if (ancestor.getClassVariables().containsKey(name)) {
ancestor.getClassVariables().put(name, value);
ancestor.setClassVariable(currentNode, name, value);
return;
}
}

// Not existing class variable - set in the current module

module.getClassVariables().put(name, value);
module.setClassVariable(currentNode, name, value);
}

}
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@
*/
public class RubyEncoding extends RubyBasicObject {

// Both are mutated only in CoreLibrary.initializeEncodingConstants().
private static RubyEncoding[] encodingList = new RubyEncoding[EncodingDB.getEncodings().size()];
private static Map<String, RubyEncoding> lookup = new HashMap<>();

Original file line number Diff line number Diff line change
@@ -215,13 +215,13 @@ private void setConstantInternal(RubyNode currentNode, String name, Object value

checkFrozen(currentNode);

RubyConstant previous = getConstants().get(name);
RubyConstant previous = constants.get(name);
if (previous == null) {
getConstants().put(name, new RubyConstant(this, value, false, autoload));
constants.put(name, new RubyConstant(this, value, false, autoload));
} else {
// TODO(CS): warn when redefining a constant
// TODO (nirvdrum 18-Feb-15): But don't warn when redefining an autoloaded constant.
getConstants().put(name, new RubyConstant(this, value, previous.isPrivate(), autoload));
constants.put(name, new RubyConstant(this, value, previous.isPrivate(), autoload));
}

newLexicalVersion();
@@ -232,11 +232,20 @@ public RubyConstant removeConstant(RubyNode currentNode, String name) {
RubyNode.notDesignedForCompilation();

checkFrozen(currentNode);
RubyConstant oldConstant = getConstants().remove(name);
RubyConstant oldConstant = constants.remove(name);
newLexicalVersion();
return oldConstant;
}

@TruffleBoundary
public void setClassVariable(RubyNode currentNode, String variableName, Object value) {
RubyNode.notDesignedForCompilation();

checkFrozen(currentNode);

classVariables.put(variableName, value);
}

@TruffleBoundary
public void removeClassVariable(RubyNode currentNode, String variableName) {
RubyNode.notDesignedForCompilation();
@@ -251,10 +260,9 @@ public void addMethod(RubyNode currentNode, InternalMethod method) {
RubyNode.notDesignedForCompilation();

assert method != null;
assert getMethods() != null;

checkFrozen(currentNode);
getMethods().put(method.getName(), method.withDeclaringModule(this));
methods.put(method.getName(), method.withDeclaringModule(this));
newVersion();
}

@@ -264,7 +272,7 @@ public void removeMethod(RubyNode currentNode, String methodName) {

checkFrozen(currentNode);

getMethods().remove(methodName);
methods.remove(methodName);
newVersion();
}

Original file line number Diff line number Diff line change
@@ -10,10 +10,11 @@
package org.jruby.truffle.runtime.core;

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.frame.FrameDescriptor;
import com.oracle.truffle.api.source.SourceSection;

import org.jcodings.Encoding;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.RubyRootNode;
@@ -25,6 +26,7 @@
import org.jruby.util.CodeRangeable;
import org.jruby.util.StringSupport;

import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;

/**
@@ -107,7 +109,7 @@ public int getCodeRange() {
}

@Override
@CompilerDirectives.TruffleBoundary
@TruffleBoundary
public int scanForCodeRange() {
int cr = getCodeRange();

@@ -155,7 +157,7 @@ public ByteList getByteList() {
return bytes;
}

@CompilerDirectives.TruffleBoundary
@TruffleBoundary
private int slowCodeRangeScan() {
return StringSupport.codeRangeScan(bytes.getEncoding(), bytes);
}
@@ -169,45 +171,40 @@ public SymbolTable(RubyContext context) {
this.context = context;
}

@TruffleBoundary
public RubySymbol getSymbol(String name) {
ByteList byteList = org.jruby.RubySymbol.symbolBytesFromString(context.getRuntime(), name);

RubySymbol symbol = symbolsTable.get(byteList);

if (symbol == null) {
symbol = createSymbol(name);
symbol = createSymbol(name, byteList);
}
return symbol;
}

@TruffleBoundary
public RubySymbol getSymbol(ByteList byteList) {
// TODO(CS): is this broken? ByteList is mutable...

RubySymbol symbol = symbolsTable.get(byteList);

if (symbol == null) {
symbol = createSymbol(byteList);
symbol = createSymbol(byteList.toString(), byteList);
}
return symbol;

}

private RubySymbol createSymbol(ByteList byteList) {
RubySymbol symbol = new RubySymbol(context.getCoreLibrary().getSymbolClass(), byteList.toString(), byteList);
symbolsTable.put(byteList, symbol);
return symbol;
}

private RubySymbol createSymbol(String name) {
ByteList byteList = org.jruby.RubySymbol.symbolBytesFromString(context.getRuntime(), name);
private RubySymbol createSymbol(String name, ByteList byteList) {
RubySymbol symbol = new RubySymbol(context.getCoreLibrary().getSymbolClass(), name, byteList);

RubySymbol existingSymbol = symbolsTable.putIfAbsent(byteList, symbol);
return existingSymbol == null ? symbol : existingSymbol;
}

public ConcurrentHashMap<ByteList, RubySymbol> getSymbolsTable(){
return symbolsTable;
@TruffleBoundary
public Collection<RubySymbol> allSymbols() {
return symbolsTable.values();
}
}

Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ public class RubyThread extends RubyBasicObject {

private final RubyBasicObject threadLocals;

private final List<Lock> ownedLocks = new ArrayList<Lock>();
private final List<Lock> ownedLocks = new ArrayList<Lock>(); // Always accessed by the same underlying Java thread.

public RubyThread(RubyClass rubyClass, ThreadManager manager) {
super(rubyClass);
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@

import org.jruby.truffle.runtime.core.RubyProc;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;

@@ -20,13 +20,13 @@
*/
public class AtExitManager {

private final List<RubyProc> blocks = new ArrayList<>();
private final List<RubyProc> blocks = new LinkedList<>();

public void add(RubyProc block) {
public synchronized void add(RubyProc block) {
blocks.add(block);
}

public void run() {
public synchronized void run() {
final ListIterator<RubyProc> iterator = blocks.listIterator(blocks.size());

while (iterator.hasPrevious()) {
Original file line number Diff line number Diff line change
@@ -73,7 +73,7 @@ public ObjectSpaceManager(RubyContext context) {
this.context = context;
}

public void defineFinalizer(RubyBasicObject object, RubyProc proc) {
public synchronized void defineFinalizer(RubyBasicObject object, RubyProc proc) {
RubyNode.notDesignedForCompilation();

// Record the finalizer against the object
@@ -102,7 +102,7 @@ public void run() {
}
}

public void undefineFinalizer(RubyBasicObject object) {
public synchronized void undefineFinalizer(RubyBasicObject object) {
RubyNode.notDesignedForCompilation();

final FinalizerReference finalizerReference = finalizerReferences.get(object);
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Phaser;
import java.util.concurrent.locks.ReentrantLock;

public class SafepointManager {

@@ -32,6 +33,7 @@ public class SafepointManager {
private final Set<Thread> runningThreads = Collections.newSetFromMap(new ConcurrentHashMap<Thread, Boolean>());

@CompilerDirectives.CompilationFinal private Assumption assumption = Truffle.getRuntime().createAssumption();
private final ReentrantLock lock = new ReentrantLock();
private final Phaser phaser = new Phaser();
private volatile Consumer<RubyThread> action;

@@ -41,11 +43,16 @@ public SafepointManager(RubyContext context) {
enterThread();
}

public synchronized void enterThread() {
public void enterThread() {
CompilerAsserts.neverPartOfCompilation();

phaser.register();
runningThreads.add(Thread.currentThread());
lock.lock();
try {
phaser.register();
runningThreads.add(Thread.currentThread());
} finally {
lock.unlock();
}
}

public void leaveThread() {
@@ -117,19 +124,36 @@ public void pauseAllThreadsAndExecuteFromNonRubyThread(Consumer<RubyThread> acti
}
}

private synchronized void pauseAllThreadsAndExecute(boolean holdsGlobalLock, Consumer<RubyThread> action) {
private void pauseAllThreadsAndExecute(boolean holdsGlobalLock, Consumer<RubyThread> action) {
CompilerDirectives.transferToInterpreter();

this.action = action;
if (lock.isHeldByCurrentThread()) {
throw new IllegalStateException("Re-entered SafepointManager");
}

/* this is a potential cause for race conditions,
* but we need to invalidate first so the interrupted threads
* see the invalidation in poll() in their catch(InterruptedException) clause
* and wait on the barrier instead of retrying their blocking action. */
assumption.invalidate();
interruptAllThreads();
while (true) {
try {
lock.lockInterruptibly();
break;
} catch (InterruptedException e) {
poll(holdsGlobalLock);
}
}

assumptionInvalidated(holdsGlobalLock, true);
try {
this.action = action;

/* this is a potential cause for race conditions,
* but we need to invalidate first so the interrupted threads
* see the invalidation in poll() in their catch(InterruptedException) clause
* and wait on the barrier instead of retrying their blocking action. */
assumption.invalidate();
interruptAllThreads();

assumptionInvalidated(holdsGlobalLock, true);
} finally {
lock.unlock();
}
}

private void interruptAllThreads() {
Loading