]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - heap/Weak.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / heap / Weak.h
index a235a570b820a371cf541ee213e01013a683efd5..80cdbd82c66d6204e0838087ebb47c661e6b54b7 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2012, 2013 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #ifndef Weak_h
 #define Weak_h
 
 #ifndef Weak_h
 #define Weak_h
 
-#include "Assertions.h"
-#include "Handle.h"
-#include "HandleHeap.h"
-#include "JSGlobalData.h"
+#include <cstddef>
+#include <wtf/Noncopyable.h>
 
 namespace JSC {
 
 
 namespace JSC {
 
-// A weakly referenced handle that becomes 0 when the value it points to is garbage collected.
-template <typename T> class Weak : public Handle<T> {
-    using Handle<T>::slot;
-    using Handle<T>::setSlot;
+class WeakImpl;
+class WeakHandleOwner;
 
 
-public:
-    typedef typename Handle<T>::ExternalType ExternalType;
+// This is a free function rather than a Weak<T> member function so we can put it in Weak.cpp.
+JS_EXPORT_PRIVATE void weakClearSlowCase(WeakImpl*&);
 
 
+template<typename T> class Weak {
+    WTF_MAKE_NONCOPYABLE(Weak);
+public:
     Weak()
     Weak()
-        : Handle<T>()
+        : m_impl(0)
     {
     }
 
     {
     }
 
-    Weak(JSGlobalData& globalData, ExternalType value = ExternalType(), WeakHandleOwner* weakOwner = 0, void* context = 0)
-        : Handle<T>(globalData.allocateGlobalHandle())
+    Weak(std::nullptr_t)
+        : m_impl(0)
     {
     {
-        HandleHeap::heapFor(slot())->makeWeak(slot(), weakOwner, context);
-        set(value);
     }
 
     }
 
-    enum AdoptTag { Adopt };
-    template<typename U> Weak(AdoptTag, Handle<U> handle)
-        : Handle<T>(handle.slot())
-    {
-        validateCell(get());
-    }
-    
-    Weak(const Weak& other)
-        : Handle<T>()
-    {
-        if (!other.slot())
-            return;
-        setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
-    }
+    Weak(T*, WeakHandleOwner* = 0, void* context = 0);
 
 
-    template <typename U> Weak(const Weak<U>& other)
-        : Handle<T>()
-    {
-        if (!other.slot())
-            return;
-        setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
-    }
-    
     enum HashTableDeletedValueTag { HashTableDeletedValue };
     enum HashTableDeletedValueTag { HashTableDeletedValue };
-    bool isHashTableDeletedValue() const { return slot() == hashTableDeletedValue(); }
-    Weak(HashTableDeletedValueTag)
-        : Handle<T>(hashTableDeletedValue())
-    {
-    }
+    bool isHashTableDeletedValue() const;
+    Weak(HashTableDeletedValueTag);
+
+    Weak(Weak&&);
 
     ~Weak()
     {
         clear();
     }
 
 
     ~Weak()
     {
         clear();
     }
 
-    void swap(Weak& other)
-    {
-        Handle<T>::swap(other);
-    }
+    void swap(Weak&);
 
 
-    ExternalType get() const { return  HandleTypes<T>::getFromSlot(slot()); }
-    
-    void clear()
-    {
-        if (!slot())
-            return;
-        HandleHeap::heapFor(slot())->deallocate(slot());
-        setSlot(0);
-    }
-    
-    void set(JSGlobalData& globalData, ExternalType value, WeakHandleOwner* weakOwner = 0, void* context = 0)
-    {
-        if (!slot()) {
-            setSlot(globalData.allocateGlobalHandle());
-            HandleHeap::heapFor(slot())->makeWeak(slot(), weakOwner, context);
-        }
-        ASSERT(HandleHeap::heapFor(slot())->hasWeakOwner(slot(), weakOwner));
-        set(value);
-    }
+    Weak& operator=(Weak&&);
 
 
-    template <typename U> Weak& operator=(const Weak<U>& other)
-    {
-        clear();
-        if (other.slot())
-            setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
-        return *this;
-    }
+    bool operator!() const;
+    T* operator->() const;
+    T& operator*() const;
+    T* get() const;
 
 
-    Weak& operator=(const Weak& other)
+    bool was(T*) const;
+
+    // This conversion operator allows implicit conversion to bool but not to other integer types.
+    typedef void* (Weak::*UnspecifiedBoolType);
+    operator UnspecifiedBoolType*() const;
+
+    WeakImpl* leakImpl() WARN_UNUSED_RETURN;
+    void clear()
     {
     {
-        clear();
-        if (other.slot())
-            setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
-        return *this;
+        if (!m_impl)
+            return;
+        weakClearSlowCase(m_impl);
     }
     
     }
     
-    HandleSlot leakHandle()
-    {
-        ASSERT(HandleHeap::heapFor(slot())->hasFinalizer(slot()));
-        HandleSlot result = slot();
-        setSlot(0);
-        return result;
-    }
-
 private:
 private:
-    static HandleSlot hashTableDeletedValue() { return reinterpret_cast<HandleSlot>(-1); }
+    static WeakImpl* hashTableDeletedValue();
 
 
-    void set(ExternalType externalType)
-    {
-        ASSERT(slot());
-        JSValue value = HandleTypes<T>::toJSValue(externalType);
-        ASSERT(!value || !value.isCell() || Heap::isMarked(value.asCell()));
-        HandleHeap::heapFor(slot())->writeBarrier(slot(), value);
-        *slot() = value;
-    }
+    WeakImpl* m_impl;
 };
 
 };
 
-template<class T> inline void swap(Weak<T>& a, Weak<T>& b)
-{
-    a.swap(b);
-}
-
 } // namespace JSC
 
 } // namespace JSC
 
-namespace WTF {
-
-template<typename T> struct VectorTraits<JSC::Weak<T> > : SimpleClassVectorTraits {
-    static const bool canCompareWithMemcmp = false;
-};
-
-template<typename P> struct HashTraits<JSC::Weak<P> > : SimpleClassHashTraits<JSC::Weak<P> > { };
-
-}
-
 #endif // Weak_h
 #endif // Weak_h