Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,34 @@ private static void registerUnsafePlugins0(Registration r, boolean sunMiscUnsafe
r.register(new CacheWritebackPlugin(true, "writebackPreSync0", Receiver.class));
r.register(new CacheWritebackPlugin(false, "writebackPostSync0", Receiver.class));
}

r.register(new InvocationPlugin("arrayBaseOffset", Receiver.class, Class.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode arrayClass) {
return handleArrayBaseOffsetOrIndexScale(b, unsafe, arrayClass, true);
}
});
r.register(new InvocationPlugin("arrayIndexScale", Receiver.class, Class.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode arrayClass) {
return handleArrayBaseOffsetOrIndexScale(b, unsafe, arrayClass, false);
}
});
}

private static boolean handleArrayBaseOffsetOrIndexScale(GraphBuilderContext b, Receiver unsafe, ValueNode arrayClass, boolean arrayBaseOffset) {
var arrayClassConstant = arrayClass.asJavaConstant();
if (arrayClassConstant != null && arrayClassConstant.isNonNull()) {
var arrayType = b.getConstantReflection().asJavaType(arrayClassConstant);
if (arrayType != null && arrayType.isArray()) {
unsafe.get();
var elementKind = b.getMetaAccessExtensionProvider().getStorageKind(arrayType.getComponentType());
int result = arrayBaseOffset ? b.getMetaAccess().getArrayBaseOffset(elementKind) : b.getMetaAccess().getArrayIndexScale(elementKind);
b.addPush(JavaKind.Int, ConstantNode.forInt(result));
return true;
}
}
return false;
}

