Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
gluon-bot committed Sep 7, 2023
2 parents f2cf7ef + 1b68ee6 commit 40232e6
Show file tree
Hide file tree
Showing 34 changed files with 603 additions and 224 deletions.
2 changes: 1 addition & 1 deletion common.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"Jsonnet files should not include this file directly but use ci/common.jsonnet instead."
],

"mx_version": "6.45.0",
"mx_version": "6.46.1",

"COMMENT.jdks": "When adding or removing JDKs keep in sync with JDKs in ci/common.jsonnet",
"jdks": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import org.junit.Assert;
import org.junit.Test;

import sun.misc.Unsafe;

/**
* Test on-stack-replacement with Graal. The test manually triggers a Graal OSR-compilation which is
* later invoked when hitting the backedge counter overflow.
Expand Down Expand Up @@ -58,6 +60,11 @@ public void testOSR04() {
testOSR(getInitialOptions(), "testDeoptAfterCountedLoop");
}

@Test
public void testOSR05() {
testOSR(getInitialOptions(), "testBooleanArray");
}

static int limit = 10000;

public static int sideEffect;
Expand Down Expand Up @@ -115,4 +122,18 @@ public static ReturnValue testDeoptAfterCountedLoop() {
GraalDirectives.controlFlowAnchor();
return ret + 1 == limit * limit ? ReturnValue.SUCCESS : ReturnValue.FAILURE;
}

public static ReturnValue testBooleanArray() {
boolean[] array = new boolean[16];
for (int i = 0; GraalDirectives.injectIterationCount(17, i < array.length); i++) {
array[i] = !array[i];

byte rawValue = UNSAFE.getByte(array, Unsafe.ARRAY_BYTE_BASE_OFFSET + i * Unsafe.ARRAY_BYTE_INDEX_SCALE);
if (rawValue != 1) {
return ReturnValue.FAILURE;
}
}
GraalDirectives.controlFlowAnchor();
return ReturnValue.SUCCESS;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4012,6 +4012,14 @@ protected void genLoadConstant(int cpi, int opcode) {
}
}

/**
* Tries to refine the access kind for an array access. That is, if the given {@code kind} is
* {@link JavaKind#Byte}, tries to determine if the array access ({@code baload} or
* {@code bastore}) refers to a {@code byte} or a {@code boolean} array and returns
* {@link JavaKind#Byte} or {@link JavaKind#Boolean} accordingly. If {@code array}'s stamp does
* not provide enough information to determine the correct kind, returns {@code null}. Returns
* the input {@code kind} unchanged if it is not {@link JavaKind#Byte}.
*/
private JavaKind refineComponentType(ValueNode array, JavaKind kind) {
if (kind == JavaKind.Byte) {
JavaType type = array.stamp(NodeView.DEFAULT).javaType(getMetaAccess());
Expand All @@ -4023,6 +4031,13 @@ private JavaKind refineComponentType(ValueNode array, JavaKind kind) {
return refinedKind;
}
}
/*
* We weren't able to recover enough type information from the array input. This can be
* the case for certain loop phi shapes where we don't have precise type information
* available during parsing. It can also be the case during OSR compilations where entry
* proxies deliberately coarsen stamps.
*/
return null;
}
return kind;
}
Expand All @@ -4041,7 +4056,40 @@ private void genLoadIndexed(JavaKind kind) {
}

JavaKind actualKind = refineComponentType(array, kind);
frameState.push(actualKind, append(genLoadIndexed(array, index, boundsCheck, actualKind)));
if (actualKind != null) {
frameState.push(actualKind, append(genLoadIndexed(array, index, boundsCheck, actualKind)));
} else {
GraalError.guarantee(kind == JavaKind.Byte, "refineComponentType should not have failed for %s", kind);
genByteSizedLoadIndexed(index, array, boundsCheck);
}
}

/**
* Build code for a byte-sized array element load where we don't know if the load is from a
* {@code byte} or a {@code boolean} array. This builds both kinds of load and a type check to
* choose one or the other dynamically. After the whole graph is built, canonicalization can
* usually recover concrete types for loop phis and OSR entry proxies. We expect this check to
* fold away, and only the correct load to remain.
*/
private void genByteSizedLoadIndexed(ValueNode index, ValueNode array, GuardingNode boundsCheck) {
LoadIndexedNode loadByte = graph.add(new LoadIndexedNode(graph.getAssumptions(), array, index, boundsCheck, JavaKind.Byte));
EndNode loadByteEnd = graph.add(new EndNode());
loadByte.setNext(loadByteEnd);
LoadIndexedNode loadBoolean = graph.add(new LoadIndexedNode(graph.getAssumptions(), array, index, boundsCheck, JavaKind.Boolean));
EndNode loadBooleanEnd = graph.add(new EndNode());
loadBoolean.setNext(loadBooleanEnd);

LogicNode isByteArray = createInstanceOfAllowNull(TypeReference.createExactTrusted(getMetaAccess().lookupJavaType(byte[].class)), array, null);
ValueNode ifNode = genIfNode(isByteArray, loadByte, loadBoolean, BranchProbabilityData.unknown());
postProcessIfNode(ifNode);
append(ifNode);

MergeNode merge = graph.add(new MergeNode());
merge.addForwardEnd(loadByteEnd);
merge.addForwardEnd(loadBooleanEnd);
frameState.push(JavaKind.Byte, add(new ValuePhiNode(loadByte.stamp(NodeView.DEFAULT), merge, loadByte, loadBoolean)));
setStateAfter(merge);
updateLastInstruction(merge);
}

private void genStoreIndexed(JavaKind kind) {
Expand All @@ -4060,7 +4108,39 @@ private void genStoreIndexed(JavaKind kind) {
}

JavaKind actualKind = refineComponentType(array, kind);
genStoreIndexed(array, index, boundsCheck, storeCheck, actualKind, maskSubWordValue(value, actualKind));
if (actualKind != null) {
genStoreIndexed(array, index, boundsCheck, storeCheck, actualKind, maskSubWordValue(value, actualKind));
} else {
GraalError.guarantee(kind == JavaKind.Byte, "refineComponentType should not have failed for %s", kind);
genByteSizedStoreIndexed(value, index, array, boundsCheck, storeCheck);
}
}

/**
* Build code for a byte-sized array element store where we don't know if the store is to a
* {@code byte} or a {@code boolean} array. This builds both kinds of store and a type check to
* choose one or the other dynamically. After the whole graph is built, canonicalization can
* usually recover concrete types for loop phis and OSR entry proxies. We expect this check to
* fold away, and only the correct store to remain.
*/
private void genByteSizedStoreIndexed(ValueNode value, ValueNode index, ValueNode array, GuardingNode boundsCheck, GuardingNode storeCheck) {
StoreIndexedNode storeByte = graph.add(new StoreIndexedNode(array, index, boundsCheck, storeCheck, JavaKind.Byte, maskSubWordValue(value, JavaKind.Byte)));
setStateAfter(storeByte);
EndNode storeByteEnd = graph.add(new EndNode());
storeByte.setNext(storeByteEnd);
StoreIndexedNode storeBoolean = graph.add(new StoreIndexedNode(array, index, boundsCheck, storeCheck, JavaKind.Boolean, maskSubWordValue(value, JavaKind.Boolean)));
setStateAfter(storeBoolean);
EndNode storeBooleanEnd = graph.add(new EndNode());
storeBoolean.setNext(storeBooleanEnd);

LogicNode isByteArray = createInstanceOfAllowNull(TypeReference.createExactTrusted(getMetaAccess().lookupJavaType(byte[].class)), array, null);
ValueNode ifNode = genIfNode(isByteArray, storeByte, storeBoolean, BranchProbabilityData.unknown());
postProcessIfNode(ifNode);
append(ifNode);

MergeNode merge = add(new MergeNode());
merge.addForwardEnd(storeByteEnd);
merge.addForwardEnd(storeBooleanEnd);
}

