Merge last green (and non Ts-regressing) changeset from m-i to m-c
authorEd Morley <bmo@edmorley.co.uk>
Tue, 30 Aug 2011 12:09:51 +0100
changeset 77240 31b79d4e90f45f9e8922098b109748029663db8b
parent 77208 e6591ea9b27b4f3a652a11645aa63ccfae67603e (current diff)
parent 77239 2642c7b0dc60937f33bb032da5f06516ee9c6d50 (diff)
child 77241 04a58ba1ce1e2bfc3b681cc445c9b6ea26b6de0b
child 77256 fdfc74d7e8268802102a28977b00204b89421140
push id340
push userclegnitto@mozilla.com
push dateTue, 08 Nov 2011 22:56:33 +0000
treeherdermozilla-beta@f745dc151615 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge last green (and non Ts-regressing) changeset from m-i to m-c
dom/plugins/base/nsNPAPIPluginInstance.cpp
dom/plugins/base/nsNPAPIPluginInstance.h
dom/plugins/base/nsPluginInstanceOwner.cpp
dom/plugins/base/nsPluginInstanceOwner.h
js/src/jsarena.h
js/src/jsgc.cpp
js/src/methodjit/Compiler.cpp
js/src/shell/js.cpp
--- a/content/media/nsBuiltinDecoder.cpp
+++ b/content/media/nsBuiltinDecoder.cpp
@@ -775,18 +775,18 @@ void nsBuiltinDecoder::SeekingStoppedAtE
 
     // An additional seek was requested while the current seek was
     // in operation.
     if (mRequestedSeekTime >= 0.0) {
       ChangeState(PLAY_STATE_SEEKING);
       seekWasAborted = PR_TRUE;
     } else {
       UnpinForSeek();
-      fireEnded = mNextState != PLAY_STATE_PLAYING;
-      ChangeState(fireEnded ? PLAY_STATE_ENDED : mNextState);
+      fireEnded = PR_TRUE;
+      ChangeState(PLAY_STATE_ENDED);
     }
   }
 
   if (mElement) {
     UpdateReadyStateForData();
     if (!seekWasAborted) {
       mElement->SeekCompleted();
       if (fireEnded) {
--- a/content/media/test/test_fragment_play.html
+++ b/content/media/test/test_fragment_play.html
@@ -18,23 +18,23 @@ var manager = new MediaTestManager;
 // try playing the video. Tests for other fragment
 // formats are in test_fragment_noplay.html.
 var gFragmentParams = [
   { fragment: "", start: null, end: null },
   { fragment: "#t=,", start: null, end: null },
   { fragment: "#t=3,3", start: null, end: null },
   { fragment: "#t=7,3", start: null, end: null },
   { fragment: "#t=7,15", start: 7, end: null },
-  { fragment: "#t=15,20", start: 9.287981, end: null, todo: "See Bug 679262" },
+  { fragment: "#t=15,20", start: 9.287981, end: null },
   { fragment: "#t=5", start: 5, end: null },
   { fragment: "#t=5.5", start: 5.5, end: null },
   { fragment: "#t=5,", start: null, end: null },
   { fragment: "#t=,5", start: 0, end: 5 },
-  { fragment: "#t=2.5,5.5", start: 2.5, end: 5.5 },
-  { fragment: "#t=1,2.5", start: 1, end: 2.5 },
+  { fragment: "#t=2.5,5.5", start: 2.5, end: 5.5, todo: "See Bug 682141" },
+  { fragment: "#t=1,2.5", start: 1, end: 2.5, todo: "See Bug 682141" },
   { fragment: "#t=,15", start: 0, end: null }
 ];
 
 function createTestArray() {
   var tests = [];
   var tmpVid = document.createElement("video");
 
   for (var testNum=0; testNum<gFragmentTests.length; testNum++) {
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -1485,16 +1485,17 @@ void nsSVGElement::LengthAttributesInfo:
 void
 nsSVGElement::SetLength(nsIAtom* aName, const nsSVGLength2 &aLength)
 {
   LengthAttributesInfo lengthInfo = GetLengthInfo();
 
   for (PRUint32 i = 0; i < lengthInfo.mLengthCount; i++) {
     if (aName == *lengthInfo.mLengthInfo[i].mName) {
       lengthInfo.mLengths[i] = aLength;
+      DidChangeLength(i, PR_TRUE);
       return;
     }
   }
   NS_ABORT_IF_FALSE(false, "no length found to set");
 }
 
 void
 nsSVGElement::DidChangeLength(PRUint8 aAttrEnum, PRBool aDoSetAttr)
--- a/content/xml/document/src/nsXMLContentSink.cpp
+++ b/content/xml/document/src/nsXMLContentSink.cpp
@@ -642,24 +642,38 @@ nsXMLContentSink::CloseElement(nsIConten
                                   &willNotify,
                                   &isAlternate);
       if (NS_SUCCEEDED(rv) && willNotify && !isAlternate && !mFragmentMode) {
         ++mPendingSheetCount;
         mScriptLoader->AddExecuteBlocker();
       }
     }
     // Look for <link rel="dns-prefetch" href="hostname">
+    // and look for <link rel="next" href="hostname"> like in HTML sink
     if (nodeInfo->Equals(nsGkAtoms::link, kNameSpaceID_XHTML)) {
       nsAutoString relVal;
       aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::rel, relVal);
-      if (relVal.EqualsLiteral("dns-prefetch")) {
-        nsAutoString hrefVal;
-        aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
-        if (!hrefVal.IsEmpty()) {
-          PrefetchDNS(hrefVal);
+      if (!relVal.IsEmpty()) {
+        // XXX seems overkill to generate this string array
+        nsAutoTArray<nsString, 4> linkTypes;
+        nsStyleLinkElement::ParseLinkTypes(relVal, linkTypes);
+        PRBool hasPrefetch = linkTypes.Contains(NS_LITERAL_STRING("prefetch"));
+        if (hasPrefetch || linkTypes.Contains(NS_LITERAL_STRING("next"))) {
+          nsAutoString hrefVal;
+          aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
+          if (!hrefVal.IsEmpty()) {
+            PrefetchHref(hrefVal, aContent, hasPrefetch);
+          }
+        }
+        if (linkTypes.Contains(NS_LITERAL_STRING("dns-prefetch"))) {
+          nsAutoString hrefVal;
+          aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
+          if (!hrefVal.IsEmpty()) {
+            PrefetchDNS(hrefVal);
+          }
         }
       }
     }
   }
 
   return rv;
 }  
 
--- a/dom/interfaces/html/nsIDOMHTMLSourceElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLSourceElement.idl
@@ -34,17 +34,17 @@
  * 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 "nsIDOMHTMLElement.idl"
 
 /**
- * The nsIDOMHTMLVideoElement interface is the interface to a HTML
+ * The nsIDOMHTMLSourceElement interface is the interface to a HTML
  * <source> element.
  *
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/#source
  *
  * @status UNDER_DEVELOPMENT
  */
 
--- a/dom/plugins/base/PluginPRLibrary.cpp
+++ b/dom/plugins/base/PluginPRLibrary.cpp
@@ -241,16 +241,27 @@ PluginPRLibrary::NPP_GetSitesWithData(In
 nsresult
 PluginPRLibrary::AsyncSetWindow(NPP instance, NPWindow* window)
 {
   nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
   NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
+#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
+nsresult
+PluginPRLibrary::HandleGUIEvent(NPP instance, const nsGUIEvent& anEvent,
+                                bool* handled)
+{
+  nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
+  NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+#endif
+
 nsresult
 PluginPRLibrary::GetImage(NPP instance, ImageContainer* aContainer, Image** aImage)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 #if defined(XP_MACOSX)
 nsresult
--- a/dom/plugins/base/PluginPRLibrary.h
+++ b/dom/plugins/base/PluginPRLibrary.h
@@ -149,16 +149,20 @@ public:
     NS_OVERRIDE
     virtual nsresult SetBackgroundUnknown(NPP instance);
     NS_OVERRIDE
     virtual nsresult BeginUpdateBackground(NPP instance,
                                            const nsIntRect&, gfxContext** aCtx);
     NS_OVERRIDE
     virtual nsresult EndUpdateBackground(NPP instance,
                                          gfxContext* aCtx, const nsIntRect&);
+#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
+    virtual nsresult HandleGUIEvent(NPP instance,
+                                    const nsGUIEvent& anEvent, bool* handled);
+#endif
 
 private:
     NP_InitializeFunc mNP_Initialize;
     NP_ShutdownFunc mNP_Shutdown;
     NP_GetMIMEDescriptionFunc mNP_GetMIMEDescription;
 #if defined(XP_UNIX) && !defined(XP_MACOSX)
     NP_GetValueFunc mNP_GetValue;
 #endif
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp
+++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -837,16 +837,33 @@ nsNPAPIPluginInstance::AsyncSetWindow(NP
 
   AutoPluginLibraryCall library(this);
   if (!library)
     return NS_ERROR_FAILURE;
 
   return library->AsyncSetWindow(&mNPP, window);
 }
 
+#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
+nsresult
+nsNPAPIPluginInstance::HandleGUIEvent(const nsGUIEvent& anEvent, bool* handled)
+{
+  if (RUNNING != mRunning) {
+    *handled = false;
+    return NS_OK;
+  }
+
+  AutoPluginLibraryCall library(this);
+  if (!library)
+    return NS_ERROR_FAILURE;
+
+  return library->HandleGUIEvent(&mNPP, anEvent, handled);
+}
+#endif
+
 nsresult
 nsNPAPIPluginInstance::GetImage(ImageContainer* aContainer, Image** aImage)
 {
   *aImage = nsnull;
 
   if (RUNNING != mRunning)
     return NS_OK;
 
--- a/dom/plugins/base/nsNPAPIPluginInstance.h
+++ b/dom/plugins/base/nsNPAPIPluginInstance.h
@@ -109,16 +109,19 @@ public:
   nsresult InvalidateRegion(NPRegion invalidRegion);
   nsresult ForceRedraw();
   nsresult GetMIMEType(const char* *result);
   nsresult GetJSContext(JSContext* *outContext);
   nsresult GetOwner(nsIPluginInstanceOwner **aOwner);
   nsresult SetOwner(nsIPluginInstanceOwner *aOwner);
   nsresult ShowStatus(const char* message);
   nsresult InvalidateOwner();
+#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
+  nsresult HandleGUIEvent(const nsGUIEvent& anEvent, bool* handled);
+#endif
 
   nsNPAPIPlugin* GetPlugin();
 
   nsresult GetNPP(NPP * aNPP);
 
   void SetURI(nsIURI* uri);
   nsIURI* GetURI();
 
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -1683,16 +1683,39 @@ nsresult nsPluginInstanceOwner::Dispatch
     }
     else NS_ASSERTION(PR_FALSE, "nsPluginInstanceOwner::DispatchFocusToPlugin failed, focusEvent null");   
   }
   else NS_ASSERTION(PR_FALSE, "nsPluginInstanceOwner::DispatchFocusToPlugin failed, privateEvent null");   
   
   return NS_OK;
 }    
 
+#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
+nsresult nsPluginInstanceOwner::Text(nsIDOMEvent* aTextEvent)
+{
+  if (mInstance) {
+    nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(aTextEvent));
+    if (privateEvent) {
+      nsEvent *event = privateEvent->GetInternalNSEvent();
+      if (event && event->eventStructType == NS_TEXT_EVENT) {
+        nsEventStatus rv = ProcessEvent(*static_cast<nsGUIEvent*>(event));
+        if (nsEventStatus_eConsumeNoDefault == rv) {
+          aTextEvent->PreventDefault();
+          aTextEvent->StopPropagation();
+        }
+      }
+      else NS_ASSERTION(PR_FALSE, "nsPluginInstanceOwner::DispatchTextToPlugin failed, textEvent null");
+    }
+    else NS_ASSERTION(PR_FALSE, "nsPluginInstanceOwner::DispatchTextToPlugin failed, privateEvent null");
+  }
+
+  return NS_OK;
+}
+#endif
+
 nsresult nsPluginInstanceOwner::KeyPress(nsIDOMEvent* aKeyEvent)
 {
 #ifdef XP_MACOSX
 #ifndef NP_NO_CARBON
   if (GetEventModel() == NPEventModelCarbon) {
     // KeyPress events are really synthesized keyDown events.
     // Here we check the native message of the event so that
     // we won't send the plugin two keyDown events.
@@ -1866,16 +1889,21 @@ nsPluginInstanceOwner::HandleEvent(nsIDO
   }
   if (eventType.EqualsLiteral("keydown") ||
       eventType.EqualsLiteral("keyup")) {
     return DispatchKeyToPlugin(aEvent);
   }
   if (eventType.EqualsLiteral("keypress")) {
     return KeyPress(aEvent);
   }
+#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
+  if (eventType.EqualsLiteral("text")) {
+    return Text(aEvent);
+  }
+#endif
 
   nsCOMPtr<nsIDOMDragEvent> dragEvent(do_QueryInterface(aEvent));
   if (dragEvent && mInstance) {
     nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(aEvent));
     if (privateEvent) {
       nsEvent* ievent = privateEvent->GetInternalNSEvent();
       if ((ievent && NS_IS_TRUSTED_EVENT(ievent)) &&
            ievent->message != NS_DRAGDROP_ENTER && ievent->message != NS_DRAGDROP_OVER) {
@@ -2363,20 +2391,39 @@ nsEventStatus nsPluginInstanceOwner::Pro
           event.same_screen = False;
         }
       else
         {
           // If we need to send synthesized key events, then
           // DOMKeyCodeToGdkKeyCode(keyEvent.keyCode) and
           // gdk_keymap_get_entries_for_keyval will be useful, but the
           // mappings will not be unique.
+#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
+          bool handled;
+          if (NS_SUCCEEDED(mInstance->HandleGUIEvent(anEvent, &handled)) &&
+              handled) {
+            rv = nsEventStatus_eConsumeNoDefault;
+          }
+#else
           NS_WARNING("Synthesized key event not sent to plugin");
+#endif
         }
       break;
 
+#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
+   case NS_TEXT_EVENT:
+        {
+          bool handled;
+          if (NS_SUCCEEDED(mInstance->HandleGUIEvent(anEvent, &handled)) &&
+              handled) {
+            rv = nsEventStatus_eConsumeNoDefault;
+          }
+        }
+      break;
+#endif
     default: 
       switch (anEvent.message)
         {
         case NS_FOCUS_CONTENT:
         case NS_BLUR_CONTENT:
           {
             XFocusChangeEvent &event = pluginEvent.xfocus;
             event.type =
@@ -2447,16 +2494,19 @@ nsPluginInstanceOwner::Destroy()
   mContent->RemoveEventListener(NS_LITERAL_STRING("drag"), this, PR_TRUE);
   mContent->RemoveEventListener(NS_LITERAL_STRING("dragenter"), this, PR_TRUE);
   mContent->RemoveEventListener(NS_LITERAL_STRING("dragover"), this, PR_TRUE);
   mContent->RemoveEventListener(NS_LITERAL_STRING("dragleave"), this, PR_TRUE);
   mContent->RemoveEventListener(NS_LITERAL_STRING("dragexit"), this, PR_TRUE);
   mContent->RemoveEventListener(NS_LITERAL_STRING("dragstart"), this, PR_TRUE);
   mContent->RemoveEventListener(NS_LITERAL_STRING("draggesture"), this, PR_TRUE);
   mContent->RemoveEventListener(NS_LITERAL_STRING("dragend"), this, PR_TRUE);
+#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
+  mContent->RemoveEventListener(NS_LITERAL_STRING("text"), this, PR_TRUE);
+#endif
 
   if (mWidget) {
     nsCOMPtr<nsIPluginWidget> pluginWidget = do_QueryInterface(mWidget);
     if (pluginWidget)
       pluginWidget->SetPluginInstanceOwner(nsnull);
 
     if (mDestroyWidget)
       mWidget->Destroy();
@@ -2907,16 +2957,19 @@ nsresult nsPluginInstanceOwner::Init(nsP
   mContent->AddEventListener(NS_LITERAL_STRING("drag"), this, PR_TRUE);
   mContent->AddEventListener(NS_LITERAL_STRING("dragenter"), this, PR_TRUE);
   mContent->AddEventListener(NS_LITERAL_STRING("dragover"), this, PR_TRUE);
   mContent->AddEventListener(NS_LITERAL_STRING("dragleave"), this, PR_TRUE);
   mContent->AddEventListener(NS_LITERAL_STRING("dragexit"), this, PR_TRUE);
   mContent->AddEventListener(NS_LITERAL_STRING("dragstart"), this, PR_TRUE);
   mContent->AddEventListener(NS_LITERAL_STRING("draggesture"), this, PR_TRUE);
   mContent->AddEventListener(NS_LITERAL_STRING("dragend"), this, PR_TRUE);
+#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
+  mContent->AddEventListener(NS_LITERAL_STRING("text"), this, PR_TRUE);
+#endif
   
   // Register scroll position listeners
   // We need to register a scroll position listener on every scrollable
   // frame up to the top
   for (nsIFrame* f = mObjectFrame; f; f = nsLayoutUtils::GetCrossDocParentFrame(f)) {
     nsIScrollableFrame* sf = do_QueryFrame(f);
     if (sf) {
       sf->AddScrollPositionListener(this);
--- a/dom/plugins/base/nsPluginInstanceOwner.h
+++ b/dom/plugins/base/nsPluginInstanceOwner.h
@@ -125,16 +125,19 @@ public:
   //nsIPluginTagInfo interface
   NS_DECL_NSIPLUGINTAGINFO
   
   // nsIDOMEventListener interfaces 
   NS_DECL_NSIDOMEVENTLISTENER
   
   nsresult MouseDown(nsIDOMEvent* aKeyEvent);
   nsresult KeyPress(nsIDOMEvent* aKeyEvent);
+#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
+  nsresult Text(nsIDOMEvent* aTextEvent);
+#endif
 
   nsresult Destroy();  
   
   void PrepareToStop(PRBool aDelayedStop);
   
 #ifdef XP_WIN
   void Paint(const RECT& aDirty, HDC aDC);
 #elif defined(XP_MACOSX)
--- a/dom/plugins/ipc/PPluginInstance.ipdl
+++ b/dom/plugins/ipc/PPluginInstance.ipdl
@@ -41,29 +41,32 @@ include protocol PPluginBackgroundDestro
 include protocol PPluginModule;
 include protocol PPluginScriptableObject;
 include protocol PBrowserStream;
 include protocol PPluginStream;
 include protocol PStreamNotify;
 include protocol PPluginSurface;
 
 include "mozilla/plugins/PluginMessageUtils.h";
+include "IPC/nsGUIEventIPC.h";
 
 using NPError;
 using NPRemoteWindow;
 using NPRemoteEvent;
 using NPRect;
 using NPNURLVariable;
 using NPCoordinateSpace;
 using mozilla::plugins::NativeWindowHandle;
 using mozilla::gfxSurfaceType;
 using gfxIntSize;
 using mozilla::null_t;
 using mozilla::plugins::WindowsSharedMemoryHandle;
 using nsIntRect;
+using nsTextEvent;
+using nsKeyEvent;
 
 namespace mozilla {
 namespace plugins {
 
 struct SurfaceDescriptorX11 {
   int XID;
   int xrenderPictID;
   gfxIntSize size;
@@ -142,16 +145,21 @@ child:
 
   // There is now an opaque background behind this instance (or the
   // background was updated).  The changed area is |rect|.  The
   // browser owns the background surface, and it's read-only from
   // within the plugin process.  |background| is either null_t to
   // refer to the existing background or a fresh descriptor.
   async UpdateBackground(SurfaceDescriptor background, nsIntRect rect);
 
+  rpc HandleTextEvent(nsTextEvent event)
+    returns (bool handled);
+  rpc HandleKeyEvent(nsKeyEvent event)
+    returns (bool handled);
+
   rpc NPP_Destroy()
     returns (NPError rv);
 
 parent:
   rpc NPN_GetValue_NPNVjavascriptEnabledBool()
     returns (bool value, NPError result);
   rpc NPN_GetValue_NPNVisOfflineBool()
     returns (bool value, NPError result);
--- a/dom/plugins/ipc/PluginInstanceChild.cpp
+++ b/dom/plugins/ipc/PluginInstanceChild.cpp
@@ -32,16 +32,24 @@
  * 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 ***** */
 
+#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
+#include <QEvent>
+#include <QKeyEvent>
+#include <QApplication>
+#include <QInputMethodEvent>
+#include "nsQtKeyUtils.h"
+#endif
+
 #include "PluginBackgroundDestroyer.h"
 #include "PluginInstanceChild.h"
 #include "PluginModuleChild.h"
 #include "BrowserStreamChild.h"
 #include "PluginStreamChild.h"
 #include "StreamNotifyChild.h"
 #include "PluginProcessChild.h"
 #include "gfxASurface.h"
@@ -69,16 +77,18 @@ using namespace mozilla::plugins;
 
 #include <gtk/gtk.h>
 #include <gdk/gdkx.h>
 #include <gdk/gdk.h>
 #include "gtk2xtbin.h"
 
 #elif defined(MOZ_WIDGET_QT)
 #include <QX11Info>
+#undef KeyPress
+#undef KeyRelease
 #elif defined(OS_WIN)
 #ifndef WM_MOUSEHWHEEL
 #define WM_MOUSEHWHEEL     0x020E
 #endif
 
 #include "nsWindowsDllInterceptor.h"
 
 typedef BOOL (WINAPI *User32TrackPopupMenu)(HMENU hMenu,
@@ -2312,16 +2322,67 @@ PluginInstanceChild::RecvAsyncSetWindow(
         MessageLoop::current()->PostTask(FROM_HERE, mCurrentAsyncSetWindowTask);
     } else {
         DoAsyncSetWindow(aSurfaceType, aWindow, false);
     }
 
     return true;
 }
 
+bool
+PluginInstanceChild::AnswerHandleKeyEvent(const nsKeyEvent& aKeyEvent,
+                                          bool* handled)
+{
+    AssertPluginThread();
+#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
+    Qt::KeyboardModifiers modifier;
+    if (aKeyEvent.isShift)
+        modifier |= Qt::ShiftModifier;
+    if (aKeyEvent.isControl)
+        modifier |= Qt::ControlModifier;
+    if (aKeyEvent.isAlt)
+        modifier |= Qt::AltModifier;
+    if (aKeyEvent.isMeta)
+        modifier |= Qt::MetaModifier;
+
+    QEvent::Type type;
+    if (aKeyEvent.message == NS_KEY_DOWN) {
+        type = QEvent::KeyPress;
+    } else if (aKeyEvent.message == NS_KEY_UP) {
+        type = QEvent::KeyRelease;
+    } else {
+        *handled = false;
+        return true;
+    }
+    QKeyEvent keyEv(type, DOMKeyCodeToQtKeyCode(aKeyEvent.keyCode), modifier);
+    *handled = QApplication::sendEvent(qApp, &keyEv);
+#else
+    NS_ERROR("Not implemented");
+#endif
+
+    return true;
+}
+
+bool
+PluginInstanceChild::AnswerHandleTextEvent(const nsTextEvent& aEvent,
+                                           bool* handled)
+{
+    AssertPluginThread();
+#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
+    QInputMethodEvent event;
+    event.setCommitString(QString((const QChar*)aEvent.theText.get(),
+                          aEvent.theText.Length()));
+    *handled = QApplication::sendEvent(qApp, &event);
+#else
+    NS_ERROR("Not implemented");
+#endif
+
+    return true;
+}
+
 void
 PluginInstanceChild::DoAsyncSetWindow(const gfxSurfaceType& aSurfaceType,
                                       const NPRemoteWindow& aWindow,
                                       bool aIsAsync)
 {
     PLUGIN_LOG_DEBUG(
         ("[InstanceChild][%p] AsyncSetWindow to <x=%d,y=%d, w=%d,h=%d>",
          this, aWindow.x, aWindow.y, aWindow.width, aWindow.height));
--- a/dom/plugins/ipc/PluginInstanceChild.h
+++ b/dom/plugins/ipc/PluginInstanceChild.h
@@ -115,16 +115,21 @@ protected:
     RecvAsyncSetWindow(const gfxSurfaceType& aSurfaceType,
                        const NPRemoteWindow& aWindow);
 
     virtual void
     DoAsyncSetWindow(const gfxSurfaceType& aSurfaceType,
                      const NPRemoteWindow& aWindow,
                      bool aIsAsync);
 
+    virtual bool
+    AnswerHandleKeyEvent(const nsKeyEvent& aEvent, bool* handled);
+    virtual bool
+    AnswerHandleTextEvent(const nsTextEvent& aEvent, bool* handled);
+
     virtual PPluginSurfaceChild* AllocPPluginSurface(const WindowsSharedMemoryHandle&,
                                                      const gfxIntSize&, const bool&) {
         return new PPluginSurfaceChild();
     }
 
     virtual bool DeallocPPluginSurface(PPluginSurfaceChild* s) {
         delete s;
         return true;
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -613,16 +613,41 @@ PluginInstanceParent::AsyncSetWindow(NPW
     window.type = aWindow->type;
     if (!SendAsyncSetWindow(gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType(),
                             window))
         return NS_ERROR_FAILURE;
 
     return NS_OK;
 }
 
+#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
+nsresult
+PluginInstanceParent::HandleGUIEvent(const nsGUIEvent& anEvent, bool* handled)
+{
+    switch (anEvent.eventStructType) {
+    case NS_KEY_EVENT:
+        if (!CallHandleKeyEvent(static_cast<const nsKeyEvent&>(anEvent),
+                                handled)) {
+            return NS_ERROR_FAILURE;
+        }
+        break;
+    case NS_TEXT_EVENT:
+        if (!CallHandleTextEvent(static_cast<const nsTextEvent&>(anEvent),
+                                 handled)) {
+            return NS_ERROR_FAILURE;
+        }
+        break;
+    default:
+        NS_ERROR("Not implemented for this event type");
+        return NS_ERROR_FAILURE;
+    }
+    return NS_OK;
+}
+#endif
+
 nsresult
 PluginInstanceParent::GetImage(ImageContainer* aContainer, Image** aImage)
 {
 #ifdef XP_MACOSX
     nsIOSurface* ioSurface = NULL;
   
     if (mFrontIOSurface) {
       ioSurface = mFrontIOSurface;
--- a/dom/plugins/ipc/PluginInstanceParent.h
+++ b/dom/plugins/ipc/PluginInstanceParent.h
@@ -52,16 +52,17 @@
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "nsRect.h"
 #include "gfxASurface.h"
 #include "ImageLayers.h"
 #ifdef MOZ_X11
 class gfxXlibSurface;
 #endif
+#include "nsGUIEvent.h"
 
 namespace mozilla {
 namespace plugins {
 
 class PBrowserStreamParent;
 class PluginModuleParent;
 
 class PluginInstanceParent : public PPluginInstanceParent
@@ -285,16 +286,19 @@ public:
 #ifdef XP_MACOSX
     nsresult IsRemoteDrawingCoreAnimation(PRBool *aDrawing);
 #endif
     nsresult SetBackgroundUnknown();
     nsresult BeginUpdateBackground(const nsIntRect& aRect,
                                    gfxContext** aCtx);
     nsresult EndUpdateBackground(gfxContext* aCtx,
                                  const nsIntRect& aRect);
+#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
+    nsresult HandleGUIEvent(const nsGUIEvent& anEvent, bool* handled);
+#endif
 
 private:
     // Create an appropriate platform surface for a background of size
     // |aSize|.  Return true if successful.
     bool CreateBackground(const nsIntSize& aSize);
     void DestroyBackground();
     SurfaceDescriptor BackgroundDescriptor() /*const*/;
 
--- a/dom/plugins/ipc/PluginLibrary.h
+++ b/dom/plugins/ipc/PluginLibrary.h
@@ -47,16 +47,17 @@
 #include "nsPluginError.h"
 
 class gfxASurface;
 class gfxContext;
 class nsCString;
 struct nsIntRect;
 struct nsIntSize;
 class nsNPAPIPlugin;
+class nsGUIEvent;
 
 namespace mozilla {
 namespace layers {
 class Image;
 class ImageContainer;
 }
 }
 
@@ -111,14 +112,17 @@ public:
    * PluginInstanceParent.  They approximately follow the ReadbackSink
    * API.
    */
   virtual nsresult SetBackgroundUnknown(NPP instance) = 0;
   virtual nsresult BeginUpdateBackground(NPP instance,
                                          const nsIntRect&, gfxContext**) = 0;
   virtual nsresult EndUpdateBackground(NPP instance,
                                        gfxContext*, const nsIntRect&) = 0;
+#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
+  virtual nsresult HandleGUIEvent(NPP instance, const nsGUIEvent&, bool*) = 0;
+#endif
 };
 
 
 } // namespace mozilla
 
 #endif  // ifndef mozilla_PluginLibrary_h
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -698,16 +698,30 @@ PluginModuleParent::AsyncSetWindow(NPP i
 {
     PluginInstanceParent* i = InstCast(instance);
     if (!i)
         return NS_ERROR_FAILURE;
 
     return i->AsyncSetWindow(window);
 }
 
+#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
+nsresult
+PluginModuleParent::HandleGUIEvent(NPP instance,
+                                   const nsGUIEvent& anEvent,
+                                   bool* handled)
+{
+    PluginInstanceParent* i = InstCast(instance);
+    if (!i)
+        return NS_ERROR_FAILURE;
+
+    return i->HandleGUIEvent(anEvent, handled);
+}
+#endif
+
 nsresult
 PluginModuleParent::GetImage(NPP instance,
                              mozilla::layers::ImageContainer* aContainer,
                              mozilla::layers::Image** aImage)
 {
     PluginInstanceParent* i = InstCast(instance);
     return !i ? NS_ERROR_FAILURE : i->GetImage(aContainer, aImage);
 }
--- a/dom/plugins/ipc/PluginModuleParent.h
+++ b/dom/plugins/ipc/PluginModuleParent.h
@@ -291,16 +291,20 @@ private:
                              NPError* error);
     virtual nsresult NPP_ClearSiteData(const char* site, uint64_t flags,
                                        uint64_t maxAge);
     virtual nsresult NPP_GetSitesWithData(InfallibleTArray<nsCString>& result);
 
 #if defined(XP_MACOSX)
     virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, PRBool *aDrawing);
 #endif
+#if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
+    virtual nsresult HandleGUIEvent(NPP instance, const nsGUIEvent& anEvent,
+                                    bool* handled);
+#endif
 
 private:
     void WritePluginExtraDataForMinidump(const nsAString& id);
     void WriteExtraDataForHang();
     void CleanupFromTimeout();
     static int TimeoutChanged(const char* aPref, void* aModule);
     void NotifyPluginCrashed();
 
--- a/gfx/layers/basic/BasicLayers.cpp
+++ b/gfx/layers/basic/BasicLayers.cpp
@@ -708,22 +708,23 @@ BasicThebesLayer::PaintThebes(gfxContext
 
       aContext->Restore();
     }
     return;
   }
 
   {
     PRUint32 flags = 0;
+#ifndef MOZ_GFX_OPTIMIZE_MOBILE
     gfxMatrix transform;
     if (!GetEffectiveTransform().CanDraw2D(&transform) ||
-        transform.HasNonIntegerTranslation() ||
-        MustRetainContent() /*<=> has shadow layer*/) {
+        transform.HasNonIntegerTranslation()) {
       flags |= ThebesLayerBuffer::PAINT_WILL_RESAMPLE;
     }
+#endif
     Buffer::PaintState state =
       mBuffer.BeginPaint(this, contentType, flags);
     mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate);
 
     if (state.mContext) {
       // The area that became invalid and is visible needs to be repainted
       // (this could be the whole visible area if our buffer switched
       // from RGB to RGBA, because we might need to repaint with
--- a/gfx/layers/ipc/ShadowLayersParent.cpp
+++ b/gfx/layers/ipc/ShadowLayersParent.cpp
@@ -461,23 +461,16 @@ ShadowLayersParent::RecvUpdate(const Inf
   // other's buffer contents.
   ShadowLayerManager::PlatformSyncBeforeReplyUpdate();
 
   Frame()->ShadowLayersUpdated();
 
   return true;
 }
 
-bool
-ShadowLayersParent::RecvGetParentType(LayersBackend* aBackend)
-{
-  *aBackend = layer_manager()->GetBackendType();
-  return true;
-}
-
 PLayerParent*
 ShadowLayersParent::AllocPLayer()
 {
   return new ShadowLayerParent();
 }
 
 bool
 ShadowLayersParent::DeallocPLayer(PLayerParent* actor)
--- a/gfx/layers/ipc/ShadowLayersParent.h
+++ b/gfx/layers/ipc/ShadowLayersParent.h
@@ -69,18 +69,16 @@ public:
   ShadowLayerManager* layer_manager() const { return mLayerManager; }
 
   ContainerLayer* GetRoot() const { return mRoot; }
 
 protected:
   NS_OVERRIDE virtual bool RecvUpdate(const EditArray& cset,
                                       EditReplyArray* reply);
 
-  NS_OVERRIDE virtual bool RecvGetParentType(LayersBackend* aBackend);
-
   NS_OVERRIDE virtual PLayerParent* AllocPLayer();
   NS_OVERRIDE virtual bool DeallocPLayer(PLayerParent* actor);
 
 private:
   RenderFrameParent* Frame();
 
   nsRefPtr<ShadowLayerManager> mLayerManager;
   // Hold the root because it might be grafted under various
--- a/gfx/layers/opengl/ThebesLayerOGL.cpp
+++ b/gfx/layers/opengl/ThebesLayerOGL.cpp
@@ -744,25 +744,27 @@ ThebesLayerOGL::RenderLayer(int aPreviou
 
   mOGLManager->MakeCurrent();
   gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
 
   TextureImage::ContentType contentType =
     CanUseOpaqueSurface() ? gfxASurface::CONTENT_COLOR :
                             gfxASurface::CONTENT_COLOR_ALPHA;
 
+  PRUint32 flags = 0;
+#ifndef MOZ_GFX_OPTIMIZE_MOBILE
   gfxMatrix transform2d;
-  PRUint32 flags = 0;
   if (GetEffectiveTransform().Is2D(&transform2d)) {
     if (transform2d.HasNonIntegerTranslation()) {
       flags |= ThebesLayerBufferOGL::PAINT_WILL_RESAMPLE;
     }
   } else {
     flags |= ThebesLayerBufferOGL::PAINT_WILL_RESAMPLE;
   }
+#endif
 
   Buffer::PaintState state = mBuffer->BeginPaint(contentType, flags);
   mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate);
 
   if (state.mContext) {
     state.mRegionToInvalidate.And(state.mRegionToInvalidate, mVisibleRegion);
 
     LayerManager::DrawThebesLayerCallback callback =
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -2479,16 +2479,27 @@ gfxFontGroup::InitTextRun(gfxContext *aC
                     NS_ConvertUTF16toUTF8(aString + runStart, runLen).get()));
         }
 #endif
 
         InitScriptRun(aContext, aTextRun, aString, aLength,
                       runStart, runLimit, runScript);
     }
 
+    // It's possible for CoreText to omit glyph runs if it decides they contain
+    // only invisibles (e.g., U+FEFF, see reftest 474417-1). In this case, we
+    // need to eliminate them from the glyph run array to avoid drawing "partial
+    // ligatures" with the wrong font.
+    // We don't do this during InitScriptRun (or gfxFont::InitTextRun) because
+    // it will iterate back over all glyphruns in the textrun, which leads to
+    // pathologically-bad perf in the case where a textrun contains many script
+    // changes (see bug 680402) - we'd end up re-sanitizing all the earlier runs
+    // every time a new script subrun is processed.
+    aTextRun->SanitizeGlyphRuns();
+
     aTextRun->SortGlyphRuns();
 }
 
 void
 gfxFontGroup::InitScriptRun(gfxContext *aContext,
                             gfxTextRun *aTextRun,
                             const PRUnichar *aString,
                             PRUint32 aTotalLength,
@@ -2560,23 +2571,16 @@ gfxFontGroup::InitScriptRun(gfxContext *
                         aTextRun->SetMissingGlyph(index, ch);
                     }
                 }
             }
         }
 
         runStart += matchedLength;
     }
-
-    // It's possible for CoreText to omit glyph runs if it decides they contain
-    // only invisibles (e.g., U+FEFF, see reftest 474417-1). In this case, we
-    // need to eliminate them from the glyph run array to avoid drawing "partial
-    // ligatures" with the wrong font.
-    aTextRun->SanitizeGlyphRuns();
-
 }
 
 
 already_AddRefed<gfxFont>
 gfxFontGroup::FindFontForChar(PRUint32 aCh, PRUint32 aPrevCh,
                               PRInt32 aRunScript, gfxFont *aPrevMatchedFont,
                               PRUint8 *aMatchType)
 {
@@ -4040,16 +4044,19 @@ gfxTextRun::SortGlyphRuns()
             NS_ASSERTION(i == 0 ||
                          runs[i].mCharacterOffset !=
                          runs[i - 1].mCharacterOffset,
                          "Two fonts for the same run, glyph indices may not match the font");
         }
     }
 }
 
+// Note that SanitizeGlyphRuns scans all glyph runs in the textrun;
+// therefore we only call it once, at the end of textrun construction,
+// NOT incrementally as each glyph run is added (bug 680402).
 void
 gfxTextRun::SanitizeGlyphRuns()
 {
     if (mGlyphRuns.Length() <= 1)
         return;
 
     // If any glyph run starts with ligature-continuation characters, we need to advance it
     // to the first "real" character to avoid drawing partial ligature glyphs from wrong font
--- a/gfx/thebes/gfxFontconfigUtils.cpp
+++ b/gfx/thebes/gfxFontconfigUtils.cpp
@@ -259,18 +259,18 @@ gfxFontconfigUtils::NewPattern(const nsT
             // aliases (so that the preferred font depends on language).
             // However, this would give them lower priority than subsequent
             // non-generic families in the list.  To ensure that subsequent
             // families do not have a higher priority, they are given weak
             // bindings.
             for (PRUint32 g = 0;
                  g < NS_ARRAY_LENGTH(sFontconfigGenerics);
                  ++g) {
-                if (FcStrCmpIgnoreCase(ToFcChar8(sFontconfigGenerics[g]),
-                                       ToFcChar8(family.get()))) {
+                if (0 == FcStrCmpIgnoreCase(ToFcChar8(sFontconfigGenerics[g]),
+                                            ToFcChar8(family.get()))) {
                     useWeakBinding = PR_TRUE;
                     break;
                 }
             }
         } else {
             AddWeakString(pattern, FC_FAMILY, family.get());
         }
     }
--- a/js/src/jsarena.cpp
+++ b/js/src/jsarena.cpp
@@ -48,192 +48,128 @@
 #include "jstypes.h"
 #include "jsstdint.h"
 #include "jsbit.h"
 #include "jsarena.h"
 #include "jsprvtd.h"
 
 using namespace js;
 
-#define JS_ARENA_DEFAULT_ALIGN  sizeof(double)
+/* If JSArena's length is a multiple of 8, that ensures its payload is 8-aligned. */
+JS_STATIC_ASSERT(sizeof(JSArena) % 8 == 0);
 
 JS_PUBLIC_API(void)
-JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size,
-                 size_t align)
+JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size, size_t align)
 {
-    if (align == 0)
-        align = JS_ARENA_DEFAULT_ALIGN;
-    pool->mask = JS_BITMASK(JS_CeilingLog2(align));
+    /* Restricting ourselves to some simple alignments keeps things simple. */
+    if (align == 1 || align == 2 || align == 4 || align == 8) {
+        pool->mask = align - 1;
+    } else {
+        /* This shouldn't happen, but set pool->mask reasonably if it does. */
+        JS_NOT_REACHED("JS_InitArenaPool: bad align");
+        pool->mask = 7;
+    }
     pool->first.next = NULL;
+    /* pool->first is a zero-sized dummy arena that's never allocated from. */
     pool->first.base = pool->first.avail = pool->first.limit =
         JS_ARENA_ALIGN(pool, &pool->first + 1);
     pool->current = &pool->first;
     pool->arenasize = size;
 }
 
-/*
- * An allocation that consumes more than pool->arenasize also has a header
- * pointing back to its previous arena's next member.  This header is not
- * included in [a->base, a->limit), so its space can't be wrongly claimed.
- *
- * As the header is a pointer, it must be well-aligned.  If pool->mask is
- * greater than or equal to POINTER_MASK, the header just preceding a->base
- * for an oversized arena a is well-aligned, because a->base is well-aligned.
- * However, we may need to add more space to pad the JSArena ** back-pointer
- * so that it lies just behind a->base, because a might not be aligned such
- * that (jsuword)(a + 1) is on a pointer boundary.
- *
- * By how much must we pad?  Let M be the alignment modulus for pool and P
- * the modulus for a pointer.  Given M >= P, the base of an oversized arena
- * that satisfies M is well-aligned for P.
- *
- * On the other hand, if M < P, we must include enough space in the header
- * size to align the back-pointer on a P boundary so that it can be found by
- * subtracting P from a->base.  This means a->base must be on a P boundary,
- * even though subsequent allocations from a may be aligned on a lesser (M)
- * boundary.  Given powers of two M and P as above, the extra space needed
- * when M < P is P-M or POINTER_MASK - pool->mask.
- *
- * The size of a header including padding is given by the HEADER_SIZE macro,
- * below, for any pool (for any value of M).
- *
- * The mask to align a->base for any pool is (pool->mask | POINTER_MASK), or
- * HEADER_BASE_MASK(pool).
- *
- * PTR_TO_HEADER computes the address of the back-pointer, given an oversized
- * allocation at p.  By definition, p must be a->base for the arena a that
- * contains p.  GET_HEADER and SET_HEADER operate on an oversized arena a, in
- * the case of SET_HEADER with back-pointer ap.
- */
-#define POINTER_MASK            ((jsuword)(JS_ALIGN_OF_POINTER - 1))
-#define HEADER_SIZE(pool)       (sizeof(JSArena **)                           \
-                                 + (((pool)->mask < POINTER_MASK)             \
-                                    ? POINTER_MASK - (pool)->mask             \
-                                    : 0))
-#define HEADER_BASE_MASK(pool)  ((pool)->mask | POINTER_MASK)
-#define PTR_TO_HEADER(pool,p)   (JS_ASSERT(((jsuword)(p)                      \
-                                            & HEADER_BASE_MASK(pool))         \
-                                           == 0),                             \
-                                 (JSArena ***)(p) - 1)
-#define GET_HEADER(pool,a)      (*PTR_TO_HEADER(pool, (a)->base))
-#define SET_HEADER(pool,a,ap)   (*PTR_TO_HEADER(pool, (a)->base) = (ap))
-
 JS_PUBLIC_API(void *)
 JS_ArenaAllocate(JSArenaPool *pool, size_t nb)
 {
-    JSArena **ap, *a, *b;
-    jsuword extra, hdrsz, gross;
-    void *p;
-
     /*
      * Search pool from current forward till we find or make enough space.
      *
      * NB: subtract nb from a->limit in the loop condition, instead of adding
-     * nb to a->avail, to avoid overflowing a 32-bit address space (possible
-     * when running a 32-bit program on a 64-bit system where the kernel maps
-     * the heap up against the top of the 32-bit address space).
-     *
-     * Thanks to Juergen Kreileder <jk@blackdown.de>, who brought this up in
-     * https://bugzilla.mozilla.org/show_bug.cgi?id=279273.
+     * nb to a->avail, to avoid overflow (possible when running a 32-bit
+     * program on a 64-bit system where the kernel maps the heap up against the
+     * top of the 32-bit address space, see bug 279273).  Note that this
+     * necessitates a comparison between nb and a->limit that looks like a
+     * (conceptual) type error but isn't.
      */
     JS_ASSERT((nb & pool->mask) == 0);
-    for (a = pool->current; nb > a->limit || a->avail > a->limit - nb;
-         pool->current = a) {
-        ap = &a->next;
+    JSArena *a;
+    /*
+     * Comparing nb to a->limit looks like a (conceptual) type error, but it's
+     * necessary to avoid wrap-around.  Yuk.
+     */
+    for (a = pool->current; nb > a->limit || a->avail > a->limit - nb; pool->current = a) {
+        JSArena **ap = &a->next;
         if (!*ap) {
             /* Not enough space in pool, so we must malloc. */
-            extra = (nb > pool->arenasize) ? HEADER_SIZE(pool) : 0;
-            hdrsz = sizeof *a + extra + pool->mask;
-            gross = hdrsz + JS_MAX(nb, pool->arenasize);
-            if (gross < nb)
-                return NULL;
-            b = (JSArena *) OffTheBooks::malloc_(gross);
-            if (!b)
+            size_t gross = sizeof(JSArena) + JS_MAX(nb, pool->arenasize);
+            a = (JSArena *) OffTheBooks::malloc_(gross);
+            if (!a)
                 return NULL;
 
-            b->next = NULL;
-            b->limit = (jsuword)b + gross;
+            a->next = NULL;
+            a->base = a->avail = jsuword(a) + sizeof(JSArena);
+            /*
+             * Because malloc returns 8-aligned pointers and sizeof(JSArena) is
+             * a multiple of 8, a->base will always be 8-aligned, which should
+             * suffice for any valid pool.
+             */
+            JS_ASSERT(a->base == JS_ARENA_ALIGN(pool, a->base));
+            a->limit = (jsuword)a + gross;
 
-            /* If oversized, store ap in the header, just before a->base. */
-            *ap = a = b;
-            JS_ASSERT(gross <= JS_UPTRDIFF(a->limit, a));
-            if (extra) {
-                a->base = a->avail =
-                    ((jsuword)a + hdrsz) & ~HEADER_BASE_MASK(pool);
-                SET_HEADER(pool, a, ap);
-            } else {
-                a->base = a->avail = JS_ARENA_ALIGN(pool, a + 1);
-            }
+            *ap = a;
             continue;
         }
-        a = *ap;                                /* move to next arena */
+        a = *ap;        /* move to next arena */
     }
 
-    p = (void *)a->avail;
+    void* p = (void *)a->avail;
     a->avail += nb;
     JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
     return p;
 }
 
 JS_PUBLIC_API(void *)
 JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr)
 {
-    JSArena **ap, *a, *b;
-    jsuword boff, aoff, extra, hdrsz, gross;
+    /* If we've called JS_ArenaRealloc, the new size must be bigger than pool->arenasize. */
+    JS_ASSERT(size + incr > pool->arenasize);
 
-    /*
-     * Use the oversized-single-allocation header to avoid searching for ap.
-     * See JS_ArenaAllocate, the SET_HEADER call.
-     */
-    if (size > pool->arenasize) {
-        ap = *PTR_TO_HEADER(pool, p);
+    /* Find the arena containing |p|. */
+    JSArena *a;
+    JSArena **ap = &pool->first.next;
+    while (true) {
         a = *ap;
-    } else {
-        ap = &pool->first.next;
-        while ((a = *ap) != pool->current)
-            ap = &a->next;
+        if (JS_IS_IN_ARENA(a, p))
+            break;
+        JS_ASSERT(a != pool->current);
+        ap = &a->next;
     }
+    /* If we've called JS_ArenaRealloc, p must be at the start of an arena. */
+    JS_ASSERT(a->base == jsuword(p));
 
-    JS_ASSERT(a->base == (jsuword)p);
-    boff = JS_UPTRDIFF(a->base, a);
-    aoff = JS_ARENA_ALIGN(pool, size + incr);
-    JS_ASSERT(aoff > pool->arenasize);
-    extra = HEADER_SIZE(pool);                  /* oversized header holds ap */
-    hdrsz = sizeof *a + extra + pool->mask;     /* header and alignment slop */
-    gross = hdrsz + aoff;
-    JS_ASSERT(gross > aoff);
+    size_t gross = sizeof(JSArena) + JS_ARENA_ALIGN(pool, size + incr);
     a = (JSArena *) OffTheBooks::realloc_(a, gross);
     if (!a)
         return NULL;
 
+    a->base = jsuword(a) + sizeof(JSArena);
+    a->avail = a->limit = jsuword(a) + gross;
+    /*
+     * Because realloc returns 8-aligned pointers and sizeof(JSArena) is a
+     * multiple of 8, a->base will always be 8-aligned, which should suffice
+     * for any valid pool.
+     */
+    JS_ASSERT(a->base == JS_ARENA_ALIGN(pool, a->base));
+
     if (a != *ap) {
-        /* Oops, realloc moved the allocation: update other pointers to a. */
+        /* realloc moved the allocation: update other pointers to a. */
         if (pool->current == *ap)
             pool->current = a;
-        b = a->next;
-        if (b && b->avail - b->base > pool->arenasize) {
-            JS_ASSERT(GET_HEADER(pool, b) == &(*ap)->next);
-            SET_HEADER(pool, b, &a->next);
-        }
-
-        /* Now update *ap, the next link of the arena before a. */
         *ap = a;
     }
 
-    a->base = ((jsuword)a + hdrsz) & ~HEADER_BASE_MASK(pool);
-    a->limit = (jsuword)a + gross;
-    a->avail = a->base + aoff;
-    JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
-
-    /* Check whether realloc aligned differently, and copy if necessary. */
-    if (boff != JS_UPTRDIFF(a->base, a))
-        memmove((void *)a->base, (char *)a + boff, size);
-
-    /* Store ap in the oversized-load arena header. */
-    SET_HEADER(pool, a, ap);
     return (void *)a->base;
 }
 
 JS_PUBLIC_API(void *)
 JS_ArenaGrow(JSArenaPool *pool, void *p, size_t size, size_t incr)
 {
     void *newp;
 
@@ -285,17 +221,17 @@ FreeArenaList(JSArenaPool *pool, JSArena
 JS_PUBLIC_API(void)
 JS_ArenaRelease(JSArenaPool *pool, char *mark)
 {
     JSArena *a;
 
     for (a = &pool->first; a; a = a->next) {
         JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
 
-        if (JS_ARENA_MARK_MATCH(a, mark)) {
+        if (JS_IS_IN_ARENA(a, mark)) {
             a->avail = JS_ARENA_ALIGN(pool, mark);
             JS_ASSERT(a->avail <= a->limit);
             FreeArenaList(pool, a);
             return;
         }
     }
 }
 
--- a/js/src/jsarena.h
+++ b/js/src/jsarena.h
@@ -78,23 +78,21 @@ struct JSArenaPool {
 #define JS_ARENA_ALLOCATE_TYPE(p, type, pool)                                 \
     JS_ARENA_ALLOCATE_COMMON(p, type *, pool, sizeof(type), 0)
 
 #define JS_ARENA_ALLOCATE_CAST(p, type, pool, nb)                             \
     JS_ARENA_ALLOCATE_COMMON(p, type, pool, nb, _nb > _a->limit)
 
 /*
  * NB: In JS_ARENA_ALLOCATE_CAST and JS_ARENA_GROW_CAST, always subtract _nb
- * from a->limit rather than adding _nb to _p, to avoid overflowing a 32-bit
- * address space (possible when running a 32-bit program on a 64-bit system
- * where the kernel maps the heap up against the top of the 32-bit address
- * space).
- *
- * Thanks to Juergen Kreileder <jk@blackdown.de>, who brought this up in
- * https://bugzilla.mozilla.org/show_bug.cgi?id=279273.
+ * from a->limit rather than adding _nb to _p, to avoid overflow (possible when
+ * running a 32-bit program on a 64-bit system where the kernel maps the heap
+ * up against the top of the 32-bit address space, see bug 279273).  Note that
+ * this necessitates a comparison between nb and a->limit that looks like a
+ * (conceptual) type error but isn't.
  */
 #define JS_ARENA_ALLOCATE_COMMON(p, type, pool, nb, guard)                    \
     JS_BEGIN_MACRO                                                            \
         JSArena *_a = (pool)->current;                                        \
         size_t _nb = JS_ARENA_ALIGN(pool, nb);                                \
         jsuword _p = _a->avail;                                               \
         if ((guard) || _p > _a->limit - _nb)                                  \
             _p = (jsuword)JS_ArenaAllocate(pool, _nb);                        \
@@ -106,38 +104,43 @@ struct JSArenaPool {
 
 #define JS_ARENA_GROW(p, pool, size, incr)                                    \
     JS_ARENA_GROW_CAST(p, void *, pool, size, incr)
 
 #define JS_ARENA_GROW_CAST(p, type, pool, size, incr)                         \
     JS_BEGIN_MACRO                                                            \
         JSArena *_a = (pool)->current;                                        \
         if (_a->avail == (jsuword)(p) + JS_ARENA_ALIGN(pool, size)) {         \
+            /* p was the last thing allocated in the current arena... */      \
             size_t _nb = (size) + (incr);                                     \
             _nb = JS_ARENA_ALIGN(pool, _nb);                                  \
             if (_a->limit >= _nb && (jsuword)(p) <= _a->limit - _nb) {        \
+                /* ... and we have space, so just extend p in-place */        \
                 _a->avail = (jsuword)(p) + _nb;                               \
             } else if ((jsuword)(p) == _a->base) {                            \
+                /* ... p is also the 1st thing in this arena */               \
                 p = (type) JS_ArenaRealloc(pool, p, size, incr);              \
             } else {                                                          \
+                /* hard case */                                               \
                 p = (type) JS_ArenaGrow(pool, p, size, incr);                 \
             }                                                                 \
         } else {                                                              \
+            /* hard case */                                                   \
             p = (type) JS_ArenaGrow(pool, p, size, incr);                     \
         }                                                                     \
         STATIC_ASSUME(!p || ubound((char *)p) >= size + incr);                \
     JS_END_MACRO
 
 #define JS_ARENA_MARK(pool)     ((void *) (pool)->current->avail)
 #define JS_UPTRDIFF(p,q)        ((jsuword)(p) - (jsuword)(q))
 
 /*
  * Check if the mark is inside arena's allocated area.
  */
-#define JS_ARENA_MARK_MATCH(a, mark)                                          \
+#define JS_IS_IN_ARENA(a, mark)                                               \
     (JS_UPTRDIFF(mark, (a)->base) <= JS_UPTRDIFF((a)->avail, (a)->base))
 
 #ifdef DEBUG
 #define JS_CLEAR_UNUSED(a)      (JS_ASSERT((a)->avail <= (a)->limit),         \
                                  memset((void*)(a)->avail, JS_FREE_PATTERN,   \
                                         (a)->limit - (a)->avail))
 #define JS_CLEAR_ARENA(a)       memset((void*)(a), JS_FREE_PATTERN,           \
                                        (a)->limit - (jsuword)(a))
@@ -145,17 +148,17 @@ struct JSArenaPool {
 #define JS_CLEAR_UNUSED(a)      /* nothing */
 #define JS_CLEAR_ARENA(a)       /* nothing */
 #endif
 
 #define JS_ARENA_RELEASE(pool, mark)                                          \
     JS_BEGIN_MACRO                                                            \
         char *_m = (char *)(mark);                                            \
         JSArena *_a = (pool)->current;                                        \
-        if (_a != &(pool)->first && JS_ARENA_MARK_MATCH(_a, _m)) {            \
+        if (_a != &(pool)->first && JS_IS_IN_ARENA(_a, _m)) {                 \
             _a->avail = (jsuword)JS_ARENA_ALIGN(pool, _m);                    \
             JS_ASSERT(_a->avail <= _a->limit);                                \
             JS_CLEAR_UNUSED(_a);                                              \
         } else {                                                              \
             JS_ArenaRelease(pool, _m);                                        \
         }                                                                     \
     JS_END_MACRO
 
@@ -165,17 +168,18 @@ struct JSArenaPool {
         if ((pool)->current == (a)) (pool)->current = &(pool)->first;         \
         *(pnext) = (a)->next;                                                 \
         JS_CLEAR_ARENA(a);                                                    \
         js::UnwantedForeground::free_(a);                                      \
         (a) = NULL;                                                           \
     JS_END_MACRO
 
 /*
- * Initialize an arena pool with a minimum size per arena of size bytes.
+ * Initialize an arena pool with a minimum size per arena of |size| bytes.
+ * |align| must be 1, 2, 4 or 8.
  */
 extern JS_PUBLIC_API(void)
 JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size,
                  size_t align);
 
 /*
  * Free the arenas in pool.  The user may continue to allocate from pool
  * after calling this function.  There is no need to call JS_InitArenaPool()
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -336,20 +336,21 @@ Chunk::init(JSRuntime *rt)
         a->aheader.setAsNotAllocated();
         prevp = &a->aheader.next;
     }
     *prevp = NULL;
 
     for (size_t i = 0; i != JS_ARRAY_LENGTH(markingDelay); ++i)
         markingDelay[i].init();
 
-    /*
-     * The rest of info fields is initailzied in PickChunk. We do not clear
-     * the mark bitmap as that is done at the start of the next GC.
-     */
+    /* We clear the bitmap to guard against xpc_IsGrayGCThing being called on
+       uninitialized data, which would happen before the first GC cycle. */
+    bitmap.clear();
+
+    /* The rest of info fields are initialized in PickChunk. */
 }
 
 inline Chunk **
 GetAvailableChunkList(JSCompartment *comp)
 {
     JSRuntime *rt = comp->rt;
     return comp->isSystemCompartment
            ? &rt->gcSystemAvailableChunkListHead
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -515,18 +515,18 @@ mjit::Compiler::performCompilation(JITSc
         CHECK_STATUS(finishThisUp(jitp));
     }
 
 #ifdef JS_METHODJIT_SPEW
     prof.stop();
     JaegerSpew(JSpew_Prof, "compilation took %d us\n", prof.time_us());
 #endif
 
-    JaegerSpew(JSpew_Scripts, "successfully compiled (code \"%p\") (size \"%ld\")\n",
-               (*jitp)->code.m_code.executableAddress(), (*jitp)->code.m_size);
+    JaegerSpew(JSpew_Scripts, "successfully compiled (code \"%p\") (size \"%u\")\n",
+               (*jitp)->code.m_code.executableAddress(), unsigned((*jitp)->code.m_size));
 
     if (!*jitp)
         return Compile_Abort;
 
     return Compile_Okay;
 }
 
 #undef CHECK_STATUS
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -5639,16 +5639,18 @@ main(int argc, char **argv, char **envp)
 #endif
         || !op.addOptionalStringArg("script", "A script to execute (after all options)")
         || !op.addOptionalMultiStringArg("scriptArgs",
                                          "String arguments to bind as |arguments| in the "
                                          "shell's global")) {
         return EXIT_FAILURE;
     }
 
+    op.setArgTerminatesOptions("script", true);
+
     switch (op.parseArgs(argc, argv)) {
       case OptionParser::ParseHelp:
         return EXIT_SUCCESS;
       case OptionParser::ParseError:
         op.printHelp(argv[0]);
         return EXIT_FAILURE;
       case OptionParser::Fail:
         return EXIT_FAILURE;
--- a/js/src/shell/jsoptparse.cpp
+++ b/js/src/shell/jsoptparse.cpp
@@ -79,16 +79,22 @@ Option::asValued() const
     return const_cast<Option *>(this)->asValued();
 }
 
 OPTION_CONVERT_IMPL(Bool)
 OPTION_CONVERT_IMPL(String)
 OPTION_CONVERT_IMPL(Int)
 OPTION_CONVERT_IMPL(MultiString)
 
+void
+OptionParser::setArgTerminatesOptions(const char *name, bool enabled)
+{
+    findArgument(name)->setTerminatesOptions(enabled);
+}
+
 OptionParser::Result
 OptionParser::error(const char *fmt, ...)
 {
     va_list args;
     va_start(args, fmt);
     fprintf(stderr, "Error: ");
     vfprintf(stderr, fmt, args);
     va_end(args);
@@ -279,18 +285,21 @@ OptionParser::extractValue(size_t argc, 
         return error("Expected a value for option %s", argv[*i]);
 
     *i += 1;
     *value = argv[*i];
     return Okay;
 }
 
 OptionParser::Result
-OptionParser::handleOption(Option *opt, size_t argc, char **argv, size_t *i)
+OptionParser::handleOption(Option *opt, size_t argc, char **argv, size_t *i, bool *optionsAllowed)
 {
+    if (opt->getTerminatesOptions())
+        *optionsAllowed = false;
+
     switch (opt->kind) {
       case OptionKindBool:
       {
         if (opt == &helpOption)
             return printHelp(argv[0]);
         opt->asBoolOption()->value = true;
         return Okay;
       }
@@ -324,22 +333,26 @@ OptionParser::handleOption(Option *opt, 
       }
       default:
         JS_NOT_REACHED("unhandled option kind");
         return Fail;
     }
 }
 
 OptionParser::Result
-OptionParser::handleArg(size_t argc, char **argv, size_t *i)
+OptionParser::handleArg(size_t argc, char **argv, size_t *i, bool *optionsAllowed)
 {
     if (nextArgument >= arguments.length())
         return error("Too many arguments provided");
 
     Option *arg = arguments[nextArgument];
+
+    if (arg->getTerminatesOptions())
+        *optionsAllowed = false;
+
     switch (arg->kind) {
       case OptionKindString:
         arg->asStringOption()->value = argv[*i];
         nextArgument += 1;
         return Okay;
       case OptionKindMultiString:
       {
         /* Don't advance the next argument -- there can only be one (final) variadic argument. */
@@ -352,21 +365,23 @@ OptionParser::handleArg(size_t argc, cha
     }
 }
 
 OptionParser::Result
 OptionParser::parseArgs(int inputArgc, char **argv)
 {
     JS_ASSERT(inputArgc >= 0);
     size_t argc = inputArgc;
+    /* Permit a "no more options" capability, like |--| offers in many shell interfaces. */
+    bool optionsAllowed = true;
 
     for (size_t i = 1; i < argc; ++i) {
         char *arg = argv[i];
         Result r;
-        if (arg[0] == '-') {
+        if (arg[0] == '-' && optionsAllowed) {
             /* Option. */
             size_t arglen = strlen(arg);
             if (arglen < 2) /* Do not permit solo dash option. */
                 return error("Invalid dash option");
 
             Option *opt;
             if (arg[1] == '-') {
                 /* Long option. */
@@ -377,20 +392,20 @@ OptionParser::parseArgs(int inputArgc, c
                 /* Short option */
                 if (arg[2] != '\0')
                     return error("Short option followed by junk: %s", arg);
                 opt = findOption(arg[1]);
                 if (!opt)
                     return error("Invalid short option: %s", arg);
             }
 
-            r = handleOption(opt, argc, argv, &i);
+            r = handleOption(opt, argc, argv, &i, &optionsAllowed);
         } else {
             /* Argument. */
-            r = handleArg(argc, argv, &i);
+            r = handleArg(argc, argv, &i, &optionsAllowed);
         }
         switch (r) {
           case Okay:
             break;
           default:
             return r;
         }
     }
--- a/js/src/shell/jsoptparse.h
+++ b/js/src/shell/jsoptparse.h
@@ -65,23 +65,27 @@ enum OptionKind
 };
 
 struct Option
 {
     const char  *longflag;
     const char  *help;
     OptionKind  kind;
     char        shortflag;
+    bool        terminatesOptions;
 
     Option(OptionKind kind, char shortflag, const char *longflag, const char *help)
-      : longflag(longflag), help(help), kind(kind), shortflag(shortflag)
+      : longflag(longflag), help(help), kind(kind), shortflag(shortflag), terminatesOptions(false)
     {}
 
     virtual ~Option() = 0;
 
+    void setTerminatesOptions(bool enabled) { terminatesOptions = enabled; }
+    bool getTerminatesOptions() const { return terminatesOptions; }
+
     virtual bool isValued() const { return false; }
 
     /* Only some valued options are variadic (like MultiStringOptions). */
     virtual bool isVariadic() const { return false; }
 
     /* 
      * For arguments, the shortflag field is used to indicate whether the
      * argument is optional.
@@ -243,18 +247,18 @@ class OptionParser
     const Option *findOption(char shortflag) const;
     Option *findOption(const char *longflag);
     const Option *findOption(const char *longflag) const;
     Option *findArgument(const char *name);
     const Option *findArgument(const char *name) const;
 
     Result error(const char *fmt, ...);
     Result extractValue(size_t argc, char **argv, size_t *i, char **value);
-    Result handleArg(size_t argc, char **argv, size_t *i);
-    Result handleOption(Option *opt, size_t argc, char **argv, size_t *i);
+    Result handleArg(size_t argc, char **argv, size_t *i, bool *optsAllowed);
+    Result handleOption(Option *opt, size_t argc, char **argv, size_t *i, bool *optsAllowed);
 
   public:
     explicit OptionParser(const char *usage)
       : helpOption('h', "help", "Display help information"),
         usage(usage), ver(NULL), descr(NULL), descrWidth(80), helpWidth(80), nextArgument(0)
     {}
 
     ~OptionParser();
@@ -264,16 +268,17 @@ class OptionParser
 
     /* Metadata */
 
     void setVersion(const char *version) { ver = version; }
     void setHelpWidth(size_t width) { helpWidth = width; }
     void setDescriptionWidth(size_t width) { descrWidth = width; }
     void setDescription(const char *description) { descr = description; }
     void setHelpOption(char shortflag, const char *longflag, const char *help);
+    void setArgTerminatesOptions(const char *name, bool enabled);
 
     /* Arguments: no further arguments may be added after a variadic argument. */
 
     bool addOptionalStringArg(const char *name, const char *help);
     bool addOptionalMultiStringArg(const char *name, const char *help);
 
     const char *getStringArg(const char *name) const;
     MultiStringRange getMultiStringArg(const char *name) const;
--- a/js/src/xpconnect/src/xpcstack.cpp
+++ b/js/src/xpconnect/src/xpcstack.cpp
@@ -128,16 +128,19 @@ XPCJSStackFrame::~XPCJSStackFrame()
 }
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(XPCJSStackFrame, nsIStackFrame)
 
 nsresult
 XPCJSStackFrame::CreateStack(JSContext* cx, JSStackFrame* fp,
                              XPCJSStackFrame** stack)
 {
+    static const unsigned MAX_FRAMES = 3000;
+    unsigned numFrames = 0;
+
     nsRefPtr<XPCJSStackFrame> first = new XPCJSStackFrame();
     nsRefPtr<XPCJSStackFrame> self = first;
     while(fp && self)
     {
         if(!JS_IsScriptFrame(cx, fp))
         {
             self->mLanguage = nsIProgrammingLanguage::CPLUSPLUS;
         }
@@ -182,17 +185,21 @@ XPCJSStackFrame::CreateStack(JSContext* 
                 }
             }
             else
             {
                 self->mLanguage = nsIProgrammingLanguage::CPLUSPLUS;
             }
         }
 
-        if(JS_FrameIterator(cx, &fp))
+        if (++numFrames > MAX_FRAMES)
+        {
+            fp = NULL;
+        }
+        else if(JS_FrameIterator(cx, &fp))
         {
             XPCJSStackFrame* frame = new XPCJSStackFrame();
             self->mCaller = frame;
             self = frame;
         }
     }
 
     *stack = first.forget().get();
--- a/layout/generic/frame-verify.js
+++ b/layout/generic/frame-verify.js
@@ -55,25 +55,25 @@ let haveIDs = {};
 
 // We match up needIDs with haveIDs at the end because static variables are
 // not present in the .members array of a type
 
 function process_tree_decl(d)
 {
   d = dehydra_convert(d);
   
-  if (d.name && frameIIDRE(d.name)) {
+  if (d.name && frameIIDRE.exec(d.name)) {
     haveIDs[d.memberOf.name] = 1;
   }
 }
 
 function process_cp_pre_genericize(d)
 {
   d = dehydra_convert(d);
-  if (queryFrameRE(d.name) && d.template === undefined) {
+  if (queryFrameRE.exec(d.name) && d.template === undefined) {
     let templtype = d.type.type.type;
     while (templtype.typedef !== undefined)
       templtype = templtype.typedef;
       
     needIDs.push([templtype.name, d.loc]);
   }
 }
 
--- a/layout/reftests/border-radius/reftest.list
+++ b/layout/reftests/border-radius/reftest.list
@@ -32,17 +32,17 @@ random == corner-2.html corner-2-ref.svg
 
 # Test that radii too long are reduced
 == border-reduce-height.html border-reduce-height-ref.html
 
 # Tests for border clipping
 fails == clipping-1.html clipping-1-ref.html # background color should completely fill box; bug 466572
 != clipping-2.html about:blank # background color clipped to inner/outer border, can't get
 # great tests for this due to antialiasing problems described in bug 466572
-fails-if(Android) == clipping-3.html clipping-3-ref.xhtml # edge of border-radius clips an underlying object's background, Android failure is bug 650569
+== clipping-3.html clipping-3-ref.xhtml # edge of border-radius clips an underlying object's background, Android failure is bug 650569
 
 # Tests for clipping the contents of replaced elements and overflow!=visible
 != clipping-4-ref.html clipping-4-notref.html
 fails-if(cocoaWidget) == clipping-4-canvas.html clipping-4-ref.html
 fails-if(Android) == clipping-4-image.html clipping-4-ref.html
 == clipping-4-overflow-hidden.html clipping-4-ref.html
 == clipping-5-canvas.html clipping-5-refc.html
 == clipping-5-image.html clipping-5-refi.html
--- a/layout/reftests/image-element/reftest.list
+++ b/layout/reftests/image-element/reftest.list
@@ -11,17 +11,17 @@ fails-if(cocoaWidget) == canvas-outside-
 == element-paint-recursion.html element-paint-recursion-ref.html
 HTTP(..) == element-paint-continuation.html element-paint-continuation-ref.html
 == element-paint-transform-01.html element-paint-transform-01-ref.html
 random-if(d2d) == element-paint-transform-02.html element-paint-transform-02-ref.html # bug 587133
 == element-paint-background-size-01.html element-paint-background-size-01-ref.html
 == element-paint-background-size-02.html element-paint-background-size-02-ref.html
 == element-paint-transform-repeated.html element-paint-transform-repeated-ref.html
 == element-paint-transform-03.html element-paint-transform-03-ref.html
-fails-if(Android) == element-paint-native-widget.html element-paint-native-widget-ref.html # bug 650589
+== element-paint-native-widget.html element-paint-native-widget-ref.html # bug 650589
 == element-paint-subimage-sampling-restriction.html about:blank
 == element-paint-clippath.html element-paint-clippath-ref.html
 == element-paint-sharpness-01a.html element-paint-sharpness-01b.html
 == element-paint-sharpness-01b.html element-paint-sharpness-01c.html
 == element-paint-sharpness-01c.html element-paint-sharpness-01d.html
 == element-paint-sharpness-02a.html element-paint-sharpness-02b.html
 == element-paint-sharpness-02b.html element-paint-sharpness-02c.html
 == element-paint-paintserversize-rounding-01.html element-paint-paintserversize-rounding-01-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/dynamic-use-05.svg
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink"
+     style="background: red;" class="reftest-wait">
+  <defs>
+     <symbol id="sym1">
+       <rect width="100" height="100" fill="lime" />
+    </symbol>
+  </defs>
+  <rect width="100%" height="100%" fill="lime"/>
+  <rect width="100" height="100" fill="red" />
+  <use id="u" xlink:href="#sym1" width="1" />
+  <script type="text/javascript">
+    <![CDATA[
+
+    document.addEventListener("MozReftestInvalidate", doTest, false);
+    // in case we're not gecko
+    setTimeout(doTest, 5000);
+
+    function doTest() {
+        var u = document.getElementById("u");
+        u.setAttribute("width", "100");
+        document.documentElement.removeAttribute('class');
+      }
+
+    ]]>
+</script>
+</svg>
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -90,16 +90,17 @@ fails-if(Android) == dynamic-switch-01.s
 == dynamic-text-02.svg dynamic-text-02-ref.svg
 == dynamic-text-03.svg dynamic-text-03-ref.svg
 fails-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) == dynamic-text-04.svg dynamic-text-04-ref.svg # bug 421587 for WinXP
 == dynamic-textPath-01.svg dynamic-textPath-01-ref.svg
 == dynamic-use-01.svg pass.svg
 == dynamic-use-02.svg pass.svg
 == dynamic-use-03.svg pass.svg
 == dynamic-use-04.svg pass.svg
+== dynamic-use-05.svg pass.svg
 random == dynamic-use-nested-01.svg dynamic-use-nested-01-ref.svg # bug 467498
 == dynamic-use-remove-width.svg dynamic-use-remove-width-ref.svg
 == linked-pattern-01.svg pass.svg
 == use-01.svg pass.svg
 == use-01-extref.svg pass.svg
 == use-02-extref.svg use-02-extref-ref.svg
 == use-children.svg pass.svg
 == fallback-color-01a.svg pass.svg
new file mode 100644
--- /dev/null
+++ b/layout/reftests/text/font-selection-fallback-1-ref.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+	<title>Reference for test that language support doesn't override
+	specified family - Bug 678561</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+	<style type="text/css">
+
+	@font-face {
+		font-family: "MarkA";
+		src: url(../fonts/markA.ttf);
+	}
+	@font-face {
+		font-family: "MarkB";
+		src: url(../fonts/markB.ttf);
+	}
+	@font-face {
+		font-family: "DejaVu Sans Mono";
+		src: url(../fonts/DejaVuSansMono.otf);
+	}
+
+	.c1 { font-family: MarkA; }
+	.c2 { font-family: MarkB; }
+	.c3 { font-family: DejaVu Sans Mono; }
+
+        /* to ensure the same vertical positioning of the text */
+        .spacer { line-height: 3em }
+	</style>
+</head>
+<body>
+
+<p><span class="c1">A</span></p>
+<p><span class="c2">B</span><span class="spacer"></span></p>
+<p><span class="c3">C</span><span class="spacer"></span></p>
+
+<p class="c3">A</p>
+<p class="c3">B</p>
+<p class="c3">C</p>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/text/font-selection-fallback-1.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+	<title>Test that language support doesn't override specified family - Bug 678561</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+	<style type="text/css">
+
+	@font-face {
+		font-family: "MarkA";
+		src: url(../fonts/markA.ttf);
+	}
+	@font-face {
+		font-family: "MarkB";
+		src: url(../fonts/markB.ttf);
+	}
+	@font-face {
+		font-family: "DejaVu Sans Mono";
+		src: url(../fonts/DejaVuSansMono.otf);
+	}
+
+	.c1 { font-family: MarkA, MarkB, DejaVu Sans Mono; }
+
+	.c2 { font-family: DejaVu Sans Mono, MarkA, MarkB; }
+
+        /* to ensure the same vertical positioning of the text */
+        .spacer { line-height: 3em }
+	</style>
+</head>
+<body>
+
+<p><span class="c1">A</span></p>
+<p><span class="c1">B</span><span class="spacer"></span></p>
+<p><span class="c1">C</span><span class="spacer"></span></p>
+
+<p class="c2">A</p>
+<p class="c2">B</p>
+<p class="c2">C</p>
+
+</body>
+</html>
--- a/layout/reftests/text/reftest.list
+++ b/layout/reftests/text/reftest.list
@@ -1,10 +1,11 @@
 fails-if(Android) == fallback-01.xhtml fallback-01-ref.xhtml
 == font-selection-by-lang-01.html font-selection-by-lang-01-ref.html
+== font-selection-fallback-1.html font-selection-fallback-1-ref.html
 HTTP(..) == font-selection-generic-1.html font-selection-generic-1-ref.html
 fails-if(Android) != font-size-adjust-01.html font-size-adjust-01-ref.html
 # The following test passes consistently only on Mac OS X;
 # both Windows and Linux give results that vary depending on the font size/zoom factor used,
 # because hinting affects the metrics used to compute the font size adjustment. See bug 429605.
 random-if(!cocoaWidget) == font-size-adjust-02.html font-size-adjust-02-ref.html
 # This currently fails because line spacing does not respect font-size-adjust
 # in the "obvious" way, but it is unclear what the behavior should really be;
--- a/layout/xul/base/src/grid/reftests/reftest.list
+++ b/layout/xul/base/src/grid/reftests/reftest.list
@@ -1,18 +1,18 @@
 == row-sizing-1.xul row-sizing-1-ref.xul
 == column-sizing-1.xul column-sizing-1-ref.xul
 == row-or-column-sizing-1.xul row-or-column-sizing-2.xul
 == row-or-column-sizing-1.xul row-or-column-sizing-3.xul
 == row-or-column-sizing-1.xul row-or-column-sizing-4.xul
 == z-order-1.xul z-order-1-ref.xul
 == z-order-2.xul z-order-2-ref.xul
-fails-if(Android) == not-full-basic.xul not-full-basic-ref.xhtml # bug 650597
-fails-if(Android) == not-full-grid-pack-align.xul not-full-basic-ref.xhtml # bug 650597
+== not-full-basic.xul not-full-basic-ref.xhtml # bug 650597
+== not-full-grid-pack-align.xul not-full-basic-ref.xhtml # bug 650597
 == not-full-row-group-align.xul not-full-row-group-align-ref.xhtml # does anyone want/need this behavior?
 == not-full-row-group-pack.xul not-full-row-group-pack-ref.xhtml
-fails-if(Android) == not-full-row-group-direction.xul not-full-row-group-direction-ref.xhtml # bug 650597
-fails-if(Android) == not-full-row-leaf-align.xul not-full-basic-ref.xhtml # bug 650597
-fails-if(Android) == not-full-row-leaf-pack.xul not-full-row-leaf-pack-ref.xhtml # bug 650597
-fails-if(Android) == not-full-row-leaf-direction.xul not-full-row-leaf-pack-ref.xhtml # bug 650597
+== not-full-row-group-direction.xul not-full-row-group-direction-ref.xhtml # bug 650597
+== not-full-row-leaf-align.xul not-full-basic-ref.xhtml # bug 650597
+== not-full-row-leaf-pack.xul not-full-row-leaf-pack-ref.xhtml # bug 650597
+== not-full-row-leaf-direction.xul not-full-row-leaf-pack-ref.xhtml # bug 650597
 fails-if(Android) == scrollable-columns.xul scrollable-columns-ref.xhtml # bug 650597
 fails == scrollable-rows.xul scrollable-rows-ref.xhtml
 == sizing-2d.xul sizing-2d-ref.xul
--- a/memory/jemalloc/jemalloc.c
+++ b/memory/jemalloc/jemalloc.c
@@ -2190,16 +2190,36 @@ pages_map_align(size_t size, int pfd, si
 	return (ret);
 }
 #endif
 
 static void *
 pages_map(void *addr, size_t size, int pfd)
 {
 	void *ret;
+#if defined(__ia64__)
+        /*
+         * The JS engine assumes that all allocated pointers have their high 17 bits clear,
+         * which ia64's mmap doesn't support directly. However, we can emulate it by passing
+         * mmap an "addr" parameter with those bits clear. The mmap will return that address,
+         * or the nearest available memory above that address, providing a near-guarantee
+         * that those bits are clear. If they are not, we return NULL below to indicate
+         * out-of-memory.
+         * 
+         * The addr is chosen as 0x0000070000000000, which still allows about 120TB of virtual 
+         * address space.
+         * 
+         * See Bug 589735 for more information.
+         */
+	bool check_placement = true;
+        if (addr == NULL) {
+		addr = (void*)0x0000070000000000;
+		check_placement = false;
+	}
+#endif
 
 	/*
 	 * We don't use MAP_FIXED here, because it can cause the *replacement*
 	 * of existing mappings, and we only want to create new mappings.
 	 */
 #ifdef MALLOC_PAGEFILE
 	if (pfd != -1) {
 		ret = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE |
@@ -2209,34 +2229,52 @@ pages_map(void *addr, size_t size, int p
 	       {
 		ret = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE |
 		    MAP_ANON, -1, 0);
 	}
 	assert(ret != NULL);
 
 	if (ret == MAP_FAILED)
 		ret = NULL;
+#if defined(__ia64__)
+        /* 
+         * If the allocated memory doesn't have its upper 17 bits clear, consider it 
+         * as out of memory.
+        */
+        else if ((long long)ret & 0xffff800000000000) {
+		munmap(ret, size);
+                ret = NULL;
+        }
+        /* If the caller requested a specific memory location, verify that's what mmap returned. */
+	else if (check_placement && ret != addr) {
+#else
 	else if (addr != NULL && ret != addr) {
+#endif
 		/*
 		 * We succeeded in mapping memory, but not in the right place.
 		 */
 		if (munmap(ret, size) == -1) {
 			char buf[STRERROR_BUF];
 
 			strerror_r(errno, buf, sizeof(buf));
 			_malloc_message(_getprogname(),
 			    ": (malloc) Error in munmap(): ", buf, "\n");
 			if (opt_abort)
 				abort();
 		}
 		ret = NULL;
 	}
 
+#if defined(__ia64__)
+	assert(ret == NULL || (!check_placement && ret != NULL)
+	    || (check_placement && ret == addr));
+#else
 	assert(ret == NULL || (addr == NULL && ret != addr)
 	    || (addr != NULL && ret == addr));
+#endif
 	return (ret);
 }
 
 static void
 pages_unmap(void *addr, size_t size)
 {
 
 	if (munmap(addr, size) == -1) {
--- a/mobile/chrome/content/browser.js
+++ b/mobile/chrome/content/browser.js
@@ -177,17 +177,16 @@ var Browser = {
     // XXX change
 
     /* handles dispatching clicks on browser into clicks in content or zooms */
     Elements.browsers.customDragger = new Browser.MainDragger();
 
     /* handles web progress management for open browsers */
     Elements.browsers.webProgress = new Browser.WebProgress();
 
-    this.keySender = new ContentCustomKeySender(Elements.browsers);
     let mouseModule = new MouseModule();
     let gestureModule = new GestureModule(Elements.browsers);
     let scrollWheelModule = new ScrollwheelModule(Elements.browsers);
 
     ContentTouchHandler.init();
 
     // Warning, total hack ahead. All of the real-browser related scrolling code
     // lies in a pretend scrollbox here. Let's not land this as-is. Maybe it's time
@@ -1972,62 +1971,16 @@ const ContentTouchHandler = {
     this._dispatchMouseEvent("Browser:MouseLong", aX, aY);
   },
 
   toString: function toString() {
     return "[ContentTouchHandler] { }";
   }
 };
 
-
-/** Watches for mouse events in chrome and sends them to content. */
-function ContentCustomKeySender(container) {
-  container.addEventListener("keypress", this, false);
-  container.addEventListener("keyup", this, false);
-  container.addEventListener("keydown", this, false);
-}
-
-ContentCustomKeySender.prototype = {
-  handleEvent: function handleEvent(aEvent) {
-    if (Elements.contentShowing.getAttribute("disabled") == "true")
-      return;
-
-    let browser = getBrowser();
-    if (browser && browser.active && browser.getAttribute("remote") == "true") {
-      aEvent.stopPropagation();
-      aEvent.preventDefault();
-
-      let fl = browser.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader;
-      fl.sendCrossProcessKeyEvent(aEvent.type,
-                                  aEvent.keyCode,
-                                  (aEvent.type != "keydown") ? aEvent.charCode : null,
-                                  this._parseModifiers(aEvent));
-    }
-  },
-
-  _parseModifiers: function _parseModifiers(aEvent) {
-    const masks = Ci.nsIDOMNSEvent;
-    let mval = 0;
-    if (aEvent.shiftKey)
-      mval |= masks.SHIFT_MASK;
-    if (aEvent.ctrlKey)
-      mval |= masks.CONTROL_MASK;
-    if (aEvent.altKey)
-      mval |= masks.ALT_MASK;
-    if (aEvent.metaKey)
-      mval |= masks.META_MASK;
-    return mval;
-  },
-
-  toString: function toString() {
-    return "[ContentCustomKeySender] { }";
-  }
-};
-
-
 /**
  * Utility class to handle manipulations of the identity indicators in the UI
  */
 function IdentityHandler() {
   this._staticStrings = {};
   this._staticStrings[this.IDENTITY_MODE_DOMAIN_VERIFIED] = {
     encryption_label: Strings.browser.GetStringFromName("identity.encrypted2")
   };
@@ -2916,17 +2869,16 @@ Tab.prototype = {
     notification.appendChild(browser);
     Elements.browsers.insertBefore(notification, aInsertBefore);
 
     // stop about:blank from loading
     browser.stop();
 
     let fl = browser.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader;
     fl.renderMode = Ci.nsIFrameLoader.RENDER_MODE_ASYNC_SCROLL;
-    fl.eventMode = Ci.nsIFrameLoader.EVENT_MODE_DONT_FORWARD_TO_CHILD;
 
     return browser;
   },
 
   _destroyBrowser: function _destroyBrowser() {
     if (this._browser) {
       let notification = this._notification;
       let browser = this._browser;
--- a/mobile/chrome/content/common-ui.js
+++ b/mobile/chrome/content/common-ui.js
@@ -805,17 +805,16 @@ var FormHelperUI = {
         }
 
         // If the focus is not on the browser element, the key will not be sent
         // to the content so do it ourself
         let focusedElement = gFocusManager.getFocusedElementForWindow(window, true, {});
         if (focusedElement && focusedElement.localName == "browser")
           return;
 
-        Browser.keySender.handleEvent(aEvent);
         break;
 
       case "SizeChanged":
         setTimeout(function(self) {
           SelectHelperUI.sizeToContent();
           self._zoom(self._currentElementRect, self._currentCaretRect);
         }, 0, this);
         break;
--- a/testing/mochitest/browser-test.js
+++ b/testing/mochitest/browser-test.js
@@ -51,32 +51,32 @@ function Tester(aTests, aDumper, aCallba
   this._scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/SimpleTest.js", simpleTestScope);
   this._scriptLoader.loadSubScript("chrome://mochikit/content/chrome-harness.js", simpleTestScope);
   this.SimpleTest = simpleTestScope.SimpleTest;
 }
 Tester.prototype = {
   EventUtils: {},
   SimpleTest: {},
 
-  loops: 0,
+  repeat: 0,
   checker: null,
   currentTestIndex: -1,
   lastStartTime: null,
   get currentTest() {
     return this.tests[this.currentTestIndex];
   },
   get done() {
     return this.currentTestIndex == this.tests.length - 1;
   },
 
   start: function Tester_start() {
     //if testOnLoad was not called, then gConfig is not defined
     if(!gConfig)
       gConfig = readConfig();
-    this.loops = gConfig.loops;
+    this.repeat = gConfig.repeat;
     this.dumper.dump("*** Start BrowserChrome Test Results ***\n");
     this._cs.registerListener(this);
 
     if (this.tests.length)
       this.nextTest();
     else
       this.finish();
   },
@@ -122,18 +122,18 @@ Tester.prototype = {
       }
     }
 
     // Make sure the window is raised before each test.
     this.SimpleTest.waitForFocus(aCallback);
   },
 
   finish: function Tester_finish(aSkipSummary) {
-    if(this.loops > 0){
-      --this.loops;
+    if (this.repeat > 0) {
+      --this.repeat;
       this.currentTestIndex = -1;
       this.nextTest();
     }
     else{
       this._cs.unregisterListener(this);
   
       this.dumper.dump("\nINFO TEST-START | Shutdown\n");
       if (this.tests.length) {
--- a/testing/mochitest/runtests.py
+++ b/testing/mochitest/runtests.py
@@ -227,22 +227,22 @@ class MochitestOptions(optparse.OptionPa
     defaults["profilePath"] = tempfile.mkdtemp()
 
     self.add_option("--use-vmware-recording",
                     action = "store_true", dest = "vmwareRecording",
                     help = "enables recording while the application is running "
                            "inside a VMware Workstation 7.0 or later VM")
     defaults["vmwareRecording"] = False
 
-    self.add_option("--loops",
+    self.add_option("--repeat",
                     action = "store", type = "int",
-                    dest = "loops", metavar = "LOOPS",
-                    help = "repeats the test or set of tests the given number of times "
-                           "without restarting the browser (given number > 0)")
-    defaults["loops"] = 0
+                    dest = "repeat", metavar = "REPEAT",
+                    help = "repeats the test or set of tests the given number of times, ie: repeat=1 will run the test twice.")
+                   
+    defaults["repeat"] = 0
 
     # -h, --help are automatically handled by OptionParser
 
     self.set_defaults(**defaults)
 
     usage = """\
 Usage instructions for runtests.py.
 All arguments are optional.
@@ -436,17 +436,17 @@ class Mochitest(object):
   def getFullPath(self, path):
     " Get an absolute path relative to self.oldcwd."
     return os.path.normpath(os.path.join(self.oldcwd, os.path.expanduser(path)))
 
   def buildTestPath(self, options):
     """ Build the url path to the specific test harness and test file or directory """
     testHost = "http://mochi.test:8888"
     testURL = ("/").join([testHost, self.TEST_PATH, options.testPath])
-    if os.path.isfile(os.path.join(self.oldcwd, os.path.dirname(__file__), self.TEST_PATH, options.testPath)) and options.loops > 0:
+    if os.path.isfile(os.path.join(self.oldcwd, os.path.dirname(__file__), self.TEST_PATH, options.testPath)) and options.repeat > 0:
        testURL = ("/").join([testHost, self.PLAIN_LOOP_PATH])
     if options.chrome or options.a11y:
        testURL = ("/").join([testHost, self.CHROME_PATH])
     elif options.browserChrome:
       testURL = "about:blank"
     elif options.ipcplugins:
       testURL = ("/").join([testHost, self.TEST_PATH, "dom/plugins/test"])
     return testURL
@@ -543,17 +543,17 @@ class Mochitest(object):
 
         autorun -- kick off tests automatically
         closeWhenDone -- runs quit.js after tests
         hideResultsTable -- hides the table of individual test results
         logFile -- logs test run to an absolute path
         totalChunks -- how many chunks to split tests into
         thisChunk -- which chunk to run
         timeout -- per-test timeout in seconds
-        loops -- How many times to run the test
+        repeat -- How many times to repeat the test, ie: repeat=1 will run the test twice.
     """
   
     # allow relative paths for logFile
     if options.logFile:
       options.logFile = self.getLogFilePath(options.logFile)
     if options.browserChrome or options.chrome or options.a11y:
       self.makeTestConfig(options)
     else:
@@ -572,19 +572,19 @@ class Mochitest(object):
         self.urlOpts.append("totalChunks=%d" % options.totalChunks)
         self.urlOpts.append("thisChunk=%d" % options.thisChunk)
       if options.chunkByDir:
         self.urlOpts.append("chunkByDir=%d" % options.chunkByDir)
       if options.shuffle:
         self.urlOpts.append("shuffle=1")
       if "MOZ_HIDE_RESULTS_TABLE" in env and env["MOZ_HIDE_RESULTS_TABLE"] == "1":
         self.urlOpts.append("hideResultsTable=1")
-      if options.loops:
-        self.urlOpts.append("loops=%d" % options.loops)
-      if os.path.isfile(os.path.join(self.oldcwd, os.path.dirname(__file__), self.TEST_PATH, options.testPath)) and options.loops > 0:
+      if options.repeat:
+        self.urlOpts.append("repeat=%d" % options.repeat)
+      if os.path.isfile(os.path.join(self.oldcwd, os.path.dirname(__file__), self.TEST_PATH, options.testPath)) and options.repeat > 0:
         self.urlOpts.append("testname=%s" % ("/").join([self.TEST_PATH, options.testPath]))
 
   def cleanup(self, manifest, options):
     """ remove temporary files and profile """
     os.remove(manifest)
     shutil.rmtree(options.profilePath)
 
   def startVMwareRecording(self, options):
--- a/testing/mochitest/tests/SimpleTest/TestRunner.js
+++ b/testing/mochitest/tests/SimpleTest/TestRunner.js
@@ -124,17 +124,17 @@ TestRunner._checkForHangs = function() {
 
 TestRunner.requestLongerTimeout = function(factor) {
     TestRunner._timeoutFactor = factor;
 }
 
 /**
  * This is used to loop tests
 **/
-TestRunner.loops = 0;
+TestRunner.repeat = 0;
 TestRunner._currentLoop = 0;
 
 /**
  * This function is called after generating the summary.
 **/
 TestRunner.onComplete = null;
 
 /**
@@ -241,28 +241,28 @@ TestRunner.resetTests = function(listURL
 }
 
 /*
  * Used to run a single test in a loop and update the UI with the results
  */
 TestRunner.loopTest = function(testPath) {
   //must set the following line so that TestHarness.updateUI finds the right div to update
   document.getElementById("current-test-path").innerHTML = testPath;
-  var numLoops = TestRunner.loops;
+  var numLoops = TestRunner.repeat;
   var completed = 0; // keep track of how many tests have finished
 
   // function to kick off the test and to check when the test is complete
   function checkComplete() {
     var testWindow = window.open(testPath, 'test window'); // kick off the test or find the active window
     if (testWindow.document.readyState == "complete") {
       // the test is complete -> mark as complete
       TestRunner.currentTestURL = testPath;
       TestRunner.updateUI(testWindow.SimpleTest._tests);
       testWindow.close();
-      if (TestRunner.loops == completed  && TestRunner.onComplete) {
+      if (TestRunner.repeat == completed  && TestRunner.onComplete) {
         TestRunner.onComplete();
       }
       completed++;
     }
     else {
       // wait and check later
       setTimeout(checkComplete, 1000);
     }
@@ -311,24 +311,25 @@ TestRunner.runNextTest = function() {
           indicator.style.backgroundColor = "red";
         }
 
         TestRunner.log("TEST-START | Shutdown"); // used by automation.py
         TestRunner.log("Passed: " + $("pass-count").innerHTML);
         TestRunner.log("Failed: " + $("fail-count").innerHTML);
         TestRunner.log("Todo:   " + $("todo-count").innerHTML);
         // If we are looping, don't send this cause it closes the log file
-        if (TestRunner.loops == 0)
+        if (TestRunner.repeat == 0) {
           TestRunner.log("SimpleTest FINISHED");
+        }
 
-        if (TestRunner.loops == 0 && TestRunner.onComplete) {
+        if (TestRunner.repeat == 0 && TestRunner.onComplete) {
              TestRunner.onComplete();
          }
  
-        if (TestRunner._currentLoop < TestRunner.loops){
+        if (TestRunner._currentLoop < TestRunner.repeat) {
           TestRunner._currentLoop++;
           TestRunner.resetTests(TestRunner._urls);
         } else {
           // Loops are finished
           if (TestRunner.logEnabled) {
             TestRunner.log("TEST-INFO | Ran " + TestRunner._currentLoop + " Loops");
             TestRunner.log("SimpleTest FINISHED");
           }
@@ -477,12 +478,12 @@ TestRunner.updateUI = function(tests) {
   tds[0].style.backgroundColor = "#0d0";
   tds[0].innerHTML = parseInt(tds[0].innerHTML) + parseInt(results.OK);
   tds[1].style.backgroundColor = results.notOK > 0 ? "red" : "#0d0";
   tds[1].innerHTML = parseInt(tds[1].innerHTML) + parseInt(results.notOK);
   tds[2].style.backgroundColor = results.todo > 0 ? "orange" : "#0d0";
   tds[2].innerHTML = parseInt(tds[2].innerHTML) + parseInt(results.todo);
 
   //if we ran in a loop, display any found errors
-  if(TestRunner.loops > 0){
+  if (TestRunner.repeat > 0) {
     TestRunner.displayLoopErrors('fail-table', tests);
   }
 }
--- a/testing/mochitest/tests/SimpleTest/setup.js
+++ b/testing/mochitest/tests/SimpleTest/setup.js
@@ -104,18 +104,18 @@ if (params.timeout) {
   TestRunner.timeout = parseInt(params.timeout) * 1000;
 }
 
 // log levels for console and logfile
 var fileLevel =  params.fileLevel || null;
 var consoleLevel = params.consoleLevel || null;
 
 // loop tells us how many times to run the tests
-if (params.loops) {
-  TestRunner.loops = params.loops;
+if (params.repeat) {
+  TestRunner.repeat = params.repeat;
 } 
 
 // closeWhenDone tells us to call quit.js when complete
 if (params.closeWhenDone) {
   TestRunner.onComplete = goQuitApplication;
 }
 
 // logFile to write our results
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_author.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_author.xml
@@ -1,30 +1,30 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!--
-
-Description: atom author name works
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).name=='John Doe Entry';
-
--->
-
-<feed xmlns="http://www.w3.org/2005/Atom">
-  
-  <title>Example Feed</title>
-  <link href="http://example.org/"/>
-  <updated>2003-12-13T18:30:02Z</updated>
-  <author>
-       <name>John Doe</name>
-  </author>
-  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
-  
-  <entry>
-    <title>Atom-Powered Robots Run Amok</title>
-    <link href="http://example.org/2003/12/13/atom03"/>
-    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
-    <updated>2003-12-13T18:30:02Z</updated>
-    <summary>Some text.</summary>
-    <author>
-      <name>John Doe Entry</name>
-    </author>
-  </entry>
-  
-</feed>
\ No newline at end of file
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+
+Description: atom author name works
+Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).name=='John Doe Entry';
+
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+  <title>Example Feed</title>
+  <link href="http://example.org/"/>
+  <updated>2003-12-13T18:30:02Z</updated>
+  <author>
+       <name>John Doe</name>
+  </author>
+  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+  <entry>
+    <title>Atom-Powered Robots Run Amok</title>
+    <link href="http://example.org/2003/12/13/atom03"/>
+    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+    <updated>2003-12-13T18:30:02Z</updated>
+    <summary>Some text.</summary>
+    <author>
+      <name>John Doe Entry</name>
+    </author>
+  </entry>
+
+</feed>
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_contributor.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_contributor.xml
@@ -1,30 +1,30 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!--
-
-Description: atom author name works
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).contributors.queryElementAt(0, Components.interfaces.nsIFeedPerson).name=='John Doe Entry';
-
--->
-
-<feed xmlns="http://www.w3.org/2005/Atom">
-  
-  <title>Example Feed</title>
-  <link href="http://example.org/"/>
-  <updated>2003-12-13T18:30:02Z</updated>
-  <author>
-       <name>John Doe</name>
-  </author>
-  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
-  
-  <entry>
-    <title>Atom-Powered Robots Run Amok</title>
-    <link href="http://example.org/2003/12/13/atom03"/>
-    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
-    <updated>2003-12-13T18:30:02Z</updated>
-    <summary>Some text.</summary>
-    <contributor>
-      <name>John Doe Entry</name>
-    </contributor>
-  </entry>
-  
-</feed>
\ No newline at end of file
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+
+Description: atom author name works
+Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).contributors.queryElementAt(0, Components.interfaces.nsIFeedPerson).name=='John Doe Entry';
+
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+  <title>Example Feed</title>
+  <link href="http://example.org/"/>
+  <updated>2003-12-13T18:30:02Z</updated>
+  <author>
+       <name>John Doe</name>
+  </author>
+  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+  <entry>
+    <title>Atom-Powered Robots Run Amok</title>
+    <link href="http://example.org/2003/12/13/atom03"/>
+    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+    <updated>2003-12-13T18:30:02Z</updated>
+    <summary>Some text.</summary>
+    <contributor>
+      <name>John Doe Entry</name>
+    </contributor>
+  </entry>
+
+</feed>
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_published.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_published.xml
@@ -1,28 +1,28 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!--
-
-Description: atom published works
-Expect: var entry = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry); entry.published == 'Tue, 09 Dec 2003 18:30:02 GMT'
-
--->
-
-<feed xmlns="http://www.w3.org/2005/Atom">
-  
-  <title>Example Feed</title>
-  <link href="http://example.org/"/>
-  <updated>2003-12-13T18:30:02Z</updated>
-  <author>
-       <name>John Doe</name>
-  </author>
-  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
-  
-  <entry>
-    <title>Atom-Powered Robots Run Amok</title>
-    <link href="http://example.org/2003/12/13/atom03"/>
-    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
-    <updated>2003-12-13T18:30:02Z</updated>
-    <published>2003-12-09T18:30:02Z</published>
-    <summary>Some text.</summary>
-  </entry>
-  
-</feed>
\ No newline at end of file
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+
+Description: atom published works
+Expect: var entry = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry); entry.published == 'Tue, 09 Dec 2003 18:30:02 GMT'
+
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+  <title>Example Feed</title>
+  <link href="http://example.org/"/>
+  <updated>2003-12-13T18:30:02Z</updated>
+  <author>
+       <name>John Doe</name>
+  </author>
+  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+  <entry>
+    <title>Atom-Powered Robots Run Amok</title>
+    <link href="http://example.org/2003/12/13/atom03"/>
+    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+    <updated>2003-12-13T18:30:02Z</updated>
+    <published>2003-12-09T18:30:02Z</published>
+    <summary>Some text.</summary>
+  </entry>
+
+</feed>
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_updated.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_updated.xml
@@ -1,27 +1,27 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!--
-
-Description: atom updated works
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).updated == 'Sat, 13 Dec 2003 18:30:02 GMT'
-
--->
-
-<feed xmlns="http://www.w3.org/2005/Atom">
-  
-  <title>Example Feed</title>
-  <link href="http://example.org/"/>
-  <updated>2003-12-13T18:30:02Z</updated>
-  <author>
-       <name>John Doe</name>
-  </author>
-  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
-  
-  <entry>
-    <title>Atom-Powered Robots Run Amok</title>
-    <link href="http://example.org/2003/12/13/atom03"/>
-    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
-    <updated>2003-12-13T18:30:02Z</updated>
-    <summary>Some text.</summary>
-  </entry>
-  
-</feed>
\ No newline at end of file
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+
+Description: atom updated works
+Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).updated == 'Sat, 13 Dec 2003 18:30:02 GMT'
+
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+  <title>Example Feed</title>
+  <link href="http://example.org/"/>
+  <updated>2003-12-13T18:30:02Z</updated>
+  <author>
+       <name>John Doe</name>
+  </author>
+  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+  <entry>
+    <title>Atom-Powered Robots Run Amok</title>
+    <link href="http://example.org/2003/12/13/atom03"/>
+    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+    <updated>2003-12-13T18:30:02Z</updated>
+    <summary>Some text.</summary>
+  </entry>
+
+</feed>
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_author.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_author.xml
@@ -1,12 +1,12 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!--
-
-Description: atom author count works
-Expect: feed.authors.length == 1;
-
--->
-<feed xmlns="http://www.w3.org/2005/Atom">
-<title>test title</title>
-<author>
-</author>
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+
+Description: atom author count works
+Expect: feed.authors.length == 1;
+
+-->
+<feed xmlns="http://www.w3.org/2005/Atom">
+<title>test title</title>
+<author>
+</author>
 </feed>
\ No newline at end of file
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_author2.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_author2.xml
@@ -1,14 +1,14 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!--
-
-Description: atom author count works
-Expect: feed.authors.length == 2
-
--->
-<feed xmlns="http://www.w3.org/2005/Atom">
-<title>test title</title>
-<author>
-</author>
-<author>
-</author>
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+
+Description: atom author count works
+Expect: feed.authors.length == 2
+
+-->
+<feed xmlns="http://www.w3.org/2005/Atom">
+<title>test title</title>
+<author>
+</author>
+<author>
+</author>
 </feed>
\ No newline at end of file
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_author_email.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_author_email.xml
@@ -1,14 +1,14 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!--
-
-Description: atom author name works
-Expect: feed.authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).email=='hmm@example.com';
-
--->
-<feed xmlns="http://www.w3.org/2005/Atom">
-<title>test title</title>
-<author>
-<email>hmm@example.com</email>
-<name>foo</name>
-</author>
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+
+Description: atom author name works
+Expect: feed.authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).email=='hmm@example.com';
+
+-->
+<feed xmlns="http://www.w3.org/2005/Atom">
+<title>test title</title>
+<author>
+<email>hmm@example.com</email>
+<name>foo</name>
+</author>
 </feed>
\ No newline at end of file
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_author_email_2.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_author_email_2.xml
@@ -1,18 +1,18 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!--
-
-Description: atom author name works
-Expect: feed.authors.queryElementAt(1, Components.interfaces.nsIFeedPerson).email=='bar@example.com';
-
--->
-<feed xmlns="http://www.w3.org/2005/Atom">
-<title>test title</title>
-<author>
-<email>hmm@example.com</email>
-<name>foo</name>
-</author>
-<author>
-<email>bar@example.com</email>
-<name>foo</name>
-</author>
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+
+Description: atom author name works
+Expect: feed.authors.queryElementAt(1, Components.interfaces.nsIFeedPerson).email=='bar@example.com';
+
+-->
+<feed xmlns="http://www.w3.org/2005/Atom">
+<title>test title</title>
+<author>
+<email>hmm@example.com</email>
+<name>foo</name>
+</author>
+<author>
+<email>bar@example.com</email>
+<name>foo</name>
+</author>
 </feed>
\ No newline at end of file
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_author_name.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_author_name.xml
@@ -1,13 +1,13 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!--
-
-Description: atom author name works
-Expect: feed.authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).name=='foo';
-
--->
-<feed xmlns="http://www.w3.org/2005/Atom">
-<title>test title</title>
-<author>
-<name>foo</name>
-</author>
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+
+Description: atom author name works
+Expect: feed.authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).name=='foo';
+
+-->
+<feed xmlns="http://www.w3.org/2005/Atom">
+<title>test title</title>
+<author>
+<name>foo</name>
+</author>
 </feed>
\ No newline at end of file
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_author_surrounded.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_author_surrounded.xml
@@ -1,27 +1,27 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!--
-
-Description: atom author name works
-Expect: feed.authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).name=='John Doe';
-
--->
-
-<feed xmlns="http://www.w3.org/2005/Atom">
-  
-  <title>Example Feed</title>
-  <link href="http://example.org/"/>
-  <updated>2003-12-13T18:30:02Z</updated>
-  <author>
-       <name>John Doe</name>
-  </author>
-  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
-  
-  <entry>
-    <title>Atom-Powered Robots Run Amok</title>
-    <link href="http://example.org/2003/12/13/atom03"/>
-    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
-    <updated>2003-12-13T18:30:02Z</updated>
-    <summary>Some text.</summary>
-  </entry>
-  
-</feed>
\ No newline at end of file
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+
+Description: atom author name works
+Expect: feed.authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).name=='John Doe';
+
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+  <title>Example Feed</title>
+  <link href="http://example.org/"/>
+  <updated>2003-12-13T18:30:02Z</updated>
+  <author>
+       <name>John Doe</name>
+  </author>
+  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+  <entry>
+    <title>Atom-Powered Robots Run Amok</title>
+    <link href="http://example.org/2003/12/13/atom03"/>
+    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+    <updated>2003-12-13T18:30:02Z</updated>
+    <summary>Some text.</summary>
+  </entry>
+
+</feed>
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_author_uri.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_author_uri.xml
@@ -1,20 +1,20 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!--
-
-Description: atom author uri works
-Expect: feed.authors.queryElementAt(1, Components.interfaces.nsIFeedPerson).uri.spec =='http://example.com/';
-
--->
-<feed xmlns="http://www.w3.org/2005/Atom">
-<title>test title</title>
-<author>
-<email>hmm@example.com</email>
-<name>foo</name>
-<uri>http://example.org</uri>
-</author>
-<author>
-<email>bar@example.com</email>
-<name>foo</name>
-<uri>http://example.com/</uri>
-</author>
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+
+Description: atom author uri works
+Expect: feed.authors.queryElementAt(1, Components.interfaces.nsIFeedPerson).uri.spec =='http://example.com/';
+
+-->
+<feed xmlns="http://www.w3.org/2005/Atom">
+<title>test title</title>
+<author>
+<email>hmm@example.com</email>
+<name>foo</name>
+<uri>http://example.org</uri>
+</author>
+<author>
+<email>bar@example.com</email>
+<name>foo</name>
+<uri>http://example.com/</uri>
+</author>
 </feed>
\ No newline at end of file
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_comment_rss_extra_att.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_comment_rss_extra_att.xml
@@ -1,29 +1,29 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!--
-
-Description: wfw works with extra attribute
-Expect: feed.fields.getProperty('wfw:commentRss') == 'http://example.org'
-
--->
-
-<feed xmlns="http://www.w3.org/2005/Atom"
-      xmlns:foo="http://example.org"
-      xmlns:bla="http://wellformedweb.org/CommentAPI/">
-  
-  <title>Example Feed</title>
-  <link href="http://example.org/"/>
-  <updated>2003-12-13T18:30:02Z</updated>
-  <author>
-       <name>John Doe</name>
-  </author>
-  <id foo:bar="baz">urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
-  <bla:commentRss hmm="yeah">http://example.org</bla:commentRss>
-  <entry>
-    <title>Atom-Powered Robots Run Amok</title>
-    <link href="http://example.org/2003/12/13/atom03"/>
-    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
-    <updated>2003-12-13T18:30:02Z</updated>
-    <summary>Some text.</summary>
-  </entry>
-  
-</feed>
\ No newline at end of file
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+
+Description: wfw works with extra attribute
+Expect: feed.fields.getProperty('wfw:commentRss') == 'http://example.org'
+
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom"
+      xmlns:foo="http://example.org"
+      xmlns:bla="http://wellformedweb.org/CommentAPI/">
+
+  <title>Example Feed</title>
+  <link href="http://example.org/"/>
+  <updated>2003-12-13T18:30:02Z</updated>
+  <author>
+       <name>John Doe</name>
+  </author>
+  <id foo:bar="baz">urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+  <bla:commentRss hmm="yeah">http://example.org</bla:commentRss>
+  <entry>
+    <title>Atom-Powered Robots Run Amok</title>
+    <link href="http://example.org/2003/12/13/atom03"/>
+    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+    <updated>2003-12-13T18:30:02Z</updated>
+    <summary>Some text.</summary>
+  </entry>
+
+</feed>
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_id.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_id.xml
@@ -1,27 +1,27 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!--
-
-Description: atom author name works
-Expect: feed.fields.getProperty('atom:id') == 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6' && feed.id == 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6'
-
--->
-
-<feed xmlns="http://www.w3.org/2005/Atom">
-  
-  <title>Example Feed</title>
-  <link href="http://example.org/"/>
-  <updated>2003-12-13T18:30:02Z</updated>
-  <author>
-       <name>John Doe</name>
-  </author>
-  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
-  
-  <entry>
-    <title>Atom-Powered Robots Run Amok</title>
-    <link href="http://example.org/2003/12/13/atom03"/>
-    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
-    <updated>2003-12-13T18:30:02Z</updated>
-    <summary>Some text.</summary>
-  </entry>
-  
-</feed>
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+
+Description: atom author name works
+Expect: feed.fields.getProperty('atom:id') == 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6' && feed.id == 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6'
+
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+  <title>Example Feed</title>
+  <link href="http://example.org/"/>
+  <updated>2003-12-13T18:30:02Z</updated>
+  <author>
+       <name>John Doe</name>
+  </author>
+  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+  <entry>
+    <title>Atom-Powered Robots Run Amok</title>
+    <link href="http://example.org/2003/12/13/atom03"/>
+    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+    <updated>2003-12-13T18:30:02Z</updated>
+    <summary>Some text.</summary>
+  </entry>
+
+</feed>
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_id_extra_att.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_id_extra_att.xml
@@ -1,28 +1,28 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!--
-
-Description: atom feed id works with extra attribute
-Expect: feed.fields.getProperty('atom:id') == 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6'
-
--->
-
-<feed xmlns="http://www.w3.org/2005/Atom"
-      xmlns:foo="http://example.org">
-  
-  <title>Example Feed</title>
-  <link href="http://example.org/"/>
-  <updated>2003-12-13T18:30:02Z</updated>
-  <author>
-       <name>John Doe</name>
-  </author>
-  <id foo:bar="baz">urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
-  
-  <entry>
-    <title>Atom-Powered Robots Run Amok</title>
-    <link href="http://example.org/2003/12/13/atom03"/>
-    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
-    <updated>2003-12-13T18:30:02Z</updated>
-    <summary>Some text.</summary>
-  </entry>
-  
-</feed>
\ No newline at end of file
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+
+Description: atom feed id works with extra attribute
+Expect: feed.fields.getProperty('atom:id') == 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6'
+
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom"
+      xmlns:foo="http://example.org">
+
+  <title>Example Feed</title>
+  <link href="http://example.org/"/>
+  <updated>2003-12-13T18:30:02Z</updated>
+  <author>
+       <name>John Doe</name>
+  </author>
+  <id foo:bar="baz">urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+  <entry>
+    <title>Atom-Powered Robots Run Amok</title>
+    <link href="http://example.org/2003/12/13/atom03"/>
+    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+    <updated>2003-12-13T18:30:02Z</updated>
+    <summary>Some text.</summary>
+  </entry>
+
+</feed>
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_title.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_title.xml
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!--
-
-Description: atom title works
-Expect:      feed.title.text == 'test title'
-
--->
-<feed xmlns="http://www.w3.org/2005/Atom">
-<title>test title</title>
-</feed>
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+
+Description: atom title works
+Expect:      feed.title.text == 'test title'
+
+-->
+<feed xmlns="http://www.w3.org/2005/Atom">
+<title>test title</title>
+</feed>
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_updated_normalized.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_updated_normalized.xml
@@ -1,27 +1,27 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!--
-
-Description: atom updated works
-Expect: feed.updated == 'Sat, 13 Dec 2003 18:30:02 GMT'
-
--->
-
-<feed xmlns="http://www.w3.org/2005/Atom">
-  
-  <title>Example Feed</title>
-  <link href="http://example.org/"/>
-  <updated>2003-12-13T18:30:02Z</updated>
-  <author>
-       <name>John Doe</name>
-  </author>
-  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
-  
-  <entry>
-    <title>Atom-Powered Robots Run Amok</title>
-    <link href="http://example.org/2003/12/13/atom03"/>
-    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
-    <updated>2003-12-13T18:30:02Z</updated>
-    <summary>Some text.</summary>
-  </entry>
-  
-</feed>
\ No newline at end of file
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+
+Description: atom updated works
+Expect: feed.updated == 'Sat, 13 Dec 2003 18:30:02 GMT'
+
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+  <title>Example Feed</title>
+  <link href="http://example.org/"/>
+  <updated>2003-12-13T18:30:02Z</updated>
+  <author>
+       <name>John Doe</name>
+  </author>
+  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+  <entry>
+    <title>Atom-Powered Robots Run Amok</title>
+    <link href="http://example.org/2003/12/13/atom03"/>
+    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+    <updated>2003-12-13T18:30:02Z</updated>
+    <summary>Some text.</summary>
+  </entry>
+
+</feed>
--- a/toolkit/components/places/PlacesDBUtils.jsm
+++ b/toolkit/components/places/PlacesDBUtils.jsm
@@ -17,16 +17,17 @@
  *
  * The Initial Developer of the Original Code is
  * the Mozilla Foundation.
  * Portions created by the Initial Developer are Copyright (C) 2008
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Marco Bonardo <mak77@bonardo.net> (Original Author)
+ *   Richard Newman <rnewman@mozilla.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * 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
@@ -298,17 +299,38 @@ let PlacesDBUtils = {
     stmts.forEach(function (aStmt) aStmt.finalize());
   },
 
   _getBoundCoherenceStatements: function PDBU__getBoundCoherenceStatements()
   {
     let cleanupStatements = [];
 
     // MOZ_ANNO_ATTRIBUTES
-    // A.1 remove unused attributes
+    // A.1 remove obsolete annotations from moz_annos.
+    // The 'weave0' idiom exploits character ordering (0 follows /) to
+    // efficiently select all annos with a 'weave/' prefix.
+    let deleteObsoleteAnnos = DBConn.createAsyncStatement(
+      "DELETE FROM moz_annos "                      +
+      "WHERE anno_attribute_id IN ( "               +
+      "  SELECT id FROM moz_anno_attributes "       +
+      "  WHERE name BETWEEN 'weave/' AND 'weave0' " +
+      ")");
+    cleanupStatements.push(deleteObsoleteAnnos);
+
+    // A.2 remove obsolete annotations from moz_items_annos.
+    let deleteObsoleteItemsAnnos = DBConn.createAsyncStatement(
+      "DELETE FROM moz_items_annos "                +
+      "WHERE anno_attribute_id IN ( "               +
+      "  SELECT id FROM moz_anno_attributes "       +
+      "  WHERE name = 'sync/children' "             +
+      "     OR name BETWEEN 'weave/' AND 'weave0' " +
+      ")");
+    cleanupStatements.push(deleteObsoleteItemsAnnos);
+
+    // A.3 remove unused attributes.
     let deleteUnusedAnnoAttributes = DBConn.createAsyncStatement(
       "DELETE FROM moz_anno_attributes WHERE id IN ( " +
         "SELECT id FROM moz_anno_attributes n " +
         "WHERE NOT EXISTS " +
             "(SELECT id FROM moz_annos WHERE anno_attribute_id = n.id LIMIT 1) " +
           "AND NOT EXISTS " +
             "(SELECT id FROM moz_items_annos WHERE anno_attribute_id = n.id LIMIT 1) " +
       ")");
--- a/toolkit/components/places/tests/unit/test_preventive_maintenance.js
+++ b/toolkit/components/places/tests/unit/test_preventive_maintenance.js
@@ -104,17 +104,17 @@ function addBookmark(aPlaceId, aType, aP
 // Tests
 
 let tests = [];
 let current_test = null;
 
 //------------------------------------------------------------------------------
 
 tests.push({
-  name: "A.1",
+  name: "A.3",
   desc: "Remove unused attributes",
 
   _usedPageAttribute: "usedPage",
   _usedItemAttribute: "usedItem",
   _unusedAttribute: "unused",
   _placeId: null,
   _bookmarkId: null,
 
@@ -139,17 +139,17 @@ tests.push({
     stmt.params['place_id'] = this._placeId;
     stmt.params['anno'] = this._usedPageAttribute;
     stmt.execute();
     stmt.finalize();
     stmt = mDBConn.createStatement("INSERT INTO moz_items_annos (item_id, anno_attribute_id) VALUES(:item_id, (SELECT id FROM moz_anno_attributes WHERE name = :anno))");
     stmt.params['item_id'] = this._bookmarkId;
     stmt.params['anno'] = this._usedItemAttribute;
     stmt.execute();
-    stmt.finalize();    
+    stmt.finalize();
   },
 
   check: function() {
     // Check that used attributes are still there
     let stmt = mDBConn.createStatement("SELECT id FROM moz_anno_attributes WHERE name = :anno");
     stmt.params['anno'] = this._usedPageAttribute;
     do_check_true(stmt.executeStep());
     stmt.reset();
@@ -482,17 +482,17 @@ tests.push({
     stmt.reset();
     stmt.params["item_id"] = this._orphanFolderId;
     stmt.params["parent"] = bs.unfiledBookmarksFolder;
     do_check_true(stmt.executeStep());
     stmt.reset();
     stmt.params["item_id"] = this._bookmarkId;
     stmt.params["parent"] = this._orphanFolderId;
     do_check_true(stmt.executeStep());
-    stmt.finalize();    
+    stmt.finalize();
   }
 });
 
 //------------------------------------------------------------------------------
 
 tests.push({
   name: "D.5",
   desc: "Fix wrong keywords",
@@ -620,17 +620,17 @@ tests.push({
 
   _validDynamicContainerId: null,
   _invalidDynamicContainerId: null,
 
   setup: function() {
     // Add a valid dynamic container with a folder type
     this._validDynamicContainerId = addBookmark(null, bs.TYPE_DYNAMIC_CONTAINER, null, null, "test");
     // Add an invalid dynamic container without a folder type
-    this._invalidDynamicContainerId = addBookmark(null, bs.TYPE_DYNAMIC_CONTAINER, null, null, null);    
+    this._invalidDynamicContainerId = addBookmark(null, bs.TYPE_DYNAMIC_CONTAINER, null, null, null);
   },
 
   check: function() {
     // Check valid dynamic container is still there
     let stmt = mDBConn.createStatement("SELECT id FROM moz_bookmarks WHERE id = :item_id AND type = :type");
     stmt.params["item_id"] = this._validDynamicContainerId;
     stmt.params["type"] = bs.TYPE_DYNAMIC_CONTAINER;
     do_check_true(stmt.executeStep());
@@ -681,17 +681,17 @@ tests.push({
     stmt.reset();
     stmt.params["item_id"] = this._bookmarkId2;
     stmt.params["parent"] = bs.unfiledBookmarksFolder;
     do_check_true(stmt.executeStep());
     stmt.reset();
     stmt.params["item_id"] = this._bookmarkId3;
     stmt.params["parent"] = bs.unfiledBookmarksFolder;
     do_check_true(stmt.executeStep());
-    stmt.finalize();    
+    stmt.finalize();
   }
 });
 
 //------------------------------------------------------------------------------
 
 tests.push({
   name: "D.10",
   desc: "Recalculate positions",
@@ -957,17 +957,17 @@ tests.push({
     // Add input history entries
     let stmt = mDBConn.createStatement("INSERT INTO moz_inputhistory (place_id, input) VALUES (:place_id, :input)");
     stmt.params["place_id"] = this._placeId;
     stmt.params["input"] = "moz";
     stmt.execute();
     stmt.reset();
     stmt.params["place_id"] = this._invalidPlaceId;
     stmt.params["input"] = "moz";
-    stmt.execute();    
+    stmt.execute();
     stmt.finalize();
   },
 
   check: function() {
     // Check that inputhistory on valid place is still there
     let stmt = mDBConn.createStatement("SELECT place_id FROM moz_inputhistory WHERE place_id = :place_id");
     stmt.params["place_id"] = this._placeId;
     do_check_true(stmt.executeStep());
@@ -1214,17 +1214,17 @@ tests.push({
     as.setPageAnnotation(this._uri2, "anno", "anno", 0, as.EXPIRE_NEVER);
     as.setItemAnnotation(this._bookmarkId, "anno", "anno", 0, as.EXPIRE_NEVER);
   },
 
   check: function() {
     // Check that all items are correct
     do_check_true(bh.isVisited(this._uri1));
     do_check_true(bh.isVisited(this._uri2));
-    
+
     do_check_eq(bs.getBookmarkURI(this._bookmarkId).spec, this._uri1.spec);
     do_check_eq(bs.getItemIndex(this._folderId), 0);
 
     do_check_eq(bs.getItemType(this._folderId), bs.TYPE_FOLDER);
     do_check_eq(bs.getItemType(this._separatorId), bs.TYPE_SEPARATOR);
 
     do_check_eq(ts.getTagsForURI(this._uri1).length, 1);
     do_check_eq(bs.getKeywordForBookmark(this._bookmarkId), "testkeyword");
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -3067,30 +3067,35 @@ XRE_main(int argc, char* argv[], const n
         PR_fprintf(PR_STDERR, "Error: no display specified\n");
         return 1;
       }
     }
 #endif /* MOZ_WIDGET_GTK2 */
 
 #ifdef MOZ_ENABLE_XREMOTE
     // handle -remote now that xpcom is fired up
+    bool disableRemote = false;
+    {
+      char *e = PR_GetEnv("MOZ_NO_REMOTE");
+      disableRemote = (e && *e);
+    }
 
     const char* xremotearg;
     ar = CheckArg("remote", PR_TRUE, &xremotearg);
     if (ar == ARG_BAD) {
       PR_fprintf(PR_STDERR, "Error: -remote requires an argument\n");
       return 1;
     }
     const char* desktopStartupIDPtr =
       desktopStartupID.IsEmpty() ? nsnull : desktopStartupID.get();
     if (ar) {
       return HandleRemoteArgument(xremotearg, desktopStartupIDPtr);
     }
 
-    if (!PR_GetEnv("MOZ_NO_REMOTE")) {
+    if (!disableRemote) {
       // Try to remote the entire command line. If this fails, start up normally.
       RemoteResult rr = RemoteCommandLine(desktopStartupIDPtr);
       if (rr == REMOTE_FOUND)
         return 0;
       else if (rr == REMOTE_ARG_BAD)
         return 1;
     }
 #endif
@@ -3522,17 +3527,18 @@ XRE_main(int argc, char* argv[], const n
 
 #ifdef MOZ_ENABLE_XREMOTE
         nsCOMPtr<nsIRemoteService> remoteService;
 #endif /* MOZ_ENABLE_XREMOTE */
         if (!shuttingDown) {
 #ifdef MOZ_ENABLE_XREMOTE
           // if we have X remote support, start listening for requests on the
           // proxy window.
-          remoteService = do_GetService("@mozilla.org/toolkit/remote-service;1");
+          if (!disableRemote)
+            remoteService = do_GetService("@mozilla.org/toolkit/remote-service;1");
           if (remoteService)
             remoteService->Startup(gAppData->name,
                                    PromiseFlatCString(profileName).get());
 #endif /* MOZ_ENABLE_XREMOTE */
 
           nativeApp->Enable();
         }
 
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -1454,51 +1454,43 @@ nsresult nsExternalAppHandler::SetUpTemp
   mMimeInfo->GetPrimaryExtension(ext);
   if (!ext.IsEmpty()) {
     ext.ReplaceChar(FILE_PATH_SEPARATOR FILE_ILLEGAL_CHARACTERS, '_');
     if (ext.First() != '.')
       tempLeafName.Append('.');
     tempLeafName.Append(ext);
   }
 
-#ifdef XP_WIN
-  // On windows, we need to temporarily create a dummy file with the correct
+  // We need to temporarily create a dummy file with the correct
   // file extension to determine the executable-ness, so do this before adding
   // the extra .part extension.
   nsCOMPtr<nsIFile> dummyFile;
   rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(dummyFile));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Set the file name without .part
   rv = dummyFile->Append(NS_ConvertUTF8toUTF16(tempLeafName));
   NS_ENSURE_SUCCESS(rv, rv);
   rv = dummyFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Store executable-ness then delete
   dummyFile->IsExecutable(&mTempFileIsExecutable);
   dummyFile->Remove(PR_FALSE);
-#endif
 
   // Add an additional .part to prevent the OS from running this file in the
   // default application.
   tempLeafName.Append(NS_LITERAL_CSTRING(".part"));
 
   rv = mTempFile->Append(NS_ConvertUTF8toUTF16(tempLeafName));
   // make this file unique!!!
   NS_ENSURE_SUCCESS(rv, rv);
   rv = mTempFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600);
   NS_ENSURE_SUCCESS(rv, rv);
 
-#ifndef XP_WIN
-  // On other platforms, the file permission bits are used, so we can just call
-  // IsExecutable
-  mTempFile->IsExecutable(&mTempFileIsExecutable);
-#endif
-
   nsCOMPtr<nsIOutputStream> outputStream;
   rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), mTempFile,
                                    PR_WRONLY | PR_CREATE_FILE, 0600);
   if (NS_FAILED(rv)) {
     mTempFile->Remove(PR_FALSE);
     return rv;
   }
 
--- a/widget/public/nsGUIEvent.h
+++ b/widget/public/nsGUIEvent.h
@@ -61,16 +61,19 @@
 #include "nsIVariant.h"
 #include "nsStyleConsts.h"
 
 namespace mozilla {
 namespace dom {
   class PBrowserParent;
   class PBrowserChild;
 }
+namespace plugins {
+  class PPluginInstanceChild;
+}
 }
 
 #ifdef ACCESSIBILITY
 class nsAccessible;
 #endif
 class nsRenderingContext;
 class nsIMenuItem;
 class nsIContent;
@@ -1117,16 +1120,17 @@ struct nsTextRange
 
 typedef nsTextRange* nsTextRangeArray;
 
 class nsTextEvent : public nsInputEvent
 {
 private:
   friend class mozilla::dom::PBrowserParent;
   friend class mozilla::dom::PBrowserChild;
+  friend class mozilla::plugins::PPluginInstanceChild;
 
   nsTextEvent()
   {
   }
 
 public:
   PRUint32 seqno;
 
--- a/widget/src/qt/Makefile.in
+++ b/widget/src/qt/Makefile.in
@@ -77,16 +77,20 @@ CPPSRCS	= \
 		nsSound.cpp \
 		nsFilePicker.cpp \
 		nsPrintOptionsQt.cpp \
 		nsPrintSettingsQt.cpp \
 		nsPrintDialogQt.cpp \
 		nsDeviceContextSpecQt.cpp \
 		$(NULL)
 
+EXPORTS		= \
+		nsQtKeyUtils.h \
+		$(NULL)
+
 ifdef MOZ_ENABLE_QTMOBILITY
 MOCSRCS += moc_mozqorientationsensorfilter.cpp
 CPPSRCS += mozqorientationsensorfilter.cpp
 endif
 
 SHARED_LIBRARY_LIBS = ../xpwidgets/libxpwidgets_s.a
 
 # If not primary toolkit, install in secondary path