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: 66aefc7ab6f5
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 38e32b003ce7
Choose a head ref
  • 20 commits
  • 16 files changed
  • 1 contributor

Commits on Apr 10, 2016

  1. Copy the full SHA
    f0bfd1d View commit details
  2. Copy the full SHA
    7cd624e View commit details
  3. Copy the full SHA
    22baf57 View commit details
  4. Copy the full SHA
    3fa007b View commit details
  5. Copy the full SHA
    0e90277 View commit details
  6. Copy the full SHA
    f54781a View commit details
  7. Copy the full SHA
    7f32fac View commit details
  8. Copy the full SHA
    e9d7eb7 View commit details
  9. Copy the full SHA
    3df2fe7 View commit details
  10. Copy the full SHA
    f018fb7 View commit details
  11. Copy the full SHA
    b417633 View commit details
  12. Copy the full SHA
    ce851b1 View commit details
  13. [Truffle] Make backtrace warnings core strings, as the whole point of…

    … them is to reduce churn.
    chrisseaton committed Apr 10, 2016
    Copy the full SHA
    d382797 View commit details
  14. Copy the full SHA
    7d7dad6 View commit details
  15. 2
    Copy the full SHA
    7e7f844 View commit details
  16. 8
    Copy the full SHA
    7d82684 View commit details
  17. Copy the full SHA
    b7fe78a View commit details
  18. Copy the full SHA
    0b6169c View commit details
  19. 2
    Copy the full SHA
    d166ef9 View commit details
  20. 1
    Copy the full SHA
    38e32b0 View commit details
8 changes: 8 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/core/CoreLibrary.java
Original file line number Diff line number Diff line change
@@ -957,6 +957,10 @@ public DynamicObject argumentError(String message, Node currentNode) {
return argumentError(message, currentNode, null);
}

public DynamicObject argumentErrorProcWithoutBlock(Node currentNode) {
return argumentError("tried to create Proc object without a block", currentNode, null);
}

public DynamicObject argumentErrorTooFewArguments(Node currentNode) {
return argumentError("too few arguments", currentNode, null);
}
@@ -1416,6 +1420,10 @@ public DynamicObject threadError(String message, Node currentNode) {
return ExceptionOperations.createRubyException(threadErrorClass, StringOperations.createString(context, StringOperations.encodeRope(message, UTF8Encoding.INSTANCE)), context.getCallStack().getBacktrace(currentNode));
}

public DynamicObject threadErrorKilledThread(Node currentNode) {
return threadError("killed thread", currentNode);
}

public DynamicObject threadErrorRecursiveLocking(Node currentNode) {
return threadError("deadlock; recursive locking", currentNode);
}
Original file line number Diff line number Diff line change
@@ -40,6 +40,10 @@ public Object yield(VirtualFrame frame, DynamicObject block, Object... arguments
return dispatchNode.dispatch(frame, block, arguments);
}

public Object yieldWithModifiedBlock(VirtualFrame frame, DynamicObject block, DynamicObject modifiedBlock, Object... arguments) {
return dispatchNode.dispatchWithModifiedBlock(frame, block, modifiedBlock, arguments);
}

public boolean yieldIsTruthy(VirtualFrame frame, DynamicObject block, Object... arguments) {
return booleanCast(frame, yield(frame, block, arguments));
}
Original file line number Diff line number Diff line change
@@ -27,6 +27,7 @@
import org.jruby.truffle.core.CoreMethod;
import org.jruby.truffle.core.CoreMethodArrayArgumentsNode;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.core.rope.RopeConstants;
import org.jruby.truffle.language.NotProvided;
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.control.RaiseException;
@@ -1121,23 +1122,29 @@ public ToSNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@TruffleBoundary
@Specialization
public DynamicObject toS(int n, NotProvided base) {
return create7BitString(Integer.toString(n), USASCIIEncoding.INSTANCE);
return createString(RopeConstants.getIntegerRope(n));
}

@TruffleBoundary
@Specialization
public DynamicObject toS(long n, NotProvided base) {
if (n >= Integer.MIN_VALUE && n <= Integer.MAX_VALUE) {
return toS((int) n, base);
}

return create7BitString(Long.toString(n), USASCIIEncoding.INSTANCE);
}

@TruffleBoundary
@Specialization
public DynamicObject toS(long n, int base) {
if (base == 10) {
return toS(n, NotProvided.INSTANCE);
}

if (base < 2 || base > 36) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(coreLibrary().argumentErrorInvalidRadix(base, this));
}

Original file line number Diff line number Diff line change
@@ -16,7 +16,6 @@
import org.jruby.RubyGC;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.thread.ThreadManager;
import org.jruby.truffle.core.thread.ThreadNodes;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.language.objects.ObjectIDOperations;

@@ -93,8 +92,8 @@ public synchronized void defineFinalizer(DynamicObject object, Object callable)
if (finalizerThread == null) {
// TODO(CS): should we be running this in a real Ruby thread?

finalizerThread = ThreadNodes.createRubyThread(context, context.getCoreLibrary().getThreadClass());
ThreadNodes.initialize(finalizerThread, context, null, "finalizer", new Runnable() {
finalizerThread = ThreadManager.createRubyThread(context, context.getCoreLibrary().getThreadClass());
ThreadManager.initialize(finalizerThread, context, null, "finalizer", new Runnable() {
@Override
public void run() {
runFinalizers();
74 changes: 53 additions & 21 deletions truffle/src/main/java/org/jruby/truffle/core/proc/ProcNodes.java
Original file line number Diff line number Diff line change
@@ -27,6 +27,7 @@
import org.jruby.truffle.core.CoreMethodArrayArgumentsNode;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.core.UnaryCoreMethodNode;
import org.jruby.truffle.core.YieldingCoreMethodNode;
import org.jruby.truffle.core.binding.BindingNodes;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.truffle.language.NotProvided;
@@ -49,7 +50,6 @@ public AllocateNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@TruffleBoundary
@Specialization
public DynamicObject allocate(DynamicObject rubyClass) {
throw new RaiseException(coreLibrary().typeErrorAllocatorUndefinedFor(rubyClass, this));
@@ -68,20 +68,23 @@ public abstract static class ProcNewNode extends CoreMethodArrayArgumentsNode {

public ProcNewNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
initializeNode = DispatchHeadNodeFactory.createMethodCallOnSelf(context);
allocateObjectNode = AllocateObjectNodeGen.create(context, sourceSection, null, null);
}

public abstract DynamicObject executeProcNew(VirtualFrame frame, DynamicObject procClass, Object[] args, Object block);
public abstract DynamicObject executeProcNew(
VirtualFrame frame,
DynamicObject procClass,
Object[] args,
Object block);

@Specialization
public DynamicObject proc(VirtualFrame frame, DynamicObject procClass, Object[] args, NotProvided block) {
final Frame parentFrame = getContext().getCallStack().getCallerFrameIgnoringSend().getFrame(FrameAccess.READ_ONLY, true);
final Frame parentFrame = getContext().getCallStack().getCallerFrameIgnoringSend()
.getFrame(FrameAccess.READ_ONLY, true);

final DynamicObject parentBlock = RubyArguments.getBlock(parentFrame.getArguments());

if (parentBlock == null) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(coreLibrary().argumentError("tried to create Proc object without a block", this));
throw new RaiseException(coreLibrary().argumentErrorProcWithoutBlock(this));
}

return executeProcNew(frame, procClass, args, parentBlock);
@@ -100,7 +103,8 @@ public DynamicObject procNormal(DynamicObject procClass, Object[] args, DynamicO
@Specialization(guards = "procClass != metaClass(block)")
public DynamicObject procSpecial(VirtualFrame frame, DynamicObject procClass, Object[] args, DynamicObject block) {
// Instantiate a new instance of procClass as classes do not correspond
DynamicObject proc = allocateObjectNode.allocate(

final DynamicObject proc = getAllocateObjectNode().allocate(
procClass,
Layouts.PROC.getType(block),
Layouts.PROC.getSharedMethodInfo(block),
@@ -111,14 +115,34 @@ public DynamicObject procSpecial(VirtualFrame frame, DynamicObject procClass, Ob
Layouts.PROC.getSelf(block),
Layouts.PROC.getBlock(block),
Layouts.PROC.getFrameOnStackMarker(block));
initializeNode.call(frame, proc, "initialize", block, args);

getInitializeNode().call(frame, proc, "initialize", block, args);

return proc;
}

protected DynamicObject metaClass(DynamicObject object) {
return Layouts.BASIC_OBJECT.getMetaClass(object);
}

private AllocateObjectNode getAllocateObjectNode() {
if (allocateObjectNode == null) {
CompilerDirectives.transferToInterpreter();
allocateObjectNode = insert(AllocateObjectNodeGen.create(getContext(), null, null, null));
}

return allocateObjectNode;
}

private CallDispatchHeadNode getInitializeNode() {
if (initializeNode == null) {
CompilerDirectives.transferToInterpreter();
initializeNode = insert(DispatchHeadNodeFactory.createMethodCallOnSelf(getContext()));
}

return initializeNode;
}

}

@CoreMethod(names = { "dup", "clone" })
@@ -128,12 +152,11 @@ public abstract static class DupNode extends UnaryCoreMethodNode {

public DupNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
allocateObjectNode = AllocateObjectNodeGen.create(context, sourceSection, null, null);
}

@Specialization
public DynamicObject dup(DynamicObject proc) {
DynamicObject copy = allocateObjectNode.allocate(
final DynamicObject copy = getAllocateObjectNode().allocate(
Layouts.BASIC_OBJECT.getLogicalClass(proc),
Layouts.PROC.getType(proc),
Layouts.PROC.getSharedMethodInfo(proc),
@@ -144,9 +167,19 @@ public DynamicObject dup(DynamicObject proc) {
Layouts.PROC.getSelf(proc),
Layouts.PROC.getBlock(proc),
Layouts.PROC.getFrameOnStackMarker(proc));

return copy;
}

private AllocateObjectNode getAllocateObjectNode() {
if (allocateObjectNode == null) {
CompilerDirectives.transferToInterpreter();
allocateObjectNode = insert(AllocateObjectNodeGen.create(getContext(), null, null, null));
}

return allocateObjectNode;
}

}

@CoreMethod(names = "arity")
@@ -179,23 +212,20 @@ public DynamicObject binding(DynamicObject proc) {
}

@CoreMethod(names = {"call", "[]", "yield"}, rest = true, needsBlock = true)
public abstract static class CallNode extends CoreMethodArrayArgumentsNode {

@Child private YieldNode yieldNode;
public abstract static class CallNode extends YieldingCoreMethodNode {

public CallNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
yieldNode = new YieldNode(context);
}

@Specialization
public Object call(VirtualFrame frame, DynamicObject proc, Object[] args, NotProvided block) {
return yieldNode.dispatch(frame, proc, args);
return yield(frame, proc, args);
}

@Specialization
public Object call(VirtualFrame frame, DynamicObject proc, Object[] args, DynamicObject block) {
return yieldNode.dispatchWithModifiedBlock(frame, proc, block, args);
return yieldWithModifiedBlock(frame, proc, block, args);
}

}
@@ -225,8 +255,8 @@ public ParametersNode(RubyContext context, SourceSection sourceSection) {
@Specialization
public DynamicObject parameters(DynamicObject proc) {
final ArgumentDescriptor[] argsDesc = Layouts.PROC.getSharedMethodInfo(proc).getArgumentDescriptors();

return ArgumentDescriptorUtils.argumentDescriptorsToParameters(getContext(), argsDesc, Layouts.PROC.getType(proc) == ProcType.LAMBDA);
final boolean isLambda = Layouts.PROC.getType(proc) == ProcType.LAMBDA;
return ArgumentDescriptorUtils.argumentDescriptorsToParameters(getContext(), argsDesc, isLambda);
}

}
@@ -246,8 +276,10 @@ public Object sourceLocation(DynamicObject proc) {
if (sourceSection.getSource() == null) {
return nil();
} else {
DynamicObject file = createString(StringOperations.encodeRope(sourceSection.getSource().getName(), UTF8Encoding.INSTANCE));
Object[] objects = new Object[]{file, sourceSection.getStartLine()};
final DynamicObject file = createString(StringOperations.encodeRope(
sourceSection.getSource().getName(), UTF8Encoding.INSTANCE));

final Object[] objects = new Object[]{file, sourceSection.getStartLine()};
return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), objects, objects.length);
}
}
Original file line number Diff line number Diff line change
@@ -10,10 +10,16 @@

package org.jruby.truffle.core.rope;

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import org.jcodings.specific.ASCIIEncoding;
import org.jcodings.specific.USASCIIEncoding;
import org.jcodings.specific.UTF8Encoding;

import java.lang.ref.WeakReference;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class RopeConstants {

public static final LeafRope EMPTY_ASCII_8BIT_ROPE;
@@ -48,4 +54,26 @@ public class RopeConstants {
}
}

private static final Map<Integer, WeakReference<LeafRope>> integerRopes = new ConcurrentHashMap<>();

@TruffleBoundary
public static LeafRope getIntegerRope(int value) {
WeakReference<LeafRope> ropeReference = integerRopes.get(value);

if (ropeReference != null && ropeReference.get() != null) {
return ropeReference.get();
}

// On misses we don't care too much about racing to populate the cache

final LeafRope rope = new AsciiOnlyLeafRope(
Integer.toString(value).getBytes(StandardCharsets.UTF_8), USASCIIEncoding.INSTANCE);

ropeReference = new WeakReference<>(rope);

integerRopes.put(value, ropeReference);

return rope;
}

}
Loading