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 } 115 116 void SharkDecacher::process_pc_slot(int offset) { 117 // Record the PC 118 builder()->CreateStore( 119 builder()->code_buffer_address(pc_offset()), 120 stack()->slot_addr(offset)); 121 } 122 123 void SharkDecacher::start_locals() { 124 // Create the array we'll record our local variables in 125 _locarray = new GrowableArray<ScopeValue*>(max_locals());} 126 127 void SharkDecacher::process_local_slot(int index, 128 SharkValue** addr, 129 int offset) { 130 SharkValue *value = *addr; 131 132 // Write the value to the frame if necessary 133 if (local_slot_needs_write(index, value)) { 134 write_value_to_frame( 135 SharkType::to_stackType(value->basic_type()), 136 value->generic_value(), 137 adjusted_offset(value, offset)); 138 } 139 140 // Record the value in the oopmap if necessary 141 if (local_slot_needs_oopmap(index, value)) { 142 oopmap()->set_oop(slot2reg(offset)); 143 } 144 145 // Record the value in the debuginfo if necessary 146 if (local_slot_needs_debuginfo(index, value)) { 147 locarray()->append(slot2lv(offset, local_location_type(index, addr))); 148 } 149 } 150 151 void SharkDecacher::end_frame() { 152 // Record the scope 153 methodHandle null_mh; 154 debug_info()->describe_scope( 155 pc_offset(), 156 null_mh, 157 target(), 158 bci(), 159 true, 160 false, 161 false, 162 false, 163 debug_info()->create_scope_values(locarray()), 164 debug_info()->create_scope_values(exparray()), 165 debug_info()->create_monitor_values(monarray())); 166 167 // Finish recording the debug information 168 debug_info()->end_safepoint(pc_offset()); 169 } 170 171 void SharkCacher::process_stack_slot(int index, 172 SharkValue** addr, 173 int offset) { 174 SharkValue *value = *addr; 175 176 // Read the value from the frame if necessary 177 if (stack_slot_needs_read(index, value)) { 178 *addr = SharkValue::create_generic( 179 value->type(), 180 read_value_from_frame( 181 SharkType::to_stackType(value->basic_type()), 182 adjusted_offset(value, offset)), 183 value->zero_checked()); 184 } 185 } 186 187 void SharkOSREntryCacher::process_monitor(int index, 188 int box_offset, 189 int obj_offset) { 190 // Copy the monitor from the OSR buffer to the frame 191 int src_offset = max_locals() + index * 2; 192 builder()->CreateStore( 193 builder()->CreateLoad( 194 CreateAddressOfOSRBufEntry(src_offset, SharkType::intptr_type())), 195 stack()->slot_addr(box_offset, SharkType::intptr_type())); 196 builder()->CreateStore( 197 builder()->CreateLoad( 198 CreateAddressOfOSRBufEntry(src_offset + 1, SharkType::oop_type())), 199 stack()->slot_addr(obj_offset, SharkType::oop_type())); 200 } 201 202 void SharkCacher::process_oop_tmp_slot(Value** value, int offset) { 203 // Cache the temporary oop 204 if (*value) 205 *value = read_value_from_frame(SharkType::oop_type(), offset); 206 } 207 208 void SharkCacher::process_method_slot(Value** value, int offset) { 209 // Cache the method pointer 210 *value = read_value_from_frame(SharkType::Method_type(), offset); 211 } 212 213 void SharkFunctionEntryCacher::process_method_slot(Value** value, int offset) { 214 // "Cache" the method pointer 215 *value = method(); 216 } 217 218 void SharkCacher::process_local_slot(int index, 219 SharkValue** addr, 220 int offset) { 221 SharkValue *value = *addr; 222 223 // Read the value from the frame if necessary 224 if (local_slot_needs_read(index, value)) { 225 *addr = SharkValue::create_generic( 226 value->type(), 227 read_value_from_frame( 228 SharkType::to_stackType(value->basic_type()), 229 adjusted_offset(value, offset)), 230 value->zero_checked()); 231 } 232 } 233 234 Value* SharkOSREntryCacher::CreateAddressOfOSRBufEntry(int offset, 235 Type* type) { 236 Value *result = builder()->CreateStructGEP(osr_buf(), offset); 237 if (type != SharkType::intptr_type()) 238 result = builder()->CreateBitCast(result, PointerType::getUnqual(type)); 239 return result; 240 } 241 242 void SharkOSREntryCacher::process_local_slot(int index, 243 SharkValue** addr, 244 int offset) { 245 SharkValue *value = *addr; 246 247 // Read the value from the OSR buffer if necessary 248 if (local_slot_needs_read(index, value)) { 249 *addr = SharkValue::create_generic( 250 value->type(), 251 builder()->CreateLoad( 252 CreateAddressOfOSRBufEntry( 253 adjusted_offset(value, max_locals() - 1 - index), 254 SharkType::to_stackType(value->basic_type()))), 255 value->zero_checked()); 256 } 257 } 258 259 void SharkDecacher::write_value_to_frame(Type* type, 260 Value* value, 261 int offset) { 262 builder()->CreateStore(value, stack()->slot_addr(offset, type)); 263 } 264 265 Value* SharkCacher::read_value_from_frame(Type* type, int offset) { 266 return builder()->CreateLoad(stack()->slot_addr(offset, type)); 267 }