Skip to content

Commit

Permalink
Merge branch 'foreign-jextract' into virtual-calls
Browse files Browse the repository at this point in the history
  • Loading branch information
mcimadamore committed Feb 23, 2021
2 parents 9709863 + 1529a7e commit 7e6ce78
Show file tree
Hide file tree
Showing 320 changed files with 9,562 additions and 2,819 deletions.
2 changes: 1 addition & 1 deletion doc/building.html
Expand Up @@ -849,7 +849,7 @@ <h3 id="handling-reconfigurations">Handling Reconfigurations</h3>
<p>If you update the repository and part of the configure script has changed, the build system will force you to re-run <code>configure</code>.</p>
<p>Most of the time, you will be fine by running <code>configure</code> again with the same arguments as the last time, which can easily be performed by <code>make reconfigure</code>. To simplify this, you can use the <code>CONF_CHECK</code> make control variable, either as <code>make CONF_CHECK=auto</code>, or by setting an environment variable. For instance, if you add <code>export CONF_CHECK=auto</code> to your <code>.bashrc</code> file, <code>make</code> will always run <code>reconfigure</code> automatically whenever the configure script has changed.</p>
<p>You can also use <code>CONF_CHECK=ignore</code> to skip the check for a needed configure update. This might speed up the build, but comes at the risk of an incorrect build result. This is only recommended if you know what you're doing.</p>
<p>From time to time, you will also need to modify the command line to <code>configure</code> due to changes. Use <code>make print-configure</code> to show the command line used for your current configuration.</p>
<p>From time to time, you will also need to modify the command line to <code>configure</code> due to changes. Use <code>make print-configuration</code> to show the command line used for your current configuration.</p>
<h3 id="using-fine-grained-make-targets">Using Fine-Grained Make Targets</h3>
<p>The default behavior for make is to create consistent and correct output, at the expense of build speed, if necessary.</p>
<p>If you are prepared to take some risk of an incorrect build, and know enough of the system to understand how things build and interact, you can speed up the build process considerably by instructing make to only build a portion of the product.</p>
Expand Down
4 changes: 2 additions & 2 deletions doc/building.md
Expand Up @@ -1556,8 +1556,8 @@ update. This might speed up the build, but comes at the risk of an incorrect
build result. This is only recommended if you know what you're doing.

From time to time, you will also need to modify the command line to `configure`
due to changes. Use `make print-configure` to show the command line used for
your current configuration.
due to changes. Use `make print-configuration` to show the command line used
for your current configuration.

### Using Fine-Grained Make Targets

Expand Down
49 changes: 49 additions & 0 deletions src/hotspot/cpu/aarch64/atomic_aarch64.hpp
@@ -0,0 +1,49 @@
/* Copyright (c) 2021, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/

#ifndef CPU_AARCH64_ATOMIC_AARCH64_HPP
#define CPU_AARCH64_ATOMIC_AARCH64_HPP

// Atomic stub implementation.
// Default implementations are in atomic_linux_aarch64.S
//
// All stubs pass arguments the same way
// x0: src/dest address
// x1: arg1
// x2: arg2 (optional)
// x3, x8, x9: scratch
typedef uint64_t (*aarch64_atomic_stub_t)(volatile void *ptr, uint64_t arg1, uint64_t arg2);

// Pointers to stubs
extern aarch64_atomic_stub_t aarch64_atomic_fetch_add_4_impl;
extern aarch64_atomic_stub_t aarch64_atomic_fetch_add_8_impl;
extern aarch64_atomic_stub_t aarch64_atomic_xchg_4_impl;
extern aarch64_atomic_stub_t aarch64_atomic_xchg_8_impl;
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_1_impl;
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_4_impl;
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_8_impl;
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_1_relaxed_impl;
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_4_relaxed_impl;
extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_8_relaxed_impl;

#endif // CPU_AARCH64_ATOMIC_AARCH64_HPP
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -23,6 +23,7 @@
*/

#include "precompiled.hpp"
#include "classfile/classLoaderData.hpp"
#include "gc/shared/barrierSet.hpp"
#include "gc/shared/barrierSetAssembler.hpp"
#include "gc/shared/barrierSetNMethod.hpp"
Expand Down
Expand Up @@ -46,7 +46,6 @@ void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register ob

