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: 796fa41117af
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: c8c6c3951835
Choose a head ref
  • 5 commits
  • 5 files changed
  • 1 contributor

Commits on Nov 24, 2015

  1. [Truffle] AppendOneNode is only called on arrays.

    * No need to check twice.
    eregon committed Nov 24, 2015
    Copy the full SHA
    e11c6f3 View commit details
  2. 1
    Copy the full SHA
    93220eb View commit details
  3. [Truffle] Add a shared frozen property for classes which always are.

    * Avoids negative guards.
    eregon committed Nov 24, 2015
    Copy the full SHA
    6e0be72 View commit details
  4. Copy the full SHA
    796159b View commit details
  5. Copy the full SHA
    c8c6c39 View commit details
Original file line number Diff line number Diff line change
@@ -759,15 +759,11 @@ public abstract static class KernelFreezeNode extends CoreMethodArrayArgumentsNo

public KernelFreezeNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
freezeNode = FreezeNodeGen.create(context, sourceSection, null);
}

@Specialization
public Object freeze(Object self) {
if (freezeNode == null) {
CompilerDirectives.transferToInterpreter();
freezeNode = insert(FreezeNodeGen.create(getContext(), getEncapsulatingSourceSection(), null));
}

return freezeNode.executeFreeze(self);
}

