Skip to content

Commit 047b8bf

Browse files
committed
8224974: Implement JEP 352
Non-Volatile Mapped Byte Buffers Reviewed-by: alanb, kvn, bpb, gromero, darcy, shade, bulasevich, dchuyko
1 parent db359f1 commit 047b8bf

Some content is hidden

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

53 files changed

+1399
-68
lines changed

make/common/Modules.gmk

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
2+
# Copyright (c) 2014, 2019, 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
@@ -64,6 +64,7 @@ BOOT_MODULES += \
6464
jdk.management.jfr \
6565
jdk.management.agent \
6666
jdk.net \
67+
jdk.nio.mapmode \
6768
jdk.sctp \
6869
jdk.unsupported \
6970
#

src/hotspot/cpu/aarch64/aarch64.ad

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2185,17 +2185,21 @@ int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf)
21852185
//=============================================================================
21862186

21872187
const bool Matcher::match_rule_supported(int opcode) {
2188+
if (!has_match_rule(opcode))
2189+
return false;
21882190

2191+
bool ret_value = true;
21892192
switch (opcode) {
2190-
default:
2191-
break;
2192-
}
2193-
2194-
if (!has_match_rule(opcode)) {
2195-
return false;
2193+
case Op_CacheWB:
2194+
case Op_CacheWBPreSync:
2195+
case Op_CacheWBPostSync:
2196+
if (!VM_Version::supports_data_cache_line_flush()) {
2197+
ret_value = false;
2198+
}
2199+
break;
21962200
}
21972201

2198-
return true; // Per default match rules are supported.
2202+
return ret_value; // Per default match rules are supported.
21992203
}
22002204