private void genArithmeticOp(JavaKind kind, int opcode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ public static void ensureInitialized() {
public static final Symbol<Name> createMemoryManager = StaticSymbols.putName("createMemoryManager");
public static final Symbol<Name> createGarbageCollector = StaticSymbols.putName("createGarbageCollector");
public static final Symbol<Name> tid = StaticSymbols.putName("tid");
public static final Symbol<Name> eetop = StaticSymbols.putName("eetop");
public static final Symbol<Name> getFromClass = StaticSymbols.putName("getFromClass");

// MemberName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ public Meta(EspressoContext context) {
java_lang_Thread$FieldHolder_daemon = java_lang_Thread$FieldHolder.requireDeclaredField(Name.daemon, Type._boolean);
}
java_lang_Thread_tid = java_lang_Thread.requireDeclaredField(Name.tid, Type._long);
java_lang_Thread_eetop = java_lang_Thread.requireDeclaredField(Name.eetop, Type._long);
java_lang_Thread_contextClassLoader = java_lang_Thread.requireDeclaredField(Name.contextClassLoader, Type.java_lang_ClassLoader);

java_lang_Thread_name = java_lang_Thread.requireDeclaredField(Name.name, java_lang_String.getType());
Expand Down Expand Up @@ -712,12 +713,6 @@ public Meta(EspressoContext context) {
.klass(VERSION_9_OR_HIGHER, Type.jdk_internal_reflect_ConstructorAccessorImpl) //
.klass();

sun_misc_VM = diff() //
.klass(VERSION_8_OR_LOWER, Type.sun_misc_VM) //
.klass(VERSION_9_OR_HIGHER, Type.jdk_internal_misc_VM) //
.klass();
sun_misc_VM_toThreadState = sun_misc_VM.requireDeclaredMethod(Name.toThreadState, Signature.Thread$State_int);

sun_misc_Signal = diff() //
.klass(VERSION_8_OR_LOWER, Type.sun_misc_Signal) //
.klass(VERSION_9_OR_HIGHER, Type.jdk_internal_misc_Signal) //
Expand Down Expand Up @@ -1337,6 +1332,7 @@ private DiffVersionLoadHelper diff() {
public final Field java_lang_Thread_threadGroup;
public final Field java_lang_Thread$FieldHolder_group;
public final Field java_lang_Thread_tid;
public final Field java_lang_Thread_eetop;
public final ObjectKlass java_lang_Thread$Constants;
public final Field java_lang_Thread$Constants_VTHREAD_GROUP;
public final Field java_lang_Thread_contextClassLoader;
Expand Down Expand Up @@ -1372,8 +1368,6 @@ private DiffVersionLoadHelper diff() {
public final ObjectKlass java_lang_ref_Reference$ReferenceHandler;
public final ObjectKlass misc_InnocuousThread;

public final ObjectKlass sun_misc_VM;
public final Method sun_misc_VM_toThreadState;
public final ObjectKlass sun_reflect_ConstantPool;

public final ObjectKlass sun_misc_Signal;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

public class WindowsArgumentsCalculator extends AbstractArgumentsCalculator {
private int globalIndex;
private boolean skipNext;
private boolean inVarArg;

public WindowsArgumentsCalculator(Platform platform, VMStorage[] callIntRegs, VMStorage[] callFloatRegs, VMStorage intReturn, VMStorage floatReturn) {
super(platform, callIntRegs, callFloatRegs, intReturn, floatReturn);
Expand All @@ -36,15 +36,20 @@ public WindowsArgumentsCalculator(Platform platform, VMStorage[] callIntRegs, VM
public int getNextInputIndex(VMStorage reg, Klass type, VMStorage nextReg, Klass nextType) {
// TODO this currently depends on order but doesn't actually need to
assert isInt(type) || isFloat(type) : platform.toString(reg) + ": " + type;
if (skipNext) {
skipNext = false;
return SKIP;
}
if (isVarArg(reg, type, nextReg, nextType)) {
skipNext = true;
if (inVarArg) {
if (skipExtraVarArgMove(reg, type)) {
return SKIP;
}
inVarArg = false;
} else if (isVarArg(reg, type, nextReg, nextType)) {
// start of 2 registers used for the same argument
inVarArg = true;
if (skipExtraVarArgMove(reg, type)) {
return SKIP;
}
}
if (globalIndex < callIntRegs.length && callIntRegs[globalIndex].equals(reg)) {
assert isInt(type) || (skipNext && isFloat(type)) : platform.toString(reg) + ": " + type;
assert isInt(type) : platform.toString(reg) + ": " + type;
return globalIndex++;
}
if (globalIndex < callFloatRegs.length && callFloatRegs[globalIndex].equals(reg)) {
Expand Down Expand Up @@ -73,6 +78,10 @@ public boolean checkReturn(VMStorage reg, Klass type) {
return false;
}

private boolean skipExtraVarArgMove(VMStorage reg, Klass type) {
return isFloat(type) && reg.type(platform).isInteger();
}

@Override
public boolean isVarArg(VMStorage reg, Klass type, VMStorage nextReg, Klass nextType) {
if (nextReg == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,17 @@ private static boolean isSystemInnocuousThread(StaticObject thread, Meta meta) {
}

@TruffleBoundary
@Substitution(isTrivial = true)
@Substitution(isTrivial = true, versionFilter = VersionFilter.Java18OrEarlier.class)
public static void yield() {
Thread.yield();
}

@TruffleBoundary
@Substitution(isTrivial = true)
public static void yield0() {
Thread.yield();
}

@SuppressWarnings("unused")
@Substitution(hasReceiver = true)
@TruffleBoundary // Host Thread.setPriority inlines too deeply.
Expand All @@ -198,25 +204,12 @@ public static void setPriority0(@JavaType(Thread.class) StaticObject self, int n
hostThread.setPriority(newPriority);
}

@Substitution(hasReceiver = true)
@Substitution(hasReceiver = true, versionFilter = VersionFilter.Java18OrEarlier.class)
public static boolean isAlive(@JavaType(Thread.class) StaticObject self,
@Inject EspressoContext context) {
return context.getThreadAccess().isAlive(self);
}

@Substitution(hasReceiver = true)
abstract static class GetState extends SubstitutionNode {
abstract @JavaType(internalName = "Ljava/lang/Thread$State;") StaticObject execute(@JavaType(Thread.class) StaticObject self);

@Specialization
@JavaType(internalName = "Ljava/lang/Thread$State;")
StaticObject doDefault(@JavaType(Thread.class) StaticObject self,
@Bind("getContext()") EspressoContext context,
@Cached("create(context.getMeta().sun_misc_VM_toThreadState.getCallTarget())") DirectCallNode toThreadState) {
return (StaticObject) toThreadState.call(context.getThreadAccess().getState(self));
}
}

@SuppressWarnings("unused")
@Substitution
public static void registerNatives() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,23 @@

package com.oracle.truffle.espresso.substitutions;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.RootCallTarget;
import com.oracle.truffle.api.ThreadLocalAction;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.TruffleSafepoint;
import com.oracle.truffle.api.frame.Frame;
import com.oracle.truffle.api.frame.FrameInstance;
import com.oracle.truffle.api.frame.FrameInstanceVisitor;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.espresso.classfile.attributes.Local;
import com.oracle.truffle.espresso.classfile.attributes.LocalVariableTable;
import com.oracle.truffle.espresso.impl.Method;
import com.oracle.truffle.espresso.meta.EspressoError;
import com.oracle.truffle.espresso.nodes.EspressoFrame;
import com.oracle.truffle.espresso.nodes.EspressoRootNode;
import com.oracle.truffle.espresso.runtime.EspressoContext;
Expand All @@ -51,7 +56,14 @@ public static void registerNatives() {
@TruffleBoundary
public static boolean closeScope0(@JavaType(internalName = "Ljdk/internal/foreign/MemorySessionImpl;") StaticObject session, @Inject EspressoContext context) {
CloseScopedMemoryAction action = new CloseScopedMemoryAction(session);
context.getEnv().submitThreadLocal(null, action);
Future<Void> future = context.getEnv().submitThreadLocal(null, action);
TruffleSafepoint.setBlockedThreadInterruptible(null, f -> {
try {
future.get();
} catch (ExecutionException e) {
throw EspressoError.shouldNotReachHere(e);
}
}, future);
return !action.found;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ public StaticObject createGuestThreadFromHost(Thread hostThread, Meta meta, VM v
if (getJavaVersion().java17OrEarlier()) {
getThreadAccess().setPriority(guestThread, Thread.NORM_PRIORITY);
}
getThreadAccess().setEETopAlive(guestThread);
getThreadAccess().initializeHiddenFields(guestThread, hostThread, managedByEspresso);
registerThread(hostThread, guestThread);
assert getThreadAccess().getCurrentGuestThread() != null;
Expand Down Expand Up @@ -322,6 +323,7 @@ public void createMainThread(Meta meta) {
if (getJavaVersion().java17OrEarlier()) {
getThreadAccess().setPriority(mainThread, Thread.NORM_PRIORITY);
}
getThreadAccess().setEETopAlive(mainThread);
getThreadAccess().initializeHiddenFields(mainThread, hostThread, false);
registerMainThread(hostThread, mainThread);

Expand Down
Loading

0 comments on commit 40232e6

Please sign in to comment.