Skip to content

Commit 9a5f3eb

Browse files
committed
Merge branch 'master' into jdk-8365606-jlong-julong-refactor
2 parents 0958b10 + 5d65c23 commit 9a5f3eb

File tree

158 files changed

+6351
-4219
lines changed

Some content is hidden

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

158 files changed

+6351
-4219
lines changed

doc/hotspot-unit-tests.html

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -305,11 +305,11 @@ <h3 id="file-location">File location</h3>
305305
the product.</p>
306306
<ul>
307307
<li><p>All unit tests for a class from <code>foo/bar/baz.cpp</code>
308-
should be placed <code>foo/bar/test_baz.cpp</code> in
309-
<code>hotspot/test/native/</code> directory. Having all tests for a
310-
class in one file is a common practice for unit tests, it helps to see
311-
all existing tests at once, share functions and/or resources without
312-
losing encapsulation.</p></li>
308+
should be placed <code>foo/bar/test_baz.cpp</code> in the
309+
<code>test/hotspot/gtest/</code> directory. Having all tests for a class
310+
in one file is a common practice for unit tests, it helps to see all
311+
existing tests at once, share functions and/or resources without losing
312+
encapsulation.</p></li>
313313
<li><p>For tests which test more than one class, directory hierarchy
314314
should be the same as product hierarchy, and file name should reflect
315315
the name of the tested subsystem/functionality. For example, if a
@@ -319,7 +319,7 @@ <h3 id="file-location">File location</h3>
319319
<p>Please note that framework prepends directory name to a test group
320320
name. For example, if <code>TEST(foo, check_this)</code> and
321321
<code>TEST(bar, check_that)</code> are defined in
322-
<code>hotspot/test/native/gc/shared/test_foo.cpp</code> file, they will
322+
<code>test/hotspot/gtest/gc/shared/test_foo.cpp</code> file, they will
323323
be reported as <code>gc/shared/foo::check_this</code> and
324324
<code>gc/shared/bar::check_that</code>.</p>
325325
<h3 id="test-names">Test names</h3>

doc/hotspot-unit-tests.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ recognize your tests.
241241
Test file location should reflect a location of the tested part of the product.
242242

243243
* All unit tests for a class from `foo/bar/baz.cpp` should be placed
244-
`foo/bar/test_baz.cpp` in `hotspot/test/native/` directory. Having all
244+
`foo/bar/test_baz.cpp` in the `test/hotspot/gtest/` directory. Having all
245245
tests for a class in one file is a common practice for unit tests, it
246246
helps to see all existing tests at once, share functions and/or
247247
resources without losing encapsulation.
@@ -254,7 +254,7 @@ sub-system under tests belongs to `gc/g1`, tests should be placed in
254254

255255
Please note that framework prepends directory name to a test group
256256
name. For example, if `TEST(foo, check_this)` and `TEST(bar, check_that)`
257-
are defined in `hotspot/test/native/gc/shared/test_foo.cpp` file, they
257+
are defined in `test/hotspot/gtest/gc/shared/test_foo.cpp` file, they
258258
will be reported as `gc/shared/foo::check_this` and
259259
`gc/shared/bar::check_that`.
260260

make/Docs.gmk

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,7 @@ define SetupApiDocsGenerationBody
291291
$1_INDIRECT_EXPORTS := $$(call FindTransitiveIndirectDepsForModules, $$($1_MODULES))
292292
$1_ALL_MODULES := $$(sort $$($1_MODULES) $$($1_INDIRECT_EXPORTS))
293293

294-
$1_JAVA_ARGS := -Dextlink.spec.version=$$(VERSION_SPECIFICATION) \
295-
-Djspec.version=$$(VERSION_SPECIFICATION)
294+
$1_JAVA_ARGS := -Dextlink.spec.version=$$(VERSION_SPECIFICATION)
296295

297296
ifeq ($$(ENABLE_FULL_DOCS), true)
298297
$1_SEALED_GRAPHS_DIR := $$(SUPPORT_OUTPUTDIR)/docs/$1-sealed-graphs

