1 /* 2 * Copyright (c) 1999, 2007, 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 "incls/_precompiled.incl" 27 #include "incls/_sharkCacheDecache.cpp.incl" 28 29 using namespace llvm; 30 31 void SharkDecacher::start_frame() { 32 // Start recording the debug information 33 _pc_offset = code_buffer()->create_unique_offset(); 34 _oopmap = new OopMap( 35 oopmap_slot_munge(stack()->oopmap_frame_size()), 36 oopmap_slot_munge(arg_size())); 37 debug_info()->add_safepoint(pc_offset(), oopmap()); 38 } 39 40 void SharkDecacher::start_stack(int stack_depth) { 41 // Create the array we'll record our stack slots in 42 _exparray = new GrowableArray<ScopeValue*>(stack_depth); 43 44 // Set the stack pointer 45 stack()->CreateStoreStackPointer( 46 builder()->CreatePtrToInt( 47 stack()->slot_addr( 48 stack()->stack_slots_offset() + max_stack() - stack_depth), 49 SharkType::intptr_type())); 50 } 51 52 void SharkDecacher::process_stack_slot(int index, 53 SharkValue** addr, 54 int offset) { 55 SharkValue *value = *addr; 56 57 // Write the value to the frame if necessary 58 if (stack_slot_needs_write(index, value)) { 59 write_value_to_frame( 60 SharkType::to_stackType(value->basic_type()), 61 value->generic_value(), 62 adjusted_offset(value, offset)); 63 } 64 65 // Record the value in the oopmap if necessary 66 if (stack_slot_needs_oopmap(index, value)) { 67 oopmap()->set_oop(slot2reg(offset)); 68 } 69 70 // Record the value in the debuginfo if necessary 71 if (stack_slot_needs_debuginfo(index, value)) { 72 exparray()->append(slot2lv(offset, stack_location_type(index, addr))); 73 } 74 } 75 76 void SharkDecacher::start_monitors(int num_monitors) { 77 // Create the array we'll record our monitors in 78 _monarray = new GrowableArray<MonitorValue*>(num_monitors); 79 } 80 81 void SharkDecacher::process_monitor(int index, int box_offset, int obj_offset) { 82 oopmap()->set_oop(slot2reg(obj_offset)); 83 84 monarray()->append(new MonitorValue( 85 slot2lv (obj_offset, Location::oop), 86 slot2loc(box_offset, Location::normal))); 87 } 88 89 void SharkDecacher::process_oop_tmp_slot(Value** value, int offset) { 90 // Decache the temporary oop slot 91 if (*value) { 92 write_value_to_frame( 93 SharkType::oop_type(), 94 *value, 95 offset); 96 97 oopmap()->set_oop(slot2reg(offset)); 98 } 99 } 100 101 void SharkDecacher::process_method_slot(Value** value, int offset) { 102 // Decache the method pointer 103 write_value_to_frame( 104 SharkType::methodOop_type(), 105 *value, 106 offset); 107 108 oopmap()->set_oop(slot2reg(offset)); 109 } 110 111 void SharkDecacher::process_pc_slot(int offset) { 112 // Record the PC 113 builder()->CreateStore( 114 builder()->code_buffer_address(pc_offset()), 115 stack()->slot_addr(offset)); 116 } 117 118 void SharkDecacher::start_locals() { 119 // Create the array we'll record our local variables in 120 _locarray = new GrowableArray<ScopeValue*>(max_locals());} 121 122 void SharkDecacher::process_local_slot(int index, 123 SharkValue** addr, 124 int offset) { 125 SharkValue *value = *addr; 126 127 // Write the value to the frame if necessary 128 if (local_slot_needs_write(index, value)) { 129 write_value_to_frame( 130 SharkType::to_stackType(value->basic_type()), 131 value->generic_value(), 132 adjusted_offset(value, offset)); 133 } 134 135 // Record the value in the oopmap if necessary 136 if (local_slot_needs_oopmap(index, value)) { 137 oopmap()->set_oop(slot2reg(offset)); 138 } 139 140 // Record the value in the debuginfo if necessary 141 if (local_slot_needs_debuginfo(index, value)) { 142 locarray()->append(slot2lv(offset, local_location_type(index, addr))); 143 } 144 } 145 146 void SharkDecacher::end_frame() { 147 // Record the scope 148 debug_info()->describe_scope( 149 pc_offset(), 150 target(), 151 bci(), 152 true, 153 false, 154 false, 155 debug_info()->create_scope_values(locarray()), 156 debug_info()->create_scope_values(exparray()), 157 debug_info()->create_monitor_values(monarray())); 158 159 // Finish recording the debug information 160 debug_info()->end_safepoint(pc_offset()); 161 } 162 163 void SharkCacher::process_stack_slot(int index, 164 SharkValue** addr, 165 int offset) { 166 SharkValue *value = *addr; 167 168 // Read the value from the frame if necessary 169 if (stack_slot_needs_read(index, value)) { 170 *addr = SharkValue::create_generic( 171 value->type(), 172 read_value_from_frame( 173 SharkType::to_stackType(value->basic_type()), 174 adjusted_offset(value, offset)), 175 value->zero_checked()); 176 } 177 } 178 179 void SharkOSREntryCacher::process_monitor(int index, 180 int box_offset, 181 int obj_offset) { 182 // Copy the monitor from the OSR buffer to the frame 183 int src_offset = max_locals() + index * 2; 184 builder()->CreateStore( 185 builder()->CreateLoad( 186 CreateAddressOfOSRBufEntry(src_offset, SharkType::intptr_type())), 187 stack()->slot_addr(box_offset, SharkType::intptr_type())); 188 builder()->CreateStore( 189 builder()->CreateLoad( 190 CreateAddressOfOSRBufEntry(src_offset + 1, SharkType::oop_type())), 191 stack()->slot_addr(obj_offset, SharkType::oop_type())); 192 } 193 194 void SharkCacher::process_oop_tmp_slot(Value** value, int offset) { 195 // Cache the temporary oop 196 if (*value) 197 *value = read_value_from_frame(SharkType::oop_type(), offset); 198 } 199 200 void SharkCacher::process_method_slot(Value** value, int offset) { 201 // Cache the method pointer 202 *value = read_value_from_frame(SharkType::methodOop_type(), offset); 203 } 204 205 void SharkFunctionEntryCacher::process_method_slot(Value** value, int offset) { 206 // "Cache" the method pointer 207 *value = method(); 208 } 209 210 void SharkCacher::process_local_slot(int index, 211 SharkValue** addr, 212 int offset) { 213 SharkValue *value = *addr; 214 215 // Read the value from the frame if necessary 216 if (local_slot_needs_read(index, value)) { 217 *addr = SharkValue::create_generic( 218 value->type(), 219 read_value_from_frame( 220 SharkType::to_stackType(value->basic_type()), 221 adjusted_offset(value, offset)), 222 value->zero_checked()); 223 } 224 } 225 226 Value* SharkOSREntryCacher::CreateAddressOfOSRBufEntry(int offset, 227 const Type* type) { 228 Value *result = builder()->CreateStructGEP(osr_buf(), offset); 229 if (type != SharkType::intptr_type()) 230 result = builder()->CreateBitCast(result, PointerType::getUnqual(type)); 231 return result; 232 } 233 234 void SharkOSREntryCacher::process_local_slot(int index, 235 SharkValue** addr, 236 int offset) { 237 SharkValue *value = *addr; 238 239 // Read the value from the OSR buffer if necessary 240 if (local_slot_needs_read(index, value)) { 241 *addr = SharkValue::create_generic( 242 value->type(), 243 builder()->CreateLoad( 244 CreateAddressOfOSRBufEntry( 245 adjusted_offset(value, max_locals() - 1 - index), 246 SharkType::to_stackType(value->basic_type()))), 247 value->zero_checked()); 248 } 249 } 250 251 void SharkDecacher::write_value_to_frame(const Type* type, 252 Value* value, 253 int offset) { 254 builder()->CreateStore(value, stack()->slot_addr(offset, type)); 255 } 256 257 Value* SharkCacher::read_value_from_frame(const Type* type, int offset) { 258 return builder()->CreateLoad(stack()->slot_addr(offset, type)); 259 }