Statistics::Statistics(JSRuntime *rt) : runtime(rt), startupTime(PRMJ_Now()), fp(nullptr), fullFormat(false), gcDepth(0), collectedCount(0), zoneCount(0), compartmentCount(0), nonincrementalReason(nullptr), preBytes(0), phaseNestingDepth(0) { PodArrayZero(phaseTotals); PodArrayZero(counts); char *env = getenv("MOZ_GCTIMER"); if (!env || strcmp(env, "none") == 0) { fp = nullptr; return; } if (strcmp(env, "stdout") == 0) { fullFormat = false; fp = stdout; } else if (strcmp(env, "stderr") == 0) { fullFormat = false; fp = stderr; } else { fullFormat = true; fp = fopen(env, "a"); JS_ASSERT(fp); } }
PerThreadDataFriendFields::PerThreadDataFriendFields() { PodArrayZero(nativeStackLimit); #if JS_STACK_GROWTH_DIRECTION > 0 for (int i=0; i<StackKindCount; i++) nativeStackLimit[i] = UINTPTR_MAX; #endif PodArrayZero(thingGCRooters); }
PerThreadDataFriendFields::PerThreadDataFriendFields() { PodArrayZero(nativeStackLimit); #if defined(JSGC_ROOT_ANALYSIS) || defined(JSGC_USE_EXACT_ROOTING) PodArrayZero(thingGCRooters); #endif #if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) skipGCRooters = nullptr; #endif }
void Statistics::beginGC() { PodArrayZero(phaseStartTimes); PodArrayZero(phaseTimes); slices.clearAndFree(); sccTimes.clearAndFree(); nonincrementalReason = nullptr; preBytes = runtime->gc.usage.gcBytes(); }
Statistics::Statistics(JSRuntime* rt) : runtime(rt), startupTime(PRMJ_Now()), fp(nullptr), gcDepth(0), nonincrementalReason_(gc::AbortReason::None), timedGCStart(0), preBytes(0), maxPauseInInterval(0), phaseNestingDepth(0), activeDagSlot(PHASE_DAG_NONE), suspended(0), sliceCallback(nullptr), nurseryCollectionCallback(nullptr), aborted(false), enableProfiling_(false), sliceCount_(0) { PodArrayZero(phaseTotals); PodArrayZero(counts); PodArrayZero(phaseStartTimes); for (auto d : MakeRange(NumTimingArrays)) PodArrayZero(phaseTimes[d]); const char* env = getenv("MOZ_GCTIMER"); if (env) { if (strcmp(env, "none") == 0) { fp = nullptr; } else if (strcmp(env, "stdout") == 0) { fp = stdout; } else if (strcmp(env, "stderr") == 0) { fp = stderr; } else { fp = fopen(env, "a"); if (!fp) MOZ_CRASH("Failed to open MOZ_GCTIMER log file."); } } env = getenv("JS_GC_PROFILE"); if (env) { if (0 == strcmp(env, "help")) { fprintf(stderr, "JS_GC_PROFILE=N\n" "\tReport major GC's taking more than N milliseconds.\n"); exit(0); } enableProfiling_ = true; profileThreshold_ = atoi(env); } PodZero(&totalTimes_); }
void Statistics::endSlice() { slices.back().end = PRMJ_Now(); slices.back().endFaults = gc::GetPageFaultCount(); if (JSAccumulateTelemetryDataCallback cb = runtime->telemetryCallback) { (*cb)(JS_TELEMETRY_GC_SLICE_MS, t(slices.back().end - slices.back().start)); (*cb)(JS_TELEMETRY_GC_RESET, !!slices.back().resetReason); } bool last = runtime->gcIncrementalState == gc::NO_INCREMENTAL; if (last) endGC(); // Slice callbacks should only fire for the outermost level if (--gcDepth == 0) { bool wasFullGC = collectedCount == zoneCount; if (JS::GCSliceCallback cb = runtime->gcSliceCallback) (*cb)(runtime, last ? JS::GC_CYCLE_END : JS::GC_SLICE_END, JS::GCDescription(!wasFullGC)); } /* Do this after the slice callback since it uses these values. */ if (last) PodArrayZero(counts); }
void JS_BasicStatsAccum(JSBasicStats *bs, uint32_t val) { unsigned oldscale, newscale, bin; double mean; ++bs->num; if (bs->max < val) bs->max = val; bs->sum += val; bs->sqsum += (double)val * val; oldscale = bs->logscale; if (oldscale != 10) { mean = bs->sum / bs->num; if (bs->max > 16 && mean > 8) { newscale = (bs->max > 1e6 && mean > 1000) ? 10 : 2; if (newscale != oldscale) { uint32_t newhist[11], newbin; PodArrayZero(newhist); for (bin = 0; bin <= 10; bin++) { newbin = ValToBin(newscale, BinToVal(oldscale, bin)); newhist[newbin] += bs->hist[bin]; } js_memcpy(bs->hist, newhist, sizeof bs->hist); bs->logscale = newscale; } } } bin = ValToBin(bs->logscale, val); ++bs->hist[bin]; }
void Statistics::endSlice() { slices.back().end = PRMJ_Now(); slices.back().endFaults = GetPageFaultCount(); runtime->addTelemetry(JS_TELEMETRY_GC_SLICE_MS, t(slices.back().end - slices.back().start)); runtime->addTelemetry(JS_TELEMETRY_GC_RESET, !!slices.back().resetReason); bool last = runtime->gc.state() == gc::NO_INCREMENTAL; if (last) endGC(); // Slice callbacks should only fire for the outermost level if (--gcDepth == 0) { bool wasFullGC = zoneStats.isCollectingAllZones(); if (sliceCallback) (*sliceCallback)(runtime, last ? JS::GC_CYCLE_END : JS::GC_SLICE_END, JS::GCDescription(!wasFullGC)); } /* Do this after the slice callback since it uses these values. */ if (last) PodArrayZero(counts); }
ParallelSpewer() : depth(0) { const char *env; PodArrayZero(active); env = getenv("PAFLAGS"); if (env) { if (strstr(env, "ops")) active[SpewOps] = true; if (strstr(env, "compile")) active[SpewCompile] = true; if (strstr(env, "bailouts")) active[SpewBailouts] = true; if (strstr(env, "full")) { for (uint32_t i = 0; i < NumSpewChannels; i++) active[i] = true; } } env = getenv("TERM"); if (env) { if (strcmp(env, "xterm-color") == 0 || strcmp(env, "xterm-256color") == 0) colorable = true; } }
JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options = JS::CompartmentOptions()) : creationOptions_(options.creationOptions()), behaviors_(options.behaviors()), zone_(zone), runtime_(zone->runtimeFromAnyThread()), principals_(nullptr), isSystem_(false), isAtomsCompartment_(false), isSelfHosting(false), marked(true), warnedAboutExprClosure(false), warnedAboutStringGenericsMethods(0), #ifdef DEBUG firedOnNewGlobalObject(false), #endif global_(nullptr), enterCompartmentDepth(0), globalHolds(0), performanceMonitoring(runtime_), data(nullptr), realmData(nullptr), allocationMetadataBuilder(nullptr), lastAnimationTime(0), regExps(), arraySpeciesLookup(), globalWriteBarriered(0), detachedTypedObjects(0), objectMetadataState(ImmediateMetadata()), selfHostingScriptSource(nullptr), objectMetadataTable(nullptr), innerViews(zone), lazyArrayBuffers(nullptr), wasm(zone), nonSyntacticLexicalEnvironments_(nullptr), gcIncomingGrayPointers(nullptr), debugModeBits(0), validAccessPtr(nullptr), randomKeyGenerator_(runtime_->forkRandomKeyGenerator()), scriptCountsMap(nullptr), scriptNameMap(nullptr), debugScriptMap(nullptr), debugEnvs(nullptr), enumerators(nullptr), compartmentStats_(nullptr), scheduledForDestruction(false), maybeAlive(true), jitCompartment_(nullptr), mappedArgumentsTemplate_(nullptr), unmappedArgumentsTemplate_(nullptr), iterResultTemplate_(nullptr), lcovOutput() { PodArrayZero(sawDeprecatedLanguageExtension); runtime_->numCompartments++; MOZ_ASSERT_IF(creationOptions_.mergeable(), creationOptions_.invisibleToDebugger()); }
js::ContextFriendFields::ContextFriendFields(bool isJSContext) : JS::RootingContext(isJSContext), compartment_(nullptr), zone_(nullptr) { PodArrayZero(nativeStackLimit); #if JS_STACK_GROWTH_DIRECTION > 0 for (int i=0; i<StackKindCount; i++) nativeStackLimit[i] = UINTPTR_MAX; #endif }
JS::RootingContext::RootingContext() : autoGCRooters_(nullptr), compartment_(nullptr), zone_(nullptr) { for (auto& stackRootPtr : stackRoots_) stackRootPtr = nullptr; PodArrayZero(nativeStackLimit); #if JS_STACK_GROWTH_DIRECTION > 0 for (int i=0; i<StackKindCount; i++) nativeStackLimit[i] = UINTPTR_MAX; #endif }
JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options = JS::CompartmentOptions()) : creationOptions_(options.creationOptions()), behaviors_(options.behaviors()), zone_(zone), runtime_(zone->runtimeFromMainThread()), principals_(nullptr), isSystem_(false), isSelfHosting(false), marked(true), warnedAboutExprClosure(false), #ifdef DEBUG firedOnNewGlobalObject(false), #endif global_(nullptr), enterCompartmentDepth(0), performanceMonitoring(runtime_), data(nullptr), allocationMetadataBuilder(nullptr), lastAnimationTime(0), regExps(runtime_), globalWriteBarriered(0), detachedTypedObjects(0), objectMetadataState(ImmediateMetadata()), propertyTree(thisForCtor()), baseShapes(zone, BaseShapeSet()), initialShapes(zone, InitialShapeSet()), selfHostingScriptSource(nullptr), objectMetadataTable(nullptr), lazyArrayBuffers(nullptr), wasmInstances(zone, WasmInstanceObjectSet()), nonSyntacticLexicalScopes_(nullptr), gcIncomingGrayPointers(nullptr), debugModeBits(0), watchpointMap(nullptr), scriptCountsMap(nullptr), debugScriptMap(nullptr), debugScopes(nullptr), enumerators(nullptr), compartmentStats_(nullptr), scheduledForDestruction(false), maybeAlive(true), jitCompartment_(nullptr), mappedArgumentsTemplate_(nullptr), unmappedArgumentsTemplate_(nullptr), lcovOutput() { PodArrayZero(sawDeprecatedLanguageExtension); runtime_->numCompartments++; MOZ_ASSERT_IF(creationOptions_.mergeable(), creationOptions_.invisibleToDebugger()); }
Statistics::Statistics(JSRuntime *rt) : runtime(rt), startupTime(PRMJ_Now()), fp(nullptr), fullFormat(false), gcDepth(0), nonincrementalReason(nullptr), timedGCStart(0), preBytes(0), maxPauseInInterval(0), phaseNestingDepth(0), suspendedPhaseNestingDepth(0), sliceCallback(nullptr) { PodArrayZero(phaseTotals); PodArrayZero(counts); PodArrayZero(phaseStartTimes); PodArrayZero(phaseTimes); char *env = getenv("MOZ_GCTIMER"); if (!env || strcmp(env, "none") == 0) { fp = nullptr; return; } if (strcmp(env, "stdout") == 0) { fullFormat = false; fp = stdout; } else if (strcmp(env, "stderr") == 0) { fullFormat = false; fp = stderr; } else { fullFormat = true; fp = fopen(env, "a"); MOZ_ASSERT(fp); } }
JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options = JS::CompartmentOptions()) : options_(options), zone_(zone), runtime_(zone->runtimeFromMainThread()), principals_(nullptr), isSystem_(false), isSelfHosting(false), marked(true), warnedAboutNoSuchMethod(false), warnedAboutFlagsArgument(false), addonId(options.addonIdOrNull()), #ifdef DEBUG firedOnNewGlobalObject(false), #endif global_(nullptr), enterCompartmentDepth(0), performanceMonitoring(runtime_), data(nullptr), objectMetadataCallback(nullptr), lastAnimationTime(0), regExps(runtime_), globalWriteBarriered(false), neuteredTypedObjects(0), objectMetadataState(ImmediateMetadata()), propertyTree(thisForCtor()), selfHostingScriptSource(nullptr), objectMetadataTable(nullptr), lazyArrayBuffers(nullptr), nonSyntacticLexicalScopes_(nullptr), gcIncomingGrayPointers(nullptr), gcPreserveJitCode(options.preserveJitCode()), debugModeBits(0), rngState(0), watchpointMap(nullptr), scriptCountsMap(nullptr), debugScriptMap(nullptr), debugScopes(nullptr), enumerators(nullptr), compartmentStats(nullptr), scheduledForDestruction(false), maybeAlive(true), jitCompartment_(nullptr), mappedArgumentsTemplate_(nullptr), unmappedArgumentsTemplate_(nullptr), lcovOutput() { PodArrayZero(sawDeprecatedLanguageExtension); runtime_->numCompartments++; MOZ_ASSERT_IF(options.mergeable(), options.invisibleToDebugger()); }
Statistics::Statistics(JSRuntime* rt) : runtime(rt), startupTime(PRMJ_Now()), fp(nullptr), gcDepth(0), nonincrementalReason_(nullptr), timedGCStart(0), preBytes(0), maxPauseInInterval(0), phaseNestingDepth(0), activeDagSlot(PHASE_DAG_NONE), suspended(0), sliceCallback(nullptr), nurseryCollectionCallback(nullptr), aborted(false) { PodArrayZero(phaseTotals); PodArrayZero(counts); PodArrayZero(phaseStartTimes); for (auto d : MakeRange(NumTimingArrays)) PodArrayZero(phaseTimes[d]); char* env = getenv("MOZ_GCTIMER"); if (env) { if (strcmp(env, "none") == 0) { fp = nullptr; } else if (strcmp(env, "stdout") == 0) { fp = stdout; } else if (strcmp(env, "stderr") == 0) { fp = stderr; } else { fp = fopen(env, "a"); if (!fp) MOZ_CRASH("Failed to open MOZ_GCTIMER log file."); } } }
void Statistics::endSlice() { if (!aborted) { slices.back().end = PRMJ_Now(); slices.back().endTimestamp = JS_GetCurrentEmbedderTime(); slices.back().endFaults = GetPageFaultCount(); slices.back().finalState = runtime->gc.state(); int64_t sliceTime = slices.back().end - slices.back().start; runtime->addTelemetry(JS_TELEMETRY_GC_SLICE_MS, t(sliceTime)); runtime->addTelemetry(JS_TELEMETRY_GC_RESET, !!slices.back().resetReason); if (slices.back().budget.isTimeBudget()) { int64_t budget_ms = slices.back().budget.timeBudget.budget; runtime->addTelemetry(JS_TELEMETRY_GC_BUDGET_MS, budget_ms); if (budget_ms == runtime->gc.defaultSliceBudget()) runtime->addTelemetry(JS_TELEMETRY_GC_ANIMATION_MS, t(sliceTime)); // Record any phase that goes more than 2x over its budget. if (sliceTime > 2 * budget_ms * 1000) { Phase longest = LongestPhase(slices.back().phaseTimes); runtime->addTelemetry(JS_TELEMETRY_GC_SLOW_PHASE, phases[longest].telemetryBucket); } } } bool last = !runtime->gc.isIncrementalGCInProgress(); if (last) endGC(); // Slice callbacks should only fire for the outermost level. if (gcDepth == 1 && !aborted) { bool wasFullGC = zoneStats.isCollectingAllZones(); if (sliceCallback) (*sliceCallback)(runtime->contextFromMainThread(), last ? JS::GC_CYCLE_END : JS::GC_SLICE_END, JS::GCDescription(!wasFullGC, gckind, slices.back().reason)); } /* Do this after the slice callback since it uses these values. */ if (last) PodArrayZero(counts); gcDepth--; MOZ_ASSERT(gcDepth >= 0); }
JSRuntime::JSRuntime(JSRuntime* parentRuntime) : mainThread(this), jitTop(nullptr), jitJSContext(nullptr), jitActivation(nullptr), jitStackLimit_(0xbad), jitStackLimitNoInterrupt_(0xbad), activation_(nullptr), profilingActivation_(nullptr), profilerSampleBufferGen_(0), profilerSampleBufferLapCount_(1), wasmActivationStack_(nullptr), asyncStackForNewActivations(this), asyncCauseForNewActivations(nullptr), asyncCallIsExplicit(false), entryMonitor(nullptr), noExecuteDebuggerTop(nullptr), parentRuntime(parentRuntime), #ifdef DEBUG updateChildRuntimeCount(parentRuntime), #endif interrupt_(false), telemetryCallback(nullptr), handlingSegFault(false), handlingJitInterrupt_(false), interruptCallback(nullptr), enqueuePromiseJobCallback(nullptr), enqueuePromiseJobCallbackData(nullptr), #ifdef DEBUG exclusiveAccessOwner(nullptr), mainThreadHasExclusiveAccess(false), #endif numExclusiveThreads(0), numCompartments(0), localeCallbacks(nullptr), defaultLocale(nullptr), defaultVersion_(JSVERSION_DEFAULT), ownerThread_(nullptr), ownerThreadNative_(0), tempLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE), jitRuntime_(nullptr), selfHostingGlobal_(nullptr), nativeStackBase(GetNativeStackBase()), cxCallback(nullptr), destroyCompartmentCallback(nullptr), sizeOfIncludingThisCompartmentCallback(nullptr), destroyZoneCallback(nullptr), sweepZoneCallback(nullptr), compartmentNameCallback(nullptr), activityCallback(nullptr), activityCallbackArg(nullptr), requestDepth(0), #ifdef DEBUG checkRequestDepth(0), activeContext(nullptr), #endif gc(thisFromCtor()), gcInitialized(false), #ifdef JS_SIMULATOR simulator_(nullptr), #endif scriptAndCountsVector(nullptr), lcovOutput(), NaNValue(DoubleNaNValue()), negativeInfinityValue(DoubleValue(NegativeInfinity<double>())), positiveInfinityValue(DoubleValue(PositiveInfinity<double>())), emptyString(nullptr), spsProfiler(thisFromCtor()), profilingScripts(false), suppressProfilerSampling(false), hadOutOfMemory(false), #ifdef DEBUG handlingInitFailure(false), #endif haveCreatedContext(false), allowRelazificationForTesting(false), data(nullptr), signalHandlersInstalled_(false), canUseSignalHandlers_(false), defaultFreeOp_(thisFromCtor()), debuggerMutations(0), securityCallbacks(&NullSecurityCallbacks), DOMcallbacks(nullptr), destroyPrincipals(nullptr), readPrincipals(nullptr), errorReporter(nullptr), buildIdOp(nullptr), propertyRemovals(0), #if !EXPOSE_INTL_API thousandsSeparator(0), decimalSeparator(0), numGrouping(0), #endif mathCache_(nullptr), activeCompilations_(0), keepAtoms_(0), trustedPrincipals_(nullptr), beingDestroyed_(false), atoms_(nullptr), atomsCompartment_(nullptr), staticStrings(nullptr), commonNames(nullptr), permanentAtoms(nullptr), wellKnownSymbols(nullptr), wrapObjectCallbacks(&DefaultWrapObjectCallbacks), preserveWrapperCallback(nullptr), jitSupportsFloatingPoint(false), jitSupportsSimd(false), ionPcScriptCache(nullptr), scriptEnvironmentPreparer(nullptr), ctypesActivityCallback(nullptr), windowProxyClass_(nullptr), offthreadIonCompilationEnabled_(true), parallelParsingEnabled_(true), autoWritableJitCodeActive_(false), #ifdef DEBUG enteredPolicy(nullptr), #endif largeAllocationFailureCallback(nullptr), oomCallback(nullptr), debuggerMallocSizeOf(ReturnZeroSize), lastAnimationTime(0), performanceMonitoring(thisFromCtor()) { setGCStoreBufferPtr(&gc.storeBuffer); liveRuntimesCount++; /* Initialize infallibly first, so we can goto bad and JS_DestroyRuntime. */ JS_INIT_CLIST(&onNewGlobalObjectWatchers); PodArrayZero(nativeStackQuota); PodZero(&asmJSCacheOps); lcovOutput.init(); }
void Statistics::endSlice() { if (!aborted) { slices.back().end = PRMJ_Now(); slices.back().endTimestamp = JS_GetCurrentEmbedderTime(); slices.back().endFaults = GetPageFaultCount(); slices.back().finalState = runtime->gc.state(); int64_t sliceTime = slices.back().end - slices.back().start; runtime->addTelemetry(JS_TELEMETRY_GC_SLICE_MS, t(sliceTime)); runtime->addTelemetry(JS_TELEMETRY_GC_RESET, slices.back().wasReset()); if (slices.back().wasReset()) runtime->addTelemetry(JS_TELEMETRY_GC_RESET_REASON, uint32_t(slices.back().resetReason)); if (slices.back().budget.isTimeBudget()) { int64_t budget_ms = slices.back().budget.timeBudget.budget; runtime->addTelemetry(JS_TELEMETRY_GC_BUDGET_MS, budget_ms); if (budget_ms == runtime->gc.defaultSliceBudget()) runtime->addTelemetry(JS_TELEMETRY_GC_ANIMATION_MS, t(sliceTime)); // Record any phase that goes more than 2x over its budget. if (sliceTime > 2 * budget_ms * 1000) { Phase longest = LongestPhase(slices.back().phaseTimes); runtime->addTelemetry(JS_TELEMETRY_GC_SLOW_PHASE, phases[longest].telemetryBucket); } } sliceCount_++; } bool last = !runtime->gc.isIncrementalGCInProgress(); if (last) endGC(); if (enableProfiling_ && !aborted && slices.back().duration() >= profileThreshold_) printSliceProfile(); // Slice callbacks should only fire for the outermost level. if (gcDepth == 1 && !aborted) { bool wasFullGC = zoneStats.isCollectingAllZones(); if (sliceCallback) (*sliceCallback)(runtime->contextFromMainThread(), last ? JS::GC_CYCLE_END : JS::GC_SLICE_END, JS::GCDescription(!wasFullGC, gckind, slices.back().reason)); } /* Do this after the slice callback since it uses these values. */ if (last) { PodArrayZero(counts); // Clear the timers at the end of a GC because we accumulate time in // between GCs for some (which come before PHASE_GC_BEGIN in the list.) PodZero(&phaseStartTimes[PHASE_GC_BEGIN], PHASE_LIMIT - PHASE_GC_BEGIN); for (size_t d = PHASE_DAG_NONE; d < NumTimingArrays; d++) PodZero(&phaseTimes[d][PHASE_GC_BEGIN], PHASE_LIMIT - PHASE_GC_BEGIN); } gcDepth--; MOZ_ASSERT(gcDepth >= 0); }
JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads) : JS::shadow::Runtime( #ifdef JSGC_GENERATIONAL &gcStoreBuffer #endif ), mainThread(this), interrupt(0), handlingSignal(false), operationCallback(nullptr), #ifdef JS_THREADSAFE operationCallbackLock(nullptr), operationCallbackOwner(nullptr), #else operationCallbackLockTaken(false), #endif #ifdef JS_WORKER_THREADS workerThreadState(nullptr), exclusiveAccessLock(nullptr), exclusiveAccessOwner(nullptr), mainThreadHasExclusiveAccess(false), numExclusiveThreads(0), #endif systemZone(nullptr), numCompartments(0), localeCallbacks(nullptr), defaultLocale(nullptr), defaultVersion_(JSVERSION_DEFAULT), #ifdef JS_THREADSAFE ownerThread_(nullptr), #endif tempLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE), freeLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE), execAlloc_(nullptr), bumpAlloc_(nullptr), jitRuntime_(nullptr), selfHostingGlobal_(nullptr), nativeStackBase(0), cxCallback(nullptr), destroyCompartmentCallback(nullptr), destroyZoneCallback(nullptr), sweepZoneCallback(nullptr), compartmentNameCallback(nullptr), activityCallback(nullptr), activityCallbackArg(nullptr), #ifdef JS_THREADSAFE requestDepth(0), # ifdef DEBUG checkRequestDepth(0), # endif #endif gcSystemAvailableChunkListHead(nullptr), gcUserAvailableChunkListHead(nullptr), gcBytes(0), gcMaxBytes(0), gcMaxMallocBytes(0), gcNumArenasFreeCommitted(0), gcMarker(this), gcVerifyPreData(nullptr), gcVerifyPostData(nullptr), gcChunkAllocationSinceLastGC(false), gcNextFullGCTime(0), gcLastGCTime(0), gcJitReleaseTime(0), gcAllocationThreshold(30 * 1024 * 1024), gcHighFrequencyGC(false), gcHighFrequencyTimeThreshold(1000), gcHighFrequencyLowLimitBytes(100 * 1024 * 1024), gcHighFrequencyHighLimitBytes(500 * 1024 * 1024), gcHighFrequencyHeapGrowthMax(3.0), gcHighFrequencyHeapGrowthMin(1.5), gcLowFrequencyHeapGrowth(1.5), gcDynamicHeapGrowth(false), gcDynamicMarkSlice(false), gcDecommitThreshold(32 * 1024 * 1024), gcShouldCleanUpEverything(false), gcGrayBitsValid(false), gcIsNeeded(0), gcStats(thisFromCtor()), gcNumber(0), gcStartNumber(0), gcIsFull(false), gcTriggerReason(JS::gcreason::NO_REASON), gcStrictCompartmentChecking(false), #ifdef DEBUG gcDisableStrictProxyCheckingCount(0), #endif gcIncrementalState(gc::NO_INCREMENTAL), gcLastMarkSlice(false), gcSweepOnBackgroundThread(false), gcFoundBlackGrayEdges(false), gcSweepingZones(nullptr), gcZoneGroupIndex(0), gcZoneGroups(nullptr), gcCurrentZoneGroup(nullptr), gcSweepPhase(0), gcSweepZone(nullptr), gcSweepKindIndex(0), gcAbortSweepAfterCurrentGroup(false), gcArenasAllocatedDuringSweep(nullptr), #ifdef DEBUG gcMarkingValidator(nullptr), #endif gcInterFrameGC(0), gcSliceBudget(SliceBudget::Unlimited), gcIncrementalEnabled(true), gcGenerationalEnabled(true), gcManipulatingDeadZones(false), gcObjectsMarkedInDeadZones(0), gcPoke(false), heapState(Idle), #ifdef JSGC_GENERATIONAL gcNursery(thisFromCtor()), gcStoreBuffer(thisFromCtor(), gcNursery), #endif #ifdef JS_GC_ZEAL gcZeal_(0), gcZealFrequency(0), gcNextScheduled(0), gcDeterministicOnly(false), gcIncrementalLimit(0), #endif gcValidate(true), gcFullCompartmentChecks(false), gcCallback(nullptr), gcSliceCallback(nullptr), gcFinalizeCallback(nullptr), gcMallocBytes(0), gcMallocGCTriggered(false), scriptAndCountsVector(nullptr), NaNValue(DoubleNaNValue()), negativeInfinityValue(DoubleValue(NegativeInfinity())), positiveInfinityValue(DoubleValue(PositiveInfinity())), emptyString(nullptr), debugMode(false), spsProfiler(thisFromCtor()), profilingScripts(false), alwaysPreserveCode(false), hadOutOfMemory(false), haveCreatedContext(false), data(nullptr), gcLock(nullptr), gcLockOwner(nullptr), gcHelperThread(thisFromCtor()), signalHandlersInstalled_(false), defaultFreeOp_(thisFromCtor(), false), debuggerMutations(0), securityCallbacks(const_cast<JSSecurityCallbacks *>(&NullSecurityCallbacks)), DOMcallbacks(nullptr), destroyPrincipals(nullptr), structuredCloneCallbacks(nullptr), telemetryCallback(nullptr), propertyRemovals(0), #if !EXPOSE_INTL_API thousandsSeparator(0), decimalSeparator(0), numGrouping(0), #endif heapProtected_(false), mathCache_(nullptr), activeCompilations_(0), keepAtoms_(0), trustedPrincipals_(nullptr), atomsCompartment_(nullptr), beingDestroyed_(false), wrapObjectCallback(TransparentObjectWrapper), sameCompartmentWrapObjectCallback(nullptr), preWrapObjectCallback(nullptr), preserveWrapperCallback(nullptr), #ifdef DEBUG noGCOrAllocationCheck(0), #endif jitHardening(false), jitSupportsFloatingPoint(false), ionPcScriptCache(nullptr), threadPool(this), defaultJSContextCallback(nullptr), ctypesActivityCallback(nullptr), parallelWarmup(0), ionReturnOverride_(MagicValue(JS_ARG_POISON)), useHelperThreads_(useHelperThreads), #ifdef JS_THREADSAFE cpuCount_(GetCPUCount()), #else cpuCount_(1), #endif parallelIonCompilationEnabled_(true), parallelParsingEnabled_(true), isWorkerRuntime_(false) #ifdef DEBUG , enteredPolicy(nullptr) #endif { MOZ_ASSERT(cpuCount_ > 0, "GetCPUCount() seems broken"); liveRuntimesCount++; setGCMode(JSGC_MODE_GLOBAL); /* Initialize infallibly first, so we can goto bad and JS_DestroyRuntime. */ JS_INIT_CLIST(&onNewGlobalObjectWatchers); PodZero(&debugHooks); PodZero(&atomState); PodArrayZero(nativeStackQuota); PodZero(&asmJSCacheOps); #if JS_STACK_GROWTH_DIRECTION > 0 nativeStackLimit = UINTPTR_MAX; #endif }
Statistics::Statistics(JSRuntime* rt) : runtime(rt), startupTime(PRMJ_Now()), fp(nullptr), fullFormat(false), gcDepth(0), nonincrementalReason_(nullptr), timedGCStart(0), preBytes(0), maxPauseInInterval(0), phaseNestingDepth(0), activeDagSlot(PHASE_DAG_NONE), suspendedPhaseNestingDepth(0), sliceCallback(nullptr), aborted(false) { PodArrayZero(phaseTotals); PodArrayZero(counts); PodArrayZero(phaseStartTimes); for (size_t d = 0; d < MAX_MULTIPARENT_PHASES + 1; d++) PodArrayZero(phaseTimes[d]); static bool initialized = false; if (!initialized) { initialized = true; for (size_t i = 0; i < PHASE_LIMIT; i++) MOZ_ASSERT(phases[i].index == i); // Create a static table of descendants for every phase with multiple // children. This assumes that all descendants come linearly in the // list, which is reasonable since full dags are not supported; any // path from the leaf to the root must encounter at most one node with // multiple parents. size_t dagSlot = 0; for (size_t i = 0; i < mozilla::ArrayLength(dagChildEdges); i++) { Phase parent = dagChildEdges[i].parent; if (!phaseExtra[parent].dagSlot) phaseExtra[parent].dagSlot = ++dagSlot; Phase child = dagChildEdges[i].child; MOZ_ASSERT(phases[child].parent == PHASE_MULTI_PARENTS); int j = child; do { dagDescendants[phaseExtra[parent].dagSlot].append(Phase(j)); j++; } while (j != PHASE_LIMIT && phases[j].parent != PHASE_MULTI_PARENTS); } MOZ_ASSERT(dagSlot <= MAX_MULTIPARENT_PHASES); // Fill in the depth of each node in the tree. Multi-parented nodes // have depth 0. mozilla::Vector<Phase> stack; stack.append(PHASE_LIMIT); // Dummy entry to avoid special-casing the first node for (int i = 0; i < PHASE_LIMIT; i++) { if (phases[i].parent == PHASE_NO_PARENT || phases[i].parent == PHASE_MULTI_PARENTS) { stack.clear(); } else { while (stack.back() != phases[i].parent) stack.popBack(); } phaseExtra[i].depth = stack.length(); stack.append(Phase(i)); } } char* env = getenv("MOZ_GCTIMER"); if (!env || strcmp(env, "none") == 0) { fp = nullptr; return; } if (strcmp(env, "stdout") == 0) { fullFormat = false; fp = stdout; } else if (strcmp(env, "stderr") == 0) { fullFormat = false; fp = stderr; } else { fullFormat = true; fp = fopen(env, "a"); MOZ_ASSERT(fp); } }
JSRuntime::JSRuntime(JSRuntime *parentRuntime, JSUseHelperThreads useHelperThreads) : JS::shadow::Runtime( #ifdef JSGC_GENERATIONAL &gc.storeBuffer #endif ), mainThread(this), parentRuntime(parentRuntime), interrupt(false), #if defined(JS_THREADSAFE) && defined(JS_ION) interruptPar(false), #endif handlingSignal(false), interruptCallback(nullptr), #ifdef JS_THREADSAFE interruptLock(nullptr), interruptLockOwner(nullptr), exclusiveAccessLock(nullptr), exclusiveAccessOwner(nullptr), mainThreadHasExclusiveAccess(false), numExclusiveThreads(0), #else interruptLockTaken(false), #endif numCompartments(0), localeCallbacks(nullptr), defaultLocale(nullptr), defaultVersion_(JSVERSION_DEFAULT), #ifdef JS_THREADSAFE ownerThread_(nullptr), #endif tempLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE), freeLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE), execAlloc_(nullptr), #ifdef JS_YARR bumpAlloc_(nullptr), #endif jitRuntime_(nullptr), selfHostingGlobal_(nullptr), nativeStackBase(0), cxCallback(nullptr), destroyCompartmentCallback(nullptr), destroyZoneCallback(nullptr), sweepZoneCallback(nullptr), compartmentNameCallback(nullptr), activityCallback(nullptr), activityCallbackArg(nullptr), #ifdef JS_THREADSAFE requestDepth(0), # ifdef DEBUG checkRequestDepth(0), # endif #endif #ifdef DEBUG activeContext(nullptr), #endif gc(thisFromCtor()), gcInitialized(false), #if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR) simulatorRuntime_(nullptr), #endif NaNValue(DoubleNaNValue()), negativeInfinityValue(DoubleValue(NegativeInfinity<double>())), positiveInfinityValue(DoubleValue(PositiveInfinity<double>())), emptyString(nullptr), debugMode(false), spsProfiler(thisFromCtor()), profilingScripts(false), hadOutOfMemory(false), haveCreatedContext(false), data(nullptr), signalHandlersInstalled_(false), defaultFreeOp_(thisFromCtor(), false), debuggerMutations(0), securityCallbacks(const_cast<JSSecurityCallbacks *>(&NullSecurityCallbacks)), DOMcallbacks(nullptr), destroyPrincipals(nullptr), structuredCloneCallbacks(nullptr), telemetryCallback(nullptr), propertyRemovals(0), #if !EXPOSE_INTL_API thousandsSeparator(0), decimalSeparator(0), numGrouping(0), #endif mathCache_(nullptr), activeCompilations_(0), keepAtoms_(0), trustedPrincipals_(nullptr), beingDestroyed_(false), atoms_(nullptr), atomsCompartment_(nullptr), staticStrings(nullptr), commonNames(nullptr), permanentAtoms(nullptr), wrapObjectCallbacks(&DefaultWrapObjectCallbacks), preserveWrapperCallback(nullptr), jitSupportsFloatingPoint(false), ionPcScriptCache(nullptr), threadPool(this), defaultJSContextCallback(nullptr), ctypesActivityCallback(nullptr), forkJoinWarmup(0), useHelperThreads_(useHelperThreads), parallelIonCompilationEnabled_(true), parallelParsingEnabled_(true), isWorkerRuntime_(false), #ifdef DEBUG enteredPolicy(nullptr), #endif largeAllocationFailureCallback(nullptr), oomCallback(nullptr) { liveRuntimesCount++; setGCMode(JSGC_MODE_GLOBAL); /* Initialize infallibly first, so we can goto bad and JS_DestroyRuntime. */ JS_INIT_CLIST(&onNewGlobalObjectWatchers); PodZero(&debugHooks); PodArrayZero(nativeStackQuota); PodZero(&asmJSCacheOps); }
AutoMessageArgs() : totalLength_(0), count_(0), allocatedElements_(false) { PodArrayZero(args_); }