make/jdk/src/classes/build/tools/taglet/JSpec.java

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
import java.util.stream.Collectors;
3434

3535
import javax.lang.model.element.Element;
36+
import javax.lang.model.element.PackageElement;
37+
import javax.lang.model.element.TypeElement;
3638

3739
import com.sun.source.doctree.DocTree;
3840
import com.sun.source.doctree.LiteralTree;
@@ -44,7 +46,7 @@
4446
import static com.sun.source.doctree.DocTree.Kind.*;
4547

4648
/**
47-
* A base class for block tags to insert a link to an external copy of JLS or JVMS.
49+
* A base class for block tags to insert a link to a local copy of JLS or JVMS.
4850
* The tags can be used as follows:
4951
*
5052
* <pre>
@@ -57,30 +59,23 @@
5759
* &commat;jls 3.4 Line Terminators
5860
* </pre>
5961
*
60-
* will produce the following HTML for a docs build configured for Java SE 12.
62+
* will produce the following HTML, depending on the file containing
63+
* the tag.
6164
*
6265
* <pre>{@code
6366
* <dt>See <i>Java Language Specification</i>:
64-
* <dd><a href="https://docs.oracle.com/javase/specs/jls/se12/html/jls-3.html#jls-3.4">3.4 Line terminators</a>
67+
* <dd><a href="../../specs/jls/jls-3.html#jls-3.4">3.4 Line terminators</a>
6568
* }</pre>
6669
*
67-
* The version of the spec must be set in the jspec.version system property.
70+
* Copies of JLS and JVMS are expected to have been placed in the {@code specs}
71+
* folder. These documents are not included in open-source repositories.
6872
*/
6973
public class JSpec implements Taglet {
70-
static final String SPEC_VERSION;
71-
72-
static {
73-
SPEC_VERSION = System.getProperty("jspec.version");
74-
if (SPEC_VERSION == null) {
75-
throw new RuntimeException("jspec.version property not set");
76-
}
77-
}
7874

7975
public static class JLS extends JSpec {
8076
public JLS() {
8177
super("jls",
8278
"Java Language Specification",
83-
"https://docs.oracle.com/javase/specs/jls/se" + SPEC_VERSION + "/html",
8479
"jls");
8580
}
8681
}
@@ -89,20 +84,17 @@ public static class JVMS extends JSpec {
8984
public JVMS() {
9085
super("jvms",
9186
"Java Virtual Machine Specification",
92-
"https://docs.oracle.com/javase/specs/jvms/se" + SPEC_VERSION + "/html",
9387
"jvms");
9488
}
9589
}
9690

9791
private String tagName;
9892
private String specTitle;
99-
private String baseURL;
10093
private String idPrefix;
10194

102-
JSpec(String tagName, String specTitle, String baseURL, String idPrefix) {
95+
JSpec(String tagName, String specTitle, String idPrefix) {
10396
this.tagName = tagName;
10497
this.specTitle = specTitle;
105-
this.baseURL = baseURL;
10698
this.idPrefix = idPrefix;
10799
}
108100

@@ -169,8 +161,8 @@ public String toString(List<? extends DocTree> tags, Element elem) {
169161
String chapter = m.group("chapter");
170162
String section = m.group("section");
171163

172-
String url = String.format("%1$s/%2$s-%3$s.html#%2$s-%3$s%4$s",
173-
baseURL, idPrefix, chapter, section);
164+
String url = String.format("%1$s/../specs/%2$s/%2$s-%3$s.html#%2$s-%3$s%4$s",
165+
docRoot(elem), idPrefix, chapter, section);
174166

175167
sb.append("<a href=\"")
176168
.append(url)
@@ -216,4 +208,35 @@ private String escape(String s) {
216208
}
217209
}).visit(trees, new StringBuilder()).toString();
218210
}
211+
212+
private String docRoot(Element elem) {
213+
switch (elem.getKind()) {
214+
case MODULE:
215+
return "..";
216+
217+
case PACKAGE:
218+
PackageElement pe = (PackageElement)elem;
219+
String pkgPart = pe.getQualifiedName()
220+
.toString()
221+
.replace('.', '/')
222+
.replaceAll("[^/]+", "..");
223+
return pe.getEnclosingElement() != null
224+
? "../" + pkgPart
225+
: pkgPart;
226+
227+
case CLASS, ENUM, RECORD, INTERFACE, ANNOTATION_TYPE:
228+
TypeElement te = (TypeElement)elem;
229+
return te.getQualifiedName()
230+
.toString()
231+
.replace('.', '/')
232+
.replaceAll("[^/]+", "..");
233+
234+
default:
235+
var enclosing = elem.getEnclosingElement();
236+
if (enclosing == null)
237+
throw new IllegalArgumentException(elem.getKind().toString());
238+
return docRoot(enclosing);
239+
}
240+
}
241+
219242
}

