зеркало из https://github.com/mozilla/gecko-dev.git
Bug 877762 - GC: Post-barrier cycle collector participants - 1 Fixes and updates to JS::Heap<T> r=terrence
This commit is contained in:
Родитель
115cb86ff1
Коммит
7295df4d69
|
@ -181,18 +181,18 @@ class Heap : public js::HeapBase<T>
|
|||
Heap() {
|
||||
MOZ_STATIC_ASSERT(sizeof(T) == sizeof(Heap<T>),
|
||||
"Heap<T> must be binary compatible with T.");
|
||||
set(js::RootMethods<T>::initial());
|
||||
init(js::RootMethods<T>::initial());
|
||||
}
|
||||
explicit Heap(T p) { set(p); }
|
||||
explicit Heap(const Heap<T> &p) { set(p.ptr); }
|
||||
explicit Heap(T p) { init(p); }
|
||||
explicit Heap(const Heap<T> &p) { init(p.ptr); }
|
||||
|
||||
~Heap() {
|
||||
if (js::RootMethods<T>::needsPostBarrier(ptr))
|
||||
relocate();
|
||||
}
|
||||
|
||||
bool operator!=(const T &other) { return *ptr != other; }
|
||||
bool operator==(const T &other) { return *ptr == other; }
|
||||
bool operator!=(const T &other) const { return ptr != other; }
|
||||
bool operator==(const T &other) const { return ptr == other; }
|
||||
|
||||
operator T() const { return ptr; }
|
||||
T operator->() const { return ptr; }
|
||||
|
@ -220,6 +220,13 @@ class Heap : public js::HeapBase<T>
|
|||
}
|
||||
|
||||
private:
|
||||
void init(T newPtr) {
|
||||
JS_ASSERT(!js::RootMethods<T>::poisoned(newPtr));
|
||||
ptr = newPtr;
|
||||
if (js::RootMethods<T>::needsPostBarrier(ptr))
|
||||
post();
|
||||
}
|
||||
|
||||
void post() {
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
JS_ASSERT(js::RootMethods<T>::needsPostBarrier(ptr));
|
||||
|
@ -320,8 +327,8 @@ class MOZ_NONHEAP_CLASS Handle : public js::HandleBase<T>
|
|||
operator const T&() const { return get(); }
|
||||
T operator->() const { return get(); }
|
||||
|
||||
bool operator!=(const T &other) { return *ptr != other; }
|
||||
bool operator==(const T &other) { return *ptr == other; }
|
||||
bool operator!=(const T &other) const { return *ptr != other; }
|
||||
bool operator==(const T &other) const { return *ptr == other; }
|
||||
|
||||
private:
|
||||
Handle() {}
|
||||
|
@ -605,8 +612,8 @@ class MOZ_STACK_CLASS Rooted : public js::RootedBase<T>
|
|||
ptr = value;
|
||||
}
|
||||
|
||||
bool operator!=(const T &other) { return ptr != other; }
|
||||
bool operator==(const T &other) { return ptr == other; }
|
||||
bool operator!=(const T &other) const { return ptr != other; }
|
||||
bool operator==(const T &other) const { return ptr == other; }
|
||||
|
||||
private:
|
||||
void commonInit(Rooted<void*> **thingGCRooters) {
|
||||
|
@ -766,8 +773,8 @@ class FakeRooted : public RootedBase<T>
|
|||
return ptr;
|
||||
}
|
||||
|
||||
bool operator!=(const T &other) { return ptr != other; }
|
||||
bool operator==(const T &other) { return ptr == other; }
|
||||
bool operator!=(const T &other) const { return ptr != other; }
|
||||
bool operator==(const T &other) const { return ptr == other; }
|
||||
|
||||
private:
|
||||
T ptr;
|
||||
|
|
|
@ -1420,6 +1420,7 @@ template <> struct RootMethods<JS::Value>
|
|||
#endif
|
||||
};
|
||||
|
||||
template <class Outer> class UnbarrieredMutableValueOperations;
|
||||
template <class Outer> class MutableValueOperations;
|
||||
|
||||
/*
|
||||
|
@ -1431,7 +1432,9 @@ template <class Outer> class MutableValueOperations;
|
|||
template <class Outer>
|
||||
class ValueOperations
|
||||
{
|
||||
friend class UnbarrieredMutableValueOperations<Outer>;
|
||||
friend class MutableValueOperations<Outer>;
|
||||
|
||||
const JS::Value * value() const { return static_cast<const Outer*>(this)->extract(); }
|
||||
|
||||
public:
|
||||
|
@ -1469,14 +1472,16 @@ class ValueOperations
|
|||
};
|
||||
|
||||
/*
|
||||
* A class designed for CRTP use in implementing the mutating parts of the
|
||||
* Value interface in Value-like classes. Outer must be a class inheriting
|
||||
* MutableValueOperations<Outer> with visible extractMutable() and extract()
|
||||
* methods returning the const Value* and Value* abstracted by Outer.
|
||||
* A class designed for CRTP use in implementing the mutating parts of the Value
|
||||
* interface in Value-like classes that don't need post barriers. Outer must be
|
||||
* a class inheriting UnbarrieredMutableValueOperations<Outer> with visible
|
||||
* extractMutable() and extract() methods returning the const Value* and Value*
|
||||
* abstracted by Outer.
|
||||
*/
|
||||
template <class Outer>
|
||||
class MutableValueOperations : public ValueOperations<Outer>
|
||||
class UnbarrieredMutableValueOperations : public ValueOperations<Outer>
|
||||
{
|
||||
friend class MutableValueOperations<Outer>;
|
||||
JS::Value * value() { return static_cast<Outer*>(this)->extractMutable(); }
|
||||
|
||||
public:
|
||||
|
@ -1484,26 +1489,65 @@ class MutableValueOperations : public ValueOperations<Outer>
|
|||
void setUndefined() { value()->setUndefined(); }
|
||||
void setInt32(int32_t i) { value()->setInt32(i); }
|
||||
void setDouble(double d) { value()->setDouble(d); }
|
||||
void setString(JSString *str) { value()->setString(str); }
|
||||
void setString(const JS::Anchor<JSString *> &str) { value()->setString(str); }
|
||||
void setObject(JSObject &obj) { value()->setObject(obj); }
|
||||
void setBoolean(bool b) { value()->setBoolean(b); }
|
||||
void setMagic(JSWhyMagic why) { value()->setMagic(why); }
|
||||
bool setNumber(uint32_t ui) { return value()->setNumber(ui); }
|
||||
bool setNumber(double d) { return value()->setNumber(d); }
|
||||
void setObjectOrNull(JSObject *arg) { value()->setObjectOrNull(arg); }
|
||||
};
|
||||
|
||||
/*
|
||||
* Augment the generic Heap<T> interface when T = Value with type-querying
|
||||
* and value-extracting operations.
|
||||
* A class designed for CRTP use in implementing all the mutating parts of the
|
||||
* Value interface in Value-like classes. Outer must be a class inheriting
|
||||
* MutableValueOperations<Outer> with visible extractMutable() and extract()
|
||||
* methods returning the const Value* and Value* abstracted by Outer.
|
||||
*/
|
||||
template <class Outer>
|
||||
class MutableValueOperations : public UnbarrieredMutableValueOperations<Outer>
|
||||
{
|
||||
public:
|
||||
void setString(JSString *str) { this->value()->setString(str); }
|
||||
void setString(const JS::Anchor<JSString *> &str) { this->value()->setString(str); }
|
||||
void setObject(JSObject &obj) { this->value()->setObject(obj); }
|
||||
void setObjectOrNull(JSObject *arg) { this->value()->setObjectOrNull(arg); }
|
||||
};
|
||||
|
||||
/*
|
||||
* Augment the generic Heap<T> interface when T = Value with
|
||||
* type-querying, value-extracting, and mutating operations.
|
||||
*/
|
||||
template <>
|
||||
class HeapBase<JS::Value> : public ValueOperations<JS::Heap<JS::Value> >
|
||||
class HeapBase<JS::Value> : public UnbarrieredMutableValueOperations<JS::Heap<JS::Value> >
|
||||
{
|
||||
friend class ValueOperations<JS::Heap<JS::Value> >;
|
||||
const JS::Value * extract() const {
|
||||
return static_cast<const JS::Heap<JS::Value>*>(this)->address();
|
||||
typedef JS::Heap<JS::Value> Outer;
|
||||
|
||||
friend class ValueOperations<Outer>;
|
||||
friend class UnbarrieredMutableValueOperations<Outer>;
|
||||
|
||||
const JS::Value * extract() const { return static_cast<const Outer*>(this)->address(); }
|
||||
JS::Value * extractMutable() { return static_cast<Outer*>(this)->unsafeGet(); }
|
||||
|
||||
/*
|
||||
* Setters that potentially change the value to a GC thing from a non-GC
|
||||
* thing must call JS::Heap::set() to trigger the post barrier.
|
||||
*
|
||||
* Changing from a GC thing to a non-GC thing value will leave the heap
|
||||
* value in the store buffer, but it will be ingored so this is not a
|
||||
* problem.
|
||||
*/
|
||||
void setBarriered(const JS::Value &v) {
|
||||
static_cast<JS::Heap<JS::Value> *>(this)->set(v);
|
||||
}
|
||||
|
||||
public:
|
||||
void setString(JSString *str) { setBarriered(JS::StringValue(str)); }
|
||||
void setString(const JS::Anchor<JSString *> &str) { setBarriered(JS::StringValue(str.get())); }
|
||||
void setObject(JSObject &obj) { setBarriered(JS::ObjectValue(obj)); }
|
||||
|
||||
void setObjectOrNull(JSObject *arg) {
|
||||
if (arg)
|
||||
setObject(*arg);
|
||||
else
|
||||
setNull();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1532,6 +1576,7 @@ class MutableHandleBase<JS::Value> : public MutableValueOperations<JS::MutableHa
|
|||
return static_cast<const JS::MutableHandle<JS::Value>*>(this)->address();
|
||||
}
|
||||
|
||||
friend class UnbarrieredMutableValueOperations<JS::MutableHandle<JS::Value> >;
|
||||
friend class MutableValueOperations<JS::MutableHandle<JS::Value> >;
|
||||
JS::Value * extractMutable() {
|
||||
return static_cast<JS::MutableHandle<JS::Value>*>(this)->address();
|
||||
|
@ -1550,6 +1595,7 @@ class RootedBase<JS::Value> : public MutableValueOperations<JS::Rooted<JS::Value
|
|||
return static_cast<const JS::Rooted<JS::Value>*>(this)->address();
|
||||
}
|
||||
|
||||
friend class UnbarrieredMutableValueOperations<JS::Rooted<JS::Value> >;
|
||||
friend class MutableValueOperations<JS::Rooted<JS::Value> >;
|
||||
JS::Value * extractMutable() {
|
||||
return static_cast<JS::Rooted<JS::Value>*>(this)->address();
|
||||
|
|
Загрузка…
Ссылка в новой задаче