mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 706885 - Move post barrier verifier to JSRuntime; r=billm
--HG-- extra : rebase_source : 0ecc660996501fb54573cc0081a12bbca838e45d
This commit is contained in:
parent
b18a8e9f53
commit
3dd5723697
@ -29,16 +29,16 @@ RelocatablePtr<T>::post()
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
JS_ASSERT(this->value);
|
||||
this->value->zone()->gcStoreBuffer.putRelocatableCell((gc::Cell **)&this->value);
|
||||
this->value->runtime()->gcStoreBuffer.putRelocatableCell((gc::Cell **)&this->value);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void
|
||||
RelocatablePtr<T>::relocate(Zone *zone)
|
||||
RelocatablePtr<T>::relocate(JSRuntime *rt)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
zone->gcStoreBuffer.removeRelocatableCell((gc::Cell **)&this->value);
|
||||
rt->gcStoreBuffer.removeRelocatableCell((gc::Cell **)&this->value);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -115,11 +115,11 @@ HeapValue::init(const Value &v)
|
||||
}
|
||||
|
||||
inline void
|
||||
HeapValue::init(Zone *zone, const Value &v)
|
||||
HeapValue::init(JSRuntime *rt, const Value &v)
|
||||
{
|
||||
JS_ASSERT(!IsPoisonedValue(v));
|
||||
value = v;
|
||||
post(zone);
|
||||
post(rt);
|
||||
}
|
||||
|
||||
inline HeapValue &
|
||||
@ -156,26 +156,24 @@ HeapValue::set(Zone *zone, const Value &v)
|
||||
pre(zone);
|
||||
JS_ASSERT(!IsPoisonedValue(v));
|
||||
value = v;
|
||||
post(zone);
|
||||
post(zone->rt);
|
||||
}
|
||||
|
||||
inline void
|
||||
HeapValue::writeBarrierPost(const Value &value, Value *addr)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
if (value.isMarkable()) {
|
||||
js::gc::Cell *cell = (js::gc::Cell *)value.toGCThing();
|
||||
cell->zone()->gcStoreBuffer.putValue(addr);
|
||||
}
|
||||
if (value.isMarkable())
|
||||
runtime(value)->gcStoreBuffer.putValue(addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void
|
||||
HeapValue::writeBarrierPost(Zone *zone, const Value &value, Value *addr)
|
||||
HeapValue::writeBarrierPost(JSRuntime *rt, const Value &value, Value *addr)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
if (value.isMarkable())
|
||||
zone->gcStoreBuffer.putValue(addr);
|
||||
rt->gcStoreBuffer.putValue(addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -186,9 +184,9 @@ HeapValue::post()
|
||||
}
|
||||
|
||||
inline void
|
||||
HeapValue::post(Zone *zone)
|
||||
HeapValue::post(JSRuntime *rt)
|
||||
{
|
||||
writeBarrierPost(zone, value, &value);
|
||||
writeBarrierPost(rt, value, &value);
|
||||
}
|
||||
|
||||
inline
|
||||
@ -244,19 +242,17 @@ inline void
|
||||
RelocatableValue::post()
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
if (value.isMarkable()) {
|
||||
js::gc::Cell *cell = (js::gc::Cell *)value.toGCThing();
|
||||
cell->zone()->gcStoreBuffer.putRelocatableValue(&value);
|
||||
}
|
||||
if (value.isMarkable())
|
||||
runtime(value)->gcStoreBuffer.putRelocatableValue(&value);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void
|
||||
RelocatableValue::post(Zone *zone)
|
||||
RelocatableValue::post(JSRuntime *rt)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
if (value.isMarkable())
|
||||
zone->gcStoreBuffer.putRelocatableValue(&value);
|
||||
rt->gcStoreBuffer.putRelocatableValue(&value);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -264,10 +260,8 @@ inline void
|
||||
RelocatableValue::relocate()
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
if (value.isMarkable()) {
|
||||
js::gc::Cell *cell = (js::gc::Cell *)value.toGCThing();
|
||||
cell->zone()->gcStoreBuffer.removeRelocatableValue(&value);
|
||||
}
|
||||
if (value.isMarkable())
|
||||
runtime(value)->gcStoreBuffer.removeRelocatableValue(&value);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -301,10 +295,10 @@ HeapSlot::init(JSObject *obj, Kind kind, uint32_t slot, const Value &v)
|
||||
}
|
||||
|
||||
inline void
|
||||
HeapSlot::init(Zone *zone, JSObject *obj, Kind kind, uint32_t slot, const Value &v)
|
||||
HeapSlot::init(JSRuntime *rt, JSObject *obj, Kind kind, uint32_t slot, const Value &v)
|
||||
{
|
||||
value = v;
|
||||
post(zone, obj, kind, slot);
|
||||
post(rt, obj, kind, slot);
|
||||
}
|
||||
|
||||
inline void
|
||||
@ -329,34 +323,22 @@ HeapSlot::set(Zone *zone, JSObject *obj, Kind kind, uint32_t slot, const Value &
|
||||
pre(zone);
|
||||
JS_ASSERT(!IsPoisonedValue(v));
|
||||
value = v;
|
||||
post(zone, obj, kind, slot);
|
||||
}
|
||||
|
||||
inline void
|
||||
HeapSlot::setCrossCompartment(JSObject *obj, Kind kind, uint32_t slot, const Value &v, Zone *vzone)
|
||||
{
|
||||
JS_ASSERT_IF(kind == Slot, &obj->getSlotRef(slot) == this);
|
||||
JS_ASSERT_IF(kind == Element, &obj->getDenseElement(slot) == (const Value *)this);
|
||||
|
||||
pre();
|
||||
JS_ASSERT(!IsPoisonedValue(v));
|
||||
value = v;
|
||||
post(vzone, obj, kind, slot);
|
||||
post(zone->rt, obj, kind, slot);
|
||||
}
|
||||
|
||||
inline void
|
||||
HeapSlot::writeBarrierPost(JSObject *obj, Kind kind, uint32_t slot)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
obj->zone()->gcStoreBuffer.putSlot(obj, kind, slot);
|
||||
obj->runtime()->gcStoreBuffer.putSlot(obj, kind, slot);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void
|
||||
HeapSlot::writeBarrierPost(Zone *zone, JSObject *obj, Kind kind, uint32_t slot)
|
||||
HeapSlot::writeBarrierPost(JSRuntime *rt, JSObject *obj, Kind kind, uint32_t slot)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
zone->gcStoreBuffer.putSlot(obj, kind, slot);
|
||||
rt->gcStoreBuffer.putSlot(obj, kind, slot);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -367,9 +349,9 @@ HeapSlot::post(JSObject *owner, Kind kind, uint32_t slot)
|
||||
}
|
||||
|
||||
inline void
|
||||
HeapSlot::post(Zone *zone, JSObject *owner, Kind kind, uint32_t slot)
|
||||
HeapSlot::post(JSRuntime *rt, JSObject *owner, Kind kind, uint32_t slot)
|
||||
{
|
||||
HeapSlot::writeBarrierPost(zone, owner, kind, slot);
|
||||
HeapSlot::writeBarrierPost(rt, owner, kind, slot);
|
||||
}
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
@ -404,11 +386,11 @@ class DenseRangeRef : public gc::BufferableRef
|
||||
#endif
|
||||
|
||||
inline void
|
||||
DenseRangeWriteBarrierPost(Zone *zone, JSObject *obj, uint32_t start, uint32_t count)
|
||||
DenseRangeWriteBarrierPost(JSRuntime *rt, JSObject *obj, uint32_t start, uint32_t count)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
if (count > 0)
|
||||
zone->gcStoreBuffer.putGeneric(DenseRangeRef(obj, start, start + count));
|
||||
rt->gcStoreBuffer.putGeneric(DenseRangeRef(obj, start, start + count));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -262,7 +262,7 @@ class RelocatablePtr : public EncapsulatedPtr<T>
|
||||
|
||||
~RelocatablePtr() {
|
||||
if (this->value)
|
||||
relocate(this->value->zone());
|
||||
relocate(this->value->runtime());
|
||||
}
|
||||
|
||||
RelocatablePtr<T> &operator=(T *v) {
|
||||
@ -272,9 +272,9 @@ class RelocatablePtr : public EncapsulatedPtr<T>
|
||||
this->value = v;
|
||||
post();
|
||||
} else if (this->value) {
|
||||
Zone *zone = this->value->zone();
|
||||
JSRuntime *rt = this->value->runtime();
|
||||
this->value = v;
|
||||
relocate(zone);
|
||||
relocate(rt);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -286,16 +286,16 @@ class RelocatablePtr : public EncapsulatedPtr<T>
|
||||
this->value = v.value;
|
||||
post();
|
||||
} else if (this->value) {
|
||||
Zone *zone = this->value->zone();
|
||||
JSRuntime *rt = this->value->runtime();
|
||||
this->value = v;
|
||||
relocate(zone);
|
||||
relocate(rt);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
inline void post();
|
||||
inline void relocate(Zone *zone);
|
||||
inline void relocate(JSRuntime *rt);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -400,6 +400,11 @@ class EncapsulatedValue : public ValueOperations<EncapsulatedValue>
|
||||
inline void pre();
|
||||
inline void pre(Zone *zone);
|
||||
|
||||
static inline JSRuntime *runtime(const Value &v) {
|
||||
JS_ASSERT(v.isMarkable());
|
||||
return static_cast<js::gc::Cell *>(v.toGCThing())->runtime();
|
||||
}
|
||||
|
||||
private:
|
||||
friend class ValueOperations<EncapsulatedValue>;
|
||||
const Value * extract() const { return &value; }
|
||||
@ -414,7 +419,7 @@ class HeapValue : public EncapsulatedValue
|
||||
inline ~HeapValue();
|
||||
|
||||
inline void init(const Value &v);
|
||||
inline void init(Zone *zone, const Value &v);
|
||||
inline void init(JSRuntime *rt, const Value &v);
|
||||
|
||||
inline HeapValue &operator=(const Value &v);
|
||||
inline HeapValue &operator=(const HeapValue &v);
|
||||
@ -428,11 +433,11 @@ class HeapValue : public EncapsulatedValue
|
||||
inline void set(Zone *zone, const Value &v);
|
||||
|
||||
static inline void writeBarrierPost(const Value &v, Value *addr);
|
||||
static inline void writeBarrierPost(Zone *zone, const Value &v, Value *addr);
|
||||
static inline void writeBarrierPost(JSRuntime *rt, const Value &v, Value *addr);
|
||||
|
||||
private:
|
||||
inline void post();
|
||||
inline void post(Zone *zone);
|
||||
inline void post(JSRuntime *rt);
|
||||
};
|
||||
|
||||
class RelocatableValue : public EncapsulatedValue
|
||||
@ -448,7 +453,7 @@ class RelocatableValue : public EncapsulatedValue
|
||||
|
||||
private:
|
||||
inline void post();
|
||||
inline void post(Zone *zone);
|
||||
inline void post(JSRuntime *rt);
|
||||
inline void relocate();
|
||||
};
|
||||
|
||||
@ -474,19 +479,17 @@ class HeapSlot : public EncapsulatedValue
|
||||
inline ~HeapSlot();
|
||||
|
||||
inline void init(JSObject *owner, Kind kind, uint32_t slot, const Value &v);
|
||||
inline void init(Zone *zone, JSObject *owner, Kind kind, uint32_t slot, const Value &v);
|
||||
inline void init(JSRuntime *rt, JSObject *owner, Kind kind, uint32_t slot, const Value &v);
|
||||
|
||||
inline void set(JSObject *owner, Kind kind, uint32_t slot, const Value &v);
|
||||
inline void set(Zone *zone, JSObject *owner, Kind kind, uint32_t slot, const Value &v);
|
||||
inline void setCrossCompartment(JSObject *owner, Kind kind, uint32_t slot, const Value &v,
|
||||
Zone *vzone);
|
||||
|
||||
static inline void writeBarrierPost(JSObject *obj, Kind kind, uint32_t slot);
|
||||
static inline void writeBarrierPost(Zone *zone, JSObject *obj, Kind kind, uint32_t slot);
|
||||
static inline void writeBarrierPost(JSRuntime *rt, JSObject *obj, Kind kind, uint32_t slot);
|
||||
|
||||
private:
|
||||
inline void post(JSObject *owner, Kind kind, uint32_t slot);
|
||||
inline void post(Zone *zone, JSObject *owner, Kind kind, uint32_t slot);
|
||||
inline void post(JSRuntime *rt, JSObject *owner, Kind kind, uint32_t slot);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -496,14 +499,14 @@ class HeapSlot : public EncapsulatedValue
|
||||
* single step.
|
||||
*/
|
||||
inline void
|
||||
DenseRangeWriteBarrierPost(Zone *zone, JSObject *obj, uint32_t start, uint32_t count);
|
||||
DenseRangeWriteBarrierPost(JSRuntime *rt, JSObject *obj, uint32_t start, uint32_t count);
|
||||
|
||||
/*
|
||||
* This is a post barrier for HashTables whose key can be moved during a GC.
|
||||
*/
|
||||
template <class Map, class Key>
|
||||
inline void
|
||||
HashTableWriteBarrierPost(Zone *zone, const Map *map, const Key &key)
|
||||
HashTableWriteBarrierPost(JSRuntime *rt, const Map *map, const Key &key)
|
||||
{
|
||||
#ifdef JS_GCGENERATIONAL
|
||||
if (key && comp->gcNursery.isInside(key))
|
||||
|
@ -808,7 +808,7 @@ struct Chunk
|
||||
}
|
||||
|
||||
private:
|
||||
inline void init();
|
||||
inline void init(JSRuntime *rt);
|
||||
|
||||
/* Search for a decommitted arena to allocate. */
|
||||
unsigned findDecommittedArenaOffset();
|
||||
|
@ -213,6 +213,9 @@ StoreBuffer::enable()
|
||||
void
|
||||
StoreBuffer::disable()
|
||||
{
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
bufferVal.disable();
|
||||
bufferCell.disable();
|
||||
bufferSlot.disable();
|
||||
|
@ -15,8 +15,7 @@
|
||||
|
||||
#include "jsgc.h"
|
||||
#include "jsalloc.h"
|
||||
|
||||
#include "gc/Marking.h"
|
||||
#include "jsobj.h"
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
@ -44,6 +43,11 @@ class Nursery
|
||||
nursery.finish();
|
||||
}
|
||||
|
||||
bool clear() {
|
||||
disable();
|
||||
return enable();
|
||||
}
|
||||
|
||||
bool isInside(void *cell) const {
|
||||
JS_ASSERT((uintptr_t(cell) & 0x3) == 0);
|
||||
return nursery.initialized() && nursery.has(cell);
|
||||
@ -358,6 +362,11 @@ class StoreBuffer
|
||||
void disable();
|
||||
bool isEnabled() { return enabled; }
|
||||
|
||||
bool clear() {
|
||||
disable();
|
||||
return enable();
|
||||
}
|
||||
|
||||
/* Get the overflowed status. */
|
||||
bool hasOverflowed() const { return overflowed; }
|
||||
|
||||
|
@ -656,25 +656,18 @@ gc::StartVerifyPostBarriers(JSRuntime *rt)
|
||||
rt->gcNumber++;
|
||||
trc->number = rt->gcNumber;
|
||||
trc->count = 0;
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
if (IsAtomsCompartment(c))
|
||||
continue;
|
||||
|
||||
if (!c->gcNursery.enable())
|
||||
goto oom;
|
||||
if (!rt->gcNursery.clear())
|
||||
goto oom;
|
||||
|
||||
if (!rt->gcStoreBuffer.clear())
|
||||
goto oom;
|
||||
|
||||
if (!c->gcStoreBuffer.enable())
|
||||
goto oom;
|
||||
}
|
||||
return;
|
||||
oom:
|
||||
trc->~VerifyPostTracer();
|
||||
js_free(trc);
|
||||
rt->gcVerifyPostData = NULL;
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
c->gcNursery.disable();
|
||||
c->gcStoreBuffer.disable();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -697,17 +690,10 @@ PostVerifierVisitEdge(JSTracer *jstrc, void **thingp, JSGCTraceKind kind)
|
||||
{
|
||||
VerifyPostTracer *trc = (VerifyPostTracer *)jstrc;
|
||||
Cell *dst = (Cell *)*thingp;
|
||||
JSCompartment *comp = dst->compartment();
|
||||
|
||||
/*
|
||||
* Note: watchpoint markAll will give us cross-compartment pointers into the
|
||||
* atoms compartment.
|
||||
*/
|
||||
if (IsAtomsCompartment(comp))
|
||||
return;
|
||||
JSRuntime *rt = dst->runtime();
|
||||
|
||||
/* Filter out non cross-generational edges. */
|
||||
if (!comp->gcNursery.isInside(dst))
|
||||
if (!rt->gcNursery.isInside(dst))
|
||||
return;
|
||||
|
||||
/*
|
||||
@ -717,7 +703,7 @@ PostVerifierVisitEdge(JSTracer *jstrc, void **thingp, JSGCTraceKind kind)
|
||||
*/
|
||||
Cell *loc = (Cell *)(trc->realLocation != NULL ? trc->realLocation : thingp);
|
||||
|
||||
AssertStoreBufferContainsEdge(&comp->gcStoreBuffer, loc, dst);
|
||||
AssertStoreBufferContainsEdge(&rt->gcStoreBuffer, loc, dst);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -731,21 +717,16 @@ js::gc::EndVerifyPostBarriers(JSRuntime *rt)
|
||||
JS_TracerInit(trc, rt, PostVerifierVisitEdge);
|
||||
trc->count = 0;
|
||||
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
if (c->gcStoreBuffer.hasOverflowed())
|
||||
continue;
|
||||
if (!c->gcStoreBuffer.coalesceForVerification())
|
||||
goto oom;
|
||||
}
|
||||
if (rt->gcStoreBuffer.hasOverflowed())
|
||||
goto oom;
|
||||
|
||||
if (!rt->gcStoreBuffer.coalesceForVerification())
|
||||
goto oom;
|
||||
|
||||
/* Walk the heap. */
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
if (!c->gcStoreBuffer.isEnabled() ||
|
||||
c->gcStoreBuffer.hasOverflowed() ||
|
||||
IsAtomsCompartment(c))
|
||||
{
|
||||
if (IsAtomsCompartment(c))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c->watchpointMap)
|
||||
c->watchpointMap->markAll(trc);
|
||||
@ -753,7 +734,7 @@ js::gc::EndVerifyPostBarriers(JSRuntime *rt)
|
||||
for (size_t kind = 0; kind < FINALIZE_LIMIT; ++kind) {
|
||||
for (CellIterUnderGC cells(c, AllocKind(kind)); !cells.done(); cells.next()) {
|
||||
Cell *src = cells.getCell();
|
||||
if (!c->gcNursery.isInside(src))
|
||||
if (!rt->gcNursery.isInside(src))
|
||||
JS_TraceChildren(trc, src, MapAllocToTraceKind(AllocKind(kind)));
|
||||
}
|
||||
}
|
||||
@ -763,11 +744,9 @@ oom:
|
||||
trc->~VerifyPostTracer();
|
||||
js_free(trc);
|
||||
rt->gcVerifyPostData = NULL;
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
c->gcNursery.disable();
|
||||
c->gcStoreBuffer.disable();
|
||||
c->gcStoreBuffer.releaseVerificationData();
|
||||
}
|
||||
rt->gcNursery.disable();
|
||||
rt->gcStoreBuffer.disable();
|
||||
rt->gcStoreBuffer.releaseVerificationData();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -854,10 +833,8 @@ js::gc::FinishVerifier(JSRuntime *rt)
|
||||
if (VerifyPostTracer *trc = (VerifyPostTracer *)rt->gcVerifyPostData) {
|
||||
trc->~VerifyPostTracer();
|
||||
js_free(trc);
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
c->gcNursery.disable();
|
||||
c->gcStoreBuffer.disable();
|
||||
}
|
||||
rt->gcNursery.disable();
|
||||
rt->gcStoreBuffer.disable();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -814,6 +814,10 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
|
||||
gcObjectsMarkedInDeadCompartments(0),
|
||||
gcPoke(false),
|
||||
heapState(Idle),
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
gcNursery(),
|
||||
gcStoreBuffer(&gcNursery),
|
||||
#endif
|
||||
#ifdef JS_GC_ZEAL
|
||||
gcZeal_(0),
|
||||
gcZealFrequency(0),
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include "ds/LifoAlloc.h"
|
||||
#include "gc/Statistics.h"
|
||||
#include "gc/StoreBuffer.h"
|
||||
#include "js/HashTable.h"
|
||||
#include "js/Vector.h"
|
||||
#include "vm/DateTime.h"
|
||||
@ -903,6 +904,11 @@ struct JSRuntime : js::RuntimeFriendFields,
|
||||
|
||||
bool isHeapCollecting() { return heapState == js::Collecting; }
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
js::gc::Nursery gcNursery;
|
||||
js::gc::StoreBuffer gcStoreBuffer;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These options control the zealousness of the GC. The fundamental values
|
||||
* are gcNextScheduled and gcDebugCompartmentGC. At every allocation,
|
||||
|
@ -52,10 +52,6 @@ JSCompartment::JSCompartment(JSRuntime *rt)
|
||||
global_(NULL),
|
||||
enterCompartmentDepth(0),
|
||||
allocator(this),
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
gcNursery(),
|
||||
gcStoreBuffer(&gcNursery),
|
||||
#endif
|
||||
ionUsingBarriers_(false),
|
||||
gcScheduled(false),
|
||||
gcState(NoGC),
|
||||
@ -135,23 +131,6 @@ JSCompartment::init(JSContext *cx)
|
||||
if (cx)
|
||||
InitRandom(cx->runtime, &rngState);
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
/*
|
||||
* If we are in the middle of post-barrier verification, we need to
|
||||
* immediately begin collecting verification data on new compartments.
|
||||
*/
|
||||
if (rt->gcVerifyPostData) {
|
||||
if (!gcNursery.enable())
|
||||
return false;
|
||||
|
||||
if (!gcStoreBuffer.enable())
|
||||
return false;
|
||||
} else {
|
||||
gcNursery.disable();
|
||||
gcStoreBuffer.disable();
|
||||
}
|
||||
#endif
|
||||
|
||||
enumerators = NativeIterator::allocateSentinel(cx);
|
||||
if (!enumerators)
|
||||
return false;
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "jsgc.h"
|
||||
#include "jsobj.h"
|
||||
|
||||
#include "gc/StoreBuffer.h"
|
||||
#include "gc/FindSCCs.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/RegExpObject.h"
|
||||
@ -195,11 +194,6 @@ struct JSCompartment : private JS::shadow::Zone, public js::gc::GraphNodeBase<JS
|
||||
*/
|
||||
void adoptWorkerAllocator(js::Allocator *workerAllocator);
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
js::gc::Nursery gcNursery;
|
||||
js::gc::StoreBuffer gcStoreBuffer;
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool ionUsingBarriers_;
|
||||
public:
|
||||
|
@ -604,7 +604,7 @@ Chunk::allocate(JSRuntime *rt)
|
||||
|
||||
if (!chunk)
|
||||
return NULL;
|
||||
chunk->init();
|
||||
chunk->init(rt);
|
||||
rt->gcStats.count(gcstats::STAT_NEW_CHUNK);
|
||||
return chunk;
|
||||
}
|
||||
@ -635,7 +635,7 @@ Chunk::prepareToBeFreed(JSRuntime *rt)
|
||||
}
|
||||
|
||||
void
|
||||
Chunk::init()
|
||||
Chunk::init(JSRuntime *rt)
|
||||
{
|
||||
JS_POISON(this, JS_FREE_PATTERN, ChunkSize);
|
||||
|
||||
@ -654,6 +654,7 @@ Chunk::init()
|
||||
info.numArenasFree = ArenasPerChunk;
|
||||
info.numArenasFreeCommitted = ArenasPerChunk;
|
||||
info.age = 0;
|
||||
info.runtime = rt;
|
||||
|
||||
/* Initialize the arena header state. */
|
||||
for (unsigned i = 0; i < ArenasPerChunk; i++) {
|
||||
@ -971,6 +972,14 @@ js_InitGC(JSRuntime *rt, uint32_t maxbytes)
|
||||
rt->gcJitReleaseTime = PRMJ_Now() + JIT_SCRIPT_RELEASE_TYPES_INTERVAL;
|
||||
#endif
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
if (!rt->gcNursery.enable())
|
||||
return false;
|
||||
|
||||
if (!rt->gcStoreBuffer.enable())
|
||||
return false;
|
||||
#endif
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
if (!InitGCZeal(rt))
|
||||
return false;
|
||||
|
@ -518,7 +518,7 @@ NewGCThing(JSContext *cx, AllocKind kind, size_t thingSize, InitialHeap heap)
|
||||
!IsAtomsCompartment(cx->compartment) &&
|
||||
heap != TenuredHeap)
|
||||
{
|
||||
zone->gcNursery.insertPointer(t);
|
||||
cx->runtime->gcNursery.insertPointer(t);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1935,10 +1935,9 @@ JSObject::TradeGuts(JSContext *cx, JSObject *a, JSObject *b, TradeGutsReserved &
|
||||
* Trigger post barriers for fixed slots. JSObject bits are barriered
|
||||
* below, in common with the other case.
|
||||
*/
|
||||
JSCompartment *comp = cx->compartment;
|
||||
for (size_t i = 0; i < a->numFixedSlots(); ++i) {
|
||||
HeapSlot::writeBarrierPost(comp, a, HeapSlot::Slot, i);
|
||||
HeapSlot::writeBarrierPost(comp, b, HeapSlot::Slot, i);
|
||||
HeapSlot::writeBarrierPost(cx->runtime, a, HeapSlot::Slot, i);
|
||||
HeapSlot::writeBarrierPost(cx->runtime, b, HeapSlot::Slot, i);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
|
@ -523,9 +523,9 @@ inline void
|
||||
JSObject::initDenseElements(unsigned dstStart, const js::Value *src, unsigned count)
|
||||
{
|
||||
JS_ASSERT(dstStart + count <= getDenseCapacity());
|
||||
JS::Zone *zone = this->zone();
|
||||
JSRuntime *rt = runtime();
|
||||
for (unsigned i = 0; i < count; ++i)
|
||||
elements[dstStart + i].init(zone, this, js::HeapSlot::Element, dstStart + i, src[i]);
|
||||
elements[dstStart + i].init(rt, this, js::HeapSlot::Element, dstStart + i, src[i]);
|
||||
}
|
||||
|
||||
inline void
|
||||
@ -561,7 +561,7 @@ JSObject::moveDenseElements(unsigned dstStart, unsigned srcStart, unsigned count
|
||||
}
|
||||
} else {
|
||||
memmove(elements + dstStart, elements + srcStart, count * sizeof(js::HeapSlot));
|
||||
DenseRangeWriteBarrierPost(zone, this, dstStart, count);
|
||||
DenseRangeWriteBarrierPost(runtime(), this, dstStart, count);
|
||||
}
|
||||
}
|
||||
|
||||
@ -597,12 +597,12 @@ JSObject::ensureDenseInitializedLength(JSContext *cx, uint32_t index, uint32_t e
|
||||
markDenseElementsNotPacked(cx);
|
||||
|
||||
if (initlen < index + extra) {
|
||||
JS::Zone *zone = this->zone();
|
||||
JSRuntime *rt = runtime();
|
||||
size_t offset = initlen;
|
||||
for (js::HeapSlot *sp = elements + initlen;
|
||||
sp != elements + (index + extra);
|
||||
sp++, offset++)
|
||||
sp->init(zone, this, js::HeapSlot::Element, offset, js::MagicValue(JS_ELEMENTS_HOLE));
|
||||
sp->init(rt, this, js::HeapSlot::Element, offset, js::MagicValue(JS_ELEMENTS_HOLE));
|
||||
initlen = index + extra;
|
||||
}
|
||||
}
|
||||
@ -668,10 +668,10 @@ JSObject::parExtendDenseElements(js::Allocator *alloc, js::Value *v, uint32_t ex
|
||||
js::HeapSlot *sp = elements + initializedLength;
|
||||
if (v) {
|
||||
for (uint32_t i = 0; i < extra; i++)
|
||||
sp[i].init(zone(), this, js::HeapSlot::Element, initializedLength+i, v[i]);
|
||||
sp[i].init(runtime(), this, js::HeapSlot::Element, initializedLength+i, v[i]);
|
||||
} else {
|
||||
for (uint32_t i = 0; i < extra; i++) {
|
||||
sp[i].init(zone(), this, js::HeapSlot::Element,
|
||||
sp[i].init(runtime(), this, js::HeapSlot::Element,
|
||||
initializedLength + i, js::MagicValue(JS_ELEMENTS_HOLE));
|
||||
}
|
||||
}
|
||||
|
@ -337,7 +337,7 @@ static void
|
||||
WeakObjectSlotBarrierPost(JSObject *obj, size_t slot, const char *desc)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
obj->compartment()->gcStoreBuffer.putGeneric(WeakObjectSlotRef(obj, slot, desc));
|
||||
obj->runtime()->gcStoreBuffer.putGeneric(WeakObjectSlotRef(obj, slot, desc));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -205,10 +205,8 @@ InitTypedArrayDataPointer(JSObject *obj, ArrayBufferObject *buffer, size_t byteO
|
||||
*/
|
||||
obj->initPrivate(buffer->dataPointer() + byteOffset);
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
JSCompartment *comp = obj->compartment();
|
||||
JS_ASSERT(comp == buffer->compartment());
|
||||
if (comp->gcNursery.isInside(buffer))
|
||||
comp->gcStoreBuffer.putGeneric(TypedArrayPrivateRef(obj, buffer, byteOffset));
|
||||
if (obj->runtime()->gcNursery.isInside(buffer))
|
||||
obj->runtime()->gcStoreBuffer.putGeneric(TypedArrayPrivateRef(obj, buffer, byteOffset));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -50,17 +50,17 @@ WatchpointMap::init()
|
||||
}
|
||||
|
||||
static void
|
||||
WatchpointWriteBarrierPost(JSCompartment *comp, WatchpointMap::Map *map, const WatchKey &key,
|
||||
WatchpointWriteBarrierPost(JSRuntime *rt, WatchpointMap::Map *map, const WatchKey &key,
|
||||
const Watchpoint &val)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
if ((JSID_IS_OBJECT(key.id) && comp->gcNursery.isInside(JSID_TO_OBJECT(key.id))) ||
|
||||
(JSID_IS_STRING(key.id) && comp->gcNursery.isInside(JSID_TO_STRING(key.id))) ||
|
||||
comp->gcNursery.isInside(key.object) ||
|
||||
comp->gcNursery.isInside(val.closure))
|
||||
if ((JSID_IS_OBJECT(key.id) && rt->gcNursery.isInside(JSID_TO_OBJECT(key.id))) ||
|
||||
(JSID_IS_STRING(key.id) && rt->gcNursery.isInside(JSID_TO_STRING(key.id))) ||
|
||||
rt->gcNursery.isInside(key.object) ||
|
||||
rt->gcNursery.isInside(val.closure))
|
||||
{
|
||||
typedef HashKeyRef<WatchpointMap::Map, WatchKey> WatchKeyRef;
|
||||
comp->gcStoreBuffer.putGeneric(WatchKeyRef(map, key));
|
||||
rt->gcStoreBuffer.putGeneric(WatchKeyRef(map, key));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -82,7 +82,7 @@ WatchpointMap::watch(JSContext *cx, HandleObject obj, HandleId id,
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
WatchpointWriteBarrierPost(obj->compartment(), &map, WatchKey(obj, id), w);
|
||||
WatchpointWriteBarrierPost(cx->runtime, &map, WatchKey(obj, id), w);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -322,7 +322,7 @@ WeakMap_set_impl(JSContext *cx, CallArgs args)
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
HashTableWriteBarrierPost(cx->zone(), map, key);
|
||||
HashTableWriteBarrierPost(cx->runtime, map, key);
|
||||
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
|
@ -699,7 +699,7 @@ Debugger::wrapDebuggeeValue(JSContext *cx, MutableHandleValue vp)
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
HashTableWriteBarrierPost(cx->zone(), &objects, obj);
|
||||
HashTableWriteBarrierPost(cx->runtime, &objects, obj);
|
||||
|
||||
if (obj->compartment() != object->compartment()) {
|
||||
CrossCompartmentKey key(CrossCompartmentKey::DebuggerObject, object, obj);
|
||||
|
@ -161,12 +161,12 @@ js::ObjectImpl::initializeSlotRange(uint32_t start, uint32_t length)
|
||||
HeapSlot *fixedStart, *fixedEnd, *slotsStart, *slotsEnd;
|
||||
getSlotRangeUnchecked(start, length, &fixedStart, &fixedEnd, &slotsStart, &slotsEnd);
|
||||
|
||||
Zone *zone = this->zone();
|
||||
JSRuntime *rt = runtime();
|
||||
uint32_t offset = start;
|
||||
for (HeapSlot *sp = fixedStart; sp < fixedEnd; sp++)
|
||||
sp->init(zone, this->asObjectPtr(), HeapSlot::Slot, offset++, UndefinedValue());
|
||||
sp->init(rt, this->asObjectPtr(), HeapSlot::Slot, offset++, UndefinedValue());
|
||||
for (HeapSlot *sp = slotsStart; sp < slotsEnd; sp++)
|
||||
sp->init(zone, this->asObjectPtr(), HeapSlot::Slot, offset++, UndefinedValue());
|
||||
sp->init(rt, this->asObjectPtr(), HeapSlot::Slot, offset++, UndefinedValue());
|
||||
}
|
||||
|
||||
inline bool
|
||||
@ -198,13 +198,6 @@ ValueCompartment(const js::Value &value)
|
||||
return static_cast<js::gc::Cell *>(value.toGCThing())->compartment();
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE JS::Zone *
|
||||
ValueZone(const js::Value &value)
|
||||
{
|
||||
JS_ASSERT(value.isMarkable());
|
||||
return static_cast<js::gc::Cell *>(value.toGCThing())->zone();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
inline bool
|
||||
IsValueInCompartment(js::Value v, JSCompartment *comp)
|
||||
@ -228,11 +221,7 @@ inline void
|
||||
js::ObjectImpl::setCrossCompartmentSlot(uint32_t slot, const js::Value &value)
|
||||
{
|
||||
MOZ_ASSERT(slotInRange(slot));
|
||||
if (value.isMarkable())
|
||||
getSlotRef(slot).setCrossCompartment(this->asObjectPtr(), HeapSlot::Slot, slot, value,
|
||||
ValueZone(value));
|
||||
else
|
||||
setSlot(slot, value);
|
||||
getSlotRef(slot).set(this->asObjectPtr(), HeapSlot::Slot, slot, value);
|
||||
}
|
||||
|
||||
inline void
|
||||
@ -249,10 +238,7 @@ js::ObjectImpl::initCrossCompartmentSlot(uint32_t slot, const js::Value &value)
|
||||
{
|
||||
MOZ_ASSERT(getSlot(slot).isUndefined());
|
||||
MOZ_ASSERT(slotInRange(slot));
|
||||
if (value.isMarkable())
|
||||
getSlotRef(slot).init(ValueZone(value), this->asObjectPtr(), HeapSlot::Slot, slot, value);
|
||||
else
|
||||
initSlot(slot, value);
|
||||
initSlotUnchecked(slot, value);
|
||||
}
|
||||
|
||||
inline void
|
||||
@ -369,7 +355,7 @@ inline void
|
||||
js::ObjectImpl::privateWriteBarrierPost(void **pprivate)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
zone()->gcStoreBuffer.putCell(reinterpret_cast<js::gc::Cell **>(pprivate));
|
||||
runtime()->gcStoreBuffer.putCell(reinterpret_cast<js::gc::Cell **>(pprivate));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -400,7 +386,7 @@ js::ObjectImpl::writeBarrierPost(ObjectImpl *obj, void *addr)
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
if (uintptr_t(obj) < 32)
|
||||
return;
|
||||
obj->zone()->gcStoreBuffer.putCell((Cell **)addr);
|
||||
obj->runtime()->gcStoreBuffer.putCell((Cell **)addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -246,13 +246,13 @@ js::ObjectImpl::checkShapeConsistency()
|
||||
void
|
||||
js::ObjectImpl::initSlotRange(uint32_t start, const Value *vector, uint32_t length)
|
||||
{
|
||||
JS::Zone *zone = this->zone();
|
||||
JSRuntime *rt = runtime();
|
||||
HeapSlot *fixedStart, *fixedEnd, *slotsStart, *slotsEnd;
|
||||
getSlotRange(start, length, &fixedStart, &fixedEnd, &slotsStart, &slotsEnd);
|
||||
for (HeapSlot *sp = fixedStart; sp < fixedEnd; sp++)
|
||||
sp->init(zone, this->asObjectPtr(), HeapSlot::Slot, start++, *vector++);
|
||||
sp->init(rt, this->asObjectPtr(), HeapSlot::Slot, start++, *vector++);
|
||||
for (HeapSlot *sp = slotsStart; sp < slotsEnd; sp++)
|
||||
sp->init(zone, this->asObjectPtr(), HeapSlot::Slot, start++, *vector++);
|
||||
sp->init(rt, this->asObjectPtr(), HeapSlot::Slot, start++, *vector++);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1688,7 +1688,7 @@ DebugScopes::addDebugScope(JSContext *cx, ScopeObject &scope, DebugScopeObject &
|
||||
return false;
|
||||
}
|
||||
|
||||
HashTableWriteBarrierPost(cx->zone(), &scopes->proxiedScopes, &scope);
|
||||
HashTableWriteBarrierPost(cx->runtime, &scopes->proxiedScopes, &scope);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -31,18 +31,18 @@
|
||||
namespace js {
|
||||
|
||||
static inline void
|
||||
GetterSetterWriteBarrierPost(JS::Zone *zone, JSObject **objp)
|
||||
GetterSetterWriteBarrierPost(JSRuntime *rt, JSObject **objp)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
zone->gcStoreBuffer.putRelocatableCell(reinterpret_cast<gc::Cell **>(objp));
|
||||
rt->gcStoreBuffer.putRelocatableCell(reinterpret_cast<gc::Cell **>(objp));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
GetterSetterWriteBarrierPostRemove(JS::Zone *zone, JSObject **objp)
|
||||
GetterSetterWriteBarrierPostRemove(JSRuntime *rt, JSObject **objp)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
zone->gcStoreBuffer.removeRelocatableCell(reinterpret_cast<gc::Cell **>(objp));
|
||||
rt->gcStoreBuffer.removeRelocatableCell(reinterpret_cast<gc::Cell **>(objp));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -69,11 +69,11 @@ BaseShape::BaseShape(Class *clasp, JSObject *parent, uint32_t objectFlags,
|
||||
this->rawSetter = rawSetter;
|
||||
if ((attrs & JSPROP_GETTER) && rawGetter) {
|
||||
this->flags |= HAS_GETTER_OBJECT;
|
||||
GetterSetterWriteBarrierPost(zone(), &this->getterObj);
|
||||
GetterSetterWriteBarrierPost(runtime(), &this->getterObj);
|
||||
}
|
||||
if ((attrs & JSPROP_SETTER) && rawSetter) {
|
||||
this->flags |= HAS_SETTER_OBJECT;
|
||||
GetterSetterWriteBarrierPost(zone(), &this->setterObj);
|
||||
GetterSetterWriteBarrierPost(runtime(), &this->setterObj);
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,9 +87,9 @@ BaseShape::BaseShape(const StackBaseShape &base)
|
||||
this->rawGetter = base.rawGetter;
|
||||
this->rawSetter = base.rawSetter;
|
||||
if ((base.flags & HAS_GETTER_OBJECT) && base.rawGetter)
|
||||
GetterSetterWriteBarrierPost(zone(), &this->getterObj);
|
||||
GetterSetterWriteBarrierPost(runtime(), &this->getterObj);
|
||||
if ((base.flags & HAS_SETTER_OBJECT) && base.rawSetter)
|
||||
GetterSetterWriteBarrierPost(zone(), &this->setterObj);
|
||||
GetterSetterWriteBarrierPost(runtime(), &this->setterObj);
|
||||
}
|
||||
|
||||
inline BaseShape &
|
||||
@ -101,17 +101,17 @@ BaseShape::operator=(const BaseShape &other)
|
||||
slotSpan_ = other.slotSpan_;
|
||||
if (flags & HAS_GETTER_OBJECT) {
|
||||
getterObj = other.getterObj;
|
||||
GetterSetterWriteBarrierPost(zone(), &getterObj);
|
||||
GetterSetterWriteBarrierPost(runtime(), &getterObj);
|
||||
} else {
|
||||
rawGetter = other.rawGetter;
|
||||
GetterSetterWriteBarrierPostRemove(zone(), &getterObj);
|
||||
GetterSetterWriteBarrierPostRemove(runtime(), &getterObj);
|
||||
}
|
||||
if (flags & HAS_SETTER_OBJECT) {
|
||||
setterObj = other.setterObj;
|
||||
GetterSetterWriteBarrierPost(zone(), &setterObj);
|
||||
GetterSetterWriteBarrierPost(runtime(), &setterObj);
|
||||
} else {
|
||||
rawSetter = other.rawSetter;
|
||||
GetterSetterWriteBarrierPostRemove(zone(), &setterObj);
|
||||
GetterSetterWriteBarrierPostRemove(runtime(), &setterObj);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -95,18 +95,18 @@ NewShortString(JSContext *cx, TwoByteChars chars)
|
||||
}
|
||||
|
||||
static inline void
|
||||
StringWriteBarrierPost(JS::Zone *zone, JSString **strp)
|
||||
StringWriteBarrierPost(JSRuntime *rt, JSString **strp)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
zone->gcStoreBuffer.putRelocatableCell(reinterpret_cast<gc::Cell **>(strp));
|
||||
rt->gcStoreBuffer.putRelocatableCell(reinterpret_cast<gc::Cell **>(strp));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
StringWriteBarrierPostRemove(JS::Zone *zone, JSString **strp)
|
||||
StringWriteBarrierPostRemove(JSRuntime *rt, JSString **strp)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
zone->gcStoreBuffer.removeRelocatableCell(reinterpret_cast<gc::Cell **>(strp));
|
||||
rt->gcStoreBuffer.removeRelocatableCell(reinterpret_cast<gc::Cell **>(strp));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -134,7 +134,7 @@ JSString::writeBarrierPost(JSString *str, void *addr)
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
if (!str)
|
||||
return;
|
||||
str->zone()->gcStoreBuffer.putCell((Cell **)addr);
|
||||
str->runtime()->gcStoreBuffer.putCell((Cell **)addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -178,8 +178,8 @@ JSRope::init(JSString *left, JSString *right, size_t length)
|
||||
d.lengthAndFlags = buildLengthAndFlags(length, ROPE_FLAGS);
|
||||
d.u1.left = left;
|
||||
d.s.u2.right = right;
|
||||
js::StringWriteBarrierPost(zone(), &d.u1.left);
|
||||
js::StringWriteBarrierPost(zone(), &d.s.u2.right);
|
||||
js::StringWriteBarrierPost(runtime(), &d.u1.left);
|
||||
js::StringWriteBarrierPost(runtime(), &d.s.u2.right);
|
||||
}
|
||||
|
||||
template <js::AllowGC allowGC>
|
||||
@ -212,7 +212,7 @@ JSDependentString::init(JSLinearString *base, const jschar *chars, size_t length
|
||||
d.lengthAndFlags = buildLengthAndFlags(length, DEPENDENT_FLAGS);
|
||||
d.u1.chars = chars;
|
||||
d.s.u2.base = base;
|
||||
js::StringWriteBarrierPost(zone(), reinterpret_cast<JSString **>(&d.s.u2.base));
|
||||
js::StringWriteBarrierPost(runtime(), reinterpret_cast<JSString **>(&d.s.u2.base));
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE JSLinearString *
|
||||
|
@ -201,7 +201,7 @@ JSRope::flattenInternal(JSContext *maybecx)
|
||||
jschar *wholeChars;
|
||||
JSString *str = this;
|
||||
jschar *pos;
|
||||
Zone *zone = this->zone();
|
||||
JSRuntime *rt = runtime();
|
||||
|
||||
if (this->leftChild()->isExtensible()) {
|
||||
JSExtensibleString &left = this->leftChild()->asExtensible();
|
||||
@ -219,8 +219,8 @@ JSRope::flattenInternal(JSContext *maybecx)
|
||||
JS_STATIC_ASSERT(!(EXTENSIBLE_FLAGS & DEPENDENT_FLAGS));
|
||||
left.d.lengthAndFlags = bits ^ (EXTENSIBLE_FLAGS | DEPENDENT_FLAGS);
|
||||
left.d.s.u2.base = (JSLinearString *)this; /* will be true on exit */
|
||||
StringWriteBarrierPostRemove(zone, &left.d.u1.left);
|
||||
StringWriteBarrierPost(zone, (JSString **)&left.d.s.u2.base);
|
||||
StringWriteBarrierPostRemove(rt, &left.d.u1.left);
|
||||
StringWriteBarrierPost(rt, (JSString **)&left.d.s.u2.base);
|
||||
goto visit_right_child;
|
||||
}
|
||||
}
|
||||
@ -237,7 +237,7 @@ JSRope::flattenInternal(JSContext *maybecx)
|
||||
|
||||
JSString &left = *str->d.u1.left;
|
||||
str->d.u1.chars = pos;
|
||||
StringWriteBarrierPostRemove(zone, &str->d.u1.left);
|
||||
StringWriteBarrierPostRemove(rt, &str->d.u1.left);
|
||||
if (left.isRope()) {
|
||||
left.d.s.u3.parent = str; /* Return to this when 'left' done, */
|
||||
left.d.lengthAndFlags = 0x200; /* but goto visit_right_child. */
|
||||
@ -267,14 +267,14 @@ JSRope::flattenInternal(JSContext *maybecx)
|
||||
str->d.lengthAndFlags = buildLengthAndFlags(wholeLength, EXTENSIBLE_FLAGS);
|
||||
str->d.u1.chars = wholeChars;
|
||||
str->d.s.u2.capacity = wholeCapacity;
|
||||
StringWriteBarrierPostRemove(zone, &str->d.u1.left);
|
||||
StringWriteBarrierPostRemove(zone, &str->d.s.u2.right);
|
||||
StringWriteBarrierPostRemove(rt, &str->d.u1.left);
|
||||
StringWriteBarrierPostRemove(rt, &str->d.s.u2.right);
|
||||
return &this->asFlat();
|
||||
}
|
||||
size_t progress = str->d.lengthAndFlags;
|
||||
str->d.lengthAndFlags = buildLengthAndFlags(pos - str->d.u1.chars, DEPENDENT_FLAGS);
|
||||
str->d.s.u2.base = (JSLinearString *)this; /* will be true on exit */
|
||||
StringWriteBarrierPost(zone, (JSString **)&str->d.s.u2.base);
|
||||
StringWriteBarrierPost(rt, (JSString **)&str->d.s.u2.base);
|
||||
str = str->d.s.u3.parent;
|
||||
if (progress == 0x200)
|
||||
goto visit_right_child;
|
||||
|
Loading…
Reference in New Issue
Block a user