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;
|
return true;
|
||||||
C2V_END
|
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))
|
C2V_VMENTRY_PREFIX(jboolean, attachCurrentThread, (JNIEnv* env, jobject c2vm, jboolean as_daemon))
|
||||||
if (base_thread == NULL) {
|
if (base_thread == NULL) {
|
||||||
// Called from unattached JVMCI shared library thread
|
// Called from unattached JVMCI shared library thread
|
||||||
@ -2743,6 +2753,7 @@ JNINativeMethod CompilerToVM::methods[] = {
|
|||||||
{CC "deleteGlobalHandle", CC "(J)V", FN_PTR(deleteGlobalHandle)},
|
{CC "deleteGlobalHandle", CC "(J)V", FN_PTR(deleteGlobalHandle)},
|
||||||
{CC "registerNativeMethods", CC "(" CLASS ")[J", FN_PTR(registerNativeMethods)},
|
{CC "registerNativeMethods", CC "(" CLASS ")[J", FN_PTR(registerNativeMethods)},
|
||||||
{CC "isCurrentThreadAttached", CC "()Z", FN_PTR(isCurrentThreadAttached)},
|
{CC "isCurrentThreadAttached", CC "()Z", FN_PTR(isCurrentThreadAttached)},
|
||||||
|
{CC "getCurrentJavaThread", CC "()J", FN_PTR(getCurrentJavaThread)},
|
||||||
{CC "attachCurrentThread", CC "(Z)Z", FN_PTR(attachCurrentThread)},
|
{CC "attachCurrentThread", CC "(Z)Z", FN_PTR(attachCurrentThread)},
|
||||||
{CC "detachCurrentThread", CC "()V", FN_PTR(detachCurrentThread)},
|
{CC "detachCurrentThread", CC "()V", FN_PTR(detachCurrentThread)},
|
||||||
{CC "translate", CC "(" OBJECT ")J", FN_PTR(translate)},
|
{CC "translate", CC "(" OBJECT ")J", FN_PTR(translate)},
|
||||||
|
@ -180,6 +180,7 @@
|
|||||||
nonstatic_field(JavaThread, _pending_transfer_to_interpreter, bool) \
|
nonstatic_field(JavaThread, _pending_transfer_to_interpreter, bool) \
|
||||||
nonstatic_field(JavaThread, _jvmci_counters, jlong*) \
|
nonstatic_field(JavaThread, _jvmci_counters, jlong*) \
|
||||||
nonstatic_field(JavaThread, _should_post_on_exceptions_flag, int) \
|
nonstatic_field(JavaThread, _should_post_on_exceptions_flag, int) \
|
||||||
|
nonstatic_field(JavaThread, _jni_environment, JNIEnv) \
|
||||||
nonstatic_field(JavaThread, _reserved_stack_activation, address) \
|
nonstatic_field(JavaThread, _reserved_stack_activation, address) \
|
||||||
\
|
\
|
||||||
static_field(java_lang_Class, _klass_offset, int) \
|
static_field(java_lang_Class, _klass_offset, int) \
|
||||||
@ -538,6 +539,7 @@
|
|||||||
declare_constant(FieldInfo::field_slots) \
|
declare_constant(FieldInfo::field_slots) \
|
||||||
\
|
\
|
||||||
declare_constant(InstanceKlass::linked) \
|
declare_constant(InstanceKlass::linked) \
|
||||||
|
declare_constant(InstanceKlass::being_initialized) \
|
||||||
declare_constant(InstanceKlass::fully_initialized) \
|
declare_constant(InstanceKlass::fully_initialized) \
|
||||||
declare_constant(InstanceKlass::_misc_is_unsafe_anonymous) \
|
declare_constant(InstanceKlass::_misc_is_unsafe_anonymous) \
|
||||||
\
|
\
|
||||||
|
@ -966,6 +966,11 @@ final class CompilerToVM {
|
|||||||
*/
|
*/
|
||||||
native boolean isCurrentThreadAttached();
|
native boolean isCurrentThreadAttached();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see HotSpotJVMCIRuntime#getCurrentJavaThread()
|
||||||
|
*/
|
||||||
|
native long getCurrentJavaThread();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see HotSpotJVMCIRuntime#attachCurrentThread
|
* @see HotSpotJVMCIRuntime#attachCurrentThread
|
||||||
*/
|
*/
|
||||||
|
@ -998,6 +998,14 @@ assert factories != null : "sanity";
|
|||||||
return compilerToVm.isCurrentThreadAttached();
|
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.
|
* Ensures the current thread is attached to the peer runtime.
|
||||||
*
|
*
|
||||||
|
@ -52,4 +52,13 @@ public abstract class HotSpotResolvedJavaType extends HotSpotJavaType implements
|
|||||||
}
|
}
|
||||||
return arrayOfType;
|
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;
|
return isArray() ? true : getInitState() == config().instanceKlassStateFullyInitialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBeingInitialized() {
|
||||||
|
return isArray() ? false : getInitState() == config().instanceKlassStateBeingInitialized;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLinked() {
|
public boolean isLinked() {
|
||||||
return isArray() ? true : getInitState() >= config().instanceKlassStateLinked;
|
return isArray() ? true : getInitState() >= config().instanceKlassStateLinked;
|
||||||
@ -379,7 +384,7 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
|
|||||||
public void initialize() {
|
public void initialize() {
|
||||||
if (!isInitialized()) {
|
if (!isInitialized()) {
|
||||||
runtime().compilerToVm.ensureInitialized(this);
|
runtime().compilerToVm.ensureInitialized(this);
|
||||||
assert isInitialized();
|
assert isInitialized() || isBeingInitialized();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -578,11 +583,6 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
|
|||||||
return new AssumptionResult<>(resolvedMethod);
|
return new AssumptionResult<>(resolvedMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resolvedMethod.canBeStaticallyBound()) {
|
|
||||||
// No assumptions are required.
|
|
||||||
return new AssumptionResult<>(resolvedMethod);
|
|
||||||
}
|
|
||||||
|
|
||||||
ResolvedJavaMethod result = resolvedMethod.uniqueConcreteMethod(this);
|
ResolvedJavaMethod result = resolvedMethod.uniqueConcreteMethod(this);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
return new AssumptionResult<>(result, new ConcreteMethod(method, this, result));
|
return new AssumptionResult<>(result, new ConcreteMethod(method, this, result));
|
||||||
|
@ -149,6 +149,11 @@ public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBeingInitialized() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLinked() {
|
public boolean isLinked() {
|
||||||
return true;
|
return true;
|
||||||
|
@ -29,7 +29,6 @@ import java.security.MessageDigest;
|
|||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import jdk.vm.ci.common.JVMCIError;
|
|
||||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
import jdk.vm.ci.meta.ResolvedJavaType;
|
||||||
import jdk.vm.ci.meta.SpeculationLog.SpeculationReasonEncoding;
|
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
|
* 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
|
* 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
|
* total length of data exceeds the length of a SHA-1 digest and a SHA-1 digest algorithm is
|
||||||
* produced instead.
|
* available, then a SHA-1 digest of the data is produced instead.
|
||||||
*/
|
*/
|
||||||
final class HotSpotSpeculationEncoding extends ByteArrayOutputStream implements SpeculationReasonEncoding {
|
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 MessageDigest SHA1;
|
||||||
private static final int SHA1_LENGTH = SHA1.getDigestLength();
|
|
||||||
|
|
||||||
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 {
|
try {
|
||||||
MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
|
sha1 = MessageDigest.getInstance("SHA-1");
|
||||||
sha1.clone();
|
sha1.clone();
|
||||||
return sha1;
|
sha1IsCloneable = true;
|
||||||
} catch (CloneNotSupportedException | NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
// Should never happen given that SHA-1 is mandated in a
|
// Should never happen given that SHA-1 is mandated in a
|
||||||
// compliant Java platform implementation.
|
// compliant Java platform implementation. However, be
|
||||||
throw new JVMCIError("Expect a cloneable implementation of a SHA-1 message digest to be available", e);
|
// 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() {
|
byte[] getByteArray() {
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
if (count > SHA1_LENGTH) {
|
if (SHA1 != null && count > SHA1_LENGTH) {
|
||||||
try {
|
try {
|
||||||
MessageDigest md = (MessageDigest) SHA1.clone();
|
MessageDigest md = SHA1_IS_CLONEABLE ? (MessageDigest) SHA1.clone() : MessageDigest.getInstance("SHA-1");
|
||||||
md.update(buf, 0, count);
|
md.update(buf, 0, count);
|
||||||
result = md.digest();
|
result = md.digest();
|
||||||
} catch (CloneNotSupportedException e) {
|
} catch (CloneNotSupportedException | NoSuchAlgorithmException e) {
|
||||||
throw new InternalError(e);
|
throw new InternalError(e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -107,6 +107,7 @@ class HotSpotVMConfig extends HotSpotVMConfigAccess {
|
|||||||
|
|
||||||
final int instanceKlassStateLinked = getConstant("InstanceKlass::linked", Integer.class);
|
final int instanceKlassStateLinked = getConstant("InstanceKlass::linked", Integer.class);
|
||||||
final int instanceKlassStateFullyInitialized = getConstant("InstanceKlass::fully_initialized", 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 instanceKlassMiscIsUnsafeAnonymous = getConstant("InstanceKlass::_misc_is_unsafe_anonymous", Integer.class);
|
||||||
|
|
||||||
final int annotationsFieldAnnotationsOffset = getFieldOffset("Annotations::_fields_annotations", Integer.class, "Array<AnnotationArray*>*");
|
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() {
|
public synchronized void testFailedSpeculations() {
|
||||||
HotSpotSpeculationLog log = new HotSpotSpeculationLog();
|
HotSpotSpeculationLog log = new HotSpotSpeculationLog();
|
||||||
DummyReason reason1 = new DummyReason("dummy1");
|
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(reason1));
|
||||||
Assert.assertTrue(log.maySpeculate(reason2));
|
Assert.assertTrue(log.maySpeculate(reason2));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user