src/cpu/zero/vm/stack_zero.hpp

Thu, 15 Apr 2010 02:40:12 -0700

author
twisti
date
Thu, 15 Apr 2010 02:40:12 -0700
changeset 1814
f9271ff9d324
parent 1445
354d3184f6b2
child 1860
0c5b3cf3c1f5
permissions
-rw-r--r--

6941224: Improved stack overflow handling for Zero
Summary: Adding stack overflow checking to Shark brought to light a bunch of deficiencies in Zero's stack overflow code.
Reviewed-by: twisti
Contributed-by: Gary Benson <gbenson@redhat.com>

     1 /*
     2  * Copyright 2003-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    21  * CA 95054 USA or visit www.sun.com if you need additional information or
    22  * have any questions.
    23  *
    24  */
    26 class ZeroStack {
    27  private:
    28   intptr_t *_base; // the last available word
    29   intptr_t *_top;  // the word past the end of the stack
    30   intptr_t *_sp;   // the top word on the stack
    32  private:
    33   int _shadow_pages_size; // how much ABI stack must we keep free?
    35  public:
    36   ZeroStack()
    37     : _base(NULL), _top(NULL), _sp(NULL) {
    38     _shadow_pages_size = StackShadowPages * os::vm_page_size();
    39   }
    41   bool needs_setup() const {
    42     return _base == NULL;
    43   }
    45   void setup(void *mem, size_t size) {
    46     assert(needs_setup(), "already set up");
    47     assert(!(size & WordAlignmentMask), "unaligned");
    49     _base = (intptr_t *) mem;
    50     _top  = _base + (size >> LogBytesPerWord);
    51     _sp   = _top;
    52   }
    53   void teardown() {
    54     assert(!needs_setup(), "not set up");
    55     assert(_sp == _top, "stuff on stack at teardown");
    57     _base = NULL;
    58     _top  = NULL;
    59     _sp   = NULL;
    60   }
    62   intptr_t *sp() const {
    63     return _sp;
    64   }
    65   void set_sp(intptr_t *new_sp) {
    66     assert(_top >= new_sp && new_sp >= _base, "bad stack pointer");
    67     _sp = new_sp;
    68   }
    70   int available_words() const {
    71     return _sp - _base;
    72   }
    74   void push(intptr_t value) {
    75     assert(_sp > _base, "stack overflow");
    76     *(--_sp) = value;
    77   }
    78   intptr_t pop() {
    79     assert(_sp < _top, "stack underflow");
    80     return *(_sp++);
    81   }
    83   void *alloc(size_t size) {
    84     int count = align_size_up(size, wordSize) >> LogBytesPerWord;
    85     assert(count <= available_words(), "stack overflow");
    86     return _sp -= count;
    87   }
    89   int shadow_pages_size() const {
    90     return _shadow_pages_size;
    91   }
    93  public:
    94   void overflow_check(int required_words, TRAPS);
    95   static void handle_overflow(TRAPS);
    97  public:
    98   static ByteSize base_offset() {
    99     return byte_offset_of(ZeroStack, _base);
   100   }
   101   static ByteSize top_offset() {
   102     return byte_offset_of(ZeroStack, _top);
   103   }
   104   static ByteSize sp_offset() {
   105     return byte_offset_of(ZeroStack, _sp);
   106   }
   107 };
   110 class EntryFrame;
   111 class InterpreterFrame;
   112 class SharkFrame;
   113 class FakeStubFrame;
   115 //
   116 // |  ...               |
   117 // +--------------------+  ------------------
   118 // |  ...               |       low addresses
   119 // | frame_type         |
   120 // | next_frame         |      high addresses
   121 // +--------------------+  ------------------
   122 // |  ...               |
   124 class ZeroFrame {
   125   friend class frame;
   126   friend class ZeroStackPrinter;
   128  protected:
   129   ZeroFrame() {
   130     ShouldNotCallThis();
   131   }
   133   enum Layout {
   134     next_frame_off,
   135     frame_type_off,
   136     jf_header_words
   137   };
   139   enum FrameType {
   140     ENTRY_FRAME = 1,
   141     INTERPRETER_FRAME,
   142     SHARK_FRAME,
   143     FAKE_STUB_FRAME
   144   };
   146  protected:
   147   intptr_t *addr_of_word(int offset) const {
   148     return (intptr_t *) this - offset;
   149   }
   150   intptr_t value_of_word(int offset) const {
   151     return *addr_of_word(offset);
   152   }
   154  public:
   155   ZeroFrame *next() const {
   156     return (ZeroFrame *) value_of_word(next_frame_off);
   157   }
   159  protected:
   160   FrameType type() const {
   161     return (FrameType) value_of_word(frame_type_off);
   162   }
   164  public:
   165   bool is_entry_frame() const {
   166     return type() == ENTRY_FRAME;
   167   }
   168   bool is_interpreter_frame() const {
   169     return type() == INTERPRETER_FRAME;
   170   }
   171   bool is_shark_frame() const {
   172     return type() == SHARK_FRAME;
   173   }
   174   bool is_fake_stub_frame() const {
   175     return type() == FAKE_STUB_FRAME;
   176   }
   178  public:
   179   EntryFrame *as_entry_frame() const {
   180     assert(is_entry_frame(), "should be");
   181     return (EntryFrame *) this;
   182   }
   183   InterpreterFrame *as_interpreter_frame() const {
   184     assert(is_interpreter_frame(), "should be");
   185     return (InterpreterFrame *) this;
   186   }
   187   SharkFrame *as_shark_frame() const {
   188     assert(is_shark_frame(), "should be");
   189     return (SharkFrame *) this;
   190   }
   191   FakeStubFrame *as_fake_stub_frame() const {
   192     assert(is_fake_stub_frame(), "should be");
   193     return (FakeStubFrame *) this;
   194   }
   196  public:
   197   void identify_word(int   frame_index,
   198                      int   offset,
   199                      char* fieldbuf,
   200                      char* valuebuf,
   201                      int   buflen) const;
   203  protected:
   204   void identify_vp_word(int       frame_index,
   205                         intptr_t* addr,
   206                         intptr_t* monitor_base,
   207                         intptr_t* stack_base,
   208                         char*     fieldbuf,
   209                         int       buflen) const;
   210 };

mercurial