Merge inbound to m-c a=merge CLOSED TREE
authorWes Kocher <wkocher@mozilla.com>
Mon, 29 Dec 2014 17:28:04 -0800
changeset 247369 67872ce1791816b5b0a273ea4b74aba6ce4b84a1
parent 247328 62e3a9f26d21e0010162986feb54265d2bbd5216 (current diff)
parent 247368 beba124659ca3f16a735e4f8b2ea02896e60c3ce (diff)
child 247374 fad6382c01fb6107c37df3cab5846db6184311bb
child 247401 c0d25f0788a8655ce4a85e4070e49b442f960ad3
child 247427 dc98810c5b0f718e5d186f3586ccd723bf417fe4
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone37.0a1
first release with
nightly linux32
67872ce17918 / 37.0a1 / 20141230030214 / files
nightly linux64
67872ce17918 / 37.0a1 / 20141230030214 / files
nightly mac
67872ce17918 / 37.0a1 / 20141230030214 / files
nightly win32
67872ce17918 / 37.0a1 / 20141230030214 / files
nightly win64
67872ce17918 / 37.0a1 / 20141230030214 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to m-c a=merge CLOSED TREE
js/src/tests/ecma_7/SIMD/float32x4select.js
js/src/tests/ecma_7/SIMD/int32x4select.js
testing/mochitest/pywebsocket/mod_pywebsocket/handshake/draft75.py
--- a/accessible/ipc/DocAccessibleParent.cpp
+++ b/accessible/ipc/DocAccessibleParent.cpp
@@ -141,19 +141,28 @@ DocAccessibleParent::AddChildDoc(DocAcce
   aChildDoc->mParent = outerDoc;
   outerDoc->SetChildDoc(aChildDoc);
   mChildDocs.AppendElement(aChildDoc);
   aChildDoc->mParentDoc = this;
   ProxyCreated(aChildDoc);
   return true;
 }
 
+PLDHashOperator
+DocAccessibleParent::ShutdownAccessibles(ProxyEntry* entry, void*)
+{
+  ProxyDestroyed(entry->mProxy);
+  return PL_DHASH_NEXT;
+}
+
 void
 DocAccessibleParent::ActorDestroy(ActorDestroyReason aWhy)
 {
-  ProxyDestroyed(this);
   MOZ_ASSERT(mChildDocs.IsEmpty(),
       "why wheren't the child docs destroyed already?");
+
+  mAccessibles.EnumerateEntries(ShutdownAccessibles, nullptr);
+  ProxyDestroyed(this);
   mParentDoc ? mParentDoc->RemoveChildDoc(this)
     : GetAccService()->RemoteDocShutdown(this);
 }
 }
 }
--- a/accessible/ipc/DocAccessibleParent.h
+++ b/accessible/ipc/DocAccessibleParent.h
@@ -100,16 +100,17 @@ private:
     enum { ALLOW_MEMMOVE = true };
 
     ProxyAccessible* mProxy;
   };
 
   uint32_t AddSubtree(ProxyAccessible* aParent,
                       const nsTArray<AccessibleData>& aNewTree, uint32_t aIdx,
                       uint32_t aIdxInParent);
+  static PLDHashOperator ShutdownAccessibles(ProxyEntry* entry, void* unused);
 
   nsTArray<DocAccessibleParent*> mChildDocs;
   DocAccessibleParent* mParentDoc;
 
   /*
    * Conceptually this is a map from IDs to proxies, but we store the ID in the
    * proxy object so we can't use a real map.
    */
--- a/accessible/ipc/ProxyAccessible.cpp
+++ b/accessible/ipc/ProxyAccessible.cpp
@@ -12,19 +12,23 @@
 namespace mozilla {
 namespace a11y {
 
 void
 ProxyAccessible::Shutdown()
 {
   MOZ_ASSERT(!mOuterDoc);
 
-  uint32_t childCount = mChildren.Length();
-  for (uint32_t idx = 0; idx < childCount; idx++)
-    mChildren[idx]->Shutdown();
+  // XXX Ideally  this wouldn't be necessary, but it seems OuterDoc accessibles
+  // can be destroyed before the doc they own.
+  if (!mOuterDoc) {
+    uint32_t childCount = mChildren.Length();
+    for (uint32_t idx = 0; idx < childCount; idx++)
+      mChildren[idx]->Shutdown();
+  }
 
   mChildren.Clear();
   ProxyDestroyed(this);
   mDoc->RemoveAccessible(this);
 }
 
 void
 ProxyAccessible::SetChildDoc(DocAccessibleParent* aParent)
--- a/accessible/ipc/ProxyAccessible.h
+++ b/accessible/ipc/ProxyAccessible.h
@@ -22,17 +22,21 @@ class ProxyAccessible
 public:
 
   ProxyAccessible(uint64_t aID, ProxyAccessible* aParent,
                   DocAccessibleParent* aDoc, role aRole) :
      mParent(aParent), mDoc(aDoc), mID(aID), mRole(aRole), mOuterDoc(false)
   {
     MOZ_COUNT_CTOR(ProxyAccessible);
   }
-  ~ProxyAccessible() { MOZ_COUNT_DTOR(ProxyAccessible); }
+  ~ProxyAccessible()
+  {
+    MOZ_COUNT_DTOR(ProxyAccessible);
+    MOZ_ASSERT(!mWrapper);
+  }
 
   void AddChildAt(uint32_t aIdx, ProxyAccessible* aChild)
   { mChildren.InsertElementAt(aIdx, aChild); }
 
   uint32_t ChildrenCount() const { return mChildren.Length(); }
 
   void Shutdown();
 
--- a/dom/base/nsStyleLinkElement.cpp
+++ b/dom/base/nsStyleLinkElement.cpp
@@ -300,16 +300,23 @@ nsStyleLinkElement::DoUpdateStyleSheet(n
   *aWillNotify = false;
 
   nsCOMPtr<nsIContent> thisContent;
   CallQueryInterface(this, getter_AddRefs(thisContent));
 
   // All instances of nsStyleLinkElement should implement nsIContent.
   NS_ENSURE_TRUE(thisContent, NS_ERROR_FAILURE);
 
+  if (thisContent->IsInAnonymousSubtree() &&
+      thisContent->IsAnonymousContentInSVGUseSubtree()) {
+    // Stylesheets in <use>-cloned subtrees are disabled until we figure out
+    // how they should behave.
+    return NS_OK;
+  }
+
   // Check for a ShadowRoot because link elements are inert in a
   // ShadowRoot.
   ShadowRoot* containingShadow = thisContent->GetContainingShadow();
   if (thisContent->IsHTML(nsGkAtoms::link) &&
       (aOldShadowRoot || containingShadow)) {
     return NS_OK;
   }
 
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_websocket_permessage_deflate_disabled_wsh.py
@@ -0,0 +1,17 @@
+from mod_pywebsocket import msgutil
+from mod_pywebsocket import common
+
+def web_socket_do_extra_handshake(request):
+  if request.ws_requested_extensions is not None:
+    for extension_request in request.ws_requested_extensions:
+      if extension_request.name() == "permessage-deflate":
+        raise ValueError('permessage-deflate should not be offered')
+
+def web_socket_transfer_data(request):
+  while True:
+    rcvd = msgutil.receive_message(request)
+    opcode = request.ws_stream.get_last_received_opcode()
+    if (opcode == common.OPCODE_BINARY):
+      msgutil.send_message(request, rcvd, binary=True)
+    elif (opcode == common.OPCODE_TEXT):
+      msgutil.send_message(request, rcvd)
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_websocket_permessage_deflate_rejected_wsh.py
@@ -0,0 +1,23 @@
+from mod_pywebsocket import msgutil
+from mod_pywebsocket import common
+
+def web_socket_do_extra_handshake(request):
+  deflate_removed = False
+
+  if request.ws_extension_processors is not None:
+    for extension_processor in request.ws_extension_processors:
+      if extension_processor.name() == "deflate":
+        request.ws_extension_processors.remove(extension_processor)
+        deflate_removed = True
+
+  if deflate_removed is False:
+    raise ValueError('deflate extension processor not found')
+
+def web_socket_transfer_data(request):
+  while True:
+    rcvd = msgutil.receive_message(request)
+    opcode = request.ws_stream.get_last_received_opcode()
+    if (opcode == common.OPCODE_BINARY):
+      msgutil.send_message(request, rcvd, binary=True)
+    elif (opcode == common.OPCODE_TEXT):
+      msgutil.send_message(request, rcvd)
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_websocket_permessage_deflate_wsh.py
@@ -0,0 +1,22 @@
+from mod_pywebsocket import msgutil
+from mod_pywebsocket import common
+
+def web_socket_do_extra_handshake(request):
+  pmce_offered = False
+
+  if request.ws_requested_extensions is not None:
+    for extension_request in request.ws_requested_extensions:
+      if extension_request.name() == "permessage-deflate":
+        pmce_offered = True
+
+  if pmce_offered is False:
+    raise ValueError('permessage-deflate not offered')
+
+def web_socket_transfer_data(request):
+  while True:
+    rcvd = msgutil.receive_message(request)
+    opcode = request.ws_stream.get_last_received_opcode()
+    if (opcode == common.OPCODE_BINARY):
+      msgutil.send_message(request, rcvd, binary=True)
+    elif (opcode == common.OPCODE_TEXT):
+      msgutil.send_message(request, rcvd)
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -189,16 +189,19 @@ support-files =
   file_mozfiledataurl_doc.html
   file_mozfiledataurl_img.jpg
   file_mozfiledataurl_inner.html
   file_mozfiledataurl_text.txt
   file_restrictedEventSource.sjs
   file_websocket_basic_wsh.py
   file_websocket_hello_wsh.py
   file_websocket_http_resource.txt
+  file_websocket_permessage_deflate_wsh.py
+  file_websocket_permessage_deflate_disabled_wsh.py
+  file_websocket_permessage_deflate_rejected_wsh.py
   file_websocket_wsh.py
   file_x-frame-options_main.html
   file_x-frame-options_page.sjs
   file_xhtmlserializer_1.xhtml
   file_xhtmlserializer_1_bodyonly.xhtml
   file_xhtmlserializer_1_format.xhtml
   file_xhtmlserializer_1_linebreak.xhtml
   file_xhtmlserializer_1_links.xhtml
@@ -729,16 +732,18 @@ skip-if = toolkit == 'android' || e10s #
 [test_w3element_traversal.xhtml]
 [test_w3element_traversal_svg.html]
 [test_websocket.html]
 skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s
 [test_websocket_basic.html]
 skip-if = buildapp == 'b2g' || toolkit == 'android'
 [test_websocket_hello.html]
 skip-if = buildapp == 'b2g' || toolkit == 'android'
+[test_websocket_permessage_deflate.html]
+skip-if = buildapp == 'b2g' || toolkit == 'android'
 [test_x-frame-options.html]
 skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # b2g(observerservice issue) b2g-debug(observerservice issue) b2g-desktop(observerservice issue)
 [test_xbl_userdata.xhtml]
 [test_xhr_abort_after_load.html]
 skip-if = toolkit == 'android'
 [test_xhr_forbidden_headers.html]
 [test_xhr_progressevents.html]
 skip-if = toolkit == 'android'
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_websocket_permessage_deflate.html
@@ -0,0 +1,105 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Basic test of permessage compression websocket extension</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload="testDeflate()">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=792831">Mozilla Bug </a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+var ws;
+var textMessage = "This is a text message";
+var binaryMessage = "This is a binary message";
+var testIdx = 0;
+var sendText = true;
+
+tests = [
+  // enable PMCE
+  [ true, true, "ws://mochi.test:8888/tests/dom/base/test/file_websocket_permessage_deflate" ],
+  // disable PMCE
+  [ false, false, "ws://mochi.test:8888/tests/dom/base/test/file_websocket_permessage_deflate_disabled" ],
+  // server rejects offered PMCE
+  [ true, false, "ws://mochi.test:8888/tests/dom/base/test/file_websocket_permessage_deflate_rejected" ] ]
+
+function ab2str(buf) {
+  return String.fromCharCode.apply(null, new Uint16Array(buf));
+}
+
+function str2ab(str) {
+  var buf = new ArrayBuffer(str.length*2);
+  var bufView = new Uint16Array(buf);
+  for (var i=0, strLen=str.length; i<strLen; i++) {
+    bufView[i] = str.charCodeAt(i);
+  }
+  return buf;
+}
+
+function sendMessage() {
+  if (sendText) {
+    ws.send(textMessage);
+  } else {
+    ws.binaryType = "arraybuffer";
+    ws.send(str2ab(binaryMessage));
+  }
+}
+
+function testDeflate() {
+  SpecialPowers.setBoolPref("network.websocket.extensions.permessage-deflate", tests[testIdx][0]);
+
+  ws = new WebSocket(tests[testIdx][2]);
+
+  ws.onopen = function(e) {
+    if (tests[testIdx][1]) {
+      is(ws.extensions, "permessage-deflate", "permessage-deflate not negotiated!");
+    } else {
+      is(ws.extensions, "", "permessage-deflate should not be negotiated!");
+    }
+
+    sendMessage();
+  }
+
+  ws.onclose = function(e) {
+    if (!e.wasClean) {
+      ok(false, "Connection should be closed cleanly!");
+      SimpleTest.finish();
+    }
+  }
+
+  ws.onerror = function(e) {
+    ok(false, "onerror called!");
+    SimpleTest.finish();
+  }
+
+  ws.onmessage = function(e) {
+    if (sendText) {
+      is(e.data, textMessage, "Text message not received successfully!");
+      sendText = false;
+      sendMessage();
+    } else {
+      ok(e.data instanceof ArrayBuffer, "Should receive an arraybuffer!");
+      is(ab2str(e.data), binaryMessage, "Binary message not received successfully!");
+      ws.close();
+
+      sendText = true;
+      testIdx++;
+      if (testIdx < tests.length) {
+        testDeflate();
+      } else {
+        SimpleTest.finish();
+      }
+    }
+  }
+}
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+</body>
+</html>
--- a/dom/base/test/unit/xpcshell.ini
+++ b/dom/base/test/unit/xpcshell.ini
@@ -19,16 +19,17 @@ support-files =
   4_result_3.xml
   4_result_4.xml
   4_result_5.xml
   4_result_6.xml
 
 [test_bug553888.js]
 [test_bug737966.js]
 [test_cspreports.js]
+skip-if = buildapp == 'mulet'
 [test_error_codes.js]
 run-sequentially = Hardcoded 4444 port.
 # Bug 1018414: hardcoded localhost doesn't work properly on some OS X installs
 skip-if = os == 'mac'
 [test_thirdpartyutil.js]
 [test_xhr_document.js]
 [test_xhr_standalone.js]
 [test_xmlserializer.js]
--- a/dom/events/test/mochitest.ini
+++ b/dom/events/test/mochitest.ini
@@ -11,17 +11,17 @@ support-files =
   window_bug493251.html
   window_bug659071.html
   window_wheel_default_action.html
 
 [test_accel_virtual_modifier.html]
 [test_addEventListenerExtraArg.html]
 [test_all_synthetic_events.html]
 [test_bug226361.xhtml]
-skip-if = buildapp == 'b2g'
+skip-if = buildapp == 'b2g' || buildapp == 'mulet'
 [test_bug238987.html]
 skip-if = buildapp == 'b2g'
 [test_bug288392.html]
 [test_bug299673-1.html]
 [test_bug1037990.html]
 [test_bug299673-2.html]
 [test_bug322588.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') || e10s #Bug 931116, b2g desktop specific, initial triage
@@ -119,17 +119,17 @@ skip-if = toolkit == 'android' #CRASH_DU
 skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
 [test_bug704423.html]
 [test_bug741666.html]
 skip-if = toolkit == 'android'
 [test_bug742376.html]
 [test_bug812744.html]
 [test_bug855741.html]
 [test_bug864040.html]
-skip-if = buildapp == 'b2g' # b2g(failing when the test gets moved around, and on debug) b2g-debug(failing when the test gets moved around, and on debug) b2g-desktop(failing when the test gets moved around, and on debug)
+skip-if = buildapp == 'mulet' || buildapp == 'b2g' # b2g(failing when the test gets moved around, and on debug)
 [test_bug930374-content.html]
 [test_bug944011.html]
 [test_bug944847.html]
 [test_bug946632.html]
 [test_bug967796.html]
 skip-if = toolkit == "gonk" || e10s
 [test_bug985988.html]
 [test_bug998809.html]
--- a/extensions/cookie/test/test_app_uninstall_cookies.html
+++ b/extensions/cookie/test/test_app_uninstall_cookies.html
@@ -23,16 +23,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 
 const Ci = Components.interfaces;
 const Cc = Components.classes;
 const Cu = Components.utils;
 
 SimpleTest.waitForExplicitFinish();
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 var httpserver = new HttpServer();
 
 var cookieSetPath = "/setcookie";
 var cookieCheckPath = "/checkcookie";
 
 var permManager = Cc["@mozilla.org/permissionmanager;1"]
                     .getService(Ci.nsIPermissionManager);
 var cookieMng = Cc["@mozilla.org/cookiemanager;1"]
@@ -89,17 +90,24 @@ function cookieCheckHandler(metadata, re
   response.setStatusLine(metadata.httpVersion, 200, "Ok");
   response.setHeader("foo-saw-cookies", cookies, false);
   response.setHeader("Content-Type", "text/plain");
   response.bodyOutputStream.write("Ok", "Ok".length);
 }
 
 function setupChannel(path) {
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-  var chan = ios.newChannel("http://localhost:4444" + path, "", null);
+  var chan = ios.newChannel2("http://localhost:4444" + path,
+                             "",
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER);
   chan.notificationCallbacks = cookies[counter].loadContext;
   chan.QueryInterface(Ci.nsIHttpChannel);
   return chan;
 }
 
 function setCookie() {
   var channel = setupChannel(cookieSetPath);
   channel.setRequestHeader("foo-set-cookie", cookies[counter].cookieName, false);
--- a/extensions/cookie/test/unit/test_cookies_persistence.js
+++ b/extensions/cookie/test/unit/test_cookies_persistence.js
@@ -24,18 +24,32 @@ function do_run_test() {
   let profile = do_get_profile();
 
   // Create URIs and channels pointing to foo.com and bar.com.
   // We will use these to put foo.com into first and third party contexts.
   var spec1 = "http://foo.com/foo.html";
   var spec2 = "http://bar.com/bar.html";
   var uri1 = NetUtil.newURI(spec1);
   var uri2 = NetUtil.newURI(spec2);
-  var channel1 = NetUtil.newChannel(uri1);
-  var channel2 = NetUtil.newChannel(uri2);
+  var channel1 = NetUtil.newChannel2(uri1,
+                                     null,
+                                     null,
+                                     null,      // aLoadingNode
+                                     Services.scriptSecurityManager.getSystemPrincipal(),
+                                     null,      // aTriggeringPrincipal
+                                     Ci.nsILoadInfo.SEC_NORMAL,
+                                     Ci.nsIContentPolicy.TYPE_OTHER);
+  var channel2 = NetUtil.newChannel2(uri2,
+                                     null,
+                                     null,
+                                     null,      // aLoadingNode
+                                     Services.scriptSecurityManager.getSystemPrincipal(),
+                                     null,      // aTriggeringPrincipal
+                                     Ci.nsILoadInfo.SEC_NORMAL,
+                                     Ci.nsIContentPolicy.TYPE_OTHER);
 
   // Force the channel URI to be used when determining the originating URI of
   // the channel.
   var httpchannel1 = channel1.QueryInterface(Ci.nsIHttpChannelInternal);
   var httpchannel2 = channel1.QueryInterface(Ci.nsIHttpChannelInternal);
   httpchannel1.forceAllowThirdPartyCookie = true;
   httpchannel2.forceAllowThirdPartyCookie = true;
 
--- a/extensions/cookie/test/unit/test_cookies_privatebrowsing.js
+++ b/extensions/cookie/test/unit/test_cookies_privatebrowsing.js
@@ -14,17 +14,24 @@ function finish_test() {
   do_execute_soon(function() {
     test_generator.close();
     do_test_finished();
   });
 }
 
 function make_channel(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-  var chan = ios.newChannel(url, null, null).QueryInterface(Ci.nsIHttpChannel);
+  var chan = ios.newChannel2(url,
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER).QueryInterface(Ci.nsIHttpChannel);
   return chan;
 }
 
 function do_run_test() {
   // Set up a profile.
   let profile = do_get_profile();
 
   // Test with cookies enabled.
--- a/extensions/cookie/test/unit/test_cookies_thirdparty.js
+++ b/extensions/cookie/test/unit/test_cookies_thirdparty.js
@@ -7,18 +7,32 @@
 
 function run_test() {
   // Create URIs and channels pointing to foo.com and bar.com.
   // We will use these to put foo.com into first and third party contexts.
   var spec1 = "http://foo.com/foo.html";
   var spec2 = "http://bar.com/bar.html";
   var uri1 = NetUtil.newURI(spec1);
   var uri2 = NetUtil.newURI(spec2);
-  var channel1 = NetUtil.newChannel(uri1);
-  var channel2 = NetUtil.newChannel(uri2);
+  var channel1 = NetUtil.newChannel2(uri1,
+                                     null,
+                                     null,
+                                     null,      // aLoadingNode
+                                     Services.scriptSecurityManager.getSystemPrincipal(),
+                                     null,      // aTriggeringPrincipal
+                                     Ci.nsILoadInfo.SEC_NORMAL,
+                                     Ci.nsIContentPolicy.TYPE_OTHER);
+  var channel2 = NetUtil.newChannel2(uri2,
+                                     null,
+                                     null,
+                                     null,      // aLoadingNode
+                                     Services.scriptSecurityManager.getSystemPrincipal(),
+                                     null,      // aTriggeringPrincipal
+                                     Ci.nsILoadInfo.SEC_NORMAL,
+                                     Ci.nsIContentPolicy.TYPE_OTHER);
 
   // test with cookies enabled
   Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
   do_set_cookies(uri1, channel1, true, [1, 2, 3, 4]);
   Services.cookies.removeAll();
   do_set_cookies(uri1, channel2, true, [1, 2, 3, 4]);
   Services.cookies.removeAll();
 
--- a/extensions/cookie/test/unit/test_cookies_thirdparty_session.js
+++ b/extensions/cookie/test/unit/test_cookies_thirdparty_session.js
@@ -24,18 +24,32 @@ function do_run_test() {
   let profile = do_get_profile();
 
   // Create URIs and channels pointing to foo.com and bar.com.
   // We will use these to put foo.com into first and third party contexts.
   var spec1 = "http://foo.com/foo.html";
   var spec2 = "http://bar.com/bar.html";
   var uri1 = NetUtil.newURI(spec1);
   var uri2 = NetUtil.newURI(spec2);
-  var channel1 = NetUtil.newChannel(uri1);
-  var channel2 = NetUtil.newChannel(uri2);
+  var channel1 = NetUtil.newChannel2(uri1,
+                                     null,
+                                     null,
+                                     null,      // aLoadingNode
+                                     Services.scriptSecurityManager.getSystemPrincipal(),
+                                     null,      // aTriggeringPrincipal
+                                     Ci.nsILoadInfo.SEC_NORMAL,
+                                     Ci.nsIContentPolicy.TYPE_OTHER);
+  var channel2 = NetUtil.newChannel2(uri2,
+                                     null,
+                                     null,
+                                     null,      // aLoadingNode
+                                     Services.scriptSecurityManager.getSystemPrincipal(),
+                                     null,      // aTriggeringPrincipal
+                                     Ci.nsILoadInfo.SEC_NORMAL,
+                                     Ci.nsIContentPolicy.TYPE_OTHER);
 
   // Force the channel URI to be used when determining the originating URI of
   // the channel.
   var httpchannel1 = channel1.QueryInterface(Ci.nsIHttpChannelInternal);
   var httpchannel2 = channel2.QueryInterface(Ci.nsIHttpChannelInternal);
   httpchannel1.forceAllowThirdPartyCookie = true;
   httpchannel2.forceAllowThirdPartyCookie = true;
 
--- a/image/test/unit/async_load_tests.js
+++ b/image/test/unit/async_load_tests.js
@@ -7,16 +7,17 @@
  */
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cr = Components.results;
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var server = new HttpServer();
 server.registerDirectory("/", do_get_file(''));
 server.registerContentType("sjs", "sjs");
 server.start(-1);
 
 
 load('image_load_helpers.js');
@@ -135,17 +136,22 @@ function getChannelLoadImageStopCallback
 
 // Load the request a second time. This should come from the image cache, and
 // therefore would be at most risk of being served synchronously.
 function checkSecondChannelLoad()
 {
   do_test_pending();
 
   var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);  
-  var channel = ioService.newChannelFromURI(uri);
+  var channel = ioService.newChannelFromURI2(uri,
+                                             null,      // aLoadingNode
+                                             Services.scriptSecurityManager.getSystemPrincipal(),
+                                             null,      // aTriggeringPrincipal
+                                             Ci.nsILoadInfo.SEC_NORMAL,
+                                             Ci.nsIContentPolicy.TYPE_OTHER);
   var channellistener = new ChannelListener();
   channel.asyncOpen(channellistener, null);
 
   var listener = new ImageListener(getChannelLoadImageStartCallback(channellistener),
                                    getChannelLoadImageStopCallback(channellistener,
                                                                    all_done_callback));
   var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
                 .createScriptedObserver(listener);
@@ -159,17 +165,22 @@ function checkSecondChannelLoad()
 function run_loadImageWithChannel_tests()
 {
   // To ensure we're testing what we expect to, create a new loader and cache.
   gCurrentLoader = Cc["@mozilla.org/image/loader;1"].createInstance(Ci.imgILoader);
 
   do_test_pending();
 
   var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);  
-  var channel = ioService.newChannelFromURI(uri);
+  var channel = ioService.newChannelFromURI2(uri,
+                                             null,      // aLoadingNode
+                                             Services.scriptSecurityManager.getSystemPrincipal(),
+                                             null,      // aTriggeringPrincipal
+                                             Ci.nsILoadInfo.SEC_NORMAL,
+                                             Ci.nsIContentPolicy.TYPE_OTHER);
   var channellistener = new ChannelListener();
   channel.asyncOpen(channellistener, null);
 
   var listener = new ImageListener(getChannelLoadImageStartCallback(channellistener),
                                    getChannelLoadImageStopCallback(channellistener,
                                                                    checkSecondChannelLoad));
   var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
                 .createScriptedObserver(listener);
--- a/image/test/unit/test_private_channel.js
+++ b/image/test/unit/test_private_channel.js
@@ -48,17 +48,22 @@ NotificationCallbacks.prototype = {
     throw Cr.NS_ERROR_NO_INTERFACE;
   }
 };
 
 var gImgPath = 'http://localhost:' + server.identity.primaryPort + '/image.png';
 
 function setup_chan(path, isPrivate, callback) {
   var uri = gIoService.newURI(gImgPath, null, null);
-  var chan = gIoService.newChannelFromURI(uri);
+  var chan = gIoService.newChannelFromURI2(uri,
+                                           null,      // aLoadingNode
+                                           Services.scriptSecurityManager.getSystemPrincipal(),
+                                           null,      // aTriggeringPrincipal
+                                           Ci.nsILoadInfo.SEC_NORMAL,
+                                           Ci.nsIContentPolicy.TYPE_OTHER);
   chan.notificationCallbacks = new NotificationCallbacks(isPrivate);
   var channelListener = new ChannelListener();
   chan.asyncOpen(channelListener, null);
 
   var listener = new ImageListener(null, callback);
   var outlistener = {};
   var loader = isPrivate ? gPrivateLoader : gPublicLoader;
   var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
--- a/intl/uconv/tests/unit/test_bug317216.js
+++ b/intl/uconv/tests/unit/test_bug317216.js
@@ -4,16 +4,21 @@
  * pairs and lone surrogate characters
  *
  * Sample text is: "A" in Mathematical Bold Capitals (U+1D400)
  *
  * The test uses buffers of 4 different lengths to test end of buffer in mid-
  * UTF16 character and mid-surrogate pair
  */
 
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/Services.jsm");
+
 const test = [
 // 0: Valid surrogate pair
               ["%D8%35%DC%20%00%2D%00%2D",
 //    expected: surrogate pair
                "\uD835\uDC20--"],
 // 1: Lone high surrogate
               ["%D8%35%00%2D%00%2D",
 //    expected: one replacement char
@@ -66,25 +71,32 @@ const ConverterInputStream =
                              "nsIConverterInputStream",
                              "init");
 const ios = new IOService();
 
 function testCase(testText, expectedText, bufferLength, charset)
 {
   var dataURI = "data:text/plain;charset=" + charset + "," + testText;
 
-  var channel = ios.newChannel(dataURI, "", null);
+  var channel = ios.newChannel2(dataURI,
+                                "",
+                                null,
+                                null,      // aLoadingNode
+                                Services.scriptSecurityManager.getSystemPrincipal(),
+                                null,      // aTriggeringPrincipal
+                                Ci.nsILoadInfo.SEC_NORMAL,
+                                Ci.nsIContentPolicy.TYPE_OTHER);
   var testInputStream = channel.open();
   var testConverter = new ConverterInputStream(testInputStream,
                                                charset,
                                                bufferLength,
                                                0xFFFD);
 
   if (!(testConverter instanceof
-        Components.interfaces.nsIUnicharLineInputStream))
+        Ci.nsIUnicharLineInputStream))
     throw "not line input stream";
 
   var outStr = "";
   var more;
   do {
     // read the line and check for eof
     var line = {};
     more = testConverter.readLine(line);
--- a/intl/uconv/tests/unit/test_bug340714.js
+++ b/intl/uconv/tests/unit/test_bug340714.js
@@ -6,16 +6,21 @@
  * Sample text is: "Все счастливые семьи похожи друг на друга, каждая несчастливая семья несчастлива по-своему."
  *
  * The enclosing quotation marks are included in the sample text to test that
  * UTF-16LE is recognized even when there is no BOM and the UTF-16LE decoder is
  * not explicitly called. This only works when the first character of the text
  * is an eight-bit character.
  */
 
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/Services.jsm");
+
 const beBOM="%FE%FF";
 const leBOM="%FF%FE";
 const sampleUTF16BE="%00%22%04%12%04%41%04%35%00%20%04%41%04%47%04%30%04%41%04%42%04%3B%04%38%04%32%04%4B%04%35%00%20%04%41%04%35%04%3C%04%4C%04%38%00%20%04%3F%04%3E%04%45%04%3E%04%36%04%38%00%20%04%34%04%40%04%43%04%33%00%20%04%3D%04%30%00%20%04%34%04%40%04%43%04%33%04%30%00%2C%00%20%04%3A%04%30%04%36%04%34%04%30%04%4F%00%20%04%3D%04%35%04%41%04%47%04%30%04%41%04%42%04%3B%04%38%04%32%04%30%04%4F%00%20%04%41%04%35%04%3C%04%4C%04%4F%00%20%04%3D%04%35%04%41%04%47%04%30%04%41%04%42%04%3B%04%38%04%32%04%30%00%20%04%3F%04%3E%00%2D%04%41%04%32%04%3E%04%35%04%3C%04%43%00%2E%00%22";
 const sampleUTF16LE="%22%00%12%04%41%04%35%04%20%00%41%04%47%04%30%04%41%04%42%04%3B%04%38%04%32%04%4B%04%35%04%20%00%41%04%35%04%3C%04%4C%04%38%04%20%00%3F%04%3E%04%45%04%3E%04%36%04%38%04%20%00%34%04%40%04%43%04%33%04%20%00%3D%04%30%04%20%00%34%04%40%04%43%04%33%04%30%04%2C%00%20%00%3A%04%30%04%36%04%34%04%30%04%4F%04%20%00%3D%04%35%04%41%04%47%04%30%04%41%04%42%04%3B%04%38%04%32%04%30%04%4F%04%20%00%41%04%35%04%3C%04%4C%04%4F%04%20%00%3D%04%35%04%41%04%47%04%30%04%41%04%42%04%3B%04%38%04%32%04%30%04%20%00%3F%04%3E%04%2D%00%41%04%32%04%3E%04%35%04%3C%04%43%04%2E%00%22%00";
 const expected = "\"\u0412\u0441\u0435 \u0441\u0447\u0430\u0441\u0442\u043B\u0438\u0432\u044B\u0435 \u0441\u0435\u043C\u044C\u0438 \u043F\u043E\u0445\u043E\u0436\u0438 \u0434\u0440\u0443\u0433 \u043D\u0430 \u0434\u0440\u0443\u0433\u0430, \u043A\u0430\u0436\u0434\u0430\u044F \u043D\u0435\u0441\u0447\u0430\u0441\u0442\u043B\u0438\u0432\u0430\u044F \u0441\u0435\u043C\u044C\u044F \u043D\u0435\u0441\u0447\u0430\u0441\u0442\u043B\u0438\u0432\u0430 \u043F\u043E-\u0441\u0432\u043E\u0435\u043C\u0443.\""; 
 
 function makeText(withBOM, charset)
 {
@@ -38,25 +43,31 @@ function testCase(withBOM, charset, char
   var IOService = Components.Constructor("@mozilla.org/network/io-service;1",
 					 "nsIIOService");
   var ConverterInputStream =
       Components.Constructor("@mozilla.org/intl/converter-input-stream;1",
 			     "nsIConverterInputStream",
 			     "init");
 
   var ios = new IOService();
-  var channel = ios.newChannel(dataURI, "", null);
+  var channel = ios.newChannel2(dataURI,
+                                "",
+                                null,
+                                null,      // aLoadingNode
+                                Services.scriptSecurityManager.getSystemPrincipal(),
+                                null,      // aTriggeringPrincipal
+                                Ci.nsILoadInfo.SEC_NORMAL,
+                                Ci.nsIContentPolicy.TYPE_OTHER);
   var testInputStream = channel.open();
   var testConverter = new ConverterInputStream(testInputStream,
 					       decoder,
 					       bufferLength,
 					       0xFFFD);
 
-  if (!(testConverter instanceof
-	Components.interfaces.nsIUnicharLineInputStream))
+  if (!(testConverter instanceof Ci.nsIUnicharLineInputStream))
       throw "not line input stream";
 
   var outStr = "";
   var more;
   do {
       // read the line and check for eof
       var line = {};
       more = testConverter.readLine(line);
--- a/intl/uconv/tests/unit/test_bug563618.js
+++ b/intl/uconv/tests/unit/test_bug563618.js
@@ -1,14 +1,19 @@
 /* Test case for bug 563618
  *
  * Uses nsIConverterInputStream to decode invalid EUC-JP text
  *
  */
 
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/Services.jsm");
+
 const test = [
 // 0: 0x8e followed by hi byte, not valid JIS X 0201
 	      ["abcdefghijklmnopqrstuvwxyz12test00%8e%80foobar",
 //    expected: one replacement character, invalid byte eaten
                "abcdefghijklmnopqrstuvwxyz12test00\uFFFDfoobar"],
 // 1: 0x8e followed by ASCII
 	      ["abcdefghijklmnopqrstuvwxyz12test01%8efoobar",
 //    expected: one replacement character, invalid byte not eaten
@@ -29,25 +34,31 @@ const ConverterInputStream =
                              "nsIConverterInputStream",
                              "init");
 const ios = new IOService();
 
 function testCase(testText, expectedText, bufferLength, charset)
 {
   var dataURI = "data:text/plain;charset=" + charset + "," + testText;
 
-  var channel = ios.newChannel(dataURI, "", null);
+  var channel = ios.newChannel2(dataURI,
+                                "",
+                                null,
+                                null,      // aLoadingNode
+                                Services.scriptSecurityManager.getSystemPrincipal(),
+                                null,      // aTriggeringPrincipal
+                                Ci.nsILoadInfo.SEC_NORMAL,
+                                Ci.nsIContentPolicy.TYPE_OTHER);
   var testInputStream = channel.open();
   var testConverter = new ConverterInputStream(testInputStream,
                                                charset,
                                                bufferLength,
                                                0xFFFD);
 
-  if (!(testConverter instanceof
-        Components.interfaces.nsIUnicharLineInputStream))
+  if (!(testConverter instanceof Ci.nsIUnicharLineInputStream))
     throw "not line input stream";
 
   var outStr = "";
   var more;
   do {
     // read the line and check for eof
     var line = {};
     more = testConverter.readLine(line);
--- a/intl/uconv/tests/unit/test_utf8_illegals.js
+++ b/intl/uconv/tests/unit/test_utf8_illegals.js
@@ -1,12 +1,15 @@
 // Tests illegal UTF-8 sequences
 
 const Cc = Components.Constructor;
 const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/Services.jsm");
 
 const tests = [
 { inStrings: ["%80",                 // Illegal or incomplete sequences
               "%8f",
               "%90",
               "%9f",
               "%a0",
               "%bf",
@@ -98,17 +101,24 @@ function testCaseInputStream(inStr, expe
   var IOService = Cc("@mozilla.org/network/io-service;1",
 		     "nsIIOService");
   var ConverterInputStream =
       Cc("@mozilla.org/intl/converter-input-stream;1",
 	 "nsIConverterInputStream",
 	 "init");
 
   var ios = new IOService();
-  var channel = ios.newChannel(dataURI, "", null);
+  var channel = ios.newChannel2(dataURI,
+                                "",
+                                null,
+                                null,      // aLoadingNode
+                                Services.scriptSecurityManager.getSystemPrincipal(),
+                                null,      // aTriggeringPrincipal
+                                Ci.nsILoadInfo.SEC_NORMAL,
+                                Ci.nsIContentPolicy.TYPE_OTHER);
   var testInputStream = channel.open();
   var testConverter = new ConverterInputStream(testInputStream,
 					       "UTF-8",
 					       16,
 					       0xFFFD);
 
   if (!(testConverter instanceof Ci.nsIUnicharLineInputStream))
       throw "not line input stream";
--- a/js/src/asmjs/AsmJSModule.cpp
+++ b/js/src/asmjs/AsmJSModule.cpp
@@ -777,17 +777,17 @@ AsmJSModule::initHeap(Handle<ArrayBuffer
     uint8_t *heapOffset = heap->dataPointer();
     for (unsigned i = 0; i < heapAccesses_.length(); i++) {
         const jit::AsmJSHeapAccess &access = heapAccesses_[i];
         if (access.hasLengthCheck()) {
             // An access is out-of-bounds iff
             //      ptr + data-type-byte-size > heapLength
             // i.e. ptr >= heapLength + 1 - data-type-byte-size
             // (Note that we need >= as this is what codegen uses.)
-            size_t scalarByteSize = 1 << TypedArrayShift(access.type());
+            size_t scalarByteSize = TypedArrayElemSize(access.type());
             X86Assembler::setPointer(access.patchLengthAt(code_),
                                      (void*)(heap->byteLength() + 1 - scalarByteSize));
         }
         void *addr = access.patchOffsetAt(code_);
         uint32_t disp = reinterpret_cast<uint32_t>(X86Assembler::getPointer(addr));
         MOZ_ASSERT(disp <= INT32_MAX);
         X86Assembler::setPointer(addr, (void *)(heapOffset + disp));
     }
@@ -799,17 +799,17 @@ AsmJSModule::initHeap(Handle<ArrayBuffer
     // checks at the right places. All accesses that have been recorded are the
     // only ones that need bound checks (see also
     // CodeGeneratorX64::visitAsmJS{Load,Store,CompareExchange,AtomicBinop}Heap)
     int32_t heapLength = int32_t(intptr_t(heap->byteLength()));
     for (size_t i = 0; i < heapAccesses_.length(); i++) {
         const jit::AsmJSHeapAccess &access = heapAccesses_[i];
         if (access.hasLengthCheck()) {
             // See comment above for x86 codegen.
-            size_t scalarByteSize = 1 << TypedArrayShift(access.type());
+            size_t scalarByteSize = TypedArrayElemSize(access.type());
             X86Assembler::setInt32(access.patchLengthAt(code_), heapLength + 1 - scalarByteSize);
         }
     }
 #elif defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
     uint32_t heapLength = heap->byteLength();
     for (unsigned i = 0; i < heapAccesses_.length(); i++) {
         jit::Assembler::UpdateBoundsCheck(heapLength,
                                           (jit::Instruction*)(heapAccesses_[i].offset() + code_));
--- a/js/src/asmjs/AsmJSValidate.cpp
+++ b/js/src/asmjs/AsmJSValidate.cpp
@@ -2642,27 +2642,27 @@ class FunctionCompiler
 
         MOZ_ASSERT(IsSimdType(vec->type()) && vec->type() == type);
         MOZ_ASSERT(!IsSimdType(val->type()));
         MSimdInsertElement *ins = MSimdInsertElement::NewAsmJS(alloc(), vec, val, type, lane);
         curBlock_->add(ins);
         return ins;
     }
 
-    MDefinition *ternarySimd(MDefinition *mask, MDefinition *lhs, MDefinition *rhs,
-                             MSimdTernaryBitwise::Operation op, MIRType type)
+    MDefinition *selectSimd(MDefinition *mask, MDefinition *lhs, MDefinition *rhs, MIRType type,
+                            bool isElementWise)
     {
         if (inDeadCode())
             return nullptr;
 
         MOZ_ASSERT(IsSimdType(mask->type()));
         MOZ_ASSERT(mask->type() == MIRType_Int32x4);
         MOZ_ASSERT(IsSimdType(lhs->type()) && rhs->type() == lhs->type());
         MOZ_ASSERT(lhs->type() == type);
-        MSimdTernaryBitwise *ins = MSimdTernaryBitwise::NewAsmJS(alloc(), mask, lhs, rhs, op, type);
+        MSimdSelect *ins = MSimdSelect::NewAsmJS(alloc(), mask, lhs, rhs, type, isElementWise);
         curBlock_->add(ins);
         return ins;
     }
 
     template<class T>
     MDefinition *convertSimd(MDefinition *vec, MIRType from, MIRType to)
     {
         if (inDeadCode())
@@ -4355,32 +4355,32 @@ CheckArrayAccess(FunctionCompiler &f, Pa
     *viewType = global->viewType();
 
     uint32_t index;
     if (IsLiteralOrConstInt(f, indexExpr, &index)) {
         uint64_t byteOffset = uint64_t(index) << TypedArrayShift(*viewType);
         if (byteOffset > INT32_MAX)
             return f.fail(indexExpr, "constant index out of range");
 
-        unsigned elementSize = 1 << TypedArrayShift(*viewType);
+        unsigned elementSize = TypedArrayElemSize(*viewType);
         if (!f.m().tryRequireHeapLengthToBeAtLeast(byteOffset + elementSize)) {
             return f.failf(indexExpr, "constant index outside heap size range declared by the "
                                       "change-heap function (0x%x - 0x%x)",
                                       f.m().minHeapLength(), f.m().module().maxHeapLength());
         }
 
         *needsBoundsCheck = NO_BOUNDS_CHECK;
         *def = f.constant(Int32Value(byteOffset), Type::Int);
         return true;
     }
 
     // Mask off the low bits to account for the clearing effect of a right shift
     // followed by the left shift implicit in the array access. E.g., H32[i>>2]
     // loses the low two bits.
-    int32_t mask = ~((uint32_t(1) << TypedArrayShift(*viewType)) - 1);
+    int32_t mask = ~(TypedArrayElemSize(*viewType) - 1);
 
     MDefinition *pointerDef;
     if (indexExpr->isKind(PNK_RSH)) {
         ParseNode *shiftNode = BinaryRight(indexExpr);
         ParseNode *pointerNode = BinaryLeft(indexExpr);
 
         uint32_t shift;
         if (!IsLiteralInt(f.m(), shiftNode, &shift))
@@ -5704,16 +5704,28 @@ CheckSimdStore(FunctionCompiler &f, Pars
 
     f.storeHeap(viewType, index, vec, needsBoundsCheck);
     *def = vec;
     *type = vecType;
     return true;
 }
 
 static bool
+CheckSimdSelect(FunctionCompiler &f, ParseNode *call, AsmJSSimdType opType, bool isElementWise,
+                MDefinition **def, Type *type)
+{
+    DefinitionVector defs;
+    if (!CheckSimdCallArgs(f, call, 3, CheckSimdSelectArgs(opType), &defs))
+        return false;
+    *type = opType;
+    *def = f.selectSimd(defs[0], defs[1], defs[2], type->toMIRType(), isElementWise);
+    return true;
+}
+
+static bool
 CheckSimdOperationCall(FunctionCompiler &f, ParseNode *call, const ModuleCompiler::Global *global,
                        MDefinition **def, Type *type)
 {
     MOZ_ASSERT(global->isSimdOperation());
 
     AsmJSSimdType opType = global->simdOperationType();
 
     switch (global->simdOperation()) {
@@ -5797,34 +5809,29 @@ CheckSimdOperationCall(FunctionCompiler 
       case AsmJSSimdOperation_shuffle:
         return CheckSimdShuffle(f, call, opType, def, type);
 
       case AsmJSSimdOperation_load:
         return CheckSimdLoad(f, call, opType, def, type);
       case AsmJSSimdOperation_store:
         return CheckSimdStore(f, call, opType, def, type);
 
+      case AsmJSSimdOperation_bitselect:
+        return CheckSimdSelect(f, call, opType, /*isElementWise */ false, def, type);
+      case AsmJSSimdOperation_select:
+        return CheckSimdSelect(f, call, opType, /*isElementWise */ true, def, type);
+
       case AsmJSSimdOperation_splat: {
         DefinitionVector defs;
         if (!CheckSimdCallArgs(f, call, 1, CheckSimdScalarArgs(opType), &defs))
             return false;
         *type = opType;
         *def = f.splatSimd(defs[0], type->toMIRType());
         return true;
       }
-
-      case AsmJSSimdOperation_select: {
-        DefinitionVector defs;
-        if (!CheckSimdCallArgs(f, call, 3, CheckSimdSelectArgs(opType), &defs))
-            return false;
-        *type = opType;
-        *def = f.ternarySimd(defs[0], defs[1], defs[2], MSimdTernaryBitwise::select,
-                             type->toMIRType());
-        return true;
-      }
     }
     MOZ_CRASH("unexpected simd operation in CheckSimdOperationCall");
 }
 
 static bool
 CheckSimdCtorCall(FunctionCompiler &f, ParseNode *call, const ModuleCompiler::Global *global,
                   MDefinition **def, Type *type)
 {
--- a/js/src/builtin/SIMD.cpp
+++ b/js/src/builtin/SIMD.cpp
@@ -876,22 +876,25 @@ Float32x4Clamp(JSContext *cx, unsigned a
     for (unsigned i = 0; i < Float32x4::lanes; i++) {
         result[i] = val[i] < lowerLimit[i] ? lowerLimit[i] : val[i];
         result[i] = result[i] > upperLimit[i] ? upperLimit[i] : result[i];
     }
 
     return StoreResult<Float32x4>(cx, args, result);
 }
 
+template<typename V>
 static bool
-Int32x4Select(JSContext *cx, unsigned argc, Value *vp)
+BitSelect(JSContext *cx, unsigned argc, Value *vp)
 {
+    typedef typename V::Elem Elem;
+
     CallArgs args = CallArgsFromVp(argc, vp);
     if (args.length() != 3 || !IsVectorObject<Int32x4>(args[0]) ||
-        !IsVectorObject<Int32x4>(args[1]) || !IsVectorObject<Int32x4>(args[2]))
+        !IsVectorObject<V>(args[1]) || !IsVectorObject<V>(args[2]))
     {
         return ErrorBadArgs(cx);
     }
 
     int32_t *val = TypedObjectMemory<int32_t *>(args[0]);
     int32_t *tv = TypedObjectMemory<int32_t *>(args[1]);
     int32_t *fv = TypedObjectMemory<int32_t *>(args[2]);
 
@@ -902,47 +905,42 @@ Int32x4Select(JSContext *cx, unsigned ar
     int32_t fr[Int32x4::lanes];
     for (unsigned i = 0; i < Int32x4::lanes; i++)
         fr[i] = And<int32_t>::apply(Not<int32_t>::apply(val[i]), fv[i]);
 
     int32_t orInt[Int32x4::lanes];
     for (unsigned i = 0; i < Int32x4::lanes; i++)
         orInt[i] = Or<int32_t>::apply(tr[i], fr[i]);
 
-    return StoreResult<Int32x4>(cx, args, orInt);
+    Elem *result = reinterpret_cast<Elem*>(orInt);
+    return StoreResult<V>(cx, args, result);
 }
 
+template<typename V>
 static bool
-Float32x4Select(JSContext *cx, unsigned argc, Value *vp)
+Select(JSContext *cx, unsigned argc, Value *vp)
 {
+    typedef typename V::Elem Elem;
+
     CallArgs args = CallArgsFromVp(argc, vp);
     if (args.length() != 3 || !IsVectorObject<Int32x4>(args[0]) ||
-        !IsVectorObject<Float32x4>(args[1]) || !IsVectorObject<Float32x4>(args[2]))
+        !IsVectorObject<V>(args[1]) || !IsVectorObject<V>(args[2]))
     {
         return ErrorBadArgs(cx);
     }
 
-    int32_t *val = TypedObjectMemory<int32_t *>(args[0]);
-    int32_t *tv = TypedObjectMemory<int32_t *>(args[1]);
-    int32_t *fv = TypedObjectMemory<int32_t *>(args[2]);
-
-    int32_t tr[Int32x4::lanes];
-    for (unsigned i = 0; i < Int32x4::lanes; i++)
-        tr[i] = And<int32_t>::apply(val[i], tv[i]);
+    int32_t *mask = TypedObjectMemory<int32_t*>(args[0]);
+    Elem *tv = TypedObjectMemory<Elem *>(args[1]);
+    Elem *fv = TypedObjectMemory<Elem *>(args[2]);
 
-    int32_t fr[Int32x4::lanes];
-    for (unsigned i = 0; i < Int32x4::lanes; i++)
-        fr[i] = And<int32_t>::apply(Not<int32_t>::apply(val[i]), fv[i]);
+    Elem result[V::lanes];
+    for (unsigned i = 0; i < V::lanes; i++)
+        result[i] = mask[i] < 0 ? tv[i] : fv[i];
 
-    int32_t orInt[Int32x4::lanes];
-    for (unsigned i = 0; i < Int32x4::lanes; i++)
-        orInt[i] = Or<int32_t>::apply(tr[i], fr[i]);
-
-    float *result = reinterpret_cast<float *>(orInt);
-    return StoreResult<Float32x4>(cx, args, result);
+    return StoreResult<V>(cx, args, result);
 }
 
 template<class VElem, unsigned NumElem>
 static bool
 TypedArrayDataPtrFromArgs(JSContext *cx, const CallArgs &args, VElem **data)
 {
     if (!args[0].isObject())
         return ErrorBadArgs(cx);
--- a/js/src/builtin/SIMD.h
+++ b/js/src/builtin/SIMD.h
@@ -56,18 +56,19 @@
   V(sub, (BinaryFunc<Float32x4, Sub, Float32x4>), 2, 0)                             \
   V(withX, (FuncWith<Float32x4, WithX>), 2, 0)                                      \
   V(withY, (FuncWith<Float32x4, WithY>), 2, 0)                                      \
   V(withZ, (FuncWith<Float32x4, WithZ>), 2, 0)                                      \
   V(withW, (FuncWith<Float32x4, WithW>), 2, 0)                                      \
   V(xor, (CoercedBinaryFunc<Float32x4, Int32x4, Xor, Float32x4>), 2, 0)
 
 #define FLOAT32X4_TERNARY_FUNCTION_LIST(V)                                          \
+  V(bitselect, BitSelect<Float32x4>, 3, 0)                                          \
   V(clamp, Float32x4Clamp, 3, 0)                                                    \
-  V(select, Float32x4Select, 3, 0)
+  V(select, Select<Float32x4>, 3, 0)
 
 #define FLOAT32X4_SHUFFLE_FUNCTION_LIST(V)                                          \
   V(swizzle, Swizzle<Float32x4>, 2, 0)                                              \
   V(shuffle, Shuffle<Float32x4>, 3, 0)
 
 #define FLOAT32X4_FUNCTION_LIST(V)                                                  \
   FLOAT32X4_UNARY_FUNCTION_LIST(V)                                                  \
   FLOAT32X4_BINARY_FUNCTION_LIST(V)                                                 \
@@ -106,17 +107,18 @@
   V(storeX,   (Store<Int32x4, 1>), 3, 0)                                            \
   V(withX, (FuncWith<Int32x4, WithX>), 2, 0)                                        \
   V(withY, (FuncWith<Int32x4, WithY>), 2, 0)                                        \
   V(withZ, (FuncWith<Int32x4, WithZ>), 2, 0)                                        \
   V(withW, (FuncWith<Int32x4, WithW>), 2, 0)                                        \
   V(xor, (BinaryFunc<Int32x4, Xor, Int32x4>), 2, 0)
 
 #define INT32X4_TERNARY_FUNCTION_LIST(V)                                            \
-  V(select, Int32x4Select, 3, 0)                                                    \
+  V(bitselect, BitSelect<Int32x4>, 3, 0)                                            \
+  V(select, Select<Int32x4>, 3, 0)
 
 #define INT32X4_QUARTERNARY_FUNCTION_LIST(V)                                        \
   V(bool, Int32x4Bool, 4, 0)
 
 #define INT32X4_SHUFFLE_FUNCTION_LIST(V)                                            \
   V(swizzle, Swizzle<Int32x4>, 2, 0)                                                \
   V(shuffle, Shuffle<Int32x4>, 3, 0)
 
@@ -153,16 +155,17 @@
     _(lessThanOrEqual)               \
     _(equal)                         \
     _(notEqual)                      \
     _(greaterThan)                   \
     _(greaterThanOrEqual)            \
     _(and)                           \
     _(or)                            \
     _(xor)                           \
+    _(bitselect)                     \
     _(select)                        \
     _(swizzle)                       \
     _(shuffle)                       \
     _(splat)                         \
     _(withX)                         \
     _(withY)                         \
     _(withZ)                         \
     _(withW)                         \
--- a/js/src/gc/Zone.cpp
+++ b/js/src/gc/Zone.cpp
@@ -102,16 +102,23 @@ void
 Zone::onTooMuchMalloc()
 {
     if (!gcMallocGCTriggered) {
         GCRuntime &gc = runtimeFromAnyThread()->gc;
         gcMallocGCTriggered = gc.triggerZoneGC(this, JS::gcreason::TOO_MUCH_MALLOC);
     }
 }
 
+bool
+Zone::isCloseToAllocTrigger(bool highFrequencyGC) const
+{
+    double factor = highFrequencyGC ? 0.85 : 0.9;
+    return usage.gcBytes() >= factor * threshold.gcTriggerBytes();
+}
+
 void
 Zone::beginSweepTypes(FreeOp *fop, bool releaseTypes)
 {
     // Periodically release observed types for all scripts. This is safe to
     // do when there are no frames for the zone on the stack.
     if (active)
         releaseTypes = false;
 
--- a/js/src/gc/Zone.h
+++ b/js/src/gc/Zone.h
@@ -148,16 +148,18 @@ struct Zone : public JS::shadow::Zone,
         gcMallocBytes -= ptrdiff_t(nbytes);
         if (MOZ_UNLIKELY(isTooMuchMalloc()))
             onTooMuchMalloc();
     }
 
     bool isTooMuchMalloc() const { return gcMallocBytes <= 0; }
     void onTooMuchMalloc();
 
+    bool isCloseToAllocTrigger(bool highFrequencyGC) const;
+
     void *onOutOfMemory(void *p, size_t nbytes) {
         return runtimeFromMainThread()->onOutOfMemory(p, nbytes);
     }
     void reportAllocationOverflow() { js_ReportAllocationOverflow(nullptr); }
 
     void beginSweepTypes(js::FreeOp *fop, bool releaseTypes);
 
     bool hasMarkedCompartments();
--- a/js/src/jit-test/tests/asm.js/testSIMD.js
+++ b/js/src/jit-test/tests/asm.js/testSIMD.js
@@ -822,42 +822,99 @@ for (var i = 1; i < 64; i++) {
     assertEqX4(asmLsh(i, 3),  vinput.map(Lsh(i + 3)));
     assertEqX4(asmRsh(i, 3),  vinput.map(Rsh(i + 3)));
     assertEqX4(asmUrsh(i, 3), vinput.map(Ursh(i + 3)));
 }
 
 // Select
 const I32SEL = 'var i4sel = i4.select;'
 const F32SEL = 'var f4sel = f4.select;'
+const I32BSEL = 'var i4sel = i4.bitselect;'
+const F32BSEL = 'var f4sel = f4.bitselect;'
 
 assertAsmTypeFail('glob', USE_ASM + F32 + I32SEL + "function f() {var x=f4(1,2,3,4); return i4(i4sel(x,x,x));} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32SEL + "function f() {var m=f4(1,2,3,4); var x=i4(1,2,3,4); return i4(i4sel(m,x,x));} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32SEL + "function f() {var m=f4(1,2,3,4); var x=f4(1,2,3,4); return i4(i4sel(m,x,x));} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32SEL + "function f() {var m=i4(1,2,3,4); var x=f4(1,2,3,4); return i4(i4sel(m,x,x));} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32SEL + "function f() {var m=i4(1,2,3,4); var x=f4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y));} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32SEL + "function f() {var m=i4(1,2,3,4); var x=i4(1,2,3,4); var y=f4(5,6,7,8); return i4(i4sel(m,x,y));} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32SEL + "function f() {var m=i4(1,2,3,4); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return i4(i4sel(m,x,y));} return f");
 
-
 assertAsmTypeFail('glob', USE_ASM + F32 + F32SEL + "function f() {var m=f4(1,2,3,4); return f4(f4sel(x,x,x));} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=f4(1,2,3,4); var x=i4(1,2,3,4); return f4(f4sel(m,x,x));} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=f4(1,2,3,4); var x=f4(1,2,3,4); return f4(f4sel(m,x,x));} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(1,2,3,4); var x=f4(1,2,3,4); var y=i4(5,6,7,8); return f4(f4sel(m,x,y));} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(1,2,3,4); var x=i4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y));} return f");
 
+// These pass with select but not bitselect
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32SEL + "function f() {var m=i4(0,0,0,0); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [5, 6, 7, 8]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32SEL + "function f() {var m=i4(-1,-2,-3,-42); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [1, 2, 3, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32SEL + "function f() {var m=i4(1,-1,2,-2); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [5, 2, 7, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32SEL + "function f() {var m=i4(42,45,-42,-47); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [5, 6, 3, 4]);
+
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(0,0,0,0); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [5, 6, 7, 8]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(-1,-2,-3,-42); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [1, 2, 3, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(1,-1,2,-2); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [5, 2, 7, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(42,45,-42,-47); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [5, 6, 3, 4]);
+
+// These pass for both select and bitselect
 assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32SEL + "function f() {var m=i4(0,0,0,0); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [5, 6, 7, 8]);
 assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32SEL + "function f() {var m=i4(0xffffffff,0xffffffff,0xffffffff,0xffffffff); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [1, 2, 3, 4]);
 assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32SEL + "function f() {var m=i4(0,0xffffffff,0,0xffffffff); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [5, 2, 7, 4]);
 assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32SEL + "function f() {var m=i4(0,0,0xffffffff,0xffffffff); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [5, 6, 3, 4]);
 
 assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(0,0,0,0); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [5, 6, 7, 8]);
 assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(0xffffffff,0xffffffff,0xffffffff,0xffffffff); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [1, 2, 3, 4]);
 assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(0,0xffffffff,0,0xffffffff); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [5, 2, 7, 4]);
 assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32SEL + "function f() {var m=i4(0,0,0xffffffff,0xffffffff); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [5, 6, 3, 4]);
 
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32BSEL + "function f() {var m=i4(0,0,0,0); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [5, 6, 7, 8]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32BSEL + "function f() {var m=i4(0xffffffff,0xffffffff,0xffffffff,0xffffffff); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [1, 2, 3, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32BSEL + "function f() {var m=i4(0,0xffffffff,0,0xffffffff); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [5, 2, 7, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + I32BSEL + "function f() {var m=i4(0,0,0xffffffff,0xffffffff); var x=i4(1,2,3,4); var y=i4(5,6,7,8); return i4(i4sel(m,x,y)); } return f"), this)(), [5, 6, 3, 4]);
+
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32BSEL + "function f() {var m=i4(0,0,0,0); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [5, 6, 7, 8]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32BSEL + "function f() {var m=i4(0xffffffff,0xffffffff,0xffffffff,0xffffffff); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [1, 2, 3, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32BSEL + "function f() {var m=i4(0,0xffffffff,0,0xffffffff); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [5, 2, 7, 4]);
+assertEqX4(asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32BSEL + "function f() {var m=i4(0,0,0xffffffff,0xffffffff); var x=f4(1,2,3,4); var y=f4(5,6,7,8); return f4(f4sel(m,x,y)); } return f"), this)(), [5, 6, 3, 4]);
+
+// Specific bitselect tests
+var masks = [
+    SIMD.int32x4(1337, 0x1337, 0x42, 42),
+    SIMD.int32x4(0x00FF1CE, 0xBAADF00D, 0xDEADBEEF, 0xCAFED00D),
+    SIMD.int32x4(0xD15EA5E, 0xDEADC0DE, 0xFACEB00C, 0x4B1D4B1D)
+];
+
+var simdToArray = (vec) => [vec.x, vec.y, vec.z, vec.w];
+
+var inputs = [
+    [SIMD.int32x4(0,4,9,16), SIMD.int32x4(1,2,3,4)],
+    [SIMD.int32x4(-1, 2, INT32_MAX, INT32_MIN), SIMD.int32x4(INT32_MAX, -4, INT32_MIN, 42)]
+];
+
+var i32bsel = asmLink(asmCompile('glob', USE_ASM + I32 + I32BSEL + "function f(mask, ifTrue, ifFalse) {mask=i4(mask); ifTrue=i4(ifTrue); ifFalse=i4(ifFalse); return i4(i4sel(mask,ifTrue,ifFalse)); } return f"), this)
+
+for (var mask of masks) {
+    for (var [x, y] of inputs) {
+        assertEqX4(i32bsel(mask, x, y), simdToArray(SIMD.int32x4.bitselect(mask, x, y)));
+    }
+}
+
+inputs = [
+    [SIMD.float32x4(0.125,4.25,9.75,16.125), SIMD.float32x4(1.5,2.75,3.25,4.5)],
+    [SIMD.float32x4(-1.5,-0,NaN,-Infinity),  SIMD.float32x4(1,-2,13.37,3.13)],
+    [SIMD.float32x4(1.5,2.75,NaN,Infinity),  SIMD.float32x4(-NaN,-Infinity,9.75,16.125)]
+];
+
+var f32bsel = asmLink(asmCompile('glob', USE_ASM + I32 + F32 + F32BSEL + "function f(mask, ifTrue, ifFalse) {mask=i4(mask); ifTrue=f4(ifTrue); ifFalse=f4(ifFalse); return f4(f4sel(mask,ifTrue,ifFalse)); } return f"), this)
+
+for (var mask of masks)
+    for (var [x, y] of inputs)
+        assertEqX4(f32bsel(mask, x, y), simdToArray(SIMD.float32x4.bitselect(mask, x, y)));
+
 // Splat
 const I32SPLAT = 'var splat=i4.splat;'
 const F32SPLAT = 'var splat=f4.splat;'
 
 assertAsmTypeFail('glob', USE_ASM + I32 + F32 + I32SPLAT + "function f() {var m=i4(1,2,3,4); var p=f4(1.,2.,3.,4.); p=splat(f32(1));} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + I32SPLAT + "function f() {var m=i4(1,2,3,4); m=splat(1, 2)} return f");
 assertAsmTypeFail('glob', USE_ASM + I32 + I32SPLAT + "function f() {var m=i4(1,2,3,4); m=splat()} return f");
 
@@ -1123,16 +1180,39 @@ assertEqX4(m.f32lbndcheck(CONSTANT_BYTE_
 //      OOB
 var BatNaN = [NaN, NaN, NaN, NaN] // NaNNaNNaNNaN etc.
 assertEqX4(f32l(-1), BatNaN);
 assertEqX4(f32l(SIZE), BatNaN);
 assertEqX4(f32l(SIZE - 1), BatNaN);
 assertEqX4(f32l(SIZE - 2), BatNaN);
 assertEqX4(f32l(SIZE - 3), BatNaN);
 
+var code = `
+    "use asm";
+    var f4 = glob.SIMD.float32x4;
+    var f4l = f4.load;
+    var u8 = new glob.Uint8Array(heap);
+
+    function g(x) {
+        x = x|0;
+        // set a constraint on the size of the heap
+        var ptr = 0;
+        ptr = u8[0xFFFF] | 0;
+        // give a precise range to x
+        x = (x>>0) > 5 ? 5 : x;
+        x = (x>>0) < 0 ? 0 : x;
+        // ptr value gets a precise range but the bounds check shouldn't get
+        // eliminated.
+        return f4(f4l(u8, 0xFFFA + x | 0));
+    }
+
+    return g;
+`;
+assertEqX4(asmLink(asmCompile('glob', 'ffi', 'heap', code), this, {}, new ArrayBuffer(0x10000))(0), BatNaN);
+
 // Float32x4.store
 function f32s(n, v) { return m.f32s((n|0) << 2 | 0, v); };
 
 var vec  = SIMD.float32x4(5,6,7,8);
 var vec2 = SIMD.float32x4(0,1,2,3);
 
 reset();
 f32s(0, vec);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug1115665.js
@@ -0,0 +1,8 @@
+Object.prototype[3] = 3
+x = Array()
+    function f() {
+        for (i = 0; i < 9; i++) {
+            if (Object[x++] != 0) {}
+        }
+    }
+f()
--- a/js/src/jit/BaselineBailouts.cpp
+++ b/js/src/jit/BaselineBailouts.cpp
@@ -1797,33 +1797,33 @@ jit::FinishBailoutToBaseline(BaselineBai
       case Bailout_Round:
       case Bailout_NonPrimitiveInput:
       case Bailout_PrecisionLoss:
       case Bailout_TypeBarrierO:
       case Bailout_TypeBarrierV:
       case Bailout_MonitorTypes:
       case Bailout_Hole:
       case Bailout_NegativeIndex:
-      case Bailout_ObjectIdentityOrTypeGuard:
       case Bailout_NonInt32Input:
       case Bailout_NonNumericInput:
       case Bailout_NonBooleanInput:
       case Bailout_NonObjectInput:
       case Bailout_NonStringInput:
       case Bailout_NonSymbolInput:
       case Bailout_GuardThreadExclusive:
       case Bailout_InitialState:
       case Bailout_Debugger:
         // Do nothing.
         break;
 
       // Invalid assumption based on baseline code.
       case Bailout_OverflowInvalidate:
       case Bailout_NonStringInputInvalidate:
       case Bailout_DoubleOutput:
+      case Bailout_ObjectIdentityOrTypeGuard:
         if (!HandleBaselineInfoBailout(cx, outerScript, innerScript))
             return false;
         break;
 
       case Bailout_ArgumentCheck:
         // Do nothing, bailout will resume before the argument monitor ICs.
         break;
       case Bailout_BoundsCheck:
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -455,16 +455,22 @@ ICStub::trace(JSTracer *trc)
       case ICStub::SetProp_CallNative: {
         ICSetProp_CallNative *callStub = toSetProp_CallNative();
         MarkShape(trc, &callStub->shape(), "baseline-setpropcallnative-stub-shape");
         MarkObject(trc, &callStub->holder(), "baseline-setpropcallnative-stub-holder");
         MarkShape(trc, &callStub->holderShape(), "baseline-setpropcallnative-stub-holdershape");
         MarkObject(trc, &callStub->setter(), "baseline-setpropcallnative-stub-setter");
         break;
       }
+      case ICStub::InstanceOf_Function: {
+        ICInstanceOf_Function *instanceofStub = toInstanceOf_Function();
+        MarkShape(trc, &instanceofStub->shape(), "baseline-instanceof-fun-shape");
+        MarkObject(trc, &instanceofStub->prototypeObject(), "baseline-instanceof-fun-prototype");
+        break;
+      }
       case ICStub::NewArray_Fallback: {
         ICNewArray_Fallback *stub = toNewArray_Fallback();
         MarkObject(trc, &stub->templateObject(), "baseline-newarray-template");
         break;
       }
       case ICStub::NewObject_Fallback: {
         ICNewObject_Fallback *stub = toNewObject_Fallback();
         MarkObject(trc, &stub->templateObject(), "baseline-newobject-template");
@@ -3787,19 +3793,20 @@ ArgumentsGetElemStubExists(ICGetElem_Fal
             continue;
         if (iter->toGetElem_Arguments()->which() == which)
             return true;
     }
     return false;
 }
 
 
-static bool TryAttachNativeGetElemStub(JSContext *cx, HandleScript script, jsbytecode *pc,
-                                       ICGetElem_Fallback *stub, HandleObject obj,
-                                       HandleValue key)
+static bool
+TryAttachNativeGetElemStub(JSContext *cx, HandleScript script, jsbytecode *pc,
+                           ICGetElem_Fallback *stub, HandleObject obj,
+                           HandleValue key)
 {
     // Native-object GetElem stubs can't deal with non-string keys.
     if (!key.isString())
         return true;
 
     // Convert to interned property name.
     RootedId id(cx);
     if (!ValueToId<CanGC>(cx, key, &id))
@@ -5997,26 +6004,28 @@ TryAttachGlobalNameStub(JSContext *cx, H
         if (current == global) {
             JitSpew(JitSpew_BaselineIC, "  Generating GetName(GlobalName/NativeGetter) stub");
             if (UpdateExistingGetPropCallStubs(stub, ICStub::GetProp_CallNative,
                                                global, JS::NullPtr(), getter)) {
                 return true;
             }
             ICGetProp_CallNative::Compiler compiler(cx, monitorStub, current,
                                                     getter, script->pcToOffset(pc),
+                                                    /* outerClass = */ nullptr,
                                                     /* inputDefinitelyObject = */ true);
             newStub = compiler.getStub(compiler.getStubSpace(script));
         } else {
             JitSpew(JitSpew_BaselineIC, "  Generating GetName(GlobalName prototype/NativeGetter) stub");
             if (UpdateExistingGetPropCallStubs(stub, ICStub::GetProp_CallNativePrototype,
                                                current, global, getter)) {
                 return true;
             }
             ICGetProp_CallNativePrototype::Compiler compiler(cx, monitorStub, global, current,
                                                              getter, script->pcToOffset(pc),
+                                                             /* outerClass = */ nullptr,
                                                              /* inputDefinitelyObject = */ true);
             newStub = compiler.getStub(compiler.getStubSpace(script));
         }
 
         if (!newStub)
             return false;
 
         stub->addNewStub(newStub);
@@ -6570,23 +6579,20 @@ TryAttachNativeGetPropStub(JSContext *cx
     RootedShape shape(cx);
     RootedObject holder(cx);
     if (!EffectlesslyLookupProperty(cx, obj, name, &holder, &shape, &isDOMProxy,
                                     &domProxyShadowsResult, &domProxyHasGeneration))
     {
         return false;
     }
 
-    if (!isDOMProxy && !obj->isNative())
-        return true;
-
     bool isCallProp = (JSOp(*pc) == JSOP_CALLPROP);
 
     ICStub *monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
-    if (!isDOMProxy && IsCacheableGetPropReadSlot(obj, holder, shape)) {
+    if (!isDOMProxy && obj->isNative() && IsCacheableGetPropReadSlot(obj, holder, shape)) {
         bool isFixedSlot;
         uint32_t offset;
         GetFixedOrDynamicSlotOffset(&holder->as<NativeObject>(), shape->slot(), &isFixedSlot, &offset);
 
         // Instantiate this property for singleton holders, for use during Ion compilation.
         if (IsIonEnabled(cx))
             types::EnsureTrackPropertyTypes(cx, holder, NameToId(name));
 
@@ -6608,18 +6614,18 @@ TryAttachNativeGetPropStub(JSContext *cx
             StripPreliminaryObjectStubs(cx, stub);
 
         stub->addNewStub(newStub);
         *attached = true;
         return true;
     }
 
     bool isScripted = false;
-    bool cacheableCall = IsCacheableGetPropCall(cx, obj, holder, shape, &isScripted,
-                                                isTemporarilyUnoptimizable, isDOMProxy);
+    bool cacheableCall = obj->isNative() && IsCacheableGetPropCall(cx, obj, holder, shape, &isScripted,
+                                                                   isTemporarilyUnoptimizable);
 
     // Try handling scripted getters.
     if (cacheableCall && isScripted && !isDOMProxy) {
 #if JS_HAS_NO_SUCH_METHOD
         // It's hard to keep the original object alive through a call, and it's unlikely
         // that a getter will be used to generate functions for calling in CALLPROP locations.
         // Just don't attach stubs in that case.
         if (isCallProp)
@@ -6649,27 +6655,76 @@ TryAttachNativeGetPropStub(JSContext *cx
         if (!newStub)
             return false;
 
         stub->addNewStub(newStub);
         *attached = true;
         return true;
     }
 
+    // If it's a shadowed listbase proxy property, attach stub to call Proxy::get instead.
+    if (isDOMProxy && domProxyShadowsResult == Shadows) {
+        MOZ_ASSERT(obj == holder);
+#if JS_HAS_NO_SUCH_METHOD
+        if (isCallProp)
+            return true;
+#endif
+
+        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(DOMProxyProxy) stub");
+        Rooted<ProxyObject*> proxy(cx, &obj->as<ProxyObject>());
+        ICGetProp_DOMProxyShadowed::Compiler compiler(cx, monitorStub, proxy, name,
+                                                      script->pcToOffset(pc));
+        ICStub *newStub = compiler.getStub(compiler.getStubSpace(script));
+        if (!newStub)
+            return false;
+        stub->addNewStub(newStub);
+        *attached = true;
+        return true;
+    }
+
+    const Class *outerClass = nullptr;
+    if (!isDOMProxy && !obj->isNative()) {
+        outerClass = obj->getClass();
+        DebugOnly<JSObject *> outer = obj.get();
+        obj = GetInnerObject(obj);
+        MOZ_ASSERT(script->global().isNative());
+        if (obj != &script->global())
+            return true;
+        // ICGetProp_CallNative*::Compiler::generateStubCode depends on this.
+        MOZ_ASSERT(&((GetProxyDataLayout(outer)->values->privateSlot).toObject()) == obj);
+        if (!EffectlesslyLookupProperty(cx, obj, name, &holder, &shape, &isDOMProxy,
+                                        &domProxyShadowsResult, &domProxyHasGeneration))
+        {
+            return false;
+        }
+        cacheableCall = IsCacheableGetPropCall(cx, obj, holder, shape, &isScripted,
+                                               isTemporarilyUnoptimizable, isDOMProxy);
+    }
+
+    if (!shape || !shape->hasGetterValue() || !shape->getterValue().isObject() ||
+        !shape->getterObject()->is<JSFunction>())
+    {
+        return true;
+    }
+
+    RootedFunction callee(cx, &shape->getterObject()->as<JSFunction>());
+
+    if (outerClass && (!callee->jitInfo() || callee->jitInfo()->needsOuterizedThisObject()))
+        return true;
+
     // Try handling JSNative getters.
     if (cacheableCall && !isScripted) {
 #if JS_HAS_NO_SUCH_METHOD
         // It's unlikely that a getter function will be used to generate functions for calling
         // in CALLPROP locations.  Just don't attach stubs in that case to avoid issues with
         // __noSuchMethod__ handling.
         if (isCallProp)
             return true;
 #endif
 
-        RootedFunction callee(cx, &shape->getterObject()->as<JSFunction>());
         MOZ_ASSERT(callee->isNative());
 
         JitSpew(JitSpew_BaselineIC, "  Generating GetProp(%s%s/NativeGetter %p) stub",
                 isDOMProxy ? "DOMProxyObj" : "NativeObj",
                 isDOMProxy && domProxyHasGeneration ? "WithGeneration" : "",
                 callee->native());
 
         ICStub *newStub = nullptr;
@@ -6692,56 +6747,36 @@ TryAttachNativeGetPropStub(JSContext *cx
         } else if (obj == holder) {
             if (UpdateExistingGetPropCallStubs(stub, ICStub::GetProp_CallNative,
                                                obj, JS::NullPtr(), callee)) {
                 *attached = true;
                 return true;
             }
 
             ICGetProp_CallNative::Compiler compiler(cx, monitorStub, obj, callee,
-                                                    script->pcToOffset(pc));
+                                                    script->pcToOffset(pc), outerClass);
             newStub = compiler.getStub(compiler.getStubSpace(script));
         } else {
             if (UpdateExistingGetPropCallStubs(stub, ICStub::GetProp_CallNativePrototype,
                                                holder, obj, callee)) {
                 *attached = true;
                 return true;
             }
 
             ICGetProp_CallNativePrototype::Compiler compiler(cx, monitorStub, obj, holder, callee,
-                                                             script->pcToOffset(pc));
+                                                             script->pcToOffset(pc), outerClass);
             newStub = compiler.getStub(compiler.getStubSpace(script));
         }
         if (!newStub)
             return false;
         stub->addNewStub(newStub);
         *attached = true;
         return true;
     }
 
-    // If it's a shadowed listbase proxy property, attach stub to call Proxy::get instead.
-    if (isDOMProxy && domProxyShadowsResult == Shadows) {
-        MOZ_ASSERT(obj == holder);
-#if JS_HAS_NO_SUCH_METHOD
-        if (isCallProp)
-            return true;
-#endif
-
-        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(DOMProxyProxy) stub");
-        Rooted<ProxyObject*> proxy(cx, &obj->as<ProxyObject>());
-        ICGetProp_DOMProxyShadowed::Compiler compiler(cx, monitorStub, proxy, name,
-                                                      script->pcToOffset(pc));
-        ICStub *newStub = compiler.getStub(compiler.getStubSpace(script));
-        if (!newStub)
-            return false;
-        stub->addNewStub(newStub);
-        *attached = true;
-        return true;
-    }
-
     return true;
 }
 
 static bool
 TryAttachTypedObjectGetPropStub(JSContext *cx, HandleScript script,
                                 ICGetProp_Fallback *stub, HandlePropertyName name, HandleValue val,
                                 bool *attached)
 {
@@ -7448,22 +7483,34 @@ ICGetProp_CallScripted::Compiler::genera
 
 bool
 ICGetProp_CallNative::Compiler::generateStubCode(MacroAssembler &masm)
 {
     Label failure;
 
     GeneralRegisterSet regs(availableGeneralRegs(0));
     Register obj = InvalidReg;
+
+    MOZ_ASSERT(!(inputDefinitelyObject_ && outerClass_));
     if (inputDefinitelyObject_) {
         obj = R0.scratchReg();
     } else {
         regs.take(R0);
         masm.branchTestObject(Assembler::NotEqual, R0, &failure);
         obj = masm.extractObject(R0, ExtractTemp0);
+        if (outerClass_) {
+            ValueOperand val = regs.takeAnyValue();
+            Register tmp = regs.takeAny();
+            masm.branchTestObjClass(Assembler::NotEqual, obj, tmp, outerClass_, &failure);
+            masm.loadPtr(Address(obj, ProxyDataOffset + offsetof(ProxyDataLayout, values)), tmp);
+            masm.loadValue(Address(tmp, offsetof(ProxyValueArray, privateSlot)), val);
+            obj = masm.extractObject(val, ExtractTemp0);
+            regs.add(val);
+            regs.add(tmp);
+        }
     }
     regs.takeUnchecked(obj);
 
     Register scratch = regs.takeAnyExcluding(BaselineTailCallReg);
 
     masm.loadPtr(Address(BaselineStubReg, ICGetProp_CallNative::offsetOfHolderShape()), scratch);
     masm.branchTestObjShape(Assembler::NotEqual, obj, scratch, &failure);
 
@@ -7496,23 +7543,34 @@ ICGetProp_CallNative::Compiler::generate
 bool
 ICGetProp_CallNativePrototype::Compiler::generateStubCode(MacroAssembler &masm)
 {
     Label failure;
 
     GeneralRegisterSet regs(availableGeneralRegs(0));
     Register objReg = InvalidReg;
 
+    MOZ_ASSERT(!(inputDefinitelyObject_ && outerClass_));
     if (inputDefinitelyObject_) {
         objReg = R0.scratchReg();
     } else {
         regs.take(R0);
         // Guard input is an object and unbox.
         masm.branchTestObject(Assembler::NotEqual, R0, &failure);
         objReg = masm.extractObject(R0, ExtractTemp0);
+        if (outerClass_) {
+            ValueOperand val = regs.takeAnyValue();
+            Register tmp = regs.takeAny();
+            masm.branchTestObjClass(Assembler::NotEqual, objReg, tmp, outerClass_, &failure);
+            masm.loadPtr(Address(objReg, ProxyDataOffset + offsetof(ProxyDataLayout, values)), tmp);
+            masm.loadValue(Address(tmp, offsetof(ProxyValueArray, privateSlot)), val);
+            objReg = masm.extractObject(val, ExtractTemp0);
+            regs.add(val);
+            regs.add(tmp);
+        }
     }
     regs.takeUnchecked(objReg);
 
     Register scratch = regs.takeAnyExcluding(BaselineTailCallReg);
 
     // Shape guard.
     masm.loadPtr(Address(BaselineStubReg, ICGetProp_CallNativePrototype::offsetOfReceiverShape()), scratch);
     masm.branchTestObjShape(Assembler::NotEqual, objReg, scratch, &failure);
@@ -11081,63 +11139,181 @@ ICIteratorClose_Fallback::Compiler::gene
     return tailCallVM(DoIteratorCloseFallbackInfo, masm);
 }
 
 //
 // InstanceOf_Fallback
 //
 
 static bool
-DoInstanceOfFallback(JSContext *cx, ICInstanceOf_Fallback *stub,
-                     HandleValue lhs, HandleValue rhs,
-                     MutableHandleValue res)
+TryAttachInstanceOfStub(JSContext *cx, BaselineFrame *frame, ICInstanceOf_Fallback *stub,
+                        HandleFunction fun, bool *attached)
+{
+    MOZ_ASSERT(!*attached);
+    if (fun->isBoundFunction())
+        return true;
+
+    Shape *shape = fun->lookupPure(cx->names().prototype);
+    if (!shape || !shape->hasSlot() || !shape->hasDefaultGetter())
+        return true;
+
+    uint32_t slot = shape->slot();
+    MOZ_ASSERT(fun->numFixedSlots() == 0, "Stub code relies on this");
+
+    if (!fun->getSlot(slot).isObject())
+        return true;
+
+    JSObject *protoObject = &fun->getSlot(slot).toObject();
+
+    JitSpew(JitSpew_BaselineIC, "  Generating InstanceOf(Function) stub");
+    ICInstanceOf_Function::Compiler compiler(cx, fun->lastProperty(), protoObject, slot);
+    ICStub *newStub = compiler.getStub(compiler.getStubSpace(frame->script()));
+    if (!newStub)
+        return false;
+
+    stub->addNewStub(newStub);
+    *attached = true;
+    return true;
+}
+
+static bool
+DoInstanceOfFallback(JSContext *cx, BaselineFrame *frame, ICInstanceOf_Fallback *stub,
+                     HandleValue lhs, HandleValue rhs, MutableHandleValue res)
 {
     FallbackICSpew(cx, stub, "InstanceOf");
 
     if (!rhs.isObject()) {
         js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS, -1, rhs, NullPtr());
         return false;
     }
 
     RootedObject obj(cx, &rhs.toObject());
-
-    // For functions, keep track of the |prototype| property in type information,
-    // for use during Ion compilation.
-    if (obj->is<JSFunction>() && IsIonEnabled(cx))
-        types::EnsureTrackPropertyTypes(cx, obj, NameToId(cx->names().prototype));
-
     bool cond = false;
     if (!HasInstance(cx, obj, lhs, &cond))
         return false;
 
     res.setBoolean(cond);
-    return true;
-}
-
-typedef bool (*DoInstanceOfFallbackFn)(JSContext *, ICInstanceOf_Fallback *, HandleValue, HandleValue,
-                                       MutableHandleValue);
+
+    if (!obj->is<JSFunction>()) {
+        stub->noteUnoptimizableAccess();
+        return true;
+    }
+
+    // For functions, keep track of the |prototype| property in type information,
+    // for use during Ion compilation.
+    types::EnsureTrackPropertyTypes(cx, obj, NameToId(cx->names().prototype));
+
+    if (stub->numOptimizedStubs() >= ICInstanceOf_Fallback::MAX_OPTIMIZED_STUBS)
+        return true;
+
+    RootedFunction fun(cx, &obj->as<JSFunction>());
+    bool attached = false;
+    if (!TryAttachInstanceOfStub(cx, frame, stub, fun, &attached))
+        return false;
+    if (!attached)
+        stub->noteUnoptimizableAccess();
+    return true;
+}
+
+typedef bool (*DoInstanceOfFallbackFn)(JSContext *, BaselineFrame *, ICInstanceOf_Fallback *,
+                                       HandleValue, HandleValue, MutableHandleValue);
 static const VMFunction DoInstanceOfFallbackInfo =
     FunctionInfo<DoInstanceOfFallbackFn>(DoInstanceOfFallback, TailCall, PopValues(2));
 
 bool
 ICInstanceOf_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
 {
     EmitRestoreTailCallReg(masm);
 
     // Sync stack for the decompiler.
     masm.pushValue(R0);
     masm.pushValue(R1);
 
     masm.pushValue(R1);
     masm.pushValue(R0);
     masm.push(BaselineStubReg);
+    masm.pushBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
 
     return tailCallVM(DoInstanceOfFallbackInfo, masm);
 }
 
+bool
+ICInstanceOf_Function::Compiler::generateStubCode(MacroAssembler &masm)
+{
+    Label failure;
+
+    // Ensure RHS is an object.
+    masm.branchTestObject(Assembler::NotEqual, R1, &failure);
+    Register rhsObj = masm.extractObject(R1, ExtractTemp0);
+
+    // Allow using R1's type register as scratch. We have to restore it when
+    // we want to jump to the next stub.
+    Label failureRestoreR1;
+    GeneralRegisterSet regs(availableGeneralRegs(1));
+    regs.takeUnchecked(rhsObj);
+
+    Register scratch1 = regs.takeAny();
+    Register scratch2 = regs.takeAny();
+
+    // Shape guard.
+    masm.loadPtr(Address(BaselineStubReg, ICInstanceOf_Function::offsetOfShape()), scratch1);
+    masm.branchTestObjShape(Assembler::NotEqual, rhsObj, scratch1, &failureRestoreR1);
+
+    // Guard on the .prototype object.
+    masm.loadPtr(Address(rhsObj, NativeObject::offsetOfSlots()), scratch1);
+    masm.load32(Address(BaselineStubReg, ICInstanceOf_Function::offsetOfSlot()), scratch2);
+    BaseValueIndex prototypeSlot(scratch1, scratch2);
+    masm.branchTestObject(Assembler::NotEqual, prototypeSlot, &failureRestoreR1);
+    masm.unboxObject(prototypeSlot, scratch1);
+    masm.branchPtr(Assembler::NotEqual,
+                   Address(BaselineStubReg, ICInstanceOf_Function::offsetOfPrototypeObject()),
+                   scratch1, &failureRestoreR1);
+
+    // If LHS is a primitive, return false.
+    Label returnFalse, returnTrue;
+    masm.branchTestObject(Assembler::NotEqual, R0, &returnFalse);
+
+    // LHS is an object. Load its proto.
+    masm.unboxObject(R0, scratch2);
+    masm.loadObjProto(scratch2, scratch2);
+
+    {
+        // Walk the proto chain until we either reach the target object,
+        // nullptr or LazyProto.
+        Label loop;
+        masm.bind(&loop);
+
+        masm.branchPtr(Assembler::Equal, scratch2, scratch1, &returnTrue);
+        masm.branchTestPtr(Assembler::Zero, scratch2, scratch2, &returnFalse);
+
+        MOZ_ASSERT(uintptr_t(TaggedProto::LazyProto) == 1);
+        masm.branchPtr(Assembler::Equal, scratch2, ImmWord(1), &failureRestoreR1);
+
+        masm.loadObjProto(scratch2, scratch2);
+        masm.jump(&loop);
+    }
+
+    EmitReturnFromIC(masm);
+
+    masm.bind(&returnFalse);
+    masm.moveValue(BooleanValue(false), R0);
+    EmitReturnFromIC(masm);
+
+    masm.bind(&returnTrue);
+    masm.moveValue(BooleanValue(true), R0);
+    EmitReturnFromIC(masm);
+
+    masm.bind(&failureRestoreR1);
+    masm.tagValue(JSVAL_TYPE_OBJECT, rhsObj, R1);
+
+    masm.bind(&failure);
+    EmitStubGuardFailure(masm);
+    return true;
+}
+
 //
 // TypeOf_Fallback
 //
 
 static bool
 DoTypeOfFallback(JSContext *cx, BaselineFrame *frame, ICTypeOf_Fallback *stub, HandleValue val,
                  MutableHandleValue res)
 {
@@ -11621,16 +11797,24 @@ ICGetPropCallPrototypeGetter::ICGetPropC
                                                            HandleShape holderShape,
                                                            HandleFunction getter, uint32_t pcOffset)
   : ICGetPropCallGetter(kind, stubCode, firstMonitorStub, holder, holderShape, getter, pcOffset),
     receiverShape_(receiverShape)
 {
     MOZ_ASSERT(kind == ICStub::GetProp_CallScripted || kind == ICStub::GetProp_CallNativePrototype);
 }
 
+ICInstanceOf_Function::ICInstanceOf_Function(JitCode *stubCode, Shape *shape,
+                                             JSObject *prototypeObj, uint32_t slot)
+  : ICStub(InstanceOf_Function, stubCode),
+    shape_(shape),
+    prototypeObj_(prototypeObj),
+    slot_(slot)
+{ }
+
 /* static */ ICGetProp_CallScripted *
 ICGetProp_CallScripted::Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub,
                               ICGetProp_CallScripted &other)
 {
     RootedShape receiverShape(cx, other.receiverShape_);
     RootedObject holder(cx, other.holder_);
     RootedShape holderShape(cx, other.holderShape_);
     RootedFunction getter(cx, other.getter_);
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -447,16 +447,17 @@ class ICEntry
     _(TableSwitch)              \
                                 \
     _(IteratorNew_Fallback)     \
     _(IteratorMore_Fallback)    \
     _(IteratorMore_Native)      \
     _(IteratorClose_Fallback)   \
                                 \
     _(InstanceOf_Fallback)      \
+    _(InstanceOf_Function)      \
                                 \
     _(TypeOf_Fallback)          \
     _(TypeOf_Typed)             \
                                 \
     _(Rest_Fallback)            \
                                 \
     _(RetSub_Fallback)          \
     _(RetSub_Resume)
@@ -4731,25 +4732,33 @@ class ICGetPropCallGetter : public ICMon
     }
 
     class Compiler : public ICStubCompiler {
       protected:
         ICStub *firstMonitorStub_;
         RootedObject holder_;
         RootedFunction getter_;
         uint32_t pcOffset_;
+        const Class *outerClass_;
+
+        virtual int32_t getKey() const {
+            return static_cast<int32_t>(kind) |
+                   (static_cast<int32_t>(!!outerClass_) << 16);
+        }
 
       public:
         Compiler(JSContext *cx, ICStub::Kind kind, ICStub *firstMonitorStub,
-                 HandleObject holder, HandleFunction getter, uint32_t pcOffset)
+                 HandleObject holder, HandleFunction getter, uint32_t pcOffset,
+                 const Class *outerClass)
           : ICStubCompiler(cx, kind),
             firstMonitorStub_(firstMonitorStub),
             holder_(cx, holder),
             getter_(cx, getter),
-            pcOffset_(pcOffset)
+            pcOffset_(pcOffset),
+            outerClass_(outerClass)
         {
             MOZ_ASSERT(kind == ICStub::GetProp_CallScripted ||
                        kind == ICStub::GetProp_CallNative ||
                        kind == ICStub::GetProp_CallNativePrototype);
         }
     };
 };
 
@@ -4778,18 +4787,20 @@ class ICGetPropCallPrototypeGetter : pub
     }
 
     class Compiler : public ICGetPropCallGetter::Compiler {
       protected:
         RootedObject receiver_;
 
       public:
         Compiler(JSContext *cx, ICStub::Kind kind, ICStub *firstMonitorStub,
-                 HandleObject obj, HandleObject holder, HandleFunction getter, uint32_t pcOffset)
-          : ICGetPropCallGetter::Compiler(cx, kind, firstMonitorStub, holder, getter, pcOffset),
+                 HandleObject obj, HandleObject holder, HandleFunction getter, uint32_t pcOffset,
+                 const Class *outerClass)
+          : ICGetPropCallGetter::Compiler(cx, kind, firstMonitorStub, holder, getter, pcOffset,
+                                          outerClass),
             receiver_(cx, obj)
         {
             MOZ_ASSERT(kind == ICStub::GetProp_CallScripted ||
                        kind == ICStub::GetProp_CallNativePrototype);
         }
     };
 };
 
@@ -4827,17 +4838,17 @@ class ICGetProp_CallScripted : public IC
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         Compiler(JSContext *cx, ICStub *firstMonitorStub, HandleObject obj,
                  HandleObject holder, HandleFunction getter, uint32_t pcOffset)
           : ICGetPropCallPrototypeGetter::Compiler(cx, ICStub::GetProp_CallScripted,
                                                    firstMonitorStub, obj, holder,
-                                                   getter, pcOffset)
+                                                   getter, pcOffset, /* outerClass = */ nullptr)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
             RootedShape receiverShape(cx, receiver_->lastProperty());
             RootedShape holderShape(cx, holder_->lastProperty());
             return ICGetProp_CallScripted::New(space, getStubCode(), firstMonitorStub_, receiverShape,
                                                holder_, holderShape, getter_, pcOffset_);
         }
@@ -4880,19 +4891,20 @@ class ICGetProp_CallNative : public ICGe
 
         virtual int32_t getKey() const {
             return static_cast<int32_t>(kind) |
                    (static_cast<int32_t>(inputDefinitelyObject_) << 16);
         }
 
       public:
         Compiler(JSContext *cx, ICStub *firstMonitorStub, HandleObject obj,
-                 HandleFunction getter, uint32_t pcOffset, bool inputDefinitelyObject = false)
+                 HandleFunction getter, uint32_t pcOffset, const Class *outerClass,
+                 bool inputDefinitelyObject = false)
           : ICGetPropCallGetter::Compiler(cx, ICStub::GetProp_CallNative, firstMonitorStub,
-                                          obj, getter, pcOffset),
+                                          obj, getter, pcOffset, outerClass),
             inputDefinitelyObject_(inputDefinitelyObject)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
             RootedShape shape(cx, holder_->lastProperty());
             return ICGetProp_CallNative::New(space, getStubCode(), firstMonitorStub_, holder_,
                                              shape, getter_, pcOffset_);
         }
@@ -4937,20 +4949,20 @@ class ICGetProp_CallNativePrototype : pu
         virtual int32_t getKey() const {
             return static_cast<int32_t>(kind) |
                    (static_cast<int32_t>(inputDefinitelyObject_) << 16);
         }
 
       public:
         Compiler(JSContext *cx, ICStub *firstMonitorStub, HandleObject obj,
                  HandleObject holder, HandleFunction getter, uint32_t pcOffset,
-                 bool inputDefinitelyObject = false)
+                 const Class *outerClass, bool inputDefinitelyObject = false)
           : ICGetPropCallPrototypeGetter::Compiler(cx, ICStub::GetProp_CallNativePrototype,
                                                    firstMonitorStub, obj, holder,
-                                                   getter, pcOffset),
+                                                   getter, pcOffset, outerClass),
             inputDefinitelyObject_(inputDefinitelyObject)
         {}
 
         ICStub *getStub(ICStubSpace *space) {
             RootedShape receiverShape(cx, receiver_->lastProperty());
             RootedShape holderShape(cx, holder_->lastProperty());
             return ICGetProp_CallNativePrototype::New(space, getStubCode(), firstMonitorStub_, receiverShape,
                                                       holder_, holderShape, getter_, pcOffset_);
@@ -6623,38 +6635,109 @@ class ICIteratorClose_Fallback : public 
 class ICInstanceOf_Fallback : public ICFallbackStub
 {
     friend class ICStubSpace;
 
     explicit ICInstanceOf_Fallback(JitCode *stubCode)
       : ICFallbackStub(ICStub::InstanceOf_Fallback, stubCode)
     { }
 
-  public:
+    static const uint16_t UNOPTIMIZABLE_ACCESS_BIT = 0x1;
+
+  public:
+    static const uint32_t MAX_OPTIMIZED_STUBS = 4;
+
     static inline ICInstanceOf_Fallback *New(ICStubSpace *space, JitCode *code) {
         if (!code)
             return nullptr;
         return space->allocate<ICInstanceOf_Fallback>(code);
     }
 
+    void noteUnoptimizableAccess() {
+        extra_ |= UNOPTIMIZABLE_ACCESS_BIT;
+    }
+    bool hadUnoptimizableAccess() const {
+        return extra_ & UNOPTIMIZABLE_ACCESS_BIT;
+    }
+
     class Compiler : public ICStubCompiler {
       protected:
         bool generateStubCode(MacroAssembler &masm);
 
       public:
         explicit Compiler(JSContext *cx)
           : ICStubCompiler(cx, ICStub::InstanceOf_Fallback)
         { }
 
         ICStub *getStub(ICStubSpace *space) {
             return ICInstanceOf_Fallback::New(space, getStubCode());
         }
     };
 };
 
+class ICInstanceOf_Function : public ICStub
+{
+    friend class ICStubSpace;
+
+    HeapPtrShape shape_;
+    HeapPtrObject prototypeObj_;
+    uint32_t slot_;
+
+    ICInstanceOf_Function(JitCode *stubCode, Shape *shape, JSObject *prototypeObj, uint32_t slot);
+
+  public:
+    static inline ICInstanceOf_Function *New(ICStubSpace *space, JitCode *code, Shape *shape,
+                                             JSObject *prototypeObj, uint32_t slot)
+    {
+        if (!code)
+            return nullptr;
+        return space->allocate<ICInstanceOf_Function>(code, shape, prototypeObj, slot);
+    }
+
+    HeapPtrShape &shape() {
+        return shape_;
+    }
+    HeapPtrObject &prototypeObject() {
+        return prototypeObj_;
+    }
+    uint32_t slot() const {
+        return slot_;
+    }
+    static size_t offsetOfShape() {
+        return offsetof(ICInstanceOf_Function, shape_);
+    }
+    static size_t offsetOfPrototypeObject() {
+        return offsetof(ICInstanceOf_Function, prototypeObj_);
+    }
+    static size_t offsetOfSlot() {
+        return offsetof(ICInstanceOf_Function, slot_);
+    }
+
+    class Compiler : public ICStubCompiler {
+        RootedShape shape_;
+        RootedObject prototypeObj_;
+        uint32_t slot_;
+
+      protected:
+        bool generateStubCode(MacroAssembler &masm);
+
+      public:
+        Compiler(JSContext *cx, Shape *shape, JSObject *prototypeObj, uint32_t slot)
+          : ICStubCompiler(cx, ICStub::InstanceOf_Function),
+            shape_(cx, shape),
+            prototypeObj_(cx, prototypeObj),
+            slot_(slot)
+        {}
+
+        ICStub *getStub(ICStubSpace *space) {
+            return ICInstanceOf_Function::New(space, getStubCode(), shape_, prototypeObj_, slot_);
+        }
+    };
+};
+
 // TypeOf
 //      JSOP_TYPEOF
 //      JSOP_TYPEOFEXPR
 class ICTypeOf_Fallback : public ICFallbackStub
 {
     friend class ICStubSpace;
 
     explicit ICTypeOf_Fallback(JitCode *stubCode)
--- a/js/src/jit/BaselineInspector.cpp
+++ b/js/src/jit/BaselineInspector.cpp
@@ -578,8 +578,38 @@ BaselineInspector::commonSetPropFunction
             // We have an unoptimizable access, so don't try to optimize.
             return nullptr;
         }
     }
     *lastProperty = holderShape;
     *commonSetter = setter;
     return holder;
 }
+
+bool
+BaselineInspector::instanceOfData(jsbytecode *pc, Shape **shape, uint32_t *slot,
+                                  JSObject **prototypeObject)
+{
+    MOZ_ASSERT(*pc == JSOP_INSTANCEOF);
+
+    if (!hasBaselineScript())
+        return false;
+
+    const ICEntry &entry = icEntryFromPC(pc);
+
+    ICStub *stub = entry.firstStub();
+    if (!stub->isInstanceOf_Function() ||
+        !stub->next()->isInstanceOf_Fallback() ||
+        stub->next()->toInstanceOf_Fallback()->hadUnoptimizableAccess())
+    {
+        return false;
+    }
+
+    ICInstanceOf_Function *optStub = stub->toInstanceOf_Function();
+    *shape = optStub->shape();
+    *prototypeObject = optStub->prototypeObject();
+    *slot = optStub->slot();
+
+    if (IsInsideNursery(*prototypeObject))
+        return false;
+
+    return true;
+}
--- a/js/src/jit/BaselineInspector.h
+++ b/js/src/jit/BaselineInspector.h
@@ -114,14 +114,16 @@ class BaselineInspector
     JSObject *getTemplateObjectForClassHook(jsbytecode *pc, const Class *clasp);
 
     DeclEnvObject *templateDeclEnvObject();
     CallObject *templateCallObject();
 
     JSObject *commonGetPropFunction(jsbytecode *pc, Shape **lastProperty, JSFunction **commonGetter,
                                     Shape **globalShape);
     JSObject *commonSetPropFunction(jsbytecode *pc, Shape **lastProperty, JSFunction **commonSetter);
+
+    bool instanceOfData(jsbytecode *pc, Shape **shape, uint32_t *slot, JSObject **prototypeObject);
 };
 
 } // namespace jit
 } // namespace js
 
 #endif /* jit_BaselineInspector_h */
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -10081,28 +10081,26 @@ IonBuilder::getPropTryInnerize(bool *emi
 
     MDefinition *inner = tryInnerizeWindow(obj);
     if (inner == obj)
         return true;
 
     // Note: the Baseline ICs don't know about this optimization, so it's
     // possible the global property's HeapTypeSet has not been initialized
     // yet. In this case we'll fall back to getPropTryCache for now.
-    //
-    // Also note that we don't call getPropTryCommonGetter below, because
-    // (a) it requires a Baseline getter stub, which we don't have for outer
-    // window proxies and (b) we have to be careful not to pass the inner
-    // object to scripted getters etc. See bug 1007631.
 
     if (!getPropTryConstant(emitted, inner, name, types) || *emitted)
         return *emitted;
 
     if (!getStaticName(&script()->global(), name, emitted) || *emitted)
         return *emitted;
 
+    if (!getPropTryCommonGetter(emitted, inner, name, types) || *emitted)
+        return *emitted;
+
     // Passing the inner object to GetProperty IC is safe, see the
     // needsOuterizedThisObject check in IsCacheableGetPropCallNative.
     BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(),
                                                        inner, name, types);
     if (!getPropTryCache(emitted, inner, name, barrier, types) || *emitted)
         return *emitted;
 
     MOZ_ASSERT(*emitted == false);
@@ -11284,16 +11282,46 @@ IonBuilder::jsop_instanceof()
         MInstanceOf *ins = MInstanceOf::New(alloc(), obj, protoObject);
 
         current->add(ins);
         current->push(ins);
 
         return resumeAfter(ins);
     } while (false);
 
+    // Try to inline a fast path based on Baseline ICs.
+    do {
+        Shape *shape;
+        uint32_t slot;
+        JSObject *protoObject;
+        if (!inspector->instanceOfData(pc, &shape, &slot, &protoObject))
+            break;
+
+        // Shape guard.
+        rhs = addShapeGuard(rhs, shape, Bailout_ShapeGuard);
+
+        // Guard .prototype == protoObject.
+        MOZ_ASSERT(shape->numFixedSlots() == 0, "Must be a dynamic slot");
+        MSlots *slots = MSlots::New(alloc(), rhs);
+        current->add(slots);
+        MLoadSlot *prototype = MLoadSlot::New(alloc(), slots, slot);
+        current->add(prototype);
+        MGuardObjectIdentity *guard = MGuardObjectIdentity::New(alloc(), prototype, protoObject,
+                                                                /* bailOnEquality = */ false);
+        current->add(guard);
+
+        if (tryFoldInstanceOf(obj, protoObject))
+            return true;
+
+        MInstanceOf *ins = MInstanceOf::New(alloc(), obj, protoObject);
+        current->add(ins);
+        current->push(ins);
+        return resumeAfter(ins);
+    } while (false);
+
     MCallInstanceOf *ins = MCallInstanceOf::New(alloc(), obj, rhs);
 
     current->add(ins);
     current->push(ins);
 
     return resumeAfter(ins);
 }
 
--- a/js/src/jit/LIR-Common.h
+++ b/js/src/jit/LIR-Common.h
@@ -493,18 +493,18 @@ class LSimdSelect : public LInstructionH
         return getOperand(1);
     }
     const LAllocation *rhs() {
         return getOperand(2);
     }
     const LDefinition *temp() {
         return getTemp(0);
     }
-    MSimdTernaryBitwise::Operation operation() const {
-        return mir_->toSimdTernaryBitwise()->operation();
+    MSimdSelect *mir() const {
+        return mir_->toSimdSelect();
     }
 };
 
 // Constant 32-bit integer.
 class LInteger : public LInstructionHelper<1, 0, 0>
 {
     int32_t i32_;
 
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -2016,52 +2016,59 @@ class MSimdShift : public MBinaryInstruc
         if (!binaryCongruentTo(ins))
             return false;
         return operation_ == ins->toSimdShift()->operation();
     }
 
     ALLOW_CLONE(MSimdShift)
 };
 
-class MSimdTernaryBitwise : public MTernaryInstruction
-{
-  public:
-    enum Operation {
-        select
-    };
-
-  private:
-    Operation operation_;
-
-    MSimdTernaryBitwise(MDefinition *mask, MDefinition *lhs, MDefinition *rhs, Operation op, MIRType type)
-      : MTernaryInstruction(mask, lhs, rhs), operation_(op)
+class MSimdSelect : public MTernaryInstruction
+{
+    bool isElementWise_;
+
+    MSimdSelect(MDefinition *mask, MDefinition *lhs, MDefinition *rhs, MIRType type,
+                bool isElementWise)
+      : MTernaryInstruction(mask, lhs, rhs), isElementWise_(isElementWise)
     {
         MOZ_ASSERT(IsSimdType(type));
         MOZ_ASSERT(mask->type() == MIRType_Int32x4);
         MOZ_ASSERT(lhs->type() == rhs->type());
         MOZ_ASSERT(lhs->type() == type);
         setResultType(type);
         setMovable();
     }
 
   public:
-    INSTRUCTION_HEADER(SimdTernaryBitwise);
-    static MSimdTernaryBitwise *NewAsmJS(TempAllocator &alloc, MDefinition *mask, MDefinition *lhs,
-                                         MDefinition *rhs, Operation op, MIRType t)
-    {
-        return new(alloc) MSimdTernaryBitwise(mask, lhs, rhs, op, t);
-    }
-
-    AliasSet getAliasSet() const {
-        return AliasSet::None();
-    }
-
-    Operation operation() const { return operation_; }
-
-    ALLOW_CLONE(MSimdTernaryBitwise)
+    INSTRUCTION_HEADER(SimdSelect);
+    static MSimdSelect *NewAsmJS(TempAllocator &alloc, MDefinition *mask, MDefinition *lhs,
+                                 MDefinition *rhs, MIRType t, bool isElementWise)
+    {
+        return new(alloc) MSimdSelect(mask, lhs, rhs, t, isElementWise);
+    }
+
+    MDefinition *mask() const {
+        return getOperand(0);
+    }
+
+    AliasSet getAliasSet() const {
+        return AliasSet::None();
+    }
+
+    bool isElementWise() const {
+        return isElementWise_;
+    }
+
+    bool congruentTo(const MDefinition *ins) const {
+        if (!congruentIfOperandsEqual(ins))
+            return false;
+        return isElementWise_ == ins->toSimdSelect()->isElementWise();
+    }
+
+    ALLOW_CLONE(MSimdSelect)
 };
 
 // Deep clone a constant JSObject.
 class MCloneLiteral
   : public MUnaryInstruction,
     public ObjectPolicy<0>::Data
 {
   protected:
--- a/js/src/jit/MOpcodes.h
+++ b/js/src/jit/MOpcodes.h
@@ -22,17 +22,17 @@ namespace jit {
     _(SimdSignMask)                                                         \
     _(SimdSwizzle)                                                          \
     _(SimdShuffle)                                                          \
     _(SimdUnaryArith)                                                       \
     _(SimdBinaryComp)                                                       \
     _(SimdBinaryArith)                                                      \
     _(SimdBinaryBitwise)                                                    \
     _(SimdShift)                                                            \
-    _(SimdTernaryBitwise)                                                   \
+    _(SimdSelect)                                                           \
     _(CloneLiteral)                                                         \
     _(Parameter)                                                            \
     _(Callee)                                                               \
     _(IsConstructing)                                                       \
     _(TableSwitch)                                                          \
     _(Goto)                                                                 \
     _(Test)                                                                 \
     _(GotoWithFake)                                                         \
--- a/js/src/jit/ParallelSafetyAnalysis.cpp
+++ b/js/src/jit/ParallelSafetyAnalysis.cpp
@@ -116,17 +116,17 @@ class ParallelSafetyVisitor : public MDe
     SAFE_OP(SimdSignMask)
     SAFE_OP(SimdSwizzle)
     SAFE_OP(SimdShuffle)
     SAFE_OP(SimdUnaryArith)
     SAFE_OP(SimdBinaryComp)
     SAFE_OP(SimdBinaryArith)
     SAFE_OP(SimdBinaryBitwise)
     SAFE_OP(SimdShift)
-    SAFE_OP(SimdTernaryBitwise)
+    SAFE_OP(SimdSelect)
     UNSAFE_OP(CloneLiteral)
     SAFE_OP(Parameter)
     SAFE_OP(Callee)
     SAFE_OP(IsConstructing)
     SAFE_OP(TableSwitch)
     SAFE_OP(Goto)
     SAFE_OP(Test)
     SAFE_OP(GotoWithFake)
--- a/js/src/jit/RangeAnalysis.cpp
+++ b/js/src/jit/RangeAnalysis.cpp
@@ -150,18 +150,21 @@ RangeAnalysis::addBetaNodes()
         BranchDirection branch_dir;
         MTest *test = block->immediateDominatorBranch(&branch_dir);
 
         if (!test || !test->getOperand(0)->isCompare())
             continue;
 
         MCompare *compare = test->getOperand(0)->toCompare();
 
-        if (compare->compareType() == MCompare::Compare_Unknown)
+        if (compare->compareType() == MCompare::Compare_Unknown ||
+            compare->compareType() == MCompare::Compare_Value)
+        {
             continue;
+        }
 
         // TODO: support unsigned comparisons
         if (compare->compareType() == MCompare::Compare_UInt32)
             continue;
 
         MDefinition *left = compare->getOperand(0);
         MDefinition *right = compare->getOperand(1);
         double bound;
@@ -2201,25 +2204,27 @@ RangeAnalysis::analyze()
 
             // Would have been nice to implement this using collectRangeInfoPreTrunc()
             // methods but it needs the minAsmJSHeapLength().
             if (mir->compilingAsmJS()) {
                 uint32_t minHeapLength = mir->minAsmJSHeapLength();
                 if (iter->isAsmJSLoadHeap()) {
                     MAsmJSLoadHeap *ins = iter->toAsmJSLoadHeap();
                     Range *range = ins->ptr()->range();
+                    uint32_t elemSize = TypedArrayElemSize(ins->viewType());
                     if (range && range->hasInt32LowerBound() && range->lower() >= 0 &&
-                        range->hasInt32UpperBound() && (uint32_t) range->upper() < minHeapLength) {
+                        range->hasInt32UpperBound() && uint32_t(range->upper()) + elemSize < minHeapLength) {
                         ins->removeBoundsCheck();
                     }
                 } else if (iter->isAsmJSStoreHeap()) {
                     MAsmJSStoreHeap *ins = iter->toAsmJSStoreHeap();
                     Range *range = ins->ptr()->range();
+                    uint32_t elemSize = TypedArrayElemSize(ins->viewType());
                     if (range && range->hasInt32LowerBound() && range->lower() >= 0 &&
-                        range->hasInt32UpperBound() && (uint32_t) range->upper() < minHeapLength) {
+                        range->hasInt32UpperBound() && uint32_t(range->upper()) + elemSize < minHeapLength) {
                         ins->removeBoundsCheck();
                     }
                 }
             }
         }
     }
 
     return true;
--- a/js/src/jit/arm/Lowering-arm.cpp
+++ b/js/src/jit/arm/Lowering-arm.cpp
@@ -558,17 +558,17 @@ LIRGeneratorARM::visitForkJoinGetSlice(M
 
 void
 LIRGeneratorARM::visitSimdBinaryArith(MSimdBinaryArith *ins)
 {
     MOZ_CRASH("NYI");
 }
 
 void
-LIRGeneratorARM::visitSimdTernaryBitwise(MSimdTernaryBitwise *ins)
+LIRGeneratorARM::visitSimdSelect(MSimdSelect *ins)
 {
     MOZ_CRASH("NYI");
 }
 
 void
 LIRGeneratorARM::visitSimdSplatX4(MSimdSplatX4 *ins)
 {
     MOZ_CRASH("NYI");
--- a/js/src/jit/arm/Lowering-arm.h
+++ b/js/src/jit/arm/Lowering-arm.h
@@ -103,17 +103,17 @@ class LIRGeneratorARM : public LIRGenera
     void visitAsmJSLoadHeap(MAsmJSLoadHeap *ins);
     void visitAsmJSStoreHeap(MAsmJSStoreHeap *ins);
     void visitAsmJSLoadFuncPtr(MAsmJSLoadFuncPtr *ins);
     void visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap *ins);
     void visitAsmJSAtomicBinopHeap(MAsmJSAtomicBinopHeap *ins);
     void visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic *ins);
     void visitForkJoinGetSlice(MForkJoinGetSlice *ins);
     void visitSimdBinaryArith(MSimdBinaryArith *ins);
-    void visitSimdTernaryBitwise(MSimdTernaryBitwise *ins);
+    void visitSimdSelect(MSimdSelect *ins);
     void visitSimdSplatX4(MSimdSplatX4 *ins);
     void visitSimdValueX4(MSimdValueX4 *ins);
     void visitCompareExchangeTypedArrayElement(MCompareExchangeTypedArrayElement *ins);
     void visitAtomicTypedArrayElementBinop(MAtomicTypedArrayElementBinop *ins);
     void visitSubstr(MSubstr *ins);
 };
 
 typedef LIRGeneratorARM LIRGeneratorSpecific;
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -3212,16 +3212,23 @@ MacroAssemblerARMCompat::unboxNonDouble(
 
 void
 MacroAssemblerARMCompat::unboxNonDouble(const Address &src, Register dest)
 {
     ma_ldr(payloadOf(src), dest);
 }
 
 void
+MacroAssemblerARMCompat::unboxNonDouble(const BaseIndex &src, Register dest)
+{
+    ma_alu(src.base, lsl(src.index, src.scale), ScratchRegister, OpAdd);
+    ma_ldr(Address(ScratchRegister, src.offset), dest);
+}
+
+void
 MacroAssemblerARMCompat::unboxDouble(const ValueOperand &operand, FloatRegister dest)
 {
     MOZ_ASSERT(dest.isDouble());
     as_vxfer(operand.payloadReg(), operand.typeReg(),
              VFPRegister(dest), CoreToFloat);
 }
 
 void
--- a/js/src/jit/arm/MacroAssembler-arm.h
+++ b/js/src/jit/arm/MacroAssembler-arm.h
@@ -795,26 +795,28 @@ class MacroAssemblerARMCompat : public M
 
     void branchTestValue(Condition cond, const ValueOperand &value, const Value &v, Label *label);
     void branchTestValue(Condition cond, const Address &valaddr, const ValueOperand &value,
                          Label *label);
 
     // Unboxing code.
     void unboxNonDouble(const ValueOperand &operand, Register dest);
     void unboxNonDouble(const Address &src, Register dest);
+    void unboxNonDouble(const BaseIndex &src, Register dest);
     void unboxInt32(const ValueOperand &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxInt32(const Address &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxBoolean(const ValueOperand &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxBoolean(const Address &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxString(const ValueOperand &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxString(const Address &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxSymbol(const ValueOperand &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxSymbol(const Address &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxObject(const ValueOperand &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxObject(const Address &src, Register dest) { unboxNonDouble(src, dest); }
+    void unboxObject(const BaseIndex &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxDouble(const ValueOperand &src, FloatRegister dest);
     void unboxDouble(const Address &src, FloatRegister dest);
     void unboxValue(const ValueOperand &src, AnyRegister dest);
     void unboxPrivate(const ValueOperand &src, Register dest);
 
     void notBoolean(const ValueOperand &val) {
         ma_eor(Imm32(1), val.payloadReg());
     }
--- a/js/src/jit/mips/Lowering-mips.cpp
+++ b/js/src/jit/mips/Lowering-mips.cpp
@@ -548,17 +548,17 @@ LIRGeneratorMIPS::visitForkJoinGetSlice(
 
 void
 LIRGeneratorMIPS::visitSimdBinaryArith(MSimdBinaryArith *ins)
 {
     MOZ_CRASH("NYI");
 }
 
 void
-LIRGeneratorMIPS::visitSimdTernaryBitwise(MSimdTernaryBitwise *ins)
+LIRGeneratorMIPS::visitSimdSelect(MSimdSelect *ins)
 {
     MOZ_CRASH("NYI");
 }
 
 void
 LIRGeneratorMIPS::visitSimdSplatX4(MSimdSplatX4 *ins)
 {
     MOZ_CRASH("NYI");
--- a/js/src/jit/mips/Lowering-mips.h
+++ b/js/src/jit/mips/Lowering-mips.h
@@ -103,17 +103,17 @@ class LIRGeneratorMIPS : public LIRGener
     void visitAsmJSLoadHeap(MAsmJSLoadHeap *ins);
     void visitAsmJSStoreHeap(MAsmJSStoreHeap *ins);
     void visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap *ins);
     void visitAsmJSAtomicBinopHeap(MAsmJSAtomicBinopHeap *ins);
     void visitAsmJSLoadFuncPtr(MAsmJSLoadFuncPtr *ins);
     void visitStoreTypedArrayElementStatic(MStoreTypedArrayElementStatic *ins);
     void visitForkJoinGetSlice(MForkJoinGetSlice *ins);
     void visitSimdBinaryArith(MSimdBinaryArith *ins);
-    void visitSimdTernaryBitwise(MSimdTernaryBitwise *ins);
+    void visitSimdSelect(MSimdSelect *ins);
     void visitSimdSplatX4(MSimdSplatX4 *ins);
     void visitSimdValueX4(MSimdValueX4 *ins);
     void visitCompareExchangeTypedArrayElement(MCompareExchangeTypedArrayElement *ins);
     void visitAtomicTypedArrayElementBinop(MAtomicTypedArrayElementBinop *ins);
     void visitSubstr(MSubstr *ins);
 };
 
 typedef LIRGeneratorMIPS LIRGeneratorSpecific;
--- a/js/src/jit/none/Lowering-none.h
+++ b/js/src/jit/none/Lowering-none.h
@@ -81,17 +81,17 @@ class LIRGeneratorNone : public LIRGener
     void visitForkJoinGetSlice(MForkJoinGetSlice *ins) { MOZ_CRASH(); }
     void visitAtomicTypedArrayElementBinop(MAtomicTypedArrayElementBinop *ins) { MOZ_CRASH(); }
     void visitCompareExchangeTypedArrayElement(MCompareExchangeTypedArrayElement *ins) { MOZ_CRASH(); }
     void visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap *ins) { MOZ_CRASH(); }
     void visitAsmJSAtomicBinopHeap(MAsmJSAtomicBinopHeap *ins) { MOZ_CRASH(); }
 
     LTableSwitch *newLTableSwitch(LAllocation, LDefinition, MTableSwitch *) { MOZ_CRASH(); }
     LTableSwitchV *newLTableSwitchV(MTableSwitch *) { MOZ_CRASH(); }
-    void visitSimdTernaryBitwise(MSimdTernaryBitwise *ins) { MOZ_CRASH(); }
+    void visitSimdSelect(MSimdSelect *ins) { MOZ_CRASH(); }
     void visitSimdSplatX4(MSimdSplatX4 *ins) { MOZ_CRASH(); }
     void visitSimdValueX4(MSimdValueX4 *lir) { MOZ_CRASH(); }
     void visitSubstr(MSubstr *) { MOZ_CRASH(); }
     void visitSimdBinaryArith(js::jit::MSimdBinaryArith*) { MOZ_CRASH(); }
 
 
 };
 
--- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp
+++ b/js/src/jit/shared/CodeGenerator-x86-shared.cpp
@@ -2959,17 +2959,32 @@ CodeGeneratorX86Shared::visitSimdSelect(
     FloatRegister output = ToFloatRegister(ins->output());
     FloatRegister temp = ToFloatRegister(ins->temp());
 
     if (onTrue != output)
         masm.vmovaps(onTrue, output);
     if (mask != temp)
         masm.vmovaps(mask, temp);
 
-    masm.bitwiseAndX4(Operand(mask), output);
+    MSimdSelect *mir = ins->mir();
+    if (mir->isElementWise()) {
+        if (AssemblerX86Shared::HasAVX()) {
+            masm.vblendvps(mask, onTrue, onFalse, output);
+            return;
+        }
+
+        // SSE4.1 has plain blendvps which can do this, but it is awkward
+        // to use because it requires the mask to be in xmm0.
+
+        // Propagate sign to all bits of mask vector, if necessary.
+        if (!mir->mask()->isSimdBinaryComp())
+            masm.packedRightShiftByScalar(Imm32(31), temp);
+    }
+
+    masm.bitwiseAndX4(Operand(temp), output);
     masm.bitwiseAndNotX4(Operand(onFalse), temp);
     masm.bitwiseOrX4(Operand(temp), output);
 }
 
 void
 CodeGeneratorX86Shared::visitForkJoinGetSlice(LForkJoinGetSlice *ins)
 {
     MOZ_ASSERT(gen->info().executionMode() == ParallelExecution);
--- a/js/src/jit/shared/Lowering-x86-shared.cpp
+++ b/js/src/jit/shared/Lowering-x86-shared.cpp
@@ -666,35 +666,33 @@ LIRGeneratorX86Shared::visitSimdBinaryAr
                      ins->operation() == MSimdBinaryArith::MinNum ||
                      ins->operation() == MSimdBinaryArith::MaxNum;
     lir->setTemp(0, needsTemp ? temp(LDefinition::FLOAT32X4) : LDefinition::BogusTemp());
 
     lowerForFPU(lir, ins, lhs, rhs);
 }
 
 void
-LIRGeneratorX86Shared::visitSimdTernaryBitwise(MSimdTernaryBitwise *ins)
+LIRGeneratorX86Shared::visitSimdSelect(MSimdSelect *ins)
 {
     MOZ_ASSERT(IsSimdType(ins->type()));
-
-    if (ins->type() == MIRType_Int32x4 || ins->type() == MIRType_Float32x4) {
-        LSimdSelect *lins = new(alloc()) LSimdSelect;
-        MDefinition *r0 = ins->getOperand(0);
-        MDefinition *r1 = ins->getOperand(1);
-        MDefinition *r2 = ins->getOperand(2);
+    MOZ_ASSERT(ins->type() == MIRType_Int32x4 || ins->type() == MIRType_Float32x4,
+               "Unknown SIMD kind when doing bitwise operations");
 
-        lins->setOperand(0, useRegister(r0));
-        lins->setOperand(1, useRegister(r1));
-        lins->setOperand(2, useRegister(r2));
-        lins->setTemp(0, temp(LDefinition::FLOAT32X4));
+    LSimdSelect *lins = new(alloc()) LSimdSelect;
+    MDefinition *r0 = ins->getOperand(0);
+    MDefinition *r1 = ins->getOperand(1);
+    MDefinition *r2 = ins->getOperand(2);
 
-        define(lins, ins);
-    } else {
-        MOZ_CRASH("Unknown SIMD kind when doing bitwise operations");
-    }
+    lins->setOperand(0, useRegister(r0));
+    lins->setOperand(1, useRegister(r1));
+    lins->setOperand(2, useRegister(r2));
+    lins->setTemp(0, temp(LDefinition::FLOAT32X4));
+
+    define(lins, ins);
 }
 
 void
 LIRGeneratorX86Shared::visitSimdSplatX4(MSimdSplatX4 *ins)
 {
     LAllocation x = useRegisterAtStart(ins->getOperand(0));
     LSimdSplatX4 *lir = new(alloc()) LSimdSplatX4(x);
 
--- a/js/src/jit/shared/Lowering-x86-shared.h
+++ b/js/src/jit/shared/Lowering-x86-shared.h
@@ -49,17 +49,17 @@ class LIRGeneratorX86Shared : public LIR
     void lowerUMod(MMod *mod);
     void lowerUrshD(MUrsh *mir);
     void lowerConstantDouble(double d, MInstruction *ins);
     void lowerConstantFloat32(float d, MInstruction *ins);
     void lowerTruncateDToInt32(MTruncateToInt32 *ins);
     void lowerTruncateFToInt32(MTruncateToInt32 *ins);
     void visitForkJoinGetSlice(MForkJoinGetSlice *ins);
     void visitSimdBinaryArith(MSimdBinaryArith *ins);
-    void visitSimdTernaryBitwise(MSimdTernaryBitwise *ins);
+    void visitSimdSelect(MSimdSelect *ins);
     void visitSimdSplatX4(MSimdSplatX4 *ins);
     void visitSimdValueX4(MSimdValueX4 *ins);
     void visitCompareExchangeTypedArrayElement(MCompareExchangeTypedArrayElement *ins);
     void visitAtomicTypedArrayElementBinop(MAtomicTypedArrayElementBinop *ins);
     void visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap *ins);
     void visitAsmJSAtomicBinopHeap(MAsmJSAtomicBinopHeap *ins);
 };
 
--- a/js/src/jit/x64/MacroAssembler-x64.h
+++ b/js/src/jit/x64/MacroAssembler-x64.h
@@ -1196,16 +1196,17 @@ class MacroAssemblerX64 : public MacroAs
     void unboxString(const Operand &src, Register dest) { unboxNonDouble(src, dest); }
 
     void unboxSymbol(const ValueOperand &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxSymbol(const Operand &src, Register dest) { unboxNonDouble(src, dest); }
 
     void unboxObject(const ValueOperand &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxObject(const Operand &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxObject(const Address &src, Register dest) { unboxNonDouble(Operand(src), dest); }
+    void unboxObject(const BaseIndex &src, Register dest) { unboxNonDouble(Operand(src), dest); }
 
     // Extended unboxing API. If the payload is already in a register, returns
     // that register. Otherwise, provides a move to the given scratch register,
     // and returns that.
     Register extractObject(const Address &address, Register scratch) {
         MOZ_ASSERT(scratch != ScratchReg);
         loadPtr(address, ScratchReg);
         // We have a special coupling with unboxObject. As long as the registers
--- a/js/src/jit/x86/MacroAssembler-x86.h
+++ b/js/src/jit/x86/MacroAssembler-x86.h
@@ -59,16 +59,19 @@ class MacroAssemblerX86 : public MacroAs
 
   protected:
     MoveResolver moveResolver_;
 
   private:
     Operand payloadOf(const Address &address) {
         return Operand(address.base, address.offset);
     }
+    Operand payloadOf(const BaseIndex &address) {
+        return Operand(address.base, address.index, address.scale, address.offset);
+    }
     Operand tagOf(const Address &address) {
         return Operand(address.base, address.offset + 4);
     }
     Operand tagOf(const BaseIndex &address) {
         return Operand(address.base, address.index, address.scale, address.offset + 4);
     }
 
     void setupABICall(uint32_t args);
@@ -883,26 +886,30 @@ class MacroAssemblerX86 : public MacroAs
 
     void unboxNonDouble(const ValueOperand &src, Register dest) {
         if (src.payloadReg() != dest)
             movl(src.payloadReg(), dest);
     }
     void unboxNonDouble(const Address &src, Register dest) {
         movl(payloadOf(src), dest);
     }
+    void unboxNonDouble(const BaseIndex &src, Register dest) {
+        movl(payloadOf(src), dest);
+    }
     void unboxInt32(const ValueOperand &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxInt32(const Address &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxBoolean(const ValueOperand &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxBoolean(const Address &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxString(const ValueOperand &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxString(const Address &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxSymbol(const ValueOperand &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxSymbol(const Address &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxObject(const ValueOperand &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxObject(const Address &src, Register dest) { unboxNonDouble(src, dest); }
+    void unboxObject(const BaseIndex &src, Register dest) { unboxNonDouble(src, dest); }
     void unboxDouble(const Address &src, FloatRegister dest) {
         loadDouble(Operand(src), dest);
     }
     void unboxDouble(const ValueOperand &src, FloatRegister dest) {
         MOZ_ASSERT(dest != ScratchDoubleReg);
         if (Assembler::HasSSE41()) {
             vmovd(src.payloadReg(), dest);
             vpinsrd(1, src.typeReg(), dest, dest);
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4840,17 +4840,17 @@ JS_CopyStringChars(JSContext *cx, mozill
         return false;
 
     MOZ_ASSERT(linear->length() <= dest.length());
     CopyChars(dest.start().get(), *linear);
     return true;
 }
 
 JS_PUBLIC_API(const Latin1Char *)
-JS_Latin1InternedStringChars(const JS::AutoCheckCannotGC &nogc, JSString *str)
+JS_GetLatin1InternedStringChars(const JS::AutoCheckCannotGC &nogc, JSString *str)
 {
     MOZ_ASSERT(str->isAtom());
     JSFlatString *flat = str->ensureFlat(nullptr);
     if (!flat)
         return nullptr;
     return flat->latin1Chars(nogc);
 }
 
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -2251,18 +2251,17 @@ JS_NewExternalString(JSContext *cx, cons
 /*
  * Return whether 'str' was created with JS_NewExternalString or
  * JS_NewExternalStringWithClosure.
  */
 extern JS_PUBLIC_API(bool)
 JS_IsExternalString(JSString *str);
 
 /*
- * Return the 'closure' arg passed to JS_NewExternalStringWithClosure or
- * nullptr if the external string was created via JS_NewExternalString.
+ * Return the 'fin' arg passed to JS_NewExternalString.
  */
 extern JS_PUBLIC_API(const JSStringFinalizer *)
 JS_GetExternalStringFinalizer(JSString *str);
 
 /*
  * Set the size of the native stack that should not be exceed. To disable
  * stack size checking pass 0.
  *
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -1108,17 +1108,17 @@ GCRuntime::GCRuntime(JSRuntime *rt) :
     marker(rt),
     usage(nullptr),
     maxMallocBytes(0),
     numArenasFreeCommitted(0),
     verifyPreData(nullptr),
     verifyPostData(nullptr),
     chunkAllocationSinceLastGC(false),
     nextFullGCTime(0),
-    lastGCTime(0),
+    lastGCTime(PRMJ_Now()),
     mode(JSGC_MODE_INCREMENTAL),
     decommitThreshold(32 * 1024 * 1024),
     cleanUpEverything(false),
     grayBitsValid(false),
     majorGCRequested(0),
     majorGCTriggerReason(JS::gcreason::NO_REASON),
     minorGCRequested(false),
     minorGCTriggerReason(JS::gcreason::NO_REASON),
@@ -3303,19 +3303,18 @@ GCRuntime::maybeGC(Zone *zone)
         gc(GC_NORMAL, JS::gcreason::MAYBEGC);
         return true;
     }
 #endif
 
     if (gcIfNeeded())
         return true;
 
-    double factor = schedulingState.inHighFrequencyGCMode() ? 0.85 : 0.9;
     if (zone->usage.gcBytes() > 1024 * 1024 &&
-        zone->usage.gcBytes() >= factor * zone->threshold.gcTriggerBytes() &&
+        zone->isCloseToAllocTrigger(schedulingState.inHighFrequencyGCMode()) &&
         incrementalState == NO_INCREMENTAL &&
         !isBackgroundSweeping())
     {
         PrepareZoneForGC(zone);
         gcSlice(GC_NORMAL, JS::gcreason::MAYBEGC);
         return true;
     }
 
@@ -5623,20 +5622,20 @@ GCRuntime::finishCollection()
 {
     MOZ_ASSERT(marker.isDrained());
     marker.stop();
 
     uint64_t currentTime = PRMJ_Now();
     schedulingState.updateHighFrequencyMode(lastGCTime, currentTime, tunables);
 
     for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
-        zone->threshold.updateAfterGC(zone->usage.gcBytes(), invocationKind, tunables,
-                                      schedulingState);
         if (zone->isCollecting()) {
             MOZ_ASSERT(zone->isGCFinished() || zone->isGCCompacting());
+            zone->threshold.updateAfterGC(zone->usage.gcBytes(), invocationKind, tunables,
+                                          schedulingState);
             zone->setGCState(Zone::NoGC);
             zone->active = false;
         }
 
         MOZ_ASSERT(!zone->isCollecting());
         MOZ_ASSERT(!zone->wasGCStarted());
     }
 
@@ -6214,16 +6213,20 @@ GCRuntime::scanZonesBeforeGC()
     for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
         if (mode == JSGC_MODE_GLOBAL)
             zone->scheduleGC();
 
         /* This is a heuristic to avoid resets. */
         if (incrementalState != NO_INCREMENTAL && zone->needsIncrementalBarrier())
             zone->scheduleGC();
 
+        /* This is a heuristic to reduce the total number of collections. */
+        if (zone->isCloseToAllocTrigger(schedulingState.inHighFrequencyGCMode()))
+            zone->scheduleGC();
+
         zoneStats.zoneCount++;
         if (zone->isGCScheduled()) {
             zoneStats.collectedZoneCount++;
             zoneStats.collectedCompartmentCount += zone->compartments.length();
         }
     }
 
     for (CompartmentsIter c(rt, WithAtoms); !c.done(); c.next())
deleted file mode 100644
--- a/js/src/tests/ecma_7/SIMD/float32x4select.js
+++ /dev/null
@@ -1,38 +0,0 @@
-// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
-var BUGNUMBER = 1060437;
-var float32x4 = SIMD.float32x4;
-var int32x4 = SIMD.int32x4;
-
-var summary = 'float32x4 select';
-
-function test() {
-  print(BUGNUMBER + ": " + summary);
-
-  var a = float32x4(0.125,4.25,9.75,16.125);
-  var b = float32x4(1.5,2.75,3.25,4.5);
-  var sel_ttff = int32x4.bool(true, true, false, false);
-  var c = SIMD.float32x4.select(sel_ttff,a,b);
-  assertEq(c.x, 0.125);
-  assertEq(c.y, 4.25);
-  assertEq(c.z, 3.25);
-  assertEq(c.w, 4.5);
-
-  var b2 = float32x4(1.5,2.75,NaN,Infinity);
-  var c = SIMD.float32x4.select(sel_ttff,a,b2);
-  assertEq(c.x, 0.125);
-  assertEq(c.y, 4.25);
-  assertEq(c.z, NaN);
-  assertEq(c.w, Infinity);
-
-  var a2 = float32x4(-NaN,-Infinity,9.75,16.125);
-  var c = SIMD.float32x4.select(sel_ttff,a2,b2);
-  assertEq(c.x, -NaN);
-  assertEq(c.y, -Infinity);
-  assertEq(c.z, NaN);
-  assertEq(c.w, Infinity);
-
-  if (typeof reportCompare === "function")
-    reportCompare(true, true);
-}
-
-test();
deleted file mode 100644
--- a/js/src/tests/ecma_7/SIMD/int32x4select.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
-var BUGNUMBER = 1060437;
-var int32x4 = SIMD.int32x4;
-
-var summary = 'int32x4 select';
-
-function test() {
-  print(BUGNUMBER + ": " + summary);
-
-  var a = int32x4(0,4,9,16)
-  var b = int32x4(1,2,3,4)
-  var sel_ttff = int32x4.bool(true, true, false, false);
-  var c = SIMD.int32x4.select(sel_ttff,a,b);
-  assertEq(c.x, 0);
-  assertEq(c.y, 4);
-  assertEq(c.z, 3);
-  assertEq(c.w, 4);
-
-  var a2 = int32x4(INT32_MAX,INT32_MIN,9,16)
-  var c = SIMD.int32x4.select(sel_ttff,a2,b);
-  assertEq(c.x, INT32_MAX);
-  assertEq(c.y, INT32_MIN);
-  assertEq(c.z, 3);
-  assertEq(c.w, 4);
-
-  var b2 = int32x4(1,2,INT32_MAX,INT32_MIN)
-  var c = SIMD.int32x4.select(sel_ttff,a2,b2);
-  assertEq(c.x, INT32_MAX);
-  assertEq(c.y, INT32_MIN);
-  assertEq(c.z, INT32_MAX);
-  assertEq(c.w, INT32_MIN);
-
-  if (typeof reportCompare === "function")
-    reportCompare(true, true);
-}
-
-test();
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/select-bitselect.js
@@ -0,0 +1,122 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var float32x4 = SIMD.float32x4;
+var int32x4 = SIMD.int32x4;
+
+function select(mask, ifTrue, ifFalse) {
+    var m = simdToArray(mask);
+    var tv = simdToArray(ifTrue);
+    var fv = simdToArray(ifFalse);
+    return m.map(function(v, i) {
+        return (v < 0 ? tv : fv)[i];
+    });
+}
+
+/**
+ * Tests type.select on all input pairs, for all possible masks. As the mask
+ * has 4 lanes and 2 possible values (true or false), there are 16 possible
+ * masks.
+ */
+function testSelect(type, inputs) {
+    var x, y;
+    for (var i = 0; i < 16; i++) {
+        var mask = int32x4.bool(!!(i & 1), !!((i >> 1) & 1), !!((i >> 2) & 1), !!((i >> 3) & 1));
+        for ([x, y] of inputs)
+            assertEqX4(type.select(mask, x, y), select(mask, x, y));
+    }
+}
+
+function bitselect(ScalarTypedArray, mask, ifTrue, ifFalse) {
+    var m = simdToArray(mask);
+
+    var tv = new ScalarTypedArray(simdToArray(ifTrue));
+    var fv = new ScalarTypedArray(simdToArray(ifFalse));
+
+    tv = new Int32Array(tv.buffer);
+    fv = new Int32Array(fv.buffer);
+    var res = new Int32Array(4);
+
+    for (var i = 0; i < 4; i++) {
+        var t = 0;
+        for (var bit = 0; bit < 32; bit++) {
+            var readVal = (m[i] >> bit) & 1 ? tv[i] : fv[i];
+            var readBit = (readVal >> bit) & 1;
+            t |= readBit << bit;
+        }
+        res[i] = t;
+    }
+
+    res = new ScalarTypedArray(res.buffer);
+    return Array.prototype.map.call(res, x => x);
+}
+
+function findCorrespondingScalarTypedArray(type) {
+    switch (type) {
+        case int32x4: return Int32Array;
+        case float32x4: return Float32Array;
+        default: throw new Error("undefined scalar typed array");
+    }
+}
+
+/**
+ * This tests type.bitselect on all boolean masks, as in select. For these,
+ *          bitselect(mask, x, y) === select(mask, x, y)
+ */
+function testBitSelectSimple(type, inputs) {
+    var x, y;
+    var ScalarTypedArray = findCorrespondingScalarTypedArray(type);
+    for (var i = 0; i < 16; i++) {
+        var mask = int32x4.bool(!!(i & 1), !!((i >> 1) & 1), !!((i >> 2) & 1), !!((i >> 3) & 1));
+        for ([x, y] of inputs)
+            assertEqX4(type.bitselect(mask, x, y), bitselect(ScalarTypedArray, mask, x, y));
+    }
+}
+
+/**
+ * This tests type.bitselect on a few hand-defined masks. For these,
+ *          bitselect(mask, x, y) !== select(mask, x, y)
+ */
+function testBitSelectComplex(type, inputs) {
+    var x, y;
+    var masks = [
+        int32x4(1337, 0x1337, 0x42, 42),
+        int32x4(0x00FF1CE, 0xBAADF00D, 0xDEADBEEF, 0xCAFED00D),
+        int32x4(0xD15EA5E, 0xDEADC0DE, 0xFACEB00C, 0x4B1D4B1D)
+    ];
+    var ScalarTypedArray = findCorrespondingScalarTypedArray(type);
+    for (var mask of masks) {
+        for ([x, y] of inputs)
+            assertEqX4(type.bitselect(mask, x, y), bitselect(ScalarTypedArray, mask, x, y));
+    }
+}
+
+function test() {
+    var inputs = [
+        [int32x4(0,4,9,16), int32x4(1,2,3,4)],
+        [int32x4(-1, 2, INT32_MAX, INT32_MIN), int32x4(INT32_MAX, -4, INT32_MIN, 42)]
+    ];
+
+    testSelect(int32x4, inputs);
+    testBitSelectSimple(int32x4, inputs);
+    testBitSelectComplex(int32x4, inputs);
+
+    inputs = [
+        [float32x4(0.125,4.25,9.75,16.125), float32x4(1.5,2.75,3.25,4.5)],
+        [float32x4(-1.5,-0,NaN,-Infinity), float32x4(1,-2,13.37,3.13)],
+        [float32x4(1.5,2.75,NaN,Infinity), float32x4(-NaN,-Infinity,9.75,16.125)]
+    ];
+
+    testSelect(float32x4, inputs);
+    testBitSelectSimple(float32x4, inputs);
+    testBitSelectComplex(float32x4, inputs);
+
+    if (typeof reportCompare === "function")
+        reportCompare(true, true);
+}
+
+test();
--- a/js/src/vm/TypedArrayObject.h
+++ b/js/src/vm/TypedArrayObject.h
@@ -299,16 +299,22 @@ TypedArrayShift(Scalar::Type viewType)
       case Scalar::Float32x4:
       case Scalar::Int32x4:
         return 4;
       default:;
     }
     MOZ_CRASH("Unexpected array type");
 }
 
+static inline unsigned
+TypedArrayElemSize(Scalar::Type viewType)
+{
+    return 1u << TypedArrayShift(viewType);
+}
+
 class DataViewObject : public NativeObject
 {
   private:
     static const Class protoClass;
 
     static bool is(HandleValue v) {
         return v.isObject() && v.toObject().hasClass(&class_);
     }
new file mode 100644
--- /dev/null
+++ b/layout/base/crashtests/1107508-1.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<html>
+<svg id="s">
+  <style>
+    #b { display: none; }
+    rect { fill:orange; }
+  </style>
+  <rect width="10" height="10" fill="lime"/>
+</svg>
+<style>
+  #b { display: block; }
+  rect { fill:blue; }
+</style>
+<div id="b" style="border:2px solid black">
+  <svg>
+    <use xlink:href="#s"/>
+  </svg>
+</div>
--- a/layout/base/crashtests/crashtests.list
+++ b/layout/base/crashtests/crashtests.list
@@ -449,8 +449,9 @@ load 936988-1.html
 load 931450.html
 load 931460-1.html
 load 935765-1.html
 load 942690.html
 load 973390-1.html
 load 1001237.html
 load 1043163-1.html
 load 1061028.html
+load 1107508-1.html
--- a/layout/tools/reftest/reftest.js
+++ b/layout/tools/reftest/reftest.js
@@ -31,18 +31,19 @@ const NS_NETWORK_PROTOCOL_CONTRACTID_PRE
           "@mozilla.org/network/protocol;1?name=";
 const NS_XREAPPINFO_CONTRACTID =
           "@mozilla.org/xre/app-info;1";
 const NS_DIRECTORY_SERVICE_CONTRACTID =
           "@mozilla.org/file/directory_service;1";
 const NS_OBSERVER_SERVICE_CONTRACTID =
           "@mozilla.org/observer-service;1";
 
-Components.utils.import("resource://gre/modules/FileUtils.jsm");
-Components.utils.import("chrome://reftest/content/httpd.jsm", this);
+CU.import("resource://gre/modules/FileUtils.jsm");
+CU.import("chrome://reftest/content/httpd.jsm", this);
+CU.import("resource://gre/modules/Services.jsm");
 
 var gLoadTimeout = 0;
 var gTimeoutHook = null;
 var gRemote = false;
 var gIgnoreWindowSize = false;
 var gShuffle = false;
 var gTotalChunks = 0;
 var gThisChunk = 0;
@@ -793,17 +794,22 @@ function AddTestItem(aTest)
 // Note: If you materially change the reftest manifest parsing,
 // please keep the parser in print-manifest-dirs.py in sync.
 function ReadManifest(aURL, inherited_status)
 {
     var secMan = CC[NS_SCRIPTSECURITYMANAGER_CONTRACTID]
                      .getService(CI.nsIScriptSecurityManager);
 
     var listURL = aURL;
-    var channel = gIOService.newChannelFromURI(aURL);
+    var channel = gIOService.newChannelFromURI2(aURL,
+                                                null,      // aLoadingNode
+                                                Services.scriptSecurityManager.getSystemPrincipal(),
+                                                null,      // aTriggeringPrincipal
+                                                CI.nsILoadInfo.SEC_NORMAL,
+                                                CI.nsIContentPolicy.TYPE_OTHER);
     var inputStream = channel.open();
     if (channel instanceof Components.interfaces.nsIHttpChannel
         && channel.responseStatus != 200) {
       gDumpLog("REFTEST TEST-UNEXPECTED-FAIL | | HTTP ERROR : " +
         channel.responseStatus + "\n");
     }
     var streamBuf = getStreamContent(inputStream);
     inputStream.close();
--- a/media/mtransport/transportlayerdtls.cpp
+++ b/media/mtransport/transportlayerdtls.cpp
@@ -587,18 +587,16 @@ bool TransportLayerDtls::Setup() {
 // builds, but can be disabled with prefs and they aren't on in our unit tests
 // since that uses NSS default configuration.
 // Only override prefs to comply with MUST statements in the security-arch.
 static const uint32_t EnabledCiphers[] = {
   TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
   TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
 };
 
-// Don't remove suites; TODO(mt@mozilla.com) restore; bug 1052610
-#if 0
 // Disable all NSS suites modes without PFS or with old and rusty ciphersuites.
 // Anything outside this list is governed by the usual combination of policy
 // and user preferences.
 static const uint32_t DisabledCiphers[] = {
   TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
   TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
   TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
   TLS_ECDHE_RSA_WITH_RC4_128_SHA,
@@ -644,17 +642,16 @@ static const uint32_t DisabledCiphers[] 
   TLS_ECDHE_RSA_WITH_NULL_SHA,
   TLS_ECDH_ECDSA_WITH_NULL_SHA,
   TLS_ECDH_RSA_WITH_NULL_SHA,
 
   TLS_RSA_WITH_NULL_SHA,
   TLS_RSA_WITH_NULL_SHA256,
   TLS_RSA_WITH_NULL_MD5,
 };
-#endif // bug 1052610
 
 bool TransportLayerDtls::SetupCipherSuites(PRFileDesc* ssl_fd) const {
   SECStatus rv;
 
   // Set the SRTP ciphers
   if (!srtp_ciphers_.empty()) {
     // Note: std::vector is guaranteed to contiguous
     rv = SSL_SetSRTPCiphers(ssl_fd, &srtp_ciphers_[0], srtp_ciphers_.size());
@@ -670,18 +667,16 @@ bool TransportLayerDtls::SetupCipherSuit
     rv = SSL_CipherPrefSet(ssl_fd, EnabledCiphers[i], PR_TRUE);
     if (rv != SECSuccess) {
       MOZ_MTLOG(ML_ERROR, LAYER_INFO <<
                 "Unable to enable suite: " << EnabledCiphers[i]);
       return false;
     }
   }
 
-// Don't remove suites; TODO(mt@mozilla.com) restore; bug 1052610
-#if 0
   for (size_t i = 0; i < PR_ARRAY_SIZE(DisabledCiphers); ++i) {
     MOZ_MTLOG(ML_INFO, LAYER_INFO << "Disabling: " << DisabledCiphers[i]);
 
     PRBool enabled = false;
     rv = SSL_CipherPrefGet(ssl_fd, DisabledCiphers[i], &enabled);
     if (rv != SECSuccess) {
       MOZ_MTLOG(ML_NOTICE, LAYER_INFO <<
                 "Unable to check if suite is enabled: " << DisabledCiphers[i]);
@@ -691,17 +686,17 @@ bool TransportLayerDtls::SetupCipherSuit
       rv = SSL_CipherPrefSet(ssl_fd, DisabledCiphers[i], PR_FALSE);
       if (rv != SECSuccess) {
         MOZ_MTLOG(ML_NOTICE, LAYER_INFO <<
                   "Unable to disable suite: " << DisabledCiphers[i]);
         return false;
       }
     }
   }
-#endif
+
   return true;
 }
 
 nsresult TransportLayerDtls::GetCipherSuite(uint16_t* cipherSuite) const {
   CheckThread();
   if (!cipherSuite) {
     MOZ_MTLOG(ML_ERROR, LAYER_INFO << "GetCipherSuite passed a nullptr");
     return NS_ERROR_NULL_POINTER;
--- a/memory/build/mozjemalloc_compat.c
+++ b/memory/build/mozjemalloc_compat.c
@@ -145,30 +145,26 @@ jemalloc_stats_impl(jemalloc_stats_t *st
   int ret = je_(mallctl)("epoch", &epoch, &esz, &epoch, esz);
 
   CTL_GET("arenas.narenas", narenas);
   CTL_GET("arenas.page", page);
   CTL_GET("stats.active", active);
   CTL_GET("stats.allocated", allocated);
   CTL_GET("stats.mapped", mapped);
   CTL_GET("opt.lg_chunk", lg_chunk);
+  CTL_GET("stats.bookkeeping", stats->bookkeeping);
 
   /* get the summation for all arenas, i == narenas */
   CTL_I_GET("stats.arenas.0.pdirty", pdirty, narenas);
 
   stats->chunksize = 1 << lg_chunk;
   stats->mapped = mapped;
   stats->allocated = allocated;
   stats->waste = active - allocated;
   stats->page_cache = pdirty * page;
-
-  // We could get this value out of base.c::base_pages, but that really should
-  // be an upstream change, so don't worry about it for now.
-  stats->bookkeeping = 0;
-
   stats->bin_unused = compute_bin_unused(narenas);
   stats->waste -= stats->bin_unused;
 }
 
 MOZ_JEMALLOC_API void
 jemalloc_purge_freed_pages_impl()
 {
 }
new file mode 100644
--- /dev/null
+++ b/memory/jemalloc/0004-Implement-stats.bookkeeping.patch
@@ -0,0 +1,158 @@
+commit a8a2e2b34e21870733c75121f431530d42d4d3cd
+Author: Guilherme Goncalves <guilherme.p.gonc@gmail.com>
+Date:   Tue Dec 23 15:21:04 2014 -0200
+
+    Implement stats.bookkeeping.
+    
+    This measures the number of bytes used for arena and chunk headers and all base
+    allocations (note that arena headers are already allocated through the base
+    allocator). It does not account for internal allocations made through arenas.
+
+diff --git a/include/jemalloc/internal/base.h b/include/jemalloc/internal/base.h
+index 3fb80b9..9dc431c 100644
+--- a/include/jemalloc/internal/base.h
++++ b/include/jemalloc/internal/base.h
+@@ -9,6 +9,10 @@
+ /******************************************************************************/
+ #ifdef JEMALLOC_H_EXTERNS
+ 
++/* base_mtx synchronizes base allocations and protects base_allocated */
++extern malloc_mutex_t	base_mtx;
++extern size_t base_allocated;
++
+ void	*base_alloc(size_t size);
+ void	*base_calloc(size_t number, size_t size);
+ extent_node_t *base_node_alloc(void);
+diff --git a/include/jemalloc/internal/ctl.h b/include/jemalloc/internal/ctl.h
+index a3e899e..cbb0923 100644
+--- a/include/jemalloc/internal/ctl.h
++++ b/include/jemalloc/internal/ctl.h
+@@ -52,6 +52,7 @@ struct ctl_arena_stats_s {
+ struct ctl_stats_s {
+ 	size_t			allocated;
+ 	size_t			active;
++	size_t			bookkeeping;
+ 	size_t			mapped;
+ 	struct {
+ 		size_t		current;	/* stats_chunks.curchunks */
+diff --git a/include/jemalloc/internal/private_symbols.txt b/include/jemalloc/internal/private_symbols.txt
+index ee973c9..93271ce 100644
+--- a/include/jemalloc/internal/private_symbols.txt
++++ b/include/jemalloc/internal/private_symbols.txt
+@@ -91,8 +91,10 @@ atomic_sub_uint32
+ atomic_sub_uint64
+ atomic_sub_z
+ base_alloc
++base_allocated
+ base_boot
+ base_calloc
++base_mtx
+ base_node_alloc
+ base_node_dalloc
+ base_postfork_child
+diff --git a/src/base.c b/src/base.c
+index 409c7bb..3350ca3 100644
+--- a/src/base.c
++++ b/src/base.c
+@@ -4,7 +4,7 @@
+ /******************************************************************************/
+ /* Data. */
+ 
+-static malloc_mutex_t	base_mtx;
++malloc_mutex_t	base_mtx;
+ 
+ /*
+  * Current pages that are being used for internal memory allocations.  These
+@@ -16,6 +16,8 @@ static void		*base_next_addr;
+ static void		*base_past_addr; /* Addr immediately past base_pages. */
+ static extent_node_t	*base_nodes;
+ 
++size_t base_allocated;
++
+ /******************************************************************************/
+ 
+ static bool
+@@ -54,6 +56,8 @@ base_alloc(size_t size)
+ 	/* Allocate. */
+ 	ret = base_next_addr;
+ 	base_next_addr = (void *)((uintptr_t)base_next_addr + csize);
++	if (config_stats)
++		base_allocated += csize;
+ 	malloc_mutex_unlock(&base_mtx);
+ 	JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, csize);
+ 
+diff --git a/src/ctl.c b/src/ctl.c
+index b367c9f..1999145 100644
+--- a/src/ctl.c
++++ b/src/ctl.c
+@@ -187,6 +187,7 @@ INDEX_PROTO(stats_arenas_i)
+ CTL_PROTO(stats_cactive)
+ CTL_PROTO(stats_allocated)
+ CTL_PROTO(stats_active)
++CTL_PROTO(stats_bookkeeping)
+ CTL_PROTO(stats_mapped)
+ 
+ /******************************************************************************/
+@@ -448,12 +449,13 @@ static const ctl_indexed_node_t stats_arenas_node[] = {
+ };
+ 
+ static const ctl_named_node_t stats_node[] = {
+-	{NAME("cactive"),	CTL(stats_cactive)},
+-	{NAME("allocated"),	CTL(stats_allocated)},
+-	{NAME("active"),	CTL(stats_active)},
+-	{NAME("mapped"),	CTL(stats_mapped)},
+-	{NAME("chunks"),	CHILD(named, stats_chunks)},
+-	{NAME("arenas"),	CHILD(indexed, stats_arenas)}
++	{NAME("cactive"),		CTL(stats_cactive)},
++	{NAME("allocated"),		CTL(stats_allocated)},
++	{NAME("active"),		CTL(stats_active)},
++	{NAME("bookkeeping"),	CTL(stats_bookkeeping)},
++	{NAME("mapped"),		CTL(stats_mapped)},
++	{NAME("chunks"),		CHILD(named, stats_chunks)},
++	{NAME("arenas"),		CHILD(indexed, stats_arenas)}
+ };
+ 
+ static const ctl_named_node_t	root_node[] = {
+@@ -705,6 +707,12 @@ ctl_refresh(void)
+ 		ctl_stats.active =
+ 		    (ctl_stats.arenas[ctl_stats.narenas].pactive << LG_PAGE);
+ 		ctl_stats.mapped = (ctl_stats.chunks.current << opt_lg_chunk);
++
++		/* add chunk headers to bookkeeping */
++		ctl_stats.bookkeeping = ctl_stats.chunks.current * (map_bias << LG_PAGE);
++		malloc_mutex_lock(&base_mtx);
++		ctl_stats.bookkeeping += base_allocated;
++		malloc_mutex_unlock(&base_mtx);
+ 	}
+ 
+ 	ctl_epoch++;
+@@ -1806,6 +1814,7 @@ CTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t)
+ CTL_RO_CGEN(config_stats, stats_cactive, &stats_cactive, size_t *)
+ CTL_RO_CGEN(config_stats, stats_allocated, ctl_stats.allocated, size_t)
+ CTL_RO_CGEN(config_stats, stats_active, ctl_stats.active, size_t)
++CTL_RO_CGEN(config_stats, stats_bookkeeping, ctl_stats.bookkeeping, size_t)
+ CTL_RO_CGEN(config_stats, stats_mapped, ctl_stats.mapped, size_t)
+ 
+ CTL_RO_CGEN(config_stats, stats_chunks_current, ctl_stats.chunks.current,
+diff --git a/test/unit/stats.c b/test/unit/stats.c
+index 946e737..e84cbf7 100644
+--- a/test/unit/stats.c
++++ b/test/unit/stats.c
+@@ -3,7 +3,7 @@
+ TEST_BEGIN(test_stats_summary)
+ {
+ 	size_t *cactive;
+-	size_t sz, allocated, active, mapped;
++	size_t sz, allocated, active, mapped, bookkeeping;
+ 	int expected = config_stats ? 0 : ENOENT;
+ 
+ 	sz = sizeof(cactive);
+@@ -17,6 +17,8 @@ TEST_BEGIN(test_stats_summary)
+ 	    "Unexpected mallctl() result");
+ 	assert_d_eq(mallctl("stats.mapped", &mapped, &sz, NULL, 0), expected,
+ 	    "Unexpected mallctl() result");
++	assert_d_eq(mallctl("stats.bookkeeping", &bookkeeping, &sz, NULL, 0),
++	    expected, "Unexpected mallctl() result");
+ 
+ 	if (config_stats) {
+ 		assert_zu_le(active, *cactive,
--- a/memory/jemalloc/src/include/jemalloc/internal/base.h
+++ b/memory/jemalloc/src/include/jemalloc/internal/base.h
@@ -4,16 +4,20 @@
 #endif /* JEMALLOC_H_TYPES */
 /******************************************************************************/
 #ifdef JEMALLOC_H_STRUCTS
 
 #endif /* JEMALLOC_H_STRUCTS */
 /******************************************************************************/
 #ifdef JEMALLOC_H_EXTERNS
 
+/* base_mtx synchronizes base allocations and protects base_allocated */
+extern malloc_mutex_t	base_mtx;
+extern size_t base_allocated;
+
 void	*base_alloc(size_t size);
 void	*base_calloc(size_t number, size_t size);
 extent_node_t *base_node_alloc(void);
 void	base_node_dalloc(extent_node_t *node);
 bool	base_boot(void);
 void	base_prefork(void);
 void	base_postfork_parent(void);
 void	base_postfork_child(void);
--- a/memory/jemalloc/src/include/jemalloc/internal/ctl.h
+++ b/memory/jemalloc/src/include/jemalloc/internal/ctl.h
@@ -47,16 +47,17 @@ struct ctl_arena_stats_s {
 	malloc_bin_stats_t	bstats[NBINS];
 	malloc_large_stats_t	*lstats;	/* nlclasses elements. */
 	malloc_huge_stats_t	*hstats;	/* nhclasses elements. */
 };
 
 struct ctl_stats_s {
 	size_t			allocated;
 	size_t			active;
+	size_t			bookkeeping;
 	size_t			mapped;
 	struct {
 		size_t		current;	/* stats_chunks.curchunks */
 		uint64_t	total;		/* stats_chunks.nchunks */
 		size_t		high;		/* stats_chunks.highchunks */
 	} chunks;
 	unsigned		narenas;
 	ctl_arena_stats_t	*arenas;	/* (narenas + 1) elements. */
--- a/memory/jemalloc/src/include/jemalloc/internal/private_symbols.txt
+++ b/memory/jemalloc/src/include/jemalloc/internal/private_symbols.txt
@@ -86,18 +86,20 @@ atomic_add_u
 atomic_add_uint32
 atomic_add_uint64
 atomic_add_z
 atomic_sub_u
 atomic_sub_uint32
 atomic_sub_uint64
 atomic_sub_z
 base_alloc
+base_allocated
 base_boot
 base_calloc
+base_mtx
 base_node_alloc
 base_node_dalloc
 base_postfork_child
 base_postfork_parent
 base_prefork
 bitmap_full
 bitmap_get
 bitmap_info_init
--- a/memory/jemalloc/src/src/base.c
+++ b/memory/jemalloc/src/src/base.c
@@ -1,26 +1,28 @@
 #define	JEMALLOC_BASE_C_
 #include "jemalloc/internal/jemalloc_internal.h"
 
 /******************************************************************************/
 /* Data. */
 
-static malloc_mutex_t	base_mtx;
+malloc_mutex_t	base_mtx;
 
 /*
  * Current pages that are being used for internal memory allocations.  These
  * pages are carved up in cacheline-size quanta, so that there is no chance of
  * false cache line sharing.
  */
 static void		*base_pages;
 static void		*base_next_addr;
 static void		*base_past_addr; /* Addr immediately past base_pages. */
 static extent_node_t	*base_nodes;
 
+size_t base_allocated;
+
 /******************************************************************************/
 
 static bool
 base_pages_alloc(size_t minsize)
 {
 	size_t csize;
 
 	assert(minsize != 0);
@@ -49,16 +51,18 @@ base_alloc(size_t size)
 		if (base_pages_alloc(csize)) {
 			malloc_mutex_unlock(&base_mtx);
 			return (NULL);
 		}
 	}
 	/* Allocate. */
 	ret = base_next_addr;
 	base_next_addr = (void *)((uintptr_t)base_next_addr + csize);
+	if (config_stats)
+		base_allocated += csize;
 	malloc_mutex_unlock(&base_mtx);
 	JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, csize);
 
 	return (ret);
 }
 
 void *
 base_calloc(size_t number, size_t size)
--- a/memory/jemalloc/src/src/ctl.c
+++ b/memory/jemalloc/src/src/ctl.c
@@ -182,16 +182,17 @@ CTL_PROTO(stats_arenas_i_pdirty)
 CTL_PROTO(stats_arenas_i_mapped)
 CTL_PROTO(stats_arenas_i_npurge)
 CTL_PROTO(stats_arenas_i_nmadvise)
 CTL_PROTO(stats_arenas_i_purged)
 INDEX_PROTO(stats_arenas_i)
 CTL_PROTO(stats_cactive)
 CTL_PROTO(stats_allocated)
 CTL_PROTO(stats_active)
+CTL_PROTO(stats_bookkeeping)
 CTL_PROTO(stats_mapped)
 
 /******************************************************************************/
 /* mallctl tree. */
 
 /* Maximum tree depth. */
 #define	CTL_MAX_DEPTH	6
 
@@ -443,22 +444,23 @@ static const ctl_named_node_t super_stat
 	{NAME(""),		CHILD(named, stats_arenas_i)}
 };
 
 static const ctl_indexed_node_t stats_arenas_node[] = {
 	{INDEX(stats_arenas_i)}
 };
 
 static const ctl_named_node_t stats_node[] = {
-	{NAME("cactive"),	CTL(stats_cactive)},
-	{NAME("allocated"),	CTL(stats_allocated)},
-	{NAME("active"),	CTL(stats_active)},
-	{NAME("mapped"),	CTL(stats_mapped)},
-	{NAME("chunks"),	CHILD(named, stats_chunks)},
-	{NAME("arenas"),	CHILD(indexed, stats_arenas)}
+	{NAME("cactive"),		CTL(stats_cactive)},
+	{NAME("allocated"),		CTL(stats_allocated)},
+	{NAME("active"),		CTL(stats_active)},
+	{NAME("bookkeeping"),	CTL(stats_bookkeeping)},
+	{NAME("mapped"),		CTL(stats_mapped)},
+	{NAME("chunks"),		CHILD(named, stats_chunks)},
+	{NAME("arenas"),		CHILD(indexed, stats_arenas)}
 };
 
 static const ctl_named_node_t	root_node[] = {
 	{NAME("version"),	CTL(version)},
 	{NAME("epoch"),		CTL(epoch)},
 	{NAME("thread"),	CHILD(named, thread)},
 	{NAME("config"),	CHILD(named, config)},
 	{NAME("opt"),		CHILD(named, opt)},
@@ -700,16 +702,22 @@ ctl_refresh(void)
 	if (config_stats) {
 		ctl_stats.allocated =
 		    ctl_stats.arenas[ctl_stats.narenas].allocated_small
 		    + ctl_stats.arenas[ctl_stats.narenas].astats.allocated_large
 		    + ctl_stats.arenas[ctl_stats.narenas].astats.allocated_huge;
 		ctl_stats.active =
 		    (ctl_stats.arenas[ctl_stats.narenas].pactive << LG_PAGE);
 		ctl_stats.mapped = (ctl_stats.chunks.current << opt_lg_chunk);
+
+		/* add chunk headers to bookkeeping */
+		ctl_stats.bookkeeping = ctl_stats.chunks.current * (map_bias << LG_PAGE);
+		malloc_mutex_lock(&base_mtx);
+		ctl_stats.bookkeeping += base_allocated;
+		malloc_mutex_unlock(&base_mtx);
 	}
 
 	ctl_epoch++;
 }
 
 static bool
 ctl_init(void)
 {
@@ -1801,16 +1809,17 @@ label_return:
 CTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t)
 CTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t)
 
 /******************************************************************************/
 
 CTL_RO_CGEN(config_stats, stats_cactive, &stats_cactive, size_t *)
 CTL_RO_CGEN(config_stats, stats_allocated, ctl_stats.allocated, size_t)
 CTL_RO_CGEN(config_stats, stats_active, ctl_stats.active, size_t)
+CTL_RO_CGEN(config_stats, stats_bookkeeping, ctl_stats.bookkeeping, size_t)
 CTL_RO_CGEN(config_stats, stats_mapped, ctl_stats.mapped, size_t)
 
 CTL_RO_CGEN(config_stats, stats_chunks_current, ctl_stats.chunks.current,
     size_t)
 CTL_RO_CGEN(config_stats, stats_chunks_total, ctl_stats.chunks.total, uint64_t)
 CTL_RO_CGEN(config_stats, stats_chunks_high, ctl_stats.chunks.high, size_t)
 
 CTL_RO_GEN(stats_arenas_i_dss, ctl_stats.arenas[mib[2]].dss, const char *)
--- a/memory/jemalloc/src/test/unit/stats.c
+++ b/memory/jemalloc/src/test/unit/stats.c
@@ -1,27 +1,29 @@
 #include "test/jemalloc_test.h"
 
 TEST_BEGIN(test_stats_summary)
 {
 	size_t *cactive;
-	size_t sz, allocated, active, mapped;
+	size_t sz, allocated, active, mapped, bookkeeping;
 	int expected = config_stats ? 0 : ENOENT;
 
 	sz = sizeof(cactive);
 	assert_d_eq(mallctl("stats.cactive", &cactive, &sz, NULL, 0), expected,
 	    "Unexpected mallctl() result");
 
 	sz = sizeof(size_t);
 	assert_d_eq(mallctl("stats.allocated", &allocated, &sz, NULL, 0),
 	    expected, "Unexpected mallctl() result");
 	assert_d_eq(mallctl("stats.active", &active, &sz, NULL, 0), expected,
 	    "Unexpected mallctl() result");
 	assert_d_eq(mallctl("stats.mapped", &mapped, &sz, NULL, 0), expected,
 	    "Unexpected mallctl() result");
+	assert_d_eq(mallctl("stats.bookkeeping", &bookkeeping, &sz, NULL, 0),
+	    expected, "Unexpected mallctl() result");
 
 	if (config_stats) {
 		assert_zu_le(active, *cactive,
 		    "active should be no larger than cactive");
 		assert_zu_le(allocated, active,
 		    "allocated should be no larger than active");
 		assert_zu_le(active, mapped,
 		    "active should be no larger than mapped");
--- a/memory/jemalloc/update.sh
+++ b/memory/jemalloc/update.sh
@@ -12,13 +12,14 @@ cd src
 git checkout "$UPSTREAM_COMMIT"
 autoconf
 git describe --long --abbrev=40 > VERSION
 rm -rf .git .gitignore .gitattributes autom4te.cache .autom4te.cfg
 
 patch -p1 < ../0001-Dont-overwrite-VERSION-on-a-git-repository.patch
 patch -p1 < ../0002-Move-variable-declaration-to-the-top-its-block-for-M.patch
 patch -p1 < ../0003-Add-a-isblank-definition-for-MSVC-2013.patch
+patch -p1 < ../0004-Implement-stats.bookkeeping.patch
 
 cd ..
 hg addremove -q src
 
 echo "jemalloc has now been updated.  Don't forget to run hg commit!"
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -760,17 +760,17 @@ public class BrowserApp extends GeckoApp
         final String args = ContextUtils.getStringExtra(getIntent(), "args");
         // If an external intent tries to start Fennec in guest mode, and it's not already
         // in guest mode, this will change modes before opening the url.
         // NOTE: OnResume is called twice sometimes when showing on the lock screen.
         final boolean enableGuestSession = GuestSession.shouldUse(this, args);
         final boolean inGuestSession = GeckoProfile.get(this).inGuestMode();
         if (enableGuestSession != inGuestSession) {
             doRestart(getIntent());
-            GeckoAppShell.systemExit();
+            GeckoAppShell.gracefulExit();
             return;
         }
 
         EventDispatcher.getInstance().unregisterGeckoThreadListener((GeckoEventListener)this,
             "Prompt:ShowTop");
     }
 
     @Override
@@ -3005,17 +3005,17 @@ public class BrowserApp extends GeckoApp
                         } else {
                             GeckoProfile.leaveGuestSession(BrowserApp.this);
 
                             // Now's a good time to make sure we're not displaying the Guest Browsing notification.
                             GuestSession.hideNotification(BrowserApp.this);
                         }
 
                         doRestart(args);
-                        GeckoAppShell.systemExit();
+                        GeckoAppShell.gracefulExit();
                     }
                 } catch(JSONException ex) {
                     Log.e(LOGTAG, "Exception reading guest mode prompt result", ex);
                 }
             }
         });
 
         Resources res = getResources();
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -1213,17 +1213,17 @@ public abstract class GeckoApp
         // This is using a sledgehammer to crack a nut, but it'll do for
         // now.
         // Our OS locale pref will be detected as invalid after the
         // restart, and will be propagated to Gecko accordingly, so there's
         // no need to touch that here.
         if (BrowserLocaleManager.getInstance().systemLocaleDidChange()) {
             Log.i(LOGTAG, "System locale changed. Restarting.");
             doRestart();
-            GeckoAppShell.systemExit();
+            GeckoAppShell.gracefulExit();
             return;
         }
 
         if (GeckoThread.isCreated()) {
             // This happens when the GeckoApp activity is destroyed by Android
             // without killing the entire application (see Bug 769269).
             mIsRestoringActivity = true;
             Telemetry.addToHistogram("FENNEC_RESTORING_ACTIVITY", 1);
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -788,16 +788,23 @@ public class GeckoAppShell
             } else {
                 getGeckoInterface().getActivity().finish();
             }
         }
 
         systemExit();
     }
 
+    static void gracefulExit() {
+        Log.d(LOGTAG, "Initiating graceful exit...");
+        sendEventToGeckoSync(GeckoEvent.createBroadcastEvent("Browser:Quit", ""));
+        GeckoThread.setLaunchState(GeckoThread.LaunchState.GeckoExited);
+        System.exit(0);
+    }
+
     static void systemExit() {
         Log.d(LOGTAG, "Killing via System.exit()");
         GeckoThread.setLaunchState(GeckoThread.LaunchState.GeckoExited);
         System.exit(0);
     }
 
     @WrapElementForJNI
     static void scheduleRestart() {
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1350,21 +1350,19 @@ pref("network.websocket.timeout.close", 
 // ping probe. 0 to disable.
 pref("network.websocket.timeout.ping.request", 0);
 
 // the deadline, expressed in seconds, for some read activity to occur after
 // generating a ping. If no activity happens then an error and unclean close
 // event is sent to the javascript websockets application
 pref("network.websocket.timeout.ping.response", 10);
 
-// Defines whether or not to try and negotiate the stream-deflate compression
-// extension with the websocket server. Stream-Deflate has been removed from
-// the standards track document, but can still be used by servers who opt
-// into it.
-pref("network.websocket.extensions.stream-deflate", false);
+// Defines whether or not to try to negotiate the permessage compression
+// extension with the websocket server.
+pref("network.websocket.extensions.permessage-deflate", true);
 
 // the maximum number of concurrent websocket sessions. By specification there
 // is never more than one handshake oustanding to an individual host at
 // one time.
 pref("network.websocket.max-connections", 200);
 
 // by default scripts loaded from a https:// origin can only open secure
 // (i.e. wss://) websockets.
--- a/netwerk/base/src/NetUtil.jsm
+++ b/netwerk/base/src/NetUtil.jsm
@@ -239,16 +239,18 @@ this.NetUtil = {
             pump.init(aSource, -1, -1, 0, 0, true);
             pump.asyncRead(listener, null);
             return;
         }
 
         let channel = aSource;
         if (!(channel instanceof Ci.nsIChannel)) {
             channel = this.newChannel2(aSource,
+                                       "",   // aOriginCharset
+                                       null, // aBaseURI
                                        aLoadingNode,
                                        aLoadingPrincipal,
                                        aTriggeringPrincipal,
                                        aSecurityFlags,
                                        aContentPolicyType);
 
         }
 
--- a/netwerk/dns/effective_tld_names.dat
+++ b/netwerk/dns/effective_tld_names.dat
@@ -6775,17 +6775,17 @@ xxx
 
 // zm : http://en.wikipedia.org/wiki/.zm
 *.zm
 
 // zw : http://en.wikipedia.org/wiki/.zw
 *.zw
 
 
-// List of new gTLDs imported from https://newgtlds.icann.org/newgtlds.csv on 2014-12-12T06:02:07Z
+// List of new gTLDs imported from https://newgtlds.icann.org/newgtlds.csv on 2014-12-22T18:02:07Z
 
 // abb : 2014-10-24 ABB Ltd
 abb
 
 // abbott : 2014-07-24 Abbott Laboratories, Inc.
 abbott
 
 // abogado : 2014-04-24 Top Level Domain Holdings Limited
@@ -6819,31 +6819,37 @@ adult
 afl
 
 // africa : 2014-03-24 ZA Central Registry NPC trading as Registry.Africa
 africa
 
 // agency : 2013-11-14 Steel Falls, LLC
 agency
 
+// aig : 2014-12-18 American International Group, Inc.
+aig
+
 // airforce : 2014-03-06 United TLD Holdco Ltd.
 airforce
 
 // airtel : 2014-10-24 Bharti Airtel Limited
 airtel
 
 // allfinanz : 2014-07-03 Allfinanz Deutsche Vermögensberatung Aktiengesellschaft
 allfinanz
 
 // alsace : 2014-07-02 REGION D ALSACE
 alsace
 
 // amsterdam : 2014-07-24 Gemeente Amsterdam
 amsterdam
 
+// analytics : 2014-12-18 Campus IP LLC
+analytics
+
 // android : 2014-08-07 Charleston Road Registry Inc.
 android
 
 // apartments : 2014-12-11 June Maple, LLC
 apartments
 
 // aquarelle : 2014-07-24 Aquarelle.com
 aquarelle
@@ -6858,35 +6864,41 @@ archi
 army
 
 // arte : 2014-12-11 Association Relative à la Télévision Européenne G.E.I.E.
 arte
 
 // associates : 2014-03-06 Baxter Hill, LLC
 associates
 
-// attorney : 2014-03-20
+// attorney : 2014-03-20  
 attorney
 
-// auction : 2014-03-20
+// auction : 2014-03-20  
 auction
 
 // audio : 2014-03-20 Uniregistry, Corp.
 audio
 
+// author : 2014-12-18 Amazon EU S.à r.l.
+author
+
 // auto : 2014-11-13 Uniregistry, Corp.
 auto
 
 // autos : 2014-01-09 DERAutos, LLC
 autos
 
 // axa : 2013-12-19 AXA SA
 axa
 
-// band : 2014-06-12
+// azure : 2014-12-18 Microsoft Corporation
+azure
+
+// band : 2014-06-12  
 band
 
 // bank : 2014-09-25 fTLD Registry Services LLC
 bank
 
 // bar : 2013-12-12 Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable
 bar
 
@@ -6903,25 +6915,31 @@ barclays
 bargains
 
 // bauhaus : 2014-04-17 Werkhaus GmbH
 bauhaus
 
 // bayern : 2014-01-23 Bayern Connect GmbH
 bayern
 
+// bbc : 2014-12-18 British Broadcasting Corporation
+bbc
+
 // bbva : 2014-10-02 BANCO BILBAO VIZCAYA ARGENTARIA, S.A.
 bbva
 
 // bcn : 2014-07-24 Municipi de Barcelona
 bcn
 
 // beer : 2014-01-09 Top Level Domain Holdings Limited
 beer
 
+// bentley : 2014-12-18 Bentley Motors Limited
+bentley
+
 // berlin : 2013-10-31 dotBERLIN GmbH & Co. KG
 berlin
 
 // best : 2013-12-19 BestTLD Pty Ltd
 best
 
 // bharti : 2014-01-09 Bharti Enterprises (Holding) Private Limited
 bharti
@@ -6930,16 +6948,19 @@ bharti
 bible
 
 // bid : 2013-12-19 dot Bid Limited
 bid
 
 // bike : 2013-08-27 Grand Hollow, LLC
 bike
 
+// bing : 2014-12-18 Microsoft Corporation
+bing
+
 // bingo : 2014-12-04 Sand Cedar, LLC
 bingo
 
 // bio : 2014-03-06 STARTING DOT LIMITED
 bio
 
 // black : 2014-01-16 Afilias Limited
 black
@@ -6972,19 +6993,28 @@ boats
 bom
 
 // bond : 2014-06-05 Bond University Limited
 bond
 
 // boo : 2014-01-30 Charleston Road Registry Inc.
 boo
 
+// bot : 2014-12-18 Amazon EU S.à r.l.
+bot
+
 // boutique : 2013-11-14 Over Galley, LLC
 boutique
 
+// bradesco : 2014-12-18 Banco Bradesco S.A.
+bradesco
+
+// bridgestone : 2014-12-18 Bridgestone Corporation
+bridgestone
+
 // broker : 2014-12-11 IG Group Holdings PLC
 broker
 
 // brussels : 2014-02-06 DNS.be vzw
 brussels
 
 // budapest : 2013-11-21 Top Level Domain Holdings Limited
 budapest
@@ -6993,28 +7023,34 @@ budapest
 build
 
 // builders : 2013-11-07 Atomic Madison, LLC
 builders
 
 // business : 2013-11-07 Spring Cross, LLC
 business
 
+// buy : 2014-12-18 Amazon EU S.à r.l.
+buy
+
 // buzz : 2013-10-02 DOTSTRATEGY CO.
 buzz
 
 // bzh : 2014-02-27 Association www.bzh
 bzh
 
 // cab : 2013-10-24 Half Sunset, LLC
 cab
 
 // cal : 2014-07-24 Charleston Road Registry Inc.
 cal
 
+// call : 2014-12-18 Amazon EU S.à r.l.
+call
+
 // camera : 2013-08-27 Atomic Maple, LLC
 camera
 
 // camp : 2013-11-07 Delta Dynamite, LLC
 camp
 
 // cancerresearch : 2014-05-15 Australian Cancer Research Foundation
 cancerresearch
@@ -7050,16 +7086,19 @@ cars
 cartier
 
 // casa : 2013-11-21 Top Level Domain Holdings Limited
 casa
 
 // cash : 2014-03-06 Delta Lake, LLC
 cash
 
+// casino : 2014-12-18 Binky Sky, LLC
+casino
+
 // catering : 2013-12-05 New Falls. LLC
 catering
 
 // cba : 2014-06-26 COMMONWEALTH BANK OF AUSTRALIA
 cba
 
 // cbn : 2014-08-22 The Christian Broadcasting Network, Inc.
 cbn
@@ -7095,16 +7134,19 @@ chloe
 christmas
 
 // chrome : 2014-07-24 Charleston Road Registry Inc.
 chrome
 
 // church : 2014-02-06 Holly Fileds, LLC
 church
 
+// circle : 2014-12-18 Amazon EU S.à r.l.
+circle
+
 // citic : 2014-01-09 CITIC Group Corporation
 citic
 
 // city : 2014-05-29 Snow Sky, LLC
 city
 
 // cityeats : 2014-12-11 Lifestyle Domain Holdings, Inc.
 cityeats
@@ -7155,17 +7197,17 @@ company
 computer
 
 // condos : 2013-12-05 Pine House, LLC
 condos
 
 // construction : 2013-09-16 Fox Dynamite, LLC
 construction
 
-// consulting : 2013-12-05
+// consulting : 2013-12-05  
 consulting
 
 // contractors : 2013-09-10 Magic Woods, LLC
 contractors
 
 // cooking : 2013-11-21 Top Level Domain Holdings Limited
 cooking
 
@@ -7230,32 +7272,32 @@ datsun
 day
 
 // dclk : 2014-11-20 Charleston Road Registry Inc.
 dclk
 
 // deals : 2014-05-22 Sand Sunset, LLC
 deals
 
-// degree : 2014-03-06
+// degree : 2014-03-06  
 degree
 
 // delivery : 2014-09-11 Steel Station, LLC
 delivery
 
 // dell : 2014-10-24 Dell Inc.
 dell
 
 // democrat : 2013-10-24 United TLD Holdco Ltd.
 democrat
 
 // dental : 2014-03-20 Tin Birch, LLC
 dental
 
-// dentist : 2014-03-20
+// dentist : 2014-03-20  
 dentist
 
 // desi : 2013-11-14 Desi Networks LLC
 desi
 
 // design : 2014-11-07 Top Level Design, LLC
 design
 
@@ -7308,16 +7350,19 @@ durban
 dvag
 
 // earth : 2014-12-04 Interlink Co., Ltd.
 earth
 
 // eat : 2014-01-23 Charleston Road Registry Inc.
 eat
 
+// edeka : 2014-12-18 EDEKA Verband kaufmännischer Genossenschaften e.V.
+edeka
+
 // education : 2013-11-07 Brice Way, LLC
 education
 
 // email : 2013-10-31 Spring Madison, LLC
 email
 
 // emerck : 2014-04-03 Merck KGaA
 emerck
@@ -7365,49 +7410,61 @@ everbank
 exchange
 
 // expert : 2013-11-21 Magic Pass, LLC
 expert
 
 // exposed : 2013-12-05 Victor Beach, LLC
 exposed
 
+// fage : 2014-12-18 Fage International S.A.
+fage
+
 // fail : 2014-03-06 Atomic Pipe, LLC
 fail
 
 // fairwinds : 2014-11-13 FairWinds Partners, LLC
 fairwinds
 
 // faith : 2014-11-20 dot Faith Limited
 faith
 
-// fan : 2014-03-06
+// fan : 2014-03-06  
 fan
 
 // fans : 2014-11-07 Asiamix Digital Limited
 fans
 
 // farm : 2013-11-07 Just Maple, LLC
 farm
 
 // fashion : 2014-07-03 Top Level Domain Holdings Limited
 fashion
 
+// fast : 2014-12-18 Amazon EU S.à r.l.
+fast
+
 // feedback : 2013-12-19 Top Level Spectrum, Inc.
 feedback
 
+// ferrero : 2014-12-18 Ferrero Trading Lux S.A.
+ferrero
+
 // final : 2014-10-16 Núcleo de Informação e Coordenação do Ponto BR - NIC.br
 final
 
 // finance : 2014-03-20 Cotton Cypress, LLC
 finance
 
 // financial : 2014-03-06 Just Cover, LLC
 financial
 
+// firestone : 2014-12-18 Bridgestone Corporation
+firestone
+
 // firmdale : 2014-03-27 Firmdale Holdings Limited
 firmdale
 
 // fish : 2013-12-12 Fox Woods, LLC
 fish
 
 // fishing : 2013-11-21 Top Level Domain Holdings Limited
 fishing
@@ -7431,23 +7488,26 @@ flowers
 flsmidth
 
 // fly : 2014-05-08 Charleston Road Registry Inc.
 fly
 
 // foo : 2014-01-23 Charleston Road Registry Inc.
 foo
 
+// football : 2014-12-18 Foggy Farms, LLC
+football
+
 // ford : 2014-11-13 Ford Motor Company
 ford
 
 // forex : 2014-12-11 IG Group Holdings PLC
 forex
 
-// forsale : 2014-05-22
+// forsale : 2014-05-22  
 forsale
 
 // foundation : 2013-12-05 John Dale, LLC
 foundation
 
 // frl : 2014-05-15 FRLregistry B.V.
 frl
 
@@ -7455,17 +7515,17 @@ frl
 frogans
 
 // fund : 2014-03-20 John Castle, LLC
 fund
 
 // furniture : 2014-03-20 Lone Fields, LLC
 furniture
 
-// futbol : 2013-09-20
+// futbol : 2013-09-20  
 futbol
 
 // gal : 2013-11-07 Asociación puntoGAL
 gal
 
 // gallery : 2013-09-13 Sugar House, LLC
 gallery
 
@@ -7518,25 +7578,34 @@ gmail
 gmo
 
 // gmx : 2014-04-24 1&1 Mail & Media GmbH
 gmx
 
 // goldpoint : 2014-11-20 YODOBASHI CAMERA CO.,LTD.
 goldpoint
 
+// golf : 2014-12-18 Lone falls, LLC
+golf
+
+// goo : 2014-12-18 NTT Resonant Inc.
+goo
+
 // goog : 2014-11-20 Charleston Road Registry Inc.
 goog
 
 // google : 2014-07-24 Charleston Road Registry Inc.
 google
 
 // gop : 2014-01-16 Republican State Leadership Committee, Inc.
 gop
 
+// got : 2014-12-18 Amazon EU S.à r.l.
+got
+
 // graphics : 2013-09-13 Over Madison, LLC
 graphics
 
 // gratis : 2014-03-20 Pioneer Tigers, LLC
 gratis
 
 // green : 2014-05-08 Afilias Limited
 green
@@ -7563,17 +7632,17 @@ guitars
 guru
 
 // hamburg : 2014-02-20 Hamburg Top-Level-Domain GmbH
 hamburg
 
 // hangout : 2014-11-13 Charleston Road Registry Inc.
 hangout
 
-// haus : 2013-12-05
+// haus : 2013-12-05  
 haus
 
 // healthcare : 2014-06-12 Silver Glen, LLC
 healthcare
 
 // help : 2014-06-26 Uniregistry, Corp.
 help
 
@@ -7596,25 +7665,31 @@ hiv
 holdings
 
 // holiday : 2013-11-07 Goose Woods, LLC
 holiday
 
 // homes : 2014-01-09 DERHomes, LLC
 homes
 
+// honda : 2014-12-18 Honda Motor Co., Ltd.
+honda
+
 // horse : 2013-11-21 Top Level Domain Holdings Limited
 horse
 
 // host : 2014-04-17 DotHost Inc.
 host
 
 // hosting : 2014-05-29 Uniregistry, Corp.
 hosting
 
+// hotmail : 2014-12-18 Microsoft Corporation
+hotmail
+
 // house : 2013-11-07 Sugar Park, LLC
 house
 
 // how : 2014-01-23 Charleston Road Registry Inc.
 how
 
 // hsbc : 2014-10-24 HSBC Holdings PLC
 hsbc
@@ -7692,16 +7767,22 @@ jcb
 jetzt
 
 // jlc : 2014-12-04 Richemont DNS Inc.
 jlc
 
 // joburg : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry
 joburg
 
+// jot : 2014-12-18 Amazon EU S.à r.l.
+jot
+
+// joy : 2014-12-18 Amazon EU S.à r.l.
+joy
+
 // jprs : 2014-09-18 Japan Registry Services Co., Ltd.
 jprs
 
 // juegos : 2014-03-20 Uniregistry, Corp.
 juegos
 
 // kaufen : 2013-11-07 United TLD Holdco Ltd.
 kaufen
@@ -7746,17 +7827,17 @@ land
 landrover
 
 // lat : 2014-10-16 ECOM-LAC Federaciòn de Latinoamèrica y el Caribe para Internet y el Comercio Electrònico
 lat
 
 // latrobe : 2014-06-16 La Trobe University
 latrobe
 
-// lawyer : 2014-03-20
+// lawyer : 2014-03-20  
 lawyer
 
 // lds : 2014-03-20 IRI Domain Management, LLC (\
 lds
 
 // lease : 2014-03-06 Victor Trail, LLC
 lease
 
@@ -7779,16 +7860,19 @@ lidl
 life
 
 // lifestyle : 2014-12-11 Lifestyle Domain Holdings, Inc.
 lifestyle
 
 // lighting : 2013-08-27 John McCook, LLC
 lighting
 
+// like : 2014-12-18 Amazon EU S.à r.l.
+like
+
 // limited : 2014-03-06 Big Fest, LLC
 limited
 
 // limo : 2013-10-17 Hidden Frostbite, LLC
 limo
 
 // lincoln : 2014-11-13 Ford Motor Company
 lincoln
@@ -7845,17 +7929,17 @@ maison
 man
 
 // management : 2013-11-07 John Goodbye, LLC
 management
 
 // mango : 2013-10-24 PUNTO FA S.L.
 mango
 
-// market : 2014-03-06
+// market : 2014-03-06  
 market
 
 // marketing : 2013-11-07 Fern Pass, LLC
 marketing
 
 // markets : 2014-12-11 IG Group Holdings PLC
 markets
 
@@ -7881,41 +7965,50 @@ memorial
 menu
 
 // meo : 2014-11-07 PT Comunicacoes S.A.
 meo
 
 // miami : 2013-12-19 Top Level Domain Holdings Limited
 miami
 
+// microsoft : 2014-12-18 Microsoft Corporation
+microsoft
+
 // mini : 2014-01-09 Bayerische Motoren Werke Aktiengesellschaft
 mini
 
 // mma : 2014-11-07 MMA IARD
 mma
 
+// mobily : 2014-12-18 GreenTech Consultancy Company W.L.L.
+mobily
+
 // moda : 2013-11-07 United TLD Holdco Ltd.
 moda
 
 // moe : 2013-11-13 Interlink Co., Ltd.
 moe
 
+// moi : 2014-12-18 Amazon EU S.à r.l.
+moi
+
 // monash : 2013-09-30 Monash University
 monash
 
 // money : 2014-10-16 Outer McCook, LLC
 money
 
 // montblanc : 2014-06-23 Richemont DNS Inc.
 montblanc
 
 // mormon : 2013-12-05 IRI Domain Management, LLC (\
 mormon
 
-// mortgage : 2014-03-20
+// mortgage : 2014-03-20  
 mortgage
 
 // moscow : 2013-12-19 Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID)
 moscow
 
 // motorcycles : 2014-01-09 DERMotorcycles, LLC
 motorcycles
 
@@ -7947,16 +8040,19 @@ netbank
 network
 
 // neustar : 2013-12-05 NeuStar, Inc.
 neustar
 
 // new : 2014-01-30 Charleston Road Registry Inc.
 new
 
+// news : 2014-12-18 Hidden Bloom, LLC
+news
+
 // nexus : 2014-07-24 Charleston Road Registry Inc.
 nexus
 
 // ngo : 2014-03-06 Public Interest Registry
 ngo
 
 // nhk : 2014-02-13 Japan Broadcasting Corporation (NHK)
 nhk
@@ -8067,16 +8163,19 @@ piaget
 pics
 
 // pictet : 2014-06-26 Pictet Europe S.A.
 pictet
 
 // pictures : 2014-03-06 Foggy Sky, LLC
 pictures
 
+// pin : 2014-12-18 Amazon EU S.à r.l.
+pin
+
 // pink : 2013-10-01 Afilias Limited
 pink
 
 // pizza : 2014-06-26 Foggy Moon, LLC
 pizza
 
 // place : 2014-04-24 Snow Galley, LLC
 place
@@ -8103,16 +8202,19 @@ press
 prod
 
 // productions : 2013-12-05 Magic Birch, LLC
 productions
 
 // prof : 2014-07-24 Charleston Road Registry Inc.
 prof
 
+// promo : 2014-12-18 Play.PROMO Oy
+promo
+
 // properties : 2013-12-05 Big Pass, LLC
 properties
 
 // property : 2014-05-22 Uniregistry, Corp.
 property
 
 // pub : 2013-12-12 United TLD Holdco Ltd.
 pub
@@ -8121,16 +8223,19 @@ pub
 qpon
 
 // quebec : 2013-12-19 PointQuébec Inc
 quebec
 
 // racing : 2014-12-04 Premier Registry Limited
 racing
 
+// read : 2014-12-18 Amazon EU S.à r.l.
+read
+
 // realtor : 2014-05-29 Real Estate Domains LLC
 realtor
 
 // recipes : 2013-10-17 Grand Island, LLC
 recipes
 
 // red : 2013-11-07 Afilias Limited
 red
@@ -8172,50 +8277,62 @@ republican
 rest
 
 // restaurant : 2014-07-03 Snow Avenue, LLC
 restaurant
 
 // review : 2014-11-20 dot Review Limited
 review
 
-// reviews : 2013-09-13
+// reviews : 2013-09-13  
 reviews
 
 // rich : 2013-11-21 I-Registry Ltd.
 rich
 
 // ricoh : 2014-11-20 Ricoh Company, Ltd.
 ricoh
 
 // rio : 2014-02-27 Empresa Municipal de Informática SA - IPLANRIO
 rio
 
 // rip : 2014-07-10 United TLD Holdco Ltd.
 rip
 
-// rocks : 2013-11-14
+// rocher : 2014-12-18 Ferrero Trading Lux S.A.
+rocher
+
+// rocks : 2013-11-14  
 rocks
 
 // rodeo : 2013-12-19 Top Level Domain Holdings Limited
 rodeo
 
+// room : 2014-12-18 Amazon EU S.à r.l.
+room
+
 // rsvp : 2014-05-08 Charleston Road Registry Inc.
 rsvp
 
 // ruhr : 2013-10-02 regiodot GmbH & Co. KG
 ruhr
 
 // ryukyu : 2014-01-09 BusinessRalliart Inc.
 ryukyu
 
 // saarland : 2013-12-12 dotSaarland GmbH
 saarland
 
-// sale : 2014-10-16
+// safe : 2014-12-18 Amazon EU S.à r.l.
+safe
+
+// sakura : 2014-12-18 SAKURA Internet Inc.
+sakura
+
+// sale : 2014-10-16  
 sale
 
 // salon : 2014-12-11 Outer Orchard, LLC
 salon
 
 // samsung : 2014-04-03 SAMSUNG SDS CO., LTD
 samsung
 
@@ -8250,16 +8367,19 @@ sca
 scb
 
 // schmidt : 2014-04-03 SALM S.A.S.
 schmidt
 
 // scholarships : 2014-04-24 Scholarships.com, LLC
 scholarships
 
+// school : 2014-12-18 Little Galley, LLC
+school
+
 // schule : 2014-03-06 Outer Moon, LLC
 schule
 
 // schwarz : 2014-09-18 Schwarz Domains und Services GmbH & Co. KG
 schwarz
 
 // science : 2014-09-11 dot Science Limited
 science
@@ -8307,20 +8427,26 @@ shoes
 shriram
 
 // singles : 2013-08-27 Fern Madison, LLC
 singles
 
 // sky : 2014-06-19 Sky IP International Ltd, a company incorporated in England and Wales, operating via its registered Swiss branch
 sky
 
+// skype : 2014-12-18 Microsoft Corporation
+skype
+
+// smile : 2014-12-18 Amazon EU S.à r.l.
+smile
+
 // social : 2013-11-07 United TLD Holdco Ltd.
 social
 
-// software : 2014-03-20
+// software : 2014-03-20  
 software
 
 // sohu : 2013-12-19 Sohu.com Limited
 sohu
 
 // solar : 2013-11-07 Ruby Town, LLC
 solar
 
@@ -8346,16 +8472,19 @@ stada
 statoil
 
 // stc : 2014-10-09 Saudi Telecom Company
 stc
 
 // stcgroup : 2014-10-09 Saudi Telecom Company
 stcgroup
 
+// stockholm : 2014-12-18 Stockholms kommun
+stockholm
+
 // study : 2014-12-11 OPEN UNIVERSITIES AUSTRALIA PTY LTD
 study
 
 // style : 2014-12-04 Binky Moon, LLC
 style
 
 // supplies : 2013-12-19 Atomic Fields, LLC
 supplies
@@ -8436,16 +8565,19 @@ today
 tokyo
 
 // tools : 2013-11-21 Pioneer North, LLC
 tools
 
 // top : 2014-03-20 Jiangsu Bangning Science & Technology Co.,Ltd.
 top
 
+// toray : 2014-12-18 Toray Industries, Inc.
+toray
+
 // toshiba : 2014-04-10 TOSHIBA Corporation
 toshiba
 
 // town : 2014-03-06 Koko Moon, LLC
 town
 
 // toys : 2014-03-06 Pioneer Orchard, LLC
 toys
@@ -8454,22 +8586,25 @@ toys
 trade
 
 // trading : 2014-12-11 IG Group Holdings PLC
 trading
 
 // training : 2013-11-07 Wild Willow, LLC
 training
 
-// trust : 2014-10-16
+// trust : 2014-10-16  
 trust
 
 // tui : 2014-07-03 TUI AG
 tui
 
+// tushu : 2014-12-18 Amazon EU S.à r.l.
+tushu
+
 // ubs : 2014-12-11 UBS AG
 ubs
 
 // university : 2014-03-06 Little Station, LLC
 university
 
 // uno : 2013-09-11 Dot Latin LLC
 uno
@@ -8487,23 +8622,23 @@ vana
 vegas
 
 // ventures : 2013-08-27 Binky Lake, LLC
 ventures
 
 // versicherung : 2014-03-20 dotversicherung-registry GmbH
 versicherung
 
-// vet : 2014-03-06
+// vet : 2014-03-06  
 vet
 
 // viajes : 2013-10-17 Black Madison, LLC
 viajes
 
-// video : 2014-10-16
+// video : 2014-10-16  
 video
 
 // villas : 2013-12-05 New Sky, LLC
 villas
 
 // virgin : 2014-09-25 Virgin Enterprises Limited
 virgin
 
@@ -8541,16 +8676,19 @@ voyage
 wales
 
 // walter : 2014-11-13 Sandvik AB
 walter
 
 // wang : 2013-10-24 Zodiac Leo Limited
 wang
 
+// wanggou : 2014-12-18 Amazon EU S.à r.l.
+wanggou
+
 // watch : 2013-11-14 Sand Shadow, LLC
 watch
 
 // webcam : 2014-01-23 dot Webcam Limited
 webcam
 
 // website : 2014-04-03 DotWebsite Inc.
 website
@@ -8571,16 +8709,19 @@ wien
 wiki
 
 // williamhill : 2014-03-13 William Hill Organization Limited
 williamhill
 
 // win : 2014-11-20 First Registry Limited
 win
 
+// windows : 2014-12-18 Microsoft Corporation
+windows
+
 // wme : 2014-02-13 William Morris Endeavor Entertainment, LLC
 wme
 
 // work : 2013-12-19 Top Level Domain Holdings Limited
 work
 
 // works : 2013-11-14 Little Dynamite, LLC
 works
@@ -8589,16 +8730,19 @@ works
 world
 
 // wtc : 2013-12-19 World Trade Centers Association, Inc.
 wtc
 
 // wtf : 2014-03-06 Hidden Way, LLC
 wtf
 
+// xbox : 2014-12-18 Microsoft Corporation
+xbox
+
 // xerox : 2014-10-24 Xerox DNHC LLC
 xerox
 
 // xin : 2014-12-11 Elegant Leader Limited
 xin
 
 // xn--1qqw23a : 2014-01-09 Guangzhou YU Wei Information Technology Co., Ltd.
 佛山
@@ -8658,16 +8802,19 @@ xin
 商店
 
 // xn--czru2d : 2013-11-21 Zodiac Capricorn Limited
 商城
 
 // xn--d1acj3b : 2013-11-20 The Foundation for Network Initiatives “The Smart Internet”
 дети
 
+// xn--eckvdtc9d : 2014-12-18 Amazon EU S.à r.l.
+ポイント
+
 // xn--efvy88h : 2014-08-22 Xinhua News Agency Guangdong Branch 新华通讯社广东分社
 新闻
 
 // xn--fiq228c5hs : 2013-09-08 TLD REGISTRY LIMITED
 中文网
 
 // xn--fiq64b : 2013-10-14 CITIC Group Corporation
 中信
@@ -8697,16 +8844,19 @@ xin
 手机
 
 // xn--mgba3a3ejt : 2014-11-20 Aramco Services Company
 ارامكو
 
 // xn--mgbab2bd : 2013-10-31 CORE Association
 بازار
 
+// xn--mgbb9fbpob : 2014-12-18 GreenTech Consultancy Company W.L.L.
+موبايلي
+
 // xn--mgbt3dhd : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
 همراه
 
 // xn--mxtq1m : 2014-03-06 Net-Chinese Co., Ltd.
 政府
 
 // xn--ngbc5azd : 2013-07-13 International Domain Registry Pty. Ltd.
 شبكة
@@ -8760,16 +8910,19 @@ vermögensberatung
 政务
 
 // xyz : 2013-12-05 XYZ.COM LLC
 xyz
 
 // yachts : 2014-01-09 DERYachts, LLC
 yachts
 
+// yamaxun : 2014-12-18 Amazon EU S.à r.l.
+yamaxun
+
 // yandex : 2014-04-10 YANDEX, LLC
 yandex
 
 // yodobashi : 2014-11-20 YODOBASHI CAMERA CO.,LTD.
 yodobashi
 
 // yoga : 2014-05-29 Top Level Domain Holdings Limited
 yoga
@@ -8778,16 +8931,19 @@ yoga
 yokohama
 
 // youtube : 2014-05-01 Charleston Road Registry Inc.
 youtube
 
 // zara : 2014-11-07 Industria de Diseño Textil, S.A. (INDITEX, S.A.)
 zara
 
+// zero : 2014-12-18 Amazon EU S.à r.l.
+zero
+
 // zip : 2014-05-08 Charleston Road Registry Inc.
 zip
 
 // zone : 2013-11-14 Outer Falls, LLC
 zone
 
 // zuerich : 2014-11-07 Kanton Zürich (Canton of Zurich)
 zuerich
--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
@@ -709,16 +709,196 @@ private:
   nsRefPtr<WebSocketChannel>     mChannel;
   nsCOMPtr<nsISocketTransport>   mTransport;
   nsCOMPtr<nsIAsyncInputStream>  mSocketIn;
   nsCOMPtr<nsIAsyncOutputStream> mSocketOut;
 };
 NS_IMPL_ISUPPORTS(CallOnTransportAvailable, nsIRunnable)
 
 //-----------------------------------------------------------------------------
+// PMCECompression
+//-----------------------------------------------------------------------------
+
+class PMCECompression
+{
+public:
+  explicit PMCECompression(bool aNoContextTakeover)
+    : mActive(false)
+    , mNoContextTakeover(aNoContextTakeover)
+    , mResetDeflater(false)
+    , mMessageDeflated(false)
+  {
+    MOZ_COUNT_CTOR(PMCECompression);
+
+    mDeflater.zalloc = mInflater.zalloc = Z_NULL;
+    mDeflater.zfree  = mInflater.zfree  = Z_NULL;
+    mDeflater.opaque = mInflater.opaque = Z_NULL;
+
+    if (deflateInit2(&mDeflater, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -15,
+                     8, Z_DEFAULT_STRATEGY) == Z_OK) {
+      if (inflateInit2(&mInflater, -15) == Z_OK) {
+        mActive = true;
+      } else {
+        deflateEnd(&mDeflater);
+      }
+    }
+  }
+
+  ~PMCECompression()
+  {
+    MOZ_COUNT_DTOR(PMCECompression);
+
+    if (mActive) {
+      inflateEnd(&mInflater);
+      deflateEnd(&mDeflater);
+    }
+  }
+
+  bool Active()
+  {
+    return mActive;
+  }
+
+  void SetMessageDeflated()
+  {
+    MOZ_ASSERT(!mMessageDeflated);
+    mMessageDeflated = true;
+  }
+  bool IsMessageDeflated()
+  {
+    return mMessageDeflated;
+  }
+
+  bool UsingContextTakeover()
+  {
+    return !mNoContextTakeover;
+  }
+
+  nsresult Deflate(uint8_t *data, uint32_t dataLen, nsACString &_retval)
+  {
+    if (mResetDeflater || mNoContextTakeover) {
+      if (deflateReset(&mDeflater) != Z_OK) {
+        return NS_ERROR_UNEXPECTED;
+      }
+      mResetDeflater = false;
+    }
+
+    mDeflater.avail_out = kBufferLen;
+    mDeflater.next_out = mBuffer;
+    mDeflater.avail_in = dataLen;
+    mDeflater.next_in = data;
+
+    while (true) {
+      int zerr = deflate(&mDeflater, Z_SYNC_FLUSH);
+
+      if (zerr != Z_OK) {
+        mResetDeflater = true;
+        return NS_ERROR_UNEXPECTED;
+      }
+
+      uint32_t deflated = kBufferLen - mDeflater.avail_out;
+      if (deflated > 0) {
+        _retval.Append(reinterpret_cast<char *>(mBuffer), deflated);
+      }
+
+      mDeflater.avail_out = kBufferLen;
+      mDeflater.next_out = mBuffer;
+
+      if (mDeflater.avail_in > 0) {
+        continue; // There is still some data to deflate
+      }
+
+      if (deflated == kBufferLen) {
+        continue; // There was not enough space in the buffer
+      }
+
+      break;
+    }
+
+    if (_retval.Length() < 4) {
+      MOZ_ASSERT(false, "Expected trailing not found in deflated data!");
+      mResetDeflater = true;
+      return NS_ERROR_UNEXPECTED;
+    }
+
+    _retval.Truncate(_retval.Length() - 4);
+
+    return NS_OK;
+  }
+
+  nsresult Inflate(uint8_t *data, uint32_t dataLen, nsACString &_retval)
+  {
+    mMessageDeflated = false;
+
+    Bytef trailingData[] = { 0x00, 0x00, 0xFF, 0xFF };
+    bool trailingDataUsed = false;
+
+    mInflater.avail_out = kBufferLen;
+    mInflater.next_out = mBuffer;
+    mInflater.avail_in = dataLen;
+    mInflater.next_in = data;
+
+    while (true) {
+      int zerr = inflate(&mInflater, Z_NO_FLUSH);
+
+      if (zerr == Z_STREAM_END) {
+        Bytef *saveNextIn = mInflater.next_in;
+        uint32_t saveAvailIn = mInflater.avail_in;
+        Bytef *saveNextOut = mInflater.next_out;
+        uint32_t saveAvailOut = mInflater.avail_out;
+
+        inflateReset(&mInflater);
+
+        mInflater.next_in = saveNextIn;
+        mInflater.avail_in = saveAvailIn;
+        mInflater.next_out = saveNextOut;
+        mInflater.avail_out = saveAvailOut;
+      } else if (zerr != Z_OK && zerr != Z_BUF_ERROR) {
+        return NS_ERROR_INVALID_CONTENT_ENCODING;
+      }
+
+      uint32_t inflated = kBufferLen - mInflater.avail_out;
+      if (inflated > 0) {
+        _retval.Append(reinterpret_cast<char *>(mBuffer), inflated);
+      }
+
+      mInflater.avail_out = kBufferLen;
+      mInflater.next_out = mBuffer;
+
+      if (mInflater.avail_in > 0) {
+        continue; // There is still some data to inflate
+      }
+
+      if (inflated == kBufferLen) {
+        continue; // There was not enough space in the buffer
+      }
+
+      if (!trailingDataUsed) {
+        trailingDataUsed = true;
+        mInflater.avail_in = sizeof(trailingData);
+        mInflater.next_in = trailingData;
+        continue;
+      }
+
+      return NS_OK;
+    }
+  }
+
+private:
+  bool                  mActive;
+  bool                  mNoContextTakeover;
+  bool                  mResetDeflater;
+  bool                  mMessageDeflated;
+  z_stream              mDeflater;
+  z_stream              mInflater;
+  const static uint32_t kBufferLen = 4096;
+  uint8_t               mBuffer[kBufferLen];
+};
+
+//-----------------------------------------------------------------------------
 // OutboundMessage
 //-----------------------------------------------------------------------------
 
 enum WsMsgType {
   kMsgTypeString = 0,
   kMsgTypeBinaryString,
   kMsgTypeStream,
   kMsgTypePing,
@@ -734,25 +914,26 @@ static const char* msgNames[] = {
   "pong",
   "close"
 };
 
 class OutboundMessage
 {
 public:
   OutboundMessage(WsMsgType type, nsCString *str)
-    : mMsgType(type)
+    : mMsgType(type), mDeflated(false), mOrigLength(0)
   {
     MOZ_COUNT_CTOR(OutboundMessage);
     mMsg.pString = str;
     mLength = str ? str->Length() : 0;
   }
 
   OutboundMessage(nsIInputStream *stream, uint32_t length)
-    : mMsgType(kMsgTypeStream), mLength(length)
+    : mMsgType(kMsgTypeStream), mLength(length), mDeflated(false)
+    , mOrigLength(0)
   {
     MOZ_COUNT_CTOR(OutboundMessage);
     mMsg.pStream = stream;
     mMsg.pStream->AddRef();
   }
 
  ~OutboundMessage() {
     MOZ_COUNT_DTOR(OutboundMessage);
@@ -772,16 +953,17 @@ public:
         break;
       case kMsgTypeFin:
         break;    // do-nothing: avoid compiler warning
     }
   }
 
   WsMsgType GetMsgType() const { return mMsgType; }
   int32_t Length() const { return mLength; }
+  int32_t OrigLength() const { return mDeflated ? mOrigLength : mLength; }
 
   uint8_t* BeginWriting() {
     NS_ABORT_IF_FALSE(mMsgType != kMsgTypeStream,
                       "Stream should have been converted to string by now");
     return (uint8_t *)(mMsg.pString ? mMsg.pString->BeginWriting() : nullptr);
   }
 
   uint8_t* BeginReading() {
@@ -809,23 +991,67 @@ public:
     mMsg.pStream->Close();
     mMsg.pStream->Release();
     mMsg.pString = temp.forget();
     mMsgType = kMsgTypeBinaryString;
 
     return NS_OK;
   }
 
+  bool DeflatePayload(PMCECompression *aCompressor)
+  {
+    NS_ABORT_IF_FALSE(mMsgType != kMsgTypeStream,
+                      "Stream should have been converted to string by now");
+    MOZ_ASSERT(!mDeflated);
+
+    nsresult rv;
+
+    if (mLength == 0) {
+      // Empty message
+      return false;
+    }
+
+    nsAutoPtr<nsCString> temp(new nsCString());
+    rv = aCompressor->Deflate(BeginReading(), mLength, *temp);
+    if (NS_FAILED(rv)) {
+      LOG(("WebSocketChannel::OutboundMessage: Deflating payload failed "
+           "[rv=0x%08x]\n", rv));
+      return false;
+    }
+
+    if (!aCompressor->UsingContextTakeover() && temp->Length() > mLength) {
+      // When "client_no_context_takeover" was negotiated, do not send deflated
+      // payload if it's larger that the original one. OTOH, it makes sense
+      // to send the larger deflated payload when the sliding window is not
+      // reset between messages because if we would skip some deflated block
+      // we would need to empty the sliding window which could affect the
+      // compression of the subsequent messages.
+      LOG(("WebSocketChannel::OutboundMessage: Not deflating message since the "
+           "deflated payload is larger than the original one [deflated=%d, "
+           "original=%d]", temp->Length(), mLength));
+      return false;
+    }
+
+    mOrigLength = mLength;
+    mDeflated = true;
+    mLength = temp->Length();
+    delete mMsg.pString;
+    mMsg.pString = temp.forget();
+    return true;
+  }
+
 private:
   union {
     nsCString      *pString;
     nsIInputStream *pStream;
   }                           mMsg;
   WsMsgType                   mMsgType;
   uint32_t                    mLength;
+  bool                        mDeflated;
+  uint32_t                    mOrigLength;
 };
 
 //-----------------------------------------------------------------------------
 // OutboundEnqueuer
 //-----------------------------------------------------------------------------
 
 class OutboundEnqueuer MOZ_FINAL : public nsIRunnable
 {
@@ -844,142 +1070,16 @@ public:
 private:
   ~OutboundEnqueuer() {}
 
   nsRefPtr<WebSocketChannel>  mChannel;
   OutboundMessage            *mMessage;
 };
 NS_IMPL_ISUPPORTS(OutboundEnqueuer, nsIRunnable)
 
-//-----------------------------------------------------------------------------
-// nsWSCompression
-//
-// similar to nsDeflateConverter except for the mandatory FLUSH calls
-// required by websocket and the absence of the deflate termination
-// block which is appropriate because it would create data bytes after
-// sending the websockets CLOSE message.
-//-----------------------------------------------------------------------------
-
-class nsWSCompression
-{
-public:
-  nsWSCompression(nsIStreamListener *aListener,
-                  nsISupports *aContext)
-    : mActive(false),
-      mContext(aContext),
-      mListener(aListener)
-  {
-    MOZ_COUNT_CTOR(nsWSCompression);
-
-    mZlib.zalloc = allocator;
-    mZlib.zfree = destructor;
-    mZlib.opaque = Z_NULL;
-
-    // Initialize the compressor - these are all the normal zlib
-    // defaults except window size is set to -15 instead of +15.
-    // This is the zlib way of specifying raw RFC 1951 output instead
-    // of the zlib rfc 1950 format which has a 2 byte header and
-    // adler checksum as a trailer
-
-    nsresult rv;
-    mStream = do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID, &rv);
-    if (NS_SUCCEEDED(rv) && aContext && aListener &&
-      deflateInit2(&mZlib, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -15, 8,
-                   Z_DEFAULT_STRATEGY) == Z_OK) {
-      mActive = true;
-    }
-  }
-
-  ~nsWSCompression()
-  {
-    MOZ_COUNT_DTOR(nsWSCompression);
-
-    if (mActive)
-      deflateEnd(&mZlib);
-  }
-
-  bool Active()
-  {
-    return mActive;
-  }
-
-  nsresult Deflate(uint8_t *buf1, uint32_t buf1Len,
-                   uint8_t *buf2, uint32_t buf2Len)
-  {
-    NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread,
-                          "not socket thread");
-    NS_ABORT_IF_FALSE(mActive, "not active");
-
-    mZlib.avail_out = kBufferLen;
-    mZlib.next_out = mBuffer;
-    mZlib.avail_in = buf1Len;
-    mZlib.next_in = buf1;
-
-    nsresult rv;
-
-    while (mZlib.avail_in > 0) {
-      deflate(&mZlib, (buf2Len > 0) ? Z_NO_FLUSH : Z_SYNC_FLUSH);
-      rv = PushData();
-      if (NS_FAILED(rv))
-        return rv;
-      mZlib.avail_out = kBufferLen;
-      mZlib.next_out = mBuffer;
-    }
-
-    mZlib.avail_in = buf2Len;
-    mZlib.next_in = buf2;
-
-    while (mZlib.avail_in > 0) {
-      deflate(&mZlib, Z_SYNC_FLUSH);
-      rv = PushData();
-      if (NS_FAILED(rv))
-        return rv;
-      mZlib.avail_out = kBufferLen;
-      mZlib.next_out = mBuffer;
-    }
-
-    return NS_OK;
-  }
-
-private:
-
-  // use zlib data types
-  static void *allocator(void *opaque, uInt items, uInt size)
-  {
-    return moz_xmalloc(items * size);
-  }
-
-  static void destructor(void *opaque, void *addr)
-  {
-    moz_free(addr);
-  }
-
-  nsresult PushData()
-  {
-    uint32_t bytesToWrite = kBufferLen - mZlib.avail_out;
-    if (bytesToWrite > 0) {
-      mStream->ShareData(reinterpret_cast<char *>(mBuffer), bytesToWrite);
-      nsresult rv =
-        mListener->OnDataAvailable(nullptr, mContext, mStream, 0, bytesToWrite);
-      if (NS_FAILED(rv))
-        return rv;
-    }
-    return NS_OK;
-  }
-
-  bool                            mActive;
-  z_stream                        mZlib;
-  nsCOMPtr<nsIStringInputStream>  mStream;
-
-  nsISupports                    *mContext;     /* weak ref */
-  nsIStreamListener              *mListener;    /* weak ref */
-
-  const static int32_t            kBufferLen = 4096;
-  uint8_t                         mBuffer[kBufferLen];
-};
 
 //-----------------------------------------------------------------------------
 // WebSocketChannel
 //-----------------------------------------------------------------------------
 
 uint32_t WebSocketChannel::sSerialSeed = 0;
 
 WebSocketChannel::WebSocketChannel() :
@@ -991,35 +1091,34 @@ WebSocketChannel::WebSocketChannel() :
   mGotUpgradeOK(0),
   mRecvdHttpUpgradeTransport(0),
   mRequestedClose(0),
   mClientClosed(0),
   mServerClosed(0),
   mStopped(0),
   mCalledOnStop(0),
   mPingOutstanding(0),
-  mAllowCompression(1),
   mAutoFollowRedirects(0),
   mReleaseOnTransmit(0),
   mTCPClosed(0),
   mOpenedHttpChannel(0),
   mDataStarted(0),
   mIncrementedSessionCount(0),
   mDecrementedSessionCount(0),
+  mAllowPMCE(1),
   mMaxMessageSize(INT32_MAX),
   mStopOnClose(NS_OK),
   mServerCloseCode(CLOSE_ABNORMAL),
   mScriptCloseCode(0),
   mFragmentOpcode(kContinuation),
   mFragmentAccumulator(0),
   mBuffered(0),
   mBufferSize(kIncomingBufferInitialSize),
   mCurrentOut(nullptr),
   mCurrentOutSent(0),
-  mCompressor(nullptr),
   mDynamicOutputSize(0),
   mDynamicOutput(nullptr),
   mPrivateBrowsing(false),
   mConnectionLogService(nullptr),
   mCountRecv(0),
   mCountSent(0),
   mAppId(NECKO_NO_APP_ID)
 {
@@ -1047,17 +1146,16 @@ WebSocketChannel::~WebSocketChannel()
     MOZ_ASSERT(mCalledOnStop, "WebSocket was opened but OnStop was not called");
     MOZ_ASSERT(mStopped, "WebSocket was opened but never stopped");
   }
   MOZ_ASSERT(!mCancelable, "DNS/Proxy Request still alive at destruction");
   MOZ_ASSERT(!mConnecting, "Should not be connecting in destructor");
 
   moz_free(mBuffer);
   moz_free(mDynamicOutput);
-  delete mCompressor;
   delete mCurrentOut;
 
   while ((mCurrentOut = (OutboundMessage *) mOutgoingPingMessages.PopFront()))
     delete mCurrentOut;
   while ((mCurrentOut = (OutboundMessage *) mOutgoingPongMessages.PopFront()))
     delete mCurrentOut;
   while ((mCurrentOut = (OutboundMessage *) mOutgoingMessages.PopFront()))
     delete mCurrentOut;
@@ -1310,16 +1408,18 @@ WebSocketChannel::UpdateReadBuffer(uint8
 }
 
 nsresult
 WebSocketChannel::ProcessInput(uint8_t *buffer, uint32_t count)
 {
   LOG(("WebSocketChannel::ProcessInput %p [%d %d]\n", this, count, mBuffered));
   NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "not socket thread");
 
+  nsresult rv;
+
   // The purpose of ping/pong is to actively probe the peer so that an
   // unreachable peer is not mistaken for a period of idleness. This
   // implementation accepts any application level read activity as a sign of
   // life, it does not necessarily have to be a pong.
   ResetPingTimer();
 
   uint32_t avail;
 
@@ -1335,17 +1435,17 @@ WebSocketChannel::ProcessInput(uint8_t *
   }
 
   uint8_t *payload;
   uint32_t totalAvail = avail;
 
   while (avail >= 2) {
     int64_t payloadLength64 = mFramePtr[1] & 0x7F;
     uint8_t finBit  = mFramePtr[0] & kFinalFragBit;
-    uint8_t rsvBits = mFramePtr[0] & 0x70;
+    uint8_t rsvBits = mFramePtr[0] & kRsvBitsMask;
     uint8_t maskBit = mFramePtr[1] & kMaskBit;
     uint8_t opcode  = mFramePtr[0] & 0x0F;
 
     uint32_t framingLength = 2;
     if (maskBit)
       framingLength += 4;
 
     if (payloadLength64 < 126) {
@@ -1403,18 +1503,27 @@ WebSocketChannel::ProcessInput(uint8_t *
 
     // Control codes are required to have the fin bit set
     if (!finBit && (opcode & kControlFrameMask)) {
       LOG(("WebSocketChannel:: fragmented control frame code %d\n", opcode));
       return NS_ERROR_ILLEGAL_VALUE;
     }
 
     if (rsvBits) {
-      LOG(("WebSocketChannel:: unexpected reserved bits %x\n", rsvBits));
-      return NS_ERROR_ILLEGAL_VALUE;
+      // PMCE sets RSV1 bit in the first fragment when the non-control frame
+      // is deflated
+      if (mPMCECompressor && rsvBits == kRsv1Bit && mFragmentAccumulator == 0 &&
+          !(opcode & kControlFrameMask)) {
+        mPMCECompressor->SetMessageDeflated();
+        LOG(("WebSocketChannel::ProcessInput: received deflated frame\n"));
+      } else {
+        LOG(("WebSocketChannel::ProcessInput: unexpected reserved bits %x\n",
+             rsvBits));
+        return NS_ERROR_ILLEGAL_VALUE;
+      }
     }
 
     if (!finBit || opcode == kContinuation) {
       // This is part of a fragment response
 
       // Only the first frame has a non zero op code: Make sure we don't see a
       // first frame while some old fragments are open
       if ((mFragmentAccumulator != 0) && (opcode != kContinuation)) {
@@ -1468,22 +1577,37 @@ WebSocketChannel::ProcessInput(uint8_t *
     if (mServerClosed) {
       LOG(("WebSocketChannel:: ignoring read frame code %d after close\n",
                  opcode));
       // nop
     } else if (mStopped) {
       LOG(("WebSocketChannel:: ignoring read frame code %d after completion\n",
            opcode));
     } else if (opcode == kText) {
-      LOG(("WebSocketChannel:: text frame received\n"));
+      bool isDeflated = mPMCECompressor && mPMCECompressor->IsMessageDeflated();
+      LOG(("WebSocketChannel:: %stext frame received\n",
+           isDeflated ? "deflated " : ""));
+
       if (mListener) {
         nsCString utf8Data;
-        if (!utf8Data.Assign((const char *)payload, payloadLength,
-                             mozilla::fallible_t()))
-          return NS_ERROR_OUT_OF_MEMORY;
+
+        if (isDeflated) {
+          rv = mPMCECompressor->Inflate(payload, payloadLength, utf8Data);
+          if (NS_FAILED(rv)) {
+            return rv;
+          }
+          LOG(("WebSocketChannel:: message successfully inflated "
+               "[origLength=%d, newLength=%d]\n", payloadLength,
+               utf8Data.Length()));
+        } else {
+          if (!utf8Data.Assign((const char *)payload, payloadLength,
+                               mozilla::fallible_t())) {
+            return NS_ERROR_OUT_OF_MEMORY;
+          }
+        }
 
         // Section 8.1 says to fail connection if invalid utf-8 in text message
         if (!IsUTF8(utf8Data, false)) {
           LOG(("WebSocketChannel:: text frame invalid utf-8\n"));
           return NS_ERROR_CANNOT_CONVERT_DATA;
         }
 
         mTargetThread->Dispatch(new CallOnMessageAvailable(this, utf8Data, -1),
@@ -1563,22 +1687,41 @@ WebSocketChannel::ProcessInput(uint8_t *
         ::memmove(mFramePtr, payload + payloadLength, avail - payloadLength);
         payload = mFramePtr;
         avail -= payloadLength;
         if (mBuffered)
           mBuffered -= framingLength + payloadLength;
         payloadLength = 0;
       }
     } else if (opcode == kBinary) {
-      LOG(("WebSocketChannel:: binary frame received\n"));
+      bool isDeflated = mPMCECompressor && mPMCECompressor->IsMessageDeflated();
+      LOG(("WebSocketChannel:: %sbinary frame received\n",
+           isDeflated ? "deflated " : ""));
+
       if (mListener) {
-        nsCString binaryData((const char *)payload, payloadLength);
-        mTargetThread->Dispatch(new CallOnMessageAvailable(this, binaryData,
-                                                           payloadLength),
-                                NS_DISPATCH_NORMAL);
+        nsCString binaryData;
+
+        if (isDeflated) {
+          rv = mPMCECompressor->Inflate(payload, payloadLength, binaryData);
+          if (NS_FAILED(rv)) {
+            return rv;
+          }
+          LOG(("WebSocketChannel:: message successfully inflated "
+               "[origLength=%d, newLength=%d]\n", payloadLength,
+               binaryData.Length()));
+        } else {
+          if (!binaryData.Assign((const char *)payload, payloadLength,
+                                 mozilla::fallible_t())) {
+            return NS_ERROR_OUT_OF_MEMORY;
+          }
+        }
+
+        mTargetThread->Dispatch(
+          new CallOnMessageAvailable(this, binaryData, binaryData.Length()),
+          NS_DISPATCH_NORMAL);
         // To add the header to 'Networking Dashboard' log
         if (mConnectionLogService && !mPrivateBrowsing) {
           mConnectionLogService->NewMsgReceived(mHost, mSerial, count);
           LOG(("Added new received msg for %s", mHost.get()));
         }
       }
     } else if (opcode != kContinuation) {
       /* unknown opcode */
@@ -1853,16 +1996,29 @@ WebSocketChannel::PrimeNewOutgoingMessag
     case kMsgTypeBinaryString:
       mOutHeader[0] = kFinalFragBit | kBinary;
       break;
     case kMsgTypeFin:
       NS_ABORT_IF_FALSE(false, "unreachable");  // avoid compiler warning
       break;
     }
 
+    // deflate the payload if PMCE is negotiated
+    if (mPMCECompressor &&
+        (msgType == kMsgTypeString || msgType == kMsgTypeBinaryString)) {
+      if (mCurrentOut->DeflatePayload(mPMCECompressor)) {
+        // The payload was deflated successfully, set RSV1 bit
+        mOutHeader[0] |= kRsv1Bit;
+
+        LOG(("WebSocketChannel::PrimeNewOutgoingMessage %p current msg %p was "
+             "deflated [origLength=%d, newLength=%d].\n", this, mCurrentOut,
+             mCurrentOut->OrigLength(), mCurrentOut->Length()));
+      }
+    }
+
     if (mCurrentOut->Length() < 126) {
       mOutHeader[1] = mCurrentOut->Length() | kMaskBit;
       mHdrOutToSend = 6;
     } else if (mCurrentOut->Length() <= 0xffff) {
       mOutHeader[1] = 126 | kMaskBit;
       NetworkEndian::writeUint16(mOutHeader + sizeof(uint16_t),
                                  mCurrentOut->Length());
       mHdrOutToSend = 8;
@@ -1914,32 +2070,16 @@ WebSocketChannel::PrimeNewOutgoingMessag
 
   // for small frames, copy it all together for a contiguous write
   if (len && len <= kCopyBreak) {
     memcpy(mOutHeader + mHdrOutToSend, mCurrentOut->BeginWriting(), len);
     mHdrOutToSend += len;
     mCurrentOutSent = len;
   }
 
-  if (len && mCompressor) {
-    // assume a 1/3 reduction in size for sizing the buffer
-    // the buffer is used multiple times if necessary
-    uint32_t currentHeaderSize = mHdrOutToSend;
-    mHdrOutToSend = 0;
-
-    EnsureHdrOut(32 + (currentHeaderSize + len - mCurrentOutSent) / 2 * 3);
-    mCompressor->Deflate(mOutHeader, currentHeaderSize,
-                         mCurrentOut->BeginReading() + mCurrentOutSent,
-                         len - mCurrentOutSent);
-
-    // All of the compressed data now resides in {mHdrOut, mHdrOutToSend}
-    // so do not send the body again
-    mCurrentOutSent = len;
-  }
-
   // Transmitting begins - mHdrOutToSend bytes from mOutHeader and
   // mCurrentOut->Length() bytes from mCurrentOut. The latter may be
   // coaleseced into the former for small messages or as the result of the
   // compression process,
 }
 
 void
 WebSocketChannel::DeleteCurrentOutGoingMessage()
@@ -2116,21 +2256,17 @@ WebSocketChannel::StopSession(nsresult r
     CleanupConnection();
   }
 
   if (mCancelable) {
     mCancelable->Cancel(NS_ERROR_UNEXPECTED);
     mCancelable = nullptr;
   }
 
-  mInflateReader = nullptr;
-  mInflateStream = nullptr;
-
-  delete mCompressor;
-  mCompressor = nullptr;
+  mPMCECompressor = nullptr;
 
   if (!mCalledOnStop) {
     mCalledOnStop = 1;
     mTargetThread->Dispatch(new CallOnStop(this, reason),
                             NS_DISPATCH_NORMAL);
   }
 }
 
@@ -2213,65 +2349,81 @@ WebSocketChannel::HandleExtensions()
   nsresult rv;
   nsAutoCString extensions;
 
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
 
   rv = mHttpChannel->GetResponseHeader(
     NS_LITERAL_CSTRING("Sec-WebSocket-Extensions"), extensions);
   if (NS_SUCCEEDED(rv)) {
+    LOG(("WebSocketChannel::HandleExtensions: received "
+         "Sec-WebSocket-Extensions header: %s\n", extensions.get()));
+
+    extensions.CompressWhitespace();
+
     if (!extensions.IsEmpty()) {
-      if (!extensions.EqualsLiteral("deflate-stream")) {
-        LOG(("WebSocketChannel::OnStartRequest: "
-             "HTTP Sec-WebSocket-Exensions negotiated unknown value %s\n",
+      if (StringBeginsWith(extensions,
+                           NS_LITERAL_CSTRING("permessage-deflate"))) {
+        if (!mAllowPMCE) {
+          LOG(("WebSocketChannel::HandleExtensions: "
+               "Recvd permessage-deflate which wasn't offered\n"));
+          AbortSession(NS_ERROR_ILLEGAL_VALUE);
+          return NS_ERROR_ILLEGAL_VALUE;
+        }
+
+        nsAutoCString param;
+
+        int32_t delimPos = extensions.FindChar(';');
+        if (delimPos != kNotFound) {
+          param = Substring(extensions, delimPos + 1);
+          param.CompressWhitespace(true, false);
+          extensions.Truncate(delimPos);
+          extensions.CompressWhitespace(false, true);
+        }
+ 
+        if (!extensions.EqualsLiteral("permessage-deflate")) {
+          LOG(("WebSocketChannel::HandleExtensions: "
+               "HTTP Sec-WebSocket-Extensions negotiated unknown value %s\n",
+               extensions.get()));
+          AbortSession(NS_ERROR_ILLEGAL_VALUE);
+          return NS_ERROR_ILLEGAL_VALUE;
+        }
+
+        bool noContextTakeover = false;
+        if (!param.IsEmpty()) {
+          if (param.EqualsLiteral("client_no_context_takeover")) {
+            noContextTakeover = true;
+          } else {
+            LOG(("WebSocketChannel::HandleExtensions: "
+                 "HTTP permessage-deflate extension negotiated unknown "
+                 "parameter %s\n", param.get()));
+            AbortSession(NS_ERROR_ILLEGAL_VALUE);
+            return NS_ERROR_ILLEGAL_VALUE;
+          }
+        }
+
+        mPMCECompressor = new PMCECompression(noContextTakeover);
+        if (mPMCECompressor->Active()) {
+          LOG(("WebSocketChannel::HandleExtensions: PMCE negotiated, %susing "
+               "context takeover\n", noContextTakeover ? "NOT " : ""));
+        } else {
+          LOG(("WebSocketChannel::HandleExtensions: Cannot init PMCE "
+               "compression object\n"));
+          mPMCECompressor = nullptr;
+          AbortSession(NS_ERROR_UNEXPECTED);
+          return NS_ERROR_UNEXPECTED;
+        }
+      } else {
+        LOG(("WebSocketChannel::HandleExtensions: "
+             "HTTP Sec-WebSocket-Extensions negotiated unknown value %s\n",
              extensions.get()));
         AbortSession(NS_ERROR_ILLEGAL_VALUE);
         return NS_ERROR_ILLEGAL_VALUE;
       }
 
-      if (!mAllowCompression) {
-        LOG(("WebSocketChannel::HandleExtensions: "
-             "Recvd Compression Extension that wasn't offered\n"));
-        AbortSession(NS_ERROR_ILLEGAL_VALUE);
-        return NS_ERROR_ILLEGAL_VALUE;
-      }
-
-      nsCOMPtr<nsIStreamConverterService> serv =
-        do_GetService(NS_STREAMCONVERTERSERVICE_CONTRACTID, &rv);
-      if (NS_FAILED(rv)) {
-        LOG(("WebSocketChannel:: Cannot find compression service\n"));
-        AbortSession(NS_ERROR_UNEXPECTED);
-        return NS_ERROR_UNEXPECTED;
-      }
-
-      rv = serv->AsyncConvertData("deflate", "uncompressed", this, nullptr,
-                                  getter_AddRefs(mInflateReader));
-
-      if (NS_FAILED(rv)) {
-        LOG(("WebSocketChannel:: Cannot find inflate listener\n"));
-        AbortSession(NS_ERROR_UNEXPECTED);
-        return NS_ERROR_UNEXPECTED;
-      }
-
-      mInflateStream = do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID, &rv);
-
-      if (NS_FAILED(rv)) {
-        LOG(("WebSocketChannel:: Cannot find inflate stream\n"));
-        AbortSession(NS_ERROR_UNEXPECTED);
-        return NS_ERROR_UNEXPECTED;
-      }
-
-      mCompressor = new nsWSCompression(this, mSocketOut);
-      if (!mCompressor->Active()) {
-        LOG(("WebSocketChannel:: Cannot init deflate object\n"));
-        delete mCompressor;
-        mCompressor = nullptr;
-        AbortSession(NS_ERROR_UNEXPECTED);
-        return NS_ERROR_UNEXPECTED;
-      }
       mNegotiatedExtensions = extensions;
     }
   }
 
   return NS_OK;
 }
 
 nsresult
@@ -2311,19 +2463,19 @@ WebSocketChannel::SetupRequest()
   if (!mOrigin.IsEmpty())
     mHttpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Origin"), mOrigin,
                                    false);
 
   if (!mProtocol.IsEmpty())
     mHttpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Sec-WebSocket-Protocol"),
                                    mProtocol, true);
 
-  if (mAllowCompression)
+  if (mAllowPMCE)
     mHttpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Sec-WebSocket-Extensions"),
-                                   NS_LITERAL_CSTRING("deflate-stream"),
+                                   NS_LITERAL_CSTRING("permessage-deflate"),
                                    false);
 
   uint8_t      *secKey;
   nsAutoCString secKeyString;
 
   rv = mRandomGenerator->GenerateRandomBytes(16, &secKey);
   NS_ENSURE_SUCCESS(rv, rv);
   char* b64 = PL_Base64Encode((const char *)secKey, 16, nullptr);
@@ -2838,20 +2990,20 @@ WebSocketChannel::AsyncOpen(nsIURI *aURI
     if (NS_SUCCEEDED(rv) && !mClientSetPingInterval) {
       mPingInterval = clamped(intpref, 0, 86400) * 1000;
     }
     rv = prefService->GetIntPref("network.websocket.timeout.ping.response",
                                  &intpref);
     if (NS_SUCCEEDED(rv) && !mClientSetPingTimeout) {
       mPingResponseTimeout = clamped(intpref, 1, 3600) * 1000;
     }
-    rv = prefService->GetBoolPref("network.websocket.extensions.stream-deflate",
+    rv = prefService->GetBoolPref("network.websocket.extensions.permessage-deflate",
                                   &boolpref);
     if (NS_SUCCEEDED(rv)) {
-      mAllowCompression = boolpref ? 1 : 0;
+      mAllowPMCE = boolpref ? 1 : 0;
     }
     rv = prefService->GetBoolPref("network.websocket.auto-follow-http-redirects",
                                   &boolpref);
     if (NS_SUCCEEDED(rv)) {
       mAutoFollowRedirects = boolpref ? 1 : 0;
     }
     rv = prefService->GetIntPref
       ("network.websocket.max-connections", &intpref);
@@ -3288,21 +3440,18 @@ WebSocketChannel::OnStopRequest(nsIReque
 NS_IMETHODIMP
 WebSocketChannel::OnInputStreamReady(nsIAsyncInputStream *aStream)
 {
   LOG(("WebSocketChannel::OnInputStreamReady() %p\n", this));
   NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "not socket thread");
 
   if (!mSocketIn) // did we we clean up the socket after scheduling InputReady?
     return NS_OK;
-  
-  nsRefPtr<nsIStreamListener>    deleteProtector1(mInflateReader);
-  nsRefPtr<nsIStringInputStream> deleteProtector2(mInflateStream);
-
-  // this is after the  http upgrade - so we are speaking websockets
+
+  // this is after the http upgrade - so we are speaking websockets
   char  buffer[2048];
   uint32_t count;
   nsresult rv;
 
   do {
     rv = mSocketIn->Read((char *)buffer, 2048, &count);
     LOG(("WebSocketChannel::OnInputStreamReady: read %u rv %x\n", count, rv));
 
@@ -3325,24 +3474,17 @@ WebSocketChannel::OnInputStreamReady(nsI
       AbortSession(NS_BASE_STREAM_CLOSED);
       return NS_OK;
     }
 
     if (mStopped) {
       continue;
     }
 
-    if (mInflateReader) {
-      mInflateStream->ShareData(buffer, count);
-      rv = mInflateReader->OnDataAvailable(nullptr, mSocketIn, mInflateStream, 
-                                           0, count);
-    } else {
-      rv = ProcessInput((uint8_t *)buffer, count);
-    }
-
+    rv = ProcessInput((uint8_t *)buffer, count);
     if (NS_FAILED(rv)) {
       AbortSession(rv);
       return rv;
     }
   } while (NS_SUCCEEDED(rv) && mSocketIn);
 
   return NS_OK;
 }
@@ -3407,19 +3549,19 @@ WebSocketChannel::OnOutputStreamReady(ns
       } else {
         mHdrOut += amtSent;
         mHdrOutToSend -= amtSent;
         mSocketOut->AsyncWait(this, 0, 0, mSocketThread);
       }
     } else {
       if (amtSent == toSend) {
         if (!mStopped) {
-          mTargetThread->Dispatch(new CallAcknowledge(this,
-                                                      mCurrentOut->Length()),
-                                  NS_DISPATCH_NORMAL);
+          mTargetThread->Dispatch(
+            new CallAcknowledge(this, mCurrentOut->OrigLength()),
+            NS_DISPATCH_NORMAL);
         }
         DeleteCurrentOutGoingMessage();
         PrimeNewOutgoingMessage();
       } else {
         mCurrentOutSent += amtSent;
         mSocketOut->AsyncWait(this, 0, 0, mSocketThread);
       }
     }
@@ -3437,84 +3579,20 @@ WebSocketChannel::OnDataAvailable(nsIReq
                                     nsISupports *aContext,
                                     nsIInputStream *aInputStream,
                                     uint64_t aOffset,
                                     uint32_t aCount)
 {
   LOG(("WebSocketChannel::OnDataAvailable() %p [%p %p %p %llu %u]\n",
          this, aRequest, aContext, aInputStream, aOffset, aCount));
 
-  if (aContext == mSocketIn) {
-    // This is the deflate decoder
-
-    LOG(("WebSocketChannel::OnDataAvailable: Deflate Data %u\n",
-             aCount));
-
-    uint8_t  buffer[2048];
-    uint32_t maxRead;
-    uint32_t count;
-    nsresult rv = NS_OK;  // aCount always > 0, so this just avoids warning
-
-    while (aCount > 0) {
-      if (mStopped)
-        return NS_BASE_STREAM_CLOSED;
-
-      maxRead = std::min(2048U, aCount);
-      rv = aInputStream->Read((char *)buffer, maxRead, &count);
-      LOG(("WebSocketChannel::OnDataAvailable: InflateRead read %u rv %x\n",
-           count, rv));
-      if (NS_FAILED(rv) || count == 0) {
-        AbortSession(NS_ERROR_UNEXPECTED);
-        break;
-      }
-
-      aCount -= count;
-      rv = ProcessInput(buffer, count);
-      if (NS_FAILED(rv)) {
-        AbortSession(rv);
-        break;
-      }
-    }
-    return rv;
-  }
-
-  if (aContext == mSocketOut) {
-    // This is the deflate encoder
-
-    uint32_t maxRead;
-    uint32_t count;
-    nsresult rv;
-
-    while (aCount > 0) {
-      if (mStopped)
-        return NS_BASE_STREAM_CLOSED;
-
-      maxRead = std::min(2048U, aCount);
-      EnsureHdrOut(mHdrOutToSend + aCount);
-      rv = aInputStream->Read((char *)mHdrOut + mHdrOutToSend, maxRead, &count);
-      LOG(("WebSocketChannel::OnDataAvailable: DeflateWrite read %u rv %x\n", 
-           count, rv));
-      if (NS_FAILED(rv) || count == 0) {
-        AbortSession(rv);
-        break;
-      }
-
-      mHdrOutToSend += count;
-      aCount -= count;
-    }
-    return NS_OK;
-  }
-
-
-  // Otherwise, this is the HTTP OnDataAvailable Method, which means
-  // this is http data in response to the upgrade request and
-  // there should be no http response body if the upgrade succeeded
-
-  // This generally should be caught by a non 101 response code in
-  // OnStartRequest().. so we can ignore the data here
+  // This is the HTTP OnDataAvailable Method, which means this is http data in
+  // response to the upgrade request and there should be no http response body
+  // if the upgrade succeeded. This generally should be caught by a non 101
+  // response code in OnStartRequest().. so we can ignore the data here
 
   LOG(("WebSocketChannel::OnDataAvailable: HTTP data unexpected len>=%u\n",
          aCount));
 
   return NS_OK;
 }
 
 nsresult
--- a/netwerk/protocol/websocket/WebSocketChannel.h
+++ b/netwerk/protocol/websocket/WebSocketChannel.h
@@ -38,17 +38,17 @@ class nsIRandomGenerator;
 class nsISocketTransport;
 class nsIURI;
 
 namespace mozilla { namespace net {
 
 class OutboundMessage;
 class OutboundEnqueuer;
 class nsWSAdmissionManager;
-class nsWSCompression;
+class PMCECompression;
 class CallOnMessageAvailable;
 class CallOnStop;
 class CallOnServerClose;
 class CallAcknowledge;
 
 // Used to enforce "1 connecting websocket per host" rule, and reconnect delays
 enum wsConnectingState {
   NOT_CONNECTING = 0,     // Not yet (or no longer) trying to open connection
@@ -113,16 +113,18 @@ public:
     kClose =        0x8,
     kPing =         0x9,
     kPong =         0xA
   };
 
   const static uint32_t kControlFrameMask   = 0x8;
   const static uint8_t kMaskBit             = 0x80;
   const static uint8_t kFinalFragBit        = 0x80;
+  const static uint8_t kRsvBitsMask         = 0x70;
+  const static uint8_t kRsv1Bit             = 0x40;
 
 protected:
   virtual ~WebSocketChannel();
 
 private:
   friend class OutboundEnqueuer;
   friend class nsWSAdmissionManager;
   friend class FailDelayManager;
@@ -216,24 +218,24 @@ private:
   uint32_t                        mGotUpgradeOK              : 1;
   uint32_t                        mRecvdHttpUpgradeTransport : 1;
   uint32_t                        mRequestedClose            : 1;
   uint32_t                        mClientClosed              : 1;
   uint32_t                        mServerClosed              : 1;
   uint32_t                        mStopped                   : 1;
   uint32_t                        mCalledOnStop              : 1;
   uint32_t                        mPingOutstanding           : 1;
-  uint32_t                        mAllowCompression          : 1;
   uint32_t                        mAutoFollowRedirects       : 1;
   uint32_t                        mReleaseOnTransmit         : 1;
   uint32_t                        mTCPClosed                 : 1;
   uint32_t                        mOpenedHttpChannel         : 1;
   uint32_t                        mDataStarted               : 1;
   uint32_t                        mIncrementedSessionCount   : 1;
   uint32_t                        mDecrementedSessionCount   : 1;
+  uint32_t                        mAllowPMCE                 : 1;
 
   int32_t                         mMaxMessageSize;
   nsresult                        mStopOnClose;
   uint16_t                        mServerCloseCode;
   nsCString                       mServerCloseReason;
   uint16_t                        mScriptCloseCode;
   nsCString                       mScriptCloseReason;
 
@@ -245,31 +247,29 @@ private:
   const static uint32_t kIncomingBufferStableSize = 128 * 1024;
 
   uint8_t                        *mFramePtr;
   uint8_t                        *mBuffer;
   uint8_t                         mFragmentOpcode;
   uint32_t                        mFragmentAccumulator;
   uint32_t                        mBuffered;
   uint32_t                        mBufferSize;
-  nsCOMPtr<nsIStreamListener>     mInflateReader;
-  nsCOMPtr<nsIStringInputStream>  mInflateStream;
 
   // These are for the send buffers
   const static int32_t kCopyBreak = 1000;
 
   OutboundMessage                *mCurrentOut;
   uint32_t                        mCurrentOutSent;
   nsDeque                         mOutgoingMessages;
   nsDeque                         mOutgoingPingMessages;
   nsDeque                         mOutgoingPongMessages;
   uint32_t                        mHdrOutToSend;
   uint8_t                        *mHdrOut;
   uint8_t                         mOutHeader[kCopyBreak + 16];
-  nsWSCompression                *mCompressor;
+  nsAutoPtr<PMCECompression>      mPMCECompressor;
   uint32_t                        mDynamicOutputSize;
   uint8_t                        *mDynamicOutput;
   bool                            mPrivateBrowsing;
 
   nsCOMPtr<nsIDashboardEventNotifier> mConnectionLogService;
   uint32_t mSerial;
   static uint32_t sSerialSeed;
 
--- a/netwerk/test/browser/browser_NetUtil.js
+++ b/netwerk/test/browser/browser_NetUtil.js
@@ -23,45 +23,61 @@ function nextTest() {
 }
 
 var tests = [
   test_asyncFetchBadCert,
 ];
 
 function test_asyncFetchBadCert() {
   // Try a load from an untrusted cert, with errors supressed
-  NetUtil.asyncFetch("https://untrusted.example.com", function (aInputStream, aStatusCode, aRequest) {
+  NetUtil.asyncFetch2("https://untrusted.example.com", function (aInputStream, aStatusCode, aRequest) {
     ok(!Components.isSuccessCode(aStatusCode), "request failed");
     ok(aRequest instanceof Ci.nsIHttpChannel, "request is an nsIHttpChannel");
 
     // Now try again with a channel whose notificationCallbacks doesn't suprress errors
-    let channel = NetUtil.newChannel("https://untrusted.example.com");
+    let channel = NetUtil.newChannel2("https://untrusted.example.com",
+                                      null,
+                                      null,
+                                      null,      // aLoadingNode
+                                      Services.scriptSecurityManager.getSystemPrincipal(),
+                                      null,      // aTriggeringPrincipal
+                                      Ci.nsILoadInfo.SEC_NORMAL,
+                                      Ci.nsIContentPolicy.TYPE_OTHER);
     channel.notificationCallbacks = {
       QueryInterface: XPCOMUtils.generateQI([Ci.nsIProgressEventSink,
                                              Ci.nsIInterfaceRequestor]),
       getInterface: function (aIID) this.QueryInterface(aIID),
       onProgress: function () {},
       onStatus: function () {}
     };
-    NetUtil.asyncFetch(channel, function (aInputStream, aStatusCode, aRequest) {
+    NetUtil.asyncFetch2(channel, function (aInputStream, aStatusCode, aRequest) {
       ok(!Components.isSuccessCode(aStatusCode), "request failed");
       ok(aRequest instanceof Ci.nsIHttpChannel, "request is an nsIHttpChannel");
 
       // Now try a valid request
-      NetUtil.asyncFetch("https://example.com", function (aInputStream, aStatusCode, aRequest) {
+      NetUtil.asyncFetch2("https://example.com", function (aInputStream, aStatusCode, aRequest) {
         info("aStatusCode for valid request: " + aStatusCode);
         ok(Components.isSuccessCode(aStatusCode), "request succeeded");
         ok(aRequest instanceof Ci.nsIHttpChannel, "request is an nsIHttpChannel");
         ok(aRequest.requestSucceeded, "HTTP request succeeded");
   
         nextTest();
-      });
+      },
+      null,      // aLoadingNode
+      Services.scriptSecurityManager.getSystemPrincipal(),
+      null,      // aTriggeringPrincipal
+      Ci.nsILoadInfo.SEC_NORMAL,
+      Ci.nsIContentPolicy.TYPE_OTHER);
     });
-
-  });
+  },
+  null,      // aLoadingNode
+  Services.scriptSecurityManager.getSystemPrincipal(),
+  null,      // aTriggeringPrincipal
+  Ci.nsILoadInfo.SEC_NORMAL,
+  Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 function WindowListener(aURL, aCallback) {
   this.callback = aCallback;
   this.url = aURL;
 }
 WindowListener.prototype = {
   onOpenWindow: function(aXULWindow) {
--- a/netwerk/test/httpserver/test/head_utils.js
+++ b/netwerk/test/httpserver/test/head_utils.js
@@ -8,16 +8,17 @@
  * Loads _HTTPD_JS_PATH file, which is dynamically defined by
  * <runxpcshelltests.py>.
  */
 load(_HTTPD_JS_PATH);
 
 // if these tests fail, we'll want the debug output
 DEBUG = true;
 
+Cu.import("resource://gre/modules/Services.jsm");
 
 /**
  * Constructs a new nsHttpServer instance.  This function is intended to
  * encapsulate construction of a server so that at some point in the future it
  * is possible to run these tests (with at most slight modifications) against
  * the server when used as an XPCOM component (not as an inline script).
  */
 function createServer()
@@ -30,17 +31,24 @@ function createServer()
  *
  * @param url
  *   the URL of the channel to create
  */
 function makeChannel(url)
 {
   var ios = Cc["@mozilla.org/network/io-service;1"]
               .getService(Ci.nsIIOService);
-  var chan = ios.newChannel(url, null, null)
+  var chan = ios.newChannel2(url,
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER)
                 .QueryInterface(Ci.nsIHttpChannel);
 
   return chan;
 }
 
 /**
  * Make a binary input stream wrapper for the given stream.
  *
--- a/netwerk/test/unit/test_304_responses.js
+++ b/netwerk/test/unit/test_304_responses.js
@@ -1,12 +1,13 @@
 "use strict";
 // https://bugzilla.mozilla.org/show_bug.cgi?id=761228
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "URL", function() {
   return "http://localhost:" + httpServer.identity.primaryPort;
 });
 
 var httpServer = null;
 const testFileName = "test_customConditionalRequest_304";
 const basePath = "/" + testFileName + "/";
@@ -21,17 +22,24 @@ const existingCached304 = "existingCache
 function make_uri(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
   return ios.newURI(url, null, null);
 }
 
 function make_channel(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-  var chan = ios.newChannel(url, null, null).QueryInterface(Ci.nsIHttpChannel);
+  var chan = ios.newChannel2(url,
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER).QueryInterface(Ci.nsIHttpChannel);
   return chan;
 }
 
 function clearCache() {
     var service = Components.classes["@mozilla.org/netwerk/cache-storage-service;1"]
         .getService(Ci.nsICacheStorageService);
     service.clear();
 }
--- a/netwerk/test/unit/test_307_redirect.js
+++ b/netwerk/test/unit/test_307_redirect.js
@@ -1,9 +1,10 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "URL", function() {
   return "http://localhost:" + httpserver.identity.primaryPort;
 });
 
 XPCOMUtils.defineLazyGetter(this, "uri", function() {
   return URL + "/redirect";
 });
@@ -12,17 +13,24 @@ XPCOMUtils.defineLazyGetter(this, "noRed
   return URL + "/content";
 });
 
 var httpserver = null;
 
 function make_channel(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 const requestBody = "request body";
 
 function redirectHandler(metadata, response)
 {
   response.setStatusLine(metadata.httpVersion, 307, "Moved Temporarily");
   response.setHeader("Location", noRedirectURI, false);
--- a/netwerk/test/unit/test_NetUtil.js
+++ b/netwerk/test/unit/test_NetUtil.js
@@ -8,16 +8,17 @@
  * This file tests the methods on NetUtil.jsm.
  */
 
 Cu.import("resource://testing-common/httpd.js");
 
 Cu.import("resource://gre/modules/NetUtil.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource://gre/modules/Promise.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
 
 // We need the profile directory so the test harness will clean up our test
 // files.
 do_get_profile();
 
 const OUTPUT_STREAM_CONTRACT_ID = "@mozilla.org/network/file-output-stream;1";
 const SAFE_OUTPUT_STREAM_CONTRACT_ID = "@mozilla.org/network/safe-file-output-stream;1";
 
@@ -255,30 +256,30 @@ function test_ioService()
 {
   do_check_true(NetUtil.ioService instanceof Ci.nsIIOService);
   run_next_test();
 }
 
 function test_asyncFetch_no_channel()
 {
   try {
-    NetUtil.asyncFetch(null, function() { });
+    NetUtil.asyncFetch2(null, function() { });
     do_throw("should throw!");
   }
   catch (e) {
     do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
   }
 
   run_next_test();
 }
 
 function test_asyncFetch_no_callback()
 {
   try {
-    NetUtil.asyncFetch({ });
+    NetUtil.asyncFetch2({ });
     do_throw("should throw!");
   }
   catch (e) {
     do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
   }
 
   run_next_test();
 }
@@ -293,21 +294,28 @@ function test_asyncFetch_with_nsIChannel
     aResponse.setStatusLine(aRequest.httpVersion, 200, "OK");
     aResponse.setHeader("Content-Type", "text/plain", false);
     aResponse.write(TEST_DATA);
   });
   server.start(-1);
 
   // Create our channel.
   let channel = NetUtil.ioService.
-                newChannel("http://localhost:" +
-                           server.identity.primaryPort + "/test", null, null);
+                newChannel2("http://localhost:" +
+                            server.identity.primaryPort + "/test",
+                            null,
+                            null,
+                            null,      // aLoadingNode
+                            Services.scriptSecurityManager.getSystemPrincipal(),
+                            null,      // aTriggeringPrincipal
+                            Ci.nsILoadInfo.SEC_NORMAL,
+                            Ci.nsIContentPolicy.TYPE_OTHER);
 
   // Open our channel asynchronously.
-  NetUtil.asyncFetch(channel, function(aInputStream, aResult) {
+  NetUtil.asyncFetch2(channel, function(aInputStream, aResult) {
     // Check that we had success.
     do_check_true(Components.isSuccessCode(aResult));
 
     // Check that we got the right data.
     do_check_eq(aInputStream.available(), TEST_DATA.length);
     let is = Cc["@mozilla.org/scriptableinputstream;1"].
              createInstance(Ci.nsIScriptableInputStream);
     is.init(aInputStream);
@@ -331,62 +339,72 @@ function test_asyncFetch_with_nsIURI()
   });
   server.start(-1);
 
   // Create our URI.
   let uri = NetUtil.newURI("http://localhost:" +
                            server.identity.primaryPort + "/test");
 
   // Open our URI asynchronously.
-  NetUtil.asyncFetch(uri, function(aInputStream, aResult) {
+  NetUtil.asyncFetch2(uri, function(aInputStream, aResult) {
     // Check that we had success.
     do_check_true(Components.isSuccessCode(aResult));
 
     // Check that we got the right data.
     do_check_eq(aInputStream.available(), TEST_DATA.length);
     let is = Cc["@mozilla.org/scriptableinputstream;1"].
              createInstance(Ci.nsIScriptableInputStream);
     is.init(aInputStream);
     let result = is.read(TEST_DATA.length);
     do_check_eq(TEST_DATA, result);
 
     server.stop(run_next_test);
-  });
+  },
+  null,      // aLoadingNode
+  Services.scriptSecurityManager.getSystemPrincipal(),
+  null,      // aTriggeringPrincipal
+  Ci.nsILoadInfo.SEC_NORMAL,
+  Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 function test_asyncFetch_with_string()
 {
   const TEST_DATA = "this is a test string";
 
   // Start the http server, and register our handler.
   let server = new HttpServer();
   server.registerPathHandler("/test", function(aRequest, aResponse) {
     aResponse.setStatusLine(aRequest.httpVersion, 200, "OK");
     aResponse.setHeader("Content-Type", "text/plain", false);
     aResponse.write(TEST_DATA);
   });
   server.start(-1);
 
   // Open our location asynchronously.
-  NetUtil.asyncFetch("http://localhost:" +
+  NetUtil.asyncFetch2("http://localhost:" +
                      server.identity.primaryPort + "/test",
                      function(aInputStream, aResult) {
     // Check that we had success.
     do_check_true(Components.isSuccessCode(aResult));
 
     // Check that we got the right data.
     do_check_eq(aInputStream.available(), TEST_DATA.length);
     let is = Cc["@mozilla.org/scriptableinputstream;1"].
              createInstance(Ci.nsIScriptableInputStream);
     is.init(aInputStream);
     let result = is.read(TEST_DATA.length);
     do_check_eq(TEST_DATA, result);
 
     server.stop(run_next_test);
-  });
+  },
+  null,      // aLoadingNode
+  Services.scriptSecurityManager.getSystemPrincipal(),
+  null,      // aTriggeringPrincipal
+  Ci.nsILoadInfo.SEC_NORMAL,
+  Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 function test_asyncFetch_with_nsIFile()
 {
   const TEST_DATA = "this is a test string";
 
   // First we need a file to read from.
   let file = Cc["@mozilla.org/file/directory_service;1"].
@@ -400,61 +418,78 @@ function test_asyncFetch_with_nsIFile()
                 createInstance(Ci.nsIFileOutputStream);
   ostream.init(file, -1, -1, 0);
   ostream.write(TEST_DATA, TEST_DATA.length);
 
   // Sanity check to make sure the data was written.
   do_check_eq(TEST_DATA, getFileContents(file));
 
   // Open our file asynchronously.
-  NetUtil.asyncFetch(file, function(aInputStream, aResult) {
+  NetUtil.asyncFetch2(file, function(aInputStream, aResult) {
     // Check that we had success.
     do_check_true(Components.isSuccessCode(aResult));
 
     // Check that we got the right data.
     do_check_eq(aInputStream.available(), TEST_DATA.length);
     let is = Cc["@mozilla.org/scriptableinputstream;1"].
              createInstance(Ci.nsIScriptableInputStream);
     is.init(aInputStream);
     let result = is.read(TEST_DATA.length);
     do_check_eq(TEST_DATA, result);
 
     run_next_test();
-  });
+  },
+  null,      // aLoadingNode
+  Services.scriptSecurityManager.getSystemPrincipal(),
+  null,      // aTriggeringPrincipal
+  Ci.nsILoadInfo.SEC_NORMAL,
+  Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 function test_asyncFetch_with_nsIInputString()
 {
   const TEST_DATA = "this is a test string";
   let istream = Cc["@mozilla.org/io/string-input-stream;1"].
                 createInstance(Ci.nsIStringInputStream);
   istream.setData(TEST_DATA, TEST_DATA.length);
 
   // Read the input stream asynchronously.
-  NetUtil.asyncFetch(istream, function(aInputStream, aResult) {
+  NetUtil.asyncFetch2(istream, function(aInputStream, aResult) {
     // Check that we had success.
     do_check_true(Components.isSuccessCode(aResult));
 
     // Check that we got the right data.
     do_check_eq(aInputStream.available(), TEST_DATA.length);
     do_check_eq(NetUtil.readInputStreamToString(aInputStream, TEST_DATA.length),
                 TEST_DATA);
 
     run_next_test();
-  });
+  },
+  null,      // aLoadingNode
+  Services.scriptSecurityManager.getSystemPrincipal(),
+  null,      // aTriggeringPrincipal
+  Ci.nsILoadInfo.SEC_NORMAL,
+  Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 function test_asyncFetch_does_not_block()
 {
   // Create our channel that has no data.
   let channel = NetUtil.ioService.
-                newChannel("data:text/plain,", null, null);
+                newChannel2("data:text/plain,",
+                            null,
+                            null,
+                            null,      // aLoadingNode
+                            Services.scriptSecurityManager.getSystemPrincipal(),
+                            null,      // aTriggeringPrincipal
+                            Ci.nsILoadInfo.SEC_NORMAL,
+                            Ci.nsIContentPolicy.TYPE_OTHER);
 
   // Open our channel asynchronously.
-  NetUtil.asyncFetch(channel, function(aInputStream, aResult) {
+  NetUtil.asyncFetch2(channel, function(aInputStream, aResult) {
     // Check that we had success.
     do_check_true(Components.isSuccessCode(aResult));
 
     // Check that reading a byte throws that the stream was closed (as opposed
     // saying it would block).
     let is = Cc["@mozilla.org/scriptableinputstream;1"].
              createInstance(Ci.nsIScriptableInputStream);
     is.init(aInputStream);
@@ -468,66 +503,104 @@ function test_asyncFetch_does_not_block(
 
     run_next_test();
   });
 }
 
 function test_newChannel_no_specifier()
 {
   try {
-    NetUtil.newChannel();
+    NetUtil.newChannel2();
     do_throw("should throw!");
   }
   catch (e) {
     do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
   }
 
   run_next_test();
 }
 
 function test_newChannel_with_string()
 {
   const TEST_SPEC = "http://mozilla.org";
 
   // Check that we get the same URI back from channel the IO service creates and
   // the channel the utility method creates.
   let ios = NetUtil.ioService;
-  let iosChannel = ios.newChannel(TEST_SPEC, null, null);
-  let NetUtilChannel = NetUtil.newChannel(TEST_SPEC);
+  let iosChannel = ios.newChannel2(TEST_SPEC,
+                                   null,
+                                   null,
+                                   null,      // aLoadingNode
+                                   Services.scriptSecurityManager.getSystemPrincipal(),
+                                   null,      // aTriggeringPrincipal
+                                   Ci.nsILoadInfo.SEC_NORMAL,
+                                   Ci.nsIContentPolicy.TYPE_OTHER);
+  let NetUtilChannel = NetUtil.newChannel2(TEST_SPEC,
+                                           null,
+                                           null,
+                                           null,      // aLoadingNode
+                                           Services.scriptSecurityManager.getSystemPrincipal(),
+                                           null,      // aTriggeringPrincipal
+                                           Ci.nsILoadInfo.SEC_NORMAL,
+                                           Ci.nsIContentPolicy.TYPE_OTHER);
   do_check_true(iosChannel.URI.equals(NetUtilChannel.URI));
 
   run_next_test();
 }
 
 function test_newChannel_with_nsIURI()
 {
   const TEST_SPEC = "http://mozilla.org";
 
   // Check that we get the same URI back from channel the IO service creates and
   // the channel the utility method creates.
   let uri = NetUtil.newURI(TEST_SPEC);
-  let iosChannel = NetUtil.ioService.newChannelFromURI(uri);
-  let NetUtilChannel = NetUtil.newChannel(uri);
+  let iosChannel = NetUtil.ioService.newChannelFromURI2(uri,
+                                                        null,      // aLoadingNode
+                                                        Services.scriptSecurityManager.getSystemPrincipal(),
+                                                        null,      // aTriggeringPrincipal
+                                                        Ci.nsILoadInfo.SEC_NORMAL,
+                                                        Ci.nsIContentPolicy.TYPE_OTHER);
+  let NetUtilChannel = NetUtil.newChannel2(uri,
+                                           null,
+                                           null,
+                                           null,      // aLoadingNode
+                                           Services.scriptSecurityManager.getSystemPrincipal(),
+                                           null,      // aTriggeringPrincipal
+                                           Ci.nsILoadInfo.SEC_NORMAL,
+                                           Ci.nsIContentPolicy.TYPE_OTHER);
   do_check_true(iosChannel.URI.equals(NetUtilChannel.URI));
 
   run_next_test();
 }
 
 function test_newChannel_with_nsIFile()
 {
   let file = Cc["@mozilla.org/file/directory_service;1"].
              getService(Ci.nsIProperties).
              get("ProfD", Ci.nsIFile);
   file.append("NetUtil-test-file.tmp");
 
   // Check that we get the same URI back from channel the IO service creates and
   // the channel the utility method creates.
   let uri = NetUtil.newURI(file);
-  let iosChannel = NetUtil.ioService.newChannelFromURI(uri);
-  let NetUtilChannel = NetUtil.newChannel(uri);
+  let iosChannel = NetUtil.ioService.newChannelFromURI2(uri,
+                                                        null,      // aLoadingNode
+                                                        Services.scriptSecurityManager.getSystemPrincipal(),
+                                                        null,      // aTriggeringPrincipal
+                                                        Ci.nsILoadInfo.SEC_NORMAL,
+                                                        Ci.nsIContentPolicy.TYPE_OTHER);
+  let NetUtilChannel = NetUtil.newChannel2(uri,
+                                           null,
+                                           null,
+                                           null,      // aLoadingNode
+                                           Services.scriptSecurityManager.getSystemPrincipal(),
+                                           null,      // aTriggeringPrincipal
+                                           Ci.nsILoadInfo.SEC_NORMAL,
+                                           Ci.nsIContentPolicy.TYPE_OTHER);
   do_check_true(iosChannel.URI.equals(NetUtilChannel.URI));
 
   run_next_test();
 }
 
 function test_readInputStreamToString()
 {
   const TEST_DATA = "this is a test string\0 with an embedded null";
--- a/netwerk/test/unit/test_about_networking.js
+++ b/netwerk/test/unit/test_about_networking.js
@@ -1,14 +1,15 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 const gDashboard = Cc['@mozilla.org/network/dashboard;1']
   .getService(Ci.nsIDashboard);
 
 const gServerSocket = Components.classes["@mozilla.org/network/server-socket;1"]
                              .createInstance(Components.interfaces.nsIServerSocket);
 const gHttpServer = new HttpServer();
 
@@ -79,17 +80,22 @@ add_test(function test_sockets() {
 function run_test() {
   let ioService = Cc["@mozilla.org/network/io-service;1"]
     .getService(Ci.nsIIOService);
 
   gHttpServer.start(-1);
 
   let uri = ioService.newURI("http://localhost:" + gHttpServer.identity.primaryPort,
                              null, null);
-  let channel = ioService.newChannelFromURI(uri);
+  let channel = ioService.newChannelFromURI2(uri,
+                                             null,      // aLoadingNode
+                                             Services.scriptSecurityManager.getSystemPrincipal(),
+                                             null,      // aTriggeringPrincipal
+                                             Ci.nsILoadInfo.SEC_NORMAL,
+                                             Ci.nsIContentPolicy.TYPE_OTHER);
 
   channel.open();
 
   gServerSocket.init(-1, true, -1);
 
   run_next_test();
 }
 
--- a/netwerk/test/unit/test_about_protocol.js
+++ b/netwerk/test/unit/test_about_protocol.js
@@ -6,17 +6,24 @@ let Ci = Components.interfaces;
 let Cc = Components.classes;
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 let unsafeAboutModule = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
   newChannel: function (aURI) {
-    let chan = Services.io.newChannel("about:blank", null, null);
+    let chan = Services.io.newChannel2("about:blank",
+                                       null,
+                                       null,
+                                       null,      // aLoadingNode
+                                       Services.scriptSecurityManager.getSystemPrincipal(),
+                                       null,      // aTriggeringPrincipal
+                                       Ci.nsILoadInfo.SEC_NORMAL,
+                                       Ci.nsIContentPolicy.TYPE_OTHER);
     chan.owner = Services.scriptSecurityManager.getSystemPrincipal();
     return chan;
   },
   getURIFlags: function (aURI) {
     return Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT;
   }
 };
 
@@ -33,13 +40,18 @@ let factory = {
 };
 
 function run_test() {
   let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
   let classID = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID();
   registrar.registerFactory(classID, "", "@mozilla.org/network/protocol/about;1?what=unsafe", factory);
 
   let aboutUnsafeURI = Services.io.newURI("about:unsafe", null, null);
-  let aboutUnsafeChan = Services.io.newChannelFromURI(aboutUnsafeURI);
+  let aboutUnsafeChan = Services.io.newChannelFromURI2(aboutUnsafeURI,
+                                                       null,      // aLoadingNode
+                                                       Services.scriptSecurityManager.getSystemPrincipal(),
+                                                       null,      // aTriggeringPrincipal
+                                                       Ci.nsILoadInfo.SEC_NORMAL,
+                                                       Ci.nsIContentPolicy.TYPE_OTHER);
   do_check_null(aboutUnsafeChan.owner, "URI_SAFE_FOR_UNTRUSTED_CONTENT channel has no owner");
 
   registrar.unregisterFactory(classID, factory);
 }
--- a/netwerk/test/unit/test_aboutblank.js
+++ b/netwerk/test/unit/test_aboutblank.js
@@ -1,20 +1,32 @@
+Cu.import("resource://gre/modules/Services.jsm");
+
 function run_test() {
   var ioServ = Components.classes["@mozilla.org/network/io-service;1"]
                          .getService(Components.interfaces.nsIIOService);
 
   var base = ioServ.newURI("http://www.example.com", null, null);
 
   var about1 = ioServ.newURI("about:blank", null, null);
   var about2 = ioServ.newURI("about:blank", null, base);
 
-  var chan1 = ioServ.newChannelFromURI(about1)
+  var chan1 = ioServ.newChannelFromURI2(about1,
+                                        null,      // aLoadingNode
+                                        Services.scriptSecurityManager.getSystemPrincipal(),
+                                        null,      // aTriggeringPrincipal
+                                        Ci.nsILoadInfo.SEC_NORMAL,
+                                        Ci.nsIContentPolicy.TYPE_OTHER)
                     .QueryInterface(Components.interfaces.nsIPropertyBag2);
-  var chan2 = ioServ.newChannelFromURI(about2)
+  var chan2 = ioServ.newChannelFromURI2(about2,
+                                        null,      // aLoadingNode
+                                        Services.scriptSecurityManager.getSystemPrincipal(),
+                                        null,      // aTriggeringPrincipal
+                                        Ci.nsILoadInfo.SEC_NORMAL,
+                                        Ci.nsIContentPolicy.TYPE_OTHER)
                     .QueryInterface(Components.interfaces.nsIPropertyBag2);
 
   var haveProp = false;
   var propVal = null;
   try {
     propVal = chan1.getPropertyAsInterface("baseURI",
                                            Components.interfaces.nsIURI);
     haveProp = true;
--- a/netwerk/test/unit/test_assoc.js
+++ b/netwerk/test/unit/test_assoc.js
@@ -1,9 +1,10 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpserver = new HttpServer();
 var currentTestIndex = 0;
 
 XPCOMUtils.defineLazyGetter(this, "port", function() {
     return httpserver.identity.primaryPort;
 });
 
@@ -41,17 +42,24 @@ XPCOMUtils.defineLazyGetter(this, "tests
 
 var oldPrefVal;
 var domBranch;
 
 function setupChannel(url)
 {
     var ios = Components.classes["@mozilla.org/network/io-service;1"].
                          getService(Ci.nsIIOService);
-    var chan = ios.newChannel("http://localhost:" + port + url, "", null);
+    var chan = ios.newChannel2("http://localhost:" + port + url,
+                               "",
+                               null,
+                               null,      // aLoadingNode
+                               Services.scriptSecurityManager.getSystemPrincipal(),
+                               null,      // aTriggeringPrincipal
+                               Ci.nsILoadInfo.SEC_NORMAL,
+                               Ci.nsIContentPolicy.TYPE_OTHER);
     return chan;
 }
 
 function startIter()
 {
     var channel = setupChannel(tests[currentTestIndex].url);
     channel.asyncOpen(new ChannelListener(completeIter,
                                           channel, tests[currentTestIndex].flags), null);
--- a/netwerk/test/unit/test_auth_proxy.js
+++ b/netwerk/test/unit/test_auth_proxy.js
@@ -6,16 +6,17 @@
 /**
  * This tests the automatic login to the proxy with password,
  * if the password is stored and the browser is restarted.
  *
  * <copied from="test_authentication.js"/>
  */
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 const FLAG_RETURN_FALSE   = 1 << 0;
 const FLAG_WRONG_PASSWORD = 1 << 1;
 const FLAG_PREVIOUS_FAILED = 1 << 2;
 
 function AuthPrompt2(proxyFlags, hostFlags) {
   this.proxyCred.flags = proxyFlags;
   this.hostCred.flags = hostFlags;
@@ -209,17 +210,24 @@ var listener = {
   }
 };
 
 function makeChan(url) {
   if (!url)
     url = "http://somesite/";
   var ios = Cc["@mozilla.org/network/io-service;1"]
                       .getService(Ci.nsIIOService);
-  var chan = ios.newChannel(url, null, null)
+  var chan = ios.newChannel2(url,
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER)
                 .QueryInterface(Ci.nsIHttpChannel);
 
   return chan;
 }
 
 var current_test = 0;
 var httpserv = null;
 
--- a/netwerk/test/unit/test_authentication.js
+++ b/netwerk/test/unit/test_authentication.js
@@ -1,12 +1,13 @@
 // This file tests authentication prompt callbacks
 // TODO NIT use do_check_eq(expected, actual) consistently, not sometimes eq(actual, expected)
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "URL", function() {
   return "http://localhost:" + httpserv.identity.primaryPort;
 });
 
 XPCOMUtils.defineLazyGetter(this, "PORT", function() {
   return httpserv.identity.primaryPort;
 });
@@ -266,17 +267,24 @@ var listener = {
 
     do_test_finished();
   }
 };
 
 function makeChan(url) {
   var ios = Components.classes["@mozilla.org/network/io-service;1"]
                       .getService(Components.interfaces.nsIIOService);
-  var chan = ios.newChannel(url, null, null)
+  var chan = ios.newChannel2(url,
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER)
                 .QueryInterface(Components.interfaces.nsIHttpChannel);
 
   return chan;
 }
 
 var tests = [test_noauth, test_returnfalse1, test_wrongpw1, test_prompt1,
              test_returnfalse2, test_wrongpw2, test_prompt2, test_ntlm,
              test_basicrealm, test_digest_noauth, test_digest,
--- a/netwerk/test/unit/test_authpromptwrapper.js
+++ b/netwerk/test/unit/test_authpromptwrapper.js
@@ -1,15 +1,17 @@
 // NOTE: This tests code outside of Necko. The test still lives here because
 // the contract is part of Necko.
 
 // TODO:
 // - HTTPS
 // - Proxies
 
+Cu.import("resource://gre/modules/Services.jsm");
+
 const nsIAuthInformation = Components.interfaces.nsIAuthInformation;
 const nsIAuthPromptAdapterFactory = Components.interfaces.nsIAuthPromptAdapterFactory;
 
 function run_test() {
   const contractID = "@mozilla.org/network/authprompt-adapter-factory;1";
   if (!(contractID in Components.classes)) {
     print("No adapter factory found, skipping testing");
     return;
@@ -97,17 +99,24 @@ function run_test() {
       }
     }
   };
 
 
   // Also have to make up a channel
   var ios = Components.classes["@mozilla.org/network/io-service;1"]
                       .getService(Components.interfaces.nsIIOService);
-  var chan = ios.newChannel("http://" + host, "", null);
+  var chan = ios.newChannel2("http://" + host,
+                             "",
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER);
 
   function do_tests(expectedRV) {
     var prompt1;
     var wrapper;
 
     // 1: The simple case
     prompt1 = new Prompt1();
     prompt1.rv = expectedRV;
@@ -194,17 +203,24 @@ function run_test() {
 
     info.flags &= ~nsIAuthInformation.NEED_DOMAIN;
 
     info.domain = "";
     info.username = "";
     info.password = "";
 
     // 5: FTP
-    var ftpchan = ios.newChannel("ftp://" + host, "", null);
+    var ftpchan = ios.newChannel2("ftp://" + host,
+                                  "",
+                                  null,
+                                  null,      // aLoadingNode
+                                  Services.scriptSecurityManager.getSystemPrincipal(),
+                                  null,      // aTriggeringPrincipal
+                                  Ci.nsILoadInfo.SEC_NORMAL,
+                                  Ci.nsIContentPolicy.TYPE_OTHER);
 
     prompt1 = new Prompt1();
     prompt1.rv = expectedRV;
     prompt1.scheme = "ftp";
 
     wrapper = adapter.createAdapter(prompt1);
     var rv = wrapper.promptAuth(ftpchan, 0, info);
     do_check_eq(rv, prompt1.rv);
--- a/netwerk/test/unit/test_backgroundfilesaver.js
+++ b/netwerk/test/unit/test_backgroundfilesaver.js
@@ -15,16 +15,18 @@ Cu.import("resource://gre/modules/XPCOMU
 XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
                                   "resource://gre/modules/FileUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
                                   "resource://gre/modules/NetUtil.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
                                   "resource://gre/modules/Promise.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
                                   "resource://gre/modules/Task.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Services",
+                                  "resource://gre/modules/Services.jsm");
 
 const BackgroundFileSaverOutputStream = Components.Constructor(
       "@mozilla.org/network/background-file-saver;1?mode=outputstream",
       "nsIBackgroundFileSaver");
 
 const BackgroundFileSaverStreamListener = Components.Constructor(
       "@mozilla.org/network/background-file-saver;1?mode=streamlistener",
       "nsIBackgroundFileSaver");
@@ -100,29 +102,35 @@ function toHex(str) {
  *        String containing the octets that are expected in the file.
  *
  * @return {Promise}
  * @resolves When the operation completes.
  * @rejects Never.
  */
 function promiseVerifyContents(aFile, aExpectedContents) {
   let deferred = Promise.defer();
-  NetUtil.asyncFetch(aFile, function(aInputStream, aStatus) {
+  NetUtil.asyncFetch2(aFile, function(aInputStream, aStatus) {
     do_check_true(Components.isSuccessCode(aStatus));
     let contents = NetUtil.readInputStreamToString(aInputStream,
                                                    aInputStream.available());
     if (contents.length <= TEST_DATA_SHORT.length * 2) {
       do_check_eq(contents, aExpectedContents);
     } else {
       // Do not print the entire content string to the test log.
       do_check_eq(contents.length, aExpectedContents.length);
       do_check_true(contents == aExpectedContents);
     }
     deferred.resolve();
-  });
+  },
+  null,      // aLoadingNode
+  Services.scriptSecurityManager.getSystemPrincipal(),
+  null,      // aTriggeringPrincipal
+  Ci.nsILoadInfo.SEC_NORMAL,
+  Ci.nsIContentPolicy.TYPE_OTHER);
+
   return deferred.promise;
 }
 
 /**
  * Waits for the given saver object to complete.
  *
  * @param aSaver
  *        The saver, with the output stream or a stream listener implementation.
--- a/netwerk/test/unit/test_bug1064258.js
+++ b/netwerk/test/unit/test_bug1064258.js
@@ -6,27 +6,35 @@
  * - check the entry has metadata, but zero-length content
  * - load the same URL again, now cached
  * - check the channel is giving no content (no call to OnDataAvailable) but succeeds
  * - repeat again, but for a different URL that is not cached (immediately expires)
  * - only difference is that we get a newer version of the content from the server during the second request
  */
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "URL", function() {
   return "http://localhost:" + httpServer.identity.primaryPort;
 });
 
 var httpServer = null;
 
 function make_channel(url, callback, ctx) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 const responseBody1 = "response body 1";
 const responseBody2a = "response body 2a";
 const responseBody2b = "response body 2b";
 
 function contentHandler1(metadata, response)
 {
--- a/netwerk/test/unit/test_bug203271.js
+++ b/netwerk/test/unit/test_bug203271.js
@@ -1,15 +1,16 @@
 //
 // Tests if a response with an Expires-header in the past
 // and Cache-Control: max-age  in the future works as
 // specified in RFC 2616 section 14.9.3 by letting max-age
 // take precedence
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 const BUGID = "203271";
 
 var httpserver = new HttpServer();
 var index = 0;
 var tests = [
     // original problem described in bug#203271
     {url: "/precedence", server: "0", expected: "0",
      responseheader: [ "Expires: " + getDateString(-1),
@@ -91,19 +92,25 @@ function logit(i, data, ctx) {
         }}
     );
     dump("===================================\n")
 }
 
 function setupChannel(suffix, value) {
     var ios = Components.classes["@mozilla.org/network/io-service;1"].
                          getService(Ci.nsIIOService);
-    var chan = ios.newChannel("http://localhost:" +
-                              httpserver.identity.primaryPort + suffix,
-                              "", null);
+    var chan = ios.newChannel2("http://localhost:" +
+                               httpserver.identity.primaryPort + suffix,
+                               "",
+                               null,
+                               null,      // aLoadingNode
+                               Services.scriptSecurityManager.getSystemPrincipal(),
+                               null,      // aTriggeringPrincipal
+                               Ci.nsILoadInfo.SEC_NORMAL,
+                               Ci.nsIContentPolicy.TYPE_OTHER);
     var httpChan = chan.QueryInterface(Components.interfaces.nsIHttpChannel);
     httpChan.requestMethod = "GET"; // default value, just being paranoid...
     httpChan.setRequestHeader("x-request", value, false);
     return httpChan;
 }
 
 function triggerNextTest() {
     var channel = setupChannel(tests[index].url, tests[index].server);
--- a/netwerk/test/unit/test_bug248970_cookie.js
+++ b/netwerk/test/unit/test_bug248970_cookie.js
@@ -9,17 +9,24 @@ var httpserver;
 
 function inChildProcess() {
   return Cc["@mozilla.org/xre/app-info;1"]
            .getService(Ci.nsIXULRuntime)
            .processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;  
 }
 function makeChan(path) {
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-  var chan = ios.newChannel("http://localhost:" + httpserver.identity.primaryPort + "/" + path, null, null)
+  var chan = ios.newChannel2("http://localhost:" + httpserver.identity.primaryPort + "/" + path,
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER)
                 .QueryInterface(Ci.nsIHttpChannel);
   return chan;
 }
 
 function setup_chan(path, isPrivate, callback) {
   var chan = makeChan(path);
   chan.QueryInterface(Ci.nsIPrivateBrowsingChannel).setPrivate(isPrivate);
   chan.asyncOpen(new ChannelListener(callback), null);  
--- a/netwerk/test/unit/test_bug263127.js
+++ b/netwerk/test/unit/test_bug263127.js
@@ -1,9 +1,10 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var server;
 const BUGID = "263127";
 
 var listener = {
   QueryInterface: function(iid) {
     if (!iid.equals(nsIDownloadObserver) &&
         !iid.equals(nsISupports))
@@ -35,18 +36,25 @@ var listener = {
 function run_test() {
   // start server
   server = new HttpServer();
   server.start(-1);
 
   // Initialize downloader
   var channel = Cc["@mozilla.org/network/io-service;1"]
                   .getService(Ci.nsIIOService)
-                  .newChannel("http://localhost:" +
-                              server.identity.primaryPort + "/", null, null);
+                  .newChannel2("http://localhost:" +
+                               server.identity.primaryPort + "/",
+                               null,
+                               null,
+                               null,      // aLoadingNode
+                               Services.scriptSecurityManager.getSystemPrincipal(),
+                               null,      // aTriggeringPrincipal
+                               Ci.nsILoadInfo.SEC_NORMAL,
+                               Ci.nsIContentPolicy.TYPE_OTHER);
 
   var targetFile = Cc["@mozilla.org/file/directory_service;1"]
                      .getService(Ci.nsIProperties)
                      .get("TmpD", Ci.nsIFile);
   targetFile.append("bug" + BUGID + ".test");
   if (targetFile.exists())
     targetFile.remove(false);
 
--- a/netwerk/test/unit/test_bug282432.js
+++ b/netwerk/test/unit/test_bug282432.js
@@ -1,8 +1,10 @@
+Cu.import("resource://gre/modules/Services.jsm");
+
 function run_test() {
   do_test_pending();
 
   function StreamListener() {}
 
   StreamListener.prototype = {
     QueryInterface: function(aIID) {
       if (aIID.equals(Components.interfaces.nsIStreamListener) ||
@@ -28,11 +30,16 @@ function run_test() {
   let listener = new StreamListener();
   let ios = Components.classes["@mozilla.org/network/io-service;1"]
                       .getService(Components.interfaces.nsIIOService);
 
   // This file does not exist.
   let file = do_get_file("_NOT_EXIST_.txt", true);
   do_check_false(file.exists());
 
-  let channel = ios.newChannelFromURI(ios.newFileURI(file));
+  let channel = ios.newChannelFromURI2(ios.newFileURI(file),
+                                       null,      // aLoadingNode
+                                       Services.scriptSecurityManager.getSystemPrincipal(),
+                                       null,      // aTriggeringPrincipal
+                                       Ci.nsILoadInfo.SEC_NORMAL,
+                                       Ci.nsIContentPolicy.TYPE_OTHER);
   channel.asyncOpen(listener, null);
 }
--- a/netwerk/test/unit/test_bug331825.js
+++ b/netwerk/test/unit/test_bug331825.js
@@ -1,9 +1,10 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var server;
 const BUGID = "331825";
 
 function TestListener() {
 }
 TestListener.prototype.onStartRequest = function(request, context) {
 }
@@ -21,18 +22,24 @@ function run_test() {
   server.registerPathHandler("/bug" + BUGID, bug331825);
 
   server.start(-1);
 
   // make request
   var channel =
       Components.classes["@mozilla.org/network/io-service;1"].
       getService(Components.interfaces.nsIIOService).
-      newChannel("http://localhost:" + server.identity.primaryPort + "/bug" +
-                 BUGID, null, null);
+      newChannel2("http://localhost:" + server.identity.primaryPort + "/bug" + BUGID,
+                  null,
+                  null,
+                  null,      // aLoadingNode
+                  Services.scriptSecurityManager.getSystemPrincipal(),
+                  null,      // aTriggeringPrincipal
+                  Ci.nsILoadInfo.SEC_NORMAL,
+                  Ci.nsIContentPolicy.TYPE_OTHER);
 
   channel.QueryInterface(Components.interfaces.nsIHttpChannel);
   channel.setRequestHeader("If-None-Match", "foobar", false);
   channel.asyncOpen(new TestListener(), null);
 
   do_test_pending();
 }
 
--- a/netwerk/test/unit/test_bug337744.js
+++ b/netwerk/test/unit/test_bug337744.js
@@ -13,17 +13,24 @@ const specs = [
 
 function check_for_exception(spec)
 {
   var ios =
     Cc["@mozilla.org/network/io-service;1"].
     getService(Ci.nsIIOService);
 
   try {
-    var channel = ios.newChannel(spec, null, null);
+    var channel = ios.newChannel2(spec,
+                                  null,
+                                  null,
+                                  null,      // aLoadingNode
+                                  Services.scriptSecurityManager.getSystemPrincipal(),
+                                  null,      // aTriggeringPrincipal
+                                  Ci.nsILoadInfo.SEC_NORMAL,
+                                  Ci.nsIContentPolicy.TYPE_OTHER);
   }
   catch (e) {
     return;
   }
 
   do_throw("Successfully opened invalid URI: '" + spec + "'");
 }
 
--- a/netwerk/test/unit/test_bug365133.js
+++ b/netwerk/test/unit/test_bug365133.js
@@ -76,17 +76,24 @@ function storeData(status, entry) {
              "  Expected: " + written  + "\n" +
              "  Actual: " + tests[0][0].length + "\n");
   }
   os.close();
   entry.close();
 
   var ios = Components.classes["@mozilla.org/network/io-service;1"].
             getService(Components.interfaces.nsIIOService);
-  var channel = ios.newChannel(URL, "", null);
+  var channel = ios.newChannel2(URL,
+                                "",
+                                null,
+                                null,      // aLoadingNode
+                                Services.scriptSecurityManager.getSystemPrincipal(),
+                                null,      // aTriggeringPrincipal
+                                Ci.nsILoadInfo.SEC_NORMAL,
+                                Ci.nsIContentPolicy.TYPE_OTHER);
   channel.asyncOpen(new ChannelListener(checkData, null, CL_ALLOW_UNKNOWN_CL), null);
 }
 
 function next_test() {
   if (tests.length == 0)
     do_test_finished();
   else {
     asyncOpenCacheEntry(URL,
--- a/netwerk/test/unit/test_bug369787.js
+++ b/netwerk/test/unit/test_bug369787.js
@@ -1,9 +1,10 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 const BUGID = "369787";
 var server = null;
 var channel = null;
 
 function change_content_type() {
   var origType = channel.contentType;
   const newType = "x-foo/x-bar";
@@ -52,18 +53,25 @@ function run_test() {
   server.registerPathHandler("/bug" + BUGID, bug369787);
 
   server.start(-1);
 
   // make request
   channel =
       Components.classes["@mozilla.org/network/io-service;1"].
       getService(Components.interfaces.nsIIOService).
-      newChannel("http://localhost:" +
-                 server.identity.primaryPort + "/bug" + BUGID, null, null);
+      newChannel2("http://localhost:" +
+                  server.identity.primaryPort + "/bug" + BUGID,
+                  null,
+                  null,
+                  null,      // aLoadingNode
+                  Services.scriptSecurityManager.getSystemPrincipal(),
+                  null,      // aTriggeringPrincipal
+                  Ci.nsILoadInfo.SEC_NORMAL,
+                  Ci.nsIContentPolicy.TYPE_OTHER);
 
   channel.QueryInterface(Components.interfaces.nsIHttpChannel);
   channel.asyncOpen(new TestListener(), null);
 
   do_test_pending();
 }
 
 // PATH HANDLER FOR /bug369787
--- a/netwerk/test/unit/test_bug376660.js
+++ b/netwerk/test/unit/test_bug376660.js
@@ -1,8 +1,10 @@
+Cu.import("resource://gre/modules/Services.jsm");
+
 var Cc = Components.classes;
 var Ci = Components.interfaces;
 
 var listener = {
   expect_failure: false,
   QueryInterface: function listener_qi(iid) {
     if (iid.equals(Ci.nsISupports) ||
         iid.equals(Ci.nsIUnicharStreamLoaderObserver)) {
@@ -40,29 +42,43 @@ function run_test() {
 function test1() {
   var f =
       Cc["@mozilla.org/network/unichar-stream-loader;1"].
       createInstance(Ci.nsIUnicharStreamLoader);
   f.init(listener);
 
   var ios = Components.classes["@mozilla.org/network/io-service;1"]
                       .getService(Components.interfaces.nsIIOService);
-  var chan = ios.newChannel("data:text/plain,", null, null);
+  var chan = ios.newChannel2("data:text/plain,",
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER);
   chan.asyncOpen(f, null);
   do_test_pending();
 }
 
 function test2() {
   var f =
       Cc["@mozilla.org/network/unichar-stream-loader;1"].
       createInstance(Ci.nsIUnicharStreamLoader);
   f.init(listener);
 
   var ios = Components.classes["@mozilla.org/network/io-service;1"]
                       .getService(Components.interfaces.nsIIOService);
-  var chan = ios.newChannel("http://localhost:0/", null, null);
+  var chan = ios.newChannel2("http://localhost:0/",
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER);
   listener.expect_failure = true;
   chan.asyncOpen(f, null);
   do_test_pending();
 }
 
 function done() {
 }
--- a/netwerk/test/unit/test_bug401564.js
+++ b/netwerk/test/unit/test_bug401564.js
@@ -1,11 +1,12 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 "use strict";
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpserver = null;
 const noRedirectURI = "/content";
 const pageValue = "Final page";
 const acceptType = "application/json";
 
 function redirectHandler(metadata, response)
 {
@@ -30,20 +31,25 @@ function run_test()
   httpserver.registerPathHandler("/content", contentHandler);
   httpserver.start(-1);
 
   var prefs = Cc["@mozilla.org/preferences-service;1"]
                 .getService(Components.interfaces.nsIPrefBranch);
   prefs.setBoolPref("network.http.prompt-temp-redirect", false);
 
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-  var chan = ios.newChannel("http://localhost:" +
-                            httpserver.identity.primaryPort + "/redirect",
-                            "",
-                            null);
+  var chan = ios.newChannel2("http://localhost:" +
+                             httpserver.identity.primaryPort + "/redirect",
+                             "",
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER);
 
   chan.QueryInterface(Ci.nsIHttpChannel);
   chan.setRequestHeader("Accept", acceptType, false);
 
   chan.asyncOpen(new ChannelListener(dummyHandler, null), null);
 
   do_test_pending();
 }
--- a/netwerk/test/unit/test_bug412945.js
+++ b/netwerk/test/unit/test_bug412945.js
@@ -1,9 +1,10 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpserv;
 
 function TestListener() {
 }
 
 TestListener.prototype.onStartRequest = function(request, context) {
 }
@@ -18,18 +19,25 @@ function run_test() {
   httpserv.registerPathHandler("/bug412945", bug412945);
 
   httpserv.start(-1);
 
   // make request
   var channel =
       Components.classes["@mozilla.org/network/io-service;1"].
       getService(Components.interfaces.nsIIOService).
-      newChannel("http://localhost:" + httpserv.identity.primaryPort +
-                 "/bug412945", null, null);
+      newChannel2("http://localhost:" + httpserv.identity.primaryPort +
+                  "/bug412945",
+                  null,
+                  null,
+                  null,      // aLoadingNode
+                  Services.scriptSecurityManager.getSystemPrincipal(),
+                  null,      // aTriggeringPrincipal
+                  Ci.nsILoadInfo.SEC_NORMAL,
+                  Ci.nsIContentPolicy.TYPE_OTHER);
 
   channel.QueryInterface(Components.interfaces.nsIHttpChannel);
   channel.requestMethod = "POST";
   channel.asyncOpen(new TestListener(), null);
 
   do_test_pending();
 }
 
--- a/netwerk/test/unit/test_bug455311.js
+++ b/netwerk/test/unit/test_bug455311.js
@@ -1,11 +1,13 @@
 const isWindows = ("@mozilla.org/windows-registry-key;1" in Cc);
 const isLinux = ("@mozilla.org/gnome-gconf-service;1" in Cc);
 
+Cu.import("resource://gre/modules/Services.jsm");
+
 function getLinkFile()
 {
   if (isWindows) {
     return do_get_file("test_link.url");
   }
   if (isLinux) {
     return do_get_file("test_link.desktop");
   }
@@ -90,17 +92,22 @@ RequestObserver.prototype = {
       do_check_false(chan.isPending());
     } catch(e) {}
     this._nextTest();
   }
 };
 
 function test_cancel()
 {
-  var chan = ios.newChannelFromURI(linkURI);
+  var chan = ios.newChannelFromURI2(linkURI,
+                                    null,      // aLoadingNode
+                                    Services.scriptSecurityManager.getSystemPrincipal(),
+                                    null,      // aTriggeringPrincipal
+                                    Ci.nsILoadInfo.SEC_NORMAL,
+                                    Ci.nsIContentPolicy.TYPE_OTHER);
   do_check_eq(chan.URI, linkURI);
   do_check_eq(chan.originalURI, linkURI);
   chan.asyncOpen(new RequestObserver(linkURI, newURI, do_test_finished), null);
   do_check_true(chan.isPending());
   chan.cancel(Cr.NS_ERROR_ABORT);
   do_check_true(chan.isPending());
 }
 
@@ -110,15 +117,20 @@ function run_test()
     return;
   }
 
   link = getLinkFile();
   linkURI = ios.newFileURI(link);
 
   do_test_pending();
 
-  var chan = ios.newChannelFromURI(linkURI);
+  var chan = ios.newChannelFromURI2(linkURI,
+                                    null,      // aLoadingNode
+                                    Services.scriptSecurityManager.getSystemPrincipal(),
+                                    null,      // aTriggeringPrincipal
+                                    Ci.nsILoadInfo.SEC_NORMAL,
+                                    Ci.nsIContentPolicy.TYPE_OTHER);
   do_check_eq(chan.URI, linkURI);
   do_check_eq(chan.originalURI, linkURI);
   chan.notificationCallbacks = new NotificationCallbacks(linkURI, newURI);
   chan.asyncOpen(new RequestObserver(linkURI, newURI, test_cancel), null);
   do_check_true(chan.isPending());
 }
--- a/netwerk/test/unit/test_bug468426.js
+++ b/netwerk/test/unit/test_bug468426.js
@@ -1,9 +1,10 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpserver = new HttpServer();
 var index = 0;
 var tests = [
     // Initial request. Cached variant will have no cookie
     { url : "/bug468426", server : "0", expected : "0", cookie: null},
 
     // Cache now contains a variant with no value for cookie. If we don't
@@ -30,18 +31,25 @@ var tests = [
     // no cookie in the request we expect a fresh value
     { url : "/bug468426", server : "6", expected : "6", cookie: null},
 
 ];
 
 function setupChannel(suffix, value, cookie) {
     var ios = Components.classes["@mozilla.org/network/io-service;1"]
             .getService(Ci.nsIIOService);
-    var chan = ios.newChannel("http://localhost:" +
-                             httpserver.identity.primaryPort + suffix, "", null);
+    var chan = ios.newChannel2("http://localhost:" +
+                               httpserver.identity.primaryPort + suffix,
+                               "",
+                               null,
+                               null,      // aLoadingNode
+                               Services.scriptSecurityManager.getSystemPrincipal(),
+                               null,      // aTriggeringPrincipal
+                               Ci.nsILoadInfo.SEC_NORMAL,
+                               Ci.nsIContentPolicy.TYPE_OTHER);
     var httpChan = chan.QueryInterface(Components.interfaces.nsIHttpChannel);
     httpChan.requestMethod = "GET";
     httpChan.setRequestHeader("x-request", value, false);
     if (cookie != null)
         httpChan.setRequestHeader("Cookie", cookie, false);
     return httpChan;
 }
 
--- a/netwerk/test/unit/test_bug468594.js
+++ b/netwerk/test/unit/test_bug468594.js
@@ -9,16 +9,17 @@
 // breaking the finer details of the test. This script has
 // full control of response-headers, however, and can perform
 // the intended testing plus some extra stuff.
 //
 // Please see RFC 2616 section 13.2.1 6th paragraph for the
 // definition of "explicit expiration time" being used here.
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpserver = new HttpServer();
 var index = 0;
 var tests = [
     {url: "/freshness",   server: "0", expected: "0"},
     {url: "/freshness",   server: "1", expected: "0"}, // cached
 
     // RFC 2616 section 13.9 2nd paragraph
@@ -52,17 +53,24 @@ function logit(i, data) {
     if (tests[i].responseheader)
         dump("\t[" + tests[i].responseheader + "]");
     dump("\n");
 }
 
 function setupChannel(suffix, value) {
     var ios = Components.classes["@mozilla.org/network/io-service;1"].
                          getService(Ci.nsIIOService);
-    var chan = ios.newChannel("http://localhost:" + httpserver.identity.primaryPort + suffix, "", null);
+    var chan = ios.newChannel2("http://localhost:" + httpserver.identity.primaryPort + suffix,
+                               "",
+                               null,
+                               null,      // aLoadingNode
+                               Services.scriptSecurityManager.getSystemPrincipal(),
+                               null,      // aTriggeringPrincipal
+                               Ci.nsILoadInfo.SEC_NORMAL,
+                               Ci.nsIContentPolicy.TYPE_OTHER);
     var httpChan = chan.QueryInterface(Components.interfaces.nsIHttpChannel);
     httpChan.requestMethod = "GET";
     httpChan.setRequestHeader("x-request", value, false);
     return httpChan;
 }
 
 function triggerNextTest() {
     var channel = setupChannel(tests[index].url, tests[index].server);
--- a/netwerk/test/unit/test_bug477578.js
+++ b/netwerk/test/unit/test_bug477578.js
@@ -1,10 +1,12 @@
 // test that methods are not normalized
 
+Cu.import("resource://gre/modules/Services.jsm");
+
 const testMethods = [
   ["GET"],
   ["get"],
   ["Get"],
   ["gET"],
   ["gEt"],
   ["post"],
   ["POST"],
@@ -36,16 +38,23 @@ const testMethods = [
   ["Foo"]
 ]
 
 function run_test() {
   var ios =
     Cc["@mozilla.org/network/io-service;1"].
     getService(Ci.nsIIOService);
 
-  var chan = ios.newChannel("http://localhost/", null, null)
+  var chan = ios.newChannel2("http://localhost/",
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER)
                   .QueryInterface(Components.interfaces.nsIHttpChannel);
 
   for (var i = 0; i < testMethods.length; i++) {
     chan.requestMethod = testMethods[i];
     do_check_eq(chan.requestMethod, testMethods[i]);
   }
 }
--- a/netwerk/test/unit/test_bug482601.js
+++ b/netwerk/test/unit/test_bug482601.js
@@ -1,9 +1,10 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpserv = null;
 var test_nr = 0;
 var observers_called = "";
 var handlers_called = "";
 var buffer = "";
 
 var observer = {
@@ -75,17 +76,24 @@ var tests = [test_nocache,
 
 var results = ["http-on-examine-response",
                "http-on-examine-response,http-on-examine-merged-response",
                "http-on-examine-response,http-on-examine-merged-response",
                "http-on-examine-cached-response"];
 
 function makeChan(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-  var chan = ios.newChannel(url, null, null).QueryInterface(Ci.nsIHttpChannel);
+  var chan = ios.newChannel2(url,
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER).QueryInterface(Ci.nsIHttpChannel);
   return chan;
 }
 
 function storeCache(aCacheEntry, aResponseHeads, aContent) {
   aCacheEntry.setMetaDataElement("request-method", "GET");
   aCacheEntry.setMetaDataElement("response-head", aResponseHeads);
   aCacheEntry.setMetaDataElement("charset", "ISO-8859-1");
 
--- a/netwerk/test/unit/test_bug484684.js
+++ b/netwerk/test/unit/test_bug484684.js
@@ -80,17 +80,24 @@ function storeData(status, entry) {
              "  Expected: " + written  + "\n" +
              "  Actual: " + tests[0][0].length + "\n");
   }
   os.close();
   entry.close();
 
   var ios = Components.classes["@mozilla.org/network/io-service;1"].
             getService(Components.interfaces.nsIIOService);
-  var channel = ios.newChannel(URL, "", null);
+  var channel = ios.newChannel2(URL,
+                                "",
+                                null,
+                                null,      // aLoadingNode
+                                Services.scriptSecurityManager.getSystemPrincipal(),
+                                null,      // aTriggeringPrincipal
+                                Ci.nsILoadInfo.SEC_NORMAL,
+                                Ci.nsIContentPolicy.TYPE_OTHER);
   channel.asyncOpen(new ChannelListener(checkData, null, CL_ALLOW_UNKNOWN_CL), null);
 }
 
 function next_test() {
   if (tests.length == 0)
     do_test_finished();
   else {
     asyncOpenCacheEntry(URL,
--- a/netwerk/test/unit/test_bug490095.js
+++ b/netwerk/test/unit/test_bug490095.js
@@ -1,14 +1,15 @@
 //
 // Verify that the VALIDATE_NEVER and LOAD_FROM_CACHE flags override
 // heuristic query freshness as defined in RFC 2616 section 13.9
 //
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpserver = new HttpServer();
 var index = 0;
 var tests = [
     // RFC 2616 section 13.9 2nd paragraph - query-url should be validated
     {url: "/freshness?a", server: "0", expected: "0"},
     {url: "/freshness?a", server: "1", expected: "1"},
 
@@ -39,19 +40,26 @@ function logit(i, data) {
     if (tests[i].responseheader)
         dump("\t[" + tests[i].responseheader + "]");
     dump("\n");
 }
 
 function setupChannel(suffix, value) {
     var ios = Components.classes["@mozilla.org/network/io-service;1"].
                          getService(Ci.nsIIOService);
-    var chan = ios.newChannel("http://localhost:" +
-                              httpserver.identity.primaryPort +
-                              suffix, "", null);
+    var chan = ios.newChannel2("http://localhost:" +
+                               httpserver.identity.primaryPort +
+                               suffix,
+                               "",
+                               null,
+                               null,      // aLoadingNode
+                               Services.scriptSecurityManager.getSystemPrincipal(),
+                               null,      // aTriggeringPrincipal
+                               Ci.nsILoadInfo.SEC_NORMAL,
+                               Ci.nsIContentPolicy.TYPE_OTHER);
     var httpChan = chan.QueryInterface(Components.interfaces.nsIHttpChannel);
     httpChan.requestMethod = "GET";
     httpChan.setRequestHeader("x-request", value, false);
     return httpChan;
 }
 
 function triggerNextTest() {
     var test = tests[index];
--- a/netwerk/test/unit/test_bug510359.js
+++ b/netwerk/test/unit/test_bug510359.js
@@ -1,23 +1,31 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpserver = new HttpServer();
 var index = 0;
 var tests = [
     { url : "/bug510359", server : "0", expected : "0"},
     { url : "/bug510359", server : "1", expected : "1"},
 ];
 
 function setupChannel(suffix, value) {
     var ios = Components.classes["@mozilla.org/network/io-service;1"]
             .getService(Ci.nsIIOService);
-    var chan = ios.newChannel("http://localhost:" +
-                              httpserver.identity.primaryPort +
-                              suffix, "", null);
+    var chan = ios.newChannel2("http://localhost:" +
+                               httpserver.identity.primaryPort +
+                               suffix,
+                               "",
+                               null,
+                               null,      // aLoadingNode
+                               Services.scriptSecurityManager.getSystemPrincipal(),
+                               null,      // aTriggeringPrincipal
+                               Ci.nsILoadInfo.SEC_NORMAL,
+                               Ci.nsIContentPolicy.TYPE_OTHER);
     var httpChan = chan.QueryInterface(Components.interfaces.nsIHttpChannel);
     httpChan.requestMethod = "GET";
     httpChan.setRequestHeader("x-request", value, false);
     httpChan.setRequestHeader("Cookie", "c="+value, false);
     return httpChan;
 }
 
 function triggerNextTest() {
--- a/netwerk/test/unit/test_bug515583.js
+++ b/netwerk/test/unit/test_bug515583.js
@@ -38,17 +38,24 @@ function storeData(status, entry) {
              "  Expected: " + written  + "\n" +
              "  Actual: " + tests[0][0].length + "\n");
   }
   os.close();
   entry.close();
 
   var ios = Components.classes["@mozilla.org/network/io-service;1"].
             getService(Components.interfaces.nsIIOService);
-  var channel = ios.newChannel(URL, "", null);
+  var channel = ios.newChannel2(URL,
+                                "",
+                                null,
+                                null,      // aLoadingNode
+                                Services.scriptSecurityManager.getSystemPrincipal(),
+                                null,      // aTriggeringPrincipal
+                                Ci.nsILoadInfo.SEC_NORMAL,
+                                Ci.nsIContentPolicy.TYPE_OTHER);
   channel.asyncOpen(new ChannelListener(checkData, null, CL_ALLOW_UNKNOWN_CL), null);
 }
 
 function next_test() {
   if (tests.length == 0)
     do_test_finished();
   else {
     asyncOpenCacheEntry(URL,
--- a/netwerk/test/unit/test_bug528292.js
+++ b/netwerk/test/unit/test_bug528292.js
@@ -1,9 +1,10 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 const sentCookieVal     = "foo=bar";
 const responseBody      = "response body";
 
 XPCOMUtils.defineLazyGetter(this, "baseURL", function() {
   return "http://localhost:" + httpServer.identity.primaryPort;
 });
 
@@ -58,17 +59,24 @@ function run_test()
 
   var ioService = Cc["@mozilla.org/network/io-service;1"].
                   getService(Ci.nsIIOService);
 
   // Set up a channel with forceAllowThirdPartyCookie set to true.  We'll use
   // the channel both to set a cookie (since nsICookieService::setCookieString
   // requires such a channel in order to successfully set a cookie) and then
   // to load the pre-redirect URI.
-  var chan = ioService.newChannel(preRedirectURL, "", null).
+  var chan = ioService.newChannel2(preRedirectURL,
+                                   "",
+                                   null,
+                                   null,      // aLoadingNode
+                                   Services.scriptSecurityManager.getSystemPrincipal(),
+                                   null,      // aTriggeringPrincipal
+                                   Ci.nsILoadInfo.SEC_NORMAL,
+                                   Ci.nsIContentPolicy.TYPE_OTHER).
              QueryInterface(Ci.nsIHttpChannel).
              QueryInterface(Ci.nsIHttpChannelInternal);
   chan.forceAllowThirdPartyCookie = true;
 
   // Set a cookie on one of the URIs.  It doesn't matter which one, since
   // they're both from the same host, which is enough for the cookie service
   // to send the cookie with both requests.
   var postRedirectURI = ioService.newURI(postRedirectURL, "", null);
--- a/netwerk/test/unit/test_bug536324_64bit_content_length.js
+++ b/netwerk/test/unit/test_bug536324_64bit_content_length.js
@@ -1,12 +1,13 @@
 /* Test to ensure our 64-bit content length implementation works, at least for
    a simple HTTP case */
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 // This C-L is significantly larger than (U)INT32_MAX, to make sure we do
 // 64-bit properly.
 const CONTENT_LENGTH = "1152921504606846975";
 
 var httpServer = null;
 
 var listener = {
@@ -42,18 +43,25 @@ function hugeContentLength(metadata, res
     bytes_written += text.length;
   }
 
   response.finish();
 }
 
 function test_hugeContentLength() {
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-  var chan = ios.newChannel("http://localhost:" +
-                            httpServer.identity.primaryPort + "/", null, null)
+  var chan = ios.newChannel2("http://localhost:" +
+                             httpServer.identity.primaryPort + "/",
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER)
                 .QueryInterface(Ci.nsIHttpChannel);
   chan.asyncOpen(listener, null);
 }
 
 add_test(test_hugeContentLength);
 
 function run_test() {
   httpServer = new HttpServer();
--- a/netwerk/test/unit/test_bug543805.js
+++ b/netwerk/test/unit/test_bug543805.js
@@ -56,17 +56,24 @@ function storeData(status, entry) {
              "  Expected: " + written  + "\n" +
              "  Actual: " + tests[0][0].length + "\n");
   }
   os.close();
   entry.close();
 
   var ios = Components.classes["@mozilla.org/network/io-service;1"].
             getService(Components.interfaces.nsIIOService);
-  var channel = ios.newChannel(URL, "", null);
+  var channel = ios.newChannel2(URL,
+                                "",
+                                null,
+                                null,      // aLoadingNode
+                                Services.scriptSecurityManager.getSystemPrincipal(),
+                                null,      // aTriggeringPrincipal
+                                Ci.nsILoadInfo.SEC_NORMAL,
+                                Ci.nsIContentPolicy.TYPE_OTHER);
   channel.asyncOpen(new ChannelListener(checkData, null, CL_ALLOW_UNKNOWN_CL), null);
 }
 
 function next_test() {
   if (tests.length == 0)
     do_test_finished();
   else {
     asyncOpenCacheEntry(URL,
--- a/netwerk/test/unit/test_bug561042.js
+++ b/netwerk/test/unit/test_bug561042.js
@@ -1,9 +1,10 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 const SERVER_PORT = 8080;
 const baseURL = "http://localhost:" + SERVER_PORT + "/";
 
 var cookie = "";
 for (let i =0; i < 10000; i++) {
     cookie += " big cookie";
 }
@@ -28,13 +29,20 @@ function run_test() {
     server.registerPathHandler('/', function(metadata, response) {
         response.setStatusLine(metadata.httpVersion, 200, "OK");
         response.setHeader("Set-Cookie", "BigCookie=" + cookie, false);
         response.write("Hello world");
     });
 
     var ios = Components.classes["@mozilla.org/network/io-service;1"]
                          .getService(Components.interfaces.nsIIOService);
-    var chan = ios.newChannel(baseURL, null, null)
+    var chan = ios.newChannel2(baseURL,
+                               null,
+                               null,
+                               null,      // aLoadingNode
+                               Services.scriptSecurityManager.getSystemPrincipal(),
+                               null,      // aTriggeringPrincipal
+                               Ci.nsILoadInfo.SEC_NORMAL,
+                               Ci.nsIContentPolicy.TYPE_OTHER)
                   .QueryInterface(Components.interfaces.nsIHttpChannel);
     chan.asyncOpen(listener, null);
     do_test_pending();
 }
--- a/netwerk/test/unit/test_bug561276.js
+++ b/netwerk/test/unit/test_bug561276.js
@@ -1,25 +1,33 @@
 //
 // Verify that we hit the net if we discover a cycle of redirects
 // coming from cache.
 //
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpserver = new HttpServer();
 var iteration = 0;
 
 function setupChannel(suffix)
 {
     var ios =
         Components.classes["@mozilla.org/network/io-service;1"]
         .getService(Ci.nsIIOService);
-    var chan = ios.newChannel("http://localhost:" +
-			     httpserver.identity.primaryPort + suffix, "", null);
+    var chan = ios.newChannel2("http://localhost:" +
+			                         httpserver.identity.primaryPort + suffix,
+                               "",
+                               null,
+                               null,      // aLoadingNode
+                               Services.scriptSecurityManager.getSystemPrincipal(),
+                               null,      // aTriggeringPrincipal
+                               Ci.nsILoadInfo.SEC_NORMAL,
+                               Ci.nsIContentPolicy.TYPE_OTHER);
     var httpChan = chan.QueryInterface(Components.interfaces.nsIHttpChannel);
     httpChan.requestMethod = "GET";
     return httpChan;
 }
 
 function checkValueAndTrigger(request, data, ctx)
 {
     do_check_eq("Ok", data);
--- a/netwerk/test/unit/test_bug586908.js
+++ b/netwerk/test/unit/test_bug586908.js
@@ -1,9 +1,10 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpserv = null;
 
 const CID = Components.ID("{5645d2c1-d6d8-4091-b117-fe7ee4027db7}");
 const contractID = "@mozilla.org/system-proxy-settings;1"
 
 XPCOMUtils.defineLazyGetter(this, "systemSettings", function() {
   return {
@@ -35,17 +36,24 @@ function checkValue(request, data, ctx) 
   do_check_true(called);
   do_check_eq("ok", data);
   httpserv.stop(do_test_finished);
 }
 
 function makeChan(url) {
   var ios = Components.classes["@mozilla.org/network/io-service;1"]
                       .getService(Components.interfaces.nsIIOService);
-  var chan = ios.newChannel(url, null, null)
+  var chan = ios.newChannel2(url,
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER)
                 .QueryInterface(Components.interfaces.nsIHttpChannel);
 
   return chan;
 }
 
 function run_test() {
   httpserv = new HttpServer();
   httpserv.registerPathHandler("/redirect", redirect);
--- a/netwerk/test/unit/test_bug596443.js
+++ b/netwerk/test/unit/test_bug596443.js
@@ -1,19 +1,28 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
+
 var httpserver = new HttpServer();
 
 var expectedOnStopRequests = 3;
 
 function setupChannel(suffix, xRequest, flags) {
     var ios = Components.classes["@mozilla.org/network/io-service;1"]
             .getService(Ci.nsIIOService);
-    var chan = ios.newChannel("http://localhost:" +
-                              httpserver.identity.primaryPort +
-                              suffix, "", null);
+    var chan = ios.newChannel2("http://localhost:" +
+                               httpserver.identity.primaryPort +
+                               suffix,
+                               "",
+                               null,
+                               null,      // aLoadingNode
+                               Services.scriptSecurityManager.getSystemPrincipal(),
+                               null,      // aTriggeringPrincipal
+                               Ci.nsILoadInfo.SEC_NORMAL,
+                               Ci.nsIContentPolicy.TYPE_OTHER);
     if (flags)
         chan.loadFlags |= flags;
 
     var httpChan = chan.QueryInterface(Components.interfaces.nsIHttpChannel);
     httpChan.setRequestHeader("x-request", xRequest, false);
         
     return httpChan;
 }
--- a/netwerk/test/unit/test_bug618835.js
+++ b/netwerk/test/unit/test_bug618835.js
@@ -7,24 +7,32 @@
 // redirects (301) to "/redirect". The URIs "/redirect" and "/cl" both counts
 // the number of loads from the server (handler). The response from "/post"
 // always contains the headers "Location: /redirect" and "Content-Location:
 // /cl", whose cached entries are to be invalidated. The tests verifies that
 // "/redirect" and "/cl" are loaded from server the expected number of times.
 //
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpserv;
 
 function setupChannel(path) {
     var ios =
         Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-    return chan = ios.newChannel(path, "", null)
-                                .QueryInterface(Ci.nsIHttpChannel);
+    return chan = ios.newChannel2(path,
+                                  "",
+                                  null,
+                                  null,      // aLoadingNode
+                                  Services.scriptSecurityManager.getSystemPrincipal(),
+                                  null,      // aTriggeringPrincipal
+                                  Ci.nsILoadInfo.SEC_NORMAL,
+                                  Ci.nsIContentPolicy.TYPE_OTHER)
+                     .QueryInterface(Ci.nsIHttpChannel);
 }
 
 // Verify that Content-Location-URI has been loaded once, load post_target
 function InitialListener() { }
 InitialListener.prototype = {
     onStartRequest: function(request, context) { },
     onStopRequest: function(request, context, status) {
         do_check_eq(1, numberOfCLHandlerCalls);
--- a/netwerk/test/unit/test_bug633743.js
+++ b/netwerk/test/unit/test_bug633743.js
@@ -1,22 +1,31 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 const VALUE_HDR_NAME = "X-HTTP-VALUE-HEADER";
 const VARY_HDR_NAME = "X-HTTP-VARY-HEADER";
 const CACHECTRL_HDR_NAME = "X-CACHE-CONTROL-HEADER";
 
 var httpserver = null;
 
 function make_channel(flags, vary, value) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
     getService(Ci.nsIIOService);
-  var chan = ios.newChannel("http://localhost:" +
-                            httpserver.identity.primaryPort +
-                            "/bug633743", null, null);
+  var chan = ios.newChannel2("http://localhost:" +
+                             httpserver.identity.primaryPort +
+                             "/bug633743",
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER)
+                .QueryInterface(Components.interfaces.nsIHttpChannel);
   return chan.QueryInterface(Ci.nsIHttpChannel);
 }
 
 function Test(flags, varyHdr, sendValue, expectValue, cacheHdr) {
     this._flags = flags;
     this._varyHdr = varyHdr;
     this._sendVal = sendValue;
     this._expectVal = expectValue;
--- a/netwerk/test/unit/test_bug650995.js
+++ b/netwerk/test/unit/test_bug650995.js
@@ -1,14 +1,15 @@
 //
 // Test that "max_entry_size" prefs for disk- and memory-cache prevents
 // caching resources with size out of bounds
 //
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 do_get_profile();
 
 const prefService = Cc["@mozilla.org/preferences-service;1"]
                        .getService(Ci.nsIPrefBranch);
 
 const httpserver = new HttpServer();
 
@@ -17,19 +18,26 @@ function repeatToLargerThan1K(data) {
     while(data.length <= 1024)
         data += data;
     return data;
 }
 
 function setupChannel(suffix, value) {
     var ios = Components.classes["@mozilla.org/network/io-service;1"]
             .getService(Ci.nsIIOService);
-    var chan = ios.newChannel("http://localhost:" +
-                              httpserver.identity.primaryPort +
-                              suffix, "", null);
+    var chan = ios.newChannel2("http://localhost:" +
+                               httpserver.identity.primaryPort +
+                               suffix,
+                               "",
+                               null,
+                               null,      // aLoadingNode
+                               Services.scriptSecurityManager.getSystemPrincipal(),
+                               null,      // aTriggeringPrincipal
+                               Ci.nsILoadInfo.SEC_NORMAL,
+                               Ci.nsIContentPolicy.TYPE_OTHER);
     var httpChan = chan.QueryInterface(Components.interfaces.nsIHttpChannel);
     httpChan.setRequestHeader("x-request", value, false);
     
     return httpChan;
 }
 
 var tests = [
              new InitializeCacheDevices(true, false), // enable and create mem-device
--- a/netwerk/test/unit/test_bug652761.js
+++ b/netwerk/test/unit/test_bug652761.js
@@ -1,18 +1,27 @@
 // This is just a crashtest for a url that is rejected at parse time (port 80,000)
 
+Cu.import("resource://gre/modules/Services.jsm");
+
 function completeTest(request, data, ctx)
 {
     do_test_finished();
 }
 
 function run_test()
 {
     var ios = Components.classes["@mozilla.org/network/io-service;1"].
                          getService(Components.interfaces.nsIIOService);
-    var chan = ios.newChannel("http://localhost:80000/", "", null);
+    var chan = ios.newChannel2("http://localhost:80000/",
+                               "",
+                               null,
+                               null,      // aLoadingNode
+                               Services.scriptSecurityManager.getSystemPrincipal(),
+                               null,      // aTriggeringPrincipal
+                               Ci.nsILoadInfo.SEC_NORMAL,
+                               Ci.nsIContentPolicy.TYPE_OTHER);
     var httpChan = chan.QueryInterface(Components.interfaces.nsIHttpChannel);
     httpChan.asyncOpen(new ChannelListener(completeTest,
                                            httpChan, CL_EXPECT_FAILURE), null);
     do_test_pending();
 }
 
--- a/netwerk/test/unit/test_bug659569.js
+++ b/netwerk/test/unit/test_bug659569.js
@@ -2,19 +2,26 @@ Cu.import("resource://testing-common/htt
 Cu.import("resource://gre/modules/Services.jsm");
 var httpserver = new HttpServer();
 
 function setupChannel(suffix)
 {
     var ios =
         Components.classes["@mozilla.org/network/io-service;1"]
         .getService(Ci.nsIIOService);
-    var chan = ios.newChannel("http://localhost:" +
-			      httpserver.identity.primaryPort +
-			      suffix, "", null);
+    var chan = ios.newChannel2("http://localhost:" +
+			                         httpserver.identity.primaryPort +
+			                         suffix,
+                               "",
+                               null,
+                               null,      // aLoadingNode
+                               Services.scriptSecurityManager.getSystemPrincipal(),
+                               null,      // aTriggeringPrincipal
+                               Ci.nsILoadInfo.SEC_NORMAL,
+                               Ci.nsIContentPolicy.TYPE_OTHER);
     return chan;
 }
 
 function checkValueAndTrigger(request, data, ctx)
 {
     do_check_eq("Ok", data);
     httpserver.stop(do_test_finished);
 }
--- a/netwerk/test/unit/test_bug667907.js
+++ b/netwerk/test/unit/test_bug667907.js
@@ -1,9 +1,10 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpserver = null;
 var simplePath = "/simple";
 var normalPath = "/normal";
 var httpbody = "<html></html>";
 
 XPCOMUtils.defineLazyGetter(this, "uri1", function() {
   return "http://localhost:" + httpserver.identity.primaryPort + simplePath;
@@ -11,17 +12,24 @@ XPCOMUtils.defineLazyGetter(this, "uri1"
 
 XPCOMUtils.defineLazyGetter(this, "uri2", function() {
   return "http://localhost:" + httpserver.identity.primaryPort + normalPath;
 });
 
 function make_channel(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 var listener_proto = {
   QueryInterface: function(iid) {
     if (iid.equals(Components.interfaces.nsIStreamListener) ||
         iid.equals(Components.interfaces.nsIRequestObserver) ||
         iid.equals(Components.interfaces.nsISupports))
       return this;
--- a/netwerk/test/unit/test_bug669001.js
+++ b/netwerk/test/unit/test_bug669001.js
@@ -1,21 +1,29 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpServer = null;
 var path = "/bug699001";
 
 XPCOMUtils.defineLazyGetter(this, "URI", function() {
   return "http://localhost:" + httpServer.identity.primaryPort + path;
 });
 
 function make_channel(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 var fetched;
 
 // The test loads a resource that expires in one year, has an etag and varies only by User-Agent
 // First we load it, then check we load it only from the cache w/o even checking with the server
 // Then we modify our User-Agent and try it again
 // We have to get a new content (even though with the same etag) and again on next load only from
--- a/netwerk/test/unit/test_bug770243.js
+++ b/netwerk/test/unit/test_bug770243.js
@@ -3,16 +3,17 @@
  1. 200 + ETag: "one"
  2. 401 followed by 200 + ETag: "two"
  3. 401 followed by 304
  4. 407 followed by 200 + ETag: "three"
  5. 407 followed by 304
 */
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpserv;
 
 function addCreds(scheme, host)
 {
   var authMgr = Components.classes['@mozilla.org/network/http-auth-manager;1']
                           .getService(Ci.nsIHttpAuthManager);
   authMgr.setAuthIdentity(scheme, host, httpserv.identity.primaryPort,
@@ -24,18 +25,25 @@ function clearCreds()
   var authMgr = Components.classes['@mozilla.org/network/http-auth-manager;1']
                           .getService(Ci.nsIHttpAuthManager);
   authMgr.clearAll();
 }
 
 function makeChan() {
   var ios = Cc["@mozilla.org/network/io-service;1"]
                       .getService(Ci.nsIIOService);
-  var chan = ios.newChannel("http://localhost:" +
-                            httpserv.identity.primaryPort + "/", null, null)
+  var chan = ios.newChannel2("http://localhost:" +
+                             httpserv.identity.primaryPort + "/",
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER)
                 .QueryInterface(Ci.nsIHttpChannel);
   return chan;
 }
 
 // Array of handlers that are called one by one in response to expected requests
 
 var handlers = [
   // Test 1
--- a/netwerk/test/unit/test_bug812167.js
+++ b/netwerk/test/unit/test_bug812167.js
@@ -1,9 +1,10 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 /*
 - get 302 with Cache-control: no-store
 - check cache entry for the 302 response is cached only in memory device
 - get 302 with Expires: -1
 - check cache entry for the 302 response is not cached at all
 */
 
@@ -19,17 +20,24 @@ var randomPath2 = "/redirect-expires-pas
 
 XPCOMUtils.defineLazyGetter(this, "randomURI2", function() {
   return "http://localhost:" + httpserver.identity.primaryPort + randomPath2;
 });
 
 function make_channel(url, callback, ctx) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 const responseBody = "response body";
 
 var redirectHandler_NoStore_calls = 0;
 function redirectHandler_NoStore(metadata, response)
 {
   response.setStatusLine(metadata.httpVersion, 302, "Found");
--- a/netwerk/test/unit/test_bug826063.js
+++ b/netwerk/test/unit/test_bug826063.js
@@ -20,17 +20,24 @@ function LoadContext(usePrivateBrowsing)
 }
 LoadContext.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsILoadContext, Ci.nsIInterfaceRequestor]),
   getInterface: XPCOMUtils.generateQI([Ci.nsILoadContext])
 };
 
 function getChannels() {
   for (let u of URIs) {
-    yield Services.io.newChannel(u, null, null);
+    yield Services.io.newChannel2(u,
+                                  null,
+                                  null,
+                                  null,      // aLoadingNode
+                                  Services.scriptSecurityManager.getSystemPrincipal(),
+                                  null,      // aTriggeringPrincipal
+                                  Ci.nsILoadInfo.SEC_NORMAL,
+                                  Ci.nsIContentPolicy.TYPE_OTHER);
   }
 }
 
 function checkPrivate(channel, shouldBePrivate) {
   do_check_eq(channel.QueryInterface(Ci.nsIPrivateBrowsingChannel).isChannelPrivate,
               shouldBePrivate);
 }
 
--- a/netwerk/test/unit/test_bug856978.js
+++ b/netwerk/test/unit/test_bug856978.js
@@ -5,16 +5,17 @@
 // This test makes sure that the authorization header can get deleted e.g. by
 // extensions if they are observing "http-on-modify-request". In a first step
 // the auth cache is filled with credentials which then get added to the
 // following request. On "http-on-modify-request" it is tested whether the
 // authorization header got added at all and if so it gets removed. This test
 // passes iff both succeeds.
 
 Components.utils.import("resource://testing-common/httpd.js");
+Components.utils.import("resource://gre/modules/Services.jsm");
 
 var notification = "http-on-modify-request";
 
 var httpServer = null;
 
 var authCredentials = "guest:guest";
 var authPath = "/authTest";
 var authCredsURL = "http://" + authCredentials + "@localhost:8888" + authPath;
@@ -92,17 +93,24 @@ var listener = {
       httpServer.stop(do_test_finished);
     }
     do_test_finished();
   }
 };
 
 function makeChan(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-  var chan = ios.newChannel(url, null, null).QueryInterface(Ci.nsIHttpChannel);
+  var chan = ios.newChannel2(url,
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER).QueryInterface(Ci.nsIHttpChannel);
   return chan;
 }
 
 var tests = [startAuthHeaderTest, removeAuthHeaderTest];
 
 var current_test = 0;
 
 var requestObserver = null;
--- a/netwerk/test/unit/test_bug894586.js
+++ b/netwerk/test/unit/test_bug894586.js
@@ -39,17 +39,22 @@ ProtocolHandler.prototype = {
   get contentLength() -1,
   set contentLength(val) {
     throw Components.Exception("Setting content length", NS_ERROR_NOT_IMPLEMENTED);
   },
   open: function() {
     var file = do_get_file("test_bug894586.js", false);
     do_check_true(file.exists());
     var url = Services.io.newFileURI(file);
-    return Services.io.newChannelFromURI(url).open();
+    return Services.io.newChannelFromURI2(url,
+                                          null,      // aLoadingNode
+                                          Services.scriptSecurityManager.getSystemPrincipal(),
+                                          null,      // aTriggeringPrincipal
+                                          Ci.nsILoadInfo.SEC_NORMAL,
+                                          Ci.nsIContentPolicy.TYPE_OTHER).open();
   },
   asyncOpen: function(aListener, aContext) {
     throw Components.Exception("Not implemented",
                                Cr.NS_ERROR_NOT_IMPLEMENTED);
   },
   contentDisposition: Ci.nsIChannel.DISPOSITION_INLINE,
   get contentDispositionFilename() {
     throw Components.Exception("No file name",
--- a/netwerk/test/unit/test_cache2-28-concurrent_read_resumable_entry_size_zero.js
+++ b/netwerk/test/unit/test_cache2-28-concurrent_read_resumable_entry_size_zero.js
@@ -18,17 +18,24 @@ XPCOMUtils.defineLazyGetter(this, "URL",
   return "http://localhost:" + httpServer.identity.primaryPort;
 });
 
 var httpServer = null;
 
 function make_channel(url, callback, ctx) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 const responseBody = "response body";
 
 function contentHandler(metadata, response)
 {
   response.setHeader("Content-Type", "text/plain");
   response.setHeader("ETag", "Just testing");
--- a/netwerk/test/unit/test_cache2-29-concurrent_read_non-resumable_entry_size_zero.js
+++ b/netwerk/test/unit/test_cache2-29-concurrent_read_non-resumable_entry_size_zero.js
@@ -20,17 +20,24 @@ XPCOMUtils.defineLazyGetter(this, "URL",
   return "http://localhost:" + httpServer.identity.primaryPort;
 });
 
 var httpServer = null;
 
 function make_channel(url, callback, ctx) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 const responseBody = "c\r\ndata reached\r\n3\r\nhej\r\n0\r\n\r\n";
 const responseBodyDecoded = "data reachedhej";
 
 function contentHandler(metadata, response)
 {
   response.seizePower();
--- a/netwerk/test/unit/test_cacheForOfflineUse_no-store.js
+++ b/netwerk/test/unit/test_cacheForOfflineUse_no-store.js
@@ -1,12 +1,13 @@
 "use strict";
 // https://bugzilla.mozilla.org/show_bug.cgi?id=760955
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpServer = null;
 const testFileName = "test_nsHttpChannel_CacheForOfflineUse-no-store";
 const cacheClientID = testFileName + "|fake-group-id";
 const basePath = "/" + testFileName + "/";
 
 XPCOMUtils.defineLazyGetter(this, "baseURI", function() {
   return "http://localhost:" + httpServer.identity.primaryPort + basePath;
@@ -16,17 +17,24 @@ const normalEntry = "normal";
 const noStoreEntry = "no-store";
 
 var cacheUpdateObserver = null;
 var appCache = null;
 
 function make_channel_for_offline_use(url, callback, ctx) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  var chan = ios.newChannel(url, "", null);
+  var chan = ios.newChannel2(url,
+                             "",
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER);
   
   var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"].
                      getService(Components.interfaces.nsIApplicationCacheService);
   appCache = cacheService.getApplicationCache(cacheClientID);
   
   var appCacheChan = chan.QueryInterface(Ci.nsIApplicationCacheChannel);
   appCacheChan.applicationCacheForWrite = appCache;
   return chan;
--- a/netwerk/test/unit/test_cache_jar.js
+++ b/netwerk/test/unit/test_cache_jar.js
@@ -15,17 +15,24 @@ function cached_handler(metadata, respon
   response.setStatusLine(metadata.httpVersion, 200, "OK");
   var body = "0123456789";
   response.bodyOutputStream.write(body, body.length);
   handlers_called++;
 }
 
 function makeChan(url, appId, inBrowser) {
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-  var chan = ios.newChannel(url, null, null).QueryInterface(Ci.nsIHttpChannel);
+  var chan = ios.newChannel2(url,
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER).QueryInterface(Ci.nsIHttpChannel);
   chan.notificationCallbacks = {
     appId: appId,
     isInBrowserElement: inBrowser,
     QueryInterface: function(iid) {
       if (iid.equals(Ci.nsILoadContext))
         return this;
       throw Cr.NS_ERROR_NO_INTERFACE;
     },
--- a/netwerk/test/unit/test_cacheflags.js
+++ b/netwerk/test/unit/test_cacheflags.js
@@ -1,9 +1,10 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpserver = new HttpServer();
 httpserver.start(-1);
 
 // Need to randomize, because apparently no one clears our cache
 var suffix = Math.random();
 var httpBase = "http://localhost:" + httpserver.identity.primaryPort;
 var httpsBase = "http://localhost:4445";
@@ -35,17 +36,24 @@ LoadContext.prototype = {
   }
 };
 
 PrivateBrowsingLoadContext = new LoadContext(true);
 
 function make_channel(url, flags, usePrivateBrowsing) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
     getService(Ci.nsIIOService);
-  var req = ios.newChannel(url, null, null);
+  var req = ios.newChannel2(url,
+                            null,
+                            null,
+                            null,      // aLoadingNode
+                            Services.scriptSecurityManager.getSystemPrincipal(),
+                            null,      // aTriggeringPrincipal
+                            Ci.nsILoadInfo.SEC_NORMAL,
+                            Ci.nsIContentPolicy.TYPE_OTHER);
   req.loadFlags = flags;
   if (usePrivateBrowsing) {
     req.notificationCallbacks = PrivateBrowsingLoadContext;    
   }
   return req;
 }
 
 function Test(path, flags, expectSuccess, readFromCache, hitServer, 
--- a/netwerk/test/unit/test_channel_close.js
+++ b/netwerk/test/unit/test_channel_close.js
@@ -1,9 +1,10 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "URL", function() {
   return "http://localhost:" + httpserver.identity.primaryPort;
 });
 
 var httpserver = new HttpServer();
 var testpath = "/simple";
 var httpbody = "0123456789";
@@ -33,17 +34,24 @@ function run_test() {
   live_channels[1].asyncOpen(
       new ChannelListener(checkRequestFinish, live_channels[1]), null);
 
   do_test_pending();
 }
 
 function setupChannel(path) {
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-  var chan = ios.newChannel(URL + path, "", null);
+  var chan = ios.newChannel2(URL + path,
+                             "",
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER);
   chan.QueryInterface(Ci.nsIHttpChannel);
   chan.requestMethod = "GET";
   return chan;
 }
 
 function serverHandler(metadata, response) {
   response.setHeader("Content-Type", "text/plain", false);
   response.bodyOutputStream.write(httpbody, httpbody.length);
--- a/netwerk/test/unit/test_chunked_responses.js
+++ b/netwerk/test/unit/test_chunked_responses.js
@@ -1,16 +1,17 @@
 /*
  * Test Chunked-Encoded response parsing.
  */
 
 ////////////////////////////////////////////////////////////////////////////////
 // Test infrastructure
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "URL", function() {
   return "http://localhost:" + httpserver.identity.primaryPort;
 });
 
 var httpserver = new HttpServer();
 var index = 0;
 var test_flags = new Array();
@@ -34,17 +35,24 @@ function run_test_number(num)
   channel.asyncOpen(new ChannelListener(eval("completeTest" + num),
                                         channel, flags), null);
 }
 
 function setupChannel(url)
 {
   var ios = Components.classes["@mozilla.org/network/io-service;1"].
                        getService(Ci.nsIIOService);
-  var chan = ios.newChannel(URL + url, "", null);
+  var chan = ios.newChannel2(URL + url,
+                             "",
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER);
   var httpChan = chan.QueryInterface(Components.interfaces.nsIHttpChannel);
   return httpChan;
 }
 
 function endTests()
 {
   httpserver.stop(do_test_finished);
 }
--- a/netwerk/test/unit/test_content_encoding_gzip.js
+++ b/netwerk/test/unit/test_content_encoding_gzip.js
@@ -1,9 +1,10 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpserver = new HttpServer();
 var index = 0;
 var tests = [
     {url: "/test/cegzip1",
      flags: CL_EXPECT_GZIP,
      ce: "gzip",
      body: [
@@ -23,18 +24,25 @@ var tests = [
 	 0x00, 0x6e, 0x90, 0x7a, 0x85, 0x24, 0x00, 0x00, 0x00],
      datalen: 14 // the data length of the uncompressed document
     },
 ];
 
 function setupChannel(url) {
     var ios = Components.classes["@mozilla.org/network/io-service;1"].
                          getService(Ci.nsIIOService);
-    var chan = ios.newChannel("http://localhost:" +
-			      httpserver.identity.primaryPort + url, "", null);
+    var chan = ios.newChannel2("http://localhost:" +
+                               httpserver.identity.primaryPort + url,
+                               "",
+                               null,
+                               null,      // aLoadingNode
+                               Services.scriptSecurityManager.getSystemPrincipal(),
+                               null,      // aTriggeringPrincipal
+                               Ci.nsILoadInfo.SEC_NORMAL,
+                               Ci.nsIContentPolicy.TYPE_OTHER);
     return chan;
 }
 
 function startIter() {
     var channel = setupChannel(tests[index].url);
     channel.asyncOpen(new ChannelListener(completeIter, channel, tests[index].flags), null);
 }
 
--- a/netwerk/test/unit/test_content_length_underrun.js
+++ b/netwerk/test/unit/test_content_length_underrun.js
@@ -1,16 +1,17 @@
 /*
  * Test Content-Length underrun behavior
  */
 
 ////////////////////////////////////////////////////////////////////////////////
 // Test infrastructure
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "URL", function() {
   return "http://localhost:" + httpserver.identity.primaryPort;
 });
 
 var httpserver = new HttpServer();
 var index = 0;
 var test_flags = new Array();
@@ -41,17 +42,24 @@ function run_test_number(num)
   channel.asyncOpen(new ChannelListener(eval("completeTest" + num),
                                         channel, flags), null);
 }
 
 function setupChannel(url)
 {
   var ios = Components.classes["@mozilla.org/network/io-service;1"].
                        getService(Ci.nsIIOService);
-  var chan = ios.newChannel(URL + url, "", null);
+  var chan = ios.newChannel2(URL + url,
+                             "",
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER);
   var httpChan = chan.QueryInterface(Components.interfaces.nsIHttpChannel);
   return httpChan;
 }
 
 function endTests()
 {
   prefs.setBoolPref("network.http.enforce-framing.http1", enforcePref);
   httpserver.stop(do_test_finished);
--- a/netwerk/test/unit/test_content_sniffer.js
+++ b/netwerk/test/unit/test_content_sniffer.js
@@ -1,11 +1,12 @@
 // This file tests nsIContentSniffer, introduced in bug 324985
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 const unknownType = "application/x-unknown-content-type";
 const sniffedType = "application/x-sniffed";
 
 const snifferCID = Components.ID("{4c93d2db-8a56-48d7-b261-9cf2a8d998eb}");
 const snifferContract = "@mozilla.org/network/unittest/contentsniffer;1";
 const categoryName = "net-content-sniffers";
 
@@ -67,17 +68,24 @@ var listener = {
   },
 
   _iteration: 1
 };
 
 function makeChan(url) {
   var ios = Components.classes["@mozilla.org/network/io-service;1"]
                       .getService(Components.interfaces.nsIIOService);
-  var chan = ios.newChannel(url, null, null);
+  var chan = ios.newChannel2(url,
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER);
   if (sniffing_enabled)
     chan.loadFlags |= Components.interfaces.nsIChannel.LOAD_CALL_CONTENT_SNIFFERS;
 
   return chan;
 }
 
 var httpserv = null;
 var urls = null;
--- a/netwerk/test/unit/test_cookie_header.js
+++ b/netwerk/test/unit/test_cookie_header.js
@@ -53,17 +53,24 @@ var listener = {
   },
 
   _iteration: 1
 };
 
 function makeChan() {
   var ios = Components.classes["@mozilla.org/network/io-service;1"]
                       .getService(Components.interfaces.nsIIOService);
-  var chan = ios.newChannel(URL, null, null)
+  var chan = ios.newChannel2(URL,
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER)
                 .QueryInterface(Components.interfaces.nsIHttpChannel);
 
   return chan;
 }
 
 var httpserv = null;
 
 function run_test() {
--- a/netwerk/test/unit/test_cookiejars.js
+++ b/netwerk/test/unit/test_cookiejars.js
@@ -44,17 +44,24 @@ var tests = [
 ];
 
 // test number: index into 'tests' array
 var i = 0;
 
 function setupChannel(path)
 {
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-  var chan = ios.newChannel(URL + path, "", null);
+  var chan = ios.newChannel2(URL + path,
+                             "",
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER);
   chan.notificationCallbacks = tests[i].loadContext;
   chan.QueryInterface(Ci.nsIHttpChannel);
   return chan;
 }
 
 function setCookie() {
   var channel = setupChannel(cookieSetPath);
   channel.setRequestHeader("foo-set-cookie", tests[i].cookieName, false);
--- a/netwerk/test/unit/test_cookiejars_safebrowsing.js
+++ b/netwerk/test/unit/test_cookiejars_safebrowsing.js
@@ -64,17 +64,24 @@ function safebrowsingUpdateHandler(metad
   response.setStatusLine(metadata.httpVersion, 200, "Ok");
   response.setHeader("set-Cookie", cookieName + "=1; Path=/", false);
   response.setHeader("Content-Type", "text/plain");
   response.bodyOutputStream.write("Ok", "Ok".length);
 }
 
 function setupChannel(path, loadContext) {
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-  var channel = ios.newChannel(URL + path, "", null);
+  var channel = ios.newChannel2(URL + path,
+                                "",
+                                null,
+                                null,      // aLoadingNode
+                                Services.scriptSecurityManager.getSystemPrincipal(),
+                                null,      // aTriggeringPrincipal
+                                Ci.nsILoadInfo.SEC_NORMAL,
+                                Ci.nsIContentPolicy.TYPE_OTHER);
   channel.notificationCallbacks = loadContext;
   channel.QueryInterface(Ci.nsIHttpChannel);
   return channel;
 }
 
 function run_test() {
 
   // Set up a profile
--- a/netwerk/test/unit/test_data_protocol.js
+++ b/netwerk/test/unit/test_data_protocol.js
@@ -1,9 +1,10 @@
 /* run some tests on the data: protocol handler */
+Cu.import("resource://gre/modules/Services.jsm");
 
 // The behaviour wrt spaces is:
 // - Textual content keeps all spaces
 // - Other content strips unescaped spaces
 // - Base64 content strips escaped and unescaped spaces
 var urls = [
   ["data:,foo",                                     "text/plain",               "foo"],
   ["data:application/octet-stream,foo bar",         "application/octet-stream", "foobar"],
@@ -34,14 +35,21 @@ function run_test() {
     do_test_finished();
   }
 
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
   for (var i = 0; i < urls.length; ++i) {
     dump("*** opening channel " + i + "\n");
     do_test_pending();
-    var chan = ios.newChannel(urls[i][0], "", null);
+    var chan = ios.newChannel2(urls[i][0],
+                               "",
+                               null,
+                               null,      // aLoadingNode
+                               Services.scriptSecurityManager.getSystemPrincipal(),
+                               null,      // aTriggeringPrincipal
+                               Ci.nsILoadInfo.SEC_NORMAL,
+                               Ci.nsIContentPolicy.TYPE_OTHER);
     chan.contentType = "foo/bar"; // should be ignored
     chan.asyncOpen(new ChannelListener(on_read_complete, i), null);
   }
 }
 
--- a/netwerk/test/unit/test_duplicate_headers.js
+++ b/netwerk/test/unit/test_duplicate_headers.js
@@ -2,16 +2,17 @@
  * Tests bugs 597706, 655389: prevent duplicate headers with differing values
  * for some headers like Content-Length, Location, etc.
  */
 
 ////////////////////////////////////////////////////////////////////////////////
 // Test infrastructure
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "URL", function() {
   return "http://localhost:" + httpserver.identity.primaryPort;
 });
 
 var httpserver = new HttpServer();
 var index = 0;
 var test_flags = new Array();
@@ -35,17 +36,24 @@ function run_test_number(num)
   channel.asyncOpen(new ChannelListener(eval("completeTest" + num),
                                         channel, flags), null);
 }
 
 function setupChannel(url)
 {
   var ios = Components.classes["@mozilla.org/network/io-service;1"].
                        getService(Ci.nsIIOService);
-  var chan = ios.newChannel(URL + url, "", null);
+  var chan = ios.newChannel2(URL + url,
+                             "",
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER);
   var httpChan = chan.QueryInterface(Components.interfaces.nsIHttpChannel);
   return httpChan;
 }
 
 function endTests()
 {
   httpserver.stop(do_test_finished);
 }
--- a/netwerk/test/unit/test_event_sink.js
+++ b/netwerk/test/unit/test_event_sink.js
@@ -1,11 +1,12 @@
 // This file tests channel event sinks (bug 315598 et al)
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "URL", function() {
   return "http://localhost:" + httpserv.identity.primaryPort;
 });
 
 const sinkCID = Components.ID("{14aa4b81-e266-45cb-88f8-89595dece114}");
 const sinkContract = "@mozilla.org/network/unittest/channeleventsink;1";
 
@@ -93,17 +94,24 @@ var listener = {
   },
 
   _iteration: 1
 };
 
 function makeChan(url) {
   var ios = Components.classes["@mozilla.org/network/io-service;1"]
                       .getService(Components.interfaces.nsIIOService);
-  var chan = ios.newChannel(url, null, null)
+  var chan = ios.newChannel2(url,
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER)
                 .QueryInterface(Components.interfaces.nsIHttpChannel);
 
   return chan;
 }
 
 var httpserv = null;
 
 function run_test() {
--- a/netwerk/test/unit/test_fallback_no-cache-entry_canceled.js
+++ b/netwerk/test/unit/test_fallback_no-cache-entry_canceled.js
@@ -1,24 +1,32 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpServer = null;
 // Need to randomize, because apparently no one clears our cache
 var randomPath = "/redirect/" + Math.random();
 
 XPCOMUtils.defineLazyGetter(this, "randomURI", function() {
   return "http://localhost:" + httpServer.identity.primaryPort + randomPath;
 });
 
 var cacheUpdateObserver = null;
 
 function make_channel(url, callback, ctx) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 function make_uri(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
   return ios.newURI(url, null, null);
 }
 
--- a/netwerk/test/unit/test_fallback_no-cache-entry_passing.js
+++ b/netwerk/test/unit/test_fallback_no-cache-entry_passing.js
@@ -1,24 +1,32 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpServer = null;
 // Need to randomize, because apparently no one clears our cache
 var randomPath = "/redirect/" + Math.random();
 
 XPCOMUtils.defineLazyGetter(this, "randomURI", function() {
   return "http://localhost:" + httpServer.identity.primaryPort + randomPath;
 });
 
 var cacheUpdateObserver = null;
 
 function make_channel(url, callback, ctx) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 function make_uri(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
   return ios.newURI(url, null, null);
 }
 
--- a/netwerk/test/unit/test_fallback_redirect-to-different-origin_canceled.js
+++ b/netwerk/test/unit/test_fallback_redirect-to-different-origin_canceled.js
@@ -1,24 +1,32 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpServer = null;
 // Need to randomize, because apparently no one clears our cache
 var randomPath = "/redirect/" + Math.random();
 
 XPCOMUtils.defineLazyGetter(this, "randomURI", function() {
   return "http://localhost:" + httpServer.identity.primaryPort + randomPath;
 });
 
 var cacheUpdateObserver = null;
 
 function make_channel(url, callback, ctx) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 function make_uri(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
   return ios.newURI(url, null, null);
 }
 
--- a/netwerk/test/unit/test_fallback_redirect-to-different-origin_passing.js
+++ b/netwerk/test/unit/test_fallback_redirect-to-different-origin_passing.js
@@ -1,24 +1,32 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpServer = null;
 // Need to randomize, because apparently no one clears our cache
 var randomPath = "/redirect/" + Math.random();
 
 XPCOMUtils.defineLazyGetter(this, "randomURI", function() {
   return "http://localhost:" + httpServer.identity.primaryPort + randomPath;
 });
 
 var cacheUpdateObserver = null;
 
 function make_channel(url, callback, ctx) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 function make_uri(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
   return ios.newURI(url, null, null);
 }
 
--- a/netwerk/test/unit/test_fallback_request-error_canceled.js
+++ b/netwerk/test/unit/test_fallback_request-error_canceled.js
@@ -1,24 +1,32 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpServer = null;
 // Need to randomize, because apparently no one clears our cache
 var randomPath = "/redirect/" + Math.random();
 
 XPCOMUtils.defineLazyGetter(this, "randomURI", function() {
   return "http://localhost:" + httpServer.identity.primaryPort + randomPath;
 });
 
 var cacheUpdateObserver = null;
 
 function make_channel(url, callback, ctx) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 function make_uri(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
   return ios.newURI(url, null, null);
 }
 
--- a/netwerk/test/unit/test_fallback_request-error_passing.js
+++ b/netwerk/test/unit/test_fallback_request-error_passing.js
@@ -1,24 +1,32 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpServer = null;
 // Need to randomize, because apparently no one clears our cache
 var randomPath = "/redirect/" + Math.random();
 
 XPCOMUtils.defineLazyGetter(this, "randomURI", function() {
   return "http://localhost:" + httpServer.identity.primaryPort + randomPath;
 });
 
 var cacheUpdateObserver = null;
 
 function make_channel(url, callback, ctx) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 function make_uri(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
   return ios.newURI(url, null, null);
 }
 
--- a/netwerk/test/unit/test_fallback_response-error_canceled.js
+++ b/netwerk/test/unit/test_fallback_response-error_canceled.js
@@ -1,24 +1,32 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpServer = null;
 // Need to randomize, because apparently no one clears our cache
 var randomPath = "/error/" + Math.random();
 
 XPCOMUtils.defineLazyGetter(this, "randomURI", function() {
   return "http://localhost:" + httpServer.identity.primaryPort + randomPath;
 });
 
 var cacheUpdateObserver = null;
 
 function make_channel(url, callback, ctx) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 function make_uri(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
   return ios.newURI(url, null, null);
 }
 
--- a/netwerk/test/unit/test_fallback_response-error_passing.js
+++ b/netwerk/test/unit/test_fallback_response-error_passing.js
@@ -1,24 +1,32 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpServer = null;
 // Need to randomize, because apparently no one clears our cache
 var randomPath = "/error/" + Math.random();
 
 XPCOMUtils.defineLazyGetter(this, "randomURI", function() {
   return "http://localhost:" + httpServer.identity.primaryPort + randomPath;
 });
 
 var cacheUpdateObserver = null;
 
 function make_channel(url, callback, ctx) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 function make_uri(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
   return ios.newURI(url, null, null);
 }
 
--- a/netwerk/test/unit/test_file_protocol.js
+++ b/netwerk/test/unit/test_file_protocol.js
@@ -1,10 +1,12 @@
 /* run some tests on the file:// protocol handler */
 
+Cu.import("resource://gre/modules/Services.jsm");
+
 const PR_RDONLY = 0x1;  // see prio.h
 
 const special_type = "application/x-our-special-type";
 
 [
   test_read_file,
   test_read_dir_1,
   test_read_dir_2,
@@ -33,17 +35,22 @@ function new_file_input_stream(file, buf
   buffer.init(stream, 4096);
   return buffer;
 }
 
 function new_file_channel(file) {
   var ios =
       Cc["@mozilla.org/network/io-service;1"].
       getService(Ci.nsIIOService);
-  return ios.newChannelFromURI(ios.newFileURI(file));
+  return ios.newChannelFromURI2(ios.newFileURI(file),
+                                null,      // aLoadingNode
+                                Services.scriptSecurityManager.getSystemPrincipal(),
+                                null,      // aTriggeringPrincipal
+                                Ci.nsILoadInfo.SEC_NORMAL,
+                                Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 /*
  * stream listener
  * this listener has some additional file-specific tests, so we can't just use
  * ChannelListener here.
  */
 function FileStreamListener(closure) {
--- a/netwerk/test/unit/test_freshconnection.js
+++ b/netwerk/test/unit/test_freshconnection.js
@@ -1,11 +1,12 @@
 // This is essentially a debug mode crashtest to make sure everything
 // involved in a reload runs on the right thread. It relies on the
 // assertions in necko.
+Cu.import("resource://gre/modules/Services.jsm");
 
 var listener = {
   onStartRequest: function test_onStartR(request, ctx) {
   },
 
   onDataAvailable: function test_ODA() {
     do_throw("Should not get any data!");
   },
@@ -13,16 +14,23 @@ var listener = {
   onStopRequest: function test_onStopR(request, ctx, status) {
     do_test_finished();
   },
 };
 
 function run_test() {
   var ios = Cc["@mozilla.org/network/io-service;1"].
                        getService(Ci.nsIIOService);
-  var chan = ios.newChannel("http://localhost:4444", "", null);
+  var chan = ios.newChannel2("http://localhost:4444",
+                             "",
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER);
   chan.loadFlags = Ci.nsIRequest.LOAD_FRESH_CONNECTION |
 	           Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI;
   chan.QueryInterface(Ci.nsIHttpChannel);
   chan.asyncOpen(listener, null);
   do_test_pending();
 }
 
--- a/netwerk/test/unit/test_gre_resources.js
+++ b/netwerk/test/unit/test_gre_resources.js
@@ -1,23 +1,31 @@
 // test that things that are expected to be in gre-resources are still there
+Cu.import("resource://gre/modules/Services.jsm");
 
 var ios = Cc["@mozilla.org/network/io-service;1"]. getService(Ci.nsIIOService);
 
 function wrapInputStream(input)
 {
   var nsIScriptableInputStream = Components.interfaces.nsIScriptableInputStream;
   var factory = Components.classes["@mozilla.org/scriptableinputstream;1"];
   var wrapper = factory.createInstance(nsIScriptableInputStream);
   wrapper.init(input);
   return wrapper;
 }
 
 function check_file(file) {
-  var channel = ios.newChannel("resource://gre-resources/"+file, null, null);
+  var channel = ios.newChannel2("resource://gre-resources/"+file,
+                                null,
+                                null,
+                                null,      // aLoadingNode
+                                Services.scriptSecurityManager.getSystemPrincipal(),
+                                null,      // aTriggeringPrincipal
+                                Ci.nsILoadInfo.SEC_NORMAL,
+                                Ci.nsIContentPolicy.TYPE_OTHER);
   try {
     let instr = wrapInputStream(channel.open());
     do_check_true(instr.read(1024).length > 0)
   } catch (e) {
     do_throw("Failed to read " + file + " from gre-resources:"+e)
   }
 }
 
--- a/netwerk/test/unit/test_gzipped_206.js
+++ b/netwerk/test/unit/test_gzipped_206.js
@@ -7,17 +7,24 @@ var httpserver = null;
 const responseBody = [0x1f, 0x8b, 0x08, 0x08, 0xef, 0x70, 0xe6, 0x4c, 0x00, 0x03, 0x74, 0x65, 0x78, 0x74, 0x66, 0x69,
                      0x6c, 0x65, 0x2e, 0x74, 0x78, 0x74, 0x00, 0x0b, 0xc9, 0xc8, 0x2c, 0x56, 0x00, 0xa2, 0x44, 0x85,
                      0xe2, 0x9c, 0xcc, 0xf4, 0x8c, 0x92, 0x9c, 0x4a, 0x85, 0x9c, 0xfc, 0xbc, 0xf4, 0xd4, 0x22, 0x85,
                      0x92, 0xd4, 0xe2, 0x12, 0x2e, 0x2e, 0x00, 0x00, 0xe5, 0xe6, 0xf0, 0x20, 0x00, 0x00, 0x00];
 
 function make_channel(url, callback, ctx) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 var doRangeResponse = false;
 
 function cachedHandler(metadata, response) {
   response.setHeader("Content-Type", "application/x-gzip", false);
   response.setHeader("Content-Encoding", "gzip", false);
   response.setHeader("ETag", "Just testing");
--- a/netwerk/test/unit/test_head.js
+++ b/netwerk/test/unit/test_head.js
@@ -1,15 +1,16 @@
 //
 //  HTTP headers test
 //
 
 // Note: sets Cc and Ci variables
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "URL", function() {
   return "http://localhost:" + httpserver.identity.primaryPort;
 });
 
 var httpserver = new HttpServer();
 var testpath = "/simple";
 var httpbody = "0123456789";
@@ -59,17 +60,24 @@ function setup_test() {
   // ChannelListener defined in head_channels.js
   channel.asyncOpen(new ChannelListener(checkRequestResponse, channel), null);
 
   if (dbg) { print("============== setup_test: out"); }
 }
 
 function setupChannel(path) {
   ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-  var chan = ios.newChannel(URL + path, "", null);
+  var chan = ios.newChannel2(URL + path,
+                             "",
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER);
   chan.QueryInterface(Ci.nsIHttpChannel);
   chan.requestMethod = "GET";
   return chan;
 }
 
 function serverHandler(metadata, response) {
   if (dbg) { print("============== serverHandler: in"); }
 
--- a/netwerk/test/unit/test_header_Accept-Language.js
+++ b/netwerk/test/unit/test_header_Accept-Language.js
@@ -1,12 +1,14 @@
 //
 //  HTTP Accept-Language header test
 //
 
+Cu.import("resource://gre/modules/Services.jsm");
+
 var testpath = "/bug672448";
 
 function run_test() {
   let intlPrefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService).getBranch("intl.");
 
   // Save old value of preference for later.
   let oldPref = intlPrefs.getCharPref("accept_languages");
 
@@ -74,12 +76,19 @@ function test_accepted_languages() {
       // All the other languages should have an evenly-spaced quality value.
       do_check_eq(parseFloat(qualityValue).toFixed(decimalPlaces), (1.0 - ((1 / acceptedLanguagesLength) * i)).toFixed(decimalPlaces));
     }
   }
 }
 
 function setupChannel(path) {
   let ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-  let chan = ios.newChannel("http://localhost:4444" + path, "", null);
+  let chan = ios.newChannel2("http://localhost:4444" + path,
+                             "",
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER);
   chan.QueryInterface(Ci.nsIHttpChannel);
   return chan;
 }
--- a/netwerk/test/unit/test_headers.js
+++ b/netwerk/test/unit/test_headers.js
@@ -17,16 +17,17 @@
 
 var firstTest = 1;   // set to test of interest when debugging
 var lastTest = 4;    // set to test of interest when debugging
 ////////////////////////////////////////////////////////////////////////////////
 
 // Note: sets Cc and Ci variables
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "URL", function() {
   return "http://localhost:" + httpserver.identity.primaryPort;
 });
 
 var httpserver = new HttpServer();
 var index = 0;
 var nextTest = firstTest;
@@ -67,17 +68,24 @@ function run_test_number(num)
   channel.asyncOpen(new ChannelListener(eval("completeTest" + num),
                                         channel, flags), null);
 }
 
 function setupChannel(url)
 {
   var ios = Components.classes["@mozilla.org/network/io-service;1"].
                        getService(Ci.nsIIOService);
-  var chan = ios.newChannel(URL + url, "", null);
+  var chan = ios.newChannel2(URL + url,
+                             "",
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER);
   var httpChan = chan.QueryInterface(Components.interfaces.nsIHttpChannel);
   return httpChan;
 }
 
 function endTests()
 {
   httpserver.stop(do_test_finished);
 }
--- a/netwerk/test/unit/test_http2.js
+++ b/netwerk/test/unit/test_http2.js
@@ -186,17 +186,24 @@ Http2PostListener.prototype.onDataAvaila
   this.onDataAvailableFired = true;
   this.isHttp2Connection = checkIsHttp2(request);
   read_stream(stream, cnt);
   do_check_eq(this.expected_md5, request.getResponseHeader("X-Calculated-MD5"));
 };
 
 function makeChan(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-  var chan = ios.newChannel(url, null, null).QueryInterface(Ci.nsIHttpChannel);
+  var chan = ios.newChannel2(url,
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER).QueryInterface(Ci.nsIHttpChannel);
 
   return chan;
 }
 
 // Make sure we make a HTTP2 connection and both us and the server mark it as such
 function test_http2_basic() {
   var chan = makeChan("https://localhost:6944/");
   var listener = new Http2CheckListener();
@@ -350,16 +357,18 @@ function test_http2_post() {
 // Make sure we can do a POST that covers more than 2 frames
 function test_http2_post_big() {
   var chan = makeChan("https://localhost:6944/post");
   var listener = new Http2PostListener(md5s[1]);
   do_post(posts[1], chan, listener);
 }
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
+
 var httpserv = null;
 var ios = Components.classes["@mozilla.org/network/io-service;1"]
                     .getService(Components.interfaces.nsIIOService);
 
 var altsvcClientListener = {
   onStartRequest: function test_onStartR(request, ctx) {
     do_check_eq(request.status, Components.results.NS_OK);
   },
@@ -367,18 +376,25 @@ var altsvcClientListener = {
   onDataAvailable: function test_ODA(request, cx, stream, offset, cnt) {
    read_stream(stream, cnt);
   },
 
   onStopRequest: function test_onStopR(request, ctx, status) {
     var isHttp2Connection = checkIsHttp2(request);
     if (!isHttp2Connection) {
 	// not over tls yet - retry. It's all async and transparent to client
-	var chan = ios.newChannel("http://localhost:" + httpserv.identity.primaryPort + "/altsvc1",
-				  null, null).QueryInterface(Components.interfaces.nsIHttpChannel);
+	var chan = ios.newChannel2("http://localhost:" + httpserv.identity.primaryPort + "/altsvc1",
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER)
+                .QueryInterface(Components.interfaces.nsIHttpChannel);
 	chan.asyncOpen(altsvcClientListener, null);
     } else {
         do_check_true(isHttp2Connection);
 	httpserv.stop(do_test_finished);
 	run_next_test();
     }
   }
 };
@@ -391,18 +407,25 @@ function altsvcHttp1Server(metadata, res
   response.bodyOutputStream.write(body, body.length);
 }
 
 function test_http2_altsvc() {
   httpserv = new HttpServer();
   httpserv.registerPathHandler("/altsvc1", altsvcHttp1Server);
   httpserv.start(-1);
 
-  var chan = ios.newChannel("http://localhost:" + httpserv.identity.primaryPort + "/altsvc1",
-			    null, null).QueryInterface(Components.interfaces.nsIHttpChannel);
+  var chan = ios.newChannel2("http://localhost:" + httpserv.identity.primaryPort + "/altsvc1",
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER)
+                .QueryInterface(Components.interfaces.nsIHttpChannel);
   chan.asyncOpen(altsvcClientListener, null);
 }
 
 var Http2PushApiListener = function() {};
 
 Http2PushApiListener.prototype = {
   checksPending: 9, // 4 onDataAvailable and 5 onStop
 
--- a/netwerk/test/unit/test_httpResponseTimeout.js
+++ b/netwerk/test/unit/test_httpResponseTimeout.js
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var baseURL;
 const kResponseTimeoutPref = "network.http.response.timeout";
 const kResponseTimeout = 1;
 const kShortLivedKeepalivePref =
   "network.http.tcp_keepalive.short_lived_connections";
 const kLongLivedKeepalivePref =
   "network.http.tcp_keepalive.long_lived_connections";
@@ -52,17 +53,24 @@ function testTimeout(timeoutEnabled, exp
   if (timeoutEnabled) {
     prefService.setIntPref(kResponseTimeoutPref, kResponseTimeout);
   } else {
     prefService.setIntPref(kResponseTimeoutPref, 0);
   }
 
   var ios = Cc["@mozilla.org/network/io-service;1"]
   .getService(Ci.nsIIOService);
-  var chan = ios.newChannel(baseURL, null, null)
+  var chan = ios.newChannel2(baseURL,
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER)
   .QueryInterface(Ci.nsIHttpChannel);
   var listener = new TimeoutListener(expectResponse);
   chan.asyncOpen(listener, null);
 }
 
 function testTimeoutEnabled() {
   // Set a timeout value; expect a timeout and no response.
   testTimeout(true, false);
--- a/netwerk/test/unit/test_http_headers.js
+++ b/netwerk/test/unit/test_http_headers.js
@@ -1,22 +1,31 @@
+Cu.import("resource://gre/modules/Services.jsm");
+
 function check_request_header(chan, name, value) {
   var chanValue;
   try {
     chanValue = chan.getRequestHeader(name);
   } catch (e) {
     do_throw("Expected to find header '" + name + "' but didn't find it");
   }
   do_check_eq(chanValue, value);
 }
 
 function run_test() {
   var ios = Components.classes["@mozilla.org/network/io-service;1"]
                       .getService(Components.interfaces.nsIIOService);
-  var chan = ios.newChannel("http://www.mozilla.org/", null, null)
+  var chan = ios.newChannel2("http://www.mozilla.org/",
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER)
                 .QueryInterface(Components.interfaces.nsIHttpChannel);
 
   check_request_header(chan, "host", "www.mozilla.org");
   check_request_header(chan, "Host", "www.mozilla.org");
 
   chan.setRequestHeader("foopy", "bar", false);
   check_request_header(chan, "foopy", "bar");
 
--- a/netwerk/test/unit/test_httpcancel.js
+++ b/netwerk/test/unit/test_httpcancel.js
@@ -1,15 +1,16 @@
 // This file ensures that canceling a channel early does not
 // send the request to the server (bug 350790)
 //
 // I've also shoehorned in a test that ENSURE_CALLED_BEFORE_CONNECT works as
 // expected: see comments that start with ENSURE_CALLED_BEFORE_CONNECT:
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var ios = Components.classes["@mozilla.org/network/io-service;1"]
                     .getService(Components.interfaces.nsIIOService);
 var observer = {
   QueryInterface: function eventsink_qi(iid) {
     if (iid.equals(Components.interfaces.nsISupports) ||
         iid.equals(Components.interfaces.nsIObserver))
       return this;
@@ -67,17 +68,24 @@ var listener = {
   },
 
   onStopRequest: function test_onStopR(request, ctx, status) {
     httpserv.stop(do_test_finished);
   }
 };
 
 function makeChan(url) {
-  var chan = ios.newChannel(url, null, null)
+  var chan = ios.newChannel2(url,
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER)
                 .QueryInterface(Components.interfaces.nsIHttpChannel);
 
   // ENSURE_CALLED_BEFORE_CONNECT: set original value
   var uri = ios.newURI("http://site1.com", null, null);
   chan.referrer = uri;
 
   return chan;
 }
--- a/netwerk/test/unit/test_httpsuspend.js
+++ b/netwerk/test/unit/test_httpsuspend.js
@@ -1,12 +1,13 @@
 // This file ensures that suspending a channel directly after opening it
 // suspends future notifications correctly.
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "URL", function() {
   return "http://localhost:" + httpserv.identity.primaryPort;
 });
 
 const MIN_TIME_DIFFERENCE = 3000;
 const RESUME_DELAY = 5000;
 
@@ -50,17 +51,24 @@ var listener = {
   onStopRequest: function(request, ctx, status) {
     do_check_true(this._gotData);
     httpserv.stop(do_test_finished);
   }
 };
 
 function makeChan(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-  var chan = ios.newChannel(url, null, null).QueryInterface(Ci.nsIHttpChannel);
+  var chan = ios.newChannel2(url,
+                             null,
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER).QueryInterface(Ci.nsIHttpChannel);
   return chan;
 }
 
 var httpserv = null;
 
 function run_test() {
   httpserv = new HttpServer();
   httpserv.registerPathHandler("/woo", data);
--- a/netwerk/test/unit/test_invalidport.js
+++ b/netwerk/test/unit/test_invalidport.js
@@ -1,12 +1,14 @@
 // This is essentially a crashtest for accessing an out of range port
 // Perform the async open several times in order to induce exponential
 // scheduling behavior bugs.
 
+Cu.import("resource://gre/modules/Services.jsm");
+
 const CC = Components.Constructor;
 
 var counter = 0;
 const iterations = 10;
 
 var listener = {
   onStartRequest: function test_onStartR(request, ctx) {
   },
@@ -26,13 +28,20 @@ var listener = {
 function run_test() {
   execute_test();
   do_test_pending();
 }
 
 function execute_test() {
   var ios = Cc["@mozilla.org/network/io-service;1"].
                        getService(Ci.nsIIOService);
-  var chan = ios.newChannel("http://localhost:75000", "", null);
+  var chan = ios.newChannel2("http://localhost:75000",
+                             "",
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER);
   chan.QueryInterface(Ci.nsIHttpChannel);
   chan.asyncOpen(listener, null);
 }
 
--- a/netwerk/test/unit/test_localstreams.js
+++ b/netwerk/test/unit/test_localstreams.js
@@ -1,9 +1,10 @@
 // Tests bug 304414
+Cu.import("resource://gre/modules/Services.jsm");
 
 const PR_RDONLY = 0x1;  // see prio.h
 
 // Does some sanity checks on the stream and returns the number of bytes read
 // when the checks passed.
 function test_stream(stream) {
   // This test only handles blocking streams; that's desired for file streams
   // anyway.
@@ -63,17 +64,22 @@ function stream_for_file(file) {
   str.init(file, PR_RDONLY, 0, 0);
   return str;
 }
 
 function stream_from_channel(file) {
   var ios = Components.classes["@mozilla.org/network/io-service;1"]
                       .getService(Components.interfaces.nsIIOService);
   var uri = ios.newFileURI(file);
-  return ios.newChannelFromURI(uri).open();
+  return ios.newChannelFromURI2(uri,
+                                null,      // aLoadingNode
+                                Services.scriptSecurityManager.getSystemPrincipal(),
+                                null,      // aTriggeringPrincipal
+                                Ci.nsILoadInfo.SEC_NORMAL,
+                                Ci.nsIContentPolicy.TYPE_OTHER).open();
 }
 
 function run_test() {
   // Get a file and a directory in order to do some testing
   var file = do_get_file("../unit/data/test_readline6.txt");
   var len = file.fileSize;
   do_check_eq(test_stream(stream_for_file(file)), len);
   do_check_eq(test_stream(stream_from_channel(file)), len);
--- a/netwerk/test/unit/test_mismatch_last-modified.js
+++ b/netwerk/test/unit/test_mismatch_last-modified.js
@@ -1,9 +1,10 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 var httpserver = new HttpServer();
 
 var ios;
 
 // Test the handling of a cache revalidation with mismatching last-modified
 // headers. If we get such a revalidation the cache entry should be purged.
 // see bug 717350
 
@@ -62,22 +63,29 @@ XPCOMUtils.defineLazyGetter(this, "liste
       
 	// This is 'A' from a cache revalidation, but that reval will clean the cache
 	// because of mismatched last-modified response headers
 	
 	do_check_eq(data[0], "A".charCodeAt(0));
     },
 
     onStopRequest: function test_onStopR(request, ctx, status) {
-	var channel = request.QueryInterface(Ci.nsIHttpChannel);
+    var channel = request.QueryInterface(Ci.nsIHttpChannel);
 
-	var chan = ios.newChannel("http://localhost:" +
-				  httpserver.identity.primaryPort +
-				  "/test1", "", null);
-	chan.asyncOpen(listener_3, null);
+    var chan = ios.newChannel2("http://localhost:" +
+                               httpserver.identity.primaryPort +
+                               "/test1",
+                               "",
+                               null,
+                               null,      // aLoadingNode
+                               Services.scriptSecurityManager.getSystemPrincipal(),
+                               null,      // aTriggeringPrincipal
+                               Ci.nsILoadInfo.SEC_NORMAL,
+                               Ci.nsIContentPolicy.TYPE_OTHER);
+    chan.asyncOpen(listener_3, null);
     }
 };
 });
 
 XPCOMUtils.defineLazyGetter(this, "listener_1", function() {
     return {
     // this listener processes the initial request from a empty cache.
     // the server responds with the wrong data ('A')
@@ -96,19 +104,26 @@ XPCOMUtils.defineLazyGetter(this, "liste
                                        offset, count) {
 	var data = new BinaryInputStream(inputStream).readByteArray(count);
 	do_check_eq(data[0], "A".charCodeAt(0));
     },
 
     onStopRequest: function test_onStopR(request, ctx, status) {
 	var channel = request.QueryInterface(Ci.nsIHttpChannel);
 
-	var chan = ios.newChannel("http://localhost:" +
-				  httpserver.identity.primaryPort +
-				  "/test1", "", null);
+	var chan = ios.newChannel2("http://localhost:" +
+				                     httpserver.identity.primaryPort +
+				                     "/test1",
+                             "",
+                             null,
+                             null,      // aLoadingNode
+                             Services.scriptSecurityManager.getSystemPrincipal(),
+                             null,      // aTriggeringPrincipal
+                             Ci.nsILoadInfo.SEC_NORMAL,
+                             Ci.nsIContentPolicy.TYPE_OTHER);
 	chan.asyncOpen(listener_2, null);
     }
 };
 });
 
 function run_test() {
     do_get_profile();
     ios = Cc["@mozilla.org/network/io-service;1"]
@@ -116,17 +131,24 @@ function run_test() {
 
     evict_cache_entries();
 
     httpserver.registerPathHandler("/test1", handler);
     httpserver.start(-1);
 
     var port = httpserver.identity.primaryPort;
 
-    var chan = ios.newChannel("http://localhost:" + port + "/test1", "", null);
+    var chan = ios.newChannel2("http://localhost:" + port + "/test1",
+                               "",
+                               null,
+                               null,      // aLoadingNode
+                               Services.scriptSecurityManager.getSystemPrincipal(),
+                               null,      // aTriggeringPrincipal
+                               Ci.nsILoadInfo.SEC_NORMAL,
+                               Ci.nsIContentPolicy.TYPE_OTHER);
     chan.asyncOpen(listener_1, null);
 
     do_test_pending();
 }
 
 var iter=0;
 function handler(metadata, response) {
     iter++;
--- a/netwerk/test/unit/test_multipart_byteranges.js
+++ b/netwerk/test/unit/test_multipart_byteranges.js
@@ -1,20 +1,28 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpserver = null;
 
 XPCOMUtils.defineLazyGetter(this, "uri", function() {
   return "http://localhost:" + httpserver.identity.primaryPort + "/multipart";
 });
 
 function make_channel(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 var multipartBody = "--boundary\r\n"+
 "Content-type: text/plain\r\n"+
 "Content-range: bytes 0-2/10\r\n"+
 "\r\n"+
 "aaa\r\n"+
 "--boundary\r\n"+
@@ -29,17 +37,24 @@ var multipartBody = "--boundary\r\n"+
 "\r\n"+
 "cc"+
 "\r\n"+
 "--boundary--";
 
 function make_channel(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 function contentHandler(metadata, response)
 {
   response.setHeader("Content-Type", 'multipart/byteranges; boundary="boundary"');
   response.bodyOutputStream.write(multipartBody, multipartBody.length);
 }
 
--- a/netwerk/test/unit/test_multipart_streamconv.js
+++ b/netwerk/test/unit/test_multipart_streamconv.js
@@ -1,28 +1,43 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpserver = null;
 
 XPCOMUtils.defineLazyGetter(this, "uri", function() {
   return "http://localhost:" + httpserver.identity.primaryPort + "/multipart";
 });
 
 function make_channel(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 var multipartBody = "--boundary\r\n\r\nSome text\r\n--boundary\r\n\r\n<?xml version='1.0'?><root/>\r\n--boundary--";
 
 function make_channel(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 function contentHandler(metadata, response)
 {
   response.setHeader("Content-Type", 'multipart/mixed; boundary="boundary"');
   response.bodyOutputStream.write(multipartBody, multipartBody.length);
 }
 
--- a/netwerk/test/unit/test_multipart_streamconv_missing_lead_boundary.js
+++ b/netwerk/test/unit/test_multipart_streamconv_missing_lead_boundary.js
@@ -1,28 +1,43 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpserver = null;
 
 XPCOMUtils.defineLazyGetter(this, "uri", function() {
   return "http://localhost:" + httpserver.identity.primaryPort + "/multipart";
 });
 
 function make_channel(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 var multipartBody = "\r\nSome text\r\n--boundary\r\n\r\n<?xml version='1.0'?><root/>\r\n--boundary--";
 
 function make_channel(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 function contentHandler(metadata, response)
 {
   response.setHeader("Content-Type", 'multipart/mixed; boundary="boundary"');
   response.bodyOutputStream.write(multipartBody, multipartBody.length);
 }
 
--- a/netwerk/test/unit/test_nojsredir.js
+++ b/netwerk/test/unit/test_nojsredir.js
@@ -1,9 +1,10 @@
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 var httpserver = new HttpServer();
 var index = 0;
 var tests = [
     {url : "/test/test",
      datalen : 16},
 
     // Test that the http channel fails and the response body is suppressed
@@ -12,18 +13,25 @@ var tests = [
      responseheader: [ "Location: javascript:alert()"],
      flags : CL_EXPECT_FAILURE,
      datalen : 0},
 ];
 
 function setupChannel(url) {
     var ios = Components.classes["@mozilla.org/network/io-service;1"].
                          getService(Ci.nsIIOService);
-    var chan = ios.newChannel("http://localhost:" +
-			      httpserver.identity.primaryPort + url, "", null);
+    var chan = ios.newChannel2("http://localhost:" +
+                               httpserver.identity.primaryPort + url,
+                               "",
+                               null,
+                               null,      // aLoadingNode
+                               Services.scriptSecurityManager.getSystemPrincipal(),
+                               null,      // aTriggeringPrincipal
+                               Ci.nsILoadInfo.SEC_NORMAL,
+                               Ci.nsIContentPolicy.TYPE_OTHER);
     return chan;
 }
 
 function startIter() {
     var channel = setupChannel(tests[index].url);
     channel.asyncOpen(new ChannelListener(completeIter, channel, tests[index].flags), null);
 }
 
--- a/netwerk/test/unit/test_offlinecache_custom-directory.js
+++ b/netwerk/test/unit/test_offlinecache_custom-directory.js
@@ -12,17 +12,24 @@
 Cu.import("resource://testing-common/httpd.js");
 
 var httpServer = null;
 var cacheUpdateObserver = null;
 
 function make_channel(url, callback, ctx) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                         "",
+                         null,
+                         null,      // aLoadingNode
+                         Services.scriptSecurityManager.getSystemPrincipal(),
+                         null,      // aTriggeringPrincipal
+                         Ci.nsILoadInfo.SEC_NORMAL,
+                         Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 function make_uri(url) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
   return ios.newURI(url, null, null);
 }
 
--- a/netwerk/test/unit/test_partial_response_entry_size_smart_shrink.js
+++ b/netwerk/test/unit/test_partial_response_entry_size_smart_shrink.js
@@ -14,17 +14,24 @@ XPCOMUtils.defineLazyGetter(this, "URL",
   return "http://localhost:" + httpServer.identity.primaryPort;
 });
 
 var httpServer = null;
 
 function make_channel(url, callback, ctx) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
             getService(Ci.nsIIOService);
-  return ios.newChannel(url, "", null);
+  return ios.newChannel2(url,
+                        "",
+                        null,
+                        null,      // aLoadingNode
+                        Services.scriptSecurityManager.getSystemPrincipal(),
+                        null,      // aTriggeringPrincipal
+                        Ci.nsILoadInfo.SEC_NORMAL,
+                        Ci.nsIContentPolicy.TYPE_OTHER);
 }
 
 // Have 2kb response (8 * 2 ^ 8)
 var responseBody = "response";
 for (var i = 0; i < 8; ++i) responseBody += responseBody;
 
 function contentHandler(metadata, response)
 {
--- a/netwerk/test/unit/test_plaintext_sniff.js
+++ b/netwerk/test/unit/test_plaintext_sniff.js
@@ -71,18 +71,25 @@ for (i = 0; i <= 127; ++i) {
                     BOMList[j].length == 2 && isBinaryChar(i) ]);
   }
 }
 
 function makeChan(headerIdx, bodyIdx) {
   var ios = Components.classes["@mozilla.org/network/io-service;1"]
                       .getService(Components.interfaces.nsIIOService);
   var chan =
-    ios.newChannel("http://localhost:" + httpserv.identity.primaryPort +
-                   "/" + headerIdx + "/" + bodyIdx, null, null)
+    ios.newChannel2("http://localhost:" + httpserv.identity.primaryPort +
+                    "/" + headerIdx + "/" + bodyIdx,
+                    null,
+                    null,
+                    null,      // aLoadingNode
+                    Services.scriptSecurityManager.getSystemPrincipal(),
+                    null,      // aTriggeringPrincipal
+                    Ci.nsILoadInfo.SEC_NORMAL,
+                    Ci.nsIContentPolicy.TYPE_OTHER)
        .QueryInterface(Components.interfaces.nsIHttpChannel);
 
   chan.loadFlags |=
     Components.interfaces.nsIChannel.LOAD_CALL_CONTENT_SNIFFERS;
 
   return chan;
 }
 
--- a/netwerk/test/unit/test_post.js
+++ b/netwerk/test/unit/test_post.js
@@ -1,13 +1,14 @@
 //
 // POST test
 //
 
 Cu.import("resource://testing-common/httpd.js");
+Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "URL", function() {
   return "http://localhost:" + httpserver.identity.primaryPort;
 });
 
 var httpserver = new HttpServer();
 var testpath = "/simple";
 
@@ -65,17 +66,24 @@ function run_test() {
 
   channel.asyncOpen(new ChannelListener(checkRequest, channel), null);
 
   do_test_pending();
 }
 
 function setupChannel(path) {
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-  return chan = ios.newChannel(URL + path, "", null)
+  return chan = ios.newChannel2(URL + path,
+                               "",
+                               null,
+                               null,      // aLoadingNode
+                               Services.scriptSecurityManager.getSystemPrincipal(),
+                               null,      // aTriggeringPrincipal
+                               Ci.nsILoadInfo.SEC_NORMAL,
+                               Ci.nsIContentPolicy.TYPE_OTHER)
                    .QueryInterface(Ci.nsIHttpChannel);
 }
 
 function serverHandler(metadata, response) {
   do_check_eq(metadata.method, "POST");
 
   var data = read_stream(metadata.bodyInputStream,
 			 metadata.bodyInputStream.available());
--- a/netwerk/test/unit/test_private_cookie_changed.js
+++ b/netwerk/test/unit/test_private_cookie_changed.js
@@ -1,17 +1,24 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/NetUtil.jsm");
 
 function makeChan(uri, isPrivate) {
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-  var chan = ios.newChannel(uri.spec, null, null)
+  var chan = ios.newChannel2(uri.spec,
+                             null,
+                             null,
+                             null,      // aLoadingNode