Bug 1150253 - Part 2: Gecko should provide a callback for SpiderMonkey to

enqueue the onGarbageCollection hook runnable; r=mccr8
This commit is contained in:
Nick Fitzgerald 2015-04-22 09:43:02 -07:00
parent 5f39b84c47
commit 3abd34129d
5 changed files with 108 additions and 0 deletions

View File

@ -60,6 +60,7 @@
#include "mozilla/AutoRestore.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/DebuggerOnGCRunnable.h"
#include "mozilla/dom/DOMJSClass.h"
#include "mozilla/dom/ScriptSettings.h"
#include "jsprf.h"
@ -466,6 +467,7 @@ CycleCollectedJSRuntime::CycleCollectedJSRuntime(JSRuntime* aParentRuntime,
: mGCThingCycleCollectorGlobal(sGCThingCycleCollectorGlobal)
, mJSZoneCycleCollectorGlobal(sJSZoneCycleCollectorGlobal)
, mJSRuntime(nullptr)
, mPrevGCSliceCallback(nullptr)
, mJSHolders(256)
, mOutOfMemoryState(OOMState::OK)
, mLargeAllocationFailureState(OOMState::OK)
@ -482,6 +484,7 @@ CycleCollectedJSRuntime::CycleCollectedJSRuntime(JSRuntime* aParentRuntime,
}
JS_SetGrayGCRootsTracer(mJSRuntime, TraceGrayJS, this);
JS_SetGCCallback(mJSRuntime, GCCallback, this);
mPrevGCSliceCallback = JS::SetGCSliceCallback(mJSRuntime, GCSliceCallback);
JS::SetOutOfMemoryCallback(mJSRuntime, OutOfMemoryCallback, this);
JS::SetLargeAllocationFailureCallback(mJSRuntime,
LargeAllocationFailureCallback, this);
@ -745,6 +748,23 @@ CycleCollectedJSRuntime::GCCallback(JSRuntime* aRuntime,
self->OnGC(aStatus);
}
/* static */ void
CycleCollectedJSRuntime::GCSliceCallback(JSRuntime* aRuntime,
JS::GCProgress aProgress,
const JS::GCDescription& aDesc)
{
CycleCollectedJSRuntime* self = CycleCollectedJSRuntime::Get();
MOZ_ASSERT(self->Runtime() == aRuntime);
if (aProgress == JS::GC_CYCLE_END) {
NS_WARN_IF(NS_FAILED(DebuggerOnGCRunnable::Enqueue(aRuntime, aDesc)));
}
if (self->mPrevGCSliceCallback) {
self->mPrevGCSliceCallback(aRuntime, aProgress, aDesc);
}
}
/* static */ void
CycleCollectedJSRuntime::OutOfMemoryCallback(JSContext* aContext,
void* aData)

View File

@ -194,6 +194,8 @@ private:
static void TraceBlackJS(JSTracer* aTracer, void* aData);
static void TraceGrayJS(JSTracer* aTracer, void* aData);
static void GCCallback(JSRuntime* aRuntime, JSGCStatus aStatus, void* aData);
static void GCSliceCallback(JSRuntime* aRuntime, JS::GCProgress aProgress,
const JS::GCDescription& aDesc);
static void OutOfMemoryCallback(JSContext* aContext, void* aData);
static void LargeAllocationFailureCallback(void* aData);
static bool ContextCallback(JSContext* aCx, unsigned aOperation,
@ -308,6 +310,8 @@ private:
JSRuntime* mJSRuntime;
JS::GCSliceCallback mPrevGCSliceCallback;
nsDataHashtable<nsPtrHashKey<void>, nsScriptObjectTracer*> mJSHolders;
typedef nsDataHashtable<nsFuncPtrHashKey<DeferredFinalizeFunction>, void*>

View File

@ -0,0 +1,47 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/DebuggerOnGCRunnable.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/CycleCollectedJSRuntime.h"
#include "mozilla/Move.h"
#include "js/Debug.h"
namespace mozilla {
/* static */ NS_METHOD
DebuggerOnGCRunnable::Enqueue(JSRuntime* aRt, const JS::GCDescription& aDesc)
{
auto gcEvent = aDesc.toGCEvent(aRt);
if (!gcEvent) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsRefPtr<DebuggerOnGCRunnable> runOnGC =
new DebuggerOnGCRunnable(Move(gcEvent));
return NS_DispatchToCurrentThread(runOnGC);
}
NS_IMETHODIMP
DebuggerOnGCRunnable::Run()
{
AutoJSAPI jsapi;
jsapi.Init();
if (!JS::dbg::FireOnGarbageCollectionHook(jsapi.cx(), Move(mGCData))) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
NS_IMETHODIMP
DebuggerOnGCRunnable::Cancel()
{
mGCData = nullptr;
return NS_OK;
}
} // namespace mozilla

View File

@ -0,0 +1,35 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_DebuggerOnGCRunnable_h
#define mozilla_DebuggerOnGCRunnable_h
#include "nsThreadUtils.h"
#include "js/GCAPI.h"
#include "mozilla/Move.h"
#include "mozilla/UniquePtr.h"
namespace mozilla {
// Runnable to fire the SpiderMonkey Debugger API's onGarbageCollection hook.
class DebuggerOnGCRunnable : public nsCancelableRunnable
{
JS::dbg::GarbageCollectionEvent::Ptr mGCData;
explicit DebuggerOnGCRunnable(JS::dbg::GarbageCollectionEvent::Ptr&& aGCData)
: mGCData(Move(aGCData))
{ }
public:
static NS_METHOD Enqueue(JSRuntime* aRt, const JS::GCDescription& aDesc);
NS_DECL_NSIRUNNABLE
NS_DECL_NSICANCELABLERUNNABLE
};
} // namespace mozilla
#endif // ifdef mozilla_dom_DebuggerOnGCRunnable_h

View File

@ -77,6 +77,7 @@ EXPORTS.mozilla += [
'CountingAllocatorBase.h',
'CycleCollectedJSRuntime.h',
'Debug.h',
'DebuggerOnGCRunnable.h',
'DeferredFinalize.h',
'ErrorNames.h',
'HoldDropJSObjects.h',
@ -101,6 +102,7 @@ UNIFIED_SOURCES += [
'ClearOnShutdown.cpp',
'CycleCollectedJSRuntime.cpp',
'Debug.cpp',
'DebuggerOnGCRunnable.cpp',
'DeferredFinalize.cpp',
'ErrorNames.cpp',
'HoldDropJSObjects.cpp',