Skip to content

Commit

Permalink
Showing 7 changed files with 72 additions and 58 deletions.
9 changes: 9 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/nodes/RubyGuards.java
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@
import org.jruby.truffle.nodes.core.*;
import org.jruby.truffle.nodes.core.hash.HashNodes;
import org.jruby.truffle.nodes.ext.BigDecimalNodes;
import org.jruby.truffle.nodes.rubinius.ByteArrayNodes;
import org.jruby.truffle.nodes.rubinius.PointerNodes;
import org.jruby.truffle.runtime.NotProvided;
import org.jruby.truffle.runtime.ThreadLocalObject;
@@ -145,6 +146,14 @@ public static boolean isRubyPointer(RubyBasicObject value) {
return value.getDynamicObject().getShape().getObjectType() == PointerNodes.POINTER_TYPE;
}

public static boolean isRubiniusByteArray(Object value) {
return (value instanceof RubyBasicObject) && isRubiniusByteArray((RubyBasicObject) value);
}

public static boolean isRubiniusByteArray(RubyBasicObject value) {
return value.getDynamicObject().getShape().getObjectType() == ByteArrayNodes.BYTE_ARRAY_TYPE;
}

// Internal types

public static boolean isThreadLocal(Object value) {
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
import com.oracle.truffle.api.utilities.BranchProfile;
import com.oracle.truffle.api.utilities.ConditionProfile;
import org.jcodings.specific.USASCIIEncoding;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.cast.BooleanCastNode;
import org.jruby.truffle.nodes.cast.BooleanCastNodeGen;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
@@ -61,6 +62,7 @@ public static RubyBasicObject createRubyBignum(RubyClass rubyClass, BigInteger v
}

public static BigInteger getBigIntegerValue(RubyBasicObject bignum) {
assert RubyGuards.isRubyBignum(bignum);
assert bignum.getDynamicObject().getShape().hasProperty(VALUE_IDENTIFIER);
return (BigInteger) VALUE_PROPERTY.get(bignum.getDynamicObject(), true);
}
Original file line number Diff line number Diff line change
@@ -58,14 +58,14 @@
import org.jruby.truffle.nodes.objects.Allocator;
import org.jruby.truffle.nodes.objects.IsFrozenNode;
import org.jruby.truffle.nodes.objects.IsFrozenNodeGen;
import org.jruby.truffle.nodes.rubinius.ByteArrayNodes;
import org.jruby.truffle.nodes.rubinius.StringPrimitiveNodes;
import org.jruby.truffle.nodes.rubinius.StringPrimitiveNodesFactory;
import org.jruby.truffle.runtime.NotProvided;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.object.BasicObjectType;
import org.jruby.truffle.runtime.rubinius.RubiniusByteArray;
import org.jruby.util.*;
import org.jruby.util.io.EncodingUtils;

@@ -1022,8 +1022,8 @@ public DataNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public RubiniusByteArray data(RubyString string) {
return new RubiniusByteArray(getContext().getCoreLibrary().getByteArrayClass(), getByteList(string));
public RubyBasicObject data(RubyString string) {
return ByteArrayNodes.createByteArray(getContext().getCoreLibrary().getByteArrayClass(), getByteList(string));
}
}

Original file line number Diff line number Diff line change
@@ -11,20 +11,54 @@

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.object.*;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.core.CoreClass;
import org.jruby.truffle.nodes.core.CoreMethod;
import org.jruby.truffle.nodes.core.CoreMethodArrayArgumentsNode;
import org.jruby.truffle.nodes.core.StringNodes;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.core.RubyClass;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.runtime.rubinius.RubiniusByteArray;
import org.jruby.truffle.runtime.object.BasicObjectType;
import org.jruby.util.ByteList;

import java.math.BigInteger;
import java.util.EnumSet;

@CoreClass(name = "Rubinius::ByteArray")
public abstract class ByteArrayNodes {

public static class ByteArrayType extends BasicObjectType {

}

public static final ByteArrayType BYTE_ARRAY_TYPE = new ByteArrayType();

private static final HiddenKey BYTES_IDENTIFIER = new HiddenKey("bytes");
public static final Property BYTES_PROPERTY;
private static final DynamicObjectFactory BYTE_ARRAY_FACTORY;

static {
final Shape.Allocator allocator = RubyBasicObject.LAYOUT.createAllocator();
BYTES_PROPERTY = Property.create(BYTES_IDENTIFIER, allocator.locationForType(ByteList.class, EnumSet.of(LocationModifier.Final, LocationModifier.NonNull)), 0);
final Shape shape = RubyBasicObject.LAYOUT.createShape(BYTE_ARRAY_TYPE).addProperty(BYTES_PROPERTY);
BYTE_ARRAY_FACTORY = shape.createFactory();
}

public static RubyBasicObject createByteArray(RubyClass rubyClass, ByteList bytes) {
return new RubyBasicObject(rubyClass, BYTE_ARRAY_FACTORY.newInstance(bytes));
}

public static ByteList getBytes(RubyBasicObject byteArray) {
assert RubyGuards.isRubiniusByteArray(byteArray);
assert byteArray.getDynamicObject().getShape().hasProperty(BYTES_IDENTIFIER);
return (ByteList) BYTES_PROPERTY.get(byteArray.getDynamicObject(), true);
}

@CoreMethod(names = "get_byte", required = 1, lowerFixnumParameters = 0)
public abstract static class GetByteNode extends CoreMethodArrayArgumentsNode {

@@ -33,8 +67,8 @@ public GetByteNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public int getByte(RubiniusByteArray bytes, int index) {
return bytes.getBytes().get(index);
public int getByte(RubyBasicObject bytes, int index) {
return getBytes(bytes).get(index);
}

}
@@ -47,14 +81,14 @@ public PrependNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public RubiniusByteArray prepend(RubiniusByteArray bytes, RubyString string) {
public RubyBasicObject prepend(RubyBasicObject bytes, RubyString string) {
final int prependLength = StringNodes.getByteList(string).getUnsafeBytes().length;
final int originalLength = bytes.getBytes().getUnsafeBytes().length;
final int originalLength = getBytes(bytes).getUnsafeBytes().length;
final int newLength = prependLength + originalLength;
final byte[] prependedBytes = new byte[newLength];
System.arraycopy(StringNodes.getByteList(string).getUnsafeBytes(), 0, prependedBytes, 0, prependLength);
System.arraycopy(bytes.getBytes().getUnsafeBytes(), 0, prependedBytes, prependLength, originalLength);
return new RubiniusByteArray(getContext().getCoreLibrary().getByteArrayClass(), new ByteList(prependedBytes));
System.arraycopy(getBytes(bytes).getUnsafeBytes(), 0, prependedBytes, prependLength, originalLength);
return ByteArrayNodes.createByteArray(getContext().getCoreLibrary().getByteArrayClass(), new ByteList(prependedBytes));
}

}
@@ -67,14 +101,14 @@ public SetByteNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public Object setByte(RubiniusByteArray bytes, int index, int value) {
if (index < 0 || index >= bytes.getBytes().getRealSize()) {
public Object setByte(RubyBasicObject bytes, int index, int value) {
if (index < 0 || index >= getBytes(bytes).getRealSize()) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().indexError("index out of bounds", this));
}

bytes.getBytes().set(index, value);
return bytes.getBytes().get(index);
getBytes(bytes).set(index, value);
return getBytes(bytes).get(index);
}

}
@@ -87,8 +121,8 @@ public SizeNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public int size(RubiniusByteArray bytes) {
return bytes.getBytes().getRealSize();
public int size(RubyBasicObject bytes) {
return getBytes(bytes).getRealSize();
}

}
@@ -101,8 +135,8 @@ public LocateNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public Object getByte(RubiniusByteArray bytes, RubyString pattern, int start, int length) {
final int index = new ByteList(bytes.getBytes().unsafeBytes(), start, length)
public Object getByte(RubyBasicObject bytes, RubyString pattern, int start, int length) {
final int index = new ByteList(getBytes(bytes).unsafeBytes(), start, length)
.indexOf(StringNodes.getByteList(pattern));

if (index == -1) {
Original file line number Diff line number Diff line change
@@ -50,7 +50,6 @@
import org.jruby.truffle.runtime.core.RubyClass;
import org.jruby.truffle.runtime.core.RubyException;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.runtime.rubinius.RubiniusByteArray;
import org.jruby.util.ByteList;

import java.util.EnumSet;
@@ -81,7 +80,7 @@ public abstract class IOBufferPrimitiveNodes {
final Shape.Allocator allocator = RubyBasicObject.LAYOUT.createAllocator();

WRITE_SYNCED_PROPERTY = Property.create(WRITE_SYNCED_IDENTIFIER, allocator.locationForType(Boolean.class, EnumSet.of(LocationModifier.NonNull)), 0);
STORAGE_PROPERTY = Property.create(STORAGE_IDENTIFIER, allocator.locationForType(RubiniusByteArray.class, EnumSet.of(LocationModifier.NonNull)), 0);
STORAGE_PROPERTY = Property.create(STORAGE_IDENTIFIER, allocator.locationForType(RubyBasicObject.class, EnumSet.of(LocationModifier.NonNull)), 0);
USED_PROPERTY = Property.create(USED_IDENTIFIER, allocator.locationForType(Integer.class, EnumSet.of(LocationModifier.NonNull)), 0);
START_PROPERTY = Property.create(START_IDENTIFIER, allocator.locationForType(Integer.class, EnumSet.of(LocationModifier.NonNull)), 0);
TOTAL_PROPERTY = Property.create(TOTAL_IDENTIFIER, allocator.locationForType(Integer.class, EnumSet.of(LocationModifier.NonNull)), 0);
@@ -105,9 +104,9 @@ public static void setWriteSynced(RubyBasicObject io, boolean writeSynced) {
}
}

private static RubiniusByteArray getStorage(RubyBasicObject io) {
private static RubyBasicObject getStorage(RubyBasicObject io) {
assert io.getDynamicObject().getShape().hasProperty(STORAGE_IDENTIFIER);
return (RubiniusByteArray) STORAGE_PROPERTY.get(io.getDynamicObject(), true);
return (RubyBasicObject) STORAGE_PROPERTY.get(io.getDynamicObject(), true);
}

private static int getUsed(RubyBasicObject io) {
@@ -141,7 +140,7 @@ public IOBufferAllocatePrimitiveNode(RubyContext context, SourceSection sourceSe
public RubyBasicObject allocate(VirtualFrame frame, RubyClass classToAllocate) {
return new RubyBasicObject(classToAllocate, IO_BUFFER_FACTORY.newInstance(
true,
new RubiniusByteArray(getContext().getCoreLibrary().getByteArrayClass(), new ByteList(IOBUFFER_SIZE)),
ByteArrayNodes.createByteArray(getContext().getCoreLibrary().getByteArrayClass(), new ByteList(IOBUFFER_SIZE)),
0,
0,
IOBUFFER_SIZE));
@@ -168,7 +167,7 @@ public int unshift(VirtualFrame frame, RubyBasicObject ioBuffer, RubyString stri
stringSize = availableSpace;
}

ByteList storage = getStorage(ioBuffer).getBytes();
ByteList storage = ByteArrayNodes.getBytes(getStorage(ioBuffer));

// Data is copied here - can we do something COW?
System.arraycopy(StringNodes.getByteList(string).unsafeBytes(), startPosition, storage.getUnsafeBytes(), usedSpace, stringSize);
@@ -234,7 +233,7 @@ public int fill(VirtualFrame frame, RubyBasicObject ioBuffer, RubyBasicObject io
throw new RaiseException(getContext().getCoreLibrary().internalError("IO buffer overrun", this));
}
final int used = getUsed(ioBuffer);
final ByteList storage = getStorage(ioBuffer).getBytes();
final ByteList storage = ByteArrayNodes.getBytes(getStorage(ioBuffer));
System.arraycopy(readBuffer, 0, storage.getUnsafeBytes(), storage.getBegin() + used, bytesRead);
storage.setRealSize(used + bytesRead);
setUsed(ioBuffer, used + bytesRead);
Original file line number Diff line number Diff line change
@@ -74,7 +74,6 @@
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.rubinius.RubiniusByteArray;
import org.jruby.util.ByteList;
import org.jruby.util.ConvertBytes;
import org.jruby.util.StringSupport;
@@ -1269,10 +1268,10 @@ public StringFromByteArrayPrimitiveNode(RubyContext context, SourceSection sourc
super(context, sourceSection);
}

@Specialization
public RubyBasicObject stringFromByteArray(RubiniusByteArray bytes, int start, int count) {
@Specialization(guards = "isRubiniusByteArray(bytes)")
public RubyBasicObject stringFromByteArray(RubyBasicObject bytes, int start, int count) {
// Data is copied here - can we do something COW?
return createString(Arrays.copyOfRange(bytes.getBytes().unsafeBytes(), bytes.getBytes().begin() + start, bytes.getBytes().begin() + start + count));
return createString(Arrays.copyOfRange(ByteArrayNodes.getBytes(bytes).unsafeBytes(), ByteArrayNodes.getBytes(bytes).begin() + start, ByteArrayNodes.getBytes(bytes).begin() + start + count));
}

}

This file was deleted.

0 comments on commit 2cd436d

Please sign in to comment.