Merge backout; a=leak-fix
authorEhsan Akhgari <ehsan@mozilla.com>
Tue, 30 Nov 2010 14:51:15 -0500
changeset 58394 0a4135190b4846e33bc2cff86d19f8b2bf365fd0
parent 58393 76592bdf05c3a56c3a51f7d9579e09b21cca9c74 (current diff)
parent 58392 5d4678e9fc37ea1400b6e40413ed194ff5f3af1b (diff)
child 58395 78df45be19d18b39bc8ce68d3eb23ff46d7cfa7a
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersleak-fix
milestone2.0b8pre
Merge backout; a=leak-fix
netwerk/test/unit/test_offline_status.js
netwerk/test/unit/test_sockettransportsvc_available.js
--- a/content/base/public/nsIXMLHttpRequest.idl
+++ b/content/base/public/nsIXMLHttpRequest.idl
@@ -237,18 +237,18 @@ interface nsIXMLHttpRequest : nsISupport
    *              be thrown.
    * @param user (optional) A username for authentication if necessary.
    *             The default value is the empty string
    * @param password (optional) A password for authentication if necessary.
    *                 The default value is the empty string
    */
   [optional_argc] void open(in AUTF8String method, in AUTF8String url,
                             [optional] in boolean async,
-                            [optional] in DOMString user,
-                            [optional] in DOMString password);
+                            [optional,Undefined(Empty)] in DOMString user,
+                            [optional,Undefined(Empty)] in DOMString password);
 
   /**
    * Sends the request. If the request is asynchronous, returns
    * immediately after sending the request. If it is synchronous
    * returns only after the response has been received.
    *
    * All event listeners must be set before calling send().
    *
--- a/content/base/src/nsAttrValue.cpp
+++ b/content/base/src/nsAttrValue.cpp
@@ -440,19 +440,18 @@ nsAttrValue::ToString(nsAString& aResult
     case eSVGValue:
     {
       GetMiscContainer()->mSVGValue->GetValueString(aResult);
       break;
     }
 #endif
     case eFloatValue:
     {
-      nsAutoString str;
-      str.AppendFloat(GetFloatValue());
-      aResult = str;
+      aResult.Truncate();
+      aResult.AppendFloat(GetFloatValue());
       break;
     }
     default:
     {
       aResult.Truncate();
       break;
     }
   }
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -4346,31 +4346,38 @@ nsDocument::CreateElement(const nsAStrin
 }
 
 NS_IMETHODIMP
 nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
                             const nsAString& aQualifiedName,
                             nsIDOMElement** aReturn)
 {
   *aReturn = nsnull;
-
+  nsCOMPtr<nsIContent> content;
+  nsresult rv = CreateElementNS(aNamespaceURI, aQualifiedName,
+                                getter_AddRefs(content));
+  NS_ENSURE_SUCCESS(rv, rv);
+  return CallQueryInterface(content, aReturn);
+}
+
+nsresult
+nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
+                            const nsAString& aQualifiedName,
+                            nsIContent** aReturn)
+{
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nsresult rv = nsContentUtils::GetNodeInfoFromQName(aNamespaceURI,
                                                      aQualifiedName,
                                                      mNodeInfoManager,
                                                      getter_AddRefs(nodeInfo));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIContent> content;
   PRInt32 ns = nodeInfo->NamespaceID();
-  rv = NS_NewElement(getter_AddRefs(content), ns, nodeInfo.forget(),
-                     NOT_FROM_PARSER);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return CallQueryInterface(content, aReturn);
+  return NS_NewElement(aReturn, ns,
+                       nodeInfo.forget(), NOT_FROM_PARSER);
 }
 
 NS_IMETHODIMP
 nsDocument::CreateTextNode(const nsAString& aData, nsIDOMText** aReturn)
 {
   *aReturn = nsnull;
   nsCOMPtr<nsIContent> content;
   nsresult rv = CreateTextNode(aData, getter_AddRefs(content));
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -854,16 +854,19 @@ public:
 
   virtual nsresult CreateElem(const nsAString& aName, nsIAtom *aPrefix,
                               PRInt32 aNamespaceID,
                               PRBool aDocumentDefaultType,
                               nsIContent **aResult);
 
   nsresult CreateElement(const nsAString& aTagName,
                          nsIContent** aReturn);
+  nsresult CreateElementNS(const nsAString& aNamespaceURI,
+                           const nsAString& aQualifiedName,
+                           nsIContent** aReturn);
 
   nsresult CreateTextNode(const nsAString& aData, nsIContent** aReturn);
 
   virtual NS_HIDDEN_(nsresult) Sanitize();
 
   virtual NS_HIDDEN_(void) EnumerateSubDocuments(nsSubDocEnumFunc aCallback,
                                                  void *aData);
 
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -1090,41 +1090,40 @@ nsIContent::IsEqual(nsIContent* aOther)
 
       if (!element2->AttrValueIs(attrName1->NamespaceID(),
                                  attrName1->LocalName(),
                                  string1,
                                  eCaseMatters)) {
         return PR_FALSE;
       }
     }
-
-    // Child nodes count.
-    PRUint32 childCount = GetChildCount();
-    if (childCount != element2->GetChildCount()) {
-      return PR_FALSE;
-    }
-
-    // Iterate over child nodes.
-    for (PRUint32 i = 0; i < childCount; ++i) {
-      if (!GetChildAt(i)->IsEqual(element2->GetChildAt(i))) {
-        return PR_FALSE;
-      }
-    }
   } else {
     // Node value check.
     nsCOMPtr<nsIDOMNode> domNode1 = do_QueryInterface(this);
     nsCOMPtr<nsIDOMNode> domNode2 = do_QueryInterface(aOther);
     NS_ASSERTION(domNode1 && domNode2, "How'd we get nsIContent without nsIDOMNode?");
     domNode1->GetNodeValue(string1);
     domNode2->GetNodeValue(string2);
     if (!string1.Equals(string2)) {
       return PR_FALSE;
     }
   }
 
+  // Child nodes count.
+  PRUint32 childCount = GetChildCount();
+  if (childCount != aOther->GetChildCount()) {
+    return PR_FALSE;
+  }
+
+  // Iterate over child nodes.
+  for (PRUint32 i = 0; i < childCount; ++i) {
+    if (!GetChildAt(i)->IsEqual(aOther->GetChildAt(i))) {
+      return PR_FALSE;
+    }
+  }
   return PR_TRUE;
 }
 
 PRBool
 nsIContent::IsEqualNode(nsINode* aOther)
 {
   if (!aOther || !aOther->IsNodeOfType(eCONTENT))
     return PR_FALSE;
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -365,27 +365,27 @@ include $(topsrcdir)/config/rules.mk
 		test_bug503481b.html \
 		file_bug503481b_inner.html \
 		test_viewport_scroll.html \
 		test_CSP.html \
 		file_CSP.sjs \
 		file_CSP_main.html \
 		file_CSP_main.html^headers^ \
 		file_CSP_main.js \
- 		test_CSP_frameancestors.html \
- 		file_CSP_frameancestors.sjs \
- 		file_CSP_frameancestors_main.html \
- 		file_CSP_frameancestors_main.js \
- 		test_CSP_inlinescript.html \
- 		file_CSP_inlinescript_main.html \
- 		file_CSP_inlinescript_main.html^headers^ \
- 		test_CSP_evalscript.html \
- 		file_CSP_evalscript_main.html \
- 		file_CSP_evalscript_main.html^headers^ \
- 		file_CSP_evalscript_main.js \
+		test_CSP_frameancestors.html \
+		file_CSP_frameancestors.sjs \
+		file_CSP_frameancestors_main.html \
+		file_CSP_frameancestors_main.js \
+		test_CSP_inlinescript.html \
+		file_CSP_inlinescript_main.html \
+		file_CSP_inlinescript_main.html^headers^ \
+		test_CSP_evalscript.html \
+		file_CSP_evalscript_main.html \
+		file_CSP_evalscript_main.html^headers^ \
+		file_CSP_evalscript_main.js \
 		test_bug540854.html \
 		bug540854.sjs \
 		test_bug548463.html \
 		test_bug545644.html \
 		test_bug545644.xhtml \
 		test_bug553896.xhtml \
 		test_bug515401.html \
 		test_bug541937.html \
@@ -439,16 +439,17 @@ include $(topsrcdir)/config/rules.mk
 		file_bug604660-2.xsl \
 		file_bug604660-3.js \
 		file_bug604660-4.js \
 		file_bug604660-5.xml \
 		file_bug604660-6.xsl \
 		test_bug605982.html \
 		test_bug606729.html \
 		test_treewalker_nextsibling.xml \
+		test_bug614058.html \
 		$(NULL)
 
 # This test fails on the Mac for some reason
 ifneq (,$(filter gtk2 windows,$(MOZ_WIDGET_TOOLKIT)))
 _TEST_FILES2 += 	test_copyimage.html \
 		$(NULL)
 endif
 
--- a/content/base/test/file_CrossSiteXHR_inner.html
+++ b/content/base/test/file_CrossSiteXHR_inner.html
@@ -11,17 +11,21 @@
 window.addEventListener("message", function(e) {
 
   sendData = null;
 
   req = eval(e.data);
   var res = {
     didFail: false,
     events: [],
-    progressEvents: 0
+    progressEvents: 0,
+    status: 0,
+    responseText: "",
+    responseXML: null,
+    sendThrew: false
   };
   
   var xhr = new XMLHttpRequest();
   for each(type in ["load", "abort", "error", "loadstart"]) {
     xhr.addEventListener(type, function(e) {
       res.events.push(e.type);
     }, false);
   }
@@ -67,24 +71,38 @@ window.addEventListener("message", funct
   }
 
   if (req.withCred)
     xhr.withCredentials = true;
   if (req.body)
     sendData = req.body;
 
   res.events.push("opening");
-  xhr.open(req.method, req.url, true);
+  // Allow passign in falsy usernames/passwords so we can test them
+  try {
+    xhr.open(req.method, req.url, true,
+             ("username" in req) ? req.username : "",
+             ("password" in req) ? req.password : "aa");
+  } catch (ex) {
+    res.didFail = true;
+    post(e, res);
+  }
 
   for (header in req.headers) {
     xhr.setRequestHeader(header, req.headers[header]);
   }
 
   res.events.push("sending");
-  xhr.send(sendData);
+  try {
+    xhr.send(sendData);
+  } catch (ex) {
+    res.didFail = true;
+    res.sendThrew = true;
+    post(e, res);
+  }
 
 }, false);
 
 function post(e, res) {
   e.source.postMessage(res.toSource(), "http://mochi.test:8888");
 }
 
 </script>
--- a/content/base/test/test_CrossSiteXHR.html
+++ b/content/base/test/test_CrossSiteXHR.html
@@ -44,16 +44,47 @@ function runTest() {
   yield;
 
   tests =     [// Plain request
                { pass: 1,
                  method: "GET",
                  noAllowPreflight: 1,
                },
 
+               // undefined username
+               { pass: 1,
+                 method: "GET",
+                 noAllowPreflight: 1,
+                 username: undefined
+               },
+
+               // undefined username and password
+               { pass: 1,
+                 method: "GET",
+                 noAllowPreflight: 1,
+                 username: undefined,
+                 password: undefined
+               },
+
+               // nonempty username
+               { pass: 0,
+                 method: "GET",
+                 noAllowPreflight: 1,
+                 username: "user",
+               },
+
+               // nonempty password
+               // XXXbz this passes for now, because we ignore passwords
+               // without usernames in most cases.
+               { pass: 1,
+                 method: "GET",
+                 noAllowPreflight: 1,
+                 password: "password",
+               },
+
                // Default allowed headers
                { pass: 1,
                  method: "GET",
                  headers: { "Content-Type": "text/plain",
                             "Accept": "foo/bar",
                             "Accept-Language": "sv-SE" },
                  noAllowPreflight: 1,
                },
@@ -552,16 +583,24 @@ function runTest() {
       responseHeaders: test.responseHeaders,
     };
 
     if (test.pass) {
        req.url += "&origin=" + escape(origin) +
                   "&requestMethod=" + test.method;
     }
 
+    if ("username" in test) {
+      req.username = test.username;
+    }
+
+    if ("password" in test) {
+      req.password = test.password;
+    }
+
     if (test.noAllowPreflight)
       req.url += "&noAllowPreflight";
 
     if (test.pass && "headers" in test) {
       function isUnsafeHeader(name) {
         lName = name.toLowerCase();
         return lName != "accept" &&
                lName != "accept-language" &&
@@ -648,19 +687,21 @@ function runTest() {
       is(res.didFail, true,
         "should have failed in test for " + test.toSource());
       is(res.status, 0, "wrong status in test for " + test.toSource());
       is(res.statusText, "", "wrong status in test for " + test.toSource());
       is(res.responseXML, null,
          "wrong responseXML in test for " + test.toSource());
       is(res.responseText, "",
          "wrong responseText in test for " + test.toSource());
-      is(res.events.join(","),
-         "opening,rs1,sending,rs1,loadstart,rs2,rs4,error",
-         "wrong events in test for " + test.toSource());
+      if (!res.sendThrew) {
+        is(res.events.join(","),
+           "opening,rs1,sending,rs1,loadstart,rs2,rs4,error",
+           "wrong events in test for " + test.toSource());
+      }
       is(res.progressEvents, 0,
          "wrong events in test for " + test.toSource());
       if (test.responseHeaders) {
         for (header in test.responseHeaders) {
           is(res.responseHeaders[header], null,
              "wrong response header (" + header + ") in test for " +
              test.toSource());
         }
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug614058.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=614058
+-->
+<head>
+  <title>Test for Bug 614058</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=614058">Mozilla Bug 614058</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 614058 **/
+var f1 = document.createDocumentFragment(); 
+f2 = f1.cloneNode(true); 
+f1.appendChild(document.createElement("foo"));
+is(f1.isEqualNode(f2), false, "Fragments have different kids!");
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -943,19 +943,17 @@ nsCanvasRenderingContext2D::StyleColorTo
                                         NS_GET_B(aColor)),
                         aStr);
     } else {
         CopyUTF8toUTF16(nsPrintfCString(100, "rgba(%d, %d, %d, ",
                                         NS_GET_R(aColor),
                                         NS_GET_G(aColor),
                                         NS_GET_B(aColor)),
                         aStr);
-        nsString tmp;
-        tmp.AppendFloat(nsStyleUtil::ColorComponentToFloat(NS_GET_A(aColor)));
-        aStr.Append(tmp);
+        aStr.AppendFloat(nsStyleUtil::ColorComponentToFloat(NS_GET_A(aColor)));
         aStr.Append(')');
     }
 }
 
 void
 nsCanvasRenderingContext2D::DirtyAllStyles()
 {
     for (int i = 0; i < STYLE_MAX; i++) {
@@ -2796,19 +2794,21 @@ nsCanvasRenderingContext2D::DrawOrMeasur
             ShadowFinalize(blur);
         }
 
         processor.mThebes = mThebes;
     }
 
     gfxContextPathAutoSaveRestore pathSR(mThebes, PR_FALSE);
 
