Merge last green changeset from mozilla-inbound to mozilla-central
authorMarco Bonardo <mbonardo@mozilla.com>
Fri, 19 Aug 2011 11:39:42 +0200
changeset 75528 1881f9b5f8b50fa29a6b4f9885948e9ce632d22b
parent 75480 6181ba4693f9face8f50d367f3de5593b500742d (current diff)
parent 75527 54a15fc04437f437a88253f971e343b03f591b0a (diff)
child 75531 d963476cbf67a6a4e10223806842fa8af28ff03d
push id21031
push usermak77@bonardo.net
push dateFri, 19 Aug 2011 09:40:40 +0000
treeherdermozilla-central@1881f9b5f8b5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone9.0a1
first release with
nightly linux32
1881f9b5f8b5 / 9.0a1 / 20110819030749 / files
nightly linux64
1881f9b5f8b5 / 9.0a1 / 20110819030749 / files
nightly mac
1881f9b5f8b5 / 9.0a1 / 20110819030749 / files
nightly win32
1881f9b5f8b5 / 9.0a1 / 20110819030749 / files
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
Merge last green changeset from mozilla-inbound to mozilla-central
content/base/src/nsGkAtomList.h
docshell/base/nsIGlobalHistory3.idl
js/src/jit-test/tests/bug666448.js
modules/libreg/src/mmapio.c
modules/libreg/src/mmapio.h
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -876,17 +876,17 @@ pref("browser.privatebrowsing.autostart"
 // Whether we should skip prompting before starting the private browsing mode
 pref("browser.privatebrowsing.dont_prompt_on_enter", false);
 
 // Don't try to alter this pref, it'll be reset the next time you use the
 // bookmarking dialog
 pref("browser.bookmarks.editDialog.firstEditField", "namePicker");
 
 // base url for the wifi geolocation network provider
-pref("geo.wifi.uri", "https://www.google.com/loc/json");
+pref("geo.wifi.uri", "https://maps.googleapis.com/maps/api/browserlocation/json");
 pref("geo.wifi.protocol", 0);
 
 // Whether to use a panel that looks like an OS X sheet for customization
 #ifdef XP_MACOSX
 pref("toolbar.customization.usesheet", true);
 #else
 pref("toolbar.customization.usesheet", false);
 #endif
--- a/build/mobile/sutagent/android/watcher/WatcherService.java
+++ b/build/mobile/sutagent/android/watcher/WatcherService.java
@@ -102,17 +102,16 @@ public class WatcherService extends Serv
     private Method mStartForeground;
     private Method mStopForeground;
     private Object[] mSetForegroundArgs = new Object[1];
     private Object[] mStartForegroundArgs = new Object[2];
     private Object[] mStopForegroundArgs = new Object[1];
 
 
     private IWatcherService.Stub stub = new IWatcherService.Stub() {
-        @Override
         public int UpdateApplication(String sAppName, String sFileName, String sOutFile, int bReboot) throws RemoteException
             {
             return UpdtApp(sAppName, sFileName, sOutFile, bReboot);
             }
     };
 
     @Override
     public IBinder onBind(Intent arg0) {
@@ -869,17 +868,16 @@ public class WatcherService extends Serv
             runner = new Thread(this);
             msPkgName = sPkgName;
             msPkgFileName = sPkgFileName;
             msOutFile = sOutFile;
             mbReboot = bReboot;
             runner.start();
         }
 
-        @Override
         public void run() {
                bInstalling = true;
             UpdtApp(msPkgName, msPkgFileName, msOutFile, mbReboot);
                bInstalling = false;
         }
     }
 
     private class MyTime extends TimerTask
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -1732,17 +1732,18 @@ nsScriptSecurityManager::CheckFunctionAc
     nsIPrincipal* subject =
         GetFunctionObjectPrincipal(aCx, (JSObject *)aFunObj, nsnull, &rv);
 
     // If subject is null, get a principal from the function object's scope.
     if (NS_SUCCEEDED(rv) && !subject)
     {
 #ifdef DEBUG
         {
-            JSFunction *fun = GET_FUNCTION_PRIVATE(cx, (JSObject *)aFunObj);
+            JS_ASSERT(JS_ObjectIsFunction(aCx, (JSObject *)aFunObj));
+            JSFunction *fun = (JSFunction *)JS_GetPrivate(aCx, (JSObject *)aFunObj);
             JSScript *script = JS_GetFunctionScript(aCx, fun);
 
             NS_ASSERTION(!script, "Null principal for non-native function!");
         }
 #endif
 
         subject = doGetObjectPrincipal((JSObject*)aFunObj);
     }
@@ -2213,17 +2214,17 @@ nsScriptSecurityManager::GetFunctionObje
     {
         // Protect against pseudo-functions (like SJOWs).
         nsIPrincipal *result = doGetObjectPrincipal(obj);
         if (!result)
             *rv = NS_ERROR_FAILURE;
         return result;
     }
 
-    JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj);
+    JSFunction *fun = (JSFunction *)JS_GetPrivate(cx, obj);
     JSScript *script = JS_GetFunctionScript(cx, fun);
 
     if (!script)
     {
         // A native function: skip it in order to find its scripted caller.
         return nsnull;
     }
 
@@ -2279,17 +2280,17 @@ nsScriptSecurityManager::GetFramePrincip
         return GetScriptPrincipal(cx, script, rv);
     }
 
     nsIPrincipal* result = GetFunctionObjectPrincipal(cx, obj, fp, rv);
 
 #ifdef DEBUG
     if (NS_SUCCEEDED(*rv) && !result)
     {
-        JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj);
+        JSFunction *fun = (JSFunction *)JS_GetPrivate(cx, obj);
         JSScript *script = JS_GetFunctionScript(cx, fun);
 
         NS_ASSERTION(!script, "Null principal for non-native function!");
     }
 #endif
 
     return result;
 }
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -218,17 +218,16 @@ MOZ_POST_DSO_LIB_COMMAND = @MOZ_POST_DSO
 MOZ_POST_PROGRAM_COMMAND = @MOZ_POST_PROGRAM_COMMAND@
 
 MOZ_BUILD_ROOT             = @MOZ_BUILD_ROOT@
 
 MOZ_XUL                    = @MOZ_XUL@
 MOZ_RDF                    = @MOZ_RDF@
 
 NECKO_PROTOCOLS = @NECKO_PROTOCOLS@
-NECKO_DISK_CACHE = @NECKO_DISK_CACHE@
 NECKO_COOKIES = @NECKO_COOKIES@
 NECKO_WIFI = @NECKO_WIFI@
 MOZ_AUTH_EXTENSION = @MOZ_AUTH_EXTENSION@
 
 MOZ_NATIVE_HUNSPELL = @SYSTEM_HUNSPELL@
 MOZ_HUNSPELL_LIBS = @MOZ_HUNSPELL_LIBS@
 MOZ_HUNSPELL_CFLAGS = @MOZ_HUNSPELL_CFLAGS@
 
--- a/configure.in
+++ b/configure.in
@@ -2102,16 +2102,18 @@ case "$target" in
     DSO_LDOPTS=''
     STRIP="$STRIP -x -S"
     _PLATFORM_DEFAULT_TOOLKIT='cairo-cocoa'
     TARGET_NSPR_MDCPUCFG='\"md/_darwin.cfg\"'
     # The ExceptionHandling framework is needed for Objective-C exception
     # logging code in nsObjCExceptions.h. Currently we only use that in debug
     # builds.
     MOZ_DEBUG_LDFLAGS="$MOZ_DEBUG_LDFLAGS -framework ExceptionHandling"
+    # Debug builds should always have frame pointers
+    MOZ_DEBUG_FLAGS="-g -fno-omit-frame-pointer"
 
     if test "x$lto_is_enabled" = "xyes"; then
         echo "Skipping -dead_strip because lto is enabled."
     dnl DTrace and -dead_strip don't interact well. See bug 403132.
     dnl ===================================================================
     elif test "x$enable_dtrace" = "xyes"; then
         echo "Skipping -dead_strip because DTrace is enabled. See bug 403132."
     else
@@ -2248,16 +2250,18 @@ ia64*-hpux*)
 
     MOZ_GFX_OPTIMIZE_MOBILE=1
     # If we're building with --enable-profiling, we need a frame pointer.
     if test -z "$MOZ_PROFILING"; then
         MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks -fno-reorder-functions -fomit-frame-pointer"
     else
         MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks -fno-reorder-functions -fno-omit-frame-pointer"
     fi
+    # Debug builds should always have frame pointers
+    MOZ_DEBUG_FLAGS="-g -fno-omit-frame-pointer"
     ;;
 
 *-*linux*)
     # Note: both GNU_CC and INTEL_CC are set when using Intel's C compiler.
     # Similarly for GNU_CXX and INTEL_CXX.
     if test "$INTEL_CC" -o "$INTEL_CXX"; then
         # -Os has been broken on Intel's C/C++ compilers for quite a
         # while; Intel recommends against using it.
@@ -2273,17 +2277,18 @@ ia64*-hpux*)
         # If we're building with --enable-profiling, we need a frame pointer.
         if test -z "$MOZ_PROFILING"; then
             MOZ_FRAMEPTR_FLAGS="-fomit-frame-pointer"
         else
             MOZ_FRAMEPTR_FLAGS="-fno-omit-frame-pointer"
         fi
         MOZ_PGO_OPTIMIZE_FLAGS="-O3 $MOZ_FRAMEPTR_FLAGS"
         MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks $MOZ_OPTIMIZE_SIZE_TWEAK $MOZ_FRAMEPTR_FLAGS"
-        MOZ_DEBUG_FLAGS="-g"
+        # Debug builds should always have frame pointers
+        MOZ_DEBUG_FLAGS="-g -fno-omit-frame-pointer"
     fi
 
     TARGET_NSPR_MDCPUCFG='\"md/_linux.cfg\"'
 
     MOZ_MEMORY=1
 
     case "${target_cpu}" in
     alpha*)
@@ -2366,17 +2371,18 @@ ia64*-hpux*)
         _DEFINES_CXXFLAGS='-FI $(DEPTH)/dist/include/mozilla-config.h -DMOZILLA_CLIENT'
         CFLAGS="$CFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
         CXXFLAGS="$CXXFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
         CXXFLAGS="$CXXFLAGS -wd4800" # disable warning "forcing value to bool"
         # make 'foo == bar;' error out
         CFLAGS="$CFLAGS -we4553"
         CXXFLAGS="$CXXFLAGS -we4553"
         LIBS="$LIBS kernel32.lib user32.lib gdi32.lib winmm.lib wsock32.lib advapi32.lib"
-        MOZ_DEBUG_FLAGS='-Zi'
+        # Debug builds should always have frame pointers
+        MOZ_DEBUG_FLAGS='-Zi -Oy-'
         MOZ_DEBUG_LDFLAGS='-DEBUG -DEBUGTYPE:CV'
         WARNINGS_AS_ERRORS='-WX'
         # If we're building with --enable-profiling, we need -Oy-, which forces a frame pointer.
         if test -z "$MOZ_PROFILING"; then
             MOZ_OPTIMIZE_FLAGS='-O1'
         else
             MOZ_OPTIMIZE_FLAGS='-O1 -Oy-'
         fi
@@ -3583,63 +3589,16 @@ then
 				CFLAGS="$CFLAGS -mt" 
 				CXXFLAGS="$CXXFLAGS -mt" 
 			fi
 			;;
 	esac
     LDFLAGS="${_PTHREAD_LDFLAGS} ${LDFLAGS}"
 fi
 
-dnl ========================================================
-dnl See if mmap sees writes
-dnl For cross compiling, just define it as no, which is a safe default
-dnl ========================================================
-AC_MSG_CHECKING(whether mmap() sees write()s)
-
-changequote(,)
-mmap_test_prog='
-    #include <stdlib.h>
-    #include <unistd.h>
-    #include <sys/mman.h>
-    #include <sys/types.h>
-    #include <sys/stat.h>
-    #include <fcntl.h>
-
-    char fname[] = "conftest.file";
-    char zbuff[1024]; /* Fractional page is probably worst case */
-
-    int main() {
-	char *map;
-	int fd;
-	int i;
-	unlink(fname);
-	fd = open(fname, O_RDWR | O_CREAT, 0660);
-	if(fd<0) return 1;
-	unlink(fname);
-	write(fd, zbuff, sizeof(zbuff));
-	lseek(fd, 0, SEEK_SET);
-	map = (char*)mmap(0, sizeof(zbuff), PROT_READ, MAP_SHARED, fd, 0);
-	if(map==(char*)-1) return 2;
-	for(i=0; fname[i]; i++) {
-	    int rc = write(fd, &fname[i], 1);
-	    if(map[i]!=fname[i]) return 4;
-	}
-	return 0;
-    }
-'
-changequote([,])
-
-AC_TRY_RUN($mmap_test_prog , result="yes", result="no", result="yes")
-
-AC_MSG_RESULT("$result")
-
-if test "$result" = "no"; then
-    AC_DEFINE(MMAP_MISSES_WRITES)
-fi
-
 
 dnl Checks for library functions.
 dnl ========================================================
 AC_PROG_GCC_TRADITIONAL
 AC_FUNC_MEMCMP
 AC_CHECK_FUNCS(random strerror lchown fchmod snprintf statvfs memmove rint stat64 lstat64 truncate64 statvfs64 setbuf isatty)
 AC_CHECK_FUNCS(flockfile getpagesize)
 AC_CHECK_FUNCS(localtime_r strtok_r)
@@ -4773,17 +4732,16 @@ MOZ_XTF=1
 MOZ_XUL=1
 MOZ_ZIPWRITER=1
 NS_PRINTING=1
 MOZ_PDF_PRINTING=
 MOZ_DISABLE_DOMCRYPTO=
 NSS_DISABLE_DBM=
 NECKO_WIFI=1
 NECKO_COOKIES=1
-NECKO_DISK_CACHE=1
 NECKO_PROTOCOLS_DEFAULT="about data file ftp http res viewsource websocket wyciwyg"
 USE_ARM_KUSER=
 BUILD_CTYPES=1
 MOZ_USE_NATIVE_POPUP_WINDOWS=
 
 
 case "${target}" in
 *android*|*darwin*)
@@ -5189,30 +5147,31 @@ incorrect])
                       MOZ_ENABLE_QTNETWORK=)
 
     if test "$MOZ_ENABLE_QTNETWORK"; then
       MOZ_ENABLE_QTNETWORK=1
       AC_DEFINE(MOZ_ENABLE_QTNETWORK)
     fi
 
     MOZ_ENABLE_QTMOBILITY=
-    PKG_CHECK_MODULES(_QTMOBILITY, QtSensors QtFeedback,
+    PKG_CHECK_MODULES(_QTMOBILITY, QtSensors QtFeedback QtLocation,
                       MOZ_ENABLE_QTMOBILITY=1,
                       MOZ_ENABLE_QTMOBILITY=)
     if test "$MOZ_ENABLE_QTMOBILITY"; then
        MOZ_ENABLE_QTMOBILITY=1
        MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS $_QTMOBILITY_CFLAGS"
        MOZ_QT_LIBS="$MOZ_QT_LIBS $_QTMOBILITY_LIBS"
     else
-       AC_CHECK_LIB(QtSensors QtFeedback, main, [
+       AC_CHECK_LIB(QtSensors QtFeedback QtLocation, main, [
           MOZ_ENABLE_QTMOBILITY=1
           MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I/usr/include/qt4/QtMobility"
           MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I/usr/include/qt4/QtSensors"
           MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I/usr/include/qt4/QtFeedback"
-          MOZ_QT_LIBS="$MOZ_QT_LIBS -lQtSensors -lQtFeedback"
+          MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I/usr/include/qt4/QtLocation"
+          MOZ_QT_LIBS="$MOZ_QT_LIBS -lQtSensors -lQtFeedback -lQtLocation"
        ])
     fi
     if test "$MOZ_ENABLE_QTMOBILITY"; then
        AC_DEFINE(MOZ_ENABLE_QTMOBILITY)
     fi
 fi
 
 AC_SUBST(GTK_CONFIG)
@@ -8760,29 +8719,16 @@ done],
 dnl Remove dupes
 NECKO_PROTOCOLS=`${PERL} ${srcdir}/build/unix/uniq.pl ${NECKO_PROTOCOLS}`
 AC_SUBST(NECKO_PROTOCOLS)
 for p in $NECKO_PROTOCOLS; do
     AC_DEFINE_UNQUOTED(NECKO_PROTOCOL_$p)
 done
 
 dnl
-dnl option to disable necko's disk cache
-dnl
-MOZ_ARG_DISABLE_BOOL(necko-disk-cache,
-[  --disable-necko-disk-cache
-                          Disable necko disk cache],
-    NECKO_DISK_CACHE=,
-    NECKO_DISK_CACHE=1)
-AC_SUBST(NECKO_DISK_CACHE)
-if test "$NECKO_DISK_CACHE"; then
-    AC_DEFINE(NECKO_DISK_CACHE)
-fi
-
-dnl
 dnl option to disable necko's wifi scanner
 dnl
 MOZ_ARG_DISABLE_BOOL(necko-wifi,
 [  --disable-necko-wifi    Disable necko wifi scanner],
     NECKO_WIFI=,
     NECKO_WIFI=1)
 
 if test "$OS_ARCH" = "OS2"; then
--- a/content/base/src/Makefile.in
+++ b/content/base/src/Makefile.in
@@ -90,16 +90,17 @@ CPPSRCS		= \
 		nsContentUtils.cpp \
 		nsCopySupport.cpp \
 		nsCrossSiteListenerProxy.cpp \
 		nsCSPService.cpp \
 		nsDataDocumentContentPolicy.cpp \
 		nsDOMAttribute.cpp \
 		nsDOMAttributeMap.cpp \
 		nsDOMBlobBuilder.cpp \
+		nsDOMCaretPosition.cpp \
 		nsDOMDocumentType.cpp \
 		nsDOMEventTargetWrapperCache.cpp \
 		nsDOMFile.cpp \
 		nsDOMFileReader.cpp \
 		nsDOMLists.cpp \
 		nsDOMParser.cpp \
 		nsDOMSerializer.cpp \
 		nsDOMTokenList.cpp \
new file mode 100644
--- /dev/null
+++ b/content/base/src/nsDOMCaretPosition.cpp
@@ -0,0 +1,77 @@
+/* ***** 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.org.
+ *
+ * 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):
+ *   Brad Lassey <blassey@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsDOMCaretPosition.h"
+#include "nsDOMClassInfoID.h"
+#include "nsIDOMClassInfo.h"
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMCaretPosition)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCaretPosition)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMCaretPosition)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CaretPosition)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTION_1(nsDOMCaretPosition, mNode)
+ 
+NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMCaretPosition)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMCaretPosition)
+
+DOMCI_DATA(CaretPosition, nsDOMCaretPosition)
+
+
+nsDOMCaretPosition::nsDOMCaretPosition(nsIDOMNode* aNode, PRUint32 aOffset)
+  : mNode(aNode), mOffset(aOffset)
+{
+}
+
+nsDOMCaretPosition::~nsDOMCaretPosition()
+{
+}
+
+NS_IMETHODIMP nsDOMCaretPosition::GetOffsetNode(nsIDOMNode** aOffsetNode)
+{
+  nsCOMPtr<nsIDOMNode> node = mNode;
+  node.forget(aOffsetNode);
+  return NS_OK;
+}
+
+NS_IMETHODIMP nsDOMCaretPosition::GetOffset(PRUint32* aOffset)
+{
+  *aOffset = mOffset;
+  return NS_OK;
+}
+
new file mode 100644
--- /dev/null
+++ b/content/base/src/nsDOMCaretPosition.h
@@ -0,0 +1,59 @@
+/* ***** 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.org.
+ *
+ * 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):
+ *   Brad Lassey <blassey@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * 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 ***** */
+
+#ifndef nsDOMCaretPosition_h
+#define nsDOMCaretPosition_h
+
+#include "nsIDOMCaretPosition.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsCOMPtr.h"
+
+class nsDOMCaretPosition : public nsIDOMCaretPosition
+{
+public:
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_CLASS(nsDOMCaretPosition)
+  NS_DECL_NSIDOMCARETPOSITION
+
+  nsDOMCaretPosition(nsIDOMNode* aNode, PRUint32 aOffset);
+
+protected:
+  virtual ~nsDOMCaretPosition();
+  PRUint32 mOffset;
+  nsCOMPtr<nsIDOMNode> mNode;
+};
+#endif
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -197,19 +197,23 @@
 #include "nsHTMLCSSStyleSheet.h"
 
 #include "mozilla/dom/Link.h"
 #include "nsIHTMLDocument.h"
 #include "nsXULAppAPI.h"
 #include "nsDOMTouchEvent.h"
 
 #include "mozilla/Preferences.h"
+#include "nsFrame.h"
 
 #include "imgILoader.h"
 
+#include "nsDOMCaretPosition.h"
+#include "nsIDOMHTMLTextAreaElement.h"
+
 using namespace mozilla;
 using namespace mozilla::dom;
 
 typedef nsTArray<Link*> LinkArray;
 
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gDocumentLeakPRLog;
@@ -8389,16 +8393,68 @@ nsDocument::CreateTouchList(nsIVariant* 
       nsMemory::Free(rawArray);
     }
   }
 
   *aRetVal = retval.forget().get();
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsDocument::CaretPositionFromPoint(float aX, float aY, nsIDOMCaretPosition** aCaretPos)
+{
+  NS_ENSURE_ARG_POINTER(aCaretPos);
+  *aCaretPos = nsnull;
+  
+  nscoord x = nsPresContext::CSSPixelsToAppUnits(aX);
+  nscoord y = nsPresContext::CSSPixelsToAppUnits(aY);
+  nsPoint pt(x, y);
+
+  nsIPresShell *ps = GetShell();
+  if (!ps) {
+    return NS_OK;
+  }
+
+  nsIFrame *rootFrame = ps->GetRootFrame();
+
+  // XUL docs, unlike HTML, have no frame tree until everything's done loading
+  if (!rootFrame) {
+    return NS_OK; // return null to premature XUL callers as a reminder to wait
+  }
+
+  nsIFrame *ptFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, pt, PR_TRUE,
+                                                      PR_FALSE);
+  if (!ptFrame) {
+    return NS_OK;
+  }
+
+  nsFrame::ContentOffsets offsets = ptFrame->GetContentOffsetsFromPoint(pt);
+  nsCOMPtr<nsIDOMNode> node = do_QueryInterface(offsets.content);
+  nsIContent* ptContent = offsets.content;
+  PRInt32 offset = offsets.offset;
+  if (ptContent && ptContent->IsInNativeAnonymousSubtree()) {
+    nsIContent* nonanon = ptContent->FindFirstNonNativeAnonymous();
+    nsCOMPtr<nsIDOMHTMLInputElement> input = do_QueryInterface(nonanon);
+    nsCOMPtr<nsIDOMHTMLTextAreaElement> textArea = do_QueryInterface(nonanon);
+    PRBool isText;
+    if (textArea || (input &&
+                     NS_SUCCEEDED(input->MozIsTextField(PR_FALSE, &isText)) && 
+                     isText)) {
+      node = do_QueryInterface(nonanon);
+    } else {
+      node = nsnull;
+      offset = 0;
+    }
+  }
+
+  *aCaretPos = new nsDOMCaretPosition(node, offset);
+  NS_ADDREF(*aCaretPos);
+  return NS_OK;
+}
+
 PRInt64
 nsIDocument::SizeOf() const
 {
   PRInt64 size = sizeof(*this);
 
   for (nsIContent* node = GetFirstChild(); node;
        node = node->GetNextNode(this)) {
     size += node->SizeOf();
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -1054,18 +1054,19 @@ nsINode::AddEventListener(const nsAStrin
   if (!aWantsUntrusted &&
       (aOptionalArgc < 2 &&
        !nsContentUtils::IsChromeDoc(GetOwnerDoc()))) {
     aWantsUntrusted = PR_TRUE;
   }
 
   nsEventListenerManager* listener_manager = GetListenerManager(PR_TRUE);
   NS_ENSURE_STATE(listener_manager);
-  return listener_manager->AddEventListener(aType, aListener, aUseCapture,
-                                            aWantsUntrusted);
+  listener_manager->AddEventListener(aType, aListener, aUseCapture,
+                                     aWantsUntrusted);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsINode::RemoveEventListener(const nsAString& aType,
                              nsIDOMEventListener* aListener,
                              PRBool aUseCapture)
 {
   nsEventListenerManager* elm = GetListenerManager(PR_FALSE);
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1869,16 +1869,17 @@ GK_ATOM(scrollbar_start_backward, "scrol
 GK_ATOM(scrollbar_start_forward, "scrollbar-start-forward")
 GK_ATOM(scrollbar_end_backward, "scrollbar-end-backward")
 GK_ATOM(scrollbar_end_forward, "scrollbar-end-forward")
 GK_ATOM(scrollbar_thumb_proportional, "scrollbar-thumb-proportional")
 GK_ATOM(images_in_menus, "images-in-menus")
 GK_ATOM(images_in_buttons, "images-in-buttons")
 GK_ATOM(windows_default_theme, "windows-default-theme")
 GK_ATOM(mac_graphite_theme, "mac-graphite-theme")
+GK_ATOM(mac_lion_theme, "mac-lion-theme")
 GK_ATOM(windows_compositor, "windows-compositor")
 GK_ATOM(touch_enabled, "touch-enabled")
 GK_ATOM(maemo_classic, "maemo-classic")
 GK_ATOM(menubar_drag, "menubar-drag")
 
 // windows theme selector metrics
 GK_ATOM(windows_classic, "windows-classic")
 GK_ATOM(windows_theme_aero, "windows-theme-aero")
@@ -1894,16 +1895,17 @@ GK_ATOM(_moz_scrollbar_start_backward, "
 GK_ATOM(_moz_scrollbar_start_forward, "-moz-scrollbar-start-forward")
 GK_ATOM(_moz_scrollbar_end_backward, "-moz-scrollbar-end-backward")
 GK_ATOM(_moz_scrollbar_end_forward, "-moz-scrollbar-end-forward")
 GK_ATOM(_moz_scrollbar_thumb_proportional, "-moz-scrollbar-thumb-proportional")
 GK_ATOM(_moz_images_in_menus, "-moz-images-in-menus")
 GK_ATOM(_moz_images_in_buttons, "-moz-images-in-buttons")
 GK_ATOM(_moz_windows_default_theme, "-moz-windows-default-theme")
 GK_ATOM(_moz_mac_graphite_theme, "-moz-mac-graphite-theme")
+GK_ATOM(_moz_mac_lion_theme, "-moz-mac-lion-theme")
 GK_ATOM(_moz_windows_compositor, "-moz-windows-compositor")
 GK_ATOM(_moz_windows_classic, "-moz-windows-classic")
 GK_ATOM(_moz_windows_theme, "-moz-windows-theme")
 GK_ATOM(_moz_touch_enabled, "-moz-touch-enabled")
 GK_ATOM(_moz_maemo_classic, "-moz-maemo-classic")
 GK_ATOM(_moz_menubar_drag, "-moz-menubar-drag")
 GK_ATOM(_moz_device_pixel_ratio, "-moz-device-pixel-ratio")
 GK_ATOM(_moz_device_orientation, "-moz-device-orientation")
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -498,16 +498,17 @@ include $(topsrcdir)/config/rules.mk
 		invalid_accesscontrol.resource^headers^ \
 		somedatas.resource \
 		somedatas.resource^headers^ \
 		delayedServerEvents.sjs \
 		test_bug664916.html \
 		test_bug666604.html \
 		test_bug675121.html \
 		file_bug675121.sjs \
+		test_bug654352.html \
 		$(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/test_bug654352.html
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=654352
+-->
+<head>
+  <title>Test for Bug 654352</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=654352">Mozilla Bug 654352</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+/** Test for Bug 654352 **/
+SimpleTest.waitForExplicitFinish();
+function afterLoad() {
+  var testpre = document.getElementById("testpre");
+  var rect1 = testpre.getBoundingClientRect();
+  dump(rect1 + "\n");
+  var caret1 = document.caretPositionFromPoint(rect1.right - 5, rect1.top + 10);
+  ok(caret1.offsetNode == testpre.firstChild, "node in CaretPosition not correct (" + caret1.offsetNode + " == " + testpre.firstChild + ")")
+  ok(caret1.offset == 9, "offset in CaretPosition not correct (" + caret1.offset + "== 9)")
+
+  var testinput = document.getElementById("testinput");
+  var rect2 = testinput.getBoundingClientRect();
+  dump(rect2.top +", " + rect2.left + "\n");
+  var caret2 = document.caretPositionFromPoint( rect2.right - 5, rect2.top + 10);
+  ok(caret2.offsetNode == testinput, "node in CaretPosition not correct (" + caret2.offsetNode + " == " + testinput + ")")
+  ok(caret2.offset == 9, "offset in CaretPosition not correct (" + caret2.offset + "== 9)")
+  SimpleTest.finish();
+};
+addLoadEvent(afterLoad);
+</script>
+</pre>
+<span id="testdiv">
+  <pre id="testpre">test text</pre>
+</span>
+<br>
+<br>
+</div>
+  <input id="testinput" type="text" value="test text"></input>
+</div>
+</body>
+</html>
--- a/content/base/test/test_copypaste.html
+++ b/content/base/test/test_copypaste.html
@@ -48,18 +48,18 @@ function testCopyPaste () {
 
   var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]
                             .getService(Components.interfaces.nsIClipboard);
 
   var textarea = document.getElementById('input');
 
   function copySelectionToClipboard() {
     documentViewer.copySelection();
-    is(clipboard.hasDataMatchingFlavors(["text/unicode"], 1,1), true);
-    is(clipboard.hasDataMatchingFlavors(["text/html"], 1,1), true);
+    ok(clipboard.hasDataMatchingFlavors(["text/unicode"], 1,1), "check text/unicode");
+    ok(clipboard.hasDataMatchingFlavors(["text/html"], 1,1), "check text/html");
   }
   function copyToClipboard(node) {
     textarea.blur();
     clipboard.emptyClipboard(1);
     var sel = window.getSelection();
     sel.removeAllRanges();
     var r = document.createRange();
     r.selectNode(node);
--- a/content/events/src/nsDOMEventTargetHelper.cpp
+++ b/content/events/src/nsDOMEventTargetHelper.cpp
@@ -121,17 +121,18 @@ nsDOMEventTargetHelper::AddEventListener
     NS_ENSURE_SUCCESS(rv, rv);
     nsCOMPtr<nsIDocument> doc =
       nsContentUtils::GetDocumentFromScriptContext(context);
     aWantsUntrusted = doc && !nsContentUtils::IsChromeDoc(doc);
   }
 
   nsEventListenerManager* elm = GetListenerManager(PR_TRUE);
   NS_ENSURE_STATE(elm);
-  return elm->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted);
+  elm->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMEventTargetHelper::DispatchEvent(nsIDOMEvent* aEvent, PRBool* aRetVal)
 {
   nsEventStatus status = nsEventStatus_eIgnore;
   nsresult rv =
     nsEventDispatcher::DispatchDOMEvent(this, nsnull, aEvent, nsnull, &status);
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -204,34 +204,37 @@ nsEventListenerManager::GetInnerWindowFo
   if (window) {
     NS_ASSERTION(window->IsInnerWindow(), "Target should not be an outer window");
     return window;
   }
 
   return nsnull;
 }
 
-nsresult
+void
 nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener,
                                          PRUint32 aType,
                                          nsIAtom* aTypeAtom,
                                          PRInt32 aFlags)
 {
-  NS_ENSURE_TRUE(aListener, NS_ERROR_FAILURE);
-  NS_ENSURE_TRUE(aType, NS_ERROR_FAILURE);
+  NS_ABORT_IF_FALSE(aType && aTypeAtom, "Missing type");
+
+  if (!aListener) {
+    return;
+  }
 
   nsRefPtr<nsIDOMEventListener> kungFuDeathGrip = aListener;
 
   nsListenerStruct* ls;
   PRUint32 count = mListeners.Length();
   for (PRUint32 i = 0; i < count; i++) {
     ls = &mListeners.ElementAt(i);
     if (ls->mListener == aListener && ls->mFlags == aFlags &&
         EVENT_TYPE_EQUALS(ls, aType, aTypeAtom)) {
-      return NS_OK;
+      return;
     }
   }
 
   mNoListenerForEvent = NS_EVENT_TYPE_NULL;
   mNoListenerForEventAtom = nsnull;
 
   ls = mListeners.AppendElement();
   ls->mListener = aListener;
@@ -286,18 +289,16 @@ nsEventListenerManager::AddEventListener
               aTypeAtom == nsGkAtoms::ontouchenter ||
               aTypeAtom == nsGkAtoms::ontouchleave ||
               aTypeAtom == nsGkAtoms::ontouchcancel)) {
     mMayHaveTouchEventListener = PR_TRUE;
     nsPIDOMWindow* window = GetInnerWindowForTarget();
     if (window)
       window->SetHasTouchEventListeners();
   }
-
-  return NS_OK;
 }
 
 void
 nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener, 
                                             PRUint32 aType,
                                             nsIAtom* aUserType,
                                             PRInt32 aFlags)
 {
@@ -329,24 +330,24 @@ ListenerCanHandle(nsListenerStruct* aLs,
   // This is slightly different from EVENT_TYPE_EQUALS in that it returns
   // true even when aEvent->message == NS_USER_DEFINED_EVENT and
   // aLs=>mEventType != NS_USER_DEFINED_EVENT as long as the atoms are the same
   return aEvent->message == NS_USER_DEFINED_EVENT ?
     (aLs->mTypeAtom == aEvent->userType) :
     (aLs->mEventType == aEvent->message);
 }
 
-nsresult
+void
 nsEventListenerManager::AddEventListenerByType(nsIDOMEventListener *aListener, 
                                                const nsAString& aType,
                                                PRInt32 aFlags)
 {
   nsCOMPtr<nsIAtom> atom = do_GetAtom(NS_LITERAL_STRING("on") + aType);
   PRUint32 type = nsContentUtils::GetEventId(atom);
-  return AddEventListener(aListener, type, atom, aFlags);
+  AddEventListener(aListener, type, atom, aFlags);
 }
 
 void
 nsEventListenerManager::RemoveEventListenerByType(nsIDOMEventListener *aListener, 
                                                   const nsAString& aType,
                                                   PRInt32 aFlags)
 {
   nsCOMPtr<nsIAtom> atom = do_GetAtom(NS_LITERAL_STRING("on") + aType);
@@ -938,18 +939,17 @@ nsEventListenerManager::HandleEventInter
 
 void
 nsEventListenerManager::Disconnect()
 {
   mTarget = nsnull;
   RemoveAllListeners();
 }
 
-// nsIDOMEventTarget interface
-nsresult
+void
 nsEventListenerManager::AddEventListener(const nsAString& aType,
                                          nsIDOMEventListener* aListener,
                                          PRBool aUseCapture,
                                          PRBool aWantsUntrusted)
 {
   PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
 
   if (aWantsUntrusted) {
--- a/content/events/src/nsEventListenerManager.h
+++ b/content/events/src/nsEventListenerManager.h
@@ -79,31 +79,31 @@ class nsEventListenerManager
 public:
   nsEventListenerManager(nsISupports* aTarget);
   virtual ~nsEventListenerManager();
 
   NS_INLINE_DECL_REFCOUNTING(nsEventListenerManager)
 
   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsEventListenerManager)
 
-  nsresult AddEventListener(const nsAString& aType,
-                            nsIDOMEventListener* aListener,
-                            PRBool aUseCapture,
-                            PRBool aWantsUntrusted);
+  void AddEventListener(const nsAString& aType,
+                        nsIDOMEventListener* aListener,
+                        PRBool aUseCapture,
+                        PRBool aWantsUntrusted);
   void RemoveEventListener(const nsAString& aType,
                            nsIDOMEventListener* aListener,
                            PRBool aUseCapture);
 
   /**
   * Sets events listeners of all types. 
   * @param an event listener
   */
-  nsresult AddEventListenerByType(nsIDOMEventListener *aListener,
-                                  const nsAString& type,
-                                  PRInt32 aFlags);
+  void AddEventListenerByType(nsIDOMEventListener *aListener,
+                              const nsAString& type,
+                              PRInt32 aFlags);
   void RemoveEventListenerByType(nsIDOMEventListener *aListener,
                                  const nsAString& type,
                                  PRInt32 aFlags);
   nsresult AddScriptEventListener(nsIAtom *aName,
                                   const nsAString& aFunc,
                                   PRUint32 aLanguage,
                                   PRBool aDeferCompilation,
                                   PRBool aPermitUntrustedEvents);
@@ -205,20 +205,20 @@ protected:
                                        nsListenerStruct *aListenerStruct,
                                        nsISupports* aCurrentTarget,
                                        PRBool aNeedsCxPush);
   nsListenerStruct* FindJSEventListener(PRUint32 aEventType, nsIAtom* aTypeAtom);
   nsresult SetJSEventListener(nsIScriptContext *aContext,
                               void *aScopeGlobal,
                               nsIAtom* aName, PRBool aIsString,
                               PRBool aPermitUntrustedEvents);
-  nsresult AddEventListener(nsIDOMEventListener *aListener, 
-                            PRUint32 aType,
-                            nsIAtom* aTypeAtom,
-                            PRInt32 aFlags);
+  void AddEventListener(nsIDOMEventListener *aListener, 
+                        PRUint32 aType,
+                        nsIAtom* aTypeAtom,
+                        PRInt32 aFlags);
   void RemoveEventListener(nsIDOMEventListener *aListener,
                            PRUint32 aType,
                            nsIAtom* aUserType,
                            PRInt32 aFlags);
   void RemoveAllListeners();
   const EventTypeData* GetTypeDataForIID(const nsIID& aIID);
   const EventTypeData* GetTypeDataForEventName(nsIAtom* aName);
   nsPIDOMWindow* GetInnerWindowForTarget();
--- a/content/events/src/nsEventListenerService.cpp
+++ b/content/events/src/nsEventListenerService.cpp
@@ -275,17 +275,18 @@ nsEventListenerService::AddSystemEventLi
 
   nsEventListenerManager* manager = aTarget->GetListenerManager(PR_TRUE);
   NS_ENSURE_STATE(manager);
 
   PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE |
                                 NS_EVENT_FLAG_SYSTEM_EVENT :
                                 NS_EVENT_FLAG_BUBBLE |
                                 NS_EVENT_FLAG_SYSTEM_EVENT;
-  return manager->AddEventListenerByType(aListener, aType, flags);
+  manager->AddEventListenerByType(aListener, aType, flags);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsEventListenerService::RemoveSystemEventListener(nsIDOMEventTarget *aTarget,
                                                   const nsAString& aType,
                                                   nsIDOMEventListener* aListener,
                                                   PRBool aUseCapture)
 {
--- a/content/events/test/Makefile.in
+++ b/content/events/test/Makefile.in
@@ -102,16 +102,18 @@ include $(topsrcdir)/config/rules.mk
 		test_bug648573.html \
 		test_bug615597.html \
 		test_bug656379-1.html \
 		test_bug656379-2.html \
 		test_bug656954.html \
 		test_bug662678.html \
 		test_bug667919-1.html \
 		test_bug667919-2.html \
+		test_bug667612.html \
+		empty.js \
 		$(NULL)
 
 #bug 585630
 ifneq (mobile,$(MOZ_BUILD_APP))
 _TEST_FILES += \
 		test_dragstart.html \
 		$(NULL)
 endif
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/content/events/test/test_bug667612.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=667612
+-->
+<head>
+  <title>Test for Bug 667612</title>
+  <script type="text/javascript" src="/MochiKit/packed.js"></script>
+  <script type="text/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=667612">Mozilla Bug 667612</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+xhr = new XMLHttpRequest;
+w = new Worker("empty.js");
+window.addEventListener("load", null, false);
+document.addEventListener("load", null, false);
+document.body.addEventListener("load", null, false);
+xhr.addEventListener("load", null, false);
+w.addEventListener("load", null, false);
+window.addEventListener("load", undefined, false);
+document.addEventListener("load", undefined, false);
+document.body.addEventListener("load", undefined, false);
+xhr.addEventListener("load", undefined, false);
+w.addEventListener("load", undefined, false);
+
+ok(true, "didn't throw");
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/media/test/test_delay_load.html
+++ b/content/media/test/test_delay_load.html
@@ -91,24 +91,26 @@ document.body.appendChild(v);
 
 // Load outside of doc.
 v = createVideo(test.name, test.type, "3");
 v.load();
 
 // Load and move to another document.
 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
 v = createVideo(test.name, test.type, "4");
+v.onloadstart = function(e) {
+  // Opening a new window to do this is a bit annoying, but if we use an iframe here,
+  // delaying of the iframe's load event might interfere with the firing of our load event
+  // in some confusing way. So it's simpler just to open another window.
+  var w = window.open("", "testWindow", "width=400,height=400");
+  w.document.body.appendChild(v);
+  testWindows.push(w);
+};
 v.load(); // load started while in this document, this doc's load will block until
-            // the video's finished loading (in the other document).
-// Opening a new window to do this is a bit annoying, but if we use an iframe here,
-// delaying of the iframe's load event might interfere with the firing of our load event
-// in some confusing way. So it's simpler just to open another window.
-var w = window.open("", "testWindow", "width=400,height=400");
-w.document.body.appendChild(v);
-testWindows.push(w);
+          // the video's finished loading (in the other document).
 
 if (gRegisteredElements.length > 0) {
   SimpleTest.waitForExplicitFinish();
 } else {
   todo(false, "No types supported");
 }
 
 </script>
--- a/docshell/base/Makefile.in
+++ b/docshell/base/Makefile.in
@@ -61,17 +61,16 @@ XPIDLSRCS = \
   nsCDefaultURIFixup.idl \
   nsIDocShell.idl \
   nsIDocShellLoadInfo.idl \
   nsIDocShellTreeItem.idl \
   nsIDocShellTreeNode.idl \
   nsIDocShellTreeOwner.idl \
   nsIDocShellHistory.idl \
   nsIGlobalHistory2.idl \
-  nsIGlobalHistory3.idl \
   nsIMarkupDocumentViewer.idl \
   nsIScrollable.idl \
   nsITextScroll.idl \
   nsIWebNavigation.idl \
   nsIWebNavigationInfo.idl \
   nsIContentViewer.idl \
   nsIContentViewerEdit.idl \
   nsIContentViewerFile.idl \
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -192,17 +192,16 @@
 #include "nsIJARChannel.h"
 
 #include "prlog.h"
 #include "prmem.h"
 
 #include "nsISelectionDisplay.h"
 
 #include "nsIGlobalHistory2.h"
-#include "nsIGlobalHistory3.h"
 
 #ifdef DEBUG_DOCSHELL_FOCUS
 #include "nsEventStateManager.h"
 #endif
 
 #include "nsIFrame.h"
 
 // for embedding
deleted file mode 100644
--- a/docshell/base/nsIGlobalHistory3.idl
+++ /dev/null
@@ -1,103 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * 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 the Mozilla gecko engine.
- *
- * The Initial Developer of the Original Code is
- * Google Inc.
- * Portions created by the Initial Developer are Copyright (C) 2006
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Brett Wilson <brettw@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "nsISupports.idl"
-#include "nsIGlobalHistory2.idl"
-interface nsIChannel;
-
-%{C++
-
-// This is NOT part of the interface! It could change.
-#define NS_GECKO_FLAG_NEEDS_VERTICAL_SCROLLBAR (1 << 0)
-
-%}
-
-/**
- * Provides information about global history to gecko, extending GlobalHistory2
- */
-[scriptable, uuid(24306852-c60e-49c3-a455-90f6747118ba)]
-interface nsIGlobalHistory3 : nsIGlobalHistory2
-{
-  /**
-   * Notifies the history system that the page loading via aOldChannel
-   * redirected to aNewChannel. Implementations should generally add the URI for
-   * aOldChannel to history for link coloring, but are advised not to expose it
-   * in the history user interface. This function is preferred if
-   * nsIGlobalHistory3 is available. Otherwise, nsIGlobalHistory2.addURI should
-   * be called with redirect=true.
-   *
-   * This function is preferred to nsIGlobalHistory2.addURI because it provides
-   * more information (including the redirect destination, channels involved,
-   * and redirect flags) to the history implementation.
-   *
-   * For implementors of nsIGlobalHistory3: The history implementation is
-   * responsible for sending NS_LINK_VISITED_EVENT_TOPIC to observers for
-   * redirect pages. This notification must be sent for history consumers for
-   * all non-redirect pages.
-   *
-   * @param aToplevel whether the URI is loaded in a top-level window.  If
-   *        false, the load is in a subframe.
-   *
-   * The other params to this function are the same as those for
-   * nsIChannelEventSink::OnChannelRedirect.
-   *
-   * Note: Implementors who wish to implement this interface but rely on
-   * nsIGlobalHistory2.addURI for redirect processing may throw
-   * NS_ERROR_NOT_IMPLEMENTED from this method.  If they do so, then callers
-   * must call nsIGlobalHistory2.addURI upon getting the
-   * NS_ERROR_NOT_IMPLEMENTED result.
-   */
-  void addDocumentRedirect(in nsIChannel aOldChannel,
-                           in nsIChannel aNewChannel,
-                           in PRInt32 aFlags,
-                           in boolean aTopLevel);
-
-  /**
-   * Get the Gecko flags for this URI. These flags are used by Gecko as hints
-   * to optimize page loading. Not all histories have them; this need not be
-   * supported (just return NS_ERROR_NOT_IMPLEMENTED. These flags are opaque
-   * and should not be interpreted by the history engine.
-   */
-  unsigned long getURIGeckoFlags(in nsIURI aURI);
-
-  /**
-   * Set the Gecko flags for this URI. May fail if the history entry
-   * doesn't have any flags or if there is no entry for the URI.
-   */
-  void setURIGeckoFlags(in nsIURI aURI, in unsigned long aFlags);
-};
--- a/docshell/test/chrome/docshell_helpers.js
+++ b/docshell/test/chrome/docshell_helpers.js
@@ -318,18 +318,30 @@ function finish() {
   // enableBFCache(), then restore it now.
   if (typeof(gOrigMaxTotalViewers) != "undefined") {
     SpecialPowers.setIntPref("browser.sessionhistory.max_total_viewers",
       gOrigMaxTotalViewers);
   }
 
   // Close the test window and signal the framework that the test is done.
   let opener = window.opener;
+  let SimpleTest = opener.wrappedJSObject.SimpleTest;
+
+  // Wait for the window to be closed before finishing the test
+  let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].getService(Ci.nsIWindowWatcher);
+  ww.registerNotification(function(subject, topic, data) {
+    if (topic == "domwindowclosed") {
+      ww.unregisterNotification(arguments.callee);
+      SimpleTest.waitForFocus(function() {
+        SimpleTest.finish();
+      }, opener);
+    }
+  });
+
   window.close();
-  opener.wrappedJSObject.SimpleTest.finish();
 }
 
 /**
  * Helper function which waits until another function returns true, or until a 
  * timeout occurs, and then notifies a callback.
  *
  * Parameters:
  *
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -90,16 +90,17 @@
 #include "nsIDOMEventListener.h"
 #include "nsIDOMPopStateEvent.h"
 #include "nsIDOMHashChangeEvent.h"
 #include "nsContentUtils.h"
 #include "nsDOMWindowUtils.h"
 #include "nsIDOMGlobalPropertyInitializer.h"
 #include "mozilla/Preferences.h"
 #include "nsLocation.h"
+#include "nsIDOMCaretPosition.h"
 
 // Window scriptable helper includes
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDocShellTreeNode.h"
 #include "nsIScriptExternalNameSet.h"
 #include "nsJSUtils.h"
 #include "nsIInterfaceRequestor.h"
@@ -660,16 +661,19 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(Window, nsWindowSH,
                            DEFAULT_SCRIPTABLE_FLAGS |
                            WINDOW_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(Location, nsLocationSH,
                            (DOM_DEFAULT_SCRIPTABLE_FLAGS &
                             ~nsIXPCScriptable::ALLOW_PROP_MODS_TO_PROTOTYPE))
 
+  NS_DEFINE_CLASSINFO_DATA(CaretPosition, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
   NS_DEFINE_CLASSINFO_DATA(Navigator, nsNavigatorSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS |
                            nsIXPCScriptable::WANT_PRECREATE)
   NS_DEFINE_CLASSINFO_DATA(Plugin, nsPluginSH,
                            ARRAY_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(PluginArray, nsPluginArraySH,
                            ARRAY_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(MimeType, nsDOMGenericSH,
@@ -2275,16 +2279,20 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_BEGIN(WindowUtils, nsIDOMWindowUtils)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindowUtils)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(Location, nsIDOMLocation)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMLocation)
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN(CaretPosition, nsIDOMCaretPosition)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMCaretPosition)
+  DOM_CLASSINFO_MAP_END
+
   if (nsNavigator::HasDesktopNotificationSupport()) {
     DOM_CLASSINFO_MAP_BEGIN(Navigator, nsIDOMNavigator)
       DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigator)
       DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorGeolocation)
       DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorDesktopNotification)
       DOM_CLASSINFO_MAP_ENTRY(nsIDOMClientInformation)
     DOM_CLASSINFO_MAP_END
   } else {
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -33,16 +33,17 @@
  * 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 ***** */
 
 DOMCI_CLASS(Window)
 DOMCI_CLASS(Location)
+DOMCI_CLASS(CaretPosition)
 DOMCI_CLASS(Navigator)
 DOMCI_CLASS(Plugin)
 DOMCI_CLASS(PluginArray)
 DOMCI_CLASS(MimeType)
 DOMCI_CLASS(MimeTypeArray)
 DOMCI_CLASS(BarProp)
 DOMCI_CLASS(History)
 DOMCI_CLASS(PerformanceTiming)
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1032,26 +1032,27 @@ nsGlobalWindow::~nsGlobalWindow()
 
   mDocument = nsnull;           // Forces Release
   mDoc = nsnull;
 
   NS_ASSERTION(!mArguments, "mArguments wasn't cleaned up properly!");
 
   CleanUp(PR_TRUE);
 
-  NS_ASSERTION(!mHasDeviceMotion, "Window still registered with device motion.");
-
 #ifdef DEBUG
   nsCycleCollector_DEBUG_wasFreed(static_cast<nsIScriptGlobalObject*>(this));
 #endif
 
   if (mURLProperty) {
     mURLProperty->ClearWindowReference();
   }
 
+  DisableDeviceMotionUpdates();
+  mHasDeviceMotion = PR_FALSE;
+
   nsLayoutStatics::Release();
 }
 
 // static
 void
 nsGlobalWindow::ShutDown()
 {
   NS_IF_RELEASE(sGlobalStorageList);
@@ -1160,19 +1161,16 @@ nsGlobalWindow::CleanUp(PRBool aIgnoreMo
   mParentTarget = nsnull;
 
   nsGlobalWindow *inner = GetCurrentInnerWindowInternal();
 
   if (inner) {
     inner->CleanUp(aIgnoreModalDialog);
   }
 
-  DisableDeviceMotionUpdates();
-  mHasDeviceMotion = PR_FALSE;
-
   if (mCleanMessageManager) {
     NS_ABORT_IF_FALSE(mIsChrome, "only chrome should have msg manager cleaned");
     nsGlobalChromeWindow *asChrome = static_cast<nsGlobalChromeWindow*>(this);
     if (asChrome->mMessageManager) {
       static_cast<nsFrameMessageManager*>(
         asChrome->mMessageManager.get())->Disconnect();
     }
   }
@@ -7371,18 +7369,18 @@ nsGlobalWindow::AddEventListener(const n
 
   if (!aWantsUntrusted &&
       (aOptionalArgc < 2 && !nsContentUtils::IsChromeDoc(mDoc))) {
     aWantsUntrusted = PR_TRUE;
   }
 
   nsEventListenerManager* manager = GetListenerManager(PR_TRUE);
   NS_ENSURE_STATE(manager);
-  return manager->AddEventListener(aType, aListener, aUseCapture,
-                                   aWantsUntrusted);
+  manager->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted);
+  return NS_OK;
 }
 
 nsEventListenerManager*
 nsGlobalWindow::GetListenerManager(PRBool aCreateIfNotFound)
 {
   FORWARD_TO_INNER_CREATE(GetListenerManager, (aCreateIfNotFound), nsnull);
 
   if (!mListenerManager && aCreateIfNotFound) {
--- a/dom/base/nsWindowRoot.cpp
+++ b/dom/base/nsWindowRoot.cpp
@@ -141,17 +141,18 @@ nsWindowRoot::AddEventListener(const nsA
 {
   NS_ASSERTION(!aWantsUntrusted || aOptionalArgc > 1,
                "Won't check if this is chrome, you want to set "
                "aWantsUntrusted to PR_FALSE or make the aWantsUntrusted "
                "explicit by making optional_argc non-zero.");
 
   nsEventListenerManager* elm = GetListenerManager(PR_TRUE);
   NS_ENSURE_STATE(elm);
-  return elm->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted);
+  elm->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted);
+  return NS_OK;
 }
 
 nsEventListenerManager*
 nsWindowRoot::GetListenerManager(PRBool aCreateIfNotFound)
 {
   if (!mListenerManager && aCreateIfNotFound) {
     mListenerManager =
       new nsEventListenerManager(static_cast<nsIDOMEventTarget*>(this));
--- a/dom/interfaces/core/Makefile.in
+++ b/dom/interfaces/core/Makefile.in
@@ -43,16 +43,17 @@ VPATH		= @srcdir@
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= dom
 XPIDL_MODULE	= dom_core
 GRE_MODULE	= 1
 
 SDK_XPIDLSRCS =                                 \
 	nsIDOMAttr.idl				\
+	nsIDOMCaretPosition.idl			\
 	nsIDOMCDATASection.idl			\
 	nsIDOMCharacterData.idl			\
 	nsIDOMComment.idl			\
 	nsIDOMDOMException.idl			\
 	nsIDOMDOMImplementation.idl		\
 	nsIDOMDocument.idl			\
 	nsIDOMDocumentFragment.idl		\
 	nsIDOMDocumentType.idl			\
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/core/nsIDOMCaretPosition.idl
@@ -0,0 +1,44 @@
+/* ***** 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.org.
+ *
+ * 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):
+ *   Brad Lassey <blassey@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsIDOMNode.idl"
+
+[scriptable, uuid(cf5ad6cf-6f49-4ca7-9b50-590d7bb27a13)]
+interface nsIDOMCaretPosition : nsISupports {
+  readonly attribute nsIDOMNode offsetNode;
+  readonly attribute unsigned long offset;
+};
--- a/dom/interfaces/core/nsIDOMDocument.idl
+++ b/dom/interfaces/core/nsIDOMDocument.idl
@@ -43,31 +43,32 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIDOMNode.idl"
 
 interface nsIDOMNodeIterator;
 interface nsIDOMNodeFilter;
 interface nsIDOMTreeWalker;
 interface nsIDOMLocation;
+interface nsIDOMCaretPosition;
 
 /**
  * The nsIDOMDocument interface represents the entire HTML or XML document.
  * Conceptually, it is the root of the document tree, and provides the 
  * primary access to the document's data.
  * Since elements, text nodes, comments, processing instructions, etc. 
  * cannot exist outside the context of a Document, the nsIDOMDocument 
  * interface also contains the factory methods needed to create these 
  * objects.
  *
  * For more information on this interface please see 
  * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
  */
 
-[scriptable, uuid(10034b87-384e-4e19-902c-c4edafb899be)]
+[scriptable, uuid(d19897dc-948a-42e7-8ac6-d8a0bd141b85)]
 interface nsIDOMDocument : nsIDOMNode
 {
   readonly attribute nsIDOMDocumentType         doctype;
   readonly attribute nsIDOMDOMImplementation    implementation;
   readonly attribute nsIDOMElement              documentElement;
   nsIDOMElement                 createElement(in DOMString tagName)
                                   raises(DOMException);
   nsIDOMDocumentFragment        createDocumentFragment();
@@ -363,9 +364,11 @@ interface nsIDOMDocument : nsIDOMNode
    * @param aImageElement a DOM element to be used as the source image of
    * |-moz-element(#aImageElementId)|. If this is null, the function will
    * unregister the image element ID |aImageElementId|.
    *
    * @see <https://developer.mozilla.org/en/DOM/document.mozSetImageElement>
    */
   void mozSetImageElement(in DOMString aImageElementId,
                           in nsIDOMElement aImageElement);
+
+  nsIDOMCaretPosition caretPositionFromPoint(in float x, in float y);
 };
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -300,16 +300,17 @@ nsPluginInstanceOwner::nsPluginInstanceO
   mInCGPaintLevel = 0;
   mSentInitialTopLevelWindowEvent = PR_FALSE;
   mColorProfile = nsnull;
   mPluginPortChanged = PR_FALSE;
 #endif
   mContentFocused = PR_FALSE;
   mWidgetVisible = PR_TRUE;
   mPluginWindowVisible = PR_FALSE;
+  mPluginDocumentActiveState = PR_TRUE;
   mNumCachedAttrs = 0;
   mNumCachedParams = 0;
   mCachedAttrParamNames = nsnull;
   mCachedAttrParamValues = nsnull;
   mDestroyWidget = PR_FALSE;
 
 #ifdef XP_MACOSX
 #ifndef NP_NO_QUICKDRAW
@@ -3236,17 +3237,17 @@ void nsPluginInstanceOwner::UpdateWindow
   nsIntPoint origin = mObjectFrame->GetWindowOriginInPixels(windowless);
 
   mPluginWindow->x = origin.x;
   mPluginWindow->y = origin.y;
 
   mPluginWindow->clipRect.left = 0;
   mPluginWindow->clipRect.top = 0;
 
-  if (mPluginWindowVisible) {
+  if (mPluginWindowVisible && mPluginDocumentActiveState) {
     mPluginWindow->clipRect.right = mPluginWindow->width;
     mPluginWindow->clipRect.bottom = mPluginWindow->height;
   } else {
     mPluginWindow->clipRect.right = 0;
     mPluginWindow->clipRect.bottom = 0;
   }
 
   if (!aSetWindow)
@@ -3264,16 +3265,22 @@ void nsPluginInstanceOwner::UpdateWindow
 
 void
 nsPluginInstanceOwner::UpdateWindowVisibility(PRBool aVisible)
 {
   mPluginWindowVisible = aVisible;
   UpdateWindowPositionAndClipRect(PR_TRUE);
 }
 
+void
+nsPluginInstanceOwner::UpdateDocumentActiveState(PRBool aIsActive)
+{
+  mPluginDocumentActiveState = aIsActive;
+  UpdateWindowPositionAndClipRect(PR_TRUE);
+}
 #endif // XP_MACOSX
 
 void
 nsPluginInstanceOwner::CallSetWindow()
 {
   if (!mInstance)
     return;
 
--- a/dom/plugins/base/nsPluginInstanceOwner.h
+++ b/dom/plugins/base/nsPluginInstanceOwner.h
@@ -197,16 +197,17 @@ public:
   // FixUpPluginWindow() (i.e. we need to know when FixUpPluginWindow() has
   // been called from nsObjectFrame::PaintPlugin() when we're using the
   // CoreGraphics drawing model).
   void BeginCGPaint();
   void EndCGPaint();
 #else // XP_MACOSX
   void UpdateWindowPositionAndClipRect(PRBool aSetWindow);
   void UpdateWindowVisibility(PRBool aVisible);
+  void UpdateDocumentActiveState(PRBool aIsActive);
 #endif // XP_MACOSX
   void CallSetWindow();
   
   void SetOwner(nsObjectFrame *aOwner)
   {
     mObjectFrame = aOwner;
   }
   nsObjectFrame* GetOwner() {
@@ -338,16 +339,17 @@ private:
 #ifdef XP_MACOSX
   PRPackedBool                mPluginPortChanged;
 #endif
 #ifdef MOZ_X11
   // Used with windowless plugins only, initialized in CreateWidget().
   PRPackedBool                mFlash10Quirks;
 #endif
   PRPackedBool                mPluginWindowVisible;
+  PRPackedBool                mPluginDocumentActiveState;
   
   // If true, destroy the widget on destruction. Used when plugin stop
   // is being delayed to a safer point in time.
   PRPackedBool                mDestroyWidget;
   PRUint16          mNumCachedAttrs;
   PRUint16          mNumCachedParams;
   char              **mCachedAttrParamNames;
   char              **mCachedAttrParamValues;
--- a/dom/src/geolocation/Makefile.in
+++ b/dom/src/geolocation/Makefile.in
@@ -63,16 +63,21 @@ LOCAL_INCLUDES = \
 
 EXPORTS        = nsGeoPosition.h
 
 ifdef MOZ_MAEMO_LIBLOCATION
 LOCAL_INCLUDES  += $(MOZ_PLATFORM_MAEMO_CFLAGS) \
                    -I$(topsrcdir)/dom/system/unix \
                    $(NULL)
 endif
+ifdef MOZ_ENABLE_QTMOBILITY
+LOCAL_INCLUDES  += $(MOZ_QT_CFLAGS) \
+                   -I$(topsrcdir)/dom/system/unix \
+                   $(NULL)
+endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),android)
 LOCAL_INCLUDES  += -I$(topsrcdir)/dom/system/android \
                    $(NULL)
 endif
 
 EXPORTS         += nsGeoPositionIPCSerialiser.h
 
--- a/dom/src/geolocation/nsGeolocation.cpp
+++ b/dom/src/geolocation/nsGeolocation.cpp
@@ -75,16 +75,20 @@
 #include "mozilla/Preferences.h"
 
 #include <math.h>
 
 #ifdef MOZ_MAEMO_LIBLOCATION
 #include "MaemoLocationProvider.h"
 #endif
 
+#ifdef MOZ_ENABLE_QTMOBILITY
+#include "QTMLocationProvider.h"
+#endif
+
 #ifdef ANDROID
 #include "AndroidLocationProvider.h"
 #endif
 
 #include "nsIDOMDocument.h"
 #include "nsIDocument.h"
 
 // Some limit to the number of get or watch geolocation requests
@@ -573,16 +577,22 @@ nsresult nsGeolocationService::Init()
   // we should move these providers outside of this file! dft
 
 #ifdef MOZ_MAEMO_LIBLOCATION
   provider = new MaemoLocationProvider();
   if (provider)
     mProviders.AppendObject(provider);
 #endif
 
+#ifdef MOZ_ENABLE_QTMOBILITY
+  provider = new QTMLocationProvider();
+  if (provider)
+    mProviders.AppendObject(provider);
+#endif
+
 #ifdef ANDROID
   provider = new AndroidLocationProvider();
   if (provider)
     mProviders.AppendObject(provider);
 #endif
   return NS_OK;
 }
 
--- a/dom/system/NetworkGeolocationProvider.js
+++ b/dom/system/NetworkGeolocationProvider.js
@@ -1,427 +1,311 @@
+/* ***** 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 Network Location Provider for GLS.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Doug Turner <dougt@dougt.org>
+ *
+ * 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 ***** */
+
+
+// Do not use this API without permission from Google.
+// See http://www.google.com/support/enterprise/bin/request.py?contact_type=gme&utm_campaign=en-us-ptr-mz
+// for more information.
+
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm");
 
 const Ci = Components.interfaces;
 const Cc = Components.classes;
 
-var gLoggingEnabled = false;
-var gTestingEnabled = false;
-
-function nowInSeconds()
-{
-    return Date.now() / 1000;
-}
+let gLoggingEnabled = false;
+let gTestingEnabled = false;
 
 function LOG(aMsg) {
   if (gLoggingEnabled)
   {
     aMsg = "*** WIFI GEO: " + aMsg + "\n";
     Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).logStringMessage(aMsg);
     dump(aMsg);
   }
 }
 
-function WifiGeoAddressObject(streetNumber, street, premises, city, county, region, country, countryCode, postalCode) {
-
-  this.streetNumber = streetNumber;
-  this.street       = street;
-  this.premises     = premises;
-  this.city         = city;
-  this.county       = county;
-  this.region       = region;
-  this.country      = country;
-  this.countryCode  = countryCode;
-  this.postalCode   = postalCode;
+function WifiGeoCoordsObject(lat, lon, acc, alt, altacc) {
+  this.latitude = lat;
+  this.longitude = lon;
+  this.accuracy = acc;
+  this.altitude = alt;
+  this.altitudeAccuracy = altacc;
 }
 
-WifiGeoAddressObject.prototype = {
-
-    QueryInterface:   XPCOMUtils.generateQI([Ci.nsIDOMGeoPositionAddress]),
-
-    classInfo: XPCOMUtils.generateCI({interfaces: [Ci.nsIDOMGeoPositionAddress],
-                                      flags: Ci.nsIClassInfo.DOM_OBJECT})
-};
-
-function WifiGeoCoordsObject(lat, lon, acc, alt, altacc) {
-    this.latitude = lat;
-    this.longitude = lon;
-    this.accuracy = acc;
-    this.altitude = alt;
-    this.altitudeAccuracy = altacc;
-};
-
 WifiGeoCoordsObject.prototype = {
 
-    QueryInterface:   XPCOMUtils.generateQI([Ci.nsIDOMGeoPositionCoords]),
-
-    classInfo: XPCOMUtils.generateCI({interfaces: [Ci.nsIDOMGeoPositionCoords],
-                                      flags: Ci.nsIClassInfo.DOM_OBJECT,
-                                      classDescription: "wifi geo position coords object"}),
+  QueryInterface:  XPCOMUtils.generateQI([Ci.nsIDOMGeoPositionCoords]),
 
-    latitude: 0,
-    longitude: 0,
-    accuracy: 0,
-    altitude: 0,
-    altitudeAccuracy: 0,
-
+  classInfo: XPCOMUtils.generateCI({interfaces: [Ci.nsIDOMGeoPositionCoords],
+                                    flags: Ci.nsIClassInfo.DOM_OBJECT,
+                                    classDescription: "wifi geo position coords object"}),
 };
 
-function WifiGeoPositionObject(location) {
-
-    this.coords = new WifiGeoCoordsObject(location.latitude,
-                                          location.longitude,
-                                          location.accuracy || 12450, // .5 * circumference of earth.
-                                          location.altitude || 0,
-                                          location.altitude_accuracy || 0);
-
-    if (location.address) {
-        let address = location.address;
-        this.address = new WifiGeoAddressObject(address.street_number || null,
-                                                address.street || null,
-                                                address.premises || null,
-                                                address.city || null,
-                                                address.county || null,
-                                                address.region || null,
-                                                address.country || null,
-                                                address.country_code || null,
-                                                address.postal_code || null);
-    }
-    else
-      this.address = null;
-
-    this.timestamp = Date.now();
-};
+function WifiGeoPositionObject(lat, lng, acc) {
+  this.coords = new WifiGeoCoordsObject(lat, lng, acc, 0, 0);
+  this.address = null;
+  this.timestamp = Date.now();
+}
 
 WifiGeoPositionObject.prototype = {
 
-    QueryInterface:   XPCOMUtils.generateQI([Ci.nsIDOMGeoPosition]),
+  QueryInterface:   XPCOMUtils.generateQI([Ci.nsIDOMGeoPosition]),
 
-    // Class Info is required to be able to pass objects back into the DOM.
-    classInfo: XPCOMUtils.generateCI({interfaces: [Ci.nsIDOMGeoPosition],
-                                      flags: Ci.nsIClassInfo.DOM_OBJECT,
-                                      classDescription: "wifi geo location position object"}),
-
-    coords: null,
-    timestamp: 0,
+  // Class Info is required to be able to pass objects back into the DOM.
+  classInfo: XPCOMUtils.generateCI({interfaces: [Ci.nsIDOMGeoPosition],
+                                    flags: Ci.nsIClassInfo.DOM_OBJECT,
+                                    classDescription: "wifi geo location position object"}),
 };
 
-function HELD() {};
- // For information about the HELD format, see:
- // http://tools.ietf.org/html/draft-thomson-geopriv-held-measurements-05
-HELD.encode = function(requestObject) {
-    // XML Header
-    var requestString = "<locationRequest xmlns=\"urn:ietf:params:xml:ns:geopriv:held\">";
-    // Measurements
-    if (requestObject.wifi_towers && requestObject.wifi_towers.length > 0) {
-      requestString += "<measurements xmlns=\"urn:ietf:params:xml:ns:geopriv:lm\">";
-      requestString += "<wifi xmlns=\"urn:ietf:params:xml:ns:geopriv:lm:wifi\">";
-      for (var i=0; i < requestObject.wifi_towers.length; ++i) {
-        requestString += "<neighbourWap>";
-        requestString += "<bssid>" + requestObject.wifi_towers[i].mac_address     + "</bssid>";
-        requestString += "<ssid>"  + requestObject.wifi_towers[i].ssid            + "</ssid>";
-        requestString += "<rssi>"  + requestObject.wifi_towers[i].signal_strength + "</rssi>";
-        requestString += "</neighbourWap>";
-      }
-      // XML Footer
-      requestString += "</wifi></measurements>";
+function WifiGeoPositionProvider() {
+  try {
+    gLoggingEnabled = Services.prefs.getBoolPref("geo.wifi.logging.enabled");
+  } catch (e) {}
+
+  try {
+    gTestingEnabled = Services.prefs.getBoolPref("geo.wifi.testing");
+  } catch (e) {}
+
+  wifiService = null;
+  timer = null;
+  hasSeenWiFi = false;
+  started = false;
+}
+
+WifiGeoPositionProvider.prototype = {
+  classID:          Components.ID("{77DA64D3-7458-4920-9491-86CC9914F904}"),
+  QueryInterface:   XPCOMUtils.generateQI([Ci.nsIGeolocationProvider,
+                                           Ci.nsIWifiListener,
+                                           Ci.nsITimerCallback]),
+  startup:  function() {
+    if (this.started)
+      return;
+    this.started = true;
+    this.hasSeenWiFi = false;
+
+    LOG("startup called.  testing mode is" + gTestingEnabled);
+
+    // if we don't see anything in 5 seconds, kick of one IP geo lookup.
+    // if we are testing, just hammer this callback so that we are more or less
+    // always sending data.  It doesn't matter if we have an access point or not.
+    this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+    if (!gTestingEnabled)
+      this.timer.initWithCallback(this, 5000, this.timer.TYPE_ONE_SHOT);
+    else
+      this.timer.initWithCallback(this, 200, this.timer.TYPE_REPEATING_SLACK);
+  },
+
+  watch: function(c) {
+    LOG("watch called");
+    if (!this.wifiService) {
+      this.wifiService = Cc["@mozilla.org/wifi/monitor;1"].getService(Components.interfaces.nsIWifiMonitor);
+      this.wifiService.startWatching(this);
     }
-    requestString += "</locationRequest>";
-    return requestString;
-};
+  },
 
-// Decode a HELD response into a Gears-style object
-HELD.decode = function(responseXML) {
-    // Find a Circle object in PIDF-LO and decode
-    function nsResolver(prefix) {
-        var ns = {
-            'held': 'urn:ietf:params:xml:ns:geopriv:held',
-            'pres': 'urn:ietf:params:xml:ns:pidf',
-            'gp': 'urn:ietf:params:xml:ns:pidf:geopriv10',
-            'gml': 'http://www.opengis.net/gml',
-            'gs': 'http://www.opengis.net/pidflo/1.0',
-        };
-        return ns[prefix] || null;
+  shutdown: function() { 
+    LOG("shutdown called");
+    if(this.wifiService) {
+      this.wifiService.stopWatching(this);
+      this.wifiService = null;
+    }
+    if (this.timer != null) {
+      this.timer.cancel();
+      this.timer = null;
     }
 
-    var xpathEval = Components.classes["@mozilla.org/dom/xpath-evaluator;1"].createInstance(Ci.nsIDOMXPathEvaluator);
+    // Although we aren't using cookies, we should err on the side of not
+    // saving any access tokens if the user asked us not to save cookies or
+    // has changed the lifetimePolicy.  The access token in these cases is
+    // used and valid for the life of this object (eg. between startup and
+    // shutdown).
+    if (Services.prefs.getIntPref("network.cookie.lifetimePolicy") != 0)
+      Services.prefs.deleteBranch("geo.wifi.access_token.");
+    this.started = false;
+  },
 
-    // Grab values out of XML via XPath
-    var pos = xpathEval.evaluate(
-        '/held:locationResponse/pres:presence/pres:tuple/pres:status/gp:geopriv/gp:location-info/gs:Circle/gml:pos',
-        responseXML,
-        nsResolver,
-        Ci.nsIDOMXPathResult.STRING_TYPE,
-        null);
+  getAccessTokenForURL: function(url)
+  {
+    // check to see if we have an access token:
+    let accessToken = "";
+    try {
+      let accessTokenPrefName = "geo.wifi.access_token." + url;
+      accessToken = Services.prefs.getCharPref(accessTokenPrefName);
+
+      // check to see if it has expired
+      let accessTokenDate = Services.prefs.getIntPref(accessTokenPrefName + ".time");
+      
+      let accessTokenInterval = 1209600;  // seconds in 2 weeks
+      try {
+        accessTokenInterval = Services.prefs.getIntPref("geo.wifi.access_token.recycle_interval");
+      } catch (e) {}
+            
+      if ((Date.now() / 1000) - accessTokenDate > accessTokenInterval)
+        accessToken = "";
+    }
+    catch (e) {
+      accessToken = "";
+    }
+    return accessToken;
+  },
 
-    var rad = xpathEval.evaluate(
-        '/held:locationResponse/pres:presence/pres:tuple/pres:status/gp:geopriv/gp:location-info/gs:Circle/gs:radius',
-        responseXML,
-        nsResolver,
-        Ci.nsIDOMXPathResult.NUMBER_TYPE,
-        null );
+  onChange: function(accessPoints) {
+    LOG("onChange called");
+    this.hasSeenWiFi = true;
+
+    let providerUrlBase = Services.prefs.getCharPref("geo.wifi.uri");
+    let providerUrl;
+
+    let query = providerUrlBase.indexOf("?");
+    if (query == -1)
+      providerUrl = providerUrlBase + "?"
+    else
+      providerUrl = providerUrlBase + "&";
+    providerUrl = providerUrl + "browser=firefox&sensor=true";
+    
+
+    let accessToken = this.getAccessTokenForURL(providerUrlBase);
+    if (accessToken !== "")
+      providerUrl = providerUrl + "&access_token="+access_token;
 
-    var uom = xpathEval.evaluate(
-        '/held:locationResponse/pres:presence/pres:tuple/pres:status/gp:geopriv/gp:location-info/gs:Circle/gs:radius/@uom',
-        responseXML,
-        nsResolver,
-        Ci.nsIDOMXPathResult.STRING_TYPE,
-        null);
+    function sort(a, b) {
+      return b.signal - a.signal;
+    };
+
+    function encode(ap) {
+      // make sure that the ssid doesn't contain any | chars.
+      ap.ssid = ap.ssid.replace("|", "\\|");
+      // gls service parses the | as fields
+      return "&wifi=mac:"+ap.mac+"|ssid:"+ap.ssid+"|ss:"+ap.signal;
+    };
 
-    // Bail if we don't have a valid result (all values && uom==meters)
-    if ((pos.stringValue == null) ||
-        (rad.numberValue == null) ||
-        (uom.stringValue == null) ||
-        (uom.stringValue != "urn:ogc:def:uom:EPSG::9001")) {
-        return null;
+    if (accessPoints) {
+        accessPoints.sort(sort).map(encode).join("");
+        // max length is 2k.  make sure we are under that
+        let x = providerUrl.length - 2000;
+        if (x >= 0) {
+            // we need to trim
+            let doomed = providerUrl.lastIndexOf("&", 2000);
+            LOG("Doomed:"+doomed);
+            providerUrl = providerUrl.substring(0, doomed);
+        }
     }
 
-    // Split the pos value into lat/long
-    var coords = pos.stringValue.split(/[ \t\n]+/);
-
-    // Fill out the object to return:
-    var obj = {
-        location: {
-            latitude: parseFloat(coords[0]),
-            longitude: parseFloat(coords[1]),
-            accuracy: rad.numberValue
-        }
-    };
-    return obj;
-}  
+    providerUrl = encodeURI(providerUrl);
+    LOG("************************************* Sending request:\n" + providerUrl + "\n");
 
-function WifiGeoPositionProvider() {
-    this.prefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch).QueryInterface(Ci.nsIPrefService);
-    try {
-        gLoggingEnabled = this.prefService.getBoolPref("geo.wifi.logging.enabled");
-    } catch (e) {}
-
-    try {
-        gTestingEnabled = this.prefService.getBoolPref("geo.wifi.testing");
-    } catch (e) {}
-
-};
-
-WifiGeoPositionProvider.prototype = {
-    classID:          Components.ID("{77DA64D3-7458-4920-9491-86CC9914F904}"),
-    QueryInterface:   XPCOMUtils.generateQI([Ci.nsIGeolocationProvider,
-                                             Ci.nsIWifiListener,
-                                             Ci.nsITimerCallback]),
+    // send our request to a wifi geolocation network provider:
+    let xhr = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
+                        .createInstance(Ci.nsIXMLHttpRequest);
 
-    prefService:     null,
-    wifi_service:    null,
-    timer:           null,
-    hasSeenWiFi:     false,
-    started:         false,
-
-    startup:         function() {
-        if (this.started == true)
-            return;
-
-        this.started = true;
+    // This is a background load
+    xhr.mozBackgroundRequest = true;
+    xhr.open("GET", providerUrl, false);
+    xhr.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS;
+    xhr.onerror = function(req) {
+        LOG("onerror: " + req);
+    };
+    xhr.onload = function (req) {  
+        LOG("service returned: " + req.target.responseText);
+        response = JSON.parse(req.target.responseText);
+        /*
+          {
+            "status": "OK",
+            "accuracy": 150.0,
+            "location": {
+              "lat": -33.85702,
+              "lng": 151.21494
+            },
+            "access_token": "quijibo"
+          }
+        */
 
-        LOG("startup called.  testing mode is" + gTestingEnabled);
-        // if we don't see anything in 5 seconds, kick of one IP geo lookup.
-        // if we are testing, just hammer this callback so that we are more or less
-        // always sending data.  It doesn't matter if we have an access point or not.
-        this.hasSeenWiFi = false;
-        this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-        if (gTestingEnabled == false)
-            this.timer.initWithCallback(this, 5000, this.timer.TYPE_ONE_SHOT);
-        else
-            this.timer.initWithCallback(this, 200, this.timer.TYPE_REPEATING_SLACK);
-    },
+        if (response.status != "OK")
+          return;
 
-    watch: function(c) {
-        LOG("watch called");
-        if (!this.wifi_service) {
-            this.wifi_service = Cc["@mozilla.org/wifi/monitor;1"].getService(Components.interfaces.nsIWifiMonitor);
-            this.wifi_service.startWatching(this);
-        }
-    },
+        if (response.location) {
+          let newLocation = new WifiGeoPositionObject(response.location.lat,
+                                                      response.location.lng,
+                                                      response.accuracy);
 
-    shutdown: function() { 
-        LOG("shutdown  called");
-        if(this.wifi_service)
-            this.wifi_service.stopWatching(this);
-        this.wifi_service = null;
-
-        if (this.timer != null) {
-            this.timer.cancel();
-            this.timer = null;
+          let update = Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationUpdate);
+          update.update(newLocation);
         }
 
-        // Although we aren't using cookies, we should err on the side of not
-        // saving any access tokens if the user asked us not to save cookies or
-        // has changed the lifetimePolicy.  The access token in these cases is
-        // used and valid for the life of this object (eg. between startup and
-        // shutdown).e
-        let prefBranch = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
-        if (prefBranch.getIntPref("network.cookie.lifetimePolicy") != 0)
-            prefBranch.deleteBranch("geo.wifi.access_token.");
-
-        this.started = false;
-    },
-
-    getAccessTokenForURL: function(url)
-    {
-        // check to see if we have an access token:
-        var accessToken = "";
-        
-        try {
-            var accessTokenPrefName = "geo.wifi.access_token." + url;
-            accessToken = this.prefService.getCharPref(accessTokenPrefName);
-            
-            // check to see if it has expired
-            var accessTokenDate = this.prefService.getIntPref(accessTokenPrefName + ".time");
-            
-            var accessTokenInterval = 1209600;  /* seconds in 2 weeks */
-            try {
-                accessTokenInterval = this.prefService.getIntPref("geo.wifi.access_token.recycle_interval");
-            } catch (e) {}
-            
-            if (nowInSeconds() - accessTokenDate > accessTokenInterval)
-                accessToken = "";
-        }
-        catch (e) {
-            accessToken = "";
-        }
-        return accessToken;
-    },
-
-    onChange: function(accessPoints) {
-
-        LOG("onChange called");
-        this.hasSeenWiFi = true;
-
-        // send our request to a wifi geolocation network provider:
-        var xhr = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
-                            .createInstance(Ci.nsIXMLHttpRequest);
-
-        // This is a background load
-        xhr.mozBackgroundRequest = true;
-
-        var provider_url      = this.prefService.getCharPref("geo.wifi.uri");
-        var provider_protocol = 0;
-        try {
-            provider_protocol = this.prefService.getIntPref("geo.wifi.protocol");
-        } catch (e) {}
-
-        LOG("provider url = " + provider_url);
-
-        xhr.open("POST", provider_url, false);
-        
-        // set something so that we can strip cookies
-        xhr.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS;
-            
-        xhr.onerror = function(req) {
-            LOG("onerror: " + req);
-        };
-
-        xhr.onload = function (req) {  
-
-            LOG("xhr onload...");
+        // Check to see if we have a new access token
+        let newAccessToken = response.access_token;
+        if (newAccessToken !== undefined)
+        {
+          let accessToken = "";
+          let accessTokenPrefName = "geo.wifi.access_token." + providerUrlBase;
+          try { accessToken = Services.prefs.getCharPref(accessTokenPrefName); } catch (e) {}
 
-            try { 
-                // if we get a bad response, we will throw and never report a location
-                var response;
-                switch (provider_protocol) {
-                    case 1:
-                        LOG("service returned: " + req.target.responseXML);
-                        response = HELD.decode(req.target.responseXML);
-                        break;
-                    case 0:
-                    default:
-                        LOG("service returned: " + req.target.responseText);
-                        response = JSON.parse(req.target.responseText);
-                }
-            } catch (e) {
-                LOG("Parse failed");
-                return;
-            }
-
-            // response looks something like:
-            // {"location":{"latitude":51.5090332,"longitude":-0.1212726,"accuracy":150.0},"access_token":"2:jVhRZJ-j6PiRchH_:RGMrR0W1BiwdZs12"}
-
-            // Check to see if we have a new access token
-            var newAccessToken = response.access_token;
-            if (newAccessToken != undefined)
-            {
-                var prefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
-                var accessToken = "";
-                var accessTokenPrefName = "geo.wifi.access_token." + req.target.channel.URI.spec;
-                try { accessToken = prefService.getCharPref(accessTokenPrefName); } catch (e) {}
-
-                if (accessToken != newAccessToken) {
-                    // no match, lets cache
-                    LOG("New Access Token: " + newAccessToken + "\n" + accessTokenPrefName);
-                    
-                    try {
-                        prefService.setIntPref(accessTokenPrefName + ".time", nowInSeconds());
-                        prefService.setCharPref(accessTokenPrefName, newAccessToken);
-                    } catch (x) {
-                        // XXX temporary hack for bug 575346 to allow geolocation to function
-                    }
-                }
-            }
-
-            if (response.location) {
-                var newLocation = new WifiGeoPositionObject(response.location);
-
-                var update = Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationUpdate);
-                update.update(newLocation);
-            }
-        };
+          if (accessToken != newAccessToken) {
+            // no match, lets cache
+              LOG("New Access Token: " + newAccessToken + "\n" + accessTokenPrefName);
+              try {
+                Services.prefs.setIntPref(accessTokenPrefName + ".time", nowInSeconds());
+                Services.prefs.setCharPref(accessTokenPrefName, newAccessToken);
+              } catch (x) {
+                  // XXX temporary hack for bug 575346 to allow geolocation to function
+              }
+          }
+        }
+    };
 
-        var accessToken = this.getAccessTokenForURL(provider_url);
-
-        var request = {
-            version: "1.1.0",
-            request_address: true,
-        };
-
-        if (accessToken != "")
-            request.access_token = accessToken;
+    LOG("************************************* ------>>>> sending.");
+    xhr.send(null);
+  },
 
-        if (accessPoints != null) {
-            function filterBlankSSIDs(ap) ap.ssid != ""
-            function deconstruct(ap) ({
-                    mac_address: ap.mac,
-                        ssid: ap.ssid,
-                        signal_strength: ap.signal
-                        })
-            request.wifi_towers = accessPoints.filter(filterBlankSSIDs).map(deconstruct);
-        }
+  onError: function (code) {
+    LOG("wifi error: " + code);
+  },
 
-        var requestString;
-        switch (provider_protocol) {
-          case 1:
-              requestString = HELD.encode(request);
-              break;
-          case 0:
-          default:
-              requestString = JSON.stringify(request);
-        }
-        LOG("client sending: " + requestString);
- 
-        try {
-          xhr.send(requestString);
-        } catch (e) {}
-    },
-
-    onError: function (code) {
-        LOG("wifi error: " + code);
-    },
-
-    notify: function (timer) {
-        if (!gTestingEnabled) {
-            if (this.hasSeenWiFi == false)
-                this.onChange(null);
-            this.timer = null;
-            return;
-        }
-        // if we are testing, we need to hammer this.
+  notify: function (timer) {
+    if (gTestingEnabled) {
+      // if we are testing, timer is repeating
+      this.onChange(null);
+    }
+    else {
+      if (!this.hasSeenWiFi)
         this.onChange(null);
-    },
-
+      this.timer = null;
+    }
+  },
 };
 
-var NSGetFactory = XPCOMUtils.generateNSGetFactory([WifiGeoPositionProvider]);
+let NSGetFactory = XPCOMUtils.generateNSGetFactory([WifiGeoPositionProvider]);
--- a/dom/system/unix/Makefile.in
+++ b/dom/system/unix/Makefile.in
@@ -45,16 +45,18 @@ MODULE      = dom
 LIBRARY_NAME    = domsystemunix_s
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
 EXPORT_LIBRARY = 1
 
 include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
+
 
 CPPSRCS     = \
         nsDeviceMotionSystem.cpp \
         $(NULL)
 
 ifdef MOZ_MAEMO_LIBLOCATION
         CPPSRCS         += MaemoLocationProvider.cpp
         LOCAL_INCLUDES  += $(MOZ_PLATFORM_MAEMO_CFLAGS) \
@@ -62,14 +64,19 @@ ifdef MOZ_MAEMO_LIBLOCATION
                            $(NULL)
 endif
 
 ifdef MOZ_PLATFORM_MAEMO
 CPPSRCS += nsHapticFeedback.cpp
 LOCAL_INCLUDES  += $(MOZ_DBUS_CFLAGS) \
                    $(NULL)
 ifdef MOZ_ENABLE_QTMOBILITY
+MOCSRCS         += moc_QTMLocationProvider.cpp
+CPPSRCS         += $(MOCSRCS) \
+                   QTMLocationProvider.cpp \
+                   $(NULL)
 LOCAL_INCLUDES  += $(MOZ_QT_CFLAGS) \
+                   -I$(topsrcdir)/dom/src/geolocation \
                    $(NULL)
 endif
 endif
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/dom/system/unix/QTMLocationProvider.cpp
@@ -0,0 +1,118 @@
+/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * ***** 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 Qt code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Oleg Romashin <romaxa@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "QTMLocationProvider.h"
+#include "nsGeoPosition.h"
+#include <QFeedbackEffect>
+using namespace QtMobility;
+
+using namespace mozilla;
+
+NS_IMPL_ISUPPORTS1(QTMLocationProvider, nsIGeolocationProvider)
+
+QTMLocationProvider::QTMLocationProvider()
+{
+    mLocation = QGeoPositionInfoSource::createDefaultSource(this);
+    if (mLocation)
+        connect(mLocation, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(positionUpdated(QGeoPositionInfo)));
+}
+
+QTMLocationProvider::~QTMLocationProvider()
+{
+    delete mLocation;
+}
+
+void
+QTMLocationProvider::positionUpdated(const QGeoPositionInfo &geoPosition)
+{
+    if (!geoPosition.isValid()) {
+        NS_WARNING("Invalida geoposition received");
+        return;
+    }
+
+    QGeoCoordinate coord = geoPosition.coordinate();
+    double latitude = coord.latitude();
+    double longitude = coord.longitude();
+    double altitude = coord.altitude();
+    double accuracy = geoPosition.attribute(QGeoPositionInfo::HorizontalAccuracy);
+    double altitudeAccuracy = geoPosition.attribute(QGeoPositionInfo::VerticalAccuracy);
+    double heading = geoPosition.attribute(QGeoPositionInfo::Direction);
+
+    bool providesSpeed = geoPosition.hasAttribute(QGeoPositionInfo::GroundSpeed);
+    double speed = geoPosition.attribute(QGeoPositionInfo::GroundSpeed);
+
+    nsRefPtr<nsGeoPosition> p =
+        new nsGeoPosition(latitude, longitude,
+                          altitude, accuracy,
+                          altitudeAccuracy, heading,
+                          speed, geoPosition.timestamp().toTime_t());
+    if (mCallback) {
+        mCallback->Update(p);
+    }
+}
+
+NS_IMETHODIMP
+QTMLocationProvider::Startup()
+{
+    if (!mLocation)
+        return NS_ERROR_NOT_IMPLEMENTED;
+
+    mLocation->startUpdates();
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+QTMLocationProvider::Watch(nsIGeolocationUpdate* aCallback)
+{
+    mCallback = aCallback;
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+QTMLocationProvider::Shutdown()
+{
+    if (!mLocation)
+        return NS_ERROR_NOT_IMPLEMENTED;
+
+    mLocation->stopUpdates();
+    mCallback = nsnull;
+
+    return NS_OK;
+}
+
new file mode 100644
--- /dev/null
+++ b/dom/system/unix/QTMLocationProvider.h
@@ -0,0 +1,69 @@
+/* ***** 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 Qt code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Oleg Romashin <romaxa@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * 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 ***** */
+
+#ifndef QTMLocationProvider_h
+#define QTMLocationProvider_h
+
+#include <QGeoPositionInfoSource>
+#include "nsGeolocation.h"
+#include "nsIGeolocationProvider.h"
+#include "nsCOMPtr.h"
+
+using namespace QtMobility;
+
+class QTMLocationProvider : public QObject,
+                            public nsIGeolocationProvider
+{
+    Q_OBJECT
+
+public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIGEOLOCATIONPROVIDER
+
+    QTMLocationProvider();
+
+public Q_SLOTS:
+    // QGeoPositionInfoSource
+    void positionUpdated(const QGeoPositionInfo&);
+
+private:
+    ~QTMLocationProvider();
+
+    QtMobility::QGeoPositionInfoSource* mLocation;
+    nsCOMPtr<nsIGeolocationUpdate> mCallback;
+};
+
+#endif /* QTMLocationProvider_h */
--- a/dom/tests/mochitest/geolocation/geolocation_common.js
+++ b/dom/tests/mochitest/geolocation/geolocation_common.js
@@ -72,20 +72,20 @@ function check_geolocation(location) {
 
   // eventually, coords may be optional (eg, when civic addresses are supported)
   ok("coords" in location, "Check to see if this location has a coords");
 
   var coords = location.coords;
 
   ok("latitude" in coords, "Check to see if there is a latitude");
   ok("longitude" in coords, "Check to see if there is a longitude");
-  ok("altitude" in coords, "Check to see if there is a altitude");
   ok("accuracy" in coords, "Check to see if there is a accuracy");
-  ok("altitudeAccuracy" in coords, "Check to see if there is a alt accuracy");
-
+  
+  // optional ok("altitude" in coords, "Check to see if there is a altitude");
+  // optional ok("altitudeAccuracy" in coords, "Check to see if there is a alt accuracy");
   // optional ok("heading" in coords, "Check to see if there is a heading");
   // optional ok("speed" in coords, "Check to see if there is a speed");
 
   ok (location.coords.latitude  == 37.41857, "lat matches known value");
   ok (location.coords.longitude == -122.08769, "lon matches known value");
-  ok(location.coords.altitude == 42, "alt matches known value");
-  ok(location.coords.altitudeAccuracy == 42, "alt acc matches known value");
+  // optional  ok(location.coords.altitude == 42, "alt matches known value");
+  // optional  ok(location.coords.altitudeAccuracy == 42, "alt acc matches known value");
 }
--- a/dom/tests/mochitest/geolocation/network_geolocation.sjs
+++ b/dom/tests/mochitest/geolocation/network_geolocation.sjs
@@ -14,45 +14,26 @@ function parseQueryString(str)
     params[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
   }
 
   return params;
 }
 
 function getPosition(action)
 {  
-    // this isn't the w3c data structure, it is the network location provider structure.
-
-  var address = {
-      street_number: "street_number",
-      street: "street",
-      premises: "premises",
-      city: "city",
-      county: "county",
-      region: "region",
-      country: "country",
-      country_code: "country_code",
-      postal_code: "postal_code",
-  };
-
-
-  var coords = {
-    latitude: 37.41857,
-    longitude: -122.08769,
-
-    altitude: 42,
+  var response = {
+    status: "OK",
+    location: {
+      lat: 37.41857,
+      lng: -122.08769,
+    },
     accuracy: (action == "worse-accuracy") ? 100 : 42,
-    altitude_accuracy: 42,
   };
   
-  var geoposition = {
-    location: coords,
-  };
-
-  return JSON.stringify(geoposition);
+  return JSON.stringify(response);
 }
 
 function handleRequest(request, response)
 {
   var params = parseQueryString(request.queryString);
 
   if (params.action == "stop-responding") {
       return;
--- a/editor/composer/src/nsComposerCommands.cpp
+++ b/editor/composer/src/nsComposerCommands.cpp
@@ -426,17 +426,18 @@ NS_IMETHODIMP
 nsRemoveListCommand::IsCommandEnabled(const char * aCommandName,
                                       nsISupports *refCon,
                                       PRBool *outCmdEnabled)
 {
   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
   if (editor)
   {
     PRBool isEditable = PR_FALSE;
-    NS_SUCCEEDED(editor->GetIsSelectionEditable(&isEditable));
+    nsresult rv = editor->GetIsSelectionEditable(&isEditable);
+    NS_ENSURE_SUCCESS(rv, rv);
     if (isEditable)
     {
       // It is enabled if we are in any list type
       PRBool bMixed;
       PRUnichar *tagStr;
       nsresult rv = GetListState(editor, &bMixed, &tagStr);
       NS_ENSURE_SUCCESS(rv, rv);
 
@@ -538,17 +539,18 @@ nsOutdentCommand::IsCommandEnabled(const
                                    nsISupports *refCon,
                                    PRBool *outCmdEnabled)
 {
   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(refCon);
   if (editor && htmlEditor)
   {
     PRBool canIndent, isEditable = PR_FALSE;
-    NS_SUCCEEDED(editor->GetIsSelectionEditable(&isEditable));
+    nsresult rv = editor->GetIsSelectionEditable(&isEditable);
+    NS_ENSURE_SUCCESS(rv, rv);
     if (isEditable)
       return htmlEditor->GetIndentState(&canIndent, outCmdEnabled);
   }
 
   *outCmdEnabled = PR_FALSE;
   return NS_OK;
 }
 
@@ -1046,17 +1048,18 @@ nsAbsolutePositioningCommand::IsCommandE
                                                nsISupports *aCommandRefCon,
                                                PRBool *outCmdEnabled)
 {
   nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
   nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(aCommandRefCon);
   if (htmlEditor)
   {
     PRBool isEditable = PR_FALSE;
-    NS_SUCCEEDED(editor->GetIsSelectionEditable(&isEditable));
+    nsresult rv = editor->GetIsSelectionEditable(&isEditable);
+    NS_ENSURE_SUCCESS(rv, rv);
     if (isEditable)
       return htmlEditor->GetAbsolutePositioningEnabled(outCmdEnabled);
   }
 
   *outCmdEnabled = PR_FALSE;
   return NS_OK;
 }
 
--- a/editor/libeditor/base/nsEditorCommands.cpp
+++ b/editor/libeditor/base/nsEditorCommands.cpp
@@ -66,17 +66,18 @@ nsUndoCommand::IsCommandEnabled(const ch
                                 nsISupports *aCommandRefCon, 
                                 PRBool *outCmdEnabled)
 {
   NS_ENSURE_ARG_POINTER(outCmdEnabled);
   nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
   if (editor)
   {
     PRBool isEnabled, isEditable = PR_FALSE;
-    NS_SUCCEEDED(editor->GetIsSelectionEditable(&isEditable));
+    nsresult rv = editor->GetIsSelectionEditable(&isEditable);
+    NS_ENSURE_SUCCESS(rv, rv);
     if (isEditable)
       return editor->CanUndo(&isEnabled, outCmdEnabled);
   }
 
   *outCmdEnabled = PR_FALSE;
   return NS_OK;
 }
 
@@ -114,17 +115,18 @@ nsRedoCommand::IsCommandEnabled(const ch
                                 nsISupports *aCommandRefCon,
                                 PRBool *outCmdEnabled)
 {
   NS_ENSURE_ARG_POINTER(outCmdEnabled);
   nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
   if (editor)
   {
     PRBool isEnabled, isEditable = PR_FALSE;
-    NS_SUCCEEDED(editor->GetIsSelectionEditable(&isEditable));
+    nsresult rv = editor->GetIsSelectionEditable(&isEditable);
+    NS_ENSURE_SUCCESS(rv, rv);
     if (isEditable)
       return editor->CanRedo(&isEnabled, outCmdEnabled);
   }
 
   *outCmdEnabled = PR_FALSE;
   return NS_OK;
 }
 
@@ -210,17 +212,18 @@ nsCutCommand::IsCommandEnabled(const cha
                                nsISupports *aCommandRefCon,
                                PRBool *outCmdEnabled)
 {
   NS_ENSURE_ARG_POINTER(outCmdEnabled);
   nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
   if (editor)
   {
     PRBool isEditable = PR_FALSE;
-    NS_SUCCEEDED(editor->GetIsSelectionEditable(&isEditable));
+    nsresult rv = editor->GetIsSelectionEditable(&isEditable);
+    NS_ENSURE_SUCCESS(rv, rv);
     if (isEditable)
       return editor->CanCut(outCmdEnabled);
   }
 
   *outCmdEnabled = PR_FALSE;
   return NS_OK;
 }
 
@@ -314,17 +317,18 @@ nsCopyCommand::IsCommandEnabled(const ch
                                 nsISupports *aCommandRefCon,
                                 PRBool *outCmdEnabled)
 {
   NS_ENSURE_ARG_POINTER(outCmdEnabled);
   nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
   if (editor)
   {
     PRBool isEditable = PR_FALSE;
-    NS_SUCCEEDED(editor->GetIsSelectionEditable(&isEditable));
+    nsresult rv = editor->GetIsSelectionEditable(&isEditable);
+    NS_ENSURE_SUCCESS(rv, rv);
     if (isEditable)
       return editor->CanCopy(outCmdEnabled);
   }
 
   *outCmdEnabled = PR_FALSE;
   return NS_OK;
 }
 
@@ -417,17 +421,18 @@ nsPasteCommand::IsCommandEnabled(const c
                                  nsISupports *aCommandRefCon,
                                  PRBool *outCmdEnabled)
 {
   NS_ENSURE_ARG_POINTER(outCmdEnabled);
   nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
   if (editor)
   {
     PRBool isEditable = PR_FALSE;
-    NS_SUCCEEDED(editor->GetIsSelectionEditable(&isEditable));
+    nsresult rv = editor->GetIsSelectionEditable(&isEditable);
+    NS_ENSURE_SUCCESS(rv, rv);
     if (isEditable)
       return editor->CanPaste(nsIClipboard::kGlobalClipboard, outCmdEnabled);
   }
 
   *outCmdEnabled = PR_FALSE;
   return NS_OK;
 }
 
@@ -464,17 +469,18 @@ nsPasteTransferableCommand::IsCommandEna
                                              nsISupports *aCommandRefCon,
                                              PRBool *outCmdEnabled)
 {
   NS_ENSURE_ARG_POINTER(outCmdEnabled);
   nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
   if (editor)
   {
     PRBool isEditable = PR_FALSE;
-    NS_SUCCEEDED(editor->GetIsSelectionEditable(&isEditable));
+    nsresult rv = editor->GetIsSelectionEditable(&isEditable);
+    NS_ENSURE_SUCCESS(rv, rv);
     if (isEditable)
       return editor->CanPasteTransferable(nsnull, outCmdEnabled);
   }
 
   *outCmdEnabled = PR_FALSE;
   return NS_OK;
 }
 
@@ -575,17 +581,18 @@ nsDeleteCommand::IsCommandEnabled(const 
   NS_ENSURE_ARG_POINTER(outCmdEnabled);
   nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
   *outCmdEnabled = PR_FALSE;
 
   // we can delete when we can cut
   NS_ENSURE_TRUE(editor, NS_OK);
     
   PRBool isEditable = PR_FALSE;
-  NS_SUCCEEDED(editor->GetIsSelectionEditable(&isEditable));
+  nsresult rv = editor->GetIsSelectionEditable(&isEditable);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   if (!isEditable)
     return NS_OK;
   else if (!nsCRT::strcmp(aCommandName,"cmd_delete"))
     return editor->CanCut(outCmdEnabled);
   else if (!nsCRT::strcmp(aCommandName,"cmd_deleteCharBackward"))
     *outCmdEnabled = PR_TRUE;
   else if (!nsCRT::strcmp(aCommandName,"cmd_deleteCharForward"))
--- a/editor/libeditor/base/nsEditorEventListener.cpp
+++ b/editor/libeditor/base/nsEditorEventListener.cpp
@@ -121,88 +121,72 @@ nsEditorEventListener::Connect(nsEditor*
 nsresult
 nsEditorEventListener::InstallToEditor()
 {
   NS_PRECONDITION(mEditor, "The caller must set mEditor");
 
   nsCOMPtr<nsIDOMEventTarget> piTarget = mEditor->GetDOMEventTarget();
   NS_ENSURE_TRUE(piTarget, NS_ERROR_FAILURE);
 
-  nsresult rv;
-
   // register the event listeners with the listener manager
   nsEventListenerManager* elmP = piTarget->GetListenerManager(PR_TRUE);
   NS_ENSURE_STATE(elmP);
 
-  rv = elmP->AddEventListenerByType(this,
-                                    NS_LITERAL_STRING("keypress"),
-                                    NS_EVENT_FLAG_BUBBLE |
-                                    NS_PRIV_EVENT_UNTRUSTED_PERMITTED |
-                                    NS_EVENT_FLAG_SYSTEM_EVENT);
-  NS_ENSURE_SUCCESS(rv, rv);
+  elmP->AddEventListenerByType(this,
+                               NS_LITERAL_STRING("keypress"),
+                               NS_EVENT_FLAG_BUBBLE |
+                               NS_PRIV_EVENT_UNTRUSTED_PERMITTED |
+                               NS_EVENT_FLAG_SYSTEM_EVENT);
   // See bug 455215, we cannot use the standard dragstart event yet
-  rv = elmP->AddEventListenerByType(this,
-                                    NS_LITERAL_STRING("draggesture"),
-                                    NS_EVENT_FLAG_BUBBLE |
-                                    NS_EVENT_FLAG_SYSTEM_EVENT);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = elmP->AddEventListenerByType(this,
-                                    NS_LITERAL_STRING("dragenter"),
-                                    NS_EVENT_FLAG_BUBBLE |
-                                    NS_EVENT_FLAG_SYSTEM_EVENT);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = elmP->AddEventListenerByType(this,
-                                    NS_LITERAL_STRING("dragover"),
-                                    NS_EVENT_FLAG_BUBBLE |
-                                    NS_EVENT_FLAG_SYSTEM_EVENT);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = elmP->AddEventListenerByType(this,
-                                    NS_LITERAL_STRING("dragexit"),
-                                    NS_EVENT_FLAG_BUBBLE |
-                                    NS_EVENT_FLAG_SYSTEM_EVENT);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = elmP->AddEventListenerByType(this,
-                                    NS_LITERAL_STRING("drop"),
-                                    NS_EVENT_FLAG_BUBBLE |
-                                    NS_EVENT_FLAG_SYSTEM_EVENT);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = elmP->AddEventListenerByType(this,
-                                    NS_LITERAL_STRING("mousedown"),
-                                    NS_EVENT_FLAG_CAPTURE);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = elmP->AddEventListenerByType(this,
-                                    NS_LITERAL_STRING("mouseup"),
-                                    NS_EVENT_FLAG_CAPTURE);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = elmP->AddEventListenerByType(this,
-                                    NS_LITERAL_STRING("click"),
-                                    NS_EVENT_FLAG_CAPTURE);
-  NS_ENSURE_SUCCESS(rv, rv);
-  // Focus event doesn't bubble so adding the listener to capturing phase.
-  // Make sure this works after bug 235441 gets fixed.
-  rv = elmP->AddEventListenerByType(this,
-                                    NS_LITERAL_STRING("blur"),
-                                    NS_EVENT_FLAG_CAPTURE);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = elmP->AddEventListenerByType(this,
-                                    NS_LITERAL_STRING("focus"),
-                                    NS_EVENT_FLAG_CAPTURE);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = elmP->AddEventListenerByType(this,
-                                    NS_LITERAL_STRING("text"),
-                                    NS_EVENT_FLAG_BUBBLE);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = elmP->AddEventListenerByType(this,
-                                    NS_LITERAL_STRING("compositionstart"),
-                                    NS_EVENT_FLAG_BUBBLE);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = elmP->AddEventListenerByType(this,
-                                    NS_LITERAL_STRING("compositionend"),
-                                    NS_EVENT_FLAG_BUBBLE);
-  NS_ENSURE_SUCCESS(rv, rv);
+  elmP->AddEventListenerByType(this,
+                               NS_LITERAL_STRING("draggesture"),
+                               NS_EVENT_FLAG_BUBBLE |
+                               NS_EVENT_FLAG_SYSTEM_EVENT);
+  elmP->AddEventListenerByType(this,
+                               NS_LITERAL_STRING("dragenter"),
+                               NS_EVENT_FLAG_BUBBLE |
+                               NS_EVENT_FLAG_SYSTEM_EVENT);
+  elmP->AddEventListenerByType(this,
+                               NS_LITERAL_STRING("dragover"),
+                               NS_EVENT_FLAG_BUBBLE |
+                               NS_EVENT_FLAG_SYSTEM_EVENT);
+  elmP->AddEventListenerByType(this,
+                               NS_LITERAL_STRING("dragexit"),
+                               NS_EVENT_FLAG_BUBBLE |
+                               NS_EVENT_FLAG_SYSTEM_EVENT);
+  elmP->AddEventListenerByType(this,
+                               NS_LITERAL_STRING("drop"),
+                               NS_EVENT_FLAG_BUBBLE |
+                               NS_EVENT_FLAG_SYSTEM_EVENT);
+  elmP->AddEventListenerByType(this,
+                               NS_LITERAL_STRING("mousedown"),
+                               NS_EVENT_FLAG_CAPTURE);
+  elmP->AddEventListenerByType(this,
+                               NS_LITERAL_STRING("mouseup"),
+                               NS_EVENT_FLAG_CAPTURE);
+  elmP->AddEventListenerByType(this,
+                               NS_LITERAL_STRING("click"),
+                               NS_EVENT_FLAG_CAPTURE);
+// Focus event doesn't bubble so adding the listener to capturing phase.
+// Make sure this works after bug 235441 gets fixed.
+  elmP->AddEventListenerByType(this,
+                               NS_LITERAL_STRING("blur"),
+                               NS_EVENT_FLAG_CAPTURE);
+  elmP->AddEventListenerByType(this,
+                               NS_LITERAL_STRING("focus"),
+                               NS_EVENT_FLAG_CAPTURE);
+  elmP->AddEventListenerByType(this,
+                               NS_LITERAL_STRING("text"),
+                               NS_EVENT_FLAG_BUBBLE);
+  elmP->AddEventListenerByType(this,
+                               NS_LITERAL_STRING("compositionstart"),
+                               NS_EVENT_FLAG_BUBBLE);
+  elmP->AddEventListenerByType(this,
+                               NS_LITERAL_STRING("compositionend"),
+                               NS_EVENT_FLAG_BUBBLE);
 
   return NS_OK;
 }
 
 void
 nsEditorEventListener::Disconnect()
 {
   if (!mEditor) {
--- a/embedding/android/GeckoApp.java
+++ b/embedding/android/GeckoApp.java
@@ -61,16 +61,18 @@ import android.util.*;
 import android.net.*;
 import android.database.*;
 import android.provider.*;
 import android.telephony.*;
 
 abstract public class GeckoApp
     extends Activity
 {
+    private static final String LOG_FILE_NAME     = "GeckoApp";
+
     public static final String ACTION_ALERT_CLICK = "org.mozilla.gecko.ACTION_ALERT_CLICK";
     public static final String ACTION_ALERT_CLEAR = "org.mozilla.gecko.ACTION_ALERT_CLEAR";
     public static final String ACTION_WEBAPP      = "org.mozilla.gecko.WEBAPP";
     public static final String ACTION_DEBUG       = "org.mozilla.gecko.DEBUG";
     public static final String ACTION_BOOKMARK    = "org.mozilla.gecko.BOOKMARK";
 
     public static FrameLayout mainLayout;
     public static GeckoSurfaceView surfaceView;
@@ -146,23 +148,23 @@ abstract public class GeckoApp
                 } catch (InterruptedException ie) {}
                 surfaceView.mSplashStatusMsg =
                     getResources().getString(R.string.splash_screen_loading);
                 surfaceView.drawSplashScreen();
                 // unpack files in the components directory
                 try {
                     unpackComponents();
                 } catch (FileNotFoundException fnfe) {
-                    Log.e("GeckoApp", "error unpacking components", fnfe);
+                    Log.e(LOG_FILE_NAME, "error unpacking components", fnfe);
                     Looper.prepare();
                     showErrorDialog(getString(R.string.error_loading_file));
                     Looper.loop();
                     return;
                 } catch (IOException ie) {
-                    Log.e("GeckoApp", "error unpacking components", ie);
+                    Log.e(LOG_FILE_NAME, "error unpacking components", ie);
                     String msg = ie.getMessage();
                     Looper.prepare();
                     if (msg != null && msg.equalsIgnoreCase("No space left on device"))
                         showErrorDialog(getString(R.string.no_space_to_start_error));
                     else
                         showErrorDialog(getString(R.string.error_loading_file));
                     Looper.loop();
                     return;
@@ -170,17 +172,17 @@ abstract public class GeckoApp
 
                 // and then fire us up
                 try {
                     String env = i.getStringExtra("env0");
                     GeckoAppShell.runGecko(getApplication().getPackageResourcePath(),
                                            i.getStringExtra("args"),
                                            i.getDataString());
                 } catch (Exception e) {
-                    Log.e("GeckoApp", "top level exception", e);
+                    Log.e(LOG_FILE_NAME, "top level exception", e);
                     StringWriter sw = new StringWriter();
                     e.printStackTrace(new PrintWriter(sw));
                     GeckoAppShell.reportJavaCrash(sw.toString());
                 }
             }
         }.start();
         return true;
     }
@@ -194,33 +196,33 @@ abstract public class GeckoApp
 
         if (!sTryCatchAttached) {
             sTryCatchAttached = true;
             mMainHandler.post(new Runnable() {
                 public void run() {
                     try {
                         Looper.loop();
                     } catch (Exception e) {
-                        Log.e("GeckoApp", "top level exception", e);
+                        Log.e(LOG_FILE_NAME, "top level exception", e);
                         StringWriter sw = new StringWriter();
                         e.printStackTrace(new PrintWriter(sw));
                         GeckoAppShell.reportJavaCrash(sw.toString());
                     }
                     // resetting this is kinda pointless, but oh well
                     sTryCatchAttached = false;
                 }
             });
         }
 
         SharedPreferences settings = getPreferences(Activity.MODE_PRIVATE);
         String localeCode = settings.getString(getPackageName() + ".locale", "");
         if (localeCode != null && localeCode.length() > 0)
             GeckoAppShell.setSelectedLocale(localeCode);
 
-        Log.i("GeckoApp", "create");
+        Log.i(LOG_FILE_NAME, "create");
         super.onCreate(savedInstanceState);
 
         if (sGREDir == null)
             sGREDir = new File(this.getApplicationInfo().dataDir);
 
         getWindow().setFlags(mFullscreen ?
                              WindowManager.LayoutParams.FLAG_FULLSCREEN : 0,
                              WindowManager.LayoutParams.FLAG_FULLSCREEN);
@@ -314,40 +316,40 @@ abstract public class GeckoApp
             });
             mainLayout.addView(launchButton, 300, 200);
             return;
         }
         if (checkLaunchState(LaunchState.WaitButton) || launch(intent))
             return;
 
         if (Intent.ACTION_MAIN.equals(action)) {
-            Log.i("GeckoApp", "Intent : ACTION_MAIN");
+            Log.i(LOG_FILE_NAME, "Intent : ACTION_MAIN");
             GeckoAppShell.sendEventToGecko(new GeckoEvent(""));
         }
         else if (Intent.ACTION_VIEW.equals(action)) {
             String uri = intent.getDataString();
             GeckoAppShell.sendEventToGecko(new GeckoEvent(uri));
-            Log.i("GeckoApp","onNewIntent: "+uri);
+            Log.i(LOG_FILE_NAME,"onNewIntent: "+uri);
         }
         else if (ACTION_WEBAPP.equals(action)) {
             String uri = intent.getStringExtra("args");
             GeckoAppShell.sendEventToGecko(new GeckoEvent(uri));
-            Log.i("GeckoApp","Intent : WEBAPP - " + uri);
+            Log.i(LOG_FILE_NAME,"Intent : WEBAPP - " + uri);
         }
         else if (ACTION_BOOKMARK.equals(action)) {
             String args = intent.getStringExtra("args");
             GeckoAppShell.sendEventToGecko(new GeckoEvent(args));
-            Log.i("GeckoApp","Intent : BOOKMARK - " + args);
+            Log.i(LOG_FILE_NAME,"Intent : BOOKMARK - " + args);
         }
     }
 
     @Override
     public void onPause()
     {
-        Log.i("GeckoApp", "pause");
+        Log.i(LOG_FILE_NAME, "pause");
         GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_PAUSING));
         // The user is navigating away from this activity, but nothing
         // has come to the foreground yet; for Gecko, we may want to
         // stop repainting, for example.
 
         // Whatever we do here should be fast, because we're blocking
         // the next activity from showing up until we finish.
 
@@ -359,17 +361,17 @@ abstract public class GeckoApp
         TelephonyManager tm = (TelephonyManager)
             GeckoApp.mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
         tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
     }
 
     @Override
     public void onResume()
     {
-        Log.i("GeckoApp", "resume");
+        Log.i(LOG_FILE_NAME, "resume");
         if (checkLaunchState(LaunchState.GeckoRunning))
             GeckoAppShell.onResume();
         // After an onPause, the activity is back in the foreground.
         // Undo whatever we did in onPause.
         super.onResume();
 
         // Just in case. Normally we start in onNewIntent
         if (checkLaunchState(LaunchState.PreLaunch) ||
@@ -384,17 +386,17 @@ abstract public class GeckoApp
 
         // Notify if network state changed since we paused
         GeckoAppShell.onNetworkStateChange(true);
     }
 
     @Override
     public void onStop()
     {
-        Log.i("GeckoApp", "stop");
+        Log.i(LOG_FILE_NAME, "stop");
         // We're about to be stopped, potentially in preparation for
         // being destroyed.  We're killable after this point -- as I
         // understand it, in extreme cases the process can be terminated
         // without going through onDestroy.
         //
         // We might also get an onRestart after this; not sure what
         // that would mean for Gecko if we were to kill it here.
         // Instead, what we should do here is save prefs, session,
@@ -405,52 +407,52 @@ abstract public class GeckoApp
         GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_STOPPING));
         super.onStop();
         GeckoAppShell.putChildInBackground();
     }
 
     @Override
     public void onRestart()
     {
-        Log.i("GeckoApp", "restart");
+        Log.i(LOG_FILE_NAME, "restart");
         GeckoAppShell.putChildInForeground();
         super.onRestart();
     }
 
     @Override
     public void onStart()
     {
-        Log.i("GeckoApp", "start");
+        Log.i(LOG_FILE_NAME, "start");
         super.onStart();
     }
 
     @Override
     public void onDestroy()
     {
-        Log.i("GeckoApp", "destroy");
+        Log.i(LOG_FILE_NAME, "destroy");
         // Tell Gecko to shutting down; we'll end up calling System.exit()
         // in onXreExit.
         if (isFinishing())
             GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_SHUTDOWN));
 
         super.onDestroy();
     }
 
     @Override
     public void onConfigurationChanged(android.content.res.Configuration newConfig)
     {
-        Log.i("GeckoApp", "configuration changed");
+        Log.i(LOG_FILE_NAME, "configuration changed");
         // nothing, just ignore
         super.onConfigurationChanged(newConfig);
     }
 
     @Override
     public void onLowMemory()
     {
-        Log.e("GeckoApp", "low memory");
+        Log.e(LOG_FILE_NAME, "low memory");
         if (checkLaunchState(LaunchState.GeckoRunning))
             GeckoAppShell.onLowMemory();
         super.onLowMemory();
     }
 
     abstract public String getPackageName();
     abstract public String getContentProcessName();
 
@@ -465,17 +467,17 @@ abstract public class GeckoApp
         zip = new ZipFile(getApplication().getPackageResourcePath());
 
         byte[] buf = new byte[8192];
         try {
             if (unpackFile(zip, buf, null, "removed-files"))
                 removeFiles();
         } catch (Exception ex) {
             // This file may not be there, so just log any errors and move on
-            Log.w("GeckoApp", "error removing files", ex);
+            Log.w(LOG_FILE_NAME, "error removing files", ex);
         }
         unpackFile(zip, buf, null, "application.ini");
         unpackFile(zip, buf, null, getContentProcessName());
         try {
             unpackFile(zip, buf, null, "update.locale");
         } catch (Exception e) {/* this is non-fatal */}
 
         // copy any .xpi file into an extensions/ directory
@@ -580,33 +582,33 @@ abstract public class GeckoApp
         try {
             String action = "org.mozilla.gecko.restart";
             Intent intent = new Intent(action);
             intent.setClassName(getPackageName(),
                                 getPackageName() + ".Restarter");
             addEnvToIntent(intent);
             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
                             Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
-            Log.i("GeckoAppJava", intent.toString());
+            Log.i(LOG_FILE_NAME, intent.toString());
             GeckoAppShell.killAnyZombies();
             startActivity(intent);
         } catch (Exception e) {
-            Log.i("GeckoAppJava", "error doing restart", e);
+            Log.i(LOG_FILE_NAME, "error doing restart", e);
         }
         finish();
         // Give the restart process time to start before we die
         GeckoAppShell.waitForAnotherGeckoProc();
     }
 
     public void handleNotification(String action, String alertName, String alertCookie) {
         GeckoAppShell.handleNotification(action, alertName, alertCookie);
     }
 
     private void checkAndLaunchUpdate() {
-        Log.i("GeckoAppJava", "Checking for an update");
+        Log.i(LOG_FILE_NAME, "Checking for an update");
 
         int statusCode = 8; // UNEXPECTED_ERROR
         File baseUpdateDir = null;
         if (Build.VERSION.SDK_INT >= 8)
             baseUpdateDir = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
         else
             baseUpdateDir = new File(Environment.getExternalStorageDirectory().getPath(), "download");
 
@@ -616,81 +618,85 @@ abstract public class GeckoApp
         File statusFile = new File(updateDir, "update.status");
 
         if (!statusFile.exists() || !readUpdateStatus(statusFile).equals("pending"))
             return;
 
         if (!updateFile.exists())
             return;
 
-        Log.i("GeckoAppJava", "Update is available!");
+        Log.i(LOG_FILE_NAME, "Update is available!");
 
         // Launch APK
         File updateFileToRun = new File(updateDir, getPackageName() + "-update.apk");
         try {
             if (updateFile.renameTo(updateFileToRun)) {
                 String amCmd = "/system/bin/am start -a android.intent.action.VIEW " +
                                "-n com.android.packageinstaller/.PackageInstallerActivity -d file://" +
                                updateFileToRun.getPath();
-                Log.i("GeckoAppJava", amCmd);
+                Log.i(LOG_FILE_NAME, amCmd);
                 Runtime.getRuntime().exec(amCmd);
                 statusCode = 0; // OK
             } else {
-                Log.i("GeckoAppJava", "Cannot rename the update file!");
+                Log.i(LOG_FILE_NAME, "Cannot rename the update file!");
                 statusCode = 7; // WRITE_ERROR
             }
         } catch (Exception e) {
-            Log.i("GeckoAppJava", "error launching installer to update", e);
+            Log.i(LOG_FILE_NAME, "error launching installer to update", e);
         }
 
         // Update the status file
         String status = statusCode == 0 ? "succeeded\n" : "failed: "+ statusCode + "\n";
 
         OutputStream outStream;
         try {
             byte[] buf = status.getBytes("UTF-8");
             outStream = new FileOutputStream(statusFile);
             outStream.write(buf, 0, buf.length);
             outStream.close();
         } catch (Exception e) {
-            Log.i("GeckoAppJava", "error writing status file", e);
+            Log.i(LOG_FILE_NAME, "error writing status file", e);
         }
 
         if (statusCode == 0)
             System.exit(0);
     }
 
     private String readUpdateStatus(File statusFile) {
         String status = "";
         try {
             BufferedReader reader = new BufferedReader(new FileReader(statusFile));
             status = reader.readLine();
             reader.close();
         } catch (Exception e) {
-            Log.i("GeckoAppJava", "error reading update status", e);
+            Log.i(LOG_FILE_NAME, "error reading update status", e);
         }
         return status;
     }
 
     static final int FILE_PICKER_REQUEST = 1;
 
     private SynchronousQueue<String> mFilePickerResult = new SynchronousQueue();
     public String showFilePicker(String aMimeType) {
         Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
         intent.addCategory(Intent.CATEGORY_OPENABLE);
         intent.setType(aMimeType);
         GeckoApp.this.
             startActivityForResult(
                 Intent.createChooser(intent, getString(R.string.choose_file)),
                 FILE_PICKER_REQUEST);
         String filePickerResult = "";
+
         try {
-            filePickerResult = mFilePickerResult.take();
+            while (null == (filePickerResult = mFilePickerResult.poll(1, TimeUnit.MILLISECONDS))) {
+                Log.i("GeckoApp", "processing events from showFilePicker ");
+                GeckoAppShell.processNextNativeEvent();
+            }
         } catch (InterruptedException e) {
-            Log.i("GeckoApp", "showing file picker ",  e);
+            Log.i(LOG_FILE_NAME, "showing file picker ",  e);
         }
 
         return filePickerResult;
     }
 
     @Override
     protected void onActivityResult(int requestCode, int resultCode,
                                     Intent data) {
@@ -733,18 +739,18 @@ abstract public class GeckoApp
                 int len = is.read(buf);
                 while (len != -1) {
                     fos.write(buf, 0, len);
                     len = is.read(buf);
                 }
                 fos.close();
                 filePickerResult =  file.getAbsolutePath();
             }catch (Exception e) {
-                Log.e("GeckoApp", "showing file picker", e);
+                Log.e(LOG_FILE_NAME, "showing file picker", e);
             }
         }
         try {
             mFilePickerResult.put(filePickerResult);
         } catch (InterruptedException e) {
-            Log.i("GeckoApp", "error returning file picker result", e);
+            Log.i(LOG_FILE_NAME, "error returning file picker result", e);
         }
     }
 }
--- a/embedding/android/GeckoAppShell.java
+++ b/embedding/android/GeckoAppShell.java
@@ -69,16 +69,18 @@ import android.net.Uri;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 
 import android.graphics.drawable.*;
 import android.graphics.Bitmap;
 
 public class GeckoAppShell
 {
+    private static final String LOG_FILE_NAME = "GeckoAppShell";
+
     // static members only
     private GeckoAppShell() { }
 
     static private LinkedList<GeckoEvent> gPendingEvents =
         new LinkedList<GeckoEvent>();
 
     static private boolean gRestartScheduled = false;
 
@@ -112,16 +114,18 @@ public class GeckoAppShell
     public static native void onResume();
     public static native void onLowMemory();
     public static native void callObserver(String observerKey, String topic, String data);
     public static native void removeObserver(String observerKey);
     public static native void loadLibs(String apkName, boolean shouldExtract);
     public static native void onChangeNetworkLinkStatus(String status, String type);
     public static native void reportJavaCrash(String stack);
 
+    public static native void processNextNativeEvent();
+
     // A looper thread, accessed by GeckoAppShell.getHandler
     private static class LooperThread extends Thread {
         public SynchronousQueue<Handler> mHandlerQueue =
             new SynchronousQueue<Handler>();
         
         public void run() {
             Looper.prepare();
             try {
@@ -185,35 +189,35 @@ public class GeckoAppShell
         try {
             if (sFreeSpace == -1) {
                 File cacheDir = getCacheDir();
                 if (cacheDir != null) {
                     StatFs cacheStats = new StatFs(cacheDir.getPath());
                     sFreeSpace = cacheStats.getFreeBlocks() *
                         cacheStats.getBlockSize();
                 } else {
-                    Log.i("GeckoAppShell", "Unable to get cache dir");
+                    Log.i(LOG_FILE_NAME, "Unable to get cache dir");
                 }
             }
         } catch (Exception e) {
-            Log.e("GeckoAppShell", "exception while stating cache dir: ", e);
+            Log.e(LOG_FILE_NAME, "exception while stating cache dir: ", e);
         }
         return sFreeSpace;
     }
 
     static boolean moveFile(File inFile, File outFile)
     {
-        Log.i("GeckoAppShell", "moving " + inFile + " to " + outFile);
+        Log.i(LOG_FILE_NAME, "moving " + inFile + " to " + outFile);
         if (outFile.isDirectory())
             outFile = new File(outFile, inFile.getName());
         try {
             if (inFile.renameTo(outFile))
                 return true;
         } catch (SecurityException se) {
-            Log.w("GeckoAppShell", "error trying to rename file", se);
+            Log.w(LOG_FILE_NAME, "error trying to rename file", se);
         }
         try {
             long lastModified = inFile.lastModified();
             outFile.createNewFile();
             // so copy it instead
             FileChannel inChannel = new FileInputStream(inFile).getChannel();
             FileChannel outChannel = new FileOutputStream(outFile).getChannel();
             long size = inChannel.size();
@@ -222,34 +226,34 @@ public class GeckoAppShell
             outChannel.close();
             outFile.setLastModified(lastModified);
 
             if (transferred == size)
                 inFile.delete();
             else
                 return false;
         } catch (Exception e) {
-            Log.e("GeckoAppShell", "exception while moving file: ", e);
+            Log.e(LOG_FILE_NAME, "exception while moving file: ", e);
             try {
                 outFile.delete();
             } catch (SecurityException se) {
-                Log.w("GeckoAppShell", "error trying to delete file", se);
+                Log.w(LOG_FILE_NAME, "error trying to delete file", se);
             }
             return false;
         }
         return true;
     }
 
     static boolean moveDir(File from, File to) {
         try {
             to.mkdirs();
             if (from.renameTo(to))
                 return true;
         } catch (SecurityException se) {
-            Log.w("GeckoAppShell", "error trying to rename file", se);
+            Log.w(LOG_FILE_NAME, "error trying to rename file", se);
         }
         File[] files = from.listFiles();
         boolean retVal = true;
         if (files == null)
             return false;
         try {
             Iterator fileIterator = Arrays.asList(files).iterator();
             while (fileIterator.hasNext()) {
@@ -257,17 +261,17 @@ public class GeckoAppShell
                 File dest = new File(to, file.getName());
                 if (file.isDirectory())
                     retVal = moveDir(file, dest) ? retVal : false;
                 else
                     retVal = moveFile(file, dest) ? retVal : false;
             }
             from.delete();
         } catch(Exception e) {
-            Log.e("GeckoAppShell", "error trying to move file", e);
+            Log.e(LOG_FILE_NAME, "error trying to move file", e);
         }
         return retVal;
     }
 
     // java-side stuff
     public static void loadGeckoLibs(String apkName) {
         // The package data lib directory isn't placed in ld.so's
         // search path, so we have to manually load libraries that
@@ -305,21 +309,21 @@ public class GeckoAppShell
             File intProf = new File(intHome, "mozilla");
             if (intHome != null && intProf != null && intProf.exists())
                 moveDir(intProf, profileDir);
         }
         GeckoAppShell.putenv("HOME=" + homeDir);
         GeckoAppShell.putenv("GRE_HOME=" + GeckoApp.sGREDir.getPath());
         Intent i = geckoApp.getIntent();
         String env = i.getStringExtra("env0");
-        Log.i("GeckoApp", "env0: "+ env);
+        Log.i(LOG_FILE_NAME, "env0: "+ env);
         for (int c = 1; env != null; c++) {
             GeckoAppShell.putenv(env);
             env = i.getStringExtra("env" + c);
-            Log.i("GeckoApp", "env"+ c +": "+ env);
+            Log.i(LOG_FILE_NAME, "env"+ c +": "+ env);
         }
 
         File f = geckoApp.getDir("tmp", Context.MODE_WORLD_READABLE |
                                  Context.MODE_WORLD_WRITEABLE );
 
         if (!f.exists())
             f.mkdirs();
 
@@ -341,17 +345,17 @@ public class GeckoAppShell
                 updatesDir  = GeckoApp.mAppContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
             } else {
                 updatesDir = downloadDir = new File(Environment.getExternalStorageDirectory().getPath(), "download");
             }
             GeckoAppShell.putenv("DOWNLOADS_DIRECTORY=" + downloadDir.getPath());
             GeckoAppShell.putenv("UPDATES_DIRECTORY="   + updatesDir.getPath());
         }
         catch (Exception e) {
-            Log.i("GeckoApp", "No download directory has been found: " + e);
+            Log.i(LOG_FILE_NAME, "No download directory has been found: " + e);
         }
 
         putLocaleEnv();
 
         if (freeSpace + kLibFreeSpaceBuffer < kFreeSpaceThreshold) {
             // remove any previously extracted libs since we're apparently low
             File[] files = cacheFile.listFiles();
             if (files != null) {
@@ -1102,17 +1106,17 @@ public class GeckoAppShell
                     type = "4g";
                     typeCode = 7;
                 }
             }
         }
 
         // If the network state has changed, notify Gecko
         if (notifyChanged && (state != sNetworkState || typeCode != sNetworkTypeCode)) {
-            Log.i("GeckoAppShell", "Network state changed: (" + state + ", " + type + ") ");
+            Log.i(LOG_FILE_NAME, "Network state changed: (" + state + ", " + type + ") ");
             sNetworkState = state;
             sNetworkType = type;
             sNetworkTypeCode = typeCode;
             if (GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning))
                 onChangeNetworkLinkStatus(sNetworkState, sNetworkType);
         }
     }
 
@@ -1186,17 +1190,17 @@ public class GeckoAppShell
                 public boolean callback(int pid) {
                     if (pid != android.os.Process.myPid()) {
                         try {
                             FileOutputStream fos = new FileOutputStream(
                                 new File("/dev/cpuctl/" + backgroundGroup +"/tasks"));
                             fos.write(new Integer(pid).toString().getBytes());
                             fos.close();
                         } catch(Exception e) {
-                            Log.e("GeckoAppShell", "error putting child in the background", e);
+                            Log.e(LOG_FILE_NAME, "error putting child in the background", e);
                         }
                     }
                     return true;
                 }
             };
             EnumerateGeckoProcesses(visitor);
         } catch (Exception e) {
             Log.e("GeckoInputStream", "error reading cgroup", e);
@@ -1207,17 +1211,17 @@ public class GeckoAppShell
         GeckoProcessesVisitor visitor = new GeckoProcessesVisitor() {
             public boolean callback(int pid) {
                 if (pid != android.os.Process.myPid()) {
                     try {
                         FileOutputStream fos = new FileOutputStream(new File("/dev/cpuctl/tasks"));
                         fos.write(new Integer(pid).toString().getBytes());
                         fos.close();
                     } catch(Exception e) {
-                        Log.e("GeckoAppShell", "error putting child in the foreground", e);
+                        Log.e(LOG_FILE_NAME, "error putting child in the foreground", e);
                     }
                 }
                 return true;
             }
         };   
         EnumerateGeckoProcesses(visitor);
     }
 
@@ -1295,17 +1299,17 @@ public class GeckoAppShell
                     boolean keepGoing = visiter.callback(pid);
                     if (keepGoing == false)
                         break;
                 }
             }
             in.close();
         }
         catch (Exception e) {
-            Log.i("GeckoAppShell", "finding procs throws ",  e);
+            Log.i(LOG_FILE_NAME, "finding procs throws ",  e);
         }
     }
 
     public static void waitForAnotherGeckoProc(){
         int countdown = 40;
         while (!checkForGeckoProcs() &&  --countdown > 0) {
             try {
                 Thread.currentThread().sleep(100);
@@ -1338,17 +1342,17 @@ public class GeckoAppShell
                 bitmap = Bitmap.createScaledBitmap(bitmap, iconSize, iconSize, true);
 
             ByteBuffer buf = ByteBuffer.allocate(iconSize * iconSize * 4);
             bitmap.copyPixelsToBuffer(buf);
 
             return buf.array();
         }
         catch (Exception e) {
-            Log.i("GeckoAppShell", "getIconForExtension error: ",  e);
+            Log.i(LOG_FILE_NAME, "getIconForExtension error: ",  e);
             return null;
         }
     }
 
     private static Drawable getDrawableForExtension(PackageManager pm, String aExt) {
         Intent intent = new Intent(Intent.ACTION_VIEW);
         MimeTypeMap mtm = MimeTypeMap.getSingleton();
         String mimeType = mtm.getMimeTypeFromExtension(aExt);
--- a/embedding/android/GeckoSurfaceView.java
+++ b/embedding/android/GeckoSurfaceView.java
@@ -66,16 +66,18 @@ import android.util.*;
  * similar to GLSurfaceView.  However, since we
  * already have a thread for Gecko, we don't really want
  * a separate renderer thread that GLSurfaceView provides.
  */
 class GeckoSurfaceView
     extends SurfaceView
     implements SurfaceHolder.Callback, SensorEventListener, LocationListener
 {
+    private static final String LOG_FILE_NAME = "GeckoSurfaceView";
+
     public GeckoSurfaceView(Context context) {
         super(context);
 
         getHolder().addCallback(this);
         inputConnection = new GeckoInputConnection(this);
         setFocusable(true);
         setFocusableInTouchMode(true);
         
@@ -102,17 +104,17 @@ class GeckoSurfaceView
 
     void drawSplashScreen() {
         this.drawSplashScreen(getHolder(), mWidth, mHeight);
     }
 
     void drawSplashScreen(SurfaceHolder holder, int width, int height) {
         Canvas c = holder.lockCanvas();
         if (c == null) {
-            Log.i("GeckoSurfaceView", "canvas is null");
+            Log.i(LOG_FILE_NAME, "canvas is null");
             return;
         }
         Resources res = getResources();
         c.drawColor(res.getColor(R.color.splash_background));
         Drawable drawable = res.getDrawable(R.drawable.splash);
         int w = drawable.getIntrinsicWidth();
         int h = drawable.getIntrinsicHeight();
         int x = (width - w)/2;
@@ -168,17 +170,17 @@ class GeckoSurfaceView
 
     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
         if (mShowingSplashScreen)
             drawSplashScreen(holder, width, height);
         mSurfaceLock.lock();
 
         try {
             if (mInDrawing) {
-                Log.w("GeckoAppJava", "surfaceChanged while mInDrawing is true!");
+                Log.w(LOG_FILE_NAME, "surfaceChanged while mInDrawing is true!");
             }
 
             boolean invalidSize;
 
             if (width == 0 || height == 0) {
                 mSoftwareBitmap = null;
                 mSoftwareBuffer = null;
                 mSoftwareBufferCopy = null;
@@ -193,17 +195,17 @@ class GeckoSurfaceView
                 GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning);
             mSyncDraw = doSyncDraw;
 
             mFormat = format;
             mWidth = width;
             mHeight = height;
             mSurfaceValid = true;
 
-            Log.i("GeckoAppJava", "surfaceChanged: fmt: " + format + " dim: " + width + " " + height);
+            Log.i(LOG_FILE_NAME, "surfaceChanged: fmt: " + format + " dim: " + width + " " + height);
 
             DisplayMetrics metrics = new DisplayMetrics();
             GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
 
             GeckoEvent e = new GeckoEvent(GeckoEvent.SIZE_CHANGED, width, height,
                                           metrics.widthPixels, metrics.heightPixels);
             GeckoAppShell.sendEventToGecko(e);
 
@@ -220,38 +222,38 @@ class GeckoSurfaceView
         } finally {
             mSurfaceLock.unlock();
         }
 
         Object syncDrawObject = null;
         try {
             syncDrawObject = mSyncDraws.take();
         } catch (InterruptedException ie) {
-            Log.e("GeckoAppJava", "Threw exception while getting sync draw bitmap/buffer: ", ie);
+            Log.e(LOG_FILE_NAME, "Threw exception while getting sync draw bitmap/buffer: ", ie);
         }
         if (syncDrawObject != null) {
             if (syncDrawObject instanceof Bitmap)
                 draw(holder, (Bitmap)syncDrawObject);
             else
                 draw(holder, (ByteBuffer)syncDrawObject);
         } else {
             Log.e("GeckoSurfaceViewJava", "Synchronised draw object is null");
         }
     }
 
     public void surfaceCreated(SurfaceHolder holder) {
-        Log.i("GeckoAppJava", "surface created");
+        Log.i(LOG_FILE_NAME, "surface created");
         GeckoEvent e = new GeckoEvent(GeckoEvent.SURFACE_CREATED);
         GeckoAppShell.sendEventToGecko(e);
         if (mShowingSplashScreen)
             drawSplashScreen();
     }
 
     public void surfaceDestroyed(SurfaceHolder holder) {
-        Log.i("GeckoAppJava", "surface destroyed");
+        Log.i(LOG_FILE_NAME, "surface destroyed");
         mSurfaceValid = false;
         mSoftwareBuffer = null;
         mSoftwareBufferCopy = null;
         mSoftwareBitmap = null;
         GeckoEvent e = new GeckoEvent(GeckoEvent.SURFACE_DESTROYED);
         GeckoAppShell.sendEventToGecko(e);
     }
 
@@ -289,17 +291,17 @@ class GeckoSurfaceView
      */
 
     public static final int DRAW_ERROR = 0;
     public static final int DRAW_GLES_2 = 1;
     public static final int DRAW_2D = 2;
 
     public int beginDrawing() {
         if (mInDrawing) {
-            Log.e("GeckoAppJava", "Recursive beginDrawing call!");
+            Log.e(LOG_FILE_NAME, "Recursive beginDrawing call!");
             return DRAW_ERROR;
         }
 
         /* Grab the lock, which we'll hold while we're drawing.
          * It gets released in endDrawing(), and is also used in surfaceChanged
          * to make sure that we don't change our surface details while
          * we're in the middle of drawing (and especially in the middle of
          * executing beginDrawing/endDrawing).
@@ -307,42 +309,42 @@ class GeckoSurfaceView
          * We might not need to hold this lock in between
          * beginDrawing/endDrawing, and might just be able to make
          * surfaceChanged, beginDrawing, and endDrawing synchronized,
          * but this way is safer for now.
          */
         mSurfaceLock.lock();
 
         if (!mSurfaceValid) {
-            Log.e("GeckoAppJava", "Surface not valid");
+            Log.e(LOG_FILE_NAME, "Surface not valid");
             mSurfaceLock.unlock();
             return DRAW_ERROR;
         }
 
         mInDrawing = true;
         mDrawMode = DRAW_GLES_2;
         return DRAW_GLES_2;
     }
 
     public void endDrawing() {
         if (!mInDrawing) {
-            Log.e("GeckoAppJava", "endDrawing without beginDrawing!");
+            Log.e(LOG_FILE_NAME, "endDrawing without beginDrawing!");
             return;
         }
 
         try {
             if (!mSurfaceValid) {
-                Log.e("GeckoAppJava", "endDrawing with false mSurfaceValid");
+                Log.e(LOG_FILE_NAME, "endDrawing with false mSurfaceValid");
                 return;
             }
         } finally {
             mInDrawing = false;
 
             if (!mSurfaceLock.isHeldByCurrentThread())
-                Log.e("GeckoAppJava", "endDrawing while mSurfaceLock not held by current thread!");
+                Log.e(LOG_FILE_NAME, "endDrawing while mSurfaceLock not held by current thread!");
 
             mSurfaceLock.unlock();
         }
     }
 
     /* How this works:
      * Whenever we want to draw, we want to be sure that we do not lock
      * the canvas unless we're sure we can draw. Locking the canvas clears
@@ -363,17 +365,17 @@ class GeckoSurfaceView
         try {
             if (mSyncDraw) {
                 if (bitmap != mSoftwareBitmap || width != mWidth || height != mHeight)
                     return;
                 mSyncDraw = false;
                 try {
                     mSyncDraws.put(bitmap);
                 } catch (InterruptedException ie) {
-                    Log.e("GeckoAppJava", "Threw exception while getting sync draws queue: ", ie);
+                    Log.e(LOG_FILE_NAME, "Threw exception while getting sync draws queue: ", ie);
                 }
                 return;
             }
         } finally {
             mSurfaceLock.unlock();
         }
 
         draw(getHolder(), bitmap);
@@ -384,17 +386,17 @@ class GeckoSurfaceView
         try {
             if (mSyncDraw) {
                 if (buffer != mSoftwareBuffer || stride != (mWidth * 2))
                     return;
                 mSyncDraw = false;
                 try {
                     mSyncDraws.put(buffer);
                 } catch (InterruptedException ie) {
-                    Log.e("GeckoAppJava", "Threw exception while getting sync bitmaps queue: ", ie);
+                    Log.e(LOG_FILE_NAME, "Threw exception while getting sync bitmaps queue: ", ie);
                 }
                 return;
             }
         } finally {
             mSurfaceLock.unlock();
         }
 
         draw(getHolder(), buffer);
@@ -487,17 +489,17 @@ class GeckoSurfaceView
                 List<Address> addresses = mGeocoder.getFromLocation(location[0].getLatitude(),
                                                                     location[0].getLongitude(), 1);
                 // grab the first address.  in the future,
                 // may want to expose multiple, or filter
                 // for best.
                 mLastGeoAddress = addresses.get(0);
                 GeckoAppShell.sendEventToGecko(new GeckoEvent(location[0], mLastGeoAddress));
             } catch (Exception e) {
-                Log.w("GeckoSurfaceView", "GeocoderTask "+e);
+                Log.w(LOG_FILE_NAME, "GeocoderTask "+e);
             }
             return null;
         }
     }
 
     // geolocation
     public void onLocationChanged(Location location)
     {
--- a/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
+++ b/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
@@ -882,25 +882,23 @@ nsDocShellTreeOwner::AddChromeListeners(
     }
   }
 
   // register dragover and drop event listeners with the listener manager
   nsCOMPtr<nsIDOMEventTarget> target;
   GetDOMEventTarget(mWebBrowser, getter_AddRefs(target));
 
   nsEventListenerManager* elmP = target->GetListenerManager(PR_TRUE);
-  if (elmP)
-  {
-    rv = elmP->AddEventListenerByType(this, NS_LITERAL_STRING("dragover"),
-                                      NS_EVENT_FLAG_BUBBLE |
-                                      NS_EVENT_FLAG_SYSTEM_EVENT);
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = elmP->AddEventListenerByType(this, NS_LITERAL_STRING("drop"),
-                                      NS_EVENT_FLAG_BUBBLE |
-                                      NS_EVENT_FLAG_SYSTEM_EVENT);
+  if (elmP) {
+    elmP->AddEventListenerByType(this, NS_LITERAL_STRING("dragover"),
+                                 NS_EVENT_FLAG_BUBBLE |
+                                 NS_EVENT_FLAG_SYSTEM_EVENT);
+    elmP->AddEventListenerByType(this, NS_LITERAL_STRING("drop"),
+                                 NS_EVENT_FLAG_BUBBLE |
+                                 NS_EVENT_FLAG_SYSTEM_EVENT);
   }
 
   return rv;
   
 } // AddChromeListeners
 
 
 NS_IMETHODIMP
--- a/gfx/src/nsRenderingContext.h
+++ b/gfx/src/nsRenderingContext.h
@@ -65,17 +65,17 @@ public:
     NS_INLINE_DECL_REFCOUNTING(nsRenderingContext)
 
     void Init(nsDeviceContext* aContext, gfxASurface* aThebesSurface);
     void Init(nsDeviceContext* aContext, gfxContext* aThebesContext);
 
     // These accessors will never return null.
     gfxContext *ThebesContext() { return mThebes; }
     nsDeviceContext *DeviceContext() { return mDeviceContext; }
-    PRUint32 AppUnitsPerDevPixel() { return mP2A; }
+    PRUint32 AppUnitsPerDevPixel() { return NSToIntRound(mP2A); }
 
     // Graphics state
 
     void PushState(void);
     void PopState(void);
     void IntersectClip(const nsRect& aRect);
     void SetClip(const nsIntRegion& aRegion);
     void SetLineStyle(nsLineStyle aLineStyle);
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -2007,16 +2007,18 @@ case "$target" in
     _PLATFORM_DEFAULT_TOOLKIT='cairo-cocoa'
     TARGET_NSPR_MDCPUCFG='\"md/_darwin.cfg\"'
     LDFLAGS="$LDFLAGS -framework Cocoa -lobjc"
     LIBXUL_LIBS='$(XPCOM_FROZEN_LDOPTS) $(LIBXUL_DIST)/bin/XUL'
     # The ExceptionHandling framework is needed for Objective-C exception
     # logging code in nsObjCExceptions.h. Currently we only use that in debug
     # builds.
     MOZ_DEBUG_LDFLAGS="$MOZ_DEBUG_LDFLAGS -framework ExceptionHandling"
+    # Debug builds should always have frame pointers
+    MOZ_DEBUG_FLAGS="-g -fno-omit-frame-pointer"
 
     if test "x$lto_is_enabled" = "xyes"; then
         echo "Skipping -dead_strip because lto is enabled."
     dnl DTrace and -dead_strip don't interact well. See bug 403132.
     dnl ===================================================================
     elif test "x$enable_dtrace" = "xyes"; then
         echo "Skipping -dead_strip because DTrace is enabled. See bug 403132."
     else
@@ -2155,16 +2157,18 @@ ia64*-hpux*)
     # If we're building with --enable-profiling, we need a frame pointer.
     if test -z "$MOZ_PROFILING"; then
         MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks -fno-reorder-functions -fomit-frame-pointer"
     else
         MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks -fno-reorder-functions -fno-omit-frame-pointer"
     fi
     # The Maemo builders don't know about this flag
     MOZ_ARM_VFP_FLAGS="-mfpu=vfp"
+    # Debug builds should always have frame pointers
+    MOZ_DEBUG_FLAGS="-g -fno-omit-frame-pointer"
     ;;
 
 *-*linux*)
     # Note: both GNU_CC and INTEL_CC are set when using Intel's C compiler.
     # Similarly for GNU_CXX and INTEL_CXX.
     if test "$INTEL_CC" -o "$INTEL_CXX"; then
         # -Os has been broken on Intel's C/C++ compilers for quite a
         # while; Intel recommends against using it.
@@ -2180,17 +2184,18 @@ ia64*-hpux*)
         # If we're building with --enable-profiling, we need a frame pointer.
         if test -z "$MOZ_PROFILING"; then
             MOZ_FRAMEPTR_FLAGS="-fomit-frame-pointer"
         else
             MOZ_FRAMEPTR_FLAGS="-fno-omit-frame-pointer"
         fi
         MOZ_PGO_OPTIMIZE_FLAGS="-O3 $MOZ_FRAMEPTR_FLAGS"
         MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks $MOZ_OPTIMIZE_SIZE_TWEAK $MOZ_FRAMEPTR_FLAGS"
-        MOZ_DEBUG_FLAGS="-g"
+        # Debug builds should always have frame pointers
+        MOZ_DEBUG_FLAGS="-g -fno-omit-frame-pointer"
     fi
 
     TARGET_NSPR_MDCPUCFG='\"md/_linux.cfg\"'
 
     case "${target_cpu}" in
     alpha*)
     	CFLAGS="$CFLAGS -mieee"
     	CXXFLAGS="$CXXFLAGS -mieee"
@@ -2296,17 +2301,18 @@ ia64*-hpux*)
         CFLAGS="$CFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
         CXXFLAGS="$CXXFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
         # MSVC warnings C4244 and C4800 are ubiquitous, useless, and annoying.
         CXXFLAGS="$CXXFLAGS -wd4244 -wd4800"
         # make 'foo == bar;' error out
         CFLAGS="$CFLAGS -we4553"
         CXXFLAGS="$CXXFLAGS -we4553"
         LIBS="$LIBS kernel32.lib user32.lib gdi32.lib winmm.lib wsock32.lib advapi32.lib"
-        MOZ_DEBUG_FLAGS='-Zi'
+        # Debug builds should always have frame pointers
+        MOZ_DEBUG_FLAGS='-Zi -Oy-'
         MOZ_DEBUG_LDFLAGS='-DEBUG -DEBUGTYPE:CV'
         WARNINGS_AS_ERRORS='-WX'
         # If we're building with --enable-profiling, we need -Oy-, which forces a frame pointer.
         if test -z "$MOZ_PROFILING"; then
             MOZ_OPTIMIZE_FLAGS='-O1'
         else
             MOZ_OPTIMIZE_FLAGS='-O1 -Oy-'
         fi
@@ -3489,63 +3495,16 @@ then
 				CFLAGS="$CFLAGS -mt" 
 				CXXFLAGS="$CXXFLAGS -mt" 
 			fi
 			;;
 	esac
     LDFLAGS="${_PTHREAD_LDFLAGS} ${LDFLAGS}"
 fi
 
-dnl ========================================================
-dnl See if mmap sees writes
-dnl For cross compiling, just define it as no, which is a safe default
-dnl ========================================================
-AC_MSG_CHECKING(whether mmap() sees write()s)
-
-changequote(,)
-mmap_test_prog='
-    #include <stdlib.h>
-    #include <unistd.h>
-    #include <sys/mman.h>
-    #include <sys/types.h>
-    #include <sys/stat.h>
-    #include <fcntl.h>
-
-    char fname[] = "conftest.file";
-    char zbuff[1024]; /* Fractional page is probably worst case */
-
-    int main() {
-	char *map;
-	int fd;
-	int i;
-	unlink(fname);
-	fd = open(fname, O_RDWR | O_CREAT, 0660);
-	if(fd<0) return 1;
-	unlink(fname);
-	write(fd, zbuff, sizeof(zbuff));
-	lseek(fd, 0, SEEK_SET);
-	map = (char*)mmap(0, sizeof(zbuff), PROT_READ, MAP_SHARED, fd, 0);
-	if(map==(char*)-1) return 2;
-	for(i=0; fname[i]; i++) {
-	    int rc = write(fd, &fname[i], 1);
-	    if(map[i]!=fname[i]) return 4;
-	}
-	return 0;
-    }
-'
-changequote([,])
-
-AC_TRY_RUN($mmap_test_prog , result="yes", result="no", result="yes")
-
-AC_MSG_RESULT("$result")
-
-if test "$result" = "no"; then
-    AC_DEFINE(MMAP_MISSES_WRITES)
-fi
-
 
 dnl Checks for library functions.
 dnl ========================================================
 AC_PROG_GCC_TRADITIONAL
 AC_FUNC_MEMCMP
 AC_CHECK_FUNCS([fchmod flockfile getc_unlocked _getc_nolock getpagesize \
                 lchown localtime_r lstat64 memmove random rint sbrk snprintf \
                 stat64 statvfs statvfs64 strerror strtok_r truncate64])
rename from js/src/jit-test/tests/bug666448.js
rename to js/src/jit-test/tests/basic/bug666448.js
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/testBug677367.js
@@ -0,0 +1,5 @@
+// |jit-test| debug
+
+function f() {}
+trap(f, 0, 'eval("2+2")');
+f();
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/testErrorInFinalizerCalledWhileUnwinding.js
@@ -0,0 +1,32 @@
+var finalizerRun = false;
+var caught = false;
+
+function foo(arr) {
+  finalizerRun = true;
+  return not_defined;
+}
+
+function gen() {
+  try {
+    yield 1;
+  } finally {
+    foo();
+  }
+}
+
+function test() {
+  var i_have_locals;
+  for (i in gen()) {
+    "this won't work"();
+  }
+}
+
+try {
+    test();
+} catch(e) {
+    caught = true;
+    assertEq(''+e, "ReferenceError: not_defined is not defined");
+}
+
+assertEq(finalizerRun, true);
+assertEq(caught, true);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/testEvalFromTrap.js
@@ -0,0 +1,4 @@
+// |jit-test| debug
+function f() {}
+trap(f, 0, 'eval("2+2")');
+f();
--- a/js/src/jit-test/tests/basic/testStackIter.js
+++ b/js/src/jit-test/tests/basic/testStackIter.js
@@ -123,16 +123,22 @@ var obj = { valueOf:(function valueOf() 
 var obj = { valueOf:(function valueOf() {
     assertStackIs([valueOf, "bound(valueOf)", "bound(valueOf)", "bound(valueOf)",
                    Math.sin, Array.prototype.sort, "global-code"]);
 }).bind().bind().bind() };
 [obj, obj].sort(Math.sin);
 
 /***********/
 
+var proxy = Proxy.createFunction({}, function f() { assertStackIs([f, "global-code"]) });
+proxy();
+new proxy();
+
+/***********/
+
 for (var i = 0; i < 10; ++i) {
     /* No loss for scripts. */
     (function f() {
         assertStackIs([f, Function.prototype.apply, 'global-code']);
     }).apply(null, {});
     (function f() {
         assertStackIs([f, Function.prototype.call, 'global-code']);
     }).call(null);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Object-deleteProperty-error-01.js
@@ -0,0 +1,16 @@
+// Don't crash when a scripted proxy handler throws Error.prototype.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+dbg.onDebuggerStatement = function (frame) {
+    try {
+	frame.arguments[0].deleteProperty("x");
+    } catch (exc) {
+	return;
+    }
+    throw new Error("deleteProperty should throw");
+};
+
+g.eval("function h(x) { debugger; }");
+g.eval("h(Proxy.create({delete: function () { throw Error.prototype; }}));");
+
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/onDebuggerStatement-04.js
@@ -0,0 +1,10 @@
+var g = newGlobal('new-compartment');
+var dbg = new Debugger(g);
+dbg.onDebuggerStatement = function (frame) {
+    var code = "assertEq(c, 'ok');\n";
+    assertEq(frame.evalWithBindings("eval(s)", {s: code, a: 1234}).return, undefined);
+};
+g.eval("function first() { return second(); }");
+g.eval("function second() { return eval('third()'); }");
+g.eval("function third() { debugger; }");
+g.evaluate("first();");
--- a/js/src/jsapi-tests/testLookup.cpp
+++ b/js/src/jsapi-tests/testLookup.cpp
@@ -21,17 +21,17 @@ BEGIN_TEST(testLookup_bug522590)
 
     // This lookup must not return an internal function object.
     jsvalRoot r(cx);
     CHECK(JS_LookupProperty(cx, xobj, "f", r.addr()));
     CHECK(JSVAL_IS_OBJECT(r));
     JSObject *funobj = JSVAL_TO_OBJECT(r);
     CHECK(funobj->isFunction());
     CHECK(!js::IsInternalFunctionObject(funobj));
-    CHECK(GET_FUNCTION_PRIVATE(cx, funobj) != (JSFunction *) funobj);
+    CHECK(funobj->getFunctionPrivate() != (JSFunction *) funobj);
 
     return true;
 }
 END_TEST(testLookup_bug522590)
 
 JSBool
 document_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject **objp)
 {
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -338,17 +338,17 @@ JS_ConvertArgumentsVA(JSContext *cx, uin
             *sp = OBJECT_TO_JSVAL(obj);
             *va_arg(ap, JSObject **) = obj;
             break;
           case 'f':
             obj = js_ValueToFunctionObject(cx, Valueify(sp), 0);
             if (!obj)
                 return JS_FALSE;
             *sp = OBJECT_TO_JSVAL(obj);
-            *va_arg(ap, JSFunction **) = GET_FUNCTION_PRIVATE(cx, obj);
+            *va_arg(ap, JSFunction **) = obj->getFunctionPrivate();
             break;
           case 'v':
             *va_arg(ap, jsval *) = *sp;
             break;
           case '*':
             break;
           default:
             format--;
@@ -2265,20 +2265,20 @@ JS_PrintTraceThingInfo(char *buf, size_t
         bufsize--;
 
         switch (kind) {
           case JSTRACE_OBJECT:
           {
             JSObject  *obj = (JSObject *)thing;
             Class *clasp = obj->getClass();
             if (clasp == &js_FunctionClass) {
-                JSFunction *fun = GET_FUNCTION_PRIVATE(trc->context, obj);
+                JSFunction *fun = obj->getFunctionPrivate();
                 if (!fun) {
                     JS_snprintf(buf, bufsize, "<newborn>");
-                } else if (FUN_OBJECT(fun) != obj) {
+                } else if (fun != obj) {
                     JS_snprintf(buf, bufsize, "%p", fun);
                 } else {
                     if (fun->atom)
                         PutEscapedString(buf, bufsize, fun->atom, 0);
                 }
             } else if (clasp->flags & JSCLASS_HAS_PRIVATE) {
                 JS_snprintf(buf, bufsize, "%p", obj->getPrivate());
             } else {
@@ -4203,18 +4203,18 @@ JS_CloneFunctionObject(JSContext *cx, JS
          * We cannot clone this object, so fail (we used to return funobj, bad
          * idea, but we changed incompatibly to teach any abusers a lesson!).
          */
         Value v = ObjectValue(*funobj);
         js_ReportIsNotFunction(cx, &v, 0);
         return NULL;
     }
 
-    JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj);
-    if (!FUN_FLAT_CLOSURE(fun))
+    JSFunction *fun = funobj->getFunctionPrivate();
+    if (!fun->isFlatClosure())
         return CloneFunctionObject(cx, fun, parent);
 
     /*
      * A flat closure carries its own environment, so why clone it? In case
      * someone wants to mutate its fixed slots or add ad-hoc properties. API
      * compatibility suggests we not return funobj and let callers mutate the
      * returned object at will.
      *
@@ -4249,17 +4249,17 @@ JS_CloneFunctionObject(JSContext *cx, JS
     }
 
     return clone;
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_GetFunctionObject(JSFunction *fun)
 {
-    return FUN_OBJECT(fun);
+    return fun;
 }
 
 JS_PUBLIC_API(JSString *)
 JS_GetFunctionId(JSFunction *fun)
 {
     return fun->atom;
 }
 
@@ -4352,17 +4352,17 @@ JS_DefineFunctions(JSContext *cx, JSObje
             if (!fun)
                 return JS_FALSE;
 
             /*
              * As jsapi.h notes, fs must point to storage that lives as long
              * as fun->object lives.
              */
             Value priv = PrivateValue(fs);
-            if (!js_SetReservedSlot(cx, FUN_OBJECT(fun), 0, priv))
+            if (!js_SetReservedSlot(cx, fun, 0, priv))
                 return JS_FALSE;
         }
 
         fun = JS_DefineFunction(cx, obj, fs->name, fs->call, fs->nargs, flags);
         if (!fun)
             return JS_FALSE;
     }
     return JS_TRUE;
@@ -4707,68 +4707,66 @@ CompileUCFunctionForPrincipalsCommon(JSC
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, principals);
     if (!name) {
         funAtom = NULL;
     } else {
         funAtom = js_Atomize(cx, name, strlen(name));
         if (!funAtom) {
             fun = NULL;
-            goto out2;
+            goto out;
         }
     }
 
     fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED, obj, funAtom);
     if (!fun)
-        goto out2;
+        goto out;
 
     {
         EmptyShape *emptyCallShape = EmptyShape::getEmptyCallShape(cx);
-        if (!emptyCallShape) {
+        if (!emptyCallShape)
             fun = NULL;
-            goto out2;
-        }
         AutoShapeRooter shapeRoot(cx, emptyCallShape);
 
-        AutoObjectRooter tvr(cx, FUN_OBJECT(fun));
-        MUST_FLOW_THROUGH("out");
+        AutoObjectRooter tvr(cx, fun);
 
         Bindings bindings(cx, emptyCallShape);
         AutoBindingsRooter root(cx, bindings);
         for (i = 0; i < nargs; i++) {
             argAtom = js_Atomize(cx, argnames[i], strlen(argnames[i]));
             if (!argAtom) {
                 fun = NULL;
-                goto out2;
+                goto out;
             }
 
             uint16 dummy;
             if (!bindings.addArgument(cx, argAtom, &dummy)) {
                 fun = NULL;
-                goto out2;
+                goto out;
             }
         }
 
         if (!Compiler::compileFunctionBody(cx, fun, principals, &bindings,
                                            chars, length, filename, lineno, version)) {
             fun = NULL;
-            goto out2;
+            goto out;
         }
 
         if (obj && funAtom &&
             !obj->defineProperty(cx, ATOM_TO_JSID(funAtom), ObjectValue(*fun),
                                  NULL, NULL, JSPROP_ENUMERATE)) {
             fun = NULL;
         }
     }
 
-  out2:
+  out:
     LAST_FRAME_CHECKS(cx, fun);
     return fun;
 }
+
 JS_PUBLIC_API(JSFunction *)
 JS_CompileUCFunctionForPrincipalsVersion(JSContext *cx, JSObject *obj,
                                          JSPrincipals *principals, const char *name,
                                          uintN nargs, const char **argnames,
                                          const jschar *chars, size_t length,
                                          const char *filename, uintN lineno,
                                          JSVersion version)
 {
@@ -4887,17 +4885,17 @@ JS_DecompileFunctionBody(JSContext *cx, 
 JS_PUBLIC_API(JSBool)
 JS_ExecuteScript(JSContext *cx, JSObject *obj, JSObject *scriptObj, jsval *rval)
 {
     JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
 
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, scriptObj);
 
-    JSBool ok = ExternalExecute(cx, scriptObj->getScript(), *obj, Valueify(rval));
+    JSBool ok = Execute(cx, scriptObj->getScript(), *obj, Valueify(rval));
     LAST_FRAME_CHECKS(cx, ok);
     return ok;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_ExecuteScriptVersion(JSContext *cx, JSObject *obj, JSObject *scriptObj, jsval *rval,
                         JSVersion version)
 {
@@ -4921,17 +4919,17 @@ EvaluateUCScriptForPrincipalsCommon(JSCo
                                                : TCF_COMPILE_N_GO,
                                                chars, length, filename, lineno, compileVersion);
     if (!script) {
         LAST_FRAME_CHECKS(cx, script);
         return false;
     }
     JS_ASSERT(script->getVersion() == compileVersion);
 
-    bool ok = ExternalExecute(cx, script, *obj, Valueify(rval));
+    bool ok = Execute(cx, script, *obj, Valueify(rval));
     LAST_FRAME_CHECKS(cx, ok);
     js_DestroyScript(cx, script, 5);
     return ok;
 
 }
 
 JS_PUBLIC_API(JSBool)
 JS_EvaluateUCScriptForPrincipalsVersion(JSContext *cx, JSObject *obj,
@@ -5001,18 +4999,18 @@ JS_EvaluateScript(JSContext *cx, JSObjec
 
 JS_PUBLIC_API(JSBool)
 JS_CallFunction(JSContext *cx, JSObject *obj, JSFunction *fun, uintN argc, jsval *argv,
                 jsval *rval)
 {
     JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, fun, JSValueArray(argv, argc));
-    JSBool ok = ExternalInvoke(cx, ObjectOrNullValue(obj), ObjectValue(*fun), argc,
-                               Valueify(argv), Valueify(rval));
+    JSBool ok = Invoke(cx, ObjectOrNullValue(obj), ObjectValue(*fun), argc, Valueify(argv),
+                       Valueify(rval));
     LAST_FRAME_CHECKS(cx, ok);
     return ok;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_CallFunctionName(JSContext *cx, JSObject *obj, const char *name, uintN argc, jsval *argv,
                     jsval *rval)
 {
@@ -5020,62 +5018,61 @@ JS_CallFunctionName(JSContext *cx, JSObj
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, JSValueArray(argv, argc));
 
     AutoValueRooter tvr(cx);
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
     JSBool ok =
         atom &&
         js_GetMethod(cx, obj, ATOM_TO_JSID(atom), JSGET_NO_METHOD_BARRIER, tvr.addr()) &&
-        ExternalInvoke(cx, ObjectOrNullValue(obj), tvr.value(), argc, Valueify(argv),
-                       Valueify(rval));
+        Invoke(cx, ObjectOrNullValue(obj), tvr.value(), argc, Valueify(argv), Valueify(rval));
     LAST_FRAME_CHECKS(cx, ok);
     return ok;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_CallFunctionValue(JSContext *cx, JSObject *obj, jsval fval, uintN argc, jsval *argv,
                      jsval *rval)
 {
     JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
 
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, fval, JSValueArray(argv, argc));
-    JSBool ok = ExternalInvoke(cx, ObjectOrNullValue(obj), Valueify(fval), argc, Valueify(argv),
-                               Valueify(rval));
+    JSBool ok = Invoke(cx, ObjectOrNullValue(obj), Valueify(fval), argc, Valueify(argv),
+                       Valueify(rval));
     LAST_FRAME_CHECKS(cx, ok);
     return ok;
 }
 
 namespace JS {
 
 JS_PUBLIC_API(bool)
 Call(JSContext *cx, jsval thisv, jsval fval, uintN argc, jsval *argv, jsval *rval)
 {
     JSBool ok;
 
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, thisv, fval, JSValueArray(argv, argc));
-    ok = ExternalInvoke(cx, Valueify(thisv), Valueify(fval), argc, Valueify(argv), Valueify(rval));
+    ok = Invoke(cx, Valueify(thisv), Valueify(fval), argc, Valueify(argv), Valueify(rval));
     LAST_FRAME_CHECKS(cx, ok);
     return ok;
 }
 
 } // namespace JS
 
 JS_PUBLIC_API(JSObject *)
 JS_New(JSContext *cx, JSObject *ctor, uintN argc, jsval *argv)
 {
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, ctor, JSValueArray(argv, argc));
 
     // This is not a simple variation of JS_CallFunctionValue because JSOP_NEW
     // is not a simple variation of JSOP_CALL. We have to determine what class
     // of object to create, create it, and clamp the return value to an object,
-    // among other details. js_InvokeConstructor does the hard work.
+    // among other details. InvokeConstructor does the hard work.
     InvokeArgsGuard args;
     if (!cx->stack.pushInvokeArgs(cx, argc, &args))
         return NULL;
 
     args.calleev().setObject(*ctor);
     args.thisv().setNull();
     memcpy(args.argv(), argv, argc * sizeof(jsval));
 
--- a/js/src/jsbuiltins.cpp
+++ b/js/src/jsbuiltins.cpp
@@ -305,17 +305,17 @@ JS_DEFINE_CALLINFO_2(extern, STRING, js_
 JSObject* FASTCALL
 js_NewNullClosure(JSContext* cx, JSObject* funobj, JSObject* proto, JSObject* parent)
 {
     JS_ASSERT(funobj->isFunction());
     JS_ASSERT(proto->isFunction());
     JS_ASSERT(JS_ON_TRACE(cx));
 
     JSFunction *fun = (JSFunction*) funobj;
-    JS_ASSERT(GET_FUNCTION_PRIVATE(cx, funobj) == fun);
+    JS_ASSERT(funobj->getFunctionPrivate() == fun);
 
     JSObject* closure = js_NewGCObject(cx, gc::FINALIZE_OBJECT2);
     if (!closure)
         return NULL;
 
     if (!closure->initSharingEmptyShape(cx, &js_FunctionClass, proto, parent,
                                         fun, gc::FINALIZE_OBJECT2)) {
         return NULL;
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -1078,17 +1078,17 @@ js_ReportMissingArg(JSContext *cx, const
 {
     char argbuf[11];
     char *bytes;
     JSAtom *atom;
 
     JS_snprintf(argbuf, sizeof argbuf, "%u", arg);
     bytes = NULL;
     if (IsFunctionObject(v)) {
-        atom = GET_FUNCTION_PRIVATE(cx, &v.toObject())->atom;
+        atom = v.toObject().getFunctionPrivate()->atom;
         bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK,
                                         v, atom);
         if (!bytes)
             return;
     }
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                          JSMSG_MISSING_FUN_ARG, argbuf,
                          bytes ? bytes : "");
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -344,17 +344,17 @@ CallJSPropertyOpSetter(JSContext *cx, js
     return op(cx, obj, id, strict, vp);
 }
 
 inline bool
 CallSetter(JSContext *cx, JSObject *obj, jsid id, js::StrictPropertyOp op, uintN attrs,
            uintN shortid, JSBool strict, js::Value *vp)
 {
     if (attrs & JSPROP_SETTER)
-        return ExternalGetOrSet(cx, obj, id, CastAsObjectJsval(op), JSACC_WRITE, 1, vp, vp);
+        return InvokeGetterOrSetter(cx, obj, CastAsObjectJsval(op), 1, vp, vp);
 
     if (attrs & JSPROP_GETTER)
         return js_ReportGetterOnlyAssignment(cx);
 
     if (attrs & JSPROP_SHORTID)
         id = INT_TO_JSID(shortid);
     return CallJSPropertyOpSetter(cx, op, obj, id, strict, vp);
 }
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -543,17 +543,17 @@ extern JS_PUBLIC_API(void)
 JS_ReleaseFunctionLocalNameArray(JSContext *cx, void *mark)
 {
     JS_ARENA_RELEASE(&cx->tempPool, mark);
 }
 
 JS_PUBLIC_API(JSScript *)
 JS_GetFunctionScript(JSContext *cx, JSFunction *fun)
 {
-    return FUN_SCRIPT(fun);
+    return fun->maybeScript();
 }
 
 JS_PUBLIC_API(JSNative)
 JS_GetFunctionNative(JSContext *cx, JSFunction *fun)
 {
     return Jsvalify(fun->maybeNative());
 }
 
@@ -1090,18 +1090,18 @@ GetAtomTotalSize(JSContext *cx, JSAtom *
 }
 
 JS_PUBLIC_API(size_t)
 JS_GetFunctionTotalSize(JSContext *cx, JSFunction *fun)
 {
     size_t nbytes;
 
     nbytes = sizeof *fun;
-    nbytes += JS_GetObjectTotalSize(cx, FUN_OBJECT(fun));
-    if (FUN_INTERPRETED(fun))
+    nbytes += JS_GetObjectTotalSize(cx, fun);
+    if (fun->isInterpreted())
         nbytes += JS_GetScriptTotalSize(cx, fun->script());
     if (fun->atom)
         nbytes += GetAtomTotalSize(cx, fun->atom);
     return nbytes;
 }
 
 #include "jsemit.h"
 
--- a/js/src/jsemit.cpp
+++ b/js/src/jsemit.cpp
@@ -4810,32 +4810,32 @@ js_EmitTree(JSContext *cx, JSCodeGenerat
         if (pn->pn_arity == PN_NULLARY) {
             if (js_Emit1(cx, cg, JSOP_GETFUNNS) < 0)
                 return JS_FALSE;
             break;
         }
 #endif
 
         fun = pn->pn_funbox->function();
-        JS_ASSERT(FUN_INTERPRETED(fun));
+        JS_ASSERT(fun->isInterpreted());
         if (fun->script()) {
             /*
              * This second pass is needed to emit JSOP_NOP with a source note
              * for the already-emitted function definition prolog opcode. See
              * comments in the TOK_LC case.
              */
             JS_ASSERT(pn->pn_op == JSOP_NOP);
             JS_ASSERT(cg->inFunction());
             if (!EmitFunctionDefNop(cx, cg, pn->pn_index))
                 return JS_FALSE;
             break;
         }
 
         JS_ASSERT_IF(pn->pn_funbox->tcflags & TCF_FUN_HEAVYWEIGHT,
-                     FUN_KIND(fun) == JSFUN_INTERPRETED);
+                     fun->kind() == JSFUN_INTERPRETED);
 
         /* Generate code for the function's body. */
         void *cg2mark = JS_ARENA_MARK(cg->codePool);
         void *cg2space;
         JS_ARENA_ALLOCATE_TYPE(cg2space, JSCodeGenerator, cg->codePool);
         if (!cg2space) {
             js_ReportOutOfMemory(cx);
             return JS_FALSE;
@@ -4908,17 +4908,17 @@ js_EmitTree(JSContext *cx, JSCodeGenerat
          * definitions can be scheduled before generating the rest of code.
          */
         if (!cg->inFunction()) {
             JS_ASSERT(!cg->topStmt);
             if (!BindGlobal(cx, cg, pn, fun->atom))
                 return false;
             if (pn->pn_cookie.isFree()) {
                 CG_SWITCH_TO_PROLOG(cg);
-                op = FUN_FLAT_CLOSURE(fun) ? JSOP_DEFFUN_FC : JSOP_DEFFUN;
+                op = fun->isFlatClosure() ? JSOP_DEFFUN_FC : JSOP_DEFFUN;
                 EMIT_INDEX_OP(op, index);
 
                 /* Make blockChain determination quicker. */
                 if (EmitBlockChain(cx, cg) < 0)
                     return JS_FALSE;
                 CG_SWITCH_TO_MAIN(cg);
             }
 
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -523,49 +523,49 @@ js_ErrorFromException(JSContext *cx, jsv
         return NULL;
     priv = GetExnPrivate(obj);
     if (!priv)
         return NULL;
     return priv->errorReport;
 }
 
 static JSString *
-ValueToShortSource(JSContext *cx, jsval v)
+ValueToShortSource(JSContext *cx, const Value &v)
 {
     JSString *str;
 
     /* Avoid toSource bloat and fallibility for object types. */
-    if (JSVAL_IS_PRIMITIVE(v))
-        return js_ValueToSource(cx, Valueify(v));
+    if (!v.isObject())
+        return js_ValueToSource(cx, v);
 
-    AutoCompartment ac(cx, JSVAL_TO_OBJECT(v));
+    JSObject *obj = &v.toObject();
+    AutoCompartment ac(cx, obj);
     if (!ac.enter())
         return NULL;
 
-    if (VALUE_IS_FUNCTION(cx, v)) {
+    if (obj->isFunction()) {
         /*
          * XXX Avoid function decompilation bloat for now.
          */
-        str = JS_GetFunctionId(JS_ValueToFunction(cx, v));
-        if (!str && !(str = js_ValueToSource(cx, Valueify(v)))) {
+        str = JS_GetFunctionId(obj->getFunctionPrivate());
+        if (!str && !(str = js_ValueToSource(cx, v))) {
             /*
              * Continue to soldier on if the function couldn't be
              * converted into a string.
              */
             JS_ClearPendingException(cx);
             str = JS_NewStringCopyZ(cx, "[unknown function]");
         }
     } else {
         /*
          * XXX Avoid toString on objects, it takes too long and uses too much
          * memory, for too many classes (see Mozilla bug 166743).
          */
         char buf[100];
-        JS_snprintf(buf, sizeof buf, "[object %s]",
-                    JSVAL_TO_OBJECT(v)->getClass()->name);
+        JS_snprintf(buf, sizeof buf, "[object %s]", obj->getClass()->name);
         str = JS_NewStringCopyZ(cx, buf);
     }
 
     ac.leave();
 
     if (!str || !cx->compartment->wrap(cx, &str))
         return NULL;
     return str;
@@ -633,17 +633,17 @@ StackTraceToString(JSContext *cx, JSExnP
     elem = priv->stackElems;
     for (endElem = elem + priv->stackDepth; elem != endElem; elem++) {
         if (elem->funName) {
             APPEND_STRING_TO_STACK(elem->funName);
             APPEND_CHAR_TO_STACK('(');
             for (i = 0; i != elem->argc; i++, values++) {
                 if (i > 0)
                     APPEND_CHAR_TO_STACK(',');
-                str = ValueToShortSource(cx, *values);
+                str = ValueToShortSource(cx, Valueify(*values));
                 if (!str)
                     goto bad;
                 APPEND_STRING_TO_STACK(str);
             }
             APPEND_CHAR_TO_STACK(')');
         }
         APPEND_CHAR_TO_STACK('@');
         if (elem->filename) {
--- a/js/src/jsexn.h
+++ b/js/src/jsexn.h
@@ -97,14 +97,16 @@ js_ErrorFromException(JSContext *cx, jsv
 extern const JSErrorFormatString *
 js_GetLocalizedErrorMessage(JSContext* cx, void *userRef, const char *locale,
                             const uintN errorNumber);
 
 /*
  * Make a copy of errobj parented to scope.
  *
  * cx must be in the same compartment as scope. errobj may be in a different
- * compartment, but it must be an Error object (not a wrapper of one).
+ * compartment, but it must be an Error object (not a wrapper of one) and it
+ * must not be one of the prototype objects created by js_InitExceptionClasses
+ * (errobj->getPrivate() must not be NULL).
  */
 extern JSObject *
 js_CopyErrorObject(JSContext *cx, JSObject *errobj, JSObject *scope);
 
 #endif /* jsexn_h___ */
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -1246,18 +1246,19 @@ StackFrame::getValidCalleeObject(JSConte
                             return true;
                         }
 
                         if (shape->hasSlot()) {
                             Value v = thisp->getSlot(shape->slot);
                             JSObject *clone;
 
                             if (IsFunctionObject(v, &clone) &&
-                                GET_FUNCTION_PRIVATE(cx, clone) == fun &&
-                                clone->hasMethodObj(*thisp)) {
+                                clone->getFunctionPrivate() == fun &&
+                                clone->hasMethodObj(*thisp))
+                            {
                                 JS_ASSERT(clone != &funobj);
                                 *vp = v;
                                 overwriteCallee(*clone);
                                 return true;
                             }
                         }
                     }
 
@@ -1539,18 +1540,18 @@ js_XDRFunctionObject(JSXDRState *xdr, JS
     JSFunction *fun;
     uint32 firstword;           /* flag telling whether fun->atom is non-null,
                                    plus for fun->u.i.skipmin, fun->u.i.wrapper,
                                    and 14 bits reserved for future use */
     uint32 flagsword;           /* word for argument count and fun->flags */
 
     cx = xdr->cx;
     if (xdr->mode == JSXDR_ENCODE) {
-        fun = GET_FUNCTION_PRIVATE(cx, *objp);
-        if (!FUN_INTERPRETED(fun)) {
+        fun = (*objp)->getFunctionPrivate();
+        if (!fun->isInterpreted()) {
             JSAutoByteString funNameBytes;
             if (const char *name = GetFunctionNameBytes(cx, fun, &funNameBytes)) {
                 JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_SCRIPTED_FUNCTION,
                                      name);
             }
             return false;
         }
         if (fun->u.i.wrapper) {
@@ -1561,21 +1562,21 @@ js_XDRFunctionObject(JSXDRState *xdr, JS
         }
         JS_ASSERT((fun->u.i.wrapper & ~1U) == 0);
         firstword = (fun->u.i.skipmin << 2) | (fun->u.i.wrapper << 1) | !!fun->atom;
         flagsword = (fun->nargs << 16) | fun->flags;
     } else {
         fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED, NULL, NULL);
         if (!fun)
             return false;
-        FUN_OBJECT(fun)->clearParent();
-        FUN_OBJECT(fun)->clearProto();
+        fun->clearParent();
+        fun->clearProto();
     }
 
-    AutoObjectRooter tvr(cx, FUN_OBJECT(fun));
+    AutoObjectRooter tvr(cx, fun);
 
     if (!JS_XDRUint32(xdr, &firstword))
         return false;
     if ((firstword & 1U) && !js_XDRAtom(xdr, &fun->atom))
         return false;
     if (!JS_XDRUint32(xdr, &flagsword))
         return false;
 
@@ -1592,17 +1593,17 @@ js_XDRFunctionObject(JSXDRState *xdr, JS
      * at the same time as we set the script's owner.
      */
     JSScript *script = fun->u.i.script;
     if (!js_XDRScript(xdr, &script))
         return false;
     fun->u.i.script = script;
 
     if (xdr->mode == JSXDR_DECODE) {
-        *objp = FUN_OBJECT(fun);
+        *objp = fun;
         fun->u.i.script->setOwnerObject(fun);
 #ifdef CHECK_SCRIPT_OWNER
         fun->script()->owner = NULL;
 #endif
         JS_ASSERT(fun->nargs == fun->script()->bindings.countArgs());
         js_CallNewScriptHook(cx, fun->script(), fun);
     }
 
@@ -1731,17 +1732,17 @@ fun_toStringHelper(JSContext *cx, JSObje
             return JSProxy::fun_toString(cx, obj, indent);
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                              JSMSG_INCOMPATIBLE_PROTO,
                              js_Function_str, js_toString_str,
                              "object");
         return NULL;
     }
 
-    JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj);
+    JSFunction *fun = obj->getFunctionPrivate();
     if (!fun)
         return NULL;
 
     if (!indent && !cx->compartment->toSourceCache.empty()) {
         ToSourceCache::Ptr p = cx->compartment->toSourceCache.ref().lookup(fun);
         if (p)
             return p->value;
     }
@@ -2024,17 +2025,17 @@ static JSBool
 fun_isGenerator(JSContext *cx, uintN argc, Value *vp)
 {
     JSObject *funobj;
     if (!IsFunctionObject(vp[1], &funobj)) {
         JS_SET_RVAL(cx, vp, BooleanValue(false));
         return true;
     }
 
-    JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj);
+    JSFunction *fun = funobj->getFunctionPrivate();
 
     bool result = false;
     if (fun->isInterpreted()) {
         JSScript *script = fun->script();
         JS_ASSERT(script->length != 0);
         result = script->code[0] == JSOP_GENERATOR;
     }
 
@@ -2434,17 +2435,17 @@ js_NewFunction(JSContext *cx, JSObject *
             fun->u.n.native = native;
             fun->u.n.trcinfo = NULL;
         }
         JS_ASSERT(fun->u.n.native);
     }
     fun->atom = atom;
 
     /* Set private to self to indicate non-cloned fully initialized function. */
-    FUN_OBJECT(fun)->setPrivate(fun);
+    fun->setPrivate(fun);
     return fun;
 }
 
 JSObject * JS_FASTCALL
 js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent,
                        JSObject *proto)
 {
     JS_ASSERT(parent);
@@ -2648,17 +2649,17 @@ JS_STATIC_ASSERT((JSV2F_CONSTRUCT & JSV2
 JSFunction *
 js_ValueToFunction(JSContext *cx, const Value *vp, uintN flags)
 {
     JSObject *funobj;
     if (!IsFunctionObject(*vp, &funobj)) {
         js_ReportIsNotFunction(cx, vp, flags);
         return NULL;
     }
-    return GET_FUNCTION_PRIVATE(cx, funobj);
+    return funobj->getFunctionPrivate();
 }
 
 JSObject *
 js_ValueToFunctionObject(JSContext *cx, Value *vp, uintN flags)
 {
     JSObject *funobj;
     if (!IsFunctionObject(*vp, &funobj)) {
         js_ReportIsNotFunction(cx, vp, flags);
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -55,38 +55,38 @@
  * or interpreted, and if interpreted, what kind of optimized closure form (if
  * any) it might be.
  *
  *   00   not interpreted
  *   01   interpreted, neither flat nor null closure
  *   10   interpreted, flat closure
  *   11   interpreted, null closure
  *
- * FUN_FLAT_CLOSURE implies FUN_INTERPRETED and u.i.script->upvarsOffset != 0.
- * FUN_NULL_CLOSURE implies FUN_INTERPRETED and u.i.script->upvarsOffset == 0.
+ * isFlatClosure() implies isInterpreted() and u.i.script->upvarsOffset != 0.
+ * isNullClosure() implies isInterpreted() and u.i.script->upvarsOffset == 0.
  *
- * FUN_INTERPRETED but not FUN_FLAT_CLOSURE and u.i.script->upvarsOffset != 0
+ * isInterpreted() but not isFlatClosure() and u.i.script->upvarsOffset != 0
  * is an Algol-like function expression or nested function, i.e., a function
  * that never escapes upward or downward (heapward), and is only ever called.
  *
- * Finally, FUN_INTERPRETED and u.i.script->upvarsOffset == 0 could be either
+ * Finally, isInterpreted() and u.i.script->upvarsOffset == 0 could be either
  * a non-closure (a global function definition, or any function that uses no
  * outer names), or a closure of an escaping function that uses outer names
  * whose values can't be snapshot (because the outer names could be reassigned
  * after the closure is formed, or because assignments could not be analyzed
  * due to with or eval).
  *
  * Such a hard-case function must use JSOP_NAME, etc., and reify outer function
  * activations' call objects, etc. if it's not a global function.
  *
  * NB: JSFUN_EXPR_CLOSURE reuses JSFUN_STUB_GSOPS, which is an API request flag
  * bit only, never stored in fun->flags.
  *
- * If we need more bits in the future, all flags for FUN_INTERPRETED functions
- * can move to u.i.script->flags. For now we use function flag bits to minimize
+ * If we need more bits in the future, all flags for interpreted functions can
+ * move to u.i.script->flags. For now we use function flag bits to minimize
  * pointer-chasing.
  */
 #define JSFUN_JOINABLE      0x0001  /* function is null closure that does not
                                        appear to call itself via its own name
                                        or arguments.callee */
 
 #define JSFUN_PROTOTYPE     0x0800  /* function is Function.prototype for some
                                        global object */
@@ -96,29 +96,16 @@
                                        JSFunctionSpec::call points to a
                                        JSNativeTraceInfo. */
 #define JSFUN_INTERPRETED   0x4000  /* use u.i if kind >= this value else u.n */
 #define JSFUN_FLAT_CLOSURE  0x8000  /* flat (aka "display") closure */
 #define JSFUN_NULL_CLOSURE  0xc000  /* null closure entrains no scope chain */
 #define JSFUN_KINDMASK      0xc000  /* encode interp vs. native and closure
                                        optimization level -- see above */
 
-#define FUN_OBJECT(fun)      (static_cast<JSObject *>(fun))
-#define FUN_KIND(fun)        ((fun)->flags & JSFUN_KINDMASK)
-#define FUN_SET_KIND(fun,k)  ((fun)->flags = ((fun)->flags & ~JSFUN_KINDMASK) | (k))
-#define FUN_INTERPRETED(fun) (FUN_KIND(fun) >= JSFUN_INTERPRETED)
-#define FUN_FLAT_CLOSURE(fun)(FUN_KIND(fun) == JSFUN_FLAT_CLOSURE)
-#define FUN_NULL_CLOSURE(fun)(FUN_KIND(fun) == JSFUN_NULL_CLOSURE)
-#define FUN_SCRIPT(fun)      (FUN_INTERPRETED(fun) ? (fun)->script() : NULL)
-#define FUN_CLASP(fun)       (JS_ASSERT(!FUN_INTERPRETED(fun)),               \
-                              fun->u.n.clasp)
-#define FUN_TRCINFO(fun)     (JS_ASSERT(!FUN_INTERPRETED(fun)),               \
-                              JS_ASSERT((fun)->flags & JSFUN_TRCINFO),        \
-                              fun->u.n.trcinfo)
-
 struct JSFunction : public JSObject_Slots2
 {
     /* Functions always have two fixed slots (FUN_CLASS_RESERVED_SLOTS). */
 
     uint16          nargs;        /* maximum number of specified arguments,
                                      reflected as f.length/f.arity */
     uint16          flags;        /* flags, see JSFUN_* below and in jsapi.h */
     union U {
@@ -140,26 +127,35 @@ struct JSFunction : public JSObject_Slot
                                      indirect eval; if true, then this function
                                      object's proto is the wrapped object */
             js::Shape   *names;   /* argument and variable names */
         } i;
         void            *nativeOrScript;
     } u;
     JSAtom          *atom;        /* name for diagnostics and decompiling */
 
-    bool optimizedClosure()  const { return FUN_KIND(this) > JSFUN_INTERPRETED; }
-    bool isInterpreted()     const { return FUN_INTERPRETED(this); }
-    bool isNative()          const { return !FUN_INTERPRETED(this); }
+    bool optimizedClosure()  const { return kind() > JSFUN_INTERPRETED; }
+    bool isInterpreted()     const { return kind() >= JSFUN_INTERPRETED; }
+    bool isNative()          const { return !isInterpreted(); }
     bool isConstructor()     const { return flags & JSFUN_CONSTRUCTOR; }
     bool isHeavyweight()     const { return JSFUN_HEAVYWEIGHT_TEST(flags); }
-    bool isFlatClosure()     const { return FUN_KIND(this) == JSFUN_FLAT_CLOSURE; }
+    bool isNullClosure()     const { return kind() == JSFUN_NULL_CLOSURE; }
+    bool isFlatClosure()     const { return kind() == JSFUN_FLAT_CLOSURE; }
     bool isFunctionPrototype() const { return flags & JSFUN_PROTOTYPE; }
     bool isInterpretedConstructor() const { return isInterpreted() && !isFunctionPrototype(); }
+
+    uint16 kind()            const { return flags & JSFUN_KINDMASK; }
+    void setKind(uint16 k) {
+        JS_ASSERT(!(k & ~JSFUN_KINDMASK));
+        flags = (flags & ~JSFUN_KINDMASK) | k;
+    }
+
     /* Returns the strictness of this function, which must be interpreted. */
     inline bool inStrictMode() const;
+
     void setArgCount(uint16 nargs) {
         JS_ASSERT(this->nargs == 0);
         this->nargs = nargs;
     }
 
     /* uint16 representation bounds number of call object dynamic slots. */
     enum { MAX_ARGS_AND_VARS = 2 * ((1U << 16) - 1) };
 
@@ -205,16 +201,20 @@ struct JSFunction : public JSObject_Slot
 
     inline void setMethodAtom(JSAtom *atom);
 
     JSScript *script() const {
         JS_ASSERT(isInterpreted());
         return u.i.script;
     }
 
+    JSScript * maybeScript() const {
+        return isInterpreted() ? script() : NULL;
+    }
+
     js::Native native() const {
         JS_ASSERT(isNative());
         return u.n.native;
     }
 
     js::Native maybeNative() const {
         return isInterpreted() ? NULL : native();
     }
@@ -222,16 +222,33 @@ struct JSFunction : public JSObject_Slot
     static uintN offsetOfNativeOrScript() {
         JS_STATIC_ASSERT(offsetof(U, n.native) == offsetof(U, i.script));
         JS_STATIC_ASSERT(offsetof(U, n.native) == offsetof(U, nativeOrScript));
         return offsetof(JSFunction, u.nativeOrScript);
     }
 
     /* Number of extra fixed function object slots. */
     static const uint32 CLASS_RESERVED_SLOTS = JSObject::FUN_CLASS_RESERVED_SLOTS;
+
+
+    js::Class *getConstructorClass() const {
+        JS_ASSERT(isNative());
+        return u.n.clasp;
+    }
+
+    void setConstructorClass(js::Class *clasp) {
+        JS_ASSERT(isNative());
+        u.n.clasp = clasp;
+    }
+
+    JSNativeTraceInfo *getTraceInfo() const {
+        JS_ASSERT(isNative());
+        JS_ASSERT(flags & JSFUN_TRCINFO);
+        return u.n.trcinfo;
+    }
 };
 
 /*
  * Trace-annotated native. This expands to a JSFunctionSpec initializer (like
  * JS_FN in jsapi.h). fastcall is a FastNative; trcinfo is a
  * JSNativeTraceInfo*.
  */
 #ifdef JS_TRACER
@@ -264,22 +281,16 @@ inline JSFunction *
 JSObject::getFunctionPrivate() const
 {
     JS_ASSERT(isFunction());
     return reinterpret_cast<JSFunction *>(getPrivate());
 }
 
 namespace js {
 
-/*
- * NB: jsapi.h and jsobj.h must be included before any call to this macro.
- */
-#define VALUE_IS_FUNCTION(cx, v)                                              \
-    (!JSVAL_IS_PRIMITIVE(v) && JSVAL_TO_OBJECT(v)->isFunction())
-
 static JS_ALWAYS_INLINE bool
 IsFunctionObject(const js::Value &v)
 {
     return v.isObject() && v.toObject().isFunction();
 }
 
 static JS_ALWAYS_INLINE bool
 IsFunctionObject(const js::Value &v, JSObject **funobj)
@@ -350,24 +361,16 @@ extern JS_ALWAYS_INLINE bool
 SameTraceType(const Value &lhs, const Value &rhs)
 {
     return SameType(lhs, rhs) &&
            (lhs.isPrimitive() ||
             lhs.toObject().isFunction() == rhs.toObject().isFunction());
 }
 
 /*
- * Macro to access the private slot of the function object after the slot is
- * initialized.
- */
-#define GET_FUNCTION_PRIVATE(cx, funobj)                                      \
-    (JS_ASSERT((funobj)->isFunction()),                                       \
-     (JSFunction *) (funobj)->getPrivate())
-
-/*
  * Return true if this is a compiler-created internal function accessed by
  * its own object. Such a function object must not be accessible to script
  * or embedding code.
  */
 inline bool
 IsInternalFunctionObject(JSObject *funobj)
 {
     JS_ASSERT(funobj->isFunction());
--- a/js/src/jsfuninlines.h
+++ b/js/src/jsfuninlines.h
@@ -47,17 +47,17 @@ inline bool
 JSFunction::inStrictMode() const
 {
     return script()->strictModeCode;
 }
 
 inline void
 JSFunction::setJoinable()
 {
-    JS_ASSERT(FUN_INTERPRETED(this));
+    JS_ASSERT(isInterpreted());
     setSlot(METHOD_ATOM_SLOT, js::NullValue());
     flags |= JSFUN_JOINABLE;
 }
 
 inline void
 JSFunction::setMethodAtom(JSAtom *atom)
 {
     JS_ASSERT(joinable());
--- a/js/src/jshashtable.h
+++ b/js/src/jshashtable.h
@@ -293,26 +293,35 @@ class HashTable : private AllocPolicy
 #ifdef DEBUG
     friend class js::ReentrancyGuard;
     mutable bool entered;
     uint64       mutationCount;
 #endif
 
     static const unsigned sMinSizeLog2  = 4;
     static const unsigned sMinSize      = 1 << sMinSizeLog2;
-    static const unsigned sSizeLimit    = JS_BIT(24);
+    static const unsigned sMaxInit      = JS_BIT(23);
+    static const unsigned sMaxCapacity  = JS_BIT(24);
     static const unsigned sHashBits     = tl::BitSize<HashNumber>::result;
     static const uint8    sMinAlphaFrac = 64;  /* (0x100 * .25) taken from jsdhash.h */
     static const uint8    sMaxAlphaFrac = 192; /* (0x100 * .75) taken from jsdhash.h */
     static const uint8    sInvMaxAlpha  = 171; /* (ceil(0x100 / .75) >> 1) */
     static const HashNumber sGoldenRatio  = 0x9E3779B9U;       /* taken from jsdhash.h */
     static const HashNumber sFreeKey = Entry::sFreeKey;
     static const HashNumber sRemovedKey = Entry::sRemovedKey;
     static const HashNumber sCollisionBit = Entry::sCollisionBit;
 
+    static void staticAsserts()
+    {
+        /* Rely on compiler "constant overflow warnings". */
+        JS_STATIC_ASSERT(((sMaxInit * sInvMaxAlpha) >> 7) < sMaxCapacity);
+        JS_STATIC_ASSERT((sMaxCapacity * sInvMaxAlpha) <= UINT32_MAX);
+        JS_STATIC_ASSERT((sMaxCapacity * sizeof(Entry)) <= UINT32_MAX);
+    }
+
     static bool isLiveHash(HashNumber hash)
     {
         return Entry::isLiveHash(hash);
     }
 
     static HashNumber prepareHash(const Lookup& l)
     {
         HashNumber keyHash = HashPolicy::hash(l);
@@ -360,34 +369,34 @@ class HashTable : private AllocPolicy
     {
         /* Make sure that init isn't called twice. */
         JS_ASSERT(table == NULL);
 
         /*
          * Correct for sMaxAlphaFrac such that the table will not resize
          * when adding 'length' entries.
          */
-        JS_ASSERT(length < (uint32(1) << 23));
+        if (length > sMaxInit) {
+            this->reportAllocOverflow();
+            return false;
+        }
         uint32 capacity = (length * sInvMaxAlpha) >> 7;
 
         if (capacity < sMinSize)
             capacity = sMinSize;
 
         /* FIXME: use JS_CEILING_LOG2 when PGO stops crashing (bug 543034). */
         uint32 roundUp = sMinSize, roundUpLog2 = sMinSizeLog2;
         while (roundUp < capacity) {
             roundUp <<= 1;
             ++roundUpLog2;
         }
 
         capacity = roundUp;
-        if (capacity >= sSizeLimit) {
-            this->reportAllocOverflow();
-            return false;
-        }
+        JS_ASSERT(capacity <= sMaxCapacity);
 
         table = createTable(*this, capacity);
         if (!table)
             return false;
 
         setTableSizeLog2(roundUpLog2);
         METER(memset(&stats, 0, sizeof(stats)));
         return true;
@@ -531,17 +540,17 @@ class HashTable : private AllocPolicy
 
     bool changeTableSize(int deltaLog2)
     {
         /* Look, but don't touch, until we succeed in getting new entry store. */
         Entry *oldTable = table;
         uint32 oldCap = tableCapacity;
         uint32 newLog2 = sHashBits - hashShift + deltaLog2;
         uint32 newCapacity = JS_BIT(newLog2);
-        if (newCapacity >= sSizeLimit) {
+        if (newCapacity > sMaxCapacity) {
             this->reportAllocOverflow();
             return false;
         }
 
         Entry *newTable = createTable(*this, newCapacity);
         if (!newTable)
             return false;
 
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -507,17 +507,17 @@ Class js_NoSuchMethodClass = {
     no_such_method_trace  /* trace */
 };
 
 /*
  * When JSOP_CALLPROP or JSOP_CALLELEM does not find the method property of
  * the base object, we search for the __noSuchMethod__ method in the base.
  * If it exists, we store the method and the property's id into an object of
  * NoSuchMethod class and store this object into the callee's stack slot.
- * Later, js_Invoke will recognise such an object and transfer control to
+ * Later, Invoke will recognise such an object and transfer control to
  * NoSuchMethod that invokes the method like:
  *
  *   this.__noSuchMethod__(id, args)
  *
  * where id is the name of the method that this invocation attempted to
  * call by name, and args is an Array containing this invocation's actual
  * parameters.
  */
@@ -616,17 +616,17 @@ RunScript(JSContext *cx, JSScript *scrip
 
 /*
  * Find a function reference and its 'this' value implicit first parameter
  * under argc arguments on cx's stack, and call the function.  Push missing
  * required arguments, allocate declared local variables, and pop everything
  * when done.  Then push the return value.
  */
 JS_REQUIRES_STACK bool
-Invoke(JSContext *cx, const CallArgs &argsRef, MaybeConstruct construct)
+InvokeKernel(JSContext *cx, const CallArgs &argsRef, MaybeConstruct construct)
 {
     /* N.B. Must be kept in sync with InvokeSessionGuard::start/invoke */
 
     CallArgs args = argsRef;
     JS_ASSERT(args.argc() <= StackSpace::ARGS_LENGTH_MAX);
 
     if (args.calleev().isPrimitive()) {
         js_ReportIsNotFunction(cx, &args.calleev(), ToReportFlags(construct));
@@ -776,18 +776,18 @@ InvokeSessionGuard::start(JSContext *cx,
     if (ifg_.pushed())
         ifg_.pop();
     formals_ = actuals_ = args_.argv();
     nformals_ = (unsigned)-1;
     return true;
 }
 
 bool
-ExternalInvoke(JSContext *cx, const Value &thisv, const Value &fval,
-               uintN argc, Value *argv, Value *rval)
+Invoke(JSContext *cx, const Value &thisv, const Value &fval, uintN argc, Value *argv,
+       Value *rval)
 {
     LeaveTrace(cx);
 
     InvokeArgsGuard args;
     if (!cx->stack.pushInvokeArgs(cx, argc, &args))
         return false;
 
     args.calleev() = fval;
@@ -809,18 +809,17 @@ ExternalInvoke(JSContext *cx, const Valu
     if (!Invoke(cx, args))
         return false;
 
     *rval = args.rval();
     return true;
 }
 
 bool
-ExternalInvokeConstructor(JSContext *cx, const Value &fval, uintN argc, Value *argv,
-                          Value *rval)
+InvokeConstructor(JSContext *cx, const Value &fval, uintN argc, Value *argv, Value *rval)
 {
     LeaveTrace(cx);
 
     InvokeArgsGuard args;
     if (!cx->stack.pushInvokeArgs(cx, argc, &args))
         return false;
 
     args.calleev() = fval;
@@ -830,28 +829,28 @@ ExternalInvokeConstructor(JSContext *cx,
     if (!InvokeConstructor(cx, args))
         return false;
 
     *rval = args.rval();
     return true;
 }
 
 bool
-ExternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, const Value &fval,
-                 JSAccessMode mode, uintN argc, Value *argv, Value *rval)
+InvokeGetterOrSetter(JSContext *cx, JSObject *obj, const Value &fval, uintN argc, Value *argv,
+                     Value *rval)
 {
     LeaveTrace(cx);
 
     /*
-     * ExternalInvoke could result in another try to get or set the same id
-     * again, see bug 355497.
+     * Invoke could result in another try to get or set the same id again, see
+     * bug 355497.
      */
     JS_CHECK_RECURSION(cx, return false);
 
-    return ExternalInvoke(cx, ObjectValue(*obj), fval, argc, argv, rval);
+    return Invoke(cx, ObjectValue(*obj), fval, argc, argv, rval);
 }
 
 #if JS_HAS_SHARP_VARS
 JS_STATIC_ASSERT(SHARP_NSLOTS == 2);
 
 static JS_NEVER_INLINE bool
 InitSharpSlots(JSContext *cx, StackFrame *fp)
 {
@@ -873,18 +872,18 @@ InitSharpSlots(JSContext *cx, StackFrame
         sharps[0].setUndefined();
         sharps[1].setUndefined();
     }
     return true;
 }
 #endif
 
 bool
-Execute(JSContext *cx, JSScript *script, JSObject &scopeChain, const Value &thisv,
-        ExecuteType type, StackFrame *evalInFrame, Value *result)
+ExecuteKernel(JSContext *cx, JSScript *script, JSObject &scopeChain, const Value &thisv,
+              ExecuteType type, StackFrame *evalInFrame, Value *result)
 {
     JS_ASSERT_IF(evalInFrame, type == EXECUTE_DEBUG);
 
     if (script->isEmpty()) {
         if (result)
             result->setUndefined();
         return true;
     }
@@ -914,17 +913,17 @@ Execute(JSContext *cx, JSScript *script,
         *result = fp->returnValue();
 
     Probes::stopExecution(cx, script);
 
     return !!ok;
 }
 
 bool
-ExternalExecute(JSContext *cx, JSScript *script, JSObject &scopeChainArg, Value *rval)
+Execute(JSContext *cx, JSScript *script, JSObject &scopeChainArg, Value *rval)
 {
     /* The scope chain could be anything, so innerize just in case. */
     JSObject *scopeChain = &scopeChainArg;
     OBJ_TO_INNER_OBJECT(cx, scopeChain);
     if (!scopeChain)
         return false;
 
     /* If we were handed a non-native object, complain bitterly. */
@@ -939,18 +938,18 @@ ExternalExecute(JSContext *cx, JSScript 
         scopeChain->makeVarObj();
 
     /* Use the scope chain as 'this', modulo outerization. */
     JSObject *thisObj = scopeChain->thisObject(cx);
     if (!thisObj)
         return false;
     Value thisv = ObjectValue(*thisObj);
 
-    return Execute(cx, script, *scopeChain, thisv, EXECUTE_GLOBAL,
-                   NULL /* evalInFrame */, rval);
+    return ExecuteKernel(cx, script, *scopeChain, thisv, EXECUTE_GLOBAL,
+                         NULL /* evalInFrame */, rval);
 }
 
 bool
 CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs)
 {
     JSObject *obj2;
     JSProperty *prop;
     uintN oldAttrs;
@@ -1185,17 +1184,17 @@ TypeOfValue(JSContext *cx, const Value &
         return JSTYPE_VOID;
     if (v.isObject())
         return v.toObject().typeOf(cx);
     JS_ASSERT(v.isBoolean());
     return JSTYPE_BOOLEAN;
 }
 
 JS_REQUIRES_STACK bool
-InvokeConstructor(JSContext *cx, const CallArgs &argsRef)
+InvokeConstructorKernel(JSContext *cx, const CallArgs &argsRef)
 {
     JS_ASSERT(!js_FunctionClass.construct);
     CallArgs args = argsRef;
 
     if (args.calleev().isObject()) {
         JSObject *callee = &args.callee();
         Class *clasp = callee->getClass();
         if (clasp == &js_FunctionClass) {
@@ -1207,17 +1206,17 @@ InvokeConstructor(JSContext *cx, const C
             bool ok = CallJSNativeConstructor(cx, fun->u.n.native, args);
             Probes::calloutEnd(cx, fun);
             return ok;
             }
 
             if (!fun->isInterpretedConstructor())
                 goto error;
 
-            if (!Invoke(cx, args, CONSTRUCT))
+            if (!InvokeKernel(cx, args, CONSTRUCT))
                 return false;
 
             JS_ASSERT(args.rval().isObject());
             return true;
         }
         if (clasp->construct) {
             args.thisv().setMagicWithObjectOrNullPayload(NULL);
             return CallJSNativeConstructor(cx, clasp->construct, args);
@@ -3981,17 +3980,17 @@ END_CASE(JSOP_ENUMELEM)
 
 BEGIN_CASE(JSOP_EVAL)
 {
     CallArgs args = CallArgsFromSp(GET_ARGC(regs.pc), regs.sp);
     if (IsBuiltinEvalForScope(&regs.fp()->scopeChain(), args.calleev())) {
         if (!DirectEval(cx, args))
             goto error;
     } else {
-        if (!Invoke(cx, args))
+        if (!InvokeKernel(cx, args))
             goto error;
     }
     CHECK_INTERRUPT_HANDLER();
     regs.sp = args.spAfterCall();
 }
 END_CASE(JSOP_EVAL)
 
 BEGIN_CASE(JSOP_NEW)
@@ -4005,20 +4004,20 @@ BEGIN_CASE(JSOP_FUNAPPLY)
     MaybeConstruct construct = *regs.pc == JSOP_NEW ? CONSTRUCT : NO_CONSTRUCT;
 
     JSObject *callee;
     JSFunction *fun;
 
     /* Don't bother trying to fast-path calls to scripted non-constructors. */
     if (!IsFunctionObject(args.calleev(), &callee, &fun) || !fun->isInterpretedConstructor()) {
         if (construct) {
-            if (!InvokeConstructor(cx, args))
+            if (!InvokeConstructorKernel(cx, args))
                 goto error;
         } else {
-            if (!Invoke(cx, args))
+            if (!InvokeKernel(cx, args))
                 goto error;
         }
         regs.sp = args.spAfterCall();
         CHECK_INTERRUPT_HANDLER();
         TRACE_0(NativeCallComplete);
         len = JSOP_CALL_LENGTH;
         DO_NEXT_OP(len);
     }
@@ -4585,20 +4584,20 @@ BEGIN_CASE(JSOP_DEFFUN)
     /*
      * A top-level function defined in Global or Eval code (see ECMA-262
      * Ed. 3), or else a SpiderMonkey extension: a named function statement in
      * a compound statement (not at the top statement level of global code, or
      * at the top level of a function body).
      */
     JSFunction *fun;
     LOAD_FUNCTION(0);
-    JSObject *obj = FUN_OBJECT(fun);
+    JSObject *obj = fun;
 
     JSObject *obj2;
-    if (FUN_NULL_CLOSURE(fun)) {
+    if (fun->isNullClosure()) {
         /*
          * Even a null closure needs a parent for principals finding.
          * FIXME: bug 476950, although debugger users may also demand some kind
          * of scope link for debugger-assisted eval-in-frame.
          */
         obj2 = &regs.fp()->scopeChain();
     } else {
         JS_ASSERT(!fun->isFlatClosure());
@@ -4725,20 +4724,20 @@ BEGIN_CASE(JSOP_DEFLOCALFUN)
      * function), parented by the current scope chain, stored in a local
      * variable slot that the compiler allocated.  This is an optimization over
      * JSOP_DEFFUN that avoids requiring a call object for the outer function's
      * activation.
      */
     JSFunction *fun;
     LOAD_FUNCTION(SLOTNO_LEN);
     JS_ASSERT(fun->isInterpreted());
-    JS_ASSERT(!FUN_FLAT_CLOSURE(fun));
-    JSObject *obj = FUN_OBJECT(fun);
-
-    if (FUN_NULL_CLOSURE(fun)) {
+    JS_ASSERT(!fun->isFlatClosure());
+    JSObject *obj = fun;
+
+    if (fun->isNullClosure()) {
         obj = CloneFunctionObject(cx, fun, &regs.fp()->scopeChain());
         if (!obj)
             goto error;
     } else {
         JSObject *parent = GetScopeChainFast(cx, regs.fp(), JSOP_DEFLOCALFUN,
                                              JSOP_DEFLOCALFUN_LENGTH);
         if (!parent)
             goto error;
@@ -4777,22 +4776,22 @@ BEGIN_CASE(JSOP_DEFLOCALFUN_FC)
 }
 END_CASE(JSOP_DEFLOCALFUN_FC)
 
 BEGIN_CASE(JSOP_LAMBDA)
 {
     /* Load the specified function object literal. */
     JSFunction *fun;
     LOAD_FUNCTION(0);
-    JSObject *obj = FUN_OBJECT(fun);
+    JSObject *obj = fun;
 
     /* do-while(0) so we can break instead of using a goto. */
     do {
         JSObject *parent;
-        if (FUN_NULL_CLOSURE(fun)) {
+        if (fun->isNullClosure()) {
             parent = &regs.fp()->scopeChain();
 
             if (obj->getParent() == parent) {
                 jsbytecode *pc2 = AdvanceOverBlockchainOp(regs.pc + JSOP_LAMBDA_LENGTH);
                 JSOp op2 = JSOp(*pc2);
 
                 /*
                  * Optimize var obj = {method: function () { ... }, ...},
@@ -4840,17 +4839,17 @@ BEGIN_CASE(JSOP_LAMBDA)
                          * Note that we have not yet pushed obj as the final argument,
                          * so regs.sp[1 - (iargc + 2)], and not regs.sp[-(iargc + 2)],
                          * is the callee for this JSOP_CALL.
                          */
                         const Value &cref = regs.sp[1 - (iargc + 2)];
                         JSObject *callee;
 
                         if (IsFunctionObject(cref, &callee)) {
-                            JSFunction *calleeFun = GET_FUNCTION_PRIVATE(cx, callee);
+                            JSFunction *calleeFun = callee->getFunctionPrivate();
                             if (Native native = calleeFun->maybeNative()) {
                                 if ((iargc == 1 && native == array_sort) ||
                                     (iargc == 2 && native == str_replace)) {
                                     break;
                                 }
                             }
                         }
                     } else if (op2 == JSOP_NULL) {
@@ -6087,17 +6086,17 @@ END_CASE(JSOP_ARRAYPUSH)
 
   exit:
     interpReturnOK = ScriptEpilogueOrGeneratorYield(cx, regs.fp(), interpReturnOK);
     regs.fp()->setFinishedInInterpreter();
 
     /*
      * At this point we are inevitably leaving an interpreted function or a
      * top-level script, and returning to one of:
-     * (a) an "out of line" call made through js_Invoke;
+     * (a) an "out of line" call made through Invoke;
      * (b) a js_Execute activation;
      * (c) a generator (SendToGenerator, jsiter.c).
      *
      * We must not be in an inline frame. The check above ensures that for the
      * error case and for a normal return, the code jumps directly to parent's
      * frame pc.
      */
     JS_ASSERT(entryFrame == regs.fp());
--- a/js/src/jsinterp.h
+++ b/js/src/jsinterp.h
@@ -140,43 +140,54 @@ BoxNonStrictThis(JSContext *cx, const Ca
  * call represented by |fp|. ComputeThis is necessary because fp->thisValue()
  * may be set to 'undefined' when 'this' should really be the global object (as
  * an optimization to avoid global-this computation).
  */
 inline bool
 ComputeThis(JSContext *cx, StackFrame *fp);
 
 /*
- * The js::InvokeArgumentsGuard passed to js_Invoke must come from an
- * immediately-enclosing successful call to js::StackSpace::pushInvokeArgs,
- * i.e., there must have been no un-popped pushes to cx->stack. Furthermore,
- * |args.getvp()[0]| should be the callee, |args.getvp()[1]| should be |this|,
- * and the range [args.getvp() + 2, args.getvp() + 2 + args.getArgc()) should
- * be initialized actual arguments.
+ * InvokeKernel assumes that the given args have been pushed on the top of the
+ * VM stack. Additionally, if 'args' is contained in a CallArgsList, that they
+ * have already been marked 'active'.
  */
 extern bool
-Invoke(JSContext *cx, const CallArgs &args, MaybeConstruct construct = NO_CONSTRUCT);
+InvokeKernel(JSContext *cx, const CallArgs &args, MaybeConstruct construct = NO_CONSTRUCT);
 
 /*
- * For calls to natives, the InvokeArgsGuard object provides a record of the
- * call for the debugger's callstack. For this to work, the InvokeArgsGuard
- * record needs to know when the call is actually active (because the
- * InvokeArgsGuard can be pushed long before and popped long after the actual
- * call, during which time many stack-observing things can happen).
+ * Invoke assumes that 'args' has been pushed (via ContextStack::pushInvokeArgs)
+ * and is currently at the top of the VM stack.
  */
 inline bool
 Invoke(JSContext *cx, InvokeArgsGuard &args, MaybeConstruct construct = NO_CONSTRUCT)
 {
     args.setActive();
-    bool ok = Invoke(cx, ImplicitCast<CallArgs>(args), construct);
+    bool ok = InvokeKernel(cx, args, construct);
     args.setInactive();
     return ok;
 }
 
 /*
+ * This Invoke overload places the least requirements on the caller: it may be
+ * called at any time and it takes care of copying the given callee, this, and
+ * arguments onto the stack.
+ */
+extern bool
+Invoke(JSContext *cx, const Value &thisv, const Value &fval, uintN argc, Value *argv,
+       Value *rval);
+
+/*
+ * This helper takes care of the infinite-recursion check necessary for
+ * getter/setter calls.
+ */
+extern bool
+InvokeGetterOrSetter(JSContext *cx, JSObject *obj, const Value &fval, uintN argc, Value *argv,
+                     Value *rval);
+
+/*
  * Natives like sort/forEach/replace call Invoke repeatedly with the same
  * callee, this, and number of arguments. To optimize this, such natives can
  * start an "invoke session" to factor out much of the dynamic setup logic
  * required by a normal Invoke. Usage is:
  *
  *   InvokeSessionGuard session(cx);
  *   if (!session.start(cx, callee, thisp, argc, &session))
  *     ...
@@ -193,59 +204,57 @@ Invoke(JSContext *cx, InvokeArgsGuard &a
  *     ... = session.rval();
  *   }
  *
  *   // session ended by ~InvokeSessionGuard
  */
 class InvokeSessionGuard;
 
 /*
- * "External" calls may come from C or C++ code using a JSContext on which no
- * JS is running (!cx->fp), so they may need to push a dummy StackFrame.
+ * InvokeConstructor* implement a function call from a constructor context
+ * (e.g. 'new') handling the the creation of the new 'this' object.
  */
+extern JS_REQUIRES_STACK bool
+InvokeConstructorKernel(JSContext *cx, const CallArgs &args);
 
+/* See the InvokeArgsGuard overload of Invoke. */
+inline bool
+InvokeConstructor(JSContext *cx, InvokeArgsGuard &args)
+{
+    args.setActive();
+    bool ok = InvokeConstructorKernel(cx, ImplicitCast<CallArgs>(args));
+    args.setInactive();
+    return ok;
+}
+
+/* See the fval overload of Invoke. */
 extern bool
-ExternalInvoke(JSContext *cx, const Value &thisv, const Value &fval,
-               uintN argc, Value *argv, Value *rval);
-
-extern bool
-ExternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, const Value &fval,
-                 JSAccessMode mode, uintN argc, Value *argv, Value *rval);
+InvokeConstructor(JSContext *cx, const Value &fval, uintN argc, Value *argv, Value *rval);
 
 /*
- * These two functions invoke a function called from a constructor context
- * (e.g. 'new'). InvokeConstructor handles the general case where a new object
- * needs to be created for/by the constructor. ConstructWithGivenThis directly
- * calls the constructor with the given 'this', hence the caller must
- * understand the semantics of the constructor call.
+ * InvokeConstructorWithGivenThis directly calls the constructor with the given
+ * 'this'; the caller must choose the semantically correct 'this'.
  */
-
-extern JS_REQUIRES_STACK bool
-InvokeConstructor(JSContext *cx, const CallArgs &args);
-
 extern JS_REQUIRES_STACK bool
 InvokeConstructorWithGivenThis(JSContext *cx, JSObject *thisobj, const Value &fval,
                                uintN argc, Value *argv, Value *rval);
 
-extern bool
-ExternalInvokeConstructor(JSContext *cx, const Value &fval, uintN argc, Value *argv,
-                          Value *rval);
-
-extern bool
-ExternalExecute(JSContext *cx, JSScript *script, JSObject &scopeChain, Value *rval);
-
 /*
  * Executes a script with the given scopeChain/this. The 'type' indicates
  * whether this is eval code or global code. To support debugging, the
  * evalFrame parameter can point to an arbitrary frame in the context's call
  * stack to simulate executing an eval in that frame.
  */
 extern bool
-Execute(JSContext *cx, JSScript *script, JSObject &scopeChain, const Value &thisv,
-        ExecuteType type, StackFrame *evalInFrame, Value *result);
+ExecuteKernel(JSContext *cx, JSScript *script, JSObject &scopeChain, const Value &thisv,
+              ExecuteType type, StackFrame *evalInFrame, Value *result);
+
+/* Execute a script with the given scopeChain as global code. */
+extern bool
+Execute(JSContext *cx, JSScript *script, JSObject &scopeChain, Value *rval);
 
 /* Flags to toggle js::Interpret() execution. */
 enum InterpMode
 {
     JSINTERP_NORMAL    = 0, /* interpreter is running normally */
     JSINTERP_RECORD    = 1, /* interpreter has been started to record/run traces */
     JSINTERP_SAFEPOINT = 2, /* interpreter should leave on a method JIT safe point */
     JSINTERP_PROFILE   = 3  /* interpreter should profile a loop */
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -357,17 +357,17 @@ GetCustomIterator(JSContext *cx, JSObjec
     }
 
     if (!cx->runningWithTrustedPrincipals())
         ++sCustomIteratorCount;
 
     /* Otherwise call it and return that object. */
     LeaveTrace(cx);
     Value arg = BooleanValue((flags & JSITER_FOREACH) == 0);
-    if (!ExternalInvoke(cx, ObjectValue(*obj), *vp, 1, &arg, vp))
+    if (!Invoke(cx, ObjectValue(*obj), *vp, 1, &arg, vp))
         return false;
     if (vp->isPrimitive()) {
         /*
          * We are always coming from js_ValueToIterator, and we are no longer on
          * trace, so the object we are iterating over is on top of the stack (-1).
          */
         JSAutoByteString bytes;
         if (!js_AtomToPrintableString(cx, atom, &bytes))
@@ -949,17 +949,17 @@ js_IteratorMore(JSContext *cx, JSObject 
     /* We're reentering below and can call anything. */
     JS_CHECK_RECURSION(cx, return false);
 
     /* Fetch and cache the next value from the iterator. */
     if (!ni) {
         jsid id = ATOM_TO_JSID(cx->runtime->atomState.nextAtom);
         if (!js_GetMethod(cx, iterobj, id, JSGET_METHOD_BARRIER, rval))
             return false;
-        if (!ExternalInvoke(cx, ObjectValue(*iterobj), *rval, 0, NULL, rval)) {
+        if (!Invoke(cx, ObjectValue(*iterobj), *rval, 0, NULL, rval)) {
             /* Check for StopIteration. */
             if (!cx->isExceptionPending() || !js_ValueIsStopIteration(cx->getPendingException()))
                 return false;
 
             cx->clearPendingException();
             cx->iterValue.setMagic(JS_NO_ITER_VALUE);
             rval->setBoolean(false);
             return true;
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -1186,17 +1186,16 @@ EvalKernel(JSContext *cx, const CallArgs
          * the eval code to use.
          */
         if (!ComputeThis(cx, caller))
             return false;
         thisv = caller->thisValue();
 
 #ifdef DEBUG
         jsbytecode *callerPC = caller->pcQuadratic(cx);
-        JS_ASSERT_IF(caller->isFunctionFrame(), caller->fun()->isHeavyweight());
         JS_ASSERT(callerPC && js_GetOpcode(cx, caller->script(), callerPC) == JSOP_EVAL);
 #endif
     } else {
         JS_ASSERT(call.callee().getGlobal() == &scopeobj);
         staticLevel = 0;
 
         /* Use the global as 'this', modulo outerization. */
         JSObject *thisobj = scopeobj.thisObject(cx);
@@ -1270,18 +1269,18 @@ EvalKernel(JSContext *cx, const CallArgs
                                                      chars, length, filename, lineno,
                                                      cx->findVersion(), linearStr, staticLevel);
         if (!compiled)
             return false;
 
         esg.setNewScript(compiled);
     }
 
-    return Execute(cx, esg.script(), scopeobj, thisv, ExecuteType(evalType),
-                   NULL /* evalInFrame */, &call.rval());
+    return ExecuteKernel(cx, esg.script(), scopeobj, thisv, ExecuteType(evalType),
+                         NULL /* evalInFrame */, &call.rval());
 }
 
 /*
  * We once supported a second argument to eval to use as the scope chain
  * when evaluating the code string.  Warn when such uses are seen so that
  * authors will know that support for eval(s, o) has been removed.
  */
 static inline bool
@@ -1400,18 +1399,18 @@ obj_watch_handler(JSContext *cx, JSObjec
     }
 
     /* Avoid recursion on (obj, id) already being watched on cx. */
     AutoResolving resolving(cx, obj, id, AutoResolving::WATCH);
     if (resolving.alreadyStarted())
         return true;
 
     Value argv[] = { IdToValue(id), Valueify(old), Valueify(*nvp) };
-    return ExternalInvoke(cx, ObjectValue(*obj), ObjectOrNullValue(callable),
-                          JS_ARRAY_LENGTH(argv), argv, Valueify(nvp));
+    return Invoke(cx, ObjectValue(*obj), ObjectOrNullValue(callable), JS_ARRAY_LENGTH(argv), argv,
+                  Valueify(nvp));
 }
 
 static JSBool
 obj_watch(JSContext *cx, uintN argc, Value *vp)
 {
     if (argc <= 1) {
         js_ReportMissingArg(cx, *vp, 1);
         return JS_FALSE;
@@ -3914,29 +3913,29 @@ DefineConstructorAndPrototype(JSContext 
          * because the constructor currently must have |obj| as its parent.
          * (FIXME: remove this dependency on the exact identity of the parent,
          * perhaps as part of bug 638316.)
          */
         JSFunction *fun =
             js_NewFunction(cx, NULL, constructor, nargs, JSFUN_CONSTRUCTOR, obj, atom);
         if (!fun)
             goto bad;
-        FUN_CLASP(fun) = clasp;
+        fun->setConstructorClass(clasp);
 
         AutoValueRooter tvr2(cx, ObjectValue(*fun));
         if (!DefineStandardSlot(cx, obj, key, atom, tvr2.value(), 0, named))
             goto bad;
 
         /*
          * Optionally construct the prototype object, before the class has
          * been fully initialized.  Allow the ctor to replace proto with a
          * different object, as is done for operator new -- and as at least
          * XML support requires.
          */
-        ctor = FUN_OBJECT(fun);
+        ctor = fun;
         if (clasp->flags & JSCLASS_CONSTRUCT_PROTOTYPE) {
             Value rval;
             if (!InvokeConstructorWithGivenThis(cx, proto, ObjectOrNullValue(ctor),
                                                 0, NULL, &rval)) {
                 goto bad;
             }
             if (rval.isObject() && &rval.toObject() != proto)
                 proto = &rval.toObject();
@@ -4704,17 +4703,17 @@ DefineNativeProperty(JSContext *cx, JSOb
         /* Add a new property, or replace an existing one of the same id. */
         if (defineHow & DNP_SET_METHOD) {
             JS_ASSERT(clasp == &js_ObjectClass);
             JS_ASSERT(IsFunctionObject(value));
             JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
             JS_ASSERT(!getter && !setter);
 
             JSObject *funobj = &value.toObject();
-            if (FUN_OBJECT(GET_FUNCTION_PRIVATE(cx, funobj)) == funobj) {
+            if (funobj->getFunctionPrivate() == funobj) {
                 flags |= Shape::METHOD;
                 getter = CastAsPropertyOp(funobj);
             }
         }
 
         if (const Shape *existingShape = obj->nativeLookup(id)) {
             if (existingShape->hasSlot())
                 AbortRecordingIfUnexpectedGlobalWrite(cx, obj, existingShape->slot);
@@ -5444,17 +5443,17 @@ JSObject::reportNotExtensible(JSContext 
                                     NULL, NULL, NULL);
 }
 
 bool
 JSObject::callMethod(JSContext *cx, jsid id, uintN argc, Value *argv, Value *vp)
 {
     Value fval;
     return js_GetMethod(cx, this, id, JSGET_NO_METHOD_BARRIER, &fval) &&
-           ExternalInvoke(cx, ObjectValue(*this), fval, argc, argv, vp);
+           Invoke(cx, ObjectValue(*this), fval, argc, argv, vp);
 }
 
 JSBool
 js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
                      Value *vp, JSBool strict)
 {
     JSObject *pobj;
     JSProperty *prop;
@@ -5657,17 +5656,17 @@ js_SetPropertyHelper(JSContext *cx, JSOb
          * Check for Object class here to avoid defining a method on a class
          * with magic resolve, addProperty, getProperty, etc. hooks.
          */
         if ((defineHow & DNP_SET_METHOD) && obj->canHaveMethodBarrier()) {
             JS_ASSERT(IsFunctionObject(*vp));
             JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
 
             JSObject *funobj = &vp->toObject();
-            JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj);
+            JSFunction *fun = funobj->getFunctionPrivate();
             if (fun == funobj) {
                 flags |= Shape::METHOD;
                 getter = CastAsPropertyOp(funobj);
             }
         }
 
         shape = obj->putProperty(cx, id, getter, setter, SHAPE_INVALID_SLOT,
                                  attrs, flags, shortid);
@@ -5792,17 +5791,17 @@ js_DeleteProperty(JSContext *cx, JSObjec
          * We do not check suspended frames. They can't be reached via caller,
          * so the only way they could have the method's joined function object
          * as callee is through an API abusage. We break any such edge case.
          */
         if (obj->hasMethodBarrier()) {
             JSObject *funobj;
 
             if (IsFunctionObject(v, &funobj)) {
-                JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj);
+                JSFunction *fun = funobj->getFunctionPrivate();
 
                 if (fun != funobj) {
                     for (StackFrame *fp = cx->maybefp(); fp; fp = fp->prev()) {
                         if (fp->isFunctionFrame() &&
                             fp->callee() == fun->compiledFunObj() &&
                             fp->thisValue().isObject())
                         {
                             JSObject *tmp = &fp->thisValue().toObject();
@@ -5849,17 +5848,17 @@ static bool
 MaybeCallMethod(JSContext *cx, JSObject *obj, jsid id, Value *vp)
 {
     if (!js_GetMethod(cx, obj, id, JSGET_NO_METHOD_BARRIER, vp))
         return false;
     if (!js_IsCallable(*vp)) {
         *vp = ObjectValue(*obj);
         return true;
     }
-    return ExternalInvoke(cx, ObjectValue(*obj), *vp, 0, NULL, vp);
+    return Invoke(cx, ObjectValue(*obj), *vp, 0, NULL, vp);
 }
 
 JSBool
 DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp)
 {
     JS_ASSERT(hint == JSTYPE_NUMBER || hint == JSTYPE_STRING || hint == JSTYPE_VOID);
     JS_ASSERT(!obj->isXML());
 
@@ -6487,17 +6486,17 @@ dumpValue(const Value &v)
     else if (v.isInt32())
         fprintf(stderr, "%d", v.toInt32());
     else if (v.isDouble())
         fprintf(stderr, "%g", v.toDouble());
     else if (v.isString())
         dumpString(v.toString());
     else if (v.isObject() && v.toObject().isFunction()) {
         JSObject *funobj = &v.toObject();
-        JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj);
+        JSFunction *fun = funobj->getFunctionPrivate();
         if (fun->atom) {
             fputs("<function ", stderr);
             FileEscapedString(stderr, fun->atom, 0);
         } else {
             fputs("<unnamed function", stderr);
         }
         if (fun->isInterpreted()) {
             JSScript *script = fun->script();
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -213,17 +213,17 @@ JSObject::methodReadBarrier(JSContext *c
     JS_ASSERT(shape.writable());
     JS_ASSERT(shape.slot != SHAPE_INVALID_SLOT);
     JS_ASSERT(shape.hasDefaultSetter());
     JS_ASSERT(!isGlobal());  /* i.e. we are not changing the global shape */
 
     JSObject *funobj = &vp->toObject();
     JSFunction *fun = funobj->getFunctionPrivate();
     JS_ASSERT(fun == funobj);
-    JS_ASSERT(FUN_NULL_CLOSURE(fun));
+    JS_ASSERT(fun->isNullClosure());
 
     funobj = CloneFunctionObject(cx, fun, funobj->getParent());
     if (!funobj)
         return NULL;
     funobj->setMethodObj(*this);
 
     /*
      * Replace the method property with an ordinary data property. This is
@@ -545,17 +545,17 @@ JSObject::setFlatClosureUpvar(uint32 i, 
     JS_ASSERT(i < getFunctionPrivate()->script()->bindings.countUpvars());
     getFlatClosureUpvars()[i] = v;
 }
 
 inline void
 JSObject::setFlatClosureUpvars(js::Value *upvars)
 {
     JS_ASSERT(isFunction());
-    JS_ASSERT(FUN_FLAT_CLOSURE(getFunctionPrivate()));
+    JS_ASSERT(getFunctionPrivate()->isFlatClosure());
     setSlot(JSSLOT_FLAT_CLOSURE_UPVARS, PrivateValue(upvars));
 }
 
 inline bool
 JSObject::hasMethodObj(const JSObject& obj) const
 {
     return JSSLOT_FUN_METHOD_OBJ < numSlots() &&
            getSlot(JSSLOT_FUN_METHOD_OBJ).isObject() &&
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -391,17 +391,17 @@ ToDisassemblySource(JSContext *cx, jsval
             source = JS_sprintf_append(source, "}");
             if (!source)
                 return false;
             bytes->initBytes(source);
             return true;
         }
 
         if (clasp == &js_FunctionClass) {
-            JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj);
+            JSFunction *fun = obj->getFunctionPrivate();
             JSString *str = JS_DecompileFunction(cx, fun, JS_DONT_PRETTY_PRINT);
             if (!str)
                 return false;
             return bytes->encode(cx, str);
         }
 
         if (clasp == &js_RegExpClass) {
             AutoValueRooter tvr(cx);
@@ -4967,17 +4967,17 @@ static const char native_code_str[] = "\
 
 JSBool
 js_DecompileFunctionBody(JSPrinter *jp)
 {
     JSScript *script;
 
     JS_ASSERT(jp->fun);
     JS_ASSERT(!jp->script);
-    if (!FUN_INTERPRETED(jp->fun)) {
+    if (!jp->fun->isInterpreted()) {
         js_printf(jp, native_code_str);
         return JS_TRUE;
     }
 
     script = jp->fun->script();
     return DecompileBody(jp, script, script->code);
 }
 
@@ -5006,17 +5006,17 @@ js_DecompileFunction(JSPrinter *jp)
             js_puts(jp, "(");
     }
 
     js_printf(jp, "%s ", js_function_str);
     if (fun->atom && !QuoteString(&jp->sprinter, fun->atom, 0))
         return JS_FALSE;
     js_puts(jp, "(");
 
-    if (!FUN_INTERPRETED(fun)) {
+    if (!fun->isInterpreted()) {
         js_printf(jp, ") {\n");
         jp->indent += 4;
         js_printf(jp, native_code_str);
         jp->indent -= 4;
         js_printf(jp, "\t}");
     } else {
         JSScript *script = fun->script();
 #if JS_HAS_DESTRUCTURING
--- a/js/src/jsparse.cpp
+++ b/js/src/jsparse.cpp
@@ -308,17 +308,17 @@ Parser::newFunctionBox(JSObject *obj, JS
     if (tc->innermostWith)
         funbox->tcflags |= TCF_IN_WITH;
     return funbox;
 }
 
 bool
 JSFunctionBox::joinable() const
 {
-    return FUN_NULL_CLOSURE(function()) &&
+    return function()->isNullClosure() &&
            !(tcflags & (TCF_FUN_USES_ARGUMENTS | TCF_FUN_USES_OWN_NAME));
 }
 
 bool
 JSFunctionBox::inAnyDynamicScope() const
 {
     for (const JSFunctionBox *funbox = this; funbox; funbox = funbox->parent) {
         if (funbox->tcflags & (TCF_IN_WITH | TCF_FUN_CALLS_EVAL))
@@ -985,17 +985,17 @@ Compiler::compileScript(JSContext *cx, J
         }
 
         if (callerFrame && callerFrame->isFunctionFrame()) {
             /*
              * An eval script in a caller frame needs to have its enclosing
              * function captured in case it refers to an upvar, and someone
              * wishes to decompile it while it's running.
              */
-            JSObjectBox *funbox = parser.newObjectBox(FUN_OBJECT(callerFrame->fun()));
+            JSObjectBox *funbox = parser.newObjectBox(callerFrame->fun());
             if (!funbox)
                 goto out;
             funbox->emitLink = cg.objectList.lastbox;
             cg.objectList.lastbox = funbox;
             cg.objectList.length++;
 #ifdef DEBUG
             savedCallerFun = true;
 #endif
@@ -1973,18 +1973,18 @@ Parser::newFunction(JSTreeContext *tc, J
         tc = tc->parent;
     JSObject *parent = tc->inFunction() ? NULL : tc->scopeChain();
 
     JSFunction *fun =
         js_NewFunction(context, NULL, NULL, 0,
                        JSFUN_INTERPRETED | (kind == Expression ? JSFUN_LAMBDA : 0),
                        parent, atom);
     if (fun && !tc->compileAndGo()) {
-        FUN_OBJECT(fun)->clearParent();
-        FUN_OBJECT(fun)->clearProto();
+        fun->clearParent();
+        fun->clearProto();
     }
     return fun;
 }
 
 static JSBool
 MatchOrInsertSemicolon(JSContext *cx, TokenStream *ts)
 {
     TokenKind tt = ts->peekTokenSameLine(TSF_OPERAND);
@@ -2456,22 +2456,22 @@ Parser::setFunctionKinds(JSFunctionBox *
 
                 if (funbox->shouldUnbrand(methodSets, slowMethodSets))
                     funbox->tcflags |= TCF_FUN_UNBRAND_THIS;
             }
         }
 
         JSFunction *fun = funbox->function();
 
-        JS_ASSERT(FUN_KIND(fun) == JSFUN_INTERPRETED);
+        JS_ASSERT(fun->kind() == JSFUN_INTERPRETED);
 
         if (funbox->tcflags & TCF_FUN_HEAVYWEIGHT) {
             /* nothing to do */
         } else if (funbox->inAnyDynamicScope()) {
-            JS_ASSERT(!FUN_NULL_CLOSURE(fun));
+            JS_ASSERT(!fun->isNullClosure());
         } else if (pn->pn_type != TOK_UPVARS) {
             /*
              * No lexical dependencies => null closure, for best performance.
              * A null closure needs no scope chain, but alas we've coupled
              * principals-finding to scope (for good fundamental reasons, but
              * the implementation overloads the parent slot and we should fix
              * that). See, e.g., the JSOP_LAMBDA case in jsinterp.cpp.
              *
@@ -2479,17 +2479,17 @@ Parser::setFunctionKinds(JSFunctionBox *
              * "joined function objects", or not, at its discretion. But real-
              * world implementations always create unique function objects for
              * closures, and this can be detected via mutation. Open question:
              * do popular implementations create unique function objects for
              * null closures?
              *
              * FIXME: bug 476950.
              */
-            FUN_SET_KIND(fun, JSFUN_NULL_CLOSURE);
+            fun->setKind(JSFUN_NULL_CLOSURE);
         } else {
             AtomDefnMapPtr upvars = pn->pn_names;
             JS_ASSERT(!upvars->empty());
 
             if (!fn->isFunArg()) {
                 /*
                  * This function is Algol-like, it never escapes.
                  *
@@ -2507,17 +2507,17 @@ Parser::setFunctionKinds(JSFunctionBox *
 
                     if (!lexdep->isFreeVar()) {
                         JS_ASSERT(lexdep->frameLevel() <= funbox->level);
                         break;
                     }
                 }
 
                 if (r.empty())
-                    FUN_SET_KIND(fun, JSFUN_NULL_CLOSURE);
+                    fun->setKind(JSFUN_NULL_CLOSURE);
             } else {
                 uintN nupvars = 0, nflattened = 0;
 
                 /*
                  * For each lexical dependency from this closure to an outer
                  * binding, analyze whether it is safe to copy the binding's
                  * value into a flat closure slot when the closure is formed.
                  */
@@ -2545,23 +2545,23 @@ Parser::setFunctionKinds(JSFunctionBox *
                          * closure. This is safe because we leave fun's kind
                          * set to interpreted, so all functions holding its
                          * upvars will be flagged as heavyweight.
                          */
                     }
                 }
 
                 if (nupvars == 0) {
-                    FUN_SET_KIND(fun, JSFUN_NULL_CLOSURE);
+                    fun->setKind(JSFUN_NULL_CLOSURE);
                 } else if (nflattened == nupvars) {
                     /*
                      * We made it all the way through the upvar loop, so it's
                      * safe to optimize to a flat closure.
                      */
-                    FUN_SET_KIND(fun, JSFUN_FLAT_CLOSURE);
+                    fun->setKind(JSFUN_FLAT_CLOSURE);
                     switch (PN_OP(fn)) {
                       case JSOP_DEFFUN:
                         fn->pn_op = JSOP_DEFFUN_FC;
                         break;
                       case JSOP_DEFLOCALFUN:
                         fn->pn_op = JSOP_DEFLOCALFUN_FC;
                         break;
                       case JSOP_LAMBDA:
@@ -2570,17 +2570,17 @@ Parser::setFunctionKinds(JSFunctionBox *
                       default:
                         /* js_EmitTree's case TOK_FUNCTION: will select op. */
                         JS_ASSERT(PN_OP(fn) == JSOP_NOP);
                     }
                 }
             }
         }
 
-        if (FUN_KIND(fun) == JSFUN_INTERPRETED && pn->pn_type == TOK_UPVARS) {
+        if (fun->kind() == JSFUN_INTERPRETED && pn->pn_type == TOK_UPVARS) {
             /*
              * One or more upvars cannot be safely snapshot into a flat
              * closure's non-reserved slot (see JSOP_GETFCSLOT), so we loop
              * again over all upvars, and for each non-free upvar, ensure that
              * its containing function has been flagged as heavyweight.
              *
              * The emitter must see TCF_FUN_HEAVYWEIGHT accurately before
              * generating any code for a tree of nested functions.
@@ -2616,17 +2616,17 @@ Parser::setFunctionKinds(JSFunctionBox *
  * must have their OWN_SHAPE flags set; the comments for
  * js::Bindings::extensibleParents explain why.
  */
 void
 Parser::markExtensibleScopeDescendants(JSFunctionBox *funbox, bool hasExtensibleParent) 
 {
     for (; funbox; funbox = funbox->siblings) {
         /*
-         * It would be nice to use FUN_KIND(fun) here to recognize functions
+         * It would be nice to use fun->kind() here to recognize functions
          * that will never consult their parent chains, and thus don't need
          * their 'extensible parents' flag set. Filed as bug 619750. 
          */
 
         JS_ASSERT(!funbox->bindings.extensibleParents());
         if (hasExtensibleParent)
             funbox->bindings.setExtensibleParents();
 
@@ -2658,17 +2658,17 @@ EnterFunction(JSParseNode *fn, JSTreeCon
               FunctionSyntaxKind kind = Expression)
 {
     JSTreeContext *tc = funtc->parent;
     JSFunction *fun = tc->parser->newFunction(tc, funAtom, kind);
     if (!fun)
         return NULL;
 
     /* Create box for fun->object early to protect against last-ditch GC. */
-    JSFunctionBox *funbox = tc->parser->newFunctionBox(FUN_OBJECT(fun), fn, tc);
+    JSFunctionBox *funbox = tc->parser->newFunctionBox(fun, fn, tc);
     if (!funbox)
         return NULL;
 
     /* Initialize non-default members of funtc. */
     funtc->flags |= funbox->tcflags;
     funtc->blockidGen = tc->blockidGen;
     if (!GenerateBlockId(funtc, funtc->bodyid))
         return NULL;
--- a/js/src/jsprobes.cpp
+++ b/js/src/jsprobes.cpp
@@ -85,20 +85,20 @@ FunctionName(JSContext *cx, const JSFunc
     if (!atom)
         return Probes::anonymousName;
     return bytes->encode(cx, atom) ? bytes->ptr() : Probes::nullName;
 }
 
 static const char *
 FunctionClassname(const JSFunction *fun)
 {
-    if (!fun || FUN_INTERPRETED(fun))
+    if (!fun || fun->isInterpreted())
         return Probes::nullName;
-    if (!(fun->flags & JSFUN_TRCINFO) && FUN_CLASP(fun))
-        return (char *)FUN_CLASP(fun)->name;
+    if (!(fun->flags & JSFUN_TRCINFO) && fun->getConstructorClass())
+        return fun->getConstructorClass()->name;
     return Probes::nullName;
 }
 
 /*
  * These functions call the DTrace macros for the JavaScript USDT probes.
  * Originally this code was inlined in the JavaScript code; however since
  * a number of operations are called, these have been placed into functions
  * to reduce any negative compiler optimization effect that the addition of
--- a/js/src/jspropertycache.cpp
+++ b/js/src/jspropertycache.cpp
@@ -166,17 +166,17 @@ PropertyCache::fill(JSContext *cx, JSObj
                      * obj with a new shape and set the JSObject::BRANDED flag.
                      * Once this flag is set, any property assignment that
                      * changes the value from or to a different function object
                      * will result in shape being regenerated.
                      */
                     if (!pobj->branded()) {
                         PCMETER(brandfills++);
 #ifdef DEBUG_notme
-                        JSFunction *fun = GET_FUNCTION_PRIVATE(cx, JSVAL_TO_OBJECT(v));
+                        JSFunction *fun = JSVAL_TO_OBJECT(v)->getFunctionPrivate();
                         JSAutoByteString funNameBytes;
                         if (const char *funName = GetFunctionNameBytes(cx, fun, &funNameBytes)) {
                             fprintf(stderr,
                                     "branding %p (%s) for funobj %p (%s), shape %lu\n",
                                     pobj, pobj->getClass()->name, JSVAL_TO_OBJECT(v), funName,
                                     obj->shape());
                         }
 #endif
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -124,20 +124,18 @@ JSProxyHandler::get(JSContext *cx, JSObj
         vp->setUndefined();
         return true;
     }
     if (!desc.getter ||
         (!(desc.attrs & JSPROP_GETTER) && desc.getter == PropertyStub)) {
         *vp = desc.value;
         return true;
     }
-    if (desc.attrs & JSPROP_GETTER) {
-        return ExternalGetOrSet(cx, receiver, id, CastAsObjectJsval(desc.getter),
-                                JSACC_READ, 0, NULL, vp);
-    }
+    if (desc.attrs & JSPROP_GETTER)
+        return InvokeGetterOrSetter(cx, receiver, CastAsObjectJsval(desc.getter), 0, NULL, vp);
     if (!(desc.attrs & JSPROP_SHARED))
         *vp = desc.value;
     else
         vp->setUndefined();
     if (desc.attrs & JSPROP_SHORTID)
         id = INT_TO_JSID(desc.shortid);
     return CallJSPropertyOp(cx, desc.getter, receiver, id, vp);
 }
@@ -270,32 +268,31 @@ JSProxyHandler::defaultValue(JSContext *
     return DefaultValue(cx, proxy, hint, vp);
 }
 
 bool
 JSProxyHandler::call(JSContext *cx, JSObject *proxy, uintN argc, Value *vp)
 {
     JS_ASSERT(OperationInProgress(cx, proxy));
     AutoValueRooter rval(cx);
-    JSBool ok = ExternalInvoke(cx, vp[1], GetCall(proxy), argc, JS_ARGV(cx, vp),
-                               rval.addr());
+    JSBool ok = Invoke(cx, vp[1], GetCall(proxy), argc, JS_ARGV(cx, vp), rval.addr());
     if (ok)
         JS_SET_RVAL(cx, vp, rval.value());
     return ok;
 }
 
 bool
 JSProxyHandler::construct(JSContext *cx, JSObject *proxy,
                           uintN argc, Value *argv, Value *rval)
 {
     JS_ASSERT(OperationInProgress(cx, proxy));
     Value fval = GetConstruct(proxy);
     if (fval.isUndefined())
-        return ExternalInvokeConstructor(cx, GetCall(proxy), argc, argv, rval);
-    return ExternalInvoke(cx, UndefinedValue(), fval, argc, argv, rval);
+        return InvokeConstructor(cx, GetCall(proxy), argc, argv, rval);
+    return Invoke(cx, UndefinedValue(), fval, argc, argv, rval);
 }
 
 bool
 JSProxyHandler::hasInstance(JSContext *cx, JSObject *proxy, const Value *vp, bool *bp)
 {
     JS_ASSERT(OperationInProgress(cx, proxy));
     js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS,
                         JSDVG_SEARCH_STACK, ObjectValue(*proxy), NULL);
@@ -354,17 +351,17 @@ GetDerivedTrap(JSContext *cx, JSObject *
               atom == ATOM(iterate));
 
     return GetTrap(cx, handler, atom, fvalp);
 }
 
 static bool
 Trap(JSContext *cx, JSObject *handler, Value fval, uintN argc, Value* argv, Value *rval)
 {
-    return ExternalInvoke(cx, ObjectValue(*handler), fval, argc, argv, rval);
+    return Invoke(cx, ObjectValue(*handler), fval, argc, argv, rval);
 }
 
 static bool
 Trap1(JSContext *cx, JSObject *handler, Value fval, jsid id, Value *rval)
 {
     JSString *str = js_ValueToString(cx, IdToValue(id));
     if (!str)
         return false;
@@ -1112,19 +1109,17 @@ proxy_Call(JSContext *cx, uintN argc, Va
     return JSProxy::call(cx, proxy, argc, vp);
 }
 
 JSBool
 proxy_Construct(JSContext *cx, uintN argc, Value *vp)
 {
     JSObject *proxy = &JS_CALLEE(cx, vp).toObject();
     JS_ASSERT(proxy->isProxy());
-    Value rval;
-    bool ok = JSProxy::construct(cx, proxy, argc, JS_ARGV(cx, vp), &rval);
-    *vp = rval;
+    bool ok = JSProxy::construct(cx, proxy, argc, JS_ARGV(cx, vp), vp);
     return ok;
 }
 
 JS_FRIEND_API(Class) FunctionProxyClass = {
     "Proxy",
     Class::NON_NATIVE | JSCLASS_HAS_RESERVED_SLOTS(5),
     PropertyStub,         /* addProperty */
     PropertyStub,         /* delProperty */
@@ -1310,19 +1305,17 @@ static const uint32 JSSLOT_CALLABLE_CONS
 
 static JSBool
 callable_Call(JSContext *cx, uintN argc, Value *vp)
 {
     JSObject *callable = &JS_CALLEE(cx, vp).toObject();
     JS_ASSERT(callable->getClass() == &CallableObjectClass);
     const Value &fval = callable->getSlot(JSSLOT_CALLABLE_CALL);
     const Value &thisval = vp[1];
-    Value rval;
-    bool ok = ExternalInvoke(cx, thisval, fval, argc, JS_ARGV(cx, vp), &rval);
-    *vp = rval;
+    bool ok = Invoke(cx, thisval, fval, argc, JS_ARGV(cx, vp), vp);
     return ok;
 }
 
 JSBool
 callable_Construct(JSContext *cx, uintN argc, Value *vp)
 {
     JSObject *thisobj = js_CreateThis(cx, &JS_CALLEE(cx, vp).toObject());
     if (!thisobj)
@@ -1350,30 +1343,28 @@ callable_Construct(JSContext *cx, uintN 
         }
 
         JSObject *newobj = NewNativeClassInstance(cx, &js_ObjectClass, proto, proto->getParent());
         if (!newobj)
             return false;
 
         /* If the call returns an object, return that, otherwise the original newobj. */
         Value rval;
-        if (!ExternalInvoke(cx, ObjectValue(*newobj), callable->getSlot(JSSLOT_CALLABLE_CALL),
-                            argc, vp + 2, &rval)) {
+        if (!Invoke(cx, ObjectValue(*newobj), callable->getSlot(JSSLOT_CALLABLE_CALL),
+                    argc, vp + 2, &rval)) {
             return false;
         }
         if (rval.isPrimitive())
             vp->setObject(*newobj);
         else
             *vp = rval;
         return true;
     }
 
-    Value rval;
-    bool ok = ExternalInvoke(cx, ObjectValue(*thisobj), fval, argc, vp + 2, &rval);
-    *vp = rval;
+    bool ok = Invoke(cx, ObjectValue(*thisobj), fval, argc, vp + 2, vp);
     return ok;
 }
 
 Class CallableObjectClass = {
     "Function",
     JSCLASS_HAS_RESERVED_SLOTS(2),
     PropertyStub,         /* addProperty */
     PropertyStub,         /* delProperty */
--- a/js/src/jsreflect.cpp
+++ b/js/src/jsreflect.cpp
@@ -226,87 +226,87 @@ class NodeBuilder
 
   private:
     bool callback(Value fun, TokenPos *pos, Value *dst) {
         if (saveLoc) {
             Value loc;
             if (!newNodeLoc(pos, &loc))
                 return false;
             Value argv[] = { loc };
-            return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
+            return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
         }
 
         Value argv[] = { NullValue() }; /* no zero-length arrays allowed! */
-        return ExternalInvoke(cx, userv, fun, 0, argv, dst);
+        return Invoke(cx, userv, fun, 0, argv, dst);
     }
 
     bool callback(Value fun, Value v1, TokenPos *pos, Value *dst) {
         if (saveLoc) {
             Value loc;
             if (!newNodeLoc(pos, &loc))
                 return false;
             Value argv[] = { v1, loc };
-            return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
+            return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
         }
 
         Value argv[] = { v1 };
-        return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
+        return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
     }
 
     bool callback(Value fun, Value v1, Value v2, TokenPos *pos, Value *dst) {
         if (saveLoc) {
             Value loc;
             if (!newNodeLoc(pos, &loc))
                 return false;
             Value argv[] = { v1, v2, loc };
-            return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
+            return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
         }
 
         Value argv[] = { v1, v2 };
-        return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
+        return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
     }
 
     bool callback(Value fun, Value v1, Value v2, Value v3, TokenPos *pos, Value *dst) {
         if (saveLoc) {
             Value loc;
             if (!newNodeLoc(pos, &loc))
                 return false;
             Value argv[] = { v1, v2, v3, loc };
-            return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
+            return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
         }
 
         Value argv[] = { v1, v2, v3 };
-        return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
+        return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
     }
 
     bool callback(Value fun, Value v1, Value v2, Value v3, Value v4, TokenPos *pos, Value *dst) {
         if (saveLoc) {
             Value loc;
             if (!newNodeLoc(pos, &loc))
                 return false;
             Value argv[] = { v1, v2, v3, v4, loc };
-            return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
+            return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
         }
 
         Value argv[] = { v1, v2, v3, v4 };
-        return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
+        return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
     }
 
     bool callback(Value fun, Value v1, Value v2, Value v3, Value v4, Value v5,
                   TokenPos *pos, Value *dst) {
         if (saveLoc) {
             Value loc;
             if (!newNodeLoc(pos, &loc))
                 return false;
             Value argv[] = { v1, v2, v3, v4, v5, loc };
-            return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
+            return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
         }
 
         Value argv[] = { v1, v2, v3, v4, v5 };
-        return ExternalInvoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
+        return Invoke(cx, userv, fun, JS_ARRAY_LENGTH(argv), argv, dst);
     }
 
     Value opt(Value v) {
         JS_ASSERT_IF(v.isMagic(), v.whyMagic() == JS_SERIALIZE_NO_NODE);
         return v.isMagic(JS_SERIALIZE_NO_NODE) ? UndefinedValue() : v;
     }
 
     bool atomValue(const char *s, Value *dst) {
--- a/js/src/jsscopeinlines.h
+++ b/js/src/jsscopeinlines.h
@@ -262,17 +262,17 @@ inline bool
 Shape::get(JSContext* cx, JSObject *receiver, JSObject* obj, JSObject *pobj, js::Value* vp) const
 {
     JS_ASSERT(!JSID_IS_VOID(propid));
     JS_ASSERT(!hasDefaultGetter());
 
     if (hasGetterValue()) {
         JS_ASSERT(!isMethod());
         js::Value fval = getterValue();
-        return js::ExternalGetOrSet(cx, receiver, propid, fval, JSACC_READ, 0, 0, vp);
+        return js::InvokeGetterOrSetter(cx, receiver, fval, 0, 0, vp);
     }
 
     if (isMethod()) {
         vp->setObject(methodObject());
         return pobj->methodReadBarrier(cx, *this, vp);
     }
 
     /*
@@ -286,17 +286,17 @@ Shape::get(JSContext* cx, JSObject *rece
 
 inline bool
 Shape::set(JSContext* cx, JSObject* obj, bool strict, js::Value* vp) const
 {
     JS_ASSERT_IF(hasDefaultSetter(), hasGetterValue());
 
     if (attrs & JSPROP_SETTER) {
         js::Value fval = setterValue();
-        return js::ExternalGetOrSet(cx, obj, propid, fval, JSACC_WRITE, 1, vp, vp);
+        return js::InvokeGetterOrSetter(cx, obj, fval, 1, vp, vp);
     }
 
     if (attrs & JSPROP_GETTER)
         return js_ReportGetterOnlyAssignment(cx);
 
     /* See the comment in js::Shape::get as to why we check for With. */
     if (obj->getClass() == &js_WithClass)
         obj = js_UnwrapWithObject(cx, obj);
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -1229,17 +1229,17 @@ JSScript::NewScriptFromCG(JSContext *cx,
     }
 
     script->bindings.transfer(cx, &cg->bindings);
 
     fun = NULL;
     if (cg->inFunction()) {
         /*
          * We initialize fun->u.i.script to be the script constructed above
-         * so that the debugger has a valid FUN_SCRIPT(fun).
+         * so that the debugger has a valid fun->script().
          */
         fun = cg->fun();
         JS_ASSERT(fun->isInterpreted());
         JS_ASSERT(!fun->script());
 #ifdef DEBUG
         if (JSScript::isValidOffset(script->upvarsOffset))
             JS_ASSERT(script->upvars()->length == script->bindings.countUpvars());
         else
--- a/js/src/jsscriptinlines.h
+++ b/js/src/jsscriptinlines.h
@@ -115,17 +115,17 @@ CurrentScriptFileAndLine(JSContext *cx, 
 
 inline JSFunction *
 JSScript::getFunction(size_t index)
 {
     JSObject *funobj = getObject(index);
     JS_ASSERT(funobj->isFunction());
     JS_ASSERT(funobj == (JSObject *) funobj->getPrivate());
     JSFunction *fun = (JSFunction *) funobj;
-    JS_ASSERT(FUN_INTERPRETED(fun));
+    JS_ASSERT(fun->isInterpreted());
     return fun;
 }
 
 inline JSFunction *
 JSScript::getCallerFunction()
 {
     JS_ASSERT(savedCallerFun);
     return getFunction(0);
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -3499,17 +3499,17 @@ js_ValueToSource(JSContext *cx, const Va
     }
 
     Value rval = NullValue();
     Value fval;
     jsid id = ATOM_TO_JSID(cx->runtime->atomState.toSourceAtom);
     if (!js_GetMethod(cx, &v.toObject(), id, JSGET_NO_METHOD_BARRIER, &fval))
         return false;
     if (js_IsCallable(fval)) {
-        if (!ExternalInvoke(cx, v, fval, 0, NULL, &rval))
+        if (!Invoke(cx, v, fval, 0, NULL, &rval))
             return false;
     }
 
     return js_ValueToString(cx, rval);
 }
 
 namespace js {
 
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -2805,17 +2805,17 @@ ValueToNative(const Value &v, JSValueTyp
 
       case JSVAL_TYPE_MAGIC:
         JS_ASSERT(v.isMagic());
         debug_only_print0(LC_TMTracer, "hole ");
         return;
 
       case JSVAL_TYPE_FUNOBJ: {
         JS_ASSERT(IsFunctionObject(v));
-        JSFunction* fun = GET_FUNCTION_PRIVATE(cx, &v.toObject());
+        JSFunction* fun = v.toObject().getFunctionPrivate();
 #if defined JS_JIT_SPEW
         if (LogController.lcbits & LC_TMTracer) {
             char funName[40];
             if (fun->atom)
                 JS_PutEscapedFlatString(funName, sizeof funName, fun->atom, 0);
             else
                 strcpy(funName, "unnamed");
             LogController.printf("function<%p:%s> ", (void*)*(JSObject **)slot, funName);
@@ -3104,17 +3104,17 @@ NativeToValue(JSContext* cx, Value& v, J
         break;
       case JSVAL_TYPE_MAGIC:
         debug_only_printf(LC_TMTracer, "magic<%d> ", v.whyMagic());
         break;
       case JSVAL_TYPE_FUNOBJ:
         JS_ASSERT(IsFunctionObject(v));
 #if defined JS_JIT_SPEW
         if (LogController.lcbits & LC_TMTracer) {
-            JSFunction* fun = GET_FUNCTION_PRIVATE(cx, &v.toObject());
+            JSFunction* fun = v.toObject().getFunctionPrivate();
             char funName[40];
             if (fun->atom)
                 JS_PutEscapedFlatString(funName, sizeof funName, fun->atom, 0);
             else
                 strcpy(funName, "unnamed");
             LogController.printf("function<%p:%s> ", (void*) &v.toObject(), funName);
         }
 #endif
@@ -3380,17 +3380,17 @@ GetUpvarOnTrace(JSContext* cx, uint32 up
         FrameInfo* fi = *fip;
 
         /*
          * The loop starts aligned to the top of the stack, so move down to the first meaningful
          * callee. Then read the callee directly from the frame.
          */
         stackOffset -= fi->callerHeight;
         JSObject* callee = *(JSObject**)(&state->stackBase[stackOffset]);
-        JSFunction* fun = GET_FUNCTION_PRIVATE(cx, callee);
+        JSFunction* fun = callee->getFunctionPrivate();
         uintN calleeLevel = fun->script()->staticLevel;
         if (calleeLevel == upvarLevel) {
             /*
              * Now find the upvar's value in the native stack. stackOffset is
              * the offset of the start of the activation record corresponding
              * to *fip in the native stack.
              */
             uint32 native_slot = T::native_slot(fi->callerArgc, slot);
@@ -10536,17 +10536,17 @@ TraceRecorder::record_JSOP_LEAVEWITH()
 {
     return ARECORD_STOP;
 }
 
 static JSBool JS_FASTCALL
 functionProbe(JSContext *cx, JSFunction *fun, int enter)
 {
 #ifdef MOZ_TRACE_JSCALLS
-    JSScript *script = fun ? FUN_SCRIPT(fun) : NULL;
+    JSScript *script = fun ? fun->maybeScript() : NULL;
     if (enter > 0)
         Probes::enterJSFun(cx, fun, script, enter);
     else
         Probes::exitJSFun(cx, fun, script, enter);
 #endif
     return true;
 }
 
@@ -11006,17 +11006,17 @@ TraceRecorder::record_JSOP_OBJTOP()
     return ARECORD_CONTINUE;
 }
 
 RecordingStatus
 TraceRecorder::getClassPrototype(JSObject* ctor, LIns*& proto_ins)
 {
     // ctor must be a function created via js_InitClass.
 #ifdef DEBUG
-    Class *clasp = FUN_CLASP(GET_FUNCTION_PRIVATE(cx, ctor));
+    Class *clasp = ctor->getFunctionPrivate()->getConstructorClass();
     JS_ASSERT(clasp);
 
     TraceMonitor &localtm = *traceMonitor;
 #endif
 
     Value pval;
     if (!ctor->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom), &pval))
         RETURN_ERROR("error getting prototype from constructor");
@@ -11548,17 +11548,17 @@ TraceRecorder::callNative(uintN argc, JS
                 pendingSpecializedNative = IGNORE_NATIVE_CALL_COMPLETE_CALLBACK;
                 return RECORD_CONTINUE;
             }
         }
         break;
     }
 
     if (fun->flags & JSFUN_TRCINFO) {
-        JSNativeTraceInfo *trcinfo = FUN_TRCINFO(fun);
+        JSNativeTraceInfo *trcinfo = fun->getTraceInfo();
         JS_ASSERT(trcinfo && fun->u.n.native == trcinfo->native);
 
         /* Try to call a type specialized version of the native. */
         if (trcinfo->specializations) {
             RecordingStatus status = callSpecializedNative(trcinfo, argc, mode == JSOP_NEW);
             if (status != RECORD_STOP)
                 return status;
         }
@@ -11703,28 +11703,28 @@ TraceRecorder::functionCall(uintN argc, 
      * or JSOP_CALLPROP that callee is a *particular* function, since these hit
      * the property cache and guard on the object (this) in which the callee
      * was found. So it's sufficient to test here that the particular function
      * is interpreted, not guard on that condition.
      *
      * Bytecode sequences that push shapeless callees must guard on the callee
      * class being Function and the function being interpreted.
      */
-    JSFunction* fun = GET_FUNCTION_PRIVATE(cx, &fval.toObject());
+    JSFunction* fun = fval.toObject().getFunctionPrivate();
 
     if (Probes::callTrackingActive(cx)) {
-        JSScript *script = FUN_SCRIPT(fun);
+        JSScript *script = fun->maybeScript();
         if (!script || !script->isEmpty()) {
             LIns* args[] = { w.immi(1), w.nameImmpNonGC(fun), cx_ins };
             LIns* call_ins = w.call(&functionProbe_ci, args);
             guard(false, w.eqi0(call_ins), MISMATCH_EXIT);
         }
     }
 
-    if (FUN_INTERPRETED(fun))
+    if (fun->isInterpreted())
         return interpretedFunctionCall(fval, fun, argc, mode == JSOP_NEW);
 
     Native native = fun->maybeNative();
     Value* argv = &tval + 1;
     if (native == js_Array)
         return newArray(&fval.toObject(), argc, argv, &fval);
     if (native == js_String && argc == 1) {
         if (mode == JSOP_NEW)
@@ -13612,17 +13612,18 @@ TraceRecorder::guardCallee(Value& callee
      * after, or vice versa. The function must escape, i.e., be a "funarg", or
      * else there's no need to guard callee parent at all. So once we know (by
      * static analysis) that a function may escape, we cannot avoid guarding on
      * either the private data of the Call object or the Call object itself, if
      * we wish to optimize for the particular deactivated stack frame (null
      * private data) case as noted above.
      */
     if (callee_fun->isInterpreted() &&
-        (!FUN_NULL_CLOSURE(callee_fun) || callee_fun->script()->bindings.hasUpvars())) {
+        (!callee_fun->isNullClosure() || callee_fun->script()->bindings.hasUpvars()))
+    {
         JSObject* parent = callee_obj.getParent();
 
         if (parent != globalObj) {
             if (!parent->isCall())
                 RETURN_STOP("closure scoped by neither the global object nor a Call object");
 
             guard(true,
                   w.eqp(w.ldpObjParent(callee_ins), w.immpObjGC(parent)),
@@ -13814,18 +13815,18 @@ TraceRecorder::record_JSOP_FUNAPPLY()
 
     JS_ASSERT(!cx->fp()->hasImacropc());
 
     if (!IsFunctionObject(vp[0]))
         return record_JSOP_CALL();
     RETURN_IF_XML_A(vp[0]);
 
     JSObject* obj = &vp[0].toObject();
-    JSFunction* fun = GET_FUNCTION_PRIVATE(cx, obj);
-    if (FUN_INTERPRETED(fun))
+    JSFunction* fun = obj->getFunctionPrivate();
+    if (fun->isInterpreted())
         return record_JSOP_CALL();
 
     bool apply = fun->u.n.native == js_fun_apply;
     if (!apply && fun->u.n.native != js_fun_call)
         return record_JSOP_CALL();
 
     /*
      * We don't trace apply and call with a primitive 'this', which is the
@@ -15417,44 +15418,44 @@ TraceRecorder::getFullIndex(ptrdiff_t pc
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_JSOP_LAMBDA()
 {
     JSFunction* fun;
     fun = cx->fp()->script()->getFunction(getFullIndex());
 
-    if (FUN_NULL_CLOSURE(fun) && FUN_OBJECT(fun)->getParent() != globalObj)
+    if (fun->isNullClosure() && fun->getParent() != globalObj)
         RETURN_STOP_A("Null closure function object parent must be global object");
 
     /*
      * Emit code to clone a null closure parented by this recorder's global
      * object, in order to preserve function object evaluation rules observable
      * via identity and mutation. But don't clone if our result is consumed by
      * JSOP_SETMETHOD or JSOP_INITMETHOD, since we optimize away the clone for
      * these combinations and clone only if the "method value" escapes.
      *
      * See jsinterp.cpp, the JSOP_LAMBDA null closure case. The JSOP_SETMETHOD and
      * JSOP_INITMETHOD logic governing the early ARECORD_CONTINUE returns below
      * must agree with the corresponding break-from-do-while(0) logic there.
      */
-    if (FUN_NULL_CLOSURE(fun) && FUN_OBJECT(fun)->getParent() == &cx->fp()->scopeChain()) {
+    if (fun->isNullClosure() && fun->getParent() == &cx->fp()->scopeChain()) {
         jsbytecode *pc2 = AdvanceOverBlockchainOp(cx->regs().pc + JSOP_LAMBDA_LENGTH);
         JSOp op2 = JSOp(*pc2);
 
         if (op2 == JSOP_INITMETHOD) {
-            stack(0, w.immpObjGC(FUN_OBJECT(fun)));
+            stack(0, w.immpObjGC(fun));
             return ARECORD_CONTINUE;
         }
 
         if (op2 == JSOP_SETMETHOD) {
             Value lval = stackval(-1);
 
             if (!lval.isPrimitive() && lval.toObject().canHaveMethodBarrier()) {
-                stack(0, w.immpObjGC(FUN_OBJECT(fun)));
+                stack(0, w.immpObjGC(fun));
                 return ARECORD_CONTINUE;
             }
         } else if (fun->joinable()) {
             if (op2 == JSOP_CALL) {
                 /*
                  * Array.prototype.sort and String.prototype.replace are
                  * optimized as if they are special form. We know that they
                  * won't leak the joined function object in obj, therefore
@@ -15472,36 +15473,39 @@ TraceRecorder::record_JSOP_LAMBDA()
                 JSObject *callee;
 
                 if (IsFunctionObject(cref, &callee)) {
                     JSFunction *calleeFun = callee->getFunctionPrivate();
                     Native native = calleeFun->maybeNative();
 
                     if ((iargc == 1 && native == array_sort) ||
                         (iargc == 2 && native == str_replace)) {
-                        stack(0, w.immpObjGC(FUN_OBJECT(fun)));
+                        stack(0, w.immpObjGC(fun));
                         return ARECORD_CONTINUE;
                     }
                 }
             } else if (op2 == JSOP_NULL) {
                 pc2 += JSOP_NULL_LENGTH;
                 op2 = JSOp(*pc2);
 
                 if (op2 == JSOP_CALL && GET_ARGC(pc2) == 0) {
-                    stack(0, w.immpObjGC(FUN_OBJECT(fun)));
+                    stack(0, w.immpObjGC(fun));
                     return ARECORD_CONTINUE;
                 }
             }
         }
 
         LIns *proto_ins;
         CHECK_STATUS_A(getClassPrototype(JSProto_Function, proto_ins));
 
         LIns* args[] = { w.immpObjGC(globalObj), proto_ins, w.immpFunGC(fun), cx_ins };
         LIns* x = w.call(&js_NewNullClosure_ci, args);
+        guard(false,
+              w.name(w.eqp0(x), "guard(js_NewNullClosure_ci)"),
+              OOM_EXIT);
         stack(0, x);
         return ARECORD_CONTINUE;
     }
 
     if (GetBlockChainFast(cx, cx->fp(), JSOP_LAMBDA, JSOP_LAMBDA_LENGTH))
         RETURN_STOP_A("Unable to trace creating lambda in let");
 
     LIns *proto_ins;
@@ -15519,17 +15523,17 @@ TraceRecorder::record_JSOP_LAMBDA()
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_JSOP_LAMBDA_FC()
 {
     JSFunction* fun;
     fun = cx->fp()->script()->getFunction(getFullIndex());
 
-    if (FUN_OBJECT(fun)->getParent() != globalObj)
+    if (fun->getParent() != globalObj)
         return ARECORD_STOP;
 
     if (GetBlockChainFast(cx, cx->fp(), JSOP_LAMBDA_FC, JSOP_LAMBDA_FC_LENGTH))
         RETURN_STOP_A("Unable to trace creating lambda in let");
 
     LIns* args[] = { scopeChain(), w.immpFunGC(fun), cx_ins };
     LIns* closure_ins = w.call(&js_AllocFlatClosure_ci, args);
     guard(false,
@@ -15667,19 +15671,19 @@ TraceRecorder::record_JSOP_ARGCNT()
     }
     stack(0, w.immd(fp->numActualArgs()));
     return ARECORD_CONTINUE;
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_DefLocalFunSetSlot(uint32 slot, JSObject* obj)
 {
-    JSFunction* fun = GET_FUNCTION_PRIVATE(cx, obj);
-
-    if (FUN_NULL_CLOSURE(fun) && FUN_OBJECT(fun)->getParent() == globalObj) {
+    JSFunction* fun = obj->getFunctionPrivate();
+
+    if (fun->isNullClosure() && fun->getParent() == globalObj) {
         LIns *proto_ins;
         CHECK_STATUS_A(getClassPrototype(JSProto_Function, proto_ins));
 
         LIns* args[] = { w.immpObjGC(globalObj), proto_ins, w.immpFunGC(fun), cx_ins };
         LIns* x = w.call(&js_NewNullClosure_ci, args);
         var(slot, x);
         return ARECORD_CONTINUE;
     }
@@ -16007,17 +16011,17 @@ TraceRecorder::record_JSOP_CALLPROP()
     PCVal pcval;
     CHECK_STATUS_A(test_property_cache(obj, obj_ins, obj2, pcval));
 
     if (pcval.isNull())
         RETURN_STOP_A("callprop of missing method");
 
     if (pcval.isFunObj()) {
         if (l.isPrimitive()) {
-            JSFunction* fun = GET_FUNCTION_PRIVATE(cx, &pcval.toFunObj());
+            JSFunction* fun = pcval.toFunObj().getFunctionPrivate();
             if (fun->isInterpreted() && !fun->inStrictMode())
                 RETURN_STOP_A("callee does not accept primitive |this|");
         }
         set(&l, w.immpObjGC(&pcval.toFunObj()));
     } else {
         if (l.isPrimitive())
             RETURN_STOP_A("callprop of primitive method");
         JS_ASSERT_IF(pcval.isShape(), !pcval.toShape()->isMethod());
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -479,17 +479,17 @@ AutoCompartment::leave()
 ErrorCopier::~ErrorCopier()
 {
     JSContext *cx = ac.context;
     if (cx->compartment == ac.destination &&
         ac.origin != ac.destination &&
         cx->isExceptionPending())
     {
         Value exc = cx->getPendingException();
-        if (exc.isObject() && exc.toObject().isError()) {
+        if (exc.isObject() && exc.toObject().isError() && exc.toObject().getPrivate()) {
             cx->clearPendingException();
             ac.leave();
             JSObject *copyobj = js_CopyErrorObject(cx, &exc.toObject(), scope);
             if (copyobj)
                 cx->setPendingException(ObjectValue(*copyobj));
         }
     }
 }
--- a/js/src/jsxml.cpp
+++ b/js/src/jsxml.cpp
@@ -1638,17 +1638,17 @@ fail:
  */
 static JSBool
 GetXMLSetting(JSContext *cx, const char *name, jsval *vp)
 {
     jsval v;
 
     if (!js_FindClassObject(cx, NULL, JSProto_XML, Valueify(&v)))
         return JS_FALSE;
-    if (!VALUE_IS_FUNCTION(cx, v)) {
+    if (JSVAL_IS_PRIMITIVE(v) || !JSVAL_TO_OBJECT(v)->isFunction()) {
         *vp = JSVAL_VOID;
         return JS_TRUE;
     }
     return JS_GetProperty(cx, JSVAL_TO_OBJECT(v), name, vp);
 }
 
 static JSBool
 GetBooleanXMLSetting(JSContext *cx, const char *name, JSBool *bp)
@@ -5148,17 +5148,18 @@ JS_FRIEND_DATA(Class) js_XMLClass = {
 
 static JSXML *
 StartNonListXMLMethod(JSContext *cx, jsval *vp, JSObject **objp)
 {
     JSXML *xml;
     JSFunction *fun;
     char numBuf[12];
 
-    JS_ASSERT(VALUE_IS_FUNCTION(cx, *vp));
+    JS_ASSERT(!JSVAL_IS_PRIMITIVE(*vp));
+    JS_ASSERT(JSVAL_TO_OBJECT(*vp)->isFunction());
 
     *objp = ToObject(cx, Valueify(&vp[1]));
     if (!*objp)
         return NULL;
     if (!(*objp)->isXML()) {
         ReportIncompatibleMethod(cx, Valueify(vp), &js_XMLClass);
         return NULL;
     }
@@ -5172,17 +5173,17 @@ StartNonListXMLMethod(JSContext *cx, jsv
             *objp = js_GetXMLObject(cx, xml);
             if (!*objp)
                 return NULL;
             vp[1] = OBJECT_TO_JSVAL(*objp);
             return xml;
         }
     }
 
-    fun = GET_FUNCTION_PRIVATE(cx, JSVAL_TO_OBJECT(*vp));
+    fun = JSVAL_TO_OBJECT(*vp)->getFunctionPrivate();
     JS_snprintf(numBuf, sizeof numBuf, "%u", xml->xml_kids.length);
     JSAutoByteString funNameBytes;
     if (const char *funName = GetFunctionNameBytes(cx, fun, &funNameBytes)) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NON_LIST_XML_METHOD,
                              funName, numBuf);
     }
     return NULL;
 }
@@ -7495,17 +7496,17 @@ GetXMLFunction(JSContext *cx, JSObject *
      * See comments before xml_lookupProperty about the need for the proto
      * chain lookup.
      */
     JSObject *target = obj;
     AutoObjectRooter tvr(cx);
     for (;;) {
         if (!js_GetProperty(cx, target, id, Valueify(vp)))
             return false;
-        if (VALUE_IS_FUNCTION(cx, *vp))
+        if (!JSVAL_IS_PRIMITIVE(*vp) && JSVAL_TO_OBJECT(*vp)->isFunction())
             return true;
         target = target->getProto();
         if (target == NULL || !target->isNative())
             break;
         tvr.setObject(target);
     }
 
     JSXML *xml = (JSXML *) obj->getPrivate();
--- a/js/src/methodjit/InvokeHelpers.cpp
+++ b/js/src/methodjit/InvokeHelpers.cpp
@@ -109,16 +109,17 @@ top:
             //       But the first ops of exception handlers generated by our
             //       bytecode compiler cannot throw, so this is not possible.
             if (offset - tn->start > tn->length)
                 continue;
             if (tn->stackDepth > cx->regs().sp - fp->base())
                 continue;
 
             jsbytecode *pc = script->main + tn->start + tn->length;
+            cx->regs().pc = pc;
             JSBool ok = js_UnwindScope(cx, tn->stackDepth, JS_TRUE);
             JS_ASSERT(cx->regs().sp == fp->base() + tn->stackDepth);
 
             switch (tn->kind) {
                 case JSTRY_CATCH:
                   JS_ASSERT(js_GetOpcode(cx, fp->script(), pc) == JSOP_ENTERBLOCK);
 
 #if JS_HAS_GENERATORS
@@ -186,24 +187,24 @@ InlineReturn(VMFrame &f)
               *f.regs.pc == JSOP_FUNCALL ||
               *f.regs.pc == JSOP_FUNAPPLY);
     f.regs.pc += JSOP_CALL_LENGTH;
 }
 
 void JS_FASTCALL
 stubs::SlowCall(VMFrame &f, uint32 argc)
 {
-    if (!Invoke(f.cx, CallArgsFromSp(argc, f.regs.sp)))
+    if (!InvokeKernel(f.cx, CallArgsFromSp(argc, f.regs.sp)))
         THROW();
 }
 
 void JS_FASTCALL
 stubs::SlowNew(VMFrame &f, uint32 argc)
 {
-    if (!InvokeConstructor(f.cx, CallArgsFromSp(argc, f.regs.sp)))
+    if (!InvokeConstructorKernel(f.cx, CallArgsFromSp(argc, f.regs.sp)))
         THROW();
 }
 
 /*
  * HitStackQuota is called after the early prologue pushing the new frame would
  * overflow f.stackLimit.
  */
 void JS_FASTCALL
@@ -373,17 +374,17 @@ stubs::UncachedNewHelper(VMFrame &f, uin
     CallArgs args = CallArgsFromSp(argc, f.regs.sp);
 
     /* Try to do a fast inline call before the general Invoke path. */
     if (IsFunctionObject(args.calleev(), &ucr->fun) && ucr->fun->isInterpretedConstructor()) {
         ucr->callee = &args.callee();
         if (!UncachedInlineCall(f, CONSTRUCT, &ucr->codeAddr, &ucr->unjittable, argc))
             THROW();
     } else {
-        if (!InvokeConstructor(cx, args))
+        if (!InvokeConstructorKernel(cx, args))
             THROW();
     }
 }
 
 void * JS_FASTCALL
 stubs::UncachedCall(VMFrame &f, uint32 argc)
 {
     UncachedCallResult ucr;
@@ -392,17 +393,17 @@ stubs::UncachedCall(VMFrame &f, uint32 a
 }
 
 void JS_FASTCALL
 stubs::Eval(VMFrame &f, uint32 argc)
 {
     CallArgs args = CallArgsFromSp(argc, f.regs.sp);
 
     if (!IsBuiltinEvalForScope(&f.fp()->scopeChain(), args.calleev())) {
-        if (!Invoke(f.cx, args))
+        if (!InvokeKernel(f.cx, args))
             THROW();
         return;
     }
 
     JS_ASSERT(f.fp() == f.cx->fp());
     if (!DirectEval(f.cx, args))
         THROW();
 
@@ -414,32 +415,32 @@ stubs::UncachedCallHelper(VMFrame &f, ui
 {
     ucr->init();
 
     JSContext *cx = f.cx;
     CallArgs args = CallArgsFromSp(argc, f.regs.sp);
 
     if (IsFunctionObject(args.calleev(), &ucr->callee)) {
         ucr->callee = &args.callee();
-        ucr->fun = GET_FUNCTION_PRIVATE(cx, ucr->callee);
+        ucr->fun = ucr->callee->getFunctionPrivate();
 
         if (ucr->fun->isInterpreted()) {
             if (!UncachedInlineCall(f, NO_CONSTRUCT, &ucr->codeAddr, &ucr->unjittable, argc))
                 THROW();
             return;
         }
 
         if (ucr->fun->isNative()) {
             if (!CallJSNative(cx, ucr->fun->u.n.native, args))
                 THROW();
             return;
         }
     }
 
-    if (!Invoke(f.cx, args))
+    if (!InvokeKernel(f.cx, args))
         THROW();
 
     return;
 }
 
 void JS_FASTCALL
 stubs::PutActivationObjects(VMFrame &f)
 {
--- a/js/src/methodjit/PolyIC.cpp
+++ b/js/src/methodjit/PolyIC.cpp
@@ -553,17 +553,17 @@ class SetPropCompiler : public PICStubCo
             uintN flags = 0;
             PropertyOp getter = clasp->getProperty;
 
             if (pic.kind == ic::PICInfo::SETMETHOD) {
                 if (!obj->canHaveMethodBarrier())
                     return disable("can't have method barrier");
 
                 JSObject *funobj = &f.regs.sp[-1].toObject();
-                if (funobj != GET_FUNCTION_PRIVATE(cx, funobj))
+                if (funobj != funobj->getFunctionPrivate())
                     return disable("mismatched function");
 
                 flags |= Shape::METHOD;
                 getter = CastAsPropertyOp(funobj);
             }
 
             /*
              * Define the property but do not set it yet. For setmethod,
--- a/js/src/methodjit/StubCalls.cpp
+++ b/js/src/methodjit/StubCalls.cpp
@@ -699,19 +699,19 @@ stubs::DefFun(VMFrame &f, JSFunction *fu
     StackFrame *fp = f.fp();
 
     /*
      * A top-level function defined in Global or Eval code (see ECMA-262
      * Ed. 3), or else a SpiderMonkey extension: a named function statement in
      * a compound statement (not at the top statement level of global code, or
      * at the top level of a function body).
      */
-    JSObject *obj = FUN_OBJECT(fun);
+    JSObject *obj = fun;
 
-    if (FUN_NULL_CLOSURE(fun)) {
+    if (fun->isNullClosure()) {
         /*
          * Even a null closure needs a parent for principals finding.
          * FIXME: bug 476950, although debugger users may also demand some kind
          * of scope link for debugger-assisted eval-in-frame.
          */
         obj2 = &fp->scopeChain();
     } else {
         JS_ASSERT(!fun->isFlatClosure());
@@ -1320,20 +1320,20 @@ stubs::DefLocalFun(VMFrame &f, JSFunctio
     /*
      * Define a local function (i.e., one nested at the top level of another
      * function), parented by the current scope chain, stored in a local
      * variable slot that the compiler allocated.  This is an optimization over
      * JSOP_DEFFUN that avoids requiring a call object for the outer function's
      * activation.
      */
     JS_ASSERT(fun->isInterpreted());
-    JS_ASSERT(!FUN_FLAT_CLOSURE(fun));
-    JSObject *obj = FUN_OBJECT(fun);
+    JS_ASSERT(!fun->isFlatClosure());
+    JSObject *obj = fun;
 
-    if (FUN_NULL_CLOSURE(fun)) {
+    if (fun->isNullClosure()) {
         obj = CloneFunctionObject(f.cx, fun, &f.fp()->scopeChain());
         if (!obj)
             THROWV(NULL);
     } else {
         JSObject *parent = GetScopeChainFast(f.cx, f.fp(), JSOP_DEFLOCALFUN,
                                              JSOP_DEFLOCALFUN_LENGTH);
         if (!parent)
             THROWV(NULL);
@@ -1376,43 +1376,43 @@ stubs::RegExp(VMFrame &f, JSObject *rege
     if (!obj)
         THROWV(NULL);
     return obj;
 }
 
 JSObject * JS_FASTCALL
 stubs::LambdaForInit(VMFrame &f, JSFunction *fun)
 {
-    JSObject *obj = FUN_OBJECT(fun);
-    if (FUN_NULL_CLOSURE(fun) && obj->getParent() == &f.fp()->scopeChain()) {
+    JSObject *obj = fun;
+    if (fun->isNullClosure() && obj->getParent() == &f.fp()->scopeChain()) {
         fun->setMethodAtom(f.fp()->script()->getAtom(GET_SLOTNO(f.regs.pc)));
         return obj;
     }
     return Lambda(f, fun);
 }
 
 JSObject * JS_FASTCALL
 stubs::LambdaForSet(VMFrame &f, JSFunction *fun)
 {
-    JSObject *obj = FUN_OBJECT(fun);
-    if (FUN_NULL_CLOSURE(fun) && obj->getParent() == &f.fp()->scopeChain()) {
+    JSObject *obj = fun;
+    if (fun->isNullClosure() && obj->getParent() == &f.fp()->scopeChain()) {
         const Value &lref = f.regs.sp[-1];
         if (lref.isObject() && lref.toObject().canHaveMethodBarrier()) {
             fun->setMethodAtom(f.fp()->script()->getAtom(GET_SLOTNO(f.regs.pc)));
             return obj;
         }
     }
     return Lambda(f, fun);
 }
 
 JSObject * JS_FASTCALL
 stubs::LambdaJoinableForCall(VMFrame &f, JSFunction *fun)
 {
-    JSObject *obj = FUN_OBJECT(fun);
-    if (FUN_NULL_CLOSURE(fun) && obj->getParent() == &f.fp()->scopeChain()) {
+    JSObject *obj = fun;
+    if (fun->isNullClosure() && obj->getParent() == &f.fp()->scopeChain()) {
         /*
          * Array.prototype.sort and String.prototype.replace are
          * optimized as if they are special form. We know that they
          * won't leak the joined function object in obj, therefore
          * we don't need to clone that compiler- created function
          * object for identity/mutation reasons.
          */
         int iargc = GET_ARGC(f.regs.pc);
@@ -1438,34 +1438,34 @@ stubs::LambdaJoinableForCall(VMFrame &f,
         }
     }
     return Lambda(f, fun);
 }
 
 JSObject * JS_FASTCALL
 stubs::LambdaJoinableForNull(VMFrame &f, JSFunction *fun)
 {
-    JSObject *obj = FUN_OBJECT(fun);
-    if (FUN_NULL_CLOSURE(fun) && obj->getParent() == &f.fp()->scopeChain()) {
+    JSObject *obj = fun;
+    if (fun->isNullClosure() && obj->getParent() == &f.fp()->scopeChain()) {
         jsbytecode *pc2 = f.regs.pc + JSOP_NULL_LENGTH;
         JSOp op2 = JSOp(*pc2);
 
         if (op2 == JSOP_CALL && GET_ARGC(pc2) == 0)
             return obj;
     }
     return Lambda(f, fun);
 }
 
 JSObject * JS_FASTCALL
 stubs::Lambda(VMFrame &f, JSFunction *fun)
 {
-    JSObject *obj = FUN_OBJECT(fun);
+    JSObject *obj = fun;
 
     JSObject *parent;
-    if (FUN_NULL_CLOSURE(fun)) {
+    if (fun->isNullClosure()) {
         parent = &f.fp()->scopeChain();
     } else {
         parent = GetScopeChainFast(f.cx, f.fp(), JSOP_LAMBDA, JSOP_LAMBDA_LENGTH);
         if (!parent)
             THROWV(NULL);
     }
 
     obj = CloneFunctionObject(f.cx, fun, parent);
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -1549,25 +1549,25 @@ ValueToScript(JSContext *cx, jsval v)
         JSObject *obj = JSVAL_TO_OBJECT(v);
         JSClass *clasp = JS_GET_CLASS(cx, obj);
 
         if (clasp == Jsvalify(&js_ScriptClass)) {
             script = (JSScript *) JS_GetPrivate(cx, obj);
         } else if (clasp == Jsvalify(&js_GeneratorClass)) {
             JSGenerator *gen = (JSGenerator *) JS_GetPrivate(cx, obj);
             fun = gen->floatingFrame()->fun();
-            script = FUN_SCRIPT(fun);
+            script = fun->script();
         }
     }
 
     if (!script) {
         fun = JS_ValueToFunction(cx, v);
         if (!fun)
             return NULL;
-        script = FUN_SCRIPT(fun);
+        script = fun->maybeScript();
         if (!script) {
             JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
                                  JSSMSG_SCRIPTS_ONLY);
         }
     }
 
     return script;
 }
@@ -1987,35 +1987,35 @@ TryNotes(JSContext *cx, JSScript *script
 }
 
 static bool
 DisassembleValue(JSContext *cx, jsval v, bool lines, bool recursive, Sprinter *sp)
 {
     JSScript *script = ValueToScript(cx, v);
     if (!script)
         return false;
-    if (VALUE_IS_FUNCTION(cx, v)) {
+    if (!JSVAL_IS_PRIMITIVE(v) && JSVAL_TO_OBJECT(v)->isFunction()) {
         JSFunction *fun = JS_ValueToFunction(cx, v);
         if (fun && (fun->flags & ~7U)) {
             uint16 flags = fun->flags;
             Sprint(sp, "flags:");
 
 #define SHOW_FLAG(flag) if (flags & JSFUN_##flag) Sprint(sp, " " #flag);
 
             SHOW_FLAG(LAMBDA);
             SHOW_FLAG(HEAVYWEIGHT);
             SHOW_FLAG(EXPR_CLOSURE);
             SHOW_FLAG(TRCINFO);
 
 #undef SHOW_FLAG
 
-            if (FUN_INTERPRETED(fun)) {
-                if (FUN_NULL_CLOSURE(fun))
+            if (fun->isInterpreted()) {
+                if (fun->isNullClosure())
                     Sprint(sp, " NULL_CLOSURE");
-                else if (FUN_FLAT_CLOSURE(fun))
+                else if (fun->isFlatClosure())
                     Sprint(sp, " FLAT_CLOSURE");
 
                 JSScript *script = fun->script();
                 if (script->bindings.hasUpvars()) {
                     Sprint(sp, "\nupvars: {\n");
 
                     Vector<JSAtom *> localNames(cx);
                     if (!script->bindings.getLocalNameArray(cx, &localNames))
@@ -2693,17 +2693,17 @@ Clone(JSContext *cx, uintN argc, jsval *
         if (!JSVAL_IS_PRIMITIVE(argv[0]) &&
             JSVAL_TO_OBJECT(argv[0])->isCrossCompartmentWrapper())
         {
             JSObject *obj = JSVAL_TO_OBJECT(argv[0])->unwrap();
             if (!ac.enter(cx, obj))
                 return JS_FALSE;
             argv[0] = OBJECT_TO_JSVAL(obj);
         }
-        if (VALUE_IS_FUNCTION(cx, argv[0])) {
+        if (!JSVAL_IS_PRIMITIVE(argv[0]) && JSVAL_TO_OBJECT(argv[0])->isFunction()) {
             funobj = JSVAL_TO_OBJECT(argv[0]);
         } else {
             JSFunction *fun = JS_ValueToFunction(cx, argv[0]);
             if (!fun)
                 return JS_FALSE;
             funobj = JS_GetFunctionObject(fun);
         }
     }
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/extensions/JSON-string-replacer-overflow.js
@@ -0,0 +1,24 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+var r1 = [0, 1, 2, 3];
+Object.defineProperty(r1, (1 << 23) - 1, {});
+JSON.stringify({ 0: 0, 1: 1, 2: 2, 3: 3 }, r1)
+
+var r2 = [0, 1, 2, 3];
+Object.defineProperty(r2, (1 << 30), {});
+try
+{
+  JSON.stringify({ 0: 0, 1: 1, 2: 2, 3: 3 }, r2)
+}
+catch (e)
+{
+  assertEq(""+e, "InternalError: allocation size overflow");
+}
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);
+
+print("Tests complete");
--- a/js/src/tests/ecma_5/extensions/jstests.list
+++ b/js/src/tests/ecma_5/extensions/jstests.list
@@ -11,16 +11,17 @@ script bug496985.js
 script bug566661.js
 script array-toString-recursion.js
 skip-if(!xulRuntime.shell) script cross-global-eval-is-indirect.js # needs newGlobal()
 script eval-native-callback-is-indirect.js
 script extension-methods-reject-null-undefined-this.js
 skip-if(!xulRuntime.shell) script function-definition-with.js # needs evaluate()
 script function-properties.js
 script iterator-in-catch.js
+script JSON-string-replacer-overflow.js
 skip-if(!xulRuntime.shell) script legacy-JSON.js # needs parseLegacyJSON
 fails script nested-delete-name-in-evalcode.js # bug 604301, at a minimum
 script proxy-strict.js
 script regress-bug567606.js
 script regress-bug607284.js
 script regress-bug629723.js
 script strict-function-statements.js
 script strict-option-redeclared-parameter.js
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -515,17 +515,17 @@ Debugger::handleUncaughtException(AutoCo
 {
     JSContext *cx = ac.context;
     if (cx->isExceptionPending()) {
         if (callHook && uncaughtExceptionHook) {
             Value fval = ObjectValue(*uncaughtExceptionHook);
             Value exc = cx->getPendingException();
             Value rv;
             cx->clearPendingException();
-            if (ExternalInvoke(cx, ObjectValue(*object), fval, 1, &exc, &rv))
+            if (Invoke(cx, ObjectValue(*object), fval, 1, &exc, &rv))
                 return vp ? parseResumptionValue(ac, true, rv, vp, false) : JSTRAP_CONTINUE;
         }
 
         if (cx->isExceptionPending()) {
             JS_ReportPendingException(cx);
             cx->clearPendingException();
         }
     }
@@ -621,17 +621,17 @@ CallMethodIfPresent(JSContext *cx, JSObj
                     Value *rval)
 {
     rval->setUndefined();
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
     Value fval;
     return atom &&
            js_GetMethod(cx, obj, ATOM_TO_JSID(atom), JSGET_NO_METHOD_BARRIER, &fval) &&
            (!js_IsCallable(fval) ||
-            ExternalInvoke(cx, ObjectValue(*obj), fval, argc, argv, rval));
+            Invoke(cx, ObjectValue(*obj), fval, argc, argv, rval));
 }
 
 JSTrapStatus
 Debugger::fireDebuggerStatement(JSContext *cx, Value *vp)
 {
     JSObject *hook = getHook(OnDebuggerStatement);
     JS_ASSERT(hook);
     JS_ASSERT(hook->isCallable());
@@ -642,17 +642,17 @@ Debugger::fireDebuggerStatement(JSContex
     if (!ac.enter())
         return JSTRAP_ERROR;
 
     Value argv[1];
     if (!getScriptFrame(cx, fp, argv))
         return handleUncaughtException(ac, vp, false);
 
     Value rv;
-    bool ok = ExternalInvoke(cx, ObjectValue(*object), ObjectValue(*hook), 1, argv, &rv);
+    bool ok = Invoke(cx, ObjectValue(*object), ObjectValue(*hook), 1, argv, &rv);
     return parseResumptionValue(ac, ok, rv, vp);
 }
 
 JSTrapStatus
 Debugger::fireExceptionUnwind(JSContext *cx, Value *vp)
 {
     JSObject *hook = getHook(OnExceptionUnwind);
     JS_ASSERT(hook);
@@ -667,17 +667,17 @@ Debugger::fireExceptionUnwind(JSContext 
         return JSTRAP_ERROR;
 
     Value argv[2];
     argv[1] = exc;
     if (!getScriptFrame(cx, fp, &argv[0]) || !wrapDebuggeeValue(cx, &argv[1]))
         return handleUncaughtException(ac, vp, false);
 
     Value rv;
-    bool ok = ExternalInvoke(cx, ObjectValue(*object), ObjectValue(*hook), 2, argv, &rv);
+    bool ok = Invoke(cx, ObjectValue(*object), ObjectValue(*hook), 2, argv, &rv);
     JSTrapStatus st = parseResumptionValue(ac, ok, rv, vp);
     if (st == JSTRAP_CONTINUE)
         cx->setPendingException(exc);
     return st;
 }
 
 void
 Debugger::fireEnterFrame(JSContext *cx)
@@ -692,17 +692,17 @@ Debugger::fireEnterFrame(JSContext *cx)
         return;
 
     Value argv[1];
     if (!getScriptFrame(cx, fp, &argv[0])) {
         handleUncaughtException(ac, NULL, false);
         return;
     }
     Value rv;
-    if (!ExternalInvoke(cx, ObjectValue(*object), ObjectValue(*hook), 1, argv, &rv))
+    if (!Invoke(cx, ObjectValue(*object), ObjectValue(*hook), 1, argv, &rv))
         handleUncaughtException(ac, NULL, true);
 }
 
 void
 Debugger::fireNewScript(JSContext *cx, JSScript *script, JSObject *obj, NewScriptKind kind)
 {
     JSObject *hook = getHook(OnNewScript);
     JS_ASSERT(hook);
@@ -717,17 +717,17 @@ Debugger::fireNewScript(JSContext *cx, J
     if (!dsobj) {
         handleUncaughtException(ac, NULL, false);
         return;
     }
 
     Value argv[1];
     argv[0].setObject(*dsobj);
     Value rv;
-    if (!ExternalInvoke(cx, ObjectValue(*object), ObjectValue(*hook), 1, argv, &rv))
+    if (!Invoke(cx, ObjectValue(*object), ObjectValue(*hook), 1, argv, &rv))
         handleUncaughtException(ac, NULL, true);
 }
 
 JSTrapStatus
 Debugger::dispatchHook(JSContext *cx, js::Value *vp, Hook which)
 {
     JS_ASSERT(which == OnDebuggerStatement || which == OnExceptionUnwind);
 
@@ -2653,31 +2653,35 @@ DebuggerFrame_getLive(JSContext *cx, uin
 namespace js {
 
 JSBool
 EvaluateInScope(JSContext *cx, JSObject *scobj, 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;
+
     /*
      * 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 = Compiler::compileScript(cx, scobj, fp, fp->scopeChain().principals(cx),
                                                TCF_COMPILE_N_GO, chars, length,
                                                filename, lineno, cx->findVersion(),
                                                NULL, UpvarCookie::UPVAR_LEVEL_LIMIT);
 
     if (!script)
         return false;
 
-    bool ok = Execute(cx, script, *scobj, fp->thisValue(), EXECUTE_DEBUG, fp, rval);
+    bool ok = ExecuteKernel(cx, script, *scobj, fp->thisValue(), EXECUTE_DEBUG, fp, rval);
     js_DestroyScript(cx, script, 6);
     return ok;
 }
 
 }
 
 enum EvalBindingsMode { WithoutBindings, WithBindings };
 
@@ -2998,16 +3002,17 @@ DebuggerObject_getOwnPropertyDescriptor(
 
     /* Bug: This can cause the debuggee to run! */
     AutoPropertyDescriptorRooter desc(cx);
     {
         AutoCompartment ac(cx, obj);
         if (!ac.enter() || !cx->compartment->wrapId(cx, &id))
             return false;
 
+        ErrorCopier ec(ac, dbg->toJSObject());
         if (!GetOwnPropertyDescriptor(cx, obj, id, &desc))
             return false;
     }
 
     if (desc.obj) {
         /* Rewrap the debuggee values in desc for the debugger. */
         if (!dbg->wrapDebuggeeValue(cx, &desc.value))
             return false;
@@ -3034,16 +3039,17 @@ DebuggerObject_getOwnPropertyNames(JSCon
     THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "getOwnPropertyNames", args, dbg, obj);
 
     AutoIdVector keys(cx);
     {
         AutoCompartment ac(cx, obj);
         if (!ac.enter())
             return false;
 
+        ErrorCopier ec(ac, dbg->toJSObject());
         if (!GetPropertyNames(cx, obj, JSITER_OWNONLY | JSITER_HIDDEN, &keys))
             return false;
     }
 
     AutoValueVector vals(cx);
     if (!vals.resize(keys.length()))
         return false;
 
@@ -3372,17 +3378,17 @@ ApplyOrCall(JSContext *cx, uintN argc, V
             return false;
     }
 
     /*
      * Call the function. Use newCompletionValue to return to the debugger
      * compartment and populate args.rval().
      */
     Value rval;
-    bool ok = ExternalInvoke(cx, thisv, calleev, callArgc, callArgv, &rval);
+    bool ok = Invoke(cx, thisv, calleev, callArgc, callArgv, &rval);
     return dbg->newCompletionValue(ac, ok, rval, &args.rval());
 }
 
 static JSBool
 DebuggerObject_apply(JSContext *cx, uintN argc, Value *vp)
 {
     return ApplyOrCall(cx, argc, vp, ApplyMode);
 }
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -209,17 +209,17 @@ GlobalObject::createConstructor(JSContex
     JSFunction *fun = js_NewFunction(cx, NULL, ctor, length, JSFUN_CONSTRUCTOR, this, name);
     if (!fun)
         return NULL;
 
     /*
      * Remember the class this function is a constructor for so that we know to
      * create an object of this class when we call the constructor.
      */
-    FUN_CLASP(fun) = clasp;
+    fun->setConstructorClass(clasp);
     return fun;
 }
 
 static JSObject *
 CreateBlankProto(JSContext *cx, Class *clasp, JSObject &proto, GlobalObject &global)
 {
     JS_ASSERT(clasp != &js_ObjectClass);
     JS_ASSERT(clasp != &js_FunctionClass);
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -249,16 +249,23 @@ CallArgsFromVp(uintN argc, Value *vp)
 JS_ALWAYS_INLINE CallArgs
 CallArgsFromSp(uintN argc, Value *sp)
 {
     return CallArgsFromArgv(argc, sp - argc);
 }
 
 /*****************************************************************************/
 
+/*
+ * For calls to natives, the InvokeArgsGuard object provides a record of the
+ * call for the debugger's callstack. For this to work, the InvokeArgsGuard
+ * record needs to know when the call is actually active (because the
+ * InvokeArgsGuard can be pushed long before and popped long after the actual
+ * call, during which time many stack-observing things can happen).
+ */
 class CallArgsList : public CallArgs
 {
     friend class StackSegment;
     CallArgsList *prev_;
     bool active_;
   public:
     friend CallArgsList CallArgsListFromVp(uintN, Value *, CallArgsList *);
     friend CallArgsList CallArgsListFromArgv(uintN, Value *, CallArgsList *);
--- a/js/src/xpconnect/src/xpcwrappednativejsops.cpp
+++ b/js/src/xpconnect/src/xpcwrappednativejsops.cpp
@@ -1571,17 +1571,17 @@ XPC_WN_CallMethod(JSContext *cx, uintN a
     JSObject* funobj = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
 
     JSObject* obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
 #ifdef DEBUG_slimwrappers
     {
-        JSFunction* fun = GET_FUNCTION_PRIVATE(cx, funobj);
+        JSFunction* fun = funobj->getFunctionPrivate();
         JSString *funid = JS_GetFunctionId(fun);
         JSAutoByteString bytes;
         const char *funname = !funid ? "" : bytes.encode(cx, funid) ? bytes.ptr() : "<error>";
         SLIM_LOG_WILL_MORPH_FOR_PROP(cx, obj, funname);
     }
 #endif
     if(IS_SLIM_WRAPPER(obj) && !MorphSlimWrapper(cx, obj))
         return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx);
@@ -1610,17 +1610,17 @@ XPC_WN_GetterSetter(JSContext *cx, uintN
         return JS_FALSE;
 
 #ifdef DEBUG_slimwrappers
     {
         const char* funname = nsnull;
         JSAutoByteString bytes;
         if(JS_TypeOfValue(cx, JS_CALLEE(cx, vp)) == JSTYPE_FUNCTION)
         {
-            JSString *funid = JS_GetFunctionId(GET_FUNCTION_PRIVATE(cx, funobj));
+            JSString *funid = JS_GetFunctionId(funobj->getFunctionPrivate());
             funname = !funid ? "" : bytes.encode(cx, funid) ? bytes.ptr() : "<error>";
         }
         SLIM_LOG_WILL_MORPH_FOR_PROP(cx, obj, funname);
     }
 #endif
     if(IS_SLIM_WRAPPER(obj) && !MorphSlimWrapper(cx, obj))
         return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx);
 
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -9406,31 +9406,43 @@ SetExternalResourceIsActive(nsIDocument*
 {
   nsIPresShell* shell = aDocument->GetShell();
   if (shell) {
     shell->SetIsActive(*static_cast<PRBool*>(aClosure));
   }
   return PR_TRUE;
 }
 
+static void
+SetPluginIsActive(nsIContent* aContent, void* aClosure)
+{
+  nsIFrame *frame = aContent->GetPrimaryFrame();
+  nsIObjectFrame *objectFrame = do_QueryFrame(frame);
+  if (objectFrame) {
+    objectFrame->SetIsDocumentActive(*static_cast<PRBool*>(aClosure));
+  }
+}
+
 nsresult
 PresShell::SetIsActive(PRBool aIsActive)
 {
   NS_PRECONDITION(mDocument, "should only be called with a document");
 
   mIsActive = aIsActive;
   nsPresContext* presContext = GetPresContext();
   if (presContext &&
       presContext->RefreshDriver()->PresContext() == presContext) {
     presContext->RefreshDriver()->SetThrottled(!mIsActive);
   }
 
   // Propagate state-change to my resource documents' PresShells
   mDocument->EnumerateExternalResources(SetExternalResourceIsActive,
                                         &aIsActive);
+  mDocument->EnumerateFreezableElements(SetPluginIsActive,
+                                        &aIsActive);
   nsresult rv = UpdateImageLockingState();
 #ifdef ACCESSIBILITY
   if (aIsActive) {
     nsAccessibilityService* accService = AccService();
     if (accService) {
       accService->PresShellActivated(this);
     }
   }
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -62,17 +62,16 @@
 #include "nsIDOMHTMLTextAreaElement.h"
 #include "nsNodeInfoManager.h"
 #include "nsIURI.h"
 #include "nsGUIEvent.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsISupportsPrimitives.h"
 #include "nsAutoPtr.h"
 #include "nsPresState.h"
-#include "nsIGlobalHistory3.h"
 #include "nsDocShellCID.h"
 #include "nsIHTMLDocument.h"
 #include "nsEventDispatcher.h"
 #include "nsContentUtils.h"
 #include "nsLayoutUtils.h"
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
--- a/layout/generic/nsIObjectFrame.h
+++ b/layout/generic/nsIObjectFrame.h
@@ -89,11 +89,18 @@ public:
    * is currently active in this frame.
    */
   virtual void StopPlugin() = 0;
 
   /**
    * Get the native widget for the plugin, if any.
    */
   virtual nsIWidget* GetWidget() = 0;
+
+  /**
+   * Update plugin active state. Frame should update if it is on an active tab
+   * or not and forward that information to the plugin to make it possible to
+   * throttle down plugin instance in non active case.
+   */
+  virtual void SetIsDocumentActive(PRBool aIsActive) = 0;
 };
 
 #endif /* nsIObjectFrame_h___ */
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -2490,16 +2490,26 @@ nsObjectFrame::GetCursor(const nsPoint& 
   if (!useDOMCursor) {
     return NS_ERROR_FAILURE;
   }
 
   return nsObjectFrameSuper::GetCursor(aPoint, aCursor);
 }
 
 void
+nsObjectFrame::SetIsDocumentActive(PRBool aIsActive)
+{
+#ifndef XP_MACOSX
+  if (mInstanceOwner) {
+    mInstanceOwner->UpdateDocumentActiveState(aIsActive);
+  }
+#endif
+}
+
+void
 nsObjectFrame::NotifyContentObjectWrapper()
 {
   nsCOMPtr<nsIDocument> doc = mContent->GetDocument();
   if (!doc)
     return;
 
   nsIScriptGlobalObject *sgo = doc->GetScriptGlobalObject();
   if (!sgo)
--- a/layout/generic/nsObjectFrame.h
+++ b/layout/generic/nsObjectFrame.h
@@ -123,16 +123,17 @@ public:
 
   virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
 
   NS_METHOD GetPluginInstance(nsNPAPIPluginInstance** aPluginInstance);
   virtual nsresult Instantiate(nsIChannel* aChannel, nsIStreamListener** aStreamListener);
   virtual nsresult Instantiate(const char* aMimeType, nsIURI* aURI);
   virtual void TryNotifyContentObjectWrapper();
   virtual void StopPlugin();
+  virtual void SetIsDocumentActive(PRBool aIsActive);
 
   /*
    * Stop a plugin instance. If aDelayedStop is true, the plugin will
    * be stopped at a later point when it's safe to do so (i.e. not
    * while destroying the frame tree). Delayed stopping is only
    * implemented on Win32 for now.
    */
   void StopPluginInternal(PRBool aDelayedStop);
--- a/layout/style/nsCSSRuleProcessor.cpp
+++ b/layout/style/nsCSSRuleProcessor.cpp
@@ -1103,16 +1103,21 @@ InitSystemMetrics()
     sSystemMetrics->AppendElement(nsGkAtoms::windows_default_theme);
   }
 
   rv = lookAndFeel->GetMetric(nsILookAndFeel::eMetric_MacGraphiteTheme, metricResult);
   if (NS_SUCCEEDED(rv) && metricResult) {
     sSystemMetrics->AppendElement(nsGkAtoms::mac_graphite_theme);
   }
 
+  rv = lookAndFeel->GetMetric(nsILookAndFeel::eMetric_MacLionTheme, metricResult);
+  if (NS_SUCCEEDED(rv) && metricResult) {
+    sSystemMetrics->AppendElement(nsGkAtoms::mac_lion_theme);
+  }
+
   rv = lookAndFeel->GetMetric(nsILookAndFeel::eMetric_DWMCompositor, metricResult);
   if (NS_SUCCEEDED(rv) && metricResult) {
     sSystemMetrics->AppendElement(nsGkAtoms::windows_compositor);
   }
 
   rv = lookAndFeel->GetMetric(nsILookAndFeel::eMetric_WindowsClassic, metricResult);
   if (NS_SUCCEEDED(rv) && metricResult) {
     sSystemMetrics->AppendElement(nsGkAtoms::windows_classic);
--- a/layout/style/nsMediaFeatures.cpp
+++ b/layout/style/nsMediaFeatures.cpp
@@ -517,16 +517,23 @@ nsMediaFeatures::features[] = {
     {
         &nsGkAtoms::_moz_mac_graphite_theme,
         nsMediaFeature::eMinMaxNotAllowed,
         nsMediaFeature::eBoolInteger,
         { &nsGkAtoms::mac_graphite_theme },
         GetSystemMetric
     },
     {
+        &nsGkAtoms::_moz_mac_lion_theme,
+        nsMediaFeature::eMinMaxNotAllowed,
+        nsMediaFeature::eBoolInteger,
+        { &nsGkAtoms::mac_lion_theme },
+        GetSystemMetric
+    },
+    {
         &nsGkAtoms::_moz_windows_compositor,
         nsMediaFeature::eMinMaxNotAllowed,
         nsMediaFeature::eBoolInteger,
         { &nsGkAtoms::windows_compositor },
         GetSystemMetric
     },
     {
         &nsGkAtoms::_moz_windows_classic,
--- a/layout/style/test/test_media_queries.html
+++ b/layout/style/test/test_media_queries.html
@@ -545,72 +545,77 @@ function run() {
   expression_should_be_parseable("-moz-scrollbar-start-forward");
   expression_should_be_parseable("-moz-scrollbar-end-backward");
   expression_should_be_parseable("-moz-scrollbar-end-forward");
   expression_should_be_parseable("-moz-scrollbar-thumb-proportional");
   expression_should_be_parseable("-moz-images-in-menus");
   expression_should_be_parseable("-moz-images-in-buttons");
   expression_should_be_parseable("-moz-windows-default-theme");
   expression_should_be_parseable("-moz-mac-graphite-theme");
+  expression_should_be_parseable("-moz-mac-lion-theme");
   expression_should_be_parseable("-moz-windows-compositor");
   expression_should_be_parseable("-moz-windows-classic");
   expression_should_be_parseable("-moz-touch-enabled");
   expression_should_be_parseable("-moz-maemo-classic");
 
   expression_should_be_parseable("-moz-scrollbar-start-backward: 0");
   expression_should_be_parseable("-moz-scrollbar-start-forward: 0");
   expression_should_be_parseable("-moz-scrollbar-end-backward: 0");
   expression_should_be_parseable("-moz-scrollbar-end-forward: 0");
   expression_should_be_parseable("-moz-scrollbar-thumb-proportional: 0");
   expression_should_be_parseable("-moz-images-in-menus: 0");
   expression_should_be_parseable("-moz-images-in-buttons: 0");
   expression_should_be_parseable("-moz-windows-default-theme: 0");
   expression_should_be_parseable("-moz-mac-graphite-theme: 0");
+  expression_should_be_parseable("-moz-mac-lion-theme: 0");
   expression_should_be_parseable("-moz-windows-compositor: 0");
   expression_should_be_parseable("-moz-windows-classic: 0");
   expression_should_be_parseable("-moz-touch-enabled: 0");
   expression_should_be_parseable("-moz-maemo-classic: 0");
 
   expression_should_be_parseable("-moz-scrollbar-start-backward: 1");
   expression_should_be_parseable("-moz-scrollbar-start-forward: 1");
   expression_should_be_parseable("-moz-scrollbar-end-backward: 1");
   expression_should_be_parseable("-moz-scrollbar-end-forward: 1");
   expression_should_be_parseable("-moz-scrollbar-thumb-proportional: 1");
   expression_should_be_parseable("-moz-images-in-menus: 1");
   expression_should_be_parseable("-moz-images-in-buttons: 1");
   expression_should_be_parseable("-moz-windows-default-theme: 1");
   expression_should_be_parseable("-moz-mac-graphite-theme: 1");
+  expression_should_be_parseable("-moz-mac-lion-theme: 1");
   expression_should_be_parseable("-moz-windows-compositor: 1");
   expression_should_be_parseable("-moz-windows-classic: 1");
   expression_should_be_parseable("-moz-touch-enabled: 1");
   expression_should_be_parseable("-moz-maemo-classic: 1");
 
   expression_should_not_be_parseable("-moz-scrollbar-start-backward: -1");
   expression_should_not_be_parseable("-moz-scrollbar-start-forward: -1");
   expression_should_not_be_parseable("-moz-scrollbar-end-backward: -1");
   expression_should_not_be_parseable("-moz-scrollbar-end-forward: -1");
   expression_should_not_be_parseable("-moz-scrollbar-thumb-proportional: -1");
   expression_should_not_be_parseable("-moz-images-in-menus: -1");
   expression_should_not_be_parseable("-moz-images-in-buttons: -1");
   expression_should_not_be_parseable("-moz-windows-default-theme: -1");
   expression_should_not_be_parseable("-moz-mac-graphite-theme: -1");
+  expression_should_not_be_parseable("-moz-mac-lion-theme: -1");
   expression_should_not_be_parseable("-moz-windows-compositor: -1");
   expression_should_not_be_parseable("-moz-windows-classic: -1");
   expression_should_not_be_parseable("-moz-touch-enabled: -1");
   expression_should_not_be_parseable("-moz-maemo-classic: -1");
 
   expression_should_not_be_parseable("-moz-scrollbar-start-backward: true");
   expression_should_not_be_parseable("-moz-scrollbar-start-forward: true");
   expression_should_not_be_parseable("-moz-scrollbar-end-backward: true");
   expression_should_not_be_parseable("-moz-scrollbar-end-forward: true");
   expression_should_not_be_parseable("-moz-scrollbar-thumb-proportional: true");
   expression_should_not_be_parseable("-moz-images-in-menus: true");
   expression_should_not_be_parseable("-moz-images-in-buttons: true");
   expression_should_not_be_parseable("-moz-windows-default-theme: true");
   expression_should_not_be_parseable("-moz-mac-graphite-theme: true");
+  expression_should_not_be_parseable("-moz-mac-lion-theme: true");
   expression_should_not_be_parseable("-moz-windows-compositor: true");
   expression_should_not_be_parseable("-moz-windows-classic: true");
   expression_should_not_be_parseable("-moz-touch-enabled: true");
   expression_should_not_be_parseable("-moz-maemo-classic: true");
 
   // windows theme media queries
   expression_should_be_parseable("-moz-windows-theme: aero");
   expression_should_be_parseable("-moz-windows-theme: luna-blue");
--- a/mobile/app/mobile.js
+++ b/mobile/app/mobile.js
@@ -367,17 +367,17 @@ pref("privacy.item.syncAccount", true);
 #ifdef MOZ_PLATFORM_MAEMO
 pref("plugins.force.wmode", "opaque");
 #endif
 
 // URL to the Learn More link XXX this is the firefox one.  Bug 495578 fixes this.
 pref("browser.geolocation.warning.infoURL", "http://www.mozilla.com/%LOCALE%/firefox/geolocation/");
 
 // base url for the wifi geolocation network provider
-pref("geo.wifi.uri", "https://www.google.com/loc/json");
+pref("geo.wifi.uri", "https://maps.googleapis.com/maps/api/browserlocation/json");
 
 // enable geo
 pref("geo.enabled", true);
 
 // content sink control -- controls responsiveness during page load
 // see https://bugzilla.mozilla.org/show_bug.cgi?id=481566#c9
 pref("content.sink.enable_perf_mode",  2); // 0 - switch, 1 - interactive, 2 - perf
 pref("content.sink.pending_event_mode", 0);
--- a/mobile/chrome/content/bindings/browser.js
+++ b/mobile/chrome/content/bindings/browser.js
@@ -619,16 +619,23 @@ let ContentScroll =  {
           return;
 
         sendAsyncMessage("MozScrolledAreaChanged", {
           width: aEvent.width,
           height: aEvent.height,
           left: aEvent.x
         });
 
+        // Send event only after painting to make sure content views in the parent process have
+        // been updated.
+        addEventListener("MozAfterPaint", function afterPaint() {
+          removeEventListener("MozAfterPaint", afterPaint, false);
+          sendAsyncMessage("Content:UpdateDisplayPort");
+        }, false);
+
         break;
       }
     }
   },
 
   sendScroll: function sendScroll() {
     let scrollOffset = this.getScrollOffset(content);
     if (this._scrollOffset.x == scrollOffset.x && this._scrollOffset.y == scrollOffset.y)
--- a/mobile/chrome/content/bindings/browser.xml
+++ b/mobile/chrome/content/bindings/browser.xml
@@ -129,25 +129,34 @@
                     self.loadFavicon(json.href, json.charset);
                     break;
                   case "search":
                     self._searchEngines.push({ title: json.title, href: json.href });
                     break;
                 }
                 break;
 
-              case "MozScrolledAreaChanged":
+              case "MozScrolledAreaChanged": {
                 self._contentDocumentWidth = json.width;
                 self._contentDocumentHeight = json.height;
                 self._contentDocumentLeft = (json.left < 0) ? json.left : 0;
 
                 // Recalculate whether the visible area is actually in bounds
                 let view = self.getRootView();
                 view.scrollBy(0, 0);
                 break;
+              }
+
+              case "Content:UpdateDisplayPort": {
+                // Recalculate whether the visible area is actually in bounds
+                let view = self.getRootView();
+                view.scrollBy(0, 0);
+                view._updateCacheViewport();
+                break;
+              }
             }
           }
         })
       ]]></field>
 
       <method name="loadFavicon">
         <parameter name="aURL"/>
         <parameter name="aCharset"/>
@@ -567,16 +576,17 @@
 
           this.messageManager.loadFrameScript("chrome://browser/content/bindings/browser.js", true);
           this.messageManager.addMessageListener("DOMTitleChanged", this._messageListenerLocal);
           this.messageManager.addMessageListener("DOMLinkAdded", this._messageListenerLocal);
           this.messageManager.addMessageListener("pageshow", this._messageListenerLocal);
           this.messageManager.addMessageListener("pagehide", this._messageListenerLocal);
           this.messageManager.addMessageListener("DOMPopupBlocked", this._messageListenerLocal);
           this.messageManager.addMessageListener("MozScrolledAreaChanged", this._messageListenerLocal);
+          this.messageManager.addMessageListener("Content:UpdateDisplayPort", this._messageListenerLocal);
 
           this._webProgress._init();
 
           // Remove event listeners added by toolkit <browser> binding.
           this.removeEventListener("pageshow", this.onPageShow, true);
           this.removeEventListener("pagehide", this.onPageHide, true);
           this.removeEventListener("DOMPopupBlocked", this.onPopupBlocked, true);
         ]]>
--- a/mobile/chrome/content/browser.js
+++ b/mobile/chrome/content/browser.js
@@ -382,22 +382,16 @@ var Browser = {
     messageManager.addMessageListener("Browser:CertException", this);
     messageManager.addMessageListener("Browser:BlockedSite", this);
     messageManager.addMessageListener("Browser:ErrorPage", this);
 
     // Broadcast a UIReady message so add-ons know we are finished with startup
     let event = document.createEvent("Events");
     event.initEvent("UIReady", true, false);
     window.dispatchEvent(event);
-
-    // If we have an opener this was not the first window opened and will not
-    // receive an initial resize event. instead we fire the resize handler manually
-    // Bug 610834
-    if (window.opener)
-      resizeHandler({ target: window });
   },
 
   _alertShown: function _alertShown() {
     // ensure that the full notification still visible, even if the urlbar is floating
     if (BrowserUI.isToolbarLocked())
       Browser.pageScrollboxScroller.scrollTo(0, 0);
   },
 
--- a/mobile/chrome/content/common-ui.js
+++ b/mobile/chrome/content/common-ui.js
@@ -1338,31 +1338,51 @@ var SelectionHelper = {
     window.removeEventListener("keypress", this, true);
     Elements.browsers.removeEventListener("URLChanged", this, true);
     Elements.browsers.removeEventListener("SizeChanged", this, true);
     Elements.browsers.removeEventListener("ZoomChanged", this, true);
   },
 
   handleEvent: function handleEvent(aEvent) {
     switch (aEvent.type) {
+      case "PanBegin":
+        window.removeEventListener("PanBegin", this, true);
+        window.addEventListener("PanFinished", this, true);
+        this._start.hidden = true;
+        this._end.hidden = true;
+        break;
+      case "PanFinished":
+        window.removeEventListener("PanFinished", this, true);
+        try {
+          this.popupState.target.messageManager.sendAsyncMessage("Browser:SelectionMeasure", {});
+        } catch (e) {
+          Cu.reportError(e);
+        }
+        break
       case "TapDown":
         if (aEvent.target == this._start || aEvent.target == this._end) {
           this.target = aEvent.target;
           this.deltaX = (aEvent.clientX - this.target.left);
           this.deltaY = (aEvent.clientY - this.target.top);
           window.addEventListener("TapMove", this, true);
         } else {
-          this.hide(aEvent);
+          window.addEventListener("PanBegin", this, true);
+          this.target = null;
         }
         break;
       case "TapUp":
-        window.removeEventListener("TapMove", this, true);
-        this.target = null;
-        this.deltaX = -1;
-        this.deltaY = -1;
+        if (this.target) {
+          window.removeEventListener("TapMove", this, true);
+          this.target = null;
+          this.deltaX = -1;
+          this.deltaY = -1;
+        } else {
+          window.removeEventListener("PanBegin", self, true);
+          self.hide(aEvent);
+        }
         break;
       case "TapMove":
         if (this.target) {
           this.target.left = aEvent.clientX - this.deltaX;
           this.target.top = aEvent.clientY - this.deltaY;
           let rect = this.target.getBoundingClientRect();
           let data = this.target == this._start ? { x: rect.right, y: rect.top, type: "start" } : { x: rect.left, y: rect.top, type: "end" };
           let pos = this.popupState.target.transformClientToBrowser(data.x || 0, data.y || 0);
@@ -1370,20 +1390,28 @@ var SelectionHelper = {
             type: data.type,
             x: pos.x,
             y: pos.y
           };
           this.popupState.target.messageManager.sendAsyncMessage("Browser:SelectionMove", json);
         }
         break;
       case "resize":
-      case "keypress":
-      case "URLChanged":
       case "SizeChanged":
       case "ZoomChanged":
+      {
+        try {
+          this.popupState.target.messageManager.sendAsyncMessage("Browser:SelectionMeasure", {});
+        } catch (e) {
+          Cu.reportError(e);
+        }
+        break        
+      }
+      case "URLChanged":
+      case "keypress":
         this.hide(aEvent);
         break;
     }
   },
 
   receiveMessage: function sh_receiveMessage(aMessage) {
     let json = aMessage.json;
     switch (aMessage.name) {
--- a/mobile/chrome/content/content.js
+++ b/mobile/chrome/content/content.js
@@ -1346,63 +1346,68 @@ var SelectionHandler = {
   cache: {},
   selectedText: "",
   contentWindow: null,
   
   init: function sh_init() {
     addMessageListener("Browser:SelectionStart", this);
     addMessageListener("Browser:SelectionEnd", this);
     addMessageListener("Browser:SelectionMove", this);
+    addMessageListener("Browser:SelectionMeasure", this);
+  },
+
+  getCurrentWindowAndOffset: function(x, y, offset) {
+    let utils = Util.getWindowUtils(content);
+    let elem = utils.elementFromPoint(x, y, true, false);
+    while (elem && (elem instanceof HTMLIFrameElement || elem instanceof HTMLFrameElement)) {
+      // adjust client coordinates' origin to be top left of iframe viewport
+      let rect = elem.getBoundingClientRect();
+      scrollOffset = ContentScroll.getScrollOffset(elem.ownerDocument.defaultView);
+      offset.x += rect.left;
+      x -= rect.left;
+      
+      offset.y += rect.top + scrollOffset.y;
+      y -= rect.top + scrollOffset.y;
+      utils = elem.contentDocument.defaultView.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
+      elem = utils.elementFromPoint(x, y, true, false);
+    }
+    if (!elem)
+      return;
+    
+    return { contentWindow: elem.ownerDocument.defaultView, offset: offset };
   },
 
   receiveMessage: function sh_receiveMessage(aMessage) {
     let scrollOffset = ContentScroll.getScrollOffset(content);
     let utils = Util.getWindowUtils(content);
     let json = aMessage.json;
 
     switch (aMessage.name) {
       case "Browser:SelectionStart": {
         // Clear out the text cache
         this.selectedText = "";
 
         // if this is an iframe, dig down to find the document that was clicked
         let x = json.x - scrollOffset.x;
         let y = json.y - scrollOffset.y;
-        let offset = scrollOffset;
-        let elem = utils.elementFromPoint(x, y, true, false);
-        while (elem && (elem instanceof HTMLIFrameElement || elem instanceof HTMLFrameElement)) {
-          // adjust client coordinates' origin to be top left of iframe viewport
-          let rect = elem.getBoundingClientRect();
-          scrollOffset = ContentScroll.getScrollOffset(elem.ownerDocument.defaultView);
-          offset.x += rect.left;
-          x -= rect.left;
-
-          offset.y += rect.top + scrollOffset.y;
-          y -= rect.top + scrollOffset.y;
-          utils = elem.contentDocument.defaultView.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
-          elem = utils.elementFromPoint(x, y, true, false);
-        }
-        if (!elem)
-          return;
-
-        let contentWindow = elem.ownerDocument.defaultView;
+        let { contentWindow: contentWindow, offset: offset } = this.getCurrentWindowAndOffset(x, y, scrollOffset);
         let currentDocShell = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShell);
 
         // Remove any previous selected or created ranges. Tapping anywhere on a
         // page will create an empty range.
         let selection = contentWindow.getSelection();
         selection.removeAllRanges();
 
-        // Position the caret using a fake mouse click
-        utils.sendMouseEventToWindow("mousedown", x, y, 0, 1, 0, true);
-        utils.sendMouseEventToWindow("mouseup", x, y, 0, 1, 0, true);
+        try {
+          let caretPos = contentWindow.document.caretPositionFromPoint(json.x - scrollOffset.x, json.y - scrollOffset.y);
+          let selcon = currentDocShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsISelectionDisplay).QueryInterface(Ci.nsISelectionController);
+          let sel = selcon.getSelection(1);
+          sel.collapse(caretPos.offsetNode, caretPos.offset);
 
-        // Select the word nearest the caret
-        try {
-          let selcon = currentDocShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsISelectionDisplay).QueryInterface(Ci.nsISelectionController);
+          // Select the word nearest the caret
           selcon.wordMove(false, false);
           selcon.wordMove(true, true);
         } catch(e) {
           // If we couldn't select the word at the given point, bail
           return;
         }
 
         // Find the selected text rect and send it back so the handles can position correctly
@@ -1433,69 +1438,95 @@ var SelectionHandler = {
         let tap = { x: json.x - this.cache.offset.x, y: json.y - this.cache.offset.y };
         pointInSelection = (tap.x > this.cache.rect.left && tap.x < this.cache.rect.right) && (tap.y > this.cache.rect.top && tap.y < this.cache.rect.bottom);
 
         try {
           // The selection might already be gone
           if (this.contentWindow)
             this.contentWindow.getSelection().removeAllRanges();
           this.contentWindow = null;
-        } catch(e) {}
+        } catch(e) {
+          Cu.reportError(e);
+        }
 
         if (pointInSelection && this.selectedText.length) {
           let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
           clipboard.copyString(this.selectedText);
           sendAsyncMessage("Browser:SelectionCopied", { succeeded: true });
         } else {
           sendAsyncMessage("Browser:SelectionCopied", { succeeded: false });
         }
         break;
       }
 
       case "Browser:SelectionMove":
         if (!this.contentWindow)
           return;
 
-        // Hack to avoid setting focus in a textbox [Bugs 654352 & 667243]
-        let elemUnder = elementFromPoint(json.x - scrollOffset.x, json.y - scrollOffset.y);
-        if (elemUnder && elemUnder instanceof Ci.nsIDOMHTMLInputElement || elemUnder instanceof Ci.nsIDOMHTMLTextAreaElement)
-          return;
+        let x = json.x - scrollOffset.x;
+        let y = json.y - scrollOffset.y;
 
-        // Limit the selection to the initial content window (don't leave or enter iframes)
-        if (elemUnder && elemUnder.ownerDocument.defaultView != this.contentWindow)
-          return;
+        try {
+          let caretPos = this.contentWindow.document.caretPositionFromPoint(x, y);
+          if (caretPos.offsetNode == null ||
+              caretPos.offsetNode instanceof Ci.nsIDOMHTMLInputElement || 
+              caretPos.offsetNode instanceof Ci.nsIDOMHTMLTextAreaElement ||
+              caretPos.offsetNode.ownerDocument.defaultView != this.contentWindow)
+            return;
 
-        // Use fake mouse events to update the selection
-        if (json.type == "end") {
-          // Keep the cache in "client" coordinates, but translate for the mouse event
-          this.cache.end = { x: json.x, y: json.y };
-          let end = { x: this.cache.end.x - scrollOffset.x, y: this.cache.end.y - scrollOffset.y };
-          utils.sendMouseEventToWindow("mousedown", end.x, end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
-          utils.sendMouseEventToWindow("mouseup", end.x, end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
-        } else {
-          // Keep the cache in "client" coordinates, but translate for the mouse event
-          this.cache.start = { x: json.x, y: json.y };
-          let start = { x: this.cache.start.x - scrollOffset.x, y: this.cache.start.y - scrollOffset.y };
-          let end = { x: this.cache.end.x - scrollOffset.x, y: this.cache.end.y - scrollOffset.y };
+          // Keep the cache in "client" coordinates
+          if (json.type == "end")
+            this.cache.end = { x: json.x, y: json.y };
+          else
+            this.cache.start = { x: json.x, y: json.y };
 
-          utils.sendMouseEventToWindow("mousedown", start.x, start.y, 0, 0, 0, true);
-          utils.sendMouseEventToWindow("mouseup", start.x, start.y, 0, 0, 0, true);
-
-          utils.sendMouseEventToWindow("mousedown", end.x, end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
-          utils.sendMouseEventToWindow("mouseup", end.x, end.y, 0, 1, Ci.nsIDOMNSEvent.SHIFT_MASK, true);
+          let currentDocShell = this.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShell);
+          let selcon = currentDocShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsISelectionDisplay).QueryInterface(Ci.nsISelectionController);
+          let sel = selcon.getSelection(1);
+          if (json.type != "end") {
+            let focusOffset = sel.focusOffset;
+            let focusNode = sel.focusNode;
+            sel.collapse(caretPos.offsetNode, caretPos.offset);
+            sel.extend(focusNode, focusOffset);
+          } else {
+            sel.extend(caretPos.offsetNode, caretPos.offset);
+          }
+        } catch(e) {
+          Cu.reportError(e);
+          return;
         }
 
         // Cache the selected text since the selection might be gone by the time we get the "end" message
         let selection = this.contentWindow.getSelection()
         this.selectedText = selection.toString().trim();
 
         // Update the rect we use to test when finishing the clipboard operation
         let range = selection.getRangeAt(0).QueryInterface(Ci.nsIDOMNSRange);
         this.cache.rect = this._extractFromRange(range, this.cache.offset).rect;
         break;
+      case "Browser:SelectionMeasure": {
+        let selection = this.contentWindow.getSelection();
+        let range = selection.getRangeAt(0).QueryInterface(Ci.nsIDOMNSRange);
+        if (!range)
+          return;
+
+        // Cache the selected text since the selection might be gone by the time we get the "end" message
+        this.selectedText = selection.toString().trim();
+
+        // If the range didn't have any text, let's bail
+        if (!this.selectedText.length) {
+          selection.removeAllRanges();
+          return;
+        }
+
+        this.cache = this._extractFromRange(range, this.cache.offset);
+
+        sendAsyncMessage("Browser:SelectionRange", this.cache);
+        break;
+      }
     }
   },
 
   _extractFromRange: function sh_extractFromRange(aRange, aOffset) {
     let cache = { start: {}, end: {}, rect: { left: Number.MAX_VALUE, top: Number.MAX_VALUE, right: 0, bottom: 0 } };
     let rects = aRange.getClientRects();
     for (let i=0; i<rects.length; i++) {
       if (i == 0) {
--- a/mobile/installer/debian/fennec.aegis.in
+++ b/mobile/installer/debian/fennec.aegis.in
@@ -1,7 +1,10 @@
 <aegis>
   <request>
     <credential name="TrackerReadAccess" />
     <credential name="TrackerWriteAccess" />
+    <credential name="Location" />
+    <for path="@installdir@/@MOZ_APP_NAME@" />
+    <for path="@installdir@/plugin-container" />
   </request>
 </aegis>
 
--- a/modules/libreg/src/Makefile.in
+++ b/modules/libreg/src/Makefile.in
@@ -63,21 +63,16 @@ EXPORT_LIBRARY = 1
 
 USE_STATIC_LIBS = 1
 
 SDK_LIBRARY = $(LIBRARY)
 
 include $(topsrcdir)/config/config.mk
 
 DEFINES         += -DUSE_BUFFERED_REGISTRY_IO	
-# Memory mapped files are not supported under QNX, Neutrino, HP-UX and BeOS
-#ifeq (,$(filter BeOS HP-UX QNX,$(OS_ARCH)))
-#CSRCS		+= mmapio.c
-#DEFINES		+= -DUSE_MMAP_REGISTRY_IO
-#endif
 
 include $(topsrcdir)/config/rules.mk
 
 R_%.o: %.c
 	$(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) -DSTANDALONE_REGISTRY $<
 
 ifdef _MSC_VER
 # Don't include directives about which CRT to use
deleted file mode 100644
--- a/modules/libreg/src/mmapio.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/* ***** 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 Communicator.
- *
- * The Initial Developer of the Original Code is
- * James L. Nance.
- * Portions created by the Initial Developer are Copyright (C) 1999
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   James L. Nance <jim_nance@yahoo.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-#include <string.h>
-#include "mmapio.h"
-#include "prmem.h"
-#include "prlog.h"
-
-struct MmioFileStruct
-{
-    PRFileDesc *fd;
-    PRFileMap  *fileMap;
-    PRUint32   fsize; /* The size of the file */
-    PRUint32   msize; /* The size of the mmap()ed area */
-    PRInt32    pos;   /* Our logical position for doing I/O */
-    char       *addr; /* The base address of our mapping */
-    PRBool     needSeek; /* Do we need to seek to pos before doing a write() */
-};
-
-PRStatus mmio_FileSeek(MmioFile *mmio, PRInt32 offset, PRSeekWhence whence)
-{
-    mmio->needSeek = PR_TRUE;
-
-    switch(whence) {
-        case PR_SEEK_SET:
-            mmio->pos = offset;
-            break;
-        case PR_SEEK_END:
-            mmio->pos = mmio->fsize + offset;
-            break;
-        case PR_SEEK_CUR:
-            mmio->pos = mmio->pos + offset;
-            break;
-        default:
-            return PR_FAILURE;
-    }
-
-    if(mmio->pos<0) {
-        mmio->pos = 0;
-    }
-
-    return PR_SUCCESS;
-}
-
-PRInt32  mmio_FileRead(MmioFile *mmio, char *dest, PRInt32 count)
-{
-    static PRFileMapProtect prot = PR_PROT_READONLY;
-    static PRInt64 fsize_l;
-
-    /* First see if we are going to try and read past the end of the file
-     * and shorten count if we are.
-    */
-    if(mmio->pos+count > mmio->fsize) {
-        count = mmio->fsize - mmio->pos;
-    }
-
-    if(count<1) {
-        return 0;
-    }
-
-    /* Check to see if we need to remap for this read */
-    if(mmio->pos+count > mmio->msize) {
-        if(mmio->addr && mmio->msize) {
-            PR_ASSERT(mmio->fileMap);
-            PR_MemUnmap(mmio->addr, mmio->msize);
-            PR_CloseFileMap(mmio->fileMap);
-            mmio->addr  = NULL;
-            mmio->msize = 0;
-        }
-
-        LL_UI2L(fsize_l, mmio->fsize);
-        mmio->fileMap = PR_CreateFileMap(mmio->fd, fsize_l, prot);
-
-        if(!mmio->fileMap) {
-            return -1;
-        }
-
-        mmio->addr = PR_MemMap(mmio->fileMap, 0, fsize_l);
-
-        if(!mmio->addr) {
-            return -1;
-        }
-
-        mmio->msize = mmio->fsize;
-    }
-
-    memcpy(dest, mmio->addr+mmio->pos, count);
-
-    mmio->pos += count;
-    mmio->needSeek = PR_TRUE;
-
-    return count;
-}
-
-PRInt32  mmio_FileWrite(MmioFile *mmio, const char *src, PRInt32 count)
-{
-    PRInt32 wcode;
-
-    if(mmio->needSeek) {
-        PR_Seek(mmio->fd, mmio->pos, PR_SEEK_SET);
-        mmio->needSeek = PR_FALSE;
-    }
-
-    /* If this system does not keep mmap() and write() synchronized, we can
-    ** force it to by doing an munmap() when we do a write.  This will
-    ** obviously slow things down but fortunatly we do not do that many
-    ** writes from within mozilla.  Platforms which need this may want to
-    ** use the new USE_BUFFERED_REGISTRY_IO code instead of this code though.
-    */
-#if MMAP_MISSES_WRITES
-    if(mmio->addr && mmio->msize) {
-	PR_ASSERT(mmio->fileMap);
-	PR_MemUnmap(mmio->addr, mmio->msize);
-	PR_CloseFileMap(mmio->fileMap);
-	mmio->addr  = NULL;
-	mmio->msize = 0;
-    }
-#endif
-
-    wcode = PR_Write(mmio->fd, src, count);
-
-    if(wcode>0) {
-        mmio->pos += wcode;
-        if(mmio->pos>mmio->fsize) {
-            mmio->fsize=mmio->pos;
-        }
-    }
-
-    return wcode;
-}
-
-PRInt32  mmio_FileTell(MmioFile *mmio)
-{
-    return mmio->pos;
-}
-
-PRStatus mmio_FileClose(MmioFile *mmio)
-{
-    if(mmio->addr && mmio->msize) {
-        PR_ASSERT(mmio->fileMap);
-        PR_MemUnmap(mmio->addr, mmio->msize);
-        PR_CloseFileMap(mmio->fileMap);
-    }
-
-    PR_Close(mmio->fd);
-
-    memset(mmio, 0, sizeof(*mmio)); /* Catch people who try to keep using it */
-
-    PR_Free(mmio);
-
-    return PR_SUCCESS;
-}
-
-MmioFile *mmio_FileOpen(char *path, PRIntn flags, PRIntn mode)
-{
-    PRFileDesc *fd = PR_Open(path, flags, mode);
-    PRFileInfo info;
-    MmioFile   *mmio;
-
-    if(!fd) {
-        return NULL;
-    }
-
-    mmio = PR_MALLOC(sizeof(MmioFile));
-
-    if(!mmio || PR_FAILURE==PR_GetOpenFileInfo(fd, &info)) {
-        PR_Close(fd);
-        return NULL;
-    }
-
-    mmio->fd = fd;
-    mmio->fileMap = NULL;
-    mmio->fsize = info.size;
-    mmio->msize = 0;
-    mmio->pos   = 0;
-    mmio->addr  = NULL;
-    mmio->needSeek = PR_FALSE;
-
-    return mmio;
-}
deleted file mode 100644
--- a/modules/libreg/src/mmapio.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* ***** 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 Communicator.
- *
- * The Initial Developer of the Original Code is
- * James L. Nance.
- * Portions created by the Initial Developer are Copyright (C) 1999
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   James L. Nance <jim_nance@yahoo.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "prio.h"
-
-typedef struct MmioFileStruct MmioFile;
-
-PRStatus mmio_FileSeek(MmioFile *file, PRInt32 offset, PRSeekWhence whence);
-PRInt32  mmio_FileRead(MmioFile *file, char *dest, PRInt32 count);
-PRInt32  mmio_FileWrite(MmioFile *file, const char *src, PRInt32 count);
-PRInt32  mmio_FileTell(MmioFile *file);
-PRStatus mmio_FileClose(MmioFile *file);
-MmioFile *mmio_FileOpen(char *path, PRIntn flags, PRIntn mode);
--- a/modules/libreg/src/vr_stubs.h
+++ b/modules/libreg/src/vr_stubs.h
@@ -132,36 +132,17 @@ typedef FILE          * XP_File;
 
 #else /* not standalone, use NSPR */
 
 
 /*-------------------------------------*/
 /* Alternate fileI/O function mappings */
 /*-------------------------------------*/
 
-#if USE_MMAP_REGISTRY_IO
-  /*-----------------------------------------------*/
-  /* NSPR mememory-mapped I/O (write through)      */
-  /* unfortunately this isn't supported on the Mac */
-  /*-----------------------------------------------*/
-#define USE_NSPR_MODES
-
-#include "mmapio.h"
-#define XP_FileSeek(file,offset,whence) mmio_FileSeek((file),(offset),(whence))
-#define XP_FileRead(dest,count,file)    mmio_FileRead((file), (dest), (count))
-#define XP_FileWrite(src,count,file)    mmio_FileWrite((file), (src), (count))
-#define XP_FileTell(file)               mmio_FileTell(file)
-#define XP_FileClose(file)              mmio_FileClose(file)
-#define XP_FileOpen(path, mode)         mmio_FileOpen((path), mode )
-#define XP_FileFlush(file)              ((void)1)
-#define XP_FileSetBufferSize(file, bufsize) (-1)
-
-typedef MmioFile* XP_File;
-
-#elif USE_BUFFERED_REGISTRY_IO
+#if USE_BUFFERED_REGISTRY_IO
   /*-----------------------------------------------*/
   /* home-grown XP buffering                       */
   /* writes are buffered too so use flush!         */
   /*-----------------------------------------------*/
 #define USE_STDIO_MODES
 
 #include "nr_bufio.h"
 #define XP_FileSeek(file,offset,whence) bufio_Seek((file),(offset),(whence))
--- a/netwerk/build/Makefile.in
+++ b/netwerk/build/Makefile.in
@@ -135,16 +135,13 @@ endif
 ifdef NECKO_WIFI
 SHARED_LIBRARY_LIBS += \
   ../wifi/$(LIB_PREFIX)neckowifi_s.$(LIB_SUFFIX) \
   $(NULL)
 LOCAL_INCLUDES += -I$(srcdir)/../wifi
 
 endif
 
-
-DEFINES += -DNECKO_OFFLINE_CACHE
-
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
 
 DEFINES += -DIMPL_NS_NET
--- a/netwerk/build/nsNetModule.cpp
+++ b/netwerk/build/nsNetModule.cpp
@@ -210,21 +210,19 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsNestedA
 #ifdef NS_BUILD_REFCNT_LOGGING
 #include "nsAboutBloat.h"
 #endif
 #include "nsAboutCache.h"
 #include "nsAboutCacheEntry.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsAboutCacheEntry)
 #endif
 
-#ifdef NECKO_OFFLINE_CACHE
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsOfflineCacheDevice, nsOfflineCacheDevice::GetInstance)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsApplicationCacheNamespace)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsApplicationCache)
-#endif
 
 #ifdef NECKO_PROTOCOL_file
 // file
 #include "nsFileProtocolHandler.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsFileProtocolHandler, Init)
 #endif
 
 #ifdef NECKO_PROTOCOL_ftp
@@ -764,21 +762,19 @@ NS_DEFINE_NAMED_CID(NS_ABOUT_BLOAT_MODUL
 #endif
 NS_DEFINE_NAMED_CID(NS_ABOUT_CACHE_MODULE_CID);
 NS_DEFINE_NAMED_CID(NS_ABOUT_CACHE_ENTRY_MODULE_CID);
 #endif
 NS_DEFINE_NAMED_CID(NS_SOCKSSOCKETPROVIDER_CID);
 NS_DEFINE_NAMED_CID(NS_SOCKS4SOCKETPROVIDER_CID);
 NS_DEFINE_NAMED_CID(NS_UDPSOCKETPROVIDER_CID);
 NS_DEFINE_NAMED_CID(NS_CACHESERVICE_CID);
-#ifdef NECKO_OFFLINE_CACHE
 NS_DEFINE_NAMED_CID(NS_APPLICATIONCACHESERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_APPLICATIONCACHENAMESPACE_CID);
 NS_DEFINE_NAMED_CID(NS_APPLICATIONCACHE_CID);
-#endif
 #ifdef NECKO_COOKIES
 NS_DEFINE_NAMED_CID(NS_COOKIEMANAGER_CID);
 NS_DEFINE_NAMED_CID(NS_COOKIESERVICE_CID);
 #endif
 #ifdef NECKO_WIFI
 NS_DEFINE_NAMED_CID(NS_WIFI_MONITOR_COMPONENT_CID);
 #endif
 #ifdef NECKO_PROTOCOL_data
@@ -897,21 +893,19 @@ static const mozilla::Module::CIDEntry k
 #endif
     { &kNS_ABOUT_CACHE_MODULE_CID, false, NULL, nsAboutCache::Create },
     { &kNS_ABOUT_CACHE_ENTRY_MODULE_CID, false, NULL, nsAboutCacheEntryConstructor },
 #endif
     { &kNS_SOCKSSOCKETPROVIDER_CID, false, NULL, nsSOCKSSocketProvider::CreateV5 },
     { &kNS_SOCKS4SOCKETPROVIDER_CID, false, NULL, nsSOCKSSocketProvider::CreateV4 },
     { &kNS_UDPSOCKETPROVIDER_CID, false, NULL, nsUDPSocketProviderConstructor },
     { &kNS_CACHESERVICE_CID, false, NULL, nsCacheService::Create },
-#ifdef NECKO_OFFLINE_CACHE
     { &kNS_APPLICATIONCACHESERVICE_CID, false, NULL, nsOfflineCacheDeviceConstructor },
     { &kNS_APPLICATIONCACHENAMESPACE_CID, false, NULL, nsApplicationCacheNamespaceConstructor },
     { &kNS_APPLICATIONCACHE_CID, false, NULL, nsApplicationCacheConstructor },
-#endif
 #ifdef NECKO_COOKIES
     { &kNS_COOKIEMANAGER_CID, false, NULL, nsICookieServiceConstructor },
     { &kNS_COOKIESERVICE_CID, false, NULL, nsICookieServiceConstructor },
 #endif
 #ifdef NECKO_WIFI
     { &kNS_WIFI_MONITOR_COMPONENT_CID, false, NULL, nsWifiMonitorConstructor },
 #endif
 #ifdef NECKO_PROTOCOL_data
@@ -1039,21 +1033,19 @@ static const mozilla::Module::ContractID
 #endif
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "cache", &kNS_ABOUT_CACHE_MODULE_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "cache-entry", &kNS_ABOUT_CACHE_ENTRY_MODULE_CID },
 #endif
     { NS_NETWORK_SOCKET_CONTRACTID_PREFIX "socks", &kNS_SOCKSSOCKETPROVIDER_CID },
     { NS_NETWORK_SOCKET_CONTRACTID_PREFIX "socks4", &kNS_SOCKS4SOCKETPROVIDER_CID },
     { NS_NETWORK_SOCKET_CONTRACTID_PREFIX "udp", &kNS_UDPSOCKETPROVIDER_CID },
     { NS_CACHESERVICE_CONTRACTID, &kNS_CACHESERVICE_CID },
-#ifdef NECKO_OFFLINE_CACHE
     { NS_APPLICATIONCACHESERVICE_CONTRACTID, &kNS_APPLICATIONCACHESERVICE_CID },
     { NS_APPLICATIONCACHENAMESPACE_CONTRACTID, &kNS_APPLICATIONCACHENAMESPACE_CID },
     { NS_APPLICATIONCACHE_CONTRACTID, &kNS_APPLICATIONCACHE_CID },
-#endif
 #ifdef NECKO_COOKIES
     { NS_COOKIEMANAGER_CONTRACTID, &kNS_COOKIEMANAGER_CID },
     { NS_COOKIESERVICE_CONTRACTID, &kNS_COOKIESERVICE_CID },
 #endif
 #ifdef NECKO_WIFI
     { NS_WIFI_MONITOR_CONTRACTID, &kNS_WIFI_MONITOR_COMPONENT_CID },
 #endif
 #ifdef NECKO_PROTOCOL_data
--- a/netwerk/cache/Makefile.in
+++ b/netwerk/cache/Makefile.in
@@ -67,32 +67,25 @@ EXPORTS = \
 CPPSRCS = \
   nsCache.cpp \
   nsCacheEntry.cpp \
   nsCacheEntryDescriptor.cpp \
   nsCacheMetaData.cpp \
   nsCacheService.cpp \
   nsCacheSession.cpp \
   nsMemoryCacheDevice.cpp \
-  nsDiskCacheDeviceSQL.cpp \
-  $(NULL)
-
-ifdef NECKO_DISK_CACHE
-CPPSRCS += \
   nsDiskCacheBinding.cpp \
   nsDiskCacheBlockFile.cpp \
   nsDiskCacheDevice.cpp \
+  nsDiskCacheDeviceSQL.cpp \
   nsDiskCacheEntry.cpp \
   nsDiskCacheMap.cpp \
   nsDiskCacheStreams.cpp \
   nsDeleteDir.cpp \
   $(NULL)
-endif
-
-DEFINES += -DNECKO_OFFLINE_CACHE
 
 LOCAL_INCLUDES = \
   -I$(srcdir)/../base/src \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 DEFINES += -DIMPL_NS_NET
--- a/netwerk/cache/nsCacheService.cpp
+++ b/netwerk/cache/nsCacheService.cpp
@@ -47,20 +47,17 @@
 #include "nsCacheService.h"
 #include "nsCacheRequest.h"
 #include "nsCacheEntry.h"
 #include "nsCacheEntryDescriptor.h"
 #include "nsCacheDevice.h"
 #include "nsMemoryCacheDevice.h"
 #include "nsICacheVisitor.h"
 #include "nsDiskCacheDevice.h"
-
-#ifdef NECKO_OFFLINE_CACHE
 #include "nsDiskCacheDeviceSQL.h"
-#endif
 
 #include "nsIMemoryReporter.h"
 #include "nsIObserverService.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefBranch2.h"
 #include "nsILocalFile.h"
 #include "nsIOService.h"
@@ -107,28 +104,24 @@ using namespace mozilla;
 
 static const char * observerList[] = { 
     "profile-before-change",
     "profile-do-change",
     NS_XPCOM_SHUTDOWN_OBSERVER_ID,
     NS_PRIVATE_BROWSING_SWITCH_TOPIC
 };
 static const char * prefList[] = { 
-#ifdef NECKO_DISK_CACHE
     DISK_CACHE_ENABLE_PREF,
     DISK_CACHE_SMART_SIZE_ENABLED_PREF,
     DISK_CACHE_CAPACITY_PREF,
     DISK_CACHE_DIR_PREF,
     DISK_CACHE_MAX_ENTRY_SIZE_PREF,
-#endif
-#ifdef NECKO_OFFLINE_CACHE
     OFFLINE_CACHE_ENABLE_PREF,
     OFFLINE_CACHE_CAPACITY_PREF,
     OFFLINE_CACHE_DIR_PREF,
-#endif
     MEMORY_CACHE_ENABLE_PREF,
     MEMORY_CACHE_CAPACITY_PREF,
     MEMORY_CACHE_MAX_ENTRY_SIZE_PREF
 };
 
 // Cache sizes, in KB
 const PRInt32 DEFAULT_CACHE_SIZE = 250 * 1024;  // 250 MB
 const PRInt32 MIN_CACHE_SIZE = 50 * 1024;       //  50 MB
@@ -405,17 +398,16 @@ nsCacheProfilePrefObserver::Observe(nsIS
         // ignore pref changes until we're done switch profiles
         if (!mHaveProfile)  
             return NS_OK;
 
         nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(subject, &rv);
         if (NS_FAILED(rv))  
             return rv;
 
-#ifdef NECKO_DISK_CACHE
         // which preference changed?
         if (!strcmp(DISK_CACHE_ENABLE_PREF, data.get())) {
 
             if (!mInPrivateBrowsing) {
                 rv = branch->GetBoolPref(DISK_CACHE_ENABLE_PREF,
                                          &mDiskCacheEnabled);
                 if (NS_FAILED(rv))  
                     return rv;
@@ -473,20 +465,18 @@ nsCacheProfilePrefObserver::Observe(nsIS
           
 #if 0            
         } else if (!strcmp(DISK_CACHE_DIR_PREF, data.get())) {
             // XXX We probaby don't want to respond to this pref except after
             // XXX profile changes.  Ideally, there should be somekind of user
             // XXX notification that the pref change won't take effect until
             // XXX the next time the profile changes (browser launch)
 #endif            
-        } else 
-#endif // !NECKO_DISK_CACHE
-
-#ifdef NECKO_OFFLINE_CACHE
+        } else
+
         // which preference changed?
         if (!strcmp(OFFLINE_CACHE_ENABLE_PREF, data.get())) {
 
             if (!mInPrivateBrowsing) {
                 rv = branch->GetBoolPref(OFFLINE_CACHE_ENABLE_PREF,
                                          &mOfflineCacheEnabled);
                 if (NS_FAILED(rv))  return rv;
                 nsCacheService::SetOfflineCacheEnabled(OfflineCacheEnabled());
@@ -502,17 +492,16 @@ nsCacheProfilePrefObserver::Observe(nsIS
 #if 0
         } else if (!strcmp(OFFLINE_CACHE_DIR_PREF, data.get())) {
             // XXX We probaby don't want to respond to this pref except after
             // XXX profile changes.  Ideally, there should be some kind of user
             // XXX notification that the pref change won't take effect until
             // XXX the next time the profile changes (browser launch)
 #endif
         } else
-#endif // !NECKO_OFFLINE_CACHE
 
         if (!strcmp(MEMORY_CACHE_ENABLE_PREF, data.get())) {
 
             rv = branch->GetBoolPref(MEMORY_CACHE_ENABLE_PREF,
                                      &mMemoryCacheEnabled);
             if (NS_FAILED(rv))  
                 return rv;
             nsCacheService::SetMemoryCache();
@@ -534,49 +523,39 @@ nsCacheProfilePrefObserver::Observe(nsIS
             nsCacheService::SetMemoryCacheMaxEntrySize(mMemoryCacheMaxEntrySize);
         }
     } else if (!strcmp(NS_PRIVATE_BROWSING_SWITCH_TOPIC, topic)) {
         if (!strcmp(NS_PRIVATE_BROWSING_ENTER, data.get())) {
             mInPrivateBrowsing = PR_TRUE;
 
             nsCacheService::OnEnterExitPrivateBrowsing();
 
-#ifdef NECKO_DISK_CACHE
             mDiskCacheEnabled = PR_FALSE;
             nsCacheService::SetDiskCacheEnabled(DiskCacheEnabled());
-#endif // !NECKO_DISK_CACHE
-
-#ifdef NECKO_OFFLINE_CACHE
+
             mOfflineCacheEnabled = PR_FALSE;
             nsCacheService::SetOfflineCacheEnabled(OfflineCacheEnabled());
-#endif // !NECKO_OFFLINE_CACHE
         } else if (!strcmp(NS_PRIVATE_BROWSING_LEAVE, data.get())) {
             mInPrivateBrowsing = PR_FALSE;
 
             nsCacheService::OnEnterExitPrivateBrowsing();
 
-#if defined(NECKO_DISK_CACHE) || defined(NECKO_OFFLINE_CACHE)
             nsCOMPtr<nsIPrefBranch> branch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
             if (NS_FAILED(rv))  
                 return rv;
-#endif // !NECKO_DISK_CACHE && !NECKO_OFFLINE_CACHE
-
-#ifdef NECKO_DISK_CACHE
+
             mDiskCacheEnabled = PR_TRUE; // by default enabled
             (void) branch->GetBoolPref(DISK_CACHE_ENABLE_PREF,
                                        &mDiskCacheEnabled);
             nsCacheService::SetDiskCacheEnabled(DiskCacheEnabled());
-#endif // !NECKO_DISK_CACHE
-
-#ifdef NECKO_OFFLINE_CACHE
+
             mOfflineCacheEnabled = PR_TRUE; // by default enabled
             (void) branch->GetBoolPref(OFFLINE_CACHE_ENABLE_PREF,
                                        &mOfflineCacheEnabled);
             nsCacheService::SetOfflineCacheEnabled(OfflineCacheEnabled());
-#endif // !NECKO_OFFLINE_CACHE
         }
     }
     
     return NS_OK;
 }
 
  /* Computes our best guess for the default size of the user's disk cache, 
   * based on the amount of space they have free on their hard drive. 
@@ -669,17 +648,16 @@ nsCacheProfilePrefObserver::PermittedToS
 }
 
 
 nsresult
 nsCacheProfilePrefObserver::ReadPrefs(nsIPrefBranch* branch)
 {
     nsresult rv = NS_OK;
 
-#ifdef NECKO_DISK_CACHE
     // read disk cache device prefs
     if (!mInPrivateBrowsing) {
         mDiskCacheEnabled = PR_TRUE;  // presume disk cache is enabled
         (void) branch->GetBoolPref(DISK_CACHE_ENABLE_PREF, &mDiskCacheEnabled);
     }
 
     mDiskCacheCapacity = DISK_CACHE_CAPACITY;
     (void)branch->GetIntPref(DISK_CACHE_CAPACITY_PREF, &mDiskCacheCapacity);
@@ -765,19 +743,17 @@ nsCacheProfilePrefObserver::ReadPrefs(ns
         if (firstSmartSizeRun) {
             // It is no longer our first run
             rv = branch->SetBoolPref(DISK_CACHE_SMART_SIZE_FIRST_RUN_PREF, 
                                      PR_FALSE);
             if (NS_FAILED(rv)) 
                 NS_WARNING("Failed setting first_run pref in ReadPrefs.");
         }
     }
-#endif // !NECKO_DISK_CACHE
-
-#ifdef NECKO_OFFLINE_CACHE
+
     // read offline cache device prefs
     if (!mInPrivateBrowsing) {
         mOfflineCacheEnabled = PR_TRUE;  // presume offline cache is enabled
         (void) branch->GetBoolPref(OFFLINE_CACHE_ENABLE_PREF,
                                    &mOfflineCacheEnabled);
     }
 
     mOfflineCacheCapacity = OFFLINE_CACHE_CAPACITY;
@@ -810,18 +786,17 @@ nsCacheProfilePrefObserver::ReadPrefs(ns
             // use current process directory during development
             rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
                                         getter_AddRefs(directory));
         }
 #endif
         if (directory)
             mOfflineCacheParentDirectory = do_QueryInterface(directory, &rv);
     }
-#endif // !NECKO_OFFLINE_CACHE
-    
+
     // read memory cache device prefs
     (void) branch->GetBoolPref(MEMORY_CACHE_ENABLE_PREF, &mMemoryCacheEnabled);
 
     mMemoryCacheCapacity = -1;
     (void) branch->GetIntPref(MEMORY_CACHE_CAPACITY_PREF,
                               &mMemoryCacheCapacity);
 
     (void) branch->GetIntPref(MEMORY_CACHE_MAX_ENTRY_SIZE_PREF,
@@ -1116,26 +1091,22 @@ nsCacheService::Shutdown()
         // to be safe
         NS_UnregisterMemoryReporter(MemoryCacheReporter);
         MemoryCacheReporter = nsnull;
 
         // deallocate memory and disk caches
         delete mMemoryDevice;
         mMemoryDevice = nsnull;
 
-#ifdef NECKO_DISK_CACHE
         delete mDiskDevice;
         mDiskDevice = nsnull;
-#endif // !NECKO_DISK_CACHE
-
-#ifdef NECKO_OFFLINE_CACHE
+
         NS_IF_RELEASE(mOfflineDevice);
-#endif // !NECKO_OFFLINE_CACHE
-
-#if defined(NECKO_DISK_CACHE) && defined(PR_LOGGING)
+
+#ifdef PR_LOGGING
         LogCacheStatistics();
 #endif
 
         mCacheIOThread.swap(cacheIOThread);
     }
     } // lock
 
     if (cacheIOThread)
@@ -1216,44 +1187,40 @@ nsCacheService::EvictEntriesForClient(co
                                       NS_CACHESERVICE_EMPTYCACHE_TOPIC_ID,
                                       nsnull);
         }
     }
 
     nsCacheServiceAutoLock lock;
     nsresult res = NS_OK;
 
-#ifdef NECKO_DISK_CACHE
     if (storagePolicy == nsICache::STORE_ANYWHERE ||
         storagePolicy == nsICache::STORE_ON_DISK) {
 
         if (mEnableDiskDevice) {
             nsresult rv;
             if (!mDiskDevice)
                 rv = CreateDiskDevice();
             if (mDiskDevice)
                 rv = mDiskDevice->EvictEntries(clientID);
             if (NS_FAILED(rv)) res = rv;
         }
     }
-#endif // ! NECKO_DISK_CACHE
-
-#ifdef NECKO_OFFLINE_CACHE
+
     // Only clear the offline cache if it has been specifically asked for.
     if (storagePolicy == nsICache::STORE_OFFLINE) {
         if (mEnableOfflineDevice) {
             nsresult rv;
             if (!mOfflineDevice)
                 rv = CreateOfflineDevice();
             if (mOfflineDevice)
                 rv = mOfflineDevice->EvictEntries(clientID);
             if (NS_FAILED(rv)) res = rv;
         }
     }
-#endif // ! NECKO_OFFLINE_CACHE
 
     if (storagePolicy == nsICache::STORE_ANYWHERE ||
         storagePolicy == nsICache::STORE_IN_MEMORY) {
 
         // If there is no memory device, there is no need to evict it...
         if (mMemoryDevice) {
             nsresult rv;
             rv = mMemoryDevice->EvictEntries(clientID);
@@ -1313,37 +1280,33 @@ NS_IMETHODIMP nsCacheService::VisitEntri
     
     nsresult rv = NS_OK;
     // If there is no memory device, there are then also no entries to visit...
     if (mMemoryDevice) {
         rv = mMemoryDevice->Visit(visitor);
         if (NS_FAILED(rv)) return rv;
     }
 
-#ifdef NECKO_DISK_CACHE
     if (mEnableDiskDevice) {
         if (!mDiskDevice) {
             rv = CreateDiskDevice();
             if (NS_FAILED(rv)) return rv;
         }
         rv = mDiskDevice->Visit(visitor);
         if (NS_FAILED(rv)) return rv;
     }
-#endif // !NECKO_DISK_CACHE
-
-#ifdef NECKO_OFFLINE_CACHE
+
     if (mEnableOfflineDevice) {
         if (!mOfflineDevice) {
             rv = CreateOfflineDevice();
             if (NS_FAILED(rv)) return rv;
         }
         rv = mOfflineDevice->Visit(visitor);
         if (NS_FAILED(rv)) return rv;
     }
-#endif // !NECKO_OFFLINE_CACHE
 
     // XXX notify any shutdown process that visitation is complete for THIS visitor.
     // XXX keep queue of visitors
 
     return NS_OK;
 }
 
 
@@ -1364,17 +1327,16 @@ NS_IMETHODIMP nsCacheService::GetCacheIO
 }
 
 /**
  * Internal Methods
  */
 nsresult
 nsCacheService::CreateDiskDevice()
 {
-#ifdef NECKO_DISK_CACHE
     if (!mInitialized)      return NS_ERROR_NOT_AVAILABLE;
     if (!mEnableDiskDevice) return NS_ERROR_NOT_AVAILABLE;
     if (mDiskDevice)        return NS_OK;
 
     mDiskDevice = new nsDiskCacheDevice;
     if (!mDiskDevice)       return NS_ERROR_OUT_OF_MEMORY;
 
     // set the preferences
@@ -1390,26 +1352,21 @@ nsCacheService::CreateDiskDevice()
         printf("###    - disabling disk cache for this session.\n");
         printf("###\n");
 #endif        
         mEnableDiskDevice = PR_FALSE;
         delete mDiskDevice;
         mDiskDevice = nsnull;
     }
     return rv;
-#else // !NECKO_DISK_CACHE
-    NS_NOTREACHED("nsCacheService::CreateDiskDevice");
-    return NS_ERROR_NOT_IMPLEMENTED;
-#endif
 }
 
 nsresult
 nsCacheService::CreateOfflineDevice()
 {
-#ifdef NECKO_OFFLINE_CACHE
     CACHE_LOG_ALWAYS(("Creating offline device"));
 
     if (!mInitialized)         return NS_ERROR_NOT_AVAILABLE;
     if (!mEnableOfflineDevice) return NS_ERROR_NOT_AVAILABLE;
     if (mOfflineDevice)        return NS_OK;
 
     mOfflineDevice = new nsOfflineCacheDevice;
     if (!mOfflineDevice)       return NS_ERROR_OUT_OF_MEMORY;
@@ -1425,20 +1382,16 @@ nsCacheService::CreateOfflineDevice()
     if (NS_FAILED(rv)) {
         CACHE_LOG_DEBUG(("mOfflineDevice->Init() failed (0x%.8x)\n", rv));
         CACHE_LOG_DEBUG(("    - disabling offline cache for this session.\n"));
 
         mEnableOfflineDevice = PR_FALSE;
         NS_RELEASE(mOfflineDevice);
     }
     return rv;
-#else // !NECKO_DISK_CACHE
-    NS_NOTREACHED("nsCacheService::CreateOfflineDevice");
-    return NS_ERROR_NOT_IMPLEMENTED;
-#endif
 }
 
 nsresult
 nsCacheService::CreateMemoryDevice()
 {
     if (!mInitialized)        return NS_ERROR_NOT_AVAILABLE;
     if (!mEnableMemoryDevice) return NS_ERROR_NOT_AVAILABLE;
     if (mMemoryDevice)        return NS_OK;
@@ -1815,60 +1768,55 @@ nsCacheService::SearchCacheDevices(nsCSt
             CACHE_LOG_DEBUG(("Searching mMemoryDevice for key %s found: 0x%p, "
                              "collision: %d\n", key->get(), entry, collision));
         }
     }
 
     if (!entry && 
         ((policy == nsICache::STORE_ANYWHERE) || (policy == nsICache::STORE_ON_DISK))) {
 
-#ifdef NECKO_DISK_CACHE
         if (mEnableDiskDevice) {
             if (!mDiskDevice) {
                 nsresult rv = CreateDiskDevice();
                 if (NS_FAILED(rv))
                     return nsnull;
             }
             
             entry = mDiskDevice->FindEntry(key, collision);
         }
-#endif // !NECKO_DISK_CACHE
     }
 
     if (!entry && (policy == nsICache::STORE_OFFLINE ||
                    (policy == nsICache::STORE_ANYWHERE &&
                     gIOService->IsOffline()))) {
 
-#ifdef NECKO_OFFLINE_CACHE
         if (mEnableOfflineDevice) {
             if (!mOfflineDevice) {
                 nsresult rv = CreateOfflineDevice();
                 if (NS_FAILED(rv))
                     return nsnull;
             }
 
             entry = mOfflineDevice->FindEntry(key, collision);
         }
-#endif // !NECKO_OFFLINE_CACHE
     }
 
     return entry;
 }
 
 
 nsCacheDevice *
 nsCacheService::EnsureEntryHasDevice(nsCacheEntry * entry)
 {
     nsCacheDevice * device = entry->CacheDevice();
     // return device if found, possibly null if the entry is doomed i.e prevent
     // doomed entries to bind to a device (see e.g. bugs #548406 and #596443)
     if (device || entry->IsDoomed())  return device;
 
     PRInt64 predictedDataSize = entry->PredictedDataSize();
-#ifdef NECKO_DISK_CACHE
     if (entry->IsStreamData() && entry->IsAllowedOnDisk() && mEnableDiskDevice) {
         // this is the default
         if (!mDiskDevice) {
             (void)CreateDiskDevice();  // ignore the error (check for mDiskDevice instead)
         }
 
         if (mDiskDevice) {
             // Bypass the cache if Content-Length says the entry will be too big
@@ -1882,17 +1830,16 @@ nsCacheService::EnsureEntryHasDevice(nsC
 
             entry->MarkBinding();  // enter state of binding
             nsresult rv = mDiskDevice->BindEntry(entry);
             entry->ClearBinding(); // exit state of binding
             if (NS_SUCCEEDED(rv))
                 device = mDiskDevice;
         }
     }
-#endif // !NECKO_DISK_CACHE
 
     // if we can't use mDiskDevice, try mMemoryDevice
     if (!device && mEnableMemoryDevice && entry->IsAllowedInMemory()) {        
         if (!mMemoryDevice) {
             (void)CreateMemoryDevice();  // ignore the error (check for mMemoryDevice instead)
         }
         if (mMemoryDevice) {
             // Bypass the cache if Content-Length says entry will be too big
@@ -1906,32 +1853,30 @@ nsCacheService::EnsureEntryHasDevice(nsC
             entry->MarkBinding();  // enter state of binding
             nsresult rv = mMemoryDevice->BindEntry(entry);
             entry->ClearBinding(); // exit state of binding
             if (NS_SUCCEEDED(rv))
                 device = mMemoryDevice;
         }
     }
 
-#ifdef NECKO_OFFLINE_CACHE
     if (!device && entry->IsStreamData() &&
         entry->IsAllowedOffline() && mEnableOfflineDevice) {
         if (!mOfflineDevice) {
             (void)CreateOfflineDevice(); // ignore the error (check for mOfflineDevice instead)
         }
 
         if (mOfflineDevice) {
             entry->MarkBinding();
             nsresult rv = mOfflineDevice->BindEntry(entry);
             entry->ClearBinding();
             if (NS_SUCCEEDED(rv))
                 device = mOfflineDevice;
         }
     }
-#endif // ! NECKO_OFFLINE_CACHE
 
     if (device) 
         entry->SetCacheDevice(device);
     return device;
 }
 
 PRInt64
 nsCacheService::MemoryDeviceSize()
@@ -1999,35 +1944,31 @@ nsCacheService::OnProfileShutdown(PRBool
 
     gService->DoomActiveEntries();
     gService->ClearDoomList();
 
     // Make sure to wait for any pending cache-operations before
     // proceeding with destructive actions (bug #620660)
     (void) SyncWithCacheIOThread();
 
-#ifdef NECKO_DISK_CACHE
     if (gService->mDiskDevice && gService->mEnableDiskDevice) {
         if (cleanse)
             gService->mDiskDevice->EvictEntries(nsnull);
 
         gService->mDiskDevice->Shutdown();
     }
     gService->mEnableDiskDevice = PR_FALSE;
-#endif // !NECKO_DISK_CACHE
-
-#ifdef NECKO_OFFLINE_CACHE
+
     if (gService->mOfflineDevice && gService->mEnableOfflineDevice) {
         if (cleanse)
             gService->mOfflineDevice->EvictEntries(nsnull);
 
         gService->mOfflineDevice->Shutdown();
     }
     gService->mEnableOfflineDevice = PR_FALSE;
-#endif // !NECKO_OFFLINE_CACHE
 
     if (gService->mMemoryDevice) {
         // clear memory cache
         gService->mMemoryDevice->EvictEntries(nsnull);
     }
 
 }
 
@@ -2040,46 +1981,42 @@ nsCacheService::OnProfileChanged()
     CACHE_LOG_DEBUG(("nsCacheService::OnProfileChanged"));
  
     nsCacheServiceAutoLock lock;
     
     gService->mEnableDiskDevice    = gService->mObserver->DiskCacheEnabled();
     gService->mEnableOfflineDevice = gService->mObserver->OfflineCacheEnabled();
     gService->mEnableMemoryDevice  = gService->mObserver->MemoryCacheEnabled();
 
-#ifdef NECKO_DISK_CACHE
     if (gService->mDiskDevice) {
         gService->mDiskDevice->SetCacheParentDirectory(gService->mObserver->DiskCacheParentDirectory());
         gService->mDiskDevice->SetCapacity(gService->mObserver->DiskCacheCapacity());
 
         // XXX initialization of mDiskDevice could be made lazily, if mEnableDiskDevice is false
         nsresult rv = gService->mDiskDevice->Init();
         if (NS_FAILED(rv)) {
             NS_ERROR("nsCacheService::OnProfileChanged: Re-initializing disk device failed");
             gService->mEnableDiskDevice = PR_FALSE;
             // XXX delete mDiskDevice?
         }
     }
-#endif // !NECKO_DISK_CACHE
-
-#ifdef NECKO_OFFLINE_CACHE
+
     if (gService->mOfflineDevice) {
         gService->mOfflineDevice->SetCacheParentDirectory(gService->mObserver->OfflineCacheParentDirectory());
         gService->mOfflineDevice->SetCapacity(gService->mObserver->OfflineCacheCapacity());
 
         // XXX initialization of mOfflineDevice could be made lazily, if mEnableOfflineDevice is false
         nsresult rv = gService->mOfflineDevice->Init();
         if (NS_FAILED(rv)) {
             NS_ERROR("nsCacheService::OnProfileChanged: Re-initializing offline device failed");
             gService->mEnableOfflineDevice = PR_FALSE;
             // XXX delete mOfflineDevice?
         }
     }
-#endif // !NECKO_OFFLINE_CACHE
-    
+
     // If memoryDevice exists, reset its size to the new profile
     if (gService->mMemoryDevice) {
         if (gService->mEnableMemoryDevice) {
             // make sure that capacity is reset to the right value
             PRInt32 capacity = gService->mObserver->MemoryCacheCapacity();
             CACHE_LOG_DEBUG(("Resetting memory device capacity to %d\n",
                              capacity));
             gService->mMemoryDevice->SetCapacity(capacity);
@@ -2103,37 +2040,33 @@ nsCacheService::SetDiskCacheEnabled(PRBo
 
 
 void
 nsCacheService::SetDiskCacheCapacity(PRInt32  capacity)
 {
     if (!gService)  return;
     nsCacheServiceAutoLock lock;
 
-#ifdef NECKO_DISK_CACHE
     if (gService->mDiskDevice) {
         gService->mDiskDevice->SetCapacity(capacity);
     }
-#endif // !NECKO_DISK_CACHE
-    
+
     if (gService->mObserver)
         gService->mEnableDiskDevice = gService->mObserver->DiskCacheEnabled();
 }
 
 void
 nsCacheService::SetDiskCacheMaxEntrySize(PRInt32  maxSize)
 {
     if (!gService)  return;
     nsCacheServiceAutoLock lock;
 
-#ifdef NECKO_DISK_CACHE
     if (gService->mDiskDevice) {
         gService->mDiskDevice->SetMaxEntrySize(maxSize);
     }
-#endif // !NECKO_DISK_CACHE
 }
 
 void
 nsCacheService::SetMemoryCacheMaxEntrySize(PRInt32  maxSize)
 {
     if (!gService)  return;
     nsCacheServiceAutoLock lock;
 
@@ -2151,21 +2084,19 @@ nsCacheService::SetOfflineCacheEnabled(P
 }
 
 void
 nsCacheService::SetOfflineCacheCapacity(PRInt32  capacity)
 {
     if (!gService)  return;
     nsCacheServiceAutoLock lock;
 
-#ifdef NECKO_OFFLINE_CACHE
     if (gService->mOfflineDevice) {
         gService->mOfflineDevice->SetCapacity(capacity);
     }
-#endif // !NECKO_OFFLINE_CACHE
 
     gService->mEnableOfflineDevice = gService->mObserver->OfflineCacheEnabled();
 }
 
 
 void
 nsCacheService::SetMemoryCache()
 {
--- a/netwerk/necko-config.h.in
+++ b/netwerk/necko-config.h.in
@@ -32,18 +32,16 @@
  * 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 _NECKO_CONFIG_H_
 #define _NECKO_CONFIG_H_
 
-#undef NECKO_DISK_CACHE
-
 #undef NECKO_COOKIES
 
 #undef NECKO_WIFI
 
 #undef NECKO_PROTOCOL_about
 #undef NECKO_PROTOCOL_data
 #undef NECKO_PROTOCOL_device
 #undef NECKO_PROTOCOL_file
--- a/other-licenses/android/APKOpen.cpp
+++ b/other-licenses/android/APKOpen.cpp
@@ -228,16 +228,17 @@ extern "C" NS_EXPORT void JNICALL \
 Java_org_mozilla_gecko_GeckoAppShell_ ## name(JNIEnv *jenv, jclass jc, type1 one, type2 two, type3 three) \
 { \
   f_ ## name(jenv, jc, one, two, three); \
 }
 
 SHELL_WRAPPER0(nativeInit)
 SHELL_WRAPPER1(nativeRun, jstring)
 SHELL_WRAPPER1(notifyGeckoOfEvent, jobject)
+SHELL_WRAPPER0(processNextNativeEvent)
 SHELL_WRAPPER1(setSurfaceView, jobject)
 SHELL_WRAPPER0(onResume)
 SHELL_WRAPPER0(onLowMemory)
 SHELL_WRAPPER3(callObserver, jstring, jstring, jstring)
 SHELL_WRAPPER1(removeObserver, jstring)
 SHELL_WRAPPER2(onChangeNetworkLinkStatus, jstring, jstring)
 SHELL_WRAPPER1(reportJavaCrash, jstring)
 
@@ -671,16 +672,17 @@ loadLibs(const char *apkName)
 
   if (!xul_handle)
     __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't get a handle to libxul!");
 
 #define GETFUNC(name) f_ ## name = (name ## _t) __wrap_dlsym(xul_handle, "Java_org_mozilla_gecko_GeckoAppShell_" #name)
   GETFUNC(nativeInit);
   GETFUNC(nativeRun);
   GETFUNC(notifyGeckoOfEvent);
+  GETFUNC(processNextNativeEvent);
   GETFUNC(setSurfaceView);
   GETFUNC(onResume);
   GETFUNC(onLowMemory);
   GETFUNC(callObserver);
   GETFUNC(removeObserver);
   GETFUNC(onChangeNetworkLinkStatus);
   GETFUNC(reportJavaCrash);
 #undef GETFUNC
--- a/security/manager/pki/resources/content/viewCertDetails.js
+++ b/security/manager/pki/resources/content/viewCertDetails.js
@@ -254,17 +254,17 @@ function DisplayVerificationData(cert, r
   } else if (verifystate == cert.ISSUER_UNKNOWN) {
     verifystr = bundle.GetStringFromName('certNotVerified_IssuerUnknown');
   } else if (verifystate == cert.INVALID_CA) {
     verifystr = bundle.GetStringFromName('certNotVerified_CAInvalid');
   } else { /* if (verifystate == cert.NOT_VERIFIED_UNKNOWN || == USAGE_NOT_ALLOWED) */
     verifystr = bundle.GetStringFromName('certNotVerified_Unknown');
   }
   var verified=document.getElementById('verified');
-  verified.setAttribute("value", verifystr);
+  verified.textContent = verifystr;
   if (count > 0) {
     var verifyInfoBox = document.getElementById('verify_info_box');
     for (var i=0; i<count; i++) {
       AddUsage(usageList[i],verifyInfoBox);
     }
   }
 }
 
--- a/storage/test/test_file_perms.cpp
+++ b/storage/test/test_file_perms.cpp
@@ -44,18 +44,17 @@
  * This file tests that the file permissions of the sqlite files match what
  * we request they be
  */
 
 void
 test_file_perms()
 {
   nsCOMPtr<nsIFile> profDir;
-  nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
-                                       getter_AddRefs(profDir));
+  (void)NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(profDir));
   nsCOMPtr<nsILocalFile> sqlite_file = do_QueryInterface(profDir);
   sqlite_file->Append(NS_LITERAL_STRING("places.sqlite"));
   PRUint32 perms = 0;
   sqlite_file->GetPermissions(&perms);
 
   // This reflexts the permissions defined by SQLITE_DEFAULT_FILE_PERMISSIONS in
   // db/sqlite3/src/Makefile.in and must be kept in sync with that
 #ifdef ANDROID
--- a/toolkit/components/places/PlacesUtils.jsm
+++ b/toolkit/components/places/PlacesUtils.jsm
@@ -2161,20 +2161,16 @@ XPCOMUtils.defineLazyServiceGetter(Place
 XPCOMUtils.defineLazyGetter(PlacesUtils, "bhistory", function() {
   return PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory);
 });
 
 XPCOMUtils.defineLazyGetter(PlacesUtils, "ghistory2", function() {
   return PlacesUtils.history.QueryInterface(Ci.nsIGlobalHistory2);
 });
 
-XPCOMUtils.defineLazyGetter(PlacesUtils, "ghistory3", function() {
-  return PlacesUtils.history.QueryInterface(Ci.nsIGlobalHistory3);
-});
-
 XPCOMUtils.defineLazyServiceGetter(PlacesUtils, "favicons",
                                    "@mozilla.org/browser/favicon-service;1",
                                    "nsIFaviconService");
 
 XPCOMUtils.defineLazyServiceGetter(PlacesUtils, "bookmarks",
                                    "@mozilla.org/browser/nav-bookmarks-service;1",
                                    "nsINavBookmarksService");
 
--- a/toolkit/components/places/nsNavHistory.cpp
+++ b/toolkit/components/places/nsNavHistory.cpp
@@ -207,35 +207,33 @@ static const PRInt64 USECS_PER_DAY = LL_
 
 NS_IMPL_THREADSAFE_ADDREF(nsNavHistory)
 NS_IMPL_THREADSAFE_RELEASE(nsNavHistory)
 
 NS_IMPL_CLASSINFO(nsNavHistory, NULL, nsIClassInfo::SINGLETON,
                   NS_NAVHISTORYSERVICE_CID)
 NS_INTERFACE_MAP_BEGIN(nsNavHistory)
   NS_INTERFACE_MAP_ENTRY(nsINavHistoryService)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIGlobalHistory2, nsIGlobalHistory3)
-  NS_INTERFACE_MAP_ENTRY(nsIGlobalHistory3)
+  NS_INTERFACE_MAP_ENTRY(nsIGlobalHistory2)
   NS_INTERFACE_MAP_ENTRY(nsIDownloadHistory)
   NS_INTERFACE_MAP_ENTRY(nsIBrowserHistory)
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY(nsICharsetResolver)
   NS_INTERFACE_MAP_ENTRY(nsPIPlacesDatabase)
   NS_INTERFACE_MAP_ENTRY(nsPIPlacesHistoryListenersNotifier)
   NS_INTERFACE_MAP_ENTRY(mozIStorageVacuumParticipant)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsINavHistoryService)
   NS_IMPL_QUERY_CLASSINFO(nsNavHistory)
 NS_INTERFACE_MAP_END
 
 // We don't care about flattening everything
-NS_IMPL_CI_INTERFACE_GETTER5(
+NS_IMPL_CI_INTERFACE_GETTER4(
   nsNavHistory
 , nsINavHistoryService
-, nsIGlobalHistory3
 , nsIGlobalHistory2
 , nsIDownloadHistory
 , nsIBrowserHistory
 )
 
 namespace {
 
 static PRInt64 GetSimpleBookmarksQueryFolder(
@@ -466,18 +464,16 @@ nsNavHistory::Init()
 
   // recent events hash tables
   NS_ENSURE_TRUE(mRecentTyped.Init(RECENT_EVENTS_INITIAL_CACHE_SIZE),
                  NS_ERROR_OUT_OF_MEMORY);
   NS_ENSURE_TRUE(mRecentLink.Init(RECENT_EVENTS_INITIAL_CACHE_SIZE),
                  NS_ERROR_OUT_OF_MEMORY);
   NS_ENSURE_TRUE(mRecentBookmark.Init(RECENT_EVENTS_INITIAL_CACHE_SIZE),
                  NS_ERROR_OUT_OF_MEMORY);
-  NS_ENSURE_TRUE(mRecentRedirects.Init(RECENT_EVENTS_INITIAL_CACHE_SIZE),
-                 NS_ERROR_OUT_OF_MEMORY);
 
   // Embed visits hash table.
   NS_ENSURE_TRUE(mEmbedVisits.Init(EMBED_VISITS_INITIAL_CACHE_SIZE),
                  NS_ERROR_OUT_OF_MEMORY);
 
   /*****************************************************************************
    *** IMPORTANT NOTICE!
    ***
@@ -2721,19 +2717,18 @@ nsNavHistory::AddVisit(nsIURI* aURI, PRT
   // FIXME bug 325241: make a way to observe hidden URLs
   if (!hidden) {
     NotifyOnVisit(aURI, *aVisitID, aTime, aSessionID, referringVisitID,
                   aTransitionType, guid);
   }
 
   // Normally docshell sends the link visited observer notification for us (this
   // will tell all the documents to update their visited link coloring).
-  // However, for redirects (since we implement nsIGlobalHistory3) and downloads
-  // (since we implement nsIDownloadHistory) this will not happen and we need to
-  // send it ourselves.
+  // However, for redirects and downloads (since we implement nsIDownloadHistory)
+  // this will not happen and we need to send it ourselves.
   if (newItem && (aIsRedirect || aTransitionType == TRANSITION_DOWNLOAD)) {
     nsCOMPtr<nsIObserverService> obsService =
       do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
     if (obsService)
       obsService->NotifyObservers(aURI, NS_LINK_VISITED_EVENT_TOPIC, nsnull);
   }
 
   // Because we implement IHistory, we always have to notify about the visit.
@@ -4834,21 +4829,17 @@ nsNavHistory::AddURIInternal(nsIURI* aUR
 // nsNavHistory::AddVisitChain
 //
 //    This function is sits between AddURI (which is called when a page is
 //    visited) and AddVisit (which creates the DB entries) to figure out what
 //    we should add and what are the detailed parameters that should be used
 //    (like referring visit ID and typed/bookmarked state).
 //
 //    This function walks up the referring chain and recursively calls itself,
-//    each time calling InternalAdd to create a new history entry. (When we
-//    get notified of redirects, we don't actually add any history entries, just
-//    save them in mRecentRedirects. This function will add all of them for a
-//    given destination page when that page is actually visited.)
-//    See GetRedirectFor for more information about how redirects work.
+//    each time calling InternalAdd to create a new history entry.
 
 nsresult
 nsNavHistory::AddVisitChain(nsIURI* aURI,
                             PRTime aTime,
                             PRBool aToplevel,
                             PRBool aIsRedirect,
                             nsIURI* aReferrerURI,
                             PRInt64* aVisitID,
@@ -4864,62 +4855,20 @@ nsNavHistory::AddVisitChain(nsIURI* aURI
 
   // A visit is considered EMBED if it's in a frame and the page visit does not
   // come from a user's action (like clicking a link), otherwise is FRAMED_LINK.
   // An embed visit should not appear in history views.
   // See bug 381453 for details.
   PRBool isEmbedVisit = !aToplevel &&
                         !CheckIsRecentEvent(&mRecentLink, spec);
 
-  // Check if this visit came from a redirect.
   PRUint32 transitionType = 0;
-  PRTime redirectTime = 0;
-  nsCAutoString redirectSourceUrl;
-  if (GetRedirectFor(spec, redirectSourceUrl, &redirectTime, &transitionType)) {
-    // redirectSourceUrl redirected to aURL, at redirectTime, with
-    // a transitionType redirect.
-    nsCOMPtr<nsIURI> redirectSourceURI;
-    rv = NS_NewURI(getter_AddRefs(redirectSourceURI), redirectSourceUrl);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // Don't add a new visit if a page redirects to itself.
-    PRBool redirectIsSame;
-    if (NS_SUCCEEDED(aURI->Equals(redirectSourceURI, &redirectIsSame)) &&
-        redirectIsSame)
-      return NS_OK;
-
-    // Recusively call addVisitChain to walk up the chain till the first
-    // not-redirected URI.
-    // Ensure that the sources have a visit time smaller than aTime, otherwise
-    // visits would end up incorrectly ordered.
-    PRTime sourceTime = NS_MIN(redirectTime, aTime - 1);
-    PRInt64 sourceVisitId = 0;
-    rv = AddVisitChain(redirectSourceURI, sourceTime, aToplevel,
-                       PR_TRUE, // Is a redirect.
-                       aReferrerURI, // This one is the originating source.
-                       &sourceVisitId, // Get back the visit id of the source.
-                       aSessionID);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // All the visits for preceding pages in the redirects chain have been
-    // added, now add the visit to aURI.
-    if (isEmbedVisit)
-      transitionType = nsINavHistoryService::TRANSITION_EMBED;
-    else if (!aToplevel)
-      transitionType = nsINavHistoryService::TRANSITION_FRAMED_LINK;
-
-    // This page is result of a redirect, save the source page in from_visit,
-    // to be able to walk up the chain.
-    // See bug 411966 and bug 428690 for details.
-    // TODO: Add a closure table with a chain id to easily reconstruct chains
-    // without having to recurse through the table.  See bug 468710.
-    fromVisitURI = redirectSourceURI;
-  }
-  else if (aReferrerURI) {
-    // This page does not come from a redirect and had a referrer.
+
+  if (aReferrerURI) {
+  // This page had a referrer.
 
     // Check if the referrer has a previous visit.
     PRTime lastVisitTime;
     PRInt64 referringVisitId;
     PRBool referrerHasPreviousVisit =
       FindLastVisit(aReferrerURI, &referringVisitId, &lastVisitTime, aSessionID);
 
     // Don't add a new visit if the referring site is the same as
@@ -5077,117 +5026,16 @@ nsNavHistory::GetPageTitle(nsIURI* aURI,
   }
 
   rv = stmt->GetString(nsNavHistory::kGetInfoIndex_Title, aTitle);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
-// nsNavHistory::GetURIGeckoFlags
-//
-//    FIXME: should we try to use annotations for this stuff?
-
-NS_IMETHODIMP
-nsNavHistory::GetURIGeckoFlags(nsIURI* aURI, PRUint32* aResult)
-{
-  NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread");
-  NS_ENSURE_ARG(aURI);
-  NS_ENSURE_ARG_POINTER(aResult);
-
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-
-// nsNavHistory::SetURIGeckoFlags
-//
-//    FIXME: should we try to use annotations for this stuff?
-
-NS_IMETHODIMP
-nsNavHistory::SetURIGeckoFlags(nsIURI* aURI, PRUint32 aFlags)
-{
-  NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread");
-  NS_ENSURE_ARG(aURI);
-
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-// nsIGlobalHistory3 ***********************************************************
-
-// nsNavHistory::AddDocumentRedirect
-//
-//    This adds a redirect mapping from the destination of the redirect to the
-//    source, time, and type. This mapping is used by GetRedirectFor when we
-//    get a page added to reconstruct the redirects that happened when a page
-//    is visited. See GetRedirectFor for more information
-
-// this is the expiration callback function that deletes stale entries
-PLDHashOperator nsNavHistory::ExpireNonrecentRedirects(
-    nsCStringHashKey::KeyType aKey, RedirectInfo& aData, void* aUserArg)
-{
-  PRInt64* threshold = reinterpret_cast<PRInt64*>(aUserArg);
-  if (aData.mTimeCreated < *threshold)
-    return PL_DHASH_REMOVE;
-  return PL_DHASH_NEXT;
-}
-
-NS_IMETHODIMP
-nsNavHistory::AddDocumentRedirect(nsIChannel *aOldChannel,
-                                  nsIChannel *aNewChannel,
-                                  PRInt32 aFlags,
-                                  PRBool aToplevel)
-{
-  NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread");
-  NS_ENSURE_ARG(aOldChannel);
-  NS_ENSURE_ARG(aNewChannel);
-
-  // Ignore internal redirects.
-  // These redirects are not initiated by the remote server, but specific to the
-  // channel implementation, so they are ignored.
-  if (aFlags & nsIChannelEventSink::REDIRECT_INTERNAL)
-    return NS_OK;
-
-  nsresult rv;
-  nsCOMPtr<nsIURI> oldURI, newURI;
-  rv = aOldChannel->GetURI(getter_AddRefs(oldURI));
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = aNewChannel->GetURI(getter_AddRefs(newURI));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCString oldSpec, newSpec;
-  rv = oldURI->GetSpec(oldSpec);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = newURI->GetSpec(newSpec);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (mRecentRedirects.Count() > RECENT_EVENT_QUEUE_MAX_LENGTH) {
-    // Expire outdated cached redirects.
-    PRInt64 threshold = PR_Now() - RECENT_EVENT_THRESHOLD;
-    mRecentRedirects.Enumerate(ExpireNonrecentRedirects,
-                               reinterpret_cast<void*>(&threshold));
-  }
-
-  RedirectInfo info;
-
-  // Remove any old entries for this redirect destination, since they are going
-  // to be replaced.
-  if (mRecentRedirects.Get(newSpec, &info))
-    mRecentRedirects.Remove(newSpec);
-  // Save the new redirect info.
-  info.mSourceURI = oldSpec;
-  info.mTimeCreated = PR_Now();
-  if (aFlags & nsIChannelEventSink::REDIRECT_TEMPORARY)
-    info.mType = TRANSITION_REDIRECT_TEMPORARY;
-  else
-    info.mType = TRANSITION_REDIRECT_PERMANENT;
-  mRecentRedirects.Put(newSpec, info);
-
-  return NS_OK;
-}
-
 
 ////////////////////////////////////////////////////////////////////////////////
 //// mozIStorageVacuumParticipant
 
 NS_IMETHODIMP
 nsNavHistory::GetDatabaseConnection(mozIStorageConnection** _DBConnection)
 {
   return GetDBConnection(_DBConnection);
@@ -6328,87 +6176,16 @@ void
 nsNavHistory::ExpireNonrecentEvents(RecentEventHash* hashTable)
 {
   PRInt64 threshold = GetNow() - RECENT_EVENT_THRESHOLD;
   hashTable->Enumerate(ExpireNonrecentEventsCallback,
                        reinterpret_cast<void*>(&threshold));
 }
 
 
-// nsNavHistory::GetRedirectFor
-//
-//    Given a destination URI, this finds a recent redirect that resulted in
-//    this URI. If it finds one, it will put the redirect source info into
-//    the out params and return true. If there is no matching redirect, it will
-//    return false.
-//
-//    @param aDestination The destination URI spec of the redirect to look for.
-//    @param aSource      Will be filled with the redirect source URI when a
-//                        redirect is found.
-//    @param aTime        Will be filled with the time the redirect happened
-//                         when a redirect is found.
-//    @param aRedirectType Will be filled with the redirect type when a redirect
-//                         is found. Will be either
-//                         TRANSITION_REDIRECT_PERMANENT or
-//                         TRANSITION_REDIRECT_TEMPORARY
-//    @returns True if the redirect is found.
-//
-//    HOW REDIRECT TRACKING WORKS
-//    ---------------------------
-//    When we get an AddDocumentRedirect message, we store the redirect in
-//    our mRecentRedirects which maps the destination URI to a source,time pair.
-//    When we get a new URI, we see if there were any redirects to this page
-//    in the hash table. If found, we know that the page came through the given
-//    redirect and add it.
-//
-//    Example: Page S redirects throught R1, then R2, to give page D. Page S
-//    will have been already added to history.
-//    - AddDocumentRedirect(R1, R2)
-//    - AddDocumentRedirect(R2, D)
-//    - AddURI(uri=D, referrer=S)
-//
-//    When we get the AddURI(D), we see the hash table has a value for D from R2.
-//    We have to recursively check that source since there could be more than
-//    one redirect, as in this case. Here we see there was a redirect to R2 from
-//    R1. The referrer for D is S, so we know S->R1->R2->D.
-//
-//    Alternatively, the user could have typed or followed a bookmark from S.
-//    In this case, with two redirects we'll get:
-//    - MarkPageAsTyped(S)
-//    - AddDocumentRedirect(S, R)
-//    - AddDocumentRedirect(R, D)
-//    - AddURI(uri=D, referrer=null)
-//    We need to be careful to add a visit to S in this case with an incoming
-//    transition of typed and an outgoing transition of redirect.
-//
-//    Note that this can get confused in some cases where you have a page
-//    open in more than one window loading at the same time. This should be rare,
-//    however, and should not affect much.
-
-PRBool
-nsNavHistory::GetRedirectFor(const nsACString& aDestination,
-                             nsACString& aSource,
-                             PRTime* aTime,
-                             PRUint32* aRedirectType)
-{
-  RedirectInfo info;
-  if (mRecentRedirects.Get(aDestination, &info)) {
-    // Consume the redirect entry, it's no longer useful.
-    mRecentRedirects.Remove(aDestination);
-    if (info.mTimeCreated < GetNow() - RECENT_EVENT_THRESHOLD)
-      return PR_FALSE; // too long ago, probably invalid
-    aSource = info.mSourceURI;
-    *aTime = info.mTimeCreated;
-    *aRedirectType = info.mType;
-    return PR_TRUE;
-  }
-  return PR_FALSE;
-}
-
-
 // nsNavHistory::RowToResult
 //
 //    Here, we just have a generic row. It could be a query, URL, visit,
 //    or full visit.
 
 nsresult
 nsNavHistory::RowToResult(mozIStorageValueArray* aRow,
                           nsNavHistoryQueryOptions* aOptions,
--- a/toolkit/components/places/nsNavHistory.h
+++ b/toolkit/components/places/nsNavHistory.h
@@ -42,17 +42,16 @@
 #ifndef nsNavHistory_h_
 #define nsNavHistory_h_
 
 #include "nsINavHistoryService.h"
 #include "nsPIPlacesDatabase.h"
 #include "nsPIPlacesHistoryListenersNotifier.h"
 #include "nsIBrowserHistory.h"
 #include "nsIGlobalHistory.h"
-#include "nsIGlobalHistory3.h"
 #include "nsIDownloadHistory.h"
 
 #include "nsIPrefService.h"
 #include "nsIPrefBranch2.h"
 #include "nsIObserverService.h"
 #include "nsICollation.h"
 #include "nsIStringBundle.h"
 #include "nsITimer.h"
@@ -96,19 +95,16 @@
 #ifdef MOZ_XUL
 // Fired after autocomplete feedback has been updated.
 #define TOPIC_AUTOCOMPLETE_FEEDBACK_UPDATED "places-autocomplete-feedback-updated"
 #endif
 
 // Fired after frecency has been updated.
 #define TOPIC_FRECENCY_UPDATED "places-frecency-updated"
 
-// Fired after frecency has been updated.
-#define TOPIC_FRECENCY_UPDATED "places-frecency-updated"
-
 // Fired when Places is shutting down.  Any code should stop accessing Places
 // APIs after this notification.  If you need to listen for Places shutdown
 // you should only use this notification, next ones are intended only for
 // internal Places use.
 #define TOPIC_PLACES_SHUTDOWN "places-shutdown"
 // For Internal use only.  Fired when connection is about to be closed, only
 // cleanup tasks should run at this stage, nothing should be added to the
 // database, nor APIs should be called.
@@ -166,33 +162,31 @@ class PlacesSQLQueryBuilder;
 class nsIAutoCompleteController;
 
 // nsNavHistory
 
 class nsNavHistory : public nsSupportsWeakReference
                    , public nsINavHistoryService
                    , public nsIObserver
                    , public nsIBrowserHistory
-                   , public nsIGlobalHistory3
                    , public nsIDownloadHistory
                    , public nsICharsetResolver
                    , public nsPIPlacesDatabase
                    , public nsPIPlacesHistoryListenersNotifier
                    , public mozIStorageVacuumParticipant
 {
   friend class PlacesSQLQueryBuilder;
 
 public:
   nsNavHistory();
 
   NS_DECL_ISUPPORTS
 
   NS_DECL_NSINAVHISTORYSERVICE
   NS_DECL_NSIGLOBALHISTORY2
-  NS_DECL_NSIGLOBALHISTORY3
   NS_DECL_NSIDOWNLOADHISTORY
   NS_DECL_NSIBROWSERHISTORY
   NS_DECL_NSIOBSERVER
   NS_DECL_NSPIPLACESDATABASE
   NS_DECL_NSPIPLACESHISTORYLISTENERSNOTIFIER
   NS_DECL_MOZISTORAGEVACUUMPARTICIPANT
 
 
@@ -845,29 +839,16 @@ protected:
   };
 
   nsTHashtable<VisitHashKey> mEmbedVisits;
 
   PRBool CheckIsRecentEvent(RecentEventHash* hashTable,
                             const nsACString& url);
   void ExpireNonrecentEvents(RecentEventHash* hashTable);
 
-  // redirect tracking. See GetRedirectFor for a description of how this works.
-  struct RedirectInfo {
-    nsCString mSourceURI;
-    PRTime mTimeCreated;
-    PRUint32 mType; // one of TRANSITION_REDIRECT_[TEMPORARY,PERMANENT]
-  };
-  typedef nsDataHashtable<nsCStringHashKey, RedirectInfo> RedirectHash;
-  RedirectHash mRecentRedirects;
-  static PLDHashOperator ExpireNonrecentRedirects(
-      nsCStringHashKey::KeyType aKey, RedirectInfo& aData, void* aUserArg);
-  PRBool GetRedirectFor(const nsACString& aDestination, nsACString& aSource,
-                        PRTime* aTime, PRUint32* aRedirectType);
-
   // Sessions tracking.
   PRInt64 mLastSessionID;
 
 #ifdef MOZ_XUL
   nsresult AutoCompleteFeedback(PRInt32 aIndex,
                                 nsIAutoCompleteController *aController);
 #endif
 
--- a/toolkit/components/places/tests/mochitest/bug_411966/redirect.js
+++ b/toolkit/components/places/tests/mochitest/bug_411966/redirect.js
@@ -48,18 +48,16 @@ ok(Cc != null, "Access Cc");
 var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
               getService(Ci.nsINavHistoryService);
 ok(histsvc != null, "Could not get History Service");
 var bhist = histsvc.QueryInterface(Ci.nsIBrowserHistory);
 ok(bhist != null, "Could not get Browser History Service");
 var ghist = Cc["@mozilla.org/browser/global-history;2"].
             getService(Ci.nsIGlobalHistory2);
 ok(ghist != null, "Could not get Global History Service");
-var ghist3 = ghist.QueryInterface(Ci.nsIGlobalHistory3);
-ok(ghist3 != null, "Could not get Global History Service");
 var ios = Cc["@mozilla.org/network/io-service;1"].
           getService(Components.interfaces.nsIIOService);
 ok(ios != null, "Could not get IO Service");
 var storage = Cc["@mozilla.org/storage/service;1"].
               getService(Ci.mozIStorageService);
 ok(storage != null, "Could not get Storage Service");
 
 // Get database connection.
@@ -108,17 +106,16 @@ StreamListener.prototype = {
       throw("Could not get page.");
 
     this.mChannel = null;
   },
 
   // nsIChannelEventSink
   asyncOnChannelRedirect: function (aOldChannel, aNewChannel, aFlags, callback) {
     netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
-    ghist3.addDocumentRedirect(aOldChannel, aNewChannel, aFlags, true);
     // If redirecting, store the new channel
     this.mChannel = aNewChannel;
     callback.onRedirectVerifyCallback(Components.results.NS_OK);
   },
 
   // nsIInterfaceRequestor
   getInterface: function (aIID) {
     netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
--- a/toolkit/components/places/tests/network/test_history_redirects.js
+++ b/toolkit/components/places/tests/network/test_history_redirects.js
@@ -3,17 +3,16 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /* Tests history redirects handling */
 
 let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
          getService(Ci.nsINavHistoryService);
 let bh = hs.QueryInterface(Ci.nsIBrowserHistory);
-let ghist3 = hs.QueryInterface(Ci.nsIGlobalHistory3);
 
 const PERMA_REDIR_PATH = "/permaredir";
 const TEMP_REDIR_PATH = "/tempredir";
 const FOUND_PATH = "/found";
 
 const HTTPSVR = new nsHttpServer();
 const PORT = 4444;
 HTTPSVR.registerPathHandler(PERMA_REDIR_PATH, permaRedirHandler);
@@ -176,23 +175,18 @@ ChannelListener.prototype = {
     do_log_info("onStopRequest");
     this._got_onstoprequest++;
     let success = Components.isSuccessCode(status);
     do_check_true(success);
     do_check_true(this._got_onstartrequest);
     do_check_true(this._got_onchannelredirect);
     do_check_true(this._buffer.length > 0);
 
-    // The referrer is wrong since it's the first element in the redirects
-    // chain, but this is good, since it will test a special path.
-    ghist3.addURI(uri(FOUND_URL), false, true, uri(PERMA_REDIR_URL));
-
     continue_test();
   },
 
   // nsIChannelEventSink
   asyncOnChannelRedirect: function (aOldChannel, aNewChannel, aFlags, callback) {
     do_log_info("onChannelRedirect");
     this._got_onchannelredirect = true;
-    ghist3.addDocumentRedirect(aOldChannel, aNewChannel, aFlags, true);
     callback.onRedirectVerifyCallback(Components.results.NS_OK);
   },
 };
--- a/toolkit/content/aboutSupport.js
+++ b/toolkit/content/aboutSupport.js
@@ -61,17 +61,16 @@ const PREFS_WHITELIST = [
   "browser.zoom.",
   "dom.",
   "extensions.checkCompatibility",
   "extensions.lastAppVersion",
   "font.",
   "general.useragent.",
   "gfx.",
   "html5.",
-  "mozilla.widget.render-mode",
   "layers.",
   "javascript.",
   "keyword.",
   "layout.css.dpi",
   "network.",
   "places.",
   "plugin.",
   "plugins.",
--- a/toolkit/toolkit-makefiles.sh
+++ b/toolkit/toolkit-makefiles.sh
@@ -317,17 +317,16 @@ MAKEFILES_libvorbis="
   media/libvorbis/lib/Makefile
   media/libvorbis/include/Makefile
   media/libvorbis/include/vorbis/Makefile
 "
 
 MAKEFILES_libtremor="
   media/libtremor/Makefile
   media/libtremor/lib/Makefile
-  media/libtremor/include/Makefile
   media/libtremor/include/tremor/Makefile
 "
 
 MAKEFILES_libvpx="
   media/libvpx/Makefile
 "
 
 MAKEFILES_libtheora="
--- a/widget/public/nsILookAndFeel.h
+++ b/widget/public/nsILookAndFeel.h
@@ -245,16 +245,26 @@ public:
      * being used.
      *
      * The value of this metric is not used on other platforms. These platforms
      * should return NS_ERROR_NOT_IMPLEMENTED when queried for this metric.
      */
     eMetric_MacGraphiteTheme,
 
     /*
+     * A Boolean value to determine whether the Mac OS X Lion-specific theming
+     * should be used.
+     *
+     * The value of this metric is not used on non-Mac platforms. These
+     * platforms should return NS_ERROR_NOT_IMPLEMENTED when queried for this
+     * metric.
+     */
+    eMetric_MacLionTheme,
+
+    /*
      * A Boolean value to determine whether Mameo is using the new Fremantle
      * theme.
      *
      * The value of this metric is not used on other platforms. These platforms
      * should return NS_ERROR_NOT_IMPLEMENTED when queried for this metric.
      */
     eMetric_MaemoClassic,
 
--- a/widget/src/android/AndroidJNI.cpp
+++ b/widget/src/android/AndroidJNI.cpp
@@ -59,16 +59,17 @@
 
 using namespace mozilla;
 
 /* Forward declare all the JNI methods as extern "C" */
 
 extern "C" {
     NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_nativeInit(JNIEnv *, jclass);
     NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_notifyGeckoOfEvent(JNIEnv *, jclass, jobject event);
+    NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_processNextNativeEvent(JNIEnv *, jclass);
     NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_setSurfaceView(JNIEnv *jenv, jclass, jobject sv);
     NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_onResume(JNIEnv *, jclass);
     NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_onLowMemory(JNIEnv *, jclass);
     NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_callObserver(JNIEnv *, jclass, jstring observerKey, jstring topic, jstring data);
     NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_removeObserver(JNIEnv *jenv, jclass, jstring jObserverKey);
     NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_onChangeNetworkLinkStatus(JNIEnv *, jclass, jstring status, jstring type);
     NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_reportJavaCrash(JNIEnv *, jclass, jstring stack);
 }
@@ -88,16 +89,24 @@ NS_EXPORT void JNICALL
 Java_org_mozilla_gecko_GeckoAppShell_notifyGeckoOfEvent(JNIEnv *jenv, jclass jc, jobject event)
 {
     // poke the appshell
     if (nsAppShell::gAppShell)
         nsAppShell::gAppShell->PostEvent(new AndroidGeckoEvent(jenv, event));
 }
 
 NS_EXPORT void JNICALL
+Java_org_mozilla_gecko_GeckoAppShell_processNextNativeEvent(JNIEnv *jenv, jclass)
+{
+    // poke the appshell
+    if (nsAppShell::gAppShell)
+        nsAppShell::gAppShell->ProcessNextNativeEvent(PR_FALSE);
+}
+
+NS_EXPORT void JNICALL
 Java_org_mozilla_gecko_GeckoAppShell_setSurfaceView(JNIEnv *jenv, jclass, jobject obj)
 {
     AndroidBridge::Bridge()->SetSurfaceView(jenv->NewGlobalRef(obj));
 }
 
 NS_EXPORT void JNICALL
 Java_org_mozilla_gecko_GeckoAppShell_onLowMemory(JNIEnv *jenv, jclass jc)
 {
--- a/widget/src/android/AndroidJavaWrappers.cpp
+++ b/widget/src/android/AndroidJavaWrappers.cpp
@@ -453,16 +453,29 @@ AndroidGeckoEvent::Init(int aType)
 void
 AndroidGeckoEvent::Init(int x1, int y1, int x2, int y2)
 {
     mType = DRAW;
     mRect.SetEmpty();
 }
 
 void
+AndroidGeckoEvent::Init(AndroidGeckoEvent *aResizeEvent)
+{
+    NS_ASSERTION(aResizeEvent->Type() == SIZE_CHANGED, "Init called on non-SIZE_CHANGED event");
+
+    mType = FORCED_RESIZE;
+    mTime = aResizeEvent->mTime;
+    mP0.x = aResizeEvent->mP0.x;
+    mP0.y = aResizeEvent->mP0.y;
+    mP1.x = aResizeEvent->mP1.x;
+    mP1.y = aResizeEvent->mP1.y;
+}
+
+void
 AndroidGeckoSurfaceView::Init(jobject jobj)
 {
     NS_ASSERTION(wrapped_obj == nsnull, "Init called on non-null wrapped_obj!");
 
     wrapped_obj = jobj;
 }
 
 int
--- a/widget/src/android/AndroidJavaWrappers.h
+++ b/widget/src/android/AndroidJavaWrappers.h
@@ -381,20 +381,24 @@ public:
         Init(aType);
     }
     AndroidGeckoEvent(int x1, int y1, int x2, int y2) {
         Init(x1, y1, x2, y2);
     }
     AndroidGeckoEvent(JNIEnv *jenv, jobject jobj) {
         Init(jenv, jobj);
     }
+    AndroidGeckoEvent(AndroidGeckoEvent *aResizeEvent) {
+        Init(aResizeEvent);
+    }
 
     void Init(JNIEnv *jenv, jobject jobj);
     void Init(int aType);