mCallback;
diff --git a/content/svg/content/src/SVGContentUtils.cpp b/content/svg/content/src/SVGContentUtils.cpp
index 78aef2a03080..99fa00c52505 100644
--- a/content/svg/content/src/SVGContentUtils.cpp
+++ b/content/svg/content/src/SVGContentUtils.cpp
@@ -141,7 +141,7 @@ SVGContentUtils::ReportToConsole(nsIDocument* doc,
uint32_t aParamsLength)
{
return nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
- "SVG", doc,
+ NS_LITERAL_CSTRING("SVG"), doc,
nsContentUtils::eSVG_PROPERTIES,
aWarning,
aParams, aParamsLength);
diff --git a/content/svg/content/src/SVGFragmentIdentifier.cpp b/content/svg/content/src/SVGFragmentIdentifier.cpp
index dd7140998b06..c7996cb55fed 100644
--- a/content/svg/content/src/SVGFragmentIdentifier.cpp
+++ b/content/svg/content/src/SVGFragmentIdentifier.cpp
@@ -9,6 +9,7 @@
#include "mozilla/dom/SVGViewElement.h"
#include "nsContentUtils.h" // for nsCharSeparatedTokenizerTemplate
#include "nsSVGAnimatedTransformList.h"
+#include "nsCharSeparatedTokenizer.h"
using namespace mozilla;
diff --git a/content/xbl/src/nsXBLContentSink.cpp b/content/xbl/src/nsXBLContentSink.cpp
index 6dac5d50f09e..10f0273f08e8 100644
--- a/content/xbl/src/nsXBLContentSink.cpp
+++ b/content/xbl/src/nsXBLContentSink.cpp
@@ -213,7 +213,7 @@ nsXBLContentSink::ReportUnexpectedElement(nsIAtom* aElementName,
const PRUnichar* params[] = { elementName.get() };
return nsContentUtils::ReportToConsole(nsIScriptError::errorFlag,
- "XBL Content Sink",
+ NS_LITERAL_CSTRING("XBL Content Sink"),
mDocument,
nsContentUtils::eXBL_PROPERTIES,
"UnexpectedElement",
@@ -556,7 +556,7 @@ nsXBLContentSink::ConstructBinding(uint32_t aLineNumber)
}
} else {
nsContentUtils::ReportToConsole(nsIScriptError::errorFlag,
- "XBL Content Sink", nullptr,
+ NS_LITERAL_CSTRING("XBL Content Sink"), nullptr,
nsContentUtils::eXBL_PROPERTIES,
"MissingIdAttr", nullptr, 0,
mDocumentURI,
@@ -645,7 +645,7 @@ nsXBLContentSink::ConstructHandler(const PRUnichar **aAtts, uint32_t aLineNumber
// shorthand syntax.
mState = eXBL_Error;
nsContentUtils::ReportToConsole(nsIScriptError::errorFlag,
- "XBL Content Sink",
+ NS_LITERAL_CSTRING("XBL Content Sink"),
mDocument,
nsContentUtils::eXBL_PROPERTIES,
"CommandNotInChrome", nullptr, 0,
diff --git a/content/xbl/src/nsXBLPrototypeBinding.cpp b/content/xbl/src/nsXBLPrototypeBinding.cpp
index cc82fbec11ca..dbd534cbe5bd 100644
--- a/content/xbl/src/nsXBLPrototypeBinding.cpp
+++ b/content/xbl/src/nsXBLPrototypeBinding.cpp
@@ -1621,7 +1621,7 @@ nsXBLPrototypeBinding::ResolveBaseBinding()
if (!CheckTagNameWhiteList(nameSpaceID, tagName)) {
const PRUnichar* params[] = { display.get() };
nsContentUtils::ReportToConsole(nsIScriptError::errorFlag,
- "XBL", nullptr,
+ NS_LITERAL_CSTRING("XBL"), nullptr,
nsContentUtils::eXBL_PROPERTIES,
"InvalidExtendsBinding",
params, ArrayLength(params),
diff --git a/content/xbl/src/nsXBLPrototypeHandler.cpp b/content/xbl/src/nsXBLPrototypeHandler.cpp
index 413d1c5a9f65..bcdd39148792 100644
--- a/content/xbl/src/nsXBLPrototypeHandler.cpp
+++ b/content/xbl/src/nsXBLPrototypeHandler.cpp
@@ -902,7 +902,7 @@ nsXBLPrototypeHandler::ReportKeyConflict(const PRUnichar* aKey, const PRUnichar*
const PRUnichar* params[] = { aKey, aModifiers };
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
- "XBL Prototype Handler", doc,
+ NS_LITERAL_CSTRING("XBL Prototype Handler"), doc,
nsContentUtils::eXBL_PROPERTIES,
aMessageName,
params, ArrayLength(params),
diff --git a/content/xbl/src/nsXBLService.cpp b/content/xbl/src/nsXBLService.cpp
index 62ad0f1a1653..8ac8c9b064c9 100644
--- a/content/xbl/src/nsXBLService.cpp
+++ b/content/xbl/src/nsXBLService.cpp
@@ -90,7 +90,7 @@ IsAncestorBinding(nsIDocument* aDocument,
NS_ConvertUTF8toUTF16 bindingURI(spec);
const PRUnichar* params[] = { bindingURI.get() };
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
- "XBL", aDocument,
+ NS_LITERAL_CSTRING("XBL"), aDocument,
nsContentUtils::eXBL_PROPERTIES,
"TooDeepBindingRecursion",
params, ArrayLength(params));
@@ -331,7 +331,7 @@ nsXBLStreamListener::HandleEvent(nsIDOMEvent* aEvent)
NS_WARNING("An XBL file is malformed. Did you forget the XBL namespace on the bindings tag?");
}
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
- "XBL", nullptr,
+ NS_LITERAL_CSTRING("XBL"), nullptr,
nsContentUtils::eXBL_PROPERTIES,
"MalformedXBL",
nullptr, 0, documentURI);
@@ -763,7 +763,7 @@ nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
NS_ConvertUTF8toUTF16 baseSpecUTF16(basespec);
const PRUnichar* params[] = { protoSpec.get(), baseSpecUTF16.get() };
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
- "XBL", nullptr,
+ NS_LITERAL_CSTRING("XBL"), nullptr,
nsContentUtils::eXBL_PROPERTIES,
"CircularExtendsBinding",
params, ArrayLength(params),
diff --git a/content/xbl/test/test_bug379959.html b/content/xbl/test/test_bug379959.html
index 137b28d318db..32b0e2029736 100644
--- a/content/xbl/test/test_bug379959.html
+++ b/content/xbl/test/test_bug379959.html
@@ -1,15 +1,15 @@
- Test for Bug 366770
+ Test for Bug 379959
-
- Mozilla Bug 366770
+
+ Mozilla Bug 379959
Note: In order to re-run this test correctly you need to shift-reload
rather than simply reload. If you just reload we will restore the
@@ -23,63 +23,74 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=366770
diff --git a/content/xml/document/src/XMLDocument.cpp b/content/xml/document/src/XMLDocument.cpp
index ab0f9b9832a3..5736e52c44dd 100644
--- a/content/xml/document/src/XMLDocument.cpp
+++ b/content/xml/document/src/XMLDocument.cpp
@@ -279,7 +279,7 @@ static void
ReportUseOfDeprecatedMethod(nsIDocument *aDoc, const char* aWarning)
{
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
- "DOM3 Load", aDoc,
+ NS_LITERAL_CSTRING("DOM3 Load"), aDoc,
nsContentUtils::eDOM_PROPERTIES,
aWarning);
}
diff --git a/content/xul/document/src/XULDocument.cpp b/content/xul/document/src/XULDocument.cpp
index 95c22ed0e8c2..7612b965203f 100644
--- a/content/xul/document/src/XULDocument.cpp
+++ b/content/xul/document/src/XULDocument.cpp
@@ -3076,7 +3076,7 @@ XULDocument::ResumeWalk()
nsContentUtils::ReportToConsole(
nsIScriptError::warningFlag,
- "XUL Document", nullptr,
+ NS_LITERAL_CSTRING("XUL Document"), nullptr,
nsContentUtils::eXUL_PROPERTIES,
"PINotInProlog",
params, ArrayLength(params),
@@ -3369,7 +3369,7 @@ XULDocument::ReportMissingOverlay(nsIURI* aURI)
NS_ConvertUTF8toUTF16 utfSpec(spec);
const PRUnichar* params[] = { utfSpec.get() };
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
- "XUL Document", this,
+ NS_LITERAL_CSTRING("XUL Document"), this,
nsContentUtils::eXUL_PROPERTIES,
"MissingOverlay",
params, ArrayLength(params));
diff --git a/content/xul/document/src/nsXULContentSink.cpp b/content/xul/document/src/nsXULContentSink.cpp
index 6918b9f26dd4..e6e33f1abeb4 100644
--- a/content/xul/document/src/nsXULContentSink.cpp
+++ b/content/xul/document/src/nsXULContentSink.cpp
@@ -56,6 +56,7 @@
#include "nsXMLContentSink.h"
#include "nsIConsoleService.h"
#include "nsIScriptError.h"
+#include "nsContentTypeParser.h"
#ifdef PR_LOGGING
static PRLogModuleInfo* gLog;
diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
index cda0c59c3833..eae632896218 100644
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -11983,7 +11983,7 @@ nsDocShell::GetControllerForCommand(const char * inCommand,
return root->GetControllerForCommand(inCommand, outController);
}
-nsresult
+NS_IMETHODIMP
nsDocShell::IsCommandEnabled(const char * inCommand, bool* outEnabled)
{
NS_ENSURE_ARG_POINTER(outEnabled);
@@ -11999,7 +11999,7 @@ nsDocShell::IsCommandEnabled(const char * inCommand, bool* outEnabled)
return rv;
}
-nsresult
+NS_IMETHODIMP
nsDocShell::DoCommand(const char * inCommand)
{
nsresult rv = NS_ERROR_FAILURE;
diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h
index 454ec925afaa..8ebe45fbfcd6 100644
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -643,8 +643,6 @@ protected:
// helpers for executing commands
nsresult GetControllerForCommand(const char *inCommand,
nsIController** outController);
- nsresult IsCommandEnabled(const char * inCommand, bool* outEnabled);
- nsresult DoCommand(const char * inCommand);
nsresult EnsureCommandHandler();
nsIChannel* GetCurrentDocChannel();
diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl
index 3f4110922819..63d5f2d4180f 100644
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -42,7 +42,7 @@ interface nsIVariant;
interface nsIPrivacyTransitionObserver;
interface nsIReflowObserver;
-[scriptable, builtinclass, uuid(b5bd6052-ec8c-45bf-b55c-409ad15cecfb)]
+[scriptable, builtinclass, uuid(365e7446-6c4b-45ae-ae08-b7b401900093)]
interface nsIDocShell : nsIDocShellTreeItem
{
/**
@@ -873,4 +873,12 @@ interface nsIDocShell : nsIDocShellTreeItem
* Returns false for mLSHE, true for mOSHE
*/
boolean getCurrentSHEntry(out nsISHEntry aEntry);
+
+ /**
+ * Cherry picked parts of nsIController.
+ * They are here, because we want to call these functions
+ * from JS.
+ */
+ boolean isCommandEnabled(in string command);
+ void doCommand(in string command);
};
diff --git a/docshell/test/test_bug369814.html b/docshell/test/test_bug369814.html
index a47b9fc72ffa..3e257f9af305 100644
--- a/docshell/test/test_bug369814.html
+++ b/docshell/test/test_bug369814.html
@@ -26,13 +26,9 @@ SimpleTest.waitForExplicitFinish();
// checking the results.
const gLoadEventLoopCount = 100;
-var Ci = SpecialPowers.Ci;
-
var gCurrentTest;
var gTargetWindow;
var gNumPokes;
-var gPrefValue;
-
var gTestFrame;
/**
@@ -186,49 +182,36 @@ var gNextTest = 0;
function runNextTest()
{
- var prefs = SpecialPowers.Cc["@mozilla.org/preferences-service;1"]
- .getService(SpecialPowers.Ci.nsIPrefBranch);
-
if (gNextTest < gTests.length) {
gCurrentTest = gTests[gNextTest++];
gNumPokes = 0;
- prefs.setBoolPref("network.jar.open-unsafe-types", gCurrentTest['pref']);
+ SpecialPowers.pushPrefEnv({"set": [["network.jar.open-unsafe-types", gCurrentTest['pref']]]}, function() {
- // Create a new frame each time, so our restictions on loads in a
- // jar:-loaded iframe don't interfere with the test.
- if (gTestFrame) {
- document.body.removeChild(gTestFrame);
- }
- gTestFrame = document.createElement("iframe");
- document.body.insertBefore(gTestFrame, $("test"));
+ // Create a new frame each time, so our restictions on loads in a
+ // jar:-loaded iframe don't interfere with the test.
+ if (gTestFrame) {
+ document.body.removeChild(gTestFrame);
+ }
+ gTestFrame = document.createElement("iframe");
+ document.body.insertBefore(gTestFrame, $("test"));
- gCurrentTest['func'](gCurrentTest);
+ gCurrentTest['func'](gCurrentTest);
+ });
} else {
- // Put back the pref value we had at test start
- prefs.setBoolPref("network.jar.open-unsafe-types", gPrefValue);
SimpleTest.finish();
}
}
function finishTest()
{
- var prefs = SpecialPowers.Cc["@mozilla.org/preferences-service;1"]
- .getService(SpecialPowers.Ci.nsIPrefBranch);
- prefs.setBoolPref("network.jar.open-unsafe-types", false);
+ SpecialPowers.pushPrefEnv({"set": [["network.jar.open-unsafe-types", false]]}, function() {
+ if (gNumPokes == 0) {
+ ok(true, gCurrentTest["name"] + ": no unexpected pokes");
+ }
- if (gNumPokes == 0) {
- ok(true, gCurrentTest["name"] + ": no unexpected pokes");
- }
-
- runNextTest();
-}
-
-function startTests()
-{
- var prefs = SpecialPowers.Cc["@mozilla.org/preferences-service;1"]
- .getService(SpecialPowers.Ci.nsIPrefBranch);
- gPrefValue = prefs.getBoolPref("network.jar.open-unsafe-types");
+ runNextTest();
+ });
}
addLoadEvent(runNextTest);
@@ -237,4 +220,3 @@ addLoadEvent(runNextTest);
-
diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp
index b5fe80ff25b8..df630fa0f090 100644
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2565,7 +2565,7 @@ nsDOMWindowUtils::GetOuterWindowWithId(uint64_t aWindowID,
// XXX This method is deprecated. See bug 865664.
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
- "DOM",
+ NS_LITERAL_CSTRING("DOM"),
nsContentUtils::GetDocumentFromCaller(),
nsContentUtils::eDOM_PROPERTIES,
"GetWindowWithOuterIdWarning");
diff --git a/dom/base/nsFocusManager.cpp b/dom/base/nsFocusManager.cpp
index b73fa2465956..ace94abc1257 100644
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -1158,7 +1158,7 @@ nsFocusManager::SetFocusInner(nsIContent* aNewContent, int32_t aFlags,
(fullscreenAncestor = nsContentUtils::GetFullscreenAncestor(contentToFocus->OwnerDoc())) &&
nsContentUtils::HasPluginWithUncontrolledEventDispatch(contentToFocus)) {
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
- "DOM",
+ NS_LITERAL_CSTRING("DOM"),
contentToFocus->OwnerDoc(),
nsContentUtils::eDOM_PROPERTIES,
"FocusedWindowedPluginWhileFullScreen");
diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
index 495221856b0c..78236c8c37ea 100644
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1535,7 +1535,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindow)
if (!sWarnedAboutWindowInternal) {
sWarnedAboutWindowInternal = true;
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
- "Extensions", mDoc,
+ NS_LITERAL_CSTRING("Extensions"), mDoc,
nsContentUtils::eDOM_PROPERTIES,
"nsIDOMWindowInternalWarning");
}
@@ -6204,7 +6204,7 @@ ReportUseOfDeprecatedMethod(nsGlobalWindow* aWindow, const char* aWarning)
{
nsCOMPtr doc = aWindow->GetExtantDoc();
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
- "DOM Events", doc,
+ NS_LITERAL_CSTRING("DOM Events"), doc,
nsContentUtils::eDOM_PROPERTIES,
aWarning);
}
@@ -7087,7 +7087,7 @@ nsGlobalWindow::Close()
// report localized error msg in JS console
nsContentUtils::ReportToConsole(
nsIScriptError::warningFlag,
- "DOM Window", mDoc, // Better name for the category?
+ NS_LITERAL_CSTRING("DOM Window"), mDoc, // Better name for the category?
nsContentUtils::eDOM_PROPERTIES,
"WindowCloseBlockedWarning");
diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp
index cefe79c494de..c8019f5cc090 100644
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -174,6 +174,7 @@ static uint32_t sForgetSkippableBeforeCC = 0;
static uint32_t sPreviousSuspectedCount = 0;
static uint32_t sCleanupsSinceLastGC = UINT32_MAX;
static bool sNeedsFullCC = false;
+static bool sNeedsGCAfterCC = false;
static nsJSContext *sContextList = nullptr;
static nsScriptNameSpaceManager *gNameSpaceManager;
@@ -685,7 +686,8 @@ static const char js_werror_option_str[] = JS_OPTIONS_DOT_STR "werror";
static const char js_zeal_option_str[] = JS_OPTIONS_DOT_STR "gczeal";
static const char js_zeal_frequency_str[] = JS_OPTIONS_DOT_STR "gczeal.frequency";
#endif
-static const char js_typeinfer_str[] = JS_OPTIONS_DOT_STR "typeinference";
+static const char js_typeinfer_content_str[] = JS_OPTIONS_DOT_STR "typeinference.content";
+static const char js_typeinfer_chrome_str[] = JS_OPTIONS_DOT_STR "typeinference.chrome";
static const char js_jit_hardening_str[] = JS_OPTIONS_DOT_STR "jit_hardening";
static const char js_memlog_option_str[] = JS_OPTIONS_DOT_STR "mem.log";
static const char js_memnotify_option_str[] = JS_OPTIONS_DOT_STR "mem.notify";
@@ -694,6 +696,7 @@ static const char js_baselinejit_content_str[] = JS_OPTIONS_DOT_STR "baselinejit
static const char js_baselinejit_chrome_str[] = JS_OPTIONS_DOT_STR "baselinejit.chrome";
static const char js_baselinejit_eager_str[] = JS_OPTIONS_DOT_STR "baselinejit.unsafe_eager_compilation";
static const char js_ion_content_str[] = JS_OPTIONS_DOT_STR "ion.content";
+static const char js_ion_chrome_str[] = JS_OPTIONS_DOT_STR "ion.chrome";
static const char js_ion_eager_str[] = JS_OPTIONS_DOT_STR "ion.unsafe_eager_compilation";
static const char js_ion_parallel_compilation_str[] = JS_OPTIONS_DOT_STR "ion.parallel_compilation";
@@ -723,13 +726,17 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
nsCOMPtr contentWindow(do_QueryInterface(global));
nsCOMPtr chromeWindow(do_QueryInterface(global));
- bool useTypeInference = !chromeWindow && contentWindow && Preferences::GetBool(js_typeinfer_str);
+ bool useTypeInference = Preferences::GetBool((chromeWindow || !contentWindow) ?
+ js_typeinfer_chrome_str :
+ js_typeinfer_content_str);
bool useHardening = Preferences::GetBool(js_jit_hardening_str);
- bool useBaselineJIT = Preferences::GetBool(chromeWindow || !contentWindow ?
+ bool useBaselineJIT = Preferences::GetBool((chromeWindow || !contentWindow) ?
js_baselinejit_chrome_str :
js_baselinejit_content_str);
bool useBaselineJITEager = Preferences::GetBool(js_baselinejit_eager_str);
- bool useIon = Preferences::GetBool(js_ion_content_str);
+ bool useIon = Preferences::GetBool((chromeWindow || !contentWindow) ?
+ js_ion_chrome_str :
+ js_ion_content_str);
bool useIonEager = Preferences::GetBool(js_ion_eager_str);
bool useAsmJS = Preferences::GetBool(js_asmjs_content_str);
bool parallelIonCompilation = Preferences::GetBool(js_ion_parallel_compilation_str);
@@ -2049,7 +2056,8 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
// If we collected a substantial amount of cycles, poke the GC since more objects
// might be unreachable now.
if (sCCollectedWaitingForGC > 250 ||
- sLikelyShortLivingObjectsNeedingGC > 2500) {
+ sLikelyShortLivingObjectsNeedingGC > 2500 ||
+ sNeedsGCAfterCC) {
PokeGC(JS::gcreason::CC_WAITING);
}
@@ -2164,6 +2172,7 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
sRemovedPurples = 0;
sForgetSkippableBeforeCC = 0;
sNeedsFullCC = false;
+ sNeedsGCAfterCC = false;
}
// static
@@ -2314,6 +2323,14 @@ nsJSContext::PokeGC(JS::gcreason::Reason aReason, int aDelay)
return;
}
+ if (sCCTimer) {
+ // Make sure CC is called...
+ sNeedsFullCC = true;
+ // and GC after it.
+ sNeedsGCAfterCC = true;
+ return;
+ }
+
CallCreateInstance("@mozilla.org/timer;1", &sGCTimer);
if (!sGCTimer) {
@@ -2579,6 +2596,7 @@ mozilla::dom::StartupJSEnvironment()
sLikelyShortLivingObjectsNeedingGC = 0;
sPostGCEventsToConsole = false;
sNeedsFullCC = false;
+ sNeedsGCAfterCC = false;
gNameSpaceManager = nullptr;
sRuntimeService = nullptr;
sRuntime = nullptr;
diff --git a/dom/base/nsWrapperCache.h b/dom/base/nsWrapperCache.h
index 41052db84dfb..21963d71d88b 100644
--- a/dom/base/nsWrapperCache.h
+++ b/dom/base/nsWrapperCache.h
@@ -656,4 +656,50 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsWrapperCache, NS_WRAPPERCACHE_IID)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
+#define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_12(_class, \
+ _field1, \
+ _field2, \
+ _field3, \
+ _field4, \
+ _field5, \
+ _field6, \
+ _field7, \
+ _field8, \
+ _field9, \
+ _field10, \
+ _field11, \
+ _field12) \
+ NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(_field1) \
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(_field2) \
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(_field3) \
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(_field4) \
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(_field5) \
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(_field6) \
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(_field7) \
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(_field8) \
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(_field9) \
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(_field10) \
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(_field11) \
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(_field12) \
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field1) \
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field2) \
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field3) \
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field4) \
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field5) \
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field6) \
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field7) \
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field8) \
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field9) \
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field10) \
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field11) \
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field12) \
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
+ NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
+
#endif /* nsWrapperCache_h___ */
diff --git a/dom/icc/src/StkCommandEvent.h b/dom/icc/src/StkCommandEvent.h
index 30ac05d87b5f..feeadeb95c63 100644
--- a/dom/icc/src/StkCommandEvent.h
+++ b/dom/icc/src/StkCommandEvent.h
@@ -22,7 +22,6 @@ public:
NS_DECL_ISUPPORTS_INHERITED
NS_FORWARD_TO_NSDOMEVENT
NS_DECL_NSIDOMMOZSTKCOMMANDEVENT
- NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(StkCommandEvent, nsDOMEvent)
static already_AddRefed
Create(EventTarget* aOwner, const nsAString& aMessage);
diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp
index aad2bde6b200..96bb12ee7101 100644
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -45,6 +45,7 @@
#include "ipc/IndexedDBParent.h"
#include "IndexedDatabaseInlines.h"
+#include "nsCharSeparatedTokenizer.h"
#define FILE_COPY_BUFFER_SIZE 32768
diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp
index 0a06f8971748..ab6275d5f70f 100644
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -110,6 +110,8 @@ static const char BROWSER_ZOOM_TO_RECT[] = "browser-zoom-to-rect";
static const char BEFORE_FIRST_PAINT[] = "before-first-paint";
static const char DETECT_SCROLLABLE_SUBFRAME[] = "detect-scrollable-subframe";
+static bool sCpowsEnabled = false;
+
NS_IMETHODIMP
ContentListener::HandleEvent(nsIDOMEvent* aEvent)
{
@@ -2339,6 +2341,11 @@ TabChild::InitRenderingState()
false);
}
+ // This state can't really change during the lifetime of the child.
+ sCpowsEnabled = Preferences::GetBool("browser.tabs.remote", false);
+ if (Preferences::GetBool("dom.ipc.cpows.force-disabled", false))
+ sCpowsEnabled = false;
+
return true;
}
@@ -2469,8 +2476,10 @@ TabChild::DoSendSyncMessage(JSContext* aCx,
return false;
}
InfallibleTArray cpows;
- if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
- return false;
+ if (sCpowsEnabled) {
+ if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
+ return false;
+ }
}
return SendSyncMessage(nsString(aMessage), data, cpows, aJSONRetVal);
}
@@ -2487,8 +2496,10 @@ TabChild::DoSendAsyncMessage(JSContext* aCx,
return false;
}
InfallibleTArray cpows;
- if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
- return false;
+ if (sCpowsEnabled) {
+ if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
+ return false;
+ }
}
return SendAsyncMessage(nsString(aMessage), data, cpows);
}
diff --git a/dom/src/json/nsJSON.cpp b/dom/src/json/nsJSON.cpp
index 5a2f85aaeaf7..31fc81e23959 100644
--- a/dom/src/json/nsJSON.cpp
+++ b/dom/src/json/nsJSON.cpp
@@ -49,7 +49,7 @@ static nsresult
WarnDeprecatedMethod(DeprecationWarning warning)
{
return nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
- "DOM Core", nullptr,
+ NS_LITERAL_CSTRING("DOM Core"), nullptr,
nsContentUtils::eDOM_PROPERTIES,
warning == EncodeWarning
? "nsIJSONEncodeDeprecatedWarning"
diff --git a/dom/webidl/WebGL2RenderingContext.webidl b/dom/webidl/WebGL2RenderingContext.webidl
index 612211e2e031..5851ac49a7f1 100644
--- a/dom/webidl/WebGL2RenderingContext.webidl
+++ b/dom/webidl/WebGL2RenderingContext.webidl
@@ -77,6 +77,9 @@ interface WebGL2RenderingContext : WebGLRenderingContext {
const GLenum TRANSFORM_FEEDBACK_BUFFER_SIZE = 0x8C85;
const GLenum MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 0x8C8B;
+ /* transform feedback queries */
+ const GLenum TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = 0x8C88;
+
/* buffer objects */
void bindBufferBase(GLenum target, GLuint index, WebGLBuffer? buffer);
void bindBufferRange(GLenum target, GLuint index, WebGLBuffer? buffer,
diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp
index a5ca54d1773d..3f6835969fd4 100644
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -292,9 +292,6 @@ LoadJSContextOptions(const char* aPrefName, void* /* aClosure */)
if (GetWorkerPref(NS_LITERAL_CSTRING("werror"))) {
commonOptions |= JSOPTION_WERROR;
}
- if (GetWorkerPref(NS_LITERAL_CSTRING("typeinference"))) {
- commonOptions |= JSOPTION_TYPE_INFERENCE;
- }
if (GetWorkerPref(NS_LITERAL_CSTRING("asmjs"))) {
commonOptions |= JSOPTION_ASMJS;
}
@@ -307,6 +304,9 @@ LoadJSContextOptions(const char* aPrefName, void* /* aClosure */)
if (GetWorkerPref(NS_LITERAL_CSTRING("ion.content"))) {
contentOptions |= JSOPTION_ION;
}
+ if (GetWorkerPref(NS_LITERAL_CSTRING("typeinference.content"))) {
+ contentOptions |= JSOPTION_TYPE_INFERENCE;
+ }
// Chrome options.
uint32_t chromeOptions = commonOptions;
@@ -316,6 +316,9 @@ LoadJSContextOptions(const char* aPrefName, void* /* aClosure */)
if (GetWorkerPref(NS_LITERAL_CSTRING("ion.chrome"))) {
chromeOptions |= JSOPTION_ION;
}
+ if (GetWorkerPref(NS_LITERAL_CSTRING("typeinference.chrome"))) {
+ chromeOptions |= JSOPTION_TYPE_INFERENCE;
+ }
#ifdef DEBUG
if (GetWorkerPref(NS_LITERAL_CSTRING("strict.debug"))) {
chromeOptions |= JSOPTION_EXTRA_WARNINGS;
diff --git a/js/src/jit-test/tests/ion/bug904315.js b/js/src/jit-test/tests/ion/bug904315.js
new file mode 100644
index 000000000000..64239408f6b2
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug904315.js
@@ -0,0 +1,15 @@
+
+function g(o, idx, exp) {
+ for (var i=0; i<3000; i++) {
+ assertEq(o[idx], exp);
+ }
+}
+function f() {
+ var o = [];
+ for (var i=1; i<100; i++) {
+ o[-i] = 1;
+ }
+ g(o, 50, undefined);
+ g(o, -50, 1);
+}
+f();
diff --git a/js/src/jit-test/tests/ion/bug906035.js b/js/src/jit-test/tests/ion/bug906035.js
new file mode 100644
index 000000000000..7c847aed3eff
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug906035.js
@@ -0,0 +1,9 @@
+// |jit-test| ion-eager
+function y() { return "foo,bar"; }
+function x() {
+ var z = y().split(',');
+ for (var i = 0; i < z.length; i++) {}
+}
+gczeal(2);
+Object.prototype.length = function () {};
+x();
diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp
index 1437dbda53ad..0af7cd101277 100644
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -3598,6 +3598,12 @@ TryAttachGetElemStub(JSContext *cx, HandleScript script, ICGetElem_Fallback *stu
if (!obj->isNative() && !obj->is())
stub->noteNonNativeAccess();
+ // GetElem operations which could access negative indexes generally can't
+ // be optimized without the potential for bailouts, as we can't statically
+ // determine that an object has no properties on such indexes.
+ if (rhs.isNumber() && rhs.toNumber() < 0)
+ stub->noteNegativeIndex();
+
return true;
}
diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h
index 7417ead70301..2ec65bd40a48 100644
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -2787,6 +2787,9 @@ class ICGetElem_Fallback : public ICMonitoredFallbackStub
: ICMonitoredFallbackStub(ICStub::GetElem_Fallback, stubCode)
{ }
+ static const uint16_t EXTRA_NON_NATIVE = 0x1;
+ static const uint16_t EXTRA_NEGATIVE_INDEX = 0x2;
+
public:
static const uint32_t MAX_OPTIMIZED_STUBS = 16;
@@ -2797,10 +2800,17 @@ class ICGetElem_Fallback : public ICMonitoredFallbackStub
}
void noteNonNativeAccess() {
- extra_ = 1;
+ extra_ |= EXTRA_NON_NATIVE;
}
bool hasNonNativeAccess() const {
- return extra_;
+ return extra_ & EXTRA_NON_NATIVE;
+ }
+
+ void noteNegativeIndex() {
+ extra_ |= EXTRA_NEGATIVE_INDEX;
+ }
+ bool hasNegativeIndex() const {
+ return extra_ & EXTRA_NEGATIVE_INDEX;
}
// Compiler for this stub kind.
diff --git a/js/src/jit/BaselineInspector.cpp b/js/src/jit/BaselineInspector.cpp
index 94ca8ad114fb..a0cd4eca4a74 100644
--- a/js/src/jit/BaselineInspector.cpp
+++ b/js/src/jit/BaselineInspector.cpp
@@ -303,6 +303,20 @@ BaselineInspector::hasSeenNonNativeGetElement(jsbytecode *pc)
return false;
}
+bool
+BaselineInspector::hasSeenNegativeIndexGetElement(jsbytecode *pc)
+{
+ if (!hasBaselineScript())
+ return false;
+
+ const ICEntry &entry = icEntryFromPC(pc);
+ ICStub *stub = entry.fallbackStub();
+
+ if (stub->isGetElem_Fallback())
+ return stub->toGetElem_Fallback()->hasNegativeIndex();
+ return false;
+}
+
bool
BaselineInspector::hasSeenAccessedGetter(jsbytecode *pc)
{
diff --git a/js/src/jit/BaselineInspector.h b/js/src/jit/BaselineInspector.h
index c2772ad45035..81a09dff8706 100644
--- a/js/src/jit/BaselineInspector.h
+++ b/js/src/jit/BaselineInspector.h
@@ -104,6 +104,7 @@ class BaselineInspector
MIRType expectedBinaryArithSpecialization(jsbytecode *pc);
bool hasSeenNonNativeGetElement(jsbytecode *pc);
+ bool hasSeenNegativeIndexGetElement(jsbytecode *pc);
bool hasSeenAccessedGetter(jsbytecode *pc);
bool hasSeenDoubleResult(jsbytecode *pc);
};
diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp
index fcf338f26719..32b83aeaa3a6 100644
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -6433,6 +6433,8 @@ CodeGenerator::visitLoadElementHole(LLoadElementHole *lir)
Register initLength = ToRegister(lir->initLength());
const ValueOperand out = ToOutValue(lir);
+ const MLoadElementHole *mir = lir->mir();
+
// If the index is out of bounds, load |undefined|. Otherwise, load the
// value.
Label undefined, done;
@@ -6452,6 +6454,19 @@ CodeGenerator::visitLoadElementHole(LLoadElementHole *lir)
masm.jump(&done);
masm.bind(&undefined);
+
+ if (mir->needsNegativeIntCheck()) {
+ if (lir->index()->isConstant()) {
+ if (ToInt32(lir->index()) < 0 && !bailout(lir->snapshot()))
+ return false;
+ } else {
+ Label negative;
+ masm.branch32(Assembler::LessThan, ToRegister(lir->index()), Imm32(0), &negative);
+ if (!bailoutFrom(&negative, lir->snapshot()))
+ return false;
+ }
+ }
+
masm.moveValue(UndefinedValue(), out);
masm.bind(&done);
return true;
diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp
index 9eab8d3a54a2..0745e5b6cc6c 100644
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -6465,6 +6465,11 @@ IonBuilder::getElemTryDense(bool *emitted, MDefinition *obj, MDefinition *index)
if (ElementAccessHasExtraIndexedProperty(cx, obj) && failedBoundsCheck_)
return true;
+ // Don't generate a fast path if this pc has seen negative indexes accessed,
+ // which will not appear to be extra indexed properties.
+ if (inspector->hasSeenNegativeIndexGetElement(pc))
+ return true;
+
// Emit dense getelem variant.
if (!jsop_getelem_dense(obj, index))
return false;
diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp
index 4d986080230f..a40ce0eea6d8 100644
--- a/js/src/jit/IonCaches.cpp
+++ b/js/src/jit/IonCaches.cpp
@@ -1078,6 +1078,22 @@ GenerateTypedArrayLength(JSContext *cx, MacroAssembler &masm, IonCache::StubAtta
attacher.jumpNextStub(masm);
}
+static bool
+IsCacheableArrayLength(JSContext *cx, HandleObject obj, HandlePropertyName name,
+ TypedOrValueRegister output)
+{
+ if (!obj->is())
+ return false;
+
+ if (output.type() != MIRType_Value && output.type() != MIRType_Int32) {
+ // The stub assumes that we always output Int32, so make sure our output
+ // is equipped to handle that.
+ return false;
+ }
+
+ return true;
+}
+
template
static GetPropertyIC::NativeGetPropCacheability
CanAttachNativeGetProp(typename GetPropCache::Context cx, const GetPropCache &cache,
@@ -1111,7 +1127,9 @@ CanAttachNativeGetProp(typename GetPropCache::Context cx, const GetPropCache &ca
return GetPropertyIC::CanAttachReadSlot;
}
- if (obj->is() && cx->names().length == name) {
+ if (cx->names().length == name &&
+ IsCacheableArrayLength(cx, obj, name, cache.output()))
+ {
// The array length property is non-configurable, which means both that
// checking the class of the object and the name of the property is enough
// and that we don't need to worry about monitoring, since we know the
diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp
index 378c15dcdb36..4beec7b7e573 100644
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -2068,6 +2068,8 @@ LIRGenerator::visitLoadElementHole(MLoadElementHole *ins)
LLoadElementHole *lir = new LLoadElementHole(useRegister(ins->elements()),
useRegisterOrConstant(ins->index()),
useRegister(ins->initLength()));
+ if (ins->needsNegativeIntCheck() && !assignSnapshot(lir))
+ return false;
return defineBox(lir, ins);
}
diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h
index d27a4dfd63b9..548a3be07bb7 100644
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -4821,10 +4821,12 @@ class MLoadElementHole
: public MTernaryInstruction,
public SingleObjectPolicy
{
+ bool needsNegativeIntCheck_;
bool needsHoleCheck_;
MLoadElementHole(MDefinition *elements, MDefinition *index, MDefinition *initLength, bool needsHoleCheck)
: MTernaryInstruction(elements, index, initLength),
+ needsNegativeIntCheck_(true),
needsHoleCheck_(needsHoleCheck)
{
setResultType(MIRType_Value);
@@ -4854,12 +4856,16 @@ class MLoadElementHole
MDefinition *initLength() const {
return getOperand(2);
}
+ bool needsNegativeIntCheck() const {
+ return needsNegativeIntCheck_;
+ }
bool needsHoleCheck() const {
return needsHoleCheck_;
}
AliasSet getAliasSet() const {
return AliasSet::Load(AliasSet::Element);
}
+ void collectRangeInfo();
};
class MStoreElementCommon
diff --git a/js/src/jit/RangeAnalysis.cpp b/js/src/jit/RangeAnalysis.cpp
index c1e031fb5191..d8e710996513 100644
--- a/js/src/jit/RangeAnalysis.cpp
+++ b/js/src/jit/RangeAnalysis.cpp
@@ -2005,6 +2005,12 @@ MInArray::collectRangeInfo()
needsNegativeIntCheck_ = !index()->range() || index()->range()->lower() < 0;
}
+void
+MLoadElementHole::collectRangeInfo()
+{
+ needsNegativeIntCheck_ = !index()->range() || index()->range()->lower() < 0;
+}
+
void
MMod::collectRangeInfo()
{
diff --git a/js/src/jscntxt.cpp b/js/src/jscntxt.cpp
index d8417a135046..be5f944c3ae0 100644
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -262,6 +262,11 @@ js::DestroyContext(JSContext *cx, DestroyContextMode mode)
CancelOffThreadIonCompile(c, NULL);
WaitForOffThreadParsingToFinish(rt);
+#ifdef JS_WORKER_THREADS
+ if (rt->workerThreadState)
+ rt->workerThreadState->cleanup(rt);
+#endif
+
/* Unpin all common names before final GC. */
FinishCommonNames(rt);
diff --git a/js/src/jscntxtinlines.h b/js/src/jscntxtinlines.h
index 6cdf75841685..eb5030185a0f 100644
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -10,6 +10,7 @@
#include "jscntxt.h"
#include "jsiter.h"
+#include "jsworkers.h"
#include "builtin/Object.h"
#include "jit/IonFrames.h"
diff --git a/js/src/jsmath.cpp b/js/src/jsmath.cpp
index a3347d793319..67e05ccfa7ac 100644
--- a/js/src/jsmath.cpp
+++ b/js/src/jsmath.cpp
@@ -1101,6 +1101,8 @@ js::math_atanh(JSContext *cx, unsigned argc, Value *vp)
return math_function(cx, argc, vp);
}
+// Math.hypot is disabled pending the resolution of spec issues (bug 896264).
+#if 0
#if !HAVE_HYPOT
double hypot(double x, double y)
{
@@ -1166,6 +1168,7 @@ js::math_hypot(JSContext *cx, unsigned argc, Value *vp)
args.rval().setNumber(math_hypot_impl(math_hypot_impl(x, y), z));
return true;
}
+#endif
#if !HAVE_TRUNC
double trunc(double x)
@@ -1274,7 +1277,10 @@ static const JSFunctionSpec math_static_methods[] = {
JS_FN("acosh", math_acosh, 1, 0),
JS_FN("asinh", math_asinh, 1, 0),
JS_FN("atanh", math_atanh, 1, 0),
+// Math.hypot is disabled pending the resolution of spec issues (bug 896264).
+#if 0
JS_FN("hypot", math_hypot, 2, 0),
+#endif
JS_FN("trunc", math_trunc, 1, 0),
JS_FN("sign", math_sign, 1, 0),
JS_FN("cbrt", math_cbrt, 1, 0),
diff --git a/js/src/jsmath.h b/js/src/jsmath.h
index 3a643d546dce..8e9ccece422c 100644
--- a/js/src/jsmath.h
+++ b/js/src/jsmath.h
@@ -159,8 +159,11 @@ math_asinh(JSContext *cx, unsigned argc, js::Value *vp);
extern bool
math_atanh(JSContext *cx, unsigned argc, js::Value *vp);
+// Math.hypot is disabled pending the resolution of spec issues (bug 896264).
+#if 0
extern bool
math_hypot(JSContext *cx, unsigned argc, Value *vp);
+#endif
extern bool
math_trunc(JSContext *cx, unsigned argc, Value *vp);
@@ -243,8 +246,11 @@ math_asinh_impl(MathCache *cache, double x);
extern double
math_atanh_impl(MathCache *cache, double x);
+// Math.hypot is disabled pending the resolution of spec issues (bug 896264).
+#if 0
extern double
math_hypot_impl(double x, double y);
+#endif
extern double
math_trunc_impl(MathCache *cache, double x);
diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp
index fae864ede0a9..97801aedf378 100644
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -637,7 +637,7 @@ js::XDRScript(XDRState *xdr, HandleObject enclosingScope, HandleScript enc
code = ssd->data;
if (natoms != 0) {
script->natoms = natoms;
- script->atoms = ssd->atoms();
+ script->atoms = ssd->atoms(length, nsrcnotes);
}
}
@@ -1518,26 +1518,15 @@ js::SharedScriptData::new_(ExclusiveContext *cx, uint32_t codeLength,
uint32_t baseLength = codeLength + srcnotesLength;
uint32_t padding = sizeof(JSAtom *) - baseLength % sizeof(JSAtom *);
uint32_t length = baseLength + padding + sizeof(JSAtom *) * natoms;
- JS_ASSERT(length % sizeof(JSAtom *) == 0);
SharedScriptData *entry = (SharedScriptData *)cx->malloc_(length +
offsetof(SharedScriptData, data));
if (!entry)
return NULL;
- entry->length = length;
- entry->natoms = natoms;
entry->marked = false;
+ entry->length = length;
memset(entry->data + baseLength, 0, padding);
-
- /*
- * Call constructors to initialize the storage that will be accessed as a
- * HeapPtrAtom array via atoms().
- */
- HeapPtrAtom *atoms = entry->atoms();
- for (unsigned i = 0; i < natoms; ++i)
- new (&atoms[i]) HeapPtrAtom();
-
return entry;
}
@@ -1585,7 +1574,7 @@ SaveSharedScriptData(ExclusiveContext *cx, Handle script, SharedScri
#endif
script->code = ssd->data;
- script->atoms = ssd->atoms();
+ script->atoms = ssd->atoms(script->length, nsrcnotes);
return true;
}
@@ -1929,7 +1918,7 @@ JSScript::fullyInitFromEmitter(ExclusiveContext *cx, HandleScript script, Byteco
PodCopy(code + prologLength, bce->code().begin(), mainLength);
if (!FinishTakingSrcNotes(cx, bce, (jssrcnote *)(code + script->length)))
return false;
- InitAtomMap(bce->atomIndices.getMap(), ssd->atoms());
+ InitAtomMap(bce->atomIndices.getMap(), ssd->atoms(script->length, nsrcnotes));
if (!SaveSharedScriptData(cx, script, ssd, nsrcnotes))
return false;
@@ -2806,7 +2795,7 @@ JSScript::markChildren(JSTracer *trc)
if (IS_GC_MARKING_TRACER(trc)) {
compartment()->mark();
- if (code || natoms)
+ if (code)
MarkScriptData(trc->runtime, code);
}
diff --git a/js/src/jsscript.h b/js/src/jsscript.h
index ee20caf4239b..a845c52d50c9 100644
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -1427,27 +1427,22 @@ CallDestroyScriptHook(FreeOp *fop, JSScript *script);
struct SharedScriptData
{
- uint32_t length;
- uint32_t natoms;
bool marked;
+ uint32_t length;
jsbytecode data[1];
static SharedScriptData *new_(ExclusiveContext *cx, uint32_t codeLength,
uint32_t srcnotesLength, uint32_t natoms);
- HeapPtrAtom *atoms() {
- if (!natoms)
- return NULL;
- return reinterpret_cast(data + length - sizeof(JSAtom *) * natoms);
+ HeapPtrAtom *atoms(uint32_t codeLength, uint32_t srcnotesLength) {
+ uint32_t length = codeLength + srcnotesLength;
+ return reinterpret_cast(data + length + sizeof(JSAtom *) -
+ length % sizeof(JSAtom *));
}
static SharedScriptData *fromBytecode(const jsbytecode *bytecode) {
return (SharedScriptData *)(bytecode - offsetof(SharedScriptData, data));
}
-
- private:
- SharedScriptData() MOZ_DELETE;
- SharedScriptData(const SharedScriptData&) MOZ_DELETE;
};
struct ScriptBytecodeHasher
diff --git a/js/src/jsworkers.cpp b/js/src/jsworkers.cpp
index fde2174e0c66..3a10377accda 100644
--- a/js/src/jsworkers.cpp
+++ b/js/src/jsworkers.cpp
@@ -359,18 +359,33 @@ WorkerThreadState::init(JSRuntime *rt)
return true;
}
-WorkerThreadState::~WorkerThreadState()
+void
+WorkerThreadState::cleanup(JSRuntime *rt)
{
- /*
- * Join created threads first, which needs locks and condition variables
- * to be intact.
- */
+ // Do preparatory work for shutdown before the final GC has destroyed most
+ // of the GC heap.
+
+ // Join created threads, to ensure there is no in progress work.
if (threads) {
for (size_t i = 0; i < numThreads; i++)
threads[i].destroy();
js_free(threads);
+ threads = NULL;
+ numThreads = 0;
}
+ // Clean up any parse tasks which haven't been finished yet.
+ while (!parseFinishedList.empty()) {
+ JSScript *script = parseFinishedList[0]->script;
+ finishParseTaskForScript(rt, script);
+ }
+}
+
+WorkerThreadState::~WorkerThreadState()
+{
+ JS_ASSERT(!threads);
+ JS_ASSERT(parseFinishedList.empty());
+
if (workerLock)
PR_DestroyLock(workerLock);
diff --git a/js/src/jsworkers.h b/js/src/jsworkers.h
index e258ad953c82..934670410285 100644
--- a/js/src/jsworkers.h
+++ b/js/src/jsworkers.h
@@ -30,8 +30,7 @@ namespace ion {
class IonBuilder;
}
-#if defined(JS_THREADSAFE) && defined(JS_ION)
-# define JS_WORKER_THREADS
+#ifdef JS_WORKER_THREADS
/* Per-runtime state for off thread work items. */
class WorkerThreadState
@@ -75,6 +74,7 @@ class WorkerThreadState
~WorkerThreadState();
bool init(JSRuntime *rt);
+ void cleanup(JSRuntime *rt);
void lock();
void unlock();
@@ -236,27 +236,31 @@ WaitForOffThreadParsingToFinish(JSRuntime *rt);
class AutoLockWorkerThreadState
{
- WorkerThreadState &state;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
+#ifdef JS_WORKER_THREADS
+ WorkerThreadState &state;
+
public:
AutoLockWorkerThreadState(WorkerThreadState &state
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: state(state)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-#ifdef JS_WORKER_THREADS
state.lock();
-#else
- (void)state;
-#endif
}
~AutoLockWorkerThreadState() {
-#ifdef JS_WORKER_THREADS
state.unlock();
-#endif
}
+#else
+ public:
+ AutoLockWorkerThreadState(WorkerThreadState &state
+ MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+ {
+ MOZ_GUARD_OBJECT_NOTIFIER_INIT;
+ }
+#endif
};
class AutoUnlockWorkerThreadState
diff --git a/js/src/tests/ecma_6/Math/hypot-approx.js b/js/src/tests/ecma_6/Math/hypot-approx.js
index 1b68aad52fcd..9960d55d2ea6 100644
--- a/js/src/tests/ecma_6/Math/hypot-approx.js
+++ b/js/src/tests/ecma_6/Math/hypot-approx.js
@@ -1,3 +1,6 @@
+// |reftest| skip
+// Math.hypot is disabled pending the resolution of spec issues (bug 896264).
+
for (var i = -20; i < 20; i++)
assertEq(Math.hypot(+0, i), Math.abs(i));
diff --git a/js/src/tests/ecma_6/Math/hypot-exact.js b/js/src/tests/ecma_6/Math/hypot-exact.js
index 6f37b6607e59..059c896ffb1a 100644
--- a/js/src/tests/ecma_6/Math/hypot-exact.js
+++ b/js/src/tests/ecma_6/Math/hypot-exact.js
@@ -1,3 +1,6 @@
+// |reftest| skip
+// Math.hypot is disabled pending the resolution of spec issues (bug 896264).
+
// Properties of Math.hypot that are guaranteed by the spec.
// If any argument is +∞, the result is +∞.
diff --git a/js/src/vm/Runtime-inl.h b/js/src/vm/Runtime-inl.h
index 1736037a16b7..7386c79d9888 100644
--- a/js/src/vm/Runtime-inl.h
+++ b/js/src/vm/Runtime-inl.h
@@ -74,7 +74,7 @@ ThreadDataIter::ThreadDataIter(JSRuntime *rt)
#ifdef JS_WORKER_THREADS
// Only allow iteration over a runtime's threads when those threads are
// paused, to avoid racing when reading data from the PerThreadData.
- JS_ASSERT_IF(rt->workerThreadState, rt->workerThreadState->shouldPause);
+ JS_ASSERT(rt->exclusiveThreadsPaused);
#endif
iter = rt->threadList.getFirst();
}
diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h
index 8a2bb7bce51b..e0fbd0b1d343 100644
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -663,6 +663,7 @@ typedef Vector ZoneVector;
class AutoLockForExclusiveAccess;
class AutoPauseWorkersForGC;
+class ThreadDataIter;
} // namespace js
@@ -772,6 +773,7 @@ struct JSRuntime : public JS::shadow::Runtime,
friend class js::AutoLockForExclusiveAccess;
friend class js::AutoPauseWorkersForGC;
+ friend class js::ThreadDataIter;
public:
void setUsedByExclusiveThread(JS::Zone *zone);
@@ -1317,6 +1319,7 @@ struct JSRuntime : public JS::shadow::Runtime,
#ifdef JS_THREADSAFE
# ifdef JS_ION
js::WorkerThreadState *workerThreadState;
+# define JS_WORKER_THREADS
# endif
js::SourceCompressorThread sourceCompressorThread;
diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h
index 054f667ee7b5..c96995f89fd2 100644
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -2267,6 +2267,7 @@ public:
NS_IMETHOD Unroot(void *p) { return NS_OK; }
NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(XPCWrappedNative)
};
+ NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(XPCWrappedNative);
static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
void DeleteCycleCollectable() {}
diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp
index e57e0dd503b4..3d7acc8b20ab 100644
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -9169,7 +9169,8 @@ nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState,
(display->mDisplay == NS_STYLE_DISPLAY_INLINE_BOX)
? "NeededToWrapXULInlineBox" : "NeededToWrapXUL";
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
- "FrameConstructor", mDocument,
+ NS_LITERAL_CSTRING("FrameConstructor"),
+ mDocument,
nsContentUtils::eXUL_PROPERTIES,
message,
params, ArrayLength(params));
diff --git a/layout/generic/nsImageMap.cpp b/layout/generic/nsImageMap.cpp
index 1b20d5e2dbb3..8cc50b8e7096 100644
--- a/layout/generic/nsImageMap.cpp
+++ b/layout/generic/nsImageMap.cpp
@@ -91,7 +91,7 @@ static void logMessage(nsIContent* aContent,
nsIDocument* doc = aContent->OwnerDoc();
nsContentUtils::ReportToConsole(
- aFlags, "ImageMap", doc,
+ aFlags, NS_LITERAL_CSTRING("ImageMap"), doc,
nsContentUtils::eLAYOUT_PROPERTIES,
aMessageName,
nullptr, /* params */
diff --git a/layout/mathml/nsMathMLContainerFrame.cpp b/layout/mathml/nsMathMLContainerFrame.cpp
index e92b6d46159e..0a1ae413a9c1 100644
--- a/layout/mathml/nsMathMLContainerFrame.cpp
+++ b/layout/mathml/nsMathMLContainerFrame.cpp
@@ -1523,7 +1523,7 @@ nsMathMLContainerFrame::ReportErrorToConsole(const char* errorMsgId,
uint32_t aParamCount)
{
return nsContentUtils::ReportToConsole(nsIScriptError::errorFlag,
- "MathML", mContent->OwnerDoc(),
+ NS_LITERAL_CSTRING("MathML"), mContent->OwnerDoc(),
nsContentUtils::eMATHML_PROPERTIES,
errorMsgId, aParams, aParamCount);
}
diff --git a/layout/style/Loader.cpp b/layout/style/Loader.cpp
index add571174f19..11a3db478c42 100644
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -916,7 +916,8 @@ SheetLoadData::OnStreamComplete(nsIUnicharStreamLoader* aLoader,
nsCOMPtr referrer = GetReferrerURI();
nsContentUtils::ReportToConsole(errorFlag,
- "CSS Loader", mLoader->mDocument,
+ NS_LITERAL_CSTRING("CSS Loader"),
+ mLoader->mDocument,
nsContentUtils::eCSS_PROPERTIES,
errorMessage,
strings, ArrayLength(strings),
diff --git a/layout/style/nsCSSValue.cpp b/layout/style/nsCSSValue.cpp
index 8f8a7fd0da78..d4dc8af186a3 100644
--- a/layout/style/nsCSSValue.cpp
+++ b/layout/style/nsCSSValue.cpp
@@ -56,11 +56,6 @@ nsCSSValue::nsCSSValue(const nsString& aValue, nsCSSUnit aUnit)
NS_ABORT_IF_FALSE(UnitHasStringValue(), "not a string value");
if (UnitHasStringValue()) {
mValue.mString = BufferFromString(aValue).get();
- if (MOZ_UNLIKELY(!mValue.mString)) {
- // XXXbz not much we can do here; just make sure that our promise of a
- // non-null mValue.mString holds for string units.
- mUnit = eCSSUnit_Null;
- }
}
else {
mUnit = eCSSUnit_Null;
@@ -345,11 +340,6 @@ void nsCSSValue::SetStringValue(const nsString& aValue,
NS_ABORT_IF_FALSE(UnitHasStringValue(), "not a string unit");
if (UnitHasStringValue()) {
mValue.mString = BufferFromString(aValue).get();
- if (MOZ_UNLIKELY(!mValue.mString)) {
- // XXXbz not much we can do here; just make sure that our promise of a
- // non-null mValue.mString holds for string units.
- mUnit = eCSSUnit_Null;
- }
} else
mUnit = eCSSUnit_Null;
}
diff --git a/layout/style/nsCSSValue.h b/layout/style/nsCSSValue.h
index bcc3846785ee..fecaf0dbd447 100644
--- a/layout/style/nsCSSValue.h
+++ b/layout/style/nsCSSValue.h
@@ -514,8 +514,8 @@ public:
// Checks if this is a function value with the specified function id.
bool EqualsFunction(nsCSSKeyword aFunctionId) const;
- // Returns an already addrefed buffer. Can return null on allocation
- // failure.
+ // Returns an already addrefed buffer. Guaranteed to return non-null.
+ // (Will abort on allocation failure.)
static already_AddRefed
BufferFromString(const nsString& aValue);
diff --git a/layout/style/nsStyleAnimation.cpp b/layout/style/nsStyleAnimation.cpp
index 71ee46b25fb3..baa602b9bda0 100644
--- a/layout/style/nsStyleAnimation.cpp
+++ b/layout/style/nsStyleAnimation.cpp
@@ -3402,11 +3402,6 @@ nsStyleAnimation::Value::SetUnparsedStringValue(const nsString& aString)
FreeValue();
mUnit = eUnit_UnparsedString;
mValue.mString = nsCSSValue::BufferFromString(aString).get();
- if (MOZ_UNLIKELY(!mValue.mString)) {
- // not much we can do here; just make sure that our promise of a
- // non-null mValue.mString holds for string units.
- mUnit = eUnit_Null;
- }
}
void
diff --git a/mfbt/LinkedList.h b/mfbt/LinkedList.h
index c29760b3e73c..8308fb3dfd93 100644
--- a/mfbt/LinkedList.h
+++ b/mfbt/LinkedList.h
@@ -252,8 +252,8 @@ class LinkedListElement
}
private:
- LinkedListElement& operator=(const LinkedList& other) MOZ_DELETE;
- LinkedListElement(const LinkedList& other) MOZ_DELETE;
+ LinkedListElement& operator=(const LinkedListElement& other) MOZ_DELETE;
+ LinkedListElement(const LinkedListElement& other) MOZ_DELETE;
};
template
@@ -361,7 +361,7 @@ class LinkedList
for (slow = sentinel.next,
fast1 = sentinel.next->next,
fast2 = sentinel.next->next->next;
- slow != sentinel && fast1 != sentinel && fast2 != sentinel;
+ slow != &sentinel && fast1 != &sentinel && fast2 != &sentinel;
slow = slow->next, fast1 = fast2->next, fast2 = fast1->next)
{
MOZ_ASSERT(slow != fast1);
@@ -372,7 +372,7 @@ class LinkedList
for (slow = sentinel.prev,
fast1 = sentinel.prev->prev,
fast2 = sentinel.prev->prev->prev;
- slow != sentinel && fast1 != sentinel && fast2 != sentinel;
+ slow != &sentinel && fast1 != &sentinel && fast2 != &sentinel;
slow = slow->prev, fast1 = fast2->prev, fast2 = fast1->prev)
{
MOZ_ASSERT(slow != fast1);
@@ -384,14 +384,14 @@ class LinkedList
* isSentinel == true.
*/
for (const LinkedListElement* elem = sentinel.next;
- elem != sentinel;
+ elem != &sentinel;
elem = elem->next)
{
MOZ_ASSERT(!elem->isSentinel);
}
/* Check that the next/prev pointers match up. */
- const LinkedListElement* prev = sentinel;
+ const LinkedListElement* prev = &sentinel;
const LinkedListElement* cur = sentinel.next;
do {
MOZ_ASSERT(cur->prev == prev);
@@ -399,7 +399,7 @@ class LinkedList
prev = cur;
cur = cur->next;
- } while (cur != sentinel);
+ } while (cur != &sentinel);
#endif /* ifdef DEBUG */
}
diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js
index 98ed61d1ee8f..b7430818a22a 100644
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -475,9 +475,6 @@ pref("view_source.editor.args", "");
// When true this will word-wrap plain text documents.
pref("plain_text.wrap_long_lines", false);
-// dispatch left clicks only to content in browser (still allows clicks to chrome/xul)
-pref("nglayout.events.dispatchLeftClickOnly", true);
-
// whether or not to draw images while dragging
pref("nglayout.enable_drag_images", true);
@@ -822,10 +819,12 @@ pref("javascript.options.strict.debug", true);
pref("javascript.options.baselinejit.content", true);
pref("javascript.options.baselinejit.chrome", true);
pref("javascript.options.ion.content", true);
+pref("javascript.options.ion.chrome", false);
pref("javascript.options.asmjs", true);
pref("javascript.options.ion.parallel_compilation", true);
pref("javascript.options.jit_hardening", true);
-pref("javascript.options.typeinference", true);
+pref("javascript.options.typeinference.content", true);
+pref("javascript.options.typeinference.chrome", false);
// This preference limits the memory usage of javascript.
// If you want to change these values for your device,
// please find Bug 417052 comment 17 and Bug 456721
diff --git a/netwerk/base/public/nsNetUtil.h b/netwerk/base/public/nsNetUtil.h
index 1949c5e42441..91afd760d4e1 100644
--- a/netwerk/base/public/nsNetUtil.h
+++ b/netwerk/base/public/nsNetUtil.h
@@ -1976,19 +1976,26 @@ NS_RelaxStrictFileOriginPolicy(nsIURI *aTargetURI,
// inherit its source principal and be scriptable by that source.
//
bool sourceIsDir;
- bool contained = false;
+ bool allowed = false;
nsresult rv = sourceFile->IsDirectory(&sourceIsDir);
if (NS_SUCCEEDED(rv) && sourceIsDir) {
- rv = sourceFile->Contains(targetFile, true, &contained);
+ rv = sourceFile->Contains(targetFile, true, &allowed);
} else {
nsCOMPtr sourceParent;
rv = sourceFile->GetParent(getter_AddRefs(sourceParent));
if (NS_SUCCEEDED(rv) && sourceParent) {
- rv = sourceParent->Contains(targetFile, true, &contained);
+ rv = sourceParent->Equals(targetFile, &allowed);
+ if (NS_FAILED(rv) || !allowed) {
+ rv = sourceParent->Contains(targetFile, true, &allowed);
+ } else {
+ MOZ_ASSERT(aAllowDirectoryTarget,
+ "sourceFile->Parent == targetFile, but targetFile "
+ "should've been disallowed if it is a directory");
+ }
}
}
- if (NS_SUCCEEDED(rv) && contained) {
+ if (NS_SUCCEEDED(rv) && allowed) {
return true;
}
diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
index 636e35e92e63..c2f2865ac1cf 100644
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -270,39 +270,39 @@ nsHttpConnectionMgr::Observe(nsISupports *subject,
//-----------------------------------------------------------------------------
nsresult
-nsHttpConnectionMgr::AddTransaction(nsHttpTransaction *aTrans, int32_t priority)
+nsHttpConnectionMgr::AddTransaction(nsHttpTransaction *trans, int32_t priority)
{
- LOG(("nsHttpConnectionMgr::AddTransaction [trans=%x %d]\n", aTrans, priority));
+ LOG(("nsHttpConnectionMgr::AddTransaction [trans=%x %d]\n", trans, priority));
- nsRefPtr trans(aTrans);
+ NS_ADDREF(trans);
nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgNewTransaction, priority, trans);
- if (NS_SUCCEEDED(rv))
- trans.forget();
+ if (NS_FAILED(rv))
+ NS_RELEASE(trans);
return rv;
}
nsresult
-nsHttpConnectionMgr::RescheduleTransaction(nsHttpTransaction *aTrans, int32_t priority)
+nsHttpConnectionMgr::RescheduleTransaction(nsHttpTransaction *trans, int32_t priority)
{
- LOG(("nsHttpConnectionMgr::RescheduleTransaction [trans=%x %d]\n", aTrans, priority));
+ LOG(("nsHttpConnectionMgr::RescheduleTransaction [trans=%x %d]\n", trans, priority));
- nsRefPtr trans(aTrans);
+ NS_ADDREF(trans);
nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgReschedTransaction, priority, trans);
- if (NS_SUCCEEDED(rv))
- trans.forget();
+ if (NS_FAILED(rv))
+ NS_RELEASE(trans);
return rv;
}
nsresult
-nsHttpConnectionMgr::CancelTransaction(nsHttpTransaction *aTrans, nsresult reason)
+nsHttpConnectionMgr::CancelTransaction(nsHttpTransaction *trans, nsresult reason)
{
- LOG(("nsHttpConnectionMgr::CancelTransaction [trans=%x reason=%x]\n", aTrans, reason));
+ LOG(("nsHttpConnectionMgr::CancelTransaction [trans=%x reason=%x]\n", trans, reason));
- nsRefPtr trans(aTrans);
+ NS_ADDREF(trans);
nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgCancelTransaction,
static_cast(reason), trans);
- if (NS_SUCCEEDED(rv))
- trans.forget();
+ if (NS_FAILED(rv))
+ NS_RELEASE(trans);
return rv;
}
@@ -359,14 +359,14 @@ nsHttpConnectionMgr::GetSocketThreadTarget(nsIEventTarget **target)
}
nsresult
-nsHttpConnectionMgr::ReclaimConnection(nsHttpConnection *aConn)
+nsHttpConnectionMgr::ReclaimConnection(nsHttpConnection *conn)
{
- LOG(("nsHttpConnectionMgr::ReclaimConnection [conn=%x]\n", aConn));
+ LOG(("nsHttpConnectionMgr::ReclaimConnection [conn=%x]\n", conn));
- nsRefPtr conn(aConn);
+ NS_ADDREF(conn);
nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgReclaimConnection, 0, conn);
- if (NS_SUCCEEDED(rv))
- conn.forget();
+ if (NS_FAILED(rv))
+ NS_RELEASE(conn);
return rv;
}
@@ -405,14 +405,14 @@ nsHttpConnectionMgr::UpdateParam(nsParamName name, uint16_t value)
}
nsresult
-nsHttpConnectionMgr::ProcessPendingQ(nsHttpConnectionInfo *aCI)
+nsHttpConnectionMgr::ProcessPendingQ(nsHttpConnectionInfo *ci)
{
- LOG(("nsHttpConnectionMgr::ProcessPendingQ [ci=%s]\n", aCI->HashKey().get()));
+ LOG(("nsHttpConnectionMgr::ProcessPendingQ [ci=%s]\n", ci->HashKey().get()));
- nsRefPtr ci(aCI);
+ NS_ADDREF(ci);
nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgProcessPendingQ, 0, ci);
- if (NS_SUCCEEDED(rv))
- ci.forget();
+ if (NS_FAILED(rv))
+ NS_RELEASE(ci);
return rv;
}
@@ -2090,12 +2090,12 @@ nsHttpConnectionMgr::OnMsgNewTransaction(int32_t priority, void *param)
{
LOG(("nsHttpConnectionMgr::OnMsgNewTransaction [trans=%p]\n", param));
- nsRefPtr trans =
- dont_AddRef(static_cast(param));
+ nsHttpTransaction *trans = (nsHttpTransaction *) param;
trans->SetPriority(priority);
nsresult rv = ProcessNewTransaction(trans);
if (NS_FAILED(rv))
trans->Close(rv); // for whatever its worth
+ NS_RELEASE(trans);
}
void
@@ -2104,8 +2104,7 @@ nsHttpConnectionMgr::OnMsgReschedTransaction(int32_t priority, void *param)
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
LOG(("nsHttpConnectionMgr::OnMsgReschedTransaction [trans=%p]\n", param));
- nsRefPtr trans =
- dont_AddRef(static_cast(param));
+ nsHttpTransaction *trans = (nsHttpTransaction *) param;
trans->SetPriority(priority);
nsConnectionEntry *ent = LookupConnectionEntry(trans->ConnectionInfo(),
@@ -2118,6 +2117,8 @@ nsHttpConnectionMgr::OnMsgReschedTransaction(int32_t priority, void *param)
InsertTransactionSorted(ent->mPendingQ, trans);
}
}
+
+ NS_RELEASE(trans);
}
void
@@ -2127,8 +2128,7 @@ nsHttpConnectionMgr::OnMsgCancelTransaction(int32_t reason, void *param)
LOG(("nsHttpConnectionMgr::OnMsgCancelTransaction [trans=%p]\n", param));
nsresult closeCode = static_cast(reason);
- nsRefPtr trans =
- dont_AddRef(static_cast(param));
+ nsHttpTransaction *trans = (nsHttpTransaction *) param;
//
// if the transaction owns a connection and the transaction is not done,
// then ask the connection to close the transaction. otherwise, close the
@@ -2151,14 +2151,14 @@ nsHttpConnectionMgr::OnMsgCancelTransaction(int32_t reason, void *param)
}
trans->Close(closeCode);
}
+ NS_RELEASE(trans);
}
void
nsHttpConnectionMgr::OnMsgProcessPendingQ(int32_t, void *param)
{
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
- nsRefPtr ci =
- dont_AddRef(static_cast(param));
+ nsHttpConnectionInfo *ci = (nsHttpConnectionInfo *) param;
if (!ci) {
LOG(("nsHttpConnectionMgr::OnMsgProcessPendingQ [ci=nullptr]\n"));
@@ -2177,6 +2177,8 @@ nsHttpConnectionMgr::OnMsgProcessPendingQ(int32_t, void *param)
// for the specified connection info. walk the connection table...
mCT.Enumerate(ProcessOneTransactionCB, this);
}
+
+ NS_RELEASE(ci);
}
void
@@ -2214,8 +2216,7 @@ nsHttpConnectionMgr::OnMsgReclaimConnection(int32_t, void *param)
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
LOG(("nsHttpConnectionMgr::OnMsgReclaimConnection [conn=%p]\n", param));
- nsRefPtr conn =
- dont_AddRef(static_cast(param));
+ nsHttpConnection *conn = (nsHttpConnection *) param;
//
// 1) remove the connection from the active list
@@ -2225,16 +2226,16 @@ nsHttpConnectionMgr::OnMsgReclaimConnection(int32_t, void *param)
nsConnectionEntry *ent = LookupConnectionEntry(conn->ConnectionInfo(),
conn, nullptr);
- nsRefPtr ci;
+ nsHttpConnectionInfo *ci = nullptr;
if (!ent) {
// this should never happen
LOG(("nsHttpConnectionMgr::OnMsgReclaimConnection ent == null\n"));
MOZ_ASSERT(false, "no connection entry");
- ci = conn->ConnectionInfo();
+ NS_ADDREF(ci = conn->ConnectionInfo());
}
else {
- ci = ent->mConnInfo;
+ NS_ADDREF(ci = ent->mConnInfo);
// If the connection is in the active list, remove that entry
// and the reference held by the mActiveConns list.
@@ -2254,9 +2255,8 @@ nsHttpConnectionMgr::OnMsgReclaimConnection(int32_t, void *param)
if (ent->mActiveConns.RemoveElement(conn)) {
if (conn == ent->mYellowConnection)
ent->OnYellowComplete();
-
- // drop a reference that was held by list
- conn.get()->Release();
+ nsHttpConnection *temp = conn;
+ NS_RELEASE(temp);
DecrementActiveConnCount(conn);
ConditionallyStopTimeoutTick();
}
@@ -2277,8 +2277,7 @@ nsHttpConnectionMgr::OnMsgReclaimConnection(int32_t, void *param)
break;
}
- // manually add a ref to the connection when it is in the list
- conn.get()->AddRef();
+ NS_ADDREF(conn);
ent->mIdleConns.InsertElementAt(idx, conn);
mNumIdleConns++;
conn->BeginIdleMonitoring();
@@ -2296,7 +2295,8 @@ nsHttpConnectionMgr::OnMsgReclaimConnection(int32_t, void *param)
}
}
- OnMsgProcessPendingQ(0, ci.forget().get()); // releases |ci|
+ OnMsgProcessPendingQ(0, ci); // releases |ci|
+ NS_RELEASE(conn);
}
void
@@ -2359,6 +2359,8 @@ nsHttpConnectionMgr::nsConnectionEntry::~nsConnectionEntry()
{
if (mSpdyPreferred)
gHttpHandler->ConnMgr()->RemoveSpdyPreferredEnt(mCoalescingKey);
+
+ NS_RELEASE(mConnInfo);
}
void
@@ -2469,6 +2471,7 @@ nsHttpConnectionMgr::nsConnectionHandle::~nsConnectionHandle()
{
if (mConn) {
gHttpHandler->ReclaimConnection(mConn);
+ NS_RELEASE(mConn);
}
}
@@ -3094,6 +3097,7 @@ nsConnectionEntry::nsConnectionEntry(nsHttpConnectionInfo *ci)
, mPreferIPv4(false)
, mPreferIPv6(false)
{
+ NS_ADDREF(mConnInfo);
if (gHttpHandler->GetPipelineAggressive()) {
mGreenDepth = kPipelineUnlimited;
mPipelineState = PS_GREEN;
diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.h b/netwerk/protocol/http/nsHttpConnectionMgr.h
index da16d8b0e35a..9e539286d414 100644
--- a/netwerk/protocol/http/nsHttpConnectionMgr.h
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
@@ -273,7 +273,7 @@ private:
nsConnectionEntry(nsHttpConnectionInfo *ci);
~nsConnectionEntry();
- nsRefPtr mConnInfo;
+ nsHttpConnectionInfo *mConnInfo;
nsTArray mPendingQ; // pending transaction queue
nsTArray mActiveConns; // active connections
nsTArray mIdleConns; // idle persistent connections
@@ -393,10 +393,10 @@ private:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSAHTTPCONNECTION(mConn)
- nsConnectionHandle(nsHttpConnection *conn) : mConn(conn) { }
+ nsConnectionHandle(nsHttpConnection *conn) { NS_ADDREF(mConn = conn); }
virtual ~nsConnectionHandle();
- nsRefPtr mConn;
+ nsHttpConnection *mConn;
};
// nsHalfOpenSocket is used to hold the state of an opening TCP socket
diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp
index d143239afd0e..2ff39548fffc 100644
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -121,14 +121,19 @@ NewURI(const nsACString &aSpec,
int32_t aDefaultPort,
nsIURI **aURI)
{
- nsRefPtr url = new nsStandardURL();
+ nsStandardURL *url = new nsStandardURL();
+ if (!url)
+ return NS_ERROR_OUT_OF_MEMORY;
+ NS_ADDREF(url);
nsresult rv = url->Init(nsIStandardURL::URLTYPE_AUTHORITY,
aDefaultPort, aSpec, aCharset, aBaseURI);
if (NS_FAILED(rv)) {
+ NS_RELEASE(url);
return rv;
}
- url.forget(aURI);
+
+ *aURI = url; // no QI needed
return NS_OK;
}
@@ -139,7 +144,8 @@ NewURI(const nsACString &aSpec,
nsHttpHandler *gHttpHandler = nullptr;
nsHttpHandler::nsHttpHandler()
- : mHttpVersion(NS_HTTP_VERSION_1_1)
+ : mConnMgr(nullptr)
+ , mHttpVersion(NS_HTTP_VERSION_1_1)
, mProxyHttpVersion(NS_HTTP_VERSION_1_1)
, mCapabilities(NS_HTTP_ALLOW_KEEPALIVE)
, mReferrerLevel(0xff) // by default we always send a referrer
@@ -218,7 +224,7 @@ nsHttpHandler::~nsHttpHandler()
// make sure the connection manager is shutdown
if (mConnMgr) {
mConnMgr->Shutdown();
- mConnMgr = nullptr;
+ NS_RELEASE(mConnMgr);
}
// Note: don't call NeckoChild::DestroyNeckoChild() here, as it's too late
@@ -374,8 +380,12 @@ nsHttpHandler::InitConnectionMgr()
{
nsresult rv;
- if (!mConnMgr)
+ if (!mConnMgr) {
mConnMgr = new nsHttpConnectionMgr();
+ if (!mConnMgr)
+ return NS_ERROR_OUT_OF_MEMORY;
+ NS_ADDREF(mConnMgr);
+ }
rv = mConnMgr->Init(mMaxConnections,
mMaxPersistentConnectionsPerServer,
diff --git a/netwerk/protocol/http/nsHttpHandler.h b/netwerk/protocol/http/nsHttpHandler.h
index e78ab1153c6a..dc419dbbe4fa 100644
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -315,7 +315,7 @@ private:
nsHttpAuthCache mPrivateAuthCache;
// the connection manager
- nsRefPtr mConnMgr;
+ nsHttpConnectionMgr *mConnMgr;
//
// prefs
diff --git a/netwerk/protocol/http/nsHttpPipeline.cpp b/netwerk/protocol/http/nsHttpPipeline.cpp
index dde16a709783..e7c04a46002b 100644
--- a/netwerk/protocol/http/nsHttpPipeline.cpp
+++ b/netwerk/protocol/http/nsHttpPipeline.cpp
@@ -63,7 +63,8 @@ private:
//-----------------------------------------------------------------------------
nsHttpPipeline::nsHttpPipeline()
- : mStatus(NS_OK)
+ : mConnection(nullptr)
+ , mStatus(NS_OK)
, mRequestIsPartial(false)
, mResponseIsPartial(false)
, mClosed(false)
@@ -83,6 +84,8 @@ nsHttpPipeline::~nsHttpPipeline()
// make sure we aren't still holding onto any transactions!
Close(NS_ERROR_ABORT);
+ NS_IF_RELEASE(mConnection);
+
if (mPushBackBuf)
free(mPushBackBuf);
}
@@ -407,13 +410,14 @@ nsHttpPipeline::SetConnection(nsAHttpConnection *conn)
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
MOZ_ASSERT(!mConnection, "already have a connection");
- mConnection = conn;
+
+ NS_IF_ADDREF(mConnection = conn);
}
nsAHttpConnection *
nsHttpPipeline::Connection()
{
- LOG(("nsHttpPipeline::Connection [this=%p conn=%x]\n", this, mConnection.get()));
+ LOG(("nsHttpPipeline::Connection [this=%p conn=%x]\n", this, mConnection));
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
return mConnection;
diff --git a/netwerk/protocol/http/nsHttpPipeline.h b/netwerk/protocol/http/nsHttpPipeline.h
index 4c41a5c3a0a1..8570e83ca9d9 100644
--- a/netwerk/protocol/http/nsHttpPipeline.h
+++ b/netwerk/protocol/http/nsHttpPipeline.h
@@ -52,7 +52,7 @@ private:
// overload of nsAHttpTransaction::QueryPipeline()
nsHttpPipeline *QueryPipeline();
- nsRefPtr mConnection;
+ nsAHttpConnection *mConnection;
nsTArray mRequestQ; // array of transactions
nsTArray mResponseQ; // array of transactions
nsresult mStatus;
diff --git a/netwerk/protocol/http/nsHttpTransaction.cpp b/netwerk/protocol/http/nsHttpTransaction.cpp
index b1a160387843..2f0519e9be29 100644
--- a/netwerk/protocol/http/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/nsHttpTransaction.cpp
@@ -82,6 +82,8 @@ LogHeaders(const char *lineStart)
nsHttpTransaction::nsHttpTransaction()
: mCallbacksLock("transaction mCallbacks lock")
, mRequestSize(0)
+ , mConnection(nullptr)
+ , mConnInfo(nullptr)
, mRequestHead(nullptr)
, mResponseHead(nullptr)
, mContentLength(-1)
@@ -135,6 +137,9 @@ nsHttpTransaction::~nsHttpTransaction()
// Force the callbacks to be released right now
mCallbacks = nullptr;
+ NS_IF_RELEASE(mConnection);
+ NS_IF_RELEASE(mConnInfo);
+
delete mResponseHead;
delete mForTakeResponseHead;
delete mChunkedDecoder;
@@ -227,7 +232,7 @@ nsHttpTransaction::Init(uint32_t caps,
!activityDistributorActive);
if (NS_FAILED(rv)) return rv;
- mConnInfo = cinfo;
+ NS_ADDREF(mConnInfo = cinfo);
mCallbacks = callbacks;
mConsumerTarget = target;
mCaps = caps;
@@ -403,7 +408,8 @@ nsHttpTransaction::TakeSubTransactions(
void
nsHttpTransaction::SetConnection(nsAHttpConnection *conn)
{
- mConnection = conn;
+ NS_IF_RELEASE(mConnection);
+ NS_IF_ADDREF(mConnection = conn);
if (conn) {
MOZ_EVENT_TRACER_EXEC(static_cast(this),
@@ -818,8 +824,8 @@ nsHttpTransaction::Close(nsresult reason)
mTimings.responseEnd.IsNull() && !mTimings.responseStart.IsNull())
mTimings.responseEnd = TimeStamp::Now();
- if (relConn)
- mConnection = nullptr;
+ if (relConn && mConnection)
+ NS_RELEASE(mConnection);
mStatus = reason;
mTransactionDone = true; // forcibly flag the transaction as complete
@@ -952,7 +958,7 @@ nsHttpTransaction::Restart()
// clear old connection state...
mSecurityInfo = 0;
- mConnection = nullptr;
+ NS_IF_RELEASE(mConnection);
// disable pipelining for the next attempt in case pipelining caused the
// reset. this is being overly cautious since we don't know if pipelining
diff --git a/netwerk/protocol/http/nsHttpTransaction.h b/netwerk/protocol/http/nsHttpTransaction.h
index 3b5913d561f5..f0b61a2f44f2 100644
--- a/netwerk/protocol/http/nsHttpTransaction.h
+++ b/netwerk/protocol/http/nsHttpTransaction.h
@@ -180,11 +180,10 @@ private:
nsCOMPtr mRequestStream;
uint64_t mRequestSize;
- nsRefPtr mConnInfo;
- nsRefPtr mConnection;
-
+ nsAHttpConnection *mConnection; // hard ref
+ nsHttpConnectionInfo *mConnInfo; // hard ref
nsHttpRequestHead *mRequestHead; // weak ref
- nsHttpResponseHead *mResponseHead; // owning ref
+ nsHttpResponseHead *mResponseHead; // hard ref
nsAHttpSegmentReader *mReader;
nsAHttpSegmentWriter *mWriter;
diff --git a/parser/html/nsHtml5StreamParser.cpp b/parser/html/nsHtml5StreamParser.cpp
index e71bf879eb6e..b3187694f882 100644
--- a/parser/html/nsHtml5StreamParser.cpp
+++ b/parser/html/nsHtml5StreamParser.cpp
@@ -1494,7 +1494,7 @@ nsHtml5StreamParser::ContinueAfterScripts(nsHtml5Tokenizer* aTokenizer,
mTokenizer->setLineNumber(speculation->GetStartLineNumber());
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
- "DOM Events",
+ NS_LITERAL_CSTRING("DOM Events"),
mExecutor->GetDocument(),
nsContentUtils::eDOM_PROPERTIES,
"SpeculationFailed",
diff --git a/parser/html/nsHtml5TreeOpExecutor.cpp b/parser/html/nsHtml5TreeOpExecutor.cpp
index 4a9a0e3e7e1a..2bcaf0bf591f 100644
--- a/parser/html/nsHtml5TreeOpExecutor.cpp
+++ b/parser/html/nsHtml5TreeOpExecutor.cpp
@@ -887,7 +887,7 @@ nsHtml5TreeOpExecutor::MaybeComplainAboutCharset(const char* aMsgId,
mAlreadyComplainedAboutCharset = true;
nsContentUtils::ReportToConsole(aError ? nsIScriptError::errorFlag
: nsIScriptError::warningFlag,
- "HTML parser",
+ NS_LITERAL_CSTRING("HTML parser"),
mDocument,
nsContentUtils::eHTMLPARSER_PROPERTIES,
aMsgId,
@@ -905,7 +905,7 @@ nsHtml5TreeOpExecutor::ComplainAboutBogusProtocolCharset(nsIDocument* aDoc)
"How come we already managed to complain?");
mAlreadyComplainedAboutCharset = true;
nsContentUtils::ReportToConsole(nsIScriptError::errorFlag,
- "HTML parser",
+ NS_LITERAL_CSTRING("HTML parser"),
aDoc,
nsContentUtils::eHTMLPARSER_PROPERTIES,
"EncProtocolUnsupported");
diff --git a/testing/marionette/client/marionette/marionette.py b/testing/marionette/client/marionette/marionette.py
index 30e312eaec5e..d363f4d6e999 100644
--- a/testing/marionette/client/marionette/marionette.py
+++ b/testing/marionette/client/marionette/marionette.py
@@ -456,7 +456,7 @@ class Marionette(object):
self.instance = instance_class(host=self.host, port=self.port,
bin=self.bin, profile=self.profile, app_args=app_args)
self.instance.start()
- assert(self.wait_for_port())
+ assert(self.wait_for_port()), "Timed out waiting for port!"
if emulator:
self.emulator = Emulator(homedir=homedir,
@@ -469,14 +469,14 @@ class Marionette(object):
res=emulator_res)
self.emulator.start()
self.port = self.emulator.setup_port_forwarding(self.port)
- assert(self.emulator.wait_for_port())
+ assert(self.emulator.wait_for_port()), "Timed out waiting for port!"
if connectToRunningEmulator:
self.emulator = Emulator(homedir=homedir,
logcat_dir=self.logcat_dir)
self.emulator.connect()
self.port = self.emulator.setup_port_forwarding(self.port)
- assert(self.emulator.wait_for_port())
+ assert(self.emulator.wait_for_port()), "Timed out waiting for port!"
self.client = MarionetteClient(self.host, self.port)
diff --git a/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py b/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py
index a7013c7f329a..c71af93821c0 100644
--- a/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py
+++ b/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py
@@ -6,9 +6,10 @@ import multiprocessing
import sys
import time
+# psutil will raise NotImplementedError if the platform is not supported.
try:
import psutil
-except ImportError:
+except (ImportError, NotImplementedError):
psutil = None
from collections import (
diff --git a/toolkit/components/printing/content/printUtils.js b/toolkit/components/printing/content/printUtils.js
index 66948922b5fc..ab9e25927331 100644
--- a/toolkit/components/printing/content/printUtils.js
+++ b/toolkit/components/printing/content/printUtils.js
@@ -218,9 +218,9 @@ var PrintUtils = {
// Set the original window as an active window so any mozPrintCallbacks can
// run without delayed setTimeouts.
- var docShell = originalWindow.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell);
+ var docShell = originalWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+ .getInterface(Components.interfaces.nsIWebNavigation)
+ .QueryInterface(Components.interfaces.nsIDocShell);
docShell.isActive = true;
// show the toolbar after we go into print preview mode so
diff --git a/toolkit/content/browser-child.js b/toolkit/content/browser-child.js
index 78f189bba829..6a3f4a94ffb8 100644
--- a/toolkit/content/browser-child.js
+++ b/toolkit/content/browser-child.js
@@ -186,6 +186,23 @@ let SecurityUI = {
}
};
+let ControllerCommands = {
+ init: function () {
+ addMessageListener("ControllerCommands:Do", this);
+ },
+
+ receiveMessage: function(message) {
+ switch(message.name) {
+ case "ControllerCommands:Do":
+ if (docShell.isCommandEnabled(message.data))
+ docShell.doCommand(message.data);
+ break;
+ }
+ }
+}
+
+ControllerCommands.init()
+
addEventListener("DOMTitleChanged", function (aEvent) {
let document = content.document;
switch (aEvent.type) {
diff --git a/toolkit/content/widgets/remote-browser.xml b/toolkit/content/widgets/remote-browser.xml
index f2f9f0b89a50..8a52b40a250c 100644
--- a/toolkit/content/widgets/remote-browser.xml
+++ b/toolkit/content/widgets/remote-browser.xml
@@ -101,12 +101,18 @@
this.messageManager.addMessageListener("ImageDocumentLoaded", this);
this.messageManager.loadFrameScript("chrome://global/content/browser-child.js", true);
this.webProgress._init();
+
+ let jsm = "resource://gre/modules/RemoteController.jsm";
+ let RemoteController = Components.utils.import(jsm, {}).RemoteController;
+ this._controller = new RemoteController(this);
+ this.controllers.appendController(this._controller);
]]>
diff --git a/toolkit/modules/RemoteController.jsm b/toolkit/modules/RemoteController.jsm
new file mode 100644
index 000000000000..aa3183456149
--- /dev/null
+++ b/toolkit/modules/RemoteController.jsm
@@ -0,0 +1,58 @@
+// -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// 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/.
+
+this.EXPORTED_SYMBOLS = ["RemoteController"];
+
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function RemoteController(browser)
+{
+ this._browser = browser;
+}
+
+RemoteController.prototype = {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIController]),
+
+ isCommandEnabled: function(aCommand) {
+ // We can't synchronously ask content if a command is enabled,
+ // so we always pretend is.
+ // The right way forward would be to never use nsIController
+ // to ask if something in content is enabled. Maybe even
+ // by replacing the nsIController architecture by something else.
+ // See bug 905768.
+ return true;
+ },
+
+ supportsCommand: function(aCommand) {
+ // Optimize the lookup a bit.
+ if (!aCommand.startsWith("cmd_"))
+ return false;
+
+ // For now only support the commands used in "browser-context.inc"
+ let commands = [
+ "cmd_copyLink",
+ "cmd_copyImage",
+ "cmd_undo",
+ "cmd_cut",
+ "cmd_copy",
+ "cmd_paste",
+ "cmd_delete",
+ "cmd_selectAll",
+ "cmd_switchTextDirection"
+ ];
+
+ return commands.indexOf(aCommand) >= 0;
+ },
+
+ doCommand: function(aCommand) {
+ this._browser.messageManager.sendAsyncMessage("ControllerCommands:Do", aCommand);
+ },
+
+ onEvent: function () {}
+};
diff --git a/toolkit/modules/moz.build b/toolkit/modules/moz.build
index f60dd1c9ffc0..c28d4dbaa6c5 100644
--- a/toolkit/modules/moz.build
+++ b/toolkit/modules/moz.build
@@ -21,6 +21,7 @@ EXTRA_JS_MODULES += [
'PrivateBrowsingUtils.jsm',
'Promise.jsm',
'PropertyListUtils.jsm',
+ 'RemoteController.jsm',
'RemoteSecurityUI.jsm',
'RemoteWebNavigation.jsm',
'RemoteWebProgress.jsm',
diff --git a/widget/cocoa/nsNativeThemeCocoa.mm b/widget/cocoa/nsNativeThemeCocoa.mm
index 267605cbda45..81e68f1d0bd1 100644
--- a/widget/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/cocoa/nsNativeThemeCocoa.mm
@@ -2329,7 +2329,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
BOOL isHorizontal = (aWidgetType == NS_THEME_SCROLLBAR_THUMB_HORIZONTAL);
BOOL isRolledOver = CheckBooleanAttr(GetParentScrollbarFrame(aFrame),
nsGkAtoms::hover);
- if (!isRolledOver) {
+ if (!nsCocoaFeatures::OnMountainLionOrLater() || !isRolledOver) {
if (isHorizontal) {
macRect.origin.y += 4;
macRect.size.height -= 4;
@@ -2375,6 +2375,20 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
if (nsLookAndFeel::UseOverlayScrollbars() &&
CheckBooleanAttr(GetParentScrollbarFrame(aFrame), nsGkAtoms::hover)) {
BOOL isHorizontal = (aWidgetType == NS_THEME_SCROLLBAR_TRACK_HORIZONTAL);
+ if (!nsCocoaFeatures::OnMountainLionOrLater()) {
+ // On OSX 10.7, scrollbars don't grow when hovered. The adjustments
+ // below were obtained by trial and error.
+ if (isHorizontal) {
+ macRect.origin.y += 2.0;
+ } else {
+ if (aFrame->StyleVisibility()->mDirection !=
+ NS_STYLE_DIRECTION_RTL) {
+ macRect.origin.x += 3.0;
+ } else {
+ macRect.origin.x -= 1.0;
+ }
+ }
+ }
const BOOL isOnTopOfDarkBackground = IsDarkBackground(aFrame);
CUIDraw([NSWindow coreUIRenderer], macRect, cgContext,
(CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
diff --git a/xpcom/base/nsAgg.h b/xpcom/base/nsAgg.h
index ca7d6f4fa087..6c5fe76859eb 100644
--- a/xpcom/base/nsAgg.h
+++ b/xpcom/base/nsAgg.h
@@ -92,6 +92,7 @@ public: \
return &_class::NS_CYCLE_COLLECTION_INNERNAME; \
} \
}; \
+NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class); \
static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
// Put this in your class's constructor:
diff --git a/xpcom/glue/nsCycleCollectionParticipant.h b/xpcom/glue/nsCycleCollectionParticipant.h
index cf418e4da195..d8a4af719622 100644
--- a/xpcom/glue/nsCycleCollectionParticipant.h
+++ b/xpcom/glue/nsCycleCollectionParticipant.h
@@ -232,6 +232,12 @@ public:
#define NS_CYCLE_COLLECTION_UPCAST(obj, clazz) \
NS_CYCLE_COLLECTION_CLASSNAME(clazz)::Upcast(obj)
+#ifdef DEBUG
+#define NS_CHECK_FOR_RIGHT_PARTICIPANT(_ptr) _ptr->CheckForRightParticipant()
+#else
+#define NS_CHECK_FOR_RIGHT_PARTICIPANT(_ptr)
+#endif
+
// The default implementation of this class template is empty, because it
// should never be used: see the partial specializations below.
template
nsISupports *s = static_cast(p);
MOZ_ASSERT(NS_CYCLE_COLLECTION_CLASSNAME(T)::CheckForRightISupports(s),
"not the nsISupports pointer we expect");
- return NS_CYCLE_COLLECTION_CLASSNAME(T)::Downcast(s);
+ T *rval = NS_CYCLE_COLLECTION_CLASSNAME(T)::Downcast(s);
+ NS_CHECK_FOR_RIGHT_PARTICIPANT(rval);
+ return rval;
}
};
@@ -432,6 +440,21 @@ T* DowncastCCParticipant(void *p)
// Helpers for implementing a concrete nsCycleCollectionParticipant
///////////////////////////////////////////////////////////////////////////////
+// If a class defines a participant, then QIing an instance of that class to
+// nsXPCOMCycleCollectionParticipant should produce that participant.
+#ifdef DEBUG
+#define NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class) \
+ virtual void CheckForRightParticipant() \
+ { \
+ nsXPCOMCycleCollectionParticipant *p; \
+ CallQueryInterface(this, &p); \
+ MOZ_ASSERT(p == &NS_CYCLE_COLLECTION_INNERNAME, \
+ #_class " should QI to its own CC participant"); \
+ }
+#else
+#define NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class)
+#endif
+
#define NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _base) \
public: \
NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb); \
@@ -483,6 +506,7 @@ class NS_CYCLE_COLLECTION_INNERCLASS \
NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base) \
NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class) \
}; \
+NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class) \
static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME; \
NOT_INHERITED_CANT_OVERRIDE
@@ -504,6 +528,7 @@ private:
NS_IMETHOD_(bool) CanSkipThisReal(void *p); \
NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class) \
}; \
+NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class) \
static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME; \
NOT_INHERITED_CANT_OVERRIDE
@@ -518,6 +543,7 @@ class NS_CYCLE_COLLECTION_INNERCLASS
NS_IMETHOD_(void) Trace(void *p, const TraceCallbacks &cb, void *closure); \
NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class) \
}; \
+NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class) \
static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME; \
NOT_INHERITED_CANT_OVERRIDE
@@ -536,6 +562,7 @@ private:
NS_IMETHOD_(bool) CanSkipThisReal(void *p); \
NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class) \
}; \
+NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class) \
static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME; \
NOT_INHERITED_CANT_OVERRIDE
@@ -554,6 +581,7 @@ class NS_CYCLE_COLLECTION_INNERCLASS
NS_IMETHOD_(bool) CanSkipThisReal(void *p); \
NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class) \
}; \
+NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class) \
static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
#define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(_class) \
@@ -581,6 +609,7 @@ public: \
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(_class, _base_class) \
NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class) \
}; \
+NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class) \
static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
#define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(_class, \
@@ -592,6 +621,7 @@ public: \
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY_NO_UNLINK(_class, _base_class) \
NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class) \
}; \
+NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class) \
static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
#define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(_class, \
@@ -603,6 +633,7 @@ class NS_CYCLE_COLLECTION_INNERCLASS
NS_IMETHOD_(void) Trace(void *p, const TraceCallbacks &cb, void *closure); \
NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class) \
}; \
+NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class) \
static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
// Cycle collector participant declarations.