Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge to tag jdk-21.0.5+11 #1848

Open
wants to merge 10 commits into
base: sapmachine21
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion make/conf/version-numbers.conf
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@ DEFAULT_VERSION_CLASSFILE_MINOR=0
DEFAULT_VERSION_DOCS_API_SINCE=11
DEFAULT_ACCEPTABLE_BOOT_VERSIONS="20 21"
DEFAULT_JDK_SOURCE_TARGET_VERSION=21
DEFAULT_PROMOTED_VERSION_PRE=ea
DEFAULT_PROMOTED_VERSION_PRE=
6 changes: 6 additions & 0 deletions src/hotspot/share/classfile/verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "classfile/stackMapTableFormat.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/systemDictionaryShared.hpp"
#include "classfile/verifier.hpp"
#include "classfile/vmClasses.hpp"
#include "classfile/vmSymbols.hpp"
Expand Down Expand Up @@ -211,6 +212,11 @@ bool Verifier::verify(InstanceKlass* klass, bool should_verify_class, TRAPS) {
exception_name == vmSymbols::java_lang_ClassFormatError())) {
log_info(verification)("Fail over class verification to old verifier for: %s", klass->external_name());
log_info(class, init)("Fail over class verification to old verifier for: %s", klass->external_name());
// Exclude any classes that fail over during dynamic dumping
if (CDS_ONLY(DynamicDumpSharedSpaces) NOT_CDS(false)) {
SystemDictionaryShared::warn_excluded(klass, "Failed over class verification while dynamic dumping");
SystemDictionaryShared::set_excluded(klass);
}
message_buffer = NEW_RESOURCE_ARRAY(char, message_buffer_len);
exception_message = message_buffer;
exception_name = inference_verify(
Expand Down
6 changes: 3 additions & 3 deletions src/hotspot/share/opto/loopnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2540,7 +2540,7 @@ Node *LoopLimitNode::Ideal(PhaseGVN *phase, bool can_reshape) {

const TypeInt* init_t = phase->type(in(Init) )->is_int();
const TypeInt* limit_t = phase->type(in(Limit))->is_int();
int stride_p;
jlong stride_p;
jlong lim, ini;
julong max;
if (stride_con > 0) {
Expand All @@ -2549,10 +2549,10 @@ Node *LoopLimitNode::Ideal(PhaseGVN *phase, bool can_reshape) {
ini = init_t->_lo;
max = (julong)max_jint;
} else {
stride_p = -stride_con;
stride_p = -(jlong)stride_con;
lim = init_t->_hi;
ini = limit_t->_lo;
max = (julong)min_jint;
max = (julong)(juint)min_jint; // double cast to get 0x0000000080000000, not 0xffffffff80000000
}
julong range = lim - ini + stride_p;
if (range <= max) {
Expand Down
538 changes: 526 additions & 12 deletions src/hotspot/share/opto/superword.cpp

Large diffs are not rendered by default.

90 changes: 88 additions & 2 deletions src/hotspot/share/opto/superword.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -640,13 +640,51 @@ class SuperWord : public ResourceObj {

//------------------------------SWPointer---------------------------
// Information about an address for dependence checking and vector alignment
//
// We parse and represent pointers of the simple form:
//
// pointer = adr + offset + invar + scale * ConvI2L(iv)
//
// Where:
//
// adr: the base address of an array (base = adr)
// OR
// some address to off-heap memory (base = TOP)
//
// offset: a constant offset
// invar: a runtime variable, which is invariant during the loop
// scale: scaling factor
// iv: loop induction variable
//
// But more precisely, we parse the composite-long-int form:
//
// pointer = adr + long_offset + long_invar + long_scale * ConvI2L(int_offset + inv_invar + int_scale * iv)
//
// pointer = adr + long_offset + long_invar + long_scale * ConvI2L(int_index)
// int_index = int_offset + int_invar + int_scale * iv
//
// However, for aliasing and adjacency checks (e.g. SWPointer::cmp()) we always use the simple form to make
// decisions. Hence, we must make sure to only create a "valid" SWPointer if the optimisations based on the
// simple form produce the same result as the compound-long-int form would. Intuitively, this depends on
// if the int_index overflows, but the precise conditions are given in SWPointer::is_safe_to_use_as_simple_form().
//
// ConvI2L(int_index) = ConvI2L(int_offset + int_invar + int_scale * iv)
// = Convi2L(int_offset) + ConvI2L(int_invar) + ConvI2L(int_scale) * ConvI2L(iv)
//
// scale = long_scale * ConvI2L(int_scale)
// offset = long_offset + long_scale * ConvI2L(int_offset)
// invar = long_invar + long_scale * ConvI2L(int_invar)
//
// pointer = adr + offset + invar + scale * ConvI2L(iv)
//
class SWPointer : public ArenaObj {
protected:
MemNode* _mem; // My memory reference node
SuperWord* _slp; // SuperWord class

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

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

// The int_index components of the compound-long-int form. Used to decide if it is safe to use the
// simple form rather than the compound-long-int form that was parsed.
bool _has_int_index_after_convI2L;
int _int_index_after_convI2L_offset;
Node* _int_index_after_convI2L_invar;
int _int_index_after_convI2L_scale;

Node_Stack* _nstack; // stack used to record a swpointer trace of variants
bool _analyze_only; // Used in loop unrolling only for swpointer trace
uint _stack_idx; // Used in loop unrolling only for swpointer trace
Expand All @@ -675,6 +720,8 @@ class SWPointer : public ArenaObj {
// Match: offset is (k [+/- invariant])
bool offset_plus_k(Node* n, bool negate = false);

bool is_safe_to_use_as_simple_form(Node* base, Node* adr) const;

public:
enum CMP {
Less = 1,
Expand Down Expand Up @@ -710,10 +757,43 @@ class SWPointer : public ArenaObj {
return _invar == q._invar;
}

// We compute if and how two SWPointers can alias at runtime, i.e. if the two addressed regions of memory can
// ever overlap. There are essentially 3 relevant return states:
// - NotComparable: Synonymous to "unknown aliasing".
// We have no information about how the two SWPointers can alias. They could overlap, refer
// to another location in the same memory object, or point to a completely different object.
// -> Memory edge required. Aliasing unlikely but possible.
//
// - Less / Greater: Synonymous to "never aliasing".
// The two SWPointers may point into the same memory object, but be non-aliasing (i.e. we
// know both address regions inside the same memory object, but these regions are non-
// overlapping), or the SWPointers point to entirely different objects.
// -> No memory edge required. Aliasing impossible.
//
// - Equal: Synonymous to "overlap, or point to different memory objects".
// The two SWPointers either overlap on the same memory object, or point to two different
// memory objects.
// -> Memory edge required. Aliasing likely.
//
// In a future refactoring, we can simplify to two states:
// - NeverAlias: instead of Less / Greater
// - MayAlias: instead of Equal / NotComparable
//
// Two SWPointer are "comparable" (Less / Greater / Equal), iff all of these conditions apply:
// 1) Both are valid, i.e. expressible in the compound-long-int or simple form.
// 2) The adr are identical, or both are array bases of different arrays.
// 3) They have identical scale.
// 4) They have identical invar.
// 5) The difference in offsets is limited: abs(offset0 - offset1) < 2^31.
int cmp(SWPointer& q) {
if (valid() && q.valid() &&
(_adr == q._adr || (_base == _adr && q._base == q._adr)) &&
_scale == q._scale && invar_equals(q)) {
jlong difference = abs(java_subtract((jlong)_offset, (jlong)q._offset));
jlong max_diff = (jlong)1 << 31;
if (difference >= max_diff) {
return NotComparable;
}
bool overlap = q._offset < _offset + memory_size() &&
_offset < q._offset + q.memory_size();
return overlap ? Equal : (_offset < q._offset ? Less : Greater);
Expand Down Expand Up @@ -821,6 +901,12 @@ class SWPointer : public ArenaObj {

void maybe_add_to_invar(Node* new_invar, bool negate);

static bool try_AddI_no_overflow(int offset1, int offset2, int& result);
static bool try_SubI_no_overflow(int offset1, int offset2, int& result);
static bool try_AddSubI_no_overflow(int offset1, int offset2, bool is_sub, int& result);
static bool try_LShiftI_no_overflow(int offset1, int offset2, int& result);
static bool try_MulI_no_overflow(int offset1, int offset2, int& result);

Node* register_if_new(Node* n) const;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,15 @@ <H2>Misc HTTP URL stream protocol handler properties</H2>
</OL>
<P>The channel binding tokens generated are of the type "tls-server-end-point" as defined in
RFC 5929.</P>

<LI><P><B>{@systemProperty jdk.http.maxHeaderSize}</B> (default: 393216 or 384kB)<BR>
This is the maximum header field section size that a client is prepared to accept.
This is computed as the sum of the size of the uncompressed header name, plus
the size of the uncompressed header value, plus an overhead of 32 bytes for
each field section line. If a peer sends a field section that exceeds this
size a {@link java.net.ProtocolException ProtocolException} will be raised.
This applies to all versions of the HTTP protocol. A value of zero or a negative
value means no limit. If left unspecified, the default value is 393216 bytes.
</UL>
<P>All these properties are checked only once at startup.</P>
<a id="AddressCache"></a>
Expand Down
60 changes: 50 additions & 10 deletions src/java.base/share/classes/java/text/MessageFormat.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import java.io.InvalidObjectException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -1008,6 +1009,8 @@ public Object[] parse(String source, ParsePosition pos) {
maximumArgumentNumber = argumentNumbers[i];
}
}

// Constructors/applyPattern ensure that resultArray.length < MAX_ARGUMENT_INDEX
Object[] resultArray = new Object[maximumArgumentNumber + 1];

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

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

if (argumentNumber >= MAX_ARGUMENT_INDEX) {
throw new IllegalArgumentException(
argumentNumber + " exceeds the ArgumentIndex implementation limit");
}

// resize format information arrays if necessary
if (offsetNumber >= formats.length) {
int newLength = formats.length * 2;
Expand Down Expand Up @@ -1631,24 +1642,53 @@ private static final void copyAndFixQuotes(String source, int start, int end,
*/
@java.io.Serial
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
boolean isValid = maxOffset >= -1
&& formats.length > maxOffset
&& offsets.length > maxOffset
&& argumentNumbers.length > maxOffset;
ObjectInputStream.GetField fields = in.readFields();
if (fields.defaulted("argumentNumbers") || fields.defaulted("offsets")
|| fields.defaulted("formats") || fields.defaulted("locale")
|| fields.defaulted("pattern") || fields.defaulted("maxOffset")){
throw new InvalidObjectException("Stream has missing data");
}

locale = (Locale) fields.get("locale", null);
String patt = (String) fields.get("pattern", null);
int maxOff = fields.get("maxOffset", -2);
int[] argNums = ((int[]) fields.get("argumentNumbers", null)).clone();
int[] offs = ((int[]) fields.get("offsets", null)).clone();
Format[] fmts = ((Format[]) fields.get("formats", null)).clone();

// Check arrays/maxOffset have correct value/length
boolean isValid = maxOff >= -1 && argNums.length > maxOff
&& offs.length > maxOff && fmts.length > maxOff;

// Check the correctness of arguments and offsets
if (isValid) {
int lastOffset = pattern.length() + 1;
for (int i = maxOffset; i >= 0; --i) {
if ((offsets[i] < 0) || (offsets[i] > lastOffset)) {
int lastOffset = patt.length() + 1;
for (int i = maxOff; i >= 0; --i) {
if (argNums[i] < 0 || argNums[i] >= MAX_ARGUMENT_INDEX
|| offs[i] < 0 || offs[i] > lastOffset) {
isValid = false;
break;
} else {
lastOffset = offsets[i];
lastOffset = offs[i];
}
}
}

if (!isValid) {
throw new InvalidObjectException("Could not reconstruct MessageFormat from corrupt stream.");
throw new InvalidObjectException("Stream has invalid data");
}
maxOffset = maxOff;
pattern = patt;
offsets = offs;
formats = fmts;
argumentNumbers = argNums;
}

/**
* Serialization without data not supported for this class.
*/
@java.io.Serial
private void readObjectNoData() throws ObjectStreamException {
throw new InvalidObjectException("Deserialized MessageFormat objects need data");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -981,7 +981,9 @@ public final ForkJoinWorkerThread newThread(ForkJoinPool pool) {
boolean isCommon = (pool.workerNamePrefix == null);
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null && isCommon)
if (sm == null)
return new ForkJoinWorkerThread(null, pool, true, false);
else if (isCommon)
return newCommonWithACC(pool);
else
return newRegularWithACC(pool);
Expand Down
Loading
Loading