1 /* 2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 3 * Copyright 2008, 2009 Red Hat, Inc. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 #include "precompiled.hpp" 27 #include "ci/ciMethod.hpp" 28 #include "code/debugInfoRec.hpp" 29 #include "shark/llvmValue.hpp" 30 #include "shark/sharkBuilder.hpp" 31 #include "shark/sharkCacheDecache.hpp" 32 #include "shark/sharkFunction.hpp" 33 #include "shark/sharkState.hpp" 34 35 using namespace llvm; 36 37 void SharkDecacher::start_frame() { 38 // Start recording the debug information 39 _pc_offset = code_buffer()->create_unique_offset(); 40 _oopmap = new OopMap( 41 oopmap_slot_munge(stack()->oopmap_frame_size()), 42 oopmap_slot_munge(arg_size())); 43 debug_info()->add_safepoint(pc_offset(), oopmap()); 44 } 45 46 void SharkDecacher::start_stack(int stack_depth) { 47 // Create the array we'll record our stack slots in 48 _exparray = new GrowableArray<ScopeValue*>(stack_depth); 49 50 // Set the stack pointer 51 stack()->CreateStoreStackPointer( 52 builder()->CreatePtrToInt( 53 stack()->slot_addr( 54 stack()->stack_slots_offset() + max_stack() - stack_depth), 55 SharkType::intptr_type())); 56 } 57 58 void SharkDecacher::process_stack_slot(int index, 59 SharkValue** addr, 60 int offset) { 61 SharkValue *value = *addr; 62 63 // Write the value to the frame if necessary 64 if (stack_slot_needs_write(index, value)) { 65 write_value_to_frame( 66 SharkType::to_stackType(value->basic_type()), 67 value->generic_value(), 68 adjusted_offset(value, offset)); 69 } 70 71 // Record the value in the oopmap if necessary 72 if (stack_slot_needs_oopmap(index, value)) { 73 oopmap()->set_oop(slot2reg(offset)); 74 } 75 76 // Record the value in the debuginfo if necessary 77 if (stack_slot_needs_debuginfo(index, value)) { 78 exparray()->append(slot2lv(offset, stack_location_type(index, addr))); 79 } 80 } 81 82 void SharkDecacher::start_monitors(int num_monitors) { 83 // Create the array we'll record our monitors in 84 _monarray = new GrowableArray<MonitorValue*>(num_monitors); 85 } 86 87 void SharkDecacher::process_monitor(int index, int box_offset, int obj_offset) { 88 oopmap()->set_oop(slot2reg(obj_offset)); 89 90 monarray()->append(new MonitorValue( 91 slot2lv (obj_offset, Location::oop), 92 slot2loc(box_offset, Location::normal))); 93 } 94 95 void SharkDecacher::process_oop_tmp_slot(Value** value, int offset) { 96 // Decache the temporary oop slot 97 if (*value) { 98 write_value_to_frame( 99 SharkType::oop_type(), 100 *value, 101 offset); 102 103 oopmap()->set_oop(slot2reg(offset)); 104 } 105 } 106 107 void SharkDecacher::process_method_slot(Value** value, int offset) { 108 // Decache the method pointer 109 write_value_to_frame( 110 SharkType::Method*_type(), 111 *value, 112 offset); 113 114 oopmap()->set_oop(slot2reg(offset)); 115 } 116 117 void SharkDecacher::process_pc_slot(int offset) { 118 // Record the PC 119 builder()->CreateStore( 120 builder()->code_buffer_address(pc_offset()), 121 stack()->slot_addr(offset)); 122 } 123 124 void SharkDecacher::start_locals() { 125 // Create the array we'll record our local variables in 126 _locarray = new GrowableArray<ScopeValue*>(max_locals());} 127 128 void SharkDecacher::process_local_slot(int index, 129 SharkValue** addr, 130 int offset) { 131 SharkValue *value = *addr; 132 133 // Write the value to the frame if necessary 134 if (local_slot_needs_write(index, value)) { 135 write_value_to_frame( 136 SharkType::to_stackType(value->basic_type()), 137 value->generic_value(), 138 adjusted_offset(value, offset)); 139 } 140 141 // Record the value in the oopmap if necessary 142 if (local_slot_needs_oopmap(index, value)) { 143 oopmap()->set_oop(slot2reg(offset)); 144 } 145 146 // Record the value in the debuginfo if necessary 147 if (local_slot_needs_debuginfo(index, value)) { 148 locarray()->append(slot2lv(offset, local_location_type(index, addr))); 149 } 150 } 151 152 void SharkDecacher::end_frame() { 153 // Record the scope 154 debug_info()->describe_scope( 155 pc_offset(), 156 target(), 157 bci(), 158 true, 159 false, 160 false, 161 debug_info()->create_scope_values(locarray()), 162 debug_info()->create_scope_values(exparray()), 163 debug_info()->create_monitor_values(monarray())); 164 165 // Finish recording the debug information 166 debug_info()->end_safepoint(pc_offset()); 167 } 168 169 void SharkCacher::process_stack_slot(int index, 170 SharkValue** addr, 171 int offset) { 172 SharkValue *value = *addr; 173 174 // Read the value from the frame if necessary 175 if (stack_slot_needs_read(index, value)) { 176 *addr = SharkValue::create_generic( 177 value->type(), 178 read_value_from_frame( 179 SharkType::to_stackType(value->basic_type()), 180 adjusted_offset(value, offset)), 181 value->zero_checked()); 182 } 183 } 184 185 void SharkOSREntryCacher::process_monitor(int index, 186 int box_offset, 187 int obj_offset) { 188 // Copy the monitor from the OSR buffer to the frame 189 int src_offset = max_locals() + index * 2; 190 builder()->CreateStore( 191 builder()->CreateLoad( 192 CreateAddressOfOSRBufEntry(src_offset, SharkType::intptr_type())), 193 stack()->slot_addr(box_offset, SharkType::intptr_type())); 194 builder()->CreateStore( 195 builder()->CreateLoad( 196 CreateAddressOfOSRBufEntry(src_offset + 1, SharkType::oop_type())), 197 stack()->slot_addr(obj_offset, SharkType::oop_type())); 198 } 199 200 void SharkCacher::process_oop_tmp_slot(Value** value, int offset) { 201 // Cache the temporary oop 202 if (*value) 203 *value = read_value_from_frame(SharkType::oop_type(), offset); 204 } 205 206 void SharkCacher::process_method_slot(Value** value, int offset) { 207 // Cache the method pointer 208 *value = read_value_from_frame(SharkType::Method*_type(), offset); 209 } 210 211 void SharkFunctionEntryCacher::process_method_slot(Value** value, int offset) { 212 // "Cache" the method pointer 213 *value = method(); 214 } 215 216 void SharkCacher::process_local_slot(int index, 217 SharkValue** addr, 218 int offset) { 219 SharkValue *value = *addr; 220 221 // Read the value from the frame if necessary 222 if (local_slot_needs_read(index, value)) { 223 *addr = SharkValue::create_generic( 224 value->type(), 225 read_value_from_frame( 226 SharkType::to_stackType(value->basic_type()), 227 adjusted_offset(value, offset)), 228 value->zero_checked()); 229 } 230 } 231 232 Value* SharkOSREntryCacher::CreateAddressOfOSRBufEntry(int offset, 233 const Type* type) { 234 Value *result = builder()->CreateStructGEP(osr_buf(), offset); 235 if (type != SharkType::intptr_type()) 236 result = builder()->CreateBitCast(result, PointerType::getUnqual(type)); 237 return result; 238 } 239 240 void SharkOSREntryCacher::process_local_slot(int index, 241 SharkValue** addr, 242 int offset) { 243 SharkValue *value = *addr; 244 245 // Read the value from the OSR buffer if necessary 246 if (local_slot_needs_read(index, value)) { 247 *addr = SharkValue::create_generic( 248 value->type(), 249 builder()->CreateLoad( 250 CreateAddressOfOSRBufEntry( 251 adjusted_offset(value, max_locals() - 1 - index), 252 SharkType::to_stackType(value->basic_type()))), 253 value->zero_checked()); 254 } 255 } 256 257 void SharkDecacher::write_value_to_frame(const Type* type, 258 Value* value, 259 int offset) { 260 builder()->CreateStore(value, stack()->slot_addr(offset, type)); 261 } 262 263 Value* SharkCacher::read_value_from_frame(const Type* type, int offset) { 264 return builder()->CreateLoad(stack()->slot_addr(offset, type)); 265 }