make/jdk/src/classes/build/tools/taglet/ToolGuide.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,15 +156,19 @@ private String docRoot(Element elem) {
156156
return pe.getEnclosingElement() != null
157157
? "../" + pkgPart
158158
: pkgPart;
159-
case CLASS:
159+
160+
case CLASS, ENUM, RECORD, INTERFACE, ANNOTATION_TYPE:
160161
TypeElement te = (TypeElement)elem;
161162
return te.getQualifiedName()
162163
.toString()
163164
.replace('.', '/')
164165
.replaceAll("[^/]+", "..");
165166

166167
default:
167-
throw new IllegalArgumentException(elem.getKind().toString());
168+
var enclosing = elem.getEnclosingElement();
169+
if (enclosing == null)
170+
throw new IllegalArgumentException(elem.getKind().toString());
171+
return docRoot(enclosing);
168172
}
169173
}
170174
}

src/hotspot/cpu/aarch64/aarch64_vector.ad

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,32 @@ source %{
393393
return false;
394394
}
395395

396+
bool Matcher::mask_op_prefers_predicate(int opcode, const TypeVect* vt) {
397+
// Only SVE supports the predicate feature.
398+
if (UseSVE == 0) {
399+
// On architectures that do not support predicate, masks are stored in
400+
// general vector registers (TypeVect) with sizes ranging from TypeVectA
401+
// to TypeVectX based on the vector size in bytes.
402+
assert(vt->isa_vectmask() == nullptr, "mask type is not matched");
403+
return false;
404+
}
405+
406+
assert(vt->isa_vectmask() != nullptr, "expected TypeVectMask on SVE");
407+
switch (opcode) {
408+
case Op_VectorMaskToLong:
409+
case Op_VectorLongToMask:
410+
// These operations lack native SVE predicate instructions and are
411+
// implemented using general vector instructions instead. Use vector
412+
// registers rather than predicate registers to save the mask for
413+
// better performance.
414+
return false;
415+
default:
416+
// By default, the mask operations are implemented with predicate
417+
// instructions with a predicate input/output.
418+
return true;
419+
}
420+
}
421+
396422
// Assert that the given node is not a variable shift.
397423
bool assert_not_var_shift(const Node* n) {
398424
assert(!n->as_ShiftV()->is_var_shift(), "illegal variable shift");
@@ -6249,31 +6275,44 @@ instruct vmask_tolong_neon(iRegLNoSp dst, vReg src) %{
62496275
ins_pipe(pipe_slow);
62506276
%}
62516277

6252-
instruct vmask_tolong_sve(iRegLNoSp dst, pReg src, vReg tmp1, vReg tmp2) %{
6253-
predicate(UseSVE > 0);
6278+
instruct vmask_tolong_sve(iRegLNoSp dst, vReg src, vReg tmp) %{
6279+
predicate(UseSVE > 0 && !VM_Version::supports_svebitperm());
6280+
match(Set dst (VectorMaskToLong src));
6281+
effect(TEMP tmp);
6282+
format %{ "vmask_tolong_sve $dst, $src\t# KILL $tmp" %}
6283+
ins_encode %{
6284+
// Input "src" is a vector of boolean represented as
6285+
// bytes with 0x00/0x01 as element values.
6286+
__ sve_vmask_tolong($dst$$Register, $src$$FloatRegister,
6287+
$tmp$$FloatRegister, Matcher::vector_length(this, $src));
6288+
%}
6289+
ins_pipe(pipe_slow);
6290+
%}
6291+
6292+
instruct vmask_tolong_sve2(iRegLNoSp dst, vReg src, vReg tmp1, vReg tmp2) %{
6293+
predicate(VM_Version::supports_svebitperm());
62546294
match(Set dst (VectorMaskToLong src));
62556295
effect(TEMP tmp1, TEMP tmp2);
6256-
format %{ "vmask_tolong_sve $dst, $src\t# KILL $tmp1, $tmp2" %}
6296+
format %{ "vmask_tolong_sve2 $dst, $src\t# KILL $tmp1, $tmp2" %}
62576297
ins_encode %{
6258-
__ sve_vmask_tolong($dst$$Register, $src$$PRegister,
6259-
Matcher::vector_element_basic_type(this, $src),
6260-
Matcher::vector_length(this, $src),
6261-
$tmp1$$FloatRegister, $tmp2$$FloatRegister);
6298+
// Input "src" is a vector of boolean represented as
6299+
// bytes with 0x00/0x01 as element values.
6300+
__ sve2_vmask_tolong($dst$$Register, $src$$FloatRegister,
6301+
$tmp1$$FloatRegister, $tmp2$$FloatRegister,
6302+
Matcher::vector_length(this, $src));
62626303
%}
62636304
ins_pipe(pipe_slow);
62646305
%}
62656306

62666307
// fromlong
62676308

6268-
instruct vmask_fromlong(pReg dst, iRegL src, vReg tmp1, vReg tmp2) %{
6309+
instruct vmask_fromlong(vReg dst, iRegL src, vReg tmp) %{
62696310
match(Set dst (VectorLongToMask src));
6270-
effect(TEMP tmp1, TEMP tmp2);
6271-
format %{ "vmask_fromlong $dst, $src\t# vector (sve2). KILL $tmp1, $tmp2" %}
6311+
effect(TEMP_DEF dst, TEMP tmp);
6312+
format %{ "vmask_fromlong $dst, $src\t# vector (sve2). KILL $tmp" %}
62726313
ins_encode %{
6273-
__ sve_vmask_fromlong($dst$$PRegister, $src$$Register,
6274-
Matcher::vector_element_basic_type(this),
6275-
Matcher::vector_length(this),
6276-
$tmp1$$FloatRegister, $tmp2$$FloatRegister);
6314+
__ sve_vmask_fromlong($dst$$FloatRegister, $src$$Register,
6315+
$tmp$$FloatRegister, Matcher::vector_length(this));
62776316
%}
62786317
ins_pipe(pipe_slow);
62796318
%}

src/hotspot/cpu/aarch64/aarch64_vector_ad.m4

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,32 @@ source %{
383383
return false;
384384
}
385385

386+
bool Matcher::mask_op_prefers_predicate(int opcode, const TypeVect* vt) {
387+
// Only SVE supports the predicate feature.
388+
if (UseSVE == 0) {
389+
// On architectures that do not support predicate, masks are stored in
390+
// general vector registers (TypeVect) with sizes ranging from TypeVectA
391+
// to TypeVectX based on the vector size in bytes.
392+
assert(vt->isa_vectmask() == nullptr, "mask type is not matched");
393+
return false;
394+
}
395+
396+
assert(vt->isa_vectmask() != nullptr, "expected TypeVectMask on SVE");
397+
switch (opcode) {
398+
case Op_VectorMaskToLong:
399+
case Op_VectorLongToMask:
400+
// These operations lack native SVE predicate instructions and are
401+
// implemented using general vector instructions instead. Use vector
402+
// registers rather than predicate registers to save the mask for
403+
// better performance.
404+
return false;
405+
default:
406+
// By default, the mask operations are implemented with predicate
407+
// instructions with a predicate input/output.
408+
return true;
409+
}
410+
}
411+
386412
// Assert that the given node is not a variable shift.
387413
bool assert_not_var_shift(const Node* n) {
388414
assert(!n->as_ShiftV()->is_var_shift(), "illegal variable shift");
@@ -4303,31 +4329,44 @@ instruct vmask_tolong_neon(iRegLNoSp dst, vReg src) %{
43034329
ins_pipe(pipe_slow);
43044330
%}
43054331

4306-
instruct vmask_tolong_sve(iRegLNoSp dst, pReg src, vReg tmp1, vReg tmp2) %{
4307-
predicate(UseSVE > 0);
4332+
instruct vmask_tolong_sve(iRegLNoSp dst, vReg src, vReg tmp) %{
4333+
predicate(UseSVE > 0 && !VM_Version::supports_svebitperm());
4334+
match(Set dst (VectorMaskToLong src));
4335+
effect(TEMP tmp);
4336+
format %{ "vmask_tolong_sve $dst, $src\t# KILL $tmp" %}
4337+
ins_encode %{
4338+
// Input "src" is a vector of boolean represented as
4339+
// bytes with 0x00/0x01 as element values.
4340+
__ sve_vmask_tolong($dst$$Register, $src$$FloatRegister,
4341+
$tmp$$FloatRegister, Matcher::vector_length(this, $src));
4342+
%}
4343+
ins_pipe(pipe_slow);
4344+
%}
4345+
4346+
instruct vmask_tolong_sve2(iRegLNoSp dst, vReg src, vReg tmp1, vReg tmp2) %{
4347+
predicate(VM_Version::supports_svebitperm());
43084348
match(Set dst (VectorMaskToLong src));
43094349
effect(TEMP tmp1, TEMP tmp2);
4310-
format %{ "vmask_tolong_sve $dst, $src\t# KILL $tmp1, $tmp2" %}
4350+
format %{ "vmask_tolong_sve2 $dst, $src\t# KILL $tmp1, $tmp2" %}
43114351
ins_encode %{
4312-
__ sve_vmask_tolong($dst$$Register, $src$$PRegister,
4313-
Matcher::vector_element_basic_type(this, $src),
4314-
Matcher::vector_length(this, $src),
4315-
$tmp1$$FloatRegister, $tmp2$$FloatRegister);
4352+
// Input "src" is a vector of boolean represented as
4353+
// bytes with 0x00/0x01 as element values.
4354+
__ sve2_vmask_tolong($dst$$Register, $src$$FloatRegister,
4355+
$tmp1$$FloatRegister, $tmp2$$FloatRegister,
4356+
Matcher::vector_length(this, $src));
43164357
%}
43174358
ins_pipe(pipe_slow);
43184359
%}
43194360

43204361
// fromlong
43214362

4322-
instruct vmask_fromlong(pReg dst, iRegL src, vReg tmp1, vReg tmp2) %{
4363+
instruct vmask_fromlong(vReg dst, iRegL src, vReg tmp) %{
43234364
match(Set dst (VectorLongToMask src));
4324-
effect(TEMP tmp1, TEMP tmp2);
4325-
format %{ "vmask_fromlong $dst, $src\t# vector (sve2). KILL $tmp1, $tmp2" %}
4365+
effect(TEMP_DEF dst, TEMP tmp);
4366+
format %{ "vmask_fromlong $dst, $src\t# vector (sve2). KILL $tmp" %}
43264367
ins_encode %{
4327-
__ sve_vmask_fromlong($dst$$PRegister, $src$$Register,
4328-
Matcher::vector_element_basic_type(this),
4329-
Matcher::vector_length(this),
4330-
$tmp1$$FloatRegister, $tmp2$$FloatRegister);
4368+
__ sve_vmask_fromlong($dst$$FloatRegister, $src$$Register,
4369+
$tmp$$FloatRegister, Matcher::vector_length(this));
43314370
%}
43324371
ins_pipe(pipe_slow);
43334372
%}

0 commit comments

Comments
 (0)