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: 221bd6c68b23
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 2889a8a83e3a
Choose a head ref
  • 19 commits
  • 20 files changed
  • 3 contributors

Commits on Jun 8, 2016

  1. Dynamic constructs were never using frozen strings for StrNodes.

    We had a check for this in IRBuilder but at some point we ended up
    adding a copyAndReturn to buildStr.  This defeated the check.
    enebo committed Jun 8, 2016
    Copy the full SHA
    f30009c View commit details
  2. Copy the full SHA
    1d0b00a View commit details
  3. All StrNodes encountered need not worry about order and can get

    created out of order.
    enebo committed Jun 8, 2016
    Copy the full SHA
    a1047ee View commit details
  4. Copy the full SHA
    cba8d93 View commit details
  5. [Truffle] Fix visibility to respond_to? when at the top level and in …

    …the first required file.
    chrisseaton committed Jun 8, 2016
    Copy the full SHA
    4071392 View commit details
  6. Copy the full SHA
    fa866cf View commit details
  7. Copy the full SHA
    6344c26 View commit details
  8. Copy the full SHA
    5be7e53 View commit details

Commits on Jun 9, 2016

  1. Copy the full SHA
    15d4bfc View commit details
  2. Copy the full SHA
    37dcc3b View commit details
  3. Copy the full SHA
    cd7ac37 View commit details
  4. Copy the full SHA
    139fc91 View commit details
  5. Copy the full SHA
    6831172 View commit details
  6. Copy the full SHA
    7bd354f View commit details
  7. Copy the full SHA
    5b5eb0d View commit details
  8. Copy the full SHA
    87495b6 View commit details
  9. 2
    Copy the full SHA
    f3b1c13 View commit details
  10. Copy the full SHA
    27f8571 View commit details
  11. Copy the full SHA
    2889a8a View commit details
10 changes: 5 additions & 5 deletions ci.hocon
Original file line number Diff line number Diff line change
@@ -138,13 +138,13 @@ builds: [
{name: ruby-test-specs-truffle} ${common} ${gate-caps} {run: [${jt} [test, specs, ":truffle"]]},
{name: ruby-test-integration} ${common} ${gate-caps} {run: [${jt} [test, integration]]},
{name: ruby-test-tck} ${common} ${gate-caps} {run: [${jt} [test, tck]]},
{name: ruby-tarball} ${common} ${gate-caps} {run: [${jt} [tarball]]},
{name: ruby-test-tarball} ${common} ${gate-caps} {run: [${jt} [tarball]]},

{name: ruby-test-compiler-graal-core} ${common} ${graal-core} ${gate-caps} {run: [${jt} [test, compiler]]},
{name: ruby-test-compiler-graalvm} ${common} ${graalvm} ${gate-caps} {run: [${jt} [test, compiler]]},

{name: ruby-test-metrics-noindy} ${common} ${no-graal} ${daily-bench-caps} ${jruby-noindy} ${metrics},
{name: ruby-test-metrics-indy} ${common} ${no-graal} ${daily-bench-caps} ${jruby-indy} ${metrics},
{name: ruby-test-metrics-truffle} ${common} ${no-graal} ${bench-caps} ${jruby-truffle} ${metrics},
{name: ruby-test-metrics-compiler} ${common} ${graalvm} ${bench-caps} ${jruby-truffle} ${compiler-metrics}
{name: ruby-metrics-noindy} ${common} ${no-graal} ${daily-bench-caps} ${jruby-noindy} ${metrics},
{name: ruby-metrics-indy} ${common} ${no-graal} ${daily-bench-caps} ${jruby-indy} ${metrics},
{name: ruby-metrics-truffle} ${common} ${no-graal} ${bench-caps} ${jruby-truffle} ${metrics},
{name: ruby-metrics-compiler} ${common} ${graalvm} ${bench-caps} ${jruby-truffle} ${compiler-metrics}
]
21 changes: 15 additions & 6 deletions core/src/main/java/org/jruby/ir/IRBuilder.java
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
import org.jruby.ast.*;
import org.jruby.ast.types.INameNode;
import org.jruby.compiler.NotCompilableException;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.runtime.ArgumentDescriptor;
import org.jruby.runtime.ArgumentType;
import org.jruby.ir.instructions.*;
@@ -560,6 +561,10 @@ protected Variable copyAndReturnValue(Operand val) {
}

