8232904: Update JVMCI
Reviewed-by: dnsimon
This commit is contained in:
parent
cd4d0bc498
commit
e15849a0f8
@ -2330,6 +2330,16 @@ C2V_VMENTRY_PREFIX(jboolean, isCurrentThreadAttached, (JNIEnv* env, jobject c2vm
|
||||
return true;
|
||||
C2V_END
|
||||
|
||||
C2V_VMENTRY_PREFIX(jlong, getCurrentJavaThread, (JNIEnv* env, jobject c2vm))
|
||||
if (base_thread == NULL) {
|
||||
// Called from unattached JVMCI shared library thread
|
||||
return 0L;
|
||||
}
|
||||
JVMCITraceMark jtm("getCurrentJavaThread");
|
||||
assert(base_thread->is_Java_thread(), "just checking");
|
||||
return (jlong) p2i(base_thread);
|
||||
C2V_END
|
||||
|
||||
C2V_VMENTRY_PREFIX(jboolean, attachCurrentThread, (JNIEnv* env, jobject c2vm, jboolean as_daemon))
|
||||
if (base_thread == NULL) {
|
||||
// Called from unattached JVMCI shared library thread
|
||||
@ -2743,6 +2753,7 @@ JNINativeMethod CompilerToVM::methods[] = {
|
||||
{CC "deleteGlobalHandle", CC "(J)V", FN_PTR(deleteGlobalHandle)},
|
||||
{CC "registerNativeMethods", CC "(" CLASS ")[J", FN_PTR(registerNativeMethods)},
|
||||
{CC "isCurrentThreadAttached", CC "()Z", FN_PTR(isCurrentThreadAttached)},
|
||||
{CC "getCurrentJavaThread", CC "()J", FN_PTR(getCurrentJavaThread)},
|
||||
{CC "attachCurrentThread", CC "(Z)Z", FN_PTR(attachCurrentThread)},
|
||||
{CC "detachCurrentThread", CC "()V", FN_PTR(detachCurrentThread)},
|
||||
{CC "translate", CC "(" OBJECT ")J", FN_PTR(translate)},
|
||||
|
@ -180,6 +180,7 @@
|
||||
nonstatic_field(JavaThread, _pending_transfer_to_interpreter, bool) \
|
||||
nonstatic_field(JavaThread, _jvmci_counters, jlong*) \
|
||||
nonstatic_field(JavaThread, _should_post_on_exceptions_flag, int) \
|
||||
nonstatic_field(JavaThread, _jni_environment, JNIEnv) \
|
||||
nonstatic_field(JavaThread, _reserved_stack_activation, address) \
|
||||
\
|
||||
static_field(java_lang_Class, _klass_offset, int) \
|
||||
@ -538,6 +539,7 @@
|
||||
declare_constant(FieldInfo::field_slots) \
|
||||
\
|
||||
declare_constant(InstanceKlass::linked) \
|
||||
declare_constant(InstanceKlass::being_initialized) \
|
||||
declare_constant(InstanceKlass::fully_initialized) \
|
||||
declare_constant(InstanceKlass::_misc_is_unsafe_anonymous) \
|
||||
\
|
||||
|
@ -966,6 +966,11 @@ final class CompilerToVM {
|
||||
*/
|
||||
native boolean isCurrentThreadAttached();
|
||||
|
||||
/**
|
||||
* @see HotSpotJVMCIRuntime#getCurrentJavaThread()
|
||||
*/
|
||||
native long getCurrentJavaThread();
|
||||
|
||||
/**
|
||||
* @see HotSpotJVMCIRuntime#attachCurrentThread
|
||||
*/
|
||||
|
@ -998,6 +998,14 @@ assert factories != null : "sanity";
|
||||
return compilerToVm.isCurrentThreadAttached();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the address of the HotSpot {@code JavaThread} C++ object for the current thread. This
|
||||
* will return {@code 0} if called from an unattached JVMCI shared library thread.
|
||||
*/
|
||||
public long getCurrentJavaThread() {
|
||||
return compilerToVm.getCurrentJavaThread();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the current thread is attached to the peer runtime.
|
||||
*
|
||||
|
@ -52,4 +52,13 @@ public abstract class HotSpotResolvedJavaType extends HotSpotJavaType implements
|
||||
}
|
||||
return arrayOfType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this type is currently being initialized. If a type is being initialized it
|
||||
* implies that it was {@link #isLinked() linked} and that the static initializer is currently
|
||||
* being run.
|
||||
*
|
||||
* @return {@code true} if this type is being initialized
|
||||
*/
|
||||
abstract boolean isBeingInitialized();
|
||||
}
|
||||
|
@ -359,6 +359,11 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
|
||||
return isArray() ? true : getInitState() == config().instanceKlassStateFullyInitialized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBeingInitialized() {
|
||||
return isArray() ? false : getInitState() == config().instanceKlassStateBeingInitialized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLinked() {
|
||||
return isArray() ? true : getInitState() >= config().instanceKlassStateLinked;
|
||||
@ -379,7 +384,7 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
|
||||
public void initialize() {
|
||||
if (!isInitialized()) {
|
||||
runtime().compilerToVm.ensureInitialized(this);
|
||||
assert isInitialized();
|
||||
assert isInitialized() || isBeingInitialized();
|
||||
}
|
||||
}
|
||||
|
||||
@ -578,11 +583,6 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
|
||||
return new AssumptionResult<>(resolvedMethod);
|
||||
}
|
||||
|
||||
if (resolvedMethod.canBeStaticallyBound()) {
|
||||
// No assumptions are required.
|
||||
return new AssumptionResult<>(resolvedMethod);
|
||||
}
|
||||
|
||||
ResolvedJavaMethod result = resolvedMethod.uniqueConcreteMethod(this);
|
||||
if (result != null) {
|
||||
return new AssumptionResult<>(result, new ConcreteMethod(method, this, result));
|
||||
|
@ -149,6 +149,11 @@ public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBeingInitialized() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLinked() {
|
||||
return true;
|
||||
|
@ -29,7 +29,6 @@ import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import jdk.vm.ci.common.JVMCIError;
|
||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
||||
import jdk.vm.ci.meta.SpeculationLog.SpeculationReasonEncoding;
|
||||
@ -37,8 +36,8 @@ import jdk.vm.ci.meta.SpeculationLog.SpeculationReasonEncoding;
|
||||
/**
|
||||
* Implements a {@link SpeculationReasonEncoding} that {@linkplain #getByteArray() produces} a byte
|
||||
* array. Data is added via a {@link DataOutputStream}. When producing the final byte array, if the
|
||||
* total length of data exceeds the length of a SHA-1 digest, then a SHA-1 digest of the data is
|
||||
* produced instead.
|
||||
* total length of data exceeds the length of a SHA-1 digest and a SHA-1 digest algorithm is
|
||||
* available, then a SHA-1 digest of the data is produced instead.
|
||||
*/
|
||||
final class HotSpotSpeculationEncoding extends ByteArrayOutputStream implements SpeculationReasonEncoding {
|
||||
|
||||
@ -152,21 +151,33 @@ final class HotSpotSpeculationEncoding extends ByteArrayOutputStream implements
|
||||
}
|
||||
|
||||
/**
|
||||
* Prototype SHA1 digest that is cloned before use.
|
||||
* Prototype SHA1 digest.
|
||||
*/
|
||||
private static final MessageDigest SHA1 = getSHA1();
|
||||
private static final int SHA1_LENGTH = SHA1.getDigestLength();
|
||||
private static final MessageDigest SHA1;
|
||||
|
||||
private static MessageDigest getSHA1() {
|
||||
/**
|
||||
* Cloning the prototype is quicker than calling {@link MessageDigest#getInstance(String)} every
|
||||
* time.
|
||||
*/
|
||||
private static final boolean SHA1_IS_CLONEABLE;
|
||||
private static final int SHA1_LENGTH;
|
||||
|
||||
static {
|
||||
MessageDigest sha1 = null;
|
||||
boolean sha1IsCloneable = false;
|
||||
try {
|
||||
MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
|
||||
sha1 = MessageDigest.getInstance("SHA-1");
|
||||
sha1.clone();
|
||||
return sha1;
|
||||
} catch (CloneNotSupportedException | NoSuchAlgorithmException e) {
|
||||
sha1IsCloneable = true;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
// Should never happen given that SHA-1 is mandated in a
|
||||
// compliant Java platform implementation.
|
||||
throw new JVMCIError("Expect a cloneable implementation of a SHA-1 message digest to be available", e);
|
||||
// compliant Java platform implementation. However, be
|
||||
// conservative and fall back to not using a digest.
|
||||
} catch (CloneNotSupportedException e) {
|
||||
}
|
||||
SHA1 = sha1;
|
||||
SHA1_IS_CLONEABLE = sha1IsCloneable;
|
||||
SHA1_LENGTH = SHA1 == null ? 20 : SHA1.getDigestLength();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -175,12 +186,12 @@ final class HotSpotSpeculationEncoding extends ByteArrayOutputStream implements
|
||||
*/
|
||||
byte[] getByteArray() {
|
||||
if (result == null) {
|
||||
if (count > SHA1_LENGTH) {
|
||||
if (SHA1 != null && count > SHA1_LENGTH) {
|
||||
try {
|
||||
MessageDigest md = (MessageDigest) SHA1.clone();
|
||||
MessageDigest md = SHA1_IS_CLONEABLE ? (MessageDigest) SHA1.clone() : MessageDigest.getInstance("SHA-1");
|
||||
md.update(buf, 0, count);
|
||||
result = md.digest();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
} catch (CloneNotSupportedException | NoSuchAlgorithmException e) {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
} else {
|
||||
|
@ -107,6 +107,7 @@ class HotSpotVMConfig extends HotSpotVMConfigAccess {
|
||||
|
||||
final int instanceKlassStateLinked = getConstant("InstanceKlass::linked", Integer.class);
|
||||
final int instanceKlassStateFullyInitialized = getConstant("InstanceKlass::fully_initialized", Integer.class);
|
||||
final int instanceKlassStateBeingInitialized = getConstant("InstanceKlass::being_initialized", Integer.class);
|
||||
final int instanceKlassMiscIsUnsafeAnonymous = getConstant("InstanceKlass::_misc_is_unsafe_anonymous", Integer.class);
|
||||
|
||||
final int annotationsFieldAnnotationsOffset = getFieldOffset("Annotations::_fields_annotations", Integer.class, "Array<AnnotationArray*>*");
|
||||
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package jdk.vm.ci.hotspot;
|
||||
|
||||
/**
|
||||
* A wrapper that holds a strong reference to a "master" speculation log that
|
||||
* {@linkplain HotSpotSpeculationLog#managesFailedSpeculations() manages} the failed speculations
|
||||
* list.
|
||||
*/
|
||||
public class SharedHotSpotSpeculationLog extends HotSpotSpeculationLog {
|
||||
private final HotSpotSpeculationLog masterLog;
|
||||
|
||||
public SharedHotSpotSpeculationLog(HotSpotSpeculationLog masterLog) {
|
||||
super(masterLog.getFailedSpeculationsAddress());
|
||||
this.masterLog = masterLog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return masterLog.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
package jdk.vm.ci.meta;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import jdk.vm.ci.meta.SpeculationLog.SpeculationReason;
|
||||
|
||||
/**
|
||||
* An implementation of {@link SpeculationReason} based on encoded values.
|
||||
*/
|
||||
public class EncodedSpeculationReason implements SpeculationReason {
|
||||
final int groupId;
|
||||
final String groupName;
|
||||
final Object[] context;
|
||||
private SpeculationLog.SpeculationReasonEncoding encoding;
|
||||
|
||||
public EncodedSpeculationReason(int groupId, String groupName, Object[] context) {
|
||||
this.groupId = groupId;
|
||||
this.groupName = groupName;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof EncodedSpeculationReason) {
|
||||
if (obj instanceof EncodedSpeculationReason) {
|
||||
EncodedSpeculationReason that = (EncodedSpeculationReason) obj;
|
||||
return this.groupId == that.groupId && Arrays.equals(this.context, that.context);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpeculationLog.SpeculationReasonEncoding encode(Supplier<SpeculationLog.SpeculationReasonEncoding> encodingSupplier) {
|
||||
if (encoding == null) {
|
||||
encoding = encodingSupplier.get();
|
||||
encoding.addInt(groupId);
|
||||
for (Object o : context) {
|
||||
if (o == null) {
|
||||
encoding.addInt(0);
|
||||
} else {
|
||||
addNonNullObject(encoding, o);
|
||||
}
|
||||
}
|
||||
}
|
||||
return encoding;
|
||||
}
|
||||
|
||||
static void addNonNullObject(SpeculationLog.SpeculationReasonEncoding encoding, Object o) {
|
||||
Class<? extends Object> c = o.getClass();
|
||||
if (c == String.class) {
|
||||
encoding.addString((String) o);
|
||||
} else if (c == Byte.class) {
|
||||
encoding.addByte((Byte) o);
|
||||
} else if (c == Short.class) {
|
||||
encoding.addShort((Short) o);
|
||||
} else if (c == Character.class) {
|
||||
encoding.addShort((Character) o);
|
||||
} else if (c == Integer.class) {
|
||||
encoding.addInt((Integer) o);
|
||||
} else if (c == Long.class) {
|
||||
encoding.addLong((Long) o);
|
||||
} else if (c == Float.class) {
|
||||
encoding.addInt(Float.floatToRawIntBits((Float) o));
|
||||
} else if (c == Double.class) {
|
||||
encoding.addLong(Double.doubleToRawLongBits((Double) o));
|
||||
} else if (o instanceof Enum) {
|
||||
encoding.addInt(((Enum<?>) o).ordinal());
|
||||
} else if (o instanceof ResolvedJavaMethod) {
|
||||
encoding.addMethod((ResolvedJavaMethod) o);
|
||||
} else if (o instanceof ResolvedJavaType) {
|
||||
encoding.addType((ResolvedJavaType) o);
|
||||
} else if (o instanceof ResolvedJavaField) {
|
||||
encoding.addField((ResolvedJavaField) o);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported type for encoding: " + c.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return groupId + Arrays.hashCode(this.context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s@%d%s", groupName, groupId, Arrays.toString(context));
|
||||
}
|
||||
}
|
@ -78,7 +78,8 @@ public class TestHotSpotSpeculationLog {
|
||||
public synchronized void testFailedSpeculations() {
|
||||
HotSpotSpeculationLog log = new HotSpotSpeculationLog();
|
||||
DummyReason reason1 = new DummyReason("dummy1");
|
||||
DummyReason reason2 = new DummyReason("dummy2");
|
||||
String longName = new String(new char[2000]).replace('\0', 'X');
|
||||
DummyReason reason2 = new DummyReason(longName);
|
||||
Assert.assertTrue(log.maySpeculate(reason1));
|
||||
Assert.assertTrue(log.maySpeculate(reason2));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user