Home | History | Annotate | Download | only in heap
      1 /*
      2  * Copyright (C) 2010 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
     14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
     17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     23  * THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #ifndef HandleStack_h
     27 #define HandleStack_h
     28 
     29 #include "Assertions.h"
     30 #include "BlockStack.h"
     31 #include "Handle.h"
     32 
     33 #include <wtf/UnusedParam.h>
     34 
     35 namespace JSC {
     36 
     37 class LocalScope;
     38 class HeapRootMarker;
     39 
     40 class HandleStack {
     41 public:
     42     class Frame {
     43     public:
     44         HandleSlot m_next;
     45         HandleSlot m_end;
     46     };
     47 
     48     HandleStack();
     49 
     50     void enterScope(Frame&);
     51     void leaveScope(Frame&);
     52 
     53     HandleSlot push();
     54 
     55     void mark(HeapRootMarker&);
     56 
     57 private:
     58     void grow();
     59     void zapTo(Frame&);
     60     HandleSlot findFirstAfter(HandleSlot);
     61 
     62 #ifndef NDEBUG
     63     size_t m_scopeDepth;
     64 #endif
     65     BlockStack<JSValue> m_blockStack;
     66     Frame m_frame;
     67 };
     68 
     69 inline void HandleStack::enterScope(Frame& lastFrame)
     70 {
     71 #ifndef NDEBUG
     72     ++m_scopeDepth;
     73 #endif
     74 
     75     lastFrame = m_frame;
     76 }
     77 
     78 
     79 
     80 inline void HandleStack::zapTo(Frame& lastFrame)
     81 {
     82 #ifdef NDEBUG
     83     UNUSED_PARAM(lastFrame);
     84 #else
     85     const Vector<HandleSlot>& blocks = m_blockStack.blocks();
     86 
     87     if (lastFrame.m_end != m_frame.m_end) { // Zapping to a frame in a different block.
     88         int i = blocks.size() - 1;
     89         for ( ; blocks[i] + m_blockStack.blockLength != lastFrame.m_end; --i) {
     90             for (int j = m_blockStack.blockLength - 1; j >= 0; --j)
     91                 blocks[i][j] = JSValue();
     92         }
     93 
     94         for (HandleSlot it = blocks[i] + m_blockStack.blockLength - 1; it != lastFrame.m_next - 1; --it)
     95             *it = JSValue();
     96 
     97         return;
     98     }
     99 
    100     for (HandleSlot it = m_frame.m_next - 1; it != lastFrame.m_next - 1; --it)
    101         *it = JSValue();
    102 #endif
    103 }
    104 
    105 inline void HandleStack::leaveScope(Frame& lastFrame)
    106 {
    107 #ifndef NDEBUG
    108     --m_scopeDepth;
    109 #endif
    110 
    111     zapTo(lastFrame);
    112 
    113     if (lastFrame.m_end != m_frame.m_end) // Popping to a frame in a different block.
    114         m_blockStack.shrink(lastFrame.m_end);
    115 
    116     m_frame = lastFrame;
    117 }
    118 
    119 inline HandleSlot HandleStack::push()
    120 {
    121     ASSERT(m_scopeDepth); // Creating a Local outside of a LocalScope is a memory leak.
    122     if (m_frame.m_next == m_frame.m_end)
    123         grow();
    124     return m_frame.m_next++;
    125 }
    126 
    127 }
    128 
    129 #endif
    130