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

Commits on Feb 5, 2015

  1. Copy the full SHA
    db3bdba View commit details
  2. Copy the full SHA
    6e50fca View commit details
  3. Copy the full SHA
    63a865b View commit details
41 changes: 24 additions & 17 deletions core/src/main/java/org/jruby/util/cli/Options.java
Original file line number Diff line number Diff line change
@@ -128,36 +128,43 @@ public class Options {
public static final Option<Boolean> IR_WRITING_DEBUG = bool(IR, "ir.writing.debug", false, "Debug writing JRuby IR file.");
public static final Option<String> IR_INLINE_COMPILER_PASSES = string(IR, "ir.inline_passes", "Specify comma delimeted list of passes to run after inlining a method.");

public static final Option<Boolean> TRUFFLE_LOAD_CORE = bool(TRUFFLE, "truffle.load_core", true, "Load the Truffle core library.");
public static final Option<Boolean> TRUFFLE_PRINT_RUNTIME = bool(TRUFFLE, "truffle.printRuntime", false, "Print the name of the Truffle runtime on startup.");
public static final Option<Boolean> TRUFFLE_RUNTIME_VERSION_CHECK = bool(TRUFFLE, "truffle.runtime.version_check", true, "Check the version of Truffle supplied by the JVM before starting.");
public static final Option<Boolean> TRUFFLE_PROC_BINDING = bool(TRUFFLE, "truffle.proc.binding", true, "Enable Proc#binding.");
public static final Option<Boolean> TRUFFLE_EXCEPTIONS_PRINT_JAVA = bool(TRUFFLE, "truffle.exceptions.print_java", false, "Print Java exceptions at the point of translating them to Ruby exceptions.");

public static final Option<Integer> TRUFFLE_DISPATCH_POLYMORPHIC_MAX = integer(TRUFFLE, "truffle.dispatch.polymorphic.max", 8, "Maximum size of a polymorphic call site cache.");
public static final Option<Integer> TRUFFLE_ARRAYS_UNINITIALIZED_SIZE = integer(TRUFFLE, "truffle.arrays.uninitialized_size", 32, "How large an array to allocate when we have no other information to go on.");
public static final Option<Boolean> TRUFFLE_ARRAYS_OPTIMISTIC_LONG = bool(TRUFFLE, "truffle.arrays.optimistic.long", true, "If we allocate an int[] for an Array and it has been converted to a long[], directly allocate a long[] next time.");
public static final Option<Integer> TRUFFLE_ARRAYS_SMALL = integer(TRUFFLE, "truffle.arrays.small", 3, "Maximum size of an Array to consider small for optimisations.");
public static final Option<Integer> TRUFFLE_HASHES_SMALL = integer(TRUFFLE, "truffle.hashes.small", 3, "Maximum size of a Hash to consider small for optimisations.");
public static final Option<Boolean> TRUFFLE_ALLOW_SIMPLE_SOURCE_SECTIONS = bool(TRUFFLE, "truffle.allow_simple_source_sections", false, "Allow simple source sections.");
public static final Option<TruffleBridge.BacktraceFormatter> TRUFFLE_BACKTRACE_DISPLAY_FORMAT = enumeration(TRUFFLE, "truffle.backtrace.display_format", TruffleBridge.BacktraceFormatter.class, TruffleBridge.BacktraceFormatter.MRI, "How to format backtraces displayed to the user.");
public static final Option<TruffleBridge.BacktraceFormatter> TRUFFLE_BACKTRACE_DEBUG_FORMAT = enumeration(TRUFFLE, "truffle.backtrace.debug_format", TruffleBridge.BacktraceFormatter.class, TruffleBridge.BacktraceFormatter.DEBUG, "How to format backtraces displayed using TruffleDebug.dump_call_stack.");
public static final Option<TruffleBridge.BacktraceFormatter> TRUFFLE_BACKTRACE_EXCEPTION_FORMAT = enumeration(TRUFFLE, "truffle.backtrace.exception_format", TruffleBridge.BacktraceFormatter.class, TruffleBridge.BacktraceFormatter.MRI, "How to format backtraces in Exception objects.");
public static final Option<TruffleBridge.BacktraceFormatter> TRUFFLE_BACKTRACE_PANIC_FORMAT = enumeration(TRUFFLE, "truffle.backtrace.panic_format", TruffleBridge.BacktraceFormatter.class, TruffleBridge.BacktraceFormatter.IMPL_DEBUG, "How to format backtraces in panics.");
public static final Option<Integer> TRUFFLE_BACKTRACE_MAX_VALUE_LENGTH = integer(TRUFFLE, "truffle.backtrace.max_value_length", 20, "Max length for values when displayed in a backtrace.");
public static final Option<Boolean> TRUFFLE_BACKTRACE_GENERATE = bool(TRUFFLE, "truffle.backtrace.generate", true, "Generate backtraces on exceptions.");
public static final Option<Integer> TRUFFLE_DISPATCH_POLYMORPHIC_MAX = integer(TRUFFLE, "truffle.dispatch.polymorphic.max", 8, "Maximum size of a polymorphic call site cache.");
public static final Option<Boolean> TRUFFLE_DEBUG_ENABLE_ASSERT_CONSTANT = bool(TRUFFLE, "truffle.debug.enable_assert_constant", false, "Enable special 'truffle_assert_constant' form.");

public static final Option<Boolean> TRUFFLE_LOAD_CORE = bool(TRUFFLE, "truffle.load_core", true, "Load the Truffle core library.");
public static final Option<Boolean> TRUFFLE_PROC_BINDING = bool(TRUFFLE, "truffle.proc.binding", true, "Enable Proc#binding.");

public static final Option<Integer> TRUFFLE_PASSALOT = integer(TRUFFLE, "truffle.passalot", 0, "Probabilty between 0 and 100 to randomly insert Thread.pass at a given line.");
public static final Option<Integer> TRUFFLE_STACK_SERVER_PORT = integer(TRUFFLE, "truffle.stack_server_port", 0, "Port number to run an HTTP server on that returns stack traces");
public static final Option<String> TRUFFLE_TRANSLATOR_PRINT_AST = string(TRUFFLE, "truffle.translator.print_asts", "", "Comma delimited list of method names to print the AST of after translation.");
public static final Option<String> TRUFFLE_TRANSLATOR_PRINT_FULL_AST = string(TRUFFLE, "truffle.translator.print_full_asts", "", "Comma delimited list of method names to print the full AST of after translation.");
public static final Option<String> TRUFFLE_TRANSLATOR_PRINT_PARSE_TREE = string(TRUFFLE, "truffle.translator.print_parse_trees", "", "Comma delimited list of method names to print the JRuby parse tree of before translation.");
public static final Option<Boolean> TRUFFLE_PANIC_ON_JAVA_ASSERT = bool(TRUFFLE, "truffle.debug.panic_on_java_assert", false, "Panic as soon as a Java assertion failure is found.");
public static final Option<Boolean> TRUFFLE_DEBUG_ENABLE_ASSERT_CONSTANT = bool(TRUFFLE, "truffle.debug.enable_assert_constant", false, "Enable special 'truffle_assert_constant' form.");
public static final Option<Boolean> TRUFFLE_EXCEPTIONS_PRINT_JAVA = bool(TRUFFLE, "truffle.exceptions.print_java", false, "Print Java exceptions at the point of translating them to Ruby exceptions.");
public static final Option<Boolean> TRUFFLE_ALLOW_SIMPLE_SOURCE_SECTIONS = bool(TRUFFLE, "truffle.allow_simple_source_sections", false, "Allow simple source sections.");

public static final Option<Boolean> TRUFFLE_INLINER_ALWAYS_CLONE_YIELD = bool(TRUFFLE, "truffle.inliner.always_clone_yield", true, "Always clone yield call targets.");
public static final Option<Boolean> TRUFFLE_INLINER_ALWAYS_INLINE_YIELD = bool(TRUFFLE, "truffle.inliner.always_inline_yield", true, "Always inline yield call targets.");
public static final Option<Boolean> TRUFFLE_DISPATCH_METAPROGRAMMING_ALWAYS_UNCACHED = bool(TRUFFLE, "truffle.dispatch.metaprogramming_always_uncached", false, "Always use uncached dispatch for the metaprogramming methods #__send__, #send and #respond_to?, and for any call site that has to use #method_missing or #const_missing.");
public static final Option<Boolean> TRUFFLE_DISPATCH_METAPROGRAMMING_ALWAYS_INDIRECT = bool(TRUFFLE, "truffle.dispatch.metaprogramming_always_indirect", false, "Always use indirect calls for the metaprogramming methods #__send__ and #send, and for any call site that has to use #method_missing or #const_missing.");
public static final Option<Boolean> TRUFFLE_DISPATCH_METHODMISSING_ALWAYS_CLONED = bool(TRUFFLE, "truffle.call.method_missing_always_cloned", true, "Always clone #method_missing call targets.");
public static final Option<Boolean> TRUFFLE_DISPATCH_METHODMISSING_ALWAYS_INLINED = bool(TRUFFLE, "truffle.call.method_missing_always_inlined", true, "Always inline #method_missing call targets.");
public static final Option<String> TRUFFLE_TRANSLATOR_PRINT_AST = string(TRUFFLE, "truffle.translator.print_asts", "", "Comma delimited list of method names to print the AST of after translation.");
public static final Option<String> TRUFFLE_TRANSLATOR_PRINT_FULL_AST = string(TRUFFLE, "truffle.translator.print_full_asts", "", "Comma delimited list of method names to print the full AST of after translation.");
public static final Option<String> TRUFFLE_TRANSLATOR_PRINT_PARSE_TREE = string(TRUFFLE, "truffle.translator.print_parse_trees", "", "Comma delimited list of method names to print the JRuby parse tree of before translation.");
public static final Option<Integer> TRUFFLE_PASSALOT = integer(TRUFFLE, "truffle.passalot", 0, "Probabilty between 0 and 100 to randomly insert Thread.pass at a given line.");
public static final Option<Integer> TRUFFLE_STACK_SERVER_PORT = integer(TRUFFLE, "truffle.stack_server_port", 0, "Port number to run an HTTP server on that returns stack traces");

public static final Option<Boolean> TRUFFLE_RANDOMIZE_STORAGE_ARRAY = bool(TRUFFLE, "truffle.randomize_storage.array", false, "Randomize Array storage strategy.");

public static final Option<TruffleBridge.BacktraceFormatter> TRUFFLE_BACKTRACE_DISPLAY_FORMAT = enumeration(TRUFFLE, "truffle.backtrace.display_format", TruffleBridge.BacktraceFormatter.class, TruffleBridge.BacktraceFormatter.MRI, "How to format backtraces displayed to the user.");
public static final Option<TruffleBridge.BacktraceFormatter> TRUFFLE_BACKTRACE_DEBUG_FORMAT = enumeration(TRUFFLE, "truffle.backtrace.debug_format", TruffleBridge.BacktraceFormatter.class, TruffleBridge.BacktraceFormatter.DEBUG, "How to format backtraces displayed using TruffleDebug.dump_call_stack.");
public static final Option<TruffleBridge.BacktraceFormatter> TRUFFLE_BACKTRACE_EXCEPTION_FORMAT = enumeration(TRUFFLE, "truffle.backtrace.exception_format", TruffleBridge.BacktraceFormatter.class, TruffleBridge.BacktraceFormatter.MRI, "How to format backtraces in Exception objects.");
public static final Option<TruffleBridge.BacktraceFormatter> TRUFFLE_BACKTRACE_PANIC_FORMAT = enumeration(TRUFFLE, "truffle.backtrace.panic_format", TruffleBridge.BacktraceFormatter.class, TruffleBridge.BacktraceFormatter.IMPL_DEBUG, "How to format backtraces in panics.");
public static final Option<Integer> TRUFFLE_BACKTRACE_MAX_VALUE_LENGTH = integer(TRUFFLE, "truffle.backtrace.max_value_length", 20, "Max length for values when displayed in a backtrace.");
public static final Option<Boolean> TRUFFLE_BACKTRACE_GENERATE = bool(TRUFFLE, "truffle.backtrace.generate", true, "Generate backtraces on exceptions.");

public static final Option<Boolean> NATIVE_ENABLED = bool(NATIVE, "native.enabled", true, "Enable/disable native code, including POSIX features and C exts.");
public static final Option<Boolean> NATIVE_VERBOSE = bool(NATIVE, "native.verbose", false, "Enable verbose logging of native extension loading.");
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@
import org.jruby.util.cli.Options;

import java.util.Arrays;
import java.util.Random;

/**
* Implements the Ruby {@code Array} class.
@@ -28,6 +29,9 @@ public final class RubyArray extends RubyBasicObject {

public static final int ARRAYS_SMALL = Options.TRUFFLE_ARRAYS_SMALL.load();

private static final boolean RANDOMIZE_STORAGE_ARRAY = Options.TRUFFLE_RANDOMIZE_STORAGE_ARRAY.load();
private static final Random random = new Random(0);

private final ArrayAllocationSite allocationSite;
private Object store;
private int size;
@@ -65,14 +69,14 @@ public static RubyArray fromObject(RubyClass arrayClass, Object object) {
}

public static RubyArray fromObjects(RubyClass arrayClass, Object... objects) {
return new RubyArray(arrayClass, storeFromObjects(objects), objects.length);
}

private static Object storeFromObjects(Object... objects) {
RubyNode.notDesignedForCompilation();

if (objects.length == 0) {
return new RubyArray(arrayClass);
}

if (objects.length == 1) {
return fromObject(arrayClass, objects[0]);
return null;
}

boolean canUseInteger = true;
@@ -109,7 +113,7 @@ public static RubyArray fromObjects(RubyClass arrayClass, Object... objects) {
}
}

return new RubyArray(arrayClass, store, objects.length);
return store;
} else if (canUseLong) {
final long[] store = new long[objects.length];

@@ -124,17 +128,17 @@ public static RubyArray fromObjects(RubyClass arrayClass, Object... objects) {
}
}

return new RubyArray(arrayClass, store, objects.length);
return store;
} else if (canUseDouble) {
final double[] store = new double[objects.length];

for (int n = 0; n < objects.length; n++) {
store[n] = CoreLibrary.toDouble(objects[n]);
}

return new RubyArray(arrayClass, store, objects.length);
return store;
} else {
return new RubyArray(arrayClass, objects, objects.length);
return objects;
}
}

@@ -207,10 +211,52 @@ public Object getStore() {

public void setStore(Object store, int size) {
assert verifyStore(store, size);

if (RANDOMIZE_STORAGE_ARRAY) {
store = randomizeStorageStrategy(store);
}

this.store = store;
this.size = size;
}

@CompilerDirectives.TruffleBoundary
private static Object randomizeStorageStrategy(Object store) {
// Convert to the canonical store type first

final Object[] boxedStore = ArrayUtils.box(store);
final Object canonicalStore = storeFromObjects(boxedStore);

// Then promote it at random

if (canonicalStore instanceof int[]) {
switch (random.nextInt(3)) {
case 0:
return boxedStore;
case 1:
ArrayUtils.longCopyOf((int[]) canonicalStore);
case 2:
return canonicalStore;
default:
throw new IllegalStateException();
}
} else if (canonicalStore instanceof long[]) {
if (random.nextBoolean()) {
return boxedStore;
} else {
return canonicalStore;
}
} else if (canonicalStore instanceof double[]) {
if (random.nextBoolean()) {
return boxedStore;
} else {
return canonicalStore;
}
} else {
return canonicalStore;
}
}

public int getSize() {
return size;
}
@@ -231,6 +277,7 @@ private boolean verifyStore(Object store, int size) {
assert !(store instanceof int[]) || size <= ((int[]) store).length;
assert !(store instanceof long[]) || size <= ((long[]) store).length;
assert !(store instanceof double[]) || size <= ((double[]) store).length;

return true;
}

47 changes: 47 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/runtime/core/RubyHash.java
Original file line number Diff line number Diff line change
@@ -56,12 +56,59 @@ public Object getStore() {
}

public void setStore(Object store, int storeSize, Entry firstInSequence, Entry lastInSequence) {
assert verifyStore(store, storeSize, firstInSequence, lastInSequence);
this.store = store;
this.storeSize = storeSize;
this.firstInSequence = firstInSequence;
this.lastInSequence = lastInSequence;
}

public boolean verifyStore(Object store, int storeSize, Entry firstInSequence, Entry lastInSequence) {
assert store == null || store instanceof Object[] || store instanceof Entry[];

if (store == null) {
assert storeSize == 0;
assert firstInSequence == null;
assert lastInSequence == null;
}

if (store instanceof Entry[]) {
final Entry[] entryStore = (Entry[]) store;

int foundSize = 0;
boolean foundFirst = false;
boolean foundLast = true;

for (int n = 0; n < entryStore.length; n++) {
Entry entry = entryStore[n];

while (entry != null) {
foundSize++;

if (entry == firstInSequence) {
foundFirst = true;
}

if (entry == lastInSequence) {
foundLast = true;
}

entry = entry.getNextInLookup();
}
}

//assert foundSize == storeSize; Can't do this because sometimes we set the store and then fill it up
assert firstInSequence == null || foundFirst;
assert lastInSequence == null || foundLast;
} else if (store instanceof Object[]) {
assert ((Object[]) store).length == HashOperations.SMALL_HASH_SIZE * 2 : ((Object[]) store).length;
assert firstInSequence == null;
assert lastInSequence == null;
}

return true;
}

public int getSize() {
return storeSize;
}