-    // back up path if stroking
-    if (aOp == nsCanvasRenderingContext2D::TEXT_DRAW_OPERATION_STROKE)
+    // back up and clear path if stroking
+    if (aOp == nsCanvasRenderingContext2D::TEXT_DRAW_OPERATION_STROKE) {
         pathSR.Save();
+        mThebes->NewPath();
+    }
     // doUseIntermediateSurface is mutually exclusive to op == STROKE
     else {
         if (doUseIntermediateSurface) {
             mThebes->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
 
             // don't want operators to be applied twice
             mThebes->SetOperator(gfxContext::OPERATOR_SOURCE);
         }
--- a/content/svg/content/src/nsSVGNumber2.cpp
+++ b/content/svg/content/src/nsSVGNumber2.cpp
@@ -117,19 +117,18 @@ nsSVGNumber2::SetBaseValueString(const n
   // nsSVGElement::ParseAttribute under nsGenericElement::SetAttr,
   // which takes care of notifying.
   return NS_OK;
 }
 
 void
 nsSVGNumber2::GetBaseValueString(nsAString & aValueAsString)
 {
-  nsAutoString s;
-  s.AppendFloat(mBaseVal);
-  aValueAsString.Assign(s);
+  aValueAsString.Truncate();
+  aValueAsString.AppendFloat(mBaseVal);
 }
 
 void
 nsSVGNumber2::SetBaseValue(float aValue,
                            nsSVGElement *aSVGElement,
                            PRBool aDoSetAttr)
 {
   mBaseVal = aValue;
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -3999,17 +3999,17 @@ SetMemoryHighWaterMarkPrefChangedCallbac
     /*
      * There are two ways to allocate memory in SpiderMonkey. One is
      * to use jsmalloc() and the other is to use GC-owned memory
      * (e.g. js_NewGCThing()).
      *
      * In the browser, we don't cap the amount of GC-owned memory.
      */
     JS_SetGCParameter(nsJSRuntime::sRuntime, JSGC_MAX_MALLOC_BYTES,
-                      128L * 1024L * 1024L);
+                      80L * 1024L * 1024L);
     JS_SetGCParameter(nsJSRuntime::sRuntime, JSGC_MAX_BYTES,
                       0xffffffff);
   } else {
     JS_SetGCParameter(nsJSRuntime::sRuntime, JSGC_MAX_MALLOC_BYTES,
                       highwatermark * 1024L * 1024L);
     JS_SetGCParameter(nsJSRuntime::sRuntime, JSGC_MAX_BYTES,
                       highwatermark * 1024L * 1024L);
   }
