src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java
changeset 58650 d068b1e534de
parent 52381 7f90bc64b0fc
equal deleted inserted replaced
58649:6b6bf0de534b 58650:d068b1e534de
     1 /*
     1 /*
     2  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
   124 
   124 
   125     public static final Register heapBaseRegister = r27;
   125     public static final Register heapBaseRegister = r27;
   126     public static final Register threadRegister = r28;
   126     public static final Register threadRegister = r28;
   127     public static final Register fp = r29;
   127     public static final Register fp = r29;
   128 
   128 
   129     private static final RegisterArray reservedRegisters = new RegisterArray(rscratch1, rscratch2, threadRegister, fp, lr, r31, zr, sp);
   129     /**
   130 
   130      * The heapBaseRegister, i.e. r27, is reserved unconditionally because HotSpot does not intend
   131     private static RegisterArray initAllocatable(Architecture arch, boolean reserveForHeapBase) {
   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);
       
   138 
       
   139     private static RegisterArray initAllocatable(Architecture arch) {
   132         RegisterArray allRegisters = arch.getAvailableValueRegisters();
   140         RegisterArray allRegisters = arch.getAvailableValueRegisters();
   133         Register[] registers = new Register[allRegisters.size() - reservedRegisters.size() - (reserveForHeapBase ? 1 : 0)];
   141         Register[] registers = new Register[allRegisters.size() - reservedRegisters.size()];
   134         List<Register> reservedRegistersList = reservedRegisters.asList();
   142         List<Register> reservedRegistersList = reservedRegisters.asList();
   135 
   143 
   136         int idx = 0;
   144         int idx = 0;
   137         for (Register reg : allRegisters) {
   145         for (Register reg : allRegisters) {
   138             if (reservedRegistersList.contains(reg)) {
   146             if (reservedRegistersList.contains(reg)) {
   139                 // skip reserved registers
   147                 // skip reserved registers
   140                 continue;
   148                 continue;
   141             }
   149             }
   142             assert !(reg.equals(threadRegister) || reg.equals(fp) || reg.equals(lr) || reg.equals(r31) || reg.equals(zr) || reg.equals(sp));
   150             assert !(reg.equals(heapBaseRegister) || reg.equals(threadRegister) || reg.equals(fp) || reg.equals(lr) || reg.equals(r31) || reg.equals(zr) || reg.equals(sp)) : reg;
   143             if (reserveForHeapBase && reg.equals(heapBaseRegister)) {
       
   144                 // skip heap base register
       
   145                 continue;
       
   146             }
       
   147 
       
   148             registers[idx++] = reg;
   151             registers[idx++] = reg;
   149         }
   152         }
   150 
   153 
   151         assert idx == registers.length;
   154         assert idx == registers.length;
   152         return new RegisterArray(registers);
   155         return new RegisterArray(registers);
   153     }
   156     }
   154 
   157 
   155     public AArch64HotSpotRegisterConfig(TargetDescription target, boolean useCompressedOops) {
   158     public AArch64HotSpotRegisterConfig(TargetDescription target) {
   156         this(target, initAllocatable(target.arch, useCompressedOops));
   159         this(target, initAllocatable(target.arch));
   157         assert callerSaved.size() >= allocatable.size();
   160         assert callerSaved.size() >= allocatable.size();
   158     }
   161     }
   159 
   162 
   160     public AArch64HotSpotRegisterConfig(TargetDescription target, RegisterArray allocatable) {
   163     public AArch64HotSpotRegisterConfig(TargetDescription target, RegisterArray allocatable) {
   161         this.target = target;
   164         this.target = target;