Bug 650161 - Add functions for forwarding cells r=terrence

This commit is contained in:
Jon Coppeard 2014-08-14 11:46:29 +01:00
parent 6846d7c355
commit e93ae2a7fc
2 changed files with 92 additions and 0 deletions

View File

@ -1985,6 +1985,25 @@ ArenaLists::wipeDuringParallelExecution(JSRuntime *rt)
}
}
#ifdef JSGC_COMPACTING
static void
ForwardCell(Cell *dest, Cell *src)
{
// Mark a cell has having been relocated and astore forwarding pointer to
// the new cell.
MOZ_ASSERT(src->tenuredZone() == dest->tenuredZone());
// Putting the values this way round is a terrible hack to make
// ObjectImpl::zone() work on forwarded objects.
MOZ_ASSERT(ObjectImpl::offsetOfShape() == 0);
uintptr_t *ptr = reinterpret_cast<uintptr_t *>(src);
ptr[0] = reinterpret_cast<uintptr_t>(dest); // Forwarding address
ptr[1] = ForwardedCellMagicValue; // Moved!
}
#endif
void
ArenaLists::finalizeNow(FreeOp *fop, AllocKind thingKind)
{

View File

@ -12,6 +12,7 @@
#include "mozilla/Atomics.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/TypeTraits.h"
#include "jslock.h"
#include "jsobj.h"
@ -1206,6 +1207,78 @@ namespace gc {
void
MergeCompartments(JSCompartment *source, JSCompartment *target);
#ifdef JSGC_COMPACTING
/* Functions for checking and updating things that might be moved by compacting GC. */
#ifdef JS_PUNBOX64
const uintptr_t ForwardedCellMagicValue = 0xf1f1f1f1f1f1f1f1;
#else
const uintptr_t ForwardedCellMagicValue = 0xf1f1f1f1;
#endif
template <typename T>
inline bool
IsForwarded(T *t)
{
static_assert(mozilla::IsBaseOf<Cell, T>::value, "T must be a subclass of Cell");
uintptr_t *ptr = reinterpret_cast<uintptr_t *>(t);
return ptr[1] == ForwardedCellMagicValue;
}
inline bool
IsForwarded(const JS::Value &value)
{
if (value.isObject())
return IsForwarded(&value.toObject());
if (value.isString())
return IsForwarded(value.toString());
if (value.isSymbol())
return IsForwarded(value.toSymbol());
JS_ASSERT(!value.isGCThing());
return false;
}
template <typename T>
inline T *
Forwarded(T *t)
{
JS_ASSERT(IsForwarded(t));
uintptr_t *ptr = reinterpret_cast<uintptr_t *>(t);
return reinterpret_cast<T *>(ptr[0]);
}
inline Value
Forwarded(const JS::Value &value)
{
if (value.isObject())
return ObjectValue(*Forwarded(&value.toObject()));
else if (value.isString())
return StringValue(Forwarded(value.toString()));
else if (value.isSymbol())
return SymbolValue(Forwarded(value.toSymbol()));
JS_ASSERT(!value.isGCThing());
return value;
}
template <typename T>
inline T
MaybeForwarded(T t)
{
return IsForwarded(t) ? Forwarded(t) : t;
}
#else
template <typename T> inline bool IsForwarded(T t) { return false; }
template <typename T> inline T MaybeForwarded(T t) { return t; }
#endif // JSGC_COMPACTING
const int ZealPokeValue = 1;
const int ZealAllocValue = 2;
const int ZealFrameGCValue = 3;