Backed out 3 changesets (bug 896124, bug 784739, bug 894026) for Windows checktest orange on a CLOSED TREE.
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 26 Jul 2013 00:08:51 -0400
changeset 140102 bbf37166d07cc117d5e6304706e7f0d00b5415d5
parent 140101 9308a970daee28e4431da34b1d3e258524db4337
child 140106 52f9e8ffe111884e934c7efeae4ffea67a44b128
push id31594
push userryanvm@gmail.com
push dateFri, 26 Jul 2013 04:08:56 +0000
treeherdermozilla-inbound@bbf37166d07c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs896124, 784739, 894026
milestone25.0a1
backs out631b3d5d54f46823f660ff5ad5ae298356309b10
5e1dd28ede5d12a37dee6a9d0ac75f66c015d32a
c10c0a6270ecbf817fe472b8dc04d195b6900d28
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 3 changesets (bug 896124, bug 784739, bug 894026) for Windows checktest orange on a CLOSED TREE. Backed out changeset 631b3d5d54f4 (bug 896124) Backed out changeset 5e1dd28ede5d (bug 894026) Backed out changeset c10c0a6270ec (bug 784739)
js/src/frontend/TokenStream.cpp
js/src/js.msg
js/src/jsapi-tests/tests.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsfriendapi.h
js/src/shell/js.cpp
js/src/tests/ecma_6/Expressions/binary-literals.js
js/src/tests/ecma_6/Expressions/browser.js
js/src/tests/ecma_6/Expressions/octal-literals.js
js/src/tests/ecma_6/Expressions/shell.js
js/src/vm/ForkJoin.cpp
js/src/vm/Runtime.cpp
js/src/vm/Runtime.h
js/xpconnect/src/XPCJSRuntime.cpp
mfbt/GuardObjects.h
mfbt/LinkedList.h
mfbt/RangedPtr.h
mfbt/Scoped.h
mfbt/ThreadLocal.h
mfbt/Vector.h
mfbt/tests/TestPoisonArea.cpp
xpcom/build/nsXPComInit.cpp
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -998,17 +998,17 @@ enum FirstCharKind {
     OneChar,
     Ident,
     Dot,
     Equals,
     String,
     Dec,
     Colon,
     Plus,
-    BasePrefix,
+    HexOct,
 
     /* These two must be last, so that |c >= Space| matches both. */
     Space,
     EOL
 };
 
 #define _______ Other
 
@@ -1017,27 +1017,27 @@ enum FirstCharKind {
  *          '(', ')', ',', ';', '?', '[', ']', '{', '}', '~'
  * Ident:   36, 65..90, 95, 97..122: '$', 'A'..'Z', '_', 'a'..'z'
  * Dot:     46: '.'
  * Equals:  61: '='
  * String:  34, 39: '"', '\''
  * Dec:     49..57: '1'..'9'
  * Colon:   58: ':'
  * Plus:    43: '+'
- * BasePrefix:  48: '0'
+ * HexOct:  48: '0'
  * Space:   9, 11, 12: '\t', '\v', '\f'
  * EOL:     10, 13: '\n', '\r'
  */
 static const uint8_t firstCharKinds[] = {
 /*         0        1        2        3        4        5        6        7        8        9    */
 /*   0+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______,   Space,
 /*  10+ */     EOL,   Space,   Space,     EOL, _______, _______, _______, _______, _______, _______,
 /*  20+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
 /*  30+ */ _______, _______,   Space, _______,  String, _______,   Ident, _______, _______,  String,
-/*  40+ */ OneChar, OneChar, _______,    Plus, OneChar, _______,     Dot, _______, BasePrefix,  Dec,
+/*  40+ */ OneChar, OneChar, _______,    Plus, OneChar, _______,     Dot, _______,  HexOct,     Dec,
 /*  50+ */     Dec,     Dec,     Dec,     Dec,     Dec,     Dec,     Dec,     Dec,   Colon, OneChar,
 /*  60+ */ _______,  Equals, _______, OneChar, _______,   Ident,   Ident,   Ident,   Ident,   Ident,
 /*  70+ */   Ident,   Ident,   Ident,   Ident,   Ident,   Ident,   Ident,   Ident,   Ident,   Ident,
 /*  80+ */   Ident,   Ident,   Ident,   Ident,   Ident,   Ident,   Ident,   Ident,   Ident,   Ident,
 /*  90+ */   Ident, OneChar, _______, OneChar, _______,   Ident, _______,   Ident,   Ident,   Ident,
 /* 100+ */   Ident,   Ident,   Ident,   Ident,   Ident,   Ident,   Ident,   Ident,   Ident,   Ident,
 /* 110+ */   Ident,   Ident,   Ident,   Ident,   Ident,   Ident,   Ident,   Ident,   Ident,   Ident,
 /* 120+ */   Ident,   Ident,   Ident, OneChar, _______, OneChar, OneChar, _______
@@ -1392,53 +1392,33 @@ TokenStream::getTokenInternal()
     if (c1kind == Plus) {
         if (matchChar('+'))
             tt = TOK_INC;
         else
             tt = matchChar('=') ? TOK_ADDASSIGN : TOK_PLUS;
         goto out;
     }
 
-    // Look for a hexadecimal, octal, or binary number.
-    if (c1kind == BasePrefix) {
+    /*
+     * Look for a hexadecimal or octal number.
+     */
+    if (c1kind == HexOct) {
         int radix;
         c = getCharIgnoreEOL();
         if (c == 'x' || c == 'X') {
             radix = 16;
             c = getCharIgnoreEOL();
             if (!JS7_ISHEX(c)) {
                 ungetCharIgnoreEOL(c);
                 reportError(JSMSG_MISSING_HEXDIGITS);
                 goto error;
             }
             numStart = userbuf.addressOfNextRawChar() - 1;  /* one past the '0x' */
             while (JS7_ISHEX(c))
                 c = getCharIgnoreEOL();
-        } else if (c == 'b' || c == 'B') {
-            radix = 2;
-            c = getCharIgnoreEOL();
-            if (c != '0' && c != '1') {
-                ungetCharIgnoreEOL(c);
-                reportError(JSMSG_MISSING_BINARY_DIGITS);
-                goto error;
-            }
-            numStart = userbuf.addressOfNextRawChar() - 1;  /* one past the '0b' */
-            while (c == '0' || c == '1')
-                c = getCharIgnoreEOL();
-        } else if (c == 'o' || c == 'O') {
-            radix = 8;
-            c = getCharIgnoreEOL();
-            if (c < '0' || c > '7') {
-                ungetCharIgnoreEOL(c);
-                reportError(JSMSG_MISSING_OCTAL_DIGITS);
-                goto error;
-            }
-            numStart = userbuf.addressOfNextRawChar() - 1;  /* one past the '0o' */
-            while ('0' <= c && c <= '7')
-                c = getCharIgnoreEOL();
         } else if (JS7_ISDEC(c)) {
             radix = 8;
             numStart = userbuf.addressOfNextRawChar() - 1;  /* one past the '0' */
             while (JS7_ISDEC(c)) {
                 /* Octal integer literals are not permitted in strict mode code. */
                 if (!reportStrictModeError(JSMSG_DEPRECATED_OCTAL))
                     goto error;
 
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -179,26 +179,26 @@ MSG_DEF(JSMSG_BAD_LABEL,              12
 MSG_DEF(JSMSG_DUPLICATE_LABEL,        126, 0, JSEXN_SYNTAXERR, "duplicate label")
 MSG_DEF(JSMSG_VAR_HIDES_ARG,          127, 1, JSEXN_TYPEERR, "variable {0} redeclares argument")
 MSG_DEF(JSMSG_BAD_VAR_INIT,           128, 0, JSEXN_SYNTAXERR, "invalid variable initialization")
 MSG_DEF(JSMSG_BAD_LEFTSIDE_OF_ASS,    129, 0, JSEXN_REFERENCEERR, "invalid assignment left-hand side")
 MSG_DEF(JSMSG_BAD_OPERAND,            130, 1, JSEXN_SYNTAXERR, "invalid {0} operand")
 MSG_DEF(JSMSG_BAD_PROP_ID,            131, 0, JSEXN_SYNTAXERR, "invalid property id")
 MSG_DEF(JSMSG_RESERVED_ID,            132, 1, JSEXN_SYNTAXERR, "{0} is a reserved identifier")
 MSG_DEF(JSMSG_SYNTAX_ERROR,           133, 0, JSEXN_SYNTAXERR, "syntax error")
-MSG_DEF(JSMSG_MISSING_BINARY_DIGITS,  134, 0, JSEXN_SYNTAXERR, "missing binary digits after '0b'")
+MSG_DEF(JSMSG_UNUSED134,              134, 0, JSEXN_NONE, "")
 MSG_DEF(JSMSG_BAD_PROTOTYPE,          135, 1, JSEXN_TYPEERR,   "'prototype' property of {0} is not an object")
 MSG_DEF(JSMSG_MISSING_EXPONENT,       136, 0, JSEXN_SYNTAXERR, "missing exponent")
 MSG_DEF(JSMSG_OUT_OF_MEMORY,          137, 0, JSEXN_ERR, "out of memory")
 MSG_DEF(JSMSG_UNTERMINATED_STRING,    138, 0, JSEXN_SYNTAXERR, "unterminated string literal")
 MSG_DEF(JSMSG_TOO_MANY_PARENS,        139, 0, JSEXN_INTERNALERR, "too many parentheses in regular expression")
 MSG_DEF(JSMSG_UNTERMINATED_COMMENT,   140, 0, JSEXN_SYNTAXERR, "unterminated comment")
 MSG_DEF(JSMSG_UNTERMINATED_REGEXP,    141, 0, JSEXN_SYNTAXERR, "unterminated regular expression literal")
 MSG_DEF(JSMSG_BAD_CLONE_FUNOBJ_SCOPE, 142, 0, JSEXN_TYPEERR, "bad cloned function scope chain")
-MSG_DEF(JSMSG_MISSING_OCTAL_DIGITS,   143, 0, JSEXN_SYNTAXERR, "missing octal digits after '0o'")
+MSG_DEF(JSMSG_UNUSED143,              143, 0, JSEXN_NONE, "")
 MSG_DEF(JSMSG_ILLEGAL_CHARACTER,      144, 0, JSEXN_SYNTAXERR, "illegal character")
 MSG_DEF(JSMSG_BAD_OCTAL,              145, 1, JSEXN_SYNTAXERR, "{0} is not a legal ECMA-262 octal constant")
 MSG_DEF(JSMSG_REPEAT_RANGE,           146, 0, JSEXN_RANGEERR, "repeat count must be positive and less than inifinity")
 MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION,     147, 1, JSEXN_INTERNALERR, "uncaught exception: {0}")
 MSG_DEF(JSMSG_INVALID_BACKREF,        148, 0, JSEXN_SYNTAXERR, "non-octal digit in an escape sequence that doesn't match a back-reference")
 MSG_DEF(JSMSG_BAD_BACKREF,            149, 0, JSEXN_SYNTAXERR, "back-reference exceeds number of capturing parentheses")
 MSG_DEF(JSMSG_PRECISION_RANGE,        150, 1, JSEXN_RANGEERR, "precision {0} out of range")
 MSG_DEF(JSMSG_BAD_GETTER_OR_SETTER,   151, 1, JSEXN_TYPEERR, "invalid {0} usage")
--- a/js/src/jsapi-tests/tests.cpp
+++ b/js/src/jsapi-tests/tests.cpp
@@ -77,45 +77,37 @@ int main(int argc, char *argv[])
     int failures = 0;
     const char *filter = (argc == 2) ? argv[1] : NULL;
 
     for (JSAPITest *test = JSAPITest::list; test; test = test->next) {
         const char *name = test->name();
         if (filter && strstr(name, filter) == NULL)
             continue;
 
-        if (!JS_Init()) {
-            printf("TEST-UNEXPECTED-FAIL | %s | JS_Init() failed.\n", name);
-            failures++;
-            continue;
-        }
-
         total += 1;
 
         printf("%s\n", name);
         if (!test->init()) {
             printf("TEST-UNEXPECTED-FAIL | %s | Failed to initialize.\n", name);
             failures++;
-            JS_ShutDown();
             continue;
         }
 
         JS::HandleObject global = JS::HandleObject::fromMarkedLocation(&test->global);
         if (test->run(global)) {
             printf("TEST-PASS | %s | ok\n", name);
         } else {
             JSAPITestString messages = test->messages();
             printf("%s | %s | %.*s\n",
                    (test->knownFail ? "TEST-KNOWN-FAIL" : "TEST-UNEXPECTED-FAIL"),
                    name, (int) messages.length(), messages.begin());
             if (!test->knownFail)
                 failures++;
         }
         test->uninit();
-        JS_ShutDown();
     }
 
     if (failures) {
         printf("\n%d unexpected failure%s.\n", failures, (failures == 1 ? "" : "s"));
         return 1;
     }
     printf("\nPassed: ran %d tests.\n", total);
     return 0;
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -5,19 +5,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
  * JavaScript API.
  */
 
 #include "jsapi.h"
 
-#include "mozilla/DebugOnly.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/PodOperations.h"
+#include "mozilla/ThreadLocal.h"
 
 #include <ctype.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
 
 #include "jsarray.h"
@@ -74,17 +74,16 @@
 #include "unicode/uclean.h"
 #include "unicode/utypes.h"
 #endif
 #include "vm/DateObject.h"
 #include "vm/Debugger.h"
 #include "vm/ErrorObject.h"
 #include "vm/Interpreter.h"
 #include "vm/NumericConversions.h"
-#include "vm/Runtime.h"
 #include "vm/Shape.h"
 #include "vm/StopIterationObject.h"
 #include "vm/StringBuffer.h"
 #include "vm/TypedArrayObject.h"
 #include "vm/WeakMapObject.h"
 #include "vm/WrapperObject.h"
 #include "vm/Xdr.h"
 #include "yarr/BumpPointerAllocator.h"
@@ -98,17 +97,16 @@
 #include "vm/RegExpStatics-inl.h"
 #include "vm/Shape-inl.h"
 #include "vm/String-inl.h"
 
 using namespace js;
 using namespace js::gc;
 using namespace js::types;
 
-using mozilla::DebugOnly;
 using mozilla::Maybe;
 using mozilla::PodCopy;
 using mozilla::PodZero;
 
 using js::frontend::Parser;
 
 bool
 JS::detail::CallMethodIfWrapped(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
@@ -629,84 +627,25 @@ JS_PUBLIC_API(JSBool)
 JS_IsBuiltinFunctionConstructor(JSFunction *fun)
 {
     return fun->isBuiltinFunctionConstructor();
 }
 
 /************************************************************************/
 
 /*
- * Has SpiderMonkey been initialized?  This flag is used to control things that
- * should happen only once across all runtimes.  It's an API requirement that
- * JS_Init (and JS_ShutDown, if called) be called in a thread-aware manner, so
- * this variable doesn't need to be atomic.
+ * Has a new runtime ever been created?  This flag is used to control things
+ * that should happen only once across all runtimes.
  */
-static bool jsInitialized;
-
-JS_PUBLIC_API(JSBool)
-JS_Init(void)
-{
-    MOZ_ASSERT(!jsInitialized,
-               "must call JS_Init before any other JSAPI operation");
-    MOZ_ASSERT(!JSRuntime::hasLiveRuntimes(),
-               "how do we have live runtimes before JS_Init?");
-
-#ifdef DEBUG
-    // Assert that the numbers associated with the error names in js.msg are
-    // monotonically increasing.  It's not a compile-time check, but it's
-    // better than nothing.
-    int errorNumber = 0;
-#define MSG_DEF(name, number, count, exception, format)                       \
-    JS_ASSERT(name == errorNumber++);
-#include "js.msg"
-#undef MSG_DEF
-
-    // Assert that each message format has the correct number of braced
-    // parameters.
-#define MSG_DEF(name, number, count, exception, format)                       \
-    JS_BEGIN_MACRO                                                            \
-        unsigned numfmtspecs = 0;                                             \
-        for (const char *fmt = format; *fmt != '\0'; fmt++) {                 \
-            if (*fmt == '{' && isdigit(fmt[1]))                               \
-                ++numfmtspecs;                                                \
-        }                                                                     \
-        JS_ASSERT(count == numfmtspecs);                                      \
-    JS_END_MACRO;
-#include "js.msg"
-#undef MSG_DEF
-#endif /* DEBUG */
-
-    using js::TlsPerThreadData;
-    if (!TlsPerThreadData.initialized() && !TlsPerThreadData.init())
-        return false;
-
-#if defined(JS_ION)
-    if (!ion::InitializeIon())
-        return false;
-#endif
-
-    if (!ForkJoinSlice::InitializeTLS())
-        return false;
-
-    jsInitialized = true;
-    return true;
-}
-
-JS_PUBLIC_API(void)
-JS_ShutDown(void)
-{
-    MOZ_ASSERT(jsInitialized,
-               "JS_ShutDown must only be called after JS_Init and can't race with it");
-    MOZ_ASSERT(!JSRuntime::hasLiveRuntimes(),
-               "forgot to destroy a runtime before shutting down");
-
-    PRMJ_NowShutdown();
-
-    jsInitialized = false;
-}
+static JSBool js_NewRuntimeWasCalled = JS_FALSE;
+
+/*
+ * Thread Local Storage slot for storing the runtime for a thread.
+ */
+mozilla::ThreadLocal<PerThreadData *> js::TlsPerThreadData;
 
 #ifdef DEBUG
 JS_FRIEND_API(bool)
 JS::isGCEnabled()
 {
     return !TlsPerThreadData.get()->suppressGC;
 }
 #else
@@ -954,19 +893,16 @@ JSRuntime::JSRuntime(JSUseHelperThreads 
     parallelWarmup(0),
     ionReturnOverride_(MagicValue(JS_ARG_POISON)),
     useHelperThreads_(useHelperThreads),
     requestedHelperThreadCount(-1)
 #ifdef DEBUG
     , enteredPolicy(NULL)
 #endif
 {
-    MOZ_ASSERT(jsInitialized, "must call JS_Init prior to creating any JSRuntimes");
-    liveRuntimesCount++;
-
     /* Initialize infallibly first, so we can goto bad and JS_DestroyRuntime. */
     JS_INIT_CLIST(&onNewGlobalObjectWatchers);
 
     PodZero(&debugHooks);
     PodZero(&atomState);
 
 #if JS_STACK_GROWTH_DIRECTION > 0
     nativeStackLimit = UINTPTR_MAX;
@@ -1115,45 +1051,42 @@ JSRuntime::~JSRuntime()
 
     if (ionPcScriptCache)
         js_delete(ionPcScriptCache);
 
 #ifdef JSGC_GENERATIONAL
     gcStoreBuffer.disable();
     gcNursery.disable();
 #endif
-
-    DebugOnly<size_t> oldCount = liveRuntimesCount--;
-    JS_ASSERT(oldCount > 0);
 }
 
 #ifdef JS_THREADSAFE
 void
 JSRuntime::setOwnerThread()
 {
     JS_ASSERT(ownerThread_ == (void *)0xc1ea12);  /* "clear" */
     JS_ASSERT(requestDepth == 0);
-    JS_ASSERT(jsInitialized);
+    JS_ASSERT(js_NewRuntimeWasCalled);
     JS_ASSERT(js::TlsPerThreadData.get() == NULL);
     ownerThread_ = PR_GetCurrentThread();
     js::TlsPerThreadData.set(&mainThread);
     nativeStackBase = GetNativeStackBase();
     if (nativeStackQuota)
         JS_SetNativeStackQuota(this, nativeStackQuota);
 #ifdef XP_MACOSX
     asmJSMachExceptionHandler.setCurrentThread();
 #endif
 }
 
 void
 JSRuntime::clearOwnerThread()
 {
     assertValidThread();
     JS_ASSERT(requestDepth == 0);
-    JS_ASSERT(jsInitialized);
+    JS_ASSERT(js_NewRuntimeWasCalled);
     ownerThread_ = (void *)0xc1ea12;  /* "clear" */
     js::TlsPerThreadData.set(NULL);
     nativeStackBase = 0;
 #if JS_STACK_GROWTH_DIRECTION > 0
     mainThread.nativeStackLimit = UINTPTR_MAX;
 #else
     mainThread.nativeStackLimit = 0;
 #endif
@@ -1179,20 +1112,62 @@ JSRuntime::assertValidThread() const
     JS_ASSERT(js::TlsPerThreadData.get()->associatedWith(this));
 }
 #endif  /* DEBUG */
 #endif  /* JS_THREADSAFE */
 
 JS_PUBLIC_API(JSRuntime *)
 JS_NewRuntime(uint32_t maxbytes, JSUseHelperThreads useHelperThreads)
 {
+    if (!js_NewRuntimeWasCalled) {
+#ifdef DEBUG
+        /*
+         * This code asserts that the numbers associated with the error names
+         * in jsmsg.def are monotonically increasing.  It uses values for the
+         * error names enumerated in jscntxt.c.  It's not a compile-time check
+         * but it's better than nothing.
+         */
+        int errorNumber = 0;
+#define MSG_DEF(name, number, count, exception, format)                       \
+    JS_ASSERT(name == errorNumber++);
+#include "js.msg"
+#undef MSG_DEF
+
+#define MSG_DEF(name, number, count, exception, format)                       \
+    JS_BEGIN_MACRO                                                            \
+        unsigned numfmtspecs = 0;                                                \
+        const char *fmt;                                                      \
+        for (fmt = format; *fmt != '\0'; fmt++) {                             \
+            if (*fmt == '{' && isdigit(fmt[1]))                               \
+                ++numfmtspecs;                                                \
+        }                                                                     \
+        JS_ASSERT(count == numfmtspecs);                                      \
+    JS_END_MACRO;
+#include "js.msg"
+#undef MSG_DEF
+#endif /* DEBUG */
+
+        if (!js::TlsPerThreadData.init())
+            return NULL;
+
+        js_NewRuntimeWasCalled = JS_TRUE;
+    }
+
     JSRuntime *rt = js_new<JSRuntime>(useHelperThreads);
     if (!rt)
         return NULL;
 
+#if defined(JS_ION)
+    if (!ion::InitializeIon())
+        return NULL;
+#endif
+
+    if (!ForkJoinSlice::InitializeTLS())
+        return NULL;
+
     if (!rt->init(maxbytes)) {
         JS_DestroyRuntime(rt);
         return NULL;
     }
 
     return rt;
 }
 
@@ -1210,16 +1185,22 @@ JS_SetICUMemoryFunctions(JS_ICUAllocFn a
     UErrorCode status = U_ZERO_ERROR;
     u_setMemoryFunctions(/* context = */ NULL, allocFn, reallocFn, freeFn, &status);
     return U_SUCCESS(status);
 #else
     return true;
 #endif
 }
 
+JS_PUBLIC_API(void)
+JS_ShutDown(void)
+{
+    PRMJ_NowShutdown();
+}
+
 JS_PUBLIC_API(void *)
 JS_GetRuntimePrivate(JSRuntime *rt)
 {
     return rt->data;
 }
 
 JS_PUBLIC_API(void)
 JS_SetRuntimePrivate(JSRuntime *rt, void *data)
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1765,47 +1765,16 @@ JS_IsBuiltinFunctionConstructor(JSFuncti
  */
 
 typedef enum JSUseHelperThreads
 {
     JS_NO_HELPER_THREADS,
     JS_USE_HELPER_THREADS
 } JSUseHelperThreads;
 
-/**
- * Initialize SpiderMonkey, returning true only if initialization succeeded.
- * Once this method has succeeded, it is safe to call JS_NewRuntime and other
- * JSAPI methods.
- *
- * This method must be called before any other JSAPI method is used on any
- * thread.  Once it has been used, it is safe to call any JSAPI method, and it
- * remains safe to do so until JS_ShutDown is correctly called.
- */
-extern JS_PUBLIC_API(JSBool)
-JS_Init(void);
-
-/**
- * Destroy free-standing resources allocated by SpiderMonkey, not associated
- * with any runtime, context, or other structure.
- *
- * This method should be called after all other JSAPI data has been properly
- * cleaned up: every new runtime must have been destroyed, every new context
- * must have been destroyed, and so on.  Calling this method before all other
- * resources have been destroyed has undefined behavior.
- *
- * Failure to call this method, at present, has no adverse effects other than
- * leaking memory.  This may not always be the case; it's recommended that all
- * embedders call this method when all other JSAPI operations have completed.
- *
- * It is safe to call JS_Init again, and then to resume using SpiderMonkey as
- * usual, once this method has returned.
- */
-extern JS_PUBLIC_API(void)
-JS_ShutDown(void);
-
 extern JS_PUBLIC_API(JSRuntime *)
 JS_NewRuntime(uint32_t maxbytes, JSUseHelperThreads useHelperThreads);
 
 extern JS_PUBLIC_API(void)
 JS_DestroyRuntime(JSRuntime *rt);
 
 // These are equivalent to ICU's |UMemAllocFn|, |UMemReallocFn|, and
 // |UMemFreeFn| types.  The first argument (called |context| in the ICU docs)
@@ -1814,16 +1783,19 @@ typedef void *(*JS_ICUAllocFn)(const voi
 typedef void *(*JS_ICUReallocFn)(const void *, void *p, size_t size);
 typedef void (*JS_ICUFreeFn)(const void *, void *p);
 
 // This function can be used to track memory used by ICU.
 // Do not use it unless you know what you are doing!
 extern JS_PUBLIC_API(bool)
 JS_SetICUMemoryFunctions(JS_ICUAllocFn allocFn, JS_ICUReallocFn reallocFn, JS_ICUFreeFn freeFn);
 
+extern JS_PUBLIC_API(void)
+JS_ShutDown(void);
+
 JS_PUBLIC_API(void *)
 JS_GetRuntimePrivate(JSRuntime *rt);
 
 extern JS_PUBLIC_API(JSRuntime *)
 JS_GetRuntime(JSContext *cx);
 
 JS_PUBLIC_API(void)
 JS_SetRuntimePrivate(JSRuntime *rt, void *data);
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -199,16 +199,18 @@ JS_DefineFunctionsWithHelp(JSContext *cx
 typedef bool (* JS_SourceHook)(JSContext *cx, JS::Handle<JSScript*> script,
                                jschar **src, uint32_t *length);
 
 extern JS_FRIEND_API(void)
 JS_SetSourceHook(JSRuntime *rt, JS_SourceHook hook);
 
 namespace js {
 
+extern mozilla::ThreadLocal<PerThreadData *> TlsPerThreadData;
+
 inline JSRuntime *
 GetRuntime(const JSContext *cx)
 {
     return ContextFriendFields::get(cx)->runtime_;
 }
 
 inline JSCompartment *
 GetContextCompartment(const JSContext *cx)
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -5417,20 +5417,16 @@ main(int argc, char **argv, char **envp)
         OOM_printAllocationCount = true;
 
 #if defined(JS_CPU_X86)
     if (op.getBoolOption("no-fpu"))
         JSC::MacroAssembler::SetFloatingPointDisabled();
 #endif
 #endif
 
-    // Start the engine.
-    if (!JS_Init())
-        return 1;
-
     /* Use the same parameters as the browser in xpcjsruntime.cpp. */
     rt = JS_NewRuntime(32L * 1024L * 1024L, JS_USE_HELPER_THREADS);
     if (!rt)
         return 1;
     gTimeoutFunc = NullValue();
     if (!JS_AddNamedValueRootRT(rt, &gTimeoutFunc, "gTimeoutFunc"))
         return 1;
 
deleted file mode 100644
--- a/js/src/tests/ecma_6/Expressions/binary-literals.js
+++ /dev/null
@@ -1,115 +0,0 @@
-// Any copyright is dedicated to the Public Domain.
-// http://creativecommons.org/licenses/publicdomain/
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 894026;
-var summary = "Implement ES6 binary literals";
-
-print(BUGNUMBER + ": " + summary);
-
-/**************
- * BEGIN TEST *
- **************/
-
-var chars = ['b', 'B'];
-
-for (var i = 0; i < 2; i++)
-{
-  if (i === 2)
-  {
-    chars.forEach(function(v)
-    {
-      try
-      {
-        eval('0' + v + i);
-        throw "didn't throw";
-      }
-      catch (e)
-      {
-        assertEq(e instanceof SyntaxError, true,
-                 "no syntax error evaluating 0" + v + i + ", " +
-                 "got " + e);
-      }
-    });
-    continue;
-  }
-
-  for (var j = 0; j < 2; j++)
-  {
-    if (j === 2)
-    {
-      chars.forEach(function(v)
-      {
-        try
-        {
-          eval('0' + v + i + j);
-          throw "didn't throw";
-        }
-        catch (e)
-        {
-          assertEq(e instanceof SyntaxError, true,
-                   "no syntax error evaluating 0" + v + i + j + ", " +
-                   "got " + e);
-        }
-      });
-      continue;
-    }
-
-    for (var k = 0; k < 2; k++)
-    {
-      if (k === 2)
-      {
-        chars.forEach(function(v)
-        {
-          try
-          {
-            eval('0' + v + i + j + k);
-            throw "didn't throw";
-          }
-          catch (e)
-          {
-            assertEq(e instanceof SyntaxError, true,
-                     "no syntax error evaluating 0" + v + i + j + k + ", " +
-                     "got " + e);
-          }
-        });
-        continue;
-      }
-
-      chars.forEach(function(v)
-      {
-        assertEq(eval('0' + v + i + j + k), i * 4 + j * 2 + k);
-      });
-    }
-  }
-}
-
-chars.forEach(function(v)
-{
-  try
-  {
-  }
-  catch (e)
-  {
-    assertEq(e instanceof SyntaxError, true,
-             "no syntax error evaluating 0" + v + ", got " + e);
-  }
-});
-
-// Off-by-one check: '/' immediately precedes '0'.
-assertEq(0b110/1, 6);
-assertEq(0B10110/1, 22);
-
-function strict()
-{
-  "use strict";
-  return 0b11010101;
-}
-assertEq(strict(), 128 + 64 + 16 + 4 + 1);
-
-/******************************************************************************/
-
-if (typeof reportCompare === "function")
-  reportCompare(true, true);
-
-print("Tests complete");
deleted file mode 100644
deleted file mode 100644
--- a/js/src/tests/ecma_6/Expressions/octal-literals.js
+++ /dev/null
@@ -1,103 +0,0 @@
-// Any copyright is dedicated to the Public Domain.
-// http://creativecommons.org/licenses/publicdomain/
-
-//-----------------------------------------------------------------------------
-var BUGNUMBER = 894026;
-var summary = "Implement ES6 octal literals";
-
-print(BUGNUMBER + ": " + summary);
-
-/**************
- * BEGIN TEST *
- **************/
-
-var chars = ['o', 'O'];
-
-for (var i = 0; i < 8; i++)
-{
-  if (i === 8)
-  {
-    chars.forEach(function(v)
-    {
-      try
-      {
-        eval('0' + v + i);
-        throw "didn't throw";
-      }
-      catch (e)
-      {
-        assertEq(e instanceof SyntaxError, true,
-                 "no syntax error evaluating 0" + v + i + ", " +
-                 "got " + e);
-      }
-    });
-    continue;
-  }
-
-  for (var j = 0; j < 8; j++)
-  {
-    if (j === 8)
-    {
-      chars.forEach(function(v)
-      {
-        try
-        {
-          eval('0' + v + i + j);
-          throw "didn't throw";
-        }
-        catch (e)
-        {
-          assertEq(e instanceof SyntaxError, true,
-                   "no syntax error evaluating 0" + v + i + j + ", " +
-                   "got " + e);
-        }
-      });
-      continue;
-    }
-
-    for (var k = 0; k < 8; k++)
-    {
-      if (k === 8)
-      {
-        chars.forEach(function(v)
-        {
-          try
-          {
-            eval('0' + v + i + j + k);
-            throw "didn't throw";
-          }
-          catch (e)
-          {
-            assertEq(e instanceof SyntaxError, true,
-                     "no syntax error evaluating 0" + v + i + j + k + ", " +
-                     "got " + e);
-          }
-        });
-        continue;
-      }
-
-      chars.forEach(function(v)
-      {
-        assertEq(eval('0' + v + i + j + k), i * 64 + j * 8 + k);
-      });
-    }
-  }
-}
-
-// Off-by-one check: '/' immediately precedes '0'.
-assertEq(0o110/2, 36);
-assertEq(0O644/2, 210);
-
-function strict()
-{
-  "use strict";
-  return 0o755;
-}
-assertEq(strict(), 7 * 64 + 5 * 8 + 5);
-
-/******************************************************************************/
-
-if (typeof reportCompare === "function")
-  reportCompare(true, true);
-
-print("Tests complete");
deleted file mode 100644
--- a/js/src/vm/ForkJoin.cpp
+++ b/js/src/vm/ForkJoin.cpp
@@ -1707,19 +1707,19 @@ ForkJoinSlice::check()
     else
         return true;
 }
 
 bool
 ForkJoinSlice::InitializeTLS()
 {
     if (!TLSInitialized) {
-        if (PR_NewThreadPrivateIndex(&ThreadPrivateIndex, NULL) != PR_SUCCESS)
-            return false;
         TLSInitialized = true;
+        PRStatus status = PR_NewThreadPrivateIndex(&ThreadPrivateIndex, NULL);
+        return status == PR_SUCCESS;
     }
     return true;
 }
 
 void
 ForkJoinSlice::requestGC(JS::gcreason::Reason reason)
 {
     shared->requestGC(reason);
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -2,17 +2,16 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "vm/Runtime-inl.h"
 
 #include "mozilla/MemoryReporting.h"
-#include "mozilla/ThreadLocal.h"
 #include "mozilla/Util.h"
 
 #include <locale.h>
 #include <string.h>
 
 #include "jsatom.h"
 #include "jsgc.h"
 #include "jsmath.h"
@@ -23,23 +22,17 @@
 #include "yarr/BumpPointerAllocator.h"
 
 #include "jscntxtinlines.h"
 #include "jsgcinlines.h"
 
 using namespace js;
 using namespace js::gc;
 
-using mozilla::Atomic;
 using mozilla::PodZero;
-using mozilla::ThreadLocal;
-
-/* static */ ThreadLocal<PerThreadData*> js::TlsPerThreadData;
-
-/* static */ Atomic<size_t> JSRuntime::liveRuntimesCount;
 
 void
 NewObjectCache::clearNurseryObjects(JSRuntime *rt)
 {
     for (unsigned i = 0; i < mozilla::ArrayLength(entries); ++i) {
         Entry &e = entries[i];
         JSObject *obj = reinterpret_cast<JSObject *>(&e.templateObject);
         if (IsInsideNursery(rt, e.key) ||
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -2,22 +2,20 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef vm_Runtime_h
 #define vm_Runtime_h
 
-#include "mozilla/Atomics.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/PodOperations.h"
 #include "mozilla/TemplateLib.h"
-#include "mozilla/ThreadLocal.h"
 
 #include <setjmp.h>
 #include <string.h>
 
 #include "jsapi.h"
 #include "jsatom.h"
 #include "jsclist.h"
 #include "jsfriendapi.h"
@@ -39,23 +37,16 @@
 
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable:4100) /* Silence unreferenced formal parameter warnings */
 #pragma warning(push)
 #pragma warning(disable:4355) /* Silence warning about "this" used in base member initializer list */
 #endif
 
-namespace js {
-
-/* Thread Local Storage slot for storing the runtime for a thread. */
-extern mozilla::ThreadLocal<PerThreadData*> TlsPerThreadData;
-
-} // namespace js
-
 struct DtoaState;
 
 extern void
 js_ReportOutOfMemory(js::ThreadSafeContext *cx);
 
 extern void
 js_ReportAllocationOverflow(js::ThreadSafeContext *cx);
 
@@ -1425,23 +1416,17 @@ struct JSRuntime : public JS::shadow::Ru
     //
     // To allow the GetPropertyCacheT optimization, we allow the ability for
     // GetPropertyCache to override the return value at the top of the stack - the
     // value that will be temporarily corrupt. This special override value is set
     // only in callVM() targets that are about to return *and* have invalidated
     // their callee.
     js::Value            ionReturnOverride_;
 
-    static mozilla::Atomic<size_t> liveRuntimesCount;
-
   public:
-    static bool hasLiveRuntimes() {
-        return liveRuntimesCount > 0;
-    }
-
     bool hasIonReturnOverride() const {
         return !ionReturnOverride_.isMagic();
     }
     js::Value takeIonReturnOverride() {
         js::Value v = ionReturnOverride_;
         ionReturnOverride_ = js::MagicValue(JS_ARG_POISON);
         return v;
     }
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -1414,16 +1414,17 @@ XPCJSRuntime::~XPCJSRuntime()
 #ifdef XPC_DUMP_AT_SHUTDOWN
         uint32_t count = mDetachedWrappedNativeProtoMap->Count();
         if (count)
             printf("deleting XPCJSRuntime with %d live detached XPCWrappedNativeProto\n", (int)count);
 #endif
         delete mDetachedWrappedNativeProtoMap;
     }
 
+    JS_ShutDown();
 #ifdef MOZ_ENABLE_PROFILER_SPS
     // Tell the profiler that the runtime is gone
     if (PseudoStack *stack = mozilla_get_pseudo_stack())
         stack->sampleRuntime(nullptr);
 #endif
 
 #ifdef DEBUG
     for (uint32_t i = 0; i < XPCCCX_STRING_CACHE_SIZE; ++i) {
--- a/mfbt/GuardObjects.h
+++ b/mfbt/GuardObjects.h
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Implementation of macros to ensure correct use of RAII Auto* objects. */
 
 #ifndef mozilla_GuardObjects_h
 #define mozilla_GuardObjects_h
 
 #include "mozilla/Assertions.h"
-#include "mozilla/NullPtr.h"
 #include "mozilla/Types.h"
 
 #ifdef __cplusplus
 
 #ifdef DEBUG
 
 namespace mozilla {
 namespace detail {
@@ -69,17 +68,17 @@ namespace detail {
  * https://developer.mozilla.org/en/Using_RAII_classes_in_Mozilla
  */
 class MOZ_EXPORT GuardObjectNotifier
 {
   private:
     bool* statementDone;
 
   public:
-    GuardObjectNotifier() : statementDone(nullptr) { }
+    GuardObjectNotifier() : statementDone(NULL) { }
 
     ~GuardObjectNotifier() {
       *statementDone = true;
     }
 
     void setStatementDone(bool* statementIsDone) {
       statementDone = statementIsDone;
     }
--- a/mfbt/LinkedList.h
+++ b/mfbt/LinkedList.h
@@ -41,45 +41,44 @@
  *       void removeObserver(Observer* observer) {
  *         // Will assert if |observer| is not part of some list.
  *         observer.remove();
  *         // Or, will assert if |observer| is not part of |list| specifically.
  *         // observer.removeFrom(list);
  *       }
  *
  *       void notifyObservers(char* topic) {
- *         for (Observer* o = list.getFirst(); o != nullptr; o = o->getNext())
- *           o->observe(topic);
+ *         for (Observer* o = list.getFirst(); o != NULL; o = o->getNext())
+ *           o->Observe(topic);
  *       }
  *   };
  *
  */
 
 #ifndef mozilla_LinkedList_h
 #define mozilla_LinkedList_h
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
-#include "mozilla/NullPtr.h"
 
 #ifdef __cplusplus
 
 namespace mozilla {
 
 template<typename T>
 class LinkedList;
 
 template<typename T>
 class LinkedListElement
 {
     /*
-     * It's convenient that we return nullptr when getNext() or getPrevious()
-     * hits the end of the list, but doing so costs an extra word of storage in
-     * each linked list node (to keep track of whether |this| is the sentinel
-     * node) and a branch on this value in getNext/getPrevious.
+     * It's convenient that we return NULL when getNext() or getPrevious() hits
+     * the end of the list, but doing so costs an extra word of storage in each
+     * linked list node (to keep track of whether |this| is the sentinel node)
+     * and a branch on this value in getNext/getPrevious.
      *
      * We could get rid of the extra word of storage by shoving the "is
      * sentinel" bit into one of the pointers, although this would, of course,
      * have performance implications of its own.
      *
      * But the goal here isn't to win an award for the fastest or slimmest
      * linked list; rather, we want a *convenient* linked list.  So we won't
      * waste time guessing which micro-optimization strategy is best.
@@ -117,29 +116,29 @@ class LinkedListElement
     { }
 
     ~LinkedListElement() {
       if (!isSentinel && isInList())
         remove();
     }
 
     /*
-     * Get the next element in the list, or nullptr if this is the last element
-     * in the list.
+     * Get the next element in the list, or NULL if this is the last element in
+     * the list.
      */
     T* getNext() {
       return next->asT();
     }
     const T* getNext() const {
       return next->asT();
     }
 
     /*
-     * Get the previous element in the list, or nullptr if this is the first
-     * element in the list.
+     * Get the previous element in the list, or NULL if this is the first element
+     * in the list.
      */
     T* getPrevious() {
       return prev->asT();
     }
     const T* getPrevious() const {
       return prev->asT();
     }
 
@@ -202,28 +201,28 @@ class LinkedListElement
 
     LinkedListElement(NodeKind nodeKind)
       : next(MOZ_THIS_IN_INITIALIZER_LIST()),
         prev(MOZ_THIS_IN_INITIALIZER_LIST()),
         isSentinel(nodeKind == NODE_KIND_SENTINEL)
     { }
 
     /*
-     * Return |this| cast to T* if we're a normal node, or return nullptr if
-     * we're a sentinel node.
+     * Return |this| cast to T* if we're a normal node, or return NULL if we're
+     * a sentinel node.
      */
     T* asT() {
       if (isSentinel)
-        return nullptr;
+        return NULL;
 
       return static_cast<T*>(this);
     }
     const T* asT() const {
       if (isSentinel)
-        return nullptr;
+        return NULL;
 
       return static_cast<const T*>(this);
     }
 
     /*
      * Insert elem after this element, but don't check that this element is in
      * the list.  This is called by LinkedList::insertFront().
      */
@@ -280,49 +279,49 @@ class LinkedList
     /*
      * Add elem to the back of the list.
      */
     void insertBack(T* elem) {
       sentinel.setPreviousUnsafe(elem);
     }
 
     /*
-     * Get the first element of the list, or nullptr if the list is empty.
+     * Get the first element of the list, or NULL if the list is empty.
      */
     T* getFirst() {
       return sentinel.getNext();
     }
     const T* getFirst() const {
       return sentinel.getNext();
     }
 
     /*
-     * Get the last element of the list, or nullptr if the list is empty.
+     * Get the last element of the list, or NULL if the list is empty.
      */
     T* getLast() {
       return sentinel.getPrevious();
     }
     const T* getLast() const {
       return sentinel.getPrevious();
     }
 
     /*
      * Get and remove the first element of the list.  If the list is empty,
-     * return nullptr.
+     * return NULL.
      */
     T* popFirst() {
       T* ret = sentinel.getNext();
       if (ret)
         static_cast<LinkedListElement<T>*>(ret)->remove();
       return ret;
     }
 
     /*
      * Get and remove the last element of the list.  If the list is empty,
-     * return nullptr.
+     * return NULL.
      */
     T* popLast() {
       T* ret = sentinel.getPrevious();
       if (ret)
         static_cast<LinkedListElement<T>*>(ret)->remove();
       return ret;
     }
 
--- a/mfbt/RangedPtr.h
+++ b/mfbt/RangedPtr.h
@@ -9,17 +9,16 @@
  * construction.
  */
 
 #ifndef mozilla_RangedPtr_h
 #define mozilla_RangedPtr_h
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
-#include "mozilla/NullPtr.h"
 #include "mozilla/Util.h"
 
 namespace mozilla {
 
 /*
  * RangedPtr is a smart pointer restricted to an address range specified at
  * creation.  The pointer (and any smart pointers derived from it) must remain
  * within the range [start, end] (inclusive of end to facilitate use as
@@ -56,17 +55,17 @@ class RangedPtr
       MOZ_ASSERT(ptr <= rangeEnd);
     }
 
     /* Creates a new pointer for |p|, restricted to this pointer's range. */
     RangedPtr<T> create(T *p) const {
 #ifdef DEBUG
       return RangedPtr<T>(p, rangeStart, rangeEnd);
 #else
-      return RangedPtr<T>(p, nullptr, size_t(0));
+      return RangedPtr<T>(p, NULL, size_t(0));
 #endif
     }
 
     uintptr_t asUintptr() const { return uintptr_t(ptr); }
 
   public:
     RangedPtr(T* p, T* start, T* end)
       : ptr(p)
--- a/mfbt/Scoped.h
+++ b/mfbt/Scoped.h
@@ -49,17 +49,16 @@
  * and |MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE|  to simplify the definition
  * of RAII classes for other scenarios. These macros have been used to
  * automatically close file descriptors/file handles when reaching the end of
  * the scope, graphics contexts, etc.
  */
 
 #include "mozilla/Attributes.h"
 #include "mozilla/GuardObjects.h"
-#include "mozilla/NullPtr.h"
 
 namespace mozilla {
 
 /*
  * Scoped is a helper to create RAII wrappers
  * Type argument |Traits| is expected to have the following structure:
  *
  *   struct Traits {
@@ -191,17 +190,17 @@ struct name : public mozilla::Scoped<Tra
  *   struct S { ... };
  *   ScopedFreePtr<S> foo = malloc(sizeof(S));
  *   ScopedFreePtr<char> bar = strdup(str);
  */
 template<typename T>
 struct ScopedFreePtrTraits
 {
     typedef T* type;
-    static T* empty() { return nullptr; }
+    static T* empty() { return NULL; }
     static void release(T* ptr) { free(ptr); }
 };
 SCOPED_TEMPLATE(ScopedFreePtr, ScopedFreePtrTraits)
 
 /*
  * ScopedDeletePtr is a RAII wrapper for pointers that need to be deleted.
  *
  *   struct S { ... };
@@ -254,17 +253,17 @@ template <> inline void TypeSpecificDele
 typedef ::mozilla::TypeSpecificScopedPointer<Type> name;
 
 template <typename T> void TypeSpecificDelete(T * value);
 
 template <typename T>
 struct TypeSpecificScopedPointerTraits
 {
     typedef T* type;
-    const static type empty() { return nullptr; }
+    const static type empty() { return NULL; }
     const static void release(type value)
     {
       if (value)
         TypeSpecificDelete(value);
     }
 };
 
 SCOPED_TEMPLATE(TypeSpecificScopedPointer, TypeSpecificScopedPointerTraits)
--- a/mfbt/ThreadLocal.h
+++ b/mfbt/ThreadLocal.h
@@ -24,17 +24,16 @@ extern "C" {
 }
 #else
 #  include <pthread.h>
 #  include <signal.h>
 #endif
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
-#include "mozilla/NullPtr.h"
 
 namespace mozilla {
 
 // sig_safe_t denotes an atomic type which can be read or stored in a single
 // instruction.  This means that data of this type is safe to be manipulated
 // from a signal handler, or other similar asynchronous execution contexts.
 #if defined(XP_WIN)
 typedef unsigned long sig_safe_t;
@@ -103,17 +102,17 @@ ThreadLocal<T>::init()
   MOZ_STATIC_ASSERT(sizeof(T) <= sizeof(void*),
                     "mozilla::ThreadLocal can't be used for types larger than "
                     "a pointer");
   MOZ_ASSERT(!initialized());
 #ifdef XP_WIN
   key = TlsAlloc();
   inited = key != 0xFFFFFFFFUL; // TLS_OUT_OF_INDEXES
 #else
-  inited = !pthread_key_create(&key, nullptr);
+  inited = !pthread_key_create(&key, NULL);
 #endif
   return inited;
 }
 
 template<typename T>
 inline T
 ThreadLocal<T>::get() const
 {
--- a/mfbt/Vector.h
+++ b/mfbt/Vector.h
@@ -1045,17 +1045,17 @@ VectorBase<T, N, AP, TV>::popCopy()
 template<typename T, size_t N, class AP, class TV>
 inline T*
 VectorBase<T, N, AP, TV>::extractRawBuffer()
 {
   T* ret;
   if (usingInlineStorage()) {
     ret = reinterpret_cast<T*>(this->malloc_(mLength * sizeof(T)));
     if (!ret)
-      return nullptr;
+        return NULL;
     Impl::copyConstruct(ret, beginNoCheck(), endNoCheck());
     Impl::destroy(beginNoCheck(), endNoCheck());
     /* mBegin, mCapacity are unchanged. */
     mLength = 0;
   } else {
     ret = mBegin;
     mBegin = static_cast<T*>(storage.addr());
     mLength = 0;
@@ -1100,24 +1100,24 @@ VectorBase<T, N, AP, TV>::replaceRawBuff
   mReserved = aLength;
 #endif
 }
 
 template<typename T, size_t N, class AP, class TV>
 inline size_t
 VectorBase<T, N, AP, TV>::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const
 {
-  return usingInlineStorage() ? 0 : mallocSizeOf(beginNoCheck());
+    return usingInlineStorage() ? 0 : mallocSizeOf(beginNoCheck());
 }
 
 template<typename T, size_t N, class AP, class TV>
 inline size_t
 VectorBase<T, N, AP, TV>::sizeOfIncludingThis(MallocSizeOf mallocSizeOf) const
 {
-  return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf);
+    return mallocSizeOf(this) + sizeOfExcludingThis(mallocSizeOf);
 }
 
 template<typename T, size_t N, class AP, class TV>
 inline void
 VectorBase<T, N, AP, TV>::swap(TV& other)
 {
   MOZ_STATIC_ASSERT(N == 0,
                     "still need to implement this for N != 0");
--- a/mfbt/tests/TestPoisonArea.cpp
+++ b/mfbt/tests/TestPoisonArea.cpp
@@ -74,18 +74,16 @@
  *    *64*-bit processes on Linux - and we don't even run this code for
  *    64-bit processes.
  *
  * 4. VirtualQuery() does not produce any useful information if
  *    applied to kernel memory - in fact, it doesn't write its output
  *    at all.  Thus, it is not used here.
  */
 
-#include "mozilla/NullPtr.h"
-
 // MAP_ANON(YMOUS) is not in any standard, and the C99 PRI* macros are
 // not in C++98.  Add defines as necessary.
 #define __STDC_FORMAT_MACROS
 #define _GNU_SOURCE 1
 #define _DARWIN_C_SOURCE 1
 
 #include <stddef.h>
 
@@ -192,18 +190,18 @@ static const ia64_instr _return_instr =
 // Uses of this function deliberately leak the string.
 static LPSTR
 StrW32Error(DWORD errcode)
 {
   LPSTR errmsg;
   FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                  FORMAT_MESSAGE_FROM_SYSTEM |
                  FORMAT_MESSAGE_IGNORE_INSERTS,
-                 nullptr, errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-                 (LPSTR)&errmsg, 0, nullptr);
+                 NULL, errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                 (LPSTR) &errmsg, 0, NULL);
 
   // FormatMessage puts an unwanted newline at the end of the string
   size_t n = strlen(errmsg)-1;
   while (errmsg[n] == '\r' || errmsg[n] == '\n') n--;
   errmsg[n+1] = '\0';
   return errmsg;
 }
 #define LastErrMsg() (StrW32Error(GetLastError()))
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -123,18 +123,16 @@ extern nsresult nsStringInputStreamConst
 #include "mozilla/ClearOnShutdown.h"
 
 #ifdef MOZ_VISUAL_EVENT_TRACER
 #include "mozilla/VisualEventTracer.h"
 #endif
 
 #include "GeckoProfiler.h"
 
-#include "jsapi.h"
-
 using namespace mozilla;
 using base::AtExitManager;
 using mozilla::ipc::BrowserProcessSubThread;
 #ifdef MOZ_VISUAL_EVENT_TRACER
 using mozilla::eventtracer::VisualEventTracer;
 #endif
 
 namespace {
@@ -461,21 +459,16 @@ NS_InitXPCOM2(nsIServiceManager* *result
     if (!nsCycleCollector_init()) {
         return NS_ERROR_UNEXPECTED;
     }
 
     // And start it up for this thread too.
     rv = nsCycleCollector_startup(CCSingleThread);
     if (NS_FAILED(rv)) return rv;
 
-    // Initialize the JS engine.
-    if (!JS_Init()) {
-        NS_RUNTIMEABORT("JS_Init failed");
-    }
-
     rv = nsComponentManagerImpl::gComponentManager->Init();
     if (NS_FAILED(rv))
     {
         NS_RELEASE(nsComponentManagerImpl::gComponentManager);
         return rv;
     }
 
     if (result) {
@@ -695,22 +688,18 @@ ShutdownXPCOM(nsIServiceManager* servMgr
     NS_ShutdownNativeCharsetUtils();
 #endif
 
     // Shutdown xpcom. This will release all loaders and cause others holding
     // a refcount to the component manager to release it.
     if (nsComponentManagerImpl::gComponentManager) {
         rv = (nsComponentManagerImpl::gComponentManager)->Shutdown();
         NS_ASSERTION(NS_SUCCEEDED(rv), "Component Manager shutdown failed.");
-    } else {
+    } else
         NS_WARNING("Component Manager was never created ...");
-    }
-
-    // Shut down the JS engine.
-    JS_ShutDown();
 
     // Release our own singletons
     // Do this _after_ shutting down the component manager, because the
     // JS component loader will use XPConnect to call nsIModule::canUnload,
     // and that will spin up the InterfaceInfoManager again -- bad mojo
     XPTInterfaceInfoManager::FreeInterfaceInfoManager();
 
     // Finally, release the component manager last because it unloads the