зеркало из https://github.com/mozilla/gecko-dev.git
Bug 915482 (part 1) - Move most of gc/Barrier-inl.h into gc/Barrier.h. r=terrence.
--HG-- extra : rebase_source : e3fbf54420858cd5ae5328f4cf5c5001d1d0ccb9
This commit is contained in:
Родитель
7cc64cec66
Коммит
05a8238e35
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "jstypes.h"
|
||||
|
||||
#include "js/RootingAPI.h"
|
||||
#include "js/TypeDecls.h"
|
||||
#include "js/Utility.h"
|
||||
|
||||
|
@ -160,4 +161,30 @@ extern JS_PUBLIC_DATA(const jsid) JSID_EMPTY;
|
|||
extern JS_PUBLIC_DATA(const JS::Handle<jsid>) JSID_VOIDHANDLE;
|
||||
extern JS_PUBLIC_DATA(const JS::Handle<jsid>) JSID_EMPTYHANDLE;
|
||||
|
||||
namespace js {
|
||||
|
||||
inline bool
|
||||
IsPoisonedId(jsid iden)
|
||||
{
|
||||
if (JSID_IS_STRING(iden))
|
||||
return JS::IsPoisonedPtr(JSID_TO_STRING(iden));
|
||||
if (JSID_IS_OBJECT(iden))
|
||||
return JS::IsPoisonedPtr(JSID_TO_OBJECT(iden));
|
||||
return false;
|
||||
}
|
||||
|
||||
template <> struct GCMethods<jsid>
|
||||
{
|
||||
static jsid initial() { return JSID_VOID; }
|
||||
static ThingRootKind kind() { return THING_ROOT_ID; }
|
||||
static bool poisoned(jsid id) { return IsPoisonedId(id); }
|
||||
static bool needsPostBarrier(jsid id) { return false; }
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
static void postBarrier(jsid *idp) {}
|
||||
static void relocate(jsid *idp) {}
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* js_Id_h */
|
||||
|
|
|
@ -18,134 +18,6 @@
|
|||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* This is a post barrier for HashTables whose key is a GC pointer. Any
|
||||
* insertion into a HashTable not marked as part of the runtime, with a GC
|
||||
* pointer as a key, must call this immediately after each insertion.
|
||||
*/
|
||||
template <class Map, class Key>
|
||||
inline void
|
||||
HashTableWriteBarrierPost(JSRuntime *rt, Map *map, const Key &key)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
if (key && IsInsideNursery(rt, key))
|
||||
rt->gcStoreBuffer.putGeneric(gc::HashKeyRef<Map, Key>(map, key));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline
|
||||
EncapsulatedId::~EncapsulatedId()
|
||||
{
|
||||
pre();
|
||||
}
|
||||
|
||||
inline EncapsulatedId &
|
||||
EncapsulatedId::operator=(const EncapsulatedId &v)
|
||||
{
|
||||
if (v.value != value)
|
||||
pre();
|
||||
JS_ASSERT(!IsPoisonedId(v.value));
|
||||
value = v.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void
|
||||
EncapsulatedId::pre()
|
||||
{
|
||||
#ifdef JSGC_INCREMENTAL
|
||||
if (JSID_IS_OBJECT(value)) {
|
||||
JSObject *obj = JSID_TO_OBJECT(value);
|
||||
Zone *zone = obj->zone();
|
||||
if (zone->needsBarrier()) {
|
||||
js::gc::MarkObjectUnbarriered(zone->barrierTracer(), &obj, "write barrier");
|
||||
JS_ASSERT(obj == JSID_TO_OBJECT(value));
|
||||
}
|
||||
} else if (JSID_IS_STRING(value)) {
|
||||
JSString *str = JSID_TO_STRING(value);
|
||||
Zone *zone = str->zone();
|
||||
if (zone->needsBarrier()) {
|
||||
js::gc::MarkStringUnbarriered(zone->barrierTracer(), &str, "write barrier");
|
||||
JS_ASSERT(str == JSID_TO_STRING(value));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline
|
||||
RelocatableId::~RelocatableId()
|
||||
{
|
||||
pre();
|
||||
}
|
||||
|
||||
inline RelocatableId &
|
||||
RelocatableId::operator=(jsid id)
|
||||
{
|
||||
if (id != value)
|
||||
pre();
|
||||
JS_ASSERT(!IsPoisonedId(id));
|
||||
value = id;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline RelocatableId &
|
||||
RelocatableId::operator=(const RelocatableId &v)
|
||||
{
|
||||
if (v.value != value)
|
||||
pre();
|
||||
JS_ASSERT(!IsPoisonedId(v.value));
|
||||
value = v.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline
|
||||
HeapId::HeapId(jsid id)
|
||||
: EncapsulatedId(id)
|
||||
{
|
||||
JS_ASSERT(!IsPoisonedId(id));
|
||||
post();
|
||||
}
|
||||
|
||||
inline
|
||||
HeapId::~HeapId()
|
||||
{
|
||||
pre();
|
||||
}
|
||||
|
||||
inline void
|
||||
HeapId::init(jsid id)
|
||||
{
|
||||
JS_ASSERT(!IsPoisonedId(id));
|
||||
value = id;
|
||||
post();
|
||||
}
|
||||
|
||||
inline void
|
||||
HeapId::post()
|
||||
{
|
||||
}
|
||||
|
||||
inline HeapId &
|
||||
HeapId::operator=(jsid id)
|
||||
{
|
||||
if (id != value)
|
||||
pre();
|
||||
JS_ASSERT(!IsPoisonedId(id));
|
||||
value = id;
|
||||
post();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline HeapId &
|
||||
HeapId::operator=(const HeapId &v)
|
||||
{
|
||||
if (v.value != value)
|
||||
pre();
|
||||
JS_ASSERT(!IsPoisonedId(v.value));
|
||||
value = v.value;
|
||||
post();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const Value &
|
||||
ReadBarrieredValue::get() const
|
||||
{
|
||||
|
|
|
@ -124,11 +124,33 @@ namespace gc {
|
|||
// Direct value access used by the write barriers and the jits.
|
||||
void
|
||||
MarkValueUnbarriered(JSTracer *trc, Value *v, const char *name);
|
||||
|
||||
// These two declarations are also present in gc/Marking.h, via the DeclMarker
|
||||
// macro. Not great, but hard to avoid.
|
||||
void
|
||||
MarkObjectUnbarriered(JSTracer *trc, JSObject **obj, const char *name);
|
||||
void
|
||||
MarkStringUnbarriered(JSTracer *trc, JSString **str, const char *name);
|
||||
}
|
||||
|
||||
// Note: these functions must be equivalent to the zone() functions implemented
|
||||
// by all the subclasses of Cell.
|
||||
|
||||
JS::Zone *
|
||||
ZoneOfObject(const JSObject &obj);
|
||||
|
||||
static inline JS::shadow::Zone *
|
||||
ShadowZoneOfObject(JSObject *obj)
|
||||
{
|
||||
return JS::shadow::Zone::asShadowZone(ZoneOfObject(*obj));
|
||||
}
|
||||
|
||||
static inline JS::shadow::Zone *
|
||||
ShadowZoneOfString(JSString *str)
|
||||
{
|
||||
return JS::shadow::Zone::asShadowZone(reinterpret_cast<const js::gc::Cell *>(str)->tenuredZone());
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE JS::Zone *
|
||||
ZoneOfValue(const JS::Value &value)
|
||||
{
|
||||
|
@ -138,6 +160,23 @@ ZoneOfValue(const JS::Value &value)
|
|||
return static_cast<js::gc::Cell *>(value.toGCThing())->tenuredZone();
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a post barrier for HashTables whose key is a GC pointer. Any
|
||||
* insertion into a HashTable not marked as part of the runtime, with a GC
|
||||
* pointer as a key, must call this immediately after each insertion.
|
||||
*/
|
||||
template <class Map, class Key>
|
||||
inline void
|
||||
HashTableWriteBarrierPost(JSRuntime *rt, Map *map, const Key &key)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
if (key && IsInsideNursery(rt, key)) {
|
||||
JS::shadow::Runtime *shadowRuntime = JS::shadow::Runtime::asShadowRuntime(rt);
|
||||
shadowRuntime->gcStoreBufferPtr()->putGeneric(gc::HashKeyRef<Map, Key>(map, key));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class T, typename Unioned = uintptr_t>
|
||||
class EncapsulatedPtr
|
||||
{
|
||||
|
@ -823,9 +862,15 @@ class EncapsulatedId
|
|||
public:
|
||||
explicit EncapsulatedId() : value(JSID_VOID) {}
|
||||
explicit EncapsulatedId(jsid id) : value(id) {}
|
||||
~EncapsulatedId();
|
||||
~EncapsulatedId() { pre(); }
|
||||
|
||||
inline EncapsulatedId &operator=(const EncapsulatedId &v);
|
||||
EncapsulatedId &operator=(const EncapsulatedId &v) {
|
||||
if (v.value != value)
|
||||
pre();
|
||||
JS_ASSERT(!IsPoisonedId(v.value));
|
||||
value = v.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(jsid id) const { return value == id; }
|
||||
bool operator!=(jsid id) const { return value != id; }
|
||||
|
@ -836,7 +881,25 @@ class EncapsulatedId
|
|||
operator jsid() const { return value; }
|
||||
|
||||
protected:
|
||||
inline void pre();
|
||||
void pre() {
|
||||
#ifdef JSGC_INCREMENTAL
|
||||
if (JSID_IS_OBJECT(value)) {
|
||||
JSObject *obj = JSID_TO_OBJECT(value);
|
||||
JS::shadow::Zone *shadowZone = ShadowZoneOfObject(obj);
|
||||
if (shadowZone->needsBarrier()) {
|
||||
js::gc::MarkObjectUnbarriered(shadowZone->barrierTracer(), &obj, "write barrier");
|
||||
JS_ASSERT(obj == JSID_TO_OBJECT(value));
|
||||
}
|
||||
} else if (JSID_IS_STRING(value)) {
|
||||
JSString *str = JSID_TO_STRING(value);
|
||||
JS::shadow::Zone *shadowZone = ShadowZoneOfString(str);
|
||||
if (shadowZone->needsBarrier()) {
|
||||
js::gc::MarkStringUnbarriered(shadowZone->barrierTracer(), &str, "write barrier");
|
||||
JS_ASSERT(str == JSID_TO_STRING(value));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
class RelocatableId : public EncapsulatedId
|
||||
|
@ -844,26 +907,65 @@ class RelocatableId : public EncapsulatedId
|
|||
public:
|
||||
explicit RelocatableId() : EncapsulatedId() {}
|
||||
explicit inline RelocatableId(jsid id) : EncapsulatedId(id) {}
|
||||
inline ~RelocatableId();
|
||||
~RelocatableId() { pre(); }
|
||||
|
||||
inline RelocatableId &operator=(jsid id);
|
||||
inline RelocatableId &operator=(const RelocatableId &v);
|
||||
RelocatableId &operator=(jsid id) {
|
||||
if (id != value)
|
||||
pre();
|
||||
JS_ASSERT(!IsPoisonedId(id));
|
||||
value = id;
|
||||
return *this;
|
||||
}
|
||||
|
||||
RelocatableId &operator=(const RelocatableId &v) {
|
||||
if (v.value != value)
|
||||
pre();
|
||||
JS_ASSERT(!IsPoisonedId(v.value));
|
||||
value = v.value;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
class HeapId : public EncapsulatedId
|
||||
{
|
||||
public:
|
||||
explicit HeapId() : EncapsulatedId() {}
|
||||
explicit inline HeapId(jsid id);
|
||||
inline ~HeapId();
|
||||
|
||||
inline void init(jsid id);
|
||||
explicit HeapId(jsid id)
|
||||
: EncapsulatedId(id)
|
||||
{
|
||||
JS_ASSERT(!IsPoisonedId(id));
|
||||
post();
|
||||
}
|
||||
|
||||
inline HeapId &operator=(jsid id);
|
||||
inline HeapId &operator=(const HeapId &v);
|
||||
~HeapId() { pre(); }
|
||||
|
||||
void init(jsid id) {
|
||||
JS_ASSERT(!IsPoisonedId(id));
|
||||
value = id;
|
||||
post();
|
||||
}
|
||||
|
||||
HeapId &operator=(jsid id) {
|
||||
if (id != value)
|
||||
pre();
|
||||
JS_ASSERT(!IsPoisonedId(id));
|
||||
value = id;
|
||||
post();
|
||||
return *this;
|
||||
}
|
||||
|
||||
HeapId &operator=(const HeapId &v) {
|
||||
if (v.value != value)
|
||||
pre();
|
||||
JS_ASSERT(!IsPoisonedId(v.value));
|
||||
value = v.value;
|
||||
post();
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
inline void post();
|
||||
void post() {};
|
||||
|
||||
HeapId(const HeapId &v) MOZ_DELETE;
|
||||
};
|
||||
|
|
|
@ -1359,28 +1359,6 @@ JS_IsInRequest(JSRuntime *rt);
|
|||
|
||||
namespace js {
|
||||
|
||||
inline bool
|
||||
IsPoisonedId(jsid iden)
|
||||
{
|
||||
if (JSID_IS_STRING(iden))
|
||||
return JS::IsPoisonedPtr(JSID_TO_STRING(iden));
|
||||
if (JSID_IS_OBJECT(iden))
|
||||
return JS::IsPoisonedPtr(JSID_TO_OBJECT(iden));
|
||||
return false;
|
||||
}
|
||||
|
||||
template <> struct GCMethods<jsid>
|
||||
{
|
||||
static jsid initial() { return JSID_VOID; }
|
||||
static ThingRootKind kind() { return THING_ROOT_ID; }
|
||||
static bool poisoned(jsid id) { return IsPoisonedId(id); }
|
||||
static bool needsPostBarrier(jsid id) { return false; }
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
static void postBarrier(jsid *idp) {}
|
||||
static void relocate(jsid *idp) {}
|
||||
#endif
|
||||
};
|
||||
|
||||
void
|
||||
AssertHeapIsIdle(JSRuntime *rt);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче