Bug 781390 - Make barrier verifier testing work better with the methodjit (r=bhackett)

This commit is contained in:
Bill McCloskey 2012-08-15 10:39:48 -07:00
parent 6ffc6f7672
commit 1197b8262a
15 changed files with 57 additions and 30 deletions

View File

@ -7107,17 +7107,25 @@ JS_SetGCZeal(JSContext *cx, uint8_t zeal, uint32_t frequency)
frequency = p ? atoi(p + 1) : JS_DEFAULT_ZEAL_FREQ;
}
JSRuntime *rt = cx->runtime;
if (zeal == 0) {
if (cx->runtime->gcVerifyPreData)
VerifyBarriers(cx->runtime, PreBarrierVerifier);
if (cx->runtime->gcVerifyPostData)
VerifyBarriers(cx->runtime, PostBarrierVerifier);
if (rt->gcVerifyPreData)
VerifyBarriers(rt, PreBarrierVerifier);
if (rt->gcVerifyPostData)
VerifyBarriers(rt, PostBarrierVerifier);
}
bool schedule = zeal >= js::gc::ZealAllocValue;
cx->runtime->gcZeal_ = zeal;
cx->runtime->gcZealFrequency = frequency;
cx->runtime->gcNextScheduled = schedule ? frequency : 0;
rt->gcZeal_ = zeal;
rt->gcZealFrequency = frequency;
rt->gcNextScheduled = schedule ? frequency : 0;
#ifdef JS_METHODJIT
/* In case JSCompartment::compileBarriers() changed... */
for (CompartmentsIter c(rt); !c.done(); c.next())
mjit::ClearAllFrames(c);
#endif
}
JS_PUBLIC_API(void)

View File

@ -112,7 +112,9 @@ void
JSCompartment::setNeedsBarrier(bool needs)
{
#ifdef JS_METHODJIT
if (needsBarrier_ != needs)
/* ClearAllFrames calls compileBarriers() and needs the old value. */
bool old = compileBarriers();
if (compileBarriers(needs) != old)
mjit::ClearAllFrames(this);
#endif
needsBarrier_ = needs;

View File

@ -155,6 +155,14 @@ struct JSCompartment
return needsBarrier_;
}
bool compileBarriers(bool needsBarrier) const {
return needsBarrier || rt->gcZeal() == js::gc::ZealVerifierPreValue;
}
bool compileBarriers() const {
return compileBarriers(needsBarrier());
}
void setNeedsBarrier(bool needs);
js::GCMarker *barrierTracer() {

View File

@ -299,7 +299,7 @@ struct AutoEnterCompilation
CompilerOutput co;
co.script = script;
co.constructing = constructing;
co.barriers = cx->compartment->needsBarrier();
co.barriers = cx->compartment->compileBarriers();
co.chunkIndex = chunkIndex;
// This flag is used to prevent adding the current compiled script in

View File

@ -115,7 +115,7 @@ mjit::Compiler::compile()
if (status != Compile_Okay && status != Compile_Retry) {
if (!outerScript->ensureHasMJITInfo(cx))
return Compile_Error;
JSScript::JITScriptHandle *jith = outerScript->jitHandle(isConstructing, cx->compartment->needsBarrier());
JSScript::JITScriptHandle *jith = outerScript->jitHandle(isConstructing, cx->compartment->compileBarriers());
JSScript::ReleaseCode(cx->runtime->defaultFreeOp(), jith);
jith->setUnjittable();
@ -942,7 +942,7 @@ mjit::CanMethodJIT(JSContext *cx, JSScript *script, jsbytecode *pc,
return Compile_Skipped;
if (script->hasMJITInfo()) {
JSScript::JITScriptHandle *jith = script->jitHandle(construct, cx->compartment->needsBarrier());
JSScript::JITScriptHandle *jith = script->jitHandle(construct, cx->compartment->compileBarriers());
if (jith->isUnjittable())
return Compile_Abort;
}
@ -967,7 +967,7 @@ mjit::CanMethodJIT(JSContext *cx, JSScript *script, jsbytecode *pc,
if (!script->ensureHasMJITInfo(cx))
return Compile_Error;
JSScript::JITScriptHandle *jith = script->jitHandle(construct, cx->compartment->needsBarrier());
JSScript::JITScriptHandle *jith = script->jitHandle(construct, cx->compartment->compileBarriers());
JITScript *jit;
if (jith->isEmpty()) {
@ -975,7 +975,7 @@ mjit::CanMethodJIT(JSContext *cx, JSScript *script, jsbytecode *pc,
if (!jit)
return Compile_Error;
// Script analysis can trigger GC, watch in case needsBarrier() changed.
// Script analysis can trigger GC, watch in case compileBarriers() changed.
if (gcNumber != cx->runtime->gcNumber) {
FreeOp *fop = cx->runtime->defaultFreeOp();
jit->destroy(fop);
@ -5444,7 +5444,7 @@ mjit::Compiler::jsop_setprop(PropertyName *name, bool popGuaranteed)
if (!isObject)
notObject = frame.testObject(Assembler::NotEqual, lhs);
#ifdef JSGC_INCREMENTAL_MJ
if (cx->compartment->needsBarrier() && propertyTypes->needsBarrier(cx)) {
if (cx->compartment->compileBarriers() && propertyTypes->needsBarrier(cx)) {
/* Write barrier. */
Jump j = masm.testGCThing(Address(reg, JSObject::getFixedSlotOffset(slot)));
stubcc.linkExit(j, Uses(0));
@ -5477,7 +5477,7 @@ mjit::Compiler::jsop_setprop(PropertyName *name, bool popGuaranteed)
#ifdef JSGC_INCREMENTAL_MJ
/* Write barrier. We don't have type information for JSOP_SETNAME. */
if (cx->compartment->needsBarrier() &&
if (cx->compartment->compileBarriers() &&
(!types || JSOp(*PC) == JSOP_SETNAME || types->propertyNeedsBarrier(cx, id)))
{
jsop_setprop_slow(name);
@ -5845,7 +5845,7 @@ mjit::Compiler::jsop_aliasedArg(unsigned arg, bool get, bool poppedAfter)
frame.push(Address(reg), type, true /* = reuseBase */);
} else {
#ifdef JSGC_INCREMENTAL_MJ
if (cx->compartment->needsBarrier()) {
if (cx->compartment->compileBarriers()) {
/* Write barrier. */
stubcc.linkExit(masm.testGCThing(Address(reg)), Uses(0));
stubcc.leave();
@ -5888,7 +5888,7 @@ mjit::Compiler::jsop_aliasedVar(ScopeCoordinate sc, bool get, bool poppedAfter)
finishBarrier(barrier, REJOIN_FALLTHROUGH, 0);
} else {
#ifdef JSGC_INCREMENTAL_MJ
if (cx->compartment->needsBarrier()) {
if (cx->compartment->compileBarriers()) {
/* Write barrier. */
stubcc.linkExit(masm.testGCThing(addr), Uses(0));
stubcc.leave();
@ -6035,7 +6035,7 @@ mjit::Compiler::iter(unsigned flags)
* Write barrier for stores to the iterator. We only need to take a write
* barrier if NativeIterator::obj is actually going to change.
*/
if (cx->compartment->needsBarrier()) {
if (cx->compartment->compileBarriers()) {
Jump j = masm.branchPtr(Assembler::NotEqual,
Address(nireg, offsetof(NativeIterator, obj)), reg);
stubcc.linkExit(j, Uses(1));
@ -6418,7 +6418,7 @@ mjit::Compiler::jsop_setgname(PropertyName *name, bool popGuaranteed)
RegisterID reg = frame.allocReg();
#ifdef JSGC_INCREMENTAL_MJ
/* Write barrier. */
if (cx->compartment->needsBarrier() && types->needsBarrier(cx)) {
if (cx->compartment->compileBarriers() && types->needsBarrier(cx)) {
stubcc.linkExit(masm.jump(), Uses(0));
stubcc.leave();
stubcc.masm.move(ImmPtr(value), Registers::ArgReg1);
@ -6436,7 +6436,7 @@ mjit::Compiler::jsop_setgname(PropertyName *name, bool popGuaranteed)
#ifdef JSGC_INCREMENTAL_MJ
/* Write barrier. */
if (cx->compartment->needsBarrier()) {
if (cx->compartment->compileBarriers()) {
jsop_setgname_slow(name);
return true;
}

View File

@ -486,7 +486,7 @@ private:
}
JITScript *outerJIT() {
return outerScript->getJIT(isConstructing, cx->compartment->needsBarrier());
return outerScript->getJIT(isConstructing, cx->compartment->compileBarriers());
}
ChunkDescriptor &outerChunkRef() {

View File

@ -473,7 +473,7 @@ mjit::Compiler::compileArrayPopShift(FrameEntry *thisValue, bool isPacked, bool
#ifdef JSGC_INCREMENTAL_MJ
/* Write barrier. */
if (cx->compartment->needsBarrier())
if (cx->compartment->compileBarriers())
return Compile_InlineAbort;
#endif

View File

@ -1170,7 +1170,7 @@ mjit::Compiler::jsop_setelem_dense()
* undefined.
*/
types::TypeSet *types = frame.extra(obj).types;
if (cx->compartment->needsBarrier() && (!types || types->propertyNeedsBarrier(cx, JSID_VOID))) {
if (cx->compartment->compileBarriers() && (!types || types->propertyNeedsBarrier(cx, JSID_VOID))) {
Label barrierStart = stubcc.masm.label();
stubcc.linkExitDirect(masm.jump(), barrierStart);
@ -1576,7 +1576,7 @@ mjit::Compiler::jsop_setelem(bool popGuaranteed)
#ifdef JSGC_INCREMENTAL_MJ
// Write barrier.
if (cx->compartment->needsBarrier()) {
if (cx->compartment->compileBarriers()) {
jsop_setelem_slow();
return true;
}

View File

@ -299,7 +299,7 @@ UncachedInlineCall(VMFrame &f, InitialFrameFlags initial,
* will be constructing a new type object for 'this'.
*/
if (!newType) {
if (JITScript *jit = newscript->getJIT(regs.fp()->isConstructing(), cx->compartment->needsBarrier())) {
if (JITScript *jit = newscript->getJIT(regs.fp()->isConstructing(), cx->compartment->compileBarriers())) {
if (jit->invokeEntry) {
*pret = jit->invokeEntry;

View File

@ -1079,7 +1079,7 @@ mjit::JaegerShot(JSContext *cx, bool partial)
{
StackFrame *fp = cx->fp();
JSScript *script = fp->script();
JITScript *jit = script->getJIT(fp->isConstructing(), cx->compartment->needsBarrier());
JITScript *jit = script->getJIT(fp->isConstructing(), cx->compartment->compileBarriers());
JS_ASSERT(cx->regs().pc == script->code);

View File

@ -1002,7 +1002,7 @@ VMFrame::pc()
inline void *
JSScript::nativeCodeForPC(bool constructing, jsbytecode *pc)
{
js::mjit::JITScript *jit = getJIT(constructing, compartment()->needsBarrier());
js::mjit::JITScript *jit = getJIT(constructing, compartment()->compileBarriers());
if (!jit)
return NULL;
js::mjit::JITChunk *chunk = jit->chunk(pc);

View File

@ -580,7 +580,7 @@ class CallCompiler : public BaseCompiler
masm.loadPtr(Address(t0, JSScript::offsetOfMJITInfo()), t0);
Jump hasNoJitInfo = masm.branchPtr(Assembler::Equal, t0, ImmPtr(NULL));
size_t offset = JSScript::JITScriptSet::jitHandleOffset(callingNew,
f.cx->compartment->needsBarrier());
f.cx->compartment->compileBarriers());
masm.loadPtr(Address(t0, offset), t0);
Jump hasNoJitCode = masm.branchPtr(Assembler::BelowOrEqual, t0,
ImmPtr(JSScript::JITScriptHandle::UNJITTABLE));

View File

@ -1712,12 +1712,21 @@ stubs::ConvertToTypedFloat(JSContext *cx, Value *vp)
void JS_FASTCALL
stubs::WriteBarrier(VMFrame &f, Value *addr)
{
#ifdef JS_GC_ZEAL
if (!f.cx->compartment->needsBarrier())
return;
#endif
gc::MarkValueUnbarriered(f.cx->compartment->barrierTracer(), addr, "write barrier");
}
void JS_FASTCALL
stubs::GCThingWriteBarrier(VMFrame &f, Value *addr)
{
#ifdef JS_GC_ZEAL
if (!f.cx->compartment->needsBarrier())
return;
#endif
gc::Cell *cell = (gc::Cell *)addr->toGCThing();
if (cell && !cell->isMarked())
gc::MarkValueUnbarriered(f.cx->compartment->barrierTracer(), addr, "write barrier");

View File

@ -74,7 +74,7 @@ inline mjit::JITScript *
StackFrame::jit()
{
JSScript *script_ = script();
return script_->getJIT(isConstructing(), script_->compartment()->needsBarrier());
return script_->getJIT(isConstructing(), script_->compartment()->compileBarriers());
}
#endif

View File

@ -185,7 +185,7 @@ StackFrame::prevpcSlow(InlinedSite **pinlined)
JS_ASSERT(!(flags_ & HAS_PREVPC));
#if defined(JS_METHODJIT) && defined(JS_MONOIC)
StackFrame *p = prev();
mjit::JITScript *jit = p->script()->getJIT(p->isConstructing(), p->compartment()->needsBarrier());
mjit::JITScript *jit = p->script()->getJIT(p->isConstructing(), p->compartment()->compileBarriers());
prevpc_ = jit->nativeToPC(ncode_, &prevInline_);
flags_ |= HAS_PREVPC;
if (pinlined)