Skip to content

Commit

Permalink
Showing 28 changed files with 348 additions and 223 deletions.
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.core.RubyClass;
import org.jruby.truffle.runtime.core.RubyHash;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;

/**
* Read the rest of arguments after a certain point into an array.
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@
import org.jruby.truffle.runtime.UndefinedPlaceholder;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;

@CoreClass(name = "BasicObject")
public abstract class BasicObjectNodes {
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@
import org.jruby.truffle.runtime.methods.Arity;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.truffle.runtime.methods.SharedMethodInfo;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;

import java.util.ArrayList;
import java.util.Arrays;
Original file line number Diff line number Diff line change
@@ -17,7 +17,6 @@
import com.oracle.truffle.api.frame.*;
import com.oracle.truffle.api.nodes.DirectCallNode;
import com.oracle.truffle.api.nodes.IndirectCallNode;
import com.oracle.truffle.api.nodes.Node.Child;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;
@@ -55,7 +54,7 @@
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.truffle.runtime.subsystems.FeatureManager;
import org.jruby.truffle.runtime.subsystems.ThreadManager.BlockingActionWithoutGlobalLock;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;
import org.jruby.util.ByteList;

import java.io.BufferedReader;
Original file line number Diff line number Diff line change
@@ -14,10 +14,9 @@
import com.oracle.truffle.api.utilities.ConditionProfile;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.array.ArrayMirror;
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.util.ArrayUtils;

import java.util.Arrays;
import org.jruby.truffle.runtime.array.ArrayUtils;

@NodeChildren({
@NodeChild("array"),
@@ -32,103 +31,84 @@ public AppendOneNode(RubyContext context, SourceSection sourceSection) {

public abstract RubyArray executeAppendOne(RubyArray array, Object value);

// Append into an array with null storage
// Append into an empty array

// TODO CS 12-May-15 differentiate between null and empty but possibly having enough space

@Specialization(guards = "isNull(array)")
public RubyArray appendNull(RubyArray array, int value) {
@Specialization(guards = "isEmpty(array)")
public RubyArray appendOneEmpty(RubyArray array, int value) {
array.setStore(new int[]{value}, 1);
return array;
}

@Specialization(guards = "isNull(array)")
public RubyArray appendNull(RubyArray array, long value) {
@Specialization(guards = "isEmpty(array)")
public RubyArray appendOneEmpty(RubyArray array, long value) {
array.setStore(new long[]{value}, 1);
return array;
}

@Specialization(guards = "isNull(array)")
public RubyArray appendNull(RubyArray array, Object value) {
array.setStore(new Object[]{value}, 1);
return array;
}

// Append into empty, but non-null storage; we would be better off reusing any existing space, but don't worry for now

@Specialization(guards = {"!isNull(array)", "isEmpty(array)"})
public RubyArray appendEmpty(RubyArray array, int value) {
array.setStore(new int[]{value}, 1);
return array;
}

@Specialization(guards = {"!isNull(array)", "isEmpty(array)"})
public RubyArray appendEmpty(RubyArray array, long value) {
array.setStore(new long[]{value}, 1);
@Specialization(guards = "isEmpty(array)")
public RubyArray appendOneEmpty(RubyArray array, double value) {
array.setStore(new double[]{value}, 1);
return array;
}

@Specialization(guards ={"!isNull(array)", "isEmpty(array)"})
public RubyArray appendEmpty(RubyArray array, Object value) {
@Specialization(guards = "isEmpty(array)")
public RubyArray appendOneEmpty(RubyArray array, Object value) {
array.setStore(new Object[]{value}, 1);
return array;
}

// Append of the correct type

@Specialization(guards = "isIntegerFixnum(array)")
public RubyArray appendInteger(RubyArray array, int value,
public RubyArray appendOneSameType(RubyArray array, int value,
@Cached("createBinaryProfile()") ConditionProfile extendProfile) {
final int oldSize = array.getSize();
final int newSize = oldSize + 1;

int[] store = (int[]) array.getStore();

if (extendProfile.profile(newSize > store.length)) {
store = Arrays.copyOf(store, ArrayUtils.capacity(store.length, newSize));
}

store[oldSize] = value;
array.setStore(store, newSize);
appendOneSameTypeGeneric(array, ArrayMirror.reflect((int[]) array.getStore()), value, extendProfile);
return array;
}

@Specialization(guards = "isLongFixnum(array)")
public RubyArray appendLong(RubyArray array, long value,
public RubyArray appendOneSameType(RubyArray array, long value,
@Cached("createBinaryProfile()") ConditionProfile extendProfile) {
final int oldSize = array.getSize();
final int newSize = oldSize + 1;

long[] store = (long[]) array.getStore();

if (extendProfile.profile(newSize > store.length)) {
store = Arrays.copyOf(store, ArrayUtils.capacity(store.length, newSize));
}
appendOneSameTypeGeneric(array, ArrayMirror.reflect((long[]) array.getStore()), value, extendProfile);
return array;
}

store[oldSize] = value;
array.setStore(store, newSize);
@Specialization(guards = "isFloat(array)")
public RubyArray appendOneSameType(RubyArray array, double value,
@Cached("createBinaryProfile()") ConditionProfile extendProfile) {
appendOneSameTypeGeneric(array, ArrayMirror.reflect((double[]) array.getStore()), value, extendProfile);
return array;
}

@Specialization(guards = "isObject(array)")
public RubyArray appendObject(RubyArray array, Object value,
public RubyArray appendOneSameType(RubyArray array, Object value,
@Cached("createBinaryProfile()") ConditionProfile extendProfile) {
appendOneSameTypeGeneric(array, ArrayMirror.reflect((Object[]) array.getStore()), value, extendProfile);
return array;
}

public void appendOneSameTypeGeneric(RubyArray array, ArrayMirror storeMirror, Object value, ConditionProfile extendProfile) {
final int oldSize = array.getSize();
final int newSize = oldSize + 1;

Object[] store = (Object[]) array.getStore();
final ArrayMirror newStoreMirror;

if (extendProfile.profile(newSize > store.length)) {
store = Arrays.copyOf(store, ArrayUtils.capacity(store.length, newSize));
if (extendProfile.profile(newSize > storeMirror.getLength())) {
newStoreMirror = storeMirror.copyMirror(ArrayUtils.capacity(storeMirror.getLength(), newSize));
} else {
newStoreMirror = storeMirror;
}

store[oldSize] = value;
array.setStore(store, newSize);
return array;
newStoreMirror.set(oldSize, value);
array.setStore(newStoreMirror.getArray(), newSize);
}

// Append forcing a generalization
// Append forcing a generalization from int[] to long[]

@Specialization(guards = "isIntegerFixnum(array)")
public RubyArray appendLongIntoInteger(RubyArray array, long value) {
public RubyArray appendOneLongIntoInteger(RubyArray array, long value) {
final int oldSize = array.getSize();
final int newSize = oldSize + 1;

@@ -140,30 +120,32 @@ public RubyArray appendLongIntoInteger(RubyArray array, long value) {
return array;
}

// Append forcing a generalization to Object[]

@Specialization(guards = {"isIntegerFixnum(array)", "!isInteger(value)", "!isLong(value)"})
public RubyArray appendObjectIntoInteger(RubyArray array, Object value) {
final int oldSize = array.getSize();
final int newSize = oldSize + 1;
public RubyArray appendOneGeneralizeInteger(RubyArray array, Object value) {
appendOneGeneralizeGeneric(array, ArrayMirror.reflect((int[]) array.getStore()), value);
return array;
}

final int[] oldStore = (int[]) array.getStore();
Object[] newStore = ArrayUtils.box(oldStore, ArrayUtils.capacity(oldStore.length, newSize) - oldStore.length);
@Specialization(guards = {"isLongFixnum(array)", "!isInteger(value)", "!isLong(value)"})
public RubyArray appendOneGeneralizeLong(RubyArray array, Object value) {
appendOneGeneralizeGeneric(array, ArrayMirror.reflect((long[]) array.getStore()), value);
return array;
}

newStore[oldSize] = value;
array.setStore(newStore, newSize);
@Specialization(guards = {"isFloat(array)", "!isDouble(value)"})
public RubyArray appendOneGeneralizeDouble(RubyArray array, Object value) {
appendOneGeneralizeGeneric(array, ArrayMirror.reflect((double[]) array.getStore()), value);
return array;
}

@Specialization(guards = {"isLongFixnum(array)", "!isInteger(value)", "!isLong(value)"})
public RubyArray appendObjectIntoLong(RubyArray array, Object value) {
public void appendOneGeneralizeGeneric(RubyArray array, ArrayMirror storeMirror, Object value) {
final int oldSize = array.getSize();
final int newSize = oldSize + 1;

final long[] oldStore = (long[]) array.getStore();
Object[] newStore = ArrayUtils.box(oldStore, ArrayUtils.capacity(oldStore.length, newSize) - oldStore.length);

Object[] newStore = storeMirror.getBoxedCopy(ArrayUtils.capacity(storeMirror.getLength(), newSize));
newStore[oldSize] = value;
array.setStore(newStore, newSize);
return array;
}

}
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@
import com.oracle.truffle.api.nodes.Node;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;
import org.jruby.util.cli.Options;

import java.util.Arrays;
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;

@NodeChildren({@NodeChild(value = "array", type = RubyNode.class)})
@ImportStatic(ArrayGuards.class)
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;

@NodeChildren({@NodeChild(value = "array", type = RubyNode.class)})
@ImportStatic(ArrayGuards.class)
Original file line number Diff line number Diff line change
@@ -55,7 +55,7 @@
import org.jruby.truffle.runtime.methods.Arity;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.truffle.runtime.methods.SharedMethodInfo;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;
import org.jruby.util.ByteList;
import org.jruby.util.Memo;

@@ -3171,7 +3171,7 @@ public RubyArray pushIntegerFixnum(RubyArray array, Object... values) {

if (oldStore.length < newSize) {
extendBranch.enter();
store = ArrayUtils.box(oldStore, ArrayUtils.capacity(oldStore.length, newSize) - oldStore.length);
store = ArrayUtils.boxExtra(oldStore, ArrayUtils.capacity(oldStore.length, newSize) - oldStore.length);
} else {
store = ArrayUtils.box(oldStore);
}
@@ -3303,7 +3303,7 @@ public RubyArray pushIntegerFixnumObject(RubyArray array, Object value) {

if (oldStore.length < newSize) {
extendBranch.enter();
newStore = ArrayUtils.box(oldStore, ArrayUtils.capacity(oldStore.length, newSize) - oldStore.length);
newStore = ArrayUtils.boxExtra(oldStore, ArrayUtils.capacity(oldStore.length, newSize) - oldStore.length);
} else {
newStore = ArrayUtils.box(oldStore);
}
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;

@NodeChildren({@NodeChild(value = "array", type = RubyNode.class)})
@ImportStatic(ArrayGuards.class)

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;

@NodeChildren({
@NodeChild(value="array", type=RubyNode.class),
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;

import java.util.Arrays;

Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;

@NodeChildren({
@NodeChild(value="array", type=RubyNode.class),
@@ -48,7 +48,7 @@ public RubyArray generalizeNull(RubyArray array, int requiredCapacity) {
)
public RubyArray generalizeInt(RubyArray array, int requiredCapacity) {
final int[] intStore = (int[]) array.getStore();
array.setStore(ArrayUtils.box(intStore, requiredCapacity - intStore.length), array.getSize());
array.setStore(ArrayUtils.boxExtra(intStore, requiredCapacity - intStore.length), array.getSize());
return array;
}

@@ -57,7 +57,7 @@ public RubyArray generalizeInt(RubyArray array, int requiredCapacity) {
)
public RubyArray generalizeLong(RubyArray array, int requiredCapacity) {
final long[] intStore = (long[]) array.getStore();
array.setStore(ArrayUtils.box(intStore, requiredCapacity - intStore.length), array.getSize());
array.setStore(ArrayUtils.boxExtra(intStore, requiredCapacity - intStore.length), array.getSize());
return array;
}

@@ -66,7 +66,7 @@ public RubyArray generalizeLong(RubyArray array, int requiredCapacity) {
)
public RubyArray generalizeDouble(RubyArray array, int requiredCapacity) {
final double[] intStore = (double[]) array.getStore();
array.setStore(ArrayUtils.box(intStore, requiredCapacity - intStore.length), array.getSize());
array.setStore(ArrayUtils.boxExtra(intStore, requiredCapacity - intStore.length), array.getSize());
return array;
}

Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.array.ArrayMirror;
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.core.RubyBasicObject;

@@ -39,29 +40,27 @@ public RubyBasicObject popOneEmpty(RubyArray array) {

@Specialization(guards = {"!isEmpty(array)", "isIntegerFixnum(array)"})
public Object popOneInteger(RubyArray array) {
return popOne(array, ArrayViews.view((int[]) array.getStore()));
return popOneGeneric(array, ArrayMirror.reflect((int[]) array.getStore()));
}

@Specialization(guards = {"!isEmpty(array)", "isLongFixnum(array)"})
public Object popOneLong(RubyArray array) {
return popOne(array, ArrayViews.view((long[]) array.getStore()));
return popOneGeneric(array, ArrayMirror.reflect((long[]) array.getStore()));
}

@Specialization(guards = {"!isEmpty(array)", "isFloat(array)"})
public Object popOneDouble(RubyArray array) {
return popOne(array, ArrayViews.view((double[]) array.getStore()));
return popOneGeneric(array, ArrayMirror.reflect((double[]) array.getStore()));
}

@Specialization(guards = {"!isEmpty(array)", "isObject(array)"})
public Object popOneObject(RubyArray array) {
return popOne(array, ArrayViews.view((Object[]) array.getStore()));
return popOneGeneric(array, ArrayMirror.reflect((Object[]) array.getStore()));
}

// General implementation

private Object popOne(RubyArray array, ArrayView view) {
private Object popOneGeneric(RubyArray array, ArrayMirror storeMirror) {
final int size = array.getSize();
final Object value = view.get(size - 1);
final Object value = storeMirror.get(size - 1);
array.setSize(size - 1);
return value;
}
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@
import org.jruby.truffle.runtime.core.RubyClass;
import org.jruby.truffle.runtime.core.RubyProc;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;
import org.jruby.util.cli.Options;

public class CachedBoxedMethodMissingDispatchNode extends CachedDispatchNode {
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@
import com.oracle.truffle.interop.node.ForeignObjectAccessNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyBasicObject;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;

public final class CachedForeignGlobalDispatchNode extends CachedDispatchNode {

Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@
import org.jruby.truffle.runtime.core.RubyProc;
import org.jruby.truffle.runtime.core.RubySymbol;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;

import java.util.ArrayList;
import java.util.List;
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@
import org.jruby.truffle.runtime.core.RubyModule;
import org.jruby.truffle.runtime.core.RubyProc;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;

public class UncachedDispatchNode extends DispatchNode {

Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;

public class SymbolProcNode extends RubyNode {

Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@
import org.jruby.truffle.pack.runtime.PackEncoding;
import org.jruby.truffle.pack.runtime.PackFrameDescriptor;
import org.jruby.truffle.pack.runtime.PackResult;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;

/**
* The node at the root of a pack expression.
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@
import org.jruby.truffle.runtime.core.RubyHash;
import org.jruby.truffle.runtime.core.RubyProc;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;

/**
* Pack and unpack Ruby method arguments to and from an array of objects.
207 changes: 207 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/runtime/array/ArrayMirror.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
/*
* 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
*/
package org.jruby.truffle.runtime.array;

