diff --git a/js/src/gc/Barrier.h b/js/src/gc/Barrier.h index c38bdaea1c87..7f4b71907f62 100644 --- a/js/src/gc/Barrier.h +++ b/js/src/gc/Barrier.h @@ -277,7 +277,7 @@ struct InternalGCMethods if (vp->isObject()) { gc::StoreBuffer* sb = reinterpret_cast(&vp->toObject())->storeBuffer(); if (sb) - sb->putValueFromAnyThread(vp); + sb->putRelocatableValueFromAnyThread(vp); } } @@ -287,7 +287,7 @@ struct InternalGCMethods MOZ_ASSERT(!CurrentThreadIsIonCompiling()); JSRuntime* rt = static_cast(vp->toGCThing())->runtimeFromAnyThread(); JS::shadow::Runtime* shadowRuntime = JS::shadow::Runtime::asShadowRuntime(rt); - shadowRuntime->gcStoreBufferPtr()->unputValueFromAnyThread(vp); + shadowRuntime->gcStoreBufferPtr()->removeRelocatableValueFromAnyThread(vp); } static void readBarrier(const Value& v) { diff --git a/js/src/gc/Nursery.cpp b/js/src/gc/Nursery.cpp index a1a164c8748d..cca867dadda2 100644 --- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -445,6 +445,14 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList sb.traceWholeCells(mover); TIME_END(traceWholeCells); + TIME_START(traceRelocatableValues); + sb.traceRelocatableValues(mover); + TIME_END(traceRelocatableValues); + + TIME_START(traceRelocatableCells); + sb.traceRelocatableCells(mover); + TIME_END(traceRelocatableCells); + TIME_START(traceGenericEntries); sb.traceGenericEntries(&mover); TIME_END(traceGenericEntries); @@ -549,13 +557,13 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList static bool printedHeader = false; if (!printedHeader) { fprintf(stderr, - "MinorGC: Reason PRate Size Time mkVals mkClls mkSlts mkWCll mkGnrc ckTbls mkRntm mkDbgr clrNOC collct swpABO updtIn runFin frSlts clrSB sweep resize pretnr\n"); + "MinorGC: Reason PRate Size Time mkVals mkClls mkSlts mkWCll mkRVal mkRCll mkGnrc ckTbls mkRntm mkDbgr clrNOC collct swpABO updtIn runFin frSlts clrSB sweep resize pretnr\n"); printedHeader = true; } #define FMT " %6" PRIu64 fprintf(stderr, - "MinorGC: %20s %5.1f%% %4d" FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT "\n", + "MinorGC: %20s %5.1f%% %4d" FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT "\n", js::gcstats::ExplainReason(reason), promotionRate * 100, numActiveChunks_, @@ -565,6 +573,8 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList TIME_TOTAL(traceCells), TIME_TOTAL(traceSlots), TIME_TOTAL(traceWholeCells), + TIME_TOTAL(traceRelocatableValues), + TIME_TOTAL(traceRelocatableCells), TIME_TOTAL(traceGenericEntries), TIME_TOTAL(checkHashTables), TIME_TOTAL(markRuntime), diff --git a/js/src/gc/StoreBuffer.cpp b/js/src/gc/StoreBuffer.cpp index d918865b24a7..ef9f545c8276 100644 --- a/js/src/gc/StoreBuffer.cpp +++ b/js/src/gc/StoreBuffer.cpp @@ -44,6 +44,8 @@ StoreBuffer::enable() !bufferCell.init() || !bufferSlot.init() || !bufferWholeCell.init() || + !bufferRelocVal.init() || + !bufferRelocCell.init() || !bufferGeneric.init()) { return false; @@ -77,6 +79,8 @@ StoreBuffer::clear() bufferCell.clear(); bufferSlot.clear(); bufferWholeCell.clear(); + bufferRelocVal.clear(); + bufferRelocCell.clear(); bufferGeneric.clear(); return true; @@ -100,6 +104,8 @@ StoreBuffer::addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::GCSi sizes->storeBufferCells += bufferCell.sizeOfExcludingThis(mallocSizeOf); sizes->storeBufferSlots += bufferSlot.sizeOfExcludingThis(mallocSizeOf); sizes->storeBufferWholeCells += bufferWholeCell.sizeOfExcludingThis(mallocSizeOf); + sizes->storeBufferRelocVals += bufferRelocVal.sizeOfExcludingThis(mallocSizeOf); + sizes->storeBufferRelocCells += bufferRelocCell.sizeOfExcludingThis(mallocSizeOf); sizes->storeBufferGenerics += bufferGeneric.sizeOfExcludingThis(mallocSizeOf); } diff --git a/js/src/gc/StoreBuffer.h b/js/src/gc/StoreBuffer.h index 41b780098961..08bcd2aa5e06 100644 --- a/js/src/gc/StoreBuffer.h +++ b/js/src/gc/StoreBuffer.h @@ -351,6 +351,8 @@ class StoreBuffer MonoTypeBuffer bufferCell; MonoTypeBuffer bufferSlot; MonoTypeBuffer bufferWholeCell; + MonoTypeBuffer bufferRelocVal; + MonoTypeBuffer bufferRelocCell; GenericBuffer bufferGeneric; bool cancelIonCompilations_; @@ -363,9 +365,10 @@ class StoreBuffer public: explicit StoreBuffer(JSRuntime* rt, const Nursery& nursery) - : bufferVal(), bufferCell(), bufferSlot(), bufferWholeCell(), bufferGeneric(), - cancelIonCompilations_(false), runtime_(rt), nursery_(nursery), aboutToOverflow_(false), - enabled_(false), mEntered(false) + : bufferVal(), bufferCell(), bufferSlot(), bufferWholeCell(), + bufferRelocVal(), bufferRelocCell(), bufferGeneric(), cancelIonCompilations_(false), + runtime_(rt), nursery_(nursery), aboutToOverflow_(false), enabled_(false), + mEntered(false) { } @@ -381,10 +384,8 @@ class StoreBuffer bool cancelIonCompilations() const { return cancelIonCompilations_; } /* Insert a single edge into the buffer/remembered set. */ - void putValueFromAnyThread(JS::Value* vp) { putFromAnyThread(bufferVal, ValueEdge(vp)); } - void unputValueFromAnyThread(JS::Value* vp) { unputFromAnyThread(bufferVal, ValueEdge(vp)); } + void putValueFromAnyThread(JS::Value* valuep) { putFromAnyThread(bufferVal, ValueEdge(valuep)); } void putCellFromAnyThread(Cell** cellp) { putFromAnyThread(bufferCell, CellPtrEdge(cellp)); } - void unputCellFromAnyThread(Cell** cellp) { unputFromAnyThread(bufferCell, CellPtrEdge(cellp)); } void putSlotFromAnyThread(NativeObject* obj, int kind, int32_t start, int32_t count) { putFromAnyThread(bufferSlot, SlotsEdge(obj, kind, start, count)); } @@ -393,6 +394,20 @@ class StoreBuffer putFromMainThread(bufferWholeCell, WholeCellEdges(cell)); } + /* Insert or update a single edge in the Relocatable buffer. */ + void putRelocatableValueFromAnyThread(JS::Value* valuep) { + putFromAnyThread(bufferRelocVal, ValueEdge(valuep)); + } + void removeRelocatableValueFromAnyThread(JS::Value* valuep) { + unputFromAnyThread(bufferRelocVal, ValueEdge(valuep)); + } + void putRelocatableCellFromAnyThread(Cell** cellp) { + putFromAnyThread(bufferRelocCell, CellPtrEdge(cellp)); + } + void removeRelocatableCellFromAnyThread(Cell** cellp) { + unputFromAnyThread(bufferRelocCell, CellPtrEdge(cellp)); + } + /* Insert an entry into the generic buffer. */ template void putGeneric(const T& t) { putFromAnyThread(bufferGeneric, t);} @@ -412,6 +427,8 @@ class StoreBuffer void traceCells(TenuringTracer& mover) { bufferCell.trace(this, mover); } void traceSlots(TenuringTracer& mover) { bufferSlot.trace(this, mover); } void traceWholeCells(TenuringTracer& mover) { bufferWholeCell.trace(this, mover); } + void traceRelocatableValues(TenuringTracer& mover) { bufferRelocVal.trace(this, mover); } + void traceRelocatableCells(TenuringTracer& mover) { bufferRelocCell.trace(this, mover); } void traceGenericEntries(JSTracer *trc) { bufferGeneric.trace(this, trc); } /* For use by our owned buffers and for testing. */ diff --git a/js/src/jsobj.h b/js/src/jsobj.h index 05b3424fc8ce..23fd3b35cb06 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -649,7 +649,7 @@ JSObject::writeBarrierPostRelocate(JSObject* obj, void* cellp) MOZ_ASSERT(obj == *static_cast(cellp)); js::gc::StoreBuffer* storeBuffer = obj->storeBuffer(); if (storeBuffer) - storeBuffer->putCellFromAnyThread(static_cast(cellp)); + storeBuffer->putRelocatableCellFromAnyThread(static_cast(cellp)); } /* static */ MOZ_ALWAYS_INLINE void @@ -658,7 +658,7 @@ JSObject::writeBarrierPostRemove(JSObject* obj, void* cellp) MOZ_ASSERT(cellp); MOZ_ASSERT(obj); MOZ_ASSERT(obj == *static_cast(cellp)); - obj->shadowRuntimeFromAnyThread()->gcStoreBufferPtr()->unputCellFromAnyThread( + obj->shadowRuntimeFromAnyThread()->gcStoreBufferPtr()->removeRelocatableCellFromAnyThread( static_cast(cellp)); }