Skip to content

Commit dcf07ff

Browse files
committed
Merge branch 'master' of https://github.com/openjdk/jdk into docs/cf-overall
2 parents b2894aa + 605b53e commit dcf07ff

File tree

37 files changed

+666
-637
lines changed

37 files changed

+666
-637
lines changed

make/InitSupport.gmk

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
2+
# Copyright (c) 2011, 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
@@ -211,13 +211,15 @@ ifeq ($(HAS_SPEC), )
211211
$$(if $$(findstring $$(CONF), $$(var)), $$(var))))
212212
endif
213213
ifneq ($$(filter $$(CONF), $$(matching_confs)), )
214+
ifneq ($$(word 2, $$(matching_confs)), )
215+
# Don't repeat this output on make restarts caused by including
216+
# generated files.
217+
ifeq ($$(MAKE_RESTARTS), )
218+
$$(info Using exact match for CONF=$$(CONF) (other matches are possible))
219+
endif
220+
endif
214221
# If we found an exact match, use that
215222
matching_confs := $$(CONF)
216-
# Don't repeat this output on make restarts caused by including
217-
# generated files.
218-
ifeq ($$(MAKE_RESTARTS), )
219-
$$(info Using exact match for CONF=$$(CONF) (other matches are possible))
220-
endif
221223
endif
222224
endif
223225
ifeq ($$(matching_confs), )

make/autoconf/basic.m4

