Bug 1337112 - Remove links from JSRuntime to its single context and zone group, r=jandem,jonco.

--HG--
extra : rebase_source : ebf319af724d5f829cdf5c2386dc82d49be89989
This commit is contained in:
Brian Hackett 2017-02-10 16:47:50 -07:00
Родитель e1b82a23c1
Коммит 01a649c197
29 изменённых файлов: 239 добавлений и 184 удалений

Просмотреть файл

@ -1655,7 +1655,7 @@ nsMessageManagerScriptExecutor::InitChildGlobalInternal(
const uint32_t flags = nsIXPConnect::INIT_JS_STANDARD_CLASSES;
JS::CompartmentOptions options;
options.creationOptions().setZone(JS::SystemZone);
options.creationOptions().setSystemZone();
options.behaviors().setVersion(JSVERSION_LATEST);
if (xpc::SharedMemoryEnabled()) {

Просмотреть файл

@ -2736,7 +2736,7 @@ CreateNativeGlobalForInner(JSContext* aCx,
}
if (top && top->GetGlobalJSObject()) {
options.creationOptions().setSameZoneAs(top->GetGlobalJSObject());
options.creationOptions().setExistingZone(top->GetGlobalJSObject());
}
options.creationOptions().setSecureContext(aIsSecureContext);

Просмотреть файл

@ -110,7 +110,7 @@ SimpleGlobalObject::Create(GlobalType globalType, JS::Handle<JS::Value> proto)
// lots of zones for what are probably very short-lived
// compartments. This should help them be GCed quicker and take up
// less memory before they're GCed.
.setZone(JS::SystemZone);
.setSystemZone();
if (NS_IsMainThread()) {
nsCOMPtr<nsIPrincipal> principal = nsNullPrincipal::Create();

Просмотреть файл

@ -1075,10 +1075,10 @@ public:
mWorkerPrivate = nullptr;
}
nsresult Initialize(JSContext* aParentContext)
nsresult Initialize(JSRuntime* aParentRuntime)
{
nsresult rv =
CycleCollectedJSContext::Initialize(aParentContext,
CycleCollectedJSContext::Initialize(aParentRuntime,
WORKER_DEFAULT_RUNTIME_HEAPSIZE,
WORKER_DEFAULT_NURSERY_SIZE);
if (NS_WARN_IF(NS_FAILED(rv))) {
@ -1187,7 +1187,7 @@ class WorkerThreadPrimaryRunnable final : public Runnable
{
WorkerPrivate* mWorkerPrivate;
RefPtr<WorkerThread> mThread;
JSContext* mParentContext;
JSRuntime* mParentRuntime;
class FinishedRunnable final : public Runnable
{
@ -1213,8 +1213,8 @@ class WorkerThreadPrimaryRunnable final : public Runnable
public:
WorkerThreadPrimaryRunnable(WorkerPrivate* aWorkerPrivate,
WorkerThread* aThread,
JSContext* aParentContext)
: mWorkerPrivate(aWorkerPrivate), mThread(aThread), mParentContext(aParentContext)
JSRuntime* aParentRuntime)
: mWorkerPrivate(aWorkerPrivate), mThread(aThread), mParentRuntime(aParentRuntime)
{
MOZ_ASSERT(aWorkerPrivate);
MOZ_ASSERT(aThread);
@ -1893,7 +1893,7 @@ RuntimeService::ScheduleWorker(WorkerPrivate* aWorkerPrivate)
JSContext* cx = CycleCollectedJSContext::Get()->Context();
nsCOMPtr<nsIRunnable> runnable =
new WorkerThreadPrimaryRunnable(aWorkerPrivate, thread,
JS_GetParentContext(cx));
JS_GetParentRuntime(cx));
if (NS_FAILED(thread->DispatchPrimaryRunnable(friendKey, runnable.forget()))) {
UnregisterWorker(aWorkerPrivate);
return false;
@ -2861,7 +2861,7 @@ WorkerThreadPrimaryRunnable::Run()
nsCycleCollector_startup();
WorkerJSContext context(mWorkerPrivate);
nsresult rv = context.Initialize(mParentContext);
nsresult rv = context.Initialize(mParentRuntime);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

Просмотреть файл

@ -451,7 +451,7 @@ XPCShellEnvironment::Init()
}
JS::CompartmentOptions options;
options.creationOptions().setZone(JS::SystemZone);
options.creationOptions().setSystemZone();
options.behaviors().setVersion(JSVERSION_LATEST);
if (xpc::SharedMemoryEnabled())
options.creationOptions().setSharedMemoryAndAtomicsEnabled(true);

Просмотреть файл

@ -347,6 +347,7 @@ MinorGC(JSContext* cx, unsigned argc, Value* vp)
#define FOR_EACH_GC_PARAM(_) \
_("maxBytes", JSGC_MAX_BYTES, true) \
_("maxMallocBytes", JSGC_MAX_MALLOC_BYTES, true) \
_("maxNurseryBytes", JSGC_MAX_NURSERY_BYTES, true) \
_("gcBytes", JSGC_BYTES, false) \
_("gcNumber", JSGC_NUMBER, false) \
_("mode", JSGC_MODE, true) \
@ -421,9 +422,16 @@ GCParameter(JSContext* cx, unsigned argc, Value* vp)
return false;
}
if (disableOOMFunctions && (param == JSGC_MAX_BYTES || param == JSGC_MAX_MALLOC_BYTES)) {
args.rval().setUndefined();
return true;
if (disableOOMFunctions) {
switch (param) {
case JSGC_MAX_BYTES:
case JSGC_MAX_MALLOC_BYTES:
case JSGC_MAX_NURSERY_BYTES:
args.rval().setUndefined();
return true;
default:
break;
}
}
double d;

Просмотреть файл

@ -980,8 +980,9 @@ class GCRuntime
public:
JSRuntime* const rt;
/* Embedders can use this zone however they wish. */
/* Embedders can use this zone and group however they wish. */
UnprotectedData<JS::Zone*> systemZone;
UnprotectedData<ZoneGroup*> systemZoneGroup;
// List of all zone groups (protected by the GC lock).
ActiveThreadOrGCTaskData<ZoneGroupVector> groups;

Просмотреть файл

@ -553,7 +553,6 @@ void
js::Nursery::collect(JS::gcreason::Reason reason)
{
MOZ_ASSERT(!TlsContext.get()->suppressGC);
MOZ_RELEASE_ASSERT(zoneGroup()->ownedByCurrentThread());
if (!isEnabled() || isEmpty()) {
// Our barriers are not always exact, and there may be entries in the

Просмотреть файл

@ -562,10 +562,6 @@ struct Zone : public JS::shadow::Zone,
source->uniqueIds().clear();
}
JSContext* contextFromMainThread() {
return runtime_->contextFromMainThread();
}
#ifdef JSGC_HASH_TABLE_CHECKS
// Assert that the UniqueId table has been redirected successfully.
void checkUniqueIdTableAfterMovingGC();

Просмотреть файл

@ -48,6 +48,9 @@ ZoneGroup::init(size_t maxNurseryBytes)
ZoneGroup::~ZoneGroup()
{
js_delete(jitZoneGroup.ref());
if (this == runtime->gc.systemZoneGroup)
runtime->gc.systemZoneGroup = nullptr;
}
void
@ -60,6 +63,8 @@ ZoneGroup::enter()
MOZ_ASSERT(ownerContext().context() == nullptr);
MOZ_ASSERT(enterCount == 0);
ownerContext_ = CooperatingContext(cx);
if (cx->generationalDisabled)
nursery().disable();
}
enterCount++;
}

Просмотреть файл

@ -130,42 +130,6 @@ class ZoneGroup
mozilla::LinkedList<js::Debugger>& debuggerList() { return debuggerList_.ref(); }
};
class MOZ_RAII AutoAccessZoneGroup
{
ZoneGroup* group;
public:
explicit AutoAccessZoneGroup(ZoneGroup* group)
: group(group)
{
group->enter();
}
~AutoAccessZoneGroup() {
group->leave();
}
};
class MOZ_RAII AutoAccessZoneGroups
{
Vector<ZoneGroup*, 4, SystemAllocPolicy> acquiredGroups;
public:
AutoAccessZoneGroups() {}
~AutoAccessZoneGroups() {
for (size_t i = 0; i < acquiredGroups.length(); i++)
acquiredGroups[i]->leave();
}
void access(ZoneGroup* group) {
group->enter();
AutoEnterOOMUnsafeRegion oomUnsafe;
if (!acquiredGroups.append(group))
oomUnsafe.crash("acquiredGroups.append failed");
}
};
} // namespace js
#endif // gc_Zone_h

Просмотреть файл

@ -463,18 +463,14 @@ JS_FRIEND_API(bool) JS::isGCEnabled() { return true; }
#endif
JS_PUBLIC_API(JSContext*)
JS_NewContext(uint32_t maxbytes, uint32_t maxNurseryBytes, JSContext* parentContext)
JS_NewContext(uint32_t maxbytes, uint32_t maxNurseryBytes, JSRuntime* parentRuntime)
{
MOZ_ASSERT(JS::detail::libraryInitState == JS::detail::InitState::Running,
"must call JS_Init prior to creating any JSContexts");
// Make sure that all parent runtimes are the topmost parent.
JSRuntime* parentRuntime = nullptr;
if (parentContext) {
parentRuntime = parentContext->runtime();
while (parentRuntime && parentRuntime->parentRuntime)
parentRuntime = parentRuntime->parentRuntime;
}
while (parentRuntime && parentRuntime->parentRuntime)
parentRuntime = parentRuntime->parentRuntime;
return NewContext(maxbytes, maxNurseryBytes, parentRuntime);
}
@ -546,10 +542,10 @@ JS_EndRequest(JSContext* cx)
StopRequest(cx);
}
JS_PUBLIC_API(JSContext*)
JS_GetParentContext(JSContext* cx)
JS_PUBLIC_API(JSRuntime*)
JS_GetParentRuntime(JSContext* cx)
{
return cx->runtime()->parentRuntime ? cx->runtime()->parentRuntime->unsafeContextFromAnyThread() : cx;
return cx->runtime()->parentRuntime ? cx->runtime()->parentRuntime : cx->runtime();
}
JS_PUBLIC_API(JSVersion)
@ -1743,16 +1739,42 @@ JS::CompartmentBehaviors::extraWarnings(JSContext* cx) const
}
JS::CompartmentCreationOptions&
JS::CompartmentCreationOptions::setZone(ZoneSpecifier spec)
JS::CompartmentCreationOptions::setSystemZone()
{
zone_.spec = spec;
zoneSpec_ = JS::SystemZone;
zonePointer_ = nullptr;
return *this;
}
JS::CompartmentCreationOptions&
JS::CompartmentCreationOptions::setSameZoneAs(JSObject* obj)
JS::CompartmentCreationOptions::setExistingZone(JSObject* obj)
{
zone_.pointer = static_cast<void*>(obj->zone());
zoneSpec_ = JS::ExistingZone;
zonePointer_ = obj->zone();
return *this;
}
JS::CompartmentCreationOptions&
JS::CompartmentCreationOptions::setNewZoneInNewZoneGroup()
{
zoneSpec_ = JS::NewZoneInNewZoneGroup;
zonePointer_ = nullptr;
return *this;
}
JS::CompartmentCreationOptions&
JS::CompartmentCreationOptions::setNewZoneInSystemZoneGroup()
{
zoneSpec_ = JS::NewZoneInSystemZoneGroup;
zonePointer_ = nullptr;
return *this;
}
JS::CompartmentCreationOptions&
JS::CompartmentCreationOptions::setNewZoneInExistingZoneGroup(JSObject* obj)
{
zoneSpec_ = JS::NewZoneInExistingZoneGroup;
zonePointer_ = obj->zone()->group();
return *this;
}

Просмотреть файл

@ -981,7 +981,7 @@ JS_IsBuiltinFunctionConstructor(JSFunction* fun);
extern JS_PUBLIC_API(JSContext*)
JS_NewContext(uint32_t maxbytes,
uint32_t maxNurseryBytes = JS::DefaultNurseryBytes,
JSContext* parentContext = nullptr);
JSRuntime* parentRuntime = nullptr);
extern JS_PUBLIC_API(void)
JS_DestroyContext(JSContext* cx);
@ -992,8 +992,8 @@ JS_GetContextPrivate(JSContext* cx);
JS_PUBLIC_API(void)
JS_SetContextPrivate(JSContext* cx, void* data);
extern JS_PUBLIC_API(JSContext*)
JS_GetParentContext(JSContext* cx);
extern JS_PUBLIC_API(JSRuntime*)
JS_GetParentRuntime(JSContext* cx);
extern JS_PUBLIC_API(void)
JS_BeginRequest(JSContext* cx);
@ -1710,6 +1710,9 @@ typedef enum JSGCParamKey {
/** Number of JS_malloc bytes before last ditch GC. */
JSGC_MAX_MALLOC_BYTES = 1,
/** Maximum size of the generational GC nurseries. */
JSGC_MAX_NURSERY_BYTES = 2,
/** Amount of bytes allocated by the GC. */
JSGC_BYTES = 3,
@ -2178,9 +2181,23 @@ JS_GetConstructor(JSContext* cx, JS::Handle<JSObject*> proto);
namespace JS {
// Specification for which zone a newly created compartment should use.
enum ZoneSpecifier {
FreshZone = 0,
SystemZone = 1
// Use the single runtime wide system zone. The meaning of this zone is
// left to the embedder.
SystemZone,
// Use a particular existing zone.
ExistingZone,
// Create a new zone with its own new zone group.
NewZoneInNewZoneGroup,
// Create a new zone in the same zone group as the system zone.
NewZoneInSystemZoneGroup,
// Create a new zone in the same zone group as another existing zone.
NewZoneInExistingZoneGroup
};
/**
@ -2197,6 +2214,8 @@ class JS_PUBLIC_API(CompartmentCreationOptions)
CompartmentCreationOptions()
: addonId_(nullptr),
traceGlobal_(nullptr),
zoneSpec_(NewZoneInSystemZoneGroup),
zonePointer_(nullptr),
invisibleToDebugger_(false),
mergeable_(false),
preserveJitCode_(false),
@ -2204,9 +2223,7 @@ class JS_PUBLIC_API(CompartmentCreationOptions)
experimentalNumberFormatFormatToPartsEnabled_(false),
sharedMemoryAndAtomics_(false),
secureContext_(false)
{
zone_.spec = JS::FreshZone;
}
{}
// A null add-on ID means that the compartment is not associated with an
// add-on.
@ -2224,13 +2241,15 @@ class JS_PUBLIC_API(CompartmentCreationOptions)
return *this;
}
void* zonePointer() const {
MOZ_ASSERT(uintptr_t(zone_.pointer) > uintptr_t(JS::SystemZone));
return zone_.pointer;
}
ZoneSpecifier zoneSpecifier() const { return zone_.spec; }
CompartmentCreationOptions& setZone(ZoneSpecifier spec);
CompartmentCreationOptions& setSameZoneAs(JSObject* obj);
void* zonePointer() const { return zonePointer_; }
ZoneSpecifier zoneSpecifier() const { return zoneSpec_; }
// Set the zone to use for the compartment. See ZoneSpecifier above.
CompartmentCreationOptions& setSystemZone();
CompartmentCreationOptions& setExistingZone(JSObject* obj);
CompartmentCreationOptions& setNewZoneInNewZoneGroup();
CompartmentCreationOptions& setNewZoneInSystemZoneGroup();
CompartmentCreationOptions& setNewZoneInExistingZoneGroup(JSObject* obj);
// Certain scopes (i.e. XBL compilation scopes) are implementation details
// of the embedding, and references to them should never leak out to script.
@ -2299,10 +2318,8 @@ class JS_PUBLIC_API(CompartmentCreationOptions)
private:
JSAddonId* addonId_;
JSTraceOp traceGlobal_;
union {
ZoneSpecifier spec;
void* pointer; // js::Zone* is not exposed in the API.
} zone_;
ZoneSpecifier zoneSpec_;
void* zonePointer_; // Per zoneSpec_, either a Zone, ZoneGroup, or null.
bool invisibleToDebugger_;
bool mergeable_;
bool preserveJitCode_;

Просмотреть файл

@ -176,10 +176,28 @@ js::DestroyContext(JSContext* cx)
cx->checkNoGCRooters();
js_delete(cx->ionPcScriptCache.ref());
// Cancel all off thread Ion compiles before destroying a cooperative
// context. Completed Ion compiles may try to interrupt arbitrary
// cooperative contexts which they have read off the owner context of a
// zone group. See HelperThread::handleIonWorkload.
CancelOffThreadIonCompile(cx->runtime());
cx->runtime()->destroyRuntime();
js_delete(cx->runtime());
if (cx->runtime()->cooperatingContexts().length() == 1) {
// Destroy the runtime along with its last context.
cx->runtime()->destroyRuntime();
js_delete(cx->runtime());
} else {
DebugOnly<bool> found = false;
for (size_t i = 0; i < cx->runtime()->cooperatingContexts().length(); i++) {
CooperatingContext& target = cx->runtime()->cooperatingContexts()[i];
if (cx == target.context()) {
cx->runtime()->cooperatingContexts().erase(&target);
found = true;
break;
}
}
MOZ_ASSERT(found);
}
js_delete_poison(cx);
}
@ -1034,6 +1052,8 @@ JSContext::~JSContext()
/* Free the stuff hanging off of cx. */
MOZ_ASSERT(!resolvingList);
js_delete(ionPcScriptCache.ref());
if (dtoaState)
DestroyDtoaState(dtoaState);

Просмотреть файл

@ -406,10 +406,6 @@ struct JSCompartment
return runtime_;
}
JSContext* contextFromMainThread() const {
return runtime_->contextFromMainThread();
}
/*
* Nb: global_ might be nullptr, if (a) it's the atoms compartment, or
* (b) the compartment's global has been collected. The latter can happen

Просмотреть файл

@ -810,6 +810,7 @@ GCRuntime::releaseArena(Arena* arena, const AutoLockGC& lock)
GCRuntime::GCRuntime(JSRuntime* rt) :
rt(rt),
systemZone(nullptr),
systemZoneGroup(nullptr),
atomsZone(nullptr),
stats_(rt),
marker(rt),
@ -1044,6 +1045,7 @@ GCRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes)
* for default backward API compatibility.
*/
MOZ_ALWAYS_TRUE(tunables.setParameter(JSGC_MAX_BYTES, maxbytes, lock));
MOZ_ALWAYS_TRUE(tunables.setParameter(JSGC_MAX_NURSERY_BYTES, maxNurseryBytes, lock));
setMaxMallocBytes(maxbytes);
const char* size = getenv("JSGC_MARK_STACK_LIMIT");
@ -1165,6 +1167,9 @@ GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value, const AutoL
case JSGC_MAX_BYTES:
gcMaxBytes_ = value;
break;
case JSGC_MAX_NURSERY_BYTES:
gcMaxNurseryBytes_ = value;
break;
case JSGC_HIGH_FREQUENCY_TIME_LIMIT:
highFrequencyThresholdUsec_ = value * PRMJ_USEC_PER_MSEC;
break;
@ -3550,9 +3555,7 @@ GCRuntime::sweepZoneGroups(FreeOp* fop, bool destroyingRuntime)
ZoneGroup* group = *read++;
sweepZones(fop, group, destroyingRuntime);
// For now, the singleton zone group is not destroyed until the runtime
// itself is, bug 1323066.
if (group->zones().empty() && group != rt->zoneGroupFromMainThread()) {
if (group->zones().empty()) {
MOZ_ASSERT(numActiveZoneIters == 0);
fop->delete_(group);
} else {
@ -6169,7 +6172,6 @@ namespace {
class AutoScheduleZonesForGC
{
JSRuntime* rt_;
AutoAccessZoneGroups aazg;
public:
explicit AutoScheduleZonesForGC(JSRuntime* rt) : rt_(rt) {
@ -6187,9 +6189,6 @@ class AutoScheduleZonesForGC
{
zone->scheduleGC();
}
if (zone->isGCScheduled() && !zone->isAtomsZone())
aazg.access(zone->group());
}
}
@ -6753,15 +6752,61 @@ AutoPrepareForTracing::AutoPrepareForTracing(JSContext* cx, ZoneSelector selecto
}
JSCompartment*
js::NewCompartment(JSContext* cx, Zone* zone, JSPrincipals* principals,
js::NewCompartment(JSContext* cx, JSPrincipals* principals,
const JS::CompartmentOptions& options)
{
JSRuntime* rt = cx->runtime();
JS_AbortIfWrongThread(cx);
ScopedJSDeletePtr<ZoneGroup> groupHolder;
ScopedJSDeletePtr<Zone> zoneHolder;
Zone* zone = nullptr;
ZoneGroup* group = nullptr;
JS::ZoneSpecifier zoneSpec = options.creationOptions().zoneSpecifier();
switch (zoneSpec) {
case JS::SystemZone:
// systemZone and possibly systemZoneGroup might be null here, in which
// case we'll make a zone/group and set these fields below.
zone = rt->gc.systemZone;
group = rt->gc.systemZoneGroup;
break;
case JS::ExistingZone:
zone = static_cast<Zone*>(options.creationOptions().zonePointer());
MOZ_ASSERT(zone);
group = zone->group();
break;
case JS::NewZoneInNewZoneGroup:
break;
case JS::NewZoneInSystemZoneGroup:
// As above, systemZoneGroup might be null here.
group = rt->gc.systemZoneGroup;
break;
case JS::NewZoneInExistingZoneGroup:
group = static_cast<ZoneGroup*>(options.creationOptions().zonePointer());
MOZ_ASSERT(group);
break;
}
if (!group) {
MOZ_ASSERT(!zone);
group = cx->new_<ZoneGroup>(rt);
if (!group)
return nullptr;
groupHolder.reset(group);
if (!group->init(rt->gc.tunables.gcMaxNurseryBytes())) {
ReportOutOfMemory(cx);
return nullptr;
}
if (cx->generationalDisabled)
group->nursery().disable();
}
if (!zone) {
zone = cx->new_<Zone>(cx->runtime(), rt->zoneGroupFromMainThread());
zone = cx->new_<Zone>(cx->runtime(), group);
if (!zone)
return nullptr;
@ -6789,12 +6834,35 @@ js::NewCompartment(JSContext* cx, Zone* zone, JSPrincipals* principals,
return nullptr;
}
if (zoneHolder && zoneHolder->group() && !zoneHolder->group()->zones().append(zone)) {
ReportOutOfMemory(cx);
return nullptr;
if (zoneHolder) {
if (!group->zones().append(zone)) {
ReportOutOfMemory(cx);
return nullptr;
}
// Lazily set the runtime's sytem zone.
if (zoneSpec == JS::SystemZone) {
MOZ_RELEASE_ASSERT(!rt->gc.systemZone);
rt->gc.systemZone = zone;
zone->isSystem = true;
}
}
if (groupHolder) {
if (!rt->gc.groups.ref().append(group)) {
ReportOutOfMemory(cx);
return nullptr;
}
// Lazily set the runtime's system zone group.
if (zoneSpec == JS::SystemZone || zoneSpec == JS::NewZoneInSystemZoneGroup) {
MOZ_RELEASE_ASSERT(!rt->gc.systemZoneGroup);
rt->gc.systemZoneGroup = group;
}
}
zoneHolder.forget();
groupHolder.forget();
return compartment.forget();
}

Просмотреть файл

@ -1057,7 +1057,7 @@ extern void
FinalizeStringRT(JSRuntime* rt, JSString* str);
JSCompartment*
NewCompartment(JSContext* cx, JS::Zone* zone, JSPrincipals* principals,
NewCompartment(JSContext* cx, JSPrincipals* principals,
const JS::CompartmentOptions& options);
namespace gc {

Просмотреть файл

@ -3364,12 +3364,12 @@ EvalInContext(JSContext* cx, unsigned argc, Value* vp)
struct WorkerInput
{
JSContext* context;
JSRuntime* parentRuntime;
char16_t* chars;
size_t length;
WorkerInput(JSContext* context, char16_t* chars, size_t length)
: context(context), chars(chars), length(length)
WorkerInput(JSRuntime* parentRuntime, char16_t* chars, size_t length)
: parentRuntime(parentRuntime), chars(chars), length(length)
{}
~WorkerInput() {
@ -3384,7 +3384,7 @@ WorkerMain(void* arg)
{
WorkerInput* input = (WorkerInput*) arg;
JSContext* cx = JS_NewContext(8L * 1024L * 1024L, 2L * 1024L * 1024L, input->context);
JSContext* cx = JS_NewContext(8L * 1024L * 1024L, 2L * 1024L * 1024L, input->parentRuntime);
if (!cx) {
js_delete(input);
return;
@ -3513,7 +3513,7 @@ EvalInWorker(JSContext* cx, unsigned argc, Value* vp)
CopyChars(chars, *str);
WorkerInput* input = js_new<WorkerInput>(JS_GetParentContext(cx), chars, str->length());
WorkerInput* input = js_new<WorkerInput>(JS_GetParentRuntime(cx), chars, str->length());
if (!input) {
ReportOutOfMemory(cx);
return false;
@ -4846,7 +4846,7 @@ NewGlobal(JSContext* cx, unsigned argc, Value* vp)
if (!JS_GetProperty(cx, opts, "sameZoneAs", &v))
return false;
if (v.isObject())
creationOptions.setSameZoneAs(UncheckedUnwrap(&v.toObject()));
creationOptions.setExistingZone(UncheckedUnwrap(&v.toObject()));
if (!JS_GetProperty(cx, opts, "disableLazyParsing", &v))
return false;

Просмотреть файл

@ -346,27 +346,10 @@ GlobalObject::new_(JSContext* cx, const Class* clasp, JSPrincipals* principals,
MOZ_ASSERT(!cx->isExceptionPending());
MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
JSRuntime* rt = cx->runtime();
auto zoneSpecifier = options.creationOptions().zoneSpecifier();
Zone* zone;
if (zoneSpecifier == JS::SystemZone)
zone = rt->gc.systemZone;
else if (zoneSpecifier == JS::FreshZone)
zone = nullptr;
else
zone = static_cast<Zone*>(options.creationOptions().zonePointer());
JSCompartment* compartment = NewCompartment(cx, zone, principals, options);
JSCompartment* compartment = NewCompartment(cx, principals, options);
if (!compartment)
return nullptr;
// Lazily create the system zone.
if (!rt->gc.systemZone && zoneSpecifier == JS::SystemZone) {
rt->gc.systemZone = compartment->zone();
rt->gc.systemZone->isSystem = true;
}
Rooted<GlobalObject*> global(cx);
{
AutoCompartment ac(cx, compartment);

Просмотреть файл

@ -541,7 +541,7 @@ CreateGlobalForOffThreadParse(JSContext* cx, ParseTaskKind kind, const gc::AutoS
creationOptions.setInvisibleToDebugger(true)
.setMergeable(true)
.setZone(JS::FreshZone);
.setNewZoneInSystemZoneGroup();
// Don't falsely inherit the host's global trace hook.
creationOptions.setTrace(nullptr);
@ -1565,15 +1565,24 @@ HelperThread::handleIonWorkload(AutoLockHelperThreadState& locked)
}
FinishOffThreadIonCompile(builder, locked);
// Ping any thread currently operating on the compiled script's zone group
// so that the compiled code can be incorporated at the next interrupt
// callback. Don't interrupt Ion code for this, as this incorporation can
// be delayed indefinitely without affecting performance as long as the
// main thread is actually executing Ion code.
//
// This must happen before the current task is reset. DestroyContext
// cancels in progress Ion compilations before destroying its target
// context, and after we reset the current task we are no longer considered
// to be Ion compiling.
JSContext* target = builder->script()->zoneFromAnyThread()->group()->ownerContext().context();
if (target)
target->requestInterrupt(JSContext::RequestInterruptCanWait);
currentTask.reset();
pause = false;
// Ping the main thread so that the compiled code can be incorporated
// at the next interrupt callback. Don't interrupt Ion code for this, as
// this incorporation can be delayed indefinitely without affecting
// performance as long as the main thread is actually executing Ion code.
rt->unsafeContextFromAnyThread()->requestInterrupt(JSContext::RequestInterruptCanWait);
// Notify the main thread in case it is waiting for the compilation to finish.
HelperThreadState().notifyAll(GlobalHelperThreadState::CONSUMER, locked);

Просмотреть файл

@ -143,8 +143,6 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
lcovOutput_(),
jitRuntime_(nullptr),
selfHostingGlobal_(nullptr),
singletonContext(nullptr),
singletonZoneGroup(nullptr),
gc(thisFromCtor()),
gcInitialized(false),
NaNValue(DoubleNaNValue()),
@ -199,24 +197,13 @@ JSRuntime::init(JSContext* cx, uint32_t maxbytes, uint32_t maxNurseryBytes)
if (!cooperatingContexts().append(cx))
return false;
singletonContext = cx;
defaultFreeOp_ = js_new<js::FreeOp>(this);
if (!defaultFreeOp_)
return false;
ScopedJSDeletePtr<ZoneGroup> zoneGroup(js_new<ZoneGroup>(this));
if (!zoneGroup)
return false;
singletonZoneGroup = zoneGroup;
if (!gc.init(maxbytes, maxNurseryBytes))
return false;
if (!zoneGroup->init(maxNurseryBytes) || !gc.groups.ref().append(zoneGroup))
return false;
zoneGroup.forget();
ScopedJSDeletePtr<Zone> atomsZone(new_<Zone>(this, nullptr));
if (!atomsZone || !atomsZone->init(true))
return false;
@ -342,8 +329,6 @@ JSRuntime::destroyRuntime()
DebugOnly<size_t> oldCount = liveRuntimesCount--;
MOZ_ASSERT(oldCount > 0);
js_delete(zoneGroupFromMainThread());
}
void

Просмотреть файл

@ -616,24 +616,6 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
return !!jitRuntime_;
}
// These will be removed soon.
private:
JSContext* singletonContext;
js::ZoneGroup* singletonZoneGroup;
public:
JSContext* unsafeContextFromAnyThread() const { return singletonContext; }
JSContext* contextFromMainThread() const {
MOZ_ASSERT(CurrentThreadCanAccessRuntime(this));
return singletonContext;
}
js::ZoneGroup* zoneGroupFromAnyThread() const { return singletonZoneGroup; }
js::ZoneGroup* zoneGroupFromMainThread() const {
MOZ_ASSERT(CurrentThreadCanAccessRuntime(this));
return singletonZoneGroup;
}
private:
// Used to generate random keys for hash tables.
mozilla::Maybe<mozilla::non_crypto::XorShift128PlusRNG> randomKeyGenerator_;

Просмотреть файл

@ -2745,10 +2745,10 @@ JSRuntime::createSelfHostingGlobal(JSContext* cx)
MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
JS::CompartmentOptions options;
options.creationOptions().setZone(JS::FreshZone);
options.creationOptions().setNewZoneInSystemZoneGroup();
options.behaviors().setDiscardSource(true);
JSCompartment* compartment = NewCompartment(cx, nullptr, nullptr, options);
JSCompartment* compartment = NewCompartment(cx, nullptr, options);
if (!compartment)
return nullptr;

Просмотреть файл

@ -562,7 +562,7 @@ mozJSComponentLoader::PrepareObjectForLocation(JSContext* aCx,
CompartmentOptions options;
options.creationOptions()
.setZone(SystemZone)
.setSystemZone()
.setAddonId(aReuseLoaderGlobal ? nullptr : MapURIToAddonID(aURI));
options.behaviors().setVersion(JSVERSION_LATEST);

Просмотреть файл

@ -1067,11 +1067,11 @@ xpc::CreateSandboxObject(JSContext* cx, MutableHandleValue vp, nsISupports* prin
creationOptions.setSharedMemoryAndAtomicsEnabled(true);
if (options.sameZoneAs)
creationOptions.setSameZoneAs(js::UncheckedUnwrap(options.sameZoneAs));
creationOptions.setExistingZone(js::UncheckedUnwrap(options.sameZoneAs));
else if (options.freshZone)
creationOptions.setZone(JS::FreshZone);
creationOptions.setNewZoneInSystemZoneGroup();
else
creationOptions.setZone(JS::SystemZone);
creationOptions.setSystemZone();
creationOptions.setInvisibleToDebugger(options.invisibleToDebugger)
.setTrace(TraceXPCGlobal);

Просмотреть файл

@ -1522,7 +1522,7 @@ XRE_XPCShellMain(int argc, char** argv, char** envp,
// Make the default XPCShell global use a fresh zone (rather than the
// System Zone) to improve cross-zone test coverage.
JS::CompartmentOptions options;
options.creationOptions().setZone(JS::FreshZone);
options.creationOptions().setNewZoneInSystemZoneGroup();
if (xpc::SharedMemoryEnabled())
options.creationOptions().setSharedMemoryAndAtomicsEnabled(true);
options.behaviors().setVersion(JSVERSION_LATEST);

Просмотреть файл

@ -628,7 +628,7 @@ private:
JSAutoRequest ar(mContext);
JS::CompartmentOptions options;
options.creationOptions().setZone(JS::SystemZone);
options.creationOptions().setSystemZone();
options.behaviors().setVersion(JSVERSION_LATEST);
mGlobal = JS_NewGlobalObject(mContext, &sGlobalClass, nullptr,
JS::DontFireOnNewGlobalHook, options);

Просмотреть файл

@ -493,7 +493,7 @@ MozCrashWarningReporter(JSContext*, JSErrorReport*)
}
nsresult
CycleCollectedJSContext::Initialize(JSContext* aParentContext,
CycleCollectedJSContext::Initialize(JSRuntime* aParentRuntime,
uint32_t aMaxBytes,
uint32_t aMaxNurseryBytes)
{
@ -504,7 +504,7 @@ CycleCollectedJSContext::Initialize(JSContext* aParentContext,
mBaseRecursionDepth = RecursionDepth();
mozilla::dom::InitScriptSettings();
mJSContext = JS_NewContext(aMaxBytes, aMaxNurseryBytes, aParentContext);
mJSContext = JS_NewContext(aMaxBytes, aMaxNurseryBytes, aParentRuntime);
if (!mJSContext) {
return NS_ERROR_OUT_OF_MEMORY;
}

Просмотреть файл

@ -147,7 +147,7 @@ protected:
virtual ~CycleCollectedJSContext();
MOZ_IS_CLASS_INIT
nsresult Initialize(JSContext* aParentContext,
nsresult Initialize(JSRuntime* aParentRuntime,
uint32_t aMaxBytes,
uint32_t aMaxNurseryBytes);