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