22012205
const bool Matcher::match_rule_supported_vector(int opcode, int vlen) {
@@ -7769,6 +7773,47 @@ instruct storeD_volatile(vRegD src, /* sync_memory*/indirect mem)
77697773

77707774
// ---------------- end of volatile loads and stores ----------------
77717775

7776+
instruct cacheWB(indirect addr)
7777+
%{
7778+
predicate(VM_Version::supports_data_cache_line_flush());
7779+
match(CacheWB addr);
7780+
7781+
ins_cost(100);
7782+
format %{"cache wb $addr" %}
7783+
ins_encode %{
7784+
assert($addr->index_position() < 0, "should be");
7785+
assert($addr$$disp == 0, "should be");
7786+
__ cache_wb(Address($addr$$base$$Register, 0));
7787+
%}
7788+
ins_pipe(pipe_slow); // XXX
7789+
%}
7790+
7791+
instruct cacheWBPreSync()
7792+
%{
7793+
predicate(VM_Version::supports_data_cache_line_flush());
7794+
match(CacheWBPreSync);
7795+
7796+
ins_cost(100);
7797+
format %{"cache wb presync" %}
7798+
ins_encode %{
7799+
__ cache_wbsync(true);
7800+
%}
7801+
ins_pipe(pipe_slow); // XXX
7802+
%}
7803+
7804+
instruct cacheWBPostSync()
7805+
%{
7806+
predicate(VM_Version::supports_data_cache_line_flush());
7807+
match(CacheWBPostSync);
7808+
7809+
ins_cost(100);
7810+
format %{"cache wb postsync" %}
7811+
ins_encode %{
7812+
__ cache_wbsync(false);
7813+
%}
7814+
ins_pipe(pipe_slow); // XXX
7815+
%}
7816+
77727817
// ============================================================================
77737818
// BSWAP Instructions
77747819

src/hotspot/cpu/aarch64/assembler_aarch64.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
3-
* Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
3+
* Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
66
* This code is free software; you can redistribute it and/or modify it
@@ -1058,12 +1058,13 @@ class Assembler : public AbstractAssembler {
10581058
// op1 CRn CRm op2
10591059
// IC IVAU 3 7 5 1
10601060
// DC CVAC 3 7 10 1
1061+
// DC CVAP 3 7 12 1
10611062
// DC CVAU 3 7 11 1
10621063
// DC CIVAC 3 7 14 1
10631064
// DC ZVA 3 7 4 1
10641065
// So only deal with the CRm field.
10651066
enum icache_maintenance {IVAU = 0b0101};
1066-
enum dcache_maintenance {CVAC = 0b1010, CVAU = 0b1011, CIVAC = 0b1110, ZVA = 0b100};
1067+
enum dcache_maintenance {CVAC = 0b1010, CVAP = 0b1100, CVAU = 0b1011, CIVAC = 0b1110, ZVA = 0b100};
10671068

10681069
void dc(dcache_maintenance cm, Register Rt) {
10691070
sys(0b011, 0b0111, cm, 0b001, Rt);

src/hotspot/cpu/aarch64/globals_aarch64.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
3-
* Copyright (c) 2015, Red Hat Inc. All rights reserved.
3+
* Copyright (c) 2015, 2019, Red Hat Inc. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
66
* This code is free software; you can redistribute it and/or modify it

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5833,3 +5833,25 @@ void MacroAssembler::get_thread(Register dst) {
58335833

58345834
pop(saved_regs, sp);
58355835
}
5836+
5837+
void MacroAssembler::cache_wb(Address line) {
5838+
assert(line.getMode() == Address::base_plus_offset, "mode should be base_plus_offset");
5839+
assert(line.index() == noreg, "index should be noreg");
5840+
assert(line.offset() == 0, "offset should be 0");
5841+
// would like to assert this
5842+
// assert(line._ext.shift == 0, "shift should be zero");
5843+
if (VM_Version::supports_dcpop()) {
5844+
// writeback using clear virtual address to point of persistence
5845+
dc(Assembler::CVAP, line.base());
5846+
} else {
5847+
// no need to generate anything as Unsafe.writebackMemory should
5848+
// never invoke this stub
5849+
}
5850+
}
5851+
5852+
void MacroAssembler::cache_wbsync(bool is_pre) {
5853+
// we only need a barrier post sync
5854+
if (!is_pre) {
5855+
membar(Assembler::AnyAny);
5856+
}
5857+
}

src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
3-
* Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
3+
* Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
66
* This code is free software; you can redistribute it and/or modify it
@@ -1344,6 +1344,9 @@ class MacroAssembler: public Assembler {
13441344
spill(tmp1, true, dst_offset+8);
13451345
}
13461346
}
1347+
1348+
void cache_wb(Address line);
1349+
void cache_wbsync(bool is_pre);
13471350
};
13481351

13491352
#ifdef ASSERT

src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2350,6 +2350,44 @@ class StubGenerator: public StubCodeGenerator {
23502350
return start;
23512351
}
23522352

2353+
address generate_data_cache_writeback() {
2354+
const Register line = c_rarg0; // address of line to write back
2355+
2356+
__ align(CodeEntryAlignment);
2357+
2358+
StubCodeMark mark(this, "StubRoutines", "_data_cache_writeback");
2359+
2360+
address start = __ pc();
2361+
__ enter();
2362+
__ cache_wb(Address(line, 0));
2363+
__ leave();
2364+
__ ret(lr);
2365+
2366+
return start;
2367+
}
2368+
2369+
address generate_data_cache_writeback_sync() {
2370+
const Register is_pre = c_rarg0; // pre or post sync
2371+
2372+
__ align(CodeEntryAlignment);
2373+
2374+
StubCodeMark mark(this, "StubRoutines", "_data_cache_writeback_sync");
2375+
2376+
// pre wbsync is a no-op
2377+
// post wbsync translates to an sfence
2378+
2379+
Label skip;
2380+
address start = __ pc();
2381+
__ enter();
2382+
__ cbnz(is_pre, skip);
2383+
__ cache_wbsync(false);
2384+
__ bind(skip);
2385+
__ leave();
2386+
__ ret(lr);
2387+
2388+
return start;
2389+
}
2390+
23532391
void generate_arraycopy_stubs() {
23542392
address entry;
23552393
address entry_jbyte_arraycopy;
@@ -5739,6 +5777,10 @@ class StubGenerator: public StubCodeGenerator {
57395777
StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks();
57405778
}
57415779

5780+
// data cache line writeback
5781+
StubRoutines::_data_cache_writeback = generate_data_cache_writeback();
5782+
StubRoutines::_data_cache_writeback_sync = generate_data_cache_writeback_sync();
5783+
57425784
if (UseAESIntrinsics) {
57435785
StubRoutines::_aescrypt_encryptBlock = generate_aescrypt_encryptBlock();
57445786
StubRoutines::_aescrypt_decryptBlock = generate_aescrypt_decryptBlock();

src/hotspot/cpu/aarch64/vm_version_aarch64.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
3-
* Copyright (c) 2015, Red Hat Inc. All rights reserved.
2+
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2015, 2019, Red Hat Inc. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
66
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
2828
#include "asm/macroAssembler.inline.hpp"
2929
#include "memory/resourceArea.hpp"
3030
#include "runtime/java.hpp"
31+
#include "runtime/os.hpp"
3132
#include "runtime/stubCodeGenerator.hpp"
3233
#include "utilities/macros.hpp"
3334
#include "vm_version_aarch64.hpp"
@@ -67,6 +68,7 @@ int VM_Version::_model2;
6768
int VM_Version::_variant;
6869
int VM_Version::_revision;
6970
int VM_Version::_stepping;
71+
bool VM_Version::_dcpop;
7072
VM_Version::PsrInfo VM_Version::_psr_info = { 0, };
7173

7274
static BufferBlob* stub_blob;
@@ -167,7 +169,8 @@ void VM_Version::get_processor_features() {
167169

168170
int cpu_lines = 0;
169171
if (FILE *f = fopen("/proc/cpuinfo", "r")) {
170-
char buf[128], *p;
172+
// need a large buffer as the flags line may include lots of text
173+
char buf[1024], *p;
171174
while (fgets(buf, sizeof (buf), f) != NULL) {
172175
if ((p = strchr(buf, ':')) != NULL) {
173176
long v = strtol(p+1, NULL, 0);
@@ -181,12 +184,25 @@ void VM_Version::get_processor_features() {
181184
_model = v;
182185
} else if (strncmp(buf, "CPU revision", sizeof "CPU revision" - 1) == 0) {
183186
_revision = v;
187+
} else if (strncmp(buf, "flags", sizeof("flags") - 1) == 0) {
188+
if (strstr(p+1, "dcpop")) {
189+
_dcpop = true;
190+
}
184191
}
185192
}
186193
}
187194
fclose(f);
188195
}
189196

197+
if (os::supports_map_sync()) {
198+
// if dcpop is available publish data cache line flush size via
199+
// generic field, otherwise let if default to zero thereby
200+
// disabling writeback
201+
if (_dcpop) {
202+
_data_cache_line_flush_size = dcache_line;
203+
}
204+
}
205+
190206
// Enable vendor specific features
191207

192208
// Ampere eMAG

src/hotspot/cpu/aarch64/vm_version_aarch64.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
3-
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
3+
* Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
66
* This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,7 @@ class VM_Version : public Abstract_VM_Version {
4040
static int _variant;
4141
static int _revision;
4242
static int _stepping;
43-
43+
static bool _dcpop;
4444
struct PsrInfo {
4545
uint32_t dczid_el0;
4646
uint32_t ctr_el0;
@@ -106,6 +106,7 @@ class VM_Version : public Abstract_VM_Version {
106106
static int cpu_model2() { return _model2; }
107107
static int cpu_variant() { return _variant; }
108108
static int cpu_revision() { return _revision; }
109+
static bool supports_dcpop() { return _dcpop; }
109110
static ByteSize dczid_el0_offset() { return byte_offset_of(PsrInfo, dczid_el0); }
110111
static ByteSize ctr_el0_offset() { return byte_offset_of(PsrInfo, ctr_el0); }
111112
static bool is_zva_enabled() {

src/hotspot/cpu/x86/assembler_x86.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2274,6 +2274,14 @@ void Assembler::mfence() {
22742274
emit_int8((unsigned char)0xF0);
22752275
}
22762276

2277+
// Emit sfence instruction
2278+
void Assembler::sfence() {
2279+
NOT_LP64(assert(VM_Version::supports_sse2(), "unsupported");)
2280+
emit_int8(0x0F);
2281+
emit_int8((unsigned char)0xAE);
2282+
emit_int8((unsigned char)0xF8);
2283+
}
2284+
22772285
void Assembler::mov(Register dst, Register src) {
22782286
LP64_ONLY(movq(dst, src)) NOT_LP64(movl(dst, src));
22792287
}
@@ -8617,12 +8625,45 @@ void Assembler::cdqq() {
86178625
}
86188626

86198627
void Assembler::clflush(Address adr) {
8628+
assert(VM_Version::supports_clflush(), "should do");
86208629
prefix(adr);
86218630
emit_int8(0x0F);
86228631
emit_int8((unsigned char)0xAE);
86238632
emit_operand(rdi, adr);
86248633
}
86258634

8635+
void Assembler::clflushopt(Address adr) {
8636+
assert(VM_Version::supports_clflushopt(), "should do!");
8637+
// adr should be base reg only with no index or offset
8638+
assert(adr.index() == noreg, "index should be noreg");
8639+
assert(adr.scale() == Address::no_scale, "scale should be no_scale");
8640+
assert(adr.disp() == 0, "displacement should be 0");
8641+
// instruction prefix is 0x66
8642+
emit_int8(0x66);
8643+
prefix(adr);
8644+
// opcode family is 0x0f 0xAE
8645+
emit_int8(0x0F);
8646+
emit_int8((unsigned char)0xAE);
8647+
// extended opcode byte is 7 == rdi
8648+
emit_operand(rdi, adr);
8649+
}
8650+
8651+
void Assembler::clwb(Address adr) {
8652+
assert(VM_Version::supports_clwb(), "should do!");
8653+
// adr should be base reg only with no index or offset
8654+
assert(adr.index() == noreg, "index should be noreg");
8655+
assert(adr.scale() == Address::no_scale, "scale should be no_scale");
8656+
assert(adr.disp() == 0, "displacement should be 0");
8657+
// instruction prefix is 0x66
8658+
emit_int8(0x66);
8659+
prefix(adr);
8660+
// opcode family is 0x0f 0xAE
8661+
emit_int8(0x0F);
8662+
emit_int8((unsigned char)0xAE);
8663+
// extended opcode byte is 6 == rsi
8664+
emit_operand(rsi, adr);
8665+
}
8666+
86268667
void Assembler::cmovq(Condition cc, Register dst, Register src) {
86278668
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
86288669
emit_int8(0x0F);

0 commit comments

Comments
 (0)