Bug 885607 - Store the correct IonCode in the store buffer; r=bhackett

--HG--
extra : rebase_source : b2bdcdfde7d76bc4c341db94e680784a238a3f14
This commit is contained in:
Terrence Cole 2013-06-21 19:25:17 -07:00
parent cbbecb47d7
commit 31f4eb939b
5 changed files with 44 additions and 11 deletions

View File

@ -450,8 +450,8 @@ GeneratePrototypeGuards(JSContext *cx, IonScript *ion, MacroAssembler &masm, JSO
// use objectReg in the rest of this function.
masm.loadPtr(Address(objectReg, JSObject::offsetOfType()), scratchReg);
Address proto(scratchReg, offsetof(types::TypeObject, proto));
masm.branchPtr(Assembler::NotEqual, proto,
ImmMaybeNurseryPtr(ion->method(), obj->getProto()), failures);
masm.branchNurseryPtr(Assembler::NotEqual, proto,
ImmMaybeNurseryPtr(obj->getProto()), failures);
}
JSObject *pobj = IsCacheableDOMProxy(obj)
@ -462,7 +462,7 @@ GeneratePrototypeGuards(JSContext *cx, IonScript *ion, MacroAssembler &masm, JSO
while (pobj != holder) {
if (pobj->hasUncacheableProto()) {
JS_ASSERT(!pobj->hasSingletonType());
masm.movePtr(ImmMaybeNurseryPtr(ion->method(), pobj), scratchReg);
masm.moveNurseryPtr(ImmMaybeNurseryPtr(pobj), scratchReg);
Address objType(scratchReg, JSObject::offsetOfType());
masm.branchPtr(Assembler::NotEqual, objType, ImmGCPtr(pobj->type()), failures);
}
@ -768,7 +768,7 @@ GenerateReadSlot(JSContext *cx, IonScript *ion, MacroAssembler &masm,
if (holder) {
// Guard on the holder's shape.
holderReg = scratchReg;
masm.movePtr(ImmMaybeNurseryPtr(ion->method(), holder), holderReg);
masm.moveNurseryPtr(ImmMaybeNurseryPtr(holder), holderReg);
masm.branchPtr(Assembler::NotEqual,
Address(holderReg, JSObject::offsetOfShape()),
ImmGCPtr(holder->lastProperty()),
@ -852,7 +852,7 @@ GenerateCallGetter(JSContext *cx, IonScript *ion, MacroAssembler &masm,
// Guard on the holder's shape.
Register holderReg = scratchReg;
masm.movePtr(ImmMaybeNurseryPtr(ion->method(), holder), holderReg);
masm.moveNurseryPtr(ImmMaybeNurseryPtr(holder), holderReg);
masm.branchPtr(Assembler::NotEqual,
Address(holderReg, JSObject::offsetOfShape()),
ImmGCPtr(holder->lastProperty()),
@ -1799,7 +1799,7 @@ SetPropertyIC::attachSetterCall(JSContext *cx, IonScript *ion,
if (obj != holder)
GeneratePrototypeGuards(cx, ion, masm, obj, holder, object(), scratchReg, &protoFailure);
masm.movePtr(ImmMaybeNurseryPtr(ion->method(), holder), scratchReg);
masm.moveNurseryPtr(ImmMaybeNurseryPtr(holder), scratchReg);
masm.branchPtr(Assembler::NotEqual,
Address(scratchReg, JSObject::offsetOfShape()),
ImmGCPtr(holder->lastProperty()),

View File

@ -58,6 +58,10 @@ class Linker
return fail(cx);
code->copyFrom(masm);
masm.link(code);
#ifdef JSGC_GENERATIONAL
if (masm.embedsNurseryPointers())
cx->runtime()->gcStoreBuffer.putWholeCell(code);
#endif
return code;
}

View File

@ -18,6 +18,7 @@
#include "js/RootingAPI.h"
#include "vm/ForkJoin.h"
#include "jsgcinlines.h"
#include "jsinferinlines.h"
using namespace js;
@ -220,6 +221,27 @@ MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore)
JS_ASSERT(diffG == 0);
}
void
MacroAssembler::branchNurseryPtr(Condition cond, const Address &ptr1, const ImmMaybeNurseryPtr &ptr2,
Label *label)
{
#ifdef JSGC_GENERATIONAL
if (ptr2.value && gc::IsInsideNursery(GetIonContext()->cx->runtime(), (void *)ptr2.value))
embedsNurseryPointers_ = true;
#endif
branchPtr(cond, ptr1, ptr2, label);
}
void
MacroAssembler::moveNurseryPtr(const ImmMaybeNurseryPtr &ptr, const Register &reg)
{
#ifdef JSGC_GENERATIONAL
if (ptr.value && gc::IsInsideNursery(GetIonContext()->cx->runtime(), (void *)ptr.value))
embedsNurseryPointers_ = true;
#endif
movePtr(ptr, reg);
}
template<typename T>
void
MacroAssembler::loadFromTypedArray(int arrayType, const T &src, AnyRegister dest, Register temp,

View File

@ -59,6 +59,7 @@ class MacroAssembler : public MacroAssemblerSpecific
mozilla::Maybe<IonContext> ionContext_;
mozilla::Maybe<AutoIonContextAlloc> alloc_;
bool enoughMemory_;
bool embedsNurseryPointers_;
private:
// This field is used to manage profiling instrumentation output. If
@ -74,6 +75,7 @@ class MacroAssembler : public MacroAssemblerSpecific
// instrumentation from being emitted.
MacroAssembler()
: enoughMemory_(true),
embedsNurseryPointers_(false),
sps_(NULL)
{
JSContext *cx = GetIonContext()->cx;
@ -95,6 +97,7 @@ class MacroAssembler : public MacroAssemblerSpecific
// (for example, Trampoline-$(ARCH).cpp and IonCaches.cpp).
MacroAssembler(JSContext *cx)
: enoughMemory_(true),
embedsNurseryPointers_(false),
sps_(NULL)
{
constructRoot(cx);
@ -134,6 +137,10 @@ class MacroAssembler : public MacroAssemblerSpecific
return !enoughMemory_ || MacroAssemblerSpecific::oom();
}
bool embedsNurseryPointers() const {
return embedsNurseryPointers_;
}
// Emits a test of a value against all types in a TypeSet. A scratch
// register is required.
template <typename Source, typename TypeSet>
@ -503,6 +510,10 @@ class MacroAssembler : public MacroAssemblerSpecific
bind(&done);
}
void branchNurseryPtr(Condition cond, const Address &ptr1, const ImmMaybeNurseryPtr &ptr2,
Label *label);
void moveNurseryPtr(const ImmMaybeNurseryPtr &ptr, const Register &reg);
void canonicalizeDouble(FloatRegister reg) {
Label notNaN;
branchDouble(DoubleOrdered, reg, reg, &notNaN);

View File

@ -131,14 +131,10 @@ struct ImmGCPtr
// Used for immediates which require relocation and may be traced during minor GC.
struct ImmMaybeNurseryPtr : public ImmGCPtr
{
explicit ImmMaybeNurseryPtr(IonCode *code, gc::Cell *ptr)
explicit ImmMaybeNurseryPtr(gc::Cell *ptr)
{
this->value = reinterpret_cast<uintptr_t>(ptr);
JS_ASSERT(!IsPoisonedPtr(ptr));
#ifdef JSGC_GENERATIONAL
if (ptr && ptr->runtime()->gcNursery.isInside(ptr))
ptr->runtime()->gcStoreBuffer.putWholeCell(code);
#endif
}
};