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 35namespace JSC { 36 37class LocalScope; 38class HeapRootMarker; 39 40class HandleStack { 41public: 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 57private: 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 69inline void HandleStack::enterScope(Frame& lastFrame) 70{ 71#ifndef NDEBUG 72 ++m_scopeDepth; 73#endif 74 75 lastFrame = m_frame; 76} 77 78 79 80inline 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 105inline 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 119inline 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