1 /*
2  * Copyright (c) 1999, 2010, 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 #ifndef SHARE_VM_SHARK_SHARKSTACK_HPP
27 #define SHARE_VM_SHARK_SHARKSTACK_HPP
28 
29 #include "shark/llvmHeaders.hpp"
30 #include "shark/sharkInvariants.hpp"
31 #include "shark/sharkType.hpp"
32 
33 class SharkFunction;
34 class SharkNativeWrapper;
35 class SharkStackWithNormalFrame;
36 class SharkStackWithNativeFrame;
37 
38 class SharkStack : public SharkCompileInvariants {
39  public:
40   static SharkStack* CreateBuildAndPushFrame(
41     SharkFunction* function, llvm::Value* method);
42   static SharkStack* CreateBuildAndPushFrame(
43     SharkNativeWrapper* wrapper, llvm::Value* method);
44 
45  protected:
SharkStack(const SharkCompileInvariants * parent)46   SharkStack(const SharkCompileInvariants* parent)
47     : SharkCompileInvariants(parent) {}
48 
49  protected:
50   void initialize(llvm::Value* method);
51 
52  protected:
53   void CreateStackOverflowCheck(llvm::Value* sp);
54 
55   // Properties of the method being compiled
56  protected:
57   virtual int arg_size() const = 0;
58   virtual int max_locals() const = 0;
59   virtual int max_stack() const = 0;
60   virtual int max_monitors() const = 0;
61 
62   // BasicBlock creation
63  protected:
64   virtual llvm::BasicBlock* CreateBlock(const char* name = "") const = 0;
65 
66   // Interpreter entry point for bailouts
67  protected:
68   virtual address interpreter_entry_point() const = 0;
69 
70   // Interface with the Zero stack
71  private:
zero_stack() const72   llvm::Value* zero_stack() const {
73     return builder()->CreateAddressOfStructEntry(
74       thread(),
75       JavaThread::zero_stack_offset(),
76       SharkType::zeroStack_type(),
77       "zero_stack");
78   }
stack_base() const79   llvm::Value* stack_base() const {
80     return builder()->CreateValueOfStructEntry(
81       zero_stack(),
82       ZeroStack::base_offset(),
83       SharkType::intptr_type(),
84       "stack_base");
85   }
stack_pointer_addr() const86   llvm::Value* stack_pointer_addr() const {
87     return builder()->CreateAddressOfStructEntry(
88       zero_stack(),
89       ZeroStack::sp_offset(),
90       llvm::PointerType::getUnqual(SharkType::intptr_type()),
91       "stack_pointer_addr");
92   }
frame_pointer_addr() const93   llvm::Value* frame_pointer_addr() const {
94     return builder()->CreateAddressOfStructEntry(
95       thread(),
96       JavaThread::top_zero_frame_offset(),
97       llvm::PointerType::getUnqual(SharkType::intptr_type()),
98       "frame_pointer_addr");
99   }
100 
101  public:
CreateLoadStackPointer(const char * name="")102   llvm::LoadInst* CreateLoadStackPointer(const char *name = "") {
103     return builder()->CreateLoad(stack_pointer_addr(), name);
104   }
CreateStoreStackPointer(llvm::Value * value)105   llvm::StoreInst* CreateStoreStackPointer(llvm::Value* value) {
106     return builder()->CreateStore(value, stack_pointer_addr());
107   }
CreateLoadFramePointer(const char * name="")108   llvm::LoadInst* CreateLoadFramePointer(const char *name = "") {
109     return builder()->CreateLoad(frame_pointer_addr(), name);
110   }
CreateStoreFramePointer(llvm::Value * value)111   llvm::StoreInst* CreateStoreFramePointer(llvm::Value* value) {
112     return builder()->CreateStore(value, frame_pointer_addr());
113   }
114   llvm::Value* CreatePopFrame(int result_slots);
115 
116   // Interface with the frame anchor
117  private:
last_Java_sp_addr() const118   llvm::Value* last_Java_sp_addr() const {
119     return builder()->CreateAddressOfStructEntry(
120       thread(),
121       JavaThread::last_Java_sp_offset(),
122       llvm::PointerType::getUnqual(SharkType::intptr_type()),
123       "last_Java_sp_addr");
124   }
last_Java_fp_addr() const125   llvm::Value* last_Java_fp_addr() const {
126     return builder()->CreateAddressOfStructEntry(
127       thread(),
128       JavaThread::last_Java_fp_offset(),
129       llvm::PointerType::getUnqual(SharkType::intptr_type()),
130       "last_Java_fp_addr");
131   }
132 
133  public:
CreateSetLastJavaFrame()134   void CreateSetLastJavaFrame() {
135     // Note that whenever _last_Java_sp != NULL other anchor fields
136     // must be valid.  The profiler apparently depends on this.
137     NOT_PRODUCT(CreateAssertLastJavaSPIsNull());
138     builder()->CreateStore(CreateLoadFramePointer(), last_Java_fp_addr());
139     // XXX There's last_Java_pc as well, but I don't think anything uses it
140     // Also XXX: should we fence here?  Zero doesn't...
141     builder()->CreateStore(CreateLoadStackPointer(), last_Java_sp_addr());
142     // Also also XXX: we could probably cache the sp (and the fp we know??)
143   }
CreateResetLastJavaFrame()144   void CreateResetLastJavaFrame() {
145     builder()->CreateStore(LLVMValue::intptr_constant(0), last_Java_sp_addr());
146   }
147 
148  private:
149   void CreateAssertLastJavaSPIsNull() const PRODUCT_RETURN;
150 
151   // Our method's frame
152  private:
153   llvm::Value* _frame;
154   int          _extended_frame_size;
155   int          _stack_slots_offset;
156 
157  public:
extended_frame_size() const158   int extended_frame_size() const {
159     return _extended_frame_size;
160   }
oopmap_frame_size() const161   int oopmap_frame_size() const {
162     return extended_frame_size() - arg_size();
163   }
164 
165   // Offsets of things in the frame
166  private:
167   int _monitors_slots_offset;
168   int _oop_tmp_slot_offset;
169   int _method_slot_offset;
170   int _pc_slot_offset;
171   int _locals_slots_offset;
172 
173  public:
stack_slots_offset() const174   int stack_slots_offset() const {
175     return _stack_slots_offset;
176   }
oop_tmp_slot_offset() const177   int oop_tmp_slot_offset() const {
178     return _oop_tmp_slot_offset;
179   }
method_slot_offset() const180   int method_slot_offset() const {
181     return _method_slot_offset;
182   }
pc_slot_offset() const183   int pc_slot_offset() const {
184     return _pc_slot_offset;
185   }
locals_slots_offset() const186   int locals_slots_offset() const {
187     return _locals_slots_offset;
188   }
monitor_offset(int index) const189   int monitor_offset(int index) const {
190     assert(index >= 0 && index < max_monitors(), "invalid monitor index");
191     return _monitors_slots_offset +
192       (max_monitors() - 1 - index) * frame::interpreter_frame_monitor_size();
193   }
monitor_object_offset(int index) const194   int monitor_object_offset(int index) const {
195     return monitor_offset(index) +
196       (BasicObjectLock::obj_offset_in_bytes() >> LogBytesPerWord);
197   }
monitor_header_offset(int index) const198   int monitor_header_offset(int index) const {
199     return monitor_offset(index) +
200       ((BasicObjectLock::lock_offset_in_bytes() +
201         BasicLock::displaced_header_offset_in_bytes()) >> LogBytesPerWord);
202   }
203 
204   // Addresses of things in the frame
205  public:
206   llvm::Value* slot_addr(int               offset,
207                          llvm::Type* type = NULL,
208                          const char*       name = "") const;
209 
monitor_addr(int index) const210   llvm::Value* monitor_addr(int index) const {
211     return slot_addr(
212       monitor_offset(index),
213       SharkType::monitor_type(),
214       "monitor");
215   }
monitor_object_addr(int index) const216   llvm::Value* monitor_object_addr(int index) const {
217     return slot_addr(
218       monitor_object_offset(index),
219       SharkType::oop_type(),
220       "object_addr");
221   }
monitor_header_addr(int index) const222   llvm::Value* monitor_header_addr(int index) const {
223     return slot_addr(
224       monitor_header_offset(index),
225       SharkType::intptr_type(),
226       "displaced_header_addr");
227   }
228 
229   // oopmap helpers
230  public:
oopmap_slot_munge(int offset)231   static int oopmap_slot_munge(int offset) {
232     return offset << (LogBytesPerWord - LogBytesPerInt);
233   }
slot2reg(int offset)234   static VMReg slot2reg(int offset) {
235     return VMRegImpl::stack2reg(oopmap_slot_munge(offset));
236   }
237 };
238 
239 class SharkStackWithNormalFrame : public SharkStack {
240   friend class SharkStack;
241 
242  protected:
243   SharkStackWithNormalFrame(SharkFunction* function, llvm::Value* method);
244 
245  private:
246   SharkFunction* _function;
247 
248  private:
function() const249   SharkFunction* function() const {
250     return _function;
251   }
252 
253   // Properties of the method being compiled
254  private:
255   int arg_size() const;
256   int max_locals() const;
257   int max_stack() const;
258   int max_monitors() const;
259 
260   // BasicBlock creation
261  private:
262   llvm::BasicBlock* CreateBlock(const char* name = "") const;
263 
264   // Interpreter entry point for bailouts
265  private:
266   address interpreter_entry_point() const;
267 };
268 
269 class SharkStackWithNativeFrame : public SharkStack {
270   friend class SharkStack;
271 
272  protected:
273   SharkStackWithNativeFrame(SharkNativeWrapper* wrapper, llvm::Value* method);
274 
275  private:
276   SharkNativeWrapper* _wrapper;
277 
278  private:
wrapper() const279   SharkNativeWrapper* wrapper() const {
280     return _wrapper;
281   }
282 
283   // Properties of the method being compiled
284  private:
285   int arg_size() const;
286   int max_locals() const;
287   int max_stack() const;
288   int max_monitors() const;
289 
290   // BasicBlock creation
291  private:
292   llvm::BasicBlock* CreateBlock(const char* name = "") const;
293 
294   // Interpreter entry point for bailouts
295  private:
296   address interpreter_entry_point() const;
297 };
298 
299 #endif // SHARE_VM_SHARK_SHARKSTACK_HPP
300