зеркало из https://github.com/mozilla/gecko-dev.git
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
This commit is contained in:
Родитель
e218334a65
Коммит
ea7268ed2f
|
@ -92,6 +92,7 @@ UNIFIED_SOURCES += [
|
|||
'testRegExp.cpp',
|
||||
'testResolveRecursion.cpp',
|
||||
'tests.cpp',
|
||||
'testSABAccounting.cpp',
|
||||
'testSameValue.cpp',
|
||||
'testSavedStacks.cpp',
|
||||
'testScriptInfo.cpp',
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
#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, JS::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, JS::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) {
|
|||
.setStreamsEnabled(true)
|
||||
.setFieldsEnabled(true)
|
||||
.setAwaitFixEnabled(true)
|
||||
.setWeakRefsEnabled(true);
|
||||
.setWeakRefsEnabled(true)
|
||||
.setSharedMemoryAndAtomicsEnabled(true);
|
||||
newGlobal = JS_NewGlobalObject(cx, getGlobalClass(), principals,
|
||||
JS::FireOnNewGlobalHook, options);
|
||||
if (!newGlobal) {
|
||||
|
|
|
@ -390,6 +390,10 @@ JS_PUBLIC_API void JS_SetFutexCanWait(JSContext* cx) {
|
|||
cx->fx.setCanWait(true);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API bool JS_ContainsSharedArrayBuffer(JSContext* cx) {
|
||||
return cx->runtime()->hasLiveSABs();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API JSRuntime* JS_GetParentRuntime(JSContext* cx) {
|
||||
return cx->runtime()->parentRuntime ? cx->runtime()->parentRuntime
|
||||
: cx->runtime();
|
||||
|
|
|
@ -344,6 +344,12 @@ extern JS_PUBLIC_API JSRuntime* JS_GetRuntime(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 {
|
||||
|
||||
void AssertHeapIsIdle();
|
||||
|
|
|
@ -149,6 +149,7 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
|
|||
staticStrings(nullptr),
|
||||
commonNames(nullptr),
|
||||
wellKnownSymbols(nullptr),
|
||||
liveSABs(0),
|
||||
offthreadIonCompilationEnabled_(true),
|
||||
parallelParsingEnabled_(true),
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -840,6 +840,24 @@ struct JSRuntime {
|
|||
|
||||
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:
|
||||
void reportAllocationOverflow() { js::ReportAllocationOverflow(nullptr); }
|
||||
|
||||
|
|
|
@ -251,6 +251,7 @@ SharedArrayBufferObject* SharedArrayBufferObject::New(
|
|||
|
||||
MOZ_ASSERT(obj->getClass() == &class_);
|
||||
|
||||
cx->runtime()->incSABCount();
|
||||
obj->acceptRawBuffer(buffer, length);
|
||||
|
||||
return obj;
|
||||
|
@ -273,7 +274,9 @@ SharedArrayRawBuffer* SharedArrayBufferObject::rawBufferObject() const {
|
|||
}
|
||||
|
||||
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>();
|
||||
|
||||
|
@ -327,6 +330,7 @@ SharedArrayBufferObject* SharedArrayBufferObject::createFromNewRawBuffer(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
cx->runtime()->incSABCount();
|
||||
obj->acceptRawBuffer(buffer, initialSize);
|
||||
|
||||
return obj;
|
||||
|
@ -373,7 +377,7 @@ const JSClass SharedArrayBufferObject::class_ = {
|
|||
JSCLASS_DELAY_METADATA_BUILDER |
|
||||
JSCLASS_HAS_RESERVED_SLOTS(SharedArrayBufferObject::RESERVED_SLOTS) |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_SharedArrayBuffer) |
|
||||
JSCLASS_BACKGROUND_FINALIZE,
|
||||
JSCLASS_FOREGROUND_FINALIZE,
|
||||
&SharedArrayBufferObjectClassOps, &SharedArrayBufferObjectClassSpec,
|
||||
JS_NULL_CLASS_EXT};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче