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

Commits on Apr 7, 2016

  1. Copy the full SHA
    8e400ca View commit details
  2. Copy the full SHA
    69e2c8f View commit details
  3. Copy the full SHA
    431b26e View commit details
  4. Copy the full SHA
    9bfdab4 View commit details
  5. Copy the full SHA
    e8417fe View commit details
  6. Copy the full SHA
    4e400ad View commit details
  7. Copy the full SHA
    8714775 View commit details
  8. Copy the full SHA
    87d314a View commit details
  9. Copy the full SHA
    af2a342 View commit details
39 changes: 39 additions & 0 deletions spec/truffle/specs/truffle/digest.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
# code is released under a tri EPL/GPL/LGPL license. You can use it,
# redistribute it and/or modify it under the terms of the:
#
# Eclipse Public License version 1.0
# GNU General Public License version 2
# GNU Lesser General Public License version 2.1

require_relative '../../../ruby/spec_helper'

require 'digest'

describe "digest updating" do

it "works on leaf ropes" do
Digest::MD5.hexdigest('foo').should == 'acbd18db4cc2f85cedef654fccc4a4d8'
end

it "works on concat ropes" do
Digest::MD5.hexdigest('foo' + 'bar').should == '3858f62230ac3c915f300c664312c63f'
end

it "works on substring ropes" do
Digest::MD5.hexdigest('foo'[1...-1]).should == 'd95679752134a2d9eb61dbd7b91c4bcc'
end

it "works on substring ropes that cross a concat rope" do
Digest::MD5.hexdigest(('foo' + 'bar')[2...-2]).should == '99faee4e1a331a7595932b7c18f9f5f6'
end

it "works on substring ropes that only use the left of a concat rope" do
Digest::MD5.hexdigest(('foo' + 'bar')[1...2]).should == 'd95679752134a2d9eb61dbd7b91c4bcc'
end

it "works on substring ropes that only use the right of a concat rope" do
Digest::MD5.hexdigest(('foo' + 'bar')[4...5]).should == '0cc175b9c0f1b6a831c399e269772661'
end

end
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
@@ -1381,6 +1381,14 @@ public DynamicObject internalError(String message, Node currentNode) {
return internalError(message, currentNode, null);
}

public DynamicObject internalErrorAssertConstantNotConstant(Node currentNode) {
return internalError("Value in Truffle::Primitive.assert_constant was not constant", currentNode);
}

public DynamicObject internalErrorAssertNotCompiledCompiled(Node currentNode) {
return internalError("Call to Truffle::Primitive.assert_not_compiled was compiled", currentNode);
}

public DynamicObject internalError(String message, Node currentNode, Throwable javaThrowable) {
CompilerAsserts.neverPartOfCompilation();
return ExceptionNodes.createRubyException(context.getCoreLibrary().getRubyTruffleErrorClass(), StringOperations.createString(context, StringOperations.encodeRope("internal implementation error - " + message, UTF8Encoding.INSTANCE)), context.getCallStack().getBacktrace(currentNode, javaThrowable));
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.core.rope;

public interface BytesVisitor {

void accept(byte[] bytes, int offset, int length);

}
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import org.jcodings.Encoding;
import org.jruby.util.func.Function1;

public class ConcatRope extends Rope {

@@ -55,47 +56,6 @@ public byte getByteSlow(int index) {
return right.getByteSlow(index - left.byteLength());
}

@Override
@TruffleBoundary
public byte[] extractRange(int offset, int length) {
assert length <= this.byteLength();

if (getRawBytes() != null) {
final byte[] ret = new byte[length];
System.arraycopy(getRawBytes(), offset, ret, 0, length);

return ret;
}

byte[] leftBytes;
byte[] rightBytes;
final int leftLength = left.byteLength();

if (offset < leftLength) {
// The left branch might not be large enough to extract the full byte range we want. In that case,
// we'll extract what we can and extract the difference from the right side.
if (offset + length > leftLength) {
leftBytes = left.extractRange(offset, leftLength - offset);
} else {
leftBytes = left.extractRange(offset, length);
}

if (leftBytes.length < length) {
rightBytes = right.extractRange(0, length - leftBytes.length);

final byte[] ret = new byte[length];
System.arraycopy(leftBytes, 0, ret, 0, leftBytes.length);
System.arraycopy(rightBytes, 0, ret, leftBytes.length, rightBytes.length);

return ret;
} else {
return leftBytes;
}
}

return right.extractRange(offset - leftLength, length);
}

public Rope getLeft() {
return left;
}
12 changes: 0 additions & 12 deletions truffle/src/main/java/org/jruby/truffle/core/rope/LeafRope.java
Original file line number Diff line number Diff line change
@@ -22,18 +22,6 @@ public byte getByteSlow(int index) {
return getRawBytes()[index];
}

@Override
public byte[] extractRange(int offset, int length) {
assert offset + length <= byteLength();

final int trueLength = Math.min(length, byteLength());
final byte[] ret = new byte[trueLength];

System.arraycopy(getRawBytes(), offset, ret, 0, trueLength);

return ret;
}

@Override
public String toString() {
// This should be used for debugging only.
Original file line number Diff line number Diff line change
@@ -41,11 +41,6 @@ public byte getByteSlow(int index) {
return (byte) byteList.get(index);
}

@Override
public byte[] extractRange(int offset, int length) {
return new ByteList(byteList, offset, length).bytes();
}

public ByteList getByteList() {
return byteList;
}
2 changes: 0 additions & 2 deletions truffle/src/main/java/org/jruby/truffle/core/rope/Rope.java
Original file line number Diff line number Diff line change
@@ -66,8 +66,6 @@ public byte[] getBytesCopy() {
return getBytes().clone();
}

public abstract byte[] extractRange(int offset, int length);

public final Encoding getEncoding() {
return encoding;
}
Original file line number Diff line number Diff line change
@@ -197,6 +197,48 @@ public static LeafRope flatten(Rope rope) {
return create(flattenBytes(rope), rope.getEncoding(), rope.getCodeRange());
}

public static void visitBytes(Rope rope, BytesVisitor visitor) {
visitBytes(rope, visitor, 0, rope.byteLength());
}

@TruffleBoundary
public static void visitBytes(Rope rope, BytesVisitor visitor, int offset, int length) {
if (rope instanceof LeafRope) {
visitor.accept(rope.getRawBytes(), rope.begin() + offset, length);
} else if (rope instanceof ConcatRope) {
final ConcatRope concat = (ConcatRope) rope;

assert length <= rope.byteLength();

final int leftLength = concat.getLeft().byteLength();

if (offset < leftLength) {
final int leftUsed;

if (offset + length > leftLength) {
leftUsed = leftLength - offset;
} else {
leftUsed = length;
}

visitBytes(concat.getLeft(), visitor, offset, leftUsed);

if (leftUsed < length) {
visitBytes(concat.getRight(), visitor, 0, length - leftUsed);
}
} else {
visitBytes(concat.getRight(), visitor, offset - leftLength, length);
}
} else if (rope instanceof SubstringRope) {
final SubstringRope substring = (SubstringRope) rope;

visitBytes(substring.getChild(), visitor, rope.begin() + substring.getOffset() + offset, length);
} else {
CompilerDirectives.transferToInterpreter();
throw new UnsupportedOperationException("Don't know how to visit rope of type: " + rope.getClass().getName());
}
}

/**
* Performs an iterative depth first search of the Rope tree to calculate its byte[] without needing to populate
* the byte[] for each level beneath. Every LeafRope has its byte[] populated by definition. The goal is to determine
Original file line number Diff line number Diff line change
@@ -46,21 +46,6 @@ public byte getByteSlow(int index) {
return child.getByteSlow(index + offset);
}

@Override
@TruffleBoundary
public byte[] extractRange(int offset, int length) {
assert length <= this.byteLength();

if (getRawBytes() != null) {
final byte[] ret = new byte[length];
System.arraycopy(getRawBytes(), offset, ret, 0, length);

return ret;
}

return child.extractRange(this.offset + offset, length);
}

public Rope getChild() {
return child;
}
Original file line number Diff line number Diff line change
@@ -29,13 +29,15 @@ public AssertConstantNode(RubyContext context, SourceSection sourceSection) {

@Specialization
public Object assertCompilationConstant(Object value) {
final boolean[] compilationConstant = new boolean[]{CompilerDirectives.isCompilationConstant(value)};
final boolean[] compilationConstant = new boolean[]{ CompilerDirectives.isCompilationConstant(value) };

// If we didn't cause the value to escape, the transfer would float above the isCompilationConstant

sideEffect = compilationConstant;

if (!compilationConstant[0]) {
CompilerDirectives.transferToInterpreterAndInvalidate();
throw new RaiseException(coreLibrary().internalError("Value in Truffle::Primitive.assert_constant was not constant", this));
throw new RaiseException(coreLibrary().internalErrorAssertConstantNotConstant(this));
}

return value;
Original file line number Diff line number Diff line change
@@ -28,13 +28,15 @@ public AssertNotCompiledNode(RubyContext context, SourceSection sourceSection) {

@Specialization
public DynamicObject assertNotCompiled() {
final boolean[] compiled = new boolean[]{CompilerDirectives.inCompiledCode()};
final boolean[] compiled = new boolean[]{ CompilerDirectives.inCompiledCode() };

// If we didn't cause the value to escape, the transfer would float above the isCompilationConstant

sideEffect = compiled;

if (compiled[0]) {
CompilerDirectives.transferToInterpreterAndInvalidate();
throw new RaiseException(coreLibrary().internalError("Call to Truffle::Primitive.assert_not_compiled was compiled", this));
throw new RaiseException(coreLibrary().internalErrorAssertNotCompiledCompiled(this));
}

return nil();
Original file line number Diff line number Diff line change
@@ -45,7 +45,6 @@ public class AttachmentsManager {

private final RubyContext context;
private final LineToProbesMap lineToProbesMap;
private final Map<LineLocation, List<Instrument>> attachments = new HashMap<>();

public AttachmentsManager(RubyContext context) {
this.context = context;
14 changes: 12 additions & 2 deletions truffle/src/main/java/org/jruby/truffle/stdlib/DigestNodes.java
Original file line number Diff line number Diff line change
@@ -19,7 +19,9 @@
import org.jruby.truffle.core.CoreMethod;
import org.jruby.truffle.core.CoreMethodArrayArgumentsNode;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.core.rope.BytesVisitor;
import org.jruby.truffle.core.rope.Rope;
import org.jruby.truffle.core.rope.RopeOperations;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.util.ByteList;

@@ -146,9 +148,17 @@ public UpdateNode(RubyContext context, SourceSection sourceSection) {
@TruffleBoundary
@Specialization(guards = "isRubyString(message)")
public DynamicObject update(DynamicObject digestObject, DynamicObject message) {
final Rope rope = StringOperations.rope(message);
final MessageDigest digest = DigestLayoutImpl.INSTANCE.getDigest(digestObject);

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

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

});

DigestLayoutImpl.INSTANCE.getDigest(digestObject).update(rope.getBytes(), rope.begin(), rope.byteLength());
return digestObject;
}

Loading