Skip to content

Commit

Permalink
[JSC] Use synchronous GCActivityCallback GC with RunLoopObserver
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=265515
rdar://118930139

Reviewed by Wenson Hsieh.

Now we can schedule GC only when we are idle from GCActivityCallback. So we do not need to run async version.
This patch changes two things.

1. We set up RunLoopObserver and run GC when RunLoop gets idle state after GCActivityCallback detects GC opportunities.
2. We use sync GC instead of async GC since we now run this only when we are idle. We do not need to run async version.

* Source/JavaScriptCore/heap/EdenGCActivityCallback.cpp:
(JSC::EdenGCActivityCallback::EdenGCActivityCallback):
(JSC::EdenGCActivityCallback::doCollection):
* Source/JavaScriptCore/heap/EdenGCActivityCallback.h:
(JSC::EdenGCActivityCallback::tryCreate):
* Source/JavaScriptCore/heap/FullGCActivityCallback.cpp:
(JSC::FullGCActivityCallback::FullGCActivityCallback):
(JSC::FullGCActivityCallback::doCollection):
* Source/JavaScriptCore/heap/FullGCActivityCallback.h:
(JSC::FullGCActivityCallback::tryCreate):
* Source/JavaScriptCore/heap/GCActivityCallback.cpp:
(JSC::GCActivityCallback::GCActivityCallback):
* Source/JavaScriptCore/heap/GCActivityCallback.h:
* Source/JavaScriptCore/heap/Synchronousness.h:
* Source/WebCore/page/OpportunisticTaskScheduler.cpp:
(WebCore::OpportunisticTaskScheduler::FullGCActivityCallback::FullGCActivityCallback):
(WebCore::OpportunisticTaskScheduler::FullGCActivityCallback::doCollection):
(WebCore::OpportunisticTaskScheduler::EdenGCActivityCallback::EdenGCActivityCallback):
(WebCore::OpportunisticTaskScheduler::EdenGCActivityCallback::doCollection):
* Source/WebCore/page/OpportunisticTaskScheduler.h:

Canonical link: https://commits.webkit.org/271324@main
  • Loading branch information
Constellation committed Nov 30, 2023
1 parent c4e7c9c commit e0c479c
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 25 deletions.
6 changes: 3 additions & 3 deletions Source/JavaScriptCore/heap/EdenGCActivityCallback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@

