Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: openjdk/jdk
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 4aa65cbe
Choose a base ref
...
head repository: openjdk/jdk
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0c5ab1c6
Choose a head ref
  • 18 commits
  • 12 files changed
  • 2 contributors

Commits on Mar 17, 2023

  1. Copy the full SHA
    18d7f39 View commit details

Commits on Mar 20, 2023

  1. Copy the full SHA
    7d6d250 View commit details

Commits on Apr 24, 2023

  1. Copy the full SHA
    c33740a View commit details
  2. merge

    VladimirKempik committed Apr 24, 2023
    Copy the full SHA
    9a4ca3e View commit details
  3. Fix risc-v

    VladimirKempik committed Apr 24, 2023
    Copy the full SHA
    5ba0436 View commit details

Commits on Apr 25, 2023

  1. Copy the full SHA
    6ed7262 View commit details
  2. refix branch in interp

    VladimirKempik committed Apr 25, 2023
    Copy the full SHA
    f2e0262 View commit details
  3. clean up comments

    VladimirKempik committed Apr 25, 2023
    Copy the full SHA
    00cfe09 View commit details

Commits on Apr 26, 2023

  1. fix nits

    VladimirKempik committed Apr 26, 2023
    Copy the full SHA
    adbf3cb View commit details
  2. spaces

    VladimirKempik committed Apr 26, 2023
    Copy the full SHA
    8323870 View commit details

Commits on Apr 28, 2023

  1. Remove unused macros

    VladimirKempik committed Apr 28, 2023
    Copy the full SHA
    8b9aa84 View commit details

Commits on May 2, 2023

  1. Copy the full SHA
    33d5451 View commit details

Commits on May 4, 2023

  1. Copy the full SHA
    5a5217e View commit details
  2. Copy the full SHA
    26d60cc View commit details

Commits on May 5, 2023

  1. Copy the full SHA
    90e78e0 View commit details

Commits on May 6, 2023

  1. Copy the full SHA
    0335cd5 View commit details

Commits on May 8, 2023

  1. merge

    VladimirKempik committed May 8, 2023
    Copy the full SHA
    1de88ec View commit details

Commits on May 10, 2023

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    0c5ab1c View commit details
24 changes: 20 additions & 4 deletions src/hotspot/cpu/riscv/assembler_riscv.hpp
Original file line number Diff line number Diff line change
@@ -364,6 +364,22 @@ class Assembler : public AbstractAssembler {
rdy = 0b111, // in instruction's rm field, selects dynamic rounding mode.In Rounding Mode register, Invalid.
};

// handle unaligned access
static inline uint16_t ld_c_instr(address addr) {
return Bytes::get_native_u2(addr);
}
static inline void sd_c_instr(address addr, uint16_t c_instr) {
Bytes::put_native_u2(addr, c_instr);
}

// handle unaligned access
static inline uint32_t ld_instr(address addr) {
return Bytes::get_native_u4(addr);
}
static inline void sd_instr(address addr, uint32_t instr) {
Bytes::put_native_u4(addr, instr);
}

