Ignore:
Timestamp:
Feb 16, 2012, 5:56:13 PM (13 years ago)
Author:
[email protected]
Message:

Made Weak<T> single-owner, adding PassWeak<T>
https://bugs.webkit.org/show_bug.cgi?id=78740

Reviewed by Sam Weinig.

Source/JavaScriptCore:

This works basically the same way as OwnPtr<T> and PassOwnPtr<T>.

This clarifies the semantics of finalizers: It's ambiguous and probably
a bug to copy a finalizer (i.e., it's a bug to run a C++ destructor
twice), so I've made Weak<T> non-copyable. Anywhere we used to copy a
Weak<T>, we now use PassWeak<T>.

This also makes Weak<T> HashMaps more efficient.

  • API/JSClassRef.cpp:

(OpaqueJSClass::prototype): Use PassWeak<T> instead of set(), since
set() is gone now.

  • heap/PassWeak.h: Added.

(JSC):
(PassWeak):
(JSC::PassWeak::PassWeak):
(JSC::PassWeak::~PassWeak):
(JSC::PassWeak::get):
(JSC::::leakHandle):
(JSC::adoptWeak):
(JSC::operator==):
(JSC::operator!=): This is the Weak<T> version of PassOwnPtr<T>.

  • heap/Weak.h:

(Weak):
(JSC::Weak::Weak):
(JSC::Weak::release):
(JSC::Weak::hashTableDeletedValue):
(JSC::=):
(JSC): Changed to be non-copyable, removing a lot of copying-related
APIs. Added hash traits so hash maps still work.

  • jit/JITStubs.cpp:

(JSC::JITThunks::hostFunctionStub):

  • runtime/RegExpCache.cpp:

(JSC::RegExpCache::lookupOrCreate): Use PassWeak<T>, as required by
our new hash map API.

Source/WebCore:

  • bindings/js/JSDOMBinding.cpp:

(WebCore::jsStringSlowCase): Use PassWeak<T>, as required by our new
hash map API.

  • bindings/js/JSDOMBinding.h:

(WebCore::getCachedWrapper):
(WebCore::cacheWrapper): Use PassWeak<T> and raw pointer, as required by
our new hash map API.

  • bindings/js/JSEventListener.h:

(WebCore::JSEventListener::setWrapper):

  • bindings/js/ScriptWrappable.h:

(WebCore::ScriptWrappable::setWrapper):

  • bridge/jsc/BridgeJSC.cpp:

(JSC::Bindings::Instance::createRuntimeObject):

  • bridge/runtime_root.cpp:

(JSC::Bindings::RootObject::addRuntimeObject): Use PassWeak<T>, as
required by our new hash map and Weak<T> APIs.

Source/WebKit2:

  • WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp:

(WebKit::NPRuntimeObjectMap::getOrCreateJSObject): Use raw pointer and
PassWeak<T>, as required by our new hash map API.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/heap/Weak.h

    r96465 r108010  
    11/*
    2  * Copyright (C) 2009 Apple Inc. All rights reserved.
     2 * Copyright (C) 2009, 2012 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3131#include "HandleHeap.h"
    3232#include "JSGlobalData.h"
     33#include "PassWeak.h"
    3334
    3435namespace JSC {
     
    3637// A weakly referenced handle that becomes 0 when the value it points to is garbage collected.
    3738template <typename T> class Weak : public Handle<T> {
     39    WTF_MAKE_NONCOPYABLE(Weak);
     40
    3841    using Handle<T>::slot;
    3942    using Handle<T>::setSlot;
     
    4750    }
    4851
    49     Weak(JSGlobalData& globalData, ExternalType value = ExternalType(), WeakHandleOwner* weakOwner = 0, void* context = 0)
     52    Weak(std::nullptr_t)
     53        : Handle<T>()
     54    {
     55    }
     56
     57    Weak(JSGlobalData& globalData, ExternalType externalType = ExternalType(), WeakHandleOwner* weakOwner = 0, void* context = 0)
    5058        : Handle<T>(globalData.heap.handleHeap()->allocate())
    5159    {
    5260        HandleHeap::heapFor(slot())->makeWeak(slot(), weakOwner, context);
    53         set(value);
     61        JSValue value = HandleTypes<T>::toJSValue(externalType);
     62        HandleHeap::heapFor(slot())->writeBarrier(slot(), value);
     63        *slot() = value;
    5464    }
    5565
     
    6070        validateCell(get());
    6171    }
    62    
    63     Weak(const Weak& other)
    64         : Handle<T>()
    65     {
    66         if (!other.slot())
    67             return;
    68         setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
    69     }
    7072
    71     template <typename U> Weak(const Weak<U>& other)
    72         : Handle<T>()
    73     {
    74         if (!other.slot())
    75             return;
    76         setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
    77     }
    78    
    7973    enum HashTableDeletedValueTag { HashTableDeletedValue };
    8074    bool isHashTableDeletedValue() const { return slot() == hashTableDeletedValue(); }
    8175    Weak(HashTableDeletedValueTag)
    8276        : Handle<T>(hashTableDeletedValue())
     77    {
     78    }
     79
     80    template<typename U> Weak(const PassWeak<U>& other)
     81        : Handle<T>(other.leakHandle())
    8382    {
    8483    }
     
    9493    }
    9594
     95    Weak& operator=(const PassWeak<T>&);
     96
    9697    ExternalType get() const { return  HandleTypes<T>::getFromSlot(slot()); }
    9798   
     99    PassWeak<T> release() { PassWeak<T> tmp = adoptWeak<T>(slot()); setSlot(0); return tmp; }
     100
    98101    void clear()
    99102    {
     
    102105        HandleHeap::heapFor(slot())->deallocate(slot());
    103106        setSlot(0);
    104     }
    105    
    106     void set(JSGlobalData& globalData, ExternalType value, WeakHandleOwner* weakOwner = 0, void* context = 0)
    107     {
    108         if (!slot()) {
    109             setSlot(globalData.heap.handleHeap()->allocate());
    110             HandleHeap::heapFor(slot())->makeWeak(slot(), weakOwner, context);
    111         }
    112         ASSERT(HandleHeap::heapFor(slot())->hasWeakOwner(slot(), weakOwner));
    113         set(value);
    114     }
    115 
    116     template <typename U> Weak& operator=(const Weak<U>& other)
    117     {
    118         clear();
    119         if (other.slot())
    120             setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
    121         return *this;
    122     }
    123 
    124     Weak& operator=(const Weak& other)
    125     {
    126         clear();
    127         if (other.slot())
    128             setSlot(HandleHeap::heapFor(other.slot())->copyWeak(other.slot()));
    129         return *this;
    130107    }
    131108   
     
    140117private:
    141118    static HandleSlot hashTableDeletedValue() { return reinterpret_cast<HandleSlot>(-1); }
    142 
    143     void set(ExternalType externalType)
    144     {
    145         ASSERT(slot());
    146         JSValue value = HandleTypes<T>::toJSValue(externalType);
    147         HandleHeap::heapFor(slot())->writeBarrier(slot(), value);
    148         *slot() = value;
    149     }
    150119};
    151120
     
    153122{
    154123    a.swap(b);
     124}
     125
     126template<typename T> inline Weak<T>& Weak<T>::operator=(const PassWeak<T>& o)
     127{
     128    clear();
     129    setSlot(o.leakHandle());
     130    return *this;
    155131}
    156132
     
    163139};
    164140
    165 template<typename P> struct HashTraits<JSC::Weak<P> > : SimpleClassHashTraits<JSC::Weak<P> > { };
     141template<typename T> struct HashTraits<JSC::Weak<T> > : SimpleClassHashTraits<JSC::Weak<T> > {
     142    typedef JSC::Weak<T> StorageType;
     143
     144    typedef std::nullptr_t EmptyValueType;
     145    static EmptyValueType emptyValue() { return EmptyValueType(); }
     146
     147    typedef JSC::PassWeak<T> PassInType;
     148    static void store(PassInType value, StorageType& storage) { storage = value; }
     149
     150    typedef JSC::PassWeak<T> PassOutType;
     151    static PassOutType passOut(StorageType& value) { return value.release(); }
     152    static PassOutType passOut(EmptyValueType) { return PassOutType(); }
     153
     154    typedef typename StorageType::ExternalType PeekType;
     155    static PeekType peek(const StorageType& value) { return value.get(); }
     156    static PeekType peek(EmptyValueType) { return PeekType(); }
     157};
    166158
    167159}
Note: See TracChangeset for help on using the changeset viewer.