Add incremental barriers to addprop ICs (bug 811058, r=billm).

--HG--
extra : rebase_source : 518dcb987ddd2967ffd24e79afcee203d9d83820
This commit is contained in:
David Anderson 2012-11-26 13:57:46 -08:00
Родитель dcd17e367e
Коммит ee12984cba
10 изменённых файлов: 78 добавлений и 38 удалений

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

@ -187,8 +187,12 @@ IonRuntime::initialize(JSContext *cx)
if (!enterJIT_)
return false;
preBarrier_ = generatePreBarrier(cx);
if (!preBarrier_)
valuePreBarrier_ = generatePreBarrier(cx, MIRType_Value);
if (!valuePreBarrier_)
return false;
shapePreBarrier_ = generatePreBarrier(cx, MIRType_Shape);
if (!shapePreBarrier_)
return false;
for (VMFunction *fun = VMFunction::functions; fun; fun = fun->next) {
@ -1916,11 +1920,17 @@ ion::FinishInvalidation(FreeOp *fop, JSScript *script)
}
void
ion::MarkFromIon(JSRuntime *rt, Value *vp)
ion::MarkValueFromIon(JSRuntime *rt, Value *vp)
{
gc::MarkValueUnbarriered(&rt->gcMarker, vp, "write barrier");
}
void
ion::MarkShapeFromIon(JSRuntime *rt, Shape **shapep)
{
gc::MarkShapeUnbarriered(&rt->gcMarker, shapep, "write barrier");
}
void
ion::ForbidCompilation(JSContext *cx, JSScript *script)
{

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

@ -269,7 +269,8 @@ void Invalidate(types::TypeCompartment &types, FreeOp *fop,
void Invalidate(JSContext *cx, const Vector<types::RecompileInfo> &invalid, bool resetUses = true);
bool Invalidate(JSContext *cx, JSScript *script, bool resetUses = true);
void MarkFromIon(JSRuntime *rt, Value *vp);
void MarkValueFromIon(JSRuntime *rt, Value *vp);
void MarkShapeFromIon(JSRuntime *rt, Shape **shapep);
void ToggleBarriers(JSCompartment *comp, bool needs);

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

@ -1173,7 +1173,10 @@ IonCacheSetProperty::attachNativeAdding(JSContext *cx, IonScript *ion, JSObject
masm.pop(object()); // restore object reg
/* Changing object shape. Write the object's new shape. */
masm.storePtr(ImmGCPtr(newShape), Address(object(), JSObject::offsetOfShape()));
Address shapeAddr(object(), JSObject::offsetOfShape());
if (cx->compartment->needsBarrier())
masm.callPreBarrier(shapeAddr, MIRType_Shape);
masm.storePtr(ImmGCPtr(newShape), shapeAddr);
/* Set the value on the object. */
if (obj->isFixedSlot(propShape->slot())) {

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

@ -51,7 +51,8 @@ class IonRuntime
IonCode *invalidator_;
// Thunk that calls the GC pre barrier.
IonCode *preBarrier_;
IonCode *valuePreBarrier_;
IonCode *shapePreBarrier_;
// Map VMFunction addresses to the IonCode of the wrapper.
typedef WeakCache<const VMFunction *, IonCode *> VMWrapperMap;
@ -63,7 +64,7 @@ class IonRuntime
IonCode *generateBailoutTable(JSContext *cx, uint32 frameClass);
IonCode *generateBailoutHandler(JSContext *cx);
IonCode *generateInvalidator(JSContext *cx);
IonCode *generatePreBarrier(JSContext *cx);
IonCode *generatePreBarrier(JSContext *cx, MIRType type);
IonCode *generateVMWrapper(JSContext *cx, const VMFunction &f);
public:
@ -127,8 +128,12 @@ class IonCompartment
return rt->enterJIT_->as<EnterIonCode>();
}
IonCode *preBarrier() {
return rt->preBarrier_;
IonCode *valuePreBarrier() {
return rt->valuePreBarrier_;
}
IonCode *shapePreBarrier() {
return rt->shapePreBarrier_;
}
AutoFlushCache *flusher() {

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

@ -385,7 +385,10 @@ class MacroAssembler : public MacroAssemblerSpecific
template <typename T>
void callPreBarrier(const T &address, MIRType type) {
JS_ASSERT(type == MIRType_Value || type == MIRType_String || type == MIRType_Object);
JS_ASSERT(type == MIRType_Value ||
type == MIRType_String ||
type == MIRType_Object ||
type == MIRType_Shape);
Label done;
if (type == MIRType_Value)
@ -395,7 +398,9 @@ class MacroAssembler : public MacroAssemblerSpecific
computeEffectiveAddress(address, PreBarrierReg);
JSCompartment *compartment = GetIonContext()->compartment;
IonCode *preBarrier = compartment->ionCompartment()->preBarrier();
IonCode *preBarrier = (type == MIRType_Shape)
? compartment->ionCompartment()->shapePreBarrier()
: compartment->ionCompartment()->valuePreBarrier();
call(preBarrier);
Pop(PreBarrierReg);

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

@ -59,6 +59,27 @@ enum BailoutKind
Bailout_CachedShapeGuard
};
// The ordering of this enumeration is important: Anything < Value is a
// specialized type. Furthermore, anything < String has trivial conversion to
// a number.
enum MIRType
{
MIRType_Undefined,
MIRType_Null,
MIRType_Boolean,
MIRType_Int32,
MIRType_Double,
MIRType_String,
MIRType_Object,
MIRType_Magic,
MIRType_Value,
MIRType_None, // Invalid, used as a placeholder.
MIRType_Slots, // A slots vector
MIRType_Elements, // An elements vector
MIRType_StackFrame, // StackFrame pointer for OSR.
MIRType_Shape // A Shape pointer.
};
#ifdef DEBUG
// Track the pipeline of opcodes which has produced a snapshot.
#define TRACK_SNAPSHOTS 1

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

@ -13,27 +13,6 @@
namespace js {
namespace ion {
// The ordering of this enumeration is important: Anything < Value is a
// specialized type. Furthermore, anything < String has trivial conversion to
// a number.
enum MIRType
{
MIRType_Undefined,
MIRType_Null,
MIRType_Boolean,
MIRType_Int32,
MIRType_Double,
MIRType_String,
MIRType_Object,
MIRType_Magic,
MIRType_Value,
MIRType_None, // Invalid, used as a placeholder.
MIRType_Slots, // A slots vector
MIRType_Elements, // An elements vector
MIRType_StackFrame // StackFrame pointer for OSR.
};
enum LazyArgumentsType {
MaybeArguments = 0,
DefinitelyArguments,

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

@ -609,7 +609,7 @@ IonRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f)
}
IonCode *
IonRuntime::generatePreBarrier(JSContext *cx)
IonRuntime::generatePreBarrier(JSContext *cx, MIRType type)
{
MacroAssembler masm;
@ -623,7 +623,12 @@ IonRuntime::generatePreBarrier(JSContext *cx)
masm.setupUnalignedABICall(2, r2);
masm.passABIArg(r0);
masm.passABIArg(r1);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, MarkFromIon));
if (type == MIRType_Value) {
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, MarkValueFromIon));
} else {
JS_ASSERT(type == MIRType_Shape);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, MarkShapeFromIon));
}
masm.PopRegsInMask(save);
masm.ret();

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

@ -517,7 +517,7 @@ IonRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f)
}
IonCode *
IonRuntime::generatePreBarrier(JSContext *cx)
IonRuntime::generatePreBarrier(JSContext *cx, MIRType type)
{
MacroAssembler masm;
@ -531,7 +531,12 @@ IonRuntime::generatePreBarrier(JSContext *cx)
masm.setupUnalignedABICall(2, rax);
masm.passABIArg(rcx);
masm.passABIArg(rdx);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, MarkFromIon));
if (type == MIRType_Value) {
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, MarkValueFromIon));
} else {
JS_ASSERT(type == MIRType_Shape);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, MarkShapeFromIon));
}
masm.PopRegsInMask(regs);
masm.ret();

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

@ -544,7 +544,7 @@ IonRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f)
}
IonCode *
IonRuntime::generatePreBarrier(JSContext *cx)
IonRuntime::generatePreBarrier(JSContext *cx, MIRType type)
{
MacroAssembler masm;
@ -558,7 +558,13 @@ IonRuntime::generatePreBarrier(JSContext *cx)
masm.setupUnalignedABICall(2, eax);
masm.passABIArg(ecx);
masm.passABIArg(edx);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, MarkFromIon));
if (type == MIRType_Value) {
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, MarkValueFromIon));
} else {
JS_ASSERT(type == MIRType_Shape);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, MarkShapeFromIon));
}
masm.PopRegsInMask(save);
masm.ret();