static inline uint32_t extract(uint32_t val, unsigned msb, unsigned lsb) {
assert_cond(msb >= lsb && msb <= 31);
unsigned nbits = msb - lsb + 1;
@@ -388,10 +404,10 @@ class Assembler : public AbstractAssembler {
unsigned mask = (1U << nbits) - 1;
val <<= lsb;
mask <<= lsb;
unsigned target = *(unsigned *)a;
unsigned target = ld_instr(a);
target &= ~mask;
target |= val;
*(unsigned *)a = target;
sd_instr(a, target);
}

static void patch(address a, unsigned bit, unsigned val) {
@@ -1966,10 +1982,10 @@ enum Nf {
uint16_t mask = (1U << nbits) - 1;
val <<= lsb;
mask <<= lsb;
uint16_t target = *(uint16_t *)a;
uint16_t target = ld_c_instr(a);
target &= ~mask;
target |= val;
*(uint16_t *)a = target;
sd_c_instr(a, target);
}

static void c_patch(address a, unsigned bit, uint16_t val) {
74 changes: 23 additions & 51 deletions src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp
Original file line number Diff line number Diff line change
@@ -1110,10 +1110,8 @@ void C2_MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
// For Strings we're passed the address of the first characters in a1
// and a2 and the length in cnt1.
// elem_size is the element size in bytes: either 1 or 2.
// There are two implementations. For arrays >= 8 bytes, all
// comparisons (including the final one, which may overlap) are
// performed 8 bytes at a time. For strings < 8 bytes, we compare a
// halfword, then a short, and then a byte.
// All comparisons (including the final one, which may overlap) are
// performed 8 bytes at a time.

void C2_MacroAssembler::string_equals(Register a1, Register a2,
Register result, Register cnt1, int elem_size)
@@ -1127,11 +1125,12 @@ void C2_MacroAssembler::string_equals(Register a1, Register a2,

BLOCK_COMMENT("string_equals {");

beqz(cnt1, SAME);
mv(result, false);

// Check for short strings, i.e. smaller than wordSize.
sub(cnt1, cnt1, wordSize);
bltz(cnt1, SHORT);
blez(cnt1, SHORT);

// Main 8 byte comparison loop.
bind(NEXT_WORD); {
@@ -1143,55 +1142,28 @@ void C2_MacroAssembler::string_equals(Register a1, Register a2,
bne(tmp1, tmp2, DONE);
} bgtz(cnt1, NEXT_WORD);

// Last longword. In the case where length == 4 we compare the
// same longword twice, but that's still faster than another
// conditional branch.
// cnt1 could be 0, -1, -2, -3, -4 for chars; -4 only happens when
// length == 4.
add(tmp1, a1, cnt1);
ld(tmp1, Address(tmp1, 0));
add(tmp2, a2, cnt1);
ld(tmp2, Address(tmp2, 0));
bne(tmp1, tmp2, DONE);
j(SAME);

bind(SHORT);
Label TAIL03, TAIL01;

// 0-7 bytes left.
test_bit(t0, cnt1, 2);
beqz(t0, TAIL03);
{
lwu(tmp1, Address(a1, 0));
add(a1, a1, 4);
lwu(tmp2, Address(a2, 0));
add(a2, a2, 4);
bne(tmp1, tmp2, DONE);
}

bind(TAIL03);
// 0-3 bytes left.
test_bit(t0, cnt1, 1);
beqz(t0, TAIL01);
{
lhu(tmp1, Address(a1, 0));
add(a1, a1, 2);
lhu(tmp2, Address(a2, 0));
add(a2, a2, 2);
if (!AvoidUnalignedAccesses) {
// Last longword. In the case where length == 4 we compare the
// same longword twice, but that's still faster than another
// conditional branch.
// cnt1 could be 0, -1, -2, -3, -4 for chars; -4 only happens when
// length == 4.
add(tmp1, a1, cnt1);
ld(tmp1, Address(tmp1, 0));
add(tmp2, a2, cnt1);
ld(tmp2, Address(tmp2, 0));
bne(tmp1, tmp2, DONE);
j(SAME);
}

bind(TAIL01);
if (elem_size == 1) { // Only needed when comparing 1-byte elements
// 0-1 bytes left.
test_bit(t0, cnt1, 0);
beqz(t0, SAME);
{
lbu(tmp1, Address(a1, 0));
lbu(tmp2, Address(a2, 0));
bne(tmp1, tmp2, DONE);
}
}
bind(SHORT);
ld(tmp1, Address(a1));
ld(tmp2, Address(a2));
xorr(tmp1, tmp1, tmp2);
neg(cnt1, cnt1);
slli(cnt1, cnt1, LogBitsPerByte);
sll(tmp1, tmp1, cnt1);
bnez(tmp1, DONE);

// Arrays are equal.
bind(SAME);
6 changes: 3 additions & 3 deletions src/hotspot/cpu/riscv/gc/shared/barrierSetNMethod_riscv.cpp
Original file line number Diff line number Diff line change
@@ -143,11 +143,11 @@ static const struct CheckInsn barrierInsn[] = {
// BarrierSetAssembler::nmethod_entry_barrier. The matching ignores the specific
// register numbers and immediate values in the encoding.
bool NativeNMethodBarrier::check_barrier(err_msg& msg) const {
intptr_t addr = (intptr_t) instruction_address();
address addr = instruction_address();
for(unsigned int i = 0; i < sizeof(barrierInsn)/sizeof(struct CheckInsn); i++ ) {
uint32_t inst = *((uint32_t*) addr);
uint32_t inst = Assembler::ld_instr(addr);
if ((inst & barrierInsn[i].mask) != barrierInsn[i].bits) {
msg.print("Addr: " INTPTR_FORMAT " Code: 0x%x not an %s instruction", addr, inst, barrierInsn[i].name);
msg.print("Addr: " INTPTR_FORMAT " Code: 0x%x not an %s instruction", p2i(addr), inst, barrierInsn[i].name);
return false;
}
addr += 4;
32 changes: 26 additions & 6 deletions src/hotspot/cpu/riscv/interp_masm_riscv.cpp
Original file line number Diff line number Diff line change
@@ -177,7 +177,14 @@ void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread)

void InterpreterMacroAssembler::get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset) {
assert(bcp_offset >= 0, "bcp is still pointing to start of bytecode");
lhu(reg, Address(xbcp, bcp_offset));
if (AvoidUnalignedAccesses && (bcp_offset % 2)) {
lbu(t1, Address(xbcp, bcp_offset));
lbu(reg, Address(xbcp, bcp_offset + 1));
slli(reg, reg, 8);
add(reg, t1, reg);
} else {
lhu(reg, Address(xbcp, bcp_offset));
}
revb_h(reg, reg);
}

@@ -191,13 +198,23 @@ void InterpreterMacroAssembler::get_dispatch() {
}

void InterpreterMacroAssembler::get_cache_index_at_bcp(Register index,
Register tmp,
int bcp_offset,
size_t index_size) {
assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
if (index_size == sizeof(u2)) {
load_unsigned_short(index, Address(xbcp, bcp_offset));
if (AvoidUnalignedAccesses) {
assert_different_registers(index, tmp);
load_unsigned_byte(index, Address(xbcp, bcp_offset));
load_unsigned_byte(tmp, Address(xbcp, bcp_offset + 1));
slli(tmp, tmp, 8);
add(index, index, tmp);
} else {
load_unsigned_short(index, Address(xbcp, bcp_offset));
}
} else if (index_size == sizeof(u4)) {
lwu(index, Address(xbcp, bcp_offset));
load_int_misaligned(index, Address(xbcp, bcp_offset), tmp, false);

// Check if the secondary index definition is still ~x, otherwise
// we have to change the following assembler code to calculate the
// plain index.
@@ -224,7 +241,8 @@ void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache,
size_t index_size) {
assert_different_registers(cache, index);
assert_different_registers(cache, xcpool);
get_cache_index_at_bcp(index, bcp_offset, index_size);
// register "cache" is trashed in next shadd, so lets use it as a temporary register
get_cache_index_at_bcp(index, cache, bcp_offset, index_size);
assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
// Convert from field index to ConstantPoolCacheEntry
// riscv already has the cache in xcpool so there is no need to
@@ -261,7 +279,8 @@ void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
int bcp_offset,
size_t index_size) {
assert_different_registers(cache, tmp);
get_cache_index_at_bcp(tmp, bcp_offset, index_size);
// register "cache" is trashed in next ld, so lets use it as a temporary register
get_cache_index_at_bcp(tmp, cache, bcp_offset, index_size);
assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
// Convert from field index to ConstantPoolCacheEntry index
// and from word offset to byte offset
@@ -1957,7 +1976,8 @@ void InterpreterMacroAssembler::profile_parameters_type(Register mdp, Register t

void InterpreterMacroAssembler::load_resolved_indy_entry(Register cache, Register index) {
// Get index out of bytecode pointer, get_cache_entry_pointer_at_bcp
get_cache_index_at_bcp(index, 1, sizeof(u4));
// register "cache" is trashed in next ld, so lets use it as a temporary register
get_cache_index_at_bcp(index, cache, 1, sizeof(u4));
// Get address of invokedynamic array
ld(cache, Address(xcpool, in_bytes(ConstantPoolCache::invokedynamic_entries_offset())));
// Scale the index to be the entry index * sizeof(ResolvedInvokeDynamicInfo)
2 changes: 1 addition & 1 deletion src/hotspot/cpu/riscv/interp_masm_riscv.hpp
Original file line number Diff line number Diff line change
@@ -137,7 +137,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
void get_cache_and_index_at_bcp(Register cache, Register index, int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_and_index_and_bytecode_at_bcp(Register cache, Register index, Register bytecode, int byte_no, int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2));
void get_cache_index_at_bcp(Register index, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
void get_method_counters(Register method, Register mcs, Label& skip);

// Load cpool->resolved_references(index).
50 changes: 34 additions & 16 deletions src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
Original file line number Diff line number Diff line change
@@ -1418,7 +1418,7 @@ int MacroAssembler::patch_imm_in_li32(address branch, int32_t target) {
static long get_offset_of_jal(address insn_addr) {
assert_cond(insn_addr != nullptr);
long offset = 0;
unsigned insn = *(unsigned*)insn_addr;
unsigned insn = Assembler::ld_instr(insn_addr);
long val = (long)Assembler::sextract(insn, 31, 12);
offset |= ((val >> 19) & 0x1) << 20;
offset |= (val & 0xff) << 12;
@@ -1431,7 +1431,7 @@ static long get_offset_of_jal(address insn_addr) {
static long get_offset_of_conditional_branch(address insn_addr) {
long offset = 0;
assert_cond(insn_addr != nullptr);
unsigned insn = *(unsigned*)insn_addr;
unsigned insn = Assembler::ld_instr(insn_addr);
offset = (long)Assembler::sextract(insn, 31, 31);
offset = (offset << 12) | (((long)(Assembler::sextract(insn, 7, 7) & 0x1)) << 11);
offset = offset | (((long)(Assembler::sextract(insn, 30, 25) & 0x3f)) << 5);
@@ -1443,35 +1443,35 @@ static long get_offset_of_conditional_branch(address insn_addr) {
static long get_offset_of_pc_relative(address insn_addr) {
long offset = 0;
assert_cond(insn_addr != nullptr);
offset = ((long)(Assembler::sextract(((unsigned*)insn_addr)[0], 31, 12))) << 12; // Auipc.
offset += ((long)Assembler::sextract(((unsigned*)insn_addr)[1], 31, 20)); // Addi/Jalr/Load.
offset = ((long)(Assembler::sextract(Assembler::ld_instr(insn_addr), 31, 12))) << 12; // Auipc.
offset += ((long)Assembler::sextract(Assembler::ld_instr(insn_addr + 4), 31, 20)); // Addi/Jalr/Load.
offset = (offset << 32) >> 32;
return offset;
}

static address get_target_of_movptr(address insn_addr) {
assert_cond(insn_addr != nullptr);
intptr_t target_address = (((int64_t)Assembler::sextract(((unsigned*)insn_addr)[0], 31, 12)) & 0xfffff) << 29; // Lui.
target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[1], 31, 20)) << 17; // Addi.
target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[3], 31, 20)) << 6; // Addi.
target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[5], 31, 20)); // Addi/Jalr/Load.
intptr_t target_address = (((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr), 31, 12)) & 0xfffff) << 29; // Lui.
target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 4), 31, 20)) << 17; // Addi.
target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 12), 31, 20)) << 6; // Addi.
target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 20), 31, 20)); // Addi/Jalr/Load.
return (address) target_address;
}

static address get_target_of_li64(address insn_addr) {
assert_cond(insn_addr != nullptr);
intptr_t target_address = (((int64_t)Assembler::sextract(((unsigned*)insn_addr)[0], 31, 12)) & 0xfffff) << 44; // Lui.
target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[1], 31, 20)) << 32; // Addi.
target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[3], 31, 20)) << 20; // Addi.
target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[5], 31, 20)) << 8; // Addi.
target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[7], 31, 20)); // Addi.
intptr_t target_address = (((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr), 31, 12)) & 0xfffff) << 44; // Lui.
target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 4), 31, 20)) << 32; // Addi.
target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 12), 31, 20)) << 20; // Addi.
target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 20), 31, 20)) << 8; // Addi.
target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 28), 31, 20)); // Addi.
return (address)target_address;
}