protected Operand buildWithOrder(Node node, boolean preserveOrder) {
// Even though String literals are mutable they cannot fail or depend on rest of program's semantics so
// they can ignore order.
if (node instanceof StrNode) return buildStrRaw((StrNode) node);

Operand value = build(node);

// We need to preserve order in cases (like in presence of assignments) except that immutable
@@ -2182,7 +2187,7 @@ public Operand buildDot(final DotNode dotNode) {
}

private Operand dynamicPiece(Node pieceNode) {
Operand piece = build(pieceNode);
Operand piece = pieceNode instanceof StrNode ? buildStrRaw((StrNode) pieceNode) : build(pieceNode);

if (piece instanceof StringLiteral) {
piece = ((StringLiteral)piece).frozenString;
@@ -3445,15 +3450,19 @@ public Operand buildSplat(SplatNode splatNode) {
}

public Operand buildStr(StrNode strNode) {
Operand literal = buildStrRaw(strNode);

return literal instanceof FrozenString ? literal : copyAndReturnValue(literal);
}

public Operand buildStrRaw(StrNode strNode) {
if (strNode instanceof FileNode) return new Filename();

Operand literal = strNode.isFrozen() ?
new FrozenString(strNode.getValue(), strNode.getCodeRange(), strNode.getPosition().getFile(), strNode.getPosition().getLine()) :
new StringLiteral(strNode.getValue(), strNode.getCodeRange(), strNode.getPosition().getFile(), strNode.getPosition().getLine());
ISourcePosition pos = strNode.getPosition();

Operand result = copyAndReturnValue(literal);
if (strNode.isFrozen()) return new FrozenString(strNode.getValue(), strNode.getCodeRange(), pos.getFile(), pos.getLine());

return result;
return new StringLiteral(strNode.getValue(), strNode.getCodeRange(), pos.getFile(), pos.getLine());
}

private Operand buildSuperInstr(Operand block, Operand[] args) {
1 change: 1 addition & 0 deletions core/src/main/java/org/jruby/util/cli/Options.java
Original file line number Diff line number Diff line change
@@ -239,6 +239,7 @@ public class Options {
public static final Option<Boolean> TRUFFLE_PROFILER = bool(TRUFFLE, "truffle.profiler", false, "Run the Truffle profiler.");

public static final Option<String> TRUFFLE_CORE_LOAD_PATH = string(TRUFFLE, "truffle.core.load_path", "truffle:/jruby-truffle", "Location to load the Truffle core library from.");
public static final Option<Boolean> TRUFFLE_CORE_PARALLEL_LOAD = bool(TRUFFLE, "truffle.core.parallel_load", true, "Load the Truffle core library in parallel.");

public static final Option<Integer> TRUFFLE_ARRAY_UNINITIALIZED_SIZE = integer(TRUFFLE, "truffle.array.uninitialized_size", 32, "How large an Array to allocate when we have no other information to go on.");
public static final Option<Integer> TRUFFLE_ARRAY_SMALL = integer(TRUFFLE, "truffle.array.small", 3, "Maximum size of an Array to consider small for optimisations.");
2 changes: 1 addition & 1 deletion mx.jruby/suite.py
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
"suites": [
{
"name": "truffle",
"version": "9c16d110f3aa63a17e3e2cf1b857e039c507078a",
"version": "4cedec080054e9be81d8f6fdf7a2fa37587afde6",
"urls": [
{"url": "https://github.com/graalvm/truffle.git",
"kind": "git"},
Original file line number Diff line number Diff line change
@@ -9,10 +9,10 @@
*/
package org.jruby.truffle.builtins;

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.dsl.GeneratedBy;
import com.oracle.truffle.api.dsl.NodeFactory;
import com.oracle.truffle.api.nodes.NodeUtil;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.runtime.Visibility;
@@ -43,13 +43,13 @@
import org.jruby.truffle.language.objects.SingletonClassNode;
import org.jruby.truffle.language.parser.jruby.Translator;
import org.jruby.truffle.platform.UnsafeGroup;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CoreMethodNodeManager {

private static final boolean CHECK_AMBIGUOUS_OPTIONAL_ARGS = System.getenv("TRUFFLE_CHECK_AMBIGUOUS_OPTIONAL_ARGS") != null;
private final RubyContext context;
private final SingletonClassNode singletonClassNode;

@@ -59,25 +59,22 @@ public CoreMethodNodeManager(RubyContext context, SingletonClassNode singletonCl
}

public void addCoreMethodNodes(List<? extends NodeFactory<? extends RubyNode>> nodeFactories) {
final Class<?> firstNodeClass = nodeFactories.get(0).getClass().getAnnotation(GeneratedBy.class).value();
final String moduleName = firstNodeClass.getEnclosingClass().getAnnotation(CoreClass.class).value();
final DynamicObject module = getModule(moduleName);

for (NodeFactory<? extends RubyNode> nodeFactory : nodeFactories) {
final GeneratedBy generatedBy = nodeFactory.getClass().getAnnotation(GeneratedBy.class);
final Class<?> nodeClass = generatedBy.value();
final CoreClass classAnnotation = nodeClass.getEnclosingClass().getAnnotation(CoreClass.class);
final Class<?> nodeClass = nodeFactory.getClass().getAnnotation(GeneratedBy.class).value();
final CoreMethod methodAnnotation = nodeClass.getAnnotation(CoreMethod.class);

if (methodAnnotation != null) {
addCoreMethod(new MethodDetails(classAnnotation, methodAnnotation, nodeFactory));
addCoreMethod(module, new MethodDetails(moduleName, methodAnnotation, nodeFactory));
}
}
}

private DynamicObject getSingletonClass(Object object) {
return singletonClassNode.executeSingletonClass(object);
}

private void addCoreMethod(MethodDetails methodDetails) {
private DynamicObject getModule(String fullName) {
DynamicObject module;
String fullName = methodDetails.getClassAnnotation().value();

if (fullName.equals("main")) {
module = getSingletonClass(context.getCoreLibrary().getMainObject());
@@ -96,11 +93,18 @@ private void addCoreMethod(MethodDetails methodDetails) {
}

assert RubyGuards.isRubyModule(module) : fullName;
return module;
}

private DynamicObject getSingletonClass(Object object) {
return singletonClassNode.executeSingletonClass(object);
}

private void addCoreMethod(DynamicObject module, MethodDetails methodDetails) {
final CoreMethod method = methodDetails.getMethodAnnotation();

final List<String> names = Arrays.asList(method.names());
assert names.size() >= 1;
final String[] names = method.names();
assert names.length >= 1;

final Visibility visibility = method.visibility();

@@ -122,39 +126,38 @@ private void addCoreMethod(MethodDetails methodDetails) {
System.err.println("WARNING: Either onSingleton or constructor for " + methodDetails.getIndicativeName());
}

final RubyRootNode rootNode = makeGenericMethod(context, methodDetails);
final SharedMethodInfo sharedMethodInfo = makeSharedMethodInfo(context, methodDetails);
final CallTarget callTarget = makeGenericMethod(context, methodDetails, sharedMethodInfo);

if (method.isModuleFunction()) {
addMethod(context, module, rootNode, names, Visibility.PRIVATE);
addMethod(context, getSingletonClass(module), rootNode, names, Visibility.PUBLIC);
addMethod(context, module, sharedMethodInfo, callTarget, names, Visibility.PRIVATE);
addMethod(context, getSingletonClass(module), sharedMethodInfo, callTarget, names, Visibility.PUBLIC);
} else if (method.onSingleton() || method.constructor()) {
addMethod(context, getSingletonClass(module), rootNode, names, visibility);
addMethod(context, getSingletonClass(module), sharedMethodInfo, callTarget, names, visibility);
} else {
addMethod(context, module, rootNode, names, visibility);
addMethod(context, module, sharedMethodInfo, callTarget, names, visibility);
}
}

private static void addMethod(RubyContext context, DynamicObject module, RubyRootNode rootNode, List<String> names, final Visibility originalVisibility) {
private static void addMethod(RubyContext context, DynamicObject module, SharedMethodInfo sharedMethodInfo, CallTarget callTarget, String[] names, Visibility originalVisibility) {
assert RubyGuards.isRubyModule(module);

for (String name : names) {
final RubyRootNode rootNodeCopy = NodeUtil.cloneNode(rootNode);

Visibility visibility = originalVisibility;
if (ModuleOperations.isMethodPrivateFromName(name)) {
visibility = Visibility.PRIVATE;
}

final InternalMethod method = new InternalMethod(rootNodeCopy.getSharedMethodInfo(), name, module, visibility, Truffle.getRuntime().createCallTarget(rootNodeCopy));
final InternalMethod method = new InternalMethod(sharedMethodInfo, name, module, visibility, callTarget);

Layouts.MODULE.getFields(module).addMethod(context, null, method.withVisibility(visibility).withName(name));
Layouts.MODULE.getFields(module).addMethod(context, null, method);
}
}

private static RubyRootNode makeGenericMethod(RubyContext context, MethodDetails methodDetails) {
private static SharedMethodInfo makeSharedMethodInfo(RubyContext context, MethodDetails methodDetails) {
final CoreMethod method = methodDetails.getMethodAnnotation();

final SourceSection sourceSection = SourceSection.createUnavailable("core", String.format("%s#%s", methodDetails.getClassAnnotation().value(), method.names()[0]));
final String methodName = method.names()[0];
final SourceSection sourceSection = SourceSection.createUnavailable("core", methodDetails.getIndicativeName());

final int required = method.required();
final int optional = method.optional();
@@ -163,11 +166,19 @@ private static RubyRootNode makeGenericMethod(RubyContext context, MethodDetails

final Arity arity = new Arity(required, optional, method.rest());

final SharedMethodInfo sharedMethodInfo = new SharedMethodInfo(sourceSection, LexicalScope.NONE, arity, method.names()[0], false, null, context.getOptions().CORE_ALWAYS_CLONE, alwaysInline, needsCallerFrame);
return new SharedMethodInfo(sourceSection, LexicalScope.NONE, arity, methodName, false, null, context.getOptions().CORE_ALWAYS_CLONE, alwaysInline, needsCallerFrame);
}

private static CallTarget makeGenericMethod(RubyContext context, MethodDetails methodDetails, SharedMethodInfo sharedMethodInfo) {
final CoreMethod method = methodDetails.getMethodAnnotation();

final SourceSection sourceSection = sharedMethodInfo.getSourceSection();
final int required = method.required();
final int optional = method.optional();

final List<RubyNode> argumentsNodes = new ArrayList<>();

if (needsCallerFrame) {
if (method.needsCallerFrame()) {
argumentsNodes.add(new ReadCallerFrameNode());
}

@@ -189,7 +200,9 @@ private static RubyRootNode makeGenericMethod(RubyContext context, MethodDetails
argumentsNodes.add(readSelfNode);
}

for (int n = 0; n < arity.getPreRequired() + arity.getOptional(); n++) {
final int nArgs = required + optional;

for (int n = 0; n < nArgs; n++) {
RubyNode readArgumentNode = new ReadPreArgumentNode(n, MissingArgumentBehavior.UNDEFINED);

if (ArrayUtils.contains(method.lowerFixnumParameters(), n)) {
@@ -203,7 +216,7 @@ private static RubyRootNode makeGenericMethod(RubyContext context, MethodDetails
argumentsNodes.add(readArgumentNode);
}
if (method.rest()) {
argumentsNodes.add(new ReadRemainingArgumentsNode(arity.getPreRequired() + arity.getOptional()));
argumentsNodes.add(new ReadRemainingArgumentsNode(nArgs));
}

if (method.needsBlock()) {
@@ -237,11 +250,11 @@ private static RubyRootNode makeGenericMethod(RubyContext context, MethodDetails
}
}

if (System.getenv("TRUFFLE_CHECK_AMBIGUOUS_OPTIONAL_ARGS") != null) {
if (CHECK_AMBIGUOUS_OPTIONAL_ARGS) {
AmbiguousOptionalArgumentChecker.verifyNoAmbiguousOptionalArguments(methodDetails);
}

final RubyNode checkArity = Translator.createCheckArityNode(context, sourceSection, arity);
final RubyNode checkArity = Translator.createCheckArityNode(context, sourceSection, sharedMethodInfo.getArity());

RubyNode sequence;

@@ -264,7 +277,9 @@ private static RubyRootNode makeGenericMethod(RubyContext context, MethodDetails

final ExceptionTranslatingNode exceptionTranslatingNode = new ExceptionTranslatingNode(context, sourceSection, sequence, method.unsupportedOperationBehavior());

return new RubyRootNode(context, sourceSection, null, sharedMethodInfo, exceptionTranslatingNode, false);
final RubyRootNode rootNode = new RubyRootNode(context, sourceSection, null, sharedMethodInfo, exceptionTranslatingNode, false);

return Truffle.getRuntime().createCallTarget(rootNode);
}

public static boolean isSafe(RubyContext context, UnsafeGroup[] groups) {
@@ -314,31 +329,23 @@ public static boolean isSafe(RubyContext context, UnsafeGroup[] groups) {
}

public void allMethodInstalled() {
if (System.getenv("TRUFFLE_CHECK_AMBIGUOUS_OPTIONAL_ARGS") != null &&
!AmbiguousOptionalArgumentChecker.SUCCESS) {
if (CHECK_AMBIGUOUS_OPTIONAL_ARGS && !AmbiguousOptionalArgumentChecker.SUCCESS) {
System.exit(1);
}
}

public static class MethodDetails {

private final CoreClass classAnnotation;
private final String moduleName;
private final CoreMethod methodAnnotation;
private final NodeFactory<? extends RubyNode> nodeFactory;

public MethodDetails(CoreClass classAnnotation, CoreMethod methodAnnotation, NodeFactory<? extends RubyNode> nodeFactory) {
assert classAnnotation != null;
assert methodAnnotation != null;
assert nodeFactory != null;
this.classAnnotation = classAnnotation;
public MethodDetails(String moduleName, CoreMethod methodAnnotation, NodeFactory<? extends RubyNode> nodeFactory) {
this.moduleName = moduleName;
this.methodAnnotation = methodAnnotation;
this.nodeFactory = nodeFactory;
}

public CoreClass getClassAnnotation() {
return classAnnotation;
}

public CoreMethod getMethodAnnotation() {
return methodAnnotation;
}
@@ -348,7 +355,7 @@ public NodeFactory<? extends RubyNode> getNodeFactory() {
}

public String getIndicativeName() {
return classAnnotation.value() + "#" + methodAnnotation.names()[0];
return moduleName + "#" + methodAnnotation.names()[0];
}
}

This file was deleted.

Loading