+6
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,15 @@ AC_DEFUN_ONCE([BASIC_SETUP_PATHS],
8484
8585
# We get the top-level directory from the supporting wrappers.
8686
BASIC_WINDOWS_VERIFY_DIR($TOPDIR, source)
87+
orig_topdir="$TOPDIR"
8788
UTIL_FIXUP_PATH(TOPDIR)
8889
AC_MSG_CHECKING([for top-level directory])
8990
AC_MSG_RESULT([$TOPDIR])
91+
if test "x$TOPDIR" != "x$orig_topdir"; then
92+
AC_MSG_WARN([Your top dir was originally represented as $orig_topdir,])
93+
AC_MSG_WARN([but after rewriting it became $TOPDIR.])
94+
AC_MSG_WARN([This typically means you have characters like space in the path, which can cause all kind of trouble.])
95+
fi
9096
AC_SUBST(TOPDIR)
9197
9298
if test "x$CUSTOM_ROOT" != x; then

make/autoconf/util_paths.m4

+6-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,10 @@ AC_DEFUN([UTIL_FIXUP_PATH],
7777
imported_path=""
7878
fi
7979
fi
80-
if test "x$imported_path" != "x$path"; then
80+
[ imported_path_lower=`$ECHO $imported_path | $TR '[:upper:]' '[:lower:]'` ]
81+
[ orig_path_lower=`$ECHO $path | $TR '[:upper:]' '[:lower:]'` ]
82+
# If only case differs, keep original path
83+
if test "x$imported_path_lower" != "x$orig_path_lower"; then
8184
$1="$imported_path"
8285
fi
8386
else
@@ -357,6 +360,8 @@ AC_DEFUN([UTIL_SETUP_TOOL],
357360
fi
358361
$1="$tool_command"
359362
fi
363+
# Make sure we add fixpath if needed
364+
UTIL_FIXUP_EXECUTABLE($1)
360365
if test "x$tool_args" != x; then
361366
# If we got arguments, re-append them to the command after the fixup.
362367
$1="[$]$1 $tool_args"

src/hotspot/share/nmt/mallocHeader.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class outputStream;
3636
/*
3737
* Malloc tracking header.
3838
*
39-
* If NMT is active (state >= minimal), we need to track allocations. A simple and cheap way to
39+
* If NMT is active (state >= summary), we need to track allocations. A simple and cheap way to
4040
* do this is by using malloc headers.
4141
*
4242
* The user allocation is preceded by a header and is immediately followed by a (possibly unaligned)

src/hotspot/share/opto/stringopts.cpp

+98-63
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ class StringConcat : public ResourceObj {
173173
assert(!_control.contains(ctrl), "only push once");
174174
_control.push(ctrl);
175175
}
176+
bool has_control(Node* ctrl) {
177+
return _control.contains(ctrl);
178+
}
176179
void add_constructor(Node* init) {
177180
assert(!_constructors.contains(init), "only push once");
178181
_constructors.push(init);
@@ -407,7 +410,66 @@ Node_List PhaseStringOpts::collect_toString_calls() {
407410
return string_calls;
408411
}
409412

410-
// Recognize a fluent-chain of StringBuilder/Buffer. They are either explicit usages
413+
PhaseStringOpts::ProcessAppendResult PhaseStringOpts::process_append_candidate(CallStaticJavaNode* cnode,
414+
StringConcat* sc,
415+
ciMethod* m,
416+
ciSymbol* string_sig,
417+
ciSymbol* int_sig,
418+
ciSymbol* char_sig) {
419+
if (cnode->method() != nullptr && !cnode->method()->is_static() &&
420+
cnode->method()->holder() == m->holder() &&
421+
cnode->method()->name() == ciSymbols::append_name() &&
422+
(cnode->method()->signature()->as_symbol() == string_sig ||
423+
cnode->method()->signature()->as_symbol() == char_sig ||
424+
cnode->method()->signature()->as_symbol() == int_sig)) {
425+
if (sc->has_control(cnode)) {
426+
return ProcessAppendResult::AppendWasAdded;
427+
}
428+
sc->add_control(cnode);
429+
Node* arg = cnode->in(TypeFunc::Parms + 1);
430+
if (arg == nullptr || arg->is_top()) {
431+
#ifndef PRODUCT
432+
if (PrintOptimizeStringConcat) {
433+
tty->print("giving up because the call is effectively dead");
434+
cnode->jvms()->dump_spec(tty);
435+
tty->cr();
436+
}
437+
#endif
438+
return ProcessAppendResult::AbortOptimization;
439+
}
440+
441+
if (cnode->method()->signature()->as_symbol() == int_sig) {
442+
sc->push_int(arg);
443+
} else if (cnode->method()->signature()->as_symbol() == char_sig) {
444+
sc->push_char(arg);
445+
} else if (arg->is_Proj() && arg->in(0)->is_CallStaticJava()) {
446+
CallStaticJavaNode* csj = arg->in(0)->as_CallStaticJava();
447+
if (csj->method() != nullptr &&
448+
csj->method()->intrinsic_id() == vmIntrinsics::_Integer_toString &&
449+
arg->outcnt() == 1) {
450+
// _control is the list of StringBuilder calls nodes which
451+
// will be replaced by new String code after this optimization.
452+
// Integer::toString() call is not part of StringBuilder calls
453+
// chain. It could be eliminated only if its result is used
454+
// only by this SB calls chain.
455+
// Another limitation: it should be used only once because
456+
// it is unknown that it is used only by this SB calls chain
457+
// until all related SB calls nodes are collected.
458+
assert(arg->unique_out() == cnode, "sanity");
459+
sc->add_control(csj);
460+
sc->push_int(csj->in(TypeFunc::Parms));
461+
} else {
462+
sc->push_string(arg);
463+
}
464+
} else {
465+
sc->push_string(arg);
466+
}
467+
return ProcessAppendResult::AppendWasAdded;
468+
}
469+
return ProcessAppendResult::CandidateIsNotAppend;
470+
}
471+
472+
// Recognize fluent-chain and non-fluent uses of StringBuilder/Buffer. They are either explicit usages
411473
// of them or the legacy bytecodes of string concatenation prior to JEP-280. eg.
412474
//
413475
// String result = new StringBuilder()
@@ -416,18 +478,17 @@ Node_List PhaseStringOpts::collect_toString_calls() {
416478
// .append(123)
417479
// .toString(); // "foobar123"
418480
//
419-
// PS: Only a certain subset of constructor and append methods are acceptable.
420-
// The criterion is that the length of argument is easy to work out in this phrase.
421-
// It will drop complex cases such as Object.
481+
// Fluent-chains are recognized by walking upwards along the receivers, starting from toString().
482+
// Once the allocation of the StringBuilder has been reached, DU pairs are examined to find the
483+
// constructor and non-fluent uses of the StringBuilder such as in this example:
422484
//
423-
// Since it walks along the receivers of fluent-chain, it will give up if the codeshape is
424-
// not "fluent" enough. eg.
425485
// StringBuilder sb = new StringBuilder();
426486
// sb.append("foo");
427487
// sb.toString();
428488
//
429-
// The receiver of toString method is the result of Allocation Node(CheckCastPP).
430-
// The append method is overlooked. It will fail at validate_control_flow() test.
489+
// PS: Only a certain subset of constructor and append methods are acceptable.
490+
// The criterion is that the length of argument is easy to work out in this phrase.
491+
// It will drop complex cases such as Object.
431492
//
432493
StringConcat* PhaseStringOpts::build_candidate(CallStaticJavaNode* call) {
433494
ciMethod* m = call->method();
@@ -466,7 +527,7 @@ StringConcat* PhaseStringOpts::build_candidate(CallStaticJavaNode* call) {
466527
if (cnode == nullptr) {
467528
alloc = recv->isa_Allocate();
468529
if (alloc == nullptr) {
469-
break;
530+
return nullptr;
470531
}
471532
// Find the constructor call
472533
Node* result = alloc->result_cast();
@@ -478,7 +539,7 @@ StringConcat* PhaseStringOpts::build_candidate(CallStaticJavaNode* call) {
478539
alloc->jvms()->dump_spec(tty); tty->cr();
479540
}
480541
#endif
481-
break;
542+
return nullptr;
482543
}
483544
Node* constructor = nullptr;
484545
for (SimpleDUIterator i(result); i.has_next(); i.next()) {
@@ -489,6 +550,10 @@ StringConcat* PhaseStringOpts::build_candidate(CallStaticJavaNode* call) {
489550
use->method()->name() == ciSymbols::object_initializer_name() &&
490551
use->method()->holder() == m->holder()) {
491552
// Matched the constructor.
553+
if (constructor != nullptr) {
554+
// The constructor again. We must only process it once.
555+
continue;
556+
}
492557
ciSymbol* sig = use->method()->signature()->as_symbol();
493558
if (sig == ciSymbols::void_method_signature() ||
494559
sig == ciSymbols::int_void_signature() ||
@@ -542,7 +607,16 @@ StringConcat* PhaseStringOpts::build_candidate(CallStaticJavaNode* call) {
542607
}
543608
#endif
544609
}
545-
break;
610+
} else if (use != nullptr) {
611+
if (process_append_candidate(use, sc, m, string_sig, int_sig, char_sig) == ProcessAppendResult::AbortOptimization) {
612+
// We must abort if process_append_candidate tells us to...
613+
return nullptr;
614+
}
615+
// ...but we do not care if we really found an append or not:
616+
// - If we found an append, that's perfect. Nothing further to do.
617+
// - If this is a call to an unrelated method, validate_mem_flow() (and validate_control_flow())
618+
// will later check if this call prevents the optimization. So nothing to do here.
619+
// We will continue to look for the constructor (if not found already) and appends.
546620
}
547621
}
548622
if (constructor == nullptr) {
@@ -553,7 +627,7 @@ StringConcat* PhaseStringOpts::build_candidate(CallStaticJavaNode* call) {
553627
alloc->jvms()->dump_spec(tty); tty->cr();
554628
}
555629
#endif
556-
break;
630+
return nullptr;
557631
}
558632

559633
// Walked all the way back and found the constructor call so see
@@ -568,62 +642,23 @@ StringConcat* PhaseStringOpts::build_candidate(CallStaticJavaNode* call) {
568642
} else {
569643
return nullptr;
570644
}
571-
} else if (cnode->method() == nullptr) {
572-
break;
573-
} else if (!cnode->method()->is_static() &&
574-
cnode->method()->holder() == m->holder() &&
575-
cnode->method()->name() == ciSymbols::append_name() &&
576-
(cnode->method()->signature()->as_symbol() == string_sig ||
577-
cnode->method()->signature()->as_symbol() == char_sig ||
578-
cnode->method()->signature()->as_symbol() == int_sig)) {
579-
sc->add_control(cnode);
580-
Node* arg = cnode->in(TypeFunc::Parms + 1);
581-
if (arg == nullptr || arg->is_top()) {
645+
} else {
646+
ProcessAppendResult result = process_append_candidate(cnode, sc, m, string_sig, int_sig, char_sig);
647+
648+
if (result == ProcessAppendResult::AbortOptimization) {
649+
return nullptr;
650+
} else if (result == ProcessAppendResult::CandidateIsNotAppend) {
651+
// some unhandled signature
582652
#ifndef PRODUCT
583653
if (PrintOptimizeStringConcat) {
584-
tty->print("giving up because the call is effectively dead");
585-
cnode->jvms()->dump_spec(tty); tty->cr();
654+
tty->print("giving up because encountered unexpected signature ");
655+
cnode->tf()->dump();
656+
tty->cr();
657+
cnode->in(TypeFunc::Parms + 1)->dump();
586658
}
587659
#endif
588-
break;
589-
}
590-
if (cnode->method()->signature()->as_symbol() == int_sig) {
591-
sc->push_int(arg);
592-
} else if (cnode->method()->signature()->as_symbol() == char_sig) {
593-
sc->push_char(arg);
594-
} else {
595-
if (arg->is_Proj() && arg->in(0)->is_CallStaticJava()) {
596-
CallStaticJavaNode* csj = arg->in(0)->as_CallStaticJava();
597-
if (csj->method() != nullptr &&
598-
csj->method()->intrinsic_id() == vmIntrinsics::_Integer_toString &&
599-
arg->outcnt() == 1) {
600-
// _control is the list of StringBuilder calls nodes which
601-
// will be replaced by new String code after this optimization.
602-
// Integer::toString() call is not part of StringBuilder calls
603-
// chain. It could be eliminated only if its result is used
604-
// only by this SB calls chain.
605-
// Another limitation: it should be used only once because
606-
// it is unknown that it is used only by this SB calls chain
607-
// until all related SB calls nodes are collected.
608-
assert(arg->unique_out() == cnode, "sanity");
609-
sc->add_control(csj);
610-
sc->push_int(csj->in(TypeFunc::Parms));
611-
continue;
612-
}
613-
}
614-
sc->push_string(arg);
615-
}
616-
continue;
617-
} else {
618-
// some unhandled signature
619-
#ifndef PRODUCT
620-
if (PrintOptimizeStringConcat) {
621-
tty->print("giving up because encountered unexpected signature ");
622-
cnode->tf()->dump(); tty->cr();
623-
cnode->in(TypeFunc::Parms + 1)->dump();
660+
return nullptr;
624661
}
625-
#endif
626-
break;
627662
}
628663
}
629664
return nullptr;

src/hotspot/share/opto/stringopts.hpp

+22-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2009, 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
@@ -34,7 +34,7 @@ class IdealVariable;
3434
class PhaseStringOpts : public Phase {
3535
friend class StringConcat;
3636

37-
private:
37+
private:
3838
PhaseGVN* _gvn;
3939

4040
// List of dead nodes to clean up aggressively at the end
@@ -53,6 +53,23 @@ class PhaseStringOpts : public Phase {
5353
// a single string construction.
5454
StringConcat* build_candidate(CallStaticJavaNode* call);
5555

56+
enum class ProcessAppendResult {
57+
// Indicates that the candidate was indeed an append and process_append_candidate processed it
58+
// accordingly (added it to the StringConcat etc.)
59+
AppendWasAdded,
60+
// The candidate turned out not to be an append call. process_append_candidate did not do anything.
61+
CandidateIsNotAppend,
62+
// The candidate is an append call, but circumstances completely preventing string concat
63+
// optimization were detected and the optimization must abort.
64+
AbortOptimization
65+
};
66+
67+
// Called from build_candidate. Looks at an "append candidate", a call that might be a call
68+
// to StringBuilder::append. If so, adds it to the StringConcat.
69+
ProcessAppendResult process_append_candidate(CallStaticJavaNode* cnode, StringConcat* sc,
70+
ciMethod* m, ciSymbol* string_sig, ciSymbol* int_sig,
71+
ciSymbol* char_sig);
72+
5673
// Replace all the SB calls in concat with an optimization String allocation
5774
void replace_string_concat(StringConcat* concat);
5875

@@ -105,12 +122,13 @@ class PhaseStringOpts : public Phase {
105122
unroll_string_copy_length = 6
106123
};
107124

108-
public:
125+
public:
109126
PhaseStringOpts(PhaseGVN* gvn);
110127

111128
#ifndef PRODUCT
112129
static void print_statistics();
113-
private:
130+
131+
private:
114132
static uint _stropts_replaced;
115133
static uint _stropts_merged;
116134
static uint _stropts_total;

src/java.base/share/data/tzdata/VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@
2121
# or visit www.oracle.com if you need additional information or have any
2222
# questions.
2323
#
24-
tzdata2024b
24+
tzdata2025a

src/java.base/share/data/tzdata/antarctica

+2
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ Zone Antarctica/Mawson 0 - -00 1954 Feb 13
197197

198198
# France & Italy - year-round base
199199
# Concordia, -750600+1232000, since 2005
200+
# https://en.wikipedia.org/wiki/Concordia_Station
201+
# Can use Asia/Singapore, which it has agreed with since inception.
200202

201203
# Germany - year-round base
202204
# Neumayer III, -704080-0081602, since 2009

0 commit comments

Comments
 (0)