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 76200 31b79d4e90f45f9e8922098b109748029663db8b
parent 76168 e6591ea9b27b4f3a652a11645aa63ccfae67603e (current diff)
parent 76199 2642c7b0dc60937f33bb032da5f06516ee9c6d50 (diff)
child 76201 04a58ba1ce1e2bfc3b681cc445c9b6ea26b6de0b
child 76216 fdfc74d7e8268802102a28977b00204b89421140
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
milestone9.0a1
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