mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 12:25:53 +00:00
Merge m-i to m-c
This commit is contained in:
commit
7f4dcbf266
@ -116,6 +116,7 @@ run-if = crashreporter
|
||||
[browser_CTP_resize.js]
|
||||
[browser_URLBarSetURI.js]
|
||||
[browser_aboutAccounts.js]
|
||||
skip-if = os == "linux" # Bug 958026
|
||||
[browser_aboutHealthReport.js]
|
||||
skip-if = os == "linux" # Bug 924307
|
||||
[browser_aboutHome.js]
|
||||
|
@ -2331,7 +2331,7 @@ PerformanceStatisticsView.prototype = {
|
||||
sorted: true,
|
||||
totals: {
|
||||
size: L10N.getStr("charts.totalSize"),
|
||||
time: L10N.getStr("charts.totalTime"),
|
||||
time: L10N.getStr("charts.totalTime2"),
|
||||
cached: L10N.getStr("charts.totalCached"),
|
||||
count: L10N.getStr("charts.totalCount")
|
||||
}
|
||||
@ -2353,7 +2353,7 @@ PerformanceStatisticsView.prototype = {
|
||||
sorted: true,
|
||||
totals: {
|
||||
size: L10N.getStr("charts.totalSize"),
|
||||
time: L10N.getStr("charts.totalTime"),
|
||||
time: L10N.getStr("charts.totalTime2"),
|
||||
cached: L10N.getStr("charts.totalCached"),
|
||||
count: L10N.getStr("charts.totalCount")
|
||||
}
|
||||
@ -2452,7 +2452,7 @@ PerformanceStatisticsView.prototype = {
|
||||
let size = L10N.numberWithDecimals(chartItem.size / 1024, CONTENT_SIZE_DECIMALS);
|
||||
let time = L10N.numberWithDecimals(chartItem.time / 1000, REQUEST_TIME_DECIMALS);
|
||||
chartItem.size = L10N.getFormatStr("charts.sizeKB", size);
|
||||
chartItem.time = L10N.getFormatStr("charts.totalMS", time);
|
||||
chartItem.time = L10N.getFormatStr("charts.totalS", time);
|
||||
}
|
||||
|
||||
return data.filter(e => e.count > 0);
|
||||
|
@ -120,6 +120,7 @@ support-files =
|
||||
[browser_console_click_focus.js]
|
||||
[browser_console_consolejsm_output.js]
|
||||
[browser_console_dead_objects.js]
|
||||
skip-if = true # bug 963869
|
||||
[browser_console_error_source_click.js]
|
||||
[browser_console_filters.js]
|
||||
[browser_console_iframe_messages.js]
|
||||
|
@ -136,10 +136,6 @@ networkMenu.second=%S s
|
||||
# in the network menu specifying timing interval divisions (in minutes).
|
||||
networkMenu.minute=%S min
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.minute): This is the label displayed
|
||||
# in the network menu specifying timing interval divisions (in minutes).
|
||||
networkMenu.minute=%S min
|
||||
|
||||
# LOCALIZATION NOTE (pieChart.empty): This is the label displayed
|
||||
# for pie charts (e.g., in the performance analysis view) when there is
|
||||
# no data available yet.
|
||||
@ -154,9 +150,9 @@ tableChart.empty=Please wait…
|
||||
# in pie or table charts specifying the size of a request (in kilobytes).
|
||||
charts.sizeKB=%S KB
|
||||
|
||||
# LOCALIZATION NOTE (charts.totalMS): This is the label displayed
|
||||
# in pie or table charts specifying the time for a request to finish (in milliseconds).
|
||||
charts.totalMS=%S ms
|
||||
# LOCALIZATION NOTE (charts.totalS): This is the label displayed
|
||||
# in pie or table charts specifying the time for a request to finish (in seconds).
|
||||
charts.totalS=%S s
|
||||
|
||||
# LOCALIZATION NOTE (charts.cacheEnabled): This is the label displayed
|
||||
# in the performance analysis view for "cache enabled" charts.
|
||||
@ -170,9 +166,9 @@ charts.cacheDisabled=Empty cache
|
||||
# in the performance analysis view for total requests size, in kilobytes.
|
||||
charts.totalSize=Size: %S KB
|
||||
|
||||
# LOCALIZATION NOTE (charts.totalTime): This is the label displayed
|
||||
# in the performance analysis view for total requests time, in milliseconds.
|
||||
charts.totalTime=Time: %S ms
|
||||
# LOCALIZATION NOTE (charts.totalTime2): This is the label displayed
|
||||
# in the performance analysis view for total requests time, in seconds.
|
||||
charts.totalTime2=Time: %S seconds
|
||||
|
||||
# LOCALIZATION NOTE (charts.totalCached): This is the label displayed
|
||||
# in the performance analysis view for total cached responses.
|
||||
|
@ -49,3 +49,14 @@
|
||||
obj:/lib64/libgobject-2.0.so.0.2200.5
|
||||
...
|
||||
}
|
||||
{
|
||||
Bug 966673
|
||||
Memcheck:Leak
|
||||
fun:malloc
|
||||
obj:/lib64/libresolv-2.12.so
|
||||
...
|
||||
fun:gaih_inet
|
||||
fun:getaddrinfo
|
||||
fun:PR_GetAddrInfoByName
|
||||
...
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
conformance/limits/gl-max-texture-dimensions.html
|
||||
conformance/misc/type-conversion-test.html
|
||||
conformance/more/conformance/quickCheckAPI-B2.html
|
||||
conformance/reading/read-pixels-test.html
|
||||
conformance/textures/texture-mips.html
|
||||
|
@ -27,11 +27,6 @@
|
||||
# * workers - Indicates whether the descriptor is intended to be used solely
|
||||
# for worker threads (defaults to false). If true the interface
|
||||
# will not be made available on the main thread.
|
||||
# * customFinalize - The native class will use a custom finalize hook
|
||||
# (defaults to true for workers, false otherwise).
|
||||
# * customWrapperManagement - The native class will be responsible for
|
||||
# preserving its own wrapper (no AddProperty
|
||||
# hook will be generated, defaults to false).
|
||||
# * notflattened - The native type does not have nsIClassInfo, so when
|
||||
# wrapping it the right IID needs to be passed in.
|
||||
# * register - True if this binding should be registered. Defaults to true.
|
||||
@ -221,8 +216,6 @@ DOMInterfaces = {
|
||||
'ChromeWorker': {
|
||||
'headerFile': 'mozilla/dom/WorkerPrivate.h',
|
||||
'nativeType': 'mozilla::dom::workers::ChromeWorkerPrivate',
|
||||
'customFinalize': True,
|
||||
'customWrapperManagement': True,
|
||||
},
|
||||
|
||||
'DOMRectList': {
|
||||
@ -1526,8 +1519,6 @@ DOMInterfaces = {
|
||||
'implicitJSContext': [
|
||||
'terminate',
|
||||
],
|
||||
'customFinalize': True,
|
||||
'customWrapperManagement': True,
|
||||
},
|
||||
|
||||
'WorkerGlobalScope': {
|
||||
|
@ -45,7 +45,7 @@ def isTypeCopyConstructible(type):
|
||||
|
||||
def wantsAddProperty(desc):
|
||||
return desc.concrete and \
|
||||
desc.wrapperCache and not desc.customWrapperManagement and \
|
||||
desc.wrapperCache and \
|
||||
not desc.interface.getExtendedAttribute("Global")
|
||||
|
||||
class CGThing():
|
||||
@ -1078,18 +1078,15 @@ def DeferredFinalizeSmartPtr(descriptor):
|
||||
return smartPtr
|
||||
|
||||
def finalizeHook(descriptor, hookName, freeOp):
|
||||
if descriptor.customFinalize:
|
||||
finalize = "self->%s(CastToJSFreeOp(%s));" % (hookName, freeOp)
|
||||
else:
|
||||
finalize = "JSBindingFinalized<%s>::Finalized(self);\n" % descriptor.nativeType
|
||||
if descriptor.wrapperCache:
|
||||
finalize += "ClearWrapper(self, self);\n"
|
||||
if descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
|
||||
finalize += "self->mExpandoAndGeneration.expando = JS::UndefinedValue();\n"
|
||||
if descriptor.interface.getExtendedAttribute("Global"):
|
||||
finalize += "mozilla::dom::FinalizeGlobal(CastToJSFreeOp(%s), obj);\n" % freeOp
|
||||
finalize += ("AddForDeferredFinalization<%s, %s >(self);" %
|
||||
(descriptor.nativeType, DeferredFinalizeSmartPtr(descriptor)))
|
||||
finalize = "JSBindingFinalized<%s>::Finalized(self);\n" % descriptor.nativeType
|
||||
if descriptor.wrapperCache:
|
||||
finalize += "ClearWrapper(self, self);\n"
|
||||
if descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
|
||||
finalize += "self->mExpandoAndGeneration.expando = JS::UndefinedValue();\n"
|
||||
if descriptor.interface.getExtendedAttribute("Global"):
|
||||
finalize += "mozilla::dom::FinalizeGlobal(CastToJSFreeOp(%s), obj);\n" % freeOp
|
||||
finalize += ("AddForDeferredFinalization<%s, %s >(self);" %
|
||||
(descriptor.nativeType, DeferredFinalizeSmartPtr(descriptor)))
|
||||
return CGIfWrapper(CGGeneric(finalize), "self")
|
||||
|
||||
class CGClassFinalizeHook(CGAbstractClassHook):
|
||||
@ -10961,7 +10958,7 @@ class CGCallback(CGClass):
|
||||
"eReportExceptions"))
|
||||
# And now insert our template argument.
|
||||
argsWithoutThis = list(args)
|
||||
args.insert(0, Argument("const T&", "thisObj"))
|
||||
args.insert(0, Argument("const T&", "thisObjPtr"))
|
||||
|
||||
setupCall = ("CallSetup s(this, aRv, aExceptionHandling);\n"
|
||||
"if (!s.GetContext()) {\n"
|
||||
@ -10972,7 +10969,7 @@ class CGCallback(CGClass):
|
||||
bodyWithThis = string.Template(
|
||||
setupCall+
|
||||
"JS::Rooted<JSObject*> thisObjJS(s.GetContext(),\n"
|
||||
" WrapCallThisObject(s.GetContext(), CallbackPreserveColor(), thisObj));\n"
|
||||
" WrapCallThisObject(s.GetContext(), CallbackPreserveColor(), thisObjPtr));\n"
|
||||
"if (!thisObjJS) {\n"
|
||||
" aRv.Throw(NS_ERROR_FAILURE);\n"
|
||||
" return${errorReturn};\n"
|
||||
|
@ -368,17 +368,11 @@ class Descriptor(DescriptorProvider):
|
||||
raise TypeError("Descriptor for %s has unrecognized value (%s) "
|
||||
"for nativeOwnership" %
|
||||
(self.interface.identifier.name, self.nativeOwnership))
|
||||
self.customFinalize = desc.get('customFinalize', False)
|
||||
self.customWrapperManagement = desc.get('customWrapperManagement', False)
|
||||
if desc.get('wantsQI', None) != None:
|
||||
self._wantsQI = desc.get('wantsQI', None)
|
||||
self.wrapperCache = (not self.interface.isCallback() and
|
||||
(self.nativeOwnership != 'owned' and
|
||||
desc.get('wrapperCache', True)))
|
||||
if self.customWrapperManagement and not self.wrapperCache:
|
||||
raise TypeError("Descriptor for %s has customWrapperManagement "
|
||||
"but is not wrapperCached." %
|
||||
(self.interface.identifier.name))
|
||||
|
||||
def make_name(name):
|
||||
return name + "_workers" if self.workers else name
|
||||
|
@ -554,8 +554,9 @@ ContentChild::RecvDumpGCAndCCLogsToFile(const nsString& aIdentifier,
|
||||
{
|
||||
nsCOMPtr<nsIMemoryInfoDumper> dumper = do_GetService("@mozilla.org/memory-info-dumper;1");
|
||||
|
||||
nsString gcLogPath, ccLogPath;
|
||||
dumper->DumpGCAndCCLogsToFile(aIdentifier, aDumpAllTraces,
|
||||
aDumpChildProcesses);
|
||||
aDumpChildProcesses, gcLogPath, ccLogPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -769,14 +769,12 @@ private:
|
||||
NS_WARNING("Failed to dispatch, going to leak!");
|
||||
}
|
||||
|
||||
mFinishedWorker->Finish(aCx);
|
||||
|
||||
RuntimeService* runtime = RuntimeService::GetService();
|
||||
NS_ASSERTION(runtime, "This should never be null!");
|
||||
|
||||
runtime->UnregisterWorker(aCx, mFinishedWorker);
|
||||
|
||||
mFinishedWorker->Release();
|
||||
mFinishedWorker->ClearSelfRef();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -800,14 +798,12 @@ private:
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
RuntimeService* runtime = RuntimeService::GetService();
|
||||
MOZ_ASSERT(runtime);
|
||||
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest ar(cx);
|
||||
|
||||
mFinishedWorker->Finish(cx);
|
||||
|
||||
RuntimeService* runtime = RuntimeService::GetService();
|
||||
NS_ASSERTION(runtime, "This should never be null!");
|
||||
|
||||
runtime->UnregisterWorker(cx, mFinishedWorker);
|
||||
|
||||
nsTArray<nsCOMPtr<nsISupports> > doomed;
|
||||
@ -822,8 +818,7 @@ private:
|
||||
NS_WARNING("Failed to dispatch, going to leak!");
|
||||
}
|
||||
|
||||
mFinishedWorker->Release();
|
||||
|
||||
mFinishedWorker->ClearSelfRef();
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
@ -2109,7 +2104,7 @@ WorkerPrivateParent<Derived>::WorkerPrivateParent(
|
||||
mMemoryReportCondVar(mMutex, "WorkerPrivateParent Memory Report CondVar"),
|
||||
mParent(aParent), mScriptURL(aScriptURL),
|
||||
mSharedWorkerName(aSharedWorkerName), mBusyCount(0), mMessagePortSerial(0),
|
||||
mParentStatus(Pending), mRooted(false), mParentSuspended(false),
|
||||
mParentStatus(Pending), mParentSuspended(false),
|
||||
mIsChromeWorker(aIsChromeWorker), mMainThreadObjectsForgotten(false),
|
||||
mWorkerType(aWorkerType)
|
||||
{
|
||||
@ -2143,8 +2138,6 @@ WorkerPrivateParent<Derived>::WorkerPrivateParent(
|
||||
template <class Derived>
|
||||
WorkerPrivateParent<Derived>::~WorkerPrivateParent()
|
||||
{
|
||||
MOZ_ASSERT(!mRooted);
|
||||
|
||||
DropJSObjects(this);
|
||||
}
|
||||
|
||||
@ -2158,13 +2151,7 @@ WorkerPrivateParent<Derived>::WrapObject(JSContext* aCx,
|
||||
|
||||
AssertIsOnParentThread();
|
||||
|
||||
JS::Rooted<JSObject*> obj(aCx, WorkerBinding::Wrap(aCx, aScope, ParentAsWorkerPrivate()));
|
||||
|
||||
if (mRooted) {
|
||||
PreserveWrapper(this);
|
||||
}
|
||||
|
||||
return obj;
|
||||
return WorkerBinding::Wrap(aCx, aScope, ParentAsWorkerPrivate());
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
@ -2606,25 +2593,6 @@ WorkerPrivateParent<Derived>::SynchronizeAndResume(
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
void
|
||||
WorkerPrivateParent<Derived>::_finalize(JSFreeOp* aFop)
|
||||
{
|
||||
AssertIsOnParentThread();
|
||||
|
||||
MOZ_ASSERT(!mRooted);
|
||||
|
||||
ClearWrapper();
|
||||
|
||||
// Ensure that we're held alive across the TerminatePrivate call, and then
|
||||
// release the reference our wrapper held to us.
|
||||
nsRefPtr<WorkerPrivateParent<Derived> > kungFuDeathGrip = dont_AddRef(this);
|
||||
|
||||
if (!TerminatePrivate(nullptr)) {
|
||||
NS_WARNING("Failed to terminate!");
|
||||
}
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
bool
|
||||
WorkerPrivateParent<Derived>::Close(JSContext* aCx)
|
||||
@ -2651,14 +2619,11 @@ WorkerPrivateParent<Derived>::ModifyBusyCount(JSContext* aCx, bool aIncrease)
|
||||
NS_ASSERTION(aIncrease || mBusyCount, "Mismatched busy count mods!");
|
||||
|
||||
if (aIncrease) {
|
||||
if (mBusyCount++ == 0) {
|
||||
Root(true);
|
||||
}
|
||||
mBusyCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (--mBusyCount == 0) {
|
||||
Root(false);
|
||||
|
||||
bool shouldCancel;
|
||||
{
|
||||
@ -2674,32 +2639,6 @@ WorkerPrivateParent<Derived>::ModifyBusyCount(JSContext* aCx, bool aIncrease)
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
void
|
||||
WorkerPrivateParent<Derived>::Root(bool aRoot)
|
||||
{
|
||||
AssertIsOnParentThread();
|
||||
|
||||
if (aRoot == mRooted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aRoot) {
|
||||
NS_ADDREF_THIS();
|
||||
if (GetWrapperPreserveColor()) {
|
||||
PreserveWrapper(this);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (GetWrapperPreserveColor()) {
|
||||
ReleaseWrapper(this);
|
||||
}
|
||||
NS_RELEASE_THIS();
|
||||
}
|
||||
|
||||
mRooted = aRoot;
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
void
|
||||
WorkerPrivateParent<Derived>::ForgetMainThreadObjects(
|
||||
@ -3512,16 +3451,28 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
|
||||
template <class Derived>
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(WorkerPrivateParent<Derived>,
|
||||
nsDOMEventTargetHelper)
|
||||
// Nothing else to traverse
|
||||
tmp->AssertIsOnParentThread();
|
||||
|
||||
// The WorkerPrivate::mSelfRef has a reference to itself, which is really
|
||||
// held by the worker thread. We traverse this reference if and only if our
|
||||
// busy count is zero and we have not released the main thread reference.
|
||||
// We do not unlink it. This allows the CC to break cycles involving the
|
||||
// WorkerPrivate and begin shutting it down (which does happen in unlink) but
|
||||
// ensures that the WorkerPrivate won't be deleted before we're done shutting
|
||||
// down the thread.
|
||||
|
||||
if (!tmp->mBusyCount && !tmp->mMainThreadObjectsForgotten) {
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSelfRef)
|
||||
}
|
||||
|
||||
// The various strong references in LoadInfo are managed manually and cannot
|
||||
// be cycle collected.
|
||||
tmp->AssertIsOnParentThread();
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
template <class Derived>
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(WorkerPrivateParent<Derived>,
|
||||
nsDOMEventTargetHelper)
|
||||
tmp->AssertIsOnParentThread();
|
||||
tmp->Terminate(nullptr);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
template <class Derived>
|
||||
@ -3721,10 +3672,7 @@ WorkerPrivate::Constructor(const GlobalObject& aGlobal,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// The worker will be owned by its JSObject (via the reference we return from
|
||||
// this function), but it also needs to be owned by its thread, so AddRef it
|
||||
// again.
|
||||
NS_ADDREF(worker.get());
|
||||
worker->mSelfRef = worker;
|
||||
|
||||
return worker.forget();
|
||||
}
|
||||
|
@ -232,13 +232,17 @@ private:
|
||||
uint64_t mBusyCount;
|
||||
uint64_t mMessagePortSerial;
|
||||
Status mParentStatus;
|
||||
bool mRooted;
|
||||
bool mParentSuspended;
|
||||
bool mIsChromeWorker;
|
||||
bool mMainThreadObjectsForgotten;
|
||||
WorkerType mWorkerType;
|
||||
|
||||
protected:
|
||||
// The worker is owned by its thread, which is represented here. This is set
|
||||
// in Construct() and emptied by WorkerFinishedRunnable, and conditionally
|
||||
// traversed by the cycle collector if the busy count is zero.
|
||||
nsRefPtr<WorkerPrivate> mSelfRef;
|
||||
|
||||
WorkerPrivateParent(JSContext* aCx, WorkerPrivate* aParent,
|
||||
const nsAString& aScriptURL, bool aIsChromeWorker,
|
||||
WorkerType aWorkerType,
|
||||
@ -281,6 +285,14 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(WorkerPrivateParent,
|
||||
nsDOMEventTargetHelper)
|
||||
|
||||
void
|
||||
ClearSelfRef()
|
||||
{
|
||||
AssertIsOnParentThread();
|
||||
MOZ_ASSERT(mSelfRef);
|
||||
mSelfRef = nullptr;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Dispatch(WorkerRunnable* aRunnable)
|
||||
{
|
||||
@ -329,20 +341,10 @@ public:
|
||||
SynchronizeAndResume(JSContext* aCx, nsPIDOMWindow* aWindow,
|
||||
nsIScriptContext* aScriptContext);
|
||||
|
||||
void
|
||||
_finalize(JSFreeOp* aFop);
|
||||
|
||||
void
|
||||
Finish(JSContext* aCx)
|
||||
{
|
||||
Root(false);
|
||||
}
|
||||
|
||||
bool
|
||||
Terminate(JSContext* aCx)
|
||||
{
|
||||
AssertIsOnParentThread();
|
||||
Root(false);
|
||||
return TerminatePrivate(aCx);
|
||||
}
|
||||
|
||||
@ -352,9 +354,6 @@ public:
|
||||
bool
|
||||
ModifyBusyCount(JSContext* aCx, bool aIncrease);
|
||||
|
||||
void
|
||||
Root(bool aRoot);
|
||||
|
||||
void
|
||||
ForgetMainThreadObjects(nsTArray<nsCOMPtr<nsISupports> >& aDoomed);
|
||||
|
||||
|
@ -8,12 +8,12 @@ function handleRequest(request, response)
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
if (request.method == "POST") {
|
||||
setState("seenPost", "1");
|
||||
setState("seenPost" + request.queryString, "1");
|
||||
return;
|
||||
}
|
||||
|
||||
if (request.method == "GET") {
|
||||
if (getState("seenPost") == "1") {
|
||||
if (getState("seenPost" + request.queryString) == "1") {
|
||||
response.write("closed");
|
||||
}
|
||||
return;
|
||||
|
@ -4,7 +4,7 @@
|
||||
*/
|
||||
onclose = function() {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "closeOnGC_server.sjs", false);
|
||||
xhr.open("POST", "closeOnGC_server.sjs" + location.search, false);
|
||||
xhr.send();
|
||||
};
|
||||
|
||||
|
@ -15,24 +15,39 @@
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var worker = new Worker("closeOnGC_worker.js");
|
||||
worker.onmessage = function(event) {
|
||||
is(event.data, "ready");
|
||||
worker = null;
|
||||
var count = 0;
|
||||
|
||||
function testWorker(queryString) {
|
||||
++count;
|
||||
var worker = new Worker("closeOnGC_worker.js?" + queryString);
|
||||
worker.onmessage = function(event) {
|
||||
is(event.data, "ready");
|
||||
worker = null;
|
||||
}
|
||||
|
||||
var interval = setInterval(function() {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "closeOnGC_server.sjs?" + queryString, false);
|
||||
xhr.send();
|
||||
if (xhr.responseText != "closed") {
|
||||
SpecialPowers.gc();
|
||||
return;
|
||||
}
|
||||
clearInterval(interval);
|
||||
ok(true, "xhr correctly closed");
|
||||
if (--count == 0) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}, 500);
|
||||
|
||||
return worker;
|
||||
}
|
||||
|
||||
var interval = setInterval(function() {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "closeOnGC_server.sjs", false);
|
||||
xhr.send();
|
||||
if (xhr.responseText != "closed") {
|
||||
SpecialPowers.gc();
|
||||
return;
|
||||
}
|
||||
clearInterval(interval);
|
||||
ok(true, "xhr correctly closed");
|
||||
SimpleTest.finish();
|
||||
}, 500);
|
||||
testWorker("white");
|
||||
var worker = testWorker("gray");
|
||||
worker.onerror = function() {};
|
||||
worker.onerror.foo = worker;
|
||||
worker = null;
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
|
@ -988,7 +988,6 @@ void nsNSSComponent::setValidationOptions(bool isInitialSetting,
|
||||
crlDownloading ?
|
||||
CertVerifier::crl_download_allowed : CertVerifier::crl_local_only,
|
||||
odc, osc, ogc);
|
||||
|
||||
}
|
||||
|
||||
// Enable the TLS versions given in the prefs, defaulting to SSL 3.0 (min
|
||||
@ -1052,6 +1051,50 @@ nsNSSComponent::SkipOcspOff()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
GetNSSProfilePath(nsAutoCString& aProfilePath)
|
||||
{
|
||||
aProfilePath.Truncate();
|
||||
const char* dbDirOverride = getenv("MOZPSM_NSSDBDIR_OVERRIDE");
|
||||
if (dbDirOverride && strlen(dbDirOverride) > 0) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
|
||||
("Using specified MOZPSM_NSSDBDIR_OVERRIDE as NSS DB dir: %s\n",
|
||||
dbDirOverride));
|
||||
aProfilePath.Assign(dbDirOverride);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> profileFile;
|
||||
nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
|
||||
getter_AddRefs(profileFile));
|
||||
if (NS_FAILED(rv)) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_ERROR,
|
||||
("Unable to get profile directory - continuing with no NSS DB\n"));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
// Native path will drop Unicode characters that cannot be mapped to system's
|
||||
// codepage, using short (canonical) path as workaround.
|
||||
nsCOMPtr<nsILocalFileWin> profileFileWin(do_QueryInterface(profileFile));
|
||||
if (!profileFileWin) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_ERROR,
|
||||
("Could not get nsILocalFileWin for profile directory.\n"));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
rv = profileFileWin->GetNativeCanonicalPath(aProfilePath);
|
||||
#else
|
||||
rv = profileFile->GetNativePath(aProfilePath);
|
||||
#endif
|
||||
if (NS_FAILED(rv)) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_ERROR,
|
||||
("Could not get native path for profile directory.\n"));
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNSSComponent::InitializeNSS()
|
||||
{
|
||||
@ -1066,158 +1109,126 @@ nsNSSComponent::InitializeNSS()
|
||||
nsINSSErrorsService::NSS_SSL_ERROR_LIMIT == SSL_ERROR_LIMIT,
|
||||
"You must update the values in nsINSSErrorsService.idl");
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mutex);
|
||||
MutexAutoLock lock(mutex);
|
||||
|
||||
// Init phase 1, prepare own variables used for NSS
|
||||
if (mNSSInitialized) {
|
||||
PR_ASSERT(!"Trying to initialize NSS twice"); // We should never try to
|
||||
// initialize NSS more than
|
||||
// once in a process.
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (mNSSInitialized) {
|
||||
PR_ASSERT(!"Trying to initialize NSS twice"); // We should never try to
|
||||
// initialize NSS more than
|
||||
// once in a process.
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("NSS Initialization beginning\n"));
|
||||
|
||||
nsresult rv;
|
||||
nsAutoCString profileStr;
|
||||
nsCOMPtr<nsIFile> profilePath;
|
||||
// The call to ConfigureInternalPKCS11Token needs to be done before NSS is initialized,
|
||||
// but affects only static data.
|
||||
// If we could assume i18n will not change between profiles, one call per application
|
||||
// run were sufficient. As I can't predict what happens in the future, let's repeat
|
||||
// this call for every re-init of NSS.
|
||||
|
||||
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
|
||||
getter_AddRefs(profilePath));
|
||||
if (NS_FAILED(rv)) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_ERROR, ("Unable to get profile directory\n"));
|
||||
ConfigureInternalPKCS11Token();
|
||||
SECStatus init_rv = NSS_NoDB_Init(nullptr);
|
||||
if (init_rv != SECSuccess) {
|
||||
nsPSMInitPanic::SetPanic();
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* dbdir_override = getenv("MOZPSM_NSSDBDIR_OVERRIDE");
|
||||
if (dbdir_override && strlen(dbdir_override)) {
|
||||
profileStr = dbdir_override;
|
||||
}
|
||||
else {
|
||||
#if defined(XP_WIN)
|
||||
// Native path will drop Unicode characters that cannot be mapped to system's
|
||||
// codepage, using short (canonical) path as workaround.
|
||||
nsCOMPtr<nsILocalFileWin> profilePathWin(do_QueryInterface(profilePath, &rv));
|
||||
if (profilePathWin)
|
||||
rv = profilePathWin->GetNativeCanonicalPath(profileStr);
|
||||
#else
|
||||
rv = profilePath->GetNativePath(profileStr);
|
||||
#endif
|
||||
if (NS_FAILED(rv)) {
|
||||
nsPSMInitPanic::SetPanic();
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
ConfigureInternalPKCS11Token();
|
||||
|
||||
nsAutoCString profileStr;
|
||||
nsresult rv = GetNSSProfilePath(profileStr);
|
||||
if (NS_FAILED(rv)) {
|
||||
nsPSMInitPanic::SetPanic();
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// init phase 2, init calls to NSS library
|
||||
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("NSS Initialization beginning\n"));
|
||||
|
||||
// The call to ConfigureInternalPKCS11Token needs to be done before NSS is initialized,
|
||||
// but affects only static data.
|
||||
// If we could assume i18n will not change between profiles, one call per application
|
||||
// run were sufficient. As I can't predict what happens in the future, let's repeat
|
||||
// this call for every re-init of NSS.
|
||||
|
||||
ConfigureInternalPKCS11Token();
|
||||
|
||||
InitCertVerifierLog();
|
||||
|
||||
SECStatus init_rv = SECFailure;
|
||||
if (!profileStr.IsEmpty()) {
|
||||
// First try to initialize the NSS DB in read/write mode.
|
||||
SECStatus init_rv = ::mozilla::psm::InitializeNSS(profileStr.get(), false);
|
||||
// If that fails, attempt read-only mode.
|
||||
if (init_rv != SECSuccess) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("can not init NSS r/w in %s\n", profileStr.get()));
|
||||
|
||||
// try to init r/o
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("could not init NSS r/w in %s\n", profileStr.get()));
|
||||
init_rv = ::mozilla::psm::InitializeNSS(profileStr.get(), true);
|
||||
if (init_rv != SECSuccess) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("can not init in r/o either\n"));
|
||||
|
||||
init_rv = NSS_NoDB_Init(profileStr.get());
|
||||
if (init_rv != SECSuccess) {
|
||||
nsPSMInitPanic::SetPanic();
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
} // have profile dir
|
||||
} // lock
|
||||
|
||||
// init phase 3, only if phase 2 was successful
|
||||
|
||||
mNSSInitialized = true;
|
||||
|
||||
PK11_SetPasswordFunc(PK11PasswordPrompt);
|
||||
|
||||
SharedSSLState::GlobalInit();
|
||||
|
||||
// Register an observer so we can inform NSS when these prefs change
|
||||
Preferences::AddStrongObserver(this, "security.");
|
||||
|
||||
SSL_OptionSetDefault(SSL_ENABLE_SSL2, false);
|
||||
SSL_OptionSetDefault(SSL_V2_COMPATIBLE_HELLO, false);
|
||||
|
||||
rv = setEnabledTLSVersions();
|
||||
if (NS_FAILED(rv)) {
|
||||
nsPSMInitPanic::SetPanic();
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
DisableMD5();
|
||||
LoadLoadableRoots();
|
||||
|
||||
SSL_OptionSetDefault(SSL_ENABLE_SESSION_TICKETS, true);
|
||||
|
||||
bool requireSafeNegotiation =
|
||||
Preferences::GetBool("security.ssl.require_safe_negotiation",
|
||||
REQUIRE_SAFE_NEGOTIATION_DEFAULT);
|
||||
SSL_OptionSetDefault(SSL_REQUIRE_SAFE_NEGOTIATION, requireSafeNegotiation);
|
||||
|
||||
bool allowUnrestrictedRenego =
|
||||
Preferences::GetBool("security.ssl.allow_unrestricted_renego_everywhere__temporarily_available_pref",
|
||||
ALLOW_UNRESTRICTED_RENEGO_DEFAULT);
|
||||
SSL_OptionSetDefault(SSL_ENABLE_RENEGOTIATION,
|
||||
allowUnrestrictedRenego ?
|
||||
SSL_RENEGOTIATE_UNRESTRICTED :
|
||||
SSL_RENEGOTIATE_REQUIRES_XTN);
|
||||
|
||||
SSL_OptionSetDefault(SSL_ENABLE_FALSE_START,
|
||||
Preferences::GetBool("security.ssl.enable_false_start",
|
||||
FALSE_START_ENABLED_DEFAULT));
|
||||
|
||||
// SSL_ENABLE_NPN and SSL_ENABLE_ALPN also require calling
|
||||
// SSL_SetNextProtoNego in order for the extensions to be negotiated.
|
||||
// WebRTC does not do that so it will not use NPN or ALPN even when these
|
||||
// preferences are true.
|
||||
SSL_OptionSetDefault(SSL_ENABLE_NPN,
|
||||
Preferences::GetBool("security.ssl.enable_npn",
|
||||
NPN_ENABLED_DEFAULT));
|
||||
SSL_OptionSetDefault(SSL_ENABLE_ALPN,
|
||||
Preferences::GetBool("security.ssl.enable_alpn",
|
||||
ALPN_ENABLED_DEFAULT));
|
||||
|
||||
if (NS_FAILED(InitializeCipherSuite())) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_ERROR, ("Unable to initialize cipher suite settings\n"));
|
||||
return NS_ERROR_FAILURE;
|
||||
if (init_rv != SECSuccess) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("could not init in r/o either\n"));
|
||||
}
|
||||
}
|
||||
// If we haven't succeeded in initializing the DB in our profile
|
||||
// directory or we don't have a profile at all, attempt to initialize
|
||||
// with no DB.
|
||||
if (init_rv != SECSuccess) {
|
||||
init_rv = NSS_NoDB_Init(nullptr);
|
||||
}
|
||||
if (init_rv != SECSuccess) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_ERROR, ("could not initialize NSS - panicking\n"));
|
||||
nsPSMInitPanic::SetPanic();
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// dynamic options from prefs
|
||||
setValidationOptions(true, lock);
|
||||
mNSSInitialized = true;
|
||||
|
||||
mHttpForNSS.initTable();
|
||||
mHttpForNSS.registerHttpClient();
|
||||
PK11_SetPasswordFunc(PK11PasswordPrompt);
|
||||
|
||||
SharedSSLState::GlobalInit();
|
||||
|
||||
// Register an observer so we can inform NSS when these prefs change
|
||||
Preferences::AddStrongObserver(this, "security.");
|
||||
|
||||
SSL_OptionSetDefault(SSL_ENABLE_SSL2, false);
|
||||
SSL_OptionSetDefault(SSL_V2_COMPATIBLE_HELLO, false);
|
||||
|
||||
rv = setEnabledTLSVersions();
|
||||
if (NS_FAILED(rv)) {
|
||||
nsPSMInitPanic::SetPanic();
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
DisableMD5();
|
||||
// Initialize the certverifier log before calling any functions that library.
|
||||
InitCertVerifierLog();
|
||||
LoadLoadableRoots();
|
||||
|
||||
SSL_OptionSetDefault(SSL_ENABLE_SESSION_TICKETS, true);
|
||||
|
||||
bool requireSafeNegotiation =
|
||||
Preferences::GetBool("security.ssl.require_safe_negotiation",
|
||||
REQUIRE_SAFE_NEGOTIATION_DEFAULT);
|
||||
SSL_OptionSetDefault(SSL_REQUIRE_SAFE_NEGOTIATION, requireSafeNegotiation);
|
||||
|
||||
bool allowUnrestrictedRenego =
|
||||
Preferences::GetBool("security.ssl.allow_unrestricted_renego_everywhere__temporarily_available_pref",
|
||||
ALLOW_UNRESTRICTED_RENEGO_DEFAULT);
|
||||
SSL_OptionSetDefault(SSL_ENABLE_RENEGOTIATION,
|
||||
allowUnrestrictedRenego ?
|
||||
SSL_RENEGOTIATE_UNRESTRICTED :
|
||||
SSL_RENEGOTIATE_REQUIRES_XTN);
|
||||
|
||||
SSL_OptionSetDefault(SSL_ENABLE_FALSE_START,
|
||||
Preferences::GetBool("security.ssl.enable_false_start",
|
||||
FALSE_START_ENABLED_DEFAULT));
|
||||
|
||||
// SSL_ENABLE_NPN and SSL_ENABLE_ALPN also require calling
|
||||
// SSL_SetNextProtoNego in order for the extensions to be negotiated.
|
||||
// WebRTC does not do that so it will not use NPN or ALPN even when these
|
||||
// preferences are true.
|
||||
SSL_OptionSetDefault(SSL_ENABLE_NPN,
|
||||
Preferences::GetBool("security.ssl.enable_npn",
|
||||
NPN_ENABLED_DEFAULT));
|
||||
SSL_OptionSetDefault(SSL_ENABLE_ALPN,
|
||||
Preferences::GetBool("security.ssl.enable_alpn",
|
||||
ALPN_ENABLED_DEFAULT));
|
||||
|
||||
if (NS_FAILED(InitializeCipherSuite())) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_ERROR, ("Unable to initialize cipher suite settings\n"));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// dynamic options from prefs
|
||||
setValidationOptions(true, lock);
|
||||
|
||||
mHttpForNSS.initTable();
|
||||
mHttpForNSS.registerHttpClient();
|
||||
|
||||
#ifndef MOZ_DISABLE_CRYPTOLEGACY
|
||||
LaunchSmartCardThreads();
|
||||
LaunchSmartCardThreads();
|
||||
#endif
|
||||
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("NSS Initialization done\n"));
|
||||
}
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("NSS Initialization done\n"));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -283,6 +283,13 @@ function onLoad()
|
||||
"process to reduce memory usage in other ways, e.g. by " +
|
||||
"flushing various caches.";
|
||||
|
||||
const GCAndCCLogDesc = "Save garbage collection log and concise cycle " +
|
||||
"collection log.\n" +
|
||||
"WARNING: These logs may be large (>1GB).";
|
||||
const GCAndCCAllLogDesc = "Save garbage collection log and verbose cycle " +
|
||||
"collection log.\n" +
|
||||
"WARNING: These logs may be large (>1GB).";
|
||||
|
||||
let ops = appendElement(header, "div", "");
|
||||
|
||||
let row1 = appendElement(ops, "div", "opsRow");
|
||||
@ -318,10 +325,19 @@ function onLoad()
|
||||
appendButton(row3, CCDesc, doCC, "CC");
|
||||
appendButton(row3, MMDesc, doMMU, "Minimize memory usage");
|
||||
|
||||
let row4 = appendElement(ops, "div", "opsRow");
|
||||
|
||||
appendElementWithText(row4, "div", "opsRowLabel", "Save GC & CC logs");
|
||||
appendButton(row4, GCAndCCLogDesc,
|
||||
saveGCLogAndConciseCCLog, "Save concise", 'saveLogsConcise');
|
||||
appendButton(row4, GCAndCCAllLogDesc,
|
||||
saveGCLogAndVerboseCCLog, "Save verbose", 'saveLogsVerbose');
|
||||
|
||||
// Generate the main div, where content ("section" divs) will go. It's
|
||||
// hidden at first.
|
||||
|
||||
gMain = appendElement(document.body, 'div', '');
|
||||
gMain.id = 'mainDiv';
|
||||
|
||||
// Generate the footer. It's hidden at first.
|
||||
|
||||
@ -385,6 +401,39 @@ function doMeasure()
|
||||
updateAboutMemoryFromReporters();
|
||||
}
|
||||
|
||||
function saveGCLogAndConciseCCLog()
|
||||
{
|
||||
dumpGCLogAndCCLog(false);
|
||||
}
|
||||
|
||||
function saveGCLogAndVerboseCCLog()
|
||||
{
|
||||
dumpGCLogAndCCLog(true);
|
||||
}
|
||||
|
||||
function dumpGCLogAndCCLog(aVerbose)
|
||||
{
|
||||
let gcLogPath = {};
|
||||
let ccLogPath = {};
|
||||
|
||||
let dumper = Cc["@mozilla.org/memory-info-dumper;1"]
|
||||
.getService(Ci.nsIMemoryInfoDumper);
|
||||
|
||||
updateMainAndFooter("Saving logs...", HIDE_FOOTER);
|
||||
|
||||
dumper.dumpGCAndCCLogsToFile("", aVerbose, /* dumpChildProcesses = */ false,
|
||||
gcLogPath, ccLogPath);
|
||||
|
||||
updateMainAndFooter("", HIDE_FOOTER);
|
||||
let section = appendElement(gMain, 'div', "section");
|
||||
appendElementWithText(section, 'div', "",
|
||||
"Saved GC log to " + gcLogPath.value);
|
||||
|
||||
let ccLogType = aVerbose ? "verbose" : "concise";
|
||||
appendElementWithText(section, 'div', "",
|
||||
"Saved " + ccLogType + " CC log to " + ccLogPath.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Top-level function that does the work of generating the page from the memory
|
||||
* reporters.
|
||||
|
@ -11,6 +11,7 @@ support-files =
|
||||
[test_aboutmemory3.xul]
|
||||
[test_aboutmemory4.xul]
|
||||
[test_aboutmemory5.xul]
|
||||
[test_aboutmemory6.xul]
|
||||
[test_memoryReporters.xul]
|
||||
[test_memoryReporters2.xul]
|
||||
[test_sqliteMultiReporter.xul]
|
||||
|
88
toolkit/components/aboutmemory/tests/test_aboutmemory6.xul
Normal file
88
toolkit/components/aboutmemory/tests/test_aboutmemory6.xul
Normal file
@ -0,0 +1,88 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
||||
<window title="about:memory"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
|
||||
<!-- This file tests the saving of GC and CC logs in both concise and
|
||||
verbose formats. -->
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml"></body>
|
||||
|
||||
<iframe id="amFrame" height="400" src="about:memory"></iframe>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
"use strict";
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
function onFocus() {
|
||||
let frame = document.getElementById("amFrame");
|
||||
frame.focus();
|
||||
|
||||
// Checks that a file exists on the local file system and removes it if it
|
||||
// is present.
|
||||
function checkForFileAndRemove(aFilename) {
|
||||
let localFile = Cc["@mozilla.org/file/local;1"]
|
||||
.createInstance(Ci.nsILocalFile);
|
||||
localFile.initWithPath(aFilename);
|
||||
|
||||
let exists = localFile.exists();
|
||||
if (exists) {
|
||||
localFile.remove(/* recursive = */ false);
|
||||
}
|
||||
|
||||
return exists;
|
||||
}
|
||||
|
||||
// Given a save log button, triggers the action and checks if both CC & GC
|
||||
// logs were written to disk.
|
||||
function saveLogs(aLogButton, aCCLogType)
|
||||
{
|
||||
// trigger the log saving
|
||||
aLogButton.click();
|
||||
|
||||
// mainDiv
|
||||
// |-> section
|
||||
// | -> div gc log path
|
||||
// | -> div cc log path
|
||||
let mainDiv = frame.contentWindow.document.getElementById("mainDiv");
|
||||
let logNodes = mainDiv.childNodes[0];
|
||||
|
||||
// we expect 2 logs listed
|
||||
let numOfLogs = logNodes.childNodes.length;
|
||||
ok(numOfLogs == 2, "two log entries generated")
|
||||
|
||||
// grab the path portion of the text
|
||||
let gcLogPath = logNodes.childNodes[0].textContent
|
||||
.replace("Saved GC log to ", "");
|
||||
let ccLogPath = logNodes.childNodes[1].textContent
|
||||
.replace("Saved " + aCCLogType + " CC log to ", "");
|
||||
|
||||
// check that the files actually exist
|
||||
ok(checkForFileAndRemove(gcLogPath), "GC log file exists");
|
||||
ok(checkForFileAndRemove(ccLogPath), "CC log file exists");
|
||||
}
|
||||
|
||||
// get the log buttons to test
|
||||
let saveConcise = frame.contentWindow.document
|
||||
.getElementById("saveLogsConcise");
|
||||
let saveVerbose = frame.contentWindow.document
|
||||
.getElementById("saveLogsVerbose");
|
||||
|
||||
saveLogs(saveConcise, "concise");
|
||||
saveLogs(saveVerbose, "verbose");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForFocus(onFocus);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
]]>
|
||||
</script>
|
||||
</window>
|
@ -139,6 +139,7 @@ support-files = window_preferences_beforeaccept.xul
|
||||
[test_screenPersistence.xul]
|
||||
[test_scrollbar.xul]
|
||||
[test_showcaret.xul]
|
||||
skip-if = os == "win" # Bug 952350
|
||||
[test_sorttemplate.xul]
|
||||
[test_statusbar.xul]
|
||||
[test_subframe_origin.xul]
|
||||
|
@ -109,6 +109,7 @@ protected:
|
||||
// to 3%-4%). See bmo bug 395397.
|
||||
static const uint32_t kHadMoreEventsCountMax = 3;
|
||||
|
||||
int32_t mRecursionDepth;
|
||||
int32_t mNativeEventCallbackDepth;
|
||||
// Can be set from different threads, so must be modified atomically
|
||||
int32_t mNativeEventScheduledDepth;
|
||||
|
@ -210,6 +210,7 @@ nsAppShell::nsAppShell()
|
||||
, mTerminated(false)
|
||||
, mSkippedNativeCallback(false)
|
||||
, mHadMoreEventsCount(0)
|
||||
, mRecursionDepth(0)
|
||||
, mNativeEventCallbackDepth(0)
|
||||
, mNativeEventScheduledDepth(0)
|
||||
{
|
||||
@ -711,14 +712,11 @@ nsAppShell::ProcessNextNativeEvent(bool aMayWait)
|
||||
bool
|
||||
nsAppShell::InGeckoMainEventLoop()
|
||||
{
|
||||
if (gXULModalLevel > 0)
|
||||
if ((gXULModalLevel > 0) || (mRecursionDepth > 0))
|
||||
return false;
|
||||
if (mNativeEventCallbackDepth <= 0)
|
||||
return false;
|
||||
|
||||
bool isProcessingEvents = false;
|
||||
NS_GetCurrentThread()->GetIsProcessingEvents(&isProcessingEvents);
|
||||
return !isProcessingEvents;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Run
|
||||
@ -820,6 +818,8 @@ nsAppShell::OnProcessNextEvent(nsIThreadInternal *aThread, bool aMayWait,
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
mRecursionDepth = aRecursionDepth;
|
||||
|
||||
NS_ASSERTION(mAutoreleasePools,
|
||||
"No stack on which to store autorelease pool");
|
||||
|
||||
@ -845,6 +845,8 @@ nsAppShell::AfterProcessNextEvent(nsIThreadInternal *aThread,
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
mRecursionDepth = aRecursionDepth;
|
||||
|
||||
CFIndex count = ::CFArrayGetCount(mAutoreleasePools);
|
||||
|
||||
NS_ASSERTION(mAutoreleasePools && count,
|
||||
|
@ -1407,6 +1407,18 @@ public:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetGcLogPath(nsAString &aPath)
|
||||
{
|
||||
aPath = mGCLogPath;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetCcLogPath(nsAString &aPath)
|
||||
{
|
||||
aPath = mCCLogPath;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD Begin()
|
||||
{
|
||||
mCurrentAddress.AssignLiteral("0x");
|
||||
@ -1459,6 +1471,8 @@ public:
|
||||
nsString msg = NS_LITERAL_STRING("Garbage Collector log dumped to ") +
|
||||
gcLogPath;
|
||||
cs->LogStringMessage(msg.get());
|
||||
|
||||
mGCLogPath = gcLogPath;
|
||||
}
|
||||
|
||||
// Open a file for dumping the CC graph. We again prefix with
|
||||
@ -1616,6 +1630,8 @@ public:
|
||||
nsString msg = NS_LITERAL_STRING("Cycle Collector log dumped to ") +
|
||||
ccLogPath;
|
||||
cs->LogStringMessage(msg.get());
|
||||
|
||||
mCCLogPath = ccLogPath;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
@ -1713,6 +1729,8 @@ private:
|
||||
bool mDisableLog;
|
||||
bool mWantAfterProcessing;
|
||||
nsString mFilenameIdentifier;
|
||||
nsString mGCLogPath;
|
||||
nsString mCCLogPath;
|
||||
nsCString mCurrentAddress;
|
||||
mozilla::LinkedList<CCGraphDescriber> mDescribers;
|
||||
};
|
||||
|
@ -35,7 +35,7 @@ interface nsICycleCollectorHandler : nsISupports
|
||||
* a call to end(). If begin() returns an error none of the other
|
||||
* functions will be called.
|
||||
*/
|
||||
[scriptable, builtinclass, uuid(7096e77d-7834-4996-b52c-50564144d4be)]
|
||||
[scriptable, builtinclass, uuid(786215b7-1e4b-433b-b617-96b176273601)]
|
||||
interface nsICycleCollectorListener : nsISupports
|
||||
{
|
||||
nsICycleCollectorListener allTraces();
|
||||
@ -50,6 +50,12 @@ interface nsICycleCollectorListener : nsISupports
|
||||
// This string will appear somewhere in the log's filename.
|
||||
attribute AString filenameIdentifier;
|
||||
|
||||
// This string will indicate the full path of the GC log if enabled.
|
||||
readonly attribute AString gcLogPath;
|
||||
|
||||
// This string will indicate the full path of the CC log if enabled.
|
||||
readonly attribute AString ccLogPath;
|
||||
|
||||
void begin();
|
||||
void noteRefCountedObject (in unsigned long long aAddress,
|
||||
in unsigned long aRefCount,
|
||||
|
@ -11,7 +11,7 @@ interface nsIFinishDumpingCallback : nsISupports
|
||||
void callback(in nsISupports data);
|
||||
};
|
||||
|
||||
[scriptable, builtinclass, uuid(fd5de30a-e3d6-4965-8244-86709e1ed23b)]
|
||||
[scriptable, builtinclass, uuid(294df03b-e2ae-4fdd-b4fc-4c66a501e0ef)]
|
||||
interface nsIMemoryInfoDumper : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -152,8 +152,14 @@ interface nsIMemoryInfoDumper : nsISupports
|
||||
* @param aDumpChildProcesses indicates whether we should call
|
||||
* DumpGCAndCCLogsToFile in our child processes. If so, the child processes
|
||||
* will dump their children, and so on.
|
||||
*
|
||||
* @param aGCLogPath The full path of the file that the GC log was written to.
|
||||
*
|
||||
* @param aCCLogPath The full path of the file that the CC log was written to.
|
||||
*/
|
||||
void dumpGCAndCCLogsToFile(in AString aIdentifier,
|
||||
in bool aDumpAllTraces,
|
||||
in bool aDumpChildProcesses);
|
||||
in bool aDumpChildProcesses,
|
||||
out AString aGCLogPath,
|
||||
out AString aCCLogPath);
|
||||
};
|
||||
|
@ -97,8 +97,9 @@ public:
|
||||
nsCOMPtr<nsIMemoryInfoDumper> dumper =
|
||||
do_GetService("@mozilla.org/memory-info-dumper;1");
|
||||
|
||||
dumper->DumpGCAndCCLogsToFile(
|
||||
mIdentifier, mDumpAllTraces, mDumpChildProcesses);
|
||||
nsString ccLogPath, gcLogPath;
|
||||
dumper->DumpGCAndCCLogsToFile(mIdentifier, mDumpAllTraces,
|
||||
mDumpChildProcesses, gcLogPath, ccLogPath);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -573,10 +574,11 @@ EnsureNonEmptyIdentifier(nsAString& aIdentifier)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMemoryInfoDumper::DumpGCAndCCLogsToFile(
|
||||
const nsAString& aIdentifier,
|
||||
bool aDumpAllTraces,
|
||||
bool aDumpChildProcesses)
|
||||
nsMemoryInfoDumper::DumpGCAndCCLogsToFile(const nsAString& aIdentifier,
|
||||
bool aDumpAllTraces,
|
||||
bool aDumpChildProcesses,
|
||||
nsAString& aGCLogPath,
|
||||
nsAString& aCCLogPath)
|
||||
{
|
||||
nsString identifier(aIdentifier);
|
||||
EnsureNonEmptyIdentifier(identifier);
|
||||
@ -601,6 +603,10 @@ nsMemoryInfoDumper::DumpGCAndCCLogsToFile(
|
||||
}
|
||||
|
||||
nsJSContext::CycleCollectNow(logger);
|
||||
|
||||
logger->GetGcLogPath(aGCLogPath);
|
||||
logger->GetCcLogPath(aCCLogPath);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -462,17 +462,6 @@ LazyIdleThread::ProcessNextEvent(bool aMayWait,
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LazyIdleThread::GetIsProcessingEvents(bool* aIsProcessing)
|
||||
{
|
||||
if (mThread) {
|
||||
return mThread->GetIsProcessingEvents(aIsProcessing);
|
||||
}
|
||||
|
||||
*aIsProcessing = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LazyIdleThread::Notify(nsITimer* aTimer)
|
||||
{
|
||||
|
@ -17,7 +17,7 @@
|
||||
*
|
||||
* See nsIThreadManager for the API used to create and locate threads.
|
||||
*/
|
||||
[scriptable, uuid(4df07d3a-e759-4256-ba4e-7e2265354ec3)]
|
||||
[scriptable, uuid(9c889946-a73a-4af3-ae9a-ea64f7d4e3ca)]
|
||||
interface nsIThread : nsIEventTarget
|
||||
{
|
||||
/**
|
||||
@ -82,10 +82,4 @@ interface nsIThread : nsIEventTarget
|
||||
* not the current thread.
|
||||
*/
|
||||
boolean processNextEvent(in boolean mayWait);
|
||||
|
||||
/**
|
||||
* true if we're processing runnables or thread observers and if this is the
|
||||
* current thread.
|
||||
*/
|
||||
readonly attribute boolean isProcessingEvents;
|
||||
};
|
||||
|
@ -304,7 +304,6 @@ nsThread::nsThread(MainThreadFlag aMainThread, uint32_t aStackSize)
|
||||
, mThread(nullptr)
|
||||
, mRunningEvent(0)
|
||||
, mStackSize(aStackSize)
|
||||
, mProcessingEvent(0)
|
||||
, mShutdownContext(nullptr)
|
||||
, mShutdownRequired(false)
|
||||
, mEventsAreDoomed(false)
|
||||
@ -607,8 +606,6 @@ nsThread::ProcessNextEvent(bool mayWait, bool *result)
|
||||
}
|
||||
}
|
||||
|
||||
++mProcessingEvent;
|
||||
|
||||
bool notifyMainThreadObserver =
|
||||
(MAIN_THREAD == mIsMainThread) && sMainThreadObserver;
|
||||
if (notifyMainThreadObserver)
|
||||
@ -662,22 +659,9 @@ nsThread::ProcessNextEvent(bool mayWait, bool *result)
|
||||
if (notifyMainThreadObserver && sMainThreadObserver)
|
||||
sMainThreadObserver->AfterProcessNextEvent(this, mRunningEvent, *result);
|
||||
|
||||
--mProcessingEvent;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThread::GetIsProcessingEvents(bool* aIsProcessing)
|
||||
{
|
||||
if (NS_WARN_IF(PR_GetCurrentThread() != mThread)) {
|
||||
return NS_ERROR_NOT_SAME_THREAD;
|
||||
}
|
||||
|
||||
*aIsProcessing = mProcessingEvent != 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsISupportsPriority
|
||||
|
||||
|
@ -150,8 +150,6 @@ protected:
|
||||
uint32_t mRunningEvent; // counter
|
||||
uint32_t mStackSize;
|
||||
|
||||
uint32_t mProcessingEvent;
|
||||
|
||||
struct nsThreadShutdownContext *mShutdownContext;
|
||||
|
||||
bool mShutdownRequired;
|
||||
|
Loading…
Reference in New Issue
Block a user