if (UseCondCardMark) {
Label L_already_dirty;
__ membar(Assembler::StoreLoad);
__ ldrb(rscratch2, Address(obj, rscratch1));
__ cbz(rscratch2, L_already_dirty);
__ strb(zr, Address(obj, rscratch1));
Expand Down
10 changes: 8 additions & 2 deletions src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
Expand Up @@ -2567,6 +2567,8 @@ void MacroAssembler::atomic_##OP(Register prev, Register newv, Register addr) {

ATOMIC_XCHG(xchg, swp, ldxr, stxr, Assembler::xword)
ATOMIC_XCHG(xchgw, swp, ldxrw, stxrw, Assembler::word)
ATOMIC_XCHG(xchgl, swpl, ldxr, stlxr, Assembler::xword)
ATOMIC_XCHG(xchglw, swpl, ldxrw, stlxrw, Assembler::word)
ATOMIC_XCHG(xchgal, swpal, ldaxr, stlxr, Assembler::xword)
ATOMIC_XCHG(xchgalw, swpal, ldaxrw, stlxrw, Assembler::word)

Expand Down Expand Up @@ -5266,10 +5268,14 @@ void MacroAssembler::char_array_compress(Register src, Register dst, Register le
// by the call to JavaThread::aarch64_get_thread_helper() or, indeed,
// the call setup code.
//
// aarch64_get_thread_helper() clobbers only r0, r1, and flags.
// On Linux, aarch64_get_thread_helper() clobbers only r0, r1, and flags.
// On other systems, the helper is a usual C function.
//
void MacroAssembler::get_thread(Register dst) {
RegSet saved_regs = RegSet::range(r0, r1) + lr - dst;
RegSet saved_regs =
LINUX_ONLY(RegSet::range(r0, r1) + lr - dst)
NOT_LINUX (RegSet::range(r0, r17) + lr - dst);

push(saved_regs, sp);

mov(lr, CAST_FROM_FN_PTR(address, JavaThread::aarch64_get_thread_helper));
Expand Down
2 changes: 2 additions & 0 deletions src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
Expand Up @@ -1039,6 +1039,8 @@ class MacroAssembler: public Assembler {

void atomic_xchg(Register prev, Register newv, Register addr);
void atomic_xchgw(Register prev, Register newv, Register addr);
void atomic_xchgl(Register prev, Register newv, Register addr);
void atomic_xchglw(Register prev, Register newv, Register addr);
void atomic_xchgal(Register prev, Register newv, Register addr);
void atomic_xchgalw(Register prev, Register newv, Register addr);

Expand Down
208 changes: 204 additions & 4 deletions src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
Expand Up @@ -26,6 +26,7 @@
#include "precompiled.hpp"
#include "asm/macroAssembler.hpp"
#include "asm/macroAssembler.inline.hpp"
#include "atomic_aarch64.hpp"
#include "gc/shared/barrierSet.hpp"
#include "gc/shared/barrierSetAssembler.hpp"
#include "gc/shared/gc_globals.hpp"
Expand All @@ -38,6 +39,7 @@
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/atomic.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/sharedRuntime.hpp"
Expand Down Expand Up @@ -1361,7 +1363,7 @@ class StubGenerator: public StubCodeGenerator {
//
// If 'from' and/or 'to' are aligned on 4-byte boundaries, we let
// the hardware handle it. The two dwords within qwords that span
// cache line boundaries will still be loaded and stored atomicly.
// cache line boundaries will still be loaded and stored atomically.
//
// Side Effects:
// disjoint_int_copy_entry is set to the no-overlap entry point
Expand Down Expand Up @@ -1431,7 +1433,7 @@ class StubGenerator: public StubCodeGenerator {
//
// If 'from' and/or 'to' are aligned on 4-byte boundaries, we let
// the hardware handle it. The two dwords within qwords that span
// cache line boundaries will still be loaded and stored atomicly.
// cache line boundaries will still be loaded and stored atomically.
//
address generate_conjoint_copy(int size, bool aligned, bool is_oop, address nooverlap_target,
address *entry, const char *name,
Expand Down Expand Up @@ -1596,7 +1598,7 @@ class StubGenerator: public StubCodeGenerator {
//
// If 'from' and/or 'to' are aligned on 4-byte boundaries, we let
// the hardware handle it. The two dwords within qwords that span
// cache line boundaries will still be loaded and stored atomicly.
// cache line boundaries will still be loaded and stored atomically.
//
// Side Effects:
// disjoint_int_copy_entry is set to the no-overlap entry point
Expand All @@ -1620,7 +1622,7 @@ class StubGenerator: public StubCodeGenerator {
//
// If 'from' and/or 'to' are aligned on 4-byte boundaries, we let
// the hardware handle it. The two dwords within qwords that span
// cache line boundaries will still be loaded and stored atomicly.
// cache line boundaries will still be loaded and stored atomically.
//
address generate_conjoint_int_copy(bool aligned, address nooverlap_target,
address *entry, const char *name,
Expand Down Expand Up @@ -5571,6 +5573,171 @@ class StubGenerator: public StubCodeGenerator {
return start;
}

#ifdef LINUX

// ARMv8.1 LSE versions of the atomic stubs used by Atomic::PlatformXX.
//
// If LSE is in use, generate LSE versions of all the stubs. The
// non-LSE versions are in atomic_aarch64.S.

// class AtomicStubMark records the entry point of a stub and the
// stub pointer which will point to it. The stub pointer is set to
// the entry point when ~AtomicStubMark() is called, which must be
// after ICache::invalidate_range. This ensures safe publication of
// the generated code.
class AtomicStubMark {
address _entry_point;
aarch64_atomic_stub_t *_stub;
MacroAssembler *_masm;
public:
AtomicStubMark(MacroAssembler *masm, aarch64_atomic_stub_t *stub) {
_masm = masm;
__ align(32);
_entry_point = __ pc();
_stub = stub;
}
~AtomicStubMark() {
*_stub = (aarch64_atomic_stub_t)_entry_point;
}
};

// NB: For memory_order_conservative we need a trailing membar after
// LSE atomic operations but not a leading membar.
//
// We don't need a leading membar because a clause in the Arm ARM
// says:
//
// Barrier-ordered-before
//
// Barrier instructions order prior Memory effects before subsequent
// Memory effects generated by the same Observer. A read or a write
// RW1 is Barrier-ordered-before a read or a write RW 2 from the same
// Observer if and only if RW1 appears in program order before RW 2
// and [ ... ] at least one of RW 1 and RW 2 is generated by an atomic
// instruction with both Acquire and Release semantics.
//
// All the atomic instructions {ldaddal, swapal, casal} have Acquire
// and Release semantics, therefore we don't need a leading
// barrier. However, there is no corresponding Barrier-ordered-after
// relationship, therefore we need a trailing membar to prevent a
// later store or load from being reordered with the store in an
// atomic instruction.
//
// This was checked by using the herd7 consistency model simulator
// (http://diy.inria.fr/) with this test case:
//
// AArch64 LseCas
// { 0:X1=x; 0:X2=y; 1:X1=x; 1:X2=y; }
// P0 | P1;
// LDR W4, [X2] | MOV W3, #0;
// DMB LD | MOV W4, #1;
// LDR W3, [X1] | CASAL W3, W4, [X1];
// | DMB ISH;
// | STR W4, [X2];
// exists
// (0:X3=0 /\ 0:X4=1)
//
// If X3 == 0 && X4 == 1, the store to y in P1 has been reordered
// with the store to x in P1. Without the DMB in P1 this may happen.
//
// At the time of writing we don't know of any AArch64 hardware that
// reorders stores in this way, but the Reference Manual permits it.

void gen_cas_entry(Assembler::operand_size size,
atomic_memory_order order) {
Register prev = r3, ptr = c_rarg0, compare_val = c_rarg1,
exchange_val = c_rarg2;
bool acquire, release;
switch (order) {
case memory_order_relaxed:
acquire = false;
release = false;
break;
default:
acquire = true;
release = true;
break;
}
__ mov(prev, compare_val);
__ lse_cas(prev, exchange_val, ptr, size, acquire, release, /*not_pair*/true);
if (order == memory_order_conservative) {
__ membar(Assembler::StoreStore|Assembler::StoreLoad);
}
if (size == Assembler::xword) {
__ mov(r0, prev);
} else {
__ movw(r0, prev);
}
__ ret(lr);
}

void gen_ldaddal_entry(Assembler::operand_size size) {
Register prev = r2, addr = c_rarg0, incr = c_rarg1;
__ ldaddal(size, incr, prev, addr);
__ membar(Assembler::StoreStore|Assembler::StoreLoad);
if (size == Assembler::xword) {
__ mov(r0, prev);
} else {
__ movw(r0, prev);
}
__ ret(lr);
}

void gen_swpal_entry(Assembler::operand_size size) {
Register prev = r2, addr = c_rarg0, incr = c_rarg1;
__ swpal(size, incr, prev, addr);
__ membar(Assembler::StoreStore|Assembler::StoreLoad);
if (size == Assembler::xword) {
__ mov(r0, prev);
} else {
__ movw(r0, prev);
}
__ ret(lr);
}

void generate_atomic_entry_points() {
if (! UseLSE) {
return;
}

__ align(CodeEntryAlignment);
StubCodeMark mark(this, "StubRoutines", "atomic entry points");
address first_entry = __ pc();

// All memory_order_conservative
AtomicStubMark mark_fetch_add_4(_masm, &aarch64_atomic_fetch_add_4_impl);
gen_ldaddal_entry(Assembler::word);
AtomicStubMark mark_fetch_add_8(_masm, &aarch64_atomic_fetch_add_8_impl);
gen_ldaddal_entry(Assembler::xword);

AtomicStubMark mark_xchg_4(_masm, &aarch64_atomic_xchg_4_impl);
gen_swpal_entry(Assembler::word);
AtomicStubMark mark_xchg_8_impl(_masm, &aarch64_atomic_xchg_8_impl);
gen_swpal_entry(Assembler::xword);

// CAS, memory_order_conservative
AtomicStubMark mark_cmpxchg_1(_masm, &aarch64_atomic_cmpxchg_1_impl);
gen_cas_entry(MacroAssembler::byte, memory_order_conservative);
AtomicStubMark mark_cmpxchg_4(_masm, &aarch64_atomic_cmpxchg_4_impl);
gen_cas_entry(MacroAssembler::word, memory_order_conservative);
AtomicStubMark mark_cmpxchg_8(_masm, &aarch64_atomic_cmpxchg_8_impl);
gen_cas_entry(MacroAssembler::xword, memory_order_conservative);

// CAS, memory_order_relaxed
AtomicStubMark mark_cmpxchg_1_relaxed
(_masm, &aarch64_atomic_cmpxchg_1_relaxed_impl);
gen_cas_entry(MacroAssembler::byte, memory_order_relaxed);
AtomicStubMark mark_cmpxchg_4_relaxed
(_masm, &aarch64_atomic_cmpxchg_4_relaxed_impl);
gen_cas_entry(MacroAssembler::word, memory_order_relaxed);
AtomicStubMark mark_cmpxchg_8_relaxed
(_masm, &aarch64_atomic_cmpxchg_8_relaxed_impl);
gen_cas_entry(MacroAssembler::xword, memory_order_relaxed);

ICache::invalidate_range(first_entry, __ pc() - first_entry);
}
#endif // LINUX

// Continuation point for throwing of implicit exceptions that are
// not handled in the current activation. Fabricates an exception
// oop and initiates normal exception dispatching in this
Expand Down Expand Up @@ -6683,6 +6850,12 @@ class StubGenerator: public StubCodeGenerator {
StubRoutines::_updateBytesAdler32 = generate_updateBytesAdler32();
}

#ifdef LINUX

generate_atomic_entry_points();

#endif // LINUX

StubRoutines::aarch64::set_completed();
}

Expand All @@ -6703,3 +6876,30 @@ void StubGenerator_generate(CodeBuffer* code, bool all) {
}
StubGenerator g(code, all);
}


#ifdef LINUX

// Define pointers to atomic stubs and initialize them to point to the
// code in atomic_aarch64.S.

#define DEFAULT_ATOMIC_OP(OPNAME, SIZE, RELAXED) \
extern "C" uint64_t aarch64_atomic_ ## OPNAME ## _ ## SIZE ## RELAXED ## _default_impl \
(volatile void *ptr, uint64_t arg1, uint64_t arg2); \
aarch64_atomic_stub_t aarch64_atomic_ ## OPNAME ## _ ## SIZE ## RELAXED ## _impl \
= aarch64_atomic_ ## OPNAME ## _ ## SIZE ## RELAXED ## _default_impl;

DEFAULT_ATOMIC_OP(fetch_add, 4, )
DEFAULT_ATOMIC_OP(fetch_add, 8, )
DEFAULT_ATOMIC_OP(xchg, 4, )
DEFAULT_ATOMIC_OP(xchg, 8, )
DEFAULT_ATOMIC_OP(cmpxchg, 1, )
DEFAULT_ATOMIC_OP(cmpxchg, 4, )
DEFAULT_ATOMIC_OP(cmpxchg, 8, )
DEFAULT_ATOMIC_OP(cmpxchg, 1, _relaxed)
DEFAULT_ATOMIC_OP(cmpxchg, 4, _relaxed)
DEFAULT_ATOMIC_OP(cmpxchg, 8, _relaxed)

#undef DEFAULT_ATOMIC_OP

#endif // LINUX

0 comments on commit 7e6ce78

Please sign in to comment.