Skip to content

Commit e2644b7

Browse files
author
Pengfei Li
committedDec 24, 2019
8233743: AArch64: Make r27 conditionally allocatable
Reviewed-by: aph, dlong
1 parent 995da6e commit e2644b7

File tree

6 files changed

+123
-229
lines changed

6 files changed

+123
-229
lines changed
 

‎src/hotspot/cpu/aarch64/aarch64.ad

+99-203
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ reg_def R25 ( SOC, SOE, Op_RegI, 25, r25->as_VMReg() );
128128
reg_def R25_H ( SOC, SOE, Op_RegI, 25, r25->as_VMReg()->next());
129129
reg_def R26 ( SOC, SOE, Op_RegI, 26, r26->as_VMReg() );
130130
reg_def R26_H ( SOC, SOE, Op_RegI, 26, r26->as_VMReg()->next());
131-
reg_def R27 ( NS, SOE, Op_RegI, 27, r27->as_VMReg() ); // heapbase
132-
reg_def R27_H ( NS, SOE, Op_RegI, 27, r27->as_VMReg()->next());
131+
reg_def R27 ( SOC, SOE, Op_RegI, 27, r27->as_VMReg() ); // heapbase
132+
reg_def R27_H ( SOC, SOE, Op_RegI, 27, r27->as_VMReg()->next());
133133
reg_def R28 ( NS, SOE, Op_RegI, 28, r28->as_VMReg() ); // thread
134134
reg_def R28_H ( NS, SOE, Op_RegI, 28, r28->as_VMReg()->next());
135135
reg_def R29 ( NS, NS, Op_RegI, 29, r29->as_VMReg() ); // fp
@@ -435,9 +435,8 @@ alloc_class chunk2(RFLAGS);
435435
// 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
436436
//
437437

438-
// Class for all 32 bit integer registers -- excludes SP which will
439-
// never be used as an integer register
440-
reg_class any_reg32(
438+
// Class for all 32 bit general purpose registers
439+
reg_class all_reg32(
441440
R0,
442441
R1,
443442
R2,
@@ -466,9 +465,17 @@ reg_class any_reg32(
466465
R27,
467466
R28,
468467
R29,
469-
R30
468+
R30,
469+
R31
470470
);
471471

472+
473+
// Class for all 32 bit integer registers (excluding SP which
474+
// will never be used as an integer register)
475+
reg_class any_reg32 %{
476+
return _ANY_REG32_mask;
477+
%}
478+
472479
// Singleton class for R0 int register
473480
reg_class int_r0_reg(R0);
474481

@@ -481,8 +488,11 @@ reg_class int_r3_reg(R3);
481488
// Singleton class for R4 int register
482489
reg_class int_r4_reg(R4);
483490

484-
// Class for all long integer registers (including RSP)
485-
reg_class any_reg(
491+
// Singleton class for R31 int register
492+
reg_class int_r31_reg(R31);
493+
494+
// Class for all 64 bit general purpose registers
495+
reg_class all_reg(
486496
R0, R0_H,
487497
R1, R1_H,
488498
R2, R2_H,
@@ -515,143 +525,34 @@ reg_class any_reg(
515525
R31, R31_H
516526
);
517527

518-
// Class for all non-special integer registers
519-
reg_class no_special_reg32_no_fp(
520-
R0,
521-
R1,
522-
R2,
523-
R3,
524-
R4,
525-
R5,
526-
R6,
527-
R7,
528-
R10,
529-
R11,
530-
R12, // rmethod
531-
R13,
532-
R14,
533-
R15,
534-
R16,
535-
R17,
536-
R18,
537-
R19,
538-
R20,
539-
R21,
540-
R22,
541-
R23,
542-
R24,
543-
R25,
544-
R26
545-
/* R27, */ // heapbase
546-
/* R28, */ // thread
547-
/* R29, */ // fp
548-
/* R30, */ // lr
549-
/* R31 */ // sp
550-
);
528+
// Class for all long integer registers (including SP)
529+
reg_class any_reg %{
530+
return _ANY_REG_mask;
531+
%}
551532

552-
reg_class no_special_reg32_with_fp(
553-
R0,
554-
R1,
555-
R2,
556-
R3,
557-
R4,
558-
R5,
559-
R6,
560-
R7,
561-
R10,
562-
R11,
563-
R12, // rmethod
564-
R13,
565-
R14,
566-
R15,
567-
R16,
568-
R17,
569-
R18,
570-
R19,
571-
R20,
572-
R21,
573-
R22,
574-
R23,
575-
R24,
576-
R25,
577-
R26
578-
/* R27, */ // heapbase
579-
/* R28, */ // thread
580-
R29, // fp
581-
/* R30, */ // lr
582-
/* R31 */ // sp
533+
// Class for non-allocatable 32 bit registers
534+
reg_class non_allocatable_reg32(
535+
R28, // thread
536+
R30, // lr
537+
R31 // sp
583538
);
584539

585-
reg_class_dynamic no_special_reg32(no_special_reg32_no_fp, no_special_reg32_with_fp, %{ PreserveFramePointer %});
586-
587-
// Class for all non-special long integer registers
588-
reg_class no_special_reg_no_fp(
589-
R0, R0_H,
590-
R1, R1_H,
591-
R2, R2_H,
592-
R3, R3_H,
593-
R4, R4_H,
594-
R5, R5_H,
595-
R6, R6_H,
596-
R7, R7_H,
597-
R10, R10_H,
598-
R11, R11_H,
599-
R12, R12_H, // rmethod
600-
R13, R13_H,
601-
R14, R14_H,
602-
R15, R15_H,
603-
R16, R16_H,
604-
R17, R17_H,
605-
R18, R18_H,
606-
R19, R19_H,
607-
R20, R20_H,
608-
R21, R21_H,
609-
R22, R22_H,
610-
R23, R23_H,
611-
R24, R24_H,
612-
R25, R25_H,
613-
R26, R26_H,
614-
/* R27, R27_H, */ // heapbase
615-
/* R28, R28_H, */ // thread
616-
/* R29, R29_H, */ // fp
617-
/* R30, R30_H, */ // lr
618-
/* R31, R31_H */ // sp
540+
// Class for non-allocatable 64 bit registers
541+
reg_class non_allocatable_reg(
542+
R28, R28_H, // thread
543+
R30, R30_H, // lr
544+
R31, R31_H // sp
619545
);
620546

621-
reg_class no_special_reg_with_fp(
622-
R0, R0_H,
623-
R1, R1_H,
624-
R2, R2_H,
625-
R3, R3_H,
626-
R4, R4_H,
627-
R5, R5_H,
628-
R6, R6_H,
629-
R7, R7_H,
630-
R10, R10_H,
631-
R11, R11_H,
632-
R12, R12_H, // rmethod
633-
R13, R13_H,
634-
R14, R14_H,
635-
R15, R15_H,
636-
R16, R16_H,
637-
R17, R17_H,
638-
R18, R18_H,
639-
R19, R19_H,
640-
R20, R20_H,
641-
R21, R21_H,
642-
R22, R22_H,
643-
R23, R23_H,
644-
R24, R24_H,
645-
R25, R25_H,
646-
R26, R26_H,
647-
/* R27, R27_H, */ // heapbase
648-
/* R28, R28_H, */ // thread
649-
R29, R29_H, // fp
650-
/* R30, R30_H, */ // lr
651-
/* R31, R31_H */ // sp
652-
);
547+
// Class for all non-special integer registers
548+
reg_class no_special_reg32 %{
549+
return _NO_SPECIAL_REG32_mask;
550+
%}
653551

654-
reg_class_dynamic no_special_reg(no_special_reg_no_fp, no_special_reg_with_fp, %{ PreserveFramePointer %});
552+
// Class for all non-special long integer registers
553+
reg_class no_special_reg %{
554+
return _NO_SPECIAL_REG_mask;
555+
%}
655556

656557
// Class for 64 bit register r0
657558
reg_class r0_reg(
@@ -724,72 +625,14 @@ reg_class sp_reg(
724625
);
725626

726627
// Class for all pointer registers
727-
reg_class ptr_reg(
728-
R0, R0_H,
729-
R1, R1_H,
730-
R2, R2_H,
731-
R3, R3_H,
732-
R4, R4_H,
733-
R5, R5_H,
734-
R6, R6_H,
735-
R7, R7_H,
736-
R10, R10_H,
737-
R11, R11_H,
738-
R12, R12_H,
739-
R13, R13_H,
740-
R14, R14_H,
741-
R15, R15_H,
742-
R16, R16_H,
743-
R17, R17_H,
744-
R18, R18_H,
745-
R19, R19_H,
746-
R20, R20_H,
747-
R21, R21_H,
748-
R22, R22_H,
749-
R23, R23_H,
750-
R24, R24_H,
751-
R25, R25_H,
752-
R26, R26_H,
753-
R27, R27_H,
754-
R28, R28_H,
755-
R29, R29_H,
756-
R30, R30_H,
757-
R31, R31_H
758-
);
628+
reg_class ptr_reg %{
629+
return _PTR_REG_mask;
630+
%}
759631

760632
// Class for all non_special pointer registers
761-
reg_class no_special_ptr_reg(
762-
R0, R0_H,
763-
R1, R1_H,
764-
R2, R2_H,
765-
R3, R3_H,
766-
R4, R4_H,
767-
R5, R5_H,
768-
R6, R6_H,
769-
R7, R7_H,
770-
R10, R10_H,
771-
R11, R11_H,
772-
R12, R12_H,
773-
R13, R13_H,
774-
R14, R14_H,
775-
R15, R15_H,
776-
R16, R16_H,
777-
R17, R17_H,
778-
R18, R18_H,
779-
R19, R19_H,
780-
R20, R20_H,
781-
R21, R21_H,
782-
R22, R22_H,
783-
R23, R23_H,
784-
R24, R24_H,
785-
R25, R25_H,
786-
R26, R26_H,
787-
/* R27, R27_H, */ // heapbase
788-
/* R28, R28_H, */ // thread
789-
/* R29, R29_H, */ // fp
790-
/* R30, R30_H, */ // lr
791-
/* R31, R31_H */ // sp
792-
);
633+
reg_class no_special_ptr_reg %{
634+
return _NO_SPECIAL_PTR_REG_mask;
635+
%}
793636

794637
// Class for all float registers
795638
reg_class float_reg(
@@ -1141,6 +984,13 @@ source_hpp %{
1141984
#include "gc/shared/collectedHeap.hpp"
1142985
#include "opto/addnode.hpp"
1143986

987+
extern RegMask _ANY_REG32_mask;
988+
extern RegMask _ANY_REG_mask;
989+
extern RegMask _PTR_REG_mask;
990+
extern RegMask _NO_SPECIAL_REG32_mask;
991+
extern RegMask _NO_SPECIAL_REG_mask;
992+
extern RegMask _NO_SPECIAL_PTR_REG_mask;
993+
1144994
class CallStubImpl {
1145995

1146996
//--------------------------------------------------------------
@@ -1198,6 +1048,52 @@ class HandlerImpl {
11981048

11991049
source %{
12001050

1051+
// Derived RegMask with conditionally allocatable registers
1052+
1053+
RegMask _ANY_REG32_mask;
1054+
RegMask _ANY_REG_mask;
1055+
RegMask _PTR_REG_mask;
1056+
RegMask _NO_SPECIAL_REG32_mask;
1057+
RegMask _NO_SPECIAL_REG_mask;
1058+
RegMask _NO_SPECIAL_PTR_REG_mask;
1059+
1060+
void reg_mask_init() {
1061+
// We derive below RegMask(s) from the ones which are auto-generated from
1062+
// adlc register classes to make AArch64 rheapbase (r27) and rfp (r29)
1063+
// registers conditionally reserved.
1064+
1065+
_ANY_REG32_mask = _ALL_REG32_mask;
1066+
_ANY_REG32_mask.Remove(OptoReg::as_OptoReg(r31_sp->as_VMReg()));
1067+
1068+
_ANY_REG_mask = _ALL_REG_mask;
1069+
1070+
_PTR_REG_mask = _ALL_REG_mask;
1071+
1072+
_NO_SPECIAL_REG32_mask = _ALL_REG32_mask;
1073+
_NO_SPECIAL_REG32_mask.SUBTRACT(_NON_ALLOCATABLE_REG32_mask);
1074+
1075+
_NO_SPECIAL_REG_mask = _ALL_REG_mask;
1076+
_NO_SPECIAL_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask);
1077+
1078+
_NO_SPECIAL_PTR_REG_mask = _ALL_REG_mask;
1079+
_NO_SPECIAL_PTR_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask);
1080+
1081+
// r27 is not allocatable when compressed oops is on, compressed klass
1082+
// pointers doesn't use r27 after JDK-8234794
1083+
if (UseCompressedOops) {
1084+
_NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg()));
1085+
_NO_SPECIAL_REG_mask.SUBTRACT(_HEAPBASE_REG_mask);
1086+
_NO_SPECIAL_PTR_REG_mask.SUBTRACT(_HEAPBASE_REG_mask);
1087+
}
1088+
1089+
// r29 is not allocatable when PreserveFramePointer is on
1090+
if (PreserveFramePointer) {
1091+
_NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg()));
1092+
_NO_SPECIAL_REG_mask.SUBTRACT(_FP_REG_mask);
1093+
_NO_SPECIAL_PTR_REG_mask.SUBTRACT(_FP_REG_mask);
1094+
}
1095+
}
1096+
12011097
// Optimizaton of volatile gets and puts
12021098
// -------------------------------------
12031099
//

‎src/hotspot/cpu/aarch64/c2_init_aarch64.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
3-
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
2+
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
66
* This code is free software; you can redistribute it and/or modify it
@@ -27,10 +27,11 @@
2727
#include "opto/compile.hpp"
2828
#include "opto/node.hpp"
2929

30-
// processor dependent initialization for i486
30+
// processor dependent initialization for AArch64
31+
32+
extern void reg_mask_init();
3133

3234
void Compile::pd_compiler2_init() {
3335
guarantee(CodeEntryAlignment >= InteriorEntryAlignment, "" );
34-
// QQQ presumably all 64bit cpu's support this. Seems like the ifdef could
35-
// simply be left out.
36+
reg_mask_init();
3637
}

‎src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,10 @@ void ZBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm,
227227

228228
void ZBarrierSetAssembler::generate_c1_load_barrier_test(LIR_Assembler* ce,
229229
LIR_Opr ref) const {
230-
assert_different_registers(rheapbase, rthread, ref->as_register());
230+
assert_different_registers(rscratch1, rthread, ref->as_register());
231231

232-
__ ldr(rheapbase, address_bad_mask_from_thread(rthread));
233-
__ tst(ref->as_register(), rheapbase);
232+
__ ldr(rscratch1, address_bad_mask_from_thread(rthread));
233+
__ tst(ref->as_register(), rscratch1);
234234
}
235235

236236
void ZBarrierSetAssembler::generate_c1_load_barrier_stub(LIR_Assembler* ce,

‎src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
148148

149149
for (int i = 0; i < RegisterImpl::number_of_registers; i++) {
150150
Register r = as_Register(i);
151-
if (r < rheapbase && r != rscratch1 && r != rscratch2) {
151+
if (r <= rfp && r != rscratch1 && r != rscratch2) {
152152
// SP offsets are in 4-byte words.
153153
// Register slots are 8 bytes wide, 32 floating-point registers.
154154
int sp_offset = RegisterImpl::max_slots_per_register * i +

‎src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ protected HotSpotConstantReflectionProvider createConstantReflection(HotSpotJVMC
127127
return new HotSpotConstantReflectionProvider(runtime);
128128
}
129129

130-
private static RegisterConfig createRegisterConfig(TargetDescription target) {
131-
return new AArch64HotSpotRegisterConfig(target);
130+
private static RegisterConfig createRegisterConfig(AArch64HotSpotVMConfig config, TargetDescription target) {
131+
return new AArch64HotSpotRegisterConfig(target, config.useCompressedOops);
132132
}
133133

134134
protected HotSpotCodeCacheProvider createCodeCache(HotSpotJVMCIRuntime runtime, TargetDescription target, RegisterConfig regConfig) {
@@ -167,7 +167,7 @@ public JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntime runtime, JVMCIBackend
167167
metaAccess = createMetaAccess(runtime);
168168
}
169169
try (InitTimer rt = timer("create RegisterConfig")) {
170-
regConfig = createRegisterConfig(target);
170+
regConfig = createRegisterConfig(config, target);
171171
}
172172
try (InitTimer rt = timer("create CodeCache provider")) {
173173
codeCache = createCodeCache(runtime, target, regConfig);

‎src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java

+11-14
Original file line numberDiff line numberDiff line change
@@ -126,19 +126,11 @@ public RegisterAttributes[] getAttributesMap() {
126126
public static final Register threadRegister = r28;
127127
public static final Register fp = r29;
128128

129-
/**
130-
* The heapBaseRegister, i.e. r27, is reserved unconditionally because HotSpot does not intend
131-
* to support it as an allocatable register even when compressed oops is off. This register is
132-
* excluded from callee-saved register at
133-
* cpu/aarch64/sharedRuntime_aarch64.cpp:RegisterSaver::save_live_registers, which may lead to
134-
* dereferencing unknown value from the stack at
135-
* share/runtime/stackValue.cpp:StackValue::create_stack_value during deoptimization.
136-
*/
137-
private static final RegisterArray reservedRegisters = new RegisterArray(rscratch1, rscratch2, heapBaseRegister, threadRegister, fp, lr, r31, zr, sp);
129+
private static final RegisterArray reservedRegisters = new RegisterArray(rscratch1, rscratch2, threadRegister, fp, lr, r31, zr, sp);
138130

139-
private static RegisterArray initAllocatable(Architecture arch) {
131+
private static RegisterArray initAllocatable(Architecture arch, boolean reserveForHeapBase) {
140132
RegisterArray allRegisters = arch.getAvailableValueRegisters();
141-
Register[] registers = new Register[allRegisters.size() - reservedRegisters.size()];
133+
Register[] registers = new Register[allRegisters.size() - reservedRegisters.size() - (reserveForHeapBase ? 1 : 0)];
142134
List<Register> reservedRegistersList = reservedRegisters.asList();
143135

144136
int idx = 0;
@@ -147,16 +139,21 @@ private static RegisterArray initAllocatable(Architecture arch) {
147139
// skip reserved registers
148140
continue;
149141
}
150-
assert !(reg.equals(heapBaseRegister) || reg.equals(threadRegister) || reg.equals(fp) || reg.equals(lr) || reg.equals(r31) || reg.equals(zr) || reg.equals(sp)) : reg;
142+
assert !(reg.equals(threadRegister) || reg.equals(fp) || reg.equals(lr) || reg.equals(r31) || reg.equals(zr) || reg.equals(sp));
143+
if (reserveForHeapBase && reg.equals(heapBaseRegister)) {
144+
// skip heap base register
145+
continue;
146+
}
147+
151148
registers[idx++] = reg;
152149
}
153150

154151
assert idx == registers.length;
155152
return new RegisterArray(registers);
156153
}
157154

158-
public AArch64HotSpotRegisterConfig(TargetDescription target) {
159-
this(target, initAllocatable(target.arch));
155+
public AArch64HotSpotRegisterConfig(TargetDescription target, boolean useCompressedOops) {
156+
this(target, initAllocatable(target.arch, useCompressedOops));
160157
assert callerSaved.size() >= allocatable.size();
161158
}
162159

0 commit comments

Comments
 (0)
Please sign in to comment.