1 /* 2 * Copyright (C) 2011 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 Strong_h 27 #define Strong_h 28 29 #include "Assertions.h" 30 #include "Handle.h" 31 #include "HandleHeap.h" 32 33 namespace JSC { 34 35 class JSGlobalData; 36 HandleSlot allocateGlobalHandle(JSGlobalData&); 37 38 // A strongly referenced handle that prevents the object it points to from being garbage collected. 39 template <typename T> class Strong : public Handle<T> { 40 using Handle<T>::slot; 41 using Handle<T>::setSlot; 42 43 public: 44 typedef typename Handle<T>::ExternalType ExternalType; 45 46 Strong() 47 : Handle<T>() 48 { 49 } 50 51 Strong(JSGlobalData& globalData, ExternalType value = ExternalType()) 52 : Handle<T>(allocateGlobalHandle(globalData)) 53 { 54 set(value); 55 } 56 57 Strong(JSGlobalData& globalData, Handle<T> handle) 58 : Handle<T>(allocateGlobalHandle(globalData)) 59 { 60 set(handle.get()); 61 } 62 63 Strong(const Strong& other) 64 : Handle<T>() 65 { 66 if (!other.slot()) 67 return; 68 setSlot(HandleHeap::heapFor(other.slot())->allocate()); 69 set(other.get()); 70 } 71 72 template <typename U> Strong(const Strong<U>& other) 73 : Handle<T>() 74 { 75 if (!other.slot()) 76 return; 77 setSlot(HandleHeap::heapFor(other.slot())->allocate()); 78 set(other.get()); 79 } 80 81 enum HashTableDeletedValueTag { HashTableDeletedValue }; 82 bool isHashTableDeletedValue() const { return slot() == hashTableDeletedValue(); } 83 Strong(HashTableDeletedValueTag) 84 : Handle<T>(hashTableDeletedValue()) 85 { 86 } 87 88 ~Strong() 89 { 90 clear(); 91 } 92 93 void swap(Strong& other) 94 { 95 Handle<T>::swap(other); 96 } 97 98 void set(JSGlobalData& globalData, ExternalType value) 99 { 100 if (!slot()) 101 setSlot(allocateGlobalHandle(globalData)); 102 set(value); 103 } 104 105 template <typename U> Strong& operator=(const Strong<U>& other) 106 { 107 if (!other.slot()) { 108 clear(); 109 return *this; 110 } 111 112 set(*HandleHeap::heapFor(other.slot())->globalData(), other.get()); 113 return *this; 114 } 115 116 Strong& operator=(const Strong& other) 117 { 118 if (!other.slot()) { 119 clear(); 120 return *this; 121 } 122 123 set(*HandleHeap::heapFor(other.slot())->globalData(), other.get()); 124 return *this; 125 } 126 127 void clear() 128 { 129 if (!slot()) 130 return; 131 HandleHeap::heapFor(slot())->deallocate(slot()); 132 setSlot(0); 133 } 134 135 private: 136 static HandleSlot hashTableDeletedValue() { return reinterpret_cast<HandleSlot>(-1); } 137 138 void set(ExternalType externalType) 139 { 140 ASSERT(slot()); 141 JSValue value = HandleTypes<T>::toJSValue(externalType); 142 HandleHeap::heapFor(slot())->writeBarrier(slot(), value); 143 *slot() = value; 144 } 145 }; 146 147 template<class T> inline void swap(Strong<T>& a, Strong<T>& b) 148 { 149 a.swap(b); 150 } 151 152 } // namespace JSC 153 154 namespace WTF { 155 156 template<typename T> struct VectorTraits<JSC::Strong<T> > : SimpleClassVectorTraits { 157 static const bool canCompareWithMemcmp = false; 158 }; 159 160 template<typename P> struct HashTraits<JSC::Strong<P> > : SimpleClassHashTraits<JSC::Strong<P> > { }; 161 162 } 163 164 #endif // Strong_h 165