Skip to content

Commit

Permalink
8276799: Implementation of JEP 422: Linux/RISC-V Port
Browse files Browse the repository at this point in the history
8282306: os::is_first_C_frame(frame*) crashes on invalid link access
8282477: [x86, aarch64] vmassert(_last_Java_pc == NULL, "already walkable"); fails with async profiler
8283865: riscv: Break down -XX:+UseRVB into seperate options for each bitmanip extension
8284068: riscv: should call Atomic::release_store in JavaThread::set_thread_state
8284937: riscv: should not allocate special register for temp
8285303: riscv: Incorrect register mask in call_native_base
8287418: riscv: Fix correctness issue of MacroAssembler::movptr
8297644: RISC-V: Compilation error when shenandoah is disabled
8291952: riscv: Remove PRAGMA_NONNULL_IGNORED
8285437: riscv: Fix MachNode size mismatch for MacroAssembler::verify_oops*
8285699: riscv: Provide information when hitting a HaltNode
8285711: riscv: RVC: Support disassembler show-bytes option
8287425: Remove unnecessary register push for MacroAssembler::check_klass_subtype_slow_path
8287552: riscv: Fix comment typo in li64
8287970: riscv: jdk/incubator/vector/*VectorTests failing
8290137: riscv: small refactoring for add_memory_int32/64
8290164: compiler/runtime/TestConstantsInError.java fails on riscv
8290496: riscv: Fix build warnings-as-errors with GCC 11
8291893: riscv: remove fence.i used in user space
8291947: riscv: fail to build after JDK-8290840
8292867: RISC-V: Simplify weak CAS return value handling
8293050: RISC-V: Remove redundant non-null assertions about macro-assembler
8293100: RISC-V: Need to save and restore callee-saved FloatRegisters in StubGenerator::generate_call_stub
8293474: RISC-V: Unify the way of moving function pointer
8293524: RISC-V: Use macro-assembler functions as appropriate
8293566: RISC-V: Clean up push and pop registers
8294012: RISC-V: get/put_native_u8 missing the case when address&7 is 6
8294083: RISC-V: Minimal build failed with --disable-precompiled-headers
8294086: RISC-V: Cleanup InstructionMark usages in the backend
8294087: RISC-V: RVC: Fix a potential alignment issue and add more alignment assertions for the patchable calls/nops
8294187: RISC-V: Unify all relocations for the backend into AbstractAssembler::relocate()
8294366: RISC-V: Partially mark out incompressible regions
8294430: RISC-V: Small refactoring for movptr_with_offset
8294492: RISC-V: Use li instead of patchable movptr at non-patchable callsites
8294679: RISC-V: Misc crash dump improvements
8295110: RISC-V: Mark out relocations as incompressible
8295270: RISC-V: Clean up and refactoring for assembler functions
8295396: RISC-V: Cleanup useless CompressibleRegions
8295926: RISC-V: C1: Fix LIRGenerator::do_LibmIntrinsic
8295968: RISC-V: Rename some assembler intrinsic functions for RVV 1.0
8296435: RISC-V: Small refactoring for increment/decrement
8296447: RISC-V: Make the operands order of vrsub_vx/vrsub_vi consistent with RVV 1.0 spec
8296448: RISC-V: Fix temp usages of heapbase register killed by MacroAssembler::en/decode_klass_not_null
8296602: RISC-V: improve performance of copy_memory stub
8296771: RISC-V: C2: assert(false) failed: bad AD file
8296916: RISC-V: Move some small macro-assembler functions to header file
8297359: RISC-V: improve performance of floating Max Min intrinsics
8297697: RISC-V: Add support for SATP mode detection
8301067: RISC-V: better error message when reporting unsupported satp modes
8297715: RISC-V: C2: Use single-bit instructions from the Zbs extension
8299168: RISC-V: Fix MachNode size mismatch for MacroAssembler::_verify_oops*
8299847: RISC-V: Improve PrintOptoAssembly output of CMoveI/L nodes
8300109: RISC-V: Improve code generation for MinI/MaxI nodes
8301033: RISC-V: Handle special cases for MinI/MaxI nodes for Zbb
8301036: RISC-V: Factor out functions baseOffset & baseOffset32 from MacroAssembler
8301153: RISC-V: pipeline class for several instructions is not set correctly
8301313: RISC-V: C2: assert(false) failed: bad AD file due to missing match rule
8301628: RISC-V: c2 fix pipeline class for several instructions
8301818: RISC-V: Factor out function mvw from MacroAssembler
8302114: RISC-V: Several foreign jtreg tests fail with debug build after JDK-8301818
8301852: RISC-V: Optimize class atomic when order is memory_order_relaxed
8302289: RISC-V: Use bgez instruction in arraycopy_simple_check when possible
8302776: RISC-V: Fix typo CSR_INSTERT to CSR_INSTRET
8304293: RISC-V: JDK-8276799 missed atomic intrinsic support for C1
8305006: Use correct register in riscv_enc_fast_unlock()
8305008: RISC-V: Factor out immediate checking functions from assembler_riscv.inline.hpp
8305112: RISC-V: Typo fix for RVC description
8305512: RISC-V: Enable RVC extension by default on supported hardware
8305728: RISC-V: Use bexti instruction to do single-bit testing
8306667: RISC-V: Fix storeImmN0 matching rule by using zr register
8307150: RISC-V: Remove remaining StoreLoad barrier with UseCondCardMark for Serial/Parallel GC
8307446: RISC-V: Improve performance of floating point to integer conversion
8307651: RISC-V: stringL_indexof_char instruction has wrong format string
8308089: [riscv-port-jdk17u] Intrinsify Unsafe.storeStoreFence
8308277: RISC-V: Improve vectorization of Match.sqrt() on floats
8308997: RISC-V: Sign extend when comparing 32-bit value with zero instead of testing the sign bit
8309427: [riscv-port-jdk17u] Remove unused RoundDoubleModeV C2 node
8305236: Some LoadLoad barriers in the interpreter are unnecessary after JDK-8220051
8285630: Fix a configure error in RISC-V cross build
8277417: C1 LIR instruction for load-klass

Reviewed-by: vkempik, goetz, shade, yadongwang, fjiang, luhenry
Backport-of: 5905b02c0e2643ae8d097562f181953f6c88fc89
  • Loading branch information
RealFYang committed Jul 10, 2023
1 parent f02d019 commit 966fc82
Show file tree
Hide file tree
Showing 188 changed files with 60,258 additions and 136 deletions.
10 changes: 8 additions & 2 deletions make/autoconf/build-aux/config.sub
@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2014, 2022, 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 Down Expand Up @@ -46,6 +46,13 @@ if echo $* | grep pc-msys >/dev/null ; then
exit
fi

# Canonicalize for riscv which autoconf-config.sub doesn't handle
if echo $* | grep '^riscv\(32\|64\)-linux' >/dev/null ; then
result=`echo $@ | sed 's/linux/unknown-linux/'`
echo $result
exit
fi

# Filter out everything that doesn't begin with "aarch64-"
if ! echo $* | grep '^aarch64-' >/dev/null ; then
. $DIR/autoconf-config.sub "$@"
Expand Down Expand Up @@ -78,4 +85,3 @@ result=`echo $result | sed "s/^arm-/aarch64-/"`

echo $result
exit $exitcode

6 changes: 4 additions & 2 deletions make/autoconf/jvm-features.m4
Expand Up @@ -311,7 +311,8 @@ AC_DEFUN_ONCE([JVM_FEATURES_CHECK_SHENANDOAHGC],
AC_MSG_CHECKING([if platform is supported by Shenandoah])
if test "x$OPENJDK_TARGET_CPU_ARCH" = "xx86" || \
test "x$OPENJDK_TARGET_CPU" = "xaarch64" || \
test "x$OPENJDK_TARGET_CPU" = "xppc64le"; then
test "x$OPENJDK_TARGET_CPU" = "xppc64le" || \
test "x$OPENJDK_TARGET_CPU" = "xriscv64"; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no, $OPENJDK_TARGET_CPU])
Expand Down Expand Up @@ -361,7 +362,8 @@ AC_DEFUN_ONCE([JVM_FEATURES_CHECK_ZGC],
AC_MSG_RESULT([no, $OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU])
AVAILABLE=false
fi
elif test "x$OPENJDK_TARGET_CPU" = "xppc64le"; then
elif test "x$OPENJDK_TARGET_CPU" = "xppc64le" || \
test "x$OPENJDK_TARGET_CPU" = "xriscv64"; then
if test "x$OPENJDK_TARGET_OS" = "xlinux"; then
AC_MSG_RESULT([yes])
else
Expand Down
8 changes: 7 additions & 1 deletion make/autoconf/libraries.m4
@@ -1,5 +1,5 @@
#
# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2011, 2022, 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 Down Expand Up @@ -146,6 +146,12 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBRARIES],
fi
fi
# Because RISC-V only has word-sized atomics, it requries libatomic where
# other common architectures do not. So link libatomic by default.
if test "x$OPENJDK_TARGET_OS" = xlinux && test "x$OPENJDK_TARGET_CPU" = xriscv64; then
BASIC_JVM_LIBS="$BASIC_JVM_LIBS -latomic"
fi
# perfstat lib
if test "x$OPENJDK_TARGET_OS" = xaix; then
BASIC_JVM_LIBS="$BASIC_JVM_LIBS -lperfstat"
Expand Down
6 changes: 3 additions & 3 deletions make/autoconf/platform.m4
@@ -1,5 +1,5 @@
#
# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2011, 2022, 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 Down Expand Up @@ -561,6 +561,8 @@ AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS_HELPER],
HOTSPOT_$1_CPU_DEFINE=PPC64
elif test "x$OPENJDK_$1_CPU" = xppc64le; then
HOTSPOT_$1_CPU_DEFINE=PPC64
elif test "x$OPENJDK_$1_CPU" = xriscv64; then
HOTSPOT_$1_CPU_DEFINE=RISCV64
# The cpu defines below are for zero, we don't support them directly.
elif test "x$OPENJDK_$1_CPU" = xsparc; then
Expand All @@ -571,8 +573,6 @@ AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS_HELPER],
HOTSPOT_$1_CPU_DEFINE=S390
elif test "x$OPENJDK_$1_CPU" = xs390x; then
HOTSPOT_$1_CPU_DEFINE=S390
elif test "x$OPENJDK_$1_CPU" = xriscv64; then
HOTSPOT_$1_CPU_DEFINE=RISCV
elif test "x$OPENJDK_$1_CPU" != x; then
HOTSPOT_$1_CPU_DEFINE=$(echo $OPENJDK_$1_CPU | tr a-z A-Z)
fi
Expand Down
9 changes: 8 additions & 1 deletion make/hotspot/gensrc/GensrcAdlc.gmk
@@ -1,5 +1,5 @@
#
# Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2013, 2022, 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 Down Expand Up @@ -149,6 +149,13 @@ ifeq ($(call check-jvm-feature, compiler2), true)
)))
endif

ifeq ($(HOTSPOT_TARGET_CPU_ARCH), riscv)
AD_SRC_FILES += $(call uniq, $(wildcard $(foreach d, $(AD_SRC_ROOTS), \
$d/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/$(HOTSPOT_TARGET_CPU_ARCH)_v.ad \
$d/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/$(HOTSPOT_TARGET_CPU_ARCH)_b.ad \
)))
endif

ifeq ($(call check-jvm-feature, shenandoahgc), true)
AD_SRC_FILES += $(call uniq, $(wildcard $(foreach d, $(AD_SRC_ROOTS), \
$d/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/gc/shenandoah/shenandoah_$(HOTSPOT_TARGET_CPU).ad \
Expand Down
177 changes: 177 additions & 0 deletions src/hotspot/cpu/riscv/abstractInterpreter_riscv.cpp
@@ -0,0 +1,177 @@
/*
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. 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.
*
*/

#include "precompiled.hpp"
#include "interpreter/interpreter.hpp"
#include "oops/constMethod.hpp"
#include "oops/klass.inline.hpp"
#include "oops/method.hpp"
#include "runtime/frame.inline.hpp"
#include "utilities/align.hpp"
#include "utilities/debug.hpp"
#include "utilities/macros.hpp"

int AbstractInterpreter::BasicType_as_index(BasicType type) {
int i = 0;
switch (type) {
case T_BOOLEAN: i = 0; break;
case T_CHAR : i = 1; break;
case T_BYTE : i = 2; break;
case T_SHORT : i = 3; break;
case T_INT : i = 4; break;
case T_LONG : i = 5; break;
case T_VOID : i = 6; break;
case T_FLOAT : i = 7; break;
case T_DOUBLE : i = 8; break;
case T_OBJECT : i = 9; break;
case T_ARRAY : i = 9; break;
default : ShouldNotReachHere();
}
assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers,
"index out of bounds");
return i;
}

// How much stack a method activation needs in words.
int AbstractInterpreter::size_top_interpreter_activation(Method* method) {
const int entry_size = frame::interpreter_frame_monitor_size();

// total overhead size: entry_size + (saved fp thru expr stack
// bottom). be sure to change this if you add/subtract anything
// to/from the overhead area
const int overhead_size =
-(frame::interpreter_frame_initial_sp_offset) + entry_size;

const int stub_code = frame::entry_frame_after_call_words;
assert_cond(method != NULL);
const int method_stack = (method->max_locals() + method->max_stack()) *
Interpreter::stackElementWords;
return (overhead_size + method_stack + stub_code);
}

// asm based interpreter deoptimization helpers
int AbstractInterpreter::size_activation(int max_stack,
int temps,
int extra_args,
int monitors,
int callee_params,
int callee_locals,
bool is_top_frame) {
// Note: This calculation must exactly parallel the frame setup
// in TemplateInterpreterGenerator::generate_method_entry.

// fixed size of an interpreter frame:
int overhead = frame::sender_sp_offset -
frame::interpreter_frame_initial_sp_offset;
// Our locals were accounted for by the caller (or last_frame_adjust
// on the transistion) Since the callee parameters already account
// for the callee's params we only need to account for the extra
// locals.
int size = overhead +
(callee_locals - callee_params) +
monitors * frame::interpreter_frame_monitor_size() +
// On the top frame, at all times SP <= ESP, and SP is
// 16-aligned. We ensure this by adjusting SP on method
// entry and re-entry to allow room for the maximum size of
// the expression stack. When we call another method we bump
// SP so that no stack space is wasted. So, only on the top
// frame do we need to allow max_stack words.
(is_top_frame ? max_stack : temps + extra_args);

// On riscv we always keep the stack pointer 16-aligned, so we
// must round up here.
size = align_up(size, 2);

return size;
}

void AbstractInterpreter::layout_activation(Method* method,
int tempcount,
int popframe_extra_args,
int moncount,
int caller_actual_parameters,
int callee_param_count,
int callee_locals,
frame* caller,
frame* interpreter_frame,
bool is_top_frame,
bool is_bottom_frame) {
// The frame interpreter_frame is guaranteed to be the right size,
// as determined by a previous call to the size_activation() method.
// It is also guaranteed to be walkable even though it is in a
// skeletal state
assert_cond(method != NULL && caller != NULL && interpreter_frame != NULL);
int max_locals = method->max_locals() * Interpreter::stackElementWords;
int extra_locals = (method->max_locals() - method->size_of_parameters()) *
Interpreter::stackElementWords;

#ifdef ASSERT
assert(caller->sp() == interpreter_frame->sender_sp(), "Frame not properly walkable");
#endif

interpreter_frame->interpreter_frame_set_method(method);
// NOTE the difference in using sender_sp and interpreter_frame_sender_sp
// interpreter_frame_sender_sp is the original sp of the caller (the unextended_sp)
// and sender_sp is fp
intptr_t* locals = NULL;
if (caller->is_interpreted_frame()) {
locals = caller->interpreter_frame_last_sp() + caller_actual_parameters - 1;
} else {
locals = interpreter_frame->sender_sp() + max_locals - 1;
}

#ifdef ASSERT
if (caller->is_interpreted_frame()) {
assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement");
}
#endif

interpreter_frame->interpreter_frame_set_locals(locals);
BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin();
BasicObjectLock* monbot = montop - moncount;
interpreter_frame->interpreter_frame_set_monitor_end(monbot);

// Set last_sp
intptr_t* last_sp = (intptr_t*) monbot -
tempcount*Interpreter::stackElementWords -
popframe_extra_args;
interpreter_frame->interpreter_frame_set_last_sp(last_sp);

// All frames but the initial (oldest) interpreter frame we fill in have
// a value for sender_sp that allows walking the stack but isn't
// truly correct. Correct the value here.
if (extra_locals != 0 &&
interpreter_frame->sender_sp() ==
interpreter_frame->interpreter_frame_sender_sp()) {
interpreter_frame->set_interpreter_frame_sender_sp(caller->sp() +
extra_locals);
}

*interpreter_frame->interpreter_frame_cache_addr() =
method->constants()->cache();
*interpreter_frame->interpreter_frame_mirror_addr() =
method->method_holder()->java_mirror();
}
78 changes: 78 additions & 0 deletions src/hotspot/cpu/riscv/assembler_riscv.cpp
@@ -0,0 +1,78 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. 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.
*
*/

#include <stdio.h>
#include <sys/types.h>

#include "precompiled.hpp"
#include "asm/assembler.hpp"
#include "asm/assembler.inline.hpp"
#include "compiler/disassembler.hpp"
#include "interpreter/interpreter.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/sharedRuntime.hpp"

int AbstractAssembler::code_fill_byte() {
return 0;
}

Address::Address(address target, relocInfo::relocType rtype) : _base(noreg), _offset(0), _mode(literal) {
_target = target;
switch (rtype) {
case relocInfo::oop_type:
case relocInfo::metadata_type:
// Oops are a special case. Normally they would be their own section
// but in cases like icBuffer they are literals in the code stream that
// we don't have a section for. We use none so that we get a literal address
// which is always patchable.
break;
case relocInfo::external_word_type:
_rspec = external_word_Relocation::spec(target);
break;
case relocInfo::internal_word_type:
_rspec = internal_word_Relocation::spec(target);
break;
case relocInfo::opt_virtual_call_type:
_rspec = opt_virtual_call_Relocation::spec();
break;
case relocInfo::static_call_type:
_rspec = static_call_Relocation::spec();
break;
case relocInfo::runtime_call_type:
_rspec = runtime_call_Relocation::spec();
break;
case relocInfo::poll_type:
case relocInfo::poll_return_type:
_rspec = Relocation::spec_simple(rtype);