1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef ART_COMPILER_UTILS_ARM_JNI_MACRO_ASSEMBLER_ARM_VIXL_H_ 18#define ART_COMPILER_UTILS_ARM_JNI_MACRO_ASSEMBLER_ARM_VIXL_H_ 19 20#include "base/arena_containers.h" 21#include "base/logging.h" 22#include "constants_arm.h" 23#include "offsets.h" 24#include "utils/arm/assembler_arm_shared.h" 25#include "utils/arm/assembler_arm_vixl.h" 26#include "utils/arm/managed_register_arm.h" 27#include "utils/assembler.h" 28#include "utils/jni_macro_assembler.h" 29 30namespace art { 31namespace arm { 32 33class ArmVIXLJNIMacroAssembler FINAL 34 : public JNIMacroAssemblerFwd<ArmVIXLAssembler, PointerSize::k32> { 35 private: 36 class ArmException; 37 public: 38 explicit ArmVIXLJNIMacroAssembler(ArenaAllocator* arena) 39 : JNIMacroAssemblerFwd(arena), 40 exception_blocks_(arena->Adapter(kArenaAllocAssembler)) {} 41 42 virtual ~ArmVIXLJNIMacroAssembler() {} 43 void FinalizeCode() OVERRIDE; 44 45 // 46 // Overridden common assembler high-level functionality 47 // 48 49 // Emit code that will create an activation on the stack. 50 void BuildFrame(size_t frame_size, 51 ManagedRegister method_reg, 52 ArrayRef<const ManagedRegister> callee_save_regs, 53 const ManagedRegisterEntrySpills& entry_spills) OVERRIDE; 54 55 // Emit code that will remove an activation from the stack. 56 void RemoveFrame(size_t frame_size, 57 ArrayRef<const ManagedRegister> callee_save_regs) OVERRIDE; 58 59 void IncreaseFrameSize(size_t adjust) OVERRIDE; 60 void DecreaseFrameSize(size_t adjust) OVERRIDE; 61 62 // Store routines. 63 void Store(FrameOffset offs, ManagedRegister src, size_t size) OVERRIDE; 64 void StoreRef(FrameOffset dest, ManagedRegister src) OVERRIDE; 65 void StoreRawPtr(FrameOffset dest, ManagedRegister src) OVERRIDE; 66 67 void StoreImmediateToFrame(FrameOffset dest, uint32_t imm, ManagedRegister scratch) OVERRIDE; 68 69 void StoreStackOffsetToThread(ThreadOffset32 thr_offs, 70 FrameOffset fr_offs, 71 ManagedRegister scratch) OVERRIDE; 72 73 void StoreStackPointerToThread(ThreadOffset32 thr_offs) OVERRIDE; 74 75 void StoreSpanning(FrameOffset dest, 76 ManagedRegister src, 77 FrameOffset in_off, 78 ManagedRegister scratch) OVERRIDE; 79 80 // Load routines. 81 void Load(ManagedRegister dest, FrameOffset src, size_t size) OVERRIDE; 82 83 void LoadFromThread(ManagedRegister dest, 84 ThreadOffset32 src, 85 size_t size) OVERRIDE; 86 87 void LoadRef(ManagedRegister dest, FrameOffset src) OVERRIDE; 88 89 void LoadRef(ManagedRegister dest, 90 ManagedRegister base, 91 MemberOffset offs, 92 bool unpoison_reference) OVERRIDE; 93 94 void LoadRawPtr(ManagedRegister dest, ManagedRegister base, Offset offs) OVERRIDE; 95 96 void LoadRawPtrFromThread(ManagedRegister dest, ThreadOffset32 offs) OVERRIDE; 97 98 // Copying routines. 99 void Move(ManagedRegister dest, ManagedRegister src, size_t size) OVERRIDE; 100 101 void CopyRawPtrFromThread(FrameOffset fr_offs, 102 ThreadOffset32 thr_offs, 103 ManagedRegister scratch) OVERRIDE; 104 105 void CopyRawPtrToThread(ThreadOffset32 thr_offs, 106 FrameOffset fr_offs, 107 ManagedRegister scratch) OVERRIDE; 108 109 void CopyRef(FrameOffset dest, FrameOffset src, ManagedRegister scratch) OVERRIDE; 110 111 void Copy(FrameOffset dest, FrameOffset src, ManagedRegister scratch, size_t size) OVERRIDE; 112 113 void Copy(FrameOffset dest, 114 ManagedRegister src_base, 115 Offset src_offset, 116 ManagedRegister scratch, 117 size_t size) OVERRIDE; 118 119 void Copy(ManagedRegister dest_base, 120 Offset dest_offset, 121 FrameOffset src, 122 ManagedRegister scratch, 123 size_t size) OVERRIDE; 124 125 void Copy(FrameOffset dest, 126 FrameOffset src_base, 127 Offset src_offset, 128 ManagedRegister scratch, 129 size_t size) OVERRIDE; 130 131 void Copy(ManagedRegister dest, 132 Offset dest_offset, 133 ManagedRegister src, 134 Offset src_offset, 135 ManagedRegister scratch, 136 size_t size) OVERRIDE; 137 138 void Copy(FrameOffset dest, 139 Offset dest_offset, 140 FrameOffset src, 141 Offset src_offset, 142 ManagedRegister scratch, 143 size_t size) OVERRIDE; 144 145 // Sign extension. 146 void SignExtend(ManagedRegister mreg, size_t size) OVERRIDE; 147 148 // Zero extension. 149 void ZeroExtend(ManagedRegister mreg, size_t size) OVERRIDE; 150 151 // Exploit fast access in managed code to Thread::Current(). 152 void GetCurrentThread(ManagedRegister mtr) OVERRIDE; 153 void GetCurrentThread(FrameOffset dest_offset, 154 ManagedRegister scratch) OVERRIDE; 155 156 // Set up out_reg to hold a Object** into the handle scope, or to be null if the 157 // value is null and null_allowed. in_reg holds a possibly stale reference 158 // that can be used to avoid loading the handle scope entry to see if the value is 159 // null. 160 void CreateHandleScopeEntry(ManagedRegister out_reg, 161 FrameOffset handlescope_offset, 162 ManagedRegister in_reg, 163 bool null_allowed) OVERRIDE; 164 165 // Set up out_off to hold a Object** into the handle scope, or to be null if the 166 // value is null and null_allowed. 167 void CreateHandleScopeEntry(FrameOffset out_off, 168 FrameOffset handlescope_offset, 169 ManagedRegister scratch, 170 bool null_allowed) OVERRIDE; 171 172 // src holds a handle scope entry (Object**) load this into dst. 173 void LoadReferenceFromHandleScope(ManagedRegister dst, 174 ManagedRegister src) OVERRIDE; 175 176 // Heap::VerifyObject on src. In some cases (such as a reference to this) we 177 // know that src may not be null. 178 void VerifyObject(ManagedRegister src, bool could_be_null) OVERRIDE; 179 void VerifyObject(FrameOffset src, bool could_be_null) OVERRIDE; 180 181 // Call to address held at [base+offset]. 182 void Call(ManagedRegister base, Offset offset, ManagedRegister scratch) OVERRIDE; 183 void Call(FrameOffset base, Offset offset, ManagedRegister scratch) OVERRIDE; 184 void CallFromThread(ThreadOffset32 offset, ManagedRegister scratch) OVERRIDE; 185 186 // Generate code to check if Thread::Current()->exception_ is non-null 187 // and branch to a ExceptionSlowPath if it is. 188 void ExceptionPoll(ManagedRegister scratch, size_t stack_adjust); 189 190 // Create a new label that can be used with Jump/Bind calls. 191 std::unique_ptr<JNIMacroLabel> CreateLabel() OVERRIDE; 192 // Emit an unconditional jump to the label. 193 void Jump(JNIMacroLabel* label) OVERRIDE; 194 // Emit a conditional jump to the label by applying a unary condition test to the register. 195 void Jump(JNIMacroLabel* label, JNIMacroUnaryCondition cond, ManagedRegister test) OVERRIDE; 196 // Code at this offset will serve as the target for the Jump call. 197 void Bind(JNIMacroLabel* label) OVERRIDE; 198 199 void MemoryBarrier(ManagedRegister scratch) OVERRIDE; 200 201 void EmitExceptionPoll(ArmVIXLJNIMacroAssembler::ArmException *exception); 202 void Load(ArmManagedRegister dest, vixl32::Register base, int32_t offset, size_t size); 203 204 private: 205 class ArmException { 206 private: 207 ArmException(ArmManagedRegister scratch, size_t stack_adjust) 208 : scratch_(scratch), stack_adjust_(stack_adjust) {} 209 210 vixl32::Label* Entry() { return &exception_entry_; } 211 212 // Register used for passing Thread::Current()->exception_ . 213 const ArmManagedRegister scratch_; 214 215 // Stack adjust for ExceptionPool. 216 const size_t stack_adjust_; 217 218 vixl32::Label exception_entry_; 219 220 friend class ArmVIXLJNIMacroAssembler; 221 DISALLOW_COPY_AND_ASSIGN(ArmException); 222 }; 223 224 // List of exception blocks to generate at the end of the code cache. 225 ArenaVector<std::unique_ptr<ArmVIXLJNIMacroAssembler::ArmException>> exception_blocks_; 226 // Used for testing. 227 friend class ArmVIXLAssemblerTest_VixlLoadFromOffset_Test; 228 friend class ArmVIXLAssemblerTest_VixlStoreToOffset_Test; 229}; 230 231class ArmVIXLJNIMacroLabel FINAL 232 : public JNIMacroLabelCommon<ArmVIXLJNIMacroLabel, 233 vixl32::Label, 234 kArm> { 235 public: 236 vixl32::Label* AsArm() { 237 return AsPlatformLabel(); 238 } 239}; 240 241} // namespace arm 242} // namespace art 243 244#endif // ART_COMPILER_UTILS_ARM_JNI_MACRO_ASSEMBLER_ARM_VIXL_H_ 245