Bug 839303 - Add inline caches to baseline compiler for next/more iterator opcodes, r=djvj.

This commit is contained in:
Brian Hackett 2013-02-12 18:28:42 -07:00
parent 58a7229e6c
commit cbddad4163
2 changed files with 158 additions and 1 deletions

View File

@ -4167,6 +4167,16 @@ DoIteratorMoreFallback(JSContext *cx, ICIteratorMore_Fallback *stub, HandleValue
if (!IteratorMore(cx, &iterValue.toObject(), &cond, res))
return false;
res.setBoolean(cond);
if (iterValue.toObject().isPropertyIterator() && !stub->hasStub(ICStub::IteratorMore_Native)) {
RootedScript script(cx, GetTopIonJSScript(cx));
ICIteratorMore_Native::Compiler compiler(cx);
ICStub *newStub = compiler.getStub(ICStubSpace::StubSpaceFor(script));
if (!newStub)
return false;
stub->addNewStub(newStub);
}
return true;
}
@ -4186,6 +4196,42 @@ ICIteratorMore_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
return tailCallVM(DoIteratorMoreFallbackInfo, masm);
}
//
// IteratorMore_Native
//
bool
ICIteratorMore_Native::Compiler::generateStubCode(MacroAssembler &masm)
{
Label failure;
Register obj = masm.extractObject(R0, ExtractTemp0);
GeneralRegisterSet regs(availableGeneralRegs(1));
Register nativeIterator = regs.takeAny();
Register scratch = regs.takeAny();
masm.branchTestObjClass(Assembler::NotEqual, obj, scratch,
&PropertyIteratorObject::class_, &failure);
masm.loadObjPrivate(obj, JSObject::ITER_CLASS_NFIXED_SLOTS, nativeIterator);
masm.branchTest32(Assembler::NonZero, Address(nativeIterator, offsetof(NativeIterator, flags)),
Imm32(JSITER_FOREACH), &failure);
// Set output to true if props_cursor < props_end.
masm.loadPtr(Address(nativeIterator, offsetof(NativeIterator, props_end)), scratch);
masm.cmpPtr(Address(nativeIterator, offsetof(NativeIterator, props_cursor)), scratch);
masm.emitSet(Assembler::LessThan, scratch);
masm.tagValue(JSVAL_TYPE_BOOLEAN, scratch, R0);
EmitReturnFromIC(masm);
// Failure case - jump to next stub
masm.bind(&failure);
EmitStubGuardFailure(masm);
return true;
}
//
// IteratorNext_Fallback
//
@ -4197,7 +4243,19 @@ DoIteratorNextFallback(JSContext *cx, ICIteratorNext_Fallback *stub, HandleValue
FallbackICSpew(cx, stub, "IteratorNext");
RootedObject iteratorObject(cx, &iterValue.toObject());
return IteratorNext(cx, iteratorObject, res);
if (!IteratorNext(cx, iteratorObject, res))
return false;
if (iteratorObject->isPropertyIterator() && !stub->hasStub(ICStub::IteratorNext_Native)) {
RootedScript script(cx, GetTopIonJSScript(cx));
ICIteratorNext_Native::Compiler compiler(cx);
ICStub *newStub = compiler.getStub(ICStubSpace::StubSpaceFor(script));
if (!newStub)
return false;
stub->addNewStub(newStub);
}
return true;
}
typedef bool (*DoIteratorNextFallbackFn)(JSContext *, ICIteratorNext_Fallback *,
@ -4216,6 +4274,45 @@ ICIteratorNext_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
return tailCallVM(DoIteratorNextFallbackInfo, masm);
}
//
// IteratorNext_Native
//
bool
ICIteratorNext_Native::Compiler::generateStubCode(MacroAssembler &masm)
{
Label failure;
Register obj = masm.extractObject(R0, ExtractTemp0);
GeneralRegisterSet regs(availableGeneralRegs(1));
Register nativeIterator = regs.takeAny();
Register scratch = regs.takeAny();
masm.branchTestObjClass(Assembler::NotEqual, obj, scratch,
&PropertyIteratorObject::class_, &failure);
masm.loadObjPrivate(obj, JSObject::ITER_CLASS_NFIXED_SLOTS, nativeIterator);
masm.branchTest32(Assembler::NonZero, Address(nativeIterator, offsetof(NativeIterator, flags)),
Imm32(JSITER_FOREACH), &failure);
// Get cursor, next string.
masm.loadPtr(Address(nativeIterator, offsetof(NativeIterator, props_cursor)), scratch);
masm.loadPtr(Address(scratch, 0), scratch);
// Increase the cursor.
masm.addPtr(Imm32(sizeof(JSString *)),
Address(nativeIterator, offsetof(NativeIterator, props_cursor)));
masm.tagValue(JSVAL_TYPE_STRING, scratch, R0);
EmitReturnFromIC(masm);
// Failure case - jump to next stub
masm.bind(&failure);
EmitStubGuardFailure(masm);
return true;
}
//
// IteratorClose_Fallback
//

View File

@ -359,7 +359,9 @@ class ICEntry
\
_(IteratorNew_Fallback) \
_(IteratorMore_Fallback) \
_(IteratorMore_Native) \
_(IteratorNext_Fallback) \
_(IteratorNext_Native) \
_(IteratorClose_Fallback) \
\
_(InstanceOf_Fallback) \
@ -3301,6 +3303,35 @@ class ICIteratorMore_Fallback : public ICFallbackStub
};
};
// IC for testing if there are more values in a native iterator.
class ICIteratorMore_Native : public ICStub
{
friend class ICStubSpace;
ICIteratorMore_Native(IonCode *stubCode)
: ICStub(ICStub::IteratorMore_Native, stubCode)
{ }
public:
static inline ICIteratorMore_Native *New(ICStubSpace *space, IonCode *code) {
return space->allocate<ICIteratorMore_Native>(code);
}
class Compiler : public ICStubCompiler {
protected:
bool generateStubCode(MacroAssembler &masm);
public:
Compiler(JSContext *cx)
: ICStubCompiler(cx, ICStub::IteratorMore_Native)
{ }
ICStub *getStub(ICStubSpace *space) {
return ICIteratorMore_Native::New(space, getStubCode());
}
};
};
// IC for getting the next value in an iterator.
class ICIteratorNext_Fallback : public ICFallbackStub
{
@ -3330,6 +3361,35 @@ class ICIteratorNext_Fallback : public ICFallbackStub
};
};
// IC for getting the next value in a native iterator.
class ICIteratorNext_Native : public ICStub
{
friend class ICStubSpace;
ICIteratorNext_Native(IonCode *stubCode)
: ICStub(ICStub::IteratorNext_Native, stubCode)
{ }
public:
static inline ICIteratorNext_Native *New(ICStubSpace *space, IonCode *code) {
return space->allocate<ICIteratorNext_Native>(code);
}
class Compiler : public ICStubCompiler {
protected:
bool generateStubCode(MacroAssembler &masm);
public:
Compiler(JSContext *cx)
: ICStubCompiler(cx, ICStub::IteratorNext_Native)
{ }
ICStub *getStub(ICStubSpace *space) {
return ICIteratorNext_Native::New(space, getStubCode());
}
};
};
// IC for closing an iterator.
class ICIteratorClose_Fallback : public ICFallbackStub
{