https://bugs.webkit.org/show_bug.cgi?id=41318
authorggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Aug 2010 20:34:17 +0000 (20:34 +0000)
committerggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Aug 2010 20:34:17 +0000 (20:34 +0000)
GC should reclaim garbage even when new objects are not being allocated rapidly

Patch by Nathan Lawrence <nlawrence@apple.com> on 2010-08-03
Reviewed by Oliver Hunt.

Added a callback in JavaScriptCore that gets triggered after an
allocation causes the heap to reset.  This is useful for adding a
timer that will trigger garbage collection after the "last" allocation.

Also needed was to add lock and unlock methods to JSLock that needed
only a JSGlobalData object versus an ExecState object.

* CMakeLists.txt:
* GNUmakefile.am:
* JavaScriptCore.exp:
* JavaScriptCore.gypi:
* JavaScriptCore.pro:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_put_by_val):
* runtime/Collector.cpp:
(JSC::Heap::Heap):
(JSC::Heap::reset):
(JSC::Heap::setActivityCallback):
* runtime/Collector.h:
* runtime/GCActivityCallback.cpp: Added.
(JSC::DefaultGCActivityCallback::DefaultGCActivityCallback):
(JSC::DefaultGCActivityCallback::~DefaultGCActivityCallback):
(JSC::DefaultGCActivityCallback::operator()):
* runtime/GCActivityCallback.h: Added.
(JSC::GCActivityCallback::~GCActivityCallback):
(JSC::GCActivityCallback::operator()):
(JSC::GCActivityCallback::GCActivityCallback):
(JSC::DefaultGCActivityCallback::create):
* runtime/GCActivityCallbackCF.cpp: Added.
(JSC::DefaultGCActivityCallbackPlatformData::trigger):
(JSC::DefaultGCActivityCallback::DefaultGCActivityCallback):
(JSC::DefaultGCActivityCallback::~DefaultGCActivityCallback):
(JSC::DefaultGCActivityCallback::operator()):
* runtime/JSLock.cpp:
(JSC::JSLock::JSLock):
* runtime/JSLock.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@64585 268f45cc-cd09-0410-ab3c-d52691b4dbfc

15 files changed:
JavaScriptCore/CMakeLists.txt
JavaScriptCore/ChangeLog
JavaScriptCore/GNUmakefile.am
JavaScriptCore/JavaScriptCore.exp
JavaScriptCore/JavaScriptCore.gypi
JavaScriptCore/JavaScriptCore.pro
JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
JavaScriptCore/runtime/Collector.cpp
JavaScriptCore/runtime/Collector.h
JavaScriptCore/runtime/GCActivityCallback.cpp [new file with mode: 0644]
JavaScriptCore/runtime/GCActivityCallback.h [new file with mode: 0644]
JavaScriptCore/runtime/GCActivityCallbackCF.cpp [new file with mode: 0644]
JavaScriptCore/runtime/JSLock.cpp
JavaScriptCore/runtime/JSLock.h

index c33146d..9c3b07f 100644 (file)
@@ -103,6 +103,7 @@ SET(JavaScriptCore_SOURCES
     runtime/Executable.cpp
     runtime/FunctionConstructor.cpp
     runtime/FunctionPrototype.cpp
+    runtime/GCActivityCallback.cpp
     runtime/GetterSetter.cpp
     runtime/GlobalEvalFunction.cpp
     runtime/Identifier.cpp
index 186bf86..e7ef83f 100644 (file)
@@ -1,3 +1,49 @@
+2010-08-03  Nathan Lawrence  <nlawrence@apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        https://bugs.webkit.org/show_bug.cgi?id=41318
+        GC should reclaim garbage even when new objects are not being allocated rapidly
+
+        Added a callback in JavaScriptCore that gets triggered after an
+        allocation causes the heap to reset.  This is useful for adding a
+        timer that will trigger garbage collection after the "last" allocation.
+
+        Also needed was to add lock and unlock methods to JSLock that needed
+        only a JSGlobalData object versus an ExecState object.
+
+        * CMakeLists.txt:
+        * GNUmakefile.am:
+        * JavaScriptCore.exp:
+        * JavaScriptCore.gypi:
+        * JavaScriptCore.pro:
+        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emit_op_put_by_val):
+        * runtime/Collector.cpp:
+        (JSC::Heap::Heap):
+        (JSC::Heap::reset):
+        (JSC::Heap::setActivityCallback):
+        * runtime/Collector.h:
+        * runtime/GCActivityCallback.cpp: Added.
+        (JSC::DefaultGCActivityCallback::DefaultGCActivityCallback):
+        (JSC::DefaultGCActivityCallback::~DefaultGCActivityCallback):
+        (JSC::DefaultGCActivityCallback::operator()):
+        * runtime/GCActivityCallback.h: Added.
+        (JSC::GCActivityCallback::~GCActivityCallback):
+        (JSC::GCActivityCallback::operator()):
+        (JSC::GCActivityCallback::GCActivityCallback):
+        (JSC::DefaultGCActivityCallback::create):
+        * runtime/GCActivityCallbackCF.cpp: Added.
+        (JSC::DefaultGCActivityCallbackPlatformData::trigger):
+        (JSC::DefaultGCActivityCallback::DefaultGCActivityCallback):
+        (JSC::DefaultGCActivityCallback::~DefaultGCActivityCallback):
+        (JSC::DefaultGCActivityCallback::operator()):
+        * runtime/JSLock.cpp:
+        (JSC::JSLock::JSLock):
+        * runtime/JSLock.h:
+
 2010-08-02  Kevin Ollivier  <kevino@theolliviers.com>
 
         [wx] Build fix after removal of need to compile ExecutableAllocatorPosix.cpp
index 1dd15e4..7ee1246 100644 (file)
@@ -265,6 +265,8 @@ javascriptcore_sources += \
        JavaScriptCore/runtime/FunctionConstructor.h \
        JavaScriptCore/runtime/FunctionPrototype.cpp \
        JavaScriptCore/runtime/FunctionPrototype.h \
+       JavaScriptCore/runtime/GCActivityCallback.cpp \
+       JavaScriptCore/runtime/GCActivityCallback.h \
        JavaScriptCore/runtime/GetterSetter.cpp \
        JavaScriptCore/runtime/GetterSetter.h \
        JavaScriptCore/runtime/GlobalEvalFunction.cpp \
index b66d8df..5965681 100644 (file)
@@ -206,6 +206,7 @@ __ZN3JSC4Heap16objectTypeCountsEv
 __ZN3JSC4Heap16primaryHeapBeginEv
 __ZN3JSC4Heap17collectAllGarbageEv
 __ZN3JSC4Heap17globalObjectCountEv
+__ZN3JSC4Heap19setActivityCallbackEN3WTF10PassOwnPtrINS_18GCActivityCallbackEEE
 __ZN3JSC4Heap20protectedObjectCountEv
 __ZN3JSC4Heap25protectedObjectTypeCountsEv
 __ZN3JSC4Heap26protectedGlobalObjectCountEv
index 9281576..a902af9 100644 (file)
             'runtime/FunctionConstructor.h',
             'runtime/FunctionPrototype.cpp',
             'runtime/FunctionPrototype.h',
+            'runtime/GCActivityCallback.cpp',
+            'runtime/GCActivityCallback.h',
             'runtime/GetterSetter.cpp',
             'runtime/GetterSetter.h',
             'runtime/GlobalEvalFunction.cpp',
index 2489580..f30e50d 100644 (file)
@@ -139,6 +139,7 @@ SOURCES += \
     runtime/Executable.cpp \
     runtime/FunctionConstructor.cpp \
     runtime/FunctionPrototype.cpp \
+    runtime/GCActivityCallback.cpp \
     runtime/GetterSetter.cpp \
     runtime/GlobalEvalFunction.cpp \
     runtime/Identifier.cpp \
index 7819f99..c636687 100644 (file)
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath="..\..\runtime\GCActivityCallbackCF.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\runtime\GCActivityCallback.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath="..\..\runtime\GetterSetter.cpp"\r
                                >\r
                        </File>\r
