Skip to content
Permalink
Browse files

8235385: AArch64: Crash on aarch64 JDK due to long offset

Reviewed-by: adinn
  • Loading branch information
Andrew Haley
Andrew Haley committed Jan 9, 2020
1 parent 11c073b commit 21c02a5b18a8f8b0ab66f32fbb9fe7cff415376d

Large diffs are not rendered by default.

@@ -1,4 +1,4 @@
dnl Copyright (c) 2014, Red Hat Inc. All rights reserved.
dnl Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved.
dnl DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
dnl
dnl This code is free software; you can redistribute it and/or modify it
@@ -24,44 +24,50 @@ dnl Process this file with m4 ad_encode.m4 to generate the load/store
dnl patterns used in aarch64.ad.
dnl
define(choose, `loadStore($1, &MacroAssembler::$3, $2, $4,
$5, $6, $7, $8);dnl
$5, $6, $7, $8, $9);dnl

%}')dnl
define(access, `
$3Register $1_reg = as_$3Register($$1$$reg);
$4choose(MacroAssembler(&cbuf), $1_reg,$2,$mem->opcode(),
as_Register($mem$$base),$mem$$index,$mem$$scale,$mem$$disp)')dnl
as_Register($mem$$base),$mem$$index,$mem$$scale,$mem$$disp,$5)')dnl
define(load,`
enc_class aarch64_enc_$2($1 dst, memory mem) %{dnl
access(dst,$2,$3)')dnl
load(iRegI,ldrsbw)
load(iRegI,ldrsb)
load(iRegI,ldrb)
load(iRegL,ldrb)
load(iRegI,ldrshw)
load(iRegI,ldrsh)
load(iRegI,ldrh)
load(iRegL,ldrh)
load(iRegI,ldrw)
load(iRegL,ldrw)
load(iRegL,ldrsw)
load(iRegL,ldr)
load(vRegF,ldrs,Float)
load(vRegD,ldrd,Float)
// This encoding class is generated automatically from ad_encode.m4.
// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
enc_class aarch64_enc_$2($1 dst, memory$5 mem) %{dnl
access(dst,$2,$3,$4,$5)')dnl
load(iRegI,ldrsbw,,,1)
load(iRegI,ldrsb,,,1)
load(iRegI,ldrb,,,1)
load(iRegL,ldrb,,,1)
load(iRegI,ldrshw,,,2)
load(iRegI,ldrsh,,,2)
load(iRegI,ldrh,,,2)
load(iRegL,ldrh,,,2)
load(iRegI,ldrw,,,4)
load(iRegL,ldrw,,,4)
load(iRegL,ldrsw,,,4)
load(iRegL,ldr,,,8)
load(vRegF,ldrs,Float,,4)
load(vRegD,ldrd,Float,,8)
define(STORE,`
enc_class aarch64_enc_$2($1 src, memory mem) %{dnl
access(src,$2,$3,$4)')dnl
// This encoding class is generated automatically from ad_encode.m4.
// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
enc_class aarch64_enc_$2($1 src, memory$5 mem) %{dnl
access(src,$2,$3,$4,$5)')dnl
define(STORE0,`
enc_class aarch64_enc_$2`'0(memory mem) %{
// This encoding class is generated automatically from ad_encode.m4.
// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
enc_class aarch64_enc_$2`'0(memory$4 mem) %{
MacroAssembler _masm(&cbuf);
choose(_masm,zr,$2,$mem->opcode(),
as_$3Register($mem$$base),$mem$$index,$mem$$scale,$mem$$disp)')dnl
STORE(iRegI,strb)
STORE0(iRegI,strb)
STORE(iRegI,strh)
STORE0(iRegI,strh)
STORE(iRegI,strw)
STORE0(iRegI,strw)
as_$3Register($mem$$base),$mem$$index,$mem$$scale,$mem$$disp,$4)')dnl
STORE(iRegI,strb,,,1)
STORE0(iRegI,strb,,1)
STORE(iRegI,strh,,,2)
STORE0(iRegI,strh,,2)
STORE(iRegI,strw,,,4)
STORE0(iRegI,strw,,4)
STORE(iRegL,str,,
`// we sometimes get asked to store the stack pointer into the
// current thread -- we cannot do that directly on AArch64
@@ -71,28 +77,41 @@ STORE(iRegL,str,,
__ mov(rscratch2, sp);
src_reg = rscratch2;
}
')
STORE0(iRegL,str)
STORE(vRegF,strs,Float)
STORE(vRegD,strd,Float)
',8)
STORE0(iRegL,str,,8)
STORE(vRegF,strs,Float,,4)
STORE(vRegD,strd,Float,,8)

enc_class aarch64_enc_strw_immn(immN src, memory mem) %{
// This encoding class is generated automatically from ad_encode.m4.
// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
enc_class aarch64_enc_strw_immn(immN src, memory1 mem) %{
MacroAssembler _masm(&cbuf);
address con = (address)$src$$constant;
// need to do this the hard way until we can manage relocs
// for 32 bit constants
__ movoop(rscratch2, (jobject)con);
if (con) __ encode_heap_oop_not_null(rscratch2);
choose(_masm,rscratch2,strw,$mem->opcode(),
as_Register($mem$$base),$mem$$index,$mem$$scale,$mem$$disp)
as_Register($mem$$base),$mem$$index,$mem$$scale,$mem$$disp, 4)

enc_class aarch64_enc_strw_immnk(immN src, memory mem) %{
// This encoding class is generated automatically from ad_encode.m4.
// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
enc_class aarch64_enc_strw_immnk(immN src, memory4 mem) %{
MacroAssembler _masm(&cbuf);
address con = (address)$src$$constant;
// need to do this the hard way until we can manage relocs
// for 32 bit constants
__ movoop(rscratch2, (jobject)con);
__ encode_klass_not_null(rscratch2);
choose(_masm,rscratch2,strw,$mem->opcode(),
as_Register($mem$$base),$mem$$index,$mem$$scale,$mem$$disp)
as_Register($mem$$base),$mem$$index,$mem$$scale,$mem$$disp, 4)

// This encoding class is generated automatically from ad_encode.m4.
// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
enc_class aarch64_enc_strb0_ordered(memory4 mem) %{
MacroAssembler _masm(&cbuf);
__ membar(Assembler::StoreStore);
loadStore(_masm, &MacroAssembler::strb, zr, $mem->opcode(),
as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 1);
%}

@@ -554,7 +554,7 @@ class Address {

void lea(MacroAssembler *, Register) const;

static bool offset_ok_for_immed(long offset, int shift = 0) {
static bool offset_ok_for_immed(long offset, int shift) {
unsigned mask = (1 << shift) - 1;
if (offset < 0 || offset & mask) {
return (uabs(offset) < (1 << (20 - 12))); // Unscaled offset
@@ -47,7 +47,7 @@ static void z_load_barrier_slow_path(MacroAssembler& _masm, const MachNode* node
%}

// Load Pointer
instruct zLoadP(iRegPNoSp dst, memory mem, rFlagsReg cr)
instruct zLoadP(iRegPNoSp dst, memory8 mem, rFlagsReg cr)
%{
match(Set dst (LoadP mem));
predicate(UseZGC && !needs_acquiring_load(n) && (n->as_Load()->barrier_data() == ZLoadBarrierStrong));
@@ -69,7 +69,7 @@ instruct zLoadP(iRegPNoSp dst, memory mem, rFlagsReg cr)
%}

// Load Weak Pointer
instruct zLoadWeakP(iRegPNoSp dst, memory mem, rFlagsReg cr)
instruct zLoadWeakP(iRegPNoSp dst, memory8 mem, rFlagsReg cr)
%{
match(Set dst (LoadP mem));
predicate(UseZGC && !needs_acquiring_load(n) && (n->as_Load()->barrier_data() == ZLoadBarrierWeak));
@@ -1741,7 +1741,7 @@ Address MacroAssembler::form_address(Register Rd, Register base, long byte_offse
{
unsigned long word_offset = byte_offset >> shift;
unsigned long masked_offset = word_offset & 0xfff000;
if (Address::offset_ok_for_immed(word_offset - masked_offset)
if (Address::offset_ok_for_immed(word_offset - masked_offset, 0)
&& Assembler::operand_valid_for_add_sub_immediate(masked_offset << shift)) {
add(Rd, base, masked_offset << shift);
word_offset -= masked_offset;
@@ -136,6 +136,20 @@ class MacroAssembler: public Assembler {
a.lea(this, r);
}

/* Sometimes we get misaligned loads and stores, usually from Unsafe
accesses, and these can exceed the offset range. */
Address legitimize_address(const Address &a, int size, Register scratch) {
if (a.getMode() == Address::base_plus_offset) {
if (! Address::offset_ok_for_immed(a.offset(), exact_log2(size))) {
block_comment("legitimize_address {");
lea(scratch, a);
block_comment("} legitimize_address");
return Address(scratch);
}
}
return a;
}

void addmw(Address a, Register incr, Register scratch) {
ldrw(scratch, a);
addw(scratch, scratch, incr);

0 comments on commit 21c02a5

Please sign in to comment.