Skip to content

Commit 62e0147

Browse files
committed
Merge
2 parents 9e582fc + dfcd8d2 commit 62e0147

File tree

58 files changed

+2581
-435
lines changed

Some content is hidden

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

58 files changed

+2581
-435
lines changed

src/hotspot/share/classfile/verifier.cpp

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

src/hotspot/share/opto/loopnode.cpp

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

25612561
const TypeInt* init_t = phase->type(in(Init) )->is_int();
25622562
const TypeInt* limit_t = phase->type(in(Limit))->is_int();
2563-
int stride_p;
2563+
jlong stride_p;
25642564
jlong lim, ini;
25652565
julong max;
25662566
if (stride_con > 0) {
@@ -2569,10 +2569,10 @@ Node *LoopLimitNode::Ideal(PhaseGVN *phase, bool can_reshape) {
25692569
ini = init_t->_lo;
25702570
max = (julong)max_jint;
25712571
} else {
2572-
stride_p = -stride_con;
2572+
stride_p = -(jlong)stride_con;
25732573
lim = init_t->_hi;
25742574
ini = limit_t->_lo;
2575-
max = (julong)min_jint;
2575+
max = (julong)(juint)min_jint; // double cast to get 0x0000000080000000, not 0xffffffff80000000
25762576
}
25772577
julong range = lim - ini + stride_p;
25782578
if (range <= max) {

src/hotspot/share/opto/superword.cpp

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

src/hotspot/share/opto/superword.hpp

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -640,13 +640,51 @@ class SuperWord : public ResourceObj {
640640

641641
//------------------------------SWPointer---------------------------
642642
// Information about an address for dependence checking and vector alignment
643+
//
644+
// We parse and represent pointers of the simple form:
645+
//
646+
// pointer = adr + offset + invar + scale * ConvI2L(iv)
647+
//
648+
// Where:
649+
//
650+
// adr: the base address of an array (base = adr)
651+
// OR
652+
// some address to off-heap memory (base = TOP)
653+
//
654+
// offset: a constant offset
655+
// invar: a runtime variable, which is invariant during the loop
656+
// scale: scaling factor
657+
// iv: loop induction variable
658+
//
659+
// But more precisely, we parse the composite-long-int form:
660+
//
661+
// pointer = adr + long_offset + long_invar + long_scale * ConvI2L(int_offset + inv_invar + int_scale * iv)
662+
//
663+
// pointer = adr + long_offset + long_invar + long_scale * ConvI2L(int_index)
664+
// int_index = int_offset + int_invar + int_scale * iv
665+
//
666+
// However, for aliasing and adjacency checks (e.g. SWPointer::cmp()) we always use the simple form to make
667+
// decisions. Hence, we must make sure to only create a "valid" SWPointer if the optimisations based on the
668+
// simple form produce the same result as the compound-long-int form would. Intuitively, this depends on
669+
// if the int_index overflows, but the precise conditions are given in SWPointer::is_safe_to_use_as_simple_form().
670+
//
671+
// ConvI2L(int_index) = ConvI2L(int_offset + int_invar + int_scale * iv)
672+
// = Convi2L(int_offset) + ConvI2L(int_invar) + ConvI2L(int_scale) * ConvI2L(iv)
673+
//
674+
// scale = long_scale * ConvI2L(int_scale)
675+
// offset = long_offset + long_scale * ConvI2L(int_offset)
676+
// invar = long_invar + long_scale * ConvI2L(int_invar)
677+
//
678+
// pointer = adr + offset + invar + scale * ConvI2L(iv)
679+
//
643680
class SWPointer : public ArenaObj {
644681
protected:
645682
MemNode* _mem; // My memory reference node
646683
SuperWord* _slp; // SuperWord class
647684

648-
Node* _base; // null if unsafe nonheap reference
649-
Node* _adr; // address pointer
685+
// Components of the simple form:
686+
Node* _base; // Base address of an array OR null if some off-heap memory.
687+
Node* _adr; // Same as _base if an array pointer OR some off-heap memory pointer.
650688
int _scale; // multiplier for iv (in bytes), 0 if no loop iv
651689
int _offset; // constant offset (in bytes)
652690

@@ -657,6 +695,13 @@ class SWPointer : public ArenaObj {
657695
Node* _debug_invar_scale; // multiplier for invariant
658696
#endif
659697

698+
// The int_index components of the compound-long-int form. Used to decide if it is safe to use the
699+
// simple form rather than the compound-long-int form that was parsed.
700+
bool _has_int_index_after_convI2L;
701+
int _int_index_after_convI2L_offset;
702+
Node* _int_index_after_convI2L_invar;
703+
int _int_index_after_convI2L_scale;
704+
660705
Node_Stack* _nstack; // stack used to record a swpointer trace of variants
661706
bool _analyze_only; // Used in loop unrolling only for swpointer trace
662707
uint _stack_idx; // Used in loop unrolling only for swpointer trace
@@ -675,6 +720,8 @@ class SWPointer : public ArenaObj {
675720
// Match: offset is (k [+/- invariant])
676721
bool offset_plus_k(Node* n, bool negate = false);
677722

723+
bool is_safe_to_use_as_simple_form(Node* base, Node* adr) const;
724+
678725
public:
679726
enum CMP {
680727
Less = 1,
@@ -710,10 +757,43 @@ class SWPointer : public ArenaObj {
710757
return _invar == q._invar;
711758
}
712759

760+
// We compute if and how two SWPointers can alias at runtime, i.e. if the two addressed regions of memory can
761+
// ever overlap. There are essentially 3 relevant return states:
762+
// - NotComparable: Synonymous to "unknown aliasing".
763+
// We have no information about how the two SWPointers can alias. They could overlap, refer
764+
// to another location in the same memory object, or point to a completely different object.
765+
// -> Memory edge required. Aliasing unlikely but possible.
766+
//
767+
// - Less / Greater: Synonymous to "never aliasing".
768+
// The two SWPointers may point into the same memory object, but be non-aliasing (i.e. we
769+
// know both address regions inside the same memory object, but these regions are non-
770+
// overlapping), or the SWPointers point to entirely different objects.
771+
// -> No memory edge required. Aliasing impossible.
772+
//
773+
// - Equal: Synonymous to "overlap, or point to different memory objects".
774+
// The two SWPointers either overlap on the same memory object, or point to two different
775+
// memory objects.
776+
// -> Memory edge required. Aliasing likely.
777+
//
778+
// In a future refactoring, we can simplify to two states:
779+
// - NeverAlias: instead of Less / Greater
780+
// - MayAlias: instead of Equal / NotComparable
781+
//
782+
// Two SWPointer are "comparable" (Less / Greater / Equal), iff all of these conditions apply:
783+
// 1) Both are valid, i.e. expressible in the compound-long-int or simple form.
784+
// 2) The adr are identical, or both are array bases of different arrays.
785+
// 3) They have identical scale.
786+
// 4) They have identical invar.
787+
// 5) The difference in offsets is limited: abs(offset0 - offset1) < 2^31.
713788
int cmp(SWPointer& q) {
714789
if (valid() && q.valid() &&
715790
(_adr == q._adr || (_base == _adr && q._base == q._adr)) &&
716791
_scale == q._scale && invar_equals(q)) {
792+
jlong difference = abs(java_subtract((jlong)_offset, (jlong)q._offset));
793+
jlong max_diff = (jlong)1 << 31;
794+
if (difference >= max_diff) {
795+
return NotComparable;
796+
}
717797
bool overlap = q._offset < _offset + memory_size() &&
718798
_offset < q._offset + q.memory_size();
719799
return overlap ? Equal : (_offset < q._offset ? Less : Greater);
@@ -821,6 +901,12 @@ class SWPointer : public ArenaObj {
821901

822902
void maybe_add_to_invar(Node* new_invar, bool negate);
823903

904+
static bool try_AddI_no_overflow(int offset1, int offset2, int& result);
905+
static bool try_SubI_no_overflow(int offset1, int offset2, int& result);
906+
static bool try_AddSubI_no_overflow(int offset1, int offset2, bool is_sub, int& result);
907+
static bool try_LShiftI_no_overflow(int offset1, int offset2, int& result);
908+
static bool try_MulI_no_overflow(int offset1, int offset2, int& result);
909+
824910
Node* register_if_new(Node* n) const;
825911
};
826912

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
@@ -248,6 +248,15 @@ <H2>Misc HTTP URL stream protocol handler properties</H2>
248248
</OL>
249249
<P>The channel binding tokens generated are of the type "tls-server-end-point" as defined in
250250
RFC 5929.</P>
251+
252+
<LI><P><B>{@systemProperty jdk.http.maxHeaderSize}</B> (default: 393216 or 384kB)<BR>
253+
This is the maximum header field section size that a client is prepared to accept.
254+
This is computed as the sum of the size of the uncompressed header name, plus
255+
the size of the uncompressed header value, plus an overhead of 32 bytes for
256+
each field section line. If a peer sends a field section that exceeds this
257+
size a {@link java.net.ProtocolException ProtocolException} will be raised.
258+
This applies to all versions of the HTTP protocol. A value of zero or a negative
259+
value means no limit. If left unspecified, the default value is 393216 bytes.
251260
</UL>
252261
<P>All these properties are checked only once at startup.</P>
253262
<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.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;
@@ -1008,6 +1009,8 @@ public Object[] parse(String source, ParsePosition pos) {
10081009
maximumArgumentNumber = argumentNumbers[i];
10091010
}
10101011
}
1012+
1013+
// Constructors/applyPattern ensure that resultArray.length < MAX_ARGUMENT_INDEX
10111014
Object[] resultArray = new Object[maximumArgumentNumber + 1];
10121015

10131016
int patternOffset = 0;
@@ -1260,6 +1263,9 @@ protected Object readResolve() throws InvalidObjectException {
12601263
* @serial
12611264
*/
12621265
private int[] argumentNumbers = new int[INITIAL_FORMATS];
1266+
// Implementation limit for ArgumentIndex pattern element. Valid indices must
1267+
// be less than this value
1268+
private static final int MAX_ARGUMENT_INDEX = 10000;
12631269

12641270
/**
12651271
* One less than the number of entries in {@code offsets}. Can also be thought of
@@ -1484,6 +1490,11 @@ private void makeFormat(int position, int offsetNumber,
14841490
+ argumentNumber);
14851491
}
14861492

1493+
if (argumentNumber >= MAX_ARGUMENT_INDEX) {
1494+
throw new IllegalArgumentException(
1495+
argumentNumber + " exceeds the ArgumentIndex implementation limit");
1496+
}
1497+
14871498
// resize format information arrays if necessary
14881499
if (offsetNumber >= formats.length) {
14891500
int newLength = formats.length * 2;
@@ -1631,24 +1642,53 @@ private static final void copyAndFixQuotes(String source, int start, int end,
16311642
*/
16321643
@java.io.Serial
16331644
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
1634-
in.defaultReadObject();
1635-
boolean isValid = maxOffset >= -1
1636-
&& formats.length > maxOffset
1637-
&& offsets.length > maxOffset
1638-
&& argumentNumbers.length > maxOffset;
1645+
ObjectInputStream.GetField fields = in.readFields();
1646+
if (fields.defaulted("argumentNumbers") || fields.defaulted("offsets")
1647+
|| fields.defaulted("formats") || fields.defaulted("locale")
1648+
|| fields.defaulted("pattern") || fields.defaulted("maxOffset")){
1649+
throw new InvalidObjectException("Stream has missing data");
1650+
}
1651+
1652+
locale = (Locale) fields.get("locale", null);
1653+
String patt = (String) fields.get("pattern", null);
1654+
int maxOff = fields.get("maxOffset", -2);
1655+
int[] argNums = ((int[]) fields.get("argumentNumbers", null)).clone();
1656+
int[] offs = ((int[]) fields.get("offsets", null)).clone();
1657+
Format[] fmts = ((Format[]) fields.get("formats", null)).clone();
1658+
1659+
// Check arrays/maxOffset have correct value/length
1660+
boolean isValid = maxOff >= -1 && argNums.length > maxOff
1661+
&& offs.length > maxOff && fmts.length > maxOff;
1662+
1663+
// Check the correctness of arguments and offsets
16391664
if (isValid) {
1640-
int lastOffset = pattern.length() + 1;
1641-
for (int i = maxOffset; i >= 0; --i) {
1642-
if ((offsets[i] < 0) || (offsets[i] > lastOffset)) {
1665+
int lastOffset = patt.length() + 1;
1666+
for (int i = maxOff; i >= 0; --i) {
1667+
if (argNums[i] < 0 || argNums[i] >= MAX_ARGUMENT_INDEX
1668+
|| offs[i] < 0 || offs[i] > lastOffset) {
16431669
isValid = false;
16441670
break;
16451671
} else {
1646-
lastOffset = offsets[i];
1672+
lastOffset = offs[i];
16471673
}
16481674
}
16491675
}
1676+
16501677
if (!isValid) {
1651-
throw new InvalidObjectException("Could not reconstruct MessageFormat from corrupt stream.");
1678+
throw new InvalidObjectException("Stream has invalid data");
16521679
}
1680+
maxOffset = maxOff;
1681+
pattern = patt;
1682+
offsets = offs;
1683+
formats = fmts;
1684+
argumentNumbers = argNums;
1685+
}
1686+
1687+
/**
1688+
* Serialization without data not supported for this class.
1689+
*/
1690+
@java.io.Serial
1691+
private void readObjectNoData() throws ObjectStreamException {
1692+
throw new InvalidObjectException("Deserialized MessageFormat objects need data");
16531693
}
16541694
}

src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,9 @@ public final ForkJoinWorkerThread newThread(ForkJoinPool pool) {
981981
boolean isCommon = (pool.workerNamePrefix == null);
982982
@SuppressWarnings("removal")
983983
SecurityManager sm = System.getSecurityManager();
984-
if (sm != null && isCommon)
984+
if (sm == null)
985+
return new ForkJoinWorkerThread(null, pool, true, false);
986+
else if (isCommon)
985987
return newCommonWithACC(pool);
986988
else
987989
return newRegularWithACC(pool);

0 commit comments

Comments
 (0)