diff --git a/src/hotspot/share/classfile/classListParser.cpp b/src/hotspot/share/classfile/classListParser.cpp index b123a1fd959..5a7766f0ce6 100644 --- a/src/hotspot/share/classfile/classListParser.cpp +++ b/src/hotspot/share/classfile/classListParser.cpp @@ -467,6 +467,10 @@ void ClassListParser::resolve_indy(Symbol* class_name_symbol, TRAPS) { Klass* klass = SystemDictionary::resolve_or_fail(class_name_symbol, class_loader, protection_domain, true, THREAD); // FIXME should really be just a lookup if (klass != NULL && klass->is_instance_klass()) { InstanceKlass* ik = InstanceKlass::cast(klass); + if (SystemDictionaryShared::has_class_failed_verification(ik)) { + // don't attempt to resolve indy on classes that has previously failed verification + return; + } MetaspaceShared::try_link_class(ik, THREAD); assert(!HAS_PENDING_EXCEPTION, "unexpected exception"); diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp index 4623dbb2c64..d7baa8cdb1d 100644 --- a/src/hotspot/share/classfile/vmSymbols.hpp +++ b/src/hotspot/share/classfile/vmSymbols.hpp @@ -353,6 +353,7 @@ /* Panama Support */ \ template(jdk_internal_invoke_NativeEntryPoint, "jdk/internal/invoke/NativeEntryPoint") \ template(jdk_internal_invoke_NativeEntryPoint_signature, "Ljdk/internal/invoke/NativeEntryPoint;") \ + template(jdk_incubator_foreign_MemoryAccess, "jdk/incubator/foreign/MemoryAccess") \ \ /* Support for JVMCI */ \ JVMCI_VM_SYMBOLS_DO(template, do_alias) \ diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index 2971733e883..351a1bb7e2b 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -1270,7 +1270,6 @@ void nmethod::make_unloaded() { JVMCINMethodData* nmethod_data = jvmci_nmethod_data(); if (nmethod_data != NULL) { nmethod_data->invalidate_nmethod_mirror(this); - nmethod_data->clear_nmethod_mirror(this); } #endif } diff --git a/src/hotspot/share/jfr/support/jfrAllocationTracer.cpp b/src/hotspot/share/jfr/support/jfrAllocationTracer.cpp index 5f62f3e3740..ddf22be2748 100644 --- a/src/hotspot/share/jfr/support/jfrAllocationTracer.cpp +++ b/src/hotspot/share/jfr/support/jfrAllocationTracer.cpp @@ -30,11 +30,12 @@ #include "runtime/thread.hpp" JfrAllocationTracer::JfrAllocationTracer(const Klass* klass, HeapWord* obj, size_t alloc_size, bool outside_tlab, Thread* thread) : _tl(NULL) { - JfrObjectAllocationSample::send_event(klass, alloc_size, outside_tlab, thread); if (LeakProfiler::is_running()) { _tl = thread->jfr_thread_local(); LeakProfiler::sample(obj, alloc_size, thread->as_Java_thread()); } + // Let this happen after LeakProfiler::sample, to possibly reuse a cached stacktrace. + JfrObjectAllocationSample::send_event(klass, alloc_size, outside_tlab, thread); } JfrAllocationTracer::~JfrAllocationTracer() { diff --git a/src/hotspot/share/jvmci/jvmciRuntime.cpp b/src/hotspot/share/jvmci/jvmciRuntime.cpp index e8f0ba69898..a8d9c52ff0f 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.cpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp @@ -714,6 +714,12 @@ void JVMCINMethodData::invalidate_nmethod_mirror(nmethod* nm) { HotSpotJVMCI::InstalledCode::set_entryPoint(jvmciEnv, nmethod_mirror, 0); } } + + if (_nmethod_mirror_index != -1 && nm->is_unloaded()) { + // Drop the reference to the nmethod mirror object but don't clear the actual oop reference. Otherwise + // it would appear that the nmethod didn't need to be unloaded in the first place. + _nmethod_mirror_index = -1; + } } JVMCIRuntime::JVMCIRuntime(int id) { diff --git a/src/hotspot/share/oops/methodData.cpp b/src/hotspot/share/oops/methodData.cpp index fb314986d76..5b724166514 100644 --- a/src/hotspot/share/oops/methodData.cpp +++ b/src/hotspot/share/oops/methodData.cpp @@ -1601,6 +1601,18 @@ bool MethodData::profile_unsafe(const methodHandle& m, int bci) { return false; } +bool MethodData::profile_memory_access(const methodHandle& m, int bci) { + Bytecode_invoke inv(m , bci); + if (inv.is_invokestatic()) { + if (inv.klass() == vmSymbols::jdk_incubator_foreign_MemoryAccess()) { + if (inv.name()->starts_with("get") || inv.name()->starts_with("set")) { + return true; + } + } + } + return false; +} + int MethodData::profile_arguments_flag() { return TypeProfileLevel % 10; } @@ -1630,6 +1642,10 @@ bool MethodData::profile_arguments_for_invoke(const methodHandle& m, int bci) { return true; } + if (profile_memory_access(m, bci)) { + return true; + } + assert(profile_arguments_jsr292_only(), "inconsistent"); return profile_jsr292(m, bci); } diff --git a/src/hotspot/share/oops/methodData.hpp b/src/hotspot/share/oops/methodData.hpp index 83c7bd6fd6d..464e783b2a4 100644 --- a/src/hotspot/share/oops/methodData.hpp +++ b/src/hotspot/share/oops/methodData.hpp @@ -2148,6 +2148,7 @@ private: static bool profile_jsr292(const methodHandle& m, int bci); static bool profile_unsafe(const methodHandle& m, int bci); + static bool profile_memory_access(const methodHandle& m, int bci); static int profile_arguments_flag(); static bool profile_all_arguments(); static bool profile_arguments_for_invoke(const methodHandle& m, int bci); diff --git a/src/hotspot/share/opto/loopnode.hpp b/src/hotspot/share/opto/loopnode.hpp index aa89d475ef8..5eb5efaaa60 100644 --- a/src/hotspot/share/opto/loopnode.hpp +++ b/src/hotspot/share/opto/loopnode.hpp @@ -1451,6 +1451,7 @@ public: // Mark an IfNode as being dominated by a prior test, // without actually altering the CFG (and hence IDOM info). void dominated_by( Node *prevdom, Node *iff, bool flip = false, bool exclude_loop_predicate = false ); + bool no_dependent_zero_check(Node* n) const; // Split Node 'n' through merge point Node *split_thru_region( Node *n, Node *region ); diff --git a/src/hotspot/share/opto/loopopts.cpp b/src/hotspot/share/opto/loopopts.cpp index 52e56fad024..8c160c058cf 100644 --- a/src/hotspot/share/opto/loopopts.cpp +++ b/src/hotspot/share/opto/loopopts.cpp @@ -278,18 +278,23 @@ void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff, bool flip, bool exc return; // Let IGVN transformation change control dependence. } - IdealLoopTree *old_loop = get_loop(dp); + IdealLoopTree* old_loop = get_loop(dp); for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) { Node* cd = dp->fast_out(i); // Control-dependent node - if (cd->depends_only_on_test()) { + // Do not rewire Div and Mod nodes which could have a zero divisor to avoid skipping their zero check. + if (cd->depends_only_on_test() && no_dependent_zero_check(cd)) { assert(cd->in(0) == dp, ""); _igvn.replace_input_of(cd, 0, prevdom); set_early_ctrl(cd, false); - IdealLoopTree *new_loop = get_loop(get_ctrl(cd)); + IdealLoopTree* new_loop = get_loop(get_ctrl(cd)); if (old_loop != new_loop) { - if (!old_loop->_child) old_loop->_body.yank(cd); - if (!new_loop->_child) new_loop->_body.push(cd); + if (!old_loop->_child) { + old_loop->_body.yank(cd); + } + if (!new_loop->_child) { + new_loop->_body.push(cd); + } } --i; --imax; @@ -297,6 +302,25 @@ void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff, bool flip, bool exc } } +// Check if the type of a divisor of a Div or Mod node includes zero. +bool PhaseIdealLoop::no_dependent_zero_check(Node* n) const { + switch (n->Opcode()) { + case Op_DivI: + case Op_ModI: { + // Type of divisor includes 0? + const TypeInt* type_divisor = _igvn.type(n->in(2))->is_int(); + return (type_divisor->_hi < 0 || type_divisor->_lo > 0); + } + case Op_DivL: + case Op_ModL: { + // Type of divisor includes 0? + const TypeLong* type_divisor = _igvn.type(n->in(2))->is_long(); + return (type_divisor->_hi < 0 || type_divisor->_lo > 0); + } + } + return true; +} + //------------------------------has_local_phi_input---------------------------- // Return TRUE if 'n' has Phi inputs from its local block and no other // block-local inputs (all non-local-phi inputs come from earlier blocks) diff --git a/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java b/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java index 64a94d7d0e7..1fdcd81accd 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, 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 @@ -25,6 +25,7 @@ package com.sun.crypto.provider; +import java.util.Arrays; import java.util.Locale; import java.security.*; @@ -347,28 +348,40 @@ public final class RSACipher extends CipherSpi { throw new IllegalBlockSizeException("Data must not be longer " + "than " + buffer.length + " bytes"); } + byte[] paddingCopy = null; + byte[] result = null; try { - byte[] data; switch (mode) { case MODE_SIGN: - data = padding.pad(buffer, 0, bufOfs); - return RSACore.rsa(data, privateKey, true); + paddingCopy = padding.pad(buffer, 0, bufOfs); + result = RSACore.rsa(paddingCopy, privateKey, true); + break; case MODE_VERIFY: byte[] verifyBuffer = RSACore.convert(buffer, 0, bufOfs); - data = RSACore.rsa(verifyBuffer, publicKey); - return padding.unpad(data); + paddingCopy = RSACore.rsa(verifyBuffer, publicKey); + result = padding.unpad(paddingCopy); + break; case MODE_ENCRYPT: - data = padding.pad(buffer, 0, bufOfs); - return RSACore.rsa(data, publicKey); + paddingCopy = padding.pad(buffer, 0, bufOfs); + result = RSACore.rsa(paddingCopy, publicKey); + break; case MODE_DECRYPT: byte[] decryptBuffer = RSACore.convert(buffer, 0, bufOfs); - data = RSACore.rsa(decryptBuffer, privateKey, false); - return padding.unpad(data); + paddingCopy = RSACore.rsa(decryptBuffer, privateKey, false); + result = padding.unpad(paddingCopy); + break; default: throw new AssertionError("Internal error"); } + return result; } finally { + Arrays.fill(buffer, 0, bufOfs, (byte)0); bufOfs = 0; + if (paddingCopy != null // will not happen + && paddingCopy != buffer // already cleaned + && paddingCopy != result) { // DO NOT CLEAN, THIS IS RESULT! + Arrays.fill(paddingCopy, (byte)0); + } } } @@ -404,6 +417,7 @@ public final class RSACipher extends CipherSpi { byte[] result = doFinal(); int n = result.length; System.arraycopy(result, 0, out, outOfs, n); + Arrays.fill(result, (byte)0); return n; } @@ -414,15 +428,19 @@ public final class RSACipher extends CipherSpi { if ((encoded == null) || (encoded.length == 0)) { throw new InvalidKeyException("Could not obtain encoded key"); } - if (encoded.length > buffer.length) { - throw new InvalidKeyException("Key is too long for wrapping"); - } - update(encoded, 0, encoded.length); try { - return doFinal(); - } catch (BadPaddingException e) { - // should not occur - throw new InvalidKeyException("Wrapping failed", e); + if (encoded.length > buffer.length) { + throw new InvalidKeyException("Key is too long for wrapping"); + } + update(encoded, 0, encoded.length); + try { + return doFinal(); + } catch (BadPaddingException e) { + // should not occur + throw new InvalidKeyException("Wrapping failed", e); + } + } finally { + Arrays.fill(encoded, (byte)0); } } @@ -453,20 +471,26 @@ public final class RSACipher extends CipherSpi { throw new InvalidKeyException("Unwrapping failed", e); } - if (isTlsRsaPremasterSecret) { - if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) { - throw new IllegalStateException( - "No TlsRsaPremasterSecretParameterSpec specified"); + try { + if (isTlsRsaPremasterSecret) { + if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) { + throw new IllegalStateException( + "No TlsRsaPremasterSecretParameterSpec specified"); + } + + // polish the TLS premaster secret + encoded = KeyUtil.checkTlsPreMasterSecretKey( + ((TlsRsaPremasterSecretParameterSpec) spec).getClientVersion(), + ((TlsRsaPremasterSecretParameterSpec) spec).getServerVersion(), + random, encoded, (failover != null)); } - // polish the TLS premaster secret - encoded = KeyUtil.checkTlsPreMasterSecretKey( - ((TlsRsaPremasterSecretParameterSpec)spec).getClientVersion(), - ((TlsRsaPremasterSecretParameterSpec)spec).getServerVersion(), - random, encoded, (failover != null)); + return ConstructKeys.constructKey(encoded, algorithm, type); + } finally { + if (encoded != null) { + Arrays.fill(encoded, (byte) 0); + } } - - return ConstructKeys.constructKey(encoded, algorithm, type); } // see JCE spec diff --git a/src/java.base/share/classes/java/lang/Enum.java b/src/java.base/share/classes/java/lang/Enum.java index cc9b3c20b00..54a1f09c9eb 100644 --- a/src/java.base/share/classes/java/lang/Enum.java +++ b/src/java.base/share/classes/java/lang/Enum.java @@ -66,7 +66,7 @@ import static java.util.Objects.requireNonNull; * @see Class#getEnumConstants() * @see java.util.EnumSet * @see java.util.EnumMap - * @jls 8.9 Enum Types + * @jls 8.9 Enum Classes * @jls 8.9.3 Enum Members * @since 1.5 */ diff --git a/src/java.base/share/classes/java/lang/annotation/Annotation.java b/src/java.base/share/classes/java/lang/annotation/Annotation.java index cd1ed787ceb..07549913831 100644 --- a/src/java.base/share/classes/java/lang/annotation/Annotation.java +++ b/src/java.base/share/classes/java/lang/annotation/Annotation.java @@ -26,16 +26,16 @@ package java.lang.annotation; /** - * The common interface extended by all annotation types. Note that an + * The common interface extended by all annotation interfaces. Note that an * interface that manually extends this one does not define - * an annotation type. Also note that this interface does not itself - * define an annotation type. + * an annotation interface. Also note that this interface does not itself + * define an annotation interface. * - * More information about annotation types can be found in section {@jls 9.6} of - * The Java Language Specification. + * More information about annotation interfaces can be found in section + * {@jls 9.6} of The Java Language Specification. * * The {@link java.lang.reflect.AnnotatedElement} interface discusses - * compatibility concerns when evolving an annotation type from being + * compatibility concerns when evolving an annotation interface from being * non-repeatable to being repeatable. * * @author Josh Bloch @@ -46,7 +46,7 @@ public interface Annotation { * Returns true if the specified object represents an annotation * that is logically equivalent to this one. In other words, * returns true if the specified object is an instance of the same - * annotation type as this instance, all of whose members are equal + * annotation interface as this instance, all of whose members are equal * to the corresponding member of this annotation, as defined below: *