import java.util.Arrays;

public abstract class ArrayMirror {

public static IntegerArrayMirror reflect(int[] array) {
return new IntegerArrayMirror(array);
}

public static LongArrayMirror reflect(long[] array) {
return new LongArrayMirror(array);
}

public static DoubleArrayMirror reflect(double[] array) {
return new DoubleArrayMirror(array);
}

public static ObjectArrayMirror reflect(Object[] array) {
return new ObjectArrayMirror(array);
}

public abstract int getLength();
public abstract Object get(int index);
public abstract void set(int index, Object value);
public abstract ArrayMirror copyMirror(int newLength);
public abstract Object[] getBoxedCopy(int newLength);
public abstract Object getArray();

public Object copyMirror() {
return copyMirror(getLength());
}

public Object[] getBoxedCopy() {
return getBoxedCopy(getLength());
}

private static class IntegerArrayMirror extends ArrayMirror {

private final int[] array;

public IntegerArrayMirror(int[] array) {
this.array = array;
}

@Override
public int getLength() {
return array.length;
}

@Override
public Object get(int index) {
return array[index];
}

@Override
public void set(int index, Object value) {
array[index] = (int) value;
}

@Override
public ArrayMirror copyMirror(int newLength) {
return new IntegerArrayMirror(Arrays.copyOf(array, newLength));
}

@Override
public Object[] getBoxedCopy(int newLength) {
return ArrayUtils.box(array, newLength);
}

@Override
public Object getArray() {
return array;
}

}

private static class LongArrayMirror extends ArrayMirror {

private final long[] array;

public LongArrayMirror(long[] array) {
this.array = array;
}

@Override
public int getLength() {
return array.length;
}

@Override
public Object get(int index) {
return array[index];
}

@Override
public void set(int index, Object value) {
array[index] = (long) value;
}

@Override
public ArrayMirror copyMirror(int newLength) {
return new LongArrayMirror(Arrays.copyOf(array, newLength));
}

@Override
public Object[] getBoxedCopy(int newLength) {
return ArrayUtils.box(array, newLength);
}

@Override
public Object getArray() {
return array;
}

}

private static class DoubleArrayMirror extends ArrayMirror {

private final double[] array;

public DoubleArrayMirror(double[] array) {
this.array = array;
}

@Override
public int getLength() {
return array.length;
}

@Override
public Object get(int index) {
return array[index];
}

@Override
public void set(int index, Object value) {
array[index] = (double) value;
}

@Override
public ArrayMirror copyMirror(int newLength) {
return new DoubleArrayMirror(Arrays.copyOf(array, newLength));
}

@Override
public Object[] getBoxedCopy(int newLength) {
return ArrayUtils.box(array, newLength);
}

@Override
public Object getArray() {
return array;
}

}

private static class ObjectArrayMirror extends ArrayMirror {

private final Object[] array;

public ObjectArrayMirror(Object[] array) {
this.array = array;
}

@Override
public int getLength() {
return array.length;
}

@Override
public Object get(int index) {
return array[index];
}

@Override
public void set(int index, Object value) {
array[index] = value;
}

@Override
public ArrayMirror copyMirror(int newLength) {
return new ObjectArrayMirror(ArrayUtils.copyOf(array, newLength));
}

@Override
public Object[] getBoxedCopy(int newLength) {
return ArrayUtils.copyOf(array, newLength);
}

@Override
public Object getArray() {
return array;
}

}

}
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.runtime.util;
package org.jruby.truffle.runtime.array;

