[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

commit-queue at webkit.org commit-queue at webkit.org
Wed Dec 22 11:46:46 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 9412cce3f19ec0e246660a107a341b7d01f4ce3f
Author: commit-queue at webkit.org <commit-queue at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Aug 6 14:55:54 2010 +0000

    2010-08-06  Nathan Lawrence  <nlawrence at apple.com>
    
            Reviewed by Geoffrey Garen.
    
            https://bugs.webkit.org/show_bug.cgi?id=43207
    
            WeakGCPtr's should instead of directly pointing to the GC'd object
            should be directed to an array of pointers that can be updated for
            movable objects.
    
            * Android.mk:
            * GNUmakefile.am:
            * JavaScriptCore.exp:
            * JavaScriptCore.gypi:
            * JavaScriptCore.pro:
            * JavaScriptCore.xcodeproj/project.pbxproj:
            * runtime/Collector.cpp:
            (JSC::Heap::destroy):
            (JSC::Heap::allocateBlock):
            (JSC::Heap::freeBlock):
            (JSC::Heap::updateWeakGCHandles):
            (JSC::WeakGCHandlePool::update):
            (JSC::Heap::addWeakGCHandle):
            (JSC::Heap::markRoots):
            * runtime/Collector.h:
            (JSC::Heap::weakGCHandlePool):
            * runtime/GCHandle.cpp: Added.
            (JSC::WeakGCHandle::pool):
            (JSC::WeakGCHandlePool::WeakGCHandlePool):
            (JSC::WeakGCHandlePool::allocate):
            (JSC::WeakGCHandlePool::free):
            (JSC::WeakGCHandlePool::operator new):
            * runtime/GCHandle.h: Added.
            (JSC::WeakGCHandle::isValidPtr):
            (JSC::WeakGCHandle::isPtr):
            (JSC::WeakGCHandle::isNext):
            (JSC::WeakGCHandle::invalidate):
            (JSC::WeakGCHandle::get):
            (JSC::WeakGCHandle::set):
            (JSC::WeakGCHandle::getNextInFreeList):
            (JSC::WeakGCHandle::setNextInFreeList):
            (JSC::WeakGCHandlePool::isFull):
            * runtime/WeakGCPtr.h:
            (JSC::WeakGCPtr::WeakGCPtr):
            (JSC::WeakGCPtr::~WeakGCPtr):
            (JSC::WeakGCPtr::get):
            (JSC::WeakGCPtr::clear):
            (JSC::WeakGCPtr::assign):
            (JSC::get):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@64849 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/Android.mk b/JavaScriptCore/Android.mk
index 1c715a1..8dd53c1 100644
--- a/JavaScriptCore/Android.mk
+++ b/JavaScriptCore/Android.mk
@@ -96,6 +96,7 @@ LOCAL_SRC_FILES := \
 	runtime/Executable.cpp \
 	runtime/FunctionConstructor.cpp \
 	runtime/FunctionPrototype.cpp \
+	runtime/GCHandle.cpp \
 	runtime/GetterSetter.cpp \
 	runtime/GlobalEvalFunction.cpp \
 	runtime/Identifier.cpp \
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 8ef8d69..ccccd78 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,53 @@
+2010-08-06  Nathan Lawrence  <nlawrence at apple.com>
+
+        Reviewed by Geoffrey Garen.
+
+        https://bugs.webkit.org/show_bug.cgi?id=43207
+
+        WeakGCPtr's should instead of directly pointing to the GC'd object
+        should be directed to an array of pointers that can be updated for
+        movable objects.
+
+        * Android.mk:
+        * GNUmakefile.am:
+        * JavaScriptCore.exp:
+        * JavaScriptCore.gypi:
+        * JavaScriptCore.pro:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * runtime/Collector.cpp:
+        (JSC::Heap::destroy):
+        (JSC::Heap::allocateBlock):
+        (JSC::Heap::freeBlock):
+        (JSC::Heap::updateWeakGCHandles):
+        (JSC::WeakGCHandlePool::update):
+        (JSC::Heap::addWeakGCHandle):
+        (JSC::Heap::markRoots):
+        * runtime/Collector.h:
+        (JSC::Heap::weakGCHandlePool):
+        * runtime/GCHandle.cpp: Added.
+        (JSC::WeakGCHandle::pool):
+        (JSC::WeakGCHandlePool::WeakGCHandlePool):
+        (JSC::WeakGCHandlePool::allocate):
+        (JSC::WeakGCHandlePool::free):
+        (JSC::WeakGCHandlePool::operator new):
+        * runtime/GCHandle.h: Added.
+        (JSC::WeakGCHandle::isValidPtr):
+        (JSC::WeakGCHandle::isPtr):
+        (JSC::WeakGCHandle::isNext):
+        (JSC::WeakGCHandle::invalidate):
+        (JSC::WeakGCHandle::get):
+        (JSC::WeakGCHandle::set):
+        (JSC::WeakGCHandle::getNextInFreeList):
+        (JSC::WeakGCHandle::setNextInFreeList):
+        (JSC::WeakGCHandlePool::isFull):
+        * runtime/WeakGCPtr.h:
+        (JSC::WeakGCPtr::WeakGCPtr):
+        (JSC::WeakGCPtr::~WeakGCPtr):
+        (JSC::WeakGCPtr::get):
+        (JSC::WeakGCPtr::clear):
+        (JSC::WeakGCPtr::assign):
+        (JSC::get):
+
 2010-08-06  Tor Arne Vestbø  <tor.arne.vestbo at nokia.com>
 
         Reviewed by Antonio Gomes.
diff --git a/JavaScriptCore/GNUmakefile.am b/JavaScriptCore/GNUmakefile.am
index 268471a..2ead8e0 100644
--- a/JavaScriptCore/GNUmakefile.am
+++ b/JavaScriptCore/GNUmakefile.am
@@ -268,6 +268,8 @@ javascriptcore_sources += \
 	JavaScriptCore/runtime/FunctionPrototype.h \
 	JavaScriptCore/runtime/GCActivityCallback.cpp \
 	JavaScriptCore/runtime/GCActivityCallback.h \
+	JavaScriptCore/runtime/GCHandle.cpp \
+	JavaScriptCore/runtime/GCHandle.h \
 	JavaScriptCore/runtime/GetterSetter.cpp \
 	JavaScriptCore/runtime/GetterSetter.h \
 	JavaScriptCore/runtime/GlobalEvalFunction.cpp \
diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp
index 5965681..eb1aa8d 100644
--- a/JavaScriptCore/JavaScriptCore.exp
+++ b/JavaScriptCore/JavaScriptCore.exp
@@ -141,6 +141,7 @@ __ZN3JSC12StringObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10Identifie
 __ZN3JSC12StringObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
 __ZN3JSC12StringObject4infoE
 __ZN3JSC12StringObjectC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEERKNS_7UStringE
+__ZN3JSC12WeakGCHandle4poolEv
 __ZN3JSC12jsNumberCellEPNS_9ExecStateEd
 __ZN3JSC12nonInlineNaNEv
 __ZN3JSC13SamplingFlags4stopEv
@@ -171,6 +172,7 @@ __ZN3JSC16InternalFunctionC2EPNS_12JSGlobalDataEPNS_14JSGlobalObjectEN3WTF17NonN
 __ZN3JSC16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
 __ZN3JSC16JSVariableObject14symbolTableGetERKNS_10IdentifierERNS_18PropertyDescriptorE
 __ZN3JSC16JSVariableObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
+__ZN3JSC16WeakGCHandlePool4freeEPNS_12WeakGCHandleE
 __ZN3JSC16createRangeErrorEPNS_9ExecStateERKNS_7UStringE
 __ZN3JSC16throwSyntaxErrorEPNS_9ExecStateE
 __ZN3JSC16toUInt32SlowCaseEdRb
@@ -201,6 +203,7 @@ __ZN3JSC25evaluateInGlobalCallFrameERKNS_7UStringERNS_7JSValueEPNS_14JSGlobalObj
 __ZN3JSC35createInterruptedExecutionExceptionEPNS_12JSGlobalDataE
 __ZN3JSC3NaNE
 __ZN3JSC4Heap14primaryHeapEndEv
+__ZN3JSC4Heap15addWeakGCHandleEPNS_6JSCellE
 __ZN3JSC4Heap15recordExtraCostEm
 __ZN3JSC4Heap16objectTypeCountsEv
 __ZN3JSC4Heap16primaryHeapBeginEv
diff --git a/JavaScriptCore/JavaScriptCore.gypi b/JavaScriptCore/JavaScriptCore.gypi
index e48d5eb..a85d11c 100644
--- a/JavaScriptCore/JavaScriptCore.gypi
+++ b/JavaScriptCore/JavaScriptCore.gypi
@@ -217,6 +217,8 @@
             'runtime/FunctionPrototype.h',
             'runtime/GCActivityCallback.cpp',
             'runtime/GCActivityCallback.h',
+            'runtime/GCHandle.cpp',
+            'runtime/GCHandle.h',
             'runtime/GetterSetter.cpp',
             'runtime/GetterSetter.h',
             'runtime/GlobalEvalFunction.cpp',
diff --git a/JavaScriptCore/JavaScriptCore.pro b/JavaScriptCore/JavaScriptCore.pro
index 88ca876..d6c4420 100644
--- a/JavaScriptCore/JavaScriptCore.pro
+++ b/JavaScriptCore/JavaScriptCore.pro
@@ -140,6 +140,7 @@ SOURCES += \
     runtime/FunctionConstructor.cpp \
     runtime/FunctionPrototype.cpp \
     runtime/GCActivityCallback.cpp \
+    runtime/GCHandle.cpp \
     runtime/GetterSetter.cpp \
     runtime/GlobalEvalFunction.cpp \
     runtime/Identifier.cpp \
diff --git a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index f3d324d..d85264d 100644
--- a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -512,6 +512,12 @@
 		DD2724681208D1FF00F9ABE7 /* AlignedMemoryAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = DD2724671208D1FF00F9ABE7 /* AlignedMemoryAllocator.h */; };
 		DD2724691208D1FF00F9ABE7 /* AlignedMemoryAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = DD2724671208D1FF00F9ABE7 /* AlignedMemoryAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		DD377CBC12072C18006A2517 /* Bitmap.h in Headers */ = {isa = PBXBuildFile; fileRef = DD377CBB12072C18006A2517 /* Bitmap.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		DDE82AD31209D955005C1756 /* GCHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDE82AD11209D955005C1756 /* GCHandle.cpp */; };
+		DDE82AD41209D955005C1756 /* GCHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDE82AD11209D955005C1756 /* GCHandle.cpp */; };
+		DDE82AD51209D955005C1756 /* GCHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDE82AD11209D955005C1756 /* GCHandle.cpp */; };
+		DDE82AD61209D955005C1756 /* GCHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = DDE82AD21209D955005C1756 /* GCHandle.h */; };
+		DDE82AD71209D955005C1756 /* GCHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDE82AD11209D955005C1756 /* GCHandle.cpp */; };
+		DDE82AD81209D955005C1756 /* GCHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = DDE82AD21209D955005C1756 /* GCHandle.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		DDF7ABD411F60ED200108E36 /* GCActivityCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = DDF7ABD211F60ED200108E36 /* GCActivityCallback.h */; };
 		DDF7ABD511F60ED200108E36 /* GCActivityCallbackCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDF7ABD311F60ED200108E36 /* GCActivityCallbackCF.cpp */; };
 		E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */ = {isa = PBXBuildFile; fileRef = E124A8F50E555775003091F1 /* OpaqueJSString.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -1058,6 +1064,8 @@
 		D21202290AD4310C00ED79B6 /* DateConversion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DateConversion.h; sourceTree = "<group>"; };
 		DD2724671208D1FF00F9ABE7 /* AlignedMemoryAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlignedMemoryAllocator.h; sourceTree = "<group>"; };
 		DD377CBB12072C18006A2517 /* Bitmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bitmap.h; sourceTree = "<group>"; };
+		DDE82AD11209D955005C1756 /* GCHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCHandle.cpp; sourceTree = "<group>"; };
+		DDE82AD21209D955005C1756 /* GCHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCHandle.h; sourceTree = "<group>"; };
 		DDF7ABD211F60ED200108E36 /* GCActivityCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCActivityCallback.h; sourceTree = "<group>"; };
 		DDF7ABD311F60ED200108E36 /* GCActivityCallbackCF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCActivityCallbackCF.cpp; sourceTree = "<group>"; };
 		E11D51750B2E798D0056C188 /* StringExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringExtras.h; sourceTree = "<group>"; };
@@ -1624,6 +1632,8 @@
 				BC2680C10E16D4E900A06E92 /* FunctionConstructor.h */,
 				F692A85C0255597D01FF60F7 /* FunctionPrototype.cpp */,
 				F692A85D0255597D01FF60F7 /* FunctionPrototype.h */,
+				DDE82AD11209D955005C1756 /* GCHandle.cpp */,
+				DDE82AD21209D955005C1756 /* GCHandle.h */,
 				BC02E9B80E184545000F9297 /* GetterSetter.cpp */,
 				BC337BDE0E1AF0B80076918A /* GetterSetter.h */,
 				BC257DED0E1F52ED0016B6C9 /* GlobalEvalFunction.cpp */,
@@ -1912,6 +1922,7 @@
 				144005CC0A5338F80005F061 /* Node.h in Headers */,
 				1440074A0A536CC20005F061 /* NodeList.h in Headers */,
 				DD2724681208D1FF00F9ABE7 /* AlignedMemoryAllocator.h in Headers */,
+				DDE82AD61209D955005C1756 /* GCHandle.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2214,6 +2225,7 @@
 				9688CB160ED12B4E001D649F /* X86Assembler.h in Headers */,
 				DDF7ABD411F60ED200108E36 /* GCActivityCallback.h in Headers */,
 				DD2724691208D1FF00F9ABE7 /* AlignedMemoryAllocator.h in Headers */,
+				DDE82AD81209D955005C1756 /* GCHandle.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2475,6 +2487,7 @@
 				141211340A48795800480255 /* minidom.c in Sources */,
 				1440063F0A53598A0005F061 /* Node.c in Sources */,
 				1440074B0A536CC20005F061 /* NodeList.c in Sources */,
+				DDE82AD51209D955005C1756 /* GCHandle.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2483,6 +2496,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				1440F6100A4F85670005F061 /* testapi.c in Sources */,
+				DDE82AD41209D955005C1756 /* GCHandle.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2662,6 +2676,7 @@
 				86D08D5311793613006E5ED0 /* WTFThreadData.cpp in Sources */,
 				DDF7ABD511F60ED200108E36 /* GCActivityCallbackCF.cpp in Sources */,
 				8627E5EB11F1281900A313B5 /* PageAllocation.cpp in Sources */,
+				DDE82AD71209D955005C1756 /* GCHandle.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2670,6 +2685,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				932F5BDD0822A1C700736975 /* jsc.cpp in Sources */,
+				DDE82AD31209D955005C1756 /* GCHandle.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/JavaScriptCore/runtime/Collector.cpp b/JavaScriptCore/runtime/Collector.cpp
index 4bf73a3..4a81913 100644
--- a/JavaScriptCore/runtime/Collector.cpp
+++ b/JavaScriptCore/runtime/Collector.cpp
@@ -170,6 +170,9 @@ void Heap::destroy()
 
     freeBlocks();
 
+    for (unsigned i = 0; i < m_weakGCHandlePools.size(); ++i)
+        m_weakGCHandlePools[i].deallocate();
+
 #if ENABLE(JSC_MULTIPLE_THREADS)
     if (m_currentThreadRegistrar) {
         int error = pthread_key_delete(m_currentThreadRegistrar);
@@ -189,7 +192,7 @@ void Heap::destroy()
 
 NEVER_INLINE CollectorBlock* Heap::allocateBlock()
 {
-    AlignedBlock allocation = m_blockallocator.allocate();
+    AlignedCollectorBlock allocation = m_blockallocator.allocate();
     CollectorBlock* block = static_cast<CollectorBlock*>(allocation.base());
     if (!block)
         CRASH();
@@ -207,12 +210,12 @@ NEVER_INLINE CollectorBlock* Heap::allocateBlock()
 
     size_t numBlocks = m_heap.numBlocks;
     if (m_heap.usedBlocks == numBlocks) {
-        static const size_t maxNumBlocks = ULONG_MAX / sizeof(AlignedBlock) / GROWTH_FACTOR;
+        static const size_t maxNumBlocks = ULONG_MAX / sizeof(AlignedCollectorBlock) / GROWTH_FACTOR;
         if (numBlocks > maxNumBlocks)
             CRASH();
         numBlocks = max(MIN_ARRAY_SIZE, numBlocks * GROWTH_FACTOR);
         m_heap.numBlocks = numBlocks;
-        m_heap.blocks = static_cast<AlignedBlock*>(fastRealloc(m_heap.blocks, numBlocks * sizeof(AlignedBlock)));
+        m_heap.blocks = static_cast<AlignedCollectorBlock*>(fastRealloc(m_heap.blocks, numBlocks * sizeof(AlignedCollectorBlock)));
     }
     m_heap.blocks[m_heap.usedBlocks++] = allocation;
 
@@ -235,7 +238,7 @@ NEVER_INLINE void Heap::freeBlock(size_t block)
 
     if (m_heap.numBlocks > MIN_ARRAY_SIZE && m_heap.usedBlocks < m_heap.numBlocks / LOW_WATER_FACTOR) {
         m_heap.numBlocks = m_heap.numBlocks / GROWTH_FACTOR; 
-        m_heap.blocks = static_cast<AlignedBlock*>(fastRealloc(m_heap.blocks, m_heap.numBlocks * sizeof(AlignedBlock)));
+        m_heap.blocks = static_cast<AlignedCollectorBlock*>(fastRealloc(m_heap.blocks, m_heap.numBlocks * sizeof(AlignedCollectorBlock)));
     }
 }
 
@@ -906,6 +909,36 @@ void Heap::markStackObjectsConservatively(MarkStack& markStack)
 #endif
 }
 
+void Heap::updateWeakGCHandles()
+{
+    for (unsigned i = 0; i < m_weakGCHandlePools.size(); ++i)
+        weakGCHandlePool(i)->update();
+}
+
+void WeakGCHandlePool::update()
+{
+    for (unsigned i = 1; i < WeakGCHandlePool::numPoolEntries; ++i) {
+        if (m_entries[i].isValidPtr()) {
+            JSCell* cell = m_entries[i].get();
+            if (!cell || !Heap::isCellMarked(cell))
+                m_entries[i].invalidate();
+        }
+    }
+}
+
+WeakGCHandle* Heap::addWeakGCHandle(JSCell* ptr)
+{
+    for (unsigned i = 0; i < m_weakGCHandlePools.size(); ++i)
+        if (!weakGCHandlePool(i)->isFull())
+            return weakGCHandlePool(i)->allocate(ptr);
+
+    AlignedMemory<WeakGCHandlePool::poolSize> allocation = m_weakGCHandlePoolAllocator.allocate();
+    m_weakGCHandlePools.append(allocation);
+
+    WeakGCHandlePool* pool = new (allocation) WeakGCHandlePool();
+    return pool->allocate(ptr);
+}
+
 void Heap::protect(JSValue k)
 {
     ASSERT(k);
@@ -1042,6 +1075,8 @@ void Heap::markRoots()
     markStack.drain();
     markStack.compact();
 
+    updateWeakGCHandles();
+
     m_heap.operationInProgress = NoOperation;
 }
 
diff --git a/JavaScriptCore/runtime/Collector.h b/JavaScriptCore/runtime/Collector.h
index 7e4051f..38c178b 100644
--- a/JavaScriptCore/runtime/Collector.h
+++ b/JavaScriptCore/runtime/Collector.h
@@ -23,6 +23,7 @@
 #define Collector_h
 
 #include "AlignedMemoryAllocator.h"
+#include "GCHandle.h"
 #include <stddef.h>
 #include <string.h>
 #include <wtf/Bitmap.h>
@@ -62,13 +63,13 @@ namespace JSC {
     const size_t BLOCK_SIZE = 256 * 1024; // 256k
 #endif
 
-    typedef AlignedMemoryAllocator<BLOCK_SIZE> AlignedAllocator;
-    typedef AlignedMemory<BLOCK_SIZE> AlignedBlock;
+    typedef AlignedMemoryAllocator<BLOCK_SIZE> CollectorBlockAllocator;
+    typedef AlignedMemory<BLOCK_SIZE> AlignedCollectorBlock;
 
     struct CollectorHeap {
         size_t nextBlock;
         size_t nextCell;
-        AlignedBlock* blocks;
+        AlignedCollectorBlock* blocks;
         
         void* nextNumber;
 
@@ -131,6 +132,8 @@ namespace JSC {
         static bool isCellMarked(const JSCell*);
         static void markCell(JSCell*);
 
+        WeakGCHandle* addWeakGCHandle(JSCell*);
+
         void markConservatively(MarkStack&, void* start, void* end);
 
         HashSet<MarkedArgumentBuffer*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<MarkedArgumentBuffer*>; return *m_markListSet; }
@@ -172,11 +175,15 @@ namespace JSC {
         void markOtherThreadConservatively(MarkStack&, Thread*);
         void markStackObjectsConservatively(MarkStack&);
 
+        void updateWeakGCHandles();
+        WeakGCHandlePool* weakGCHandlePool(size_t index);
+
         typedef HashCountedSet<JSCell*> ProtectCountSet;
 
         CollectorHeap m_heap;
 
         ProtectCountSet m_protectedValues;
+        WTF::Vector<AlignedMemory<WeakGCHandlePool::poolSize> > m_weakGCHandlePools;
 
         HashSet<MarkedArgumentBuffer*>* m_markListSet;
 
@@ -194,7 +201,8 @@ namespace JSC {
 #endif
 
         // Allocates collector blocks with correct alignment
-        AlignedAllocator m_blockallocator; 
+        CollectorBlockAllocator m_blockallocator; 
+        WeakGCHandlePool::Allocator m_weakGCHandlePoolAllocator; 
         
         JSGlobalData* m_globalData;
     };
@@ -302,6 +310,12 @@ namespace JSC {
         m_heap.nextNumber = static_cast<char*>(result) + (CELL_SIZE / 2);
         return result;
     }
+
+
+    inline WeakGCHandlePool* Heap::weakGCHandlePool(size_t index)
+    {
+        return static_cast<WeakGCHandlePool*>(m_weakGCHandlePools[index].base());
+    }
 } // namespace JSC
 
 #endif /* Collector_h */
diff --git a/JavaScriptCore/runtime/GCHandle.cpp b/JavaScriptCore/runtime/GCHandle.cpp
new file mode 100644
index 0000000..3331517
--- /dev/null
+++ b/JavaScriptCore/runtime/GCHandle.cpp
@@ -0,0 +1,91 @@
+/*
+ * 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 "GCHandle.h"
+
+namespace JSC {
+
+WeakGCHandlePool* WeakGCHandle::pool()
+{
+    uintptr_t pool = (reinterpret_cast<uintptr_t>(this) & WeakGCHandlePool::poolMask);
+    return reinterpret_cast<WeakGCHandlePool*>(pool);
+}
+
+WeakGCHandlePool::WeakGCHandlePool()
+{
+    ASSERT(sizeof(WeakGCHandlePool) <= WeakGCHandlePool::poolSize);
+    m_entriesSize = 0;
+    m_initialAlloc = 1;
+    m_entries[0].setNextInFreeList(0);
+}
+
+WeakGCHandle* WeakGCHandlePool::allocate(JSCell* cell)
+{
+    ASSERT(cell);
+    ASSERT(m_entries[0].isNext());
+    unsigned freeList = m_entries[0].getNextInFreeList();
+    ASSERT(freeList < WeakGCHandlePool::numPoolEntries);
+    ASSERT(m_entriesSize < WeakGCHandlePool::numPoolEntries);
+
+    if (m_entriesSize == WeakGCHandlePool::numPoolEntries - 1)
+        return 0;
+
+    if (freeList) {
+        unsigned i = freeList;
+        freeList = m_entries[i].getNextInFreeList();
+        m_entries[i].set(cell);
+        m_entries[0].setNextInFreeList(freeList);
+        ++m_entriesSize;
+        return &m_entries[i];
+    }
+
+    ASSERT(m_initialAlloc < WeakGCHandlePool::numPoolEntries);
+
+    unsigned i = m_initialAlloc;
+    ++m_initialAlloc;
+    m_entries[i].set(cell);
+    ++m_entriesSize;
+    return &m_entries[i];
+
+}
+
+void WeakGCHandlePool::free(WeakGCHandle* handle)
+{
+    ASSERT(handle->pool() == this);
+    ASSERT(m_entries[0].isNext());
+    unsigned freeList = m_entries[0].getNextInFreeList();
+    ASSERT(freeList < WeakGCHandlePool::numPoolEntries);
+    handle->setNextInFreeList(freeList);
+    m_entries[0].setNextInFreeList(handle - m_entries);
+    --m_entriesSize;
+}
+
+void* WeakGCHandlePool::operator new(size_t, AlignedMemory<WeakGCHandlePool::poolSize>& allocation)
+{
+    return allocation.base();
+}
+
+}
diff --git a/JavaScriptCore/runtime/GCHandle.h b/JavaScriptCore/runtime/GCHandle.h
new file mode 100644
index 0000000..38a7be9
--- /dev/null
+++ b/JavaScriptCore/runtime/GCHandle.h
@@ -0,0 +1,120 @@
+/*
+ * 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 GCHandle_h
+#define GCHandle_h
+
+#include "AlignedMemoryAllocator.h"
+
+namespace JSC {
+
+class Heap;
+class JSCell;
+class WeakGCHandle;
+class WeakGCHandlePool;
+
+class WeakGCHandle {
+    friend class WeakGCHandlePool;
+
+public:
+    // Because JSCell objects are aligned, we can use the lower two bits as
+    // status flags. The least significant bit is set when the handle is not a
+    // pointer, i.e. when it's used as a offset for the free list in
+    // WeakGCHandlePool. The second least significant bit is set when the object
+    // the pointer corresponds to has been deleted by a garbage collection
+
+    bool isValidPtr() { return !(m_ptr & 3); }
+    bool isPtr() { return !(m_ptr & 1); }
+    bool isNext() { return (m_ptr & 3) == 1; }
+
+    void invalidate()
+    {
+        ASSERT(isValidPtr());
+        m_ptr |= 2;
+    }
+
+    JSCell* get()
+    {
+        ASSERT(isPtr());
+        return reinterpret_cast<JSCell*>(m_ptr & ~3);
+    }
+
+    void set(JSCell* p)
+    {
+        m_ptr = reinterpret_cast<uintptr_t>(p);
+        ASSERT(isPtr());
+    }
+
+    WeakGCHandlePool* pool();
+
+private:
+    uintptr_t getNextInFreeList()
+    {
+        ASSERT(isNext());
+        return m_ptr >> 2;
+    }
+
+    void setNextInFreeList(uintptr_t n)
+    {
+        m_ptr = (n << 2) | 1;
+        ASSERT(isNext());
+    }
+
+    uintptr_t m_ptr;
+};
+
+class WeakGCHandlePool {
+public:
+    static const size_t poolSize = 32 * 1024; // 32k
+    static const size_t poolMask = ~(poolSize - 1);
+    static const size_t numPoolEntries = (poolSize - sizeof(Heap*) - 3 * sizeof(unsigned)) / sizeof(WeakGCHandle);
+
+    typedef AlignedMemoryAllocator<WeakGCHandlePool::poolSize> Allocator;
+
+    WeakGCHandlePool();
+
+    WeakGCHandle* allocate(JSCell* cell);
+    void free(WeakGCHandle*);
+
+    bool isFull()
+    {
+        ASSERT(m_entriesSize < WeakGCHandlePool::numPoolEntries);
+        return m_entriesSize == WeakGCHandlePool::numPoolEntries - 1;
+    }
+
+    void update();
+
+    void* operator new(size_t, AlignedMemory<WeakGCHandlePool::poolSize>&);
+
+private:
+    Heap* m_heap;
+    unsigned m_entriesSize;
+    unsigned m_initialAlloc;
+
+    WeakGCHandle m_entries[WeakGCHandlePool::numPoolEntries];
+};
+
+}
+#endif
diff --git a/JavaScriptCore/runtime/WeakGCPtr.h b/JavaScriptCore/runtime/WeakGCPtr.h
index 9dce858..ac77cf3 100644
--- a/JavaScriptCore/runtime/WeakGCPtr.h
+++ b/JavaScriptCore/runtime/WeakGCPtr.h
@@ -27,6 +27,7 @@
 #define WeakGCPtr_h
 
 #include "Collector.h"
+#include "GCHandle.h"
 #include <wtf/Noncopyable.h>
 
 namespace JSC {
@@ -34,23 +35,34 @@ namespace JSC {
 // A smart pointer whose get() function returns 0 for cells awaiting destruction.
 template <typename T> class WeakGCPtr : Noncopyable {
 public:
-    WeakGCPtr() : m_ptr(0) { }
+    WeakGCPtr()
+        : m_ptr(0)
+    {
+    }
+
     WeakGCPtr(T* ptr) { assign(ptr); }
 
+    ~WeakGCPtr()
+    {
+        if (m_ptr)
+            m_ptr->pool()->free(m_ptr);
+    }
+
     T* get() const
     {
-        if (!m_ptr || !Heap::isCellMarked(m_ptr))
-            return 0;
-        return m_ptr;
+        if (m_ptr && m_ptr->isValidPtr())
+            return static_cast<T*>(m_ptr->get());
+        return 0;
     }
     
-    bool clear(JSCell* ptr)
+    bool clear(JSCell* p)
     {
-        if (ptr == m_ptr) {
-            m_ptr = 0;
-            return true;
-        }
-        return false;
+        if (!m_ptr || m_ptr->get() != p)
+            return false;
+
+        m_ptr->pool()->free(m_ptr);
+        m_ptr = 0;
+        return true;
     }
 
     T& operator*() const { return *get(); }
@@ -62,7 +74,7 @@ public:
 #if COMPILER(WINSCW)
     operator bool() const { return m_ptr; }
 #else
-    typedef T* WeakGCPtr::*UnspecifiedBoolType;
+    typedef WeakGCHandle* WeakGCPtr::*UnspecifiedBoolType;
     operator UnspecifiedBoolType() const { return get() ? &WeakGCPtr::m_ptr : 0; }
 #endif
 
@@ -73,14 +85,16 @@ public:
 #endif
 
 private:
-    void assign(T* ptr)
+    void assign(JSCell* ptr)
     {
         ASSERT(ptr);
-        Heap::markCell(ptr);
-        m_ptr = ptr;
+        if (m_ptr)
+            m_ptr->set(ptr);
+        else
+            m_ptr = Heap::heap(ptr)->addWeakGCHandle(ptr);
     }
 
-    T* m_ptr;
+    WeakGCHandle* m_ptr;
 };
 
 template <typename T> inline WeakGCPtr<T>& WeakGCPtr<T>::operator=(T* optr)
@@ -129,7 +143,7 @@ template <typename T, typename U> inline WeakGCPtr<T> const_pointer_cast(const W
     return WeakGCPtr<T>(const_cast<T*>(p.get())); 
 }
 
-template <typename T> inline T* getPtr(const WeakGCPtr<T>& p)
+template <typename T> inline T* get(const WeakGCPtr<T>& p)
 {
     return p.get();
 }

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list