mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-13 16:38:50 +00:00
8149415: [AArch64] implement JVMCI CodeInstaller
Reviewed-by: aph, kvn
This commit is contained in:
parent
381b9a329d
commit
98bbb4efa0
@ -30,39 +30,151 @@
|
||||
#include "vmreg_aarch64.inline.hpp"
|
||||
|
||||
jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, Handle method, TRAPS) {
|
||||
Unimplemented();
|
||||
return 0;
|
||||
if (inst->is_call() || inst->is_jump() || inst->is_blr()) {
|
||||
return pc_offset + NativeCall::instruction_size;
|
||||
} else if (inst->is_general_jump()) {
|
||||
return pc_offset + NativeGeneralJump::instruction_size;
|
||||
} else {
|
||||
JVMCI_ERROR_0("unsupported type of instruction for call site");
|
||||
}
|
||||
}
|
||||
|
||||
void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle constant, TRAPS) {
|
||||
Unimplemented();
|
||||
address pc = _instructions->start() + pc_offset;
|
||||
Handle obj = HotSpotObjectConstantImpl::object(constant);
|
||||
jobject value = JNIHandles::make_local(obj());
|
||||
if (HotSpotObjectConstantImpl::compressed(constant)) {
|
||||
int oop_index = _oop_recorder->find_index(value);
|
||||
RelocationHolder rspec = oop_Relocation::spec(oop_index);
|
||||
_instructions->relocate(pc, rspec, 1);
|
||||
Unimplemented();
|
||||
} else {
|
||||
NativeMovConstReg* move = nativeMovConstReg_at(pc);
|
||||
move->set_data((intptr_t) value);
|
||||
int oop_index = _oop_recorder->find_index(value);
|
||||
RelocationHolder rspec = oop_Relocation::spec(oop_index);
|
||||
_instructions->relocate(pc, rspec);
|
||||
}
|
||||
}
|
||||
|
||||
void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle constant, TRAPS) {
|
||||
Unimplemented();
|
||||
address pc = _instructions->start() + pc_offset;
|
||||
if (HotSpotMetaspaceConstantImpl::compressed(constant)) {
|
||||
narrowKlass narrowOop = record_narrow_metadata_reference(constant, CHECK);
|
||||
TRACE_jvmci_3("relocating (narrow metaspace constant) at " PTR_FORMAT "/0x%x", p2i(pc), narrowOop);
|
||||
Unimplemented();
|
||||
} else {
|
||||
NativeMovConstReg* move = nativeMovConstReg_at(pc);
|
||||
Metadata* reference = record_metadata_reference(constant, CHECK);
|
||||
move->set_data((intptr_t) reference);
|
||||
TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(reference));
|
||||
}
|
||||
}
|
||||
|
||||
void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) {
|
||||
Unimplemented();
|
||||
address pc = _instructions->start() + pc_offset;
|
||||
NativeInstruction* inst = nativeInstruction_at(pc);
|
||||
if (inst->is_adr_aligned()) {
|
||||
address dest = _constants->start() + data_offset;
|
||||
_instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS));
|
||||
TRACE_jvmci_3("relocating at " PTR_FORMAT " (+%d) with destination at %d", p2i(pc), pc_offset, data_offset);
|
||||
} else {
|
||||
JVMCI_ERROR("unknown load or move instruction at " PTR_FORMAT, p2i(pc));
|
||||
}
|
||||
}
|
||||
|
||||
void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, TRAPS) {
|
||||
Unimplemented();
|
||||
address pc = (address) inst;
|
||||
if (inst->is_call()) {
|
||||
NativeCall* call = nativeCall_at(pc);
|
||||
call->set_destination((address) foreign_call_destination);
|
||||
_instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec());
|
||||
} else if (inst->is_jump()) {
|
||||
NativeJump* jump = nativeJump_at(pc);
|
||||
jump->set_jump_destination((address) foreign_call_destination);
|
||||
_instructions->relocate(jump->instruction_address(), runtime_call_Relocation::spec());
|
||||
} else if (inst->is_general_jump()) {
|
||||
NativeGeneralJump* jump = nativeGeneralJump_at(pc);
|
||||
jump->set_jump_destination((address) foreign_call_destination);
|
||||
_instructions->relocate(jump->instruction_address(), runtime_call_Relocation::spec());
|
||||
} else {
|
||||
JVMCI_ERROR("unknown call or jump instruction at " PTR_FORMAT, p2i(pc));
|
||||
}
|
||||
TRACE_jvmci_3("relocating (foreign call) at " PTR_FORMAT, p2i(inst));
|
||||
}
|
||||
|
||||
void CodeInstaller::pd_relocate_JavaMethod(Handle hotspot_method, jint pc_offset, TRAPS) {
|
||||
Unimplemented();
|
||||
#ifdef ASSERT
|
||||
Method* method = NULL;
|
||||
// we need to check, this might also be an unresolved method
|
||||
if (hotspot_method->is_a(HotSpotResolvedJavaMethodImpl::klass())) {
|
||||
method = getMethodFromHotSpotMethod(hotspot_method());
|
||||
}
|
||||
#endif
|
||||
switch (_next_call_type) {
|
||||
case INLINE_INVOKE:
|
||||
break;
|
||||
case INVOKEVIRTUAL:
|
||||
case INVOKEINTERFACE: {
|
||||
assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface");
|
||||
NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
|
||||
call->set_destination(SharedRuntime::get_resolve_virtual_call_stub());
|
||||
_instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc));
|
||||
break;
|
||||
}
|
||||
case INVOKESTATIC: {
|
||||
assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic");
|
||||
NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
|
||||
call->set_destination(SharedRuntime::get_resolve_static_call_stub());
|
||||
_instructions->relocate(call->instruction_address(), relocInfo::static_call_type);
|
||||
break;
|
||||
}
|
||||
case INVOKESPECIAL: {
|
||||
assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial");
|
||||
NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
|
||||
call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub());
|
||||
_instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
JVMCI_ERROR("invalid _next_call_type value");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CodeInstaller::pd_relocate_poll(address pc, jint mark, TRAPS) {
|
||||
Unimplemented();
|
||||
switch (mark) {
|
||||
case POLL_NEAR:
|
||||
JVMCI_ERROR("unimplemented");
|
||||
break;
|
||||
case POLL_FAR:
|
||||
_instructions->relocate(pc, relocInfo::poll_type);
|
||||
break;
|
||||
case POLL_RETURN_NEAR:
|
||||
JVMCI_ERROR("unimplemented");
|
||||
break;
|
||||
case POLL_RETURN_FAR:
|
||||
_instructions->relocate(pc, relocInfo::poll_return_type);
|
||||
break;
|
||||
default:
|
||||
JVMCI_ERROR("invalid mark value");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// convert JVMCI register indices (as used in oop maps) to HotSpot registers
|
||||
VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, TRAPS) {
|
||||
return NULL;
|
||||
if (jvmci_reg < RegisterImpl::number_of_registers) {
|
||||
return as_Register(jvmci_reg)->as_VMReg();
|
||||
} else {
|
||||
jint floatRegisterNumber = jvmci_reg - RegisterImpl::number_of_registers;
|
||||
if (floatRegisterNumber < FloatRegisterImpl::number_of_registers) {
|
||||
return as_FloatRegister(floatRegisterNumber)->as_VMReg();
|
||||
}
|
||||
JVMCI_ERROR_NULL("invalid register number: %d", jvmci_reg);
|
||||
}
|
||||
}
|
||||
|
||||
bool CodeInstaller::is_general_purpose_reg(VMReg hotspotRegister) {
|
||||
return false;
|
||||
return !hotspotRegister->is_FloatRegister();
|
||||
}
|
||||
|
||||
@ -136,7 +136,7 @@ void NativeMovConstReg::set_data(intptr_t x) {
|
||||
MacroAssembler::pd_patch_instruction(instruction_address(), (address)x);
|
||||
ICache::invalidate_range(instruction_address(), instruction_size);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void NativeMovConstReg::print() {
|
||||
tty->print_cr(PTR_FORMAT ": mov reg, " INTPTR_FORMAT,
|
||||
@ -208,6 +208,32 @@ void NativeJump::set_jump_destination(address dest) {
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
address NativeGeneralJump::jump_destination() const {
|
||||
NativeMovConstReg* move = nativeMovConstReg_at(instruction_address());
|
||||
address dest = (address) move->data();
|
||||
|
||||
// We use jump to self as the unresolved address which the inline
|
||||
// cache code (and relocs) know about
|
||||
|
||||
// return -1 if jump to self
|
||||
dest = (dest == (address) this) ? (address) -1 : dest;
|
||||
return dest;
|
||||
}
|
||||
|
||||
void NativeGeneralJump::set_jump_destination(address dest) {
|
||||
NativeMovConstReg* move = nativeMovConstReg_at(instruction_address());
|
||||
|
||||
// We use jump to self as the unresolved address which the inline
|
||||
// cache code (and relocs) know about
|
||||
if (dest == (address) -1) {
|
||||
dest = instruction_address();
|
||||
}
|
||||
|
||||
move->set_data((uintptr_t) dest);
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
bool NativeInstruction::is_safepoint_poll() {
|
||||
// a safepoint_poll is implemented in two steps as either
|
||||
//
|
||||
@ -249,6 +275,22 @@ bool NativeInstruction::is_ldrw_to_zr(address instr) {
|
||||
Instruction_aarch64::extract(insn, 4, 0) == 0b11111);
|
||||
}
|
||||
|
||||
bool NativeInstruction::is_general_jump() {
|
||||
if (is_movz()) {
|
||||
NativeInstruction* inst1 = nativeInstruction_at(addr_at(instruction_size * 1));
|
||||
if (inst1->is_movk()) {
|
||||
NativeInstruction* inst2 = nativeInstruction_at(addr_at(instruction_size * 2));
|
||||
if (inst2->is_movk()) {
|
||||
NativeInstruction* inst3 = nativeInstruction_at(addr_at(instruction_size * 3));
|
||||
if (inst3->is_blr()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NativeInstruction::is_movz() {
|
||||
return Instruction_aarch64::extract(int_at(0), 30, 23) == 0b10100101;
|
||||
}
|
||||
|
||||
@ -54,11 +54,22 @@ class NativeInstruction VALUE_OBJ_CLASS_SPEC {
|
||||
friend class Relocation;
|
||||
friend bool is_NativeCallTrampolineStub_at(address);
|
||||
public:
|
||||
enum { instruction_size = 4 };
|
||||
enum {
|
||||
instruction_size = 4
|
||||
};
|
||||
|
||||
juint encoding() const {
|
||||
return uint_at(0);
|
||||
}
|
||||
|
||||
bool is_blr() const { return (encoding() & 0xfffffc1f) == 0xd63f0000; }
|
||||
bool is_adr_aligned() const { return (encoding() & 0xff000000) == 0x10000000; } // adr Xn, <label>, where label is aligned to 4 bytes (address of instruction).
|
||||
|
||||
inline bool is_nop();
|
||||
inline bool is_illegal();
|
||||
inline bool is_return();
|
||||
bool is_jump();
|
||||
bool is_general_jump();
|
||||
inline bool is_jump_or_nop();
|
||||
inline bool is_cond_jump();
|
||||
bool is_safepoint_poll();
|
||||
@ -341,11 +352,15 @@ class NativeMovRegMemPatching: public NativeMovRegMem {
|
||||
// An interface for accessing/manipulating native leal instruction of form:
|
||||
// leal reg, [reg + offset]
|
||||
|
||||
class NativeLoadAddress: public NativeMovRegMem {
|
||||
static const bool has_rex = true;
|
||||
static const int rex_size = 1;
|
||||
public:
|
||||
class NativeLoadAddress: public NativeInstruction {
|
||||
enum AArch64_specific_constants {
|
||||
instruction_size = 4,
|
||||
instruction_offset = 0,
|
||||
data_offset = 0,
|
||||
next_instruction_offset = 4
|
||||
};
|
||||
|
||||
public:
|
||||
void verify();
|
||||
void print ();
|
||||
|
||||
@ -398,6 +413,10 @@ public:
|
||||
data_offset = 0,
|
||||
next_instruction_offset = 4 * 4
|
||||
};
|
||||
|
||||
address jump_destination() const;
|
||||
void set_jump_destination(address dest);
|
||||
|
||||
static void insert_unconditional(address code_pos, address entry);
|
||||
static void replace_mt_safe(address instr_addr, address code_buffer);
|
||||
static void verify();
|
||||
|
||||
@ -70,56 +70,64 @@ public class AArch64 extends Architecture {
|
||||
public static final Register r28 = new Register(28, 28, "r28", CPU);
|
||||
public static final Register r29 = new Register(29, 29, "r29", CPU);
|
||||
public static final Register r30 = new Register(30, 30, "r30", CPU);
|
||||
|
||||
/*
|
||||
* r31 is not a general purpose register, but represents either the stackpointer or the
|
||||
* zero/discard register depending on the instruction. So we represent those two uses as two
|
||||
* different registers. The register numbers are kept in sync with register_aarch64.hpp and have
|
||||
* to be sequential, hence we also need a general r31 register here, which is never used.
|
||||
*/
|
||||
public static final Register r31 = new Register(31, 31, "r31", CPU);
|
||||
public static final Register zr = new Register(32, 31, "zr", CPU);
|
||||
public static final Register sp = new Register(33, 31, "sp", CPU);
|
||||
|
||||
public static final Register lr = r30;
|
||||
public static final Register zr = r31;
|
||||
public static final Register sp = r31;
|
||||
|
||||
// @formatter:off
|
||||
public static final Register[] cpuRegisters = {
|
||||
r0, r1, r2, r3, r4, r5, r6, r7,
|
||||
r8, r9, r10, r11, r12, r13, r14, r15,
|
||||
r16, r17, r18, r19, r20, r21, r22, r23,
|
||||
r24, r25, r26, r27, r28, r29, r30, r31
|
||||
r24, r25, r26, r27, r28, r29, r30, r31,
|
||||
zr, sp
|
||||
};
|
||||
// @formatter:on
|
||||
|
||||
public static final RegisterCategory SIMD = new RegisterCategory("SIMD");
|
||||
|
||||
// Simd registers
|
||||
public static final Register v0 = new Register(32, 0, "v0", SIMD);
|
||||
public static final Register v1 = new Register(33, 1, "v1", SIMD);
|
||||
public static final Register v2 = new Register(34, 2, "v2", SIMD);
|
||||
public static final Register v3 = new Register(35, 3, "v3", SIMD);
|
||||
public static final Register v4 = new Register(36, 4, "v4", SIMD);
|
||||
public static final Register v5 = new Register(37, 5, "v5", SIMD);
|
||||
public static final Register v6 = new Register(38, 6, "v6", SIMD);
|
||||
public static final Register v7 = new Register(39, 7, "v7", SIMD);
|
||||
public static final Register v8 = new Register(40, 8, "v8", SIMD);
|
||||
public static final Register v9 = new Register(41, 9, "v9", SIMD);
|
||||
public static final Register v10 = new Register(42, 10, "v10", SIMD);
|
||||
public static final Register v11 = new Register(43, 11, "v11", SIMD);
|
||||
public static final Register v12 = new Register(44, 12, "v12", SIMD);
|
||||
public static final Register v13 = new Register(45, 13, "v13", SIMD);
|
||||
public static final Register v14 = new Register(46, 14, "v14", SIMD);
|
||||
public static final Register v15 = new Register(47, 15, "v15", SIMD);
|
||||
public static final Register v16 = new Register(48, 16, "v16", SIMD);
|
||||
public static final Register v17 = new Register(49, 17, "v17", SIMD);
|
||||
public static final Register v18 = new Register(50, 18, "v18", SIMD);
|
||||
public static final Register v19 = new Register(51, 19, "v19", SIMD);
|
||||
public static final Register v20 = new Register(52, 20, "v20", SIMD);
|
||||
public static final Register v21 = new Register(53, 21, "v21", SIMD);
|
||||
public static final Register v22 = new Register(54, 22, "v22", SIMD);
|
||||
public static final Register v23 = new Register(55, 23, "v23", SIMD);
|
||||
public static final Register v24 = new Register(56, 24, "v24", SIMD);
|
||||
public static final Register v25 = new Register(57, 25, "v25", SIMD);
|
||||
public static final Register v26 = new Register(58, 26, "v26", SIMD);
|
||||
public static final Register v27 = new Register(59, 27, "v27", SIMD);
|
||||
public static final Register v28 = new Register(60, 28, "v28", SIMD);
|
||||
public static final Register v29 = new Register(61, 29, "v29", SIMD);
|
||||
public static final Register v30 = new Register(62, 30, "v30", SIMD);
|
||||
public static final Register v31 = new Register(63, 31, "v31", SIMD);
|
||||
public static final Register v0 = new Register(34, 0, "v0", SIMD);
|
||||
public static final Register v1 = new Register(35, 1, "v1", SIMD);
|
||||
public static final Register v2 = new Register(36, 2, "v2", SIMD);
|
||||
public static final Register v3 = new Register(37, 3, "v3", SIMD);
|
||||
public static final Register v4 = new Register(38, 4, "v4", SIMD);
|
||||
public static final Register v5 = new Register(39, 5, "v5", SIMD);
|
||||
public static final Register v6 = new Register(40, 6, "v6", SIMD);
|
||||
public static final Register v7 = new Register(41, 7, "v7", SIMD);
|
||||
public static final Register v8 = new Register(42, 8, "v8", SIMD);
|
||||
public static final Register v9 = new Register(43, 9, "v9", SIMD);
|
||||
public static final Register v10 = new Register(44, 10, "v10", SIMD);
|
||||
public static final Register v11 = new Register(45, 11, "v11", SIMD);
|
||||
public static final Register v12 = new Register(46, 12, "v12", SIMD);
|
||||
public static final Register v13 = new Register(47, 13, "v13", SIMD);
|
||||
public static final Register v14 = new Register(48, 14, "v14", SIMD);
|
||||
public static final Register v15 = new Register(49, 15, "v15", SIMD);
|
||||
public static final Register v16 = new Register(50, 16, "v16", SIMD);
|
||||
public static final Register v17 = new Register(51, 17, "v17", SIMD);
|
||||
public static final Register v18 = new Register(52, 18, "v18", SIMD);
|
||||
public static final Register v19 = new Register(53, 19, "v19", SIMD);
|
||||
public static final Register v20 = new Register(54, 20, "v20", SIMD);
|
||||
public static final Register v21 = new Register(55, 21, "v21", SIMD);
|
||||
public static final Register v22 = new Register(56, 22, "v22", SIMD);
|
||||
public static final Register v23 = new Register(57, 23, "v23", SIMD);
|
||||
public static final Register v24 = new Register(58, 24, "v24", SIMD);
|
||||
public static final Register v25 = new Register(59, 25, "v25", SIMD);
|
||||
public static final Register v26 = new Register(60, 26, "v26", SIMD);
|
||||
public static final Register v27 = new Register(61, 27, "v27", SIMD);
|
||||
public static final Register v28 = new Register(62, 28, "v28", SIMD);
|
||||
public static final Register v29 = new Register(63, 29, "v29", SIMD);
|
||||
public static final Register v30 = new Register(64, 30, "v30", SIMD);
|
||||
public static final Register v31 = new Register(65, 31, "v31", SIMD);
|
||||
|
||||
// @formatter:off
|
||||
public static final Register[] simdRegisters = {
|
||||
@ -136,6 +144,7 @@ public class AArch64 extends Architecture {
|
||||
r8, r9, r10, r11, r12, r13, r14, r15,
|
||||
r16, r17, r18, r19, r20, r21, r22, r23,
|
||||
r24, r25, r26, r27, r28, r29, r30, r31,
|
||||
zr, sp,
|
||||
|
||||
v0, v1, v2, v3, v4, v5, v6, v7,
|
||||
v8, v9, v10, v11, v12, v13, v14, v15,
|
||||
|
||||
@ -31,6 +31,7 @@ import static jdk.vm.ci.aarch64.AArch64.r27;
|
||||
import static jdk.vm.ci.aarch64.AArch64.r28;
|
||||
import static jdk.vm.ci.aarch64.AArch64.r29;
|
||||
import static jdk.vm.ci.aarch64.AArch64.r3;
|
||||
import static jdk.vm.ci.aarch64.AArch64.r31;
|
||||
import static jdk.vm.ci.aarch64.AArch64.r4;
|
||||
import static jdk.vm.ci.aarch64.AArch64.r5;
|
||||
import static jdk.vm.ci.aarch64.AArch64.r6;
|
||||
@ -45,11 +46,13 @@ import static jdk.vm.ci.aarch64.AArch64.v4;
|
||||
import static jdk.vm.ci.aarch64.AArch64.v5;
|
||||
import static jdk.vm.ci.aarch64.AArch64.v6;
|
||||
import static jdk.vm.ci.aarch64.AArch64.v7;
|
||||
import static jdk.vm.ci.aarch64.AArch64.zr;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import jdk.vm.ci.aarch64.AArch64;
|
||||
@ -130,16 +133,20 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
|
||||
public static final Register threadRegister = r28;
|
||||
public static final Register fp = r29;
|
||||
|
||||
private static final Register[] reservedRegisters = {threadRegister, fp, lr, r31, zr, sp};
|
||||
|
||||
private static Register[] initAllocatable(Architecture arch, boolean reserveForHeapBase) {
|
||||
Register[] allRegisters = arch.getAvailableValueRegisters();
|
||||
Register[] registers = new Register[allRegisters.length - (reserveForHeapBase ? 5 : 4)];
|
||||
Register[] registers = new Register[allRegisters.length - reservedRegisters.length - (reserveForHeapBase ? 1 : 0)];
|
||||
List<Register> reservedRegistersList = Arrays.asList(reservedRegisters);
|
||||
|
||||
int idx = 0;
|
||||
for (Register reg : allRegisters) {
|
||||
if (reg.equals(threadRegister) || reg.equals(fp) || reg.equals(lr) || reg.equals(sp)) {
|
||||
// skip thread register, frame pointer, link register and stack pointer
|
||||
if (reservedRegistersList.contains(reg)) {
|
||||
// skip reserved registers
|
||||
continue;
|
||||
}
|
||||
assert !(reg.equals(threadRegister) || reg.equals(fp) || reg.equals(lr) || reg.equals(r31) || reg.equals(zr) || reg.equals(sp));
|
||||
if (reserveForHeapBase && reg.equals(heapBaseRegister)) {
|
||||
// skip heap base register
|
||||
continue;
|
||||
|
||||
@ -45,6 +45,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import jdk.vm.ci.code.Architecture;
|
||||
@ -119,14 +120,17 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
|
||||
*/
|
||||
private final boolean needsNativeStackHomeSpace;
|
||||
|
||||
private static final Register[] reservedRegisters = {rsp, r15};
|
||||
|
||||
private static Register[] initAllocatable(Architecture arch, boolean reserveForHeapBase) {
|
||||
Register[] allRegisters = arch.getAvailableValueRegisters();
|
||||
Register[] registers = new Register[allRegisters.length - (reserveForHeapBase ? 3 : 2)];
|
||||
Register[] registers = new Register[allRegisters.length - reservedRegisters.length - (reserveForHeapBase ? 1 : 0)];
|
||||
List<Register> reservedRegistersList = Arrays.asList(reservedRegisters);
|
||||
|
||||
int idx = 0;
|
||||
for (Register reg : allRegisters) {
|
||||
if (reg.equals(rsp) || reg.equals(r15)) {
|
||||
// skip stack pointer and thread register
|
||||
if (reservedRegistersList.contains(reg)) {
|
||||
// skip reserved registers
|
||||
continue;
|
||||
}
|
||||
if (reserveForHeapBase && reg.equals(r12)) {
|
||||
|
||||
@ -68,6 +68,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import jdk.vm.ci.code.Architecture;
|
||||
import jdk.vm.ci.code.CallingConvention;
|
||||
@ -140,14 +141,17 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
|
||||
i0, i1, i2, i3, i4, i5, i6, i7};
|
||||
// @formatter:on
|
||||
|
||||
private static final Register[] reservedRegisters = {sp, g0, g2};
|
||||
|
||||
private static Register[] initAllocatable(Architecture arch, boolean reserveForHeapBase) {
|
||||
Register[] allRegisters = arch.getAvailableValueRegisters();
|
||||
Register[] registers = new Register[allRegisters.length - (reserveForHeapBase ? 4 : 3)];
|
||||
Register[] registers = new Register[allRegisters.length - reservedRegisters.length - (reserveForHeapBase ? 1 : 0)];
|
||||
List<Register> reservedRegistersList = Arrays.asList(reservedRegisters);
|
||||
|
||||
int idx = 0;
|
||||
for (Register reg : allRegisters) {
|
||||
if (reg.equals(sp) || reg.equals(g2) || reg.equals(g0)) {
|
||||
// skip g0, stack pointer and thread register
|
||||
if (reservedRegistersList.contains(reg)) {
|
||||
// skip reserved registers
|
||||
continue;
|
||||
}
|
||||
if (reserveForHeapBase && reg.equals(g6)) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user