[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