private static void registerIntegerLongPlugins(InvocationPlugins plugins, JavaKind kind) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ class InlineBeforeAnalysisMethodScope extends PEMethodScope {
super(AnalysisParsedGraph.HOST_ARCHITECTURE, graph, bb.getProviders(), null,
bb.getProviders().getGraphBuilderPlugins().getInvocationPlugins(),
new InlineInvokePlugin[]{new InlineBeforeAnalysisInlineInvokePlugin(policy)},
null, null, null, null,
null, policy.nodePlugins, null, null,
new ConcurrentHashMap<>(), new ConcurrentHashMap<>(), true, false);
this.bb = bb;
this.policy = policy;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@
*/
package com.oracle.graal.pointsto.phases;

import com.oracle.graal.pointsto.meta.AnalysisMetaAccess;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
import org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin;

import com.oracle.graal.pointsto.meta.AnalysisMetaAccess;

import jdk.vm.ci.meta.ResolvedJavaMethod;

Expand All @@ -44,7 +46,7 @@
@SuppressWarnings("unused")
public class InlineBeforeAnalysisPolicy<S extends InlineBeforeAnalysisPolicy.Scope> {

public static final InlineBeforeAnalysisPolicy<Scope> NO_INLINING = new InlineBeforeAnalysisPolicy<>();
public static final InlineBeforeAnalysisPolicy<Scope> NO_INLINING = new InlineBeforeAnalysisPolicy<>(new NodePlugin[0]);

/**
* A place for policy implementations to store per-callee information like the number of nodes
Expand All @@ -53,7 +55,10 @@ public class InlineBeforeAnalysisPolicy<S extends InlineBeforeAnalysisPolicy.Sco
public interface Scope {
}

protected InlineBeforeAnalysisPolicy() {
protected final NodePlugin[] nodePlugins;

protected InlineBeforeAnalysisPolicy(NodePlugin[] nodePlugins) {
this.nodePlugins = nodePlugins;
}

protected boolean shouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@
import java.io.File;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.BooleanSupplier;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode;
Expand All @@ -64,6 +66,7 @@
import com.oracle.svm.core.annotate.Delete;
import com.oracle.svm.core.annotate.KeepOriginal;
import com.oracle.svm.core.annotate.RecomputeFieldValue;
import com.oracle.svm.core.annotate.RecomputeFieldValue.Kind;
import com.oracle.svm.core.annotate.Substitute;
import com.oracle.svm.core.annotate.TargetClass;
import com.oracle.svm.core.annotate.TargetElement;
Expand Down Expand Up @@ -192,11 +195,79 @@ public String intern() {
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
native byte coder();

@Alias //
@Alias @RecomputeFieldValue(kind = Kind.None, isFinal = true) //
byte[] value;

@Alias //
int hash;

/**
* This is a copy of String.split from the JDK, but with the fastpath loop factored out into a
* separate method. This allows inlining and constant folding of the condition for call sites
* where the regex is a constant (which is a common usage pattern).
*
* JDK-8262994 should make that refactoring in OpenJDK, after which this substitution can be
* removed.
*/
@Substitute
public String[] split(String regex, int limit) {
/*
* fastpath if the regex is a (1) one-char String and this character is not one of the
* RegEx's meta characters ".$|()[{^?*+\\", or (2) two-char String and the first char is the
* backslash and the second is not the ascii digit or ascii letter.
*/
char ch = 0;
if (((regex.length() == 1 &&
".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
(regex.length() == 2 &&
regex.charAt(0) == '\\' &&
(((ch = regex.charAt(1)) - '0') | ('9' - ch)) < 0 &&
((ch - 'a') | ('z' - ch)) < 0 &&
((ch - 'A') | ('Z' - ch)) < 0)) &&
(ch < Character.MIN_HIGH_SURROGATE ||
ch > Character.MAX_LOW_SURROGATE)) {
return StringHelper.simpleSplit(SubstrateUtil.cast(this, String.class), limit, ch);
}
return Pattern.compile(regex).split(SubstrateUtil.cast(this, String.class), limit);
}
}

final class StringHelper {
static String[] simpleSplit(String that, int limit, char ch) {
int off = 0;
int next = 0;
boolean limited = limit > 0;
ArrayList<String> list = new ArrayList<>();
while ((next = that.indexOf(ch, off)) != -1) {
if (!limited || list.size() < limit - 1) {
list.add(that.substring(off, next));
off = next + 1;
} else { // last one
// assert (list.size() == limit - 1);
int last = that.length();
list.add(that.substring(off, last));
off = last;
break;
}
}
// If no match was found, return this
if (off == 0) {
return new String[]{that};
}
// Add remaining segment
if (!limited || list.size() < limit) {
list.add(that.substring(off, that.length()));
}
// Construct result
int resultSize = list.size();
if (limit == 0) {
while (resultSize > 0 && list.get(resultSize - 1).isEmpty()) {
resultSize--;
}
}
String[] result = new String[resultSize];
return list.subList(0, resultSize).toArray(result);
}
}

@TargetClass(className = "java.lang.StringLatin1")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,12 @@ public <T> T readConstantField(ResolvedJavaField field, ConstantFieldTool<T> ana
if (readableField.allowConstantFolding() && readableField.isValueAvailable()) {
JavaConstant fieldValue = readableField.readValue(metaAccess, universe.toHosted(analysisTool.getReceiver()));
if (fieldValue != null) {
foldedValue = analysisTool.foldConstant(constantReflection.interceptValue(metaAccess, f, universe.lookup(fieldValue)));
JavaConstant interceptedValue = constantReflection.interceptValue(metaAccess, f, universe.lookup(fieldValue));
if (isStableField(field, analysisTool) && isStableFieldValueConstant(field, interceptedValue, analysisTool)) {
foldedValue = foldStableArray(interceptedValue, field, analysisTool);
} else {
foldedValue = analysisTool.foldConstant(interceptedValue);
}
}
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.extended.ValueAnchorNode;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
import org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin;
import org.graalvm.compiler.nodes.java.AbstractNewObjectNode;
import org.graalvm.compiler.nodes.java.NewArrayNode;
import org.graalvm.compiler.nodes.spi.ValueProxy;
Expand All @@ -50,18 +51,19 @@
import org.graalvm.compiler.nodes.virtual.VirtualArrayNode;
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
import org.graalvm.compiler.options.Option;
import org.graalvm.nativeimage.AnnotationAccess;

import com.oracle.graal.pointsto.meta.AnalysisMetaAccess;
import com.oracle.graal.pointsto.meta.AnalysisMethod;
import com.oracle.graal.pointsto.phases.InlineBeforeAnalysisPolicy;
import com.oracle.svm.core.heap.RestrictHeapAccess;
import com.oracle.svm.core.ParsingReason;
import com.oracle.svm.core.Uninterruptible;
import com.oracle.svm.core.heap.RestrictHeapAccess;
import com.oracle.svm.core.option.HostedOptionKey;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.hosted.SVMHost;

import jdk.vm.ci.meta.ResolvedJavaMethod;
import org.graalvm.nativeimage.AnnotationAccess;

/**
* The defaults for node limits are very conservative. Only small methods should be inlined. The
Expand Down Expand Up @@ -114,6 +116,7 @@ public String toString() {
}

public InlineBeforeAnalysisPolicyImpl(SVMHost hostVM) {
super(new NodePlugin[]{new ConstantFoldLoadFieldPlugin(ParsingReason.PointsToAnalysis)});
this.hostVM = hostVM;
}

Expand Down