import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.CompilerDirectives;
@@ -117,22 +117,55 @@ public static boolean contains(double[] array, double value) {
}

public static Object[] box(int[] unboxed) {
return box(unboxed, 0);
return boxExtra(unboxed, 0);
}

public static Object[] box(long[] unboxed) {
return box(unboxed, 0);
return boxExtra(unboxed, 0);
}

public static Object[] box(double[] unboxed) {
return box(unboxed, 0);
return boxExtra(unboxed, 0);
}

public static Object[] box(Object array) {
return box(array, 0);
return boxExtra(array, 0);
}

public static Object[] box(int[] unboxed, int extra) {
public static Object[] box(int[] unboxed, int newLength) {
final Object[] boxed = new Object[newLength];

final int boxCount = Math.min(unboxed.length, newLength);
for (int n = 0; n < boxCount; n++) {
boxed[n] = unboxed[n];
}

return boxed;
}

public static Object[] box(long[] unboxed, int newLength) {
final Object[] boxed = new Object[newLength];

final int boxCount = Math.min(unboxed.length, newLength);
for (int n = 0; n < boxCount; n++) {
boxed[n] = unboxed[n];
}

return boxed;
}

public static Object[] box(double[] unboxed, int newLength) {
final Object[] boxed = new Object[newLength];

final int boxCount = Math.min(unboxed.length, newLength);
for (int n = 0; n < boxCount; n++) {
boxed[n] = unboxed[n];
}

return boxed;
}

public static Object[] boxExtra(int[] unboxed, int extra) {
final Object[] boxed = new Object[unboxed.length + extra];

for (int n = 0; n < unboxed.length; n++) {
@@ -142,7 +175,7 @@ public static Object[] box(int[] unboxed, int extra) {
return boxed;
}

public static Object[] box(long[] unboxed, int extra) {
public static Object[] boxExtra(long[] unboxed, int extra) {
final Object[] boxed = new Object[unboxed.length + extra];

for (int n = 0; n < unboxed.length; n++) {
@@ -152,7 +185,7 @@ public static Object[] box(long[] unboxed, int extra) {
return boxed;
}

public static Object[] box(double[] unboxed, int extra) {
public static Object[] boxExtra(double[] unboxed, int extra) {
final Object[] boxed = new Object[unboxed.length + extra];

for (int n = 0; n < unboxed.length; n++) {
@@ -192,17 +225,17 @@ public static Object[] boxUntil(double[] unboxed, int length) {
return boxed;
}

public static Object[] box(Object array, int extra) {
public static Object[] boxExtra(Object array, int extra) {
CompilerAsserts.neverPartOfCompilation();

if (array == null) {
return new Object[extra];
} if (array instanceof int[]) {
return box((int[]) array, extra);
return boxExtra((int[]) array, extra);
} else if (array instanceof long[]) {
return box((long[]) array, extra);
return boxExtra((long[]) array, extra);
} else if (array instanceof double[]) {
return box((double[]) array, extra);
return boxExtra((double[]) array, extra);
} else if (array instanceof Object[]) {
final Object[] objectArray = (Object[]) array;
return Arrays.copyOf(objectArray, objectArray.length + extra);
@@ -318,4 +351,11 @@ public static void arraycopy(Object[] src, int srcPos, Object[] dest, int destPo
System.arraycopy(src, srcPos, dest, destPos, length);
}

public static Object[] copyOf(Object[] array, int newLength) {
// Arrays.copyOf(Object, int) uses reflection
final Object[] copy = new Object[Math.max(array.length, newLength)];
System.arraycopy(array, 0, copy, 0, array.length);
return copy;
}

}
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@
import org.jruby.truffle.nodes.objects.Allocator;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.subsystems.ObjectSpaceManager;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;
import org.jruby.util.cli.Options;

import java.util.Arrays;
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@
import org.joni.Regex;
import org.joni.Region;
import org.jruby.truffle.runtime.subsystems.ObjectSpaceManager;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;
import org.jruby.util.ByteList;

import java.util.Arrays;
Original file line number Diff line number Diff line change
@@ -76,7 +76,7 @@
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.methods.Arity;
import org.jruby.truffle.runtime.methods.SharedMethodInfo;
import org.jruby.truffle.runtime.util.ArrayUtils;
import org.jruby.truffle.runtime.array.ArrayUtils;
import org.jruby.util.ByteList;
import org.jruby.util.KeyValuePair;
import org.jruby.util.StringSupport;

0 comments on commit 2416cd3

Please sign in to comment.