mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-17 14:25:49 +00:00
Bug 1093573 part 15 - Add and optimize IsSuspendedStarGenerator. r=wingo
This commit is contained in:
parent
45f6e7dcb0
commit
5f60319597
@ -3,14 +3,20 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function StarGeneratorNext(val) {
|
||||
if (!IsObject(this) || !IsStarGeneratorObject(this))
|
||||
return callFunction(CallStarGeneratorMethodIfWrapped, this, val, "StarGeneratorNext");
|
||||
// The IsSuspendedStarGenerator call below is not necessary for
|
||||
// correctness. It's a performance optimization to check for the
|
||||
// common case with a single call. It's also inlined in Baseline.
|
||||
|
||||
if (StarGeneratorObjectIsClosed(this))
|
||||
return { value: undefined, done: true };
|
||||
if (!IsSuspendedStarGenerator(this)) {
|
||||
if (!IsObject(this) || !IsStarGeneratorObject(this))
|
||||
return callFunction(CallStarGeneratorMethodIfWrapped, this, val, "StarGeneratorNext");
|
||||
|
||||
if (GeneratorIsRunning(this))
|
||||
ThrowError(JSMSG_NESTING_GENERATOR);
|
||||
if (StarGeneratorObjectIsClosed(this))
|
||||
return { value: undefined, done: true };
|
||||
|
||||
if (GeneratorIsRunning(this))
|
||||
ThrowError(JSMSG_NESTING_GENERATOR);
|
||||
}
|
||||
|
||||
try {
|
||||
return resumeGenerator(this, val, 'next');
|
||||
@ -22,14 +28,16 @@ function StarGeneratorNext(val) {
|
||||
}
|
||||
|
||||
function StarGeneratorThrow(val) {
|
||||
if (!IsObject(this) || !IsStarGeneratorObject(this))
|
||||
return callFunction(CallStarGeneratorMethodIfWrapped, this, val, "StarGeneratorThrow");
|
||||
if (!IsSuspendedStarGenerator(this)) {
|
||||
if (!IsObject(this) || !IsStarGeneratorObject(this))
|
||||
return callFunction(CallStarGeneratorMethodIfWrapped, this, val, "StarGeneratorThrow");
|
||||
|
||||
if (StarGeneratorObjectIsClosed(this))
|
||||
throw val;
|
||||
if (StarGeneratorObjectIsClosed(this))
|
||||
throw val;
|
||||
|
||||
if (GeneratorIsRunning(this))
|
||||
ThrowError(JSMSG_NESTING_GENERATOR);
|
||||
if (GeneratorIsRunning(this))
|
||||
ThrowError(JSMSG_NESTING_GENERATOR);
|
||||
}
|
||||
|
||||
try {
|
||||
return resumeGenerator(this, val, 'throw');
|
||||
|
@ -2151,9 +2151,12 @@ BaselineCompiler::emit_JSOP_GETALIASEDVAR()
|
||||
Address address = getScopeCoordinateAddress(R0.scratchReg());
|
||||
masm.loadValue(address, R0);
|
||||
|
||||
ICTypeMonitor_Fallback::Compiler compiler(cx, (ICMonitoredFallbackStub *) nullptr);
|
||||
if (!emitOpIC(compiler.getStub(&stubSpace_)))
|
||||
return false;
|
||||
if (ionCompileable_) {
|
||||
// No need to monitor types if we know Ion can't compile this script.
|
||||
ICTypeMonitor_Fallback::Compiler compiler(cx, (ICMonitoredFallbackStub *) nullptr);
|
||||
if (!emitOpIC(compiler.getStub(&stubSpace_)))
|
||||
return false;
|
||||
}
|
||||
|
||||
frame.push(R0);
|
||||
return true;
|
||||
|
@ -8817,6 +8817,20 @@ TryAttachCallStub(JSContext *cx, ICCall_Fallback *stub, HandleScript script, jsb
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fun->native() == intrinsic_IsSuspendedStarGenerator) {
|
||||
// This intrinsic only appears in self-hosted code.
|
||||
MOZ_ASSERT(argc == 1);
|
||||
JitSpew(JitSpew_BaselineIC, " Generating Call_IsSuspendedStarGenerator stub");
|
||||
|
||||
ICCall_IsSuspendedStarGenerator::Compiler compiler(cx);
|
||||
ICStub *newStub = compiler.getStub(compiler.getStubSpace(script));
|
||||
if (!newStub)
|
||||
return false;
|
||||
|
||||
stub->addNewStub(newStub);
|
||||
return true;
|
||||
}
|
||||
|
||||
RootedNativeObject templateObject(cx);
|
||||
if (MOZ_LIKELY(!isSpread)) {
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
@ -9770,6 +9784,48 @@ ICCall_StringSplit::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ICCall_IsSuspendedStarGenerator::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
// The IsSuspendedStarGenerator intrinsic is only called in self-hosted
|
||||
// code, so it's safe to assume we have a single argument and the callee
|
||||
// is our intrinsic.
|
||||
|
||||
GeneralRegisterSet regs = availableGeneralRegs(0);
|
||||
|
||||
// Load the argument.
|
||||
Address argAddr(BaselineStackReg, ICStackValueOffset);
|
||||
ValueOperand argVal = regs.takeAnyValue();
|
||||
masm.loadValue(argAddr, argVal);
|
||||
|
||||
// Check if it's an object.
|
||||
Label returnFalse;
|
||||
Register genObj = regs.takeAny();
|
||||
masm.branchTestObject(Assembler::NotEqual, argVal, &returnFalse);
|
||||
masm.unboxObject(argVal, genObj);
|
||||
|
||||
// Check if it's a StarGeneratorObject.
|
||||
Register scratch = regs.takeAny();
|
||||
masm.branchTestObjClass(Assembler::NotEqual, genObj, scratch, &StarGeneratorObject::class_,
|
||||
&returnFalse);
|
||||
|
||||
// If the yield index slot holds an int32 value < YIELD_INDEX_CLOSING,
|
||||
// the generator is suspended.
|
||||
masm.loadValue(Address(genObj, GeneratorObject::offsetOfYieldIndexSlot()), argVal);
|
||||
masm.branchTestInt32(Assembler::NotEqual, argVal, &returnFalse);
|
||||
masm.unboxInt32(argVal, scratch);
|
||||
masm.branch32(Assembler::AboveOrEqual, scratch, Imm32(StarGeneratorObject::YIELD_INDEX_CLOSING),
|
||||
&returnFalse);
|
||||
|
||||
masm.moveValue(BooleanValue(true), R0);
|
||||
EmitReturnFromIC(masm);
|
||||
|
||||
masm.bind(&returnFalse);
|
||||
masm.moveValue(BooleanValue(false), R0);
|
||||
EmitReturnFromIC(masm);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ICCall_Native::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
|
@ -380,6 +380,7 @@ class ICEntry
|
||||
_(Call_ScriptedApplyArguments) \
|
||||
_(Call_ScriptedFunCall) \
|
||||
_(Call_StringSplit) \
|
||||
_(Call_IsSuspendedStarGenerator) \
|
||||
\
|
||||
_(GetElem_Fallback) \
|
||||
_(GetElem_NativeSlot) \
|
||||
@ -6237,6 +6238,36 @@ class ICCall_StringSplit : public ICMonitoredStub
|
||||
};
|
||||
};
|
||||
|
||||
class ICCall_IsSuspendedStarGenerator : public ICStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
protected:
|
||||
explicit ICCall_IsSuspendedStarGenerator(JitCode *stubCode)
|
||||
: ICStub(ICStub::Call_IsSuspendedStarGenerator, stubCode)
|
||||
{}
|
||||
|
||||
public:
|
||||
static inline ICCall_IsSuspendedStarGenerator *New(ICStubSpace *space, JitCode *code) {
|
||||
if (!code)
|
||||
return nullptr;
|
||||
return space->allocate<ICCall_IsSuspendedStarGenerator>(code);
|
||||
}
|
||||
|
||||
class Compiler : public ICStubCompiler {
|
||||
protected:
|
||||
bool generateStubCode(MacroAssembler &masm);
|
||||
|
||||
public:
|
||||
explicit Compiler(JSContext *cx)
|
||||
: ICStubCompiler(cx, ICStub::Call_IsSuspendedStarGenerator)
|
||||
{}
|
||||
ICStub *getStub(ICStubSpace *space) {
|
||||
return ICCall_IsSuspendedStarGenerator::New(space, getStubCode());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Stub for performing a TableSwitch, updating the IC's return address to jump
|
||||
// to whatever point the switch is branching to.
|
||||
class ICTableSwitch : public ICStub
|
||||
|
@ -978,6 +978,8 @@ bool intrinsic_ObjectIsTypeDescr(JSContext *cx, unsigned argc, Value *vp);
|
||||
bool intrinsic_TypeDescrIsSimpleType(JSContext *cx, unsigned argc, Value *vp);
|
||||
bool intrinsic_TypeDescrIsArrayType(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
bool intrinsic_IsSuspendedStarGenerator(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
class AutoLockForExclusiveAccess
|
||||
{
|
||||
JSRuntime *runtime;
|
||||
|
@ -136,8 +136,12 @@ class GeneratorObject : public NativeObject
|
||||
return getFixedSlot(YIELD_INDEX_SLOT).toInt32() == YIELD_INDEX_CLOSING;
|
||||
}
|
||||
bool isSuspended() const {
|
||||
// Note: also update Baseline's IsSuspendedStarGenerator code if this
|
||||
// changes.
|
||||
MOZ_ASSERT(!isClosed());
|
||||
return !isRunning() && !isClosing();
|
||||
static_assert(YIELD_INDEX_CLOSING < YIELD_INDEX_RUNNING,
|
||||
"test below should return false for YIELD_INDEX_RUNNING");
|
||||
return getFixedSlot(YIELD_INDEX_SLOT).toInt32() < YIELD_INDEX_CLOSING;
|
||||
}
|
||||
void setRunning() {
|
||||
MOZ_ASSERT(isSuspended());
|
||||
|
@ -681,6 +681,22 @@ intrinsic_StarGeneratorObjectIsClosed(JSContext *cx, unsigned argc, Value *vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::intrinsic_IsSuspendedStarGenerator(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
MOZ_ASSERT(args.length() == 1);
|
||||
|
||||
if (!args[0].isObject() || !args[0].toObject().is<StarGeneratorObject>()) {
|
||||
args.rval().setBoolean(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
StarGeneratorObject &genObj = args[0].toObject().as<StarGeneratorObject>();
|
||||
args.rval().setBoolean(!genObj.isClosed() && genObj.isSuspended());
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
intrinsic_IsLegacyGeneratorObject(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
@ -1035,6 +1051,7 @@ static const JSFunctionSpec intrinsic_functions[] = {
|
||||
|
||||
JS_FN("IsStarGeneratorObject", intrinsic_IsStarGeneratorObject, 1,0),
|
||||
JS_FN("StarGeneratorObjectIsClosed", intrinsic_StarGeneratorObjectIsClosed, 1,0),
|
||||
JS_FN("IsSuspendedStarGenerator",intrinsic_IsSuspendedStarGenerator,1,0),
|
||||
|
||||
JS_FN("IsLegacyGeneratorObject", intrinsic_IsLegacyGeneratorObject, 1,0),
|
||||
JS_FN("LegacyGeneratorObjectIsClosed", intrinsic_LegacyGeneratorObjectIsClosed, 1,0),
|
||||
|
Loading…
x
Reference in New Issue
Block a user