1 /*
2  * Copyright (c) 1999, 2010, 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 #ifndef SHARE_VM_SHARK_SHARKSTATE_HPP
27 #define SHARE_VM_SHARK_SHARKSTATE_HPP
28 
29 #include "ci/ciMethod.hpp"
30 #include "memory/allocation.hpp"
31 #include "shark/llvmHeaders.hpp"
32 #include "shark/sharkBuilder.hpp"
33 #include "shark/sharkInvariants.hpp"
34 #include "shark/sharkValue.hpp"
35 
36 class SharkState : public SharkTargetInvariants {
37  public:
SharkState(const SharkTargetInvariants * parent)38   SharkState(const SharkTargetInvariants* parent)
39     : SharkTargetInvariants(parent),
40       _method(NULL),
41       _oop_tmp(NULL),
42       _has_safepointed(false) { initialize(NULL); }
43 
SharkState(const SharkState * state)44   SharkState(const SharkState* state)
45     : SharkTargetInvariants(state),
46       _method(state->_method),
47       _oop_tmp(state->_oop_tmp),
48       _has_safepointed(state->_has_safepointed) { initialize(state); }
49 
50  private:
51   void initialize(const SharkState* state);
52 
53  private:
54   llvm::Value* _method;
55   SharkValue** _locals;
56   SharkValue** _stack;
57   SharkValue** _sp;
58   int          _num_monitors;
59   llvm::Value* _oop_tmp;
60   bool         _has_safepointed;
61 
62   // Method
63  public:
method_addr()64   llvm::Value** method_addr() {
65     return &_method;
66   }
method() const67   llvm::Value* method() const {
68     return _method;
69   }
70  protected:
set_method(llvm::Value * method)71   void set_method(llvm::Value* method) {
72     _method = method;
73   }
74 
75   // Local variables
76  public:
local_addr(int index) const77   SharkValue** local_addr(int index) const {
78     assert(index >= 0 && index < max_locals(), "bad local variable index");
79     return &_locals[index];
80   }
local(int index) const81   SharkValue* local(int index) const {
82     return *local_addr(index);
83   }
set_local(int index,SharkValue * value)84   void set_local(int index, SharkValue* value) {
85     *local_addr(index) = value;
86   }
87 
88   // Expression stack
89  public:
stack_addr(int slot) const90   SharkValue** stack_addr(int slot) const {
91     assert(slot >= 0 && slot < stack_depth(), "bad stack slot");
92     return &_sp[-(slot + 1)];
93   }
stack(int slot) const94   SharkValue* stack(int slot) const {
95     return *stack_addr(slot);
96   }
97  protected:
set_stack(int slot,SharkValue * value)98   void set_stack(int slot, SharkValue* value) {
99     *stack_addr(slot) = value;
100   }
101  public:
stack_depth() const102   int stack_depth() const {
103     return _sp - _stack;
104   }
push(SharkValue * value)105   void push(SharkValue* value) {
106     assert(stack_depth() < max_stack(), "stack overrun");
107     *(_sp++) = value;
108   }
pop()109   SharkValue* pop() {
110     assert(stack_depth() > 0, "stack underrun");
111     return *(--_sp);
112   }
113 
114   // Monitors
115  public:
num_monitors() const116   int num_monitors() const {
117     return _num_monitors;
118   }
set_num_monitors(int num_monitors)119   void set_num_monitors(int num_monitors) {
120     _num_monitors = num_monitors;
121   }
122 
123   // Temporary oop slot
124  public:
oop_tmp_addr()125   llvm::Value** oop_tmp_addr() {
126     return &_oop_tmp;
127   }
oop_tmp() const128   llvm::Value* oop_tmp() const {
129     return _oop_tmp;
130   }
set_oop_tmp(llvm::Value * oop_tmp)131   void set_oop_tmp(llvm::Value* oop_tmp) {
132     _oop_tmp = oop_tmp;
133   }
134 
135   // Safepointed status
136  public:
has_safepointed() const137   bool has_safepointed() const {
138     return _has_safepointed;
139   }
set_has_safepointed(bool has_safepointed)140   void set_has_safepointed(bool has_safepointed) {
141     _has_safepointed = has_safepointed;
142   }
143 
144   // Comparison
145  public:
146   bool equal_to(SharkState* other);
147 
148   // Copy and merge
149  public:
copy() const150   SharkState* copy() const {
151     return new SharkState(this);
152   }
153   void merge(SharkState*       other,
154              llvm::BasicBlock* other_block,
155              llvm::BasicBlock* this_block);
156 
157   // Value replacement
158  public:
159   void replace_all(SharkValue* old_value, SharkValue* new_value);
160 };
161 
162 class SharkTopLevelBlock;
163 
164 // SharkNormalEntryState objects are used to create the state
165 // that the method will be entered with for a normal invocation.
166 class SharkNormalEntryState : public SharkState {
167  public:
168   SharkNormalEntryState(SharkTopLevelBlock* block,
169                         llvm::Value*        method);
170 };
171 
172 // SharkOSREntryState objects are used to create the state
173 // that the method will be entered with for an OSR invocation.
174 class SharkOSREntryState : public SharkState {
175  public:
176   SharkOSREntryState(SharkTopLevelBlock* block,
177                      llvm::Value*        method,
178                      llvm::Value*        osr_buf);
179 };
180 
181 // SharkPHIState objects are used to manage the entry state
182 // for blocks with more than one entry path or for blocks
183 // entered from blocks that will be compiled later.
184 class SharkPHIState : public SharkState {
185  public:
186   SharkPHIState(SharkTopLevelBlock* block);
187 
188  private:
189   SharkTopLevelBlock* _block;
190 
191  private:
block() const192   SharkTopLevelBlock* block() const {
193     return _block;
194   }
195 
196  public:
197   void add_incoming(SharkState* incoming_state);
198 };
199 
200 #endif // SHARE_VM_SHARK_SHARKSTATE_HPP
201