зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1194832 - Use a one element cache in the store buffer; r=jonco
--HG-- extra : rebase_source : 53008889e2d5f52fbe96fcbec49251ce87db5f7e
This commit is contained in:
Родитель
fe42d2decd
Коммит
4e2856a22c
|
@ -1900,7 +1900,7 @@ js::gc::StoreBuffer::MonoTypeBuffer<T>::trace(StoreBuffer* owner, TenuringTracer
|
||||||
mozilla::ReentrancyGuard g(*owner);
|
mozilla::ReentrancyGuard g(*owner);
|
||||||
MOZ_ASSERT(owner->isEnabled());
|
MOZ_ASSERT(owner->isEnabled());
|
||||||
MOZ_ASSERT(stores_.initialized());
|
MOZ_ASSERT(stores_.initialized());
|
||||||
sinkStores(owner);
|
sinkStore(owner);
|
||||||
for (typename StoreSet::Range r = stores_.all(); !r.empty(); r.popFront())
|
for (typename StoreSet::Range r = stores_.all(); !r.empty(); r.popFront())
|
||||||
r.front().trace(mover);
|
r.front().trace(mover);
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,17 +62,15 @@ class StoreBuffer
|
||||||
StoreSet stores_;
|
StoreSet stores_;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A small, fixed-size buffer in front of the canonical set to simplify
|
* A one element cache in front of the canonical set to speed up
|
||||||
* insertion via jit code.
|
* temporary instances of RelocatablePtr.
|
||||||
*/
|
*/
|
||||||
const static size_t NumBufferEntries = 4096 / sizeof(T);
|
T last_;
|
||||||
T buffer_[NumBufferEntries];
|
|
||||||
T* insert_;
|
|
||||||
|
|
||||||
/* Maximum number of entries before we request a minor GC. */
|
/* Maximum number of entries before we request a minor GC. */
|
||||||
const static size_t MaxEntries = 48 * 1024 / sizeof(T);
|
const static size_t MaxEntries = 48 * 1024 / sizeof(T);
|
||||||
|
|
||||||
explicit MonoTypeBuffer() { clearBuffer(); }
|
explicit MonoTypeBuffer() : last_(T()) {}
|
||||||
~MonoTypeBuffer() { stores_.finish(); }
|
~MonoTypeBuffer() { stores_.finish(); }
|
||||||
|
|
||||||
bool init() {
|
bool init() {
|
||||||
|
@ -82,13 +80,8 @@ class StoreBuffer
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearBuffer() {
|
|
||||||
JS_POISON(buffer_, JS_EMPTY_STOREBUFFER_PATTERN, NumBufferEntries * sizeof(T));
|
|
||||||
insert_ = buffer_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
clearBuffer();
|
last_ = T();
|
||||||
if (stores_.initialized())
|
if (stores_.initialized())
|
||||||
stores_.clear();
|
stores_.clear();
|
||||||
}
|
}
|
||||||
|
@ -96,33 +89,35 @@ class StoreBuffer
|
||||||
/* Add one item to the buffer. */
|
/* Add one item to the buffer. */
|
||||||
void put(StoreBuffer* owner, const T& t) {
|
void put(StoreBuffer* owner, const T& t) {
|
||||||
MOZ_ASSERT(stores_.initialized());
|
MOZ_ASSERT(stores_.initialized());
|
||||||
*insert_++ = t;
|
sinkStore(owner);
|
||||||
if (MOZ_UNLIKELY(insert_ == buffer_ + NumBufferEntries))
|
last_ = t;
|
||||||
sinkStores(owner);
|
}
|
||||||
|
|
||||||
|
/* Remove an item from the store buffer. */
|
||||||
|
void unput(StoreBuffer* owner, const T& v) {
|
||||||
|
// Fast, hashless remove of last put.
|
||||||
|
if (last_ == v) {
|
||||||
|
last_ = T();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
stores_.remove(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move any buffered stores to the canonical store set. */
|
/* Move any buffered stores to the canonical store set. */
|
||||||
void sinkStores(StoreBuffer* owner) {
|
void sinkStore(StoreBuffer* owner) {
|
||||||
MOZ_ASSERT(stores_.initialized());
|
MOZ_ASSERT(stores_.initialized());
|
||||||
|
if (last_) {
|
||||||
for (T* p = buffer_; p < insert_; ++p) {
|
if (!stores_.put(last_))
|
||||||
if (!stores_.put(*p))
|
CrashAtUnhandlableOOM("Failed to allocate for MonoTypeBuffer::put.");
|
||||||
CrashAtUnhandlableOOM("Failed to allocate for MonoTypeBuffer::sinkStores.");
|
|
||||||
}
|
}
|
||||||
clearBuffer();
|
last_ = T();
|
||||||
|
|
||||||
if (MOZ_UNLIKELY(stores_.count() > MaxEntries))
|
if (MOZ_UNLIKELY(stores_.count() > MaxEntries))
|
||||||
owner->setAboutToOverflow();
|
owner->setAboutToOverflow();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove an item from the store buffer. */
|
|
||||||
void unput(StoreBuffer* owner, const T& v) {
|
|
||||||
sinkStores(owner);
|
|
||||||
stores_.remove(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool has(StoreBuffer* owner, const T& v) {
|
bool has(StoreBuffer* owner, const T& v) {
|
||||||
sinkStores(owner);
|
sinkStore(owner);
|
||||||
return stores_.has(v);
|
return stores_.has(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,6 +221,8 @@ class StoreBuffer
|
||||||
CellPtrEdge untagged() const { return CellPtrEdge((Cell**)(uintptr_t(edge) & ~1)); }
|
CellPtrEdge untagged() const { return CellPtrEdge((Cell**)(uintptr_t(edge) & ~1)); }
|
||||||
bool isTagged() const { return bool(uintptr_t(edge) & 1); }
|
bool isTagged() const { return bool(uintptr_t(edge) & 1); }
|
||||||
|
|
||||||
|
explicit operator bool() const { return edge != nullptr; }
|
||||||
|
|
||||||
typedef PointerEdgeHasher<CellPtrEdge> Hasher;
|
typedef PointerEdgeHasher<CellPtrEdge> Hasher;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -251,6 +248,8 @@ class StoreBuffer
|
||||||
ValueEdge untagged() const { return ValueEdge((JS::Value*)(uintptr_t(edge) & ~1)); }
|
ValueEdge untagged() const { return ValueEdge((JS::Value*)(uintptr_t(edge) & ~1)); }
|
||||||
bool isTagged() const { return bool(uintptr_t(edge) & 1); }
|
bool isTagged() const { return bool(uintptr_t(edge) & 1); }
|
||||||
|
|
||||||
|
explicit operator bool() const { return edge != nullptr; }
|
||||||
|
|
||||||
typedef PointerEdgeHasher<ValueEdge> Hasher;
|
typedef PointerEdgeHasher<ValueEdge> Hasher;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -293,6 +292,8 @@ class StoreBuffer
|
||||||
|
|
||||||
void trace(TenuringTracer& mover) const;
|
void trace(TenuringTracer& mover) const;
|
||||||
|
|
||||||
|
explicit operator bool() const { return objectAndKind_ != 0; }
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
typedef SlotsEdge Lookup;
|
typedef SlotsEdge Lookup;
|
||||||
static HashNumber hash(const Lookup& l) { return l.objectAndKind_ ^ l.start_ ^ l.count_; }
|
static HashNumber hash(const Lookup& l) { return l.objectAndKind_ ^ l.start_ ^ l.count_; }
|
||||||
|
@ -319,6 +320,8 @@ class StoreBuffer
|
||||||
|
|
||||||
void trace(TenuringTracer& mover) const;
|
void trace(TenuringTracer& mover) const;
|
||||||
|
|
||||||
|
explicit operator bool() const { return edge != nullptr; }
|
||||||
|
|
||||||
typedef PointerEdgeHasher<WholeCellEdges> Hasher;
|
typedef PointerEdgeHasher<WholeCellEdges> Hasher;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче