Title: [89156] trunk/Source/_javascript_Core
Revision
89156
Author
gga...@apple.com
Date
2011-06-17 12:11:44 -0700 (Fri, 17 Jun 2011)

Log Message

2011-06-16  Geoffrey Garen  <gga...@apple.com>

        Reviewed by Oliver Hunt.

        Added some write barrier action, compiled out by default
        https://bugs.webkit.org/show_bug.cgi?id=62844

        * _javascript_Core.exp: Build!

        * _javascript_Core.xcodeproj/project.pbxproj: Fixed an incremental build
        issue with Heap.cpp.

        * heap/Heap.cpp:
        (JSC::Heap::writeBarrierSlowCase):
        * heap/Heap.h:
        (JSC::Heap::writeBarrier):
        * heap/MarkedBlock.h:
        (JSC::MarkedBlock::isAtomAligned):
        (JSC::MarkedBlock::blockFor):
        (JSC::MarkedBlock::atomNumber):
        (JSC::MarkedBlock::ownerSetNumber):
        (JSC::MarkedBlock::addOldSpaceOwner):
        (JSC::MarkedBlock::OwnerSet::OwnerSet):
        (JSC::MarkedBlock::OwnerSet::add):
        (JSC::MarkedBlock::OwnerSet::clear):
        (JSC::MarkedBlock::OwnerSet::size):
        (JSC::MarkedBlock::OwnerSet::didOverflow):
        (JSC::MarkedBlock::OwnerSet::owners): Added a basic write barrier that
        tracks owners for regions within blocks. Currently unused.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (89155 => 89156)


--- trunk/Source/_javascript_Core/ChangeLog	2011-06-17 19:11:14 UTC (rev 89155)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-06-17 19:11:44 UTC (rev 89156)
@@ -1,3 +1,33 @@
+2011-06-16  Geoffrey Garen  <gga...@apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        Added some write barrier action, compiled out by default
+        https://bugs.webkit.org/show_bug.cgi?id=62844
+
+        * _javascript_Core.exp: Build!
+
+        * _javascript_Core.xcodeproj/project.pbxproj: Fixed an incremental build
+        issue with Heap.cpp.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::writeBarrierSlowCase):
+        * heap/Heap.h:
+        (JSC::Heap::writeBarrier):
+        * heap/MarkedBlock.h:
+        (JSC::MarkedBlock::isAtomAligned):
+        (JSC::MarkedBlock::blockFor):
+        (JSC::MarkedBlock::atomNumber):
+        (JSC::MarkedBlock::ownerSetNumber):
+        (JSC::MarkedBlock::addOldSpaceOwner):
+        (JSC::MarkedBlock::OwnerSet::OwnerSet):
+        (JSC::MarkedBlock::OwnerSet::add):
+        (JSC::MarkedBlock::OwnerSet::clear):
+        (JSC::MarkedBlock::OwnerSet::size):
+        (JSC::MarkedBlock::OwnerSet::didOverflow):
+        (JSC::MarkedBlock::OwnerSet::owners): Added a basic write barrier that
+        tracks owners for regions within blocks. Currently unused.
+
 2011-06-17  Raphael Kubo da Costa  <k...@profusion.mobi>
 
         Reviewed by Eric Seidel.

Modified: trunk/Source/_javascript_Core/_javascript_Core.exp (89155 => 89156)


--- trunk/Source/_javascript_Core/_javascript_Core.exp	2011-06-17 19:11:14 UTC (rev 89155)
+++ trunk/Source/_javascript_Core/_javascript_Core.exp	2011-06-17 19:11:44 UTC (rev 89156)
@@ -227,6 +227,7 @@
 __ZN3JSC4Heap17isValidAllocationEm
 __ZN3JSC4Heap19setActivityCallbackEN3WTF10PassOwnPtrINS_18GCActivityCallbackEEE
 __ZN3JSC4Heap20protectedObjectCountEv
+__ZN3JSC4Heap20writeBarrierSlowCaseEPKNS_6JSCellEPS1_
 __ZN3JSC4Heap25protectedObjectTypeCountsEv
 __ZN3JSC4Heap26protectedGlobalObjectCountEv
 __ZN3JSC4Heap29reportExtraMemoryCostSlowCaseEm

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def (89155 => 89156)


--- trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def	2011-06-17 19:11:14 UTC (rev 89155)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def	2011-06-17 19:11:44 UTC (rev 89156)
@@ -374,6 +374,7 @@
     ?waitForThreadCompletion@WTF@@YAHIPAPAX@Z
     ?writable@PropertyDescriptor@JSC@@QBE_NXZ
     ?writeBarrier@HandleHeap@JSC@@QAEXPAVJSValue@2@ABV32@@Z
+    ?writeBarrierSlowCase@Heap@JSC@@CAXPBVJSCell@2@PAV32@@Z
     ?yield@WTF@@YAXXZ
     WTFLog
     WTFLogVerbose

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (89155 => 89156)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2011-06-17 19:11:14 UTC (rev 89155)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2011-06-17 19:11:44 UTC (rev 89156)
@@ -183,6 +183,8 @@
 		14B723B812D7DA6F003BD5ED /* MachineStackMarker.h in Headers */ = {isa = PBXBuildFile; fileRef = 14B7234012D7D0DA003BD5ED /* MachineStackMarker.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		14B8EC720A5652090062BE54 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6560A4CF04B3B3E7008AE952 /* CoreFoundation.framework */; };
 		14BA78F113AAB88F005B7C2C /* SlotVisitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 14BA78F013AAB88F005B7C2C /* SlotVisitor.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		14BA7A9713AADFF8005B7C2C /* Heap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BA7A9513AADFF8005B7C2C /* Heap.cpp */; };
+		14BA7A9813AADFF8005B7C2C /* Heap.h in Headers */ = {isa = PBXBuildFile; fileRef = 14BA7A9613AADFF8005B7C2C /* Heap.h */; };
 		14BD59C50A3E8F9F00BAF59C /* _javascript_Core.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* _javascript_Core.framework */; };
 		14BD5A300A3E91F600BAF59C /* JSContextRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BD5A290A3E91F600BAF59C /* JSContextRef.cpp */; };
 		14BD5A320A3E91F600BAF59C /* JSValueRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BD5A2B0A3E91F600BAF59C /* JSValueRef.cpp */; };
@@ -194,8 +196,6 @@
 		14F8BA3E107EC886009892DC /* FastMalloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65E217B908E7EECC0023E5F6 /* FastMalloc.cpp */; };
 		14F8BA43107EC88C009892DC /* TCSystemAlloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6541BD7008E80A17002CBEE7 /* TCSystemAlloc.cpp */; };
 		14F97447138C853E00DA1C67 /* HeapRootVisitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F97446138C853E00DA1C67 /* HeapRootVisitor.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		14FB986D135225410085A5DB /* Heap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14FB986B135225410085A5DB /* Heap.cpp */; };
-		14FB986E135225410085A5DB /* Heap.h in Headers */ = {isa = PBXBuildFile; fileRef = 14FB986C135225410085A5DB /* Heap.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		14FFF98C12BFFF7500795BB8 /* PageAllocationAligned.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14FFF98A12BFFF7500795BB8 /* PageAllocationAligned.cpp */; };
 		14FFF98D12BFFF7500795BB8 /* PageAllocationAligned.h in Headers */ = {isa = PBXBuildFile; fileRef = 14FFF98B12BFFF7500795BB8 /* PageAllocationAligned.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		180B9B080F16D94F009BDBC5 /* CurrentTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 180B9AF00F16C569009BDBC5 /* CurrentTime.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -815,6 +815,8 @@
 		14B7234012D7D0DA003BD5ED /* MachineStackMarker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachineStackMarker.h; sourceTree = "<group>"; };
 		14B8ECA60A5653980062BE54 /* _javascript_Core.exp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.exports; path = _javascript_Core.exp; sourceTree = "<group>"; tabWidth = 4; usesTabs = 0; };
 		14BA78F013AAB88F005B7C2C /* SlotVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlotVisitor.h; sourceTree = "<group>"; };
+		14BA7A9513AADFF8005B7C2C /* Heap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Heap.cpp; path = ../../../webkit/Source/_javascript_Core/heap/Heap.cpp; sourceTree = SOURCE_ROOT; };
+		14BA7A9613AADFF8005B7C2C /* Heap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Heap.h; path = ../../../webkit/Source/_javascript_Core/heap/Heap.h; sourceTree = SOURCE_ROOT; };
 		14BD59BF0A3E8F9000BAF59C /* testapi */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testapi; sourceTree = BUILT_PRODUCTS_DIR; };
 		14BD5A290A3E91F600BAF59C /* JSContextRef.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSContextRef.cpp; sourceTree = "<group>"; };
 		14BD5A2A0A3E91F600BAF59C /* JSContextRef.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSContextRef.h; sourceTree = "<group>"; };
@@ -830,8 +832,6 @@
 		14DE0D680D02431400AACCA2 /* JSGlobalObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalObject.cpp; sourceTree = "<group>"; };
 		14F252560D08DD8D004ECFFF /* JSVariableObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSVariableObject.h; sourceTree = "<group>"; };
 		14F97446138C853E00DA1C67 /* HeapRootVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapRootVisitor.h; sourceTree = "<group>"; };
-		14FB986B135225410085A5DB /* Heap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Heap.cpp; sourceTree = "<group>"; };
-		14FB986C135225410085A5DB /* Heap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Heap.h; sourceTree = "<group>"; };
 		14FFF98A12BFFF7500795BB8 /* PageAllocationAligned.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageAllocationAligned.cpp; sourceTree = "<group>"; };
 		14FFF98B12BFFF7500795BB8 /* PageAllocationAligned.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageAllocationAligned.h; sourceTree = "<group>"; };
 		180B9AEF0F16C569009BDBC5 /* CurrentTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CurrentTime.cpp; sourceTree = "<group>"; };
@@ -1500,8 +1500,8 @@
 				142E312E134FF0A600AFADB5 /* HandleStack.cpp */,
 				142E312F134FF0A600AFADB5 /* HandleStack.h */,
 				146FA5A81378F6B0003627A3 /* HandleTypes.h */,
-				14FB986B135225410085A5DB /* Heap.cpp */,
-				14FB986C135225410085A5DB /* Heap.h */,
+				14BA7A9513AADFF8005B7C2C /* Heap.cpp */,
+				14BA7A9613AADFF8005B7C2C /* Heap.h */,
 				14F97446138C853E00DA1C67 /* HeapRootVisitor.h */,
 				142E3130134FF0A600AFADB5 /* Local.h */,
 				142E3131134FF0A600AFADB5 /* LocalScope.h */,
@@ -2548,7 +2548,6 @@
 				86704B8A12DBA33700A9FE7B /* YarrPattern.h in Headers */,
 				86704B4312DB8A8100A9FE7B /* YarrSyntaxChecker.h in Headers */,
 				5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */,
-				14FB986E135225410085A5DB /* Heap.h in Headers */,
 				865A30F1135007E100CDB49E /* JSValueInlineMethods.h in Headers */,
 				142D6F0913539A2800B02E86 /* MarkedBlock.h in Headers */,
 				142D6F1213539A4100B02E86 /* MarkStack.h in Headers */,
@@ -2570,6 +2569,7 @@
 				141448CD13A1783700F5BA1A /* TinyBloomFilter.h in Headers */,
 				142A1D8413A19C84009DA5FE /* OldSpace.h in Headers */,
 				14BA78F113AAB88F005B7C2C /* SlotVisitor.h in Headers */,
+				14BA7A9813AADFF8005B7C2C /* Heap.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -3010,7 +3010,6 @@
 				86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */,
 				86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
 				86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
-				14FB986D135225410085A5DB /* Heap.cpp in Sources */,
 				142D6F0813539A2800B02E86 /* MarkedBlock.cpp in Sources */,
 				142D6F1113539A4100B02E86 /* MarkStack.cpp in Sources */,
 				86AE64A8135E5E1C00963012 /* MacroAssemblerSH4.cpp in Sources */,
@@ -3018,6 +3017,7 @@
 				86BB09C0138E381B0056702F /* DFGRepatch.cpp in Sources */,
 				14D2F3DA139F4BE200491031 /* NewSpace.cpp in Sources */,
 				142A1D8313A19C84009DA5FE /* OldSpace.cpp in Sources */,
+				14BA7A9713AADFF8005B7C2C /* Heap.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (89155 => 89156)


--- trunk/Source/_javascript_Core/heap/Heap.cpp	2011-06-17 19:11:14 UTC (rev 89155)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp	2011-06-17 19:11:44 UTC (rev 89156)
@@ -605,4 +605,19 @@
     freeBlocks(forEachBlock(takeIfEmpty));
 }
 
+#if ENABLE(GGC)
+void Heap::writeBarrierSlowCase(const JSCell* owner, JSCell* cell)
+{
+    if (!cell)
+        return;
+    MarkedBlock::blockFor(cell)->addOldSpaceOwner(owner, cell);
+}
+
+#else
+
+void Heap::writeBarrierSlowCase(const JSCell*, JSCell*)
+{
+}
+#endif
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/heap/Heap.h (89155 => 89156)


--- trunk/Source/_javascript_Core/heap/Heap.h	2011-06-17 19:11:14 UTC (rev 89155)
+++ trunk/Source/_javascript_Core/heap/Heap.h	2011-06-17 19:11:44 UTC (rev 89156)
@@ -141,6 +141,8 @@
 
         RegisterFile& registerFile();
 
+        static void writeBarrierSlowCase(const JSCell*, JSCell*);
+
         OperationInProgress m_operationInProgress;
         NewSpace m_newSpace;
         MarkedBlockSet m_blocks;
@@ -198,14 +200,34 @@
         MarkedBlock::blockFor(cell)->setMarked(cell);
     }
 
-    inline void Heap::writeBarrier(const JSCell*, JSValue)
+#if ENABLE(GGC)
+    inline void Heap::writeBarrier(const JSCell* owner, JSCell* cell)
     {
+        if (MarkedBlock::blockFor(owner)->inNewSpace())
+            return;
+        writeBarrierSlowCase(owner, cell);
     }
 
+    inline void Heap::writeBarrier(const JSCell* owner, JSValue value)
+    {
+        if (!value)
+            return;
+        if (!value.isCell())
+            return;
+        writeBarrier(owner, value.asCell());
+    }
+
+#else
+
     inline void Heap::writeBarrier(const JSCell*, JSCell*)
     {
     }
 
+    inline void Heap::writeBarrier(const JSCell*, JSValue)
+    {
+    }
+#endif
+
     inline void Heap::reportExtraMemoryCost(size_t cost)
     {
         if (cost > minExtraCost) 

Modified: trunk/Source/_javascript_Core/heap/MarkedBlock.h (89155 => 89156)


--- trunk/Source/_javascript_Core/heap/MarkedBlock.h	2011-06-17 19:11:14 UTC (rev 89155)
+++ trunk/Source/_javascript_Core/heap/MarkedBlock.h	2011-06-17 19:11:44 UTC (rev 89156)
@@ -42,14 +42,35 @@
     class MarkedBlock : public DoublyLinkedListNode<MarkedBlock> {
         friend class WTF::DoublyLinkedListNode<MarkedBlock>;
     public:
+        static const size_t atomSize = sizeof(double); // Ensures natural alignment for all built-in types.
+        static const size_t blockSize = 16 * KB;
+
+        static const size_t atomsPerBlock = blockSize / atomSize; // ~1.5% overhead
+        static const size_t ownerSetsPerBlock = 8; // ~2% overhead.
+
         struct VoidFunctor {
             typedef void ReturnType;
             void returnValue() { }
         };
 
-        static const size_t atomSize = sizeof(double); // Ensures natural alignment for all built-in types.
-        static const size_t blockSize = 16 * KB;
+        class OwnerSet {
+        public:
+            OwnerSet();
+            
+            void add(const JSCell*);
+            void clear();
 
+            size_t size();
+            bool didOverflow();
+            
+            const JSCell** owners();
+
+        private:
+            static const size_t capacity = 5;
+            unsigned char m_size;
+            const JSCell* m_owners[capacity];
+        };
+
         static MarkedBlock* create(Heap*, size_t cellSize);
         static void destroy(MarkedBlock*);
 
@@ -76,31 +97,33 @@
         size_t size();
         size_t capacity();
 
-        size_t atomNumber(const void*);
         bool isMarked(const void*);
         bool testAndSetMarked(const void*);
         bool testAndClearMarked(const void*);
         void setMarked(const void*);
-        
+
+        void addOldSpaceOwner(const JSCell* owner, const JSCell*);
+
         template <typename Functor> void forEachCell(Functor&);
 
     private:
         static const size_t blockMask = ~(blockSize - 1); // blockSize must be a power of two.
-
         static const size_t atomMask = ~(atomSize - 1); // atomSize must be a power of two.
-        
-        static const size_t atomsPerBlock = blockSize / atomSize;
 
         typedef char Atom[atomSize];
 
         MarkedBlock(const PageAllocationAligned&, Heap*, size_t cellSize);
         Atom* atoms();
 
+        size_t atomNumber(const void*);
+        size_t ownerSetNumber(const JSCell*);
+
         size_t m_nextAtom;
         size_t m_endAtom; // This is a fuzzy end. Always test for < m_endAtom.
         size_t m_atomsPerCell;
         WTF::Bitmap<blockSize / atomSize> m_marks;
         bool m_inNewSpace;
+        OwnerSet m_ownerSets[ownerSetsPerBlock];
         PageAllocationAligned m_allocation;
         Heap* m_heap;
         MarkedBlock* m_prev;
@@ -119,12 +142,12 @@
 
     inline bool MarkedBlock::isAtomAligned(const void* p)
     {
-        return !((intptr_t)(p) & ~atomMask);
+        return !(reinterpret_cast<Bits>(p) & ~atomMask);
     }
 
     inline MarkedBlock* MarkedBlock::blockFor(const void* p)
     {
-        return reinterpret_cast<MarkedBlock*>(reinterpret_cast<uintptr_t>(p) & blockMask);
+        return reinterpret_cast<MarkedBlock*>(reinterpret_cast<Bits>(p) & blockMask);
     }
 
     inline Heap* MarkedBlock::heap() const
@@ -181,7 +204,7 @@
 
     inline size_t MarkedBlock::atomNumber(const void* p)
     {
-        return (reinterpret_cast<uintptr_t>(p) - reinterpret_cast<uintptr_t>(this)) / atomSize;
+        return (reinterpret_cast<Bits>(p) - reinterpret_cast<Bits>(this)) / atomSize;
     }
 
     inline bool MarkedBlock::isMarked(const void* p)
@@ -227,7 +250,52 @@
 
         return 0;
     }
-    
+
+    inline size_t MarkedBlock::ownerSetNumber(const JSCell* cell)
+    {
+        return (reinterpret_cast<Bits>(cell) - reinterpret_cast<Bits>(this)) * ownerSetsPerBlock / blockSize;
+    }
+
+    inline void MarkedBlock::addOldSpaceOwner(const JSCell* owner, const JSCell* cell)
+    {
+        OwnerSet& ownerSet = m_ownerSets[ownerSetNumber(cell)];
+        ownerSet.add(owner);
+    }
+
+    inline MarkedBlock::OwnerSet::OwnerSet()
+        : m_size(0)
+    {
+    }
+
+    inline void MarkedBlock::OwnerSet::add(const JSCell* owner)
+    {
+        if (m_size < capacity) {
+            m_owners[m_size++] = owner;
+            return;
+        }
+        m_size = capacity + 1; // Signals overflow.
+    }
+
+    inline void MarkedBlock::OwnerSet::clear()
+    {
+        m_size = 0;
+    }
+
+    inline size_t MarkedBlock::OwnerSet::size()
+    {
+        return m_size;
+    }
+
+    inline bool MarkedBlock::OwnerSet::didOverflow()
+    {
+        return m_size > capacity;
+    }
+
+    inline const JSCell** MarkedBlock::OwnerSet::owners()
+    {
+        return m_owners;
+    }
+
 } // namespace JSC
 
 namespace WTF {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to