1 /*
   2  * Copyright (c) 2003, 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 CPU_ZERO_VM_STACK_ZERO_HPP
  27 #define CPU_ZERO_VM_STACK_ZERO_HPP
  28 
  29 #include "utilities/sizes.hpp"
  30 
  31 class ZeroStack {
  32  private:
  33   intptr_t *_base; // the last available word
  34   intptr_t *_top;  // the word past the end of the stack
  35   intptr_t *_sp;   // the top word on the stack
  36 
  37  private:
  38   int _shadow_pages_size; // how much ABI stack must we keep free?
  39 
  40  public:
  41   ZeroStack()
  42     : _base(NULL), _top(NULL), _sp(NULL) {
  43     _shadow_pages_size = StackShadowPages * os::vm_page_size();
  44   }
  45 
  46   bool needs_setup() const {
  47     return _base == NULL;
  48   }
  49 
  50   int suggest_size(Thread *thread) const;
  51 
  52   void setup(void *mem, size_t size) {
  53     assert(needs_setup(), "already set up");
  54     assert(!(size & WordAlignmentMask), "unaligned");
  55 
  56     _base = (intptr_t *) mem;
  57     _top  = _base + (size >> LogBytesPerWord);
  58     _sp   = _top;
  59   }
  60   void teardown() {
  61     assert(!needs_setup(), "not set up");
  62     assert(_sp == _top, "stuff on stack at teardown");
  63 
  64     _base = NULL;
  65     _top  = NULL;
  66     _sp   = NULL;
  67   }
  68 
  69   intptr_t *sp() const {
  70     return _sp;
  71   }
  72   void set_sp(intptr_t *new_sp) {
  73     assert(_top >= new_sp && new_sp >= _base, "bad stack pointer");
  74     _sp = new_sp;
  75   }
  76 
  77   int total_words() const {
  78     return _top - _base;
  79   }
  80   int available_words() const {
  81     return _sp - _base;
  82   }
  83 
  84   void push(intptr_t value) {
  85     assert(_sp > _base, "stack overflow");
  86     *(--_sp) = value;
  87   }
  88   intptr_t pop() {
  89     assert(_sp < _top, "stack underflow");
  90     return *(_sp++);
  91   }
  92 
  93   void *alloc(size_t size) {
  94     int count = align_size_up(size, wordSize) >> LogBytesPerWord;
  95     assert(count <= available_words(), "stack overflow");
  96     return _sp -= count;
  97   }
  98 
  99   int shadow_pages_size() const {
 100     return _shadow_pages_size;
 101   }
 102   int abi_stack_available(Thread *thread) const;
 103 
 104  public:
 105   void overflow_check(int required_words, TRAPS);
 106   static void handle_overflow(TRAPS);
 107 
 108  public:
 109   void zap(int c) PRODUCT_RETURN;
 110 
 111  public:
 112   static ByteSize base_offset() {
 113     return byte_offset_of(ZeroStack, _base);
 114   }
 115   static ByteSize top_offset() {
 116     return byte_offset_of(ZeroStack, _top);
 117   }
 118   static ByteSize sp_offset() {
 119     return byte_offset_of(ZeroStack, _sp);
 120   }
 121 };
 122 
 123 
 124 class EntryFrame;
 125 class InterpreterFrame;
 126 class SharkFrame;
 127 class FakeStubFrame;
 128 
 129 //
 130 // |  ...               |
 131 // +--------------------+  ------------------
 132 // |  ...               |       low addresses
 133 // | frame_type         |
 134 // | next_frame         |      high addresses
 135 // +--------------------+  ------------------
 136 // |  ...               |
 137 
 138 class ZeroFrame {
 139   friend class frame;
 140   friend class ZeroStackPrinter;
 141 
 142  protected:
 143   ZeroFrame() {
 144     ShouldNotCallThis();
 145   }
 146 
 147   enum Layout {
 148     next_frame_off,
 149     frame_type_off,
 150     jf_header_words
 151   };
 152 
 153   enum FrameType {
 154     ENTRY_FRAME = 1,
 155     INTERPRETER_FRAME,
 156     SHARK_FRAME,
 157     FAKE_STUB_FRAME
 158   };
 159 
 160  protected:
 161   intptr_t *addr_of_word(int offset) const {
 162     return (intptr_t *) this - offset;
 163   }
 164   intptr_t value_of_word(int offset) const {
 165     return *addr_of_word(offset);
 166   }
 167 
 168  public:
 169   ZeroFrame *next() const {
 170     return (ZeroFrame *) value_of_word(next_frame_off);
 171   }
 172 
 173  protected:
 174   FrameType type() const {
 175     return (FrameType) value_of_word(frame_type_off);
 176   }
 177 
 178  public:
 179   bool is_entry_frame() const {
 180     return type() == ENTRY_FRAME;
 181   }
 182   bool is_interpreter_frame() const {
 183     return type() == INTERPRETER_FRAME;
 184   }
 185   bool is_shark_frame() const {
 186     return type() == SHARK_FRAME;
 187   }
 188   bool is_fake_stub_frame() const {
 189     return type() == FAKE_STUB_FRAME;
 190   }
 191 
 192  public:
 193   EntryFrame *as_entry_frame() const {
 194     assert(is_entry_frame(), "should be");
 195     return (EntryFrame *) this;
 196   }
 197   InterpreterFrame *as_interpreter_frame() const {
 198     assert(is_interpreter_frame(), "should be");
 199     return (InterpreterFrame *) this;
 200   }
 201   SharkFrame *as_shark_frame() const {
 202     assert(is_shark_frame(), "should be");
 203     return (SharkFrame *) this;
 204   }
 205   FakeStubFrame *as_fake_stub_frame() const {
 206     assert(is_fake_stub_frame(), "should be");
 207     return (FakeStubFrame *) this;
 208   }
 209 
 210  public:
 211   void identify_word(int   frame_index,
 212                      int   offset,
 213                      char* fieldbuf,
 214                      char* valuebuf,
 215                      int   buflen) const;
 216 
 217  protected:
 218   void identify_vp_word(int       frame_index,
 219                         intptr_t* addr,
 220                         intptr_t* monitor_base,
 221                         intptr_t* stack_base,
 222                         char*     fieldbuf,
 223                         int       buflen) const;
 224 };
 225 
 226 #endif // CPU_ZERO_VM_STACK_ZERO_HPP