mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 23:38:38 +09:00
Fix compile errors pt 2 (before the HELL)
This commit is contained in:
parent
ad7238c226
commit
622cee0b14
12 changed files with 191 additions and 25 deletions
|
|
@ -108,6 +108,8 @@ const size_t gStackSize = 8192;
|
|||
// Maximum amount of time that should elapse between incremental GC slices
|
||||
#define NS_INTERSLICE_GC_DELAY 100 // ms
|
||||
|
||||
#define NS_INTERSLICE_GC_BUDGET 5 // ms
|
||||
|
||||
// Maximum amount of time that should elapse between incremental GC slices
|
||||
#define NS_INTERSLICE_GC_DELAY 100 // ms
|
||||
|
||||
|
|
@ -189,6 +191,8 @@ static bool sNeedsFullGC = false;
|
|||
static bool sNeedsGCAfterCC = false;
|
||||
static bool sIncrementalCC = false;
|
||||
static int32_t sActiveIntersliceGCBudget = 5; // ms;
|
||||
static bool sDidPaintAfterPreviousICCSlice = false;
|
||||
static uint32_t sCCTimerFireCount = 0;
|
||||
static nsScriptNameSpaceManager *gNameSpaceManager;
|
||||
|
||||
static PRTime sFirstCollectionTime;
|
||||
|
|
@ -1531,7 +1535,7 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
|
|||
|
||||
//static
|
||||
void
|
||||
nsJSContext::RunCycleCollectorSlice()
|
||||
nsJSContext::RunCycleCollectorSlice(const TimeStamp& aDeadline)
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
return;
|
||||
|
|
@ -1637,7 +1641,7 @@ ICCTimerFired(nsITimer* aTimer, void* aClosure)
|
|||
}
|
||||
}
|
||||
|
||||
nsJSContext::RunCycleCollectorSlice();
|
||||
nsJSContext::RunCycleCollectorSlice(TimeStamp());
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
@ -1816,6 +1820,7 @@ InterSliceGCTimerFired(nsITimer *aTimer, void *aClosure)
|
|||
// We use longer budgets when the CC has been locked out but the CC has tried
|
||||
// to run since that means we may have significant amount garbage to collect
|
||||
// and better to GC in several longer slices than in a very long one.
|
||||
TimeStamp aDeadline; // no idle deadline available in timer callback
|
||||
int64_t budget = aDeadline.IsNull() ?
|
||||
int64_t(sActiveIntersliceGCBudget * 2) :
|
||||
int64_t((aDeadline - TimeStamp::Now()).ToMilliseconds());
|
||||
|
|
@ -1829,8 +1834,8 @@ InterSliceGCTimerFired(nsITimer *aTimer, void *aClosure)
|
|||
std::max((double)budget, percentOfLockedTime * maxSliceGCBudget));
|
||||
}
|
||||
|
||||
uintptr_t reason = reinterpret_cast<uintptr_t>(aData);
|
||||
nsJSContext::GarbageCollectNow(aData ?
|
||||
uintptr_t reason = reinterpret_cast<uintptr_t>(aClosure);
|
||||
nsJSContext::GarbageCollectNow(aClosure ?
|
||||
static_cast<JS::gcreason::Reason>(reason) :
|
||||
JS::gcreason::INTER_SLICE_GC,
|
||||
nsJSContext::IncrementalGC,
|
||||
|
|
@ -1906,9 +1911,10 @@ CCTimerFired(nsITimer *aTimer, void *aClosure)
|
|||
int32_t numEarlyTimerFires = std::max((int32_t)ccDelay / NS_CC_SKIPPABLE_DELAY - 2, 1);
|
||||
bool isLateTimerFire = sCCRunnerFireCount > numEarlyTimerFires;
|
||||
uint32_t suspected = nsCycleCollector_suspectedCount();
|
||||
TimeStamp deadline; // no idle deadline in timer callback
|
||||
if (isLateTimerFire && ShouldTriggerCC(suspected)) {
|
||||
if (sCCRunnerFireCount == numEarlyTimerFires + 1) {
|
||||
FireForgetSkippable(suspected, true, aDeadline);
|
||||
FireForgetSkippable(suspected, true, deadline);
|
||||
didDoWork = true;
|
||||
if (ShouldTriggerCC(nsCycleCollector_suspectedCount())) {
|
||||
// Our efforts to avoid a CC have failed, so we return to let the
|
||||
|
|
@ -1919,14 +1925,14 @@ CCTimerFired(nsITimer *aTimer, void *aClosure)
|
|||
// We are in the final timer fire and still meet the conditions for
|
||||
// triggering a CC. Let RunCycleCollectorSlice finish the current IGC, if
|
||||
// any because that will allow us to include the GC time in the CC pause.
|
||||
nsJSContext::RunCycleCollectorSlice(aDeadline);
|
||||
nsJSContext::RunCycleCollectorSlice(deadline);
|
||||
didDoWork = true;
|
||||
}
|
||||
} else if (((sPreviousSuspectedCount + 100) <= suspected) ||
|
||||
(sCleanupsSinceLastGC < NS_MAJOR_FORGET_SKIPPABLE_CALLS)) {
|
||||
// Only do a forget skippable if there are more than a few new objects
|
||||
// or we're doing the initial forget skippables.
|
||||
FireForgetSkippable(suspected, false, aDeadline);
|
||||
FireForgetSkippable(suspected, false, deadline);
|
||||
didDoWork = true;
|
||||
}
|
||||
|
||||
|
|
@ -2034,7 +2040,7 @@ nsJSContext::RunNextCollectorTimer()
|
|||
|
||||
// static
|
||||
void
|
||||
nsJSContext::PokeGC(JS::gcreason::Reason aReason, int aDelay)
|
||||
nsJSContext::PokeGC(JS::gcreason::Reason aReason, int aDelay, JSObject* aObj)
|
||||
{
|
||||
sNeedsFullGC = sNeedsFullGC || aReason != JS::gcreason::CC_WAITING;
|
||||
|
||||
|
|
@ -2147,6 +2153,16 @@ nsJSContext::KillGCTimer()
|
|||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void
|
||||
nsJSContext::KillCCTimer()
|
||||
{
|
||||
if (sCCTimer) {
|
||||
sCCTimer->Cancel();
|
||||
NS_RELEASE(sCCTimer);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsJSContext::KillFullGCTimer()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ public:
|
|||
int32_t aExtraForgetSkippableCalls = 0);
|
||||
|
||||
// Run a cycle collector slice, using a heuristic to decide how long to run it.
|
||||
static void RunCycleCollectorSlice();
|
||||
static void RunCycleCollectorSlice(const mozilla::TimeStamp& aDeadline = mozilla::TimeStamp());
|
||||
|
||||
// Run a cycle collector slice, using the given work budget.
|
||||
static void RunCycleCollectorWorkSlice(int64_t aWorkBudget);
|
||||
|
|
@ -105,9 +105,11 @@ public:
|
|||
|
||||
static void RunNextCollectorTimer();
|
||||
|
||||
static void PokeGC(JS::gcreason::Reason aReason, int aDelay = 0);
|
||||
static void PokeGC(JS::gcreason::Reason aReason, int aDelay = 0, JSObject* aObj = nullptr);
|
||||
static void KillGCTimer();
|
||||
|
||||
static void KillCCTimer();
|
||||
|
||||
static void PokeShrinkingGC();
|
||||
static void KillShrinkingGCTimer();
|
||||
|
||||
|
|
@ -117,6 +119,8 @@ public:
|
|||
static void KillFullGCTimer();
|
||||
static void KillInterSliceGCRunner();
|
||||
|
||||
static void NotifyDidPaint();
|
||||
|
||||
// Calling LikelyShortLivingObjectCreated() makes a GC more likely.
|
||||
static void LikelyShortLivingObjectCreated();
|
||||
|
||||
|
|
|
|||
|
|
@ -323,7 +323,7 @@ typedef void
|
|||
* can be called off the main thread.
|
||||
*/
|
||||
struct JSStringFinalizer {
|
||||
void (*finalize)(const JSStringFinalizer* fin, char16_t* chars);
|
||||
void (*finalize)(JS::Zone* zone, const JSStringFinalizer* fin, char16_t* chars);
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -346,6 +346,7 @@ struct Zone;
|
|||
D(OUT_OF_NURSERY) \
|
||||
D(EVICT_NURSERY) \
|
||||
D(FULL_STORE_BUFFER) \
|
||||
D(FULL_SLOT_BUFFER) \
|
||||
D(SHARED_MEMORY_LIMIT) \
|
||||
D(UNUSED1) \
|
||||
D(INCREMENTAL_TOO_SLOW) \
|
||||
|
|
@ -986,6 +987,9 @@ JS_UpdateWeakPointerAfterGCUnbarriered(JSObject** objp);
|
|||
extern JS_PUBLIC_API(void)
|
||||
JS_SetGCParameter(JSContext* cx, JSGCParamKey key, uint32_t value);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_SetGGCMode(JSContext* cx, bool enabled);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_ResetGCParameter(JSContext* cx, JSGCParamKey key);
|
||||
|
||||
|
|
|
|||
113
js/src/ds/Bitmap.h
Normal file
113
js/src/ds/Bitmap.h
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef ds_Bitmap_h
|
||||
#define ds_Bitmap_h
|
||||
|
||||
#include "mozilla/PodOperations.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace js {
|
||||
|
||||
// DenseBitmap is an simple dynamically-sized bitmap backed by a vector of
|
||||
// words.
|
||||
class DenseBitmap
|
||||
{
|
||||
using Word = uintptr_t;
|
||||
|
||||
Word* data_;
|
||||
size_t numWords_;
|
||||
|
||||
public:
|
||||
DenseBitmap()
|
||||
: data_(nullptr), numWords_(0)
|
||||
{}
|
||||
|
||||
~DenseBitmap()
|
||||
{
|
||||
js_free(data_);
|
||||
}
|
||||
|
||||
bool ensureSpace(size_t newWords)
|
||||
{
|
||||
if (newWords <= numWords_)
|
||||
return true;
|
||||
|
||||
size_t newSize = sizeof(Word) * newWords;
|
||||
Word* newData = static_cast<Word*>(js_realloc(data_, newSize));
|
||||
if (!newData)
|
||||
return false;
|
||||
|
||||
mozilla::PodZero(newData + numWords_, newWords - numWords_);
|
||||
data_ = newData;
|
||||
numWords_ = newWords;
|
||||
return true;
|
||||
}
|
||||
|
||||
void copyBitsFrom(size_t dstStart, size_t wordCount, const Word* src)
|
||||
{
|
||||
MOZ_ASSERT(dstStart + wordCount <= numWords_);
|
||||
memcpy(data_ + dstStart, src, sizeof(Word) * wordCount);
|
||||
}
|
||||
|
||||
void bitwiseAndWith(const DenseBitmap& other)
|
||||
{
|
||||
MOZ_ASSERT(numWords_ == other.numWords_);
|
||||
for (size_t i = 0; i < numWords_; i++)
|
||||
data_[i] &= other.data_[i];
|
||||
}
|
||||
|
||||
void bitwiseOrRangeInto(size_t srcStart, size_t wordCount, Word* dst) const
|
||||
{
|
||||
MOZ_ASSERT(srcStart + wordCount <= numWords_);
|
||||
for (size_t i = 0; i < wordCount; i++)
|
||||
dst[i] |= data_[srcStart + i];
|
||||
}
|
||||
|
||||
void bitwiseOrInto(DenseBitmap& other) const
|
||||
{
|
||||
MOZ_ASSERT(numWords_ == other.numWords_);
|
||||
for (size_t i = 0; i < numWords_; i++)
|
||||
other.data_[i] |= data_[i];
|
||||
}
|
||||
|
||||
void bitwiseOrWith(const DenseBitmap& other)
|
||||
{
|
||||
MOZ_ASSERT(numWords_ == other.numWords_);
|
||||
for (size_t i = 0; i < numWords_; i++)
|
||||
data_[i] |= other.data_[i];
|
||||
}
|
||||
|
||||
bool getBit(size_t bit) const
|
||||
{
|
||||
size_t wordIndex = bit / (sizeof(Word) * 8);
|
||||
size_t bitIndex = bit % (sizeof(Word) * 8);
|
||||
MOZ_ASSERT(wordIndex < numWords_);
|
||||
return data_[wordIndex] & (Word(1) << bitIndex);
|
||||
}
|
||||
|
||||
void setBit(size_t bit)
|
||||
{
|
||||
size_t wordIndex = bit / (sizeof(Word) * 8);
|
||||
size_t bitIndex = bit % (sizeof(Word) * 8);
|
||||
MOZ_ASSERT(wordIndex < numWords_);
|
||||
data_[wordIndex] |= (Word(1) << bitIndex);
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Word* data() { return data_; }
|
||||
size_t numWords() const { return numWords_; }
|
||||
};
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif // ds_Bitmap_h
|
||||
|
|
@ -613,7 +613,7 @@ struct ChunkBitmap
|
|||
uintptr_t** wordp, uintptr_t* maskp)
|
||||
{
|
||||
MOZ_ASSERT(size_t(colorBit) < MarkBitsPerCell);
|
||||
detail::GetGCThingMarkWordAndMask(uintptr_t(cell), colorBit, wordp, maskp);
|
||||
detail::GetGCThingMarkWordAndMask(uintptr_t(cell), uint32_t(colorBit), wordp, maskp);
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE MOZ_TSAN_BLACKLIST bool markBit(const TenuredCell* cell, ColorBit colorBit) {
|
||||
|
|
@ -637,7 +637,7 @@ struct ChunkBitmap
|
|||
// The return value indicates if the cell went from unmarked to marked.
|
||||
MOZ_ALWAYS_INLINE bool markIfUnmarked(const TenuredCell* cell, MarkColor color) {
|
||||
uintptr_t* word, mask;
|
||||
getMarkWordAndMask(cell, BLACK, &word, &mask);
|
||||
getMarkWordAndMask(cell, ColorBit::BlackBit, &word, &mask);
|
||||
if (*word & mask)
|
||||
return false;
|
||||
if (color == MarkColor::Black) {
|
||||
|
|
@ -647,7 +647,7 @@ struct ChunkBitmap
|
|||
* We use getMarkWordAndMask to recalculate both mask and word as
|
||||
* doing just mask << color may overflow the mask.
|
||||
*/
|
||||
getMarkWordAndMask(cell, color, &word, &mask);
|
||||
getMarkWordAndMask(cell, ColorBit(uint32_t(color)), &word, &mask);
|
||||
if (*word & mask)
|
||||
return false;
|
||||
*word |= mask;
|
||||
|
|
@ -657,8 +657,8 @@ struct ChunkBitmap
|
|||
|
||||
MOZ_ALWAYS_INLINE void markBlack(const TenuredCell* cell) {
|
||||
uintptr_t* word, mask;
|
||||
getMarkWordAndMask(cell, color, &word, &mask);
|
||||
*word &= ~mask;
|
||||
getMarkWordAndMask(cell, ColorBit::BlackBit, &word, &mask);
|
||||
*word |= mask;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE void copyMarkBit(TenuredCell* dst, const TenuredCell* src,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#define gc_Nursery_h
|
||||
|
||||
#include "mozilla/EnumeratedArray.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
||||
#include "js/Class.h"
|
||||
#include "js/HeapAPI.h"
|
||||
|
|
@ -381,6 +382,8 @@ class Nursery
|
|||
*/
|
||||
unsigned chunkCountLimit_;
|
||||
|
||||
mozilla::Atomic<JS::gcreason::Reason, mozilla::Relaxed> minorGCTriggerReason_;
|
||||
|
||||
mozilla::TimeDuration timeInChunkAlloc_;
|
||||
|
||||
/* Promotion rate for the previous minor collection. */
|
||||
|
|
@ -471,7 +474,7 @@ class Nursery
|
|||
* sweep. This is because this structure is used to help implement
|
||||
* stable object hashing and we have to break the cycle somehow.
|
||||
*/
|
||||
using CellsWithUniqueIdSet = HashSet<gc::Cell*, PointerHasher<gc::Cell*, 3>, SystemAllocPolicy>;
|
||||
using CellsWithUniqueIdSet = HashSet<gc::Cell*, PointerHasher<gc::Cell*>, SystemAllocPolicy>;
|
||||
CellsWithUniqueIdSet cellsWithUid_;
|
||||
|
||||
struct SweepAction;
|
||||
|
|
@ -502,7 +505,6 @@ class Nursery
|
|||
MOZ_ALWAYS_INLINE uintptr_t currentEnd() const;
|
||||
|
||||
uintptr_t position() const { return position_; }
|
||||
void* addressOfPosition() const { return (void*)&position_; }
|
||||
|
||||
JSRuntime* runtime() const { return runtime_; }
|
||||
|
||||
|
|
|
|||
|
|
@ -625,6 +625,13 @@ struct Zone : public JS::shadow::Zone,
|
|||
js::ZoneGroupData<bool> gcPreserveCode_;
|
||||
js::ZoneGroupData<bool> keepShapeTables_;
|
||||
|
||||
js::ZoneGroupData<js::DenseBitmap> markedAtoms_;
|
||||
|
||||
public:
|
||||
js::DenseBitmap& markedAtoms() { return markedAtoms_.ref(); }
|
||||
|
||||
private:
|
||||
|
||||
// Allow zones to be linked into a list
|
||||
friend class js::gc::ZoneList;
|
||||
static Zone * const NotOnList;
|
||||
|
|
|
|||
|
|
@ -837,10 +837,10 @@ JS_IsBuiltinFunctionConstructor(JSFunction* fun);
|
|||
* See: http://developer.mozilla.org/en/docs/Category:JSAPI_Reference
|
||||
*/
|
||||
|
||||
extern JS_PUBLIC_API(JSContext*)
|
||||
JS_NewContext(uint32_t maxbytes,
|
||||
uint32_t maxNurseryBytes = JS::DefaultNurseryBytes,
|
||||
JSRuntime* parentRuntime = nullptr);
|
||||
extern JS_PUBLIC_API(JSContext*)
|
||||
JS_NewContext(uint32_t maxbytes,
|
||||
uint32_t maxNurseryBytes = JS::DefaultNurseryBytes,
|
||||
JSContext* parentContext = nullptr);
|
||||
|
||||
// The methods below for controlling the active context in a cooperatively
|
||||
// multithreaded runtime are not threadsafe, and the caller must ensure they
|
||||
|
|
|
|||
|
|
@ -1030,7 +1030,7 @@ class NativeObject : public ShapedObject
|
|||
for (size_t i = 0; i < count; i++) {
|
||||
const Value& v = elements_[start + i];
|
||||
if (v.isObject() && IsInsideNursery(&v.toObject())) {
|
||||
JS::shadow::Runtime* shadowRuntime = shadowRuntimeFromMainThread();
|
||||
JS::shadow::Runtime* shadowRuntime = JS::shadow::Runtime::asShadowRuntime(runtimeFromMainThread());
|
||||
shadowRuntime->gcStoreBufferPtr()->putSlot(this, HeapSlot::Element,
|
||||
start + i, count - i);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ class TraceLoggerThread
|
|||
private:
|
||||
typedef HashMap<const void*,
|
||||
TraceLoggerEventPayload*,
|
||||
PointerHasher<const void*, 3>,
|
||||
PointerHasher<const void*>,
|
||||
SystemAllocPolicy> PointerHashMap;
|
||||
typedef HashMap<uint32_t,
|
||||
TraceLoggerEventPayload*,
|
||||
|
|
|
|||
|
|
@ -1492,7 +1492,7 @@ ReloadPrefsCallback(const char* pref, void* data)
|
|||
JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_BASELINE_WARMUP_TRIGGER,
|
||||
baselineWarmUpThreshold);
|
||||
JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_ION_WARMUP_TRIGGER,
|
||||
useIonEager ? 0 : ionThreshold);
|
||||
useIonEager ? 0 : ionWarmUpThreshold);
|
||||
#ifdef DEBUG
|
||||
JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_FULL_DEBUG_CHECKS, fullJitDebugChecks);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -916,6 +916,20 @@ template<typename S>
|
|||
struct IsParameterStorageClass<StorensRefPtrPassByPtr<S>>
|
||||
: public mozilla::TrueType {};
|
||||
|
||||
template<typename T>
|
||||
struct StorensAutoPtrPassByRRef
|
||||
{
|
||||
typedef nsAutoPtr<T> stored_type;
|
||||
typedef nsAutoPtr<T> passed_type;
|
||||
stored_type m;
|
||||
template <typename A>
|
||||
MOZ_IMPLICIT StorensAutoPtrPassByRRef(A&& a) : m(mozilla::Forward<A>(a)) {}
|
||||
passed_type PassAsParameter() { return mozilla::Move(m); }
|
||||
};
|
||||
template<typename S>
|
||||
struct IsParameterStorageClass<StorensAutoPtrPassByRRef<S>>
|
||||
: public mozilla::TrueType {};
|
||||
|
||||
template<typename T>
|
||||
struct StorePtrPassByPtr
|
||||
{
|
||||
|
|
@ -1022,6 +1036,12 @@ struct SmartPointerStorageClass
|
|||
StoreCopyPassByConstLRef<T>>
|
||||
{};
|
||||
|
||||
template<typename T>
|
||||
struct SmartPointerStorageClass<nsAutoPtr<T>>
|
||||
{
|
||||
typedef StorensAutoPtrPassByRRef<T> Type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct NonLValueReferenceStorageClass
|
||||
: mozilla::Conditional<mozilla::IsRvalueReference<T>::value,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue