|
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 } |