Skip to content

Commit

Permalink
Showing 8 changed files with 88 additions and 34 deletions.
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
@@ -305,6 +305,7 @@ public class Options {
public static final Option<String> TRUFFLE_CALL_GRAPH_WRITE = string(TRUFFLE, "truffle.callgraph.write", "File to write the call garph to on exit.");

public static final Option<Boolean> TRUFFLE_GRAAL_WARNING_UNLESS = bool(TRUFFLE, "truffle.graal.warn_unless", true, "Warn unless the JVM has the Graal compiler.");
public static final Option<Boolean> TRUFFLE_PERF_WARNING = bool(TRUFFLE, "truffle.perf.warn", false, "Warn when using a fature which is not optimized yet.");

public static String dump() {
return "# JRuby configuration options with current values\n" +
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2016 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.language;

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import java.util.HashSet;
import java.util.Set;
import org.jruby.util.cli.Options;

public class PerformanceWarnings {

public static final String KWARGS_NOT_OPTIMIZED_YET = "Ruby keyword arguments are not yet optimized";

private static final boolean ENABLED = Options.TRUFFLE_PERF_WARNING.load();
private static final Set<String> DISPLAYED_WARNINGS = new HashSet<>();

public static void warn(String message) {
if (ENABLED) {
doWarn(message);
}
}

@TruffleBoundary
private static void doWarn(String message) {
synchronized (DISPLAYED_WARNINGS) {
if (DISPLAYED_WARNINGS.add(message)) {
System.err.println("[perf warning] " + message);
}
}
}

}
Original file line number Diff line number Diff line change
@@ -9,18 +9,18 @@
*/
package org.jruby.truffle.language.arguments;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.hash.HashOperations;
import org.jruby.truffle.language.PerformanceWarnings;
import org.jruby.truffle.language.RubyGuards;
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.language.methods.Arity;

import java.util.Map;

public class CheckKeywordArityNode extends RubyNode {
@@ -56,42 +56,46 @@ public void executeVoid(VirtualFrame frame) {

if (keywordArguments != null) {
receivedKeywordsProfile.enter();
checkArityKeywordArguments(keywordArguments, given);
}
}

@Override
public Object execute(VirtualFrame frame) {
executeVoid(frame);
return nil();
}

CompilerDirectives.bailout("Ruby keyword arguments aren't optimized");
@TruffleBoundary
private void checkArityKeywordArguments(Object keywordArguments, int given) {
PerformanceWarnings.warn(PerformanceWarnings.KWARGS_NOT_OPTIMIZED_YET);

final DynamicObject keywordHash = (DynamicObject) keywordArguments;
final DynamicObject keywordHash = (DynamicObject) keywordArguments;

for (Map.Entry<Object, Object> keyValue : HashOperations.iterableKeyValues(keywordHash)) {
if (arity.hasKeywordsRest()) {
if (RubyGuards.isRubySymbol(keyValue.getKey())) {
continue;
}
} else {
if (RubyGuards.isRubySymbol(keyValue.getKey())) {
if (!keywordAllowed(keyValue.getKey().toString())) {
throw new RaiseException(coreExceptions().argumentErrorUnknownKeyword(
keyValue.getKey(), this));
}

continue;
for (Map.Entry<Object, Object> keyValue : HashOperations.iterableKeyValues(keywordHash)) {
if (arity.hasKeywordsRest()) {
if (RubyGuards.isRubySymbol(keyValue.getKey())) {
continue;
}
} else {
if (RubyGuards.isRubySymbol(keyValue.getKey())) {
if (!keywordAllowed(keyValue.getKey().toString())) {
throw new RaiseException(coreExceptions().argumentErrorUnknownKeyword(
keyValue.getKey(), this));
}

continue;
}
}

given++;
given++;

if (given > arity.getRequired() && !arity.hasRest() && arity.getOptional() == 0) {
throw new RaiseException(coreExceptions().argumentError(given, arity.getRequired(), this));
}
if (given > arity.getRequired() && !arity.hasRest() && arity.getOptional() == 0) {
throw new RaiseException(coreExceptions().argumentError(given, arity.getRequired(), this));
}
}
}

@Override
public Object execute(VirtualFrame frame) {
executeVoid(frame);
return nil();
}

private boolean keywordAllowed(String keyword) {
for (String allowedKeyword : arity.getKeywordArguments()) {
if (keyword.equals(allowedKeyword)) {
Original file line number Diff line number Diff line change
@@ -55,6 +55,7 @@ public Object execute(VirtualFrame frame) {

@TruffleBoundary
private Object lookupKeywordInHash(DynamicObject hash) {

assert RubyGuards.isRubyHash(hash);

for (Map.Entry<Object, Object> keyValue : HashOperations.iterableKeyValues(hash)) {
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@
*/
package org.jruby.truffle.language.arguments;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.profiles.ConditionProfile;
@@ -18,9 +18,9 @@
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.hash.BucketsStrategy;
import org.jruby.truffle.core.hash.HashOperations;
import org.jruby.truffle.language.PerformanceWarnings;
import org.jruby.truffle.language.RubyGuards;
import org.jruby.truffle.language.RubyNode;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -52,7 +52,12 @@ private Object lookupRestKeywordArgumentHash(VirtualFrame frame) {
return Layouts.HASH.createHash(coreLibrary().getHashFactory(), null, 0, null, null, null, null, false);
}

CompilerDirectives.bailout("Ruby keyword arguments aren't optimized");
return extractKeywordHash(hash);
}

@TruffleBoundary
private Object extractKeywordHash(final Object hash) {
PerformanceWarnings.warn(PerformanceWarnings.KWARGS_NOT_OPTIMIZED_YET);

final DynamicObject hashObject = (DynamicObject) hash;

Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.array.ArrayReadNormalizedNode;
import org.jruby.truffle.core.array.ArrayReadNormalizedNodeGen;
import org.jruby.truffle.language.PerformanceWarnings;
import org.jruby.truffle.language.RubyGuards;
import org.jruby.truffle.language.RubyNode;

@@ -69,12 +70,13 @@ public Object execute(VirtualFrame frame) {
defaultValueProfile.enter();

if (considerRejectedKWArgs) {
CompilerDirectives.bailout("Ruby keyword arguments aren't optimized");
PerformanceWarnings.warn(PerformanceWarnings.KWARGS_NOT_OPTIMIZED_YET);

final Object rest = readRestArgumentNode.execute(frame);

if (RubyGuards.isRubyArray(rest) && Layouts.ARRAY.getSize((DynamicObject) rest) > 0) {
if (arrayReadNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
arrayReadNode = insert(ArrayReadNormalizedNodeGen.create(getContext(), null, null, null));
}

Original file line number Diff line number Diff line change
@@ -9,14 +9,14 @@
*/
package org.jruby.truffle.language.arguments;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.Layouts;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.array.ArrayUtils;
import org.jruby.truffle.language.PerformanceWarnings;
import org.jruby.truffle.language.RubyGuards;
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.SnippetNode;
@@ -83,7 +83,7 @@ public Object execute(VirtualFrame frame) {
resultStore, resultLength);

if (keywordArguments) {
CompilerDirectives.bailout("Ruby keyword arguments not optimized yet");
PerformanceWarnings.warn(PerformanceWarnings.KWARGS_NOT_OPTIMIZED_YET);

Object kwargsHash = readUserKeywordsHashNode.execute(frame);

Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@
import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.frame.VirtualFrame;
import org.jruby.truffle.Layouts;
import org.jruby.truffle.language.PerformanceWarnings;
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.SnippetNode;
import org.jruby.truffle.language.locals.ReadFrameSlotNode;
@@ -36,11 +37,12 @@ public RunBlockKWArgsHelperNode(FrameSlot arrayFrameSlot, Object kwrestName) {

@Override
public Object execute(VirtualFrame frame) {
CompilerDirectives.bailout("blocks with kwargs are not optimized yet");
PerformanceWarnings.warn(PerformanceWarnings.KWARGS_NOT_OPTIMIZED_YET);

final Object array = readArrayNode.executeRead(frame);

if (snippetNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
snippetNode = insert(new SnippetNode());
}

0 comments on commit aff1868

Please sign in to comment.