Skip to content

Commit ea26b55

Browse files
committed
Merge tag 'jdk-25.0.2+10' into sapmachine25
Added tag jdk-25.0.2+10 for changeset 405a569
2 parents 759d5a8 + 405a569 commit ea26b55

File tree

46 files changed

+1182
-572
lines changed

Some content is hidden

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

46 files changed

+1182
-572
lines changed

.jcheck/conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[general]
22
project=jdk-updates
33
jbs=JDK
4-
version=25.0.3
4+
version=25.0.2
55

66
[checks]
77
error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists,copyright

src/hotspot/share/classfile/verifier.cpp

Lines changed: 0 additions & 230 deletions
Original file line numberDiff line numberDiff line change
@@ -2436,217 +2436,6 @@ void ClassVerifier::verify_field_instructions(RawBytecodeStream* bcs,
24362436
}
24372437
}
24382438

2439-
// Look at the method's handlers. If the bci is in the handler's try block
2440-
// then check if the handler_pc is already on the stack. If not, push it
2441-
// unless the handler has already been scanned.
2442-
void ClassVerifier::push_handlers(ExceptionTable* exhandlers,
2443-
GrowableArray<u4>* handler_list,
2444-
GrowableArray<u4>* handler_stack,
2445-
u4 bci) {
2446-
int exlength = exhandlers->length();
2447-
for(int x = 0; x < exlength; x++) {
2448-
if (bci >= exhandlers->start_pc(x) && bci < exhandlers->end_pc(x)) {
2449-
u4 exhandler_pc = exhandlers->handler_pc(x);
2450-
if (!handler_list->contains(exhandler_pc)) {
2451-
handler_stack->append_if_missing(exhandler_pc);
2452-
handler_list->append(exhandler_pc);
2453-
}
2454-
}
2455-
}
2456-
}
2457-
2458-
// Return TRUE if all code paths starting with start_bc_offset end in
2459-
// bytecode athrow or loop.
2460-
bool ClassVerifier::ends_in_athrow(u4 start_bc_offset) {
2461-
ResourceMark rm;
2462-
// Create bytecode stream.
2463-
RawBytecodeStream bcs(method());
2464-
int code_length = method()->code_size();
2465-
bcs.set_start(start_bc_offset);
2466-
2467-
// Create stack for storing bytecode start offsets for if* and *switch.
2468-
GrowableArray<u4>* bci_stack = new GrowableArray<u4>(30);
2469-
// Create stack for handlers for try blocks containing this handler.
2470-
GrowableArray<u4>* handler_stack = new GrowableArray<u4>(30);
2471-
// Create list of handlers that have been pushed onto the handler_stack
2472-
// so that handlers embedded inside of their own TRY blocks only get
2473-
// scanned once.
2474-
GrowableArray<u4>* handler_list = new GrowableArray<u4>(30);
2475-
// Create list of visited branch opcodes (goto* and if*).
2476-
GrowableArray<u4>* visited_branches = new GrowableArray<u4>(30);
2477-
ExceptionTable exhandlers(_method());
2478-
2479-
while (true) {
2480-
if (bcs.is_last_bytecode()) {
2481-
// if no more starting offsets to parse or if at the end of the
2482-
// method then return false.
2483-
if ((bci_stack->is_empty()) || (bcs.end_bci() == code_length))
2484-
return false;
2485-
// Pop a bytecode starting offset and scan from there.
2486-
bcs.set_start(bci_stack->pop());
2487-
}
2488-
Bytecodes::Code opcode = bcs.raw_next();
2489-
int bci = bcs.bci();
2490-
2491-
// If the bytecode is in a TRY block, push its handlers so they
2492-
// will get parsed.
2493-
push_handlers(&exhandlers, handler_list, handler_stack, bci);
2494-
2495-
switch (opcode) {
2496-
case Bytecodes::_if_icmpeq:
2497-
case Bytecodes::_if_icmpne:
2498-
case Bytecodes::_if_icmplt:
2499-
case Bytecodes::_if_icmpge:
2500-
case Bytecodes::_if_icmpgt:
2501-
case Bytecodes::_if_icmple:
2502-
case Bytecodes::_ifeq:
2503-
case Bytecodes::_ifne:
2504-
case Bytecodes::_iflt:
2505-
case Bytecodes::_ifge:
2506-
case Bytecodes::_ifgt:
2507-
case Bytecodes::_ifle:
2508-
case Bytecodes::_if_acmpeq:
2509-
case Bytecodes::_if_acmpne:
2510-
case Bytecodes::_ifnull:
2511-
case Bytecodes::_ifnonnull: {
2512-
int target = bcs.dest();
2513-
if (visited_branches->contains(bci)) {
2514-
if (bci_stack->is_empty()) {
2515-
if (handler_stack->is_empty()) {
2516-
return true;
2517-
} else {
2518-
// Parse the catch handlers for try blocks containing athrow.
2519-
bcs.set_start(handler_stack->pop());
2520-
}
2521-
} else {
2522-
// Pop a bytecode starting offset and scan from there.
2523-
bcs.set_start(bci_stack->pop());
2524-
}
2525-
} else {
2526-
if (target > bci) { // forward branch
2527-
if (target >= code_length) return false;
2528-
// Push the branch target onto the stack.
2529-
bci_stack->push(target);
2530-
// then, scan bytecodes starting with next.
2531-
bcs.set_start(bcs.next_bci());
2532-
} else { // backward branch
2533-
// Push bytecode offset following backward branch onto the stack.
2534-
bci_stack->push(bcs.next_bci());
2535-
// Check bytecodes starting with branch target.
2536-
bcs.set_start(target);
2537-
}
2538-
// Record target so we don't branch here again.
2539-
visited_branches->append(bci);
2540-
}
2541-
break;
2542-
}
2543-
2544-
case Bytecodes::_goto:
2545-
case Bytecodes::_goto_w: {
2546-
int offset = (opcode == Bytecodes::_goto ? bcs.get_offset_s2() : bcs.get_offset_s4());
2547-
int min_offset = -1 * max_method_code_size;
2548-
// Check offset for overflow
2549-
if (offset < min_offset || offset > max_method_code_size) return false;
2550-
2551-
int target = bci + offset;
2552-
if (visited_branches->contains(bci)) {
2553-
if (bci_stack->is_empty()) {
2554-
if (handler_stack->is_empty()) {
2555-
return true;
2556-
} else {
2557-
// Parse the catch handlers for try blocks containing athrow.
2558-
bcs.set_start(handler_stack->pop());
2559-
}
2560-
} else {
2561-
// Been here before, pop new starting offset from stack.
2562-
bcs.set_start(bci_stack->pop());
2563-
}
2564-
} else {
2565-
if (target >= code_length) return false;
2566-
// Continue scanning from the target onward.
2567-
bcs.set_start(target);
2568-
// Record target so we don't branch here again.
2569-
visited_branches->append(bci);
2570-
}
2571-
break;
2572-
}
2573-
2574-
// Check that all switch alternatives end in 'athrow' bytecodes. Since it
2575-
// is difficult to determine where each switch alternative ends, parse
2576-
// each switch alternative until either hit a 'return', 'athrow', or reach
2577-
// the end of the method's bytecodes. This is gross but should be okay
2578-
// because:
2579-
// 1. tableswitch and lookupswitch byte codes in handlers for ctor explicit
2580-
// constructor invocations should be rare.
2581-
// 2. if each switch alternative ends in an athrow then the parsing should be
2582-
// short. If there is no athrow then it is bogus code, anyway.
2583-
case Bytecodes::_lookupswitch:
2584-
case Bytecodes::_tableswitch:
2585-
{
2586-
address aligned_bcp = align_up(bcs.bcp() + 1, jintSize);
2587-
int default_offset = Bytes::get_Java_u4(aligned_bcp) + bci;
2588-
int keys, delta;
2589-
if (opcode == Bytecodes::_tableswitch) {
2590-
jint low = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize);
2591-
jint high = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize);
2592-
// This is invalid, but let the regular bytecode verifier
2593-
// report this because the user will get a better error message.
2594-
if (low > high) return true;
2595-
keys = high - low + 1;
2596-
delta = 1;
2597-
} else {
2598-
keys = (int)Bytes::get_Java_u4(aligned_bcp + jintSize);
2599-
delta = 2;
2600-
}
2601-
// Invalid, let the regular bytecode verifier deal with it.
2602-
if (keys < 0) return true;
2603-
2604-
// Push the offset of the next bytecode onto the stack.
2605-
bci_stack->push(bcs.next_bci());
2606-
2607-
// Push the switch alternatives onto the stack.
2608-
for (int i = 0; i < keys; i++) {
2609-
int min_offset = -1 * max_method_code_size;
2610-
int offset = (jint)Bytes::get_Java_u4(aligned_bcp+(3+i*delta)*jintSize);
2611-
if (offset < min_offset || offset > max_method_code_size) return false;
2612-
int target = bci + offset;
2613-
if (target > code_length) return false;
2614-
bci_stack->push(target);
2615-
}
2616-
2617-
// Start bytecode parsing for the switch at the default alternative.
2618-
if (default_offset > code_length) return false;
2619-
bcs.set_start(default_offset);
2620-
break;
2621-
}
2622-
2623-
case Bytecodes::_return:
2624-
return false;
2625-
2626-
case Bytecodes::_athrow:
2627-
{
2628-
if (bci_stack->is_empty()) {
2629-
if (handler_stack->is_empty()) {
2630-
return true;
2631-
} else {
2632-
// Parse the catch handlers for try blocks containing athrow.
2633-
bcs.set_start(handler_stack->pop());
2634-
}
2635-
} else {
2636-
// Pop a bytecode offset and starting scanning from there.
2637-
bcs.set_start(bci_stack->pop());
2638-
}
2639-
}
2640-
break;
2641-
2642-
default:
2643-
;
2644-
} // end switch
2645-
} // end while loop
2646-
2647-
return false;
2648-
}
2649-
26502439
void ClassVerifier::verify_invoke_init(
26512440
RawBytecodeStream* bcs, u2 ref_class_index, VerificationType ref_class_type,
26522441
StackMapFrame* current_frame, u4 code_length, bool in_try_block,
@@ -2671,25 +2460,6 @@ void ClassVerifier::verify_invoke_init(
26712460
// sure that all catch clause paths end in a throw. Otherwise, this can
26722461
// result in returning an incomplete object.
26732462
if (in_try_block) {
2674-
ExceptionTable exhandlers(_method());
2675-
int exlength = exhandlers.length();
2676-
for(int i = 0; i < exlength; i++) {
2677-
u2 start_pc = exhandlers.start_pc(i);
2678-
u2 end_pc = exhandlers.end_pc(i);
2679-
2680-
if (bci >= start_pc && bci < end_pc) {
2681-
if (!ends_in_athrow(exhandlers.handler_pc(i))) {
2682-
verify_error(ErrorContext::bad_code(bci),
2683-
"Bad <init> method call from after the start of a try block");
2684-
return;
2685-
} else if (log_is_enabled(Debug, verification)) {
2686-
ResourceMark rm(THREAD);
2687-
log_debug(verification)("Survived call to ends_in_athrow(): %s",
2688-
current_class()->name()->as_C_string());
2689-
}
2690-
}
2691-
}
2692-
26932463
// Check the exception handler target stackmaps with the locals from the
26942464
// incoming stackmap (before initialize_object() changes them to outgoing
26952465
// state).

src/hotspot/share/classfile/verifier.hpp

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -334,17 +334,6 @@ class ClassVerifier : public StackObj {
334334
bool* this_uninit, const constantPoolHandle& cp, StackMapTable* stackmap_table,
335335
TRAPS);
336336

337-
// Used by ends_in_athrow() to push all handlers that contain bci onto the
338-
// handler_stack, if the handler has not already been pushed on the stack.
339-
void push_handlers(ExceptionTable* exhandlers,
340-
GrowableArray<u4>* handler_list,
341-
GrowableArray<u4>* handler_stack,
342-
u4 bci);
343-
344-
// Returns true if all paths starting with start_bc_offset end in athrow
345-
// bytecode or loop.
346-
bool ends_in_athrow(u4 start_bc_offset);
347-
348337
void verify_invoke_instructions(
349338
RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame,
350339
bool in_try_block, bool* this_uninit, VerificationType return_type,

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@
3535

3636
package java.util.concurrent;
3737

38+
import jdk.internal.misc.Unsafe;
39+
40+
import java.io.IOException;
41+
import java.io.ObjectInputStream;
42+
import java.io.ObjectStreamException;
43+
import java.io.Serial;
44+
import java.io.StreamCorruptedException;
3845
import java.util.AbstractSet;
3946
import java.util.Collection;
4047
import java.util.Iterator;
@@ -445,4 +452,38 @@ public Spliterator<E> spliterator() {
445452
return Spliterators.spliterator
446453
(al.getArray(), Spliterator.IMMUTABLE | Spliterator.DISTINCT);
447454
}
455+
456+
/**
457+
* De-serialization without data not supported for this class.
458+
*/
459+
@Serial
460+
private void readObjectNoData() throws ObjectStreamException {
461+
throw new StreamCorruptedException("Deserialized CopyOnWriteArraySet requires data");
462+
}
463+
464+
/**
465+
* Reconstitutes the {@code CopyOnWriteArraySet} instance from a stream
466+
* (that is, deserializes it).
467+
* @throws StreamCorruptedException if the object read from the stream is invalid.
468+
*/
469+
@Serial
470+
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
471+
CopyOnWriteArrayList<E> newAl; // Set during the duplicate check
472+
473+
@SuppressWarnings("unchecked")
474+
CopyOnWriteArrayList<E> inAl = (CopyOnWriteArrayList<E>) in.readFields().get("al", null);
475+
476+
if (inAl == null
477+
|| inAl.getClass() != CopyOnWriteArrayList.class
478+
|| (newAl = new CopyOnWriteArrayList<>()).addAllAbsent(inAl) != inAl.size()) {
479+
throw new StreamCorruptedException("Content is invalid");
480+
}
481+
482+
final Unsafe U = Unsafe.getUnsafe();
483+
U.putReference(
484+
this,
485+
U.objectFieldOffset(CopyOnWriteArraySet.class, "al"),
486+
newAl
487+
);
488+
}
448489
}

src/java.base/share/classes/jdk/internal/classfile/impl/verifier/VerifierImpl.java

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,13 +1515,6 @@ void verify_field_instructions(RawBytecodeHelper bcs, VerificationFrame current_
15151515
}
15161516
}
15171517

1518-
// Return TRUE if all code paths starting with start_bc_offset end in
1519-
// bytecode athrow or loop.
1520-
boolean ends_in_athrow(int start_bc_offset) {
1521-
log_info("unimplemented VerifierImpl.ends_in_athrow");
1522-
return true;
1523-
}
1524-
15251518
boolean verify_invoke_init(RawBytecodeHelper bcs, int ref_class_index, VerificationType ref_class_type,
15261519
VerificationFrame current_frame, int code_length, boolean in_try_block,
15271520
boolean this_uninit, ConstantPoolWrapper cp, VerificationTable stackmap_table) {
@@ -1534,16 +1527,6 @@ boolean verify_invoke_init(RawBytecodeHelper bcs, int ref_class_index, Verificat
15341527
verifyError("Bad <init> method call");
15351528
}
15361529
if (in_try_block) {
1537-
for(var exhandler : _method.exceptionTable()) {
1538-
int start_pc = exhandler[0];
1539-
int end_pc = exhandler[1];
1540-
1541-
if (bci >= start_pc && bci < end_pc) {
1542-
if (!ends_in_athrow(exhandler[2])) {
1543-
verifyError("Bad <init> method call from after the start of a try block");
1544-
}
1545-
}
1546-
}
15471530
verify_exception_handler_targets(bci, true, current_frame, stackmap_table);
15481531
}
15491532
current_frame.initialize_object(type, current_type());

0 commit comments

Comments
 (0)