index 9e86120..004d2c2 100644 (file)
                BCFD8C920EEB2EE700283848 /* JumpTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCFD8C900EEB2EE700283848 /* JumpTable.cpp */; };
                BCFD8C930EEB2EE700283848 /* JumpTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BCFD8C910EEB2EE700283848 /* JumpTable.h */; };
                C0A272630E50A06300E96E15 /* NotFound.h in Headers */ = {isa = PBXBuildFile; fileRef = C0A2723F0E509F1E00E96E15 /* NotFound.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, ); }; };
                E124A8F80E555775003091F1 /* OpaqueJSString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E124A8F60E555775003091F1 /* OpaqueJSString.cpp */; };
                E178636D0D9BEEC300D74E75 /* InitializeThreading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */; };
                C0A2723F0E509F1E00E96E15 /* NotFound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NotFound.h; sourceTree = "<group>"; };
                D21202280AD4310C00ED79B6 /* DateConversion.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DateConversion.cpp; sourceTree = "<group>"; };
                D21202290AD4310C00ED79B6 /* DateConversion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DateConversion.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>"; };
                E124A8F50E555775003091F1 /* OpaqueJSString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpaqueJSString.h; sourceTree = "<group>"; };
                E124A8F60E555775003091F1 /* OpaqueJSString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpaqueJSString.cpp; sourceTree = "<group>"; };
                7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = {
                        isa = PBXGroup;
                        children = (
+                               DDF7ABD211F60ED200108E36 /* GCActivityCallback.h */,
+                               DDF7ABD311F60ED200108E36 /* GCActivityCallbackCF.cpp */,
                                BCF605110E203EF800B9A64D /* ArgList.cpp */,
                                BCF605120E203EF800B9A64D /* ArgList.h */,
                                BC257DE50E1F51C50016B6C9 /* Arguments.cpp */,
                                868BFA18117CF19900B908B1 /* WTFString.h in Headers */,
                                86D08D5411793613006E5ED0 /* WTFThreadData.h in Headers */,
                                9688CB160ED12B4E001D649F /* X86Assembler.h in Headers */,
+                               DDF7ABD411F60ED200108E36 /* GCActivityCallback.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                E1EF79AA0CE97BA60088D500 /* UTF8.cpp in Sources */,
                                868BFA17117CF19900B908B1 /* WTFString.cpp in Sources */,
                                86D08D5311793613006E5ED0 /* WTFThreadData.cpp in Sources */,
+                               DDF7ABD511F60ED200108E36 /* GCActivityCallbackCF.cpp in Sources */,
                                8627E5EB11F1281900A313B5 /* PageAllocation.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
index 38f3ce5..4a56ede 100644 (file)
@@ -25,6 +25,7 @@
 #include "CallFrame.h"
 #include "CodeBlock.h"
 #include "CollectorHeapIterator.h"
+#include "GCActivityCallback.h"
 #include "Interpreter.h"
 #include "JSArray.h"
 #include "JSGlobalObject.h"
@@ -143,6 +144,8 @@ Heap::Heap(JSGlobalData* globalData)
     ASSERT(globalData);
     memset(&m_heap, 0, sizeof(CollectorHeap));
     allocateBlock();
+    m_activityCallback = DefaultGCActivityCallback::create(this);
+    (*m_activityCallback)();
 }
 
 Heap::~Heap()
@@ -1236,6 +1239,8 @@ void Heap::reset()
     resizeBlocks();
 
     JAVASCRIPTCORE_GC_END();
+
+    (*m_activityCallback)();
 }
 
 void Heap::collectAllGarbage()
@@ -1272,4 +1277,9 @@ LiveObjectIterator Heap::primaryHeapEnd()
     return LiveObjectIterator(m_heap, m_heap.usedBlocks);
 }
 
+void Heap::setActivityCallback(PassOwnPtr<GCActivityCallback> activityCallback)
+{
+    m_activityCallback = activityCallback;
+}
+
 } // namespace JSC
index 1dc9445..6657e42 100644 (file)
@@ -29,6 +29,7 @@
 #include <wtf/HashSet.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
 #include <wtf/StdLibExtras.h>
 #include <wtf/Threading.h>
 
@@ -45,6 +46,7 @@
 namespace JSC {
 
     class CollectorBlock;
+    class GCActivityCallback;
     class JSCell;
     class JSGlobalData;
     class JSValue;
@@ -82,6 +84,7 @@ namespace JSC {
 
         bool isBusy(); // true if an allocation or collection is in progress
         void collectAllGarbage();
+        void setActivityCallback(PassOwnPtr<GCActivityCallback>);
 
         static const size_t minExtraCost = 256;
         static const size_t maxExtraCost = 1024 * 1024;
@@ -165,6 +168,8 @@ namespace JSC {
 
         HashSet<MarkedArgumentBuffer*>* m_markListSet;
 
+        OwnPtr<GCActivityCallback> m_activityCallback;
+
 #if ENABLE(JSC_MULTIPLE_THREADS)
         void makeUsableFromMultipleThreads();
 
@@ -293,7 +298,6 @@ namespace JSC {
         m_heap.nextNumber = static_cast<char*>(result) + (CELL_SIZE / 2);
         return result;
     }
-
 } // namespace JSC
 
 #endif /* Collector_h */
