Skip to content

Commit 8ba0341

Browse files
committed
Merge
2 parents 1393271 + cee8535 commit 8ba0341

File tree

63 files changed

+3124
-442
lines changed

Some content is hidden

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

63 files changed

+3124
-442
lines changed

src/hotspot/share/opto/loopnode.cpp

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

13211321
const TypeInt* init_t = phase->type(in(Init) )->is_int();
13221322
const TypeInt* limit_t = phase->type(in(Limit))->is_int();
1323-
int stride_p;
1323+
jlong stride_p;
13241324
jlong lim, ini;
13251325
julong max;
13261326
if (stride_con > 0) {
@@ -1329,10 +1329,10 @@ Node *LoopLimitNode::Ideal(PhaseGVN *phase, bool can_reshape) {
13291329
ini = init_t->_lo;
13301330
max = (julong)max_jint;
13311331
} else {
1332-
stride_p = -stride_con;
1332+
stride_p = -(jlong)stride_con;
13331333
lim = init_t->_hi;
13341334
ini = limit_t->_lo;
1335-
max = (julong)min_jint;
1335+
max = (julong)(juint)min_jint; // double cast to get 0x0000000080000000, not 0xffffffff80000000
13361336
}
13371337
julong range = lim - ini + stride_p;
13381338
if (range <= max) {

src/hotspot/share/opto/superword.cpp

Lines changed: 530 additions & 15 deletions
Large diffs are not rendered by default.

src/hotspot/share/opto/superword.hpp

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,17 +568,63 @@ class SuperWord : public ResourceObj {
568568

569569
//------------------------------SWPointer---------------------------
570570
// Information about an address for dependence checking and vector alignment
571+
//
572+
// We parse and represent pointers of the simple form:
573+
//
574+
// pointer = adr + offset + invar + scale * ConvI2L(iv)
575+
//
576+
// Where:
577+
//
578+
// adr: the base address of an array (base = adr)
579+
// OR
580+
// some address to off-heap memory (base = TOP)
581+
//
582+
// offset: a constant offset
583+
// invar: a runtime variable, which is invariant during the loop
584+
// scale: scaling factor
585+
// iv: loop induction variable
586+
//
587+
// But more precisely, we parse the composite-long-int form:
588+
//
589+
// pointer = adr + long_offset + long_invar + long_scale * ConvI2L(int_offset + inv_invar + int_scale * iv)
590+
//
591+
// pointer = adr + long_offset + long_invar + long_scale * ConvI2L(int_index)
592+
// int_index = int_offset + int_invar + int_scale * iv
593+
//
594+
// However, for aliasing and adjacency checks (e.g. SWPointer::cmp()) we always use the simple form to make
595+
// decisions. Hence, we must make sure to only create a "valid" SWPointer if the optimisations based on the
596+
// simple form produce the same result as the compound-long-int form would. Intuitively, this depends on
597+
// if the int_index overflows, but the precise conditions are given in SWPointer::is_safe_to_use_as_simple_form().
598+
//
599+
// ConvI2L(int_index) = ConvI2L(int_offset + int_invar + int_scale * iv)
600+
// = Convi2L(int_offset) + ConvI2L(int_invar) + ConvI2L(int_scale) * ConvI2L(iv)
601+
//
602+
// scale = long_scale * ConvI2L(int_scale)
603+
// offset = long_offset + long_scale * ConvI2L(int_offset)
604+
// invar = long_invar + long_scale * ConvI2L(int_invar)
605+
//
606+
// pointer = adr + offset + invar + scale * ConvI2L(iv)
607+
//
571608
class SWPointer {
572609
protected:
573610
MemNode* _mem; // My memory reference node
574611
SuperWord* _slp; // SuperWord class
575612

576-
Node* _base; // NULL if unsafe nonheap reference
577-
Node* _adr; // address pointer
613+
// Components of the simple form:
614+
Node* _base; // Base address of an array OR NULL if some off-heap memory.
615+
Node* _adr; // Same as _base if an array pointer OR some off-heap memory pointer.
578616
jint _scale; // multiplier for iv (in bytes), 0 if no loop iv
579617
jint _offset; // constant offset (in bytes)
580618
Node* _invar; // invariant offset (in bytes), NULL if none
581619
bool _negate_invar; // if true then use: (0 - _invar)
620+
621+
// The int_index components of the compound-long-int form. Used to decide if it is safe to use the
622+
// simple form rather than the compound-long-int form that was parsed.
623+
bool _has_int_index_after_convI2L;
624+
int _int_index_after_convI2L_offset;
625+
Node* _int_index_after_convI2L_invar;
626+
int _int_index_after_convI2L_scale;
627+
582628
Node_Stack* _nstack; // stack used to record a swpointer trace of variants
583629
bool _analyze_only; // Used in loop unrolling only for swpointer trace
584630
uint _stack_idx; // Used in loop unrolling only for swpointer trace
@@ -597,6 +643,8 @@ class SWPointer {
597643
// Match: offset is (k [+/- invariant])
598644
bool offset_plus_k(Node* n, bool negate = false);
599645

646+
bool is_safe_to_use_as_simple_form(Node* base, Node* adr) const;
647+
600648
public:
601649
enum CMP {
602650
Less = 1,
@@ -625,12 +673,45 @@ class SWPointer {
625673
Node_Stack* node_stack() { return _nstack; }
626674

627675
// Comparable?
676+
// We compute if and how two SWPointers can alias at runtime, i.e. if the two addressed regions of memory can
677+
// ever overlap. There are essentially 3 relevant return states:
678+
// - NotComparable: Synonymous to "unknown aliasing".
679+
// We have no information about how the two SWPointers can alias. They could overlap, refer
680+
// to another location in the same memory object, or point to a completely different object.
681+
// -> Memory edge required. Aliasing unlikely but possible.
682+
//
683+
// - Less / Greater: Synonymous to "never aliasing".
684+
// The two SWPointers may point into the same memory object, but be non-aliasing (i.e. we
685+
// know both address regions inside the same memory object, but these regions are non-
686+
// overlapping), or the SWPointers point to entirely different objects.
687+
// -> No memory edge required. Aliasing impossible.
688+
//
689+
// - Equal: Synonymous to "overlap, or point to different memory objects".
690+
// The two SWPointers either overlap on the same memory object, or point to two different
691+
// memory objects.
692+
// -> Memory edge required. Aliasing likely.
693+
//
694+
// In a future refactoring, we can simplify to two states:
695+
// - NeverAlias: instead of Less / Greater
696+
// - MayAlias: instead of Equal / NotComparable
697+
//
698+
// Two SWPointer are "comparable" (Less / Greater / Equal), iff all of these conditions apply:
699+
// 1) Both are valid, i.e. expressible in the compound-long-int or simple form.
700+
// 2) The adr are identical, or both are array bases of different arrays.
701+
// 3) They have identical scale.
702+
// 4) They have identical invar.
703+
// 5) The difference in offsets is limited: abs(offset0 - offset1) < 2^31.
628704
int cmp(SWPointer& q) {
629705
if (valid() && q.valid() &&
630706
(_adr == q._adr || (_base == _adr && q._base == q._adr)) &&
631707
_scale == q._scale &&
632708
_invar == q._invar &&
633709
_negate_invar == q._negate_invar) {
710+
jlong difference = abs(java_subtract((jlong)_offset, (jlong)q._offset));
711+
jlong max_diff = (jlong)1 << 31;
712+
if (difference >= max_diff) {
713+
return NotComparable;
714+
}
634715
bool overlap = q._offset < _offset + memory_size() &&
635716
_offset < q._offset + q.memory_size();
636717
return overlap ? Equal : (_offset < q._offset ? Less : Greater);
@@ -717,6 +798,13 @@ class SWPointer {
717798

718799
} _tracer;//TRacer;
719800
#endif
801+
802+
static bool try_AddI_no_overflow(jint offset1, jint offset2, jint& result);
803+
static bool try_SubI_no_overflow(jint offset1, jint offset2, jint& result);
804+
static bool try_AddSubI_no_overflow(jint offset1, jint offset2, bool is_sub, jint& result);
805+
static bool try_LShiftI_no_overflow(jint offset1, int offset2, jint& result);
806+
static bool try_MulI_no_overflow(jint offset1, jint offset2, jint& result);
807+
720808
};
721809

722810
#endif // SHARE_VM_OPTO_SUPERWORD_HPP

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
@@ -238,6 +238,15 @@ <H2>Misc HTTP URL stream protocol handler properties</H2>
238238
</OL>
239239
<P>The channel binding tokens generated are of the type "tls-server-end-point" as defined in
240240
RFC 5929.</P>
241+
242+
<LI><P><B>{@systemProperty jdk.http.maxHeaderSize}</B> (default: 393216 or 384kB)<BR>
243+
This is the maximum header field section size that a client is prepared to accept.
244+
This is computed as the sum of the size of the uncompressed header name, plus
245+
the size of the uncompressed header value, plus an overhead of 32 bytes for
246+
each field section line. If a peer sends a field section that exceeds this
247+
size a {@link java.net.ProtocolException ProtocolException} will be raised.
248+
This applies to all versions of the HTTP protocol. A value of zero or a negative
249+
value means no limit. If left unspecified, the default value is 393216 bytes.
241250
</UL>
242251
<P>All these properties are checked only once at startup.</P>
243252
<a id="AddressCache"></a>

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

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import java.io.InvalidObjectException;
4242
import java.io.IOException;
4343
import java.io.ObjectInputStream;
44+
import java.io.ObjectStreamException;
4445
import java.text.DecimalFormat;
4546
import java.util.ArrayList;
4647
import java.util.Arrays;
@@ -982,6 +983,8 @@ public Object[] parse(String source, ParsePosition pos) {
982983
maximumArgumentNumber = argumentNumbers[i];
983984
}
984985
}
986+
987+
// Constructors/applyPattern ensure that resultArray.length < MAX_ARGUMENT_INDEX
985988
Object[] resultArray = new Object[maximumArgumentNumber + 1];
986989

987990
int patternOffset = 0;
@@ -1232,6 +1235,9 @@ protected Object readResolve() throws InvalidObjectException {
12321235
* @serial
12331236
*/
12341237
private int[] argumentNumbers = new int[INITIAL_FORMATS];
1238+
// Implementation limit for ArgumentIndex pattern element. Valid indices must
1239+
// be less than this value
1240+
private static final int MAX_ARGUMENT_INDEX = 10000;
12351241

12361242
/**
12371243
* One less than the number of entries in <code>offsets</code>. Can also be thought of
@@ -1456,6 +1462,11 @@ private void makeFormat(int position, int offsetNumber,
14561462
+ argumentNumber);
14571463
}
14581464

1465+
if (argumentNumber >= MAX_ARGUMENT_INDEX) {
1466+
throw new IllegalArgumentException(
1467+
argumentNumber + " exceeds the ArgumentIndex implementation limit");
1468+
}
1469+
14591470
// resize format information arrays if necessary
14601471
if (offsetNumber >= formats.length) {
14611472
int newLength = formats.length * 2;
@@ -1602,24 +1613,52 @@ private static final void copyAndFixQuotes(String source, int start, int end,
16021613
* @throws InvalidObjectException if the objects read from the stream is invalid.
16031614
*/
16041615
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
1605-
in.defaultReadObject();
1606-
boolean isValid = maxOffset >= -1
1607-
&& formats.length > maxOffset
1608-
&& offsets.length > maxOffset
1609-
&& argumentNumbers.length > maxOffset;
1616+
ObjectInputStream.GetField fields = in.readFields();
1617+
if (fields.defaulted("argumentNumbers") || fields.defaulted("offsets")
1618+
|| fields.defaulted("formats") || fields.defaulted("locale")
1619+
|| fields.defaulted("pattern") || fields.defaulted("maxOffset")){
1620+
throw new InvalidObjectException("Stream has missing data");
1621+
}
1622+
1623+
locale = (Locale) fields.get("locale", null);
1624+
String patt = (String) fields.get("pattern", null);
1625+
int maxOff = fields.get("maxOffset", -2);
1626+
int[] argNums = ((int[]) fields.get("argumentNumbers", null)).clone();
1627+
int[] offs = ((int[]) fields.get("offsets", null)).clone();
1628+
Format[] fmts = ((Format[]) fields.get("formats", null)).clone();
1629+
1630+
// Check arrays/maxOffset have correct value/length
1631+
boolean isValid = maxOff >= -1 && argNums.length > maxOff
1632+
&& offs.length > maxOff && fmts.length > maxOff;
1633+
1634+
// Check the correctness of arguments and offsets
16101635
if (isValid) {
1611-
int lastOffset = pattern.length() + 1;
1612-
for (int i = maxOffset; i >= 0; --i) {
1613-
if ((offsets[i] < 0) || (offsets[i] > lastOffset)) {
1636+
int lastOffset = patt.length() + 1;
1637+
for (int i = maxOff; i >= 0; --i) {
1638+
if (argNums[i] < 0 || argNums[i] >= MAX_ARGUMENT_INDEX
1639+
|| offs[i] < 0 || offs[i] > lastOffset) {
16141640
isValid = false;
16151641
break;
16161642
} else {
1617-
lastOffset = offsets[i];
1643+
lastOffset = offs[i];
16181644
}
16191645
}
16201646
}
1647+
16211648
if (!isValid) {
1622-
throw new InvalidObjectException("Could not reconstruct MessageFormat from corrupt stream.");
1649+
throw new InvalidObjectException("Stream has invalid data");
16231650
}
1651+
maxOffset = maxOff;
1652+
pattern = patt;
1653+
offsets = offs;
1654+
formats = fmts;
1655+
argumentNumbers = argNums;
1656+
}
1657+
1658+
/**
1659+
* Serialization without data not supported for this class.
1660+
*/
1661+
private void readObjectNoData() throws ObjectStreamException {
1662+
throw new InvalidObjectException("Deserialized MessageFormat objects need data");
16241663
}
16251664
}

src/java.base/share/classes/sun/net/www/MessageHeader.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
package sun.net.www;
3131

3232
import java.io.*;
33+
import java.lang.reflect.Array;
34+
import java.net.ProtocolException;
3335
import java.util.Collections;
3436
import java.util.*;
3537

@@ -46,11 +48,32 @@ class MessageHeader {
4648
private String values[];
4749
private int nkeys;
4850

51+
// max number of bytes for headers, <=0 means unlimited;
52+
// this corresponds to the length of the names, plus the length
53+
// of the values, plus an overhead of 32 bytes per name: value
54+
// pair.
55+
// Note: we use the same definition as HTTP/2 SETTINGS_MAX_HEADER_LIST_SIZE
56+
// see RFC 9113, section 6.5.2.
57+
// https://www.rfc-editor.org/rfc/rfc9113.html#SETTINGS_MAX_HEADER_LIST_SIZE
58+
private final int maxHeaderSize;
59+
60+
// Aggregate size of the field lines (name + value + 32) x N
61+
// that have been parsed and accepted so far.
62+
// This is defined as a long to force promotion to long
63+
// and avoid overflows; see checkNewSize;
64+
private long size;
65+
4966
public MessageHeader () {
67+
this(0);
68+
}
69+
70+
public MessageHeader (int maxHeaderSize) {
71+
this.maxHeaderSize = maxHeaderSize;
5072
grow();
5173
}
5274

5375
public MessageHeader (InputStream is) throws java.io.IOException {
76+
maxHeaderSize = 0;
5477
parseHeader(is);
5578
}
5679

@@ -466,10 +489,28 @@ public static String canonicalID(String id) {
466489
public void parseHeader(InputStream is) throws java.io.IOException {
467490
synchronized (this) {
468491
nkeys = 0;
492+
size = 0;
469493
}
470494
mergeHeader(is);
471495
}
472496

497+
private void checkMaxHeaderSize(int sz) throws ProtocolException {
498+
if (maxHeaderSize > 0) checkNewSize(size, sz, 0);
499+
}
500+
501+
private long checkNewSize(long size, int name, int value) throws ProtocolException {
502+
// See SETTINGS_MAX_HEADER_LIST_SIZE, RFC 9113, section 6.5.2.
503+
long newSize = size + name + value + 32;
504+
if (maxHeaderSize > 0 && newSize > maxHeaderSize) {
505+
Arrays.fill(keys, 0, nkeys, null);
506+
Arrays.fill(values,0, nkeys, null);
507+
nkeys = 0;
508+
throw new ProtocolException(String.format("Header size too big: %s > %s",
509+
newSize, maxHeaderSize));
510+
}
511+
return newSize;
512+
}
513+
473514
/** Parse and merge a MIME header from an input stream. */
474515
@SuppressWarnings("fallthrough")
475516
public void mergeHeader(InputStream is) throws java.io.IOException {
@@ -483,7 +524,15 @@ public void mergeHeader(InputStream is) throws java.io.IOException {
483524
int c;
484525
boolean inKey = firstc > ' ';
485526
s[len++] = (char) firstc;
527+
checkMaxHeaderSize(len);
486528
parseloop:{
529+
// We start parsing for a new name value pair here.
530+
// The max header size includes an overhead of 32 bytes per
531+
// name value pair.
532+
// See SETTINGS_MAX_HEADER_LIST_SIZE, RFC 9113, section 6.5.2.
533+
long maxRemaining = maxHeaderSize > 0
534+
? maxHeaderSize - size - 32
535+
: Long.MAX_VALUE;
487536
while ((c = is.read()) >= 0) {
488537
switch (c) {
489538
case ':':
@@ -517,6 +566,9 @@ public void mergeHeader(InputStream is) throws java.io.IOException {
517566
s = ns;
518567
}
519568
s[len++] = (char) c;
569+
if (maxHeaderSize > 0 && len > maxRemaining) {
570+
checkMaxHeaderSize(len);
571+
}
520572
}
521573
firstc = -1;
522574
}
@@ -538,6 +590,9 @@ public void mergeHeader(InputStream is) throws java.io.IOException {
538590
v = new String();
539591
else
540592
v = String.copyValueOf(s, keyend, len - keyend);
593+
int klen = k == null ? 0 : k.length();
594+
595+
size = checkNewSize(size, klen, v.length());
541596
add(k, v);
542597
}
543598
}

0 commit comments

Comments
 (0)