comparison src/share/vm/shark/sharkStack.hpp @ 1692:d2ede61b7a12

6976186: integrate Shark HotSpot changes Summary: Shark is a JIT compiler for Zero that uses the LLVM compiler infrastructure. Reviewed-by: kvn, twisti Contributed-by: Gary Benson <gbenson@redhat.com>
author twisti
date Wed, 11 Aug 2010 05:51:21 -0700
parents
children f95d63e2154a
comparison
equal deleted inserted replaced
1691:4a665be40fd3 1692:d2ede61b7a12
1 /*
2 * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
3 * Copyright 2008, 2009, 2010 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 class SharkFunction;
27 class SharkNativeWrapper;
28 class SharkStackWithNormalFrame;
29 class SharkStackWithNativeFrame;
30
31 class SharkStack : public SharkCompileInvariants {
32 public:
33 static SharkStack* CreateBuildAndPushFrame(
34 SharkFunction* function, llvm::Value* method);
35 static SharkStack* CreateBuildAndPushFrame(
36 SharkNativeWrapper* wrapper, llvm::Value* method);
37
38 protected:
39 SharkStack(const SharkCompileInvariants* parent)
40 : SharkCompileInvariants(parent) {}
41
42 protected:
43 void initialize(llvm::Value* method);
44
45 protected:
46 void CreateStackOverflowCheck(llvm::Value* sp);
47
48 // Properties of the method being compiled
49 protected:
50 virtual int arg_size() const = 0;
51 virtual int max_locals() const = 0;
52 virtual int max_stack() const = 0;
53 virtual int max_monitors() const = 0;
54
55 // BasicBlock creation
56 protected:
57 virtual llvm::BasicBlock* CreateBlock(const char* name = "") const = 0;
58
59 // Interpreter entry point for bailouts
60 protected:
61 virtual address interpreter_entry_point() const = 0;
62
63 // Interface with the Zero stack
64 private:
65 llvm::Value* zero_stack() const {
66 return builder()->CreateAddressOfStructEntry(
67 thread(),
68 JavaThread::zero_stack_offset(),
69 SharkType::zeroStack_type(),
70 "zero_stack");
71 }
72 llvm::Value* stack_base() const {
73 return builder()->CreateValueOfStructEntry(
74 zero_stack(),
75 ZeroStack::base_offset(),
76 SharkType::intptr_type(),
77 "stack_base");
78 }
79 llvm::Value* stack_pointer_addr() const {
80 return builder()->CreateAddressOfStructEntry(
81 zero_stack(),
82 ZeroStack::sp_offset(),
83 llvm::PointerType::getUnqual(SharkType::intptr_type()),
84 "stack_pointer_addr");
85 }
86 llvm::Value* frame_pointer_addr() const {
87 return builder()->CreateAddressOfStructEntry(
88 thread(),
89 JavaThread::top_zero_frame_offset(),
90 llvm::PointerType::getUnqual(SharkType::intptr_type()),
91 "frame_pointer_addr");
92 }
93
94 public:
95 llvm::LoadInst* CreateLoadStackPointer(const char *name = "") {
96 return builder()->CreateLoad(stack_pointer_addr(), name);
97 }
98 llvm::StoreInst* CreateStoreStackPointer(llvm::Value* value) {
99 return builder()->CreateStore(value, stack_pointer_addr());
100 }
101 llvm::LoadInst* CreateLoadFramePointer(const char *name = "") {
102 return builder()->CreateLoad(frame_pointer_addr(), name);
103 }
104 llvm::StoreInst* CreateStoreFramePointer(llvm::Value* value) {
105 return builder()->CreateStore(value, frame_pointer_addr());
106 }
107 llvm::Value* CreatePopFrame(int result_slots);
108
109 // Interface with the frame anchor
110 private:
111 llvm::Value* last_Java_sp_addr() const {
112 return builder()->CreateAddressOfStructEntry(
113 thread(),
114 JavaThread::last_Java_sp_offset(),
115 llvm::PointerType::getUnqual(SharkType::intptr_type()),
116 "last_Java_sp_addr");
117 }
118 llvm::Value* last_Java_fp_addr() const {
119 return builder()->CreateAddressOfStructEntry(
120 thread(),
121 JavaThread::last_Java_fp_offset(),
122 llvm::PointerType::getUnqual(SharkType::intptr_type()),
123 "last_Java_fp_addr");
124 }
125
126 public:
127 void CreateSetLastJavaFrame() {
128 // Note that whenever _last_Java_sp != NULL other anchor fields
129 // must be valid. The profiler apparently depends on this.
130 NOT_PRODUCT(CreateAssertLastJavaSPIsNull());
131 builder()->CreateStore(CreateLoadFramePointer(), last_Java_fp_addr());
132 // XXX There's last_Java_pc as well, but I don't think anything uses it
133 // Also XXX: should we fence here? Zero doesn't...
134 builder()->CreateStore(CreateLoadStackPointer(), last_Java_sp_addr());
135 // Also also XXX: we could probably cache the sp (and the fp we know??)
136 }
137 void CreateResetLastJavaFrame() {
138 builder()->CreateStore(LLVMValue::intptr_constant(0), last_Java_sp_addr());
139 }
140
141 private:
142 void CreateAssertLastJavaSPIsNull() const PRODUCT_RETURN;
143
144 // Our method's frame
145 private:
146 llvm::Value* _frame;
147 int _extended_frame_size;
148 int _stack_slots_offset;
149
150 public:
151 int extended_frame_size() const {
152 return _extended_frame_size;
153 }
154 int oopmap_frame_size() const {
155 return extended_frame_size() - arg_size();
156 }
157
158 // Offsets of things in the frame
159 private:
160 int _monitors_slots_offset;
161 int _oop_tmp_slot_offset;
162 int _method_slot_offset;
163 int _pc_slot_offset;
164 int _locals_slots_offset;
165
166 public:
167 int stack_slots_offset() const {
168 return _stack_slots_offset;
169 }
170 int oop_tmp_slot_offset() const {
171 return _oop_tmp_slot_offset;
172 }
173 int method_slot_offset() const {
174 return _method_slot_offset;
175 }
176 int pc_slot_offset() const {
177 return _pc_slot_offset;
178 }
179 int locals_slots_offset() const {
180 return _locals_slots_offset;
181 }
182 int monitor_offset(int index) const {
183 assert(index >= 0 && index < max_monitors(), "invalid monitor index");
184 return _monitors_slots_offset +
185 (max_monitors() - 1 - index) * frame::interpreter_frame_monitor_size();
186 }
187 int monitor_object_offset(int index) const {
188 return monitor_offset(index) +
189 (BasicObjectLock::obj_offset_in_bytes() >> LogBytesPerWord);
190 }
191 int monitor_header_offset(int index) const {
192 return monitor_offset(index) +
193 ((BasicObjectLock::lock_offset_in_bytes() +
194 BasicLock::displaced_header_offset_in_bytes()) >> LogBytesPerWord);
195 }
196
197 // Addresses of things in the frame
198 public:
199 llvm::Value* slot_addr(int offset,
200 const llvm::Type* type = NULL,
201 const char* name = "") const;
202
203 llvm::Value* monitor_addr(int index) const {
204 return slot_addr(
205 monitor_offset(index),
206 SharkType::monitor_type(),
207 "monitor");
208 }
209 llvm::Value* monitor_object_addr(int index) const {
210 return slot_addr(
211 monitor_object_offset(index),
212 SharkType::oop_type(),
213 "object_addr");
214 }
215 llvm::Value* monitor_header_addr(int index) const {
216 return slot_addr(
217 monitor_header_offset(index),
218 SharkType::intptr_type(),
219 "displaced_header_addr");
220 }
221
222 // oopmap helpers
223 public:
224 static int oopmap_slot_munge(int offset) {
225 return offset << (LogBytesPerWord - LogBytesPerInt);
226 }
227 static VMReg slot2reg(int offset) {
228 return VMRegImpl::stack2reg(oopmap_slot_munge(offset));
229 }
230 };
231
232 class SharkStackWithNormalFrame : public SharkStack {
233 friend class SharkStack;
234
235 protected:
236 SharkStackWithNormalFrame(SharkFunction* function, llvm::Value* method);
237
238 private:
239 SharkFunction* _function;
240
241 private:
242 SharkFunction* function() const {
243 return _function;
244 }
245
246 // Properties of the method being compiled
247 private:
248 int arg_size() const;
249 int max_locals() const;
250 int max_stack() const;
251 int max_monitors() const;
252
253 // BasicBlock creation
254 private:
255 llvm::BasicBlock* CreateBlock(const char* name = "") const;
256
257 // Interpreter entry point for bailouts
258 private:
259 address interpreter_entry_point() const;
260 };
261
262 class SharkStackWithNativeFrame : public SharkStack {
263 friend class SharkStack;
264
265 protected:
266 SharkStackWithNativeFrame(SharkNativeWrapper* wrapper, llvm::Value* method);
267
268 private:
269 SharkNativeWrapper* _wrapper;
270
271 private:
272 SharkNativeWrapper* wrapper() const {
273 return _wrapper;
274 }
275
276 // Properties of the method being compiled
277 private:
278 int arg_size() const;
279 int max_locals() const;
280 int max_stack() const;
281 int max_monitors() const;
282
283 // BasicBlock creation
284 private:
285 llvm::BasicBlock* CreateBlock(const char* name = "") const;
286
287 // Interpreter entry point for bailouts
288 private:
289 address interpreter_entry_point() const;
290 };