diff --git a/JavaScriptCore/runtime/GCActivityCallback.cpp b/JavaScriptCore/runtime/GCActivityCallback.cpp
new file mode 100644 (file)
index 0000000..2f2c079
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 "GCActivityCallback.h"
+
+namespace JSC {
+
+struct DefaultGCActivityCallbackPlatformData {
+};
+
+DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap)
+{
+}
+
+DefaultGCActivityCallback::~DefaultGCActivityCallback()
+{
+}
+
+void DefaultGCActivityCallback::operator()()
+{
+}
+
+}
+
diff --git a/JavaScriptCore/runtime/GCActivityCallback.h b/JavaScriptCore/runtime/GCActivityCallback.h
new file mode 100644 (file)
index 0000000..66d56e8
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 GCActivityCallback_h
+#define GCActivityCallback_h
+
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace JSC {
+
+class Heap;
+
+class GCActivityCallback {
+public:
+    virtual ~GCActivityCallback() {}
+    virtual void operator()() {}
+
+protected:
+    GCActivityCallback() {}
+};
+
+struct DefaultGCActivityCallbackPlatformData;
+
+class DefaultGCActivityCallback : public GCActivityCallback {
+public:
+    static PassOwnPtr<DefaultGCActivityCallback> create(Heap*);
+
+    DefaultGCActivityCallback(Heap*);
+    ~DefaultGCActivityCallback();
+
+    void operator()();
+
+private:
+    OwnPtr<DefaultGCActivityCallbackPlatformData*> d;
+};
+
+inline PassOwnPtr<DefaultGCActivityCallback> DefaultGCActivityCallback::create(Heap* heap)
+{
+    return adoptPtr(new DefaultGCActivityCallback(heap));
+}
+
+}
+
+#endif
diff --git a/JavaScriptCore/runtime/GCActivityCallbackCF.cpp b/JavaScriptCore/runtime/GCActivityCallbackCF.cpp
new file mode 100644 (file)
index 0000000..aa92fc7
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * 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. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 "GCActivityCallback.h"
+
+#include "Collector.h"
+#include "JSLock.h"
+
+#if PLATFORM(CF)
+#include <CoreFoundation/CoreFoundation.h>
+
+namespace JSC {
+
+struct DefaultGCActivityCallbackPlatformData {
+    static void trigger(CFRunLoopTimerRef, void *info);
+
+    CFRunLoopTimerRef timer;
+    CFRunLoopTimerContext context;
+};
+
+const CFTimeInterval decade = 60 * 60 * 24 * 365 * 10;
+
+void DefaultGCActivityCallbackPlatformData::trigger(CFRunLoopTimerRef, void *info)
+{
+    Heap* heap = static_cast<Heap*>(info);
+    JSLock lock(heap->globalData());
+
+    heap->collectAllGarbage();
+}
+
+DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap)
+{
+    d = adoptPtr(new DefaultGCActivityCallbackPlatformData);
+
+    memset(&d->context, '\0', sizeof(CFRunLoopTimerContext));
+    d->context.info = heap;
+    d->timer = CFRunLoopTimerCreate(0, decade, decade, 0, 0, DefaultGCActivityCallbackPlatformData::trigger, &d->context);
+    CFRunLoopAddTimer(CFRunLoopGetCurrent(), d->timer, kCFRunLoopCommonModes);
+}
+
+DefaultGCActivityCallback::~DefaultGCActivityCallback()
+{
+    CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), d->timer, kCFRunLoopCommonModes);
+    CFRunLoopTimerInvalidate(d->timer);
+    d->context.info = 0;
+    d->timer = 0;
+}
+
+void DefaultGCActivityCallback::operator()()
+{
+    CFRunLoopTimerSetNextFireDate(d->timer, CFAbsoluteTimeGetCurrent() + 2);
+}
+
+}
+
+#endif
index a1cffbd..10f4f3f 100644 (file)
@@ -65,6 +65,12 @@ JSLock::JSLock(ExecState* exec)
     lock(m_lockBehavior);
 }
 
+JSLock::JSLock(JSGlobalData* globalData)
+    : m_lockBehavior(globalData->isSharedInstance() ? LockForReal : SilenceAssertionsOnly)
+{
+    lock(m_lockBehavior);
+}
+
 void JSLock::lock(JSLockBehavior lockBehavior)
 {
 #ifdef NDEBUG
index 8b015c4..05b388c 100644 (file)
@@ -49,12 +49,14 @@ namespace JSC {
     // assertions working, so that clients that use the shared context don't break.
 
     class ExecState;
+    class JSGlobalData;
 
     enum JSLockBehavior { SilenceAssertionsOnly, LockForReal };
 
     class JSLock : public Noncopyable {
     public:
         JSLock(ExecState*);
+        JSLock(JSGlobalData*);
 
         JSLock(JSLockBehavior lockBehavior)
             : m_lockBehavior(lockBehavior)