Merge m-i to m-c

This commit is contained in:
Phil Ringnalda 2014-02-02 17:43:48 -08:00
commit 7f4dcbf266
30 changed files with 448 additions and 339 deletions

View File

@ -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]

View File

@ -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);

View File

@ -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]

View File

@ -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.

View File

@ -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
...
}

View File

@ -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

View File

@ -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': {

View File

@ -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"

View File

@ -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

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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);

View File

@ -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;

View File

@ -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();
};

View File

@ -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();

View File

@ -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;
}

View File

@ -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.

View File

@ -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]

View 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>

View File

@ -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]

View File

@ -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;

View File

@ -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,

View File

@ -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;
};

View File

@ -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,

View File

@ -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);
};

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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;
};

View File

@ -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

View File

@ -150,8 +150,6 @@ protected:
uint32_t mRunningEvent; // counter
uint32_t mStackSize;
uint32_t mProcessingEvent;
struct nsThreadShutdownContext *mShutdownContext;
bool mShutdownRequired;