Original file line number Diff line number Diff line change
@@ -37,58 +37,58 @@ public AppendOneNode(RubyContext context, SourceSection sourceSection) {

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

@Specialization(guards = {"isRubyArray(array)", "isEmptyArray(array)"})
public DynamicObject appendOneEmpty(DynamicObject array, int value) {
@Specialization(guards = "isEmptyArray(array)")
public DynamicObject appendOneEmptyInt(DynamicObject array, int value) {
Layouts.ARRAY.setStore(array, new int[]{value});
Layouts.ARRAY.setSize(array, 1);
return array;
}

@Specialization(guards = {"isRubyArray(array)", "isEmptyArray(array)"})
public DynamicObject appendOneEmpty(DynamicObject array, long value) {
@Specialization(guards = "isEmptyArray(array)")
public DynamicObject appendOneEmptyLong(DynamicObject array, long value) {
Layouts.ARRAY.setStore(array, new long[]{value});
Layouts.ARRAY.setSize(array, 1);
return array;
}

@Specialization(guards = {"isRubyArray(array)", "isEmptyArray(array)"})
public DynamicObject appendOneEmpty(DynamicObject array, double value) {
@Specialization(guards = "isEmptyArray(array)")
public DynamicObject appendOneEmptyDouble(DynamicObject array, double value) {
Layouts.ARRAY.setStore(array, new double[]{value});
Layouts.ARRAY.setSize(array, 1);
return array;
}

@Specialization(guards = {"isRubyArray(array)", "isEmptyArray(array)"})
public DynamicObject appendOneEmpty(DynamicObject array, Object value) {
@Specialization(guards = "isEmptyArray(array)")
public DynamicObject appendOneEmptyObject(DynamicObject array, Object value) {
Layouts.ARRAY.setStore(array, new Object[]{value});
Layouts.ARRAY.setSize(array, 1);
return array;
}

// Append of the correct type

@Specialization(guards = {"isRubyArray(array)", "isIntArray(array)"})
@Specialization(guards = "isIntArray(array)", contains = "appendOneEmptyInt")
public DynamicObject appendOneSameType(DynamicObject array, int value,
@Cached("createBinaryProfile()") ConditionProfile extendProfile) {
appendOneSameTypeGeneric(array, ArrayReflector.reflect((int[]) Layouts.ARRAY.getStore(array)), value, extendProfile);
return array;
}

@Specialization(guards = {"isRubyArray(array)", "isLongArray(array)"})
@Specialization(guards = "isLongArray(array)", contains = "appendOneEmptyLong")
public DynamicObject appendOneSameType(DynamicObject array, long value,
@Cached("createBinaryProfile()") ConditionProfile extendProfile) {
appendOneSameTypeGeneric(array, ArrayReflector.reflect((long[]) Layouts.ARRAY.getStore(array)), value, extendProfile);
return array;
}

@Specialization(guards = {"isRubyArray(array)", "isDoubleArray(array)"})
@Specialization(guards = "isDoubleArray(array)", contains = "appendOneEmptyDouble")
public DynamicObject appendOneSameType(DynamicObject array, double value,
@Cached("createBinaryProfile()") ConditionProfile extendProfile) {
appendOneSameTypeGeneric(array, ArrayReflector.reflect((double[]) Layouts.ARRAY.getStore(array)), value, extendProfile);
return array;
}

@Specialization(guards = {"isRubyArray(array)", "isObjectArray(array)"})
@Specialization(guards = "isObjectArray(array)", contains = "appendOneEmptyObject")
public DynamicObject appendOneSameType(DynamicObject array, Object value,
@Cached("createBinaryProfile()") ConditionProfile extendProfile) {
appendOneSameTypeGeneric(array, ArrayReflector.reflect((Object[]) Layouts.ARRAY.getStore(array)), value, extendProfile);
@@ -102,7 +102,7 @@ public void appendOneSameTypeGeneric(DynamicObject array, ArrayMirror storeMirro
final ArrayMirror newStoreMirror;

if (extendProfile.profile(newSize > storeMirror.getLength())) {
newStoreMirror = storeMirror.copyArrayAndMirror(ArrayUtils.capacity(storeMirror.getLength(), newSize));
newStoreMirror = storeMirror.copyArrayAndMirror(ArrayUtils.capacityForOneMore(storeMirror.getLength()));
} else {
newStoreMirror = storeMirror;
}
@@ -114,7 +114,7 @@ public void appendOneSameTypeGeneric(DynamicObject array, ArrayMirror storeMirro

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

@Specialization(guards = {"isRubyArray(array)", "isIntArray(array)"})
@Specialization(guards = "isIntArray(array)")
public DynamicObject appendOneLongIntoInteger(DynamicObject array, long value) {
final int oldSize = Layouts.ARRAY.getSize(array);
final int newSize = oldSize + 1;
@@ -130,19 +130,19 @@ public DynamicObject appendOneLongIntoInteger(DynamicObject array, long value) {

// Append forcing a generalization to Object[]

@Specialization(guards = {"isRubyArray(array)", "isIntArray(array)", "!isInteger(value)", "!isLong(value)"})
@Specialization(guards = { "isIntArray(array)", "!isInteger(value)", "!isLong(value)" })
public DynamicObject appendOneGeneralizeInteger(DynamicObject array, Object value) {
appendOneGeneralizeGeneric(array, ArrayReflector.reflect((int[]) Layouts.ARRAY.getStore(array)), value);
return array;
}

@Specialization(guards = {"isRubyArray(array)", "isLongArray(array)", "!isInteger(value)", "!isLong(value)"})
@Specialization(guards = { "isLongArray(array)", "!isInteger(value)", "!isLong(value)" })
public DynamicObject appendOneGeneralizeLong(DynamicObject array, Object value) {
appendOneGeneralizeGeneric(array, ArrayReflector.reflect((long[]) Layouts.ARRAY.getStore(array)), value);
return array;
}

@Specialization(guards = {"isRubyArray(array)", "isDoubleArray(array)", "!isDouble(value)"})
@Specialization(guards = { "isDoubleArray(array)", "!isDouble(value)" })
public DynamicObject appendOneGeneralizeDouble(DynamicObject array, Object value) {
appendOneGeneralizeGeneric(array, ArrayReflector.reflect((double[]) Layouts.ARRAY.getStore(array)), value);
return array;
@@ -152,7 +152,7 @@ public void appendOneGeneralizeGeneric(DynamicObject array, ArrayMirror storeMir
final int oldSize = Layouts.ARRAY.getSize(array);
final int newSize = oldSize + 1;
final int oldCapacity = storeMirror.getLength();
final int newCapacity = newSize > oldCapacity ? ArrayUtils.capacity(storeMirror.getLength(), newSize) : oldCapacity;
final int newCapacity = newSize > oldCapacity ? ArrayUtils.capacityForOneMore(storeMirror.getLength()) : oldCapacity;
Object[] newStore = storeMirror.getBoxedCopy(newCapacity);
newStore[oldSize] = value;
Layouts.ARRAY.setStore(array, newStore);
Original file line number Diff line number Diff line change
@@ -51,22 +51,7 @@ public boolean isFrozen(double object) {
return true;
}

@Specialization(guards = "isNil(nil)")
public boolean isFrozen(Object nil) {
return true;
}

@Specialization(guards = "isRubyBignum(object)")
public boolean isFrozenBignum(DynamicObject object) {
return true;
}

@Specialization(guards = "isRubySymbol(symbol)")
public boolean isFrozenSymbol(DynamicObject symbol) {
return true;
}

@Specialization(guards = { "!isNil(object)", "!isRubyBignum(object)", "!isRubySymbol(object)" })
@Specialization
protected boolean isFrozen(DynamicObject object,
@Cached("createReadFrozenNode()") ReadHeadObjectFieldNode readFrozenNode) {
try {
Original file line number Diff line number Diff line change
@@ -373,6 +373,14 @@ public static int capacity(int current, int needed) {
}
}

public static int capacityForOneMore(int current) {
if (current < INITIAL_CAPACITY) {
return INITIAL_CAPACITY;
} else {
return current << 1;
}
}

public static void arraycopy(Object[] src, int srcPos, Object[] dest, int destPos, int length) {
System.arraycopy(src, srcPos, dest, destPos, length);
}
Original file line number Diff line number Diff line change
@@ -18,6 +18,9 @@
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.object.DynamicObjectFactory;
import com.oracle.truffle.api.object.Layout;
import com.oracle.truffle.api.object.Location;
import com.oracle.truffle.api.object.Property;
import com.oracle.truffle.api.source.SourceSection;

import jnr.constants.platform.Errno;
@@ -71,6 +74,8 @@ public class CoreLibrary {

private static final String CLI_RECORD_SEPARATOR = org.jruby.util.cli.Options.CLI_RECORD_SEPARATOR.load();

private static final Property ALWAYS_FROZEN_PROPERTY = Property.create(Layouts.FROZEN_IDENTIFIER, Layout.createLayout().createAllocator().constantLocation(true), 0);

private final RubyContext context;

private final DynamicObject argumentErrorClass;
@@ -349,7 +354,7 @@ public CoreLibrary(RubyContext context) {
integerClass = defineClass(numericClass, "Integer");
fixnumClass = defineClass(integerClass, "Fixnum");
bignumClass = defineClass(integerClass, "Bignum");
bignumFactory = Layouts.BIGNUM.createBignumShape(bignumClass, bignumClass);
bignumFactory = alwaysFrozen(Layouts.BIGNUM.createBignumShape(bignumClass, bignumClass));
Layouts.CLASS.setInstanceFactoryUnsafe(bignumClass, bignumFactory);
rationalClass = defineClass(numericClass, "Rational");

@@ -398,7 +403,7 @@ public CoreLibrary(RubyContext context) {
stringFactory = Layouts.STRING.createStringShape(stringClass, stringClass);
Layouts.CLASS.setInstanceFactoryUnsafe(stringClass, stringFactory);
symbolClass = defineClass("Symbol");
Layouts.CLASS.setInstanceFactoryUnsafe(symbolClass, Layouts.SYMBOL.createSymbolShape(symbolClass, symbolClass));
Layouts.CLASS.setInstanceFactoryUnsafe(symbolClass, alwaysFrozen(Layouts.SYMBOL.createSymbolShape(symbolClass, symbolClass)));
threadClass = defineClass("Thread");
Layouts.CLASS.setInstanceFactoryUnsafe(threadClass, Layouts.THREAD.createThreadShape(threadClass, threadClass));
threadBacktraceClass = defineClass(threadClass, objectClass, "Backtrace");
@@ -496,7 +501,7 @@ public CoreLibrary(RubyContext context) {
// Create some key objects

mainObject = Layouts.CLASS.getInstanceFactory(objectClass).newInstance();
nilObject = Layouts.CLASS.getInstanceFactory(nilClass).newInstance();
nilObject = alwaysFrozen(Layouts.CLASS.getInstanceFactory(nilClass)).newInstance();
argv = Layouts.ARRAY.createArray(Layouts.CLASS.getInstanceFactory(arrayClass), null, 0);
rubiniusUndefined = Layouts.CLASS.getInstanceFactory(objectClass).newInstance();

@@ -506,6 +511,10 @@ public CoreLibrary(RubyContext context) {
Layouts.CLASS.setInstanceFactoryUnsafe(digestClass, DigestLayoutImpl.INSTANCE.createDigestShape(digestClass, digestClass));
}

private static DynamicObjectFactory alwaysFrozen(DynamicObjectFactory factory) {
return factory.getShape().addProperty(ALWAYS_FROZEN_PROPERTY).createFactory();
}

private void includeModules(DynamicObject comparableModule) {
assert RubyGuards.isRubyModule(comparableModule);