Skip to content

Commit f279ddf

Browse files
author
Patric Hedlin
committed
8248411: [aarch64] Insufficient error handling when CodeBuffer is exhausted
Reviewed-by: adinn
1 parent 4634dbe commit f279ddf

File tree

5 files changed

+141
-65
lines changed

5 files changed

+141
-65
lines changed

src/hotspot/cpu/aarch64/aarch64.ad

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3765,23 +3765,28 @@ encode %{
37653765
if (!_method) {
37663766
// A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
37673767
call = __ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf);
3768+
if (call == NULL) {
3769+
ciEnv::current()->record_failure("CodeCache is full");
3770+
return;
3771+
}
37683772
} else {
37693773
int method_index = resolved_method_index(cbuf);
37703774
RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
37713775
: static_call_Relocation::spec(method_index);
37723776
call = __ trampoline_call(Address(addr, rspec), &cbuf);
3773-
3777+
if (call == NULL) {
3778+
ciEnv::current()->record_failure("CodeCache is full");
3779+
return;
3780+
}
37743781
// Emit stub for static call
37753782
address stub = CompiledStaticCall::emit_to_interp_stub(cbuf);
37763783
if (stub == NULL) {
37773784
ciEnv::current()->record_failure("CodeCache is full");
37783785
return;
37793786
}
37803787
}
3781-
if (call == NULL) {
3782-
ciEnv::current()->record_failure("CodeCache is full");
3783-
return;
3784-
} else if (UseSVE > 0 && Compile::current()->max_vector_size() >= 16) {
3788+
3789+
if (UseSVE > 0 && Compile::current()->max_vector_size() >= 16) {
37853790
// Only non uncommon_trap calls need to reinitialize ptrue.
37863791
if (uncommon_trap_request() == 0) {
37873792
__ reinitialize_ptrue();
@@ -14725,7 +14730,11 @@ instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlag
1472514730
format %{ "ClearArray $cnt, $base" %}
1472614731

1472714732
ins_encode %{
14728-
__ zero_words($base$$Register, $cnt$$Register);
14733+
address tpc = __ zero_words($base$$Register, $cnt$$Register);
14734+
if (tpc == NULL) {
14735+
ciEnv::current()->record_failure("CodeCache is full");
14736+
return;
14737+
}
1472914738
%}
1473014739

1473114740
ins_pipe(pipe_class_memory);
@@ -16003,8 +16012,8 @@ instruct CallStaticJavaDirect(method meth)
1600316012

1600416013
format %{ "call,static $meth \t// ==> " %}
1600516014

16006-
ins_encode( aarch64_enc_java_static_call(meth),
16007-
aarch64_enc_call_epilog );
16015+
ins_encode(aarch64_enc_java_static_call(meth),
16016+
aarch64_enc_call_epilog);
1600816017

1600916018
ins_pipe(pipe_class_call);
1601016019
%}
@@ -16022,8 +16031,8 @@ instruct CallDynamicJavaDirect(method meth)
1602216031

1602316032
format %{ "CALL,dynamic $meth \t// ==> " %}
1602416033

16025-
ins_encode( aarch64_enc_java_dynamic_call(meth),
16026-
aarch64_enc_call_epilog );
16034+
ins_encode(aarch64_enc_java_dynamic_call(meth),
16035+
aarch64_enc_call_epilog);
1602716036

1602816037
ins_pipe(pipe_class_call);
1602916038
%}
@@ -16489,10 +16498,14 @@ instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
1648916498

1649016499
format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %}
1649116500
ins_encode %{
16492-
__ arrays_equals($ary1$$Register, $ary2$$Register,
16493-
$tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
16494-
$result$$Register, $tmp$$Register, 1);
16495-
%}
16501+
address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register,
16502+
$tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
16503+
$result$$Register, $tmp$$Register, 1);
16504+
if (tpc == NULL) {
16505+
ciEnv::current()->record_failure("CodeCache is full");
16506+
return;
16507+
}
16508+
%}
1649616509
ins_pipe(pipe_class_memory);
1649716510
%}
1649816511

@@ -16506,9 +16519,13 @@ instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
1650616519

1650716520
format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %}
1650816521
ins_encode %{
16509-
__ arrays_equals($ary1$$Register, $ary2$$Register,
16510-
$tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
16511-
$result$$Register, $tmp$$Register, 2);
16522+
address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register,
16523+
$tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
16524+
$result$$Register, $tmp$$Register, 2);
16525+
if (tpc == NULL) {
16526+
ciEnv::current()->record_failure("CodeCache is full");
16527+
return;
16528+
}
1651216529
%}
1651316530
ins_pipe(pipe_class_memory);
1651416531
%}
@@ -16519,7 +16536,11 @@ instruct has_negatives(iRegP_R1 ary1, iRegI_R2 len, iRegI_R0 result, rFlagsReg c
1651916536
effect(USE_KILL ary1, USE_KILL len, KILL cr);
1652016537
format %{ "has negatives byte[] $ary1,$len -> $result" %}
1652116538
ins_encode %{
16522-
__ has_negatives($ary1$$Register, $len$$Register, $result$$Register);
16539+
address tpc = __ has_negatives($ary1$$Register, $len$$Register, $result$$Register);
16540+
if (tpc == NULL) {
16541+
ciEnv::current()->record_failure("CodeCache is full");
16542+
return;
16543+
}
1652316544
%}
1652416545
ins_pipe( pipe_slow );
1652516546
%}
@@ -16552,8 +16573,13 @@ instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len
1655216573

1655316574
format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %}
1655416575
ins_encode %{
16555-
__ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register,
16556-
$tmp1$$FloatRegister, $tmp2$$FloatRegister, $tmp3$$FloatRegister, $tmp4$$Register);
16576+
address tpc = __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register,
16577+
$tmp1$$FloatRegister, $tmp2$$FloatRegister,
16578+
$tmp3$$FloatRegister, $tmp4$$Register);
16579+
if (tpc == NULL) {
16580+
ciEnv::current()->record_failure("CodeCache is full");
16581+
return;
16582+
}
1655716583
%}
1655816584
ins_pipe(pipe_class_memory);
1655916585
%}

src/hotspot/cpu/aarch64/compiledIC_aarch64.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636

3737
#define __ _masm.
3838
address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark) {
39+
precond(cbuf.stubs()->start() != badAddress);
40+
precond(cbuf.stubs()->end() != badAddress);
41+
3942
// Stub is fixed up when the corresponding call is converted from
4043
// calling compiled code to calling interpreted code.
4144
// mov rmethod, 0

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

Lines changed: 60 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,7 @@ void MacroAssembler::call_VM_helper(Register oop_result, address entry_point, in
705705
// Maybe emit a call via a trampoline. If the code cache is small
706706
// trampolines won't be emitted.
707707

708-
address MacroAssembler::trampoline_call(Address entry, CodeBuffer *cbuf) {
708+
address MacroAssembler::trampoline_call(Address entry, CodeBuffer* cbuf) {
709709
assert(JavaThread::current()->is_Compiler_thread(), "just checking");
710710
assert(entry.rspec().type() == relocInfo::runtime_call_type
711711
|| entry.rspec().type() == relocInfo::opt_virtual_call_type
@@ -726,6 +726,7 @@ address MacroAssembler::trampoline_call(Address entry, CodeBuffer *cbuf) {
726726
if (!in_scratch_emit_size) {
727727
address stub = emit_trampoline_stub(offset(), entry.target());
728728
if (stub == NULL) {
729+
postcond(pc() == badAddress);
729730
return NULL; // CodeCache is full
730731
}
731732
}
@@ -739,6 +740,7 @@ address MacroAssembler::trampoline_call(Address entry, CodeBuffer *cbuf) {
739740
bl(pc());
740741
}
741742
// just need to return a non-null address
743+
postcond(pc() != badAddress);
742744
return pc();
743745
}
744746

@@ -4490,7 +4492,7 @@ void MacroAssembler::remove_frame(int framesize) {
44904492

44914493

44924494
// This method checks if provided byte array contains byte with highest bit set.
4493-
void MacroAssembler::has_negatives(Register ary1, Register len, Register result) {
4495+
address MacroAssembler::has_negatives(Register ary1, Register len, Register result) {
44944496
// Simple and most common case of aligned small array which is not at the
44954497
// end of memory page is placed here. All other cases are in stub.
44964498
Label LOOP, END, STUB, STUB_LONG, SET_RESULT, DONE;
@@ -4527,27 +4529,38 @@ void MacroAssembler::has_negatives(Register ary1, Register len, Register result)
45274529
b(SET_RESULT);
45284530

45294531
BIND(STUB);
4530-
RuntimeAddress has_neg = RuntimeAddress(StubRoutines::aarch64::has_negatives());
4532+
RuntimeAddress has_neg = RuntimeAddress(StubRoutines::aarch64::has_negatives());
45314533
assert(has_neg.target() != NULL, "has_negatives stub has not been generated");
4532-
trampoline_call(has_neg);
4534+
address tpc1 = trampoline_call(has_neg);
4535+
if (tpc1 == NULL) {
4536+
DEBUG_ONLY(reset_labels(STUB_LONG, SET_RESULT, DONE));
4537+
postcond(pc() == badAddress);
4538+
return NULL;
4539+
}
45334540
b(DONE);
45344541

45354542
BIND(STUB_LONG);
4536-
RuntimeAddress has_neg_long = RuntimeAddress(
4537-
StubRoutines::aarch64::has_negatives_long());
4543+
RuntimeAddress has_neg_long = RuntimeAddress(StubRoutines::aarch64::has_negatives_long());
45384544
assert(has_neg_long.target() != NULL, "has_negatives stub has not been generated");
4539-
trampoline_call(has_neg_long);
4545+
address tpc2 = trampoline_call(has_neg_long);
4546+
if (tpc2 == NULL) {
4547+
DEBUG_ONLY(reset_labels(SET_RESULT, DONE));
4548+
postcond(pc() == badAddress);
4549+
return NULL;
4550+
}
45404551
b(DONE);
45414552

45424553
BIND(SET_RESULT);
45434554
cset(result, NE); // set true or false
45444555

45454556
BIND(DONE);
4557+
postcond(pc() != badAddress);
4558+
return pc();
45464559
}
45474560

4548-
void MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
4549-
Register tmp4, Register tmp5, Register result,
4550-
Register cnt1, int elem_size) {
4561+
address MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
4562+
Register tmp4, Register tmp5, Register result,
4563+
Register cnt1, int elem_size) {
45514564
Label DONE, SAME;
45524565
Register tmp1 = rscratch1;
45534566
Register tmp2 = rscratch2;
@@ -4651,7 +4664,7 @@ void MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
46514664
}
46524665
}
46534666
} else {
4654-
Label NEXT_DWORD, SHORT, TAIL, TAIL2, STUB, EARLY_OUT,
4667+
Label NEXT_DWORD, SHORT, TAIL, TAIL2, STUB,
46554668
CSET_EQ, LAST_CHECK;
46564669
mov(result, false);
46574670
cbz(a1, DONE);
@@ -4710,10 +4723,14 @@ void MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
47104723
cbnz(tmp5, DONE);
47114724
RuntimeAddress stub = RuntimeAddress(StubRoutines::aarch64::large_array_equals());
47124725
assert(stub.target() != NULL, "array_equals_long stub has not been generated");
4713-
trampoline_call(stub);
4726+
address tpc = trampoline_call(stub);
4727+
if (tpc == NULL) {
4728+
DEBUG_ONLY(reset_labels(SHORT, LAST_CHECK, CSET_EQ, SAME, DONE));
4729+
postcond(pc() == badAddress);
4730+
return NULL;
4731+
}
47144732
b(DONE);
47154733

4716-
bind(EARLY_OUT);
47174734
// (a1 != null && a2 == null) || (a1 != null && a2 != null && a1 == a2)
47184735
// so, if a2 == null => return false(0), else return true, so we can return a2
47194736
mov(result, a2);
@@ -4740,6 +4757,8 @@ void MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
47404757
bind(DONE);
47414758

47424759
BLOCK_COMMENT("} array_equals");
4760+
postcond(pc() != badAddress);
4761+
return pc();
47434762
}
47444763

47454764
// Compare Strings
@@ -4847,7 +4866,7 @@ const int MacroAssembler::zero_words_block_size = 8;
48474866
// cnt: Count in HeapWords.
48484867
//
48494868
// ptr, cnt, rscratch1, and rscratch2 are clobbered.
4850-
void MacroAssembler::zero_words(Register ptr, Register cnt)
4869+
address MacroAssembler::zero_words(Register ptr, Register cnt)
48514870
{
48524871
assert(is_power_of_2(zero_words_block_size), "adjust this");
48534872
assert(ptr == r10 && cnt == r11, "mismatch in register usage");
@@ -4857,10 +4876,15 @@ void MacroAssembler::zero_words(Register ptr, Register cnt)
48574876
Label around;
48584877
br(LO, around);
48594878
{
4860-
RuntimeAddress zero_blocks = RuntimeAddress(StubRoutines::aarch64::zero_blocks());
4879+
RuntimeAddress zero_blocks = RuntimeAddress(StubRoutines::aarch64::zero_blocks());
48614880
assert(zero_blocks.target() != NULL, "zero_blocks stub has not been generated");
48624881
if (StubRoutines::aarch64::complete()) {
4863-
trampoline_call(zero_blocks);
4882+
address tpc = trampoline_call(zero_blocks);
4883+
if (tpc == NULL) {
4884+
DEBUG_ONLY(reset_labels(around));
4885+
postcond(pc() == badAddress);
4886+
return NULL;
4887+
}
48644888
} else {
48654889
bl(zero_blocks);
48664890
}
@@ -4881,6 +4905,8 @@ void MacroAssembler::zero_words(Register ptr, Register cnt)
48814905
bind(l);
48824906
}
48834907
BLOCK_COMMENT("} zero_words");
4908+
postcond(pc() != badAddress);
4909+
return pc();
48844910
}
48854911

48864912
// base: Address of a buffer to be zeroed, 8 bytes aligned.
@@ -4893,14 +4919,15 @@ void MacroAssembler::zero_words(Register base, uint64_t cnt)
48934919
if (i) str(zr, Address(base));
48944920

48954921
if (cnt <= SmallArraySize / BytesPerLong) {
4896-
for (; i < (int)cnt; i += 2)
4922+
for (; i < (int)cnt; i += 2) {
48974923
stp(zr, zr, Address(base, i * wordSize));
4924+
}
48984925
} else {
48994926
const int unroll = 4; // Number of stp(zr, zr) instructions we'll unroll
49004927
int remainder = cnt % (2 * unroll);
4901-
for (; i < remainder; i += 2)
4928+
for (; i < remainder; i += 2) {
49024929
stp(zr, zr, Address(base, i * wordSize));
4903-
4930+
}
49044931
Label loop;
49054932
Register cnt_reg = rscratch1;
49064933
Register loop_base = rscratch2;
@@ -4910,8 +4937,9 @@ void MacroAssembler::zero_words(Register base, uint64_t cnt)
49104937
add(loop_base, base, (remainder - 2) * wordSize);
49114938
bind(loop);
49124939
sub(cnt_reg, cnt_reg, 2 * unroll);
4913-
for (i = 1; i < unroll; i++)
4940+
for (i = 1; i < unroll; i++) {
49144941
stp(zr, zr, Address(loop_base, 2 * i * wordSize));
4942+
}
49154943
stp(zr, zr, Address(pre(loop_base, 2 * unroll * wordSize)));
49164944
cbnz(cnt_reg, loop);
49174945
}
@@ -5127,9 +5155,9 @@ void MacroAssembler::encode_iso_array(Register src, Register dst,
51275155

51285156

51295157
// Inflate byte[] array to char[].
5130-
void MacroAssembler::byte_array_inflate(Register src, Register dst, Register len,
5131-
FloatRegister vtmp1, FloatRegister vtmp2, FloatRegister vtmp3,
5132-
Register tmp4) {
5158+
address MacroAssembler::byte_array_inflate(Register src, Register dst, Register len,
5159+
FloatRegister vtmp1, FloatRegister vtmp2,
5160+
FloatRegister vtmp3, Register tmp4) {
51335161
Label big, done, after_init, to_stub;
51345162

51355163
assert_different_registers(src, dst, len, tmp4, rscratch1);
@@ -5166,9 +5194,14 @@ void MacroAssembler::byte_array_inflate(Register src, Register dst, Register len
51665194

51675195
if (SoftwarePrefetchHintDistance >= 0) {
51685196
bind(to_stub);
5169-
RuntimeAddress stub = RuntimeAddress(StubRoutines::aarch64::large_byte_array_inflate());
5197+
RuntimeAddress stub = RuntimeAddress(StubRoutines::aarch64::large_byte_array_inflate());
51705198
assert(stub.target() != NULL, "large_byte_array_inflate stub has not been generated");
5171-
trampoline_call(stub);
5199+
address tpc = trampoline_call(stub);
5200+
if (tpc == NULL) {
5201+
DEBUG_ONLY(reset_labels(big, done));
5202+
postcond(pc() == badAddress);
5203+
return NULL;
5204+
}
51725205
b(after_init);
51735206
}
51745207

@@ -5222,6 +5255,8 @@ void MacroAssembler::byte_array_inflate(Register src, Register dst, Register len
52225255
strq(vtmp3, Address(dst, -16));
52235256

52245257
bind(done);
5258+
postcond(pc() != badAddress);
5259+
return pc();
52255260
}
52265261

52275262
// Compress char[] array to byte[].

0 commit comments

Comments
 (0)