Skip to content
Permalink
Browse files
Merge
  • Loading branch information
JesperIRL committed Jun 18, 2021
2 parents 8f2456e + b8f073b commit b7d78a5b661e2b00f271298db3b6cc873cf754e7
Showing 119 changed files with 6,892 additions and 5,461 deletions.
@@ -767,6 +767,9 @@
"to stress handling of long counted loops: run inner loop" \
"for at most jint_max / StressLongCountedLoop") \
range(0, max_juint) \
\
product(bool, VerifyReceiverTypes, trueInDebug, DIAGNOSTIC, \
"Verify receiver types at runtime") \

// end of C2_FLAGS

@@ -515,6 +515,10 @@ bool LateInlineVirtualCallGenerator::do_late_inline_check(Compile* C, JVMState*

// Even if inlining is not allowed, a virtual call can be strength-reduced to a direct call.
bool allow_inline = C->inlining_incrementally();
if (!allow_inline && _callee->holder()->is_interface()) {
// Don't convert the interface call to a direct call guarded by an interface subtype check.
return false;
}
CallGenerator* cg = C->call_generator(_callee,
vtable_index(),
false /*call_does_dispatch*/,
@@ -953,12 +957,12 @@ JVMState* PredictedCallGenerator::generate(JVMState* jvms) {
}

if (kit.stopped()) {
// Instance exactly does not matches the desired type.
// Instance does not match the predicted type.
kit.set_jvms(slow_jvms);
return kit.transfer_exceptions_into_jvms();
}

// fall through if the instance exactly matches the desired type
// Fall through if the instance matches the desired type.
kit.replace_in_map(receiver, casted_receiver);

// Make the hot call:
@@ -72,6 +72,9 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool
Bytecodes::Code bytecode = caller->java_code_at_bci(bci);
guarantee(callee != NULL, "failed method resolution");

const bool is_virtual_or_interface = (bytecode == Bytecodes::_invokevirtual) ||
(bytecode == Bytecodes::_invokeinterface);

// Dtrace currently doesn't work unless all calls are vanilla
if (env()->dtrace_method_probes()) {
allow_inline = false;
@@ -164,6 +167,18 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool
bool should_delay = false;
if (ilt->ok_to_inline(callee, jvms, profile, should_delay)) {
CallGenerator* cg = CallGenerator::for_inline(callee, expected_uses);
// For optimized virtual calls assert at runtime that receiver object
// is a subtype of the inlined method holder. CHA can report a method
// as a unique target under an abstract method, but receiver type
// sometimes has a broader type. Similar scenario is possible with
// default methods when type system loses information about implemented
// interfaces.
if (cg != NULL && is_virtual_or_interface && !callee->is_static()) {
CallGenerator* trap_cg = CallGenerator::for_uncommon_trap(callee,
Deoptimization::Reason_receiver_constraint, Deoptimization::Action_none);

cg = CallGenerator::for_guarded_call(callee->holder(), trap_cg, cg);
}
if (cg != NULL) {
// Delay the inlining of this method to give us the
// opportunity to perform some high level optimizations
@@ -344,9 +359,16 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool
return CallGenerator::for_virtual_call(callee, vtable_index);
}
} else {
// Class Hierarchy Analysis or Type Profile reveals a unique target,
// or it is a static or special call.
return CallGenerator::for_direct_call(callee, should_delay_inlining(callee, jvms));
// Class Hierarchy Analysis or Type Profile reveals a unique target, or it is a static or special call.
CallGenerator* cg = CallGenerator::for_direct_call(callee, should_delay_inlining(callee, jvms));
// For optimized virtual calls assert at runtime that receiver object
// is a subtype of the method holder.
if (cg != NULL && is_virtual_or_interface && !callee->is_static()) {
CallGenerator* trap_cg = CallGenerator::for_uncommon_trap(callee,
Deoptimization::Reason_receiver_constraint, Deoptimization::Action_none);
cg = CallGenerator::for_guarded_call(callee->holder(), trap_cg, cg);
}
return cg;
}
}

@@ -1105,30 +1127,19 @@ ciMethod* Compile::optimize_inlining(ciMethod* caller, ciInstanceKlass* klass, c
return NULL;
}

ciInstanceKlass *ikl = receiver_type->klass()->as_instance_klass();
if (ikl->is_loaded() && ikl->is_initialized() && !ikl->is_interface() &&
(ikl == actual_receiver || ikl->is_subtype_of(actual_receiver))) {
ciInstanceKlass* receiver_klass = receiver_type->klass()->as_instance_klass();
if (receiver_klass->is_loaded() && receiver_klass->is_initialized() && !receiver_klass->is_interface() &&
(receiver_klass == actual_receiver || receiver_klass->is_subtype_of(actual_receiver))) {
// ikl is a same or better type than the original actual_receiver,
// e.g. static receiver from bytecodes.
actual_receiver = ikl;
actual_receiver = receiver_klass;
// Is the actual_receiver exact?
actual_receiver_is_exact = receiver_type->klass_is_exact();
}

ciInstanceKlass* calling_klass = caller->holder();
ciMethod* cha_monomorphic_target = callee->find_monomorphic_target(calling_klass, klass, actual_receiver, check_access);

// Validate receiver info against target method.
if (cha_monomorphic_target != NULL) {
bool has_receiver = !cha_monomorphic_target->is_static();
bool is_interface_holder = cha_monomorphic_target->holder()->is_interface();
if (has_receiver && !is_interface_holder) {
if (!cha_monomorphic_target->holder()->is_subtype_of(receiver_type->klass())) {
cha_monomorphic_target = NULL; // not a subtype
}
}
}

if (cha_monomorphic_target != NULL) {
// Hardwiring a virtual.
assert(!callee->can_be_statically_bound(), "should have been handled earlier");
@@ -2933,7 +2933,9 @@ Node* Phase::gen_subtype_check(Node* subklass, Node* superklass, Node** ctrl, No
}

Node* GraphKit::gen_subtype_check(Node* obj_or_subklass, Node* superklass) {
if (ExpandSubTypeCheckAtParseTime) {
bool expand_subtype_check = C->post_loop_opts_phase() || // macro node expansion is over
ExpandSubTypeCheckAtParseTime; // forced expansion
if (expand_subtype_check) {
MergeMemNode* mem = merged_memory();
Node* ctrl = control();
Node* subklass = obj_or_subklass;
@@ -1193,41 +1193,32 @@ void Parse::do_method_entry() {
make_dtrace_method_entry(method());
}

#ifdef ASSERT
// Narrow receiver type when it is too broad for the method being parsed.
ciInstanceKlass* callee_holder = method()->holder();
if (!method()->is_static()) {
ciInstanceKlass* callee_holder = method()->holder();
const Type* holder_type = TypeInstPtr::make(TypePtr::BotPTR, callee_holder);

Node* receiver_obj = local(0);
const TypeInstPtr* receiver_type = _gvn.type(receiver_obj)->isa_instptr();

if (receiver_type != NULL && !receiver_type->higher_equal(holder_type)) {
// Receiver should always be a subtype of callee holder.
// But, since C2 type system doesn't properly track interfaces,
// the invariant can't be expressed in the type system for default methods.
// Example: for unrelated C <: I and D <: I, (C `meet` D) = Object </: I.
assert(callee_holder->is_interface(), "missing subtype check");

#ifdef ASSERT
// Perform dynamic receiver subtype check against callee holder class w/ a halt on failure.
Node* holder_klass = _gvn.makecon(TypeKlassPtr::make(callee_holder));
Node* not_subtype_ctrl = gen_subtype_check(receiver_obj, holder_klass);
assert(!stopped(), "not a subtype");

Node* halt = _gvn.transform(new HaltNode(not_subtype_ctrl, frameptr(), "failed receiver subtype check"));
C->root()->add_req(halt);
#endif // ASSERT

// Receiver should always be a subtype of callee holder.
// But, since C2 type system doesn't properly track interfaces,
// the invariant on default methods can't be expressed in the type system.
// Example: for unrelated C <: I and D <: I, (C `meet` D) = Object </: I.
// (Downcasting interface receiver type to concrete class is fine, though it doesn't happen in practice.)
if (!callee_holder->is_interface()) {
assert(callee_holder->is_subtype_of(receiver_type->klass()), "sanity");
assert(!receiver_type->klass()->is_interface(), "interface receiver type");
receiver_type = receiver_type->join_speculative(holder_type)->is_instptr(); // keep speculative part
Node* casted_receiver_obj = _gvn.transform(new CheckCastPPNode(control(), receiver_obj, receiver_type));
set_local(0, casted_receiver_obj);
}

}
}
#endif // ASSERT

// If the method is synchronized, we need to construct a lock node, attach
// it to the Start node, and pin it there.
@@ -380,7 +380,7 @@ class Type {
Category category() const;

static const char* str(const Type* t);
#endif
#endif // !PRODUCT
void typerr(const Type *t) const; // Mixing types error

// Create basic type
@@ -1957,7 +1957,9 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* current, jint tr

ScopeDesc* trap_scope = cvf->scope();

if (TraceDeoptimization) {
bool is_receiver_constraint_failure = VerifyReceiverTypes && (reason == Deoptimization::Reason_receiver_constraint);

if (TraceDeoptimization || is_receiver_constraint_failure) {
ttyLocker ttyl;
tty->print_cr(" bci=%d pc=" INTPTR_FORMAT ", relative_pc=" INTPTR_FORMAT ", method=%s" JVMCI_ONLY(", debug_id=%d"), trap_scope->bci(), p2i(fr.pc()), fr.pc() - nm->code_begin(), trap_scope->method()->name_and_sig_as_C_string()
#if INCLUDE_JVMCI
@@ -2016,7 +2018,7 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* current, jint tr
trap_method->name_and_sig_as_C_string(), trap_bci, nm->compiler_name());

// Print a bunch of diagnostics, if requested.
if (TraceDeoptimization || LogCompilation) {
if (TraceDeoptimization || LogCompilation || is_receiver_constraint_failure) {
ResourceMark rm;
ttyLocker ttyl;
char buf[100];
@@ -2109,6 +2111,10 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* current, jint tr
}
// (End diagnostic printout.)

if (is_receiver_constraint_failure) {
fatal("missing receiver type check");
}

// Load class if necessary
if (unloaded_class_index >= 0) {
constantPoolHandle constants(current, trap_method->constants());
@@ -2598,6 +2604,7 @@ const char* Deoptimization::_trap_reason_name[] = {
"rtm_state_change",
"unstable_if",
"unstable_fused_if",
"receiver_constraint",
#if INCLUDE_JVMCI
"aliasing",
"transfer_to_interpreter",
@@ -89,6 +89,7 @@ class Deoptimization : AllStatic {
Reason_rtm_state_change, // rtm state change detected
Reason_unstable_if, // a branch predicted always false was taken
Reason_unstable_fused_if, // fused two ifs that had each one untaken branch. One is now taken.
Reason_receiver_constraint, // receiver subtype check failed
#if INCLUDE_JVMCI
Reason_aliasing, // optimistic assumption about aliasing failed
Reason_transfer_to_interpreter, // explicit transferToInterpreter()
@@ -2402,6 +2402,7 @@ typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
declare_constant(Deoptimization::Reason_rtm_state_change) \
declare_constant(Deoptimization::Reason_unstable_if) \
declare_constant(Deoptimization::Reason_unstable_fused_if) \
declare_constant(Deoptimization::Reason_receiver_constraint) \
NOT_ZERO(JVMCI_ONLY(declare_constant(Deoptimization::Reason_aliasing))) \
NOT_ZERO(JVMCI_ONLY(declare_constant(Deoptimization::Reason_transfer_to_interpreter))) \
NOT_ZERO(JVMCI_ONLY(declare_constant(Deoptimization::Reason_not_compiled_exception_handler))) \
@@ -179,14 +179,16 @@ protected void engineInit(int opmode, Key key,
init(opmode, key);
}

// init method. Check opmode and key, then call init(byte[]).
// init method. Check key, then call init(byte[]).
private void init(int opmode, Key key) throws InvalidKeyException {

// Cipher.init() already checks opmode to be:
// ENCRYPT_MODE/DECRYPT_MODE/WRAP_MODE/UNWRAP_MODE

if (lastKey != null) {
Arrays.fill(lastKey, (byte)0);
}
if ((opmode < Cipher.ENCRYPT_MODE) || (opmode > Cipher.UNWRAP_MODE)) {
throw new InvalidKeyException("Unknown opmode: " + opmode);
}

lastKey = getEncodedKey(key);
init(lastKey);
}
@@ -535,12 +535,11 @@ private static byte[] createRandomNonce(SecureRandom random) {
*/
private void init(int opmode, Key key, byte[] newNonce)
throws InvalidKeyException {
// Cipher.init() already checks opmode to be:
// ENCRYPT_MODE/DECRYPT_MODE/WRAP_MODE/UNWRAP_MODE
if ((opmode == Cipher.WRAP_MODE) || (opmode == Cipher.UNWRAP_MODE)) {
throw new UnsupportedOperationException(
"WRAP_MODE and UNWRAP_MODE are not currently supported");
} else if ((opmode != Cipher.ENCRYPT_MODE) &&
(opmode != Cipher.DECRYPT_MODE)) {
throw new InvalidKeyException("Unknown opmode: " + opmode);
}

// Make sure that the provided key and nonce are unique before
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2021, 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
@@ -261,7 +261,8 @@ private void init(int opmode, Key key, SecureRandom random,
encrypt = false;
break;
default:
throw new InvalidKeyException("Unknown mode: " + opmode);
// should never happen; checked by Cipher.init()
throw new AssertionError("Unknown mode: " + opmode);
}
RSAKey rsaKey = RSAKeyFactory.toRSAKey(key);
if (rsaKey instanceof RSAPublicKey) {
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2021, 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
@@ -1837,6 +1837,7 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
jint fd;
jint family;
jint ipv6_join_leave;
int res;

if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
@@ -1993,9 +1994,17 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
/*
* Join the multicast group.
*/
if (setsockopt(fd, IPPROTO_IP, (join ? IP_ADD_MEMBERSHIP:IP_DROP_MEMBERSHIP),
(char *) &mname, mname_len) < 0) {
res = setsockopt(fd, IPPROTO_IP, (join ? IP_ADD_MEMBERSHIP:IP_DROP_MEMBERSHIP),
(char *) &mname, mname_len);

#ifdef __APPLE__
if (res < 0 && errno == ENOMEM) {
res = setsockopt(fd, IPPROTO_IP, (join ? IP_ADD_MEMBERSHIP:IP_DROP_MEMBERSHIP),
(char *) &mname, mname_len);
}
#endif

if (res < 0) {
/*
* If IP_ADD_MEMBERSHIP returns ENOPROTOOPT on Linux and we've got
* IPv6 enabled then it's possible that the kernel has been fixed
@@ -2096,9 +2105,16 @@ static void mcast_join_leave(JNIEnv *env, jobject this,
#endif

/* Join the multicast group */
if (setsockopt(fd, IPPROTO_IPV6, (join ? ADD_MEMBERSHIP : DRP_MEMBERSHIP),
(char *) &mname6, sizeof (mname6)) < 0) {
res = setsockopt(fd, IPPROTO_IPV6, (join ? ADD_MEMBERSHIP : DRP_MEMBERSHIP),
(char *) &mname6, sizeof(mname6));

#ifdef __APPLE__
if (res < 0 && errno == ENOMEM) {
res = setsockopt(fd, IPPROTO_IPV6, (join ? ADD_MEMBERSHIP : DRP_MEMBERSHIP),
(char *) &mname6, sizeof(mname6));
}
#endif
if (res < 0) {
if (join) {
NET_ThrowCurrent(env, "setsockopt " S_ADD_MEMBERSHIP " failed");
} else {
@@ -53,7 +53,7 @@
* serializers (xml, html, text ...) that write output to a stream.
*
* @xsl.usage internal
* @LastModified: May 2021
* @LastModified: June 2021
*/
abstract public class ToStream extends SerializerBase {

@@ -1893,10 +1893,6 @@ else if (m_cdataTagOpen)
throw new SAXException(e);
}

// process the attributes now, because after this SAX call they might be gone
if (atts != null)
addAttributes(atts);

if (m_doIndent) {
m_ispreserveSpace = m_preserveSpaces.peekOrFalse();
m_preserveSpaces.push(m_ispreserveSpace);
@@ -1905,6 +1901,10 @@ else if (m_cdataTagOpen)
m_childNodeNum = 0;
}

// process the attributes now, because after this SAX call they might be gone
if (atts != null)
addAttributes(atts);

m_elemContext = m_elemContext.push(namespaceURI,localName,name);
m_isprevtext = false;

@@ -356,9 +356,13 @@ private void implInit(int opmode, Key key, byte[] iv, int tagLen,
encrypt = false;
requireReinit = false;
break;
default:
throw new InvalidAlgorithmParameterException
case Cipher.WRAP_MODE:
case Cipher.UNWRAP_MODE:
throw new UnsupportedOperationException
("Unsupported mode: " + opmode);
default:
// should never happen; checked by Cipher.init()
throw new AssertionError("Unknown mode: " + opmode);
}

// decryption without parameters is checked in all engineInit() calls

0 comments on commit b7d78a5

Please sign in to comment.