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