Merge last green changeset of mozilla-inbound to mozilla-central
authorEd Morley <bmo@edmorley.co.uk>
Fri, 09 Dec 2011 11:12:51 +0000
changeset 109007 f159717b4e7d3ff94b59e7c7e1ba920c578118a8
parent 109006 7e5b3f29e44a6140af8edc71552c32a906c3862c (current diff)
parent 83150 6bafbaa9ac33d146df75546a7a47dc1fd59b4c7a (diff)
child 109008 9249b43d89a0016fea33768e4bd27d1f92f20f81
push id2248
push userakeybl@mozilla.com
push dateMon, 08 Oct 2012 19:23:44 +0000
treeherdermozilla-aurora@118a3b748323 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone11.0a1
Merge last green changeset of mozilla-inbound to mozilla-central
accessible/src/base/nsAccessible.cpp
accessible/src/base/nsAccessible.h
accessible/src/html/nsHTMLSelectAccessible.cpp
accessible/src/html/nsHTMLSelectAccessible.h
accessible/src/xul/nsXULMenuAccessible.cpp
accessible/src/xul/nsXULMenuAccessible.h
accessible/src/xul/nsXULTreeAccessible.cpp
accessible/src/xul/nsXULTreeAccessible.h
accessible/tests/mochitest/focus/test_takeFocus.html
b2g/chrome/jar.mn
b2g/installer/package-manifest.in
browser/base/content/browser.js
browser/base/content/browser.xul
browser/themes/gnomestripe/places/searching_16.png
browser/themes/pinstripe/places/searching_16.png
browser/themes/winstripe/places/searching_16.png
configure.in
content/base/src/nsCSPService.cpp
content/base/src/nsGkAtomList.h
content/base/src/nsXMLHttpRequest.cpp
content/base/test/Makefile.in
content/base/test/test_XHR.html
content/canvas/src/nsCanvasRenderingContext2D.cpp
content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
content/events/src/nsEventStateManager.cpp
content/html/content/src/nsDOMStringMap.cpp
content/media/webm/nsWebMReader.h
content/smil/nsSMILTimeValueSpec.cpp
content/smil/nsSMILTimeValueSpec.h
dom/base/nsDOMWindowUtils.cpp
dom/base/nsJSEnvironment.cpp
dom/locales/en-US/chrome/dom/dom.properties
dom/plugins/base/nsPluginHost.cpp
gfx/layers/basic/BasicLayers.cpp
image/test/mochitest/Makefile.in
js/src/Makefile.in
js/src/configure.in
js/src/gc/Barrier.h
js/src/jsanalyze.h
js/src/jsapi.cpp
js/src/jscntxt.cpp
js/src/jscntxtinlines.h
js/src/jsdbgapi.cpp
js/src/jsexn.cpp
js/src/jsfun.cpp
js/src/jsgcmark.cpp
js/src/jsinterp.cpp
js/src/jsnum.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsopcode.cpp
js/src/jsopcode.h
js/src/jspropertycache.cpp
js/src/jsprvtd.h
js/src/jsscript.cpp
js/src/jsscript.h
js/src/jsstr.cpp
js/src/jsutil.h
js/src/jsxml.cpp
js/src/methodjit/Compiler.cpp
js/src/methodjit/StubCalls.cpp
js/src/shell/js.cpp
js/src/vm/Debugger.cpp
js/src/vm/GlobalObject.cpp
layout/base/FrameLayerBuilder.cpp
layout/base/RestyleTracker.cpp
layout/base/nsPresShell.cpp
layout/reftests/canvas/reftest.list
mobile/android/base/AndroidManifest.xml.in
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/android/base/Makefile.in
mobile/android/base/resources/values/arrays.xml
netwerk/base/src/nsInputStreamPump.cpp
netwerk/protocol/http/nsAHttpTransaction.h
netwerk/protocol/http/nsHttpConnection.cpp
netwerk/protocol/http/nsHttpConnection.h
netwerk/protocol/http/nsHttpConnectionMgr.cpp
netwerk/protocol/http/nsHttpPipeline.cpp
netwerk/protocol/http/nsHttpPipeline.h
netwerk/protocol/http/nsHttpTransaction.cpp
storage/src/mozStorageConnection.cpp
storage/src/mozStorageConnection.h
toolkit/components/aboutmemory/content/aboutMemory.js
toolkit/components/telemetry/TelemetryHistograms.h
toolkit/components/telemetry/TelemetryPing.js
toolkit/content/license.html
toolkit/mozapps/extensions/content/extensions.js
toolkit/xre/nsAppRunner.cpp
view/src/nsViewManager.cpp
widget/src/gtk2/nsWindow.cpp
widget/src/qt/nsWindow.cpp
widget/src/windows/nsWindowGfx.cpp
xpcom/base/nsMemoryReporterManager.cpp
xulrunner/makefiles.sh
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -1061,52 +1061,37 @@ NS_IMETHODIMP nsAccessible::TakeSelectio
       selectable->ClearSelection();
     }
     return SetSelected(true);
   }
 
   return NS_ERROR_FAILURE;
 }
 
-/* void takeFocus (); */
 NS_IMETHODIMP
 nsAccessible::TakeFocus()
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsIFrame *frame = GetFrame();
   NS_ENSURE_STATE(frame);
 
   nsIContent* focusContent = mContent;
 
-  // If the current element can't take real DOM focus and if it has an ID and
-  // an ancestor with an aria-activedescendant attribute present, then set DOM
-  // focus to that ancestor and set aria-activedescendant on the ancestor to
-  // the ID of the desired element.
+  // If the accessible focus is managed by container widget then focus the
+  // widget and set the accessible as its current item.
   if (!frame->IsFocusable()) {
-    nsAutoString id;
-    if (nsCoreUtils::GetID(mContent, id)) {
-
-      nsIContent* ancestorContent = mContent;
-      while ((ancestorContent = ancestorContent->GetParent()) &&
-             !ancestorContent->HasAttr(kNameSpaceID_None,
-                                       nsGkAtoms::aria_activedescendant));
-
-      if (ancestorContent) {
-        nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
-        if (presShell) {
-          nsIFrame *frame = ancestorContent->GetPrimaryFrame();
-          if (frame && frame->IsFocusable()) {
-            focusContent = ancestorContent;
-            focusContent->SetAttr(kNameSpaceID_None,
-                                  nsGkAtoms::aria_activedescendant,
-                                  id, true);
-          }
-        }
+    nsAccessible* widget = ContainerWidget();
+    if (widget && widget->AreItemsOperable()) {
+      nsIContent* widgetElm = widget->GetContent();
+      nsIFrame* widgetFrame = widgetElm->GetPrimaryFrame();
+      if (widgetFrame && widgetFrame->IsFocusable()) {
+        focusContent = widgetElm;
+        widget->SetCurrentItem(this);
       }
     }
   }
 
   nsCOMPtr<nsIDOMElement> element(do_QueryInterface(focusContent));
   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
   if (fm)
     fm->SetFocus(element, 0);
@@ -2932,16 +2917,28 @@ nsAccessible::CurrentItem()
       nsDocAccessible* document = GetDocAccessible();
       if (document)
         return document->GetAccessible(activeDescendantElm);
     }
   }
   return nsnull;
 }
 
+void
+nsAccessible::SetCurrentItem(nsAccessible* aItem)
+{
+  nsIAtom* id = aItem->GetContent()->GetID();
+  if (id) {
+    nsAutoString idStr;
+    id->ToString(idStr);
+    mContent->SetAttr(kNameSpaceID_None,
+                      nsGkAtoms::aria_activedescendant, idStr, true);
+  }
+}
+
 nsAccessible*
 nsAccessible::ContainerWidget() const
 {
   nsIAtom* idAttribute = mContent->GetIDAttributeName();
   if (idAttribute) {
     if (mContent->HasAttr(kNameSpaceID_None, idAttribute)) {
       for (nsAccessible* parent = Parent(); parent; parent = parent->Parent()) {
         nsIContent* parentContent = parent->GetContent();
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -584,16 +584,21 @@ public:
 
   /**
    * Return the current item of the widget, i.e. an item that has or will have
    * keyboard focus when widget gets active.
    */
   virtual nsAccessible* CurrentItem();
 
   /**
+   * Set the current item of the widget.
+   */
+  virtual void SetCurrentItem(nsAccessible* aItem);
+
+  /**
    * Return container widget this accessible belongs to.
    */
   virtual nsAccessible* ContainerWidget() const;
 
 protected:
 
   //////////////////////////////////////////////////////////////////////////////
   // Initializing, cache and tree traverse methods
--- a/accessible/src/html/nsHTMLSelectAccessible.cpp
+++ b/accessible/src/html/nsHTMLSelectAccessible.cpp
@@ -146,16 +146,24 @@ nsHTMLSelectListAccessible::CurrentItem(
       nsDocAccessible* document = GetDocAccessible();
       if (document)
         return document->GetAccessible(activeOptionNode);
     }
   }
   return nsnull;
 }
 
+void
+nsHTMLSelectListAccessible::SetCurrentItem(nsAccessible* aItem)
+{
+  aItem->GetContent()->SetAttr(kNameSpaceID_None,
+                               nsGkAtoms::selected, NS_LITERAL_STRING("true"),
+                               true);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLSelectListAccessible: nsAccessible protected
 
 void
 nsHTMLSelectListAccessible::CacheChildren()
 {
   // Cache accessibles for <optgroup> and <option> DOM decendents as children,
   // as well as the accessibles for them. Avoid whitespace text nodes. We want
@@ -681,16 +689,23 @@ nsHTMLComboboxAccessible::AreItemsOperab
 }
 
 nsAccessible*
 nsHTMLComboboxAccessible::CurrentItem()
 {
   return AreItemsOperable() ? mListAccessible->CurrentItem() : nsnull;
 }
 
+void
+nsHTMLComboboxAccessible::SetCurrentItem(nsAccessible* aItem)
+{
+  if (AreItemsOperable())
+    mListAccessible->SetCurrentItem(aItem);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLComboboxAccessible: protected
 
 nsAccessible*
 nsHTMLComboboxAccessible::SelectedOption() const
 {
   nsIFrame* frame = GetFrame();
   nsIComboboxControlFrame* comboboxFrame = do_QueryFrame(frame);
--- a/accessible/src/html/nsHTMLSelectAccessible.h
+++ b/accessible/src/html/nsHTMLSelectAccessible.h
@@ -80,16 +80,17 @@ public:
   virtual bool SelectAll();
   virtual bool UnselectAll();
 
   // Widgets
   virtual bool IsWidget() const;
   virtual bool IsActiveWidget() const;
   virtual bool AreItemsOperable() const;
   virtual nsAccessible* CurrentItem();
+  virtual void SetCurrentItem(nsAccessible* aItem);
 
 protected:
 
   // nsAccessible
   virtual void CacheChildren();
 
   // nsHTMLSelectListAccessible
 
@@ -204,16 +205,17 @@ public:
   // ActionAccessible
   virtual PRUint8 ActionCount();
 
   // Widgets
   virtual bool IsWidget() const;
   virtual bool IsActiveWidget() const;
   virtual bool AreItemsOperable() const;
   virtual nsAccessible* CurrentItem();
+  virtual void SetCurrentItem(nsAccessible* aItem);
 
 protected:
   // nsAccessible
   virtual void CacheChildren();
 
   /**
    * Return selected option.
    */
--- a/accessible/src/mac/mozAccessible.h
+++ b/accessible/src/mac/mozAccessible.h
@@ -41,26 +41,42 @@
 #import <Cocoa/Cocoa.h>
 
 #import "mozAccessibleProtocol.h"
 
 @class mozRootAccessible;
 
 @interface mozAccessible : NSObject <mozAccessible>
 {
-  nsAccessibleWrap *mGeckoAccessible;  // weak reference; it owns us.
-  NSMutableArray   *mChildren;         // strong ref to array of children
+  /**
+   * Weak reference; it owns us.
+   */
+  nsAccessibleWrap* mGeckoAccessible;
+  
+  /**
+   * Strong ref to array of children
+   */
+  NSMutableArray* mChildren;
   
-  // we can be marked as 'expired' if Shutdown() is called on our geckoAccessible.
-  // since we might still be retained by some third-party, we need to do cleanup
-  // in |expire|, and prevent any potential harm that could come from someone using us
-  // after this point.
+  /** 
+   * Weak reference to the parent
+   */
+  mozAccessible* mParent;
+  
+  /**
+   * We can be marked as 'expired' if Shutdown() is called on our geckoAccessible.
+   * since we might still be retained by some third-party, we need to do cleanup
+   * in |expire|, and prevent any potential harm that could come from someone using us
+   * after this point.
+   */
   BOOL mIsExpired;
   
-  // the nsIAccessible role of our gecko accessible.
+  /**
+   * The nsIAccessible role of our gecko accessible.
+   */
   PRUint32        mRole;
 }
 
 // inits with the gecko owner.
 - (id)initWithAccessible:(nsAccessibleWrap*)geckoParent;
 
 // our accessible parent (AXParent)
 - (id <mozAccessible>)parent;
@@ -109,27 +125,30 @@
 - (void)didReceiveFocus;
 - (void)valueDidChange;
 
 #pragma mark -
 
 // invalidates and removes all our children from our cached array.
 - (void)invalidateChildren;
 
+// invalidates the cached parent, used by invalidateChildren.
+- (void)invalidateParent;
+
 // makes ourselves "expired". after this point, we might be around if someone
 // has retained us (e.g., a third-party), but we really contain no information.
 - (void)expire;
 - (BOOL)isExpired;
 
 #ifdef DEBUG
 - (void)printHierarchy;
 - (void)printHierarchyWithLevel:(unsigned)numSpaces;
 
 - (void)sanityCheckChildren;
-- (void)sanityCheckChildren:(NSArray *)theChildren;
+- (void)sanityCheckChildren:(NSArray*)theChildren;
 #endif
 
 // ---- NSAccessibility methods ---- //
 
 // whether to skip this element when traversing the accessibility
 // hierarchy.
 - (BOOL)accessibilityIsIgnored;
 
--- a/accessible/src/mac/mozAccessible.mm
+++ b/accessible/src/mac/mozAccessible.mm
@@ -42,18 +42,20 @@
 #import "mozView.h"
 #import "nsRoleMap.h"
 
 #include "nsRect.h"
 #include "nsCoord.h"
 #include "nsObjCExceptions.h"
 
 #include "nsIAccessible.h"
+#include "nsIAccessibleRelation.h"
 #include "nsIAccessibleText.h"
 #include "nsIAccessibleEditableText.h"
+#include "Relation.h"
 
 #include "nsRootAccessible.h"
 
 using namespace mozilla::a11y;
 
 // These constants are only defined in OS X SDK 10.4, so we define them in order
 // to be able to use for earlier OS versions.
 const NSString *kInstanceDescriptionAttribute = @"AXDescription";       // NSAccessibilityDescriptionAttribute
@@ -241,26 +243,30 @@ GetNativeFromGeckoAccessible(nsIAccessib
   if ([attribute isEqualToString:NSAccessibilityFocusedAttribute])
     return [NSNumber numberWithBool:[self isFocused]];
   if ([attribute isEqualToString:NSAccessibilitySizeAttribute])
     return [self size];
   if ([attribute isEqualToString:NSAccessibilityWindowAttribute])
     return [self window];
   if ([attribute isEqualToString: (NSString*) kTopLevelUIElementAttribute])
     return [self window];
-  if ([attribute isEqualToString:NSAccessibilityTitleAttribute] || 
-      [attribute isEqualToString:NSAccessibilityTitleUIElementAttribute])
+  if ([attribute isEqualToString:NSAccessibilityTitleAttribute])
     return [self title];
+  if ([attribute isEqualToString:NSAccessibilityTitleUIElementAttribute]) {
+    Relation rel = mGeckoAccessible->RelationByType(nsIAccessibleRelation::RELATION_LABELLED_BY);
+    nsAccessible* tempAcc = rel.Next();
+    return tempAcc ? GetNativeFromGeckoAccessible(tempAcc) : nil;
+  }
   if ([attribute isEqualToString:NSAccessibilityHelpAttribute])
     return [self help];
     
 #ifdef DEBUG
  NSLog (@"!!! %@ can't respond to attribute %@", self, attribute);
 #endif
-  return nil; // be nice and return empty string instead?
+  return nil;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 - (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
 
@@ -344,33 +350,38 @@ GetNativeFromGeckoAccessible(nsIAccessib
 }
 
 #pragma mark -
 
 - (id <mozAccessible>)parent
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
+  if (mParent)
+    return mParent;
+
   nsCOMPtr<nsIAccessible> accessibleParent(mGeckoAccessible->GetUnignoredParent());
   if (accessibleParent) {
     id nativeParent = GetNativeFromGeckoAccessible(accessibleParent);
-    if (nativeParent)
-      return GetClosestInterestingAccessible(nativeParent);
+    if (nativeParent) {
+      return mParent = GetClosestInterestingAccessible(nativeParent);
+    }
   }
   
   // GetUnignoredParent() returns null when there is no unignored accessible all the way up to
   // the root accessible. so we'll have to return whatever native accessible is above our root accessible 
   // (which might be the owning NSWindow in the application, for example).
   //
   // get the native root accessible, and tell it to return its first parent unignored accessible.
   nsRootAccessible* root = mGeckoAccessible->RootAccessible();
   id nativeParent = GetNativeFromGeckoAccessible(static_cast<nsIAccessible*>(root));
   NSAssert1 (nativeParent, @"!!! we can't find a parent for %@", self);
   
-  return GetClosestInterestingAccessible(nativeParent);
+  mParent = GetClosestInterestingAccessible(nativeParent);
+  return mParent;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 - (BOOL)hasRepresentedView
 {
   return NO;
 }
@@ -599,23 +610,30 @@ GetNativeFromGeckoAccessible(nsIAccessib
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 - (void)invalidateChildren
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
+  [mChildren makeObjectsPerformSelector:@selector(invalidateParent)];
+
   // make room for new children
   [mChildren release];
   mChildren = nil;
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
+- (void)invalidateParent
+{
+  mParent = nil;
+}
+
 - (void)expire
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   [self invalidateChildren];
   mIsExpired = YES;
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
--- a/accessible/src/mac/mozDocAccessible.mm
+++ b/accessible/src/mac/mozDocAccessible.mm
@@ -50,16 +50,54 @@ static id <mozAccessible, mozView> getNa
   root->GetNativeWidget ((void**)&nativeView);
   return nativeView;
 }
 
 #pragma mark -
 
 @implementation mozRootAccessible
 
+- (NSArray*)accessibilityAttributeNames
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
+  
+  // if we're expired, we don't support any attributes.
+  if (mIsExpired)
+    return [NSArray array];
+  
+  // standard attributes that are shared and supported by root accessible (AXMain) elements.
+  static NSMutableArray* attributes = nil;
+  
+  if (!attributes) {
+    attributes = [[super accessibilityAttributeNames] mutableCopy];
+    [attributes addObject:NSAccessibilityMainAttribute];
+    [attributes addObject:NSAccessibilityMinimizedAttribute];
+  }
+
+  return attributes;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
+}
+
+- (id)accessibilityAttributeValue:(NSString *)attribute
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
+  
+  if ([attribute isEqualToString:NSAccessibilityMainAttribute]) {
+    return [NSNumber numberWithBool:[[self window] isMainWindow]];
+  }
+  if ([attribute isEqualToString:NSAccessibilityMinimizedAttribute]) {
+    return [NSNumber numberWithBool:[[self window] isMiniaturized]];
+  }
+  return [super accessibilityAttributeValue:attribute];
+  
+  NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
+}
+
+
 // return the AXParent that our parallell NSView tells us about.
 - (id)parent
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
   if (!mParallelView)
     mParallelView = (id<mozView, mozAccessible>)[self representedView];
   
--- a/accessible/src/xul/nsXULMenuAccessible.cpp
+++ b/accessible/src/xul/nsXULMenuAccessible.cpp
@@ -297,16 +297,32 @@ nsXULSelectableAccessible::CurrentItem()
     nsDocAccessible* document = GetDocAccessible();
     if (document)
       return document->GetAccessible(DOMNode);
   }
 
   return nsnull;
 }
 
+void
+nsXULSelectableAccessible::SetCurrentItem(nsAccessible* aItem)
+{
+  if (!mSelectControl)
+    return;
+
+  nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
+    do_QueryInterface(aItem->GetContent());
+  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
+    do_QueryInterface(mSelectControl);
+  if (multiSelectControl)
+    multiSelectControl->SetCurrentItem(itemElm);
+  else
+    mSelectControl->SetSelectedItem(itemElm);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULMenuitemAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXULMenuitemAccessible::
   nsXULMenuitemAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
   nsAccessibleWrap(aContent, aShell)
 {
@@ -888,8 +904,14 @@ nsXULMenubarAccessible::CurrentItem()
     nsMenuFrame* menuFrame = menuBarFrame->GetCurrentMenuItem();
     if (menuFrame) {
       nsIContent* menuItemNode = menuFrame->GetContent();
       return GetAccService()->GetAccessible(menuItemNode);
     }
   }
   return nsnull;
 }
+
+void
+nsXULMenubarAccessible::SetCurrentItem(nsAccessible* aItem)
+{
+  NS_ERROR("nsXULMenubarAccessible::SetCurrentItem not implemented");
+}
--- a/accessible/src/xul/nsXULMenuAccessible.h
+++ b/accessible/src/xul/nsXULMenuAccessible.h
@@ -62,16 +62,17 @@ public:
   virtual bool IsItemSelected(PRUint32 aIndex);
   virtual bool AddItemToSelection(PRUint32 aIndex);
   virtual bool RemoveItemFromSelection(PRUint32 aIndex);
   virtual bool SelectAll();
   virtual bool UnselectAll();
 
   // Widgets
   virtual nsAccessible* CurrentItem();
+  virtual void SetCurrentItem(nsAccessible* aItem);
 
 protected:
   // nsIDOMXULMultiSelectControlElement inherits from this, so we'll always have
   // one of these if the widget is valid and not defunct
   nsCOMPtr<nsIDOMXULSelectControlElement> mSelectControl;
 };
 
 /**
@@ -165,11 +166,12 @@ public:
   virtual nsresult GetNameInternal(nsAString& aName);
   virtual PRUint32 NativeRole();
   virtual PRUint64 NativeState();
 
   // Widget
   virtual bool IsActiveWidget() const;
   virtual bool AreItemsOperable() const;
   virtual nsAccessible* CurrentItem();
+  virtual void SetCurrentItem(nsAccessible* aItem);
 };
 
 #endif  
--- a/accessible/src/xul/nsXULTreeAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeAccessible.cpp
@@ -274,16 +274,22 @@ nsXULTreeAccessible::CurrentItem()
     selection->GetCurrentIndex(&currentIndex);
     if (currentIndex >= 0)
       return GetTreeItemAccessible(currentIndex);
   }
 
   return nsnull;
 }
 
+void
+nsXULTreeAccessible::SetCurrentItem(nsAccessible* aItem)
+{
+  NS_ERROR("nsXULTreeAccessible::SetCurrentItem not implemented");
+}
+
 already_AddRefed<nsIArray>
 nsXULTreeAccessible::SelectedItems()
 {
   nsCOMPtr<nsITreeSelection> selection;
   mTreeView->GetSelection(getter_AddRefs(selection));
   if (!selection)
     return nsnull;
 
--- a/accessible/src/xul/nsXULTreeAccessible.h
+++ b/accessible/src/xul/nsXULTreeAccessible.h
@@ -101,16 +101,17 @@ public:
   virtual bool SelectAll();
   virtual bool UnselectAll();
 
   // Widgets
   virtual bool IsWidget() const;
   virtual bool IsActiveWidget() const;
   virtual bool AreItemsOperable() const;
   virtual nsAccessible* CurrentItem();
+  virtual void SetCurrentItem(nsAccessible* aItem);
 
   virtual nsAccessible* ContainerWidget() const;
 
   // nsXULTreeAccessible
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEACCESSIBLE_IMPL_CID)
 
   /**
--- a/accessible/tests/mochitest/focus/Makefile.in
+++ b/accessible/tests/mochitest/focus/Makefile.in
@@ -43,12 +43,13 @@ VPATH		= @srcdir@
 relativesrcdir  = accessible/focus
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES =\
 		test_focusedChild.html \
 		test_takeFocus.html \
+		test_takeFocus.xul \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)
--- a/accessible/tests/mochitest/focus/test_takeFocus.html
+++ b/accessible/tests/mochitest/focus/test_takeFocus.html
@@ -13,19 +13,17 @@
           src="../common.js"></script>
   <script type="application/javascript"
           src="../states.js"></script>
   <script type="application/javascript"
           src="../events.js"></script>
 
   <script type="application/javascript">
     ////////////////////////////////////////////////////////////////////////////
-    // Test
-
-    var gQueue = null;
+    // Invokers
 
     function takeFocusInvoker(aID)
     {
       this.accessible = getAccessible(aID);
 
       this.eventSeq = [ new focusChecker(this.accessible) ];
 
       this.invoke = function takeFocusInvoker_invoke()
@@ -34,26 +32,33 @@
       }
 
       this.getID = function takeFocusInvoker_getID()
       {
         return "takeFocus for " + prettyName(aID);
       }
     }
 
+    ////////////////////////////////////////////////////////////////////////////
+    // Test
+
+    //gA11yEventDumpToConsole = true; // debug stuff
+
+    var gQueue = null;
     function doTest()
     {
       gQueue = new eventQueue();
 
       gQueue.push(new takeFocusInvoker("aria-link"));
       gQueue.push(new takeFocusInvoker("aria-link2"));
       gQueue.push(new takeFocusInvoker("link"));
       gQueue.push(new takeFocusInvoker("item2"));
       gQueue.push(new takeFocusInvoker("plugin"));
       gQueue.push(new takeFocusInvoker(document));
+      gQueue.push(new takeFocusInvoker("lb_item2"));
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
@@ -70,16 +75,21 @@
      title="nsIAccessible::takeFocus testing">
     Mozilla Bug 452710
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=646361"
      title="No focus event fired on document when focus is set to the document while focused in a plugin">
     Mozilla Bug 646361
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=706067"
+     title="Make takeFocus work on widget items">
+    Mozilla Bug 706067
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <span id="aria-link" role="link" tabindex="0">link</span>
   <span id="aria-link2" role="link" tabindex="0">link</span>
 
@@ -87,10 +97,15 @@
 
   <div role="listbox" aria-activedescendant="item1" id="container" tabindex="1">
     <div role="listitem" id="item1">item1</div>
     <div role="listitem" id="item2">item2</div>
     <div role="listitem" id="item3">item3</div>
   </div>
 
   <embed id="plugin" type="application/x-test" width="200" height="200" wmode="window"></embed>
+
+  <select id="listbox" size="5">
+    <option id="lb_item1">item1</option>
+    <option id="lb_item2">item2</option>
+  </select>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/focus/test_takeFocus.xul
@@ -0,0 +1,125 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+                 type="text/css"?>
+
+<?xml-stylesheet href="chrome://browser/content/browser.css"
+                 type="text/css"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        title="Accessible focus testing">
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
+
+  <script type="application/javascript"
+          src="../common.js" />
+  <script type="application/javascript"
+          src="../states.js" />
+  <script type="application/javascript"
+          src="../events.js" />
+
+  <script type="application/javascript"
+          src="../treeview.js" />
+
+  <script type="application/javascript">
+  <![CDATA[
+    ////////////////////////////////////////////////////////////////////////////
+    // Invokers
+
+    function setTreeView(aTreeID, aView)
+    {
+      this.DOMNode = getNode(aTreeID);
+
+      this.eventSeq = [
+        new invokerChecker(EVENT_REORDER, this.DOMNode)
+      ];
+
+      this.invoke = function setTreeView_invoke()
+      {
+        this.DOMNode.treeBoxObject.view = aView;
+      }
+
+      this.getID = function setTreeView_getID()
+        { return "set tree view for " + prettyName(aTreeID); }
+    };
+
+    function takeFocusInvoker(aID, aArgConverterFunc)
+    {
+      this.targetFunc = aArgConverterFunc ? aArgConverterFunc : getAccessible;
+
+      this.eventSeq = [ new focusChecker(this.targetFunc, aID) ];
+
+      this.invoke = function takeFocusInvoker_invoke()
+      {
+        this.targetFunc.call(null, aID).takeFocus();
+      }
+
+      this.getID = function takeFocusInvoker_getID()
+      {
+        return "takeFocus for " + prettyName(aID);
+      }
+    }
+
+    function getLastChild(aID)
+    {
+      return getAccessible(aID).lastChild;
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Tests
+
+    //gA11yEventDumpID = "eventdump"; // debug stuff
+    //gA11yEventDumpToConsole = true; // debug stuff
+
+    var gQueue = null;
+    function doTests()
+    {
+      // Test focus events.
+      gQueue = new eventQueue();
+
+      gQueue.push(new setTreeView("tree", new nsTableTreeView(5)));
+      gQueue.push(new takeFocusInvoker("tree", getLastChild));
+      gQueue.push(new takeFocusInvoker("listitem2"));
+
+      gQueue.invoke(); // Will call SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTests);
+  ]]>
+  </script>
+
+  <hbox flex="1" style="overflow: auto;">
+    <body xmlns="http://www.w3.org/1999/xhtml">
+      <a target="_blank"
+         href="https://bugzilla.mozilla.org/show_bug.cgi?id=706067"
+         title="Make takeFocus work on widget items">
+        Mozilla Bug 706067
+      </a>
+      <p id="display"></p>
+      <div id="content" style="display: none"></div>
+      <pre id="test">
+      </pre>
+    </body>
+
+    <vbox flex="1">
+      <tree id="tree" flex="1">
+        <treecols>
+          <treecol id="col1" flex="1" primary="true" label="column"/>
+          <treecol id="col2" flex="1" label="column 2"/>
+        </treecols>
+        <treechildren id="treechildren"/>
+      </tree>
+
+      <listbox id="listbox">
+        <listitem id="listitem1">item1</listitem>
+        <listitem id="listitem2">item2</listitem>
+      </listbox>
+
+      <vbox id="eventdump"/>
+    </vbox>
+  </hbox>
+</window>
--- a/accessible/tests/mochitest/states/test_aria.html
+++ b/accessible/tests/mochitest/states/test_aria.html
@@ -92,16 +92,32 @@
       // aria-checked
       testStates("aria_checked_checkbox", STATE_CHECKED);
       testStates("aria_mixed_checkbox", STATE_MIXED);
 
       // test disabled group and all its descendants to see if they are
       // disabled, too. See bug 429285.
       testAriaDisabledTree("group");
 
+      // aria-multiline
+      testStates("aria_multiline_textbox", 0, EXT_STATE_MULTI_LINE);
+
+      // aria-multiselectable
+      testStates("aria_multiselectable_listbox",
+                 STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
+
+      // aria-pressed
+      testStates("aria_pressed_button", STATE_PRESSED | STATE_CHECKABLE);
+
+      // aria-readonly
+      testStates("aria_readonly_textbox", STATE_READONLY);
+
+      // aria-selectable
+      testStates("aria_selectable_listitem", STATE_SELECTABLE | STATE_SELECTED);
+
       // active state caused by aria-activedescendant
       testStates("as_item1", 0, EXT_STATE_ACTIVE);
       testStates("as_item2", 0, 0, 0, EXT_STATE_ACTIVE);
 
       // universal ARIA properties inherited from file input control
       var fileTextField = getAccessible("fileinput").firstChild;
       testStates(fileTextField,
                  STATE_BUSY | STATE_UNAVAILABLE | STATE_REQUIRED | STATE_HASPOPUP | STATE_INVALID);
@@ -188,16 +204,21 @@
      title="File input control should be propogate states to descendants">
     Mozilla Bug 699017
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=689847"
      title="Expose active state on current item of selectable widgets">
     Mozilla Bug 689847
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=457226"
+     title="Mochitests for ARIA states">
+    Mozilla Bug 457226
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <div id="textbox_autocomplete_inline" role="textbox" aria-autocomplete="inline"></div>
   <div id="textbox_autocomplete_list" role="textbox" aria-autocomplete="list"></div>
   <div id="textbox_autocomplete_both" role="textbox" aria-autocomplete="both"></div>
@@ -220,16 +241,23 @@
 
   <div id="aria_checked_checkbox" role="checkbox" aria-checked="true">
     I agree
   </div>
 
   <div id="aria_mixed_checkbox" role="checkbox" aria-checked="mixed">
     I might agree
   </div>
+  <div id="aria_multiline_textbox" role="textbox" aria-multiline="true"></div>
+  <div id="aria_multiselectable_listbox" role="listbox" aria-multiselectable="true"></div>
+  <div id="aria_pressed_button" role="button" aria-pressed="true">Button</div>
+  <div id="aria_readonly_textbox" role="textbox" aria-readonly="true">This text should be readonly</div>
+  <div role="listbox">
+    <div id="aria_selectable_listitem" role="option" aria-selected="true">Item1</div>
+  </div>
 
   <!-- Test that aria-disabled state gets propagated to all descendants -->
   <div id="group" role="group" aria-disabled="true">
     <button>hi</button>
     <div tabindex="0" role="listbox" aria-activedescendant="item1">
       <div role="option" id="item1">Item 1</div>
       <div role="option" id="item2">Item 2</div>
       <div role="option" id="item3">Item 3</div>
copy from netwerk/test/httpserver/httpd.js
copy to b2g/chrome/content/httpd.js
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -34,32 +34,65 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const CC = Components.Constructor;
 
-Cu.import('resource://gre/modules/Services.jsm');
-
 const LocalFile = CC('@mozilla.org/file/local;1',
                      'nsILocalFile',
                      'initWithPath');
+
+Cu.import('resource://gre/modules/XPCOMUtils.jsm');
+Cu.import('resource://gre/modules/Services.jsm');
+XPCOMUtils.defineLazyGetter(Services, 'env', function() {
+  return Cc['@mozilla.org/process/environment;1']
+           .getService(Ci.nsIEnvironment);
+});
+XPCOMUtils.defineLazyGetter(Services, 'ss', function() {
+  return Cc['@mozilla.org/content/style-sheet-service;1']
+           .getService(Ci.nsIStyleSheetService);
+});
+XPCOMUtils.defineLazyGetter(Services, 'fm', function() {
+  return Cc['@mozilla.org/focus-manager;1']
+           .getService(Ci.nsIFocusManager);
+});
+
+// In order to use http:// scheme instead of file:// scheme
+// (that is much more restricted) the following code kick-off
+// a local http server listening on http://127.0.0.1:8888 and
+// http://localhost:8888.
+function startupHttpd(baseDir, port) {
+  const httpdURL = 'chrome://browser/content/httpd.js';
+  let httpd = {};
+  Services.scriptloader.loadSubScript(httpdURL, httpd);
+  let server = new httpd.nsHttpServer();
+  server.registerDirectory('/', new LocalFile(baseDir));
+  server.start(port);
+}
+
+// XXX until we have a security model, just let the pre-installed
+// app used indexedDB.
+function allowIndexedDB(url) {
+  let uri = Services.io.newURI(url, null, null);
+  Services.perms.add(uri, 'indexedDB', Ci.nsIPermissionManager.ALLOW_ACTION);
+}
+
+
 var shell = {
   get home() {
     delete this.home;
     return this.home = document.getElementById('homescreen');
   },
 
-  get homeSrc() {
+  get homeURL() {
     try {
-      let homeSrc = Cc['@mozilla.org/process/environment;1']
-                      .getService(Ci.nsIEnvironment)
-                      .get('B2G_HOMESCREEN');
+      let homeSrc = Services.env.get('B2G_HOMESCREEN');
       if (homeSrc)
         return homeSrc;
     } catch (e) {}
 
     let urls = Services.prefs.getCharPref('browser.homescreenURL').split(',');
     for (let i = 0; i < urls.length; i++) {
       let url = urls[i];
       if (url.substring(0, 7) != 'file://')
@@ -68,26 +101,51 @@ var shell = {
       let file = new LocalFile(url.substring(7, url.length));
       if (file.exists())
         return url;
     }
     return null;
   },
 
   start: function shell_init() {
+    let homeURL = this.homeURL;
+    if (!homeURL) {
+      let msg = 'Fatal error during startup: [No homescreen found]';
+      return alert(msg);
+    }
+
     window.controllers.appendController(this);
     window.addEventListener('keypress', this);
     this.home.addEventListener('load', this, true);
 
-    let ioService = Cc['@mozilla.org/network/io-service;1']
-                      .getService(Ci.nsIIOService2);
-    ioService.offline = false;
+    try {
+      Services.io.offline = false;
+
+      let fileScheme = 'file://';
+      if (homeURL.substring(0, fileScheme.length) == fileScheme) {
+        homeURL = homeURL.replace(fileScheme, '');
+
+        let baseDir = homeURL.split('/');
+        baseDir.pop();
+        baseDir = baseDir.join('/');
+
+        const SERVER_PORT = 8888;
+        startupHttpd(baseDir, SERVER_PORT);
+
+        let baseHost = 'http://localhost';
+        homeURL = homeURL.replace(baseDir, baseHost + ':' + SERVER_PORT);
+      }
+      allowIndexedDB(homeURL);
+    } catch (e) {
+      let msg = 'Fatal error during startup: [' + e + '[' + homeURL + ']';
+      return alert(msg);
+    }
 
     let browser = this.home;
-    browser.homePage = this.homeSrc;
+    browser.homePage = homeURL;
     browser.goHome();
   },
 
   stop: function shell_stop() {
     window.controllers.removeController(this);
     window.removeEventListener('keypress', this);
   },
 
@@ -178,32 +236,30 @@ var shell = {
           break;
       }
     },
     observe: function vkm_observe(subject, topic, data) {
       let contentWindow = shell.home.contentWindow;
 
       let shouldOpen = parseInt(data);
       if (shouldOpen && !isKeyboardOpened) {
-        activeElement = Cc['@mozilla.org/focus-manager;1']
-                          .getService(Ci.nsIFocusManager)
-                          .focusedElement;
+        activeElement = Services.fm.focusedElement;
         if (!activeElement)
           return;
 
         let type = activeElement.type;
         shell.sendEvent(contentWindow, 'showime', { type: type });
       } else if (!shouldOpen && isKeyboardOpened) {
         shell.sendEvent(contentWindow, 'hideime');
       }
       isKeyboardOpened = shouldOpen;
     }
   };
 
-  Services.obs.addObserver(constructor, "ime-enabled-state-changed", false);
+  Services.obs.addObserver(constructor, 'ime-enabled-state-changed', false);
   ['ContentStart', 'keypress', 'mousedown'].forEach(function vkm_events(type) {
     window.addEventListener(type, constructor, true);
   });
 })();
 
 
 function MozKeyboard() {
 }
--- a/b2g/chrome/content/touch.js
+++ b/b2g/chrome/content/touch.js
@@ -146,28 +146,27 @@
             debug('click: cancel');
 
             evt.preventDefault();
             evt.stopPropagation();
           } else {
             // Mouse events has been cancelled so dispatch a sequence
             // of events to where touchend has been fired
             if (preventMouseEvents) {
+              evt.preventDefault();
+              evt.stopPropagation();
+
               let target = evt.target;
               ignoreEvents = true;
-              try {
-                this.fireMouseEvent('mousemove', evt);
-                this.fireMouseEvent('mousedown', evt);
-                this.fireMouseEvent('mouseup', evt);
-              } catch (e) {
-                alert(e);
-              }
-              evt.preventDefault();
-              evt.stopPropagation();
-              ignoreEvents = false;
+              window.setTimeout(function dispatchMouseEvents(self) {
+                self.fireMouseEvent('mousemove', evt);
+                self.fireMouseEvent('mousedown', evt);
+                self.fireMouseEvent('mouseup', evt);
+                ignoreEvents = false;
+              }, 0, this);
             }
 
             debug('click: fire');
           }
           return;
       }
 
       let target = eventTarget || this.target;
--- a/b2g/chrome/jar.mn
+++ b/b2g/chrome/jar.mn
@@ -3,11 +3,12 @@
 chrome.jar:
 % content branding %content/branding/
 % content browser %content/
 
 * content/shell.xul                     (content/shell.xul)
   content/shell.js                      (content/shell.js)
   content/touch.js                      (content/touch.js)
   content/commandUtil.js                (content/commandUtil.js)
+  content/httpd.js                      (content/httpd.js)
 
 % override chrome://global/content/netError.xhtml chrome://browser/content/netError.xhtml
   content/netError.xhtml                (content/netError.xhtml)
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -386,16 +386,22 @@
 @BINPATH@/components/contentSecurityPolicy.manifest
 @BINPATH@/components/contentSecurityPolicy.js
 @BINPATH@/components/contentAreaDropListener.manifest
 @BINPATH@/components/contentAreaDropListener.js
 @BINPATH@/components/messageWakeupService.js
 @BINPATH@/components/messageWakeupService.manifest
 @BINPATH@/components/nsFilePicker.js
 @BINPATH@/components/nsFilePicker.manifest
+#ifdef MOZ_B2G_RIL
+@BINPATH@/components/nsTelephonyWorker.manifest
+@BINPATH@/components/nsTelephonyWorker.js
+@BINPATH@/components/Telephony.manifest
+@BINPATH@/components/Telephony.js
+#endif
 #ifdef XP_MACOSX
 @BINPATH@/components/libalerts_s.dylib
 #endif
 #ifdef MOZ_ENABLE_DBUS
 @BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
 #endif
 @BINPATH@/components/nsINIProcessor.manifest
 @BINPATH@/components/nsINIProcessor.js
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -238,21 +238,16 @@ panel[noactions] > richlistbox > richlis
 #PopupAutoComplete {
   -moz-binding: url("chrome://browser/content/urlbarBindings.xml#browser-autocomplete-result-popup");
 }
 
 #PopupAutoCompleteRichResult {
   -moz-binding: url("chrome://browser/content/urlbarBindings.xml#urlbar-rich-result-popup");
 }
 
-#urlbar-throbber:not([busy="true"]),
-#urlbar-throbber[busy="true"] + #page-proxy-favicon {
-  display: none;
-}
-
 #urlbar-container[combined] > #urlbar > #urlbar-icons > #go-button,
 #urlbar[pageproxystate="invalid"] > #urlbar-icons > .urlbar-icon:not(#go-button),
 #urlbar[pageproxystate="valid"] > #urlbar-icons > #go-button,
 #urlbar[pageproxystate="invalid"][focused="true"] > #urlbar-go-button ~ toolbarbutton,
 #urlbar[pageproxystate="valid"] > #urlbar-go-button,
 #urlbar:not([focused="true"]) > #urlbar-go-button {
   visibility: collapse;
 }
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2596,38 +2596,16 @@ function UpdateUrlbarSearchSplitterState
       splitter.setAttribute("resizeafter", "flex");
       splitter.className = "chromeclass-toolbar-additional";
     }
     urlbar.parentNode.insertBefore(splitter, ibefore);
   } else if (splitter)
     splitter.parentNode.removeChild(splitter);
 }
 
-var LocationBarHelpers = {
-  _timeoutID: null,
-
-  _searchBegin: function LocBar_searchBegin() {
-    function delayedBegin(self) {
-      self._timeoutID = null;
-      document.getElementById("urlbar-throbber").setAttribute("busy", "true");
-    }
-
-    this._timeoutID = setTimeout(delayedBegin, 500, this);
-  },
-
-  _searchComplete: function LocBar_searchComplete() {
-    // Did we finish the search before delayedBegin was invoked?
-    if (this._timeoutID) {
-      clearTimeout(this._timeoutID);
-      this._timeoutID = null;
-    }
-    document.getElementById("urlbar-throbber").removeAttribute("busy");
-  }
-};
-
 function UpdatePageProxyState()
 {
   if (gURLBar && gURLBar.value != gLastValidURLStr)
     SetPageProxyState("invalid");
 }
 
 function SetPageProxyState(aState)
 {
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -511,18 +511,16 @@
                  showimagecolumn="true"
                  enablehistory="true"
                  maxrows="6"
                  newlines="stripsurroundingwhitespace"
                  oninput="gBrowser.userTypedValue = this.value;"
                  ontextentered="this.handleCommand(param);"
                  ontextreverted="return this.handleRevert();"
                  pageproxystate="invalid"
-                 onsearchbegin="LocationBarHelpers._searchBegin();"
-                 onsearchcomplete="LocationBarHelpers._searchComplete();"
                  onfocus="document.getElementById('identity-box').style.MozUserFocus= 'normal'"
                  onblur="setTimeout(function() document.getElementById('identity-box').style.MozUserFocus = '', 0);">
           <box id="notification-popup-box" hidden="true" align="center">
             <image id="default-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="geo-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="addons-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="indexedDB-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="password-notification-icon" class="notification-anchor-icon" role="button"/>
@@ -533,17 +531,16 @@
                has focus, otherwise pressing F6 focuses it instead of the location bar -->
           <box id="identity-box" role="button"
                onclick="gIdentityHandler.handleIdentityButtonEvent(event);"
                onkeypress="gIdentityHandler.handleIdentityButtonEvent(event);"
                ondragstart="gIdentityHandler.onDragStart(event);">
             <hbox id="identity-box-inner" align="center">
               <stack id="page-proxy-stack"
                      onclick="PageProxyClickHandler(event);">
-                <image id="urlbar-throbber" busy="false"/>
                 <image id="page-proxy-favicon" validate="never"
                        pageproxystate="invalid"
                        onerror="this.removeAttribute('src');"/>
               </stack>
               <hbox id="identity-icon-labels">
                 <label id="identity-icon-label" class="plain" flex="1"/>
                 <label id="identity-icon-country-label" class="plain"/>
               </hbox>
--- a/browser/config/mozconfigs/macosx64/debug
+++ b/browser/config/mozconfigs/macosx64/debug
@@ -1,8 +1,10 @@
+. $topsrcdir/build/macosx/common
+
 ac_add_options --enable-debug
 ac_add_options --enable-trace-malloc
 ac_add_options --enable-accessibility
 
 # Enable parallel compiling
 mk_add_options MOZ_MAKE_FLAGS="-j4"
 
 # Needed to enable breakpad in application.ini
--- a/browser/themes/gnomestripe/browser.css
+++ b/browser/themes/gnomestripe/browser.css
@@ -1019,18 +1019,17 @@ toolbar[iconsize="small"] #feed-button {
 
 #urlbar-display {
   margin-top: 0;
   margin-bottom: 0;
   color: GrayText;
 }
 
 /* Favicon */
-#page-proxy-favicon,
-#urlbar-throbber {
+#page-proxy-favicon {
   width: 16px;
   height: 16px;
 }
 
 #page-proxy-stack {
   width: 24px;
   height: 20px;
   padding: 2px 4px;
@@ -1039,20 +1038,16 @@ toolbar[iconsize="small"] #feed-button {
 #page-proxy-favicon:not([src]) {
   list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
 }
 
 #page-proxy-favicon[pageproxystate="invalid"] {
   opacity: 0.3;
 }
 
-#urlbar-throbber {
-  list-style-image: url("chrome://browser/skin/places/searching_16.png");
-}
-
 /* Identity indicator */
 #identity-box {
   background-image: -moz-linear-gradient(hsl(0,0%,98%), hsl(0,0%,92%));
   box-shadow: 0 1px 0 hsla(0,0%,0%,.05) inset;
   -moz-border-end: 1px solid rgba(0,0,0,.1);
   padding: 1px;
   margin: -1px;
   -moz-margin-end: 0;
--- a/browser/themes/gnomestripe/jar.mn
+++ b/browser/themes/gnomestripe/jar.mn
@@ -52,17 +52,16 @@ browser.jar:
   skin/classic/browser/places/livemark-item.png       (places/livemark-item.png)
   skin/classic/browser/places/pageStarred.png         (places/pageStarred.png)
   skin/classic/browser/places/starred48.png           (places/starred48.png)
   skin/classic/browser/places/unstarred48.png         (places/unstarred48.png)
   skin/classic/browser/places/places.css              (places/places.css)
   skin/classic/browser/places/organizer.css           (places/organizer.css)
 * skin/classic/browser/places/organizer.xml           (places/organizer.xml)
   skin/classic/browser/places/query.png               (places/query.png)
-  skin/classic/browser/places/searching_16.png        (places/searching_16.png)
   skin/classic/browser/places/starPage.png            (places/starPage.png)
   skin/classic/browser/places/tag.png                 (places/tag.png)
   skin/classic/browser/places/toolbarDropMarker.png   (places/toolbarDropMarker.png)
   skin/classic/browser/places/unsortedBookmarks.png   (places/unsortedBookmarks.png)
   skin/classic/browser/places/downloads.png           (places/downloads.png)
   skin/classic/browser/preferences/alwaysAsk.png      (preferences/alwaysAsk.png)
   skin/classic/browser/preferences/mail.png           (preferences/mail.png)
   skin/classic/browser/preferences/Options.png        (preferences/Options.png)
deleted file mode 100644
index 2f97e742a3f0855c97a356c9f699b3bda3ac7c7b..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/themes/pinstripe/browser.css
+++ b/browser/themes/pinstripe/browser.css
@@ -1101,18 +1101,17 @@ toolbar[mode="icons"] #zoom-in-button {
   min-width: 8px;
   width: 8px;
   background-image: none;
   margin: 0 -4px;
   position: relative;
   height: 22px;
 }
 
-#page-proxy-favicon,
-#urlbar-throbber {
+#page-proxy-favicon {
   width: 16px;
   height: 16px;
   margin: 0px;
   padding: 0px;
 }
 
 #page-proxy-stack {
   width: 16px;
@@ -1122,20 +1121,16 @@ toolbar[mode="icons"] #zoom-in-button {
 #page-proxy-favicon:not([src]) {
   list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
 }
 
 #page-proxy-favicon[pageproxystate="invalid"] {
   opacity: 0.5;
 }
 
-#urlbar-throbber {
-  list-style-image: url("chrome://browser/skin/places/searching_16.png");
-}
-
 #wrapper-urlbar-container[place="palette"] {
   max-width: 20em;
 }
 
 #urlbar-display-box {
   -moz-border-end: 1px solid #AAA;
   -moz-margin-end: 3px;
 }
--- a/browser/themes/pinstripe/jar.mn
+++ b/browser/themes/pinstripe/jar.mn
@@ -71,17 +71,16 @@ browser.jar:
   skin/classic/browser/places/toolbarDropMarker.png         (places/toolbarDropMarker.png)
   skin/classic/browser/places/folderDropArrow.png           (places/folderDropArrow.png)
   skin/classic/browser/places/editBookmarkOverlay.css       (places/editBookmarkOverlay.css)
   skin/classic/browser/places/minus.png                     (places/minus.png)
   skin/classic/browser/places/minus-active.png              (places/minus-active.png)
   skin/classic/browser/places/plus.png                      (places/plus.png)
   skin/classic/browser/places/plus-active.png               (places/plus-active.png)
   skin/classic/browser/places/starPage.png                  (places/starPage.png)
-  skin/classic/browser/places/searching_16.png              (places/searching_16.png)
   skin/classic/browser/places/starred48.png                 (places/starred48.png)
   skin/classic/browser/places/unstarred48.png               (places/unstarred48.png)
   skin/classic/browser/places/unfiledBookmarks.png          (places/unfiledBookmarks.png)
   skin/classic/browser/places/twisty-open.gif               (places/twisty-open.gif)
   skin/classic/browser/places/twisty-closed.gif             (places/twisty-closed.gif)
   skin/classic/browser/places/tag.png                       (places/tag.png)
   skin/classic/browser/places/downloads.png                 (places/downloads.png)
   skin/classic/browser/places/expander-closed-active.png    (places/expander-closed-active.png)
deleted file mode 100644
index 15ec5d0a76f7bc9cd478f44c17e1af60d92b8abf..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/themes/winstripe/browser.css
+++ b/browser/themes/winstripe/browser.css
@@ -1484,18 +1484,17 @@ html|*.urlbar-input:-moz-lwtheme:-moz-pl
 .urlbar-history-dropmarker:hover:active,
 .urlbar-history-dropmarker[open="true"] {
   background-image: -moz-radial-gradient(center, circle closest-side, hsla(205,100%,70%,.1), hsla(205,100%,70%,0));
   -moz-image-region: rect(0px, 33px, 14px, 22px);
 }
 
 /* page proxy icon */
 
-#page-proxy-favicon,
-#urlbar-throbber {
+#page-proxy-favicon {
   width: 16px;
   height: 16px;
 }
 
 #page-proxy-stack {
   width: 24px;
   height: 18px;
   padding: 1px 4px;
@@ -1504,20 +1503,16 @@ html|*.urlbar-input:-moz-lwtheme:-moz-pl
 #page-proxy-favicon:not([src]) {
   list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
 }
 
 #page-proxy-favicon[pageproxystate="invalid"] {
   opacity: 0.5;
 }
 
-#urlbar-throbber {
-  list-style-image: url("chrome://browser/skin/places/searching_16.png");
-}
-
 /* autocomplete */
 
 #treecolAutoCompleteImage {
   max-width: 36px;
 }
 
 .ac-result-type-bookmark,
 .autocomplete-treebody::-moz-tree-image(bookmark, treecolAutoCompleteImage) {
--- a/browser/themes/winstripe/jar.mn
+++ b/browser/themes/winstripe/jar.mn
@@ -70,17 +70,16 @@ browser.jar:
         skin/classic/browser/places/editBookmarkOverlay.css          (places/editBookmarkOverlay.css)
         skin/classic/browser/places/libraryToolbar.png               (places/libraryToolbar.png)
         skin/classic/browser/places/starred48.png                    (places/starred48.png)
         skin/classic/browser/places/unstarred48.png                  (places/unstarred48.png)
         skin/classic/browser/places/tag.png                          (places/tag.png)
         skin/classic/browser/places/history.png                      (places/history.png)
         skin/classic/browser/places/allBookmarks.png                 (places/allBookmarks.png)
         skin/classic/browser/places/unsortedBookmarks.png            (places/unsortedBookmarks.png)
-        skin/classic/browser/places/searching_16.png                 (places/searching_16.png)
         skin/classic/browser/places/downloads.png                    (places/downloads.png)
         skin/classic/browser/preferences/alwaysAsk.png               (preferences/alwaysAsk.png)
         skin/classic/browser/preferences/application.png             (preferences/application.png)
         skin/classic/browser/preferences/mail.png                    (preferences/mail.png)
         skin/classic/browser/preferences/Options.png                 (preferences/Options.png)
 #ifdef MOZ_SERVICES_SYNC
         skin/classic/browser/preferences/Options-sync.png            (preferences/Options-sync.png)
 #endif
@@ -226,17 +225,16 @@ browser.jar:
         skin/classic/aero/browser/places/editBookmarkOverlay.css     (places/editBookmarkOverlay.css)
         skin/classic/aero/browser/places/libraryToolbar.png          (places/libraryToolbar-aero.png)
         skin/classic/aero/browser/places/starred48.png               (places/starred48-aero.png)
         skin/classic/aero/browser/places/unstarred48.png             (places/unstarred48.png)
         skin/classic/aero/browser/places/tag.png                     (places/tag-aero.png)
         skin/classic/aero/browser/places/history.png                 (places/history-aero.png)
         skin/classic/aero/browser/places/allBookmarks.png            (places/allBookmarks-aero.png)
         skin/classic/aero/browser/places/unsortedBookmarks.png       (places/unsortedBookmarks-aero.png)
-        skin/classic/aero/browser/places/searching_16.png            (places/searching_16.png)
         skin/classic/aero/browser/places/downloads.png               (places/downloads.png)
         skin/classic/aero/browser/preferences/alwaysAsk.png          (preferences/alwaysAsk-aero.png)
         skin/classic/aero/browser/preferences/application.png        (preferences/application-aero.png)
         skin/classic/aero/browser/preferences/mail.png               (preferences/mail-aero.png)
         skin/classic/aero/browser/preferences/Options.png            (preferences/Options-aero.png)
 #ifdef MOZ_SERVICES_SYNC
         skin/classic/aero/browser/preferences/Options-sync.png       (preferences/Options-sync.png)
 #endif
deleted file mode 100644
index 2f97e742a3f0855c97a356c9f699b3bda3ac7c7b..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
new file mode 100644
--- /dev/null
+++ b/build/macosx/common
@@ -0,0 +1,2 @@
+CC=/usr/bin/gcc-4.2
+CXX=/usr/bin/g++-4.2
--- a/build/macosx/mozconfig.leopard
+++ b/build/macosx/mozconfig.leopard
@@ -1,15 +1,9 @@
-if test -z "$CC" ; then
-   CC=gcc-4.2
-fi
-
-if test -z "$CXX" ; then
-   CXX=g++-4.2
-fi
+. $topsrcdir/build/macosx/common
 
 # Mac builds don't nomally have to be handled as cross
 # compilation, but some of the libraries on the bots
 # (IDL for example) are built only for one arch.
 
 HOST_CC=$CC
 HOST_CXX=$CXX
 
--- a/build/macosx/universal/mozconfig.common
+++ b/build/macosx/universal/mozconfig.common
@@ -40,31 +40,25 @@ mk_add_options MOZ_POSTFLIGHT_ALL+=build
 
 # Note, the version (10) is used by libffi's configure.
 ac_add_app_options i386 --target=i386-apple-darwin10
 ac_add_app_options x86_64 --target=x86_64-apple-darwin10
 
 ac_add_app_options i386 --with-macos-sdk=/Developer/SDKs/MacOSX10.5.sdk
 ac_add_app_options x86_64 --with-macos-sdk=/Developer/SDKs/MacOSX10.6.sdk
 
+. $topsrcdir/build/macosx/common
+
 # $MOZ_BUILD_APP is only defined when sourced by configure.  That's not a
 # problem, because the variables it affects only need to be set for
 # configure.
 if test -n "$MOZ_BUILD_APP" ; then
 if test "$MOZ_BUILD_APP" = "i386" -o "$MOZ_BUILD_APP" = "x86_64"; then
   TARGET_CPU=$MOZ_BUILD_APP
 
-  if test -z "$CC" ; then
-     CC=gcc-4.2
-  fi
-
-  if test -z "$CXX" ; then
-     CXX=g++-4.2
-  fi
-
   # $HOST_CXX is presently unused.  $HOST_CC will only be used during a cross
   # compile.
   HOST_CC=$CC
   HOST_CXX=$CXX
 
   NATIVE_CPU=`$topsrcdir/build/autoconf/config.guess | cut -f1 -d-`
 
   # It's not strictly necessary to specify -arch during native builds, but it
--- a/client.mk
+++ b/client.mk
@@ -110,17 +110,17 @@ CONFIG_GUESS_SCRIPT := $(wildcard $(TOPS
 ifdef CONFIG_GUESS_SCRIPT
   CONFIG_GUESS = $(shell $(CONFIG_GUESS_SCRIPT))
 endif
 
 
 ####################################
 # Sanity checks
 
-ifneq (,$(filter MINGW%,$(shell uname -s)))
+ifneq (,$(findstring mingw,$(CONFIG_GUESS)))
 # check for CRLF line endings
 ifneq (0,$(shell $(PERL) -e 'binmode(STDIN); while (<STDIN>) { if (/\r/) { print "1"; exit } } print "0"' < $(TOPSRCDIR)/client.mk))
 $(error This source tree appears to have Windows-style line endings. To \
 convert it to Unix-style line endings, run \
 "python mozilla/build/win32/mozilla-dos2unix.py")
 endif
 endif
 
@@ -128,25 +128,30 @@ endif
 # Load mozconfig Options
 
 # See build pages, http://www.mozilla.org/build/ for how to set up mozconfig.
 
 MOZCONFIG_LOADER := build/autoconf/mozconfig2client-mk
 MOZCONFIG_FINDER := build/autoconf/mozconfig-find 
 MOZCONFIG_MODULES := build/unix/uniq.pl
 
-
-
 run_for_side_effects := \
   $(shell $(TOPSRCDIR)/$(MOZCONFIG_LOADER) $(TOPSRCDIR) $(TOPSRCDIR)/.mozconfig.mk > $(TOPSRCDIR)/.mozconfig.out)
 
 include $(TOPSRCDIR)/.mozconfig.mk
 
 ifndef MOZ_OBJDIR
   MOZ_OBJDIR = obj-$(CONFIG_GUESS)
+else
+# On Windows Pymake builds check MOZ_OBJDIR doesn't start with "/"
+  ifneq (,$(findstring mingw,$(CONFIG_GUESS)))
+  ifeq (1_a,$(.PYMAKE)_$(firstword a$(subst /, ,$(MOZ_OBJDIR))))
+  $(error For Windows Pymake builds, MOZ_OBJDIR must be a Windows [and not MSYS] style path.)
+  endif
+  endif
 endif
 
 ifdef MOZ_BUILD_PROJECTS
 
 ifdef MOZ_CURRENT_PROJECT
   OBJDIR = $(MOZ_OBJDIR)/$(MOZ_CURRENT_PROJECT)
   MOZ_MAKE = $(MAKE) $(MOZ_MAKE_FLAGS) -C $(OBJDIR)
   BUILD_PROJECT_ARG = MOZ_BUILD_APP=$(MOZ_CURRENT_PROJECT)
@@ -289,16 +294,20 @@ CONFIG_STATUS_DEPS := \
 	$(TOPSRCDIR)/.mozconfig.mk \
 	$(wildcard $(TOPSRCDIR)/nsprpub/configure) \
 	$(wildcard $(TOPSRCDIR)/config/milestone.txt) \
 	$(wildcard $(TOPSRCDIR)/js/src/config/milestone.txt) \
 	$(wildcard $(TOPSRCDIR)/browser/config/version.txt) \
 	$(wildcard $(addsuffix confvars.sh,$(wildcard $(TOPSRCDIR)/*/))) \
 	$(NULL)
 
+CONFIGURE_ENV_ARGS += \
+  MAKE="$(MAKE)" \
+  $(NULL)
+
 # configure uses the program name to determine @srcdir@. Calling it without
 #   $(TOPSRCDIR) will set @srcdir@ to "."; otherwise, it is set to the full
 #   path of $(TOPSRCDIR).
 ifeq ($(TOPSRCDIR),$(OBJDIR))
   CONFIGURE = ./configure
 else
   CONFIGURE = $(TOPSRCDIR)/configure
 endif
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -59,16 +59,18 @@ endif
 
 ifdef SDK_XPIDLSRCS
 XPIDLSRCS += $(SDK_XPIDLSRCS)
 endif
 ifdef SDK_HEADERS
 EXPORTS += $(SDK_HEADERS)
 endif
 
+REPORT_BUILD = @echo $(notdir $<)
+
 ifeq ($(OS_ARCH),OS2)
 EXEC			=
 else
 EXEC			= exec
 endif
 
 # Don't copy xulrunner files at install time, when using system xulrunner
 ifdef SYSTEM_LIBXUL
@@ -1143,45 +1145,53 @@ MAKE_DEPS_AUTO_CC = $(MAKE_DEPS_AUTO)
 MAKE_DEPS_AUTO_CXX = $(MAKE_DEPS_AUTO)
 
 endif # COMPILER_DEPEND
 
 endif # MOZ_AUTO_DEPS
 
 # Rules for building native targets must come first because of the host_ prefix
 host_%.$(OBJ_SUFFIX): %.c $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
 host_%.$(OBJ_SUFFIX): %.cpp $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
 host_%.$(OBJ_SUFFIX): %.cc $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
 host_%.$(OBJ_SUFFIX): %.m $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(HOST_CMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
 host_%.$(OBJ_SUFFIX): %.mm $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(HOST_CMMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
 %:: %.c $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
 	$(ELOG) $(CC) $(CFLAGS) $(LDFLAGS) $(OUTOPTION)$@ $(_VPATH_SRCS)
 
 %.$(OBJ_SUFFIX): %.c $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
 	$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(_VPATH_SRCS)
 
 # DEFINES and ACDEFINES are needed here to enable conditional compilation of Q_OBJECTs:
 # 'moc' only knows about #defines it gets on the command line (-D...), not in
 # included headers like mozilla-config.h
 moc_%.cpp: %.h $(GLOBAL_DEPS)
 	$(MOC) $(DEFINES) $(ACDEFINES) $< $(OUTOPTION)$@
 
 moc_%.cc: %.cc $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	$(ELOG) $(MOC) $(DEFINES) $(ACDEFINES) $(_VPATH_SRCS:.cc=.h) $(OUTOPTION)$@
 
 ifdef ASFILES
 # The AS_DASH_C_FLAG is needed cause not all assemblers (Solaris) accept
 # a '-c' flag.
 %.$(OBJ_SUFFIX): %.$(ASM_SUFFIX) $(GLOBAL_DEPS)
 	$(AS) $(ASOUTOPTION)$@ $(ASFLAGS) $(AS_DASH_C_FLAG) $(_VPATH_SRCS)
 endif
@@ -1192,34 +1202,38 @@ endif
 %:: %.cpp $(GLOBAL_DEPS)
 	@$(MAKE_DEPS_AUTO_CXX)
 	$(CCC) $(OUTOPTION)$@ $(CXXFLAGS) $(_VPATH_SRCS) $(LDFLAGS)
 
 #
 # Please keep the next two rules in sync.
 #
 %.$(OBJ_SUFFIX): %.cc $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CXX)
 	$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
 
 %.$(OBJ_SUFFIX): %.cpp $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CXX)
 ifdef STRICT_CPLUSPLUS_SUFFIX
 	echo "#line 1 \"$*.cpp\"" | cat - $*.cpp > t_$*.cc
 	$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) t_$*.cc
 	$(RM) t_$*.cc
 else
 	$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
 endif #STRICT_CPLUSPLUS_SUFFIX
 
 $(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.mm $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CXX)
 	$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(_VPATH_SRCS)
 
 $(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.m $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
 	$(ELOG) $(CC) -o $@ -c $(COMPILE_CFLAGS) $(COMPILE_CMFLAGS) $(_VPATH_SRCS)
 
 %.s: %.cpp
 	$(CCC) -S $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
 
 %.s: %.cc
 	$(CCC) -S $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
@@ -1459,27 +1473,29 @@ endif
 
 XPIDL_DEPS = \
   $(topsrcdir)/xpcom/idl-parser/header.py \
   $(topsrcdir)/xpcom/idl-parser/typelib.py \
   $(topsrcdir)/xpcom/idl-parser/xpidl.py \
   $(NULL)
 
 $(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_DEPS) $(XPIDL_GEN_DIR)/.done
+	$(REPORT_BUILD)
 	$(PYTHON_PATH) \
 	  -I$(topsrcdir)/other-licenses/ply \
 	  -I$(topsrcdir)/xpcom/idl-parser \
 	  $(topsrcdir)/xpcom/idl-parser/header.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
 	@if test -n "$(findstring $*.h, $(EXPORTS))"; \
 	  then echo "*** WARNING: file $*.h generated from $*.idl overrides $(srcdir)/$*.h"; else true; fi
 
 ifndef NO_GEN_XPT
 # generate intermediate .xpt files into $(XPIDL_GEN_DIR), then link
 # into $(XPIDL_MODULE).xpt and export it to $(FINAL_TARGET)/components.
 $(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_DEPS) $(XPIDL_GEN_DIR)/.done
+	$(REPORT_BUILD)
 	$(PYTHON_PATH) \
 	  -I$(topsrcdir)/other-licenses/ply \
 	  -I$(topsrcdir)/xpcom/idl-parser \
 	  -I$(topsrcdir)/xpcom/typelib/xpt/tools \
 	  $(topsrcdir)/xpcom/idl-parser/typelib.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
 
 # no need to link together if XPIDLSRCS contains only XPIDL_MODULE
 ifneq ($(XPIDL_MODULE).idl,$(strip $(XPIDLSRCS)))
@@ -1758,22 +1774,25 @@ else # ! COMPILER_DEPEND
 
 ifndef MOZ_AUTO_DEPS
 
 define MAKE_DEPS_NOAUTO
 	$(MKDEPEND) -w1024 -o'.$(OBJ_SUFFIX)' -f- $(DEFINES) $(ACDEFINES) $(INCLUDES) $< 2>/dev/null | sed -e "s|^[^ ]*/||" > $@
 endef
 
 $(MDDEPDIR)/%.pp: %.c
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_NOAUTO)
 
 $(MDDEPDIR)/%.pp: %.cpp
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_NOAUTO)
 
 $(MDDEPDIR)/%.pp: %.s
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_NOAUTO)
 
 ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS))
 depend:: $(SUBMAKEFILES) $(MAKE_DIRS) $(MDDEPFILES)
 else
 depend:: $(SUBMAKEFILES)
 endif
 	$(LOOP_OVER_PARALLEL_DIRS)
--- a/configure.in
+++ b/configure.in
@@ -2246,16 +2246,27 @@ changequote(,)
 $PYTHON -c "import sys; sys.exit(sys.version[:3] < sys.argv[1] or sys.version[:2] != '2.')" $PYTHON_VERSION
 _python_res=$?
 changequote([,])
 if test "$_python_res" != 0; then
     AC_MSG_ERROR([Python $PYTHON_VERSION or higher (but not Python 3.x) is required.])
 fi
 AC_MSG_RESULT([yes])
 
+dnl Check for using a custom <stdint.h> implementation
+dnl ========================================================
+AC_MSG_CHECKING(for custom <stdint.h> implementation)
+if test "$MOZ_CUSTOM_STDINT_H"; then
+  AC_DEFINE_UNQUOTED(MOZ_CUSTOM_STDINT_H, "$MOZ_CUSTOM_STDINT_H")
+  AC_SUBST(MOZ_CUSTOM_STDINT_H)
+  AC_MSG_RESULT(using $MOZ_CUSTOM_STDINT_H)
+else
+  AC_MSG_RESULT(none specified)
+fi
+
 dnl Get mozilla version from central milestone file
 MOZILLA_VERSION=`$PERL $srcdir/config/milestone.pl -topsrcdir $srcdir`
 
 dnl Get version of various core apps from the version files.
 FIREFOX_VERSION=`cat $_topsrcdir/browser/config/version.txt`
 
 if test -z "$FIREFOX_VERSION"; then
     AC_MSG_ERROR([FIREFOX_VERSION is unexpectedly blank.])
@@ -3012,57 +3023,18 @@ AC_CACHE_VAL(ac_cv_siginfo_t,
                  [ac_cv_siginfo_t=false])])
 if test "$ac_cv_siginfo_t" = true ; then
   AC_DEFINE(HAVE_SIGINFO_T)
   AC_MSG_RESULT(yes)
 else
   AC_MSG_RESULT(no)
 fi
 
-dnl Check for int16_t, int32_t, int64_t, int64, uint, uint_t, and uint16_t.
-dnl ========================================================
-AC_MSG_CHECKING(for int16_t)
-AC_CACHE_VAL(ac_cv_int16_t,
- [AC_TRY_COMPILE([#include <stdio.h>
-                  #include <sys/types.h>],
-                 [int16_t foo = 0;],
-                 [ac_cv_int16_t=true],
-                 [ac_cv_int16_t=false])])
-if test "$ac_cv_int16_t" = true ; then
-  AC_DEFINE(HAVE_INT16_T)
-  AC_MSG_RESULT(yes)
-else
-  AC_MSG_RESULT(no)
-fi
-AC_MSG_CHECKING(for int32_t)
-AC_CACHE_VAL(ac_cv_int32_t,
- [AC_TRY_COMPILE([#include <stdio.h>
-                  #include <sys/types.h>],
-                 [int32_t foo = 0;],
-                 [ac_cv_int32_t=true],
-                 [ac_cv_int32_t=false])])
-if test "$ac_cv_int32_t" = true ; then
-  AC_DEFINE(HAVE_INT32_T)
-  AC_MSG_RESULT(yes)
-else
-  AC_MSG_RESULT(no)
-fi
-AC_MSG_CHECKING(for int64_t)
-AC_CACHE_VAL(ac_cv_int64_t,
- [AC_TRY_COMPILE([#include <stdio.h>
-                  #include <sys/types.h>],
-                 [int64_t foo = 0;],
-                 [ac_cv_int64_t=true],
-                 [ac_cv_int64_t=false])])
-if test "$ac_cv_int64_t" = true ; then
-  AC_DEFINE(HAVE_INT64_T)
-  AC_MSG_RESULT(yes)
-else
-  AC_MSG_RESULT(no)
-fi
+dnl Check for int64, uint, and uint_t.
+dnl ========================================================
 AC_MSG_CHECKING(for int64)
 AC_CACHE_VAL(ac_cv_int64,
  [AC_TRY_COMPILE([#include <stdio.h>
                   #include <sys/types.h>],
                  [int64 foo = 0;],
                  [ac_cv_int64=true],
                  [ac_cv_int64=false])])
 if test "$ac_cv_int64" = true ; then
@@ -3092,29 +3064,16 @@ AC_CACHE_VAL(ac_cv_uint_t,
                  [ac_cv_uint_t=true],
                  [ac_cv_uint_t=false])])
 if test "$ac_cv_uint_t" = true ; then
   AC_DEFINE(HAVE_UINT_T)
   AC_MSG_RESULT(yes)
 else
   AC_MSG_RESULT(no)
 fi
-AC_MSG_CHECKING(for uint16_t)
-AC_CACHE_VAL(ac_cv_uint16_t,
- [AC_TRY_COMPILE([#include <stdio.h>
-                  #include <sys/types.h>],
-                 [uint16_t foo = 0;],
-                 [ac_cv_uint16_t=true],
-                 [ac_cv_uint16_t=false])])
-if test "$ac_cv_uint16_t" = true ; then
-  AC_DEFINE(HAVE_UINT16_T)
-  AC_MSG_RESULT(yes)
-else
-  AC_MSG_RESULT(no)
-fi
 
 dnl On the gcc trunk (as of 2001-02-09) _GNU_SOURCE, and thus __USE_GNU,
 dnl are defined when compiling C++ but not C.  Since the result of this
 dnl test is used only in C++, do it in C++.
 AC_LANG_CPLUSPLUS
 
 AC_MSG_CHECKING(for uname.domainname)
 AC_CACHE_VAL(ac_cv_have_uname_domainname_field,
@@ -7746,17 +7705,17 @@ dnl ====================================
 MOZ_ARG_HEADER(Compiler Options)
 
 dnl ========================================================
 dnl Check for gcc -pipe support
 dnl ========================================================
 AC_MSG_CHECKING([for gcc -pipe support])
 if test -n "$GNU_CC" -a -n "$GNU_CXX" -a -n "$GNU_AS"; then
     echo '#include <stdio.h>' > dummy-hello.c
-    echo 'int main() { printf("Hello World\n"); exit(0); }' >> dummy-hello.c
+    echo 'int main() { printf("Hello World"); exit(0); }' >> dummy-hello.c
     ${CC} -S dummy-hello.c -o dummy-hello.s 2>&5
     cat dummy-hello.s 2> /dev/null | ${AS_BIN} -o dummy-hello.S - 2>&5
     if test $? = 0; then
         _res_as_stdin="yes"
     else
         _res_as_stdin="no"
     fi
     if test "$_res_as_stdin" = "yes"; then
--- a/content/base/src/nsCSPService.cpp
+++ b/content/base/src/nsCSPService.cpp
@@ -292,17 +292,16 @@ CSPService::AsyncOnChannelRedirect(nsICh
                                         channelPolicy);
     if (NS_SUCCEEDED(rv)) {
       return NS_OK;
     }
   }
 
   // The redirecting channel isn't a writable property bag, we won't be able
   // to enforce the load policy if it redirects again, so we stop it now.
-  nsXPIDLString message;
   nsCAutoString newUriSpec;
   newUri->GetSpec(newUriSpec);
   const PRUnichar *formatParams[] = { NS_ConvertUTF8toUTF16(newUriSpec).get() };
   if (NS_SUCCEEDED(rv)) {
     nsContentUtils::ReportToConsole(nsContentUtils::eDOM_PROPERTIES,
                                    "InvalidRedirectChannelWarning",
                                     formatParams, 1, nsnull, EmptyString(),
                                     0, 0, nsIScriptError::warningFlag,
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -345,16 +345,17 @@ GK_ATOM(elementAvailable, "element-avail
 GK_ATOM(elements, "elements")
 GK_ATOM(em, "em")
 GK_ATOM(embed, "embed")
 GK_ATOM(embossed, "embossed")
 GK_ATOM(empty, "empty")
 GK_ATOM(encoding, "encoding")
 GK_ATOM(enctype, "enctype")
 GK_ATOM(end, "end")
+GK_ATOM(endEvent, "endEvent")
 GK_ATOM(end_after, "end_after")
 GK_ATOM(end_before, "end_before")
 GK_ATOM(equalsize, "equalsize")
 GK_ATOM(error, "error")
 GK_ATOM(even, "even")
 GK_ATOM(event, "event")
 GK_ATOM(events, "events")
 GK_ATOM(excludeResultPrefixes, "exclude-result-prefixes")
@@ -1365,16 +1366,17 @@ GK_ATOM(z, "z")
 GK_ATOM(zoomAndPan, "zoomAndPan")
 
 GK_ATOM(accumulate, "accumulate")
 GK_ATOM(additive, "additive")
 GK_ATOM(attributeName, "attributeName")
 GK_ATOM(attributeType, "attributeType")
 GK_ATOM(auto_reverse, "auto-reverse")
 GK_ATOM(begin, "begin")
+GK_ATOM(beginEvent, "beginEvent")
 GK_ATOM(by, "by")
 GK_ATOM(calcMode, "calcMode")
 GK_ATOM(css, "CSS")
 GK_ATOM(dur, "dur")
 GK_ATOM(keyPoints, "keyPoints")
 GK_ATOM(keySplines, "keySplines")
 GK_ATOM(keyTimes, "keyTimes")
 GK_ATOM(mozAnimateMotionDummyAttr, "_mozAnimateMotionDummyAttr")
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -696,57 +696,56 @@ NS_IMETHODIMP
 nsXMLHttpRequest::GetChannel(nsIChannel **aChannel)
 {
   NS_ENSURE_ARG_POINTER(aChannel);
   NS_IF_ADDREF(*aChannel = mChannel);
 
   return NS_OK;
 }
 
+static void LogMessage(const char* aWarning, nsPIDOMWindow* aWindow)
+{
+  nsCOMPtr<nsIDocument> doc;
+  if (aWindow) {
+    doc = do_QueryInterface(aWindow->GetExtantDocument());
+  }
+  nsContentUtils::ReportToConsole(nsContentUtils::eDOM_PROPERTIES,
+                                  aWarning,
+                                  nsnull,
+                                  0,
+                                  nsnull, // Response URL not kept around
+                                  EmptyString(),
+                                  0,
+                                  0,
+                                  nsIScriptError::warningFlag,
+                                  "DOM",
+                                  doc);
+}
+
 /* readonly attribute nsIDOMDocument responseXML; */
 NS_IMETHODIMP
 nsXMLHttpRequest::GetResponseXML(nsIDOMDocument **aResponseXML)
 {
   NS_ENSURE_ARG_POINTER(aResponseXML);
   *aResponseXML = nsnull;
   if (mResponseType != XML_HTTP_RESPONSE_TYPE_DEFAULT &&
       mResponseType != XML_HTTP_RESPONSE_TYPE_DOCUMENT) {
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
   if ((XML_HTTP_REQUEST_DONE & mState) && mResponseXML) {
     *aResponseXML = mResponseXML;
     NS_ADDREF(*aResponseXML);
   }
   if (mWarnAboutMultipartHtml) {
     mWarnAboutMultipartHtml = false;
-    nsContentUtils::ReportToConsole(nsContentUtils::eDOM_PROPERTIES,
-                                    "HTMLMultipartXHRWarning",
-                                    nsnull,
-                                    0,
-                                    nsnull, // Response URL not kept around
-                                    EmptyString(),
-                                    0,
-                                    0,
-                                    nsIScriptError::warningFlag,
-                                    "DOM",
-                                    mOwner->WindowID());
+    LogMessage("HTMLMultipartXHRWarning", mOwner);
   }
   if (mWarnAboutSyncHtml) {
     mWarnAboutSyncHtml = false;
-    nsContentUtils::ReportToConsole(nsContentUtils::eDOM_PROPERTIES,
-                                    "HTMLSyncXHRWarning",
-                                    nsnull,
-                                    0,
-                                    nsnull, // Response URL not kept around
-                                    EmptyString(),
-                                    0,
-                                    0,
-                                    nsIScriptError::warningFlag,
-                                    "DOM",
-                                    mOwner->WindowID());
+    LogMessage("HTMLSyncXHRWarning", mOwner);
   }
   return NS_OK;
 }
 
 /*
  * This piece copied from nsXMLDocument, we try to get the charset
  * from HTTP headers.
  */
@@ -779,16 +778,23 @@ nsXMLHttpRequest::DetectCharset()
     }
   }
 
   if (NS_FAILED(rv) || mResponseCharset.IsEmpty()) {
     // MS documentation states UTF-8 is default for responseText
     mResponseCharset.AssignLiteral("UTF-8");
   }
 
+  if (mResponseType == XML_HTTP_RESPONSE_TYPE_JSON &&
+      !mResponseCharset.EqualsLiteral("UTF-8")) {
+    // The XHR spec says only UTF-8 is supported for responseType == "json"
+    LogMessage("JSONCharsetWarning", mOwner);
+    mResponseCharset.AssignLiteral("UTF-8");
+  }
+
   nsCOMPtr<nsICharsetConverterManager> ccm =
     do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return ccm->GetUnicodeDecoderRaw(mResponseCharset.get(),
                                    getter_AddRefs(mDecoder));
 }
 
@@ -916,17 +922,17 @@ NS_IMETHODIMP nsXMLHttpRequest::GetRespo
 }
 
 nsresult
 nsXMLHttpRequest::CreateResponseParsedJSON(JSContext* aCx)
 {
   if (!aCx) {
     return NS_ERROR_FAILURE;
   }
-
+  // The Unicode converter has already zapped the BOM if there was one
   if (!JS_ParseJSON(aCx,
                     (jschar*)mResponseText.get(),
                     mResponseText.Length(), &mResultJSON)) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
@@ -969,17 +975,17 @@ NS_IMETHODIMP nsXMLHttpRequest::GetRespo
     break;
   case XML_HTTP_RESPONSE_TYPE_DOCUMENT:
     aResponseType.AssignLiteral("document");
     break;
   case XML_HTTP_RESPONSE_TYPE_TEXT:
     aResponseType.AssignLiteral("text");
     break;
   case XML_HTTP_RESPONSE_TYPE_JSON:
-    aResponseType.AssignLiteral("moz-json");
+    aResponseType.AssignLiteral("json");
     break;
   case XML_HTTP_RESPONSE_TYPE_CHUNKED_TEXT:
     aResponseType.AssignLiteral("moz-chunked-text");
     break;
   case XML_HTTP_RESPONSE_TYPE_CHUNKED_ARRAYBUFFER:
     aResponseType.AssignLiteral("moz-chunked-arraybuffer");
     break;
   default:
@@ -993,28 +999,35 @@ NS_IMETHODIMP nsXMLHttpRequest::GetRespo
 NS_IMETHODIMP nsXMLHttpRequest::SetResponseType(const nsAString& aResponseType)
 {
   // If the state is not OPENED or HEADERS_RECEIVED raise an
   // INVALID_STATE_ERR exception and terminate these steps.
   if (!(mState & (XML_HTTP_REQUEST_OPENED | XML_HTTP_REQUEST_SENT |
                   XML_HTTP_REQUEST_HEADERS_RECEIVED)))
     return NS_ERROR_DOM_INVALID_STATE_ERR;
 
+  // sync request is not allowed setting responseType in window context
+  if (mOwner &&
+      !(mState & (XML_HTTP_REQUEST_UNSENT | XML_HTTP_REQUEST_ASYNC))) {
+    LogMessage("ResponseTypeSyncXHRWarning", mOwner);
+    return NS_ERROR_DOM_INVALID_ACCESS_ERR;
+  }
+
   // Set the responseType attribute's value to the given value.
   if (aResponseType.IsEmpty()) {
     mResponseType = XML_HTTP_RESPONSE_TYPE_DEFAULT;
   } else if (aResponseType.EqualsLiteral("arraybuffer")) {
     mResponseType = XML_HTTP_RESPONSE_TYPE_ARRAYBUFFER;
   } else if (aResponseType.EqualsLiteral("blob")) {
     mResponseType = XML_HTTP_RESPONSE_TYPE_BLOB;
   } else if (aResponseType.EqualsLiteral("document")) {
     mResponseType = XML_HTTP_RESPONSE_TYPE_DOCUMENT;
   } else if (aResponseType.EqualsLiteral("text")) {
     mResponseType = XML_HTTP_RESPONSE_TYPE_TEXT;
-  } else if (aResponseType.EqualsLiteral("moz-json")) {
+  } else if (aResponseType.EqualsLiteral("json")) {
     mResponseType = XML_HTTP_RESPONSE_TYPE_JSON;
   } else if (aResponseType.EqualsLiteral("moz-chunked-text")) {
     if (!(mState & XML_HTTP_REQUEST_ASYNC)) {
       return NS_ERROR_DOM_INVALID_STATE_ERR;
     }
     mResponseType = XML_HTTP_RESPONSE_TYPE_CHUNKED_TEXT;
   } else if (aResponseType.EqualsLiteral("moz-chunked-arraybuffer")) {
     if (!(mState & XML_HTTP_REQUEST_ASYNC)) {
@@ -1093,19 +1106,25 @@ NS_IMETHODIMP nsXMLHttpRequest::GetRespo
       *aResult = JSVAL_NULL;
     }
     break;
 
   case XML_HTTP_RESPONSE_TYPE_JSON:
     if (mState & XML_HTTP_REQUEST_DONE) {
       if (mResultJSON == JSVAL_VOID) {
         rv = CreateResponseParsedJSON(aCx);
-        NS_ENSURE_SUCCESS(rv, rv);
-
         mResponseText.Truncate();
+        if (NS_FAILED(rv)) {
+          // Per spec, errors aren't propagated. null is returned instead.
+          rv = NS_OK;
+          // It would be nice to log the error to the console. That's hard to
+          // do without calling window.onerror as a side effect, though.
+          JS_ClearPendingException(aCx);
+          mResultJSON = JSVAL_NULL;
+        }
       }
       *aResult = mResultJSON;
     } else {
       *aResult = JSVAL_NULL;
     }
     break;
 
   default:
@@ -1514,16 +1533,30 @@ nsXMLHttpRequest::Open(const nsACString&
 
   // Disallow HTTP/1.1 TRACE method (see bug 302489)
   // and MS IIS equivalent TRACK (see bug 381264)
   if (method.LowerCaseEqualsLiteral("trace") ||
       method.LowerCaseEqualsLiteral("track")) {
     return NS_ERROR_INVALID_ARG;
   }
 
+  // sync request is not allowed using withCredential or responseType
+  // in window context
+  if (!async && mOwner &&
+      (mState & XML_HTTP_REQUEST_AC_WITH_CREDENTIALS ||
+       mResponseType != XML_HTTP_RESPONSE_TYPE_DEFAULT)) {
+    if (mState & XML_HTTP_REQUEST_AC_WITH_CREDENTIALS) {
+      LogMessage("WithCredentialsSyncXHRWarning", mOwner);
+    }
+    if (mResponseType != XML_HTTP_RESPONSE_TYPE_DEFAULT) {
+      LogMessage("ResponseTypeSyncXHRWarning", mOwner);
+    }
+    return NS_ERROR_DOM_INVALID_ACCESS_ERR;
+  }
+
   nsresult rv;
   nsCOMPtr<nsIURI> uri;
   bool authp = false;
 
   if (mState & (XML_HTTP_REQUEST_OPENED |
                 XML_HTTP_REQUEST_HEADERS_RECEIVED |
                 XML_HTTP_REQUEST_LOADING |
                 XML_HTTP_REQUEST_SENT |
@@ -2915,17 +2948,24 @@ nsXMLHttpRequest::GetWithCredentials(boo
 /* attribute boolean withCredentials; */
 NS_IMETHODIMP
 nsXMLHttpRequest::SetWithCredentials(bool aWithCredentials)
 {
   // Return error if we're already processing a request
   if (XML_HTTP_REQUEST_SENT & mState) {
     return NS_ERROR_FAILURE;
   }
-  
+
+  // sync request is not allowed setting withCredentials in window context
+  if (mOwner &&
+      !(mState & (XML_HTTP_REQUEST_UNSENT | XML_HTTP_REQUEST_ASYNC))) {
+    LogMessage("WithCredentialsSyncXHRWarning", mOwner);
+    return NS_ERROR_DOM_INVALID_ACCESS_ERR;
+  }
+
   if (aWithCredentials) {
     mState |= XML_HTTP_REQUEST_AC_WITH_CREDENTIALS;
   }
   else {
     mState &= ~XML_HTTP_REQUEST_AC_WITH_CREDENTIALS;
   }
   return NS_OK;
 }
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -528,16 +528,20 @@ include $(topsrcdir)/config/rules.mk
 		test_bug692434.html \
 		file_bug692434.xml \
 		test_bug693875.html \
 		test_nodelist_holes.html \
 		test_xhr_abort_after_load.html \
 		test_bug702439.html \
 		test_bug702439.html^headers^ \
 		file_bug702439.html \
+		test_bug707142.html \
+		file_bug707142_baseline.json \
+		file_bug707142_bom.json \
+		file_bug707142_utf-16.json \
 		$(NULL)
 
 _CHROME_FILES =	\
 		test_bug357450.js \
 		$(NULL)
 
 # This test fails on the Mac for some reason
 ifneq (,$(filter gtk2 windows,$(MOZ_WIDGET_TOOLKIT)))
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_bug707142_baseline.json
@@ -0,0 +1,1 @@
+{"foo": "bar"}
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_bug707142_bom.json
@@ -0,0 +1,1 @@
+{"foo": "bar"}
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..eb28f6bb7ee7ed29876bc03d7c09ade3fbf4cdd5
GIT binary patch
literal 32
jc%1wHubM%LA&ns)2$dMD7!-hH5<?<G5s<EB;9>v(h>!+b
--- a/content/base/test/test_XHR.html
+++ b/content/base/test/test_XHR.html
@@ -1,24 +1,29 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <title>Test for XMLHttpRequest</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>        
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
-<body>
+<body onload="gen.next();">
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
-<script class="testbody" type="text/javascript">
+<script class="testbody" type="application/javascript;version=1.7">
 SimpleTest.waitForExplicitFinish();
 
+var gen = runTests();
+function continueTest() { gen.next(); }
+
+function runTests() {
+
 var path = "/tests/content/base/test/";
 
 var passFiles = [['file_XHR_pass1.xml', 'GET'],
                  ['file_XHR_pass2.txt', 'GET'],
                  ['file_XHR_pass3.txt', 'GET'],
                  ];
 
 var failFiles = [['//example.com' + path + 'file_XHR_pass1.xml', 'GET'],
@@ -58,139 +63,168 @@ for (i = 0; i < failFiles.length; ++i) {
     is(xhr.status, 301, "wrong status");
     is(xhr.responseText, "redirect file\n", "wrong response");
   }
   else {
     ok(1, "should have thrown or given incorrect result");
   }
 }
 
-// test response (responseType='document')
 function checkResponseTextAccessThrows(xhr) {
   var didthrow = false;
   try { xhr.responseText } catch (e) { didthrow = true; }
   ok(didthrow, "should have thrown when accessing responseText");
 }
 function checkResponseXMLAccessThrows(xhr) {
   var didthrow = false;
   try { xhr.responseXML } catch (e) { didthrow = true; }
   ok(didthrow, "should have thrown when accessing responseXML");
 }
-function checkResponseAccessThrows(xhr) {
-  var didthrow = false;
-  try { xhr.response } catch (e) { didthrow = true; }
-  ok(didthrow, "should have thrown when accessing response");
-}
 function checkSetResponseTypeThrows(xhr, type) {
   var didthrow = false;
   try { xhr.responseType = type; } catch (e) { didthrow = true; }
   ok(didthrow, "should have thrown when setting responseType");
 }
+function checkOpenThrows(xhr, method, url, async) {
+  var didthrow = false;
+  try { xhr.open(method, url, async); } catch (e) { didthrow = true; }
+  ok(didthrow, "should have thrown when open is called");
+}
 
+// test response (sync, responseType is not changeable)
 xhr = new XMLHttpRequest();
+xhr.open("GET", 'file_XHR_pass2.txt', false); 
+checkSetResponseTypeThrows(xhr, "");
+checkSetResponseTypeThrows(xhr, "text");
 checkSetResponseTypeThrows(xhr, "document");
-xhr.open("GET", 'file_XHR_pass1.xml', false); 
+checkSetResponseTypeThrows(xhr, "arraybuffer");
+checkSetResponseTypeThrows(xhr, "blob");
+checkSetResponseTypeThrows(xhr, "json");
 checkSetResponseTypeThrows(xhr, "moz-chunked-text");
 checkSetResponseTypeThrows(xhr, "moz-chunked-arraybuffer");
+xhr.send(null);
+checkSetResponseTypeThrows(xhr, "document");
+is(xhr.status, 200, "wrong status");
+is(xhr.response, "hello pass\n", "wrong response");
+
+// test response (responseType='document')
+xhr = new XMLHttpRequest();
+xhr.open("GET", 'file_XHR_pass1.xml'); 
 xhr.responseType = 'document';
+xhr.onloadend = continueTest;
 xhr.send(null);
+yield;
 checkSetResponseTypeThrows(xhr, "document");
 is(xhr.status, 200, "wrong status");
 checkResponseTextAccessThrows(xhr);
 is((new XMLSerializer()).serializeToString(xhr.response.documentElement),
    "<res>hello</res>",
    "wrong response");
 
 // test response (responseType='text')
 xhr = new XMLHttpRequest();
-xhr.open("GET", 'file_XHR_pass2.txt', false); 
+xhr.open("GET", 'file_XHR_pass2.txt'); 
 xhr.responseType = 'text';
+xhr.onloadend = continueTest;
 xhr.send(null);
+yield;
 is(xhr.status, 200, "wrong status");
 checkResponseXMLAccessThrows(xhr);
 is(xhr.response, "hello pass\n", "wrong response");
 
 // test response (responseType='arraybuffer')
 function arraybuffer_equals_to(ab, s) {
   is(ab.byteLength, s.length, "wrong arraybuffer byteLength");
 
   u8v = new Uint8Array(ab);
   is(String.fromCharCode.apply(String, u8v), s, "wrong values");
 }
 
 // with a simple text file
 xhr = new XMLHttpRequest();
-xhr.open("GET", 'file_XHR_pass2.txt', false); 
+xhr.open("GET", 'file_XHR_pass2.txt'); 
 xhr.responseType = 'arraybuffer';
+xhr.onloadend = continueTest;
 xhr.send(null);
+yield;
 is(xhr.status, 200, "wrong status");
 checkResponseTextAccessThrows(xhr);
 checkResponseXMLAccessThrows(xhr);
 ab = xhr.response;
 ok(ab != null, "should have a non-null arraybuffer");
 arraybuffer_equals_to(ab, "hello pass\n");
 
 // test reusing the same XHR (Bug 680816)
-xhr.open("GET", 'file_XHR_binary1.bin', false);
+xhr.open("GET", 'file_XHR_binary1.bin');
 xhr.responseType = 'arraybuffer';
+xhr.onloadend = continueTest;
 xhr.send(null);
+yield;
 is(xhr.status, 200, "wrong status");
 ab2 = xhr.response;
 ok(ab2 != null, "should have a non-null arraybuffer");
 ok(ab2 != ab, "arraybuffer on XHR reuse should be distinct");
 arraybuffer_equals_to(ab, "hello pass\n");
 arraybuffer_equals_to(ab2, "\xaa\xee\0\x03\xff\xff\xff\xff\xbb\xbb\xbb\xbb");
 
 // with a binary file
 xhr = new XMLHttpRequest();
-xhr.open("GET", 'file_XHR_binary1.bin', false); 
+xhr.open("GET", 'file_XHR_binary1.bin'); 
 xhr.responseType = 'arraybuffer';
-xhr.send(null)
+xhr.onloadend = continueTest;
+xhr.send(null);
+yield;
 is(xhr.status, 200, "wrong status");
 checkResponseTextAccessThrows(xhr);
 checkResponseXMLAccessThrows(xhr);
 ab = xhr.response;
 ok(ab != null, "should have a non-null arraybuffer");
 arraybuffer_equals_to(ab, "\xaa\xee\0\x03\xff\xff\xff\xff\xbb\xbb\xbb\xbb");
 is(xhr.response, xhr.response, "returns the same ArrayBuffer");
 
-// test response (responseType='moz-json')
+// test response (responseType='json')
 var xhr = new XMLHttpRequest();
-xhr.open("POST", 'responseIdentical.sjs', false);
-xhr.responseType = 'moz-json';
+xhr.open("POST", 'responseIdentical.sjs');
+xhr.responseType = 'json';
 jsonObjStr = JSON.stringify({title: "aBook", author: "john"});
+xhr.onloadend = continueTest;
 xhr.send(jsonObjStr);
+yield;
 is(xhr.status, 200, "wrong status");
 checkResponseTextAccessThrows(xhr);
 checkResponseXMLAccessThrows(xhr);
 is(JSON.stringify(xhr.response), jsonObjStr, "correct result");
 is(xhr.response, xhr.response, "returning the same object on each access");
 
 // with invalid json
 var xhr = new XMLHttpRequest();
-xhr.open("POST", 'responseIdentical.sjs', false);
-xhr.responseType = 'moz-json';
+xhr.open("POST", 'responseIdentical.sjs');
+xhr.responseType = 'json';
+xhr.onloadend = continueTest;
 xhr.send("{");
+yield;
 is(xhr.status, 200, "wrong status");
 checkResponseTextAccessThrows(xhr);
 checkResponseXMLAccessThrows(xhr);
-checkResponseAccessThrows(xhr);
-checkResponseAccessThrows(xhr); // Check twice to ensure that we still throw
+is(xhr.response, null, "Bad JSON should result in null response.");
+is(xhr.response, null, "Bad JSON should result in null response even 2nd time.");
 
 // test response (responseType='blob')
 var onloadCount = 0;
 function checkOnloadCount() {
   if (++onloadCount >= 3) SimpleTest.finish();
 };
 
 // with a simple text file
 xhr = new XMLHttpRequest();
-xhr.open("GET", 'file_XHR_pass2.txt', false); 
+xhr.open("GET", 'file_XHR_pass2.txt'); 
 xhr.responseType = 'blob';
+xhr.onloadend = continueTest;
 xhr.send(null);
+yield;
 is(xhr.status, 200, "wrong status");
 checkResponseTextAccessThrows(xhr);
 checkResponseXMLAccessThrows(xhr);
 b = xhr.response;
 ok(b, "should have a non-null blob");
 ok(b instanceof Blob, "should be a Blob");
 ok(!(b instanceof File), "should not be a File");
 is(b.size, "hello pass\n".length, "wrong blob size");
@@ -276,12 +310,14 @@ client.onreadystatechange = function() {
         ok(false, "Shouldn't throw! [" + ex + "]");
       }
     }
   }
 client.open("GET", "file_XHR_pass1.xml", true);
 client.send();
 client.abort();
 
+yield;
+} /* runTests */
 </script>
 </pre>
 </body>
 </html>
--- a/content/base/test/test_XHRSendData.html
+++ b/content/base/test/test_XHRSendData.html
@@ -3,27 +3,33 @@
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=464848
 -->
 <head>
   <title>XMLHttpRequest send data and headers</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>        
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
-<body>
+<body onload="gen.next();">
 <a target="_blank"
    href="https://bugzilla.mozilla.org/show_bug.cgi?id=464848">Mozilla Bug 464848</a>
 <p id="display">
   <input id="fileList" type="file"></input>
 </p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
 <script class="testbody" type="application/javascript;version=1.8">
+SimpleTest.waitForExplicitFinish();
+
+var gen = runTests();
+function continueTest() { gen.next(); }
+
+function runTests() {
 
 xhr = new XMLHttpRequest();
 xhr.open("GET", "file_XHRSendData_doc.xml", false);
 xhr.send();
 testDoc1 = xhr.responseXML;
 is(testDoc1.inputEncoding, "ISO-8859-1", "wrong encoding");
 
 testDoc2 = document.implementation.createDocument("", "", null);
@@ -171,22 +177,26 @@ for (var i = 0; i < testDOMFiles.length;
                resContentType: fileTypes[i],
                resContentLength: testData.length,
               });
 }
 
 try {
   for each(test in tests) {
     xhr = new XMLHttpRequest;
-    xhr.open("POST", "file_XHRSendData.sjs", false);
+    xhr.open("POST", "file_XHRSendData.sjs", !!test.resType);
     if (test.contentType)
       xhr.setRequestHeader("Content-Type", test.contentType);
-    if (test.resType)
+    if (test.resType) {
       xhr.responseType = test.resType;
+      xhr.onloadend = continueTest;
+    }
     xhr.send(test.body);
+    if (test.resType)
+      yield;
 
     if (test.resContentType) {
       is(xhr.getResponseHeader("Result-Content-Type"), test.resContentType,
          "Wrong Content-Type sent");
     }
     else {
       is(xhr.getResponseHeader("Result-Content-Type"), null);
     }
@@ -229,12 +239,16 @@ function cleanUpData() {
 function is_identical_arraybuffer(ab1, ab2) {
   is(ab1.byteLength, ab2.byteLength, "arraybuffer byteLengths not equal");
   u8v1 = new Uint8Array(ab1);
   u8v2 = new Uint8Array(ab2);
   is(String.fromCharCode.apply(String, u8v1),
      String.fromCharCode.apply(String, u8v2), "arraybuffer values not equal");
 }
 
+SimpleTest.finish();
+yield;
+} /* runTests */
+
 </script>
 </pre>
 </body>
 </html>
--- a/content/base/test/test_bug338583.html
+++ b/content/base/test/test_bug338583.html
@@ -419,114 +419,122 @@ https://bugzilla.mozilla.org/show_bug.cg
   }
 
   function doTest5_c(test_id)
   {
     // credentials using the auth cache and cookies
     var xhr = SpecialPowers.createSystemXHR();
     xhr.withCredentials = true;
     // also, test mixed mode UI
-    xhr.open("GET", "https://example.com/tests/content/base/test/file_restrictedEventSource.sjs?test=user1_xhr", false, "user 1", "password 1");
+    xhr.open("GET", "https://example.com/tests/content/base/test/file_restrictedEventSource.sjs?test=user1_xhr", true, "user 1", "password 1");
     xhr.send();
-    ok(xhr.status == 200, "Failed to set credentials in test 5.c");
+    xhr.onloadend = function() {
+      ok(xhr.status == 200, "Failed to set credentials in test 5.c");
 
-    gEventSourceObj5_c = new EventSource("https://example.com/tests/content/base/test/file_restrictedEventSource.sjs?test=user1_evtsrc",
-                                         { withCredentials: true } );
-    ok(gEventSourceObj5_c.withCredentials, "Wrong withCredentials in test 5.c");
+      gEventSourceObj5_c = new EventSource("https://example.com/tests/content/base/test/file_restrictedEventSource.sjs?test=user1_evtsrc",
+                                           { withCredentials: true } );
+      ok(gEventSourceObj5_c.withCredentials, "Wrong withCredentials in test 5.c");
 
-    gEventSourceObj5_c.onmessage = function(e) {
-      ok(e.origin == "https://example.com", "Wrong Origin in test 5.c");
-      fn_onmessage(e);
+      gEventSourceObj5_c.onmessage = function(e) {
+        ok(e.origin == "https://example.com", "Wrong Origin in test 5.c");
+        fn_onmessage(e);
+      };
+      gEventSourceObj5_c.hits = [];
+      gEventSourceObj5_c.hits['fn_onmessage'] = 0;
+
+      setTimeout(function() {
+        ok(gEventSourceObj5_c.hits['fn_onmessage'] > 0, "Test 5.c failed");
+        gEventSourceObj5_c.close();
+        doTest5_d(test_id);
+      }, parseInt(3000*stress_factor));
     };
-    gEventSourceObj5_c.hits = [];
-    gEventSourceObj5_c.hits['fn_onmessage'] = 0;
-
-    setTimeout(function() {
-      ok(gEventSourceObj5_c.hits['fn_onmessage'] > 0, "Test 5.c failed");
-      gEventSourceObj5_c.close();
-      doTest5_d(test_id);
-    }, parseInt(3000*stress_factor));
   }
 
   function doTest5_d(test_id)
   {
     var xhr = SpecialPowers.createSystemXHR();
     xhr.withCredentials = true;
-    xhr.open("GET", "https://example.com/tests/content/base/test/file_restrictedEventSource.sjs?test=user2_xhr", false, "user 2", "password 2");
+    xhr.open("GET", "https://example.com/tests/content/base/test/file_restrictedEventSource.sjs?test=user2_xhr", true, "user 2", "password 2");
     xhr.send();
-    ok(xhr.status == 200, "Failed to set credentials in test 5.d");
-
-    gEventSourceObj5_d = new EventSource("https://example.com/tests/content/base/test/file_restrictedEventSource.sjs?test=user2_evtsrc");
-    ok(!gEventSourceObj5_d.withCredentials, "Wrong withCredentials in test 5.d");
-
-    gEventSourceObj5_d.onmessage = function(e) {
-      ok(e.origin == "https://example.com", "Wrong Origin in test 5.d");
-      fn_onmessage(e);
+    xhr.onloadend = function() {
+      ok(xhr.status == 200, "Failed to set credentials in test 5.d");
+  
+      gEventSourceObj5_d = new EventSource("https://example.com/tests/content/base/test/file_restrictedEventSource.sjs?test=user2_evtsrc");
+      ok(!gEventSourceObj5_d.withCredentials, "Wrong withCredentials in test 5.d");
+  
+      gEventSourceObj5_d.onmessage = function(e) {
+        ok(e.origin == "https://example.com", "Wrong Origin in test 5.d");
+        fn_onmessage(e);
+      };
+      gEventSourceObj5_d.hits = [];
+      gEventSourceObj5_d.hits['fn_onmessage'] = 0;
+  
+      setTimeout(function() {
+        ok(gEventSourceObj5_d.hits['fn_onmessage'] == 0, "Test 5.d failed");
+        gEventSourceObj5_d.close();
+        setTestHasFinished(test_id);
+      }, parseInt(3000*stress_factor));
     };
-    gEventSourceObj5_d.hits = [];
-    gEventSourceObj5_d.hits['fn_onmessage'] = 0;
-
-    setTimeout(function() {
-      ok(gEventSourceObj5_d.hits['fn_onmessage'] == 0, "Test 5.d failed");
-      gEventSourceObj5_d.close();
-      setTestHasFinished(test_id);
-    }, parseInt(3000*stress_factor));
   }
 
   function doTest5_e(test_id)
   {
     // credentials using the auth cache and cookies
     var xhr = SpecialPowers.createSystemXHR();
     xhr.withCredentials = true;
-    xhr.open("GET", "http://example.org/tests/content/base/test/file_restrictedEventSource.sjs?test=user1_xhr", false, "user 1", "password 1");
+    xhr.open("GET", "http://example.org/tests/content/base/test/file_restrictedEventSource.sjs?test=user1_xhr", true, "user 1", "password 1");
     xhr.send();
-    ok(xhr.status == 200, "Failed to set credentials in test 5.e");
+    xhr.onloadend = function() {
+      ok(xhr.status == 200, "Failed to set credentials in test 5.e");
 
-    gEventSourceObj5_e = new EventSource("http://example.org/tests/content/base/test/file_restrictedEventSource.sjs?test=user1_evtsrc",
-                                         { get withCredentials() { return true; } } );
-    ok(gEventSourceObj5_e.withCredentials, "Wrong withCredentials in test 5.e");
+      gEventSourceObj5_e = new EventSource("http://example.org/tests/content/base/test/file_restrictedEventSource.sjs?test=user1_evtsrc",
+                                           { get withCredentials() { return true; } } );
+      ok(gEventSourceObj5_e.withCredentials, "Wrong withCredentials in test 5.e");
 
-    gEventSourceObj5_e.onmessage = function(e) {
-      ok(e.origin == "http://example.org", "Wrong Origin in test 5.e");
-      fn_onmessage(e);
+      gEventSourceObj5_e.onmessage = function(e) {
+        ok(e.origin == "http://example.org", "Wrong Origin in test 5.e");
+        fn_onmessage(e);
+      };
+      gEventSourceObj5_e.hits = [];
+      gEventSourceObj5_e.hits['fn_onmessage'] = 0;
+
+      setTimeout(function() {
+        ok(gEventSourceObj5_e.hits['fn_onmessage'] > 0, "Test 5.e failed");
+        gEventSourceObj5_e.close();
+        doTest5_f(test_id);
+      }, parseInt(5000*stress_factor));
     };
-    gEventSourceObj5_e.hits = [];
-    gEventSourceObj5_e.hits['fn_onmessage'] = 0;
-
-    setTimeout(function() {
-      ok(gEventSourceObj5_e.hits['fn_onmessage'] > 0, "Test 5.e failed");
-      gEventSourceObj5_e.close();
-      doTest5_f(test_id);
-    }, parseInt(5000*stress_factor));
   }
 
   function doTest5_f(test_id)
   {
     var xhr = SpecialPowers.createSystemXHR();
     xhr.withCredentials = true;
-    xhr.open("GET", "http://example.org/tests/content/base/test/file_restrictedEventSource.sjs?test=user2_xhr", false, "user 2", "password 2");
+    xhr.open("GET", "http://example.org/tests/content/base/test/file_restrictedEventSource.sjs?test=user2_xhr", true, "user 2", "password 2");
     xhr.send();
-    ok(xhr.status == 200, "Failed to set credentials in test 5.f");
+    xhr.onloadend = function() {
+      ok(xhr.status == 200, "Failed to set credentials in test 5.f");
 
-    gEventSourceObj5_f = new EventSource("http://example.org/tests/content/base/test/file_restrictedEventSource.sjs?test=user2_evtsrc",
-                                         { });
-    ok(!gEventSourceObj5_f.withCredentials, "Wrong withCredentials in test 5.f");
+      gEventSourceObj5_f = new EventSource("http://example.org/tests/content/base/test/file_restrictedEventSource.sjs?test=user2_evtsrc",
+                                           { });
+      ok(!gEventSourceObj5_f.withCredentials, "Wrong withCredentials in test 5.f");
 
-    gEventSourceObj5_f.onmessage = function(e) {
-      ok(e.origin == "http://example.org", "Wrong Origin in test 5.f");
-      fn_onmessage(e);
+      gEventSourceObj5_f.onmessage = function(e) {
+        ok(e.origin == "http://example.org", "Wrong Origin in test 5.f");
+        fn_onmessage(e);
+      };
+      gEventSourceObj5_f.hits = [];
+      gEventSourceObj5_f.hits['fn_onmessage'] = 0;
+
+      setTimeout(function() {
+        ok(gEventSourceObj5_f.hits['fn_onmessage'] == 0, "Test 5.f failed");
+        gEventSourceObj5_f.close();
+        setTestHasFinished(test_id);
+      }, parseInt(3000*stress_factor));
     };
-    gEventSourceObj5_f.hits = [];
-    gEventSourceObj5_f.hits['fn_onmessage'] = 0;
-
-    setTimeout(function() {
-      ok(gEventSourceObj5_f.hits['fn_onmessage'] == 0, "Test 5.f failed");
-      gEventSourceObj5_f.close();
-      setTestHasFinished(test_id);
-    }, parseInt(3000*stress_factor));
   }
 
   function doTest6(test_id)
   {
     gEventSourceObj6 = new EventSource("somedatas.resource");
     var fn_somedata = function(e) {
       if (fn_somedata.expected == 0) {
         ok(e.data == "123456789\n123456789123456789\n123456789123456789123456789123456789\n 123456789123456789123456789123456789123456789123456789123456789123456789\nçãá\"\'@`~Ý Ḿyyyy",
--- a/content/base/test/test_bug466080.html
+++ b/content/base/test/test_bug466080.html
@@ -81,38 +81,47 @@ var alltests = [
 ];
 
 function onWindowLoad() {
     // First, check that resource was loaded into the iframe
     // This check in fact depends on bug #444165... :)
     ok(document.iframeWasLoaded, "Loading resource via src-attribute");
 
 
-    for each (test in alltests) {
+    function runTest(test) {
 
         var xhr =  new XMLHttpRequest();
-        
+
         var method = "GET";
         if (test.method != null) { method = test.method; }
-        xhr.open(method, test.url, false);
-        
+        xhr.open(method, test.url);
+
         xhr.withCredentials = test.withCredentials;
 
         netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
         xhr.setRequestHeader("Connection", "Keep-Alive", false);
         netscape.security.PrivilegeManager.disablePrivilege("UniversalXPConnect");
 
         try {
             xhr.send();
         } catch(e) {
         }
-        var success = eval(xhr.status + test.status_check);
-        ok(success, test.error);
+
+        xhr.onloadend = function() {
+            var success = eval(xhr.status + test.status_check);
+            ok(success, test.error);
+
+            if (alltests.length == 0) {
+                SimpleTest.finish();
+            } else {
+                runTest(alltests.shift());
+            }
+        };
     }
-    
-    SimpleTest.finish();
+
+    runTest(alltests.shift());
 }
 
 SimpleTest.waitForExplicitFinish();
 
 </script>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug707142.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=707142
+-->
+<head>
+  <title>Test for Bug 707142</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=707142">Mozilla Bug 707142</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 707142 **/
+
+SimpleTest.waitForExplicitFinish();
+
+var xhr = new XMLHttpRequest();
+xhr.onload = function() {
+  is(xhr.response["foo"], "bar", "Should have gotten bar on baseline");
+  
+  xhr.onload = function() {
+    is(xhr.response["foo"], "bar", "Should have gotten bar with BOM");
+
+    xhr.onload = function() {
+      is(xhr.response, null, "Should have gotten null response with UTF-16 JSON");
+
+      SimpleTest.finish();
+    };
+    xhr.open("GET", "file_bug707142_utf-16.json");
+    xhr.responseType = "json";
+    xhr.send();
+  };
+  xhr.open("GET", "file_bug707142_bom.json");
+  xhr.responseType = "json";
+  xhr.send();
+};
+xhr.open("GET", "file_bug707142_baseline.json");
+xhr.responseType = "json";
+xhr.send();
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/base/test/test_xhr_progressevents.html
+++ b/content/base/test/test_xhr_progressevents.html
@@ -110,17 +110,17 @@ function bufferToString(buffer) {
 function runTests() {
   var xhr = new XMLHttpRequest();
   xhr.onprogress = xhr.onload = xhr.onerror = xhr.onreadystatechange = xhr.onloadend = getEvent;
 
   var responseTypes = [{ type: "text", text: true },
                        { type: "arraybuffer", text: false, nodata: true },
                        { type: "blob", text: false, nodata: true },
                        { type: "document", text: true, nodata: true },
-                       { type: "moz-json", text: true, nodata: true },
+                       { type: "json", text: true, nodata: true },
                        { type: "", text: true },
                        { type: "moz-chunked-text", text: true, chunked: true },
                        { type: "moz-chunked-arraybuffer", text: false, chunked: true },
                       ];
   var responseType;
   var fileExpectedResult = "";
   for (var i = 0; i < 65536; i++) {
     fileExpectedResult += String.fromCharCode(i & 255);
new file mode 100644
--- /dev/null
+++ b/content/base/test/unit/test_xhr_standalone.js
@@ -0,0 +1,21 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// Test setting .responseType and .withCredentials is allowed
+// in non-window non-Worker context
+
+function run_test()
+{
+    var xhr = Components.classes['@mozilla.org/xmlextras/xmlhttprequest;1'].
+          createInstance(Components.interfaces.nsIXMLHttpRequest);
+    xhr.open('GET', 'data:,', false);
+    var exceptionThrown = false;
+    try {
+        xhr.responseType = '';
+        xhr.withCredentials = false;
+    } catch (e) {
+        exceptionThrown = true;
+    }
+    do_check_eq(false, exceptionThrown);
+}
--- a/content/base/test/unit/xpcshell.ini
+++ b/content/base/test/unit/xpcshell.ini
@@ -2,9 +2,10 @@
 head = head_utilities.js
 tail = 
 
 [test_bug553888.js]
 [test_bug558431.js]
 [test_csputils.js]
 [test_error_codes.js]
 [test_thirdpartyutil.js]
+[test_xhr_standalone.js]
 [test_xmlserializer.js]
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -2766,17 +2766,17 @@ struct NS_STACK_CLASS nsCanvasBidiProces
         }
 
         return NSToCoordRound(textRunMetrics.mAdvanceWidth);
     }
 
     virtual void DrawText(nscoord xOffset, nscoord width)
     {
         gfxPoint point = mPt;
-        point.x += xOffset * mAppUnitsPerDevPixel;
+        point.x += xOffset;
 
         // offset is given in terms of left side of string
         if (mTextRun->IsRightToLeft()) {
             // Bug 581092 - don't use rounded pixel width to advance to
             // right-hand end of run, because this will cause different
             // glyph positioning for LTR vs RTL drawing of the same
             // glyph string on OS X and DWrite where textrun widths may
             // involve fractional pixels.
--- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
@@ -2970,17 +2970,17 @@ struct NS_STACK_CLASS nsCanvasBidiProces
     }
 
     return NSToCoordRound(textRunMetrics.mAdvanceWidth);
   }
 
   virtual void DrawText(nscoord xOffset, nscoord width)
   {
     gfxPoint point = mPt;
-    point.x += xOffset * mAppUnitsPerDevPixel;
+    point.x += xOffset;
 
     // offset is given in terms of left side of string
     if (mTextRun->IsRightToLeft()) {
       // Bug 581092 - don't use rounded pixel width to advance to
       // right-hand end of run, because this will cause different
       // glyph positioning for LTR vs RTL drawing of the same
       // glyph string on OS X and DWrite where textrun widths may
       // involve fractional pixels.
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -130,16 +130,17 @@
 #include "nsIController.h"
 #include "nsICommandParams.h"
 #include "mozilla/Services.h"
 #include "mozAutoDocUpdate.h"
 #include "nsHTMLLabelElement.h"
 
 #include "mozilla/Preferences.h"
 #include "mozilla/LookAndFeel.h"
+#include "sampler.h"
 
 #ifdef XP_MACOSX
 #import <ApplicationServices/ApplicationServices.h>
 #endif
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
@@ -3803,16 +3804,17 @@ public:
   nsCOMPtr<nsIContent> mTarget;
 };
 
 nsIFrame*
 nsEventStateManager::DispatchMouseEvent(nsGUIEvent* aEvent, PRUint32 aMessage,
                                         nsIContent* aTargetContent,
                                         nsIContent* aRelatedContent)
 {
+  SAMPLE_LABEL("Input", "DispatchMouseEvent");
   nsEventStatus status = nsEventStatus_eIgnore;
   nsMouseEvent event(NS_IS_TRUSTED_EVENT(aEvent), aMessage, aEvent->widget,
                      nsMouseEvent::eReal);
   event.refPoint = aEvent->refPoint;
   event.isShift = ((nsMouseEvent*)aEvent)->isShift;
   event.isControl = ((nsMouseEvent*)aEvent)->isControl;
   event.isAlt = ((nsMouseEvent*)aEvent)->isAlt;
   event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
--- a/content/html/content/src/nsDOMStringMap.cpp
+++ b/content/html/content/src/nsDOMStringMap.cpp
@@ -45,19 +45,22 @@
 
 DOMCI_DATA(DOMStringMap, nsDOMStringMap)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMStringMap)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMStringMap)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mElement)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMStringMap)
-  // Call back to element to null out weak reference to this object.
-  tmp->mElement->ClearDataset();
-  tmp->mElement = nsnull;
+  // Check that mElement exists in case the unlink code is run more than once.
+  if (tmp->mElement) {
+    // Call back to element to null out weak reference to this object.
+    tmp->mElement->ClearDataset();
+    tmp->mElement = nsnull;
+  }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMStringMap)
   NS_INTERFACE_MAP_ENTRY(nsIDOMDOMStringMap)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DOMStringMap)
 NS_INTERFACE_MAP_END
 
--- a/content/media/webm/nsWebMReader.h
+++ b/content/media/webm/nsWebMReader.h
@@ -34,23 +34,28 @@
  * 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(nsWebMReader_h_)
 #define nsWebMReader_h_
 
+#include "mozilla/StdInt.h"
+
 #include "nsDeque.h"
 #include "nsBuiltinDecoderReader.h"
 #include "nsWebMBufferedParser.h"
 #include "nsAutoRef.h"
 #include "nestegg/nestegg.h"
+
+#define VPX_DONT_DEFINE_STDINT_TYPES
 #include "vpx/vpx_decoder.h"
 #include "vpx/vp8dx.h"
+
 #ifdef MOZ_TREMOR
 #include "tremor/ivorbiscodec.h"
 #else
 #include "vorbis/codec.h"
 #endif
 
 class nsMediaDecoder;
 
--- a/content/smil/nsSMILTimeValueSpec.cpp
+++ b/content/smil/nsSMILTimeValueSpec.cpp
@@ -317,32 +317,55 @@ nsSMILTimeValueSpec::GetTimedElement(Ele
 
   nsCOMPtr<nsISMILAnimationElement> animElement = do_QueryInterface(aElement);
   if (!animElement)
     return nsnull;
 
   return &animElement->TimedElement();
 }
 
+// Indicates whether we're allowed to register an event-listener
+// when scripting is disabled.
+bool
+nsSMILTimeValueSpec::IsWhitelistedEvent()
+{
+  // The category of (SMIL-specific) "repeat(n)" events are allowed.
+  if (mParams.mType == nsSMILTimeValueSpecParams::REPEAT) {
+    return true;
+  }
+
+  // A specific list of other SMIL-related events are allowed, too.
+  if (mParams.mType == nsSMILTimeValueSpecParams::EVENT &&
+      (mParams.mEventSymbol == nsGkAtoms::repeat ||
+       mParams.mEventSymbol == nsGkAtoms::repeatEvent ||
+       mParams.mEventSymbol == nsGkAtoms::beginEvent ||
+       mParams.mEventSymbol == nsGkAtoms::endEvent)) {
+    return true;
+  }
+
+  return false;
+}
+
 void
 nsSMILTimeValueSpec::RegisterEventListener(Element* aTarget)
 {
   NS_ABORT_IF_FALSE(IsEventBased(),
     "Attempting to register event-listener for unexpected nsSMILTimeValueSpec"
     " type");
   NS_ABORT_IF_FALSE(mParams.mEventSymbol,
     "Attempting to register event-listener but there is no event name");
 
   if (!aTarget)
     return;
 
-  // Don't listen for accessKey events if script is disabled. (see bug 704482)
-  if (mParams.mType == nsSMILTimeValueSpecParams::ACCESSKEY &&
-      !aTarget->GetOwnerDocument()->IsScriptEnabled())
+  // When script is disabled, only allow registration for whitelisted events.
+  if (!aTarget->GetOwnerDocument()->IsScriptEnabled() &&
+      !IsWhitelistedEvent()) {
     return;
+  }
 
   if (!mEventListener) {
     mEventListener = new EventListener(this);
   }
 
   nsEventListenerManager* elm = GetEventListenerManager(aTarget);
   if (!elm)
     return;
--- a/content/smil/nsSMILTimeValueSpec.h
+++ b/content/smil/nsSMILTimeValueSpec.h
@@ -88,16 +88,17 @@ public:
   // Cycle-collection support
   void Traverse(nsCycleCollectionTraversalCallback* aCallback);
   void Unlink();
 
 protected:
   void UpdateReferencedElement(Element* aFrom, Element* aTo);
   void UnregisterFromReferencedElement(Element* aElement);
   nsSMILTimedElement* GetTimedElement(Element* aElement);
+  bool IsWhitelistedEvent();
   void RegisterEventListener(Element* aElement);
   void UnregisterEventListener(Element* aElement);
   nsEventListenerManager* GetEventListenerManager(Element* aElement);
   void HandleEvent(nsIDOMEvent* aEvent);
   bool CheckEventDetail(nsIDOMEvent* aEvent);
   bool CheckRepeatEventDetail(nsIDOMEvent* aEvent);
   bool CheckAccessKeyEventDetail(nsIDOMEvent* aEvent);
   nsSMILTimeValue ConvertBetweenTimeContainers(const nsSMILTimeValue& aSrcTime,
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -78,16 +78,17 @@
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
 #endif
 
 #include "Layers.h"
 #include "nsIIOService.h"
 
 #include "mozilla/dom/Element.h"
+#include "sampler.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::layers;
 using namespace mozilla::widget;
 
 static bool IsUniversalXPConnectCapable()
 {
   bool hasCap = false;
@@ -724,16 +725,17 @@ nsDOMWindowUtils::Focus(nsIDOMElement* a
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GarbageCollect(nsICycleCollectorListener *aListener)
 {
+  SAMPLE_LABEL("GC", "GarbageCollect");
   // Always permit this in debug builds.
 #ifndef DEBUG
   if (!IsUniversalXPConnectCapable()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 #endif
 
   nsJSContext::GarbageCollectNow();
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -103,16 +103,18 @@
 #define FORCE_PR_LOG 1
 #endif
 #include "prlog.h"
 #include "prthread.h"
 
 #include "mozilla/FunctionTimer.h"
 #include "mozilla/Preferences.h"
 
+#include "sampler.h"
+
 using namespace mozilla;
 
 const size_t gStackSize = 8192;
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gJSDiagnostics;
 #endif
 
@@ -1180,16 +1182,17 @@ nsJSContext::EvaluateStringWithValue(con
                                      PRUint32 aLineNo,
                                      PRUint32 aVersion,
                                      JS::Value* aRetValue,
                                      bool* aIsUndefined)
 {
   NS_TIME_FUNCTION_MIN_FMT(1.0, "%s (line %d) (url: %s, line: %d)", MOZ_FUNCTION_NAME,
                            __LINE__, aURL, aLineNo);
 
+  SAMPLE_LABEL("JS", "EvaluateStringWithValue");
   NS_ABORT_IF_FALSE(aScopeObject,
     "Shouldn't call EvaluateStringWithValue with null scope object.");
 
   NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
 
   if (!mScriptsEnabled) {
     if (aIsUndefined) {
       *aIsUndefined = true;
@@ -1382,16 +1385,17 @@ nsJSContext::EvaluateString(const nsAStr
                             PRUint32 aLineNo,
                             PRUint32 aVersion,
                             nsAString *aRetValue,
                             bool* aIsUndefined)
 {
   NS_TIME_FUNCTION_MIN_FMT(1.0, "%s (line %d) (url: %s, line: %d)", MOZ_FUNCTION_NAME,
                            __LINE__, aURL, aLineNo);
 
+  SAMPLE_LABEL("JS", "EvaluateString");
   NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
 
   if (!mScriptsEnabled) {
     if (aIsUndefined) {
       *aIsUndefined = true;
     }
 
     if (aRetValue) {
@@ -1852,16 +1856,17 @@ nsJSContext::CallEventHandler(nsISupport
     if (js::IsFunctionProxy(obj))
       obj = js::UnwrapObject(obj);
     JSString *id = JS_GetFunctionId(static_cast<JSFunction *>(JS_GetPrivate(mContext, obj)));
     JSAutoByteString bytes;
     const char *name = !id ? "anonymous" : bytes.encode(mContext, id) ? bytes.ptr() : "<error>";
     NS_TIME_FUNCTION_FMT(1.0, "%s (line %d) (function: %s)", MOZ_FUNCTION_NAME, __LINE__, name);
   }
 #endif
+  SAMPLE_LABEL("JS", "CallEventHandler");
 
   JSAutoRequest ar(mContext);
   JSObject* target = nsnull;
   nsresult rv = JSObjectFromInterface(aTarget, aScope, &target);
   NS_ENSURE_SUCCESS(rv, rv);
 
   js::AutoObjectRooter targetVal(mContext, target);
   jsval rval = JSVAL_VOID;
@@ -3161,16 +3166,17 @@ nsJSContext::ScriptExecuted()
   return NS_OK;
 }
 
 //static
 void
 nsJSContext::GarbageCollectNow(bool shrinkingGC)
 {
   NS_TIME_FUNCTION_MIN(1.0);
+  SAMPLE_LABEL("GC", "GarbageCollectNow");
 
   KillGCTimer();
 
   // Reset sPendingLoadCount in case the timer that fired was a
   // timer we scheduled due to a normal GC timer firing while
   // documents were loading. If this happens we're waiting for a
   // document that is taking a long time to load, and we effectively
   // ignore the fact that the currently loading documents are still
@@ -3186,16 +3192,17 @@ nsJSContext::GarbageCollectNow(bool shri
 //Static
 void
 nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener)
 {
   if (!NS_IsMainThread()) {
     return;
   }
 
+  SAMPLE_LABEL("GC", "CycleCollectNow");
   NS_TIME_FUNCTION_MIN(1.0);
 
   KillCCTimer();
 
   PRTime start = PR_Now();
 
   PRUint32 suspected = nsCycleCollector_suspectedCount();
   PRUint32 collected = nsCycleCollector_collect(aListener);
--- a/dom/locales/en-US/chrome/dom/dom.properties
+++ b/dom/locales/en-US/chrome/dom/dom.properties
@@ -125,8 +125,11 @@ FullScreenDeniedMovedDocument=Request fo
 FullScreenDeniedLostWindow=Request for full-screen was denied because we no longer have a window.
 FullScreenDeniedSubDocFullScreen=Request for full-screen was denied because a subdocument of the document requesting full-screen is already full-screen.
 FullScreenDeniedNotDescendant=Request for full-screen was denied because requesting element is not a descendant of the current full-screen element.
 RemovedFullScreenElement=Exited full-screen because full-screen element was removed from document.
 AddedWindowedPluginWhileFullScreen=Exited full-screen because windowed plugin was added to document.
 HTMLMultipartXHRWarning=HTML parsing in XMLHttpRequest is not supported for multipart responses.
 HTMLSyncXHRWarning=HTML parsing in XMLHttpRequest is not supported in the synchronous mode.
 InvalidRedirectChannelWarning=Unable to redirect to %S because the channel doesn't implement nsIWritablePropertyBag2.
+ResponseTypeSyncXHRWarning=Use of XMLHttpRequest's responseType attribute is no longer supported in the synchronous mode in window context.
+WithCredentialsSyncXHRWarning=Use of XMLHttpRequest's withCredentials attribute is no longer supported in the synchronous mode in window context.
+JSONCharsetWarning=An attempt was made to declare a non-UTF-8 encoding for JSON retrieved using XMLHttpRequest. Only UTF-8 is supported for decoding JSON.
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -228,17 +228,19 @@ PRLogModuleInfo* nsPluginLogging::gNPPLo
 PRLogModuleInfo* nsPluginLogging::gPluginLog = nsnull;
 #endif
 
 #define BRAND_PROPERTIES_URL "chrome://branding/locale/brand.properties"
 #define PLUGIN_PROPERTIES_URL "chrome://global/locale/downloadProgress.properties"
 
 // #defines for plugin cache and prefs
 #define NS_PREF_MAX_NUM_CACHED_INSTANCES "browser.plugins.max_num_cached_plugins"
-#define DEFAULT_NUMBER_OF_STOPPED_INSTANCES 10
+// Raise this from '10' to '50' to work around a bug in Apple's current Java
+// plugins on OS X Lion and SnowLeopard.  See bug 705931.
+#define DEFAULT_NUMBER_OF_STOPPED_INSTANCES 50
 
 #ifdef CALL_SAFETY_ON
 // By default we run OOPP, so we don't want to cover up crashes.
 bool gSkipPluginSafeCalls = true;
 #endif
 
 nsIFile *nsPluginHost::sPluginTempDir;
 nsPluginHost *nsPluginHost::sInst;
--- a/gfx/2d/Types.h
+++ b/gfx/2d/Types.h
@@ -33,32 +33,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 ***** */
 
 #ifndef MOZILLA_GFX_TYPES_H_
 #define MOZILLA_GFX_TYPES_H_
 
-#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || defined (_sgi) || defined (__sun) || defined (sun) || defined (__digital__)
-#  include <inttypes.h>
-#elif defined (_MSC_VER)
-typedef unsigned __int8 uint8_t;
-typedef __int16 int16_t;
-typedef unsigned __int16 uint16_t;
-typedef __int32 int32_t;
-typedef unsigned __int32 uint32_t;
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-
-#elif defined (_AIX)
-#  include <sys/inttypes.h>
-#else
-#  include <stdint.h>
-#endif
+#include "mozilla/StdInt.h"
 
 #include <stddef.h>
 
 namespace mozilla {
 namespace gfx {
 
 typedef float Float;
 
--- a/gfx/cairo/libpixman/src/Makefile.in
+++ b/gfx/cairo/libpixman/src/Makefile.in
@@ -180,18 +180,21 @@ CFLAGS += -DPACKAGE="mozpixman" -D_USE_M
 
 # Disable spammy "missing initializer" GCC warning
 ifdef GNU_CC
 CFLAGS += -Wno-missing-field-initializers
 endif # GNU_CC
 
 # special rule for pixman-mmx to get the right cflags
 pixman-mmx.$(OBJ_SUFFIX): pixman-mmx.c $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
 	$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(MMX_CFLAGS) $(_VPATH_SRCS)
 
 pixman-sse2.$(OBJ_SUFFIX): pixman-sse2.c $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
 	$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(SSE2_CFLAGS) $(_VPATH_SRCS)
 
 pixman-arm-neon.$(OBJ_SUFFIX): pixman-arm-neon.c $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
 	$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(ARM_NEON_CFLAGS) $(_VPATH_SRCS)
--- a/gfx/layers/basic/BasicLayers.cpp
+++ b/gfx/layers/basic/BasicLayers.cpp
@@ -60,16 +60,18 @@
 #include "ThebesLayerBuffer.h"
 #include "nsIWidget.h"
 #include "ReadbackProcessor.h"
 #ifdef MOZ_X11
 #include "gfxXlibSurface.h"
 #endif
 
 #include "GLContext.h"
+
+#define PIXMAN_DONT_DEFINE_STDINT
 #include "pixman.h"
 
 namespace mozilla {
 namespace layers {
 
 class BasicContainerLayer;
 class ShadowableLayer;
 
--- a/gfx/qcms/Makefile.in
+++ b/gfx/qcms/Makefile.in
@@ -98,14 +98,16 @@ CFLAGS          += -DMOZ_QCMS
 
 # Disable spammy "missing initializer" GCC warning
 ifdef GNU_CC
 CFLAGS += -Wno-missing-field-initializers
 endif # GNU_CC
 
 # special rules for transform-sse*.c to get the right cflags. (taken from pixman/src/Makefile.in)
 transform-sse1.$(OBJ_SUFFIX): transform-sse1.c $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
 	$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(SSE1_FLAGS) $(_VPATH_SRCS)
 
 transform-sse2.$(OBJ_SUFFIX): transform-sse2.c $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
 	$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(SSE2_FLAGS) $(_VPATH_SRCS)
--- a/gfx/thebes/woff.h
+++ b/gfx/thebes/woff.h
@@ -35,28 +35,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef WOFF_H_
 #define WOFF_H_
 
 /* API for the WOFF encoder and decoder */
 
-#ifdef _MSC_VER /* MS VC lacks inttypes.h
-                   but we can make do with a few definitons here */
-typedef signed char    int8_t;
-typedef short          int16_t;
-typedef int            int32_t;
-typedef unsigned char  uint8_t;
-typedef unsigned short uint16_t;
-typedef unsigned int   uint32_t;
-typedef unsigned __int64  uint64_t;
-#else
-#include <inttypes.h>
-#endif
+#include "mozilla/StdInt.h"
 
 #include <stdio.h> /* only for FILE, needed for woffPrintStatus */
 
 /* error codes returned in the status parameter of WOFF functions */
 enum {
   /* Success */
   eWOFF_ok = 0,
 
--- a/image/test/mochitest/animationPolling.js
+++ b/image/test/mochitest/animationPolling.js
@@ -1,12 +1,14 @@
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 var currentTest;
 var gIsRefImageLoaded = false;
+const gShouldOutputDebugInfo = false;
 
-function pollForSuccess ()
+function pollForSuccess()
 {
   if (!currentTest.isTestFinished) {
     if (!currentTest.reusingReferenceImage || (currentTest.reusingReferenceImage
         && gRefImageLoaded)) {
       currentTest.checkImage();
     }
 
     setTimeout(pollForSuccess, currentTest.pollFreq);
@@ -18,19 +20,18 @@ function referencePoller()
   currentTest.takeReferenceSnapshot();
 }
 
 function reuseImageCallback()
 {
   gIsRefImageLoaded = true;
 }
 
-function failTest ()
-{    imageLoadCallback();
-
+function failTest()
+{
   if (currentTest.isTestFinished || currentTest.closeFunc) {
     return;
   }
 
   ok(false, "timing out after " + currentTest.timeout + "ms.  "
      + "Animated image still doesn't look correct, after poll #"
      + currentTest.pollCounter);
   currentTest.wereFailures = true;
@@ -115,16 +116,19 @@ AnimationTest.prototype.preloadImage = f
     this.myImage.src = this.srcAttr;
   } else {
     this.continueTest();
   }
 };
 
 AnimationTest.prototype.outputDebugInfo = function(message, id, dataUri)
 {
+  if (!gShouldOutputDebugInfo) {
+    return;
+  }
   var debugElement = document.getElementById(this.debugElementId);
   var newDataUriElement = document.createElement("a");
   newDataUriElement.setAttribute("id", id);
   newDataUriElement.setAttribute("href", dataUri);
   newDataUriElement.appendChild(document.createTextNode(message));
   debugElement.appendChild(newDataUriElement);
   var brElement = document.createElement("br");
   debugElement.appendChild(brElement);
@@ -198,26 +202,27 @@ AnimationTest.prototype.continueTest = f
   setTimeout(failTest, this.timeout);
 
   if (!this.reusingImageAsReference) {
     this.disableDisplay(document.getElementById(this.imageElementId));
   }
 
   this.takeReferenceSnapshot();
   this.setupPolledImage();
-  setTimeout(pollForSuccess, 10);
+  SimpleTest.executeSoon(pollForSuccess);
 };
 
 AnimationTest.prototype.setupPolledImage = function ()
 {
   // Make sure the image is visible
   if (!this.reusingImageAsReference) {
     this.enableDisplay(document.getElementById(this.imageElementId));
     var currentSnapshot = snapshotWindow(window, false);
-    var result = compareSnapshots(currentSnapshot, this.referenceSnapshot, true);
+    var result = compareSnapshots(currentSnapshot,
+                                  this.referenceSnapshot, true);
 
     this.currentSnapshotDataURI = currentSnapshot.toDataURL();
 
     if (result[0]) {
       // SUCCESS!
       ok(true, "Animated image looks correct, at poll #"
          + this.pollCounter);
 
@@ -271,35 +276,35 @@ AnimationTest.prototype.takeReferenceSna
   }
 
   // Used later to verify that the reference div disappeared
   if (!this.blankSnapshot) {
     this.takeBlankSnapshot();
   }
 
   if (this.reusingImageAsReference) {
-    // Show reference div, & take a snapshot
-    var referenceDiv = document.getElementById(this.imageElementId);
-    this.enableDisplay(referenceDiv);
+    // Show reference elem (which is actually our image), & take a snapshot
+    var referenceElem = document.getElementById(this.imageElementId);
+    this.enableDisplay(referenceElem);
 
     this.referenceSnapshot = snapshotWindow(window, false);
 
-    var snapResult = compareSnapshots(this.cleanSnapshot, this.referenceSnapshot,
-                                      false);
+    var snapResult = compareSnapshots(this.cleanSnapshot,
+                                      this.referenceSnapshot, false);
     if (!snapResult[0]) {
       if (this.blankWaitTime > 2000) {
         // if it took longer than two seconds to load the image, we probably
         // have a problem.
         this.wereFailures = true;
         ok(snapResult[0],
            "Reference snapshot shouldn't match clean (non-image) snapshot");
       } else {
-        this.blankWaitTime += 20;
+        this.blankWaitTime += currentTest.pollFreq;
         // let's wait a bit and see if it clears up
-        setTimeout(referencePoller, 20);
+        setTimeout(referencePoller, currentTest.pollFreq);
         return;
       }
     }
 
     ok(snapResult[0],
        "Reference snapshot shouldn't match clean (non-image) snapshot");
 
     var dataString = "Reference Snapshot #" + this.numRefsTaken;
@@ -309,17 +314,18 @@ AnimationTest.prototype.takeReferenceSna
     // Make sure the animation section is hidden
     this.disableDisplay(document.getElementById(this.imageElementId));
 
     // Show reference div, & take a snapshot
     var referenceDiv = document.getElementById(this.referenceElementId);
     this.enableDisplay(referenceDiv);
 
     this.referenceSnapshot = snapshotWindow(window, false);
-    var snapResult = compareSnapshots(this.cleanSnapshot, this.referenceSnapshot, false);
+    var snapResult = compareSnapshots(this.cleanSnapshot,
+                                      this.referenceSnapshot, false);
     if (!snapResult[0]) {
       if (this.blankWaitTime > 2000) {
         // if it took longer than two seconds to load the image, we probably
         // have a problem.
         this.wereFailures = true;
         ok(snapResult[0],
            "Reference snapshot shouldn't match clean (non-image) snapshot");
       } else {
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -279,18 +279,20 @@ VPATH		+= \
 		$(srcdir)/../../mfbt \
 		$(NULL)
 
 EXPORTS_NAMESPACES += mozilla
 
 EXPORTS_mozilla = \
 		Attributes.h	\
 		GuardObjects.h \
+		MSStdInt.h \
 		RangedPtr.h \
 		RefPtr.h \
+		StdInt.h \
 		Types.h	\
 		Util.h \
 		$(NULL)
 
 ifdef ENABLE_METHODJIT
 
 ###############################################
 # BEGIN include sources for the method JIT
@@ -863,32 +865,35 @@ else
 EXTRA_LIBS	+= -lposix4 -ldl -lnsl -lsocket
 endif
 endif
 
 ifdef SOLARIS_SUNPRO_CXX
 ifeq ($(TARGET_CPU),sparc)
 # Sun Studio SPARC doesn't work well with gcc inline asm, use lock_SunOS_sparc*.il
 jslock.o: jslock.cpp Makefile.in lock_sparcv8plus.il lock_sparcv9.il
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CXX)
 ifeq (sparcv9,$(findstring sparcv9,$(OS_TEST)))
 	$(CXX) -o $@ -c $(COMPILE_CFLAGS) $(srcdir)/lock_sparcv9.il $<
 else
 	$(CXX) -o $@ -c $(COMPILE_CFLAGS) $(srcdir)/lock_sparcv8plus.il $<
 endif # sparcv9
 endif # sparc
 endif # SOLARIS_SUNPRO_CXX
 
 # An AIX Optimization bug causes PR_dtoa() & JS_dtoa to produce wrong result.
 # This suppresses optimization for this single compilation unit.
 ifeq ($(OS_ARCH),AIX)
 jsatom.o: jsatom.cpp Makefile.in
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CXX)
 	$(CXX) -o $@ -c $(filter-out $(MOZ_OPTIMIZE_FLAGS), $(COMPILE_CFLAGS)) $<
 jsdtoa.o: jsdtoa.cpp Makefile.in
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CXX)
 	$(CXX) -o $@ -c $(filter-out $(MOZ_OPTIMIZE_FLAGS), $(COMPILE_CFLAGS)) $<
 endif
 
 # Compute the linker flags that programs linking against SpiderMonkey should
 # pass to get SpiderMonkey and its dependencies, beyond just the -L and -l
 # for the SpiderMonkey library itself.
 # - EXTRA_DSO_LDOPTS includes the NSPR -L and -l flags.
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -59,16 +59,18 @@ endif
 
 ifdef SDK_XPIDLSRCS
 XPIDLSRCS += $(SDK_XPIDLSRCS)
 endif
 ifdef SDK_HEADERS
 EXPORTS += $(SDK_HEADERS)
 endif
 
+REPORT_BUILD = @echo $(notdir $<)
+
 ifeq ($(OS_ARCH),OS2)
 EXEC			=
 else
 EXEC			= exec
 endif
 
 # Don't copy xulrunner files at install time, when using system xulrunner
 ifdef SYSTEM_LIBXUL
@@ -1143,45 +1145,53 @@ MAKE_DEPS_AUTO_CC = $(MAKE_DEPS_AUTO)
 MAKE_DEPS_AUTO_CXX = $(MAKE_DEPS_AUTO)
 
 endif # COMPILER_DEPEND
 
 endif # MOZ_AUTO_DEPS
 
 # Rules for building native targets must come first because of the host_ prefix
 host_%.$(OBJ_SUFFIX): %.c $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
 host_%.$(OBJ_SUFFIX): %.cpp $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
 host_%.$(OBJ_SUFFIX): %.cc $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
 host_%.$(OBJ_SUFFIX): %.m $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(HOST_CMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
 host_%.$(OBJ_SUFFIX): %.mm $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(HOST_CMMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
 %:: %.c $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
 	$(ELOG) $(CC) $(CFLAGS) $(LDFLAGS) $(OUTOPTION)$@ $(_VPATH_SRCS)
 
 %.$(OBJ_SUFFIX): %.c $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
 	$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(_VPATH_SRCS)
 
 # DEFINES and ACDEFINES are needed here to enable conditional compilation of Q_OBJECTs:
 # 'moc' only knows about #defines it gets on the command line (-D...), not in
 # included headers like mozilla-config.h
 moc_%.cpp: %.h $(GLOBAL_DEPS)
 	$(MOC) $(DEFINES) $(ACDEFINES) $< $(OUTOPTION)$@
 
 moc_%.cc: %.cc $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	$(ELOG) $(MOC) $(DEFINES) $(ACDEFINES) $(_VPATH_SRCS:.cc=.h) $(OUTOPTION)$@
 
 ifdef ASFILES
 # The AS_DASH_C_FLAG is needed cause not all assemblers (Solaris) accept
 # a '-c' flag.
 %.$(OBJ_SUFFIX): %.$(ASM_SUFFIX) $(GLOBAL_DEPS)
 	$(AS) $(ASOUTOPTION)$@ $(ASFLAGS) $(AS_DASH_C_FLAG) $(_VPATH_SRCS)
 endif
@@ -1192,34 +1202,38 @@ endif
 %:: %.cpp $(GLOBAL_DEPS)
 	@$(MAKE_DEPS_AUTO_CXX)
 	$(CCC) $(OUTOPTION)$@ $(CXXFLAGS) $(_VPATH_SRCS) $(LDFLAGS)
 
 #
 # Please keep the next two rules in sync.
 #
 %.$(OBJ_SUFFIX): %.cc $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CXX)
 	$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
 
 %.$(OBJ_SUFFIX): %.cpp $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CXX)
 ifdef STRICT_CPLUSPLUS_SUFFIX
 	echo "#line 1 \"$*.cpp\"" | cat - $*.cpp > t_$*.cc
 	$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) t_$*.cc
 	$(RM) t_$*.cc
 else
 	$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
 endif #STRICT_CPLUSPLUS_SUFFIX
 
 $(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.mm $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CXX)
 	$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(_VPATH_SRCS)
 
 $(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.m $(GLOBAL_DEPS)
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
 	$(ELOG) $(CC) -o $@ -c $(COMPILE_CFLAGS) $(COMPILE_CMFLAGS) $(_VPATH_SRCS)
 
 %.s: %.cpp
 	$(CCC) -S $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
 
 %.s: %.cc
 	$(CCC) -S $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
@@ -1459,27 +1473,29 @@ endif
 
 XPIDL_DEPS = \
   $(topsrcdir)/xpcom/idl-parser/header.py \
   $(topsrcdir)/xpcom/idl-parser/typelib.py \
   $(topsrcdir)/xpcom/idl-parser/xpidl.py \
   $(NULL)
 
 $(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_DEPS) $(XPIDL_GEN_DIR)/.done
+	$(REPORT_BUILD)
 	$(PYTHON_PATH) \
 	  -I$(topsrcdir)/other-licenses/ply \
 	  -I$(topsrcdir)/xpcom/idl-parser \
 	  $(topsrcdir)/xpcom/idl-parser/header.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
 	@if test -n "$(findstring $*.h, $(EXPORTS))"; \
 	  then echo "*** WARNING: file $*.h generated from $*.idl overrides $(srcdir)/$*.h"; else true; fi
 
 ifndef NO_GEN_XPT
 # generate intermediate .xpt files into $(XPIDL_GEN_DIR), then link
 # into $(XPIDL_MODULE).xpt and export it to $(FINAL_TARGET)/components.
 $(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_DEPS) $(XPIDL_GEN_DIR)/.done
+	$(REPORT_BUILD)
 	$(PYTHON_PATH) \
 	  -I$(topsrcdir)/other-licenses/ply \
 	  -I$(topsrcdir)/xpcom/idl-parser \
 	  -I$(topsrcdir)/xpcom/typelib/xpt/tools \
 	  $(topsrcdir)/xpcom/idl-parser/typelib.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
 
 # no need to link together if XPIDLSRCS contains only XPIDL_MODULE
 ifneq ($(XPIDL_MODULE).idl,$(strip $(XPIDLSRCS)))
@@ -1758,22 +1774,25 @@ else # ! COMPILER_DEPEND
 
 ifndef MOZ_AUTO_DEPS
 
 define MAKE_DEPS_NOAUTO
 	$(MKDEPEND) -w1024 -o'.$(OBJ_SUFFIX)' -f- $(DEFINES) $(ACDEFINES) $(INCLUDES) $< 2>/dev/null | sed -e "s|^[^ ]*/||" > $@
 endef
 
 $(MDDEPDIR)/%.pp: %.c
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_NOAUTO)
 
 $(MDDEPDIR)/%.pp: %.cpp
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_NOAUTO)
 
 $(MDDEPDIR)/%.pp: %.s
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_NOAUTO)
 
 ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS))
 depend:: $(SUBMAKEFILES) $(MAKE_DIRS) $(MDDEPFILES)
 else
 depend:: $(SUBMAKEFILES)
 endif
 	$(LOOP_OVER_PARALLEL_DIRS)
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -1235,16 +1235,21 @@ mingw*)
     MOZ_PATH_PROGS(GMAKE, $GMAKE $NOT_PYMAKE gmake make, :)
     ;;
 esac
 if test "$GMAKE" = ":"; then
    AC_MSG_ERROR([GNU make not found])
 fi
 AC_SUBST(GMAKE)
 
+# MAKE will be set by client.mk, but still need this for standalone js builds
+if test -z "$MAKE"; then
+  MAKE=$GMAKE
+fi
+
 if test "$COMPILE_ENVIRONMENT"; then
 
 AC_PATH_XTRA
 
 XCFLAGS="$X_CFLAGS"
 
 fi # COMPILE_ENVIRONMENT
 
@@ -2102,16 +2107,27 @@ changequote(,)
 $PYTHON -c "import sys; sys.exit(sys.version[:3] < sys.argv[1] or sys.version[:2] != '2.')" $PYTHON_VERSION
 _python_res=$?
 changequote([,])
 if test "$_python_res" != 0; then
     AC_MSG_ERROR([Python $PYTHON_VERSION or higher (but not Python 3.x) is required.])
 fi
 AC_MSG_RESULT([yes])
 
+dnl Check for using a custom <stdint.h> implementation
+dnl ========================================================
+AC_MSG_CHECKING(for custom <stdint.h> implementation)
+if test "$MOZ_CUSTOM_STDINT_H"; then
+  AC_DEFINE_UNQUOTED(MOZ_CUSTOM_STDINT_H, "$MOZ_CUSTOM_STDINT_H")
+  AC_SUBST(MOZ_CUSTOM_STDINT_H)
+  AC_MSG_RESULT(using $MOZ_CUSTOM_STDINT_H)
+else
+  AC_MSG_RESULT(none specified)
+fi
+
 MOZ_DOING_LTO(lto_is_enabled)
 
 dnl ========================================================
 dnl System overrides of the defaults for target
 dnl ========================================================
 
 case "$target" in
 *-aix*)
@@ -2937,38 +2953,16 @@ AC_CACHE_VAL(ac_cv_siginfo_t,
                  [ac_cv_siginfo_t=false])])
 if test "$ac_cv_siginfo_t" = true ; then
   AC_DEFINE(HAVE_SIGINFO_T)
   AC_MSG_RESULT(yes)
 else
   AC_MSG_RESULT(no)
 fi
 
-dnl Find exact-width integer types, or figure them out
-dnl ourselves.
-dnl ========================================================
-dnl Once this is working, we can delete the code for int16_t,
-dnl etc. below.
-
-MOZ_CHECK_HEADER(stdint.h)
-if test "$ac_cv_header_stdint_h" = yes; then
-    AC_DEFINE(JS_HAVE_STDINT_H)
-else
-    dnl We'll figure them out for ourselves.  List more likely types
-    dnl earlier.  If we ever really encounter a size for which none of
-    dnl the listed types are appropriate, we'll get a configure-time
-    dnl error; just add the right answer.
-    MOZ_N_BYTE_TYPE(JS_INT8_TYPE,  1, [char])
-    MOZ_N_BYTE_TYPE(JS_INT16_TYPE, 2, [short int long])
-    MOZ_N_BYTE_TYPE(JS_INT32_TYPE, 4, [int long 'long long' short])
-    MOZ_N_BYTE_TYPE(JS_INT64_TYPE, 8, [int long 'long long'])
-    MOZ_N_BYTE_TYPE(JS_INTPTR_TYPE, sizeof (void *),
-                                      [int long 'long long' short])
-fi
-
 MOZ_SIZE_OF_TYPE(JS_BYTES_PER_WORD, void*, 4 8)
 if test "$moz_cv_size_of_JS_BYTES_PER_WORD" -eq "4"; then
   AC_DEFINE(JS_BITS_PER_WORD_LOG2, 5)
 elif test "$moz_cv_size_of_JS_BYTES_PER_WORD" -eq "8"; then
   AC_DEFINE(JS_BITS_PER_WORD_LOG2, 6)
 else
   AC_MSG_ERROR([Unexpected JS_BYTES_PER_WORD])
 fi
@@ -2981,70 +2975,18 @@ if test "$ac_cv_header_endian_h" = yes; 
     AC_DEFINE(JS_HAVE_ENDIAN_H)
 fi
 
 MOZ_CHECK_HEADERS(sys/isa_defs.h)
 if test "$ac_cv_header_sys_isa_defs_h" = yes; then
     AC_DEFINE(JS_HAVE_SYS_ISA_DEFS_H)
 fi
 
-dnl Check for int16_t, int32_t, int64_t, int64, uint, uint_t, and uint16_t.
+dnl Check for uint and uint_t.
 dnl ========================================================
-AC_MSG_CHECKING(for int16_t)
-AC_CACHE_VAL(ac_cv_int16_t,
- [AC_TRY_COMPILE([#include <stdio.h>
-                  #include <sys/types.h>],
-                 [int16_t foo = 0;],
-                 [ac_cv_int16_t=true],
-                 [ac_cv_int16_t=false])])
-if test "$ac_cv_int16_t" = true ; then
-  AC_DEFINE(HAVE_INT16_T)
-  AC_MSG_RESULT(yes)
-else
-  AC_MSG_RESULT(no)
-fi
-AC_MSG_CHECKING(for int32_t)
-AC_CACHE_VAL(ac_cv_int32_t,
- [AC_TRY_COMPILE([#include <stdio.h>
-                  #include <sys/types.h>],
-                 [int32_t foo = 0;],
-                 [ac_cv_int32_t=true],
-                 [ac_cv_int32_t=false])])
-if test "$ac_cv_int32_t" = true ; then
-  AC_DEFINE(HAVE_INT32_T)
-  AC_MSG_RESULT(yes)
-else
-  AC_MSG_RESULT(no)
-fi
-AC_MSG_CHECKING(for int64_t)
-AC_CACHE_VAL(ac_cv_int64_t,
- [AC_TRY_COMPILE([#include <stdio.h>
-                  #include <sys/types.h>],
-                 [int64_t foo = 0;],
-                 [ac_cv_int64_t=true],
-                 [ac_cv_int64_t=false])])
-if test "$ac_cv_int64_t" = true ; then
-  AC_DEFINE(HAVE_INT64_T)
-  AC_MSG_RESULT(yes)
-else
-  AC_MSG_RESULT(no)
-fi
-AC_MSG_CHECKING(for int64)
-AC_CACHE_VAL(ac_cv_int64,
- [AC_TRY_COMPILE([#include <stdio.h>
-                  #include <sys/types.h>],
-                 [int64 foo = 0;],
-                 [ac_cv_int64=true],
-                 [ac_cv_int64=false])])
-if test "$ac_cv_int64" = true ; then
-  AC_DEFINE(HAVE_INT64)
-  AC_MSG_RESULT(yes)
-else
-  AC_MSG_RESULT(no)
-fi
 AC_MSG_CHECKING(for uint)
 AC_CACHE_VAL(ac_cv_uint,
  [AC_TRY_COMPILE([#include <stdio.h>
                   #include <sys/types.h>],
                  [uint foo = 0;],
                  [ac_cv_uint=true],
                  [ac_cv_uint=false])])
 if test "$ac_cv_uint" = true ; then
@@ -3061,29 +3003,16 @@ AC_CACHE_VAL(ac_cv_uint_t,
                  [ac_cv_uint_t=true],
                  [ac_cv_uint_t=false])])
 if test "$ac_cv_uint_t" = true ; then
   AC_DEFINE(HAVE_UINT_T)
   AC_MSG_RESULT(yes)
 else
   AC_MSG_RESULT(no)
 fi
-AC_MSG_CHECKING(for uint16_t)
-AC_CACHE_VAL(ac_cv_uint16_t,
- [AC_TRY_COMPILE([#include <stdio.h>
-                  #include <sys/types.h>],
-                 [uint16_t foo = 0;],
-                 [ac_cv_uint16_t=true],
-                 [ac_cv_uint16_t=false])])
-if test "$ac_cv_uint16_t" = true ; then
-  AC_DEFINE(HAVE_UINT16_T)
-  AC_MSG_RESULT(yes)
-else
-  AC_MSG_RESULT(no)
-fi
 
 dnl On the gcc trunk (as of 2001-02-09) _GNU_SOURCE, and thus __USE_GNU,
 dnl are defined when compiling C++ but not C.  Since the result of this
 dnl test is used only in C++, do it in C++.
 AC_LANG_CPLUSPLUS
 
 AC_MSG_CHECKING(for uname.domainname)
 AC_CACHE_VAL(ac_cv_have_uname_domainname_field,
@@ -4740,17 +4669,17 @@ dnl ====================================
 MOZ_ARG_HEADER(Compiler Options)
 
 dnl ========================================================
 dnl Check for gcc -pipe support
 dnl ========================================================
 AC_MSG_CHECKING([for gcc -pipe support])
 if test -n "$GNU_CC" -a -n "$GNU_CXX" -a -n "$GNU_AS"; then
     echo '#include <stdio.h>' > dummy-hello.c
-    echo 'int main() { printf("Hello World\n"); exit(0); }' >> dummy-hello.c
+    echo 'int main() { printf("Hello World"); exit(0); }' >> dummy-hello.c
     ${CC} -S dummy-hello.c -o dummy-hello.s 2>&5
     cat dummy-hello.s 2> /dev/null | ${AS_BIN} -o dummy-hello.S - 2>&5
     if test $? = 0; then
         _res_as_stdin="yes"
     else
         _res_as_stdin="no"
     fi
     if test "$_res_as_stdin" = "yes"; then
@@ -5422,28 +5351,44 @@ AC_OUTPUT_MAKE_DEFS()
 MOZ_DEFINES=$DEFS
 AC_SUBST(MOZ_DEFINES)
 rm -f confdefs.h
 mv confdefs.h.save confdefs.h
 
 MAKEFILES="
   Makefile
   shell/Makefile
-  jsapi-tests/Makefile
-  tests/Makefile
   config/Makefile
   config/autoconf.mk
   config/expandlibs_config.py
-  config/mkdepend/Makefile
 "
 
-if test -n "$JS_NATIVE_EDITLINE"; then
-   MAKEFILES="$MAKEFILES
-editline/Makefile
-"
+if test "$JS_NATIVE_EDITLINE"; then
+  MAKEFILES="$MAKEFILES
+    editline/Makefile
+  "
+fi
+
+if test ! "$COMPILER_DEPEND" -a ! "$MOZ_NATIVE_MAKEDEPEND"; then
+  MAKEFILES="$MAKEFILES
+    config/mkdepend/Makefile
+  "
+fi
+
+if test "$ENABLE_TESTS"; then
+  MAKEFILES="$MAKEFILES
+    jsapi-tests/Makefile
+    tests/Makefile
+  "
+fi
+
+if test "$DEHYDRA_PATH"; then
+  MAKEFILES="$MAKEFILES
+    analysis-tests/Makefile
+  "
 fi
 
 dnl
 dnl Run a perl script to quickly create the makefiles.
 dnl If it succeeds, it outputs a shell command to set CONFIG_FILES
 dnl   for the files it cannot handle correctly. This way, config.status
 dnl   will handle these files.
 dnl If it fails, nothing is set and config.status will run as usual.
@@ -5465,18 +5410,18 @@ if cmp -s config/autoconf.mk config/auto
   echo "config/autoconf.mk is unchanged"
   mv -f config/autoconf.mk.orig config/autoconf.mk 2> /dev/null
 else
   rm -f config/autoconf.mk.orig 2> /dev/null
 fi
 
 # Produce the js-config script at configure time; see the comments for
 # 'js-config' in Makefile.in.
-AC_MSG_RESULT(invoking make to create js-config script)
-$GMAKE js-config
+AC_MSG_RESULT(invoking $MAKE to create js-config script)
+$MAKE js-config
 
 # Build jsctypes if it's enabled.
 if test "$JS_HAS_CTYPES" -a -z "$MOZ_NATIVE_FFI"; then
   # Run the libffi 'configure' script.
   ac_configure_args="--disable-shared --enable-static --disable-raw-api"
   if test "$MOZ_DEBUG"; then
     ac_configure_args="$ac_configure_args --enable-debug"
   fi
--- a/js/src/jit-test/tests/basic/bug674776.js
+++ b/js/src/jit-test/tests/basic/bug674776.js
@@ -1,9 +1,9 @@
-// |jit-test| debug
+// |jit-test| slow; debug
 
 /* Make a lot of functions of the form:
 function x1(){x1();}
 function x2(){x2();}
 function x3(){x3();}
 ...
 */
 
--- a/js/src/jit-test/tests/basic/testCompileScript.js
+++ b/js/src/jit-test/tests/basic/testCompileScript.js
@@ -1,9 +1,9 @@
-// |jit-test| mjitalways
+// |jit-test| slow; mjitalways
 
 var nlocals = 50;
 var localstr = "";
 for (var i = 0; i < nlocals; ++i)
     localstr += "var x" + i + "; ";
 
 /*
  * Attempt to test, in a stack-parameter-independent manner, ComileFunction
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-01.js
@@ -0,0 +1,23 @@
+// A live Environment can observe the new variables introduced by ES5 non-strict direct eval.
+
+var g = newGlobal('new-compartment');
+g.eval("var x = 'global'; function f(s) { h(); eval(s); h(); }");
+g.eval("function h() { debugger; }");
+var dbg = Debugger(g);
+var env = undefined;
+var hits = 0;
+dbg.onDebuggerStatement = function (hframe) {
+    if (env === undefined) {
+        // First debugger statement.
+        env = hframe.older.environment;
+        assertEq(env.find("x") !== env, true);
+        assertEq(env.names().indexOf("x"), -1);
+    } else {
+        // Second debugger statement, post-eval.
+        assertEq(env.find("x"), env);
+        assertEq(env.names().indexOf("x") >= 0, true);
+    }
+    hits++;
+};
+g.f("var x = 'local';");
+assertEq(hits, 2);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-02.js
@@ -0,0 +1,20 @@
+// The last Environment on the environment chain always has .type == "object" and .object === the global object.
+
+var g = newGlobal('new-compartment');
+var dbg = new Debugger;
+var gw = dbg.addDebuggee(g);
+g.eval("function h() { debugger; }");
+var hits = 0;
+dbg.onDebuggerStatement = function (hframe) {
+    var env = hframe.older.environment;
+    while (env.parent)
+        env = env.parent;
+    assertEq(env.type, "object");
+    assertEq(env.object, gw);
+    hits++;
+};
+
+g.eval("h();");
+g.eval("(function () { h(); return []; })();");
+g.eval("with (Math) { h(-2 * PI); }");
+assertEq(hits, 3);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-find-01.js
@@ -0,0 +1,19 @@
+// find sees that vars are hoisted out of with statements.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+var hits = 0;
+dbg.onDebuggerStatement = function (frame) {
+    assertEq(frame.environment.find("x").type, "object");
+    hits++;
+};
+
+assertEq(g.eval("(function () {\n" +
+                "    function g() { x = 1; }\n" +
+                "    with ({x: 2}) {\n" +
+                "        var x;\n" +
+                "        debugger;\n" +
+                "        return x;\n" +
+                "    }\n" +
+                "})();"), 2);
+assertEq(hits, 1);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-find-02.js
@@ -0,0 +1,18 @@
+// env.find() finds nonenumerable names in the global environment.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+var hits = 0;
+g.h = function () {
+    var env = dbg.getNewestFrame().environment;
+    var last = env;
+    while (last.parent)
+        last = last.parent;
+
+    assertEq(env.find("Array"), last);
+    hits++;
+};
+
+g.eval("h();");
+g.eval("(function () { let (x = 1, y = 2) h(); })();");
+assertEq(hits, 2);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-find-03.js
@@ -0,0 +1,20 @@
+// env.find() finds noneumerable properties in with statements.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+var hits = 0;
+g.h = function () {
+    var frame = dbg.getNewestFrame();
+    var target = frame.eval("obj").return;
+    var env = frame.environment.find("PI");
+    assertEq(env.object, target);
+    hits++;
+};
+
+g.obj = g.Math;
+g.eval("with (obj) h();");
+g.eval("with (Math) { let x = 12; h(); }");
+g.eval("obj = {};\n" +
+       "Object.defineProperty(obj, 'PI', {enumerable: false, value: 'Marlowe'});\n" +
+       "with (obj) h();\n");
+assertEq(hits, 3);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-find-04.js
@@ -0,0 +1,21 @@
+// env.find throws a TypeError if the argument is not an identifier.
+
+load(libdir + "asserts.js");
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+var hits = 0;
+g.h = function () {
+    var env = dbg.getNewestFrame().environment;
+    assertThrowsInstanceOf(function () { env.find(); }, TypeError);
+    assertThrowsInstanceOf(function () { env.find(""); }, TypeError);
+    assertThrowsInstanceOf(function () { env.find(" "); }, TypeError);
+    assertThrowsInstanceOf(function () { env.find(0); }, TypeError);
+    assertThrowsInstanceOf(function () { env.find("0"); }, TypeError);
+    assertThrowsInstanceOf(function () { env.find("0xc"); }, TypeError);
+    assertThrowsInstanceOf(function () { env.find("Anna Karenina"); }, TypeError);
+    hits++;
+};
+g.eval("h();");
+g.eval("with ([1]) h();");
+assertEq(hits, 2);
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-find-06.js
@@ -0,0 +1,49 @@
+// Environment.prototype.find finds bindings that are function arguments, 'let'
+// bindings, or FunctionExpression names.
+
+var g = newGlobal('new-compartment');
+g.eval("function h() { debugger; }");
+
+var dbg = new Debugger(g);
+
+function test1(code) {
+    var hits = 0;
+    dbg.onDebuggerStatement = function (frame) {
+        var env = frame.older.environment.find('X');
+        assertEq(env.names().indexOf('X') !== -1, true);
+        assertEq(env.type, 'declarative');
+        assertEq(env.parent !== null, true);
+        hits++;
+    };
+    g.eval(code);
+    assertEq(hits, 1);
+}
+
+var manyNames = '';
+for (var i = 0; i < 4096; i++)
+    manyNames += 'x' + i + ', ';
+manyNames += 'X';
+
+function test2(code) {
+    print(code + " : one");
+    test1(code.replace('@@', 'X'));
+    print(code + " : many");
+    test1(code.replace('@@', manyNames));
+}
+
+test2('function f(@@) { h(); }  f(1);');
+test2('function f(@@) { h(); }  f();');
+test2('function f(@@) { return function g() { h(X); }; }  f(1)();');
+test2('function f(@@) { return function g() { h(X); }; }  f()();');
+
+test2('                    { let @@ = 0; h(); }');
+test2('function f(a, b, c) { let @@ = 0; h(); }  f(1, 2, 3);');
+test2('             { let @@ = 0; { let y = 0; h(); } }');
+test2('function f() { let @@ = 0; { let y = 0; h(); } }  f();');
+test2('             { for (let @@ = 0; X < 1; X++) h(); }');
+test2('function f() { for (let @@ = 0; X < 1; X++) h(); }  f();');
+test2('             {        (let (@@ = 0) let (y = 2, z = 3) h()); }');
+test2('function f() { return (let (@@ = 0) let (y = 2, z = 3) h()); }  f();');
+
+test1('(function X() { h(); })();');
+test1('(function X(a, b, c) { h(); })(1, 2, 3);');
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-gc-01.js
@@ -0,0 +1,19 @@
+// An Environment keeps its referent alive.
+
+var g = newGlobal('new-compartment');
+g.eval("function f(x) { return 2 * x; }");
+var dbg = Debugger(g);
+var env;
+dbg.onEnterFrame = function (frame) { env = frame.environment; };
+assertEq(g.f(22), 44);
+dbg.onEnterFrame = undefined;
+
+assertEq(env.find("x"), env);
+assertEq(env.names().join(","), "x");
+
+gc();
+g.gc(g);
+gc(env);
+
+assertEq(env.find("x"), env);
+assertEq(env.names().join(","), "x");
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-gc-02.js
@@ -0,0 +1,28 @@
+// A closure's .environment keeps the lexical environment alive even if the closure is destroyed.
+
+var N = 4;
+var g = newGlobal('new-compartment');
+g.eval("function add(a) { return function (b) { return eval('a + b'); }; }");
+var dbg = new Debugger;
+var gw = dbg.addDebuggee(g);
+var aw = gw.getOwnPropertyDescriptor("add").value;
+
+// Create N closures and collect environments.
+var arr = [];
+for (var i = 0; i < N; i++)
+    arr[i] = aw.call(null, i).return.environment;
+
+// Test that they work now.
+function check() {
+    for (var i = 0; i < N; i++) {
+        assertEq(arr[i].find("b"), null);
+        assertEq(arr[i].find("a"), arr[i]);
+    }
+}
+check();
+
+// Test that they work after gc.
+gc();
+gc({});
+g.gc(g);
+check();
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-identity-01.js
@@ -0,0 +1,40 @@
+// The value of frame.environment is the same Environment object at different
+// times within a single visit to a scope.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+g.eval("function h() { debugger; }");
+var hits, env;
+dbg.onDebuggerStatement = function (hframe) {
+    var frame = hframe.older;
+    var e = frame.environment;
+
+    // frame.environment is at least cached from one moment to the next.
+    assertEq(e, frame.environment);
+
+    // frame.environment is cached from statement to statement within a call frame.
+    if (env === undefined)
+        env = e;
+    else
+        assertEq(e, env);
+
+    hits++;
+};
+
+hits = 0;
+env = undefined;
+g.eval("function f() { (function () { var i = 0; h(); var j = 2; h(); })(); }");
+g.f();
+assertEq(hits, 2);
+
+hits = 0;
+env = undefined;
+g.eval("function f2() { { let i = 0; h(); let j = 2; h(); } }");
+g.f2();
+assertEq(hits, 2);
+
+hits = 0;
+env = undefined;
+g.eval("function f3() { { let i; for (i = 0; i < 2; i++) h(); } }");
+g.f3();
+assertEq(hits, 2);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-identity-02.js
@@ -0,0 +1,29 @@
+// frame.environment is different for different activations of a scope.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+g.eval("function h() { debugger; }");
+var arr;
+dbg.onDebuggerStatement = function (hframe) {
+    var e = hframe.older.environment;
+    assertEq(arr.indexOf(e), -1);
+    arr.push(e);
+};
+
+function test(code, expectedHits) {
+    arr = [];
+    g.eval(code);
+    assertEq(arr.length, expectedHits);
+}
+
+// two separate calls to a function
+test("(function () { var f = function (a) { h(); return a; }; f(1); f(2); })();", 2);
+
+// recursive calls to a function
+test("(function f(n) { h(); return n < 2 ? 1 : n * f(n - 1); })(3);", 3);
+
+// separate visits to a block in the same call frame
+test("(function () { for (var i = 0; i < 3; i++) { let j = i * 4; h(); }})();", 3);
+
+// two strict direct eval calls in the same function scope
+test("(function () { 'use strict'; for (var i = 0; i < 3; i++) eval('h();'); })();", 3);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-identity-03.js
@@ -0,0 +1,109 @@
+// Two Environments nested in the same runtime scope share the correct tail of their parent chains.
+
+// The compiler must be allowed to elide empty scopes and so forth, so this
+// test does not check the number of unshared Environments. Instead, each test
+// case identifies the expected innermost shared scope by the name of a
+// variable in it.
+
+var g = newGlobal('new-compartment');
+g.eval("function h() { debugger; }");
+var dbg = Debugger(g);
+var hits, name, shared, unshared;
+dbg.onDebuggerStatement = function (hframe) {
+    var frame = hframe.older;
+
+    // Find name in frame.environment.
+    var env, child = null;
+    for (env = frame.environment; env !== null; env = env.parent) {
+        if (env.names().indexOf(name) != -1)
+            break;
+        child = env;
+    }
+    assertEq(env !== null, true, "expected '" + name + "' to be in scope");
+    assertEq(env, frame.environment.find(name),
+             "env.find should find the same frame as the written out search");
+
+    if (hits === 0) {
+        // First hit.
+        shared = env;
+        unshared = child;
+    } else {
+        // Subsequent hit.
+        assertEq(env, shared, "the environment containing '" + name + "' should be shared");
+        assertEq(child === null || unshared === null || unshared !== child, true,
+                "environments nested within the one containing '" + name + "' should not be shared");
+    }
+    hits++;
+};
+
+function test(sharedName, expectedHits, code) {
+    hits = 0;
+    name = sharedName;
+    shared = unshared = undefined;
+    g.eval(code);
+    assertEq(hits, expectedHits);
+}
+
+// Basic test cases.
+//
+// (The stray "a = b" assignments in these tests are to inhibit the flat closure
+// optimization, which Environments expose. There's nothing really wrong with
+// the optimization or with the debugger exposing it, but that's not what we
+// want to test here.)
+
+test("q", 2, "var q = function (a) { h(); }; q(1); q(2);");
+test("a", 2, "q = function (a) { (function (b) { h(); a = b; })(2); h(); }; q(1);");
+test("a", 2, "q = function (a) { h(); return function (b) { h(); a = b; }; }; q(1)(2);");
+test("n", 3, "q = function (n) { for (var i = 0; i < n; i++) { let (j = i) { h(); } } }; q(3);");
+
+// Don't crash in E4X filter scopes.
+test("x", 2, "q = function () { var x = <><y/><z/></>.(function (e) { h(); }(this)); }; q();");
+
+// A function with long dynamic and static chains.
+var N = 80;
+
+var code = "function f" + N + "(a" + N + ") {\neval('a0 + a1'); h();\n}\n";
+for (var i = N; --i >= 0;) {
+    var call = "f" + (i + 1) + "(a" + i + " - 1);\n";
+    code = ("function f" + i + "(a" + i + ") {\n" +
+            code +
+            call +
+            "if (a" + i + " === 0) " + call +
+            "}\n");
+}
+
+g.eval(code);
+test("a0", 2, "f0(0);");
+test("a17", 2, "f0(17);");
+test("a" + (N-2), 2, "f0(" + (N-2) + ");");
+test("a" + (N-1), 2, "f0(" + (N-1) + ");");
+
+// A function with a short dynamic chain and a long static chain.
+N = 60;
+
+function DeepStaticShallowDynamic(i, n) {
+    var code = "function f" + i + "(a" + i + ") {\n";
+    if (i >= n)
+        code += "eval('a1 + a2'); h();\n";
+    else
+        code += "return " + DeepStaticShallowDynamic(i+1, n) + ";\n";
+    code += "}";
+    return code;
+}
+g.eval(DeepStaticShallowDynamic(1, N));
+
+function range(start, stop) {
+    for (var i = start; i < stop; i++)
+        yield i;
+}
+
+function DSSDsplit(s) {
+    return ("var mid = f1" + ["(" + i + ")" for (i in range(0, s))].join("") + ";\n" +
+            "mid" +          ["(" + i + ")" for (i in range(s, N))].join("") + ";\n" +
+            "mid" +          ["(" + i + ")" for (i in range(s, N))].join("") + ";\n");
+}
+
+test("a1", 2, DSSDsplit(1));
+test("a17", 2, DSSDsplit(17));
+test("a" + (N-2), 2, DSSDsplit(N-2));
+test("a" + (N-1), 2, DSSDsplit(N-1));
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-identity-04.js
@@ -0,0 +1,19 @@
+// Observably different visits to the same with-statement produce distinct Environments.
+
+var g = newGlobal('new-compartment');
+g.eval("function f(a, obj) { with (obj) return function () { return a; }; }");
+var dbg = Debugger(g);
+var hits = 0;
+dbg.onDebuggerStatement = function (frame) {
+    // Even though the two visits to the with-statement have the same target
+    // object, Math, the environments are observably different.
+    var f1 = frame.eval("f(1, Math);").return;
+    var f2 = frame.eval("f(2, Math);").return;
+    assertEq(f1.environment !== f2.environment, true);
+    assertEq(f1.object, f2.object);
+    assertEq(f1.call().return, 1);
+    assertEq(f2.call().return, 2);
+    hits++;
+};
+g.eval("debugger;");
+assertEq(hits, 1);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-names-01.js
@@ -0,0 +1,17 @@
+// env.names() lists nonenumerable names in with-statement environments.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+var hits = 0;
+g.h = function () {
+    var env = dbg.getNewestFrame().environment;
+    var names = env.names();
+    assertEq(names.indexOf("a") !== -1, true);
+    assertEq(names.indexOf("b") !== -1, true);
+    assertEq(names.indexOf("isPrototypeOf") !== -1, true);
+    hits++;
+};
+g.eval("var obj = {a: 1};\n" +
+       "Object.defineProperty(obj, 'b', {value: 2});\n" +
+       "with (obj) h();");
+assertEq(hits, 1);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-names-02.js
@@ -0,0 +1,15 @@
+// env.names() on object environments ignores property names that are not identifiers.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+var names;
+g.h = function () {
+    names = dbg.getNewestFrame().environment.names();
+};
+g.eval("var obj = {a: 1};\n" +
+       "with ({a: 1, '0xcafe': 2, ' ': 3, '': 4, '0': 5}) h();");
+assertEq(names.indexOf("a") !== -1, true);
+assertEq(names.indexOf("0xcafe"), -1);
+assertEq(names.indexOf(" "), -1);
+assertEq(names.indexOf(""), -1);
+assertEq(names.indexOf("0"), -1);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-parent-01.js
@@ -0,0 +1,18 @@
+// The objects on the environment chain are all Debugger.Environment objects.
+// The environment chain ends in null.
+
+var g = newGlobal('new-compartment')
+g.eval("function f(a) { return function (b) { return function (c) { h(); return a + b + c; }; }; }");
+var dbg = Debugger(g);
+var hits = 0;
+g.h = function () {
+    var n = 0;
+    for (var env = dbg.getNewestFrame().environment; env !== null; env = env.parent) {
+        n++;
+        assertEq(env instanceof Debugger.Environment, true);
+    }
+    assertEq(n >= 4, true);
+    hits++;
+};
+assertEq(g.f(5)(7)(9), 21);
+assertEq(hits, 1);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-type-01.js
@@ -0,0 +1,38 @@
+// env.type is 'object' in global environments and with-blocks, and 'declarative' otherwise.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+function test(code, expected) {
+    var actual = '';
+    g.h = function () { actual += dbg.getNewestFrame().environment.type; }
+    g.eval(code);
+    assertEq(actual, expected);
+}
+
+test("h();", 'object');
+test("(function (s) { eval(s); })('var v = h();')", 'declarative');
+test("(function (s) { h(); })();", 'declarative');
+test("{let x = 1, y = 2; h();}", 'declarative');
+test("with({x: 1, y: 2}) h();", 'object');
+test("(function (s) { with ({x: 1, y: 2}) h(); })();", 'object');
+test("let (x = 1) { h(); }", 'declarative');
+test("(let (x = 1) h());", 'declarative');
+test("for (let x = 0; x < 1; x++) h();", 'declarative');
+test("for (let x in h()) ;", 'object');
+test("for (let x in {a:1}) h();", 'declarative');
+test("try { throw new Error; } catch (x) { h(x) }", 'declarative');
+test("'use strict'; eval('var z = 1; h();');", 'declarative');
+test("for (var x in [h(m) for (m in [1])]) ;", 'declarative');
+test("for (var x in (h(m) for (m in [1]))) ;", 'declarative');
+
+// Since a generator-expression is effectively a function, the innermost scope
+// is a function scope, and thus declarative. Thanks to an odd design decision,
+// m is already in scope at the point of the call to h(). The answer here is
+// not all that important, but we shouldn't crash.
+test("for (var x in (0 for (m in h()))) ;", 'declarative');
+
+dbg.onDebuggerStatement = function (frame) {
+    assertEq(frame.eval("h(), 2 + 2;").return, 4);
+}
+test("debugger;", 'object');
+test("(function f() { debugger; })();", 'declarative');
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Frame-environment-01.js
@@ -0,0 +1,13 @@
+// frame.environment is a Debugger.Environment object
+
+var g = newGlobal('new-compartment')
+var dbg = Debugger(g);
+g.h = function () {
+    assertEq(dbg.getNewestFrame().environment instanceof Debugger.Environment, true);
+};
+
+g.eval("h()");
+g.evaluate("h()");
+g.eval("eval('h()')");
+g.eval("function f() { h(); }");
+g.f();
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Frame-environment-02.js
@@ -0,0 +1,12 @@
+// dbg.getNewestFrame().environment works.
+
+var g = newGlobal('new-compartment');
+var dbg = new Debugger;
+var gw = dbg.addDebuggee(g);
+g.h = function () {
+    var env = dbg.getNewestFrame().environment;
+    assertEq(env instanceof Debugger.Environment, true);
+    assertEq(env.object, gw);
+    assertEq(env.parent, null);
+};
+g.eval("h()");
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Frame-environment-03.js
@@ -0,0 +1,11 @@
+// If !frame.live, frame.environment throws.
+
+load(libdir + "asserts.js");
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+var frame;
+g.h = function () { frame = dbg.getNewestFrame(); };
+g.eval("h();");
+assertEq(frame.live, false);
+assertThrowsInstanceOf(function () { frame.environment; }, Error);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Frame-environment-04.js
@@ -0,0 +1,12 @@
+// frame.environment can be called from the onEnterFrame hook.
+
+var g = newGlobal('new-compartment');
+g.eval("function f(x) { return 2 * x; }");
+var dbg = Debugger(g);
+var hits = 0;
+dbg.onEnterFrame = function (frame) {
+    assertEq(frame.environment.names().join(","), "x");
+    hits++;
+};
+assertEq(g.f(22), 44);
+assertEq(hits, 1);
--- a/js/src/jit-test/tests/debug/Frame-evalWithBindings-10.js
+++ b/js/src/jit-test/tests/debug/Frame-evalWithBindings-10.js
@@ -1,9 +1,10 @@
-// Direct eval code under evalWithbindings sees both the bindings and the enclosing scope.
+// Direct eval code under evalWithBindings sees both the bindings and the enclosing scope.
+
 var g = newGlobal('new-compartment');
 var dbg = new Debugger(g);
 var hits = 0;
 dbg.onDebuggerStatement = function (frame) {
     var code =
         "assertEq(a, 1234);\n" +
         "assertEq(b, null);\n" +
         "assertEq(c, 'ok');\n";
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Object-environment-01.js
@@ -0,0 +1,17 @@
+// obj.environment is undefined when the referent is not a JS function.
+
+var g = newGlobal('new-compartment')
+var dbg = new Debugger;
+var gw = dbg.addDebuggee(g);
+assertEq(gw.environment, undefined);
+
+g.eval("var r = /x/;");
+var rw = gw.getOwnPropertyDescriptor("r").value;
+assertEq(rw.class, "RegExp");
+assertEq(rw.environment, undefined);
+
+// Native function.
+var fw = gw.getOwnPropertyDescriptor("parseInt").value;
+assertEq(fw.class, "Function");
+assertEq(fw.environment, undefined);
+
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Object-environment-02.js
@@ -0,0 +1,20 @@
+// The .environment of a function Debugger.Object is an Environment object.
+
+var g = newGlobal('new-compartment')
+var dbg = Debugger(g);
+var hits = 0;
+g.h = function () {
+    var frame = dbg.getNewestFrame();
+    var fn = frame.eval("j").return;
+    assertEq(fn.environment instanceof Debugger.Environment, true);
+    var closure = frame.eval("f").return;
+    assertEq(closure.environment instanceof Debugger.Environment, true);
+    hits++;
+};
+g.eval("function j(a) {\n" +
+       "    var f = function () { return a; };\n" +
+       "    h();\n" +
+       "    return f;\n" +
+       "}\n" +
+       "j(0);\n");
+assertEq(hits, 1);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/jaeger/bug707384.js
@@ -0,0 +1,8 @@
+// |jit-test| debug
+function f() {
+    do {
+        return
+    } while (e)
+}
+trap(f, 1, '')
+f()
--- a/js/src/js-config.h.in
+++ b/js/src/js-config.h.in
@@ -50,20 +50,16 @@
 
 /* Define to 1 if SpiderMonkey should include ctypes support.  */
 #undef JS_HAS_CTYPES
 
 /* Define to 1 if SpiderMonkey should support the ability to perform
    entirely too much GC.  */
 #undef JS_GC_ZEAL
 
-/* Define to 1 if the standard <stdint.h> header is present and
-   useable.  See jstypes.h and jsstdint.h.  */
-#undef JS_HAVE_STDINT_H
-
 /* Define to 1 if the <endian.h> header is present and
    useable.  See jscpucfg.h.  */
 #undef JS_HAVE_ENDIAN_H
 
 /* Define to 1 if the <sys/isa_defs.h> header is present and
    useable.  See jscpucfg.h.  */
 #undef JS_HAVE_SYS_ISA_DEFS_H
 
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -367,8 +367,9 @@ MSG_DEF(JSMSG_DEBUG_LOOP,             28
 MSG_DEF(JSMSG_DEBUG_NOT_IDLE,         281, 0, JSEXN_ERR, "can't start debugging: a debuggee script is on the stack")
 MSG_DEF(JSMSG_DEBUG_BAD_OFFSET,       282, 0, JSEXN_TYPEERR, "invalid script offset")
 MSG_DEF(JSMSG_DEBUG_BAD_LINE,         283, 0, JSEXN_TYPEERR, "invalid line number")
 MSG_DEF(JSMSG_DEBUG_NOT_DEBUGGING,    284, 0, JSEXN_ERR, "can't set breakpoint: script global is not a debuggee")
 MSG_DEF(JSMSG_DEBUG_COMPARTMENT_MISMATCH, 285, 2, JSEXN_TYPEERR, "{0}: descriptor .{1} property is an object in a different compartment than the target object")
 MSG_DEF(JSMSG_DEBUG_NOT_SCRIPT_FRAME, 286, 0, JSEXN_ERR, "stack frame is not running JavaScript code")
 MSG_DEF(JSMSG_CANT_WATCH_PROP,        287, 0, JSEXN_TYPEERR, "properties whose names are objects can't be watched")
 MSG_DEF(JSMSG_CSP_BLOCKED_EVAL,       288, 0, JSEXN_ERR, "call to eval() blocked by CSP")
+MSG_DEF(JSMSG_DEBUG_NO_SCOPE_OBJECT,  289, 0, JSEXN_TYPEERR, "declarative Environments don't have binding objects")
--- a/js/src/jsanalyze.h
+++ b/js/src/jsanalyze.h
@@ -1050,17 +1050,16 @@ class ScriptAnalysis
         return getCode(offset).allocation;
     }
     mjit::RegisterAllocation *&getAllocation(const jsbytecode *pc) {
         return getAllocation(pc - script->code);
     }
 
     LoopAnalysis *getLoop(uint32 offset) {
         JS_ASSERT(offset < script->length);
-        JS_ASSERT(getCode(offset).loop);
         return getCode(offset).loop;
     }
     LoopAnalysis *getLoop(const jsbytecode *pc) { return getLoop(pc - script->code); }
 
     /* For a JSOP_CALL* op, get the pc of the corresponding JSOP_CALL/NEW/etc. */
     jsbytecode *getCallPC(jsbytecode *pc)
     {
         JS_ASSERT(js_CodeSpec[*pc].format & JOF_CALLOP);
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -5277,23 +5277,16 @@ JS_TriggerAllOperationCallbacks(JSRuntim
     AutoLockGC lock(rt);
 #endif
     TriggerAllOperationCallbacks(rt);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_IsRunning(JSContext *cx)
 {
-    /*
-     * The use of cx->fp below is safe. Rationale: Here we don't care if the
-     * interpreter state is stale. We just want to know if there *is* any
-     * interpreter state.
-     */
-    VOUCH_DOES_NOT_REQUIRE_STACK();
-
 #ifdef JS_THREADSAFE
     if (!cx->thread())
         return false;
 #endif
 
     StackFrame *fp = cx->maybefp();
     while (fp && fp->isDummyFrame())
         fp = fp->prev();
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -428,17 +428,16 @@ js_NewContext(JSRuntime *rt, size_t stac
      * runtime list. After that it can be accessed from another thread via
      * js_ContextIterator.
      */
     JSContext *cx = OffTheBooks::new_<JSContext>(rt);
     if (!cx)
         return NULL;
 
     JS_ASSERT(cx->findVersion() == JSVERSION_DEFAULT);
-    VOUCH_DOES_NOT_REQUIRE_STACK();
 
     if (!cx->busyArrays.init()) {
         Foreground::delete_(cx);
         return NULL;
     }
 
 #ifdef JS_THREADSAFE
     if (!js_InitContextThreadAndLockGC(cx)) {
@@ -751,17 +750,17 @@ PopulateReportBlame(JSContext *cx, JSErr
 {
     /*
      * Walk stack until we find a frame that is associated with some script
      * rather than a native frame.
      */
     for (FrameRegsIter iter(cx); !iter.done(); ++iter) {
         if (iter.fp()->isScriptFrame()) {
             report->filename = iter.fp()->script()->filename;
-            report->lineno = js_FramePCToLineNumber(cx, iter.fp(), iter.pc());
+            report->lineno = js_PCToLineNumber(cx, iter.fp()->script(), iter.pc());
             break;
         }
     }
 }
 
 /*
  * We don't post an exception in this case, since doing so runs into
  * complications of pre-allocating an exception object which required
@@ -1469,17 +1468,16 @@ JSContext::JSContext(JSRuntime *rt)
 
 JSContext::~JSContext()
 {
 #ifdef JS_THREADSAFE
     JS_ASSERT(!thread_);
 #endif
 
     /* Free the stuff hanging off of cx. */
-    VOUCH_DOES_NOT_REQUIRE_STACK();
     if (parseMapPool_)
         Foreground::delete_<ParseMapPool>(parseMapPool_);
 
     if (lastMessage)
         Foreground::free_(lastMessage);
 
     /* Remove any argument formatters. */
     JSArgumentFormatMap *map = argumentFormatMap;
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -70,26 +70,16 @@ struct PreserveRegsGuard
   private:
     JSContext *cx;
     FrameRegs &regs_;
 };
 
 static inline GlobalObject *
 GetGlobalForScopeChain(JSContext *cx)
 {
-    /*
-     * This is essentially GetScopeChain(cx)->getGlobal(), but without
-     * falling off trace.
-     *
-     * This use of cx->fp, possibly on trace, is deliberate:
-     * cx->fp->scopeChain->getGlobal() returns the same object whether we're on
-     * trace or not, since we do not trace calls across global objects.
-     */
-    VOUCH_DOES_NOT_REQUIRE_STACK();
-
     if (cx->hasfp())
         return cx->fp()->scopeChain().getGlobal();
 
     JSObject *scope = JS_ObjectToInnerObject(cx, cx->globalObject);
     if (!scope)
         return NULL;
     return scope->asGlobal();
 }
@@ -147,17 +137,16 @@ class AutoPtr
 class CompartmentChecker
 {
     JSContext *context;
     JSCompartment *compartment;
 
   public:
     explicit CompartmentChecker(JSContext *cx) : context(cx), compartment(cx->compartment) {
         check(cx->hasfp() ? JS_GetGlobalForScopeChain(cx) : cx->globalObject);
-        VOUCH_DOES_NOT_REQUIRE_STACK();
     }
 
     /*
      * Set a breakpoint here (break js::CompartmentChecker::fail) to debug
      * compartment mismatches.
      */
     static void fail(JSCompartment *c1, JSCompartment *c2) {
         printf("*** Compartment mismatch %p vs. %p\n", (void *) c1, (void *) c2);
@@ -233,17 +222,18 @@ class CompartmentChecker
         if (script) {
             check(script->compartment());
             if (!script->isCachedEval && script->globalObject)
                 check(script->globalObject);
         }
     }
 
     void check(StackFrame *fp) {
-        check(&fp->scopeChain());
+        if (fp)
+            check(&fp->scopeChain());
     }
 };
 
 #endif
 
 /*
  * Don't perform these checks when called from a finalizer. The checking
  * depends on other objects not having been swept yet.
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -752,26 +752,26 @@ JS_PUBLIC_API(JSBool)
 JS_EvaluateUCInStackFrame(JSContext *cx, JSStackFrame *fpArg,
                           const jschar *chars, uintN length,
                           const char *filename, uintN lineno,
                           jsval *rval)
 {
     if (!CheckDebugMode(cx))
         return false;
 
-    JSObject *scobj = JS_GetFrameScopeChain(cx, fpArg);
-    if (!scobj)
+    Env *env = JS_GetFrameScopeChain(cx, fpArg);
+    if (!env)
         return false;
 
-    js::AutoCompartment ac(cx, scobj);
+    js::AutoCompartment ac(cx, env);
     if (!ac.enter())
         return false;
 
     StackFrame *fp = Valueify(fpArg);
-    return EvaluateInScope(cx, scobj, fp, chars, length, filename, lineno, rval);
+    return EvaluateInEnv(cx, env, fp, chars, length, filename, lineno, rval);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_EvaluateInStackFrame(JSContext *cx, JSStackFrame *fp,
                         const char *bytes, uintN length,
                         const char *filename, uintN lineno,
                         jsval *rval)
 {
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -335,17 +335,17 @@ InitExnPrivate(JSContext *cx, JSObject *
                 if (!fp->forEachCanonicalActualArg(AppendArg(values)))
                     return false;
             } else {
                 frame.funName.init(NULL);
                 frame.argc = 0;
             }
             if (fp->isScriptFrame()) {
                 frame.filename = fp->script()->filename;
-                frame.ulineno = js_FramePCToLineNumber(cx, fp, i.pc());
+                frame.ulineno = js_PCToLineNumber(cx, fp->script(), i.pc());
             } else {
                 frame.ulineno = 0;
                 frame.filename = NULL;
             }
         }
     }
 
     /* Do not need overflow check: the vm stack is already bigger. */
@@ -760,17 +760,17 @@ Exception(JSContext *cx, uintN argc, Val
     }
 
     /* Set the 'lineNumber' property. */
     uint32_t lineno;
     if (args.length() > 2) {
         if (!ToUint32(cx, args[2], &lineno))
             return false;
     } else {
-        lineno = iter.done() ? 0 : js_FramePCToLineNumber(cx, iter.fp(), iter.pc());
+        lineno = iter.done() ? 0 : js_PCToLineNumber(cx, iter.fp()->script(), iter.pc());
     }
 
     intN exnType = args.callee().toFunction()->getExtendedSlot(0).toInt32();
     if (!InitExnPrivate(cx, obj, message, filename, lineno, NULL, exnType))
         return false;
 
     args.rval().setObject(*obj);
     return true;
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -2284,22 +2284,17 @@ js_AllocFlatClosure(JSContext *cx, JSFun
 
 JSFunction *
 js_NewFlatClosure(JSContext *cx, JSFunction *fun, JSOp op, size_t oplen)
 {
     /*
      * Flat closures cannot yet be partial, that is, all upvars must be copied,
      * or the closure won't be flattened. Therefore they do not need to search
      * enclosing scope objects via JSOP_NAME, etc.
-     *
-     * FIXME: bug 545759 proposes to enable partial flat closures. Fixing this
-     * bug requires a GetScopeChainFast call here, along with JS_REQUIRES_STACK
-     * annotations on this function's prototype and definition.
      */
-    VOUCH_DOES_NOT_REQUIRE_STACK();
     JSObject *scopeChain = &cx->fp()->scopeChain();
 
     JSFunction *closure = js_AllocFlatClosure(cx, fun, scopeChain);
     if (!closure || !fun->script()->bindings.hasUpvars())
         return closure;
 
     uintN level = fun->script()->staticLevel;
     JSUpvarArray *uva = fun->script()->upvars();
--- a/js/src/jsgcmark.cpp
+++ b/js/src/jsgcmark.cpp
@@ -181,26 +181,16 @@ MarkObjectUnbarriered(JSTracer *trc, JSO
 {
     JS_ASSERT(trc);
     JS_ASSERT(obj);
     JS_SET_TRACING_NAME(trc, name);
     Mark(trc, obj);
 }
 
 void
-MarkObjectWithPrinterUnbarriered(JSTracer *trc, JSObject *obj, JSTraceNamePrinter printer,
-                                 const void *arg, size_t index)
-{
-    JS_ASSERT(trc);
-    JS_ASSERT(obj);
-    JS_SET_TRACING_DETAILS(trc, printer, arg, index);
-    Mark(trc, obj);
-}
-
-void
 MarkObject(JSTracer *trc, const MarkablePtr<JSObject> &obj, const char *name)
 {
     MarkObjectUnbarriered(trc, obj.value, name);
 }
 
 void
 MarkScriptUnbarriered(JSTracer *trc, JSScript *script, const char *name)
 {
@@ -714,40 +704,16 @@ MarkRootRange(JSTracer *trc, jsid *beg, 
 }
 
 void
 MarkRootRange(JSTracer *trc, size_t len, jsid *vec, const char *name)
 {
     MarkIdRangeUnbarriered(trc, len, vec, name);
 }
 
-static void
-PrintPropertyId(char *buf, size_t bufsize, jsid propid, const char *label)
-{
-    JS_ASSERT(!JSID_IS_VOID(propid));
-    if (JSID_IS_ATOM(propid)) {
-        size_t n = PutEscapedString(buf, bufsize, JSID_TO_ATOM(propid), 0);
-        if (n < bufsize)
-            JS_snprintf(buf + n, bufsize - n, " %s", label);
-    } else if (JSID_IS_INT(propid)) {
-        JS_snprintf(buf, bufsize, "%d %s", JSID_TO_INT(propid), label);
-    } else {
-        JS_snprintf(buf, bufsize, "<object> %s", label);
-    }
-}
-
-static void
-PrintPropertyGetterOrSetter(JSTracer *trc, char *buf, size_t bufsize)
-{
-    JS_ASSERT(trc->debugPrinter == PrintPropertyGetterOrSetter);
-    Shape *shape = (Shape *)trc->debugPrintArg;
-    PrintPropertyId(buf, bufsize, shape->propid(),
-                    trc->debugPrintIndex ? js_setter_str : js_getter_str); 
-}
-
 static inline void
 ScanValue(GCMarker *gcmarker, const Value &v)
 {
     if (v.isMarkable()) {
         JSGCTraceKind kind = v.gcKind();
         if (kind == JSTRACE_STRING) {
             PushMarkStack(gcmarker, v.toString());
         } else {
@@ -1042,25 +1008,20 @@ MarkChildren(JSTracer *trc, const Shape 
     MarkShapeChildrenAcyclic(trc, shape);
     if (shape->previous())
         MarkShape(trc, shape->previous(), "parent");
 }
 
 void
 MarkChildren(JSTracer *trc, BaseShape *base)
 {
-    if (base->hasGetterObject()) {
-        MarkObjectWithPrinterUnbarriered(trc, base->getterObject(),
-                                         PrintPropertyGetterOrSetter, base, 0);
-    }
-
-    if (base->hasSetterObject()) {
-        MarkObjectWithPrinterUnbarriered(trc, base->setterObject(),
-                                         PrintPropertyGetterOrSetter, base, 0);
-    }
+    if (base->hasGetterObject())
+        MarkObjectUnbarriered(trc, base->getterObject(), "getter");
+    if (base->hasSetterObject())
+        MarkObjectUnbarriered(trc, base->setterObject(), "setter");
 
     if (base->isOwned())
         MarkBaseShapeUnbarriered(trc, base->baseUnowned(), "base");
 
     if (JSObject *parent = base->getObjectParent())
         MarkObjectUnbarriered(trc, parent, "parent");
 }
 
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -147,17 +147,16 @@ js::GetScopeChain(JSContext *cx)
  * require bytecode scanning appears below.
  */
 JSObject *
 js::GetBlockChain(JSContext *cx, StackFrame *fp)
 {
     if (!fp->isScriptFrame())
         return NULL;
 
-    /* Assume that imacros don't affect blockChain */
     jsbytecode *target = fp->pcQuadratic(cx->stack);
 
     JSScript *script = fp->script();
     jsbytecode *start = script->code;
 
     /*
      * If the debugger asks for the scope chain at a pc where we are about to
      * fix it up, advance target past the fixup. See bug 672804.
@@ -3105,21 +3104,16 @@ BEGIN_CASE(JSOP_LENGTH)
                 if (js_IsTypedArray(obj)) {
                     JSObject *tarray = TypedArray::getTypedArray(obj);
                     rval = Int32Value(TypedArray::getLength(tarray));
                     break;
                 }
             }
         }
 
-        /*
-         * We do not impose the method read barrier if in an imacro,
-         * assuming any property gets it does (e.g., for 'toString'
-         * from JSOP_NEW) will not be leaked to the calling script.
-         */
         JSObject *obj;
         VALUE_TO_OBJECT(cx, vp, obj);
         JSObject *aobj = js_GetProtoIfDenseArray(obj);
 
         PropertyCacheEntry *entry;
         JSObject *obj2;
         JSAtom *atom;
         JS_PROPERTY_CACHE(cx).test(cx, regs.pc, aobj, obj2, entry, atom);
--- a/js/src/jsinttypes.h
+++ b/js/src/jsinttypes.h
@@ -34,105 +34,41 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef jsinttypes_h___
 #define jsinttypes_h___
 
 #include "js-config.h"
 
+#include "mozilla/StdInt.h"
+
 /*
  * Types:
  *   JSInt<N>, JSUint<N> (for <N> = 8, 16, 32, and 64)
  *   JSIntPtr, JSUIntPtr
  *
  * JSInt<N> and JSUint<N> are signed and unsigned types known to be
  * <N> bits long.  Note that neither JSInt8 nor JSUInt8 is necessarily
  * equivalent to a plain "char".
  *
  * JSIntPtr and JSUintPtr are signed and unsigned types capable of
  * holding an object pointer.
  *
- * Use these types in public SpiderMonkey header files, not the
- * corresponding types from the C standard <stdint.h> header.  Windows
- * doesn't support <stdint.h>, and Microsoft says it has no plans to
- * do so in the future; this means that projects that embed
- * SpiderMonkey often take matters into their own hands and define the
- * standard types themselves.  If we define them in our public
- * headers, our definitions may conflict with embedders' (see bug
- * 479258).  The JS* types are in our namespace, and can be used
- * without troubling anyone.
- *
- * Internal SpiderMonkey code wishing to use the type names ISO C
- * defines in the standard header <stdint.h> can #include
- * "jsstdint.h", which provides those types regardless of whether
- * <stdint.h> itself is available.
+ * These typedefs were once necessary to support platforms without a working
+ * <stdint.h> (i.e. MSVC++ prior to 2010).  Now that we ship a custom <stdint.h>
+ * for such compilers, they are no longer necessary and will likely be shortly
+ * removed.
  */
 
-#if defined(JS_HAVE_STDINT_H) || \
-    defined(JS_SYS_TYPES_H_DEFINES_EXACT_SIZE_TYPES)
-
-#if defined(JS_HAVE_STDINT_H)
-#include <stdint.h>
-#else
-#include <sys/types.h>
-#endif
-
 typedef int8_t   JSInt8;
 typedef int16_t  JSInt16;
 typedef int32_t  JSInt32;
 typedef int64_t  JSInt64;
 typedef intptr_t JSIntPtr;
 
 typedef uint8_t   JSUint8;
 typedef uint16_t  JSUint16;
 typedef uint32_t  JSUint32;
 typedef uint64_t  JSUint64;
 typedef uintptr_t JSUintPtr;
 
-#else
-
-#if defined(JS_HAVE___INTN)
-
-typedef __int8  JSInt8;
-typedef __int16 JSInt16;
-typedef __int32 JSInt32;
-typedef __int64 JSInt64;
-
-typedef unsigned __int8 JSUint8;
-typedef unsigned __int16 JSUint16;
-typedef unsigned __int32 JSUint32;
-typedef unsigned __int64 JSUint64;
-
-#elif defined(JS_INT8_TYPE)
-
-typedef signed JS_INT8_TYPE   JSInt8;
-typedef signed JS_INT16_TYPE  JSInt16;
-typedef signed JS_INT32_TYPE  JSInt32;
-typedef signed JS_INT64_TYPE  JSInt64;
-
-typedef unsigned JS_INT8_TYPE   JSUint8;
-typedef unsigned JS_INT16_TYPE  JSUint16;
-typedef unsigned JS_INT32_TYPE  JSUint32;
-typedef unsigned JS_INT64_TYPE  JSUint64;
-
-#else
-#error "couldn't find exact-width integer types"
-#endif
-
-/* Microsoft Visual C/C++ defines intptr_t and uintptr_t in <stddef.h>.  */
-#if defined(JS_STDDEF_H_HAS_INTPTR_T)
-#include <stddef.h>
-typedef intptr_t JSIntPtr;
-typedef uintptr_t JSUintPtr;
-
-/* Failing that, the configure script will have found something.  */
-#elif defined(JS_INTPTR_TYPE)
-typedef signed   JS_INTPTR_TYPE JSIntPtr;
-typedef unsigned JS_INTPTR_TYPE JSUintPtr;
-
-#else
-#error "couldn't find pointer-sized integer types"
-#endif
-
-#endif /* JS_HAVE_STDINT_H */
-
 #endif /* jsinttypes_h___ */
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -81,43 +81,16 @@
 #include "jsstrinlines.h"
 
 #include "vm/NumberObject-inl.h"
 #include "vm/String-inl.h"
 
 using namespace js;
 using namespace js::types;
 
-#ifndef JS_HAVE_STDINT_H /* Native support is innocent until proven guilty. */
-
-JS_STATIC_ASSERT(uint8_t(-1) == UINT8_MAX);
-JS_STATIC_ASSERT(uint16_t(-1) == UINT16_MAX);
-JS_STATIC_ASSERT(uint32_t(-1) == UINT32_MAX);
-JS_STATIC_ASSERT(uint64_t(-1) == UINT64_MAX);
-
-JS_STATIC_ASSERT(INT8_MAX > INT8_MIN);
-JS_STATIC_ASSERT(uint8_t(INT8_MAX) + uint8_t(1) == uint8_t(INT8_MIN));
-JS_STATIC_ASSERT(INT16_MAX > INT16_MIN);
-JS_STATIC_ASSERT(uint16_t(INT16_MAX) + uint16_t(1) == uint16_t(INT16_MIN));
-JS_STATIC_ASSERT(INT32_MAX > INT32_MIN);
-JS_STATIC_ASSERT(uint32_t(INT32_MAX) + uint32_t(1) == uint32_t(INT32_MIN));
-JS_STATIC_ASSERT(INT64_MAX > INT64_MIN);
-JS_STATIC_ASSERT(uint64_t(INT64_MAX) + uint64_t(1) == uint64_t(INT64_MIN));
-
-JS_STATIC_ASSERT(INTPTR_MAX > INTPTR_MIN);
-JS_STATIC_ASSERT(uintptr_t(INTPTR_MAX) + uintptr_t(1) == uintptr_t(INTPTR_MIN));
-JS_STATIC_ASSERT(uintptr_t(-1) == UINTPTR_MAX);
-JS_STATIC_ASSERT(size_t(-1) == SIZE_MAX);
-JS_STATIC_ASSERT(PTRDIFF_MAX > PTRDIFF_MIN);
-JS_STATIC_ASSERT(ptrdiff_t(PTRDIFF_MAX) == PTRDIFF_MAX);
-JS_STATIC_ASSERT(ptrdiff_t(PTRDIFF_MIN) == PTRDIFF_MIN);
-JS_STATIC_ASSERT(uintptr_t(PTRDIFF_MAX) + uintptr_t(1) == uintptr_t(PTRDIFF_MIN));
-
-#endif /* JS_HAVE_STDINT_H */
-
 /*
  * If we're accumulating a decimal number and the number is >= 2^53, then the
  * fast result from the loop in GetPrefixInteger may be inaccurate. Call
  * js_strtod_harder to get the correct answer.
  */
 static bool
 ComputeAccurateDecimalInteger(JSContext *cx, const jschar *start, const jschar *end, jsdouble *dp)
 {
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -112,16 +112,18 @@
 
 #include "jsautooplen.h"
 
 using namespace mozilla;
 using namespace js;
 using namespace js::gc;
 using namespace js::types;
 
+JS_STATIC_ASSERT(int32((JSObject::NELEMENTS_LIMIT - 1) * sizeof(Value)) == int64((JSObject::NELEMENTS_LIMIT - 1) * sizeof(Value)));
+
 Class js::ObjectClass = {
     js_Object_str,
     JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
     JS_PropertyStub,         /* addProperty */
     JS_PropertyStub,         /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
@@ -4964,42 +4966,27 @@ js_GetClassObject(JSContext *cx, JSObjec
     *objp = cobj;
     return true;
 }
 
 JSBool
 js_FindClassObject(JSContext *cx, JSObject *start, JSProtoKey protoKey,
                    Value *vp, Class *clasp)
 {
-    StackFrame *fp;
     JSObject *obj, *cobj, *pobj;
     jsid id;
     JSProperty *prop;
     const Shape *shape;
 
-    /*
-     * Find the global object. Use cx->fp() directly to avoid falling off
-     * trace; all JIT-elided stack frames have the same global object as
-     * cx->fp().
-     */
-    VOUCH_DOES_NOT_REQUIRE_STACK();
-    if (!start && (fp = cx->maybefp()) != NULL)
-        start = &fp->scopeChain();
-
     if (start) {
         obj = start->getGlobal();
+        OBJ_TO_INNER_OBJECT(cx, obj);
     } else {
-        obj = cx->globalObject;
-        if (!obj) {
-            vp->setUndefined();
-            return true;
-        }
-    }
-
-    OBJ_TO_INNER_OBJECT(cx, obj);
+        obj = GetGlobalForScopeChain(cx);
+    }
     if (!obj)
         return false;
 
     if (protoKey != JSProto_Null) {
         JS_ASSERT(JSProto_Null < protoKey);
         JS_ASSERT(protoKey < JSProto_LIMIT);
         if (!js_GetClassObject(cx, obj, protoKey, &cobj))
             return false;
@@ -6750,17 +6737,16 @@ js::FindClassPrototype(JSContext *cx, JS
 /*
  * The first part of this function has been hand-expanded and optimized into
  * NewBuiltinClassInstance in jsobjinlines.h.
  */
 JSBool
 js_GetClassPrototype(JSContext *cx, JSObject *scopeobj, JSProtoKey protoKey,
                      JSObject **protop, Class *clasp)
 {
-    VOUCH_DOES_NOT_REQUIRE_STACK();
     JS_ASSERT(JSProto_Null <= protoKey);
     JS_ASSERT(protoKey < JSProto_LIMIT);
 
     if (protoKey != JSProto_Null) {
         GlobalObject *global;
         if (scopeobj) {
             global = scopeobj->getGlobal();
         } else {
@@ -7005,17 +6991,17 @@ js_ClearNative(JSContext *cx, JSObject *
     }
 
     /* Set all remaining writable plain data properties to undefined. */
     for (Shape::Range r(obj->lastProperty()->all()); !r.empty(); r.popFront()) {
         const Shape *shape = &r.front();
         if (shape->isDataDescriptor() &&
             shape->writable() &&
             shape->hasDefaultSetter() &&
-            obj->containsSlot(shape->slot())) {
+            obj->containsSlot(shape->maybeSlot())) {
             obj->setSlot(shape->slot(), UndefinedValue());
         }
     }
     return true;
 }
 
 bool
 js_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 slot, Value *vp)
@@ -7378,18 +7364,16 @@ MaybeDumpValue(const char *name, const V
         fputc('\n', stderr);
     }
 }
 
 JS_FRIEND_API(void)
 js_DumpStackFrame(JSContext *cx, StackFrame *start)
 {
     /* This should only called during live debugging. */
-    VOUCH_DOES_NOT_REQUIRE_STACK();
-
     FrameRegsIter i(cx, StackIter::GO_THROUGH_SAVED);
     if (!start) {
         if (i.done()) {
             fprintf(stderr, "no stack for cx = %p\n", (void*) cx);
             return;
         }
         start = i.fp();
     } else {
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -526,17 +526,17 @@ struct JSObject : js::gc::Cell
 
     inline js::Shape **nativeSearch(JSContext *cx, jsid id, bool adding = false);
     const js::Shape *nativeLookup(JSContext *cx, jsid id);
 
     inline bool nativeContains(JSContext *cx, jsid id);
     inline bool nativeContains(JSContext *cx, const js::Shape &shape);
 
     /* Upper bound on the number of elements in an object. */
-    static const uint32 NELEMENTS_LIMIT = JS_BIT(29);
+    static const uint32 NELEMENTS_LIMIT = JS_BIT(28);
 
   private:
     js::HeapValue   *slots;     /* Slots for object properties. */
     js::HeapValue   *elements;  /* Slots for object elements. */
 
   public:
 
     inline bool isNative() const;
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -575,18 +575,17 @@ js_Disassemble1(JSContext *cx, JSScript 
       case JOF_OBJECT:
       case JOF_REGEXP: {
         uintN index = js_GetIndexFromBytecode(cx, script, pc, 0);
         jsval v;
         if (type == JOF_ATOM) {
             if (op == JSOP_DOUBLE) {
                 v = script->getConst(index);
             } else {
-                JSAtom *atom;
-                JS_GET_SCRIPT_ATOM(script, pc, index, atom);
+                JSAtom *atom = script->getAtom(index);
                 v = STRING_TO_JSVAL(atom);
             }
         } else {
             JSObject *obj;
             if (type == JOF_OBJECT) {
                 /* Don't call obj.toSource if analysis/inference is active. */
                 if (cx->compartment->activeAnalysis) {
                     Sprint(sp, " object");
@@ -669,18 +668,17 @@ js_Disassemble1(JSContext *cx, JSScript 
         break;
 
       case JOF_SLOTATOM:
       case JOF_SLOTOBJECT: {
         Sprint(sp, " %u", GET_SLOTNO(pc));
         uintN index = js_GetIndexFromBytecode(cx, script, pc, SLOTNO_LEN);
         jsval v;
         if (type == JOF_SLOTATOM) {
-            JSAtom *atom;
-            JS_GET_SCRIPT_ATOM(script, pc, index, atom);
+            JSAtom *atom = script->getAtom(index);
             v = STRING_TO_JSVAL(atom);
         } else {
             v = OBJECT_TO_JSVAL(script->getObject(index));
         }
 
         JSAutoByteString bytes;
         if (!ToDisassemblySource(cx, v, &bytes))
             return 0;
@@ -4346,17 +4344,16 @@ Decompile(SprintStack *ss, jsbytecode *p
                             table[j].order = j;
                             j++;
                         }
                         pc2 += jmplen;
                     }
                     tmp = (TableEntry *)
                           cx->malloc_((size_t)j * sizeof *table);
                     if (tmp) {
-                        VOUCH_DOES_NOT_REQUIRE_STACK();
                         MergeSort(table, size_t(j), tmp, CompareTableEntries);
                         Foreground::free_(tmp);
                         ok = true;
                     } else {
                         ok = false;
                     }
                 }
 
--- a/js/src/jsopcode.h
+++ b/js/src/jsopcode.h
@@ -337,17 +337,17 @@ js_GetIndexFromBytecode(JSContext *cx, J
 /*
  * A slower version of GET_ATOM when the caller does not want to maintain
  * the index segment register itself.
  */
 #define GET_ATOM_FROM_BYTECODE(script, pc, pcoff, atom)                       \
     JS_BEGIN_MACRO                                                            \
         JS_ASSERT(*(pc) != JSOP_DOUBLE);                                      \
         uintN index_ = js_GetIndexFromBytecode(cx, (script), (pc), (pcoff));  \
-        JS_GET_SCRIPT_ATOM(script, pc, index_, atom);                         \
+        (atom) = (script)->getAtom(index_);                                   \
     JS_END_MACRO
 
 #define GET_DOUBLE_FROM_BYTECODE(script, pc, pcoff, dbl)                      \
     JS_BEGIN_MACRO                                                            \
         uintN index_ = js_GetIndexFromBytecode(cx, (script), (pc), (pcoff));  \
         JS_ASSERT(index_ < (script)->consts()->length);                       \
         (dbl) = (script)->getConst(index_).toDouble();                        \
     JS_END_MACRO
--- a/js/src/jspropertycache.cpp
+++ b/js/src/jspropertycache.cpp
@@ -114,17 +114,17 @@ PropertyCache::fill(JSContext *cx, JSObj
         return JS_NO_PROP_CACHE_FILL;
     }
 
     /*
      * Optimize the cached vword based on our parameters and the current pc's
      * opcode format flags.
      */
     jsbytecode *pc;
-    JSScript *script = cx->stack.currentScript(&pc);
+    (void) cx->stack.currentScript(&pc);
     op = JSOp(*pc);
     cs = &js_CodeSpec[op];
 
     if ((cs->format & JOF_SET) && obj->watched())
         return JS_NO_PROP_CACHE_FILL;
 
     if (obj == pobj) {
         JS_ASSERT(scopeIndex == 0 && protoIndex == 0);
--- a/js/src/jsprvtd.h
+++ b/js/src/jsprvtd.h
@@ -238,16 +238,24 @@ class Debugger;
 class WatchpointMap;
 
 typedef HashMap<JSAtom *,
                 detail::RegExpPrivateCacheValue,
                 DefaultHasher<JSAtom *>,
                 RuntimeAllocPolicy>
     RegExpPrivateCache;
 
+/*
+ * Env is the type of what ES5 calls "lexical environments" (runtime
+ * activations of lexical scopes). This is currently just JSObject, and is
+ * implemented by Call, Block, With, and DeclEnv objects, among others--but
+ * environments and objects are really two different concepts.
+ */
+typedef JSObject Env;
+
 typedef JSNative             Native;
 typedef JSPropertyOp         PropertyOp;
 typedef JSStrictPropertyOp   StrictPropertyOp;
 typedef JSPropertyDescriptor PropertyDescriptor;
 
 namespace analyze {
 
 struct LifetimeVariable;
--- a/js/src/jsscope.h
+++ b/js/src/jsscope.h
@@ -503,17 +503,17 @@ struct Shape : public js::gc::Cell
     HeapPtrBaseShape    base_;
     HeapId              propid_;
 
     JS_ENUM_HEADER(SlotInfo, uint32)
     {
         /* Number of fixed slots in objects with this shape. */
         FIXED_SLOTS_MAX        = 0x1f,
         FIXED_SLOTS_SHIFT      = 27,
-        FIXED_SLOTS_MASK       = FIXED_SLOTS_MAX << FIXED_SLOTS_SHIFT,
+        FIXED_SLOTS_MASK       = uint32(FIXED_SLOTS_MAX << FIXED_SLOTS_SHIFT),
 
         /* 
          * numLinearSearches starts at zero and is incremented initially on
          * search() calls. Once numLinearSearches reaches LINEAR_SEARCHES_MAX,
          * the table is created on the next search() call. The table can also
          * be created when hashifying for dictionary mode.
          */
         LINEAR_SEARCHES_MAX    = 0x7,
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -1439,22 +1439,16 @@ js_GetSrcNoteCached(JSContext *cx, JSScr
             cache->code = script->code;
         }
     }
 
     return result;
 }
 
 uintN
-js_FramePCToLineNumber(JSContext *cx, StackFrame *fp, jsbytecode *pc)
-{
-    return js_PCToLineNumber(cx, fp->script(), pc);
-}
-
-uintN
 js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
 {
     /* Cope with StackFrame.pc value prior to entering js_Interpret. */
     if (!pc)
         return 0;
 
     /*
      * Special case: function definition needs no line number note because
@@ -1560,32 +1554,32 @@ js_GetScriptLineExtent(JSScript *script)
     return 1 + lineno - script->lineno;
 }
 
 namespace js {
 
 uintN
 CurrentLine(JSContext *cx)
 {
-    return js_FramePCToLineNumber(cx, cx->fp(), cx->regs().pc);
+    return js_PCToLineNumber(cx, cx->fp()->script(), cx->regs().pc);
 }
 
 const char *
 CurrentScriptFileAndLineSlow(JSContext *cx, uintN *linenop)
 {
     FrameRegsIter iter(cx);
     while (!iter.done() && !iter.fp()->isScriptFrame())
         ++iter;
 
     if (iter.done()) {
         *linenop = 0;
         return NULL;
     }
 
-    *linenop = js_FramePCToLineNumber(cx, iter.fp(), iter.pc());
+    *linenop = js_PCToLineNumber(cx, iter.fp()->script(), iter.pc());
     return iter.fp()->script()->filename;
 }
 
 }  /* namespace js */
 
 class DisablePrincipalsTranscoding {
     JSSecurityCallbacks *callbacks;
     JSPrincipalsTranscoder temp;
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -835,33 +835,16 @@ JS_STATIC_ASSERT(sizeof(JSScript) % js::
 #define SHARP_NSLOTS            2       /* [#array, #depth] slots if the script
                                            uses sharp variables */
 static JS_INLINE uintN
 StackDepth(JSScript *script)
 {
     return script->nslots - script->nfixed;
 }
 
-/*
- * If pc_ does not point within script_'s bytecode, then it must point into an
- * imacro body, so we use cx->runtime common atoms instead of script_'s atoms.
- * This macro uses cx from its callers' environments in the pc-in-imacro case.
- */
-#define JS_GET_SCRIPT_ATOM(script_, pc_, index, atom)                         \
-    JS_BEGIN_MACRO                                                            \
-        if ((pc_) < (script_)->code ||                                        \
-            (script_)->code + (script_)->length <= (pc_)) {                   \
-            JS_ASSERT((size_t)(index) < js_common_atom_count);                \
-            (atom) = cx->runtime->atomState.commonAtomsStart()[index];        \
-        } else {                                                              \
-            (atom) = script_->getAtom(index);                                 \
-        }                                                                     \
-    JS_END_MACRO
-
-
 extern void
 js_MarkScriptFilename(const char *filename);
 
 extern void
 js_SweepScriptFilenames(JSCompartment *comp);
 
 /*
  * New-script-hook calling is factored from NewScriptFromEmitter so that it
@@ -898,24 +881,16 @@ CheckScript(JSScript *script, JSScript *
  * cache without adding an explicit cx parameter.  Thus js_GetSrcNote becomes
  * a macro that uses cx from its calls' lexical environments.
  */
 #define js_GetSrcNote(script,pc) js_GetSrcNoteCached(cx, script, pc)
 
 extern jssrcnote *
 js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc);
 
-/*
- * NOTE: use js_FramePCToLineNumber(cx, fp) when you have an active fp, in
- * preference to js_PCToLineNumber (cx, fp->script  fp->regs->pc), because
- * fp->imacpc may be non-null, indicating an active imacro.
- */
-extern uintN
-js_FramePCToLineNumber(JSContext *cx, js::StackFrame *fp, jsbytecode *pc);
-
 extern uintN
 js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc);
 
 extern jsbytecode *
 js_LineNumberToPC(JSScript *script, uintN lineno);
 
 extern JS_FRIEND_API(uintN)
 js_GetScriptLineExtent(JSScript *script);
--- a/js/src/jsstdint.h
+++ b/js/src/jsstdint.h
@@ -33,90 +33,17 @@
  * 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 ***** */
 
 /*
- * This header provides definitions for the <stdint.h> types we use,
- * even on systems that lack <stdint.h>.
- *
- * NOTE: This header should only be included in private SpiderMonkey
- * code; public headers should use only the JS{Int,Uint}N types; see
- * the comment for them in "jsinttypes.h".
- *
- * At the moment, these types are not widely used within SpiderMonkey;
- * this file is meant to make existing uses portable, and to allow us
- * to transition portably to using them more, if desired.
+ * This header implements the functionality of <stdint.h>, even on systems that
+ * lack it.  It does so by completely delegating to a separate header, which
+ * could just as easily be used.  However, as this header is part of the
+ * SpiderMonkey interface, we retain it for compatibility.
  */
-
 #ifndef jsstdint_h___
 #define jsstdint_h___
-
-#include "jsinttypes.h"
-
-/* If we have a working stdint.h, then jsinttypes.h has already
-   defined the standard integer types.  Otherwise, define the standard
-   names in terms of the 'JS' types.  */
-#if ! defined(JS_HAVE_STDINT_H) && \
-    ! defined(JS_SYS_TYPES_H_DEFINES_EXACT_SIZE_TYPES)
-
-typedef JSInt8  int8_t;
-typedef JSInt16 int16_t;
-typedef JSInt32 int32_t;
-typedef JSInt64 int64_t;
-
-typedef JSUint8  uint8_t;
-typedef JSUint16 uint16_t;
-typedef JSUint32 uint32_t;
-typedef JSUint64 uint64_t;
-
-/* Suppress other, conflicting attempts to define stdint-bits. */
-#define _STDINT_H
-
-/* If JS_STDDEF_H_HAS_INTPTR_T or JS_CRTDEFS_H_HAS_INTPTR_T are
-   defined, then jsinttypes.h included the given header, which
-   introduced definitions for intptr_t and uintptr_t.  Otherwise,
-   define the standard names in terms of the 'JS' types.  */
-#if !defined(JS_STDDEF_H_HAS_INTPTR_T) && !defined(JS_CRTDEFS_H_HAS_INTPTR_T)
-typedef JSIntPtr  intptr_t;
-typedef JSUintPtr uintptr_t;
-#endif
-
-#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)
-
-#define INT8_MAX  127
-#define INT8_MIN  (-INT8_MAX - 1)
-#define INT16_MAX 32767
-#define INT16_MIN (-INT16_MAX - 1)
-#define INT32_MAX 2147483647
-#define INT32_MIN (-INT32_MAX - 1)
-#define INT64_MAX 9223372036854775807LL
-#define INT64_MIN (-INT64_MAX - 1)
-
-#define UINT8_MAX  255
-#define UINT16_MAX 65535
-#define UINT32_MAX 4294967295U
-#define UINT64_MAX 18446744073709551615ULL
-
-/*
- * These are technically wrong as they can't be used in the preprocessor, but
- * we would require compiler assistance, and at the moment we don't need
- * preprocessor-correctness.
- */
-#ifdef _MSC_VER
-#undef SIZE_MAX
-#endif
-
-#define INTPTR_MAX  ((intptr_t) (UINTPTR_MAX >> 1))
-#define INTPTR_MIN  (intptr_t(uintptr_t(INTPTR_MAX) + uintptr_t(1)))
-#define UINTPTR_MAX ((uintptr_t) -1)
-#define SIZE_MAX UINTPTR_MAX
-#define PTRDIFF_MAX INTPTR_MAX
-#define PTRDIFF_MIN INTPTR_MIN
-
-#endif /* !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) */
-
-#endif /* JS_HAVE_STDINT_H */
-
+#include "mozilla/StdInt.h"
 #endif /* jsstdint_h___ */
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -85,44 +85,51 @@
 #include "vm/String-inl.h"
 
 using namespace js;
 using namespace js::gc;
 using namespace js::types;
 using namespace js::unicode;
 
 static JSLinearString *
-ArgToRootedString(JSContext *cx, uintN argc, Value *vp, uintN arg)
+ArgToRootedString(JSContext *cx, CallArgs &args, uintN argno)
 {
-    if (arg >= argc)
+    if (argno >= args.length())
         return cx->runtime->atomState.typeAtoms[JSTYPE_VOID];
-    vp += 2 + arg;
-
-    if (!ToPrimitive(cx, JSTYPE_STRING, vp))
+
+    Value *arg = &args[argno];
+    if (!ToPrimitive(cx, JSTYPE_STRING, arg))
         return NULL;
 
     JSLinearString *str;
-    if (vp->isString()) {
-        str = vp->toString()->ensureLinear(cx);
-    } else if (vp->isBoolean()) {
-        str = cx->runtime->atomState.booleanAtoms[(int)vp->toBoolean()];
-    } else if (vp->isNull()) {
+    if (arg->isString()) {
+        str = arg->toString()->ensureLinear(cx);
+    } else if (arg->isBoolean()) {
+        str = cx->runtime->atomState.booleanAtoms[(int)arg->toBoolean()];
+    } else if (arg->isNull()) {
         str = cx->runtime->atomState.nullAtom;
-    } else if (vp->isUndefined()) {
+    } else if (arg->isUndefined()) {
         str = cx->runtime->atomState.typeAtoms[JSTYPE_VOID];
-    }
-    else {
-        str = NumberToString(cx, vp->toNumber());
+    } else {
+        str = NumberToString(cx, arg->toNumber());
         if (!str)
             return NULL;
-        vp->setString(str);
+        arg->setString(str);
     }
+
     return str;
 }
 
+static JSLinearString *
+ArgToRootedString(JSContext *cx, uintN argc, Value *vp, uintN argno)
+{
+    CallArgs args = CallArgsFromVp(argc, vp);
+    return ArgToRootedString(cx, args, argno);
+}
+
 /*
  * Forward declarations for URI encode/decode and helper routines
  */
 static JSBool
 str_decodeURI(JSContext *cx, uintN argc, Value *vp);
 
 static JSBool
 str_decodeURI_Component(JSContext *cx, uintN argc, Value *vp);
@@ -233,78 +240,138 @@ str_escape(JSContext *cx, uintN argc, Va
     if (!retstr) {
         cx->free_(newchars);
         return JS_FALSE;
     }
     vp->setString(retstr);
     return JS_TRUE;
 }
 
+static inline bool
+Unhex4(const jschar *chars, jschar *result)
+{
+    jschar a = chars[0],
+           b = chars[1],
+           c = chars[2],
+           d = chars[3];
+
+    if (!(JS7_ISHEX(a) && JS7_ISHEX(b) && JS7_ISHEX(c) && JS7_ISHEX(d)))
+        return false;
+
+    *result = (((((JS7_UNHEX(a) << 4) + JS7_UNHEX(b)) << 4) + JS7_UNHEX(c)) << 4) + JS7_UNHEX(d);
+    return true;
+}
+
+static inline bool
+Unhex2(const jschar *chars, jschar *result)
+{
+    jschar a = chars[0],
+           b = chars[1];
+
+    if (!(JS7_ISHEX(a) && JS7_ISHEX(b)))
+        return false;
+
+    *result = (JS7_UNHEX(a) << 4) + JS7_UNHEX(b);
+    return true;
+}
+
 /* ES5 B.2.2 */
 static JSBool
 str_unescape(JSContext *cx, uintN argc, Value *vp)
 {
-    JSLinearString *str = ArgToRootedString(cx, argc, vp, 0);
+    CallArgs args = CallArgsFromVp(argc, vp);
+
+    /* Step 1. */
+    JSLinearString *str = ArgToRootedString(cx, args, 0);
     if (!str)
         return false;
 
+    /* Step 2. */
     size_t length = str->length();
     const jschar *chars = str->chars();
 
-    /* Start by allocating the maximum required space for the new string. */
-    jschar *newchars = (jschar *) cx->malloc_((length + 1) * sizeof(jschar));
-    if (!newchars)
-        return false;
-
-    size_t ni = 0, i = 0;
-    bool escapeFound = false;
-    while (i < length) {
-        jschar ch = chars[i++];
-        if (ch == '%') {
-            /* Incomplete escapes are interpreted as literal characters. */
-            if (i + 1 < length &&
-                JS7_ISHEX(chars[i]) && JS7_ISHEX(chars[i + 1]))
-            {
-                ch = JS7_UNHEX(chars[i]) * 16 + JS7_UNHEX(chars[i + 1]);
-                i += 2;
-                escapeFound = true;
-            } else if (i + 4 < length && chars[i] == 'u' &&
-                       JS7_ISHEX(chars[i + 1]) && JS7_ISHEX(chars[i + 2]) &&
-                       JS7_ISHEX(chars[i + 3]) && JS7_ISHEX(chars[i + 4]))
-            {
-                ch = (((((JS7_UNHEX(chars[i + 1]) << 4)
-                        + JS7_UNHEX(chars[i + 2])) << 4)
-                      + JS7_UNHEX(chars[i + 3])) << 4)
-                    + JS7_UNHEX(chars[i + 4]);
-                i += 5;
-                escapeFound = true;
+    /* Step 3. */
+    StringBuffer sb(cx);
+
+    /*
+     * Note that the spec algorithm has been optimized to avoid building
+     * a string in the case where no escapes are present.
+     */
+
+    /* Step 4. */
+    size_t k = 0;
+    bool building = false;
+
+    while (true) {
+        /* Step 5. */
+        if (k == length) {
+            JSLinearString *result;
+            if (building) {
+                result = sb.finishString();
+                if (!result)
+                    return false;
+            } else {
+                result = str;
             }
+
+            args.rval().setString(result);
+            return true;
         }
-        newchars[ni++] = ch;
+
+        /* Step 6. */
+        jschar c = chars[k];
+
+        /* Step 7. */
+        if (c != '%')
+            goto step_18;
+
+        /* Step 8. */
+        if (k > length - 6)
+            goto step_14;
+
+        /* Step 9. */
+        if (chars[k + 1] != 'u')
+            goto step_14;
+
+#define ENSURE_BUILDING                             \
+    JS_BEGIN_MACRO                                  \
+        if (!building) {                            \
+            building = true;                        \
+            if (!sb.reserve(length))                \
+                return false;                       \
+            sb.infallibleAppend(chars, chars + k);  \
+        }                                           \
+    JS_END_MACRO
+
+        /* Step 10-13. */
+        if (Unhex4(&chars[k + 2], &c)) {
+            ENSURE_BUILDING;
+            k += 5;
+            goto step_18;
+        }
+
+      step_14:
+        /* Step 14. */
+        if (k > length - 3)
+            goto step_18;
+
+        /* Step 15-17. */
+        if (Unhex2(&chars[k + 1], &c)) {
+            ENSURE_BUILDING;
+            k += 2;
+        }
+
+      step_18:
+        if (building)
+            sb.infallibleAppend(c);
+
+        /* Step 19. */
+        k += 1;
     }
-    newchars[ni] = 0;
-
-    /* If escapes were found, shrink the string. */
-    if (escapeFound) {
-        JS_ASSERT(ni < length);
-        jschar *tmpchars = (jschar *) cx->realloc_(newchars, (ni + 1) * sizeof(jschar));
-        if (!tmpchars) {
-            cx->free_(newchars);
-            return false;
-        }
-        newchars = tmpchars;
-    }
-
-    JSString *retstr = js_NewString(cx, newchars, ni);
-    if (!retstr) {
-        cx->free_(newchars);
-        return false;
-    }
-    vp->setString(retstr);
-    return true;
+#undef ENSURE_BUILDING
 }
 
 #if JS_HAS_UNEVAL
 static JSBool
 str_uneval(JSContext *cx, uintN argc, Value *vp)
 {
     JSString *str;
 
@@ -3072,18 +3139,17 @@ StringBuffer::extractWellSized()
     size_t length = cb.length();
 
     jschar *buf = cb.extractRawBuffer();
     if (!buf)
         return NULL;
 
     /* For medium/big buffers, avoid wasting more than 1/4 of the memory. */
     JS_ASSERT(capacity >= length);
-    if (length > CharBuffer::sMaxInlineStorage &&
-        capacity - length > (length >> 2)) {
+    if (length > CharBuffer::sMaxInlineStorage && capacity - length > length / 4) {
         size_t bytes = sizeof(jschar) * (length + 1);
         JSContext *cx = context();
         jschar *tmp = (jschar *)cx->realloc_(buf, bytes);
         if (!tmp) {
             cx->free_(buf);
             return NULL;
         }
         buf = tmp;
--- a/js/src/jsstrinlines.h
+++ b/js/src/jsstrinlines.h
@@ -48,16 +48,23 @@
 #include "vm/String-inl.h"
 
 namespace js {
 
 /*
  * String builder that eagerly checks for over-allocation past the maximum
  * string length.
  *
+ * Any operation which would exceed the maximum string length causes an
+ * exception report on the context and results in a failed return value.
+ *
+ * Well-sized extractions (which waste no more than 1/4 of their char
+ * buffer space) are guaranteed for strings built by this interface.
+ * See |extractWellSized|.
+ *
  * Note: over-allocation is not checked for when using the infallible
  * |replaceRawBuffer|, so the implementation of |finishString| also must check
  * for over-allocation.
  */
 class StringBuffer
 {
     /* cb's buffer is taken by the new string so use ContextAllocPolicy. */
     typedef Vector<jschar, 32, ContextAllocPolicy> CharBuffer;
--- a/js/src/jsutil.h
+++ b/js/src/jsutil.h
@@ -396,22 +396,19 @@ enum MaybeReportError { REPORT_ERROR = t
 /* Static control-flow checks. */
 #ifdef NS_STATIC_CHECKING
 /* Trigger a control flow check to make sure that code flows through label */
 inline __attribute__ ((unused)) void MUST_FLOW_THROUGH(const char *label) {}
 
 /* Avoid unused goto-label warnings. */
 # define MUST_FLOW_LABEL(label) goto label; label:
 
-inline JS_FORCES_STACK void VOUCH_DOES_NOT_REQUIRE_STACK() {}
-
 #else
 # define MUST_FLOW_THROUGH(label)            ((void) 0)
 # define MUST_FLOW_LABEL(label)
-# define VOUCH_DOES_NOT_REQUIRE_STACK()      ((void) 0)
 #endif
 
 /* Crash diagnostics */
 #ifdef DEBUG
 # define JS_CRASH_DIAGNOSTICS 1
 #endif
 #ifdef JS_CRASH_DIAGNOSTICS
 # define JS_POISON(p, val, size) memset((p), (val), (size))
@@ -461,11 +458,9 @@ JS_DumpHistogram(JSBasicStats *bs, FILE 
 typedef size_t jsbitmap;
 #define JS_TEST_BIT(_map,_bit)  ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] &      \
                                  ((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1))))
 #define JS_SET_BIT(_map,_bit)   ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] |=     \
                                  ((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1))))
 #define JS_CLEAR_BIT(_map,_bit) ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] &=     \
                                  ~((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1))))
 
-#define VOUCH_HAVE_STACK                    VOUCH_DOES_NOT_REQUIRE_STACK
-
 #endif /* jsutil_h___ */
--- a/js/src/jsxml.cpp
+++ b/js/src/jsxml.cpp
@@ -1792,17 +1792,17 @@ ParseXMLSource(JSContext *cx, JSString *
     xml = NULL;
     filename = NULL;
     lineno = 1;
     FrameRegsIter i(cx);
     if (!i.done()) {
         op = (JSOp) *i.pc();
         if (op == JSOP_TOXML || op == JSOP_TOXMLLIST) {
             filename = i.fp()->script()->filename;
-            lineno = js_FramePCToLineNumber(cx, i.fp(), i.pc());
+            lineno = js_PCToLineNumber(cx, i.fp()->script(), i.pc());
             for (endp = srcp + srclen; srcp < endp; srcp++) {
                 if (*srcp == '\n')
                     --lineno;
             }
         }
     }
 
     {
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -1568,17 +1568,17 @@ mjit::Compiler::generateMethod()
                 fixedDoubleToAnyEntries.clear();
 
                 /*
                  * Watch for fallthrough to the head of a 'do while' loop.
                  * We don't know what register state we will be using at the head
                  * of the loop so sync, branch, and fix it up after the loop
                  * has been processed.
                  */
-                if (cx->typeInferenceEnabled() && op == JSOP_LOOPHEAD) {
+                if (cx->typeInferenceEnabled() && op == JSOP_LOOPHEAD && analysis->getLoop(PC)) {
                     frame.syncAndForgetEverything();
                     Jump j = masm.jump();
                     if (!startLoop(PC, j, PC))
                         return Compile_Error;
                 } else {
                     Label start = masm.label();
                     if (!frame.syncForBranch(PC, Uses(0)))
                         return Compile_Error;
--- a/js/src/methodjit/StubCalls.cpp
+++ b/js/src/methodjit/StubCalls.cpp
@@ -1473,21 +1473,16 @@ InlineGetProp(VMFrame &f)
     }
 
     JSObject *obj = ValueToObject(f.cx, vp);
     if (!obj)
         return false;
 
     Value rval;
     do {
-        /*
-         * We do not impose the method read barrier if in an imacro,
-         * assuming any property gets it does (e.g., for 'toString'
-         * from JSOP_NEW) will not be leaked to the calling script.
-         */
         JSObject *aobj = js_GetProtoIfDenseArray(obj);
 
         PropertyCacheEntry *entry;
         JSObject *obj2;
         JSAtom *atom;
         JS_PROPERTY_CACHE(cx).test(cx, f.pc(), aobj, obj2, entry, atom);
         if (!atom) {
             NATIVE_GET(cx, obj, obj2, entry->prop, JSGET_METHOD_BARRIER, &rval, return false);
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -4117,17 +4117,38 @@ static const char *const shell_help_mess
 "    \"-l\" (show line numbers)",
 "dissrc([fun])            Disassemble functions with source lines",
 "dumpHeap([fileName[, start[, toFind[, maxDepth[, toIgnore]]]]])\n"
 "  Interface to JS_DumpHeap with output sent to file",
 "dumpObject()             Dump an internal representation of an object",
 "notes([fun])             Show source notes for functions",
 "stats([string ...])      Dump 'arena', 'atom', 'global' stats",
 "findReferences(target)\n"
-"  Walk the heap and return an object describing all references to target",
+"  Walk the entire heap, looking for references to |target|, and return a\n"
+"  \"references object\" describing what we found.\n"
+"\n"
+"  Each property of the references object describes one kind of reference. The\n"
+"  property's name is the label supplied to MarkObject, JS_CALL_TRACER, or what\n"
+"  have you, prefixed with \"edge: \" to avoid collisions with system properties\n"
+"  (like \"toString\" and \"__proto__\"). The property's value is an array of things\n"
+"  that refer to |thing| via that kind of reference. Ordinary references from\n"
+"  one object to another are named after the property name (with the \"edge: \"\n"
+"  prefix).\n"
+"\n"
+"  Garbage collection roots appear as references from 'null'. We use the name\n"
+"  given to the root (with the \"edge: \" prefix) as the name of the reference.\n"
+"\n"
+"  Note that the references object does record references from objects that are\n"
+"  only reachable via |thing| itself, not just the references reachable\n"
+"  themselves from roots that keep |thing| from being collected. (We could make\n"
+"  this distinction if it is useful.)\n"
+"\n"
+"  If any references are found by the conservative scanner, the references\n"
+"  object will have a property named \"edge: machine stack\"; the referrers will\n"
+"  be 'null', because they are roots.",
 #endif
 "dumpStack()              Dump the stack as an array of callees (youngest first)",
 #ifdef TEST_CVTARGS
 "cvtargs(arg1..., arg12)  Test argument formatter",
 #endif
 "build()                  Show build date and time",
 "clear([obj])             Clear properties of object",
 "intern(str)              Internalize str in the atom table",
--- a/js/src/shell/jsheaptools.cpp
+++ b/js/src/shell/jsheaptools.cpp
@@ -9,25 +9,25 @@
  * the License. You may obtain a copy of the License at
  * http://www.mozilla.org/MPL/
  *
  * Software distributed under the License is distributed on an "AS IS" basis,
  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  * for the specific language governing rights and limitations under the
  * License.
  *
- * The Original Code is JavaScript shell workers.
+ * The Original Code is JavaScript heap tools.
  *
  * The Initial Developer of the Original Code is
  * Mozilla Corporation.
  * Portions created by the Initial Developer are Copyright (C) 2010
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
- *   Jason Orendorff <jorendorff@mozilla.com>
+ *   Jim Blandy <jimb@mozilla.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either of 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
@@ -546,42 +546,17 @@ ReferenceFinder::findReferences(JSObject
     if (!result)
         return NULL;
     if (!visit(target, NULL))
         return NULL;
 
     return result;
 }
 
-/*
- * findReferences(thing)
- *
- * Walk the entire heap, looking for references to |thing|, and return a
- * "references object" describing what we found.
- *
- * Each property of the references object describes one kind of reference. The
- * property's name is the label supplied to MarkObject, JS_CALL_TRACER, or what
- * have you, prefixed with "edge: " to avoid collisions with system properties
- * (like "toString" and "__proto__"). The property's value is an array of things
- * that refer to |thing| via that kind of reference. Ordinary references from
- * one object to another are named after the property name (with the "edge: "
- * prefix).
- *
- * Garbage collection roots appear as references from 'null'. We use the name
- * given to the root (with the "edge: " prefix) as the name of the reference.
- *
- * Note that the references object does record references from objects that are
- * only reachable via |thing| itself, not just the references reachable
- * themselves from roots that keep |thing| from being collected. (We could make
- * this distinction if it is useful.)
- *
- * If any references are found by the conservative scanner, the references
- * object will have a property named "edge: machine stack"; the referrers will
- * be 'null', because they are roots.
- */
+/* See help(findReferences). */
 JSBool
 FindReferences(JSContext *cx, uintN argc, jsval *vp)
 {
     if (argc < 1) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_MORE_ARGS_NEEDED,
                              "findReferences", "0", "s");
         return false;
     }
--- a/js/src/tests/js1_8/extensions/regress-422269.js
+++ b/js/src/tests/js1_8/extensions/regress-422269.js
@@ -33,56 +33,64 @@
  * 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 ***** */
 
 //-----------------------------------------------------------------------------
 var BUGNUMBER = 422269;
 var summary = 'Compile-time let block should not capture runtime references';
-var actual = 'No leak';
-var expect = 'No leak';
+var actual = 'referenced only by stack and closure';
+var expect = 'referenced only by stack and closure';
 
 
 //-----------------------------------------------------------------------------
 test();
 
 //-----------------------------------------------------------------------------
 
 function test()
 {
   enterFunc ('test');
   printBugNumber(BUGNUMBER);
   printStatus (summary);
 
   function f()
   {
     let m = {sin: Math.sin};
-    (function() { m.sin(1); })();
+    (function holder() { m.sin(1); })();
     return m;
   }
 
-  if (typeof countHeap == 'undefined')
+  if (typeof findReferences == 'undefined')
   {
     expect = actual = 'Test skipped';
-    print('Test skipped. Requires countHeap function.');
+    print('Test skipped. Requires findReferences function.');
   }
   else
   {
     var x = f();
-    f(); // overwrite the machine stack with new objects
-    gc();
-    var n = countHeap();
-    x = null;
-    // When running with the method JIT, null may not get stored to memory right away.
-    // Calling eval ensures that all values are stored out so that the old x is no
-    // longer rooted from the stack.
-    eval("");
-    gc();
+    var refs = findReferences(x);
 
-    var n2 = countHeap();
-    if (n2 >= n)
-      actual = "leak is detected, something roots the result of f";
+    // At this point, x should only be referenced from the stack --- the
+    // variable 'x' itself, and any random things the conservative scanner
+    // finds --- and possibly from the 'holder' closure, which could itself
+    // be held alive for random reasons. Remove those from the refs list, and 
+    // then complain if anything is left.
+    for (var edge in refs) {
+      // Remove references from roots, like the stack.
+      if (refs[edge].every(function (r) r === null))
+        delete refs[edge];
+      // Remove references from the closure, which could be held alive for
+      // random reasons.
+      else if (refs[edge].length === 1 &&
+               typeof refs[edge][0] === "function" &&
+               refs[edge][0].name === "holder")
+        delete refs[edge];
+    }
+
+    if (Object.keys(refs).length != 0)
+        actual = "unexpected references to the result of f: " + Object.keys(refs).join(", ");
   }
   reportCompare(expect, actual, summary);
 
   exitFunc ('test');
 }
--- a/js/src/tests/js1_8_5/extensions/findReferences-01.js
+++ b/js/src/tests/js1_8_5/extensions/findReferences-01.js
@@ -6,41 +6,41 @@ if (typeof findReferences == "function")
     function C() {}
     var o = new C;
     o.x = {};               // via ordinary property
     o[42] = {};             // via numeric property
     o.myself = o;           // self-references should be reported
     o.alsoMyself = o;       // multiple self-references should all be reported
 
     assertEq(referencesVia(o, 'type; type_proto', C.prototype), true);
-    assertEq(referencesVia(o, 'parent', this), true);
+    assertEq(referencesVia(o, 'shape; base; parent', this), true);
     assertEq(referencesVia(o, 'x', o.x), true);
     assertEq(referencesVia(o, '42', o[42]), true);
     assertEq(referencesVia(o, 'myself', o), true);
     assertEq(referencesVia(o, 'alsoMyself', o), true);
 
     function g() { return 42; }
     function s(v) { }
     var p = Object.defineProperty({}, 'a', { get:g, set:s });
-    assertEq(referencesVia(p, 'shape; a getter', g), true);
-    assertEq(referencesVia(p, 'shape; a setter', s), true);
+    assertEq(referencesVia(p, 'shape; base; getter', g), true);
+    assertEq(referencesVia(p, 'shape; base; setter', s), true);
 
     // If there are multiple objects with the same shape referring to a getter
     // or setter, findReferences should get all of them, even though the shape
     // gets 'marked' the first time we visit it.
     var q = Object.defineProperty({}, 'a', { get:g, set:s });
-    assertEq(referencesVia(p, 'shape; a getter', g), true);
-    assertEq(referencesVia(q, 'shape; a getter', g), true);
+    assertEq(referencesVia(p, 'shape; base; getter', g), true);
+    assertEq(referencesVia(q, 'shape; base; getter', g), true);
 
     // If we extend each object's shape chain, both should still be able to
     // reach the getter, even though the two shapes are each traversed twice.
     p.b = 9;
     q.b = 9;
-    assertEq(referencesVia(p, 'shape; a getter', g), true);
-    assertEq(referencesVia(q, 'shape; a getter', g), true);
+    assertEq(referencesVia(p, 'shape; parent; base; getter', g), true);
+    assertEq(referencesVia(q, 'shape; parent; base; getter', g), true);
 
     // These are really just ordinary own property references.
     assertEq(referencesVia(C, 'prototype', Object.getPrototypeOf(o)), true);
     assertEq(referencesVia(Object.getPrototypeOf(o), 'constructor', C), true);
 
     // Dense arrays should work, too.
     a = [];
     a[1] = o;
--- a/js/src/tests/js1_8_5/extensions/findReferences-02.js
+++ b/js/src/tests/js1_8_5/extensions/findReferences-02.js
@@ -8,21 +8,21 @@ if (typeof findReferences == "function")
      })();
 
     var o = ({});
 
     function returnFlat(x) { return function flat() { return x; }; }
     assertEq(referencesVia(returnFlat(o), 'upvars[0]', o), true);
 
     function returnHeavy(y) { eval(''); return function heavy() { return y; }; }
-    assertEq(referencesVia(returnHeavy(o), 'parent; y', o), true);
-    assertEq(referencesVia(returnHeavy(o), 'parent; parent', this), true);
+    assertEq(referencesVia(returnHeavy(o), 'fun_callscope; y', o), true);
+    assertEq(referencesVia(returnHeavy(o), 'fun_callscope; shape; base; parent', this), true);
 
     function returnBlock(z) { eval(''); let(w = z) { return function block() { return w; }; }; }
-    assertEq(referencesVia(returnBlock(o), 'parent; w', o), true);
+    assertEq(referencesVia(returnBlock(o), 'fun_callscope; w', o), true);
 
     function returnWithObj(v) { with(v) return function withObj() { return u; }; }
-    assertEq(referencesVia(returnWithObj(o), 'parent; type; type_proto', o), true);
+    assertEq(referencesVia(returnWithObj(o), 'fun_callscope; type; type_proto', o), true);
 
     reportCompare(true, true);
 } else {
     reportCompare(true, true, "test skipped: findReferences is not a function");
 }
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -73,16 +73,23 @@ enum {
 
 extern Class DebuggerArguments_class;
 
 enum {
     JSSLOT_DEBUGARGUMENTS_FRAME,
     JSSLOT_DEBUGARGUMENTS_COUNT
 };
 
+extern Class DebuggerEnv_class;
+
+enum {
+    JSSLOT_DEBUGENV_OWNER,
+    JSSLOT_DEBUGENV_COUNT
+};
+
 extern Class DebuggerObject_class;
 
 enum {
     JSSLOT_DEBUGOBJECT_OWNER,
     JSSLOT_DEBUGOBJECT_COUNT
 };
 
 extern Class DebuggerScript_class;
@@ -116,16 +123,31 @@ ReportMoreArgsNeeded(JSContext *cx, cons
 
 bool
 ReportObjectRequired(JSContext *cx)
 {
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_NONNULL_OBJECT);
     return false;
 }
 
+bool
+ValueToIdentifier(JSContext *cx, const Value &v, jsid *idp)
+{
+    jsid id;
+    if (!ValueToId(cx, v, &id))
+        return false;
+    if (!JSID_IS_ATOM(id) || !IsIdentifier(JSID_TO_ATOM(id))) {
+        js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
+                                 JSDVG_SEARCH_STACK, v, NULL, "not an identifier", NULL);
+        return false;
+    }
+    *idp = id;
+    return true;
+}
+
 
 /*** Breakpoints *********************************************************************************/
 
 BreakpointSite::BreakpointSite(JSScript *script, jsbytecode *pc)
   : script(script), pc(pc), scriptGlobal(NULL), enabledCount(0),
     trapHandler(NULL), trapClosure(UndefinedValue())
 {
     JS_ASSERT(!script->hasBreakpointsAt(pc));
@@ -292,17 +314,17 @@ Breakpoint::nextInSite()
     return (link == &site->breakpoints) ? NULL : fromSiteLinks(link);
 }
 
 
 /*** Debugger hook dispatch **********************************************************************/
 
 Debugger::Debugger(JSContext *cx, JSObject *dbg)
   : object(dbg), uncaughtExceptionHook(NULL), enabled(true),
-    frames(cx), objects(cx), scripts(cx)
+    frames(cx), scripts(cx), objects(cx), environments(cx)
 {
     assertSameCompartment(cx, dbg);
 
     JSRuntime *rt = cx->runtime;
     AutoLockGC lock(rt);
     JS_APPEND_LINK(&link, &rt->debuggerList);
     JS_INIT_CLIST(&breakpoints);
 }
@@ -314,34 +336,37 @@ Debugger::~Debugger()
     /* This always happens in the GC thread, so no locking is required. */
     JS_ASSERT(object->compartment()->rt->gcRunning);
     JS_REMOVE_LINK(&link);
 }
 
 bool
 Debugger::init(JSContext *cx)
 {
-    bool ok = frames.init() &&
+    bool ok = debuggees.init() &&
+              frames.init() &&
+              scripts.init() &&
               objects.init() &&
-              debuggees.init() &&
-              scripts.init();
+              environments.init();
     if (!ok)
         js_ReportOutOfMemory(cx);
     return ok;
 }
 
+JS_STATIC_ASSERT(uintN(JSSLOT_DEBUGFRAME_OWNER) == uintN(JSSLOT_DEBUGSCRIPT_OWNER));
 JS_STATIC_ASSERT(uintN(JSSLOT_DEBUGFRAME_OWNER) == uintN(JSSLOT_DEBUGOBJECT_OWNER));
-JS_STATIC_ASSERT(uintN(JSSLOT_DEBUGFRAME_OWNER) == uintN(JSSLOT_DEBUGSCRIPT_OWNER));
+JS_STATIC_ASSERT(uintN(JSSLOT_DEBUGFRAME_OWNER) == uintN(JSSLOT_DEBUGENV_OWNER));
 
 Debugger *
 Debugger::fromChildJSObject(JSObject *obj)
 {
     JS_ASSERT(obj->getClass() == &DebuggerFrame_class ||
+              obj->getClass() == &DebuggerScript_class ||
               obj->getClass() == &DebuggerObject_class ||
-              obj->getClass() == &DebuggerScript_class);
+              obj->getClass() == &DebuggerEnv_class);
     JSObject *dbgobj = &obj->getReservedSlot(JSSLOT_DEBUGOBJECT_OWNER).toObject();
     return fromJSObject(dbgobj);
 }
 
 bool
 Debugger::getScriptFrame(JSContext *cx, StackFrame *fp, Value *vp)
 {
     JS_ASSERT(fp->isScriptFrame());
@@ -465,16 +490,45 @@ Debugger::slowPathOnLeaveFrame(JSContext
      */
     if (fp->isEvalFrame()) {
         JSScript *script = fp->script();
         script->clearBreakpointsIn(cx, NULL, NULL);
     }
 }
 
 bool
+Debugger::wrapEnvironment(JSContext *cx, Env *env, Value *rval)
+{
+    if (!env) {
+        rval->setNull();
+        return true;
+    }
+
+    JSObject *envobj;
+    ObjectWeakMap::AddPtr p = environments.lookupForAdd(env);
+    if (p) {
+        envobj = p->value;
+    } else {
+        /* Create a new Debugger.Environment for env. */
+        JSObject *proto = &object->getReservedSlot(JSSLOT_DEBUG_ENV_PROTO).toObject();
+        envobj = NewObjectWithGivenProto(cx, &DebuggerEnv_class, proto, NULL);
+        if (!envobj)
+            return false;
+        envobj->setPrivate(env);
+        envobj->setReservedSlot(JSSLOT_DEBUGENV_OWNER, ObjectValue(*object));
+        if (!environments.relookupOrAdd(p, env, envobj)) {
+            js_ReportOutOfMemory(cx);
+            return false;
+        }
+    }
+    rval->setObject(*envobj);
+    return true;
+}
+
+bool
 Debugger::wrapDebuggeeValue(JSContext *cx, Value *vp)
 {
     assertSameCompartment(cx, object.get());
 
     if (vp->isObject()) {
         JSObject *obj = &vp->toObject();
 
         ObjectWeakMap::AddPtr p = objects.lookupForAdd(obj);
@@ -1008,16 +1062,23 @@ Debugger::markKeysInCompartment(JSTracer
         ObjectMap;
     const ObjectMap &objStorage = objects;
     for (ObjectMap::Range r = objStorage.all(); !r.empty(); r.popFront()) {
         const HeapPtrObject &key = r.front().key;
         if (key->compartment() == comp && IsAboutToBeFinalized(tracer->context, key))
             gc::MarkObject(tracer, key, "cross-compartment WeakMap key");
     }
 
+    const ObjectMap &envStorage = environments;
+    for (ObjectMap::Range r = envStorage.all(); !r.empty(); r.popFront()) {
+        const HeapPtrObject &key = r.front().key;
+        if (key->compartment() == comp && IsAboutToBeFinalized(tracer->context, key))
+            js::gc::MarkObject(tracer, key, "cross-compartment WeakMap key");
+    }
+
     typedef HashMap<HeapPtrScript, HeapPtrObject, DefaultHasher<HeapPtrScript>, RuntimeAllocPolicy>
         ScriptMap;
     const ScriptMap &scriptStorage = scripts;
     for (ScriptMap::Range r = scriptStorage.all(); !r.empty(); r.popFront()) {
         const HeapPtrScript &key = r.front().key;
         if (key->compartment() == comp && IsAboutToBeFinalized(tracer->context, key))
             gc::MarkScript(tracer, key, "cross-compartment WeakMap key");
     }
@@ -1173,21 +1234,24 @@ Debugger::trace(JSTracer *trc)
      * frames.)
      */
     for (FrameMap::Range r = frames.all(); !r.empty(); r.popFront()) {
         const HeapPtrObject &frameobj = r.front().value;
         JS_ASSERT(frameobj->getPrivate());
         MarkObject(trc, frameobj, "live Debugger.Frame");
     }
 
+    /* Trace the weak map from JSScript instances to Debugger.Script objects. */
+    scripts.trace(trc);
+
     /* Trace the referent -> Debugger.Object weak map. */
     objects.trace(trc);
 
-    /* Trace the weak map from JSScript instances to Debugger.Script objects. */
-    scripts.trace(trc);
+    /* Trace the referent -> Debugger.Environment weak map. */
+    environments.trace(trc);
 }
 
 void
 Debugger::sweepAll(JSContext *cx)
 {
     JSRuntime *rt = cx->runtime;
     JS_ASSERT(!rt->gcCurrentCompartment);
 
@@ -2397,16 +2461,20 @@ StackContains(JSContext *cx, StackFrame 
 #define THIS_FRAME(cx, argc, vp, fnname, args, thisobj, fp)                  \
     CallArgs args = CallArgsFromVp(argc, vp);                                \
     JSObject *thisobj = CheckThisFrame(cx, args, fnname, true);              \
     if (!thisobj)                                                            \
         return false;                                                        \
     StackFrame *fp = (StackFrame *) thisobj->getPrivate();                   \
     JS_ASSERT(StackContains(cx, fp))
 
+#define THIS_FRAME_OWNER(cx, argc, vp, fnname, args, thisobj, fp, dbg)       \
+    THIS_FRAME(cx, argc, vp, fnname, args, thisobj, fp);                     \
+    Debugger *dbg = Debugger::fromChildJSObject(thisobj)
+
 static JSBool
 DebuggerFrame_getType(JSContext *cx, uintN argc, Value *vp)
 {
     THIS_FRAME(cx, argc, vp, "get type", args, thisobj, fp);
 
     /*
      * Indirect eval frames are both isGlobalFrame() and isEvalFrame(), so the
      * order of checks here is significant.
@@ -2414,16 +2482,43 @@ DebuggerFrame_getType(JSContext *cx, uin
     args.rval().setString(fp->isEvalFrame()
                           ? cx->runtime->atomState.evalAtom
                           : fp->isGlobalFrame()
                           ? cx->runtime->atomState.globalAtom
                           : cx->runtime->atomState.callAtom);
     return true;
 }
 
+static Env *
+Frame_GetEnv(JSContext *cx, StackFrame *fp)
+{
+    assertSameCompartment(cx, fp);
+    if (fp->isNonEvalFunctionFrame() && !fp->hasCallObj() && !CreateFunCallObject(cx, fp))
+        return NULL;
+    return GetScopeChain(cx, fp);
+}
+
+static JSBool
+DebuggerFrame_getEnvironment(JSContext *cx, uintN argc, Value *vp)
+{
+    THIS_FRAME_OWNER(cx, argc, vp, "get environment", args, thisobj, fp, dbg);
+
+    Env *env;
+    {
+        AutoCompartment ac(cx, &fp->scopeChain());
+        if (!ac.enter())
+            return false;
+        env = Frame_GetEnv(cx, fp);
+        if (!env)
+            return false;
+    }
+
+    return dbg->wrapEnvironment(cx, env, &args.rval());
+}
+
 static JSBool
 DebuggerFrame_getCallee(JSContext *cx, uintN argc, Value *vp)
 {
     THIS_FRAME(cx, argc, vp, "get callee", args, thisobj, fp);
     Value calleev = (fp->isFunctionFrame() && !fp->isEvalFrame()) ? fp->calleev() : NullValue();
     if (!Debugger::fromChildJSObject(thisobj)->wrapDebuggeeValue(cx, &calleev))
         return false;
     args.rval() = calleev;
@@ -2685,42 +2780,44 @@ DebuggerFrame_setOnStep(JSContext *cx, u
     thisobj->setReservedSlot(JSSLOT_DEBUGFRAME_ONSTEP_HANDLER, args[0]);
     args.rval().setUndefined();
     return true;
 }
 
 namespace js {
 
 JSBool
-EvaluateInScope(JSContext *cx, JSObject *scobj, StackFrame *fp, const jschar *chars,
-                uintN length, const char *filename, uintN lineno, Value *rval)
+EvaluateInEnv(JSContext *cx, Env *env, StackFrame *fp, const jschar *chars,
+              uintN length, const char *filename, uintN lineno, Value *rval)
 {
-    assertSameCompartment(cx, scobj, fp);
-
-    /* Execute assumes an already-computed 'this" value. */
-    if (!ComputeThis(cx, fp))
-        return false;
+    assertSameCompartment(cx, env, fp);
+
+    if (fp) {
+        /* Execute assumes an already-computed 'this" value. */
+        if (!ComputeThis(cx, fp))
+            return false;
+    }
 
     /*
      * NB: This function breaks the assumption that the compiler can see all
      * calls and properly compute a static level. In order to get around this,
      * we use a static level that will cause us not to attempt to optimize
      * variable references made by this frame.
      */
-    JSScript *script = frontend::CompileScript(cx, scobj, fp,
+    JSScript *script = frontend::CompileScript(cx, env, fp,
                                                fp->scopeChain().principals(cx),
                                                TCF_COMPILE_N_GO | TCF_NEED_SCRIPT_GLOBAL,
                                                chars, length, filename, lineno,
                                                cx->findVersion(), NULL,
                                                UpvarCookie::UPVAR_LEVEL_LIMIT);
 
     if (!script)
         return false;
 
-    return ExecuteKernel(cx, script, *scobj, fp->thisValue(), EXECUTE_DEBUG, fp, rval);
+    return ExecuteKernel(cx, script, *env, fp->thisValue(), EXECUTE_DEBUG, fp, rval);
 }
 
 }
 
 enum EvalBindingsMode { WithoutBindings, WithBindings };
 
 static JSBool
 DebuggerFrameEval(JSContext *cx, uintN argc, Value *vp, EvalBindingsMode mode)
@@ -2767,40 +2864,40 @@ DebuggerFrameEval(JSContext *cx, uintN a
             }
         }
     }
 
     AutoCompartment ac(cx, &fp->scopeChain());
     if (!ac.enter())
         return false;
 
-    JSObject *scobj = JS_GetFrameScopeChain(cx, Jsvalify(fp));
-    if (!scobj)
+    Env *env = JS_GetFrameScopeChain(cx, Jsvalify(fp));
+    if (!env)
         return false;
 
-    /* If evalWithBindings, create the inner scope object. */
+    /* If evalWithBindings, create the inner environment. */
     if (mode == WithBindings) {
-        /* TODO - Should probably create a With object here. */
-        scobj = NewObjectWithGivenProto(cx, &ObjectClass, NULL, scobj);
-        if (!scobj)
+        /* TODO - This should probably be a Call object, like ES5 strict eval. */
+        env = NewObjectWithGivenProto(cx, &ObjectClass, NULL, env);
+        if (!env)
             return false;
         for (size_t i = 0; i < keys.length(); i++) {
             if (!cx->compartment->wrap(cx, &values[i]) ||
-                !DefineNativeProperty(cx, scobj, keys[i], values[i], NULL, NULL, 0, 0, 0))
+                !DefineNativeProperty(cx, env, keys[i], values[i], NULL, NULL, 0, 0, 0))
             {
                 return false;
             }
         }
     }
 
     /* Run the code and produce the completion value. */
     Value rval;
     JS::Anchor<JSString *> anchor(linearStr);
-    bool ok = EvaluateInScope(cx, scobj, fp, linearStr->chars(), linearStr->length(),
-                              "debugger eval code", 1, &rval);
+    bool ok = EvaluateInEnv(cx, env, fp, linearStr->chars(), linearStr->length(),
+                            "debugger eval code", 1, &rval);
     return dbg->newCompletionValue(ac, ok, rval, vp);
 }
 
 static JSBool
 DebuggerFrame_eval(JSContext *cx, uintN argc, Value *vp)
 {
     return DebuggerFrameEval(cx, argc, vp, WithoutBindings);
 }
@@ -2817,16 +2914,17 @@ DebuggerFrame_construct(JSContext *cx, u
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_CONSTRUCTOR, "Debugger.Frame");
     return false;
 }
 
 static JSPropertySpec DebuggerFrame_properties[] = {
     JS_PSG("arguments", DebuggerFrame_getArguments, 0),
     JS_PSG("callee", DebuggerFrame_getCallee, 0),
     JS_PSG("constructing", DebuggerFrame_getConstructing, 0),
+    JS_PSG("environment", DebuggerFrame_getEnvironment, 0),
     JS_PSG("generator", DebuggerFrame_getGenerator, 0),
     JS_PSG("live", DebuggerFrame_getLive, 0),
     JS_PSG("offset", DebuggerFrame_getOffset, 0),
     JS_PSG("older", DebuggerFrame_getOlder, 0),
     JS_PSG("script", DebuggerFrame_getScript, 0),
     JS_PSG("this", DebuggerFrame_getThis, 0),
     JS_PSG("type", DebuggerFrame_getType, 0),
     JS_PSGS("onStep", DebuggerFrame_getOnStep, DebuggerFrame_setOnStep, 0),
@@ -3009,34 +3107,51 @@ DebuggerObject_getParameterNames(JSConte
     return true;
 }
 
 static JSBool
 DebuggerObject_getScript(JSContext *cx, uintN argc, Value *vp)
 {
     THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "get script", args, dbg, obj);
 
-    args.rval().setUndefined();
-
-    if (!obj->isFunction())
+    if (!obj->isFunction()) {
+        args.rval().setUndefined();
         return true;
+    }
 
     JSFunction *fun = obj->toFunction();
-    if (!fun->isInterpreted())
+    if (!fun->isInterpreted()) {
+        args.rval().setUndefined();
         return true;
+    }
 
     JSObject *scriptObject = dbg->wrapScript(cx, fun->script());
     if (!scriptObject)
         return false;
 
     args.rval().setObject(*scriptObject);
     return true;
 }
 
 static JSBool
+DebuggerObject_getEnvironment(JSContext *cx, uintN argc, Value *vp)
+{
+    THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "get environment", args, dbg, obj);
+
+    /* Don't bother switching compartments just to check obj's type and get its env. */
+    if (!obj->isFunction() || !obj->toFunction()->isInterpreted()) {
+        args.rval().setUndefined();
+        return true;
+    }
+
+    Env *env = obj->toFunction()->environment();
+    return dbg->wrapEnvironment(cx, env, &args.rval());
+}
+
+static JSBool
 DebuggerObject_getOwnPropertyDescriptor(JSContext *cx, uintN argc, Value *vp)
 {
     THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "getOwnPropertyDescriptor", args, dbg, obj);
 
     jsid id;
     if (!ValueToId(cx, argc >= 1 ? args[0] : UndefinedValue(), &id))
         return false;
 
@@ -3441,16 +3556,17 @@ DebuggerObject_call(JSContext *cx, uintN
 
 static JSPropertySpec DebuggerObject_properties[] = {
     JS_PSG("proto", DebuggerObject_getProto, 0),
     JS_PSG("class", DebuggerObject_getClass, 0),
     JS_PSG("callable", DebuggerObject_getCallable, 0),
     JS_PSG("name", DebuggerObject_getName, 0),
     JS_PSG("parameterNames", DebuggerObject_getParameterNames, 0),
     JS_PSG("script", DebuggerObject_getScript, 0),
+    JS_PSG("environment", DebuggerObject_getEnvironment, 0),
     JS_PS_END
 };
 
 static JSFunctionSpec DebuggerObject_methods[] = {
     JS_FN("getOwnPropertyDescriptor", DebuggerObject_getOwnPropertyDescriptor, 1, 0),
     JS_FN("getOwnPropertyNames", DebuggerObject_getOwnPropertyNames, 0, 0),
     JS_FN("defineProperty", DebuggerObject_defineProperty, 2, 0),
     JS_FN("defineProperties", DebuggerObject_defineProperties, 1, 0),
@@ -3462,16 +3578,218 @@ static JSFunctionSpec DebuggerObject_met
     JS_FN("isFrozen", DebuggerObject_isFrozen, 0, 0),
     JS_FN("isExtensible", DebuggerObject_isExtensible, 0, 0),
     JS_FN("apply", DebuggerObject_apply, 0, 0),
     JS_FN("call", DebuggerObject_call, 0, 0),
     JS_FS_END
 };
 
 
+/*** Debugger.Environment ************************************************************************/
+
+static void
+DebuggerEnv_trace(JSTracer *trc, JSObject *obj)
+{
+    if (!trc->runtime->gcCurrentCompartment) {
+        /*
+         * There is a barrier on private pointers, so the Unbarriered marking
+         * is okay.
+         */
+        if (Env *referent = (JSObject *) obj->getPrivate())
+            MarkObjectUnbarriered(trc, referent, "Debugger.Environment referent");
+    }
+}
+
+Class DebuggerEnv_class = {
+    "Environment", JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGENV_COUNT),
+    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
+    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL,
+    NULL,                 /* reserved0   */
+    NULL,                 /* checkAccess */
+    NULL,                 /* call        */
+    NULL,                 /* construct   */
+    NULL,                 /* xdrObject   */
+    NULL,                 /* hasInstance */
+    DebuggerEnv_trace
+};
+
+static JSObject *
+DebuggerEnv_checkThis(JSContext *cx, const CallArgs &args, const char *fnname)
+{
+    if (!args.thisv().isObject()) {
+        ReportObjectRequired(cx);
+        return NULL;
+    }
+    JSObject *thisobj = &args.thisv().toObject();
+    if (thisobj->getClass() != &DebuggerEnv_class) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,
+                             "Debugger.Environment", fnname, thisobj->getClass()->name);
+        return NULL;
+    }
+
+    /*
+     * Forbid Debugger.Environment.prototype, which is of class DebuggerEnv_class
+     * but isn't a real working Debugger.Environment. The prototype object is
+     * distinguished by having no referent.
+     */
+    if (!thisobj->getPrivate()) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,
+                             "Debugger.Environment", fnname, "prototype object");
+        return NULL;
+    }
+    return thisobj;
+}
+
+#define THIS_DEBUGENV(cx, argc, vp, fnname, args, envobj, env)                \
+    CallArgs args = CallArgsFromVp(argc, vp);                                 \
+    JSObject *envobj = DebuggerEnv_checkThis(cx, args, fnname);               \
+    if (!envobj)                                                              \
+        return false;                                                         \
+    Env *env = static_cast<Env *>(envobj->getPrivate());                      \
+    JS_ASSERT(env)
+
+#define THIS_DEBUGENV_OWNER(cx, argc, vp, fnname, args, envobj, env, dbg)     \
+    THIS_DEBUGENV(cx, argc, vp, fnname, args, envobj, env);                   \
+    Debugger *dbg = Debugger::fromChildJSObject(envobj)
+
+static JSBool
+DebuggerEnv_construct(JSContext *cx, uintN argc, Value *vp)
+{
+    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_CONSTRUCTOR, "Debugger.Environment");
+    return false;
+}
+
+static JSBool
+DebuggerEnv_getType(JSContext *cx, uintN argc, Value *vp)
+{
+    THIS_DEBUGENV(cx, argc, vp, "get type", args, envobj, env);
+
+    /* Don't bother switching compartments just to check env's class. */
+    const char *s;
+    if (env->isCall() || env->isBlock() || env->isDeclEnv())
+        s = "declarative";
+    else
+        s = "object";
+
+    JSAtom *str = js_Atomize(cx, s, strlen(s), InternAtom, NormalEncoding);
+    if (!str)
+        return false;
+    args.rval().setString(str);
+    return true;
+}
+
+static JSBool
+DebuggerEnv_getParent(JSContext *cx, uintN argc, Value *vp)
+{
+    THIS_DEBUGENV_OWNER(cx, argc, vp, "get parent", args, envobj, env, dbg);
+
+    /* Don't bother switching compartments just to get env's parent. */
+    Env *parent = env->scopeChain();
+    return dbg->wrapEnvironment(cx, parent, &args.rval());
+}
+
+static JSBool
+DebuggerEnv_getObject(JSContext *cx, uintN argc, Value *vp)
+{
+    THIS_DEBUGENV_OWNER(cx, argc, vp, "get type", args, envobj, env, dbg);
+
+    /*
+     * Don't bother switching compartments just to check env's class and
+     * possibly get its proto.
+     */
+    if (env->isCall() || env->isBlock() || env->isDeclEnv()) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_DEBUG_NO_SCOPE_OBJECT);
+        return false;
+    }
+    JSObject *obj = env->isWith() ? env->getProto() : env;
+
+    Value rval = ObjectValue(*obj);
+    if (!dbg->wrapDebuggeeValue(cx, &rval))
+        return false;
+    args.rval() = rval;
+    return true;
+}
+
+static JSBool
+DebuggerEnv_names(JSContext *cx, uintN argc, Value *vp)
+{
+    THIS_DEBUGENV_OWNER(cx, argc, vp, "get type", args, envobj, env, dbg);
+
+    AutoIdVector keys(cx);
+    {
+        AutoCompartment ac(cx, env);
+        if (!ac.enter())
+            return false;
+
+        ErrorCopier ec(ac, dbg->toJSObject());
+        if (!GetPropertyNames(cx, env, JSITER_HIDDEN, &keys))
+            return false;
+    }
+
+    JSObject *arr = NewDenseEmptyArray(cx);
+    if (!arr)
+        return false;
+    for (size_t i = 0, len = keys.length(); i < len; i++) {
+         jsid id = keys[i];
+         if (JSID_IS_ATOM(id) && IsIdentifier(JSID_TO_ATOM(id))) {
+             if (!cx->compartment->wrapId(cx, &id))
+                 return false;
+             if (!js_NewbornArrayPush(cx, arr, StringValue(JSID_TO_STRING(id))))
+                 return false;
+         }
+    }
+    args.rval().setObject(*arr);
+    return true;
+}
+
+static JSBool
+DebuggerEnv_find(JSContext *cx, uintN argc, Value *vp)
+{
+    REQUIRE_ARGC("Debugger.Environment.find", 1);
+    THIS_DEBUGENV_OWNER(cx, argc, vp, "get type", args, envobj, env, dbg);
+
+    jsid id;
+    if (!ValueToIdentifier(cx, args[0], &id))
+        return false;
+
+    {
+        AutoCompartment ac(cx, env);
+        if (!ac.enter() || !cx->compartment->wrapId(cx, &id))
+            return false;
+
+        /* This can trigger resolve hooks. */
+        ErrorCopier ec(ac, dbg->toJSObject());
+        JSProperty *prop = NULL;
+        JSObject *pobj;
+        for (; env && !prop; env = env->scopeChain()) {
+            if (!env->lookupGeneric(cx, id, &pobj, &prop))
+                return false;
+            if (prop)
+                break;
+        }
+    }
+
+    return dbg->wrapEnvironment(cx, env, &args.rval());
+}
+
+static JSPropertySpec DebuggerEnv_properties[] = {
+    JS_PSG("type", DebuggerEnv_getType, 0),
+    JS_PSG("object", DebuggerEnv_getObject, 0),
+    JS_PSG("parent", DebuggerEnv_getParent, 0),
+    JS_PS_END
+};
+
+static JSFunctionSpec DebuggerEnv_methods[] = {
+    JS_FN("names", DebuggerEnv_names, 0, 0),
+    JS_FN("find", DebuggerEnv_find, 1, 0),
+    JS_FS_END
+};
+
+
+
 /*** Glue ****************************************************************************************/
 
 extern JS_PUBLIC_API(JSBool)
 JS_DefineDebuggerObject(JSContext *cx, JSObject *obj)
 {
     JSObject *objProto;
     if (!js_GetClassPrototype(cx, obj, JSProto_Object, &objProto))
         return false;
@@ -3499,13 +3817,21 @@ JS_DefineDebuggerObject(JSContext *cx, J
 
     JSObject *objectProto = js_InitClass(cx, debugCtor, objProto, &DebuggerObject_class,
                                          DebuggerObject_construct, 0,
                                          DebuggerObject_properties, DebuggerObject_methods,
                                          NULL, NULL);
     if (!objectProto)
         return false;
 
+    JSObject *envProto = js_InitClass(cx, debugCtor, objProto, &DebuggerEnv_class,
+                                      DebuggerEnv_construct, 0,
+                                      DebuggerEnv_properties, DebuggerEnv_methods,
+                                      NULL, NULL);
+    if (!envProto)
+        return false;
+
     debugProto->setReservedSlot(Debugger::JSSLOT_DEBUG_FRAME_PROTO, ObjectValue(*frameProto));
     debugProto->setReservedSlot(Debugger::JSSLOT_DEBUG_OBJECT_PROTO, ObjectValue(*objectProto));
     debugProto->setReservedSlot(Debugger::JSSLOT_DEBUG_SCRIPT_PROTO, ObjectValue(*scriptProto));
+    debugProto->setReservedSlot(Debugger::JSSLOT_DEBUG_ENV_PROTO, ObjectValue(*envProto));
     return true;
 }
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -67,16 +67,17 @@ class Debugger {
         OnNewScript,
         OnEnterFrame,
         HookCount
     };
 
     enum {
         JSSLOT_DEBUG_PROTO_START,
         JSSLOT_DEBUG_FRAME_PROTO = JSSLOT_DEBUG_PROTO_START,
+        JSSLOT_DEBUG_ENV_PROTO,
         JSSLOT_DEBUG_OBJECT_PROTO,
         JSSLOT_DEBUG_SCRIPT_PROTO,
         JSSLOT_DEBUG_PROTO_STOP,
         JSSLOT_DEBUG_HOOK_START = JSSLOT_DEBUG_PROTO_STOP,
         JSSLOT_DEBUG_HOOK_STOP = JSSLOT_DEBUG_HOOK_START + HookCount,
         JSSLOT_DEBUG_COUNT = JSSLOT_DEBUG_HOOK_STOP
     };
 
@@ -100,23 +101,26 @@ class Debugger {
      * thus necessarily live), but we do trace the values. It's like a WeakMap
      * that way, but since stack frames are not gc-things, the implementation
      * has to be different.
      */
     typedef HashMap<StackFrame *, HeapPtrObject, DefaultHasher<StackFrame *>, RuntimeAllocPolicy>
         FrameMap;
     FrameMap frames;
 
+    /* An ephemeral map from JSScript* to Debugger.Script instances. */
+    typedef WeakMap<HeapPtrScript, HeapPtrObject> ScriptWeakMap;
+    ScriptWeakMap scripts;
+
     /* The map from debuggee objects to their Debugger.Object instances. */
     typedef WeakMap<HeapPtrObject, HeapPtrObject> ObjectWeakMap;
     ObjectWeakMap objects;
 
-    /* An ephemeral map from JSScript* to Debugger.Script instances. */
-    typedef WeakMap<HeapPtrScript, HeapPtrObject> ScriptWeakMap;
-    ScriptWeakMap scripts;
+    /* The map from debuggee Envs to Debugger.Environment instances. */
+    ObjectWeakMap environments;
 
     bool addDebuggeeGlobal(JSContext *cx, GlobalObject *obj);
     void removeDebuggeeGlobal(JSContext *cx, GlobalObject *global,
                               GlobalObjectSet::Enum *compartmentEnum,
                               GlobalObjectSet::Enum *debugEnum);
 
     /*
      * Cope with an error or exception in a debugger hook.
@@ -268,16 +272,23 @@ class Debugger {
     /************************************* Functions for use by Debugger.cpp. */
 
     inline bool observesEnterFrame() const;
     inline bool observesNewScript() const;
     inline bool observesGlobal(GlobalObject *global) const;
     inline bool observesFrame(StackFrame *fp) const;
 
     /*
+     * If env is NULL, call vp->setNull() and return true. Otherwise, find or
+     * create a Debugger.Environment object for the given Env. On success,
+     * store the Environment object in *vp and return true.
+     */
+    bool wrapEnvironment(JSContext *cx, Env *env, Value *vp);
+
+    /*
      * Like cx->compartment->wrap(cx, vp), but for the debugger compartment.
      *
      * Preconditions: *vp is a value from a debuggee compartment; cx is in the
      * debugger's compartment.
      *
      * If *vp is an object, this produces a (new or existing) Debugger.Object
      * wrapper for it. Otherwise this is the same as JSCompartment::wrap.
      */
@@ -513,14 +524,14 @@ Debugger::onNewScript(JSContext *cx, JSS
 {
     JS_ASSERT_IF(script->compileAndGo, compileAndGoGlobal);
     JS_ASSERT_IF(!script->compileAndGo, !compileAndGoGlobal);
     if (!script->compartment()->getDebuggees().empty())
         slowPathOnNewScript(cx, script, compileAndGoGlobal);
 }
 
 extern JSBool
-EvaluateInScope(JSContext *cx, JSObject *scobj, StackFrame *fp, const jschar *chars,
-                uintN length, const char *filename, uintN lineno, Value *rval);
+EvaluateInEnv(JSContext *cx, Env *env, StackFrame *fp, const jschar *chars,
+              uintN length, const char *filename, uintN lineno, Value *rval);
 
 }
 
 #endif /* Debugger_h__ */
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -45,16 +45,17 @@
 #include "nsSubDocumentFrame.h"
 #include "nsCSSRendering.h"
 #include "nsCSSFrameConstructor.h"
 #include "gfxUtils.h"
 #include "nsImageFrame.h"
 #include "nsRenderingContext.h"
 
 #include "mozilla/Preferences.h"
+#include "sampler.h"
 
 #ifdef DEBUG
 #include <stdio.h>
 #endif
 
 using namespace mozilla::layers;
 
 namespace mozilla {
@@ -2009,16 +2010,18 @@ FrameLayerBuilder::GetDedicatedLayer(nsI
 
 /* static */ void
 FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer,
                                    gfxContext* aContext,
                                    const nsIntRegion& aRegionToDraw,
                                    const nsIntRegion& aRegionToInvalidate,
                                    void* aCallbackData)
 {
+  SAMPLE_LABEL("gfx", "DrawThebesLayer");
+
   nsDisplayListBuilder* builder = static_cast<nsDisplayListBuilder*>
     (aCallbackData);
 
   if (builder->LayerBuilder()->CheckDOMModified())
     return;
 
   nsTArray<ClippedDisplayItem> items;
   nsIFrame* containerLayerFrame;
--- a/layout/base/RestyleTracker.cpp
+++ b/layout/base/RestyleTracker.cpp
@@ -39,16 +39,17 @@
 /**
  * A class which manages pending restyles.  This handles keeping track
  * of what nodes restyles need to happen on and so forth.
  */
 
 #include "RestyleTracker.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsStyleChangeList.h"
+#include "sampler.h"
 
 namespace mozilla {
 namespace css {
 
 inline nsIDocument*
 RestyleTracker::Document() const {
   return mFrameConstructor->mDocument;
 }
@@ -162,16 +163,17 @@ RestyleTracker::ProcessOneRestyle(Elemen
     changeList.AppendChange(primaryFrame, aElement, aChangeHint);
     mFrameConstructor->ProcessRestyledFrames(changeList);
   }
 }
 
 void
 RestyleTracker::ProcessRestyles()
 {
+  SAMPLE_LABEL("CSS", "ProcessRestyles");
   // Make sure to not rebuild quote or counter lists while we're
   // processing restyles
   mFrameConstructor->BeginUpdate();
 
   mFrameConstructor->mInStyleRefresh = true;
 
   // loop so that we process any restyle events generated by processing
   while (mPendingRestyles.Count()) {
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -198,16 +198,17 @@
 // Content viewer interfaces
 #include "nsIContentViewer.h"
 #include "imgIEncoder.h"
 #include "gfxPlatform.h"
 
 #include "mozilla/FunctionTimer.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
+#include "sampler.h"
 
 #include "Layers.h"
 #include "nsPLDOMEvent.h"
 
 #ifdef NS_FUNCTION_TIMER
 #define NS_TIME_FUNCTION_DECLARE_DOCURL                \
   nsCAutoString docURL__("N/A");                       \
   nsIURI *uri__ = mDocument->GetDocumentURI();         \
@@ -3969,16 +3970,17 @@ PresShell::FlushPendingNotifications(moz
     "Flush_Styles",
     "Flush_InterruptibleLayout",
     "Flush_Layout",
     "Flush_Display"
   };
   NS_TIME_FUNCTION_MIN_FMT(1.0, "%s (line %d) (document: %s, type: %s)", MOZ_FUNCTION_NAME,
                            __LINE__, docURL__.get(), flushTypeNames[aType - 1]);
 #endif
+  SAMPLE_LABEL("layout", "FlushPendingNotifications");
 
 #ifdef ACCESSIBILITY
 #ifdef DEBUG
   nsAccessibilityService* accService = GetAccService();
   if (accService) {
     NS_ASSERTION(!accService->IsProcessingRefreshDriverNotification(),
                  "Flush during accessible tree update!");
   }
@@ -5416,16 +5418,17 @@ PresShell::Paint(nsIView*           aVie
   NS_TIME_FUNCTION_MIN_FMT(1.0, "%s (line %d) (document: %s, dirty rect: (<%f, %f>, <%f, %f>)",
                            MOZ_FUNCTION_NAME, __LINE__, docURL__.get(),
                            NSCoordToFloat(bounds__.x),
                            NSCoordToFloat(bounds__.y),
                            NSCoordToFloat(bounds__.XMost()),
                            NSCoordToFloat(bounds__.YMost()));
 #endif
 
+  SAMPLE_LABEL("Paint", "PresShell::Paint");
   NS_ASSERTION(!mIsDestroying, "painting a destroyed PresShell");
   NS_ASSERTION(aViewToPaint, "null view");
   NS_ASSERTION(aWidgetToPaint, "Can't paint without a widget");
 
   nsPresContext* presContext = GetPresContext();
   AUTO_LAYOUT_PHASE_ENTRY_POINT(presContext, Paint);
 
   nsIFrame* frame = aPaintDefaultBackground ? nsnull : aViewToPaint->GetFrame();
@@ -7198,16 +7201,17 @@ PresShell::ScheduleReflowOffTimer()
   }
   return true;
 }
 
 bool
 PresShell::DoReflow(nsIFrame* target, bool aInterruptible)
 {
   NS_TIME_FUNCTION_WITH_DOCURL;
+  SAMPLE_LABEL("layout", "DoReflow");
 
   if (mReflowContinueTimer) {
     mReflowContinueTimer->Cancel();
     mReflowContinueTimer = nsnull;
   }
 
   nsIFrame* rootFrame = FrameManager()->GetRootFrame();
 
--- a/layout/reftests/canvas/reftest.list
+++ b/layout/reftests/canvas/reftest.list
@@ -33,16 +33,17 @@ asserts-if(cocoaWidget,0-2) == size-chan
 == text-font-inherit.html text-big-fill.html
 == text-space-replace-test.html text-space-replace-ref.html
 
 == text-no-frame-test.html text-no-frame-ref.html
 == text-no-frame-2-test.html text-not-in-doc-ref.html
 == text-not-in-doc-test.html text-not-in-doc-ref.html
 
 == text-bidi-ltr-test.html text-bidi-ltr-ref.html
+!= text-bidi-ltr-test.html text-bidi-ltr-notref.html # for bug 698185
 == text-bidi-rtl-test.html text-bidi-rtl-ref.html
 
 fails-if(Android) != text-font-lang.html text-font-lang-notref.html
 
 == text-measure.html text-measure-ref.html
 
 == strokeText-path.html strokeText-path-ref.html
 
copy from layout/reftests/canvas/text-bidi-ltr-test.html
copy to layout/reftests/canvas/text-bidi-ltr-notref.html
--- a/layout/reftests/canvas/text-bidi-ltr-test.html
+++ b/layout/reftests/canvas/text-bidi-ltr-notref.html
@@ -4,17 +4,19 @@
 <title>Test to ensure bidi is resolved correctly</title>
 </head>
 <body>
 <canvas id="c" width="256" height="64" style="direction:ltr"></canvas>
 <script type="text/javascript">
   var canvas = document.getElementById('c');
   var ctx = canvas.getContext('2d');
 
-  var str = "hello\u05E9\u05DC\u05D5\u05DDgoodbye";
+  // Bug 698185 caused the RTL and trailing LTR runs to be lost
+  // var str = "hello\u05E9\u05DC\u05D5\u05DDgoodbye";
+  var str = "hello";
 
   ctx.fillStyle = 'black';
   ctx.font = '10px sans-serif';
   ctx.fillText(str, 128, 32);
 
 </script>
 </body>
 </html>
--- a/layout/reftests/forms/reftest.list
+++ b/layout/reftests/forms/reftest.list
@@ -5,16 +5,26 @@ fails-if(Android) == checkbox-radio-stre
 == input-file-width-clip-1.html input-file-width-clip-ref.html # test for bug 409587
 == input-hidden-border.html about:blank
 == input-text-size-1.html input-text-size-1-ref.html
 fails-if(Android) == input-text-size-2.html input-text-size-2-ref.html
 HTTP(..) == input-text-baseline-1.html input-text-baseline-1-ref.html
 HTTP(..) == input-text-centering-1.xul input-text-centering-1-ref.xul
 fails-if(Android) HTTP(..) == text-control-baseline-1.html text-control-baseline-1-ref.html
 == input-text-dynamic-height-1.xul input-text-dynamic-height-1-ref.xul
+
+# access-key tests are no use on OS X because access keys are not indicated visually
+skip-if(cocoaWidget) != textbox-accesskey-1.xul textbox-accesskey-1-notref.xul
+skip-if(cocoaWidget) == textbox-accesskey-2.xul textbox-accesskey-2-ref.xul
+# textbox-accesskey-3 fails because of defects in XUL bidi support
+skip-if(cocoaWidget) fails-if(!cocoaWidget) == textbox-accesskey-3.xul textbox-accesskey-3-ref.xul
+skip-if(cocoaWidget) != textbox-accesskey-3.xul textbox-accesskey-3-notref.xul
+skip-if(cocoaWidget) == textbox-accesskey-4.xul textbox-accesskey-4-ref.xul
+skip-if(cocoaWidget) != textbox-accesskey-4.xul textbox-accesskey-4-notref.xul
+
 == textbox-align-baseline-1.xul textbox-align-baseline-1-ref.xul # test for bug 494901
 fails-if(Android) == textbox-setsize.xul textbox-setsize-ref.xul
 fails-if(Android) == textarea-resize.html textarea-resize-ref.html
 # an offset seems to apply to the native resizer on windows so skip this test for now
 fails-if(Android) skip-if(winWidget) == textarea-resize-background.html textarea-resize-background-ref.html
 fails-if(Android) != textarea-ltr.html textarea-rtl.html
 fails-if(Android) != textarea-ltr-scrollbar.html textarea-rtl-scrollbar.html
 fails-if(Android) != textarea-in-ltr-doc-scrollbar.html textarea-in-rtl-doc-scrollbar.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/textbox-accesskey-1-notref.xul
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin/"?>
+<window title="textbox access key tests (see bug 698185)"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+	xmlns:html="http://www.w3.org/1999/xhtml">
+  <html:style type="text/css">
+    hbox {
+      margin-top: 0px;
+      padding-top: 0px;
+      font-size: 36px;
+    }
+    label, textbox {
+      -moz-appearance: none;
+      background: inherit;
+      border: none 0px;
+    }
+    label {
+      margin-top: 0px;
+      padding-top: 0px;
+      margin-bottom: 0px;
+      padding-bottom: 0px;
+    }
+    textbox {
+      margin-top: 12px;
+      padding-top: 8px;
+      margin-bottom: 5px;
+      padding-bottom: 9px;
+    }
+  </html:style>
+
+  <hbox align="baseline">
+    <label value="test"/>
+    <textbox value="text"/>
+  </hbox>
+</window>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/textbox-accesskey-1.xul
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin/"?>
+<window title="textbox access key tests (see bug 698185)"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+	xmlns:html="http://www.w3.org/1999/xhtml">
+  <html:style type="text/css">
+    hbox {
+      margin-top: 0px;
+      padding-top: 0px;
+      font-size: 36px;
+    }
+    label, textbox {
+      -moz-appearance: none;
+      background: inherit;
+      border: none 0px;
+    }
+    label {
+      margin-top: 0px;
+      padding-top: 0px;
+      margin-bottom: 0px;
+      padding-bottom: 0px;
+    }
+    textbox {
+      margin-top: 12px;
+      padding-top: 8px;
+      margin-bottom: 5px;
+      padding-bottom: 9px;
+    }
+  </html:style>
+
+  <hbox align="baseline">
+    <label value="test" accesskey="s"/>
+    <textbox value="text"/>
+  </hbox>
+</window>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/textbox-accesskey-2-ref.xul
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin/"?>
+<window title="textbox access key tests (see bug 698185)"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+	xmlns:html="http://www.w3.org/1999/xhtml">
+  <html:style type="text/css">
+    hbox {
+      margin-top: 0px;
+      padding-top: 0px;
+      font-size: 36px;
+    }
+    label, textbox {
+      -moz-appearance: none;
+      background: inherit;
+      border: none 0px;
+    }
+    label {
+      margin-top: 0px;
+      padding-top: 0px;
+      margin-bottom: 0px;
+      padding-bottom: 0px;
+    }
+    textbox {
+      margin-top: 12px;
+      padding-top: 8px;
+      margin-bottom: 5px;
+      padding-bottom: 9px;
+    }
+  </html:style>
+
+  <hbox align="baseline">
+    <!-- access key in LTR-overridden Arabic text -->
+    <label value="&#x202d;&#x64a;&#x628;&#x631;&#x639;&#x644;&#x627;&#x202c; test" accesskey="&#x639;"/>
+    <textbox value=""/>
+  </hbox>
+</window>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/textbox-accesskey-2.xul
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin/"?>
+<window title="textbox access key tests (see bug 698185)"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+	xmlns:html="http://www.w3.org/1999/xhtml">
+  <html:style type="text/css">
+    hbox {
+      margin-top: 0px;
+      padding-top: 0px;
+      font-size: 36px;
+    }
+    label, textbox {
+      -moz-appearance: none;
+      background: inherit;
+      border: none 0px;
+    }
+    label {
+      margin-top: 0px;
+      padding-top: 0px;
+      margin-bottom: 0px;
+      padding-bottom: 0px;
+    }
+    textbox {
+      margin-top: 12px;
+      padding-top: 8px;
+      margin-bottom: 5px;
+      padding-bottom: 9px;
+    }
+  </html:style>
+
+  <hbox align="baseline">
+    <!-- access key in RTL Arabic text -->
+    <label value="&#x627;&#x644;&#x639;&#x631;&#x628;&#x64a; test" accesskey="&#x639;"/>
+    <textbox value=""/>
+  </hbox>
+</window>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/textbox-accesskey-3-notref.xul
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin/"?>
+<window title="textbox access key tests (see bug 698185)"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+	xmlns:html="http://www.w3.org/1999/xhtml">
+  <html:style type="text/css">
+    hbox {
+      margin-top: 0px;
+      padding-top: 0px;
+      font-size: 36px;
+    }
+    label, textbox {
+      -moz-appearance: none;
+      background: inherit;
+      border: none 0px;
+    }
+    label {
+      margin-top: 0px;
+      padding-top: 0px;
+      margin-bottom: 0px;
+      padding-bottom: 0px;
+    }
+    textbox {
+      margin-top: 12px;
+      padding-top: 8px;
+      margin-bottom: 5px;
+      padding-bottom: 9px;
+    }
+  </html:style>
+
+  <hbox align="baseline">
+    <!-- no access key, for != test -->
+    <label value="&#x627;&#x644;&#x639;&#x631;&#x628;&#x64a; hello world"/>
+    <textbox value=""/>
+  </hbox>
+</window>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/textbox-accesskey-3-ref.xul
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin/"?>
+<window title="textbox access key tests (see bug 698185)"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+	xmlns:html="http://www.w3.org/1999/xhtml">
+  <html:style type="text/css">
+    hbox {
+      margin-top: 0px;
+      padding-top: 0px;
+      font-size: 36px;
+    }
+    label, textbox {
+      -moz-appearance: none;
+      background: inherit;
+      border: none 0px;
+    }
+    label {
+      margin-top: 0px;
+      padding-top: 0px;
+      margin-bottom: 0px;
+      padding-bottom: 0px;
+    }
+    textbox {
+      margin-top: 12px;
+      padding-top: 8px;
+      margin-bottom: 5px;
+      padding-bottom: 9px;
+    }
+  </html:style>
+
+  <hbox align="baseline">
+    <!-- access key in LTR text that follows RTL text (mixed direction) -->
+    <label value="&#x627;&#x644;&#x639;&#x631;&#x628;&#x64a; hello world" accesskey="d"/>
+    <textbox value=""/>
+  </hbox>
+</window>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/textbox-accesskey-3.xul
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin/"?>
+<window title="textbox access key tests (see bug 698185)"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+	xmlns:html="http://www.w3.org/1999/xhtml">
+  <html:style type="text/css">
+    hbox {
+      margin-top: 0px;
+      padding-top: 0px;
+      font-size: 36px;
+    }
+    label, textbox {
+      -moz-appearance: none;
+      background: inherit;
+      border: none 0px;
+    }
+    label {
+      margin-top: 0px;
+      padding-top: 0px;
+      margin-bottom: 0px;
+      padding-bottom: 0px;
+    }
+    textbox {
+      margin-top: 12px;
+      padding-top: 8px;
+      margin-bottom: 5px;
+      padding-bottom: 9px;
+    }
+  </html:style>
+
+  <hbox align="baseline">
+    <!-- access key in RTL-overridden English text -->
+    <label value="&#x627;&#x644;&#x639;&#x631;&#x628;&#x64a; hello &#x202e;dlrow&#x202c;" accesskey="d"/>
+    <textbox value=""/>
+  </hbox>
+</window>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/textbox-accesskey-4-notref.xul
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin/"?>
+<window title="textbox access key tests (see bug 698185)"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+	xmlns:html="http://www.w3.org/1999/xhtml">
+  <html:style type="text/css">
+    hbox {
+      margin-top: 0px;
+      padding-top: 0px;
+      font-size: 36px;
+    }
+    label, textbox {
+      -moz-appearance: none;
+      background: inherit;
+      border: none 0px;
+    }
+    label {
+      margin-top: 0px;
+      padding-top: 0px;
+      margin-bottom: 0px;
+      padding-bottom: 0px;
+    }
+    textbox {
+      margin-top: 12px;
+      padding-top: 8px;
+      margin-bottom: 5px;
+      padding-bottom: 9px;
+    }
+  </html:style>
+
+  <hbox align="baseline">
+    <!-- no access key, for != test -->
+    <label value="&#x627;&#x644;&#x639;&#x631;&#x628;&#x64a; hello world"/>
+    <textbox value=""/>
+  </hbox>
+</window>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/textbox-accesskey-4-ref.xul
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin/"?>
+<window title="textbox access key tests (see bug 698185)"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+	xmlns:html="http://www.w3.org/1999/xhtml">
+  <html:style type="text/css">
+    hbox {
+      margin-top: 0px;
+      padding-top: 0px;
+      font-size: 36px;
+    }
+    label, textbox {
+      -moz-appearance: none;
+      background: inherit;
+      border: none 0px;
+    }
+    label {
+      margin-top: 0px;
+      padding-top: 0px;
+      margin-bottom: 0px;
+      padding-bottom: 0px;
+    }
+    textbox {
+      margin-top: 12px;
+      padding-top: 8px;
+      margin-bottom: 5px;
+      padding-bottom: 9px;
+    }
+  </html:style>
+
+  <hbox align="baseline">
+    <!-- access key in English text following LTR-overridden Arabic -->
+    <label value="&#x202d;&#x64a;&#x628;&#x631;&#x639;&#x644;&#x627;&#x202c; hello world" accesskey="w"/>
+    <textbox value=""/>
+  </hbox>
+</window>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/forms/textbox-accesskey-4.xul
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin/"?>
+<window title="textbox access key tests (see bug 698185)"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+	xmlns:html="http://www.w3.org/1999/xhtml">
+  <html:style type="text/css">
+    hbox {
+      margin-top: 0px;
+      padding-top: 0px;
+      font-size: 36px;
+    }
+    label, textbox {
+      -moz-appearance: none;
+      background: inherit;
+      border: none 0px;
+    }
+    label {
+      margin-top: 0px;
+      padding-top: 0px;
+      margin-bottom: 0px;
+      padding-bottom: 0px;
+    }
+    textbox {
+      margin-top: 12px;
+      padding-top: 8px;
+      margin-bottom: 5px;
+      padding-bottom: 9px;
+    }
+  </html:style>
+
+  <hbox align="baseline">
+    <!-- access key in English text following RTL Arabic -->
+    <label value="&#x627;&#x644;&#x639;&#x631;&#x628;&#x64a; hello world" accesskey="w"/>
+    <textbox value=""/>
+  </hbox>
+</window>
--- a/media/libvpx/Makefile.in
+++ b/media/libvpx/Makefile.in
@@ -523,12 +523,13 @@ else
 endif
 
 endif
 
 # Workaround a bug of Sun Studio (CR 6963410)
 ifdef SOLARIS_SUNPRO_CC
 ifeq (86,$(findstring 86,$(OS_TEST)))
 filter.o: filter.c Makefile.in
+	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
 	$(CC) -o $@ -c $(patsubst -xO[45],-xO3,$(COMPILE_CFLAGS)) $<
 endif
 endif
new file mode 100644
--- /dev/null
+++ b/media/libvpx/stdint.patch
@@ -0,0 +1,43 @@
+diff --git a/media/libvpx/stdint.patch b/media/libvpx/stdint.patch
+new file mode 100644
+diff --git a/media/libvpx/vpx/vpx_integer.h b/media/libvpx/vpx/vpx_integer.h
+--- a/media/libvpx/vpx/vpx_integer.h
++++ b/media/libvpx/vpx/vpx_integer.h
+@@ -10,16 +10,18 @@
+ 
+ 
+ #ifndef VPX_INTEGER_H
+ #define VPX_INTEGER_H
+ 
+ /* get ptrdiff_t, size_t, wchar_t, NULL */
+ #include <stddef.h>
+ 
++#if !defined(VPX_DONT_DEFINE_STDINT_TYPES)
++
+ #if (defined(_MSC_VER) && (_MSC_VER < 1600)) || defined(VPX_EMULATE_INTTYPES)
+ typedef signed char  int8_t;
+ typedef signed short int16_t;
+ typedef signed int   int32_t;
+ 
+ typedef unsigned char  uint8_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int   uint32_t;
+@@ -47,16 +49,18 @@ typedef unsigned int   uintptr_t;
+ 
+ #if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS)
+ #define __STDC_FORMAT_MACROS
+ #endif
+ #include <stdint.h>
+ 
+ #endif
+ 
++#endif
++
+ /* VS2010 defines stdint.h, but not inttypes.h */
+ #if defined(_MSC_VER)
+ #define PRId64 "I64d"
+ #else
+ #include <inttypes.h>
+ #endif
+ 
+ #endif
--- a/media/libvpx/update.sh
+++ b/media/libvpx/update.sh
@@ -436,8 +436,11 @@ done
 # Patch to compile with Sun Studio on Solaris
 patch -p3 < solaris.patch
 
 # Patch to fix errors including C headers in C++
 patch -p3 < compile_errors.patch
 
 # Patch to fix MV clamping in the v0.9.7-p1 release.
 patch -p3 < bug696390.patch
+
+# Patch to permit vpx users to specify their own <stdint.h> types.
+patch -p3 < stdint.patch
--- a/media/libvpx/vpx/vpx_integer.h
+++ b/media/libvpx/vpx/vpx_integer.h
@@ -10,16 +10,18 @@
 
 
 #ifndef VPX_INTEGER_H
 #define VPX_INTEGER_H
 
 /* get ptrdiff_t, size_t, wchar_t, NULL */
 #include <stddef.h>
 
+#if !defined(VPX_DONT_DEFINE_STDINT_TYPES)
+
 #if (defined(_MSC_VER) && (_MSC_VER < 1600)) || defined(VPX_EMULATE_INTTYPES)
 typedef signed char  int8_t;
 typedef signed short int16_t;
 typedef signed int   int32_t;
 
 typedef unsigned char  uint8_t;
 typedef unsigned short uint16_t;
 typedef unsigned int   uint32_t;
@@ -47,16 +49,18 @@ typedef unsigned int   uintptr_t;
 
 #if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS)
 #define __STDC_FORMAT_MACROS
 #endif
 #include <stdint.h>
 
 #endif
 
+#endif
+
 /* VS2010 defines stdint.h, but not inttypes.h */
 #if defined(_MSC_VER)
 #define PRId64 "I64d"
 #else
 #include <inttypes.h>
 #endif
 
 #endif
new file mode 100644
--- /dev/null
+++ b/mfbt/MSStdInt.h
@@ -0,0 +1,247 @@
+// ISO C9x  compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
+// 
+//  Copyright (c) 2006-2008 Alexander Chemeris
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+//   1. Redistributions of source code must retain the above copyright notice,
+//      this list of conditions and the following disclaimer.
+// 
+//   2. Redistributions in binary form must reproduce the above copyright
+//      notice, this list of conditions and the following disclaimer in the
+//      documentation and/or other materials provided with the distribution.
+// 
+//   3. The name of the author may be used to endorse or promote products
+//      derived from this software without specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// 
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include <limits.h>
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler give many errors like this:
+//   error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+#  include <wchar.h>
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+#  if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+#     define _W64 __w64
+#  else
+#     define _W64
+#  endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+   typedef signed char       int8_t;
+   typedef signed short      int16_t;
+   typedef signed int        int32_t;
+   typedef unsigned char     uint8_t;
+   typedef unsigned short    uint16_t;
+   typedef unsigned int      uint32_t;
+#else
+   typedef signed __int8     int8_t;
+   typedef signed __int16    int16_t;
+   typedef signed __int32    int32_t;
+   typedef unsigned __int8   uint8_t;
+   typedef unsigned __int16  uint16_t;
+   typedef unsigned __int32  uint32_t;
+#endif
+typedef signed __int64       int64_t;
+typedef unsigned __int64     uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t    int_least8_t;
+typedef int16_t   int_least16_t;
+typedef int32_t   int_least32_t;
+typedef int64_t   int_least64_t;
+typedef uint8_t   uint_least8_t;
+typedef uint16_t  uint_least16_t;
+typedef uint32_t  uint_least32_t;
+typedef uint64_t  uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t    int_fast8_t;
+typedef int32_t   int_fast16_t;
+typedef int32_t   int_fast32_t;
+typedef int64_t   int_fast64_t;
+typedef uint8_t   uint_fast8_t;
+typedef uint32_t  uint_fast16_t;
+typedef uint32_t  uint_fast32_t;
+typedef uint64_t  uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+   typedef signed __int64    intptr_t;
+   typedef unsigned __int64  uintptr_t;
+#else // _WIN64 ][
+   typedef _W64 signed int   intptr_t;
+   typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t   intmax_t;
+typedef uint64_t  uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [   See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN     ((int8_t)_I8_MIN)
+#define INT8_MAX     _I8_MAX
+#define INT16_MIN    ((int16_t)_I16_MIN)
+#define INT16_MAX    _I16_MAX
+#define INT32_MIN    ((int32_t)_I32_MIN)
+#define INT32_MAX    _I32_MAX
+#define INT64_MIN    ((int64_t)_I64_MIN)
+#define INT64_MAX    _I64_MAX
+#define UINT8_MAX    _UI8_MAX
+#define UINT16_MAX   _UI16_MAX
+#define UINT32_MAX   _UI32_MAX
+#define UINT64_MAX   _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN    INT8_MIN
+#define INT_LEAST8_MAX    INT8_MAX
+#define INT_LEAST16_MIN   INT16_MIN
+#define INT_LEAST16_MAX   INT16_MAX
+#define INT_LEAST32_MIN   INT32_MIN
+#define INT_LEAST32_MAX   INT32_MAX
+#define INT_LEAST64_MIN   INT64_MIN
+#define INT_LEAST64_MAX   INT64_MAX
+#define UINT_LEAST8_MAX   UINT8_MAX
+#define UINT_LEAST16_MAX  UINT16_MAX
+#define UINT_LEAST32_MAX  UINT32_MAX
+#define UINT_LEAST64_MAX  UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN    INT8_MIN
+#define INT_FAST8_MAX    INT8_MAX
+#define INT_FAST16_MIN   INT16_MIN
+#define INT_FAST16_MAX   INT16_MAX
+#define INT_FAST32_MIN   INT32_MIN
+#define INT_FAST32_MAX   INT32_MAX
+#define INT_FAST64_MIN   INT64_MIN
+#define INT_FAST64_MAX   INT64_MAX
+#define UINT_FAST8_MAX   UINT8_MAX
+#define UINT_FAST16_MAX  UINT16_MAX
+#define UINT_FAST32_MAX  UINT32_MAX
+#define UINT_FAST64_MAX  UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+#  define INTPTR_MIN   INT64_MIN
+#  define INTPTR_MAX   INT64_MAX
+#  define UINTPTR_MAX  UINT64_MAX
+#else // _WIN64 ][
+#  define INTPTR_MIN   INT32_MIN
+#  define INTPTR_MAX   INT32_MAX
+#  define UINTPTR_MAX  UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN   INT64_MIN
+#define INTMAX_MAX   INT64_MAX
+#define UINTMAX_MAX  UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+#  define PTRDIFF_MIN  _I64_MIN
+#  define PTRDIFF_MAX  _I64_MAX
+#else  // _WIN64 ][
+#  define PTRDIFF_MIN  _I32_MIN
+#  define PTRDIFF_MAX  _I32_MAX
+#endif  // _WIN64 ]
+
+#define SIG_ATOMIC_MIN  INT_MIN
+#define SIG_ATOMIC_MAX  INT_MAX
+
+#ifndef SIZE_MAX // [
+#  ifdef _WIN64 // [
+#     define SIZE_MAX  _UI64_MAX
+#  else // _WIN64 ][
+#     define SIZE_MAX  _UI32_MAX
+#  endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+#  define WCHAR_MIN  0
+#endif  // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+#  define WCHAR_MAX  _UI16_MAX
+#endif  // WCHAR_MAX ]
+
+#define WINT_MIN  0
+#define WINT_MAX  _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val)  val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val)  val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+#define INTMAX_C   INT64_C
+#define UINTMAX_C  UINT64_C
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+
+#endif // _MSC_STDINT_H_ ]
new file mode 100644
--- /dev/null
+++ b/mfbt/StdInt.h
@@ -0,0 +1,73 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=99 ft=cpp:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Code.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Jeff Walden <jwalden+code@mit.edu> (original author)
+ *
+ * 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
+ * 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 ***** */
+
+/* Implements the C99 <stdint.h> interface for C and C++ code. */
+
+#ifndef mozilla_StdInt_h_
+#define mozilla_StdInt_h_
+
+/*
+ * The C99 standard header <stdint.h> exposes typedefs for common fixed-width
+ * integer types.  It would be feasible to simply #include <stdint.h>, but
+ * MSVC++ versions prior to 2010 don't provide <stdint.h>.  We could solve this
+ * by reimplementing <stdint.h> for MSVC++ 2008 and earlier.  But then we reach
+ * a second problem: our custom <stdint.h> might conflict with a <stdint.h>
+ * defined by an embedder already looking to work around the MSVC++ <stdint.h>
+ * absence.
+ *
+ * We address these issues in this manner:
+ *
+ *   1. If the preprocessor macro MOZ_CUSTOM_STDINT_H is defined to a path to a
+ *      custom <stdint.h> implementation, we will #include it.  Embedders using
+ *      a custom <stdint.h> must define this macro to an implementation that
+ *      will work with their embedding.
+ *   2. Otherwise, if we are compiling with a an MSVC++ version without
+ *      <stdint.h>, #include our custom <stdint.h> reimplementation.
+ *   3. Otherwise, #include the standard <stdint.h> provided by the compiler.
+ */
+#if defined(MOZ_CUSTOM_STDINT_H)
+#  include MOZ_CUSTOM_STDINT_H
+#elif defined(_MSC_VER) && _MSC_VER < 1600
+#  include "mozilla/MSStdInt.h"
+#else
+#  include <stdint.h>
+#endif
+
+#endif  /* mozilla_StdInt_h_ */
--- a/mfbt/Types.h
+++ b/mfbt/Types.h
@@ -40,42 +40,38 @@
 /*
  * NB: This header must be both valid C and C++.  It must be
  * include-able by code embedding SpiderMonkey *and* Gecko.
  */
 
 #ifndef mozilla_Types_h_
 #define mozilla_Types_h_
 
+/*
+ * Expose the standard integer types from <stdint.h> (and the integer type
+ * limit and constant macros, if the right __STDC_*_MACRO has been defined for
+ * each).  These are all usable throughout mfbt code, and throughout Mozilla
+ * code more generally.
+ */
+#include "mozilla/StdInt.h"
+
 /* 
  * mfbt is logically "lower level" than js/src, but needs basic
  * definitions of numerical types and macros for compiler/linker
  * directives.  js/src already goes through some pain to provide them
  * on numerous platforms, so instead of moving all that goop here,
  * this header makes use of the fact that for the foreseeable future
  * mfbt code will be part and parcel with libmozjs, static or not.
  *
  * For now, the policy is to use jstypes definitions but add a layer
  * of indirection on top of them in case a Great Refactoring ever
  * happens.
  */
 #include "jstypes.h"
 
-/*
- * The numerical types provided by jstypes.h that are allowed within
- * mfbt code are
- *
- *   stddef types:  size_t, ptrdiff_t, etc.
- *   stdin [sic] types:  int8, uint32, etc.
- *
- * stdint types (int8_t etc.), are available for use here, but doing
- * so would change SpiderMonkey's and Gecko's contracts with
- * embedders: stdint types have not yet appeared in public APIs.
- */
-
 #define MOZ_EXPORT_API(type_)  JS_EXPORT_API(type_)
 #define MOZ_IMPORT_API(type_)  JS_IMPORT_API(type_)
 
 /*
  * mfbt definitions need to see export declarations when built, but
  * other code needs to see import declarations when using mfbt.
  */
 #if defined(IMPL_MFBT)
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -409,22 +409,16 @@ pref("devtools.errorconsole.enabled", fa
 pref("browser.ui.layout.tablet", -1); // on: 1, off: 0, auto: -1
 
 // kinetic tweakables
 pref("browser.ui.kinetic.updateInterval", 16);
 pref("browser.ui.kinetic.exponentialC", 1400);
 pref("browser.ui.kinetic.polynomialC", 100);
 pref("browser.ui.kinetic.swipeLength", 160);
 
-// zooming
-pref("browser.ui.zoom.pageFitGranularity", 9); // don't zoom to fit by less than 1/9 (11%)
-pref("browser.ui.zoom.animationDuration", 200); // ms duration of double-tap zoom animation
-pref("browser.ui.zoom.reflow", false); // Change text wrapping on double-tap
-pref("browser.ui.zoom.reflow.fontSize", 720);
-
 pref("font.size.inflation.minTwips", 120);
 
 // pinch gesture
 pref("browser.ui.pinch.maxGrowth", 150);     // max pinch distance growth
 pref("browser.ui.pinch.maxShrink", 200);     // max pinch distance shrinkage
 pref("browser.ui.pinch.scalingFactor", 500); // scaling factor for above pinch limits
 
 // Touch radius (area around the touch location to look for target elements),
@@ -560,17 +554,16 @@ pref("font.default.x-western", "SwissA")
 pref("services.sync.client.type", "mobile");
 pref("services.sync.registerEngines", "Tab,Bookmarks,Form,History,Password,Prefs");
 pref("services.sync.autoconnectDelay", 5);
 
 // prefs to sync by default
 pref("services.sync.prefs.sync.browser.startup.homepage.title", true);
 pref("services.sync.prefs.sync.browser.startup.homepage", true);
 pref("services.sync.prefs.sync.browser.tabs.warnOnClose", true);
-pref("services.sync.prefs.sync.browser.ui.zoom.reflow", true);
 pref("services.sync.prefs.sync.devtools.errorconsole.enabled", true);
 pref("services.sync.prefs.sync.javascript.enabled", true);
 pref("services.sync.prefs.sync.lightweightThemes.isThemeSelected", true);
 pref("services.sync.prefs.sync.lightweightThemes.usedThemes", true);
 pref("services.sync.prefs.sync.network.cookie.cookieBehavior", true);
 pref("services.sync.prefs.sync.permissions.default.image", true);
 pref("services.sync.prefs.sync.privacy.donottrackheader.enabled", true);
 pref("services.sync.prefs.sync.signon.rememberSignons", true);
--- a/mobile/android/base/AboutHomeContent.java
+++ b/mobile/android/base/AboutHomeContent.java
@@ -58,37 +58,37 @@ import android.widget.ListAdapter;
 import android.widget.GridView;
 import android.widget.SimpleCursorAdapter;
 import java.io.*;
 import java.util.zip.*;
 import android.os.Handler;
 import org.json.*;
 import android.util.AttributeSet;
 
+import org.mozilla.gecko.db.BrowserDB;
+import org.mozilla.gecko.db.BrowserDB.URLColumns;
+
 public class AboutHomeContent extends LinearLayout {
     public interface UriLoadCallback {
         public void callback(String uriSpec);
     }
 
     UriLoadCallback mUriLoadCallback = null;
 
     void setUriLoadCallback(UriLoadCallback uriLoadCallback) {
         mUriLoadCallback = uriLoadCallback;
     }
 
     public AboutHomeContent(Context context, AttributeSet attrs) {
         super(context, attrs);
-
-        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        inflater.inflate(R.layout.abouthome_content, this);
     }
 
     private static final String LOGTAG = "GeckoAboutHome";
     private static final String TITLE_KEY = "title";
-    private static final String kAbouthomeWhereClause = Browser.BookmarkColumns.BOOKMARK + " = 1";
+    private static final int NUMBER_OF_TOP_SITES = 3;
     private static final int kTileWidth = 122;
 
     private Cursor mCursor;
     private Uri mUri;
     private String mTitle;
 
     protected ListAdapter mGridAdapter;
     protected ArrayAdapter<String> mAddonAdapter;
@@ -121,30 +121,30 @@ public class AboutHomeContent extends Li
         {
             onGridItemClick((GridView)parent, v, position, id);
         }
     };
 
     void init(final Activity activity) {
         GeckoAppShell.getHandler().post(new Runnable() {
             public void run() {
-                mCursor = activity.managedQuery(Browser.BOOKMARKS_URI,
-                                                null, kAbouthomeWhereClause, null, null);
+                ContentResolver resolver = GeckoApp.mAppContext.getContentResolver();
+                mCursor = BrowserDB.filter(resolver, "", NUMBER_OF_TOP_SITES);
                 activity.startManagingCursor(mCursor);
 
                 onActivityContentChanged(activity);
                 mAddonAdapter = new ArrayAdapter<String>(activity, R.layout.abouthome_addon_list_item);
                 GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
                     public void run() {
                         final SimpleCursorAdapter gridAdapter =
                             new SimpleCursorAdapter(activity, R.layout.abouthome_grid_box, mCursor,
-                                                    new String[] {Browser.BookmarkColumns.TITLE,
-                                                                  Browser.BookmarkColumns.FAVICON,
-                                                                  Browser.BookmarkColumns.URL,
-                                                                  "thumbnail"},
+                                                    new String[] { URLColumns.TITLE,
+                                                                   URLColumns.FAVICON,
+                                                                   URLColumns.URL,
+                                                                   URLColumns.THUMBNAIL },
                                                     new int[] {R.id.bookmark_title, R.id.bookmark_icon, R.id.bookmark_url, R.id.screenshot});
                         mGrid.setAdapter(gridAdapter);
                         gridAdapter.setViewBinder(new AwesomeCursorViewBinder());
                         mAddonList.setAdapter(mAddonAdapter);
                     }
                 });
                 readRecommendedAddons(activity);
             }
@@ -205,45 +205,52 @@ public class AboutHomeContent extends Li
                     Log.i("GeckoAddons", "error reading json file", e);
                 }
             }
         });
     }
 
     protected void onGridItemClick(GridView l, View v, int position, long id) {
         mCursor.moveToPosition(position);
-        String spec = mCursor.getString(mCursor.getColumnIndex(Browser.BookmarkColumns.URL));
+        String spec = mCursor.getString(mCursor.getColumnIndex(URLColumns.URL));
         Log.i(LOGTAG, "clicked: " + spec);
         if (mUriLoadCallback != null)
             mUriLoadCallback.callback(spec);
     }
 
 }
 class AwesomeCursorViewBinder implements SimpleCursorAdapter.ViewBinder {
+    private static final String LOGTAG = "GeckoAwesomeCursorViewBinder";
+
     private boolean updateImage(View view, Cursor cursor, int faviconIndex) {
         byte[] b = cursor.getBlob(faviconIndex);
         ImageView favicon = (ImageView) view;
 
         if (b == null) {
             favicon.setImageResource(R.drawable.favicon);
         } else {
-            Bitmap bitmap = BitmapFactory.decodeByteArray(b, 0, b.length);
-            favicon.setImageBitmap(bitmap);
+            try {
+                Bitmap bitmap = BitmapFactory.decodeByteArray(b, 0, b.length);
+                favicon.setImageBitmap(bitmap);
+            } catch (OutOfMemoryError oom) {
+                Log.e(LOGTAG, "Unable to load thumbnail bitmap", oom);
+                favicon.setImageResource(R.drawable.favicon);
+            }
         }
 
         return true;
     }
 
     private boolean updateTitle(View view, Cursor cursor, int titleIndex) {
         String title = cursor.getString(titleIndex);
         TextView titleView = (TextView)view;
         // Use the URL instead of an empty title for consistency with the normal URL
         // bar view - this is the equivalent of getDisplayTitle() in Tab.java
         if (title == null || title.length() == 0) {
-            int urlIndex = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.URL);
+            int urlIndex = cursor.getColumnIndexOrThrow(URLColumns.URL);
             title = cursor.getString(urlIndex);
         }
 
         titleView.setText(title);
         return true;
     }
 
     private boolean updateUrl(View view, Cursor cursor, int urlIndex) {
@@ -259,33 +266,32 @@ class AwesomeCursorViewBinder implements
                 title = title.substring(0, title.length() -1);
         }
         urlView.setText(title);
         return true;
     }
 
     @Override
     public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
-        int faviconIndex = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.FAVICON);
+        int faviconIndex = cursor.getColumnIndexOrThrow(URLColumns.FAVICON);
         if (columnIndex == faviconIndex) {
             return updateImage(view, cursor, faviconIndex);
         }
 
-        int titleIndex = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.TITLE);
+        int titleIndex = cursor.getColumnIndexOrThrow(URLColumns.TITLE);
         if (columnIndex == titleIndex) {
             return updateTitle(view, cursor, titleIndex);
         }
 
-        int urlIndex = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.URL);
+        int urlIndex = cursor.getColumnIndexOrThrow(URLColumns.URL);
         if (columnIndex == urlIndex) {
             return updateUrl(view, cursor, urlIndex);
         }
 
-        int thumbIndex = cursor.getColumnIndexOrThrow("thumbnail");
-
+        int thumbIndex = cursor.getColumnIndexOrThrow(URLColumns.THUMBNAIL);
         if (columnIndex == thumbIndex) {
             return updateImage(view, cursor, thumbIndex);
         }
 
         // Other columns are handled automatically
         return false;
     }
 
--- a/mobile/android/base/AndroidManifest.xml.in
+++ b/mobile/android/base/AndroidManifest.xml.in
@@ -134,10 +134,14 @@
         <activity android:name="org.mozilla.gecko.TabsTray"
                   android:theme="@style/Gecko.Translucent"/>
 
         <activity android:name="org.mozilla.gecko.GeckoPreferences"
                   android:theme="@style/Gecko.TitleBar"
                   android:label="@string/preferences_title"
                   android:excludeFromRecents="true"/>
 
+        <provider android:name="org.mozilla.gecko.db.BrowserProvider"
+                  android:authorities="org.mozilla.gecko.providers.browser"
+                  android:exported="false"/>
+
     </application>
 </manifest> 
--- a/mobile/android/base/AwesomeBar.java
+++ b/mobile/android/base/AwesomeBar.java
@@ -58,17 +58,16 @@ import android.widget.ImageButton;
 
 import org.json.JSONArray;
 import org.json.JSONObject;
 
 public class AwesomeBar extends Activity implements GeckoEventListener {
     private static final String LOGTAG = "GeckoAwesomeBar";
 
     static final String URL_KEY = "url";
-    static final String TITLE_KEY = "title";
     static final String CURRENT_URL_KEY = "currenturl";
     static final String TYPE_KEY = "type";
     static final String SEARCH_KEY = "search";
     static enum Type { ADD, EDIT };
 
     private String mType;
     private AwesomeBarTabs mAwesomeTabs;
     private AwesomeBarEditText mText;
--- a/mobile/android/base/AwesomeBarTabs.java
+++ b/mobile/android/base/AwesomeBarTabs.java
@@ -74,26 +74,30 @@ import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
+import org.mozilla.gecko.db.BrowserDB;
+import org.mozilla.gecko.db.BrowserDB.URLColumns;
+
 public class AwesomeBarTabs extends TabHost {
     private static final String LOGTAG = "GeckoAwesomeBarTabs";
 
     private static final String ALL_PAGES_TAB = "all";
     private static final String BOOKMARKS_TAB = "bookmarks";
     private static final String HISTORY_TAB = "history";
 
     private static enum HistorySection { TODAY, YESTERDAY, WEEK, OLDER };
 
     private Context mContext;
+    private boolean mInflated;
     private OnUrlOpenListener mUrlOpenListener;
     private View.OnTouchListener mListTouchListener;
     private JSONArray mSearchEngines;
 
     private AwesomeBarCursorAdapter mAllPagesCursorAdapter;
     private SimpleCursorAdapter mBookmarksAdapter;
     private SimpleExpandableListAdapter mHistoryAdapter;
 
@@ -122,17 +126,17 @@ public class AwesomeBarTabs extends TabH
 
             View childView =
                     super.getChildView(groupPosition, childPosition, isLastChild, convertView, parent); 
 
             @SuppressWarnings("unchecked")
             Map<String,Object> historyItem =
                     (Map<String,Object>) mHistoryAdapter.getChild(groupPosition, childPosition);
 
-            byte[] b = (byte[]) historyItem.get(Browser.BookmarkColumns.FAVICON);
+            byte[] b = (byte[]) historyItem.get(URLColumns.FAVICON);
             ImageView favicon = (ImageView) childView.findViewById(R.id.favicon);
 
             if (b == null) {
                 favicon.setImageResource(R.drawable.favicon);
             } else {
                 Bitmap bitmap = BitmapFactory.decodeByteArray(b, 0, b.length);
                 favicon.setImageBitmap(bitmap);
             }
@@ -157,64 +161,55 @@ public class AwesomeBarTabs extends TabH
         }
 
         private boolean updateTitle(View view, Cursor cursor, int titleIndex) {
             String title = cursor.getString(titleIndex);
             TextView titleView = (TextView)view;
             // Use the URL instead of an empty title for consistency with the normal URL
             // bar view - this is the equivalent of getDisplayTitle() in Tab.java
             if (title == null || title.length() == 0) {
-                int urlIndex = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.URL);
+                int urlIndex = cursor.getColumnIndexOrThrow(URLColumns.URL);
                 title = cursor.getString(urlIndex);
             }
 
             titleView.setText(title);
             return true;
         }
 
         public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
-            int faviconIndex = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.FAVICON);
+            int faviconIndex = cursor.getColumnIndexOrThrow(URLColumns.FAVICON);
             if (columnIndex == faviconIndex) {
                 return updateFavicon(view, cursor, faviconIndex);
             }
 
-            int titleIndex = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.TITLE);
+            int titleIndex = cursor.getColumnIndexOrThrow(URLColumns.TITLE);
             if (columnIndex == titleIndex) {
                 return updateTitle(view, cursor, titleIndex);
             }
 
             // Other columns are handled automatically
             return false;
         }
     }
 
     private class BookmarksQueryTask extends AsyncTask<Void, Void, Cursor> {
         protected Cursor doInBackground(Void... arg0) {
             ContentResolver resolver = mContext.getContentResolver();
-
-            return resolver.query(Browser.BOOKMARKS_URI,
-                                  null,
-                                  // Select all bookmarks with a non-empty URL. When the history
-                                  // is empty there appears to be a dummy entry in the database
-                                  // which has a title of "Bookmarks" and no URL; the length restriction
-                                  // is to avoid picking that up specifically.
-                                  Browser.BookmarkColumns.BOOKMARK + " = 1 AND LENGTH(" + Browser.BookmarkColumns.URL + ") > 0",
-                                  null,
-                                  Browser.BookmarkColumns.TITLE);
+            return BrowserDB.getAllBookmarks(resolver);
         }
 
         protected void onPostExecute(Cursor cursor) {
             // Load the list using a custom adapter so we can create the bitmaps
             mBookmarksAdapter = new SimpleCursorAdapter(
                 mContext,
                 R.layout.awesomebar_row,
                 cursor,
-                new String[] { AwesomeBar.TITLE_KEY,
-                               AwesomeBar.URL_KEY,
-                               Browser.BookmarkColumns.FAVICON },
+                new String[] { URLColumns.TITLE,
+                               URLColumns.URL,
+                               URLColumns.FAVICON },
                 new int[] { R.id.title, R.id.url, R.id.favicon }
             );
 
             mBookmarksAdapter.setViewBinder(new AwesomeCursorViewBinder());
 
             final ListView bookmarksList = (ListView) findViewById(R.id.bookmarks_list);
 
             bookmarksList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@@ -229,25 +224,17 @@ public class AwesomeBarTabs extends TabH
 
     private class HistoryQueryTask extends AsyncTask<Void, Void, Pair<List,List>> {
         private static final long MS_PER_DAY = 86400000;
         private static final long MS_PER_WEEK = MS_PER_DAY * 7;
 
         protected Pair<List,List> doInBackground(Void... arg0) {
             Pair<List,List> result = null;
             ContentResolver resolver = mContext.getContentResolver();
-
-            Cursor cursor =
-                    resolver.query(Browser.BOOKMARKS_URI,
-                                   null,
-                                   // Bookmarks that have not been visited have a date value
-                                   // of 0, so don't pick them up in the history view.
-                                   Browser.BookmarkColumns.DATE + " > 0",
-                                   null,
-                                   Browser.BookmarkColumns.DATE + " DESC LIMIT " + MAX_RESULTS);
+            Cursor cursor = BrowserDB.getRecentHistory(resolver, MAX_RESULTS);
 
             Date now = new Date();
             now.setHours(0);
             now.setMinutes(0);
             now.setSeconds(0);
 
             long today = now.getTime();
 
@@ -262,17 +249,17 @@ public class AwesomeBarTabs extends TabH
             // for the iteration.
             cursor.moveToPosition(-1);
 
             // Split the history query results into adapters per time
             // section (today, yesterday, week, older). Queries on content
             // Browser content provider don't support limitting the number
             // of returned rows so we limit it here.
             while (cursor.moveToNext()) {
-                long time = cursor.getLong(cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.DATE));
+                long time = cursor.getLong(cursor.getColumnIndexOrThrow(URLColumns.DATE_LAST_VISITED));
                 HistorySection itemSection = getSectionForTime(time, today);
 
                 if (groups == null)
                     groups = new LinkedList<Map<String,?>>();
 
                 if (childrenLists == null)
                     childrenLists = new LinkedList<List<Map<String,?>>>();
 
@@ -304,38 +291,38 @@ public class AwesomeBarTabs extends TabH
             }
 
             return result;
         }
 
         public Map<String,?> createHistoryItem(Cursor cursor) {
             Map<String,Object> historyItem = new HashMap<String,Object>();
 
-            String url = cursor.getString(cursor.getColumnIndexOrThrow(AwesomeBar.URL_KEY));
-            String title = cursor.getString(cursor.getColumnIndexOrThrow(AwesomeBar.TITLE_KEY));
-            byte[] favicon = cursor.getBlob(cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.FAVICON));
+            String url = cursor.getString(cursor.getColumnIndexOrThrow(URLColumns.URL));
+            String title = cursor.getString(cursor.getColumnIndexOrThrow(URLColumns.TITLE));
+            byte[] favicon = cursor.getBlob(cursor.getColumnIndexOrThrow(URLColumns.FAVICON));
 
             // Use the URL instead of an empty title for consistency with the normal URL
             // bar view - this is the equivalent of getDisplayTitle() in Tab.java
             if (title == null || title.length() == 0)
                 title = url;
 
-            historyItem.put(AwesomeBar.URL_KEY, url);
-            historyItem.put(AwesomeBar.TITLE_KEY, title);
+            historyItem.put(URLColumns.URL, url);
+            historyItem.put(URLColumns.TITLE, title);
 
             if (favicon != null)
-                historyItem.put(Browser.BookmarkColumns.FAVICON, favicon);
+                historyItem.put(URLColumns.FAVICON, favicon);
 
             return historyItem;
         }
 
         public Map<String,?> createGroupItem(HistorySection section) {
             Map<String,String> groupItem = new HashMap<String,String>();
 
-            groupItem.put(AwesomeBar.TITLE_KEY, getSectionName(section));
+            groupItem.put(URLColumns.TITLE, getSectionName(section));
 
             return groupItem;
         }
 
         private String getSectionName(HistorySection section) {
             Resources resources = mContext.getResources();
 
             switch (section) {
@@ -379,21 +366,21 @@ public class AwesomeBarTabs extends TabH
             // FIXME: display some sort of message when there's no history
             if (result == null)
                 return;
 
             mHistoryAdapter = new HistoryListAdapter(
                 mContext,
                 result.first,
                 R.layout.awesomebar_header_row,
-                new String[] { AwesomeBar.TITLE_KEY },
+                new String[] { URLColumns.TITLE },
                 new int[] { R.id.title },
                 result.second,
                 R.layout.awesomebar_row,
-                new String[] { AwesomeBar.TITLE_KEY, AwesomeBar.URL_KEY },
+                new String[] { URLColumns.TITLE, URLColumns.URL },
                 new int[] { R.id.title, R.id.url }
             );
 
             final ExpandableListView historyList =
                     (ExpandableListView) findViewById(R.id.history_list);
 
             historyList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
                 public boolean onChildClick(ExpandableListView parent, View view,
@@ -521,23 +508,31 @@ public class AwesomeBarTabs extends TabH
     };
 
     public AwesomeBarTabs(Context context, AttributeSet attrs) {
         super(context, attrs);
 
         Log.d(LOGTAG, "Creating AwesomeBarTabs");
 
         mContext = context;
+        mInflated = false;
         mSearchEngines = new JSONArray();
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
 
-        // Load layout into the custom view
-        LayoutInflater inflater =
-                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        // HACK: Without this, the onFinishInflate is called twice
+        // This issue is due to a bug when Android inflates a layout with a
+        // parent. Fixed in Honeycomb
+        if (mInflated)
+            return;
 
-        inflater.inflate(R.layout.awesomebar_tabs, this);
+        mInflated = true;
 
         // This should be called before adding any tabs
         // to the TabHost.
         setup();
 
         mListTouchListener = new View.OnTouchListener() {
             public boolean onTouch(View view, MotionEvent event) {
                 hideSoftInput(view);
@@ -606,40 +601,28 @@ public class AwesomeBarTabs extends TabH
                       R.string.awesomebar_all_pages_title,
                       R.id.all_pages_list);
 
         // Load the list using a custom adapter so we can create the bitmaps
         mAllPagesCursorAdapter = new AwesomeBarCursorAdapter(
             mContext,
             R.layout.awesomebar_row,
             null,
-            new String[] { AwesomeBar.TITLE_KEY,
-                           AwesomeBar.URL_KEY,
-                           Browser.BookmarkColumns.FAVICON },
+            new String[] { URLColumns.TITLE,
+                           URLColumns.URL,
+                           URLColumns.FAVICON },
             new int[] { R.id.title, R.id.url, R.id.favicon }
         );
 
         mAllPagesCursorAdapter.setViewBinder(new AwesomeCursorViewBinder());
 
         mAllPagesCursorAdapter.setFilterQueryProvider(new FilterQueryProvider() {
             public Cursor runQuery(CharSequence constraint) {
                 ContentResolver resolver = mContext.getContentResolver();
-
-                return resolver.query(Browser.BOOKMARKS_URI,
-                                      null,
-                                      // The length restriction on URL is for the same reason as in the general bookmark query
-                                      // (see comment earlier in this file).
-                                      "(" + Browser.BookmarkColumns.URL + " LIKE ? OR " + Browser.BookmarkColumns.TITLE + " LIKE ?)"
-                                        + " AND LENGTH(" + Browser.BookmarkColumns.URL + ") > 0", 
-                                      new String[] {"%" + constraint.toString() + "%", "%" + constraint.toString() + "%",},
-                                      // ORDER BY is number of visits times a multiplier from 1 - 120 of how recently the site 
-                                      // was accessed with a site accessed today getting 120 and a site accessed 119 or more 
-                                      // days ago getting 1
-                                      Browser.BookmarkColumns.VISITS + " * MAX(1, (" +
-                                      Browser.BookmarkColumns.DATE + " - " + new Date().getTime() + ") / 86400000 + 120) DESC LIMIT " + MAX_RESULTS);
+                return BrowserDB.filter(resolver, constraint, MAX_RESULTS);
             }
         });
 
         final ListView allPagesList = (ListView) findViewById(R.id.all_pages_list);
 
         allPagesList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                 handleItemClick(allPagesList, position);
@@ -685,30 +668,30 @@ public class AwesomeBarTabs extends TabH
         imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
     }
 
     private void handleHistoryItemClick(int groupPosition, int childPosition) {
         @SuppressWarnings("unchecked")
         Map<String,Object> historyItem =
                 (Map<String,Object>) mHistoryAdapter.getChild(groupPosition, childPosition);
 
-        String url = (String) historyItem.get(AwesomeBar.URL_KEY);
+        String url = (String) historyItem.get(URLColumns.URL);
 
         if (mUrlOpenListener != null)
             mUrlOpenListener.onUrlOpen(url);
     }
 
     private void handleItemClick(ListView list, int position) {
         Object item = list.getItemAtPosition(position);
         // If an AwesomeBar entry is clicked, item will be a Cursor containing
         // the entry's data.  Otherwise, a search engine entry was clicked, and
         // item will be a String containing the name of the search engine.
         if (item instanceof Cursor) {
             Cursor cursor = (Cursor) item;
-            String url = cursor.getString(cursor.getColumnIndexOrThrow(AwesomeBar.URL_KEY));
+            String url = cursor.getString(cursor.getColumnIndexOrThrow(URLColumns.URL));
             if (mUrlOpenListener != null)
                 mUrlOpenListener.onUrlOpen(url);
         } else {
             if (mUrlOpenListener != null)
                 mUrlOpenListener.onSearch((String)item);
         }
     }
 
--- a/mobile/android/base/BrowserToolbar.java
+++ b/mobile/android/base/BrowserToolbar.java
@@ -57,53 +57,61 @@ import android.view.View;
 import android.widget.Button;
 import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 import android.widget.TextSwitcher;
 import android.widget.ViewSwitcher.ViewFactory;
 
 public class BrowserToolbar extends LinearLayout {
-    final private Button mAwesomeBar;
-    final private ImageButton mTabs;
-    final public ImageButton mFavicon;
-    final public ImageButton mStop;
-    final public ImageButton mSiteSecurity;
-    final private AnimationDrawable mProgressSpinner;
-    final private TextSwitcher mTabsCount;
+    private Button mAwesomeBar;
+    private ImageButton mTabs;
+    public ImageButton mFavicon;
+    public ImageButton mStop;
+    public ImageButton mSiteSecurity;
+    private AnimationDrawable mProgressSpinner;
+    private TextSwitcher mTabsCount;
 
     final private Context mContext;
-    final private Handler mHandler;
-    final private int mColor;
-    final private int mCounterColor;
+    private Handler mHandler;
+    private boolean mInflated;
+    private int mColor;
+    private int mCounterColor;
 
-    final private int mDuration;
-    final private TranslateAnimation mSlideUpIn;
-    final private TranslateAnimation mSlideUpOut;
-    final private TranslateAnimation mSlideDownIn;
-    final private TranslateAnimation mSlideDownOut;
+    private int mDuration;
+    private TranslateAnimation mSlideUpIn;
+    private TranslateAnimation mSlideUpOut;
+    private TranslateAnimation mSlideDownIn;
+    private TranslateAnimation mSlideDownOut;
 
     private int mCount;
 
     public BrowserToolbar(Context context, AttributeSet attrs) {
         super(context, attrs);
+        mContext = context;
+        mInflated = false;
+    }
 
-        mContext = context;
+    @Override
+    protected void onFinishInflate () {
+        super.onFinishInflate();
+
+        // HACK: Without this, the onFinishInflate is called twice
+        // This issue is due to a bug when Android inflates a layout with a
+        // parent. Fixed in Honeycomb
+        if (mInflated)
+            return;
+
+        mInflated = true;
 
         // Get the device's highlight color
         ContextThemeWrapper wrapper = new ContextThemeWrapper(mContext, android.R.style.TextAppearance);
         TypedArray typedArray = wrapper.getTheme().obtainStyledAttributes(new int[] { android.R.attr.textColorHighlight });
         mColor = typedArray.getColor(typedArray.getIndex(0), 0);
 
-        // Load layout into the custom view
-        LayoutInflater inflater =
-                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
-        inflater.inflate(R.layout.browser_toolbar, this);
-
         mAwesomeBar = (Button) findViewById(R.id.awesome_bar);
         mAwesomeBar.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View v) {
                 onAwesomeBarSearch();
             }
         });
 
         Resources resources = getResources();
@@ -130,28 +138,29 @@ public class BrowserToolbar extends Line
                     addTab();
             }
         });
         mTabs.setImageLevel(1);
 
         mCounterColor = 0x99ffffff;
 
         mTabsCount = (TextSwitcher) findViewById(R.id.tabs_count);
+        mTabsCount.removeAllViews();
         mTabsCount.setFactory(new ViewFactory() {
             public View makeView() {
                 TextView text = new TextView(mContext);
                 text.setGravity(Gravity.CENTER);
                 text.setTextSize(16);
                 text.setTextColor(mCounterColor);
                 text.setTypeface(text.getTypeface(), Typeface.BOLD);
-                return text;
-            } 
-        });
+                return (View) text;
+            }
+        }); 
+        mTabsCount.setText("0");
         mCount = 0;
-        mTabsCount.setText("0");
 
         mFavicon = (ImageButton) findViewById(R.id.favicon);
         mSiteSecurity = (ImageButton) findViewById(R.id.site_security);
         mProgressSpinner = (AnimationDrawable) resources.getDrawable(R.drawable.progress_spinner);
         
         mStop = (ImageButton) findViewById(R.id.stop);
         mStop.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View v) {
--- a/mobile/android/base/ConfirmPreference.java
+++ b/mobile/android/base/ConfirmPreference.java
@@ -32,19 +32,20 @@
  * 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 ***** */
 
 package org.mozilla.gecko;
 
+import org.mozilla.gecko.db.BrowserDB;
+
 import android.content.Context;
 import android.preference.DialogPreference;
-import android.provider.Browser;
 import android.util.AttributeSet;
 import android.util.Log;
 
 class ConfirmPreference extends DialogPreference {
     private static final String LOGTAG = "GeckoConfirmPreference";
 
     private String mAction = null;
     private Context mContext = null;
@@ -59,17 +60,17 @@ class ConfirmPreference extends DialogPr
         mContext = context;
     }
     protected void onDialogClosed(boolean positiveResult) {
         if (!positiveResult)
             return;
         if ("clear_history".equalsIgnoreCase(mAction)) {
             GeckoAppShell.getHandler().post(new Runnable(){
                 public void run() {
-                    Browser.clearHistory(mContext.getContentResolver());
+                    BrowserDB.clearHistory(mContext.getContentResolver());
                 }
             });
         } else if ("clear_private_data".equalsIgnoreCase(mAction)) {
             GeckoAppShell.getHandler().post(new Runnable(){
                 public void run() {
                     GeckoAppShell.sendEventToGecko(new GeckoEvent("Sanitize:ClearAll", null));
                 }
             });
--- a/mobile/android/base/DoorHanger.java
+++ b/mobile/android/base/DoorHanger.java
@@ -51,45 +51,48 @@ import android.widget.TextView;
 import org.json.JSONObject;
 import org.json.JSONException;
 
 public class DoorHanger extends LinearLayout implements Button.OnClickListener {
     private Context mContext;
     private LinearLayout mChoicesLayout;
     private TextView mTextView;
     private Button mButton;
-    private LayoutParams mLayoutParams;
+    static private LayoutParams mLayoutParams;
     public Tab mTab;
     // value used to identify the notification
     private String mValue;
 
+    static private LayoutInflater mInflater;
+
     private int mPersistence = 0;
     private long mTimeout = 0;
 
     public DoorHanger(Context aContext, String aValue) {
         super(aContext);
 
         mContext = aContext;
         mValue = aValue;
 
         setOrientation(VERTICAL);
         setBackgroundResource(R.drawable.doorhanger_shadow_bg);
 
-        // Load layout into the custom view
-        LayoutInflater inflater =
-                (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        inflater.inflate(R.layout.doorhanger, this);
+        if (mInflater == null)
+            mInflater = LayoutInflater.from(mContext);
+
+        mInflater.inflate(R.layout.doorhanger, this);
         hide();
 
         mTextView = (TextView) findViewById(R.id.doorhanger_title);
         mChoicesLayout = (LinearLayout) findViewById(R.id.doorhanger_choices);
 
-        mLayoutParams = new LayoutParams(LayoutParams.FILL_PARENT,
-                                         LayoutParams.FILL_PARENT,
-                                         1.0f);
+        if (mLayoutParams == null)
+            mLayoutParams = new LayoutParams(LayoutParams.FILL_PARENT,
+                                             LayoutParams.FILL_PARENT,
+                                             1.0f);
     }
 
     public void addButton(String aText, int aCallback) {
         Button mButton = new Button(mContext);
         mButton.setText(aText);
         mButton.setTag(Integer.toString(aCallback));
         mButton.setOnClickListener(this);
         mChoicesLayout.addView(mButton, mLayoutParams);
--- a/mobile/android/base/DoorHangerPopup.java
+++ b/mobile/android/base/DoorHangerPopup.java
@@ -64,17 +64,17 @@ public class DoorHangerPopup extends Pop
     public DoorHangerPopup(Context aContext) {
         super(aContext);
         mContext = aContext;
 
         setBackgroundDrawable(new BitmapDrawable());
         setOutsideTouchable(true);
         setWindowLayoutMode(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
 
-        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        LayoutInflater inflater = LayoutInflater.from(mContext);
         RelativeLayout layout = (RelativeLayout) inflater.inflate(R.layout.doorhangerpopup, null);
         mContent = (LinearLayout) layout.findViewById(R.id.doorhanger_container);
         
         setContentView(layout);
     }
 
     public void addDoorHanger(String message, String value, JSONArray buttons,
                               Tab tab, JSONObject options) {
--- a/mobile/android/base/Favicons.java
+++ b/mobile/android/base/Favicons.java
@@ -39,37 +39,35 @@ package org.mozilla.gecko;
 
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteOpenHelper;
 import android.database.sqlite.SQLiteQueryBuilder;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
-import android.provider.Browser;
 import android.util.Log;
 
 import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
+import java.net.URLConnection;
 import java.net.HttpURLConnection;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 
+import org.mozilla.gecko.db.BrowserDB;
+
 public class Favicons {
     private static final String LOGTAG = "GeckoFavicons";
 
     public static final long NOT_LOADING = 0;
 
     private Context mContext;
     private DatabaseHelper mDbHelper;
 
@@ -230,96 +228,67 @@ public class Favicons {
                           " and favicon URL = " + faviconUrl);
         }
 
         // Runs in background thread
         private BitmapDrawable loadFaviconFromDb() {
             Log.d(LOGTAG, "Loading favicon from DB for URL = " + mPageUrl);
 
             ContentResolver resolver = mContext.getContentResolver();
-
-            Cursor c = resolver.query(Browser.BOOKMARKS_URI,
-                                      new String[] { Browser.BookmarkColumns.FAVICON },
-                                      Browser.BookmarkColumns.URL + " = ?",
-                                      new String[] { mPageUrl },
-                                      null);
-
-            if (!c.moveToFirst()) {
-                c.close();
-                return null;
-            }
+            BitmapDrawable favicon = BrowserDB.getFaviconForUrl(resolver, mPageUrl);
 
-            int faviconIndex = c.getColumnIndexOrThrow(Browser.BookmarkColumns.FAVICON);
-            
-            byte[] b = c.getBlob(faviconIndex);
-            c.close();
-            if (b == null)
-                return null;
+            if (favicon != null)
+                Log.d(LOGTAG, "Loaded favicon from DB successfully for URL = " + mPageUrl);
 
-            Bitmap bitmap = BitmapFactory.decodeByteArray(b, 0, b.length);
-
-            Log.d(LOGTAG, "Loaded favicon from DB successfully for URL = " + mPageUrl);
-
-            return new BitmapDrawable(bitmap);
+            return favicon;
         }
 
         // Runs in background thread
         private void saveFaviconToDb(BitmapDrawable favicon) {
-            Bitmap bitmap = favicon.getBitmap();
-
-            ByteArrayOutputStream stream = new ByteArrayOutputStream();
-            bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
-
-            ContentValues values = new ContentValues();
-            values.put(Browser.BookmarkColumns.FAVICON, stream.toByteArray());
-            values.put(Browser.BookmarkColumns.URL, mPageUrl);
-
+            Log.d(LOGTAG, "Saving favicon on browser database for URL = " + mPageUrl);
             ContentResolver resolver = mContext.getContentResolver();
-
-            Log.d(LOGTAG, "Saving favicon on browser database for URL = " + mPageUrl);
-            resolver.update(Browser.BOOKMARKS_URI,
-                            values,
-                            Browser.BookmarkColumns.URL + " = ?",
-                            new String[] { mPageUrl });
-
+            BrowserDB.updateFaviconForUrl(resolver, mPageUrl, favicon);
 
             Log.d(LOGTAG, "Saving favicon URL for URL = " + mPageUrl);
             mDbHelper.setFaviconUrlForPageUrl(mPageUrl, mFaviconUrl);
         }
 
         // Runs in background thread
         private BitmapDrawable downloadFavicon(URL faviconUrl) {
             Log.d(LOGTAG, "Downloading favicon for URL = " + mPageUrl +
                           " with favicon URL = " + mFaviconUrl);
 
             // due to android bug 6066, we must download the entire image before using it
             // http://code.google.com/p/android/issues/detail?id=6066
-            HttpURLConnection urlConnection = null;
+            URLConnection urlConnection = null;
             BufferedInputStream contentStream = null;
             ByteArrayInputStream byteStream = null;
             BitmapDrawable image = null;
 
             try {
-                urlConnection = (HttpURLConnection) faviconUrl.openConnection();
+                urlConnection = faviconUrl.openConnection();
                 int length = urlConnection.getContentLength();
                 contentStream = new BufferedInputStream(urlConnection.getInputStream(), length);
                 byte[] bytes = new byte[length];
                 int pos = 0;
                 int offset = 0;
                 while ((pos = contentStream.read(bytes, offset, length - offset)) > 0)
                     offset += pos;
                 if (length == offset) {
                     byteStream = new ByteArrayInputStream(bytes);
                     image = (BitmapDrawable) Drawable.createFromStream(byteStream, "src");
                 }
             } catch (Exception e) {
                 Log.d(LOGTAG, "Error downloading favicon: " + e);
             } finally {
-                if (urlConnection != null)
-                    urlConnection.disconnect();
+                if (urlConnection != null && urlConnection instanceof HttpURLConnection) {
+                    HttpURLConnection httpConnection = (HttpURLConnection) urlConnection;
+                    httpConnection.disconnect();
+                }
+
                 try {
                     if (contentStream != null)
                         contentStream.close();
                     if (byteStream != null)
                         byteStream.close();
                 } catch (IOException e) {
                     Log.d(LOGTAG, "error closing favicon stream");
                 }
@@ -331,35 +300,35 @@ public class Favicons {
             }
 
             return image;
         }
 
         @Override
         protected BitmapDrawable doInBackground(Void... unused) {
             BitmapDrawable image = null;
-            URL pageUrl = null;
 
             if (isCancelled())
                 return null;
 
-            // Handle the case of malformed URL
-            try {
-                pageUrl = new URL(mPageUrl);
-            } catch (MalformedURLException e) {
-                Log.d(LOGTAG, "The provided URL is not valid: " + e);
-                return null;
-            }
-
             URL faviconUrl = null;
 
             // Handle the case of malformed favicon URL
             try {
                 // If favicon is empty, fallback to default favicon URI
                 if (mFaviconUrl == null || mFaviconUrl.length() == 0) {
+                    // Handle the case of malformed URL
+                    URL pageUrl = null;
+                    try {
+                        pageUrl = new URL(mPageUrl);
+                    } catch (MalformedURLException e) {
+                        Log.d(LOGTAG, "The provided URL is not valid: " + e);
+                        return null;
+                    }
+
                     faviconUrl = new URL(pageUrl.getProtocol(), pageUrl.getAuthority(), "/favicon.ico");
                     mFaviconUrl = faviconUrl.toString();
                 } else {
                     faviconUrl = new URL(mFaviconUrl);
                 }
             } catch (MalformedURLException e) {
                 Log.d(LOGTAG, "The provided favicon URL is not valid: " + e);
                 return null;
--- a/mobile/android/base/GeckoActionBar.java
+++ b/mobile/android/base/GeckoActionBar.java
@@ -33,20 +33,25 @@
  * 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 ***** */
 
 package org.mozilla.gecko;
 
 import android.app.Activity;
+import android.graphics.drawable.Drawable;
 import android.view.View;
 
 public class GeckoActionBar {
 
+    public static void setBackgroundDrawable(Activity activity, Drawable drawable) {
+         activity.getActionBar().setBackgroundDrawable(drawable);
+    }
+
     public static void setDisplayOptions(Activity activity, int options, int mask) {
          activity.getActionBar().setDisplayOptions(options, mask);
     }
 
     public static void setCustomView(Activity activity, View view) {
          activity.getActionBar().setCustomView(view);
     }
 
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -718,27 +718,31 @@ abstract public class GeckoApp
         mMainHandler.post(new Runnable() { 
             public void run() {
                 if (Tabs.getInstance().isSelectedTab(tab))
                     mBrowserToolbar.setSecurityMode(mode);
             }
         });
     }
 
-    File getProfileDir() {
+    public File getProfileDir() {
+        // XXX: TO-DO read profiles.ini to get the default profile
+        return getProfileDir("default");
+    }
+
+    public File getProfileDir(final String profileName) {
         if (mProfileDir == null && !mUserDefinedProfile) {
             File mozDir = new File(GeckoAppShell.sHomeDir, "mozilla");
             File[] profiles = mozDir.listFiles(new FileFilter() {
                 public boolean accept(File pathname) {
-                    return pathname.getName().endsWith(".default");
+                    return pathname.getName().endsWith("." + profileName);
                 }
             });
             if (profiles.length == 1)
                 mProfileDir = profiles[0];
-            // XXX: TO-DO read profiles.ini to get the default profile
         }
         return mProfileDir;
     }
 
     void addTab() {
         showAwesomebar(AwesomeBar.Type.ADD);
     }
 
@@ -1125,17 +1129,17 @@ abstract public class GeckoApp
                 if (Tabs.getInstance().isSelectedTab(tab))
                     mBrowserToolbar.setTitle(tab.getDisplayTitle());
                 onTabsChanged(tab);
             }
         });
     }
 
     void handleLinkAdded(final int tabId, String rel, final String href) {
-        if (rel.indexOf("icon") != -1) {
+        if (rel.indexOf("[icon]") != -1) {
             final Tab tab = Tabs.getInstance().getTab(tabId);
             if (tab != null) {
                 tab.updateFaviconURL(href);
 
                 // If tab is not loading and the favicon is updated, we
                 // want to load the image straight away. If tab is still
                 // loading, we only load the favicon once the page's content
                 // is fully loaded (see handleContentLoaded()).
@@ -1263,16 +1267,17 @@ abstract public class GeckoApp
 
         setContentView(R.layout.gecko_app);
         mAppContext = this;
 
         if (Build.VERSION.SDK_INT >= 11) {
             GeckoActionBar actionBar = new GeckoActionBar();
             mBrowserToolbar = (BrowserToolbar) getLayoutInflater().inflate(R.layout.gecko_app_actionbar, null);
 
+            actionBar.setBackgroundDrawable(this, getResources().getDrawable(R.drawable.gecko_actionbar_bg));
             actionBar.setDisplayOptions(this, ActionBar.DISPLAY_SHOW_CUSTOM, ActionBar.DISPLAY_SHOW_CUSTOM |
                                                                              ActionBar.DISPLAY_SHOW_HOME |
                                                                              ActionBar.DISPLAY_SHOW_TITLE |
                                                                              ActionBar.DISPLAY_USE_LOGO);
             actionBar.setCustomView(this, mBrowserToolbar);
         } else {
             mBrowserToolbar = (BrowserToolbar) findViewById(R.id.browser_toolbar);
         }
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -952,17 +952,21 @@ public class GeckoAppShell
     }
 
     public static String showFilePicker(String aFilters) {
         return GeckoApp.mAppContext.
             showFilePicker(getMimeTypeFromExtensions(aFilters));
     }
 
     public static void performHapticFeedback(boolean aIsLongPress) {
-        // TODO
+        LayerController layerController = GeckoApp.mAppContext.getLayerController();
+        LayerView layerView = layerController.getView();
+        layerView.performHapticFeedback(aIsLongPress ?
+                                        HapticFeedbackConstants.LONG_PRESS :
+                                        HapticFeedbackConstants.VIRTUAL_KEY);
     }
 
     private static Vibrator vibrator() {
         LayerController layerController = GeckoApp.mAppContext.getLayerController();
         LayerView layerView = layerController.getView();
 
         return (Vibrator) layerView.getContext().getSystemService(Context.VIBRATOR_SERVICE);
     }
--- a/mobile/android/base/GeckoPreferences.java
+++ b/mobile/android/base/GeckoPreferences.java
@@ -110,17 +110,17 @@ public class GeckoPreferences
             if (pref instanceof PreferenceGroup)
                 initGroups((PreferenceGroup)pref);
             else {
                 pref.setOnPreferenceChangeListener(this);
                 mPreferencesList.add(pref.getKey());
             }
         }
     }
-    
+
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
             case android.R.id.home:
                 finish();
                 return true;
         }
 
@@ -128,58 +128,40 @@ public class GeckoPreferences
     }
 
     @Override
     public boolean onPreferenceChange(Preference preference, Object newValue) {
         String prefName = preference.getKey();
         setPreference(prefName, newValue);
         if (preference instanceof ListPreference)
             ((ListPreference)preference).setSummary((String)newValue);
+        if (preference instanceof LinkPreference)
+            finish();
         return true;
     }
 
     private void refresh(JSONArray jsonPrefs) {
         // enable all preferences once we have them from gecko
         GeckoAppShell.getMainHandler().post(new Runnable() {
             public void run() {
                 mPreferenceScreen.setEnabled(true);
             }
         });
 
         try {
             if (mPreferenceScreen == null)
                 return;
 
-            // set the current page URL for the "Home page" preference
-            final String[] homepageValues = getResources().getStringArray(R.array.pref_homepage_values);
-            final Preference homepagePref = mPreferenceScreen.findPreference("browser.startup.homepage");
-            GeckoAppShell.getMainHandler().post(new Runnable() {
-                public void run() {
-                    Tab tab = Tabs.getInstance().getSelectedTab();
-                    homepageValues[2] = tab.getURL();
-                    ((ListPreference)homepagePref).setEntryValues(homepageValues);
-                }
-            });
-
             final int length = jsonPrefs.length();
             for (int i = 0; i < length; i++) {
                 JSONObject jPref = jsonPrefs.getJSONObject(i);
                 final String prefName = jPref.getString("name");
                 final String prefType = jPref.getString("type");
                 final Preference pref = mPreferenceScreen.findPreference(prefName);
 
-                if (prefName.equals("browser.startup.homepage")) {
-                    final String value = jPref.getString("value");
-                    GeckoAppShell.getMainHandler().post(new Runnable() {
-                        public void run() {
-                            pref.setSummary(value);
-                        }
-                    });
-                }
-
                 if (pref instanceof CheckBoxPreference && "bool".equals(prefType)) {
                     final boolean value = jPref.getBoolean("value");
                     GeckoAppShell.getMainHandler().post(new Runnable() {
                         public void run() {
                             if (((CheckBoxPreference)pref).isChecked() != value)
                                 ((CheckBoxPreference)pref).setChecked(value);
                         }
                     });
--- a/mobile/android/base/GlobalHistory.java
+++ b/mobile/android/base/GlobalHistory.java
@@ -38,22 +38,23 @@
 package org.mozilla.gecko;
 
 import java.util.Ha