namespace JSC {

EdenGCActivityCallback::EdenGCActivityCallback(Heap& heap)
: GCActivityCallback(heap)
EdenGCActivityCallback::EdenGCActivityCallback(Heap& heap, Synchronousness synchronousness)
: GCActivityCallback(heap, synchronousness)
{
}

Expand All @@ -40,7 +40,7 @@ EdenGCActivityCallback::~EdenGCActivityCallback() = default;
void EdenGCActivityCallback::doCollection(VM& vm)
{
setDidGCRecently(false);
vm.heap.collectAsync(CollectionScope::Eden);
vm.heap.collect(m_synchronousness, CollectionScope::Eden);
}

Seconds EdenGCActivityCallback::lastGCLength(Heap& heap)
Expand Down
6 changes: 3 additions & 3 deletions Source/JavaScriptCore/heap/EdenGCActivityCallback.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ namespace JSC {

class EdenGCActivityCallback : public GCActivityCallback {
public:
static RefPtr<EdenGCActivityCallback> tryCreate(Heap& heap)
static RefPtr<EdenGCActivityCallback> tryCreate(Heap& heap, Synchronousness synchronousness = Synchronousness::Async)
{
return s_shouldCreateGCTimer ? adoptRef(new EdenGCActivityCallback(heap)) : nullptr;
return s_shouldCreateGCTimer ? adoptRef(new EdenGCActivityCallback(heap, synchronousness)) : nullptr;
}

JS_EXPORT_PRIVATE void doCollection(VM&) override;

JS_EXPORT_PRIVATE EdenGCActivityCallback(Heap&);
JS_EXPORT_PRIVATE EdenGCActivityCallback(Heap&, Synchronousness);
JS_EXPORT_PRIVATE ~EdenGCActivityCallback();

private:
Expand Down
6 changes: 3 additions & 3 deletions Source/JavaScriptCore/heap/FullGCActivityCallback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@

namespace JSC {

FullGCActivityCallback::FullGCActivityCallback(Heap& heap)
: GCActivityCallback(heap)
FullGCActivityCallback::FullGCActivityCallback(Heap& heap, Synchronousness synchronousness)
: GCActivityCallback(heap, synchronousness)
{
}

Expand All @@ -52,7 +52,7 @@ void FullGCActivityCallback::doCollection(VM& vm)
}
#endif

heap.collectAsync(CollectionScope::Full);
heap.collect(m_synchronousness, CollectionScope::Full);
}

Seconds FullGCActivityCallback::lastGCLength(Heap& heap)
Expand Down
6 changes: 3 additions & 3 deletions Source/JavaScriptCore/heap/FullGCActivityCallback.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ namespace JSC {

class FullGCActivityCallback : public GCActivityCallback {
public:
static RefPtr<FullGCActivityCallback> tryCreate(Heap& heap)
static RefPtr<FullGCActivityCallback> tryCreate(Heap& heap, Synchronousness synchronousness = Synchronousness::Async)
{
return s_shouldCreateGCTimer ? adoptRef(new FullGCActivityCallback(heap)) : nullptr;
return s_shouldCreateGCTimer ? adoptRef(new FullGCActivityCallback(heap, synchronousness)) : nullptr;
}

JS_EXPORT_PRIVATE void doCollection(VM&) override;

JS_EXPORT_PRIVATE FullGCActivityCallback(Heap&);
JS_EXPORT_PRIVATE FullGCActivityCallback(Heap&, Synchronousness);
JS_EXPORT_PRIVATE ~FullGCActivityCallback();

private:
Expand Down
7 changes: 4 additions & 3 deletions Source/JavaScriptCore/heap/GCActivityCallback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,14 @@ bool GCActivityCallback::s_shouldCreateGCTimer = true;

const double timerSlop = 2.0; // Fudge factor to avoid performance cost of resetting timer.

GCActivityCallback::GCActivityCallback(Heap& heap)
: GCActivityCallback(heap.vm())
GCActivityCallback::GCActivityCallback(Heap& heap, Synchronousness synchronousness)
: GCActivityCallback(heap.vm(), synchronousness)
{
}

GCActivityCallback::GCActivityCallback(VM& vm)
GCActivityCallback::GCActivityCallback(VM& vm, Synchronousness synchronousness)
: Base(vm)
, m_synchronousness(synchronousness)
{
}

Expand Down
6 changes: 4 additions & 2 deletions Source/JavaScriptCore/heap/GCActivityCallback.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#pragma once

#include "JSRunLoopTimer.h"
#include "Synchronousness.h"
#include <wtf/RefPtr.h>

namespace JSC {
Expand All @@ -40,7 +41,7 @@ class GCActivityCallback : public JSRunLoopTimer {
public:
using Base = JSRunLoopTimer;

JS_EXPORT_PRIVATE GCActivityCallback(Heap&);
JS_EXPORT_PRIVATE GCActivityCallback(Heap&, Synchronousness);
JS_EXPORT_PRIVATE ~GCActivityCallback();

JS_EXPORT_PRIVATE void doWork(VM&) override;
Expand All @@ -63,8 +64,9 @@ class GCActivityCallback : public JSRunLoopTimer {
virtual double deathRate(Heap&) = 0;
JS_EXPORT_PRIVATE void scheduleTimer(Seconds);

GCActivityCallback(VM&);
GCActivityCallback(VM&, Synchronousness);

Synchronousness m_synchronousness { Synchronousness::Async };
bool m_enabled { true };
bool m_didGCRecently { false };
Seconds m_delay { s_decade };
Expand Down
2 changes: 1 addition & 1 deletion Source/JavaScriptCore/heap/Synchronousness.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

namespace JSC {

enum Synchronousness {
enum Synchronousness : uint8_t {
Async,
Sync
};
Expand Down
36 changes: 35 additions & 1 deletion Source/WebCore/page/OpportunisticTaskScheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,18 @@ static bool isBusyForTimerBasedGC()
return opportunisticSweepingAndGarbageCollectionEnabled && isVisibleAndActive && hasPendingTasks;
}

OpportunisticTaskScheduler::FullGCActivityCallback::FullGCActivityCallback(JSC::Heap& heap)
: Base(heap, JSC::Synchronousness::Sync)
, m_vm(heap.vm())
, m_runLoopObserver(makeUnique<RunLoopObserver>(RunLoopObserver::WellKnownOrder::PostRenderingUpdate, [this] {
JSC::JSLockHolder locker(m_vm);
m_version = 0;
m_deferCount = 0;
Base::doCollection(m_vm);
}, RunLoopObserver::Type::OneShot))
{
}

// We would like to keep FullGCActivityCallback::doCollection and EdenGCActivityCallback::doCollection separate
// since we would like to encode more and more different heuristics for them.
void OpportunisticTaskScheduler::FullGCActivityCallback::doCollection(JSC::VM& vm)
Expand All @@ -194,13 +206,30 @@ void OpportunisticTaskScheduler::FullGCActivityCallback::doCollection(JSC::VM& v
setTimeUntilFire(delay);
return;
}

m_runLoopObserver->invalidate();
m_runLoopObserver->schedule();
return;
}

JSC::JSLockHolder locker(m_vm);
m_version = 0;
m_deferCount = 0;
Base::doCollection(vm);
}

OpportunisticTaskScheduler::EdenGCActivityCallback::EdenGCActivityCallback(JSC::Heap& heap)
: Base(heap, JSC::Synchronousness::Sync)
, m_vm(heap.vm())
, m_runLoopObserver(makeUnique<RunLoopObserver>(RunLoopObserver::WellKnownOrder::PostRenderingUpdate, [this] {
JSC::JSLockHolder locker(m_vm);
m_version = 0;
m_deferCount = 0;
Base::doCollection(m_vm);
}, RunLoopObserver::Type::OneShot))
{
}

void OpportunisticTaskScheduler::EdenGCActivityCallback::doCollection(JSC::VM& vm)
{
constexpr Seconds delay { 10_ms };
Expand All @@ -220,11 +249,16 @@ void OpportunisticTaskScheduler::EdenGCActivityCallback::doCollection(JSC::VM& v
setTimeUntilFire(delay);
return;
}

m_runLoopObserver->invalidate();
m_runLoopObserver->schedule();
return;
}

JSC::JSLockHolder locker(m_vm);
m_version = 0;
m_deferCount = 0;
Base::doCollection(vm);
Base::doCollection(m_vm);
}

} // namespace WebCore
12 changes: 6 additions & 6 deletions Source/WebCore/page/OpportunisticTaskScheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ class OpportunisticTaskScheduler final : public RefCounted<OpportunisticTaskSche
void doCollection(JSC::VM&) final;

private:
FullGCActivityCallback(JSC::Heap& heap)
: Base(heap)
{ }
FullGCActivityCallback(JSC::Heap&);

JSC::VM& m_vm;
std::unique_ptr<RunLoopObserver> m_runLoopObserver;
JSC::HeapVersion m_version { 0 };
unsigned m_deferCount { 0 };
};
Expand All @@ -102,10 +102,10 @@ class OpportunisticTaskScheduler final : public RefCounted<OpportunisticTaskSche
void doCollection(JSC::VM&) final;

private:
EdenGCActivityCallback(JSC::Heap& heap)
: Base(heap)
{ }
EdenGCActivityCallback(JSC::Heap&);

JSC::VM& m_vm;
std::unique_ptr<RunLoopObserver> m_runLoopObserver;
JSC::HeapVersion m_version { 0 };
unsigned m_deferCount { 0 };
};
Expand Down

0 comments on commit e0c479c

Please sign in to comment.