Skip to content

Commit 43e1328

Browse files
author
Rob McKenna
committed
Merge
2 parents c326ff1 + a3fde48 commit 43e1328

File tree

69 files changed

+3544
-439
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+3544
-439
lines changed

src/hotspot/share/classfile/verifier.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "classfile/stackMapTableFormat.hpp"
3333
#include "classfile/symbolTable.hpp"
3434
#include "classfile/systemDictionary.hpp"
35+
#include "classfile/systemDictionaryShared.hpp"
3536
#include "classfile/verifier.hpp"
3637
#include "classfile/vmClasses.hpp"
3738
#include "classfile/vmSymbols.hpp"
@@ -212,6 +213,11 @@ bool Verifier::verify(InstanceKlass* klass, bool should_verify_class, TRAPS) {
212213
exception_name == vmSymbols::java_lang_ClassFormatError())) {
213214
log_info(verification)("Fail over class verification to old verifier for: %s", klass->external_name());
214215
log_info(class, init)("Fail over class verification to old verifier for: %s", klass->external_name());
216+
// Exclude any classes that fail over during dynamic dumping
217+
if (CDSConfig::is_dumping_dynamic_archive()) {
218+
SystemDictionaryShared::warn_excluded(klass, "Failed over class verification while dynamic dumping");
219+
SystemDictionaryShared::set_excluded(klass);
220+
}
215221
message_buffer = NEW_RESOURCE_ARRAY(char, message_buffer_len);
216222
exception_message = message_buffer;
217223
exception_name = inference_verify(

src/hotspot/share/opto/loopnode.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2591,7 +2591,7 @@ Node *LoopLimitNode::Ideal(PhaseGVN *phase, bool can_reshape) {
25912591

25922592
const TypeInt* init_t = phase->type(in(Init) )->is_int();
25932593
const TypeInt* limit_t = phase->type(in(Limit))->is_int();
2594-
int stride_p;
2594+
jlong stride_p;
25952595
jlong lim, ini;
25962596
julong max;
25972597
if (stride_con > 0) {
@@ -2600,10 +2600,10 @@ Node *LoopLimitNode::Ideal(PhaseGVN *phase, bool can_reshape) {
26002600
ini = init_t->_lo;
26012601
max = (julong)max_jint;
26022602
} else {
2603-
stride_p = -stride_con;
2603+
stride_p = -(jlong)stride_con;
26042604
lim = init_t->_hi;
26052605
ini = limit_t->_lo;
2606-
max = (julong)min_jint;
2606+
max = (julong)(juint)min_jint; // double cast to get 0x0000000080000000, not 0xffffffff80000000
26072607
}
26082608
julong range = lim - ini + stride_p;
26092609
if (range <= max) {

src/hotspot/share/opto/vectorization.cpp

Lines changed: 526 additions & 12 deletions
Large diffs are not rendered by default.

src/hotspot/share/opto/vectorization.hpp

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -667,13 +667,51 @@ class VLoopAnalyzer : StackObj {
667667
// A vectorization pointer (VPointer) has information about an address for
668668
// dependence checking and vector alignment. It's usually bound to a memory
669669
// operation in a counted loop for vectorizable analysis.
670+
//
671+
// We parse and represent pointers of the simple form:
672+
//
673+
// pointer = adr + offset + invar + scale * ConvI2L(iv)
674+
//
675+
// Where:
676+
//
677+
// adr: the base address of an array (base = adr)
678+
// OR
679+
// some address to off-heap memory (base = TOP)
680+
//
681+
// offset: a constant offset
682+
// invar: a runtime variable, which is invariant during the loop
683+
// scale: scaling factor
684+
// iv: loop induction variable
685+
//
686+
// But more precisely, we parse the composite-long-int form:
687+
//
688+
// pointer = adr + long_offset + long_invar + long_scale * ConvI2L(int_offset + inv_invar + int_scale * iv)
689+
//
690+
// pointer = adr + long_offset + long_invar + long_scale * ConvI2L(int_index)
691+
// int_index = int_offset + int_invar + int_scale * iv
692+
//
693+
// However, for aliasing and adjacency checks (e.g. VPointer::cmp()) we always use the simple form to make
694+
// decisions. Hence, we must make sure to only create a "valid" VPointer if the optimisations based on the
695+
// simple form produce the same result as the compound-long-int form would. Intuitively, this depends on
696+
// if the int_index overflows, but the precise conditions are given in VPointer::is_safe_to_use_as_simple_form().
697+
//
698+
// ConvI2L(int_index) = ConvI2L(int_offset + int_invar + int_scale * iv)
699+
// = Convi2L(int_offset) + ConvI2L(int_invar) + ConvI2L(int_scale) * ConvI2L(iv)
700+
//
701+
// scale = long_scale * ConvI2L(int_scale)
702+
// offset = long_offset + long_scale * ConvI2L(int_offset)
703+
// invar = long_invar + long_scale * ConvI2L(int_invar)
704+
//
705+
// pointer = adr + offset + invar + scale * ConvI2L(iv)
706+
//
670707
class VPointer : public ArenaObj {
671708
protected:
672709
const MemNode* _mem; // My memory reference node
673710
const VLoop& _vloop;
674711

675-
Node* _base; // null if unsafe nonheap reference
676-
Node* _adr; // address pointer
712+
// Components of the simple form:
713+
Node* _base; // Base address of an array OR null if some off-heap memory.
714+
Node* _adr; // Same as _base if an array pointer OR some off-heap memory pointer.
677715
int _scale; // multiplier for iv (in bytes), 0 if no loop iv
678716
int _offset; // constant offset (in bytes)
679717

@@ -684,6 +722,13 @@ class VPointer : public ArenaObj {
684722
Node* _debug_invar_scale; // multiplier for invariant
685723
#endif
686724

725+
// The int_index components of the compound-long-int form. Used to decide if it is safe to use the
726+
// simple form rather than the compound-long-int form that was parsed.
727+
bool _has_int_index_after_convI2L;
728+
int _int_index_after_convI2L_offset;
729+
Node* _int_index_after_convI2L_invar;
730+
int _int_index_after_convI2L_scale;
731+
687732
Node_Stack* _nstack; // stack used to record a vpointer trace of variants
688733
bool _analyze_only; // Used in loop unrolling only for vpointer trace
689734
uint _stack_idx; // Used in loop unrolling only for vpointer trace
@@ -723,6 +768,8 @@ class VPointer : public ArenaObj {
723768
VPointer(VPointer* p);
724769
NONCOPYABLE(VPointer);
725770

771+
bool is_safe_to_use_as_simple_form(Node* base, Node* adr) const;
772+
726773
public:
727774
bool valid() const { return _adr != nullptr; }
728775
bool has_iv() const { return _scale != 0; }
@@ -748,10 +795,43 @@ class VPointer : public ArenaObj {
748795
return _invar == q._invar;
749796
}
750797

798+
// We compute if and how two VPointers can alias at runtime, i.e. if the two addressed regions of memory can
799+
// ever overlap. There are essentially 3 relevant return states:
800+
// - NotComparable: Synonymous to "unknown aliasing".
801+
// We have no information about how the two VPointers can alias. They could overlap, refer
802+
// to another location in the same memory object, or point to a completely different object.
803+
// -> Memory edge required. Aliasing unlikely but possible.
804+
//
805+
// - Less / Greater: Synonymous to "never aliasing".
806+
// The two VPointers may point into the same memory object, but be non-aliasing (i.e. we
807+
// know both address regions inside the same memory object, but these regions are non-
808+
// overlapping), or the VPointers point to entirely different objects.
809+
// -> No memory edge required. Aliasing impossible.
810+
//
811+
// - Equal: Synonymous to "overlap, or point to different memory objects".
812+
// The two VPointers either overlap on the same memory object, or point to two different
813+
// memory objects.
814+
// -> Memory edge required. Aliasing likely.
815+
//
816+
// In a future refactoring, we can simplify to two states:
817+
// - NeverAlias: instead of Less / Greater
818+
// - MayAlias: instead of Equal / NotComparable
819+
//
820+
// Two VPointer are "comparable" (Less / Greater / Equal), iff all of these conditions apply:
821+
// 1) Both are valid, i.e. expressible in the compound-long-int or simple form.
822+
// 2) The adr are identical, or both are array bases of different arrays.
823+
// 3) They have identical scale.
824+
// 4) They have identical invar.
825+
// 5) The difference in offsets is limited: abs(offset0 - offset1) < 2^31.
751826
int cmp(const VPointer& q) const {
752827
if (valid() && q.valid() &&
753828
(_adr == q._adr || (_base == _adr && q._base == q._adr)) &&
754829
_scale == q._scale && invar_equals(q)) {
830+
jlong difference = abs(java_subtract((jlong)_offset, (jlong)q._offset));
831+
jlong max_diff = (jlong)1 << 31;
832+
if (difference >= max_diff) {
833+
return NotComparable;
834+
}
755835
bool overlap = q._offset < _offset + memory_size() &&
756836
_offset < q._offset + q.memory_size();
757837
return overlap ? Equal : (_offset < q._offset ? Less : Greater);
@@ -851,6 +931,12 @@ class VPointer : public ArenaObj {
851931

852932
void maybe_add_to_invar(Node* new_invar, bool negate);
853933

934+
static bool try_AddI_no_overflow(int offset1, int offset2, int& result);
935+
static bool try_SubI_no_overflow(int offset1, int offset2, int& result);
936+
static bool try_AddSubI_no_overflow(int offset1, int offset2, bool is_sub, int& result);
937+
static bool try_LShiftI_no_overflow(int offset1, int offset2, int& result);
938+
static bool try_MulI_no_overflow(int offset1, int offset2, int& result);
939+
854940
Node* register_if_new(Node* n) const;
855941
};
856942

src/java.base/share/classes/java/net/doc-files/net-properties.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,15 @@ <H2>Misc HTTP URL stream protocol handler properties</H2>
253253
</OL>
254254
<P>The channel binding tokens generated are of the type "tls-server-end-point" as defined in
255255
RFC 5929.</P>
256+
257+
<LI><P><B>{@systemProperty jdk.http.maxHeaderSize}</B> (default: 393216 or 384kB)<BR>
258+
This is the maximum header field section size that a client is prepared to accept.
259+
This is computed as the sum of the size of the uncompressed header name, plus
260+
the size of the uncompressed header value, plus an overhead of 32 bytes for
261+
each field section line. If a peer sends a field section that exceeds this
262+
size a {@link java.net.ProtocolException ProtocolException} will be raised.
263+
This applies to all versions of the HTTP protocol. A value of zero or a negative
264+
value means no limit. If left unspecified, the default value is 393216 bytes.
256265
</UL>
257266
<P>All these properties are checked only once at startup.</P>
258267
<a id="AddressCache"></a>

src/java.base/share/classes/java/text/MessageFormat.java

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import java.io.IOException;
4242
import java.io.InvalidObjectException;
4343
import java.io.ObjectInputStream;
44+
import java.io.ObjectStreamException;
4445
import java.time.format.DateTimeFormatter;
4546
import java.util.ArrayList;
4647
import java.util.Arrays;
@@ -1172,6 +1173,8 @@ public Object[] parse(String source, ParsePosition pos) {
11721173
maximumArgumentNumber = argumentNumbers[i];
11731174
}
11741175
}
1176+
1177+
// Constructors/applyPattern ensure that resultArray.length < MAX_ARGUMENT_INDEX
11751178
Object[] resultArray = new Object[maximumArgumentNumber + 1];
11761179

11771180
int patternOffset = 0;
@@ -1450,6 +1453,9 @@ protected Object readResolve() throws InvalidObjectException {
14501453
* @serial
14511454
*/
14521455
private int[] argumentNumbers = new int[INITIAL_FORMATS];
1456+
// Implementation limit for ArgumentIndex pattern element. Valid indices must
1457+
// be less than this value
1458+
private static final int MAX_ARGUMENT_INDEX = 10000;
14531459

14541460
/**
14551461
* One less than the number of entries in {@code offsets}. Can also be thought of
@@ -1630,6 +1636,11 @@ private void setFormatFromPattern(int position, int offsetNumber,
16301636
+ argumentNumber);
16311637
}
16321638

1639+
if (argumentNumber >= MAX_ARGUMENT_INDEX) {
1640+
throw new IllegalArgumentException(
1641+
argumentNumber + " exceeds the ArgumentIndex implementation limit");
1642+
}
1643+
16331644
// resize format information arrays if necessary
16341645
if (offsetNumber >= formats.length) {
16351646
int newLength = formats.length * 2;
@@ -1997,24 +2008,53 @@ private static FormatStyle fromString(String text) {
19972008
*/
19982009
@java.io.Serial
19992010
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
2000-
in.defaultReadObject();
2001-
boolean isValid = maxOffset >= -1
2002-
&& formats.length > maxOffset
2003-
&& offsets.length > maxOffset
2004-
&& argumentNumbers.length > maxOffset;
2011+
ObjectInputStream.GetField fields = in.readFields();
2012+
if (fields.defaulted("argumentNumbers") || fields.defaulted("offsets")
2013+
|| fields.defaulted("formats") || fields.defaulted("locale")
2014+
|| fields.defaulted("pattern") || fields.defaulted("maxOffset")){
2015+
throw new InvalidObjectException("Stream has missing data");
2016+
}
2017+
2018+
locale = (Locale) fields.get("locale", null);
2019+
String patt = (String) fields.get("pattern", null);
2020+
int maxOff = fields.get("maxOffset", -2);
2021+
int[] argNums = ((int[]) fields.get("argumentNumbers", null)).clone();
2022+
int[] offs = ((int[]) fields.get("offsets", null)).clone();
2023+
Format[] fmts = ((Format[]) fields.get("formats", null)).clone();
2024+
2025+
// Check arrays/maxOffset have correct value/length
2026+
boolean isValid = maxOff >= -1 && argNums.length > maxOff
2027+
&& offs.length > maxOff && fmts.length > maxOff;
2028+
2029+
// Check the correctness of arguments and offsets
20052030
if (isValid) {
2006-
int lastOffset = pattern.length() + 1;
2007-
for (int i = maxOffset; i >= 0; --i) {
2008-
if ((offsets[i] < 0) || (offsets[i] > lastOffset)) {
2031+
int lastOffset = patt.length() + 1;
2032+
for (int i = maxOff; i >= 0; --i) {
2033+
if (argNums[i] < 0 || argNums[i] >= MAX_ARGUMENT_INDEX
2034+
|| offs[i] < 0 || offs[i] > lastOffset) {
20092035
isValid = false;
20102036
break;
20112037
} else {
2012-
lastOffset = offsets[i];
2038+
lastOffset = offs[i];
20132039
}
20142040
}
20152041
}
2042+
20162043
if (!isValid) {
2017-
throw new InvalidObjectException("Could not reconstruct MessageFormat from corrupt stream.");
2044+
throw new InvalidObjectException("Stream has invalid data");
20182045
}
2046+
maxOffset = maxOff;
2047+
pattern = patt;
2048+
offsets = offs;
2049+
formats = fmts;
2050+
argumentNumbers = argNums;
2051+
}
2052+
2053+
/**
2054+
* Serialization without data not supported for this class.
2055+
*/
2056+
@java.io.Serial
2057+
private void readObjectNoData() throws ObjectStreamException {
2058+
throw new InvalidObjectException("Deserialized MessageFormat objects need data");
20192059
}
20202060
}

0 commit comments

Comments
 (0)