--- a/js/src/xpconnect/src/dom_quickstubs.qsconf
+++ b/js/src/xpconnect/src/dom_quickstubs.qsconf
@@ -98,16 +98,17 @@ members = [
     'nsIDOMDocument.documentElement',
     'nsIDOMDocument.implementation',
     'nsIDOMDocument.getElementsByTagName',
     'nsIDOMDocument.doctype',
     'nsIDOMDocument.getElementsByTagNameNS',
     'nsIDOMDocument.getElementById',
     'nsIDOMDocument.createDocumentFragment',
     'nsIDOMDocument.createElement',
+    'nsIDOMDocument.createElementNS',
     'nsIDOMDocument.importNode',
     'nsIDOMDocument.createTextNode',
     'nsIDOMElement.removeAttributeNS',
     'nsIDOMElement.removeAttribute',
     'nsIDOMElement.getAttribute',
     'nsIDOMElement.getElementsByTagName',
     'nsIDOMElement.setAttribute',
     'nsIDOMElement.getElementsByTagNameNS',
@@ -422,18 +423,16 @@ members = [
     'nsIBoxObject.width',
     'nsIBoxObject.height',
 
     # XHR
     'nsIXMLHttpRequest.*',
     # nsIXMLHttpRequest.channel is not used on the web, and more
     # importantly relies on the CAPS check that quickstubs don't make.
     '-nsIXMLHttpRequest.channel',
-    # nsIXMLHttpRequest.open uses the JS stack
-    '-nsIXMLHttpRequest.open',
     # various XHR things use ACString and AUTF8String and [cstring]
     # which quickstubs don't handle as return values (or at all in the
     # case of AUTF8String) yet.
     '-nsIXMLHttpRequest.statusText',
     '-nsIXMLHttpRequest.getAllResponseHeaders',
     '-nsIXMLHttpRequest.getResponseHeader',
     '-nsIXMLHttpRequest.setRequestHeader',
     '-nsIXMLHttpRequest.overrideMimeType',
@@ -904,16 +903,21 @@ customMethodCalls = {
     'nsIDOMElement_': {
         'thisType': 'nsGenericElement'
         },
     'nsIDOMDocument_CreateElement': {
         'thisType': 'nsDocument',
         'code': '    nsCOMPtr<nsIContent> result;\n'
                 '    rv = self->CreateElement(arg0, getter_AddRefs(result));'
     },
+    'nsIDOMDocument_CreateElementNS': {
+        'thisType': 'nsDocument',
+        'code': '    nsCOMPtr<nsIContent> result;\n'
+                '    rv = self->CreateElementNS(arg0, arg1, getter_AddRefs(result));'
+    },
     'nsIDOMDocument_CreateTextNode': {
         'thisType': 'nsDocument',
         'code': '    nsCOMPtr<nsIContent> result;\n'
                 '    rv = self->CreateTextNode(arg0, getter_AddRefs(result));'
     },
     # WebGL
     'nsIDOMWebGLRenderingContext_BufferData': CUSTOM_QS,
     'nsIDOMWebGLRenderingContext_BufferSubData': CUSTOM_QS,
--- a/js/src/xpconnect/src/qsgen.py
+++ b/js/src/xpconnect/src/qsgen.py
@@ -491,16 +491,21 @@ argumentUnboxingTemplates = {
         "    if (!xpc_qsJsvalToWcharStr(cx, ${argVal}, ${argPtr}, &${name}))\n"
         "        return JS_FALSE;\n",
 
     '[cstring]':
         "    xpc_qsACString ${name}(cx, ${argVal}, ${argPtr});\n"
         "    if (!${name}.IsValid())\n"
         "        return JS_FALSE;\n",
 
+    '[utf8string]':
+        "    xpc_qsAUTF8String ${name}(cx, ${argVal}, ${argPtr});\n"
+        "    if (!${name}.IsValid())\n"
+        "        return JS_FALSE;\n",
+
     '[jsval]':
         "    jsval ${name} = ${argVal};\n"
     }
 
 # From JSData2Native.
 #
 # Omitted optional arguments are treated as though the caller had passed JS
 # `null`; this behavior is from XPCWrappedNative::CallMethod.
@@ -575,17 +580,17 @@ def writeArgumentUnboxing(f, i, name, ty
             elif haveCcx:
                 f.write("        xpc_qsThrowBadArgWithCcx(ccx, rv, %d);\n" % i)
             else:
                 f.write("        xpc_qsThrowBadArg(cx, rv, vp, %d);\n" % i)
             f.write("        return JS_FALSE;\n"
                     "    }\n")
             return True
 
-    warn("Unable to unbox argument of type %s" % type.name)
+    warn("Unable to unbox argument of type %s (native type %s)" % (type.name, typeName))
     if i is None:
         src = '*vp'
     else:
         src = 'argv[%d]' % i
     f.write("    !; // TODO - Unbox argument %s = %s\n" % (name, src))
     return rvdeclared
 
 def writeResultDecl(f, type, varname):
@@ -1126,17 +1131,17 @@ traceableArgumentConversionTemplates = {
     'float':
           "    float ${name} = (float) ${argVal};\n",
     'double':
           "    jsdouble ${name} = ${argVal};\n",
     '[astring]':
           "    XPCReadableJSStringWrapper ${name}(${argVal});\n",
     '[domstring]':
           "    XPCReadableJSStringWrapper ${name}(${argVal});\n",
-    '[cstring]':
+    '[utf8string]':
           "    NS_ConvertUTF16toUTF8 ${name}("
           "(const PRUnichar *)JS_GetStringChars(${argVal}), "
           "JS_GetStringLength(${argVal}));\n",
     'string':
           "    NS_ConvertUTF16toUTF8 ${name}_utf8("
           "(const PRUnichar *)JS_GetStringChars(${argVal}), "
           "JS_GetStringLength(${argVal}));\n"
           "    const char *${name} = ${name}_utf8.get();\n",
--- a/js/src/xpconnect/src/xpcquickstubs.cpp
+++ b/js/src/xpconnect/src/xpcquickstubs.cpp
@@ -689,105 +689,66 @@ xpc_qsGetterOnlyPropertyStub(JSContext *
                                         js_GetErrorMessage, NULL,
                                         JSMSG_GETTER_ONLY);
 }
 
 xpc_qsDOMString::xpc_qsDOMString(JSContext *cx, jsval v, jsval *pval,
                                  StringificationBehavior nullBehavior,
                                  StringificationBehavior undefinedBehavior)
 {
+    typedef implementation_type::char_traits traits;
     // From the T_DOMSTRING case in XPCConvert::JSData2Native.
-    typedef implementation_type::char_traits traits;
-    JSString *s;
-    const PRUnichar *chars;
-    size_t len;
-
-    if(JSVAL_IS_STRING(v))
-    {
-        s = JSVAL_TO_STRING(v);
-    }
-    else
-    {
-        StringificationBehavior behavior = eStringify;
-        if(JSVAL_IS_NULL(v))
-        {
-            behavior = nullBehavior;
-        }
-        else if(JSVAL_IS_VOID(v))
-        {
-            behavior = undefinedBehavior;
-        }
+    JSString *s = InitOrStringify<traits>(cx, v, pval, nullBehavior,
+                                          undefinedBehavior);
+    if (!s)
+        return;
 
-        // If pval is null, that means the argument was optional and
-        // not passed; turn those into void strings if they're
-        // supposed to be stringified.
-        if (behavior != eStringify || !pval)
-        {
-            // Here behavior == eStringify implies !pval, so both eNull and
-            // eStringify should end up with void strings.
-            (new(mBuf) implementation_type(
-                traits::sEmptyBuffer, PRUint32(0)))->SetIsVoid(behavior != eEmpty);
-            mValid = JS_TRUE;
-            return;
-        }
-
-        s = JS_ValueToString(cx, v);
-        if(!s)
-        {
-            mValid = JS_FALSE;
-            return;
-        }
-        *pval = STRING_TO_JSVAL(s);  // Root the new string.
-    }
-
-    len = s->length();
-    chars = (len == 0 ? traits::sEmptyBuffer :
-                        reinterpret_cast<const PRUnichar*>(JS_GetStringChars(s)));
+    size_t len = s->length();
+    const PRUnichar* chars =
+        (len == 0 ? traits::sEmptyBuffer :
+                    reinterpret_cast<const PRUnichar*>(JS_GetStringChars(s)));
     new(mBuf) implementation_type(chars, len);
     mValid = JS_TRUE;
 }
 
 xpc_qsACString::xpc_qsACString(JSContext *cx, jsval v, jsval *pval)
 {
+    typedef implementation_type::char_traits traits;
     // From the T_CSTRING case in XPCConvert::JSData2Native.
-    JSString *s;
-
-    if(JSVAL_IS_STRING(v))
-    {
-        s = JSVAL_TO_STRING(v);
-    }
-    else
-    {
-        if(JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v))
-        {
-            (new(mBuf) implementation_type())->SetIsVoid(PR_TRUE);
-            mValid = JS_TRUE;
-            return;
-        }
-
-        s = JS_ValueToString(cx, v);
-        if(!s)
-        {
-            mValid = JS_FALSE;
-            return;
-        }
-        *pval = STRING_TO_JSVAL(s);  // Root the new string.
-    }
+    JSString *s = InitOrStringify<traits>(cx, v, pval, eNull, eNull);
+    if (!s)
+        return;
 
     JSAutoByteString bytes(cx, s);
     if(!bytes)
     {
         mValid = JS_FALSE;
         return;
     }
 
     new(mBuf) implementation_type(bytes.ptr(), strlen(bytes.ptr()));
     mValid = JS_TRUE;
 }
 
+xpc_qsAUTF8String::xpc_qsAUTF8String(JSContext *cx, jsval v, jsval *pval)
+{
+    typedef nsCharTraits<PRUnichar> traits;
+    // From the T_UTF8STRING  case in XPCConvert::JSData2Native.
+    JSString *s = InitOrStringify<traits>(cx, v, pval, eNull, eNull);
+    if (!s)
+        return;
+
+    size_t len = s->length();
+    const PRUnichar* chars =
+        reinterpret_cast<const PRUnichar*>(JS_GetStringChars(s));
+
+    new(mBuf) implementation_type(chars, len);
+    mValid = JS_TRUE;
+}
+
 static nsresult
 getNative(nsISupports *idobj,
           QITableEntry* entries,
           JSObject *obj,
           const nsIID &iid,
           void **ppThis,
           nsISupports **pThisRef,
           jsval *vp)
--- a/js/src/xpconnect/src/xpcquickstubs.h
+++ b/js/src/xpconnect/src/xpcquickstubs.h
@@ -1,9 +1,9 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  *
  * ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
  * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
  * the License. You may obtain a copy of the License at
  * http://www.mozilla.org/MPL/
@@ -308,43 +308,16 @@ public:
         return reinterpret_cast<implementation_type *>(mBuf);
     }
 
     operator interface_type &()
     {
         return *Ptr();
     }
 
-protected:
-    /*
-     * Neither field is initialized; that is left to the derived class
-     * constructor. However, the destructor destroys the string object
-     * stored in mBuf, if mValid is true.
-     */
-    void *mBuf[JS_HOWMANY(sizeof(implementation_type), sizeof(void *))];
-    JSBool mValid;
-};
-
-/**
- * Class for converting a jsval to DOMString.
- *
- *     xpc_qsDOMString arg0(cx, &argv[0]);
- *     if (!arg0.IsValid())
- *         return JS_FALSE;
- *
- * The second argument to the constructor is an in-out parameter. It must
- * point to a rooted jsval, such as a JSNative argument or return value slot.
- * The value in the jsval on entry is converted to a string. The constructor
- * may overwrite that jsval with a string value, to protect the characters of
- * the string from garbage collection. The caller must leave the jsval alone
- * for the lifetime of the xpc_qsDOMString.
- */
-class xpc_qsDOMString : public xpc_qsBasicString<nsAString, nsDependentString>
-{
-public:
     /* Enum that defines how JS |null| and |undefined| should be treated.  See
      * the WebIDL specification.  eStringify means convert to the string "null"
      * or "undefined" respectively, via the standard JS ToString() operation;
      * eEmpty means convert to the string ""; eNull means convert to an empty
      * string with the void bit set.
      *
      * Per webidl the default behavior of an unannotated interface is
      * eStringify, but our de-facto behavior has been eNull for |null| and
@@ -355,16 +328,98 @@ public:
     enum StringificationBehavior {
         eStringify,
         eEmpty,
         eNull,
         eDefaultNullBehavior = eNull,
         eDefaultUndefinedBehavior = eStringify
     };
 
+protected:
+    /*
+     * Neither field is initialized; that is left to the derived class
+     * constructor. However, the destructor destroys the string object
+     * stored in mBuf, if mValid is true.
+     */
+    void *mBuf[JS_HOWMANY(sizeof(implementation_type), sizeof(void *))];
+    JSBool mValid;
+
+    /*
+     * If null is returned, then we either failed or fully initialized
+     * |this|; in either case the caller should return immediately
+     * without doing anything else. Otherwise, the JSString* created
+     * from |v| will be returned.  It'll be rooted, as needed, in
+     * *pval.  nullBehavior and undefinedBehavior control what happens
+     * when |v| is JSVAL_IS_NULL and JSVAL_IS_VOID respectively.
+     */
+    template<class traits>
+    JSString* InitOrStringify(JSContext* cx, jsval v, jsval* pval,
+                              StringificationBehavior nullBehavior,
+                              StringificationBehavior undefinedBehavior) {
+        JSString *s;
+        if(JSVAL_IS_STRING(v))
+        {
+            s = JSVAL_TO_STRING(v);
+        }
+        else
+        {
+            StringificationBehavior behavior = eStringify;
+            if(JSVAL_IS_NULL(v))
+            {
+                behavior = nullBehavior;
+            }
+            else if(JSVAL_IS_VOID(v))
+            {
+                behavior = undefinedBehavior;
+            }
+
+            // If pval is null, that means the argument was optional and
+            // not passed; turn those into void strings if they're
+            // supposed to be stringified.
+            if (behavior != eStringify || !pval)
+            {
+                // Here behavior == eStringify implies !pval, so both eNull and
+                // eStringify should end up with void strings.
+                (new(mBuf) implementation_type(
+                    traits::sEmptyBuffer, PRUint32(0)))->
+                    SetIsVoid(behavior != eEmpty);
+                mValid = JS_TRUE;
+                return nsnull;
+            }
+
+            s = JS_ValueToString(cx, v);
+            if(!s)
+            {
+                mValid = JS_FALSE;
+                return nsnull;
+            }
+            *pval = STRING_TO_JSVAL(s);  // Root the new string.
+        }
+
+        return s;
+    }
+};
+
+/**
+ * Class for converting a jsval to DOMString.
+ *
+ *     xpc_qsDOMString arg0(cx, &argv[0]);
+ *     if (!arg0.IsValid())
+ *         return JS_FALSE;
+ *
+ * The second argument to the constructor is an in-out parameter. It must
+ * point to a rooted jsval, such as a JSNative argument or return value slot.
+ * The value in the jsval on entry is converted to a string. The constructor
+ * may overwrite that jsval with a string value, to protect the characters of
+ * the string from garbage collection. The caller must leave the jsval alone
+ * for the lifetime of the xpc_qsDOMString.
+ */
+class xpc_qsDOMString : public xpc_qsBasicString<nsAString, nsDependentString>
+{
+public:
     xpc_qsDOMString(JSContext *cx, jsval v, jsval *pval,
                     StringificationBehavior nullBehavior,
                     StringificationBehavior undefinedBehavior);
 };
 
 /**
  * The same as xpc_qsDOMString, but with slightly different conversion behavior,
  * corresponding to the [astring] magic XPIDL annotation rather than [domstring].
@@ -382,16 +437,26 @@ public:
  * with [cstring] rather than [domstring] or [astring].
  */
 class xpc_qsACString : public xpc_qsBasicString<nsACString, nsCString>
 {
 public:
     xpc_qsACString(JSContext *cx, jsval v, jsval *pval);
 };
 
+/**
+ * And similar for AUTF8String.
+ */
+class xpc_qsAUTF8String :
+  public xpc_qsBasicString<nsACString, NS_ConvertUTF16toUTF8>
+{
+public:
+  xpc_qsAUTF8String(JSContext* cx, jsval v, jsval *pval);
+};
+
 struct xpc_qsSelfRef
 {
     xpc_qsSelfRef() : ptr(nsnull) {}
     explicit xpc_qsSelfRef(nsISupports *p) : ptr(p) {}
     ~xpc_qsSelfRef() { NS_IF_RELEASE(ptr); }
 
     nsISupports* ptr;
 };
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -2463,18 +2463,17 @@ nsCSSFrameConstructor::ConstructDocEleme
                           frameItems, &contentFrame);
       if (NS_FAILED(rv))
         return rv;
       if (!contentFrame || frameItems.IsEmpty())
         return NS_ERROR_FAILURE;
       *aNewFrame = frameItems.FirstChild();
       NS_ASSERTION(frameItems.OnlyChild(), "multiple root element frames");
     } else {
-      contentFrame = NS_NewBlockFrame(mPresShell, styleContext,
-        NS_BLOCK_FLOAT_MGR|NS_BLOCK_MARGIN_ROOT);
+      contentFrame = NS_NewBlockFormattingContext(mPresShell, styleContext);
       if (!contentFrame)
         return NS_ERROR_OUT_OF_MEMORY;
       nsFrameItems frameItems;
       // Use a null PendingBinding, since our binding is not in fact pending.
       rv = ConstructBlock(state, display, aDocElement,
                           state.GetGeometricParent(display,
                                                    mDocElementContainingBlock),
                           mDocElementContainingBlock, styleContext,
@@ -3704,16 +3703,21 @@ nsCSSFrameConstructor::ConstructFrameFro
   CHECK_ONLY_ONE_BIT(FCDATA_FUNC_IS_FULL_CTOR, FCDATA_IS_POPUP);
   CHECK_ONLY_ONE_BIT(FCDATA_FUNC_IS_FULL_CTOR, FCDATA_SKIP_ABSPOS_PUSH);
   CHECK_ONLY_ONE_BIT(FCDATA_FUNC_IS_FULL_CTOR, FCDATA_FORCE_VIEW);
   CHECK_ONLY_ONE_BIT(FCDATA_FUNC_IS_FULL_CTOR,
                      FCDATA_DISALLOW_GENERATED_CONTENT);
   CHECK_ONLY_ONE_BIT(FCDATA_FUNC_IS_FULL_CTOR, FCDATA_ALLOW_BLOCK_STYLES);
   CHECK_ONLY_ONE_BIT(FCDATA_MAY_NEED_SCROLLFRAME, FCDATA_FORCE_VIEW);
 #undef CHECK_ONLY_ONE_BIT
+  NS_ASSERTION(!(bits & FCDATA_FORCED_NON_SCROLLABLE_BLOCK) ||
+               ((bits & FCDATA_FUNC_IS_FULL_CTOR) &&
+                data->mFullConstructor ==
+                  &nsCSSFrameConstructor::ConstructNonScrollableBlock),
+               "Unexpected FCDATA_FORCED_NON_SCROLLABLE_BLOCK flag");
 
   // Don't create a subdocument frame for iframes if we're creating extra frames
   if (aState.mCreatingExtraFrames && aItem.mContent->IsHTML() &&
       aItem.mContent->Tag() == nsGkAtoms::iframe)
   {
     return NS_OK;
   }
 
@@ -4360,30 +4364,35 @@ nsCSSFrameConstructor::FindDisplayData(c
       PropagateScrollToViewport() == aContent;
   }
 
   NS_ASSERTION(!propagatedScrollToViewport ||
                !mPresShell->GetPresContext()->IsPaginated(),
                "Shouldn't propagate scroll in paginated contexts");
 
   // If the frame is a block-level frame and is scrollable, then wrap it in a
-  // scroll frame.  Except we don't want to do that for paginated contexts for
-  // frames that are block-outside and aren't frames for native anonymous stuff.
-  // The condition on skipping scrollframe construction in the
-  // paginated case needs to match code in ConstructNonScrollableBlock
-  // and in nsFrame::ApplyPaginatedOverflowClipping.
+  // scroll frame.
   // XXX Ignore tables for the time being
   // XXXbz it would be nice to combine this with the other block
   // case... Think about how do do this?
   if (aDisplay->IsBlockInside() &&
       aDisplay->IsScrollableOverflow() &&
-      !propagatedScrollToViewport &&
-      (!mPresShell->GetPresContext()->IsPaginated() ||
-       !aDisplay->IsBlockOutside() ||
-       aContent->IsInNativeAnonymousSubtree())) {
+      !propagatedScrollToViewport) {
+    // Except we don't want to do that for paginated contexts for
+    // frames that are block-outside and aren't frames for native
+    // anonymous stuff.
+    if (mPresShell->GetPresContext()->IsPaginated() &&
+        aDisplay->IsBlockOutside() &&
+        !aContent->IsInNativeAnonymousSubtree()) {
+      static const FrameConstructionData sForcedNonScrollableBlockData =
+        FULL_CTOR_FCDATA(FCDATA_FORCED_NON_SCROLLABLE_BLOCK,
+                         &nsCSSFrameConstructor::ConstructNonScrollableBlock);
+      return &sForcedNonScrollableBlockData;
+    }
+
     static const FrameConstructionData sScrollableBlockData =
       FULL_CTOR_FCDATA(0, &nsCSSFrameConstructor::ConstructScrollableBlock);
     return &sScrollableBlockData;
   }
 
   // Handle various non-scrollable blocks
   if (aDisplay->IsBlockInside() ||
       NS_STYLE_DISPLAY_RUN_IN == aDisplay->mDisplay ||
@@ -4499,32 +4508,30 @@ nsCSSFrameConstructor::ConstructNonScrol
                                                    FrameConstructionItem&   aItem,
                                                    nsIFrame*                aParentFrame,
                                                    const nsStyleDisplay*    aDisplay,
                                                    nsFrameItems&            aFrameItems,
                                                    nsIFrame**               aNewFrame)
 {
   nsStyleContext* const styleContext = aItem.mStyleContext;
 
+  // We want a block formatting context root in paginated contexts for
+  // every block that would be scrollable in a non-paginated context.
+  // We mark our blocks with a bit here if this condition is true, so
+  // we can check it later in nsFrame::ApplyPaginatedOverflowClipping.
+  PRBool clipPaginatedOverflow =
+    (aItem.mFCData->mBits & FCDATA_FORCED_NON_SCROLLABLE_BLOCK) != 0;
   if (aDisplay->IsAbsolutelyPositioned() ||
       aDisplay->IsFloating() ||
       NS_STYLE_DISPLAY_INLINE_BLOCK == aDisplay->mDisplay ||
-      // This check just needs to be the same as the check for using scrollable
-      // blocks in FindDisplayData and the check for clipping in
-      // nsFrame::ApplyPaginatedOverflowClipping; we want a block formatting
-      // context root in paginated contexts for every block that would be
-      // scrollable in a non-paginated context.  Note that IsPaginated()
-      // implies that no propagation to viewport has taken place, so we don't
-      // need to check for propagation here.
-      (mPresShell->GetPresContext()->IsPaginated() &&
-       aDisplay->IsBlockInside() &&
-       aDisplay->IsScrollableOverflow() &&
-       aDisplay->IsBlockOutside() &&
-       !aItem.mContent->IsInNativeAnonymousSubtree())) {
+      clipPaginatedOverflow) {
     *aNewFrame = NS_NewBlockFormattingContext(mPresShell, styleContext);
+    if (clipPaginatedOverflow) {
+      (*aNewFrame)->AddStateBits(NS_BLOCK_CLIP_PAGINATED_OVERFLOW);
+    }
   } else {
     *aNewFrame = NS_NewBlockFrame(mPresShell, styleContext);
   }
 
   return ConstructBlock(aState, aDisplay, aItem.mContent,
                         aState.GetGeometricParent(aDisplay, aParentFrame),
                         aParentFrame, styleContext, aNewFrame,
                         aFrameItems, aDisplay->IsPositioned(),
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -723,16 +723,20 @@ private:
   /* If FCDATA_ALLOW_BLOCK_STYLES is set, allow block styles when processing
      children.  This should not be used with FCDATA_FUNC_IS_FULL_CTOR. */
 #define FCDATA_ALLOW_BLOCK_STYLES 0x10000
   /* If FCDATA_USE_CHILD_ITEMS is set, then use the mChildItems in the relevant
      FrameConstructionItem instead of trying to process the content's children.
      This can be used with or without FCDATA_FUNC_IS_FULL_CTOR.
      The child items might still need table pseudo processing. */
 #define FCDATA_USE_CHILD_ITEMS 0x20000
+  /* If FCDATA_FORCED_NON_SCROLLABLE_BLOCK is set, then this block
+     would have been scrollable but has been forced to be
+     non-scrollable due to being in a paginated context. */
+#define FCDATA_FORCED_NON_SCROLLABLE_BLOCK 0x40000
 
   /* Structure representing information about how a frame should be
      constructed.  */
   struct FrameConstructionData {
     // Flag bits that can modify the way the construction happens
     PRUint32 mBits;
     // We have exactly one of three types of functions, so use a union for
     // better cache locality for the ones that aren't pointer-to-member.  That
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -373,17 +373,17 @@ protected:
                                    nscoord& start,
                                    nscoord& width);
 
   void TryAllLines(nsLineList::iterator* aIterator,
                    nsLineList::iterator* aStartIterator,
                    nsLineList::iterator* aEndIterator,
                    PRBool* aInOverflowLines);
 
-  void SetFlags(PRUint32 aFlags) {
+  void SetFlags(nsFrameState aFlags) {
     mState &= ~NS_BLOCK_FLAGS_MASK;
     mState |= aFlags;
   }
 
   PRBool HaveOutsideBullet() const {
 #if defined(DEBUG) && !defined(DEBUG_rods)
     if(mState & NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET) {
       NS_ASSERTION(mBullet,"NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET flag set and no mBullet");
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -1226,30 +1226,23 @@ static inline PRBool ApplyOverflowHidden
   return type == nsGkAtoms::tableFrame ||
        type == nsGkAtoms::tableCellFrame ||
        type == nsGkAtoms::bcTableCellFrame;
 }
 
 static inline PRBool ApplyPaginatedOverflowClipping(nsIFrame* aFrame,
                                                     const nsStyleDisplay* aDisp)
 {
-  // These conditions on aDisp need to match the conditions for which in
-  // non-paginated contexts we'd create a scrollframe for a block but in a
-  // paginated context we don't.  See nsCSSFrameConstructor::FindDisplayData
-  // for the relevant conditions.  These conditions must also match those in
-  // nsCSSFrameConstructor::ConstructNonScrollableBlock for creating block
-  // formatting context roots for forced-to-be-no-longer scrollable blocks in
-  // paginated contexts.
+  // If we're paginated and aFrame is a block, and it has
+  // NS_BLOCK_CLIP_PAGINATED_OVERFLOW set, then we want to clip our
+  // overflow.
   return
     aFrame->PresContext()->IsPaginated() &&
-    aDisp->IsBlockInside() &&
-    aDisp->IsScrollableOverflow() &&
-    aDisp->IsBlockOutside() &&
     aFrame->GetType() == nsGkAtoms::blockFrame &&
-    !aFrame->GetContent()->IsInNativeAnonymousSubtree();
+    (aFrame->GetStateBits() & NS_BLOCK_CLIP_PAGINATED_OVERFLOW) != 0;
 }
 
 static PRBool ApplyOverflowClipping(nsDisplayListBuilder* aBuilder,
                                     nsIFrame* aFrame,
                                     const nsStyleDisplay* aDisp, nsRect* aRect) {
   // REVIEW: from nsContainerFrame.cpp SyncFrameViewGeometryDependentProperties,
   // except that that function used the border-edge for
   // -moz-hidden-unscrollable which I don't think is correct... Also I've
--- a/layout/generic/nsHTMLParts.h
+++ b/layout/generic/nsHTMLParts.h
@@ -57,33 +57,39 @@ class nsString;
 class nsIPresShell;
 class nsIChannel;
 class nsTableColFrame;
 
 /**
  * Additional frame-state bits used by nsBlockFrame
  * See the meanings at http://www.mozilla.org/newlayout/doc/block-and-line.html
  *
+ * NS_BLOCK_CLIP_PAGINATED_OVERFLOW is only set in paginated prescontexts, on
+ *  blocks which were forced to not have scrollframes but still need to clip
+ *  the display of their kids.
+ *
  * NS_BLOCK_HAS_FIRST_LETTER_STYLE means that the block has first-letter style,
  *  even if it has no actual first-letter frame among its descendants.
  *
  * NS_BLOCK_HAS_FIRST_LETTER_CHILD means that there is an inflow first-letter
  *  frame among the block's descendants. If there is a floating first-letter
  *  frame, or the block has first-letter style but has no first letter, this
  *  bit is not set. This bit is set on the first continuation only.
  */
 #define NS_BLOCK_MARGIN_ROOT              NS_FRAME_STATE_BIT(22)
 #define NS_BLOCK_FLOAT_MGR                NS_FRAME_STATE_BIT(23)
+#define NS_BLOCK_CLIP_PAGINATED_OVERFLOW  NS_FRAME_STATE_BIT(28)
 #define NS_BLOCK_HAS_FIRST_LETTER_STYLE   NS_FRAME_STATE_BIT(29)
 #define NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET NS_FRAME_STATE_BIT(30)
 #define NS_BLOCK_HAS_FIRST_LETTER_CHILD   NS_FRAME_STATE_BIT(31)
 // These are the bits that get inherited from a block frame to its
 // next-in-flows and are not private to blocks
 #define NS_BLOCK_FLAGS_MASK               (NS_BLOCK_MARGIN_ROOT | \
                                            NS_BLOCK_FLOAT_MGR | \
+                                           NS_BLOCK_CLIP_PAGINATED_OVERFLOW | \
                                            NS_BLOCK_HAS_FIRST_LETTER_STYLE | \
                                            NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET | \
                                            NS_BLOCK_HAS_FIRST_LETTER_CHILD)
 
 // Factory methods for creating html layout objects
 
 // Create a frame that supports "display: block" layout behavior
 nsIFrame*
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/609272-1-ref.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<html class="reftest-print">
+  This text should show up
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/609272-1.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<html class="reftest-print" style="height: 0; overflow: hidden">
+  This text should show up
+</html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1536,16 +1536,17 @@ fails-if(!haveTestPlugin) == 599476.html
 == 600974-3.html 600974-1-ref.html
 == 602200-1.html 602200-1-ref.html
 == 602200-2.html 602200-2-ref.html
 == 602200-3.html 602200-3-ref.html
 == 602200-4.html 602200-4-ref.html
 == 604737.html 604737-ref.html
 == 605138-1.html 605138-1-ref.html
 == 605157-1.xhtml 605157-1-ref.xhtml
+== 609272-1.html 609272-1-ref.html
 == 608636-1.html 608636-1-ref.html
 == 613433-1.html 613433-1-ref.html
 == 613433-1.html 613433-2-ref.html
 == 613433-1.html 613433-3-ref.html
 == 613433-2.html 613433-1-ref.html
 == 613433-2.html 613433-2-ref.html
 == 613433-2.html 613433-3-ref.html
 == 613433-3.html 613433-1-ref.html
--- a/layout/reftests/canvas/reftest.list
+++ b/layout/reftests/canvas/reftest.list
@@ -34,8 +34,10 @@ asserts-if(cocoaWidget,0-2) == size-chan
 == text-no-frame-test.html text-no-frame-ref.html
 == text-no-frame-2-test.html text-not-in-doc-ref.html
 == text-not-in-doc-test.html text-not-in-doc-ref.html
 
 == text-bidi-ltr-test.html text-bidi-ltr-ref.html
 == text-bidi-rtl-test.html text-bidi-rtl-ref.html
 
 != text-font-lang.html text-font-lang-notref.html
+
+== strokeText-path.html strokeText-path-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/canvas/strokeText-path-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <script type="text/javascript"><!--
+window.onload = function () {
+  var canvas = document.getElementById('testCanvas'),
+      context = canvas.getContext('2d');
+
+  // draw some text
+  context.font = 'bold 40px sans-serif';
+  context.strokeText("Hello world!", 10, 50);
+};
+      // --></script>
+  </head>
+  <body>
+    <p>You should see only see "Hello world!" below, without any additional 
+    line. JavaScript is required.</p>
+
+    <p><canvas id="testCanvas" width="400" height="300">You need Canvas 
+    support.</canvas></p>
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/canvas/strokeText-path.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <script type="text/javascript"><!--
+window.onload = function () {
+  var canvas = document.getElementById('testCanvas'),
+      context = canvas.getContext('2d');
+
+  // draw a path
+  context.beginPath();
+  context.moveTo(10, 10);
+  context.lineTo(200, 10);
+  context.lineTo(200, 200);
+  context.stroke();
+  context.closePath();
+
+  context.clearRect(0, 0, canvas.width, canvas.height);
+
+  // draw some text
+  context.font = 'bold 40px sans-serif';
+  context.strokeText("Hello world!", 10, 50);
+};
+      // --></script>
+  </head>
+  <body>
+    <p>You should see only see "Hello world!" below, without any additional 
+    line. JavaScript is required.</p>
+
+    <p><canvas id="testCanvas" width="400" height="300">You need Canvas 
+    support.</canvas></p>
+
+  </body>
+</html>
--- a/layout/style/nsCSSStyleSheet.cpp
+++ b/layout/style/nsCSSStyleSheet.cpp
@@ -463,20 +463,17 @@ nsMediaQuery::AppendToString(nsAString& 
                          "bad unit");
             array->Item(0).AppendToString(eCSSProperty_z_index, aString);
             aString.AppendLiteral("/");
             array->Item(1).AppendToString(eCSSProperty_z_index, aString);
           }
           break;
         case nsMediaFeature::eResolution:
           {
-            nsAutoString buffer;
-            buffer.AppendFloat(expr.mValue.GetFloatValue());
-            aString.Append(buffer);
-            buffer.Truncate();
+            aString.AppendFloat(expr.mValue.GetFloatValue());
             if (expr.mValue.GetUnit() == eCSSUnit_Inch) {
               aString.AppendLiteral("dpi");
             } else {
               NS_ASSERTION(expr.mValue.GetUnit() == eCSSUnit_Centimeter,
                            "bad unit");
               aString.AppendLiteral("dpcm");
             }
           }
--- a/layout/style/nsCSSValue.cpp
+++ b/layout/style/nsCSSValue.cpp
@@ -764,19 +764,17 @@ nsCSSValue::AppendToString(nsCSSProperty
     aResult.AppendLiteral(")");
   }
   else if (IsCalcUnit()) {
     NS_ABORT_IF_FALSE(GetUnit() == eCSSUnit_Calc, "unexpected unit");
     CSSValueSerializeCalcOps ops(aProperty, aResult);
     css::SerializeCalc(*this, ops);
   }
   else if (eCSSUnit_Integer == unit) {
-    nsAutoString tmpStr;
-    tmpStr.AppendInt(GetIntValue(), 10);
-    aResult.Append(tmpStr);
+    aResult.AppendInt(GetIntValue(), 10);
   }
   else if (eCSSUnit_Enumerated == unit) {
     if (eCSSProperty_text_decoration == aProperty) {
       PRInt32 intValue = GetIntValue();
       if (NS_STYLE_TEXT_DECORATION_NONE == intValue) {
         AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue),
                            aResult);
       } else {
@@ -827,38 +825,35 @@ nsCSSValue::AppendToString(nsCSSProperty
   }
   else if (eCSSUnit_Color == unit) {
     nscolor color = GetColorValue();
     if (color == NS_RGBA(0, 0, 0, 0)) {
       // Use the strictest match for 'transparent' so we do correct
       // round-tripping of all other rgba() values.
       aResult.AppendLiteral("transparent");
     } else {
-      nsAutoString tmpStr;
       PRUint8 a = NS_GET_A(color);
       if (a < 255) {
-        tmpStr.AppendLiteral("rgba(");
+        aResult.AppendLiteral("rgba(");
       } else {
-        tmpStr.AppendLiteral("rgb(");
+        aResult.AppendLiteral("rgb(");
       }
 
       NS_NAMED_LITERAL_STRING(comma, ", ");
 
-      tmpStr.AppendInt(NS_GET_R(color), 10);
-      tmpStr.Append(comma);
-      tmpStr.AppendInt(NS_GET_G(color), 10);
-      tmpStr.Append(comma);
-      tmpStr.AppendInt(NS_GET_B(color), 10);
+      aResult.AppendInt(NS_GET_R(color), 10);
+      aResult.Append(comma);
+      aResult.AppendInt(NS_GET_G(color), 10);
+      aResult.Append(comma);
+      aResult.AppendInt(NS_GET_B(color), 10);
       if (a < 255) {
-        tmpStr.Append(comma);
-        tmpStr.AppendFloat(nsStyleUtil::ColorComponentToFloat(a));
+        aResult.Append(comma);
+        aResult.AppendFloat(nsStyleUtil::ColorComponentToFloat(a));
       }
-      tmpStr.Append(PRUnichar(')'));
-
-      aResult.Append(tmpStr);
+      aResult.Append(PRUnichar(')'));
     }
   }
   else if (eCSSUnit_URL == unit || eCSSUnit_Image == unit) {
     aResult.Append(NS_LITERAL_STRING("url("));
     nsStyleUtil::AppendEscapedCSSString(
       nsDependentString(GetOriginalURLValue()), aResult);
     aResult.Append(NS_LITERAL_STRING(")"));
   }
@@ -866,24 +861,20 @@ nsCSSValue::AppendToString(nsCSSProperty
     aResult.Append(NS_LITERAL_STRING("-moz-element(#"));
     nsAutoString tmpStr;
     GetStringValue(tmpStr);
     nsStyleUtil::AppendEscapedCSSIdent(
       nsDependentString(tmpStr), aResult);
     aResult.Append(NS_LITERAL_STRING(")"));
   }
   else if (eCSSUnit_Percent == unit) {
-    nsAutoString tmpStr;
-    tmpStr.AppendFloat(GetPercentValue() * 100.0f);
-    aResult.Append(tmpStr);
+    aResult.AppendFloat(GetPercentValue() * 100.0f);
   }
   else if (eCSSUnit_Percent < unit) {  // length unit
-    nsAutoString tmpStr;
-    tmpStr.AppendFloat(GetFloatValue());
-    aResult.Append(tmpStr);
+    aResult.AppendFloat(GetFloatValue());
   }
   else if (eCSSUnit_Gradient == unit) {
     nsCSSValueGradient* gradient = GetGradientValue();
 
     if (gradient->mIsRepeating) {
       if (gradient->mIsRadial)
         aResult.AppendLiteral("-moz-repeating-radial-gradient(");
       else
--- a/netwerk/base/src/nsIOService.cpp
+++ b/netwerk/base/src/nsIOService.cpp
@@ -169,38 +169,48 @@ static const char kProfileChangeNetResto
 // Necko buffer cache
 nsIMemory* nsIOService::gBufferCache = nsnull;
 PRUint32   nsIOService::gDefaultSegmentSize = 4096;
 PRUint32   nsIOService::gDefaultSegmentCount = 24;
 
 ////////////////////////////////////////////////////////////////////////////////
 
 nsIOService::nsIOService()
-    : mOffline(PR_TRUE)
+    : mOffline(PR_FALSE)
     , mOfflineForProfileChange(PR_FALSE)
     , mManageOfflineStatus(PR_TRUE)
     , mSettingOffline(PR_FALSE)
     , mSetOfflineValue(PR_FALSE)
     , mShutdown(PR_FALSE)
     , mChannelEventSinks(NS_CHANNEL_EVENT_SINK_CATEGORY)
     , mContentSniffers(NS_CONTENT_SNIFFER_CATEGORY)
 {
 }
 
 nsresult
 nsIOService::Init()
 {
     NS_TIME_FUNCTION;
 
     nsresult rv;
-
-    // We need to get references to the DNS service so that we can shut it
+    
+    // We need to get references to these services so that we can shut them
     // down later. If we wait until the nsIOService is being shut down,
     // GetService will fail at that point.
 
+    // TODO(darin): Load the Socket and DNS services lazily.
+
+    mSocketTransportService = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
+    if (NS_FAILED(rv)) {
+        NS_WARNING("failed to get socket transport service");
+        return rv;
+    }
+
+    NS_TIME_FUNCTION_MARK("got SocketTransportService");
+
     mDNSService = do_GetService(NS_DNSSERVICE_CONTRACTID, &rv);
     if (NS_FAILED(rv)) {
         NS_WARNING("failed to get DNS service");
         return rv;
     }
 
     NS_TIME_FUNCTION_MARK("got DNS Service");
 
@@ -278,39 +288,17 @@ nsIOService::Init()
 
     return NS_OK;
 }
 
 
 nsIOService::~nsIOService()
 {
     gIOService = nsnull;
-}
-
-nsresult
-nsIOService::InitializeSocketTransportService()
-{
-    NS_TIME_FUNCTION;
-
-    nsresult rv = NS_OK;
-
-    if (!mSocketTransportService) {
-        mSocketTransportService = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
-        if (NS_FAILED(rv)) {
-            NS_WARNING("failed to get socket transport service");
-        }
-    }
-
-    if (mSocketTransportService) {
-        rv = mSocketTransportService->Init();
-        NS_ASSERTION(NS_SUCCEEDED(rv), "socket transport service init failed");
-    }
-
-    return rv;
-}
+}   
 
 nsIOService*
 nsIOService::GetInstance() {
     if (!gIOService) {
         gIOService = new nsIOService();
         if (!gIOService)
             return nsnull;
         NS_ADDREF(gIOService);
@@ -749,17 +737,20 @@ nsIOService::SetOffline(PRBool offline)
                                                  offlineString.get());
         }
         else if (!offline && mOffline) {
             // go online
             if (mDNSService) {
                 rv = mDNSService->Init();
                 NS_ASSERTION(NS_SUCCEEDED(rv), "DNS service init failed");
             }
-            InitializeSocketTransportService();
+            if (mSocketTransportService) {
+                rv = mSocketTransportService->Init();
+                NS_ASSERTION(NS_SUCCEEDED(rv), "socket transport service init failed");
+            }
             mOffline = PR_FALSE;    // indicate success only AFTER we've
                                     // brought up the services
 
             // trigger a PAC reload when we come back online
             if (mProxyService)
                 mProxyService->ReloadPAC();
 
             // don't care if notification fails
--- a/netwerk/base/src/nsIOService.h
+++ b/netwerk/base/src/nsIOService.h
@@ -103,20 +103,16 @@ public:
     // Gets the array of registered content sniffers
     const nsCOMArray<nsIContentSniffer>& GetContentSniffers() {
       return mContentSniffers.GetEntries();
     }
 
     PRBool IsOffline() { return mOffline; }
     PRBool IsLinkUp();
 
-    PRBool IsComingOnline() const {
-      return mOffline && mSettingOffline && !mSetOfflineValue;
-    }
-
 private:
     // These shouldn't be called directly:
     // - construct using GetInstance
     // - destroy using Release
     nsIOService() NS_HIDDEN;
     ~nsIOService() NS_HIDDEN;
 
     NS_HIDDEN_(nsresult) TrackNetworkLinkStatusForOffline();
@@ -128,18 +124,16 @@ private:
     NS_HIDDEN_(nsresult) CacheProtocolHandler(const char *scheme,
                                               nsIProtocolHandler* hdlr);
 
     // Prefs wrangling
     NS_HIDDEN_(void) PrefsChanged(nsIPrefBranch *prefs, const char *pref = nsnull);
     NS_HIDDEN_(void) GetPrefBranch(nsIPrefBranch2 **);
     NS_HIDDEN_(void) ParsePortList(nsIPrefBranch *prefBranch, const char *pref, PRBool remove);
 
-    nsresult InitializeSocketTransportService();
-
 private:
     PRPackedBool                         mOffline;
     PRPackedBool                         mOfflineForProfileChange;
     PRPackedBool                         mManageOfflineStatus;
 
     // Used to handle SetOffline() reentrancy.  See the comment in
     // SetOffline() for more details.
     PRPackedBool                         mSettingOffline;
--- a/netwerk/base/src/nsSocketTransportService2.cpp
+++ b/netwerk/base/src/nsSocketTransportService2.cpp
@@ -47,17 +47,16 @@
 #include "nsNetError.h"
 #include "prnetdb.h"
 #include "prlock.h"
 #include "prerror.h"
 #include "plstr.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch2.h"
 #include "nsServiceManagerUtils.h"
-#include "nsIOService.h"
 
 #include "mozilla/FunctionTimer.h"
 
 #if defined(PR_LOGGING)
 PRLogModuleInfo *gSocketTransportLog = nsnull;
 #endif
 
 nsSocketTransportService *gSocketTransportService = nsnull;
@@ -391,20 +390,16 @@ nsSocketTransportService::Init()
     }
 
     if (mInitialized)
         return NS_OK;
 
     if (mShuttingDown)
         return NS_ERROR_UNEXPECTED;
 
-    // Don't initialize inside the offline mode
-    if (gIOService->IsOffline() && !gIOService->IsComingOnline())
-        return NS_ERROR_OFFLINE;
-
     if (!mThreadEvent) {
         mThreadEvent = PR_NewPollableEvent();
         //
         // NOTE: per bug 190000, this failure could be caused by Zone-Alarm
         // or similar software.
         //
         // NOTE: per bug 191739, this failure could also be caused by lack
         // of a loopback device on Windows and OS/2 platforms (NSPR creates
--- a/netwerk/dns/nsDNSService2.cpp
+++ b/netwerk/dns/nsDNSService2.cpp
@@ -52,17 +52,16 @@
 #include "nsNetError.h"
 #include "nsDNSPrefetch.h"
 #include "nsIProtocolProxyService.h"
 #include "prsystem.h"
 #include "prnetdb.h"
 #include "prmon.h"
 #include "prio.h"
 #include "plstr.h"
-#include "nsIOService.h"
 
 #include "mozilla/FunctionTimer.h"
 
 static const char kPrefDnsCacheEntries[]    = "network.dnsCacheEntries";
 static const char kPrefDnsCacheExpiration[] = "network.dnsCacheExpiration";
 static const char kPrefEnableIDN[]          = "network.enableIDN";
 static const char kPrefIPv4OnlyDomains[]    = "network.dns.ipv4OnlyDomains";
 static const char kPrefDisableIPv6[]        = "network.dns.disableIPv6";
@@ -378,38 +377,33 @@ nsDNSService::Init()
     }
 
     // we have to null out mIDN since we might be getting re-initialized
     // as a result of a pref change.
     nsCOMPtr<nsIIDNService> idn;
     if (enableIDN)
         idn = do_GetService(NS_IDNSERVICE_CONTRACTID);
 
-    nsDNSPrefetch::Initialize(this);
-
-    // Don't initialize the resolver if we're in offline mode.
-    // Later on, the IO service will reinitialize us when going online.
-    if (gIOService->IsOffline() && !gIOService->IsComingOnline())
-        return NS_OK;
-
     nsRefPtr<nsHostResolver> res;
     nsresult rv = nsHostResolver::Create(maxCacheEntries,
                                          maxCacheLifetime,
                                          getter_AddRefs(res));
     if (NS_SUCCEEDED(rv)) {
         // now, set all of our member variables while holding the lock
         nsAutoLock lock(mLock);
         mResolver = res;
         mIDN = idn;
         mIPv4OnlyDomains = ipv4OnlyDomains; // exchanges buffer ownership
         mDisableIPv6 = disableIPv6;
 
         // Disable prefetching either by explicit preference or if a manual proxy is configured 
         mDisablePrefetch = disablePrefetch || (proxyType == nsIProtocolProxyService::PROXYCONFIG_MANUAL);
     }
+    
+    nsDNSPrefetch::Initialize(this);
     return rv;
 }
 
 NS_IMETHODIMP
 nsDNSService::Shutdown()
 {
     nsRefPtr<nsHostResolver> res;
     {
@@ -572,18 +566,18 @@ nsDNSService::Observe(nsISupports *subje
     //
     // NOTE Shutting down and reinitializing the service like this is obviously
     // suboptimal if Observe gets called several times in a row, but we don't
     // expect that to be the case.
     //
 
     if (mResolver) {
         Shutdown();
+        Init();
     }
-    Init();
     return NS_OK;
 }
 
 PRUint16
 nsDNSService::GetAFForLookup(const nsACString &host)
 {
     if (mDisableIPv6)
         return PR_AF_INET;
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -38,17 +38,16 @@
 
 #include "nsHttpConnectionMgr.h"
 #include "nsHttpConnection.h"
 #include "nsHttpPipeline.h"
 #include "nsHttpHandler.h"
 #include "nsAutoLock.h"
 #include "nsNetCID.h"
 #include "nsCOMPtr.h"
-#include "nsNetUtil.h"
 
 #include "nsIServiceManager.h"
 
 #include "nsIObserverService.h"
 
 // defined by the socket transport service while active
 extern PRThread *gSocketThread;
 
@@ -97,65 +96,48 @@ nsHttpConnectionMgr::~nsHttpConnectionMg
 {
     LOG(("Destroying nsHttpConnectionMgr @%x\n", this));
  
     if (mMonitor)
         nsAutoMonitor::DestroyMonitor(mMonitor);
 }
 
 nsresult
-nsHttpConnectionMgr::EnsureSocketThreadTargetIfOnline()
-{
-    nsresult rv;
-    nsCOMPtr<nsIEventTarget> sts;
-    nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
-    if (NS_SUCCEEDED(rv)) {
-        PRBool offline = PR_TRUE;
-        ioService->GetOffline(&offline);
-
-        if (!offline) {
-            sts = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
-        }
-    }
-
-    nsAutoMonitor mon(mMonitor);
-
-    // do nothing if already initialized
-    if (mSocketThreadTarget)
-        return NS_OK;
-
-    mSocketThreadTarget = sts;
-
-    return rv;
-}
-
-nsresult
 nsHttpConnectionMgr::Init(PRUint16 maxConns,
                           PRUint16 maxConnsPerHost,
                           PRUint16 maxConnsPerProxy,
                           PRUint16 maxPersistConnsPerHost,
                           PRUint16 maxPersistConnsPerProxy,
                           PRUint16 maxRequestDelay,
                           PRUint16 maxPipelinedRequests)
 {
     LOG(("nsHttpConnectionMgr::Init\n"));
 
-    {
-        nsAutoMonitor mon(mMonitor);
+    nsresult rv;
+    nsCOMPtr<nsIEventTarget> sts = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
+    if (NS_FAILED(rv)) return rv;
+
+    nsAutoMonitor mon(mMonitor);
+
+    // do nothing if already initialized
+    if (mSocketThreadTarget)
+        return NS_OK;
 
-        mMaxConns = maxConns;
-        mMaxConnsPerHost = maxConnsPerHost;
-        mMaxConnsPerProxy = maxConnsPerProxy;
-        mMaxPersistConnsPerHost = maxPersistConnsPerHost;
-        mMaxPersistConnsPerProxy = maxPersistConnsPerProxy;
-        mMaxRequestDelay = maxRequestDelay;
-        mMaxPipelinedRequests = maxPipelinedRequests;
-    }
+    // no need to do any special synchronization here since there cannot be
+    // any activity on the socket thread (because Shutdown is synchronous).
+    mMaxConns = maxConns;
+    mMaxConnsPerHost = maxConnsPerHost;
+    mMaxConnsPerProxy = maxConnsPerProxy;
+    mMaxPersistConnsPerHost = maxPersistConnsPerHost;
+    mMaxPersistConnsPerProxy = maxPersistConnsPerProxy;
+    mMaxRequestDelay = maxRequestDelay;
+    mMaxPipelinedRequests = maxPipelinedRequests;
 
-    return EnsureSocketThreadTargetIfOnline();
+    mSocketThreadTarget = sts;
+    return rv;
 }
 
 nsresult
 nsHttpConnectionMgr::Shutdown()
 {
     LOG(("nsHttpConnectionMgr::Shutdown\n"));
 
     nsAutoMonitor mon(mMonitor);
@@ -179,22 +161,16 @@ nsHttpConnectionMgr::Shutdown()
     // wait for shutdown event to complete
     mon.Wait();
     return NS_OK;
 }
 
 nsresult
 nsHttpConnectionMgr::PostEvent(nsConnEventHandler handler, PRInt32 iparam, void *vparam)
 {
-    // This object doesn't get reinitialized if the offline state changes, so our
-    // socket thread target might be uninitialized if we were offline when this
-    // object was being initialized, and we go online later on.  This call takes
-    // care of initializing the socket thread target if that's the case.
-    EnsureSocketThreadTargetIfOnline();
-
     nsAutoMonitor mon(mMonitor);
 
     nsresult rv;
     if (!mSocketThreadTarget) {
         NS_WARNING("cannot post event if not initialized");
         rv = NS_ERROR_NOT_INITIALIZED;
     }
     else {
@@ -304,22 +280,16 @@ nsresult
 nsHttpConnectionMgr::PruneDeadConnections()
 {
     return PostEvent(&nsHttpConnectionMgr::OnMsgPruneDeadConnections);
 }
 
 nsresult
 nsHttpConnectionMgr::GetSocketThreadTarget(nsIEventTarget **target)
 {
-    // This object doesn't get reinitialized if the offline state changes, so our
-    // socket thread target might be uninitialized if we were offline when this
-    // object was being initialized, and we go online later on.  This call takes
-    // care of initializing the socket thread target if that's the case.
-    EnsureSocketThreadTargetIfOnline();
-
     nsAutoMonitor mon(mMonitor);
     NS_IF_ADDREF(*target = mSocketThreadTarget);
     return NS_OK;
 }
 
 void
 nsHttpConnectionMgr::AddTransactionToPipeline(nsHttpPipeline *pipeline)
 {
--- a/netwerk/protocol/http/nsHttpConnectionMgr.h
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
@@ -210,17 +210,16 @@ private:
     static PRIntn PurgeExcessIdleConnectionsCB(nsHashKey *, void *, void *);
     PRBool   ProcessPendingQForEntry(nsConnectionEntry *);
     PRBool   AtActiveConnectionLimit(nsConnectionEntry *, PRUint8 caps);
     void     GetConnection(nsConnectionEntry *, PRUint8 caps, nsHttpConnection **);
     nsresult DispatchTransaction(nsConnectionEntry *, nsAHttpTransaction *,
                                  PRUint8 caps, nsHttpConnection *);
     PRBool   BuildPipeline(nsConnectionEntry *, nsAHttpTransaction *, nsHttpPipeline **);
     nsresult ProcessNewTransaction(nsHttpTransaction *);
-    nsresult EnsureSocketThreadTargetIfOnline();
 
     // message handlers have this signature
     typedef void (nsHttpConnectionMgr:: *nsConnEventHandler)(PRInt32, void *);
 
     // nsConnEvent
     //
     // subclass of nsRunnable used to marshall events to the socket transport
     // thread.  this class is used to implement PostEvent.
deleted file mode 100644
--- a/netwerk/test/unit/test_offline_status.js
+++ /dev/null
@@ -1,10 +0,0 @@
-function run_test() {
-  var ioService = Components.classes["@mozilla.org/network/io-service;1"]
-                            .getService(Components.interfaces.nsIIOService);
-
-  var linkService = Components.classes["@mozilla.org/network/network-link-service;1"]
-                              .getService(Components.interfaces.nsINetworkLinkService);
-
-  // The offline status should depends on the link status
-  do_check_neq(ioService.offline, linkService.isLinkUp);
-}
deleted file mode 100644
--- a/netwerk/test/unit/test_sockettransportsvc_available.js
+++ /dev/null
@@ -1,8 +0,0 @@
-function run_test() {
-  try {
-    var sts = Components.classes["@mozilla.org/network/socket-transport-service;1"]
-                        .getService(Components.interfaces.nsISocketTransportService);
-  } catch(e) {}
-
-  do_check_true(!!sts);
-}
--- a/xpcom/string/public/nsTString.h
+++ b/xpcom/string/public/nsTString.h
@@ -379,44 +379,16 @@ class nsTString_CharT : public nsTSubstr
          */
 
       NS_COM void AssignWithConversion( const nsTAString_IncompatibleCharT& aString );
       NS_COM void AssignWithConversion( const incompatible_char_type* aData, PRInt32 aLength=-1 );
 
       NS_COM void AppendWithConversion( const nsTAString_IncompatibleCharT& aString );
       NS_COM void AppendWithConversion( const incompatible_char_type* aData, PRInt32 aLength=-1 );
 
-      using nsTSubstring_CharT::AppendInt;
-
-        /**
-         * Append the given integer to this string 
-         * @param aInteger The integer to append
-         * @param aRadix   The radix to use; can be 8, 10 or 16.
-         * @deprecated Use AppendInt( PRInt32 aInteger ) or
-         *             AppendInt( PRUint32 aInteger, PRInt32 aRadix = 10 )
-         */
-      NS_COM void AppendInt( PRInt32 aInteger, PRInt32 aRadix ); //radix=8,10 or 16
-
-        /**
-         * Append the given 64-bit integer to this string.
-         * @param aInteger The integer to append
-         * @param aRadix   The radix to use; can be 8, 10 or 16.
-         * @deprecated Use AppendInt( PRInt64 aInteger ) or
-         *             AppendInt( PRUint64 aInteger, PRInt32 aRadix = 10 )
-         */
-      NS_COM void AppendInt( PRInt64 aInteger, PRInt32 aRadix );
-
-        /**
-         * Append the given float to this string 
-         */
-
-      NS_COM void AppendFloat( float aFloat );
-
-      NS_COM void AppendFloat( double aFloat );
-
 #endif // !MOZ_STRING_WITH_OBSOLETE_API
 
 
     protected:
 
       explicit
       nsTString_CharT( PRUint32 flags )
         : substring_type(flags) {}
--- a/xpcom/string/public/nsTSubstring.h
+++ b/xpcom/string/public/nsTSubstring.h
@@ -413,16 +413,27 @@ class nsTSubstring_CharT
       void AppendInt( PRUint64 aInteger )
                  { AppendPrintf( "%llu", aInteger ); }
       void AppendInt( PRUint64 aInteger, int aRadix )
         {
           const char *fmt = aRadix == 10 ? "%llu" : aRadix == 8 ? "%llo" : "%llx";
           AppendPrintf( fmt, aInteger );
         }
 
+      /**
+       * Append the given float to this string 
+       */
+      void AppendFloat( float aFloat )
+                      { DoAppendFloat(aFloat, 6); }
+      void AppendFloat( double aFloat )
+                      { DoAppendFloat(aFloat, 15); }
+  private:
+      NS_COM void NS_FASTCALL DoAppendFloat( double aFloat, int digits );
+  public:
+
     // AppendLiteral must ONLY be applied to an actual literal string.
     // Do not attempt to use it with a regular char* pointer, or with a char
     // array variable. Use AppendASCII for those.
 #ifdef NS_DISABLE_LITERAL_TEMPLATE
       void AppendLiteral( const char* str )
                   { AppendASCII(str); }
 #else
       template<int N>
--- a/xpcom/string/src/nsStringObsolete.cpp
+++ b/xpcom/string/src/nsStringObsolete.cpp
@@ -46,17 +46,16 @@
 #if MOZ_STRING_WITH_OBSOLETE_API
 
 #include "nsDependentString.h"
 #include "nsDependentSubstring.h"
 #include "nsReadableUtils.h"
 #include "nsCRT.h"
 #include "nsUTF8Utils.h"
 #include "prdtoa.h"
-#include "prprf.h"
 
 /* ***** BEGIN RICKG BLOCK *****
  *
  * NOTE: This section of code was extracted from rickg's bufferRoutines.h file.
  *       For the most part it remains unmodified.  We want to eliminate (or at
  *       least clean up) this code at some point.  If you find the formatting
  *       in this section somewhat inconsistent, don't blame me! ;-)
  */
@@ -795,109 +794,16 @@ RFindCharInSet( const CharT* data, PRUin
               return iter - data; // found it!  return index of the found char.
 
             setChar = *(++charInSet);
           }
       }
     return kNotFound;
   }
 
-/**
- * This is a copy of |PR_cnvtf| with a bug fixed.  (The second argument
- * of PR_dtoa is 2 rather than 1.)
- *
- * XXX(darin): if this is the right thing, then why wasn't it fixed in NSPR?!?
- */
-void 
-Modified_cnvtf(char *buf, int bufsz, int prcsn, double fval)
-{
-  PRIntn decpt, sign, numdigits;
-  char *num, *nump;
-  char *bufp = buf;
-  char *endnum;
-
-  /* If anything fails, we store an empty string in 'buf' */
-  num = (char*)malloc(bufsz);
-  if (num == NULL) {
-    buf[0] = '\0';
-    return;
-  }
-  if (PR_dtoa(fval, 2, prcsn, &decpt, &sign, &endnum, num, bufsz)
-      == PR_FAILURE) {
-    buf[0] = '\0';
-    goto done;
-  }
-  numdigits = endnum - num;
-  nump = num;
-
-  /*
-   * The NSPR code had a fancy way of checking that we weren't dealing
-   * with -0.0 or -NaN, but I'll just use < instead.
-   * XXX Should we check !isnan(fval) as well?  Is it portable?  We
-   * probably don't need to bother since NAN isn't portable.
-   */
-  if (sign && fval < 0.0f) {
-    *bufp++ = '-';
-  }
-
-  if (decpt == 9999) {
-    while ((*bufp++ = *nump++) != 0) {} /* nothing to execute */
-    goto done;
-  }
-
-  if (decpt > (prcsn+1) || decpt < -(prcsn-1) || decpt < -5) {
-    *bufp++ = *nump++;
-    if (numdigits != 1) {
-      *bufp++ = '.';
-    }
-
-    while (*nump != '\0') {
-      *bufp++ = *nump++;
-    }
-    *bufp++ = 'e';
-    PR_snprintf(bufp, bufsz - (bufp - buf), "%+d", decpt-1);
-  }
-  else if (decpt >= 0) {
-    if (decpt == 0) {
-      *bufp++ = '0';
-    }
-    else {
-      while (decpt--) {
-        if (*nump != '\0') {
-          *bufp++ = *nump++;
-        }
-        else {
-          *bufp++ = '0';
-        }
-      }
-    }
-    if (*nump != '\0') {
-      *bufp++ = '.';
-      while (*nump != '\0') {
-        *bufp++ = *nump++;
-      }
-    }
-    *bufp++ = '\0';
-  }
-  else if (decpt < 0) {
-    *bufp++ = '0';
-    *bufp++ = '.';
-    while (decpt++) {
-      *bufp++ = '0';
-    }
-
-    while (*nump != '\0') {
-      *bufp++ = *nump++;
-    }
-    *bufp++ = '\0';
-  }
-done:
-  free(num);
-}
-
   /**
    * this method changes the meaning of |offset| and |count|:
    * 
    * upon return,
    *   |offset| specifies start of search range
    *   |count| specifies length of search range
    */ 
 static void
@@ -1166,138 +1072,9 @@ nsCString::AppendWithConversion( const n
   }
 
 void
 nsString::AppendWithConversion( const nsACString& aData )
   {
     AppendASCIItoUTF16(aData, *this);
   }
 
-
-  /**
-   * nsTString::AppendInt
-   */
-
-void
-nsCString::AppendInt( PRInt32 aInteger, PRInt32 aRadix )
-  {
-    char buf[20];
-    const char* fmt;
-    switch (aRadix) {
-      case 8:
-        fmt = "%o";
-        break;
-      case 10:
-        fmt = "%d";
-        break;
-      default:
-        NS_ASSERTION(aRadix == 16, "Invalid radix!");
-        fmt = "%x";
-    }
-    PR_snprintf(buf, sizeof(buf), fmt, aInteger);
-    Append(buf);
-  }
-
-void
-nsString::AppendInt( PRInt32 aInteger, PRInt32 aRadix )
-  {
-    char buf[20];
-    const char* fmt;
-    switch (aRadix) {
-      case 8:
-        fmt = "%o";
-        break;
-      case 10:
-        fmt = "%d";
-        break;
-      default:
-        NS_ASSERTION(aRadix == 16, "Invalid radix!");
-        fmt = "%x";
-    }
-    PR_snprintf(buf, sizeof(buf), fmt, aInteger);
-    AppendASCIItoUTF16(buf, *this);
-  }
-
-void
-nsCString::AppendInt( PRInt64 aInteger, PRInt32 aRadix )
-  {
-    char buf[30];
-    const char* fmt;
-    switch (aRadix) {
-      case 8:
-        fmt = "%llo";
-        break;
-      case 10:
-        fmt = "%lld";
-        break;
-      default:
-        NS_ASSERTION(aRadix == 16, "Invalid radix!");
-        fmt = "%llx";
-    }
-    PR_snprintf(buf, sizeof(buf), fmt, aInteger);
-    Append(buf);
-  }
-
-void
-nsString::AppendInt( PRInt64 aInteger, PRInt32 aRadix )
-  {
-    char buf[30];
-    const char* fmt;
-    switch (aRadix) {
-      case 8:
-        fmt = "%llo";
-        break;
-      case 10:
-        fmt = "%lld";
-        break;
-      default:
-        NS_ASSERTION(aRadix == 16, "Invalid radix!");
-        fmt = "%llx";
-    }
-    PR_snprintf(buf, sizeof(buf), fmt, aInteger);
-    AppendASCIItoUTF16(buf, *this);
-  }
-
-  /**
-   * nsTString::AppendFloat
-   */
-
-void
-nsCString::AppendFloat( float aFloat )
-  {
-    char buf[40];
-    // Use Modified_cnvtf, which is locale-insensitive, instead of the
-    // locale-sensitive PR_snprintf or sprintf(3)
-    Modified_cnvtf(buf, sizeof(buf), 6, aFloat);
-    Append(buf);
-  }
-
-void
-nsString::AppendFloat( float aFloat )
-  {
-    char buf[40];
-    // Use Modified_cnvtf, which is locale-insensitive, instead of the
-    // locale-sensitive PR_snprintf or sprintf(3)
-    Modified_cnvtf(buf, sizeof(buf), 6, aFloat);
-    AppendWithConversion(buf);
-  }
-
-void
-nsCString::AppendFloat( double aFloat )
-  {
-    char buf[40];
-    // Use Modified_cnvtf, which is locale-insensitive, instead of the
-    // locale-sensitive PR_snprintf or sprintf(3)
-    Modified_cnvtf(buf, sizeof(buf), 15, aFloat);
-    Append(buf);
-  }
-
-void
-nsString::AppendFloat( double aFloat )
-  {
-    char buf[40];
-    // Use Modified_cnvtf, which is locale-insensitive, instead of the
-    // locale-sensitive PR_snprintf or sprintf(3)
-    Modified_cnvtf(buf, sizeof(buf), 15, aFloat);
-    AppendWithConversion(buf);
-  }
-
 #endif // !MOZ_STRING_WITH_OBSOLETE_API
--- a/xpcom/string/src/nsTSubstring.cpp
+++ b/xpcom/string/src/nsTSubstring.cpp
@@ -30,16 +30,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
+#include "prdtoa.h"
 
 #ifdef XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE
 nsTSubstring_CharT::nsTSubstring_CharT( char_type *data, size_type length,
                                         PRUint32 flags)
   : mData(data),
     mLength(length),
     mFlags(flags)
   {
@@ -737,8 +738,116 @@ void nsTSubstring_CharT::AppendPrintf( c
   {
     char buf[32];
     va_list ap;
     va_start(ap, format);
     PRUint32 len = PR_vsnprintf(buf, sizeof(buf), format, ap);
     AppendASCII(buf, len);
     va_end(ap);
   }
+
+
+/* hack to make sure we define Modified_cnvtf only once */
+#ifdef CharT_is_PRUnichar
+/**
+ * This is a copy of |PR_cnvtf| with a bug fixed.  (The second argument
+ * of PR_dtoa is 2 rather than 1.)
+ *
+ * XXX(darin): if this is the right thing, then why wasn't it fixed in NSPR?!?
+ */
+static void 
+Modified_cnvtf(char *buf, int bufsz, int prcsn, double fval)
+{
+  PRIntn decpt, sign, numdigits;
+  char *num, *nump;
+  char *bufp = buf;
+  char *endnum;
+
+  /* If anything fails, we store an empty string in 'buf' */
+  num = (char*)malloc(bufsz);
+  if (num == NULL) {
+    buf[0] = '\0';
+    return;
+  }
+  if (PR_dtoa(fval, 2, prcsn, &decpt, &sign, &endnum, num, bufsz)
+      == PR_FAILURE) {
+    buf[0] = '\0';
+    goto done;
+  }
+  numdigits = endnum - num;
+  nump = num;
+
+  /*
+   * The NSPR code had a fancy way of checking that we weren't dealing
+   * with -0.0 or -NaN, but I'll just use < instead.
+   * XXX Should we check !isnan(fval) as well?  Is it portable?  We
+   * probably don't need to bother since NAN isn't portable.
+   */
+  if (sign && fval < 0.0f) {
+    *bufp++ = '-';
+  }
+
+  if (decpt == 9999) {
+    while ((*bufp++ = *nump++) != 0) {} /* nothing to execute */
+    goto done;
+  }
+
+  if (decpt > (prcsn+1) || decpt < -(prcsn-1) || decpt < -5) {
+    *bufp++ = *nump++;
+    if (numdigits != 1) {
+      *bufp++ = '.';
+    }
+
+    while (*nump != '\0') {
+      *bufp++ = *nump++;
+    }
+    *bufp++ = 'e';
+    PR_snprintf(bufp, bufsz - (bufp - buf), "%+d", decpt-1);
+  }
+  else if (decpt >= 0) {
+    if (decpt == 0) {
+      *bufp++ = '0';
+    }
+    else {
+      while (decpt--) {
+        if (*nump != '\0') {
+          *bufp++ = *nump++;
+        }
+        else {
+          *bufp++ = '0';
+        }
+      }
+    }
+    if (*nump != '\0') {
+      *bufp++ = '.';
+      while (*nump != '\0') {
+        *bufp++ = *nump++;
+      }
+    }
+    *bufp++ = '\0';
+  }
+  else if (decpt < 0) {
+    *bufp++ = '0';
+    *bufp++ = '.';
+    while (decpt++) {
+      *bufp++ = '0';
+    }
+
+    while (*nump != '\0') {
+      *bufp++ = *nump++;
+    }
+    *bufp++ = '\0';
+  }
+done:
+  free(num);
+}
+#endif /* CharT_is_PRUnichar */
+
+void
+nsTSubstring_CharT::DoAppendFloat( double aFloat, int digits )
+{
+  char buf[40];
+  // Use Modified_cnvtf, which is locale-insensitive, instead of the
+  // locale-sensitive PR_snprintf or sprintf(3)
+  Modified_cnvtf(buf, sizeof(buf), digits, aFloat);
+  AppendASCII(buf);
+}
+