address MacroAssembler::get_target_of_li32(address insn_addr) {
assert_cond(insn_addr != nullptr);
intptr_t target_address = (((int64_t)Assembler::sextract(((unsigned*)insn_addr)[0], 31, 12)) & 0xfffff) << 12; // Lui.
target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[1], 31, 20)); // Addiw.
intptr_t target_address = (((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr), 31, 12)) & 0xfffff) << 12; // Lui.
target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 4), 31, 20)); // Addiw.
return (address)target_address;
}

@@ -1496,7 +1496,7 @@ int MacroAssembler::pd_patch_instruction_size(address branch, address target) {
} else {
#ifdef ASSERT
tty->print_cr("pd_patch_instruction_size: instruction 0x%x at " INTPTR_FORMAT " could not be patched!\n",
*(unsigned*)branch, p2i(branch));
Assembler::ld_instr(branch), p2i(branch));
Disassembler::decode(branch - 16, branch + 16);
#endif
ShouldNotReachHere();
@@ -1690,6 +1690,24 @@ void MacroAssembler::store_sized_value(Address dst, Register src, size_t size_in
}
}

void MacroAssembler::load_int_misaligned(Register dst, Address src, Register tmp, bool is_signed) {
if (AvoidUnalignedAccesses) {
assert_different_registers(dst, tmp);
lbu(dst, src);
lbu(tmp, Address(src.base(), src.offset() + 1));
slli(tmp, tmp, 8);
add(dst, dst, tmp);
lbu(tmp, Address(src.base(), src.offset() + 2));
slli(tmp, tmp, 16);
add(dst, dst, tmp);
is_signed ? lb(tmp, Address(src.base(), src.offset() + 3)) : lbu(tmp, Address(src.base(), src.offset() + 3));
slli(tmp, tmp, 24);
add(dst, dst, tmp);
} else {
is_signed ? lw(dst, src) : lwu(dst, src);
}
}

// reverse bytes in halfword in lower 16 bits and sign-extend
// Rd[15:0] = Rs[7:0] Rs[15:8] (sign-extend to 64 bits)
void MacroAssembler::revb_h_h(Register Rd, Register Rs, Register tmp) {
3 changes: 3 additions & 0 deletions src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
Original file line number Diff line number Diff line change
@@ -430,6 +430,9 @@ class MacroAssembler: public Assembler {
void load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed);
void store_sized_value(Address dst, Register src, size_t size_in_bytes);

// Misaligned loads, will use the best way, according to the AvoidUnalignedAccess flag
void load_int_misaligned(Register dst, Address src, Register tmp, bool is_signed);

public:
// Standard pseudo instructions
inline void nop() {
Loading