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 <wtf/Assertions.h> 30#include <wtf/BlockStack.h> 31#include "Handle.h" 32 33namespace JSC { 34 35class LocalScope; 36class HeapRootVisitor; 37 38class HandleStack { 39public: 40 class Frame { 41 public: 42 HandleSlot m_next; 43 HandleSlot m_end; 44 }; 45 46 HandleStack(); 47 48 void enterScope(Frame&); 49 void leaveScope(Frame&); 50 51 HandleSlot push(); 52 53 void visit(HeapRootVisitor&); 54 55private: 56 void grow(); 57 void zapTo(Frame&); 58 HandleSlot findFirstAfter(HandleSlot); 59 60#ifndef NDEBUG 61 size_t m_scopeDepth; 62#endif 63 BlockStack<JSValue> m_blockStack; 64 Frame m_frame; 65}; 66 67inline void HandleStack::enterScope(Frame& lastFrame) 68{ 69#ifndef NDEBUG 70 ++m_scopeDepth; 71#endif 72 73 lastFrame = m_frame; 74} 75 76 77 78inline void HandleStack::zapTo(Frame& lastFrame) 79{ 80#ifdef NDEBUG 81 UNUSED_PARAM(lastFrame); 82#else 83 const Vector<HandleSlot>& blocks = m_blockStack.blocks(); 84 85 if (lastFrame.m_end != m_frame.m_end) { // Zapping to a frame in a different block. 86 int i = blocks.size() - 1; 87 for ( ; blocks[i] + m_blockStack.blockLength != lastFrame.m_end; --i) { 88 for (int j = m_blockStack.blockLength - 1; j >= 0; --j) 89 blocks[i][j] = JSValue(); 90 } 91 92 for (HandleSlot it = blocks[i] + m_blockStack.blockLength - 1; it != lastFrame.m_next - 1; --it) 93 *it = JSValue(); 94 95 return; 96 } 97 98 for (HandleSlot it = m_frame.m_next - 1; it != lastFrame.m_next - 1; --it) 99 *it = JSValue(); 100#endif 101} 102 103inline void HandleStack::leaveScope(Frame& lastFrame) 104{ 105#ifndef NDEBUG 106 --m_scopeDepth; 107#endif 108 109 zapTo(lastFrame); 110 111 if (lastFrame.m_end != m_frame.m_end) // Popping to a frame in a different block. 112 m_blockStack.shrink(lastFrame.m_end); 113 114 m_frame = lastFrame; 115} 116 117inline HandleSlot HandleStack::push() 118{ 119 ASSERT(m_scopeDepth); // Creating a Local outside of a LocalScope is a memory leak. 120 if (m_frame.m_next == m_frame.m_end) 121 grow(); 122 return m_frame.m_next++; 123} 124 125} 126 127#endif 128