diff --git a/caps/src/nsNullPrincipal.cpp b/caps/src/nsNullPrincipal.cpp index 639e064051fe..4c4191acbaff 100644 --- a/caps/src/nsNullPrincipal.cpp +++ b/caps/src/nsNullPrincipal.cpp @@ -35,11 +35,11 @@ NS_IMPL_CI_INTERFACE_GETTER2(nsNullPrincipal, nsIPrincipal, nsISerializable) -NS_IMETHODIMP_(nsrefcnt) +NS_IMETHODIMP_(nsrefcnt) nsNullPrincipal::AddRef() { NS_PRECONDITION(int32_t(refcount) >= 0, "illegal refcnt"); - nsrefcnt count = PR_ATOMIC_INCREMENT(&refcount); + nsrefcnt count = ++refcount; NS_LOG_ADDREF(this, count, "nsNullPrincipal", sizeof(*this)); return count; } @@ -48,7 +48,7 @@ NS_IMETHODIMP_(nsrefcnt) nsNullPrincipal::Release() { NS_PRECONDITION(0 != refcount, "dup release"); - nsrefcnt count = PR_ATOMIC_DECREMENT(&refcount); + nsrefcnt count = --refcount; NS_LOG_RELEASE(this, count, "nsNullPrincipal"); if (count == 0) { delete this; diff --git a/caps/src/nsPrincipal.cpp b/caps/src/nsPrincipal.cpp index ba02280324aa..21b44f3b045b 100644 --- a/caps/src/nsPrincipal.cpp +++ b/caps/src/nsPrincipal.cpp @@ -51,7 +51,7 @@ nsBasePrincipal::AddRef() { NS_PRECONDITION(int32_t(refcount) >= 0, "illegal refcnt"); // XXXcaa does this need to be threadsafe? See bug 143559. - nsrefcnt count = PR_ATOMIC_INCREMENT(&refcount); + nsrefcnt count = ++refcount; NS_LOG_ADDREF(this, count, "nsBasePrincipal", sizeof(*this)); return count; } @@ -60,7 +60,7 @@ NS_IMETHODIMP_(nsrefcnt) nsBasePrincipal::Release() { NS_PRECONDITION(0 != refcount, "dup release"); - nsrefcnt count = PR_ATOMIC_DECREMENT(&refcount); + nsrefcnt count = --refcount; NS_LOG_RELEASE(this, count, "nsBasePrincipal"); if (count == 0) { delete this; diff --git a/caps/src/nsSystemPrincipal.cpp b/caps/src/nsSystemPrincipal.cpp index 4b9b7a1e986d..3e270bd2d64e 100644 --- a/caps/src/nsSystemPrincipal.cpp +++ b/caps/src/nsSystemPrincipal.cpp @@ -29,11 +29,11 @@ NS_IMPL_CI_INTERFACE_GETTER2(nsSystemPrincipal, nsIPrincipal, nsISerializable) -NS_IMETHODIMP_(nsrefcnt) +NS_IMETHODIMP_(nsrefcnt) nsSystemPrincipal::AddRef() { NS_PRECONDITION(int32_t(refcount) >= 0, "illegal refcnt"); - nsrefcnt count = PR_ATOMIC_INCREMENT(&refcount); + nsrefcnt count = ++refcount; NS_LOG_ADDREF(this, count, "nsSystemPrincipal", sizeof(*this)); return count; } @@ -42,7 +42,7 @@ NS_IMETHODIMP_(nsrefcnt) nsSystemPrincipal::Release() { NS_PRECONDITION(0 != refcount, "dup release"); - nsrefcnt count = PR_ATOMIC_DECREMENT(&refcount); + nsrefcnt count = --refcount; NS_LOG_RELEASE(this, count, "nsSystemPrincipal"); if (count == 0) { delete this; diff --git a/dom/workers/Principal.cpp b/dom/workers/Principal.cpp index 66343b831552..b16bd590e627 100644 --- a/dom/workers/Principal.cpp +++ b/dom/workers/Principal.cpp @@ -9,21 +9,20 @@ BEGIN_WORKERS_NAMESPACE -namespace { - -JSPrincipals gPrincipal = { - 1 -#ifdef DEBUG - , kJSPrincipalsDebugToken -#endif -}; - -} // anonymous namespace - JSPrincipals* GetWorkerPrincipal() { - return &gPrincipal; + static Atomic sInitialized(0); + static JSPrincipals sPrincipal; + + uint32_t isInitialized = sInitialized.exchange(1); + if (!isInitialized) { + sPrincipal.refcount = 1; +#ifdef DEBUG + sPrincipal.debugToken = kJSPrincipalsDebugToken; +#endif + } + return &sPrincipal; } END_WORKERS_NAMESPACE diff --git a/js/src/frontend/TokenStream.cpp b/js/src/frontend/TokenStream.cpp index 712042accfc8..bb524fe2bd5e 100644 --- a/js/src/frontend/TokenStream.cpp +++ b/js/src/frontend/TokenStream.cpp @@ -287,7 +287,7 @@ TokenStream::TokenStream(ExclusiveContext *cx, const ReadOnlyCompileOptions &opt // The caller must ensure that a reference is held on the supplied principals // throughout compilation. - JS_ASSERT_IF(originPrincipals, originPrincipals->refcount); + JS_ASSERT_IF(originPrincipals, originPrincipals->refcount > 0); // Column numbers are computed as offsets from the current line's base, so the // initial line's base must be included in the buffer. linebase and userbuf diff --git a/js/src/jsapi-tests/testChromeBuffer.cpp b/js/src/jsapi-tests/testChromeBuffer.cpp index b282fc3eedad..301a63300349 100644 --- a/js/src/jsapi-tests/testChromeBuffer.cpp +++ b/js/src/jsapi-tests/testChromeBuffer.cpp @@ -6,9 +6,7 @@ #include "jsapi-tests/tests.h" -static JSPrincipals system_principals = { - 1 -}; +static TestJSPrincipals system_principals(1); static const JSClass global_class = { "global", diff --git a/js/src/jsapi-tests/testOriginPrincipals.cpp b/js/src/jsapi-tests/testOriginPrincipals.cpp index adec48b8df8b..ccbc2e8da51e 100644 --- a/js/src/jsapi-tests/testOriginPrincipals.cpp +++ b/js/src/jsapi-tests/testOriginPrincipals.cpp @@ -6,8 +6,8 @@ #include "jsapi-tests/tests.h" static JSPrincipals *sOriginPrincipalsInErrorReporter = nullptr; -static JSPrincipals prin1 = { 1 }; -static JSPrincipals prin2 = { 1 }; +static TestJSPrincipals prin1(1); +static TestJSPrincipals prin2(1); BEGIN_TEST(testOriginPrincipals) { diff --git a/js/src/jsapi-tests/testXDR.cpp b/js/src/jsapi-tests/testXDR.cpp index aaa0126103e7..7acbe3d7a212 100644 --- a/js/src/jsapi-tests/testXDR.cpp +++ b/js/src/jsapi-tests/testXDR.cpp @@ -76,10 +76,8 @@ FreezeThaw(JSContext *cx, JS::HandleObject funobj) return funobj2; } -static JSPrincipals testPrincipals[] = { - { 1 }, - { 1 }, -}; +static TestJSPrincipals testPrincipal0(1); +static TestJSPrincipals testPrincipal1(1); BEGIN_TEST(testXDR_principals) { @@ -88,21 +86,21 @@ BEGIN_TEST(testXDR_principals) for (int i = TEST_FIRST; i != TEST_END; ++i) { // Appease the new JSAPI assertions. The stuff being tested here is // going away anyway. - JS_SetCompartmentPrincipals(compartment, &testPrincipals[0]); - script = createScriptViaXDR(&testPrincipals[0], nullptr, i); + JS_SetCompartmentPrincipals(compartment, &testPrincipal0); + script = createScriptViaXDR(&testPrincipal0, nullptr, i); CHECK(script); - CHECK(JS_GetScriptPrincipals(script) == &testPrincipals[0]); - CHECK(JS_GetScriptOriginPrincipals(script) == &testPrincipals[0]); + CHECK(JS_GetScriptPrincipals(script) == &testPrincipal0); + CHECK(JS_GetScriptOriginPrincipals(script) == &testPrincipal0); - script = createScriptViaXDR(&testPrincipals[0], &testPrincipals[0], i); + script = createScriptViaXDR(&testPrincipal0, &testPrincipal0, i); CHECK(script); - CHECK(JS_GetScriptPrincipals(script) == &testPrincipals[0]); - CHECK(JS_GetScriptOriginPrincipals(script) == &testPrincipals[0]); + CHECK(JS_GetScriptPrincipals(script) == &testPrincipal0); + CHECK(JS_GetScriptOriginPrincipals(script) == &testPrincipal0); - script = createScriptViaXDR(&testPrincipals[0], &testPrincipals[1], i); + script = createScriptViaXDR(&testPrincipal0, &testPrincipal1, i); CHECK(script); - CHECK(JS_GetScriptPrincipals(script) == &testPrincipals[0]); - CHECK(JS_GetScriptOriginPrincipals(script) == &testPrincipals[1]); + CHECK(JS_GetScriptPrincipals(script) == &testPrincipal0); + CHECK(JS_GetScriptOriginPrincipals(script) == &testPrincipal1); } return true; diff --git a/js/src/jsapi-tests/tests.h b/js/src/jsapi-tests/tests.h index 517e3603aae2..07b640e4033f 100644 --- a/js/src/jsapi-tests/tests.h +++ b/js/src/jsapi-tests/tests.h @@ -400,4 +400,15 @@ class TempFile { } }; +// Just a wrapper around JSPrincipals that allows static construction. +class TestJSPrincipals : public JSPrincipals +{ + public: + TestJSPrincipals(int rc = 0) + : JSPrincipals() + { + refcount = rc; + } +}; + #endif /* jsapi_tests_tests_h */ diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 5347edfb74b3..b878ffcc6fd9 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -3864,13 +3864,13 @@ JS_CheckAccess(JSContext *cx, JSObject *objArg, jsid idArg, JSAccessMode mode, JS_PUBLIC_API(void) JS_HoldPrincipals(JSPrincipals *principals) { - JS_ATOMIC_INCREMENT(&principals->refcount); + ++principals->refcount; } JS_PUBLIC_API(void) JS_DropPrincipals(JSRuntime *rt, JSPrincipals *principals) { - int rc = JS_ATOMIC_DECREMENT(&principals->refcount); + int rc = --principals->refcount; if (rc == 0) rt->destroyPrincipals(principals); } diff --git a/js/src/jsapi.h b/js/src/jsapi.h index eca78dbc00dd..6acda9c9a245 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -9,6 +9,7 @@ #ifndef jsapi_h #define jsapi_h +#include "mozilla/Atomics.h" #include "mozilla/FloatingPoint.h" #include "mozilla/MemoryReporting.h" #include "mozilla/RangedPtr.h" @@ -3155,7 +3156,11 @@ JS_SetReservedSlot(JSObject *obj, uint32_t index, jsval v); */ struct JSPrincipals { /* Don't call "destroy"; use reference counting macros below. */ - int refcount; +#ifdef JS_THREADSAFE + mozilla::Atomic refcount; +#else + int32_t refcount; +#endif #ifdef DEBUG /* A helper to facilitate principals debugging. */ diff --git a/js/src/jslock.h b/js/src/jslock.h index 3d156ff7fc6b..40fca30fc5b6 100644 --- a/js/src/jslock.h +++ b/js/src/jslock.h @@ -15,7 +15,6 @@ #else /* JS_POSIX_NSPR */ -# include "pratom.h" # include "prcvar.h" # include "prinit.h" # include "prlock.h" @@ -23,22 +22,12 @@ #endif -# define JS_ATOMIC_INCREMENT(p) PR_ATOMIC_INCREMENT((int32_t *)(p)) -# define JS_ATOMIC_DECREMENT(p) PR_ATOMIC_DECREMENT((int32_t *)(p)) -# define JS_ATOMIC_ADD(p,v) PR_ATOMIC_ADD((int32_t *)(p), (int32_t)(v)) -# define JS_ATOMIC_SET(p,v) PR_ATOMIC_SET((int32_t *)(p), (int32_t)(v)) - #else /* JS_THREADSAFE */ typedef struct PRThread PRThread; typedef struct PRCondVar PRCondVar; typedef struct PRLock PRLock; -# define JS_ATOMIC_INCREMENT(p) (++*(p)) -# define JS_ATOMIC_DECREMENT(p) (--*(p)) -# define JS_ATOMIC_ADD(p,v) (*(p) += (v)) -# define JS_ATOMIC_SET(p,v) (*(p) = (v)) - #endif /* JS_THREADSAFE */ #endif /* jslock_h */ diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 09623d5145ad..fddb278c4697 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -5652,9 +5652,6 @@ MaybeOverrideOutFileFromEnv(const char* const envVar, } } -/* Set the initial counter to 1 so the principal will never be destroyed. */ -static const JSPrincipals shellTrustedPrincipals = { 1 }; - static bool CheckObjectAccess(JSContext *cx, HandleObject obj, HandleId id, JSAccessMode mode, MutableHandleValue vp) @@ -5885,6 +5882,10 @@ main(int argc, char **argv, char **envp) JS::DisableGenerationalGC(rt); #endif + /* Set the initial counter to 1 so the principal will never be destroyed. */ + JSPrincipals shellTrustedPrincipals; + shellTrustedPrincipals.refcount = 1; + JS_SetTrustedPrincipals(rt, &shellTrustedPrincipals); JS_SetSecurityCallbacks(rt, &securityCallbacks); JS_SetOperationCallback(rt, ShellOperationCallback); diff --git a/js/src/vm/PosixNSPR.h b/js/src/vm/PosixNSPR.h index b602a5cd427e..b49da8ed5b7f 100644 --- a/js/src/vm/PosixNSPR.h +++ b/js/src/vm/PosixNSPR.h @@ -16,11 +16,6 @@ #include #include -#define PR_ATOMIC_INCREMENT(val) __sync_add_and_fetch(val, 1) -#define PR_ATOMIC_DECREMENT(val) __sync_sub_and_fetch(val, 1) -#define PR_ATOMIC_SET(val, newval) __sync_lock_test_and_set(val, newval) -#define PR_ATOMIC_ADD(ptr, val) __sync_add_and_fetch(ptr, val) - namespace nspr { class Thread; class Lock; diff --git a/js/src/vm/Runtime.cpp b/js/src/vm/Runtime.cpp index 0d5c6e6a44b5..92c3fdaa824e 100644 --- a/js/src/vm/Runtime.cpp +++ b/js/src/vm/Runtime.cpp @@ -52,7 +52,11 @@ using JS::DoubleNaNValue; /* static */ ThreadLocal js::TlsPerThreadData; +#ifdef JS_THREADSAFE /* static */ Atomic JSRuntime::liveRuntimesCount; +#else +/* static */ size_t JSRuntime::liveRuntimesCount; +#endif const JSSecurityCallbacks js::NullSecurityCallbacks = { }; diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index 22a9f72a0943..1d3d0d2bd55b 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -1605,7 +1605,11 @@ struct JSRuntime : public JS::shadow::Runtime, // their callee. js::Value ionReturnOverride_; +#ifdef JS_THREADSAFE static mozilla::Atomic liveRuntimesCount; +#else + static size_t liveRuntimesCount; +#endif public: static bool hasLiveRuntimes() {