Commit b0370355 authored by Lars T Hansen's avatar Lars T Hansen
Browse files

Bug 1599659 - Predicate to test context for live SABs. r=jonco

SABs become foreground-finalizable so that we can access the runtime
during finalization.  Then a simple counter on the runtime will track
live SABs for the runtime, and the predicate on the context can get
its information from the runtime.

Fallout: SABs are now enabled on the globals used for jsapi-tests.

Differential Revision: https://phabricator.services.mozilla.com/D55783

--HG--
extra : moz-landing-system : lando
parent d6200622
...@@ -92,6 +92,7 @@ UNIFIED_SOURCES += [ ...@@ -92,6 +92,7 @@ UNIFIED_SOURCES += [
'testRegExp.cpp', 'testRegExp.cpp',
'testResolveRecursion.cpp', 'testResolveRecursion.cpp',
'tests.cpp', 'tests.cpp',
'testSABAccounting.cpp',
'testSameValue.cpp', 'testSameValue.cpp',
'testSavedStacks.cpp', 'testSavedStacks.cpp',
'testScriptInfo.cpp', 'testScriptInfo.cpp',
......
#include "jsapi.h"
#include "jsfriendapi.h"
#include "builtin/TestingFunctions.h"
#include "js/SharedArrayBuffer.h"
#include "jsapi-tests/tests.h"
BEGIN_TEST(testSABAccounting) {
// Purge what we can
JS::PrepareForFullGC(cx);
NonIncrementalGC(cx, GC_SHRINK, GCReason::API);
// Self-hosting and chrome code should not use SABs, or the point of this
// predicate is completely lost.
CHECK(!JS_ContainsSharedArrayBuffer(cx));
JS::RootedObject obj(cx), obj2(cx);
CHECK(obj = JS::NewSharedArrayBuffer(cx, 4096));
CHECK(JS_ContainsSharedArrayBuffer(cx));
CHECK(obj2 = JS::NewSharedArrayBuffer(cx, 4096));
CHECK(JS_ContainsSharedArrayBuffer(cx));
// Discard those objects again.
obj = nullptr;
obj2 = nullptr;
JS::PrepareForFullGC(cx);
NonIncrementalGC(cx, GC_SHRINK, GCReason::API);
// Should be back to base state.
CHECK(!JS_ContainsSharedArrayBuffer(cx));
return true;
}
END_TEST(testSABAccounting)
...@@ -92,7 +92,8 @@ JSObject* JSAPITest::createGlobal(JSPrincipals* principals) { ...@@ -92,7 +92,8 @@ JSObject* JSAPITest::createGlobal(JSPrincipals* principals) {
.setStreamsEnabled(true) .setStreamsEnabled(true)
.setFieldsEnabled(true) .setFieldsEnabled(true)
.setAwaitFixEnabled(true) .setAwaitFixEnabled(true)
.setWeakRefsEnabled(true); .setWeakRefsEnabled(true)
.setSharedMemoryAndAtomicsEnabled(true);
newGlobal = JS_NewGlobalObject(cx, getGlobalClass(), principals, newGlobal = JS_NewGlobalObject(cx, getGlobalClass(), principals,
JS::FireOnNewGlobalHook, options); JS::FireOnNewGlobalHook, options);
if (!newGlobal) { if (!newGlobal) {
......
...@@ -390,6 +390,10 @@ JS_PUBLIC_API void JS_SetFutexCanWait(JSContext* cx) { ...@@ -390,6 +390,10 @@ JS_PUBLIC_API void JS_SetFutexCanWait(JSContext* cx) {
cx->fx.setCanWait(true); cx->fx.setCanWait(true);
} }
JS_PUBLIC_API bool JS_ContainsSharedArrayBuffer(JSContext* cx) {
return cx->runtime()->hasLiveSABs();
}
JS_PUBLIC_API JSRuntime* JS_GetParentRuntime(JSContext* cx) { JS_PUBLIC_API JSRuntime* JS_GetParentRuntime(JSContext* cx) {
return cx->runtime()->parentRuntime ? cx->runtime()->parentRuntime return cx->runtime()->parentRuntime ? cx->runtime()->parentRuntime
: cx->runtime(); : cx->runtime();
......
...@@ -344,6 +344,12 @@ extern JS_PUBLIC_API JSRuntime* JS_GetRuntime(JSContext* cx); ...@@ -344,6 +344,12 @@ extern JS_PUBLIC_API JSRuntime* JS_GetRuntime(JSContext* cx);
extern JS_PUBLIC_API void JS_SetFutexCanWait(JSContext* cx); extern JS_PUBLIC_API void JS_SetFutexCanWait(JSContext* cx);
// Returns true if there are any live SharedArrayBuffer objects, including those
// for wasm memories, associated with the context. This is conservative,
// because it does not run GC. Some dead objects may not have been collected
// yet and thus will be thought live.
extern JS_PUBLIC_API bool JS_ContainsSharedArrayBuffer(JSContext* cx);
namespace js { namespace js {
void AssertHeapIsIdle(); void AssertHeapIsIdle();
......
...@@ -149,6 +149,7 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime) ...@@ -149,6 +149,7 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
staticStrings(nullptr), staticStrings(nullptr),
commonNames(nullptr), commonNames(nullptr),
wellKnownSymbols(nullptr), wellKnownSymbols(nullptr),
liveSABs(0),
offthreadIonCompilationEnabled_(true), offthreadIonCompilationEnabled_(true),
parallelParsingEnabled_(true), parallelParsingEnabled_(true),
#ifdef DEBUG #ifdef DEBUG
......
...@@ -840,6 +840,24 @@ struct JSRuntime { ...@@ -840,6 +840,24 @@ struct JSRuntime {
JSRuntime* thisFromCtor() { return this; } JSRuntime* thisFromCtor() { return this; }
private:
// Number of live SharedArrayBuffer objects, including those in Wasm shared
// memories. uint64_t to avoid any risk of overflow.
js::MainThreadData<uint64_t> liveSABs;
public:
void incSABCount() {
MOZ_RELEASE_ASSERT(liveSABs != UINT64_MAX);
liveSABs++;
}
void decSABCount() {
MOZ_RELEASE_ASSERT(liveSABs > 0);
liveSABs--;
}
bool hasLiveSABs() const { return liveSABs > 0; }
public: public:
void reportAllocationOverflow() { js::ReportAllocationOverflow(nullptr); } void reportAllocationOverflow() { js::ReportAllocationOverflow(nullptr); }
......
...@@ -251,6 +251,7 @@ SharedArrayBufferObject* SharedArrayBufferObject::New( ...@@ -251,6 +251,7 @@ SharedArrayBufferObject* SharedArrayBufferObject::New(
MOZ_ASSERT(obj->getClass() == &class_); MOZ_ASSERT(obj->getClass() == &class_);
cx->runtime()->incSABCount();
obj->acceptRawBuffer(buffer, length); obj->acceptRawBuffer(buffer, length);
return obj; return obj;
...@@ -273,7 +274,9 @@ SharedArrayRawBuffer* SharedArrayBufferObject::rawBufferObject() const { ...@@ -273,7 +274,9 @@ SharedArrayRawBuffer* SharedArrayBufferObject::rawBufferObject() const {
} }
void SharedArrayBufferObject::Finalize(JSFreeOp* fop, JSObject* obj) { void SharedArrayBufferObject::Finalize(JSFreeOp* fop, JSObject* obj) {
MOZ_ASSERT(fop->maybeOnHelperThread()); // Must be foreground finalizable so that we can account for the object.
MOZ_ASSERT(fop->onMainThread());
fop->runtime()->decSABCount();
SharedArrayBufferObject& buf = obj->as<SharedArrayBufferObject>(); SharedArrayBufferObject& buf = obj->as<SharedArrayBufferObject>();
...@@ -327,6 +330,7 @@ SharedArrayBufferObject* SharedArrayBufferObject::createFromNewRawBuffer( ...@@ -327,6 +330,7 @@ SharedArrayBufferObject* SharedArrayBufferObject::createFromNewRawBuffer(
return nullptr; return nullptr;
} }
cx->runtime()->incSABCount();
obj->acceptRawBuffer(buffer, initialSize); obj->acceptRawBuffer(buffer, initialSize);
return obj; return obj;
...@@ -373,7 +377,7 @@ const JSClass SharedArrayBufferObject::class_ = { ...@@ -373,7 +377,7 @@ const JSClass SharedArrayBufferObject::class_ = {
JSCLASS_DELAY_METADATA_BUILDER | JSCLASS_DELAY_METADATA_BUILDER |
JSCLASS_HAS_RESERVED_SLOTS(SharedArrayBufferObject::RESERVED_SLOTS) | JSCLASS_HAS_RESERVED_SLOTS(SharedArrayBufferObject::RESERVED_SLOTS) |
JSCLASS_HAS_CACHED_PROTO(JSProto_SharedArrayBuffer) | JSCLASS_HAS_CACHED_PROTO(JSProto_SharedArrayBuffer) |
JSCLASS_BACKGROUND_FINALIZE, JSCLASS_FOREGROUND_FINALIZE,
&SharedArrayBufferObjectClassOps, &SharedArrayBufferObjectClassSpec, &SharedArrayBufferObjectClassOps, &SharedArrayBufferObjectClassSpec,
JS_NULL_CLASS_EXT}; JS_NULL_CLASS_EXT};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment