Bug 990336 - Change the representation of SlotEdge for better performance; r=jonco

This commit is contained in:
Terrence Cole 2014-04-08 10:22:21 -07:00
Родитель fbac7dbf96
Коммит 8e01b9c9c7
2 изменённых файлов: 28 добавлений и 26 удалений

Просмотреть файл

@ -24,27 +24,29 @@ using mozilla::ReentrancyGuard;
void void
StoreBuffer::SlotsEdge::mark(JSTracer *trc) StoreBuffer::SlotsEdge::mark(JSTracer *trc)
{ {
if (trc->runtime->gcNursery.isInside(object_)) JSObject *obj = object();
if (trc->runtime->gcNursery.isInside(obj))
return; return;
if (!object_->isNative()) { if (!obj->isNative()) {
const Class *clasp = object_->getClass(); const Class *clasp = obj->getClass();
if (clasp) if (clasp)
clasp->trace(trc, object_); clasp->trace(trc, obj);
return; return;
} }
if (count_ > 0) { if (kind() == ElementKind) {
int32_t initLen = object_->getDenseInitializedLength(); int32_t initLen = obj->getDenseInitializedLength();
int32_t clampedStart = Min(start_, initLen); int32_t clampedStart = Min(start_, initLen);
int32_t clampedEnd = Min(start_ + count_, initLen); int32_t clampedEnd = Min(start_ + count_, initLen);
gc::MarkArraySlots(trc, clampedEnd - clampedStart, gc::MarkArraySlots(trc, clampedEnd - clampedStart,
object_->getDenseElements() + clampedStart, "element"); obj->getDenseElements() + clampedStart, "element");
} else { } else {
int32_t start = Min(uint32_t(start_), object_->slotSpan()); int32_t start = Min(uint32_t(start_), obj->slotSpan());
int32_t end = Min(uint32_t(start_) + (-count_), object_->slotSpan()); int32_t end = Min(uint32_t(start_) + count_, obj->slotSpan());
MOZ_ASSERT(end >= start); MOZ_ASSERT(end >= start);
MarkObjectSlots(trc, object_, start, end - start); MarkObjectSlots(trc, obj, start, end - start);
} }
} }

Просмотреть файл

@ -289,40 +289,40 @@ class StoreBuffer
const static int SlotKind = 0; const static int SlotKind = 0;
const static int ElementKind = 1; const static int ElementKind = 1;
JSObject *object_; uintptr_t objectAndKind_; // JSObject* | Kind
int32_t start_; int32_t start_;
int32_t count_; int32_t count_;
SlotsEdge(JSObject *object, int kind, int32_t start, int32_t count) SlotsEdge(JSObject *object, int kind, int32_t start, int32_t count)
: object_(object), start_(start), count_(count) : objectAndKind_(uintptr_t(object) | kind), start_(start), count_(count)
{ {
JS_ASSERT((uintptr_t(object) & 1) == 0);
JS_ASSERT(kind <= 1);
JS_ASSERT(start >= 0); JS_ASSERT(start >= 0);
JS_ASSERT(count > 0); // Must be non-zero size so that |count_| < 0 can be kind. JS_ASSERT(count > 0);
if (kind == SlotKind)
count_ = -count_;
} }
JSObject *object() const { return reinterpret_cast<JSObject *>(objectAndKind_ & ~1); }
int kind() const { return (int)(objectAndKind_ & 1); }
bool operator==(const SlotsEdge &other) const { bool operator==(const SlotsEdge &other) const {
return object_ == other.object_ && start_ == other.start_ && count_ == other.count_; return objectAndKind_ == other.objectAndKind_ &&
start_ == other.start_ &&
count_ == other.count_;
} }
bool operator!=(const SlotsEdge &other) const { bool operator!=(const SlotsEdge &other) const {
return object_ != other.object_ || start_ != other.start_ || count_ != other.count_; return !(*this == other);
} }
bool canMergeWith(const SlotsEdge &other) const { bool canMergeWith(const SlotsEdge &other) const {
JS_ASSERT(sizeof(count_) == 4); return objectAndKind_ == other.objectAndKind_;
return object_ == other.object_ && count_ >> 31 == other.count_ >> 31;
} }
void mergeInplace(const SlotsEdge &other) { void mergeInplace(const SlotsEdge &other) {
JS_ASSERT((count_ > 0 && other.count_ > 0) || (count_ < 0 && other.count_ < 0)); int32_t end = Max(start_ + count_, other.start_ + other.count_);
int32_t end1 = start_ + abs(count_);
int32_t end2 = other.start_ + abs(other.count_);
start_ = Min(start_, other.start_); start_ = Min(start_, other.start_);
count_ = Max(end1, end2) - start_; count_ = end - start_;
if (other.count_ < 0)
count_ = -count_;
} }
static bool supportsDeduplication() { return false; } static bool supportsDeduplication() { return false; }
@ -332,7 +332,7 @@ class StoreBuffer
} }
bool maybeInRememberedSet(const Nursery &nursery) const { bool maybeInRememberedSet(const Nursery &nursery) const {
return !nursery.isInside(object_); return !nursery.isInside(object());
} }
void mark(JSTracer *trc); void mark(JSTracer *trc);