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:
  38   SharkState(const SharkTargetInvariants* parent)
  39     : SharkTargetInvariants(parent),
  40       _method(NULL),
  41       _oop_tmp(NULL),
  42       _has_safepointed(false) { initialize(NULL); }
  43 
  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:
  64   llvm::Value** method_addr() {
  65     return &_method;
  66   }
  67   llvm::Value* method() const {
  68     return _method;
  69   }
  70  protected:
  71   void set_method(llvm::Value* method) {
  72     _method = method;
  73   }
  74 
  75   // Local variables
  76  public:
  77   SharkValue** local_addr(int index) const {
  78     assert(index >= 0 && index < max_locals(), "bad local variable index");
  79     return &_locals[index];
  80   }
  81   SharkValue* local(int index) const {
  82     return *local_addr(index);
  83   }
  84   void set_local(int index, SharkValue* value) {
  85     *local_addr(index) = value;
  86   }
  87 
  88   // Expression stack
  89  public:
  90   SharkValue** stack_addr(int slot) const {
  91     assert(slot >= 0 && slot < stack_depth(), "bad stack slot");
  92     return &_sp[-(slot + 1)];
  93   }
  94   SharkValue* stack(int slot) const {
  95     return *stack_addr(slot);
  96   }
  97  protected:
  98   void set_stack(int slot, SharkValue* value) {
  99     *stack_addr(slot) = value;
 100   }
 101  public:
 102   int stack_depth() const {
 103     return _sp - _stack;
 104   }
 105   void push(SharkValue* value) {
 106     assert(stack_depth() < max_stack(), "stack overrun");
 107     *(_sp++) = value;
 108   }
 109   SharkValue* pop() {
 110     assert(stack_depth() > 0, "stack underrun");
 111     return *(--_sp);
 112   }
 113 
 114   // Monitors
 115  public:
 116   int num_monitors() const {
 117     return _num_monitors;
 118   }
 119   void set_num_monitors(int num_monitors) {
 120     _num_monitors = num_monitors;
 121   }
 122 
 123   // Temporary oop slot
 124  public:
 125   llvm::Value** oop_tmp_addr() {
 126     return &_oop_tmp;
 127   }
 128   llvm::Value* oop_tmp() const {
 129     return _oop_tmp;
 130   }
 131   void set_oop_tmp(llvm::Value* oop_tmp) {
 132     _oop_tmp = oop_tmp;
 133   }
 134 
 135   // Safepointed status
 136  public:
 137   bool has_safepointed() const {
 138     return _has_safepointed;
 139   }
 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:
 150   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:
 192   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