twisti@2047: /* stefank@2314: * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. twisti@2047: * Copyright 2008, 2009 Red Hat, Inc. twisti@2047: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. twisti@2047: * twisti@2047: * This code is free software; you can redistribute it and/or modify it twisti@2047: * under the terms of the GNU General Public License version 2 only, as twisti@2047: * published by the Free Software Foundation. twisti@2047: * twisti@2047: * This code is distributed in the hope that it will be useful, but WITHOUT twisti@2047: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or twisti@2047: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License twisti@2047: * version 2 for more details (a copy is included in the LICENSE file that twisti@2047: * accompanied this code). twisti@2047: * twisti@2047: * You should have received a copy of the GNU General Public License version twisti@2047: * 2 along with this work; if not, write to the Free Software Foundation, twisti@2047: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. twisti@2047: * twisti@2047: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA twisti@2047: * or visit www.oracle.com if you need additional information or have any twisti@2047: * questions. twisti@2047: * twisti@2047: */ twisti@2047: stefank@2314: #ifndef SHARE_VM_SHARK_SHARKSTATE_HPP stefank@2314: #define SHARE_VM_SHARK_SHARKSTATE_HPP stefank@2314: stefank@2314: #include "ci/ciMethod.hpp" stefank@2314: #include "memory/allocation.hpp" stefank@2314: #include "shark/llvmHeaders.hpp" stefank@2314: #include "shark/sharkBuilder.hpp" stefank@2314: #include "shark/sharkInvariants.hpp" stefank@2314: #include "shark/sharkValue.hpp" stefank@2314: twisti@2047: class SharkState : public SharkTargetInvariants { twisti@2047: public: twisti@2047: SharkState(const SharkTargetInvariants* parent) twisti@2047: : SharkTargetInvariants(parent), twisti@2047: _method(NULL), twisti@2047: _oop_tmp(NULL), twisti@2047: _has_safepointed(false) { initialize(NULL); } twisti@2047: twisti@2047: SharkState(const SharkState* state) twisti@2047: : SharkTargetInvariants(state), twisti@2047: _method(state->_method), twisti@2047: _oop_tmp(state->_oop_tmp), twisti@2047: _has_safepointed(state->_has_safepointed) { initialize(state); } twisti@2047: twisti@2047: private: twisti@2047: void initialize(const SharkState* state); twisti@2047: twisti@2047: private: twisti@2047: llvm::Value* _method; twisti@2047: SharkValue** _locals; twisti@2047: SharkValue** _stack; twisti@2047: SharkValue** _sp; twisti@2047: int _num_monitors; twisti@2047: llvm::Value* _oop_tmp; twisti@2047: bool _has_safepointed; twisti@2047: twisti@2047: // Method twisti@2047: public: twisti@2047: llvm::Value** method_addr() { twisti@2047: return &_method; twisti@2047: } twisti@2047: llvm::Value* method() const { twisti@2047: return _method; twisti@2047: } twisti@2047: protected: twisti@2047: void set_method(llvm::Value* method) { twisti@2047: _method = method; twisti@2047: } twisti@2047: twisti@2047: // Local variables twisti@2047: public: twisti@2047: SharkValue** local_addr(int index) const { twisti@2047: assert(index >= 0 && index < max_locals(), "bad local variable index"); twisti@2047: return &_locals[index]; twisti@2047: } twisti@2047: SharkValue* local(int index) const { twisti@2047: return *local_addr(index); twisti@2047: } twisti@2047: void set_local(int index, SharkValue* value) { twisti@2047: *local_addr(index) = value; twisti@2047: } twisti@2047: twisti@2047: // Expression stack twisti@2047: public: twisti@2047: SharkValue** stack_addr(int slot) const { twisti@2047: assert(slot >= 0 && slot < stack_depth(), "bad stack slot"); twisti@2047: return &_sp[-(slot + 1)]; twisti@2047: } twisti@2047: SharkValue* stack(int slot) const { twisti@2047: return *stack_addr(slot); twisti@2047: } twisti@2047: protected: twisti@2047: void set_stack(int slot, SharkValue* value) { twisti@2047: *stack_addr(slot) = value; twisti@2047: } twisti@2047: public: twisti@2047: int stack_depth() const { twisti@2047: return _sp - _stack; twisti@2047: } twisti@2047: void push(SharkValue* value) { twisti@2047: assert(stack_depth() < max_stack(), "stack overrun"); twisti@2047: *(_sp++) = value; twisti@2047: } twisti@2047: SharkValue* pop() { twisti@2047: assert(stack_depth() > 0, "stack underrun"); twisti@2047: return *(--_sp); twisti@2047: } twisti@2047: twisti@2047: // Monitors twisti@2047: public: twisti@2047: int num_monitors() const { twisti@2047: return _num_monitors; twisti@2047: } twisti@2047: void set_num_monitors(int num_monitors) { twisti@2047: _num_monitors = num_monitors; twisti@2047: } twisti@2047: twisti@2047: // Temporary oop slot twisti@2047: public: twisti@2047: llvm::Value** oop_tmp_addr() { twisti@2047: return &_oop_tmp; twisti@2047: } twisti@2047: llvm::Value* oop_tmp() const { twisti@2047: return _oop_tmp; twisti@2047: } twisti@2047: void set_oop_tmp(llvm::Value* oop_tmp) { twisti@2047: _oop_tmp = oop_tmp; twisti@2047: } twisti@2047: twisti@2047: // Safepointed status twisti@2047: public: twisti@2047: bool has_safepointed() const { twisti@2047: return _has_safepointed; twisti@2047: } twisti@2047: void set_has_safepointed(bool has_safepointed) { twisti@2047: _has_safepointed = has_safepointed; twisti@2047: } twisti@2047: twisti@2047: // Comparison twisti@2047: public: twisti@2047: bool equal_to(SharkState* other); twisti@2047: twisti@2047: // Copy and merge twisti@2047: public: twisti@2047: SharkState* copy() const { twisti@2047: return new SharkState(this); twisti@2047: } twisti@2047: void merge(SharkState* other, twisti@2047: llvm::BasicBlock* other_block, twisti@2047: llvm::BasicBlock* this_block); twisti@2047: twisti@2047: // Value replacement twisti@2047: public: twisti@2047: void replace_all(SharkValue* old_value, SharkValue* new_value); twisti@2047: }; twisti@2047: twisti@2047: class SharkTopLevelBlock; twisti@2047: twisti@2047: // SharkNormalEntryState objects are used to create the state twisti@2047: // that the method will be entered with for a normal invocation. twisti@2047: class SharkNormalEntryState : public SharkState { twisti@2047: public: twisti@2047: SharkNormalEntryState(SharkTopLevelBlock* block, twisti@2047: llvm::Value* method); twisti@2047: }; twisti@2047: twisti@2047: // SharkOSREntryState objects are used to create the state twisti@2047: // that the method will be entered with for an OSR invocation. twisti@2047: class SharkOSREntryState : public SharkState { twisti@2047: public: twisti@2047: SharkOSREntryState(SharkTopLevelBlock* block, twisti@2047: llvm::Value* method, twisti@2047: llvm::Value* osr_buf); twisti@2047: }; twisti@2047: twisti@2047: // SharkPHIState objects are used to manage the entry state twisti@2047: // for blocks with more than one entry path or for blocks twisti@2047: // entered from blocks that will be compiled later. twisti@2047: class SharkPHIState : public SharkState { twisti@2047: public: twisti@2047: SharkPHIState(SharkTopLevelBlock* block); twisti@2047: twisti@2047: private: twisti@2047: SharkTopLevelBlock* _block; twisti@2047: twisti@2047: private: twisti@2047: SharkTopLevelBlock* block() const { twisti@2047: return _block; twisti@2047: } twisti@2047: twisti@2047: public: twisti@2047: void add_incoming(SharkState* incoming_state); twisti@2047: }; stefank@2314: stefank@2314: #endif // SHARE_VM_SHARK_SHARKSTATE_HPP