diff options
author | Steve Block <steveblock@google.com> | 2011-05-25 19:08:45 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2011-06-08 13:51:31 +0100 |
commit | 2bde8e466a4451c7319e3a072d118917957d6554 (patch) | |
tree | 28f4a1b869a513e565c7760d0e6a06e7cf1fe95a /Source/JavaScriptCore/collector | |
parent | 6939c99b71d9372d14a0c74a772108052e8c48c8 (diff) | |
download | external_webkit-2bde8e466a4451c7319e3a072d118917957d6554.zip external_webkit-2bde8e466a4451c7319e3a072d118917957d6554.tar.gz external_webkit-2bde8e466a4451c7319e3a072d118917957d6554.tar.bz2 |
Merge WebKit at r82507: Initial merge by git
Change-Id: I60ce9d780725b58b45e54165733a8ffee23b683e
Diffstat (limited to 'Source/JavaScriptCore/collector')
7 files changed, 449 insertions, 5 deletions
diff --git a/Source/JavaScriptCore/collector/handles/Handle.h b/Source/JavaScriptCore/collector/handles/Handle.h index 98c60ec..d4e38c0 100644 --- a/Source/JavaScriptCore/collector/handles/Handle.h +++ b/Source/JavaScriptCore/collector/handles/Handle.h @@ -111,10 +111,19 @@ template <typename Base, typename T> struct HandleConverter { }; template <typename Base> struct HandleConverter<Base, Unknown> { + Handle<JSObject> asObject() const; + bool isObject() const { return jsValue().isObject(); } + bool getNumber(double number) const { return jsValue().getNumber(number); } + UString getString(ExecState*) const; + bool isUndefinedOrNull() const { return jsValue().isUndefinedOrNull(); } + +private: + JSValue jsValue() const { return static_cast<const Base*>(this)->get(); } }; template <typename T> class Handle : public HandleBase, public HandleConverter<Handle<T>, T> { public: + template <typename A, typename B> friend class HandleConverter; typedef typename HandleTypes<T>::ExternalType ExternalType; template <typename U> Handle(Handle<U> o) { @@ -144,6 +153,11 @@ private: } }; +template <typename Base> Handle<JSObject> HandleConverter<Base, Unknown>::asObject() const +{ + return Handle<JSObject>::wrapSlot(static_cast<const Base*>(this)->slot()); +} + template <typename T, typename U> inline bool operator==(const Handle<T>& a, const Handle<U>& b) { return a.get() == b.get(); diff --git a/Source/JavaScriptCore/collector/handles/HandleHeap.cpp b/Source/JavaScriptCore/collector/handles/HandleHeap.cpp index 32fa42d..1beb407 100644 --- a/Source/JavaScriptCore/collector/handles/HandleHeap.cpp +++ b/Source/JavaScriptCore/collector/handles/HandleHeap.cpp @@ -51,11 +51,11 @@ void HandleHeap::grow() } } -void HandleHeap::markStrongHandles(MarkStack& markStack) +void HandleHeap::markStrongHandles(HeapRootMarker& heapRootMarker) { Node* end = m_strongList.end(); for (Node* node = m_strongList.begin(); node != end; node = node->next()) - markStack.deprecatedAppend(node->slot()); + heapRootMarker.mark(node->slot()); } void HandleHeap::updateAfterMark() @@ -79,7 +79,10 @@ void HandleHeap::clearWeakPointers() JSCell* cell = value.asCell(); ASSERT(!cell || cell->structure()); - + +#if ENABLE(JSC_ZOMBIES) + ASSERT(!cell->isZombie()); +#endif if (Heap::isMarked(cell)) continue; diff --git a/Source/JavaScriptCore/collector/handles/HandleHeap.h b/Source/JavaScriptCore/collector/handles/HandleHeap.h index 4bb9b00..ed462d4 100644 --- a/Source/JavaScriptCore/collector/handles/HandleHeap.h +++ b/Source/JavaScriptCore/collector/handles/HandleHeap.h @@ -36,7 +36,7 @@ namespace JSC { class HandleHeap; class JSGlobalData; class JSValue; -class MarkStack; +class HeapRootMarker; class Finalizer { public: @@ -56,7 +56,7 @@ public: void makeWeak(HandleSlot, Finalizer*, void* context); void makeSelfDestroying(HandleSlot, Finalizer*, void* context); - void markStrongHandles(MarkStack&); + void markStrongHandles(HeapRootMarker&); void updateAfterMark(); // Should only be called during teardown. diff --git a/Source/JavaScriptCore/collector/handles/HandleStack.cpp b/Source/JavaScriptCore/collector/handles/HandleStack.cpp new file mode 100644 index 0000000..1c151af --- /dev/null +++ b/Source/JavaScriptCore/collector/handles/HandleStack.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include "HandleStack.h" + +#include "MarkStack.h" + +namespace JSC { + +HandleStack::HandleStack() +#ifndef NDEBUG + : m_scopeDepth(0) +#endif +{ + grow(); +} + +void HandleStack::mark(HeapRootMarker& heapRootMarker) +{ + const Vector<HandleSlot>& blocks = m_blockStack.blocks(); + size_t blockLength = m_blockStack.blockLength; + + int end = blocks.size() - 1; + for (int i = 0; i < end; ++i) { + HandleSlot block = blocks[i]; + heapRootMarker.mark(block, blockLength); + } + HandleSlot block = blocks[end]; + heapRootMarker.mark(block, m_frame.m_next - block); +} + +void HandleStack::grow() +{ + HandleSlot block = m_blockStack.grow(); + m_frame.m_next = block; + m_frame.m_end = block + m_blockStack.blockLength; +} + +} diff --git a/Source/JavaScriptCore/collector/handles/HandleStack.h b/Source/JavaScriptCore/collector/handles/HandleStack.h new file mode 100644 index 0000000..54e6c60 --- /dev/null +++ b/Source/JavaScriptCore/collector/handles/HandleStack.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef HandleStack_h +#define HandleStack_h + +#include "Assertions.h" +#include "BlockStack.h" +#include "Handle.h" + +#include <wtf/UnusedParam.h> + +namespace JSC { + +class LocalScope; +class HeapRootMarker; + +class HandleStack { +public: + class Frame { + public: + HandleSlot m_next; + HandleSlot m_end; + }; + + HandleStack(); + + void enterScope(Frame&); + void leaveScope(Frame&); + + HandleSlot push(); + + void mark(HeapRootMarker&); + +private: + void grow(); + void zapTo(Frame&); + HandleSlot findFirstAfter(HandleSlot); + +#ifndef NDEBUG + size_t m_scopeDepth; +#endif + BlockStack<JSValue> m_blockStack; + Frame m_frame; +}; + +inline void HandleStack::enterScope(Frame& lastFrame) +{ +#ifndef NDEBUG + ++m_scopeDepth; +#endif + + lastFrame = m_frame; +} + + + +inline void HandleStack::zapTo(Frame& lastFrame) +{ +#ifdef NDEBUG + UNUSED_PARAM(lastFrame); +#else + const Vector<HandleSlot>& blocks = m_blockStack.blocks(); + + if (lastFrame.m_end != m_frame.m_end) { // Zapping to a frame in a different block. + int i = blocks.size() - 1; + for ( ; blocks[i] + m_blockStack.blockLength != lastFrame.m_end; --i) { + for (int j = m_blockStack.blockLength - 1; j >= 0; --j) + blocks[i][j] = JSValue(); + } + + for (HandleSlot it = blocks[i] + m_blockStack.blockLength - 1; it != lastFrame.m_next - 1; --it) + *it = JSValue(); + + return; + } + + for (HandleSlot it = m_frame.m_next - 1; it != lastFrame.m_next - 1; --it) + *it = JSValue(); +#endif +} + +inline void HandleStack::leaveScope(Frame& lastFrame) +{ +#ifndef NDEBUG + --m_scopeDepth; +#endif + + zapTo(lastFrame); + + if (lastFrame.m_end != m_frame.m_end) // Popping to a frame in a different block. + m_blockStack.shrink(lastFrame.m_end); + + m_frame = lastFrame; +} + +inline HandleSlot HandleStack::push() +{ + ASSERT(m_scopeDepth); // Creating a Local outside of a LocalScope is a memory leak. + if (m_frame.m_next == m_frame.m_end) + grow(); + return m_frame.m_next++; +} + +} + +#endif diff --git a/Source/JavaScriptCore/collector/handles/Local.h b/Source/JavaScriptCore/collector/handles/Local.h new file mode 100644 index 0000000..035e9e9 --- /dev/null +++ b/Source/JavaScriptCore/collector/handles/Local.h @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef Local_h +#define Local_h + +#include "Handle.h" +#include "JSGlobalData.h" + +/* + A Local is a temporary handle whose lifetime is tied to a given LocalScope. + Use Locals for local values on the stack. It is an error to create a Local + outside of any LocalScope. +*/ + +namespace JSC { +template <typename T> class Local; +} + +namespace WTF { + +template<typename T> struct VectorTraits<JSC::Local<T> > { + static const bool needsDestruction = false; + static const bool needsInitialization = true; + static const bool canInitializeWithMemset = false; + static const bool canMoveWithMemcpy = true; + static const bool canCopyWithMemcpy = false; + static const bool canFillWithMemset = false; + static const bool canCompareWithMemcmp = true; +}; + +} + +namespace JSC { + +template <typename T> class Local : public Handle<T> { + friend class LocalScope; +public: + typedef typename Handle<T>::ExternalType ExternalType; + Local(JSGlobalData&, ExternalType = ExternalType()); + Local(JSGlobalData&, Handle<T>); + Local(const Local<T>&); // Adopting constructor. Used to return a Local to a calling function. + + Local& operator=(ExternalType); + Local& operator=(Handle<T>); + + using Handle<T>::slot; + +private: + Local(HandleSlot, ExternalType); // Used by LocalScope::release() to move a Local to a containing scope. + void internalSet(ExternalType value) + { + JSValue newValue(HandleTypes<T>::toJSValue(value)); + HandleSlot slot = this->slot(); + *slot = newValue; + } +}; + +template <typename T> inline Local<T>::Local(JSGlobalData& globalData, ExternalType value) + : Handle<T>(globalData.allocateLocalHandle()) +{ + internalSet(value); +} + +template <typename T> inline Local<T>::Local(JSGlobalData& globalData, Handle<T> handle) + : Handle<T>(globalData.allocateLocalHandle()) +{ + internalSet(handle.get()); +} + +template <typename T> inline Local<T>::Local(const Local<T>& o) + : Handle<T>(o.slot()) +{ + const_cast<Local<T>&>(o).invalidate(); // Prevent accidental sharing. +} + +template <typename T> inline Local<T>::Local(HandleSlot slot, ExternalType value) + : Handle<T>(slot, value) +{ +} + +template <typename T> inline Local<T>& Local<T>::operator=(ExternalType value) +{ + internalSet(value); + return *this; +} + +template <typename T> inline Local<T>& Local<T>::operator=(Handle<T> handle) +{ + internalSet(handle.get()); + return *this; +} + +template <typename T, unsigned inlineCapacity = 0> class LocalStack { + typedef typename Handle<T>::ExternalType ExternalType; +public: + LocalStack(JSGlobalData& globalData) + : m_globalData(&globalData) + , m_count(0) + { + } + + ExternalType peek() const + { + ASSERT(m_count > 0); + return m_stack[m_count - 1].get(); + } + + ExternalType pop() + { + ASSERT(m_count > 0); + return m_stack[--m_count].get(); + } + + void push(ExternalType value) + { + if (m_count == m_stack.size()) + m_stack.append(Local<T>(*m_globalData, value)); + else + m_stack[m_count] = value; + m_count++; + } + + bool isEmpty() const { return !m_count; } + unsigned size() const { return m_count; } + +private: + RefPtr<JSGlobalData> m_globalData; + Vector<Local<T>, inlineCapacity> m_stack; + unsigned m_count; +}; + +} + +#endif diff --git a/Source/JavaScriptCore/collector/handles/LocalScope.h b/Source/JavaScriptCore/collector/handles/LocalScope.h new file mode 100644 index 0000000..cd27b32 --- /dev/null +++ b/Source/JavaScriptCore/collector/handles/LocalScope.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LocalScope_h +#define LocalScope_h + +#include "HandleStack.h" +#include "Local.h" + +namespace JSC { +/* + A LocalScope is a temporary scope in which Locals are allocated. When a + LocalScope goes out of scope, all the Locals created in it are destroyed. + + LocalScope is similar in concept to NSAutoreleasePool. +*/ + +class JSGlobalData; + +class LocalScope { +public: + explicit LocalScope(JSGlobalData&); + ~LocalScope(); + + template <typename T> Local<T> release(Local<T>); // Destroys all other locals in the scope. + +private: + HandleStack* m_handleStack; + HandleStack::Frame m_lastFrame; +}; + +inline LocalScope::LocalScope(JSGlobalData& globalData) + : m_handleStack(globalData.heap.handleStack()) +{ + m_handleStack->enterScope(m_lastFrame); +} + +inline LocalScope::~LocalScope() +{ + m_handleStack->leaveScope(m_lastFrame); +} + +template <typename T> Local<T> LocalScope::release(Local<T> local) +{ + typename Local<T>::ExternalType ptr = local.get(); + + m_handleStack->leaveScope(m_lastFrame); + HandleSlot slot = m_handleStack->push(); + m_handleStack->enterScope(m_lastFrame); + + return Local<T>(slot, ptr); +} + +} + +#endif |