Skip to content
This repository has been archived by the owner on May 29, 2024. It is now read-only.

Commit

Permalink
[GR-35073] Merge in jdk-11.0.14-ga(21.3).
Browse files Browse the repository at this point in the history
PullRequest: labsjdk-ce-11/236
  • Loading branch information
marwan-hallaoui committed Jan 20, 2022
2 parents 17ff4d9 + ea812b2 commit f3911e2
Show file tree
Hide file tree
Showing 89 changed files with 6,744 additions and 1,458 deletions.
28 changes: 26 additions & 2 deletions src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,32 @@ LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_o
LIR_Address* addr;
if (index_opr->is_constant()) {
int elem_size = type2aelembytes(type);
addr = new LIR_Address(array_opr,
offset_in_bytes + (intx)(index_opr->as_jint()) * elem_size, type);
#ifdef _LP64
jint index = index_opr->as_jint();
jlong disp = offset_in_bytes + (jlong)(index) * elem_size;
if (disp > max_jint) {
// Displacement overflow. Cannot directly use instruction with 32-bit displacement for 64-bit addresses.
// Convert array index to long to do array offset computation with 64-bit values.
index_opr = new_register(T_LONG);
__ move(LIR_OprFact::longConst(index), index_opr);
addr = new LIR_Address(array_opr, index_opr, LIR_Address::scale(type), offset_in_bytes, type);
} else {
addr = new LIR_Address(array_opr, (intx)disp, type);
}
#else
// A displacement overflow can also occur for x86 but that is not a problem due to the 32-bit address range!
// Let's assume an array 'a' and an access with displacement 'disp'. When disp overflows, then "a + disp" will
// always be negative (i.e. underflows the 32-bit address range):
// Let N = 2^32: a + signed_overflow(disp) = a + disp - N.
// "a + disp" is always smaller than N. If an index was chosen which would point to an address beyond N, then
// range checks would catch that and throw an exception. Thus, a + disp < 0 holds which means that it always
// underflows the 32-bit address range:
// unsigned_underflow(a + signed_overflow(disp)) = unsigned_underflow(a + disp - N)
// = (a + disp - N) + N = a + disp
// This shows that we still end up at the correct address with a displacement overflow due to the 32-bit address
// range limitation. This overflow only needs to be handled if addresses can be larger as on 64-bit platforms.
addr = new LIR_Address(array_opr, offset_in_bytes + (intx)(index_opr->as_jint()) * elem_size, type);
#endif // _LP64
} else {
#ifdef _LP64
if (index_opr->type() == T_INT) {
Expand Down
8 changes: 4 additions & 4 deletions src/hotspot/share/c1/c1_GraphBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1988,10 +1988,8 @@ void GraphBuilder::invoke(Bytecodes::Code code) {
if (singleton) {
cha_monomorphic_target = target->find_monomorphic_target(calling_klass, target->holder(), singleton);
if (cha_monomorphic_target != NULL) {
// If CHA is able to bind this invoke then update the class
// to match that class, otherwise klass will refer to the
// interface.
klass = cha_monomorphic_target->holder();
ciInstanceKlass* holder = cha_monomorphic_target->holder();
klass = (holder->is_subtype_of(singleton) ? holder : singleton); // avoid upcasts
actual_recv = target->holder();

// insert a check it's really the expected class.
Expand All @@ -2001,6 +1999,8 @@ void GraphBuilder::invoke(Bytecodes::Code code) {
// pass the result of the checkcast so that the compiler has
// more accurate type info in the inlinee
better_receiver = append_split(c);

dependency_recorder()->assert_unique_implementor(target->holder(), singleton);
}
}
}
Expand Down
23 changes: 12 additions & 11 deletions src/hotspot/share/classfile/classFileParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3149,6 +3149,7 @@ static int inner_classes_jump_to_outer(const Array<u2>* inner_classes, int inner
static bool inner_classes_check_loop_through_outer(const Array<u2>* inner_classes, int idx, const ConstantPool* cp, int length) {
int slow = inner_classes->at(idx + InstanceKlass::inner_class_inner_class_info_offset);
int fast = inner_classes->at(idx + InstanceKlass::inner_class_outer_class_info_offset);

while (fast != -1 && fast != 0) {
if (slow != 0 && (cp->klass_name_at(slow) == cp->klass_name_at(fast))) {
return true; // found a circularity
Expand Down Expand Up @@ -3178,14 +3179,15 @@ bool ClassFileParser::check_inner_classes_circularity(const ConstantPool* cp, in
for (int y = idx + InstanceKlass::inner_class_next_offset; y < length;
y += InstanceKlass::inner_class_next_offset) {

// To maintain compatibility, throw an exception if duplicate inner classes
// entries are found.
guarantee_property((_inner_classes->at(idx) != _inner_classes->at(y) ||
_inner_classes->at(idx+1) != _inner_classes->at(y+1) ||
_inner_classes->at(idx+2) != _inner_classes->at(y+2) ||
_inner_classes->at(idx+3) != _inner_classes->at(y+3)),
"Duplicate entry in InnerClasses attribute in class file %s",
CHECK_(true));
// 4347400: make sure there's no duplicate entry in the classes array
if (_major_version >= JAVA_1_5_VERSION) {
guarantee_property((_inner_classes->at(idx) != _inner_classes->at(y) ||
_inner_classes->at(idx+1) != _inner_classes->at(y+1) ||
_inner_classes->at(idx+2) != _inner_classes->at(y+2) ||
_inner_classes->at(idx+3) != _inner_classes->at(y+3)),
"Duplicate entry in InnerClasses attribute in class file %s",
CHECK_(true));
}
// Return true if there are two entries with the same inner_class_info_index.
if (_inner_classes->at(y) == _inner_classes->at(idx)) {
return true;
Expand Down Expand Up @@ -3278,10 +3280,9 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(const ClassFileStrea
inner_classes->at_put(index++, inner_access_flags.as_short());
}

// 4347400: make sure there's no duplicate entry in the classes array
// Also, check for circular entries.
// Check for circular and duplicate entries.
bool has_circularity = false;
if (_need_verify && _major_version >= JAVA_1_5_VERSION) {
if (_need_verify) {
has_circularity = check_inner_classes_circularity(cp, length * 4, CHECK_0);
if (has_circularity) {
// If circularity check failed then ignore InnerClasses attribute.
Expand Down
10 changes: 8 additions & 2 deletions src/hotspot/share/classfile/classLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,13 +326,19 @@ u1* ClassPathZipEntry::open_entry(const char* name, jint* filesize, bool nul_ter
}

// read contents into resource array
int size = (*filesize) + ((nul_terminate) ? 1 : 0);
size_t size = (uint32_t)(*filesize);
if (nul_terminate) {
if (sizeof(size) == sizeof(uint32_t) && size == UINT_MAX) {
return NULL; // 32-bit integer overflow will occur.
}
size++;
}
buffer = NEW_RESOURCE_ARRAY(u1, size);
if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL;

// return result
if (nul_terminate) {
buffer[*filesize] = 0;
buffer[size - 1] = 0;
}
return buffer;
}
Expand Down
29 changes: 29 additions & 0 deletions src/hotspot/share/code/dependencies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,12 @@ void Dependencies::assert_exclusive_concrete_methods(ciKlass* ctxk, ciMethod* m1
assert_common_3(exclusive_concrete_methods_2, ctxk, m1, m2);
}

void Dependencies::assert_unique_implementor(ciInstanceKlass* ctxk, ciInstanceKlass* uniqk) {
check_ctxk(ctxk);
check_unique_implementor(ctxk, uniqk);
assert_common_2(unique_implementor, ctxk, uniqk);
}

void Dependencies::assert_has_no_finalizable_subclasses(ciKlass* ctxk) {
check_ctxk(ctxk);
assert_common_1(no_finalizable_subclasses, ctxk);
Expand Down Expand Up @@ -178,6 +184,13 @@ void Dependencies::assert_abstract_with_unique_concrete_subtype(Klass* ctxk, Kla
assert_common_2(abstract_with_unique_concrete_subtype, ctxk_dv, conck_dv);
}

void Dependencies::assert_unique_implementor(InstanceKlass* ctxk, InstanceKlass* uniqk) {
check_ctxk(ctxk);
assert(ctxk->is_interface(), "not an interface");
assert(ctxk->implementor() == uniqk, "not a unique implementor");
assert_common_2(unique_implementor, DepValue(_oop_recorder, ctxk), DepValue(_oop_recorder, uniqk));
}

void Dependencies::assert_unique_concrete_method(Klass* ctxk, Method* uniqm) {
check_ctxk(ctxk);
assert_common_2(unique_concrete_method, DepValue(_oop_recorder, ctxk), DepValue(_oop_recorder, uniqm));
Expand Down Expand Up @@ -593,6 +606,7 @@ const char* Dependencies::_dep_name[TYPE_LIMIT] = {
"unique_concrete_method",
"abstract_with_exclusive_concrete_subtypes_2",
"exclusive_concrete_methods_2",
"unique_implementor",
"no_finalizable_subclasses",
"call_site_target_value"
};
Expand All @@ -607,6 +621,7 @@ int Dependencies::_dep_args[TYPE_LIMIT] = {
2, // unique_concrete_method ctxk, m
3, // unique_concrete_subtypes_2 ctxk, k1, k2
3, // unique_concrete_methods_2 ctxk, m1, m2
2, // unique_implementor ctxk, implementor
1, // no_finalizable_subclasses ctxk
2 // call_site_target_value call_site, method_handle
};
Expand Down Expand Up @@ -1816,6 +1831,17 @@ Klass* Dependencies::check_unique_concrete_method(Klass* ctxk,
return NULL;
}

Klass* Dependencies::check_unique_implementor(Klass* ctxk, Klass* uniqk, KlassDepChange* changes) {
InstanceKlass* ctxik = InstanceKlass::cast(ctxk);
assert(ctxik->is_interface(), "sanity");
assert(ctxik->nof_implementors() > 0, "no implementors");
if (ctxik->nof_implementors() == 1) {
assert(ctxik->implementor() == uniqk, "sanity");
return NULL;
}
return ctxik; // no unique implementor
}

// Search for AME.
// There are two version of checks.
// 1) Spot checking version(Classload time). Newly added class is checked for AME.
Expand Down Expand Up @@ -1985,6 +2011,9 @@ Klass* Dependencies::DepStream::check_klass_dependency(KlassDepChange* changes)
case exclusive_concrete_methods_2:
witness = check_exclusive_concrete_methods(context_type(), method_argument(1), method_argument(2), changes);
break;
case unique_implementor:
witness = check_unique_implementor(context_type(), type_argument(1), changes);
break;
case no_finalizable_subclasses:
witness = check_has_no_finalizable_subclasses(context_type(), changes);
break;
Expand Down
10 changes: 10 additions & 0 deletions src/hotspot/share/code/dependencies.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#define SHARE_VM_CODE_DEPENDENCIES_HPP

#include "ci/ciCallSite.hpp"
#include "ci/ciInstanceKlass.hpp"
#include "ci/ciKlass.hpp"
#include "ci/ciMethodHandle.hpp"
#include "classfile/systemDictionary.hpp"
Expand Down Expand Up @@ -156,6 +157,9 @@ class Dependencies: public ResourceObj {
// This dependency asserts that MM(CX, M1) is no greater than {M1,M2}.
exclusive_concrete_methods_2,

// This dependency asserts that interface CX has a unique implementor class.
unique_implementor, // one unique implementor under CX

// This dependency asserts that no instances of class or it's
// subclasses require finalization registration.
no_finalizable_subclasses,
Expand Down Expand Up @@ -341,6 +345,9 @@ class Dependencies: public ResourceObj {
check_ctxk(ctxk);
assert(!is_concrete_klass(ctxk->as_instance_klass()), "must be abstract");
}
static void check_unique_implementor(ciInstanceKlass* ctxk, ciInstanceKlass* uniqk) {
assert(ctxk->implementor() == uniqk, "not a unique implementor");
}

void assert_common_1(DepType dept, ciBaseObject* x);
void assert_common_2(DepType dept, ciBaseObject* x0, ciBaseObject* x1);
Expand All @@ -356,6 +363,7 @@ class Dependencies: public ResourceObj {
void assert_unique_concrete_method(ciKlass* ctxk, ciMethod* uniqm);
void assert_abstract_with_exclusive_concrete_subtypes(ciKlass* ctxk, ciKlass* k1, ciKlass* k2);
void assert_exclusive_concrete_methods(ciKlass* ctxk, ciMethod* m1, ciMethod* m2);
void assert_unique_implementor(ciInstanceKlass* ctxk, ciInstanceKlass* uniqk);
void assert_has_no_finalizable_subclasses(ciKlass* ctxk);
void assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle);

Expand All @@ -375,6 +383,7 @@ class Dependencies: public ResourceObj {
void assert_evol_method(Method* m);
void assert_has_no_finalizable_subclasses(Klass* ctxk);
void assert_leaf_type(Klass* ctxk);
void assert_unique_implementor(InstanceKlass* ctxk, InstanceKlass* uniqk);
void assert_unique_concrete_method(Klass* ctxk, Method* uniqm);
void assert_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck);
void assert_call_site_target_value(oop callSite, oop methodHandle);
Expand Down Expand Up @@ -427,6 +436,7 @@ class Dependencies: public ResourceObj {
KlassDepChange* changes = NULL);
static Klass* check_concrete_with_no_concrete_subtype(Klass* ctxk,
KlassDepChange* changes = NULL);
static Klass* check_unique_implementor(Klass* ctxk, Klass* uniqk, KlassDepChange* changes = NULL);
static Klass* check_unique_concrete_method(Klass* ctxk, Method* uniqm,
KlassDepChange* changes = NULL);
static Klass* check_abstract_with_exclusive_concrete_subtypes(Klass* ctxk, Klass* k1, Klass* k2,
Expand Down
4 changes: 3 additions & 1 deletion src/hotspot/share/oops/instanceKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2256,7 +2256,9 @@ void InstanceKlass::metaspace_pointers_do(MetaspaceClosure* it) {
it->push(&_transitive_interfaces);
it->push(&_method_ordering);
it->push(&_default_vtable_indices);
it->push(&_fields);

// _fields might be written into by Rewriter::scan_method() -> fd.set_has_initialized_final_update()
it->push(&_fields, MetaspaceClosure::_writable);

if (itable_length() > 0) {
itableOffsetEntry* ioe = (itableOffsetEntry*)start_of_itable();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ Key recover(EncryptedPrivateKeyInfo encrInfo)
byte[] encodedParams =
encrInfo.getAlgorithm().getEncodedParams();

if (encodedParams == null) {
throw new IOException("Missing PBE parameters");
}

// parse the PBE parameters into the corresponding spec
AlgorithmParameters pbeParams =
AlgorithmParameters.getInstance("PBE");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2018, 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
Expand Down Expand Up @@ -124,8 +124,12 @@ protected void engineInit(byte[] encoded)
if (!val.getOID().equals(OID_MGF1)) {
throw new IOException("Only MGF1 mgf is supported");
}
byte[] encodedParams = val.getEncodedParams();
if (encodedParams == null) {
throw new IOException("Missing MGF1 parameters");
}
AlgorithmId params = AlgorithmId.parse(
new DerValue(val.getEncodedParams()));
new DerValue(encodedParams));
String mgfDigestName = params.getName();
if (mgfDigestName.equals("SHA-1")) {
mgfSpec = MGF1ParameterSpec.SHA1;
Expand All @@ -151,7 +155,12 @@ protected void engineInit(byte[] encoded)
if (!val.getOID().equals(OID_PSpecified)) {
throw new IOException("Wrong OID for pSpecified");
}
DerInputStream dis = new DerInputStream(val.getEncodedParams());
byte[] encodedParams = val.getEncodedParams();
if (encodedParams == null) {
throw new IOException("Missing pSpecified label");
}

DerInputStream dis = new DerInputStream(encodedParams);
p = dis.getOctetString();
if (dis.available() != 0) {
throw new IOException("Extra data for pSpecified");
Expand Down
33 changes: 33 additions & 0 deletions src/java.base/share/classes/java/io/ObjectInputStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,8 @@ public final ObjectInputFilter getObjectInputFilter() {
* <li>each object reference previously deserialized from the stream
* (class is {@code null}, arrayLength is -1),
* <li>each regular class (class is not {@code null}, arrayLength is -1),
* <li>each interface class explicitly referenced in the stream
* (it is not called for interfaces implemented by classes in the stream),
* <li>each interface of a dynamic proxy and the dynamic proxy class itself
* (class is not {@code null}, arrayLength is -1),
* <li>each array is filtered using the array type and length of the array
Expand Down Expand Up @@ -2010,6 +2012,30 @@ private ObjectStreamClass readNonProxyDesc(boolean unshared)
totalObjectRefs++;
depth++;
desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false));

if (cl != null) {
// Check that serial filtering has been done on the local class descriptor's superclass,
// in case it does not appear in the stream.

// Find the next super descriptor that has a local class descriptor.
// Descriptors for which there is no local class are ignored.
ObjectStreamClass superLocal = null;
for (ObjectStreamClass sDesc = desc.getSuperDesc(); sDesc != null; sDesc = sDesc.getSuperDesc()) {
if ((superLocal = sDesc.getLocalDesc()) != null) {
break;
}
}

// Scan local descriptor superclasses for a match with the local descriptor of the super found above.
// For each super descriptor before the match, invoke the serial filter on the class.
// The filter is invoked for each class that has not already been filtered
// but would be filtered if the instance had been serialized by this Java runtime.
for (ObjectStreamClass lDesc = desc.getLocalDesc().getSuperDesc();
lDesc != null && lDesc != superLocal;
lDesc = lDesc.getSuperDesc()) {
filterCheck(lDesc.forClass(), -1);
}
}
} finally {
depth--;
}
Expand Down Expand Up @@ -2502,6 +2528,13 @@ private IOException readFatalException() throws IOException {
throw new InternalError();
}
clear();
// Check that an object follows the TC_EXCEPTION typecode
byte tc = bin.peekByte();
if (tc != TC_OBJECT &&
tc != TC_REFERENCE) {
throw new StreamCorruptedException(
String.format("invalid type code: %02X", tc));
}
return (IOException) readObject0(Object.class, false);
}

Expand Down
Loading

0 comments on commit f3911e2

Please sign in to comment.