зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1363054 part 4 - Attach generalized type monitor stubs for unknown/unknownObject type sets. r=tcampbell
This commit is contained in:
Родитель
b533c4c2ae
Коммит
d290cd9237
|
@ -18,6 +18,7 @@ namespace jit {
|
|||
_(TypeMonitor_SingleObject) \
|
||||
_(TypeMonitor_ObjectGroup) \
|
||||
_(TypeMonitor_PrimitiveSet) \
|
||||
_(TypeMonitor_AnyValue) \
|
||||
\
|
||||
_(TypeUpdate_Fallback) \
|
||||
_(TypeUpdate_SingleObject) \
|
||||
|
|
|
@ -2179,16 +2179,44 @@ ICTypeMonitor_Fallback::addMonitorStubForValue(JSContext* cx, BaselineFrame* fra
|
|||
{
|
||||
MOZ_ASSERT(types);
|
||||
|
||||
bool wasDetachedMonitorChain = lastMonitorStubPtrAddr_ == nullptr;
|
||||
MOZ_ASSERT_IF(wasDetachedMonitorChain, numOptimizedMonitorStubs_ == 0);
|
||||
|
||||
if (numOptimizedMonitorStubs_ >= MAX_OPTIMIZED_STUBS) {
|
||||
// TODO: if the TypeSet becomes unknown or has the AnyObject type,
|
||||
// replace stubs with a single stub to handle these.
|
||||
// Don't attach too many SingleObject/ObjectGroup stubs. If the value is a
|
||||
// primitive or if we will attach an any-object stub, we can handle this
|
||||
// with a single PrimitiveSet or AnyValue stub so we always optimize.
|
||||
if (numOptimizedMonitorStubs_ >= MAX_OPTIMIZED_STUBS &&
|
||||
val.isObject() &&
|
||||
!types->unknownObject())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (val.isPrimitive()) {
|
||||
bool wasDetachedMonitorChain = lastMonitorStubPtrAddr_ == nullptr;
|
||||
MOZ_ASSERT_IF(wasDetachedMonitorChain, numOptimizedMonitorStubs_ == 0);
|
||||
|
||||
if (types->unknown()) {
|
||||
// The TypeSet got marked as unknown so attach a stub that always
|
||||
// succeeds.
|
||||
|
||||
// Check for existing TypeMonitor_AnyValue stubs.
|
||||
for (ICStubConstIterator iter(firstMonitorStub()); !iter.atEnd(); iter++) {
|
||||
if (iter->isTypeMonitor_AnyValue())
|
||||
return true;
|
||||
}
|
||||
|
||||
// Discard existing stubs.
|
||||
resetMonitorStubChain(cx->zone());
|
||||
wasDetachedMonitorChain = (lastMonitorStubPtrAddr_ == nullptr);
|
||||
|
||||
ICTypeMonitor_AnyValue::Compiler compiler(cx);
|
||||
ICStub* stub = compiler.getStub(compiler.getStubSpace(frame->script()));
|
||||
if (!stub) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
|
||||
JitSpew(JitSpew_BaselineIC, " Added TypeMonitor stub %p for any value", stub);
|
||||
addOptimizedMonitorStub(stub);
|
||||
|
||||
} else if (val.isPrimitive() || types->unknownObject()) {
|
||||
if (val.isMagic(JS_UNINITIALIZED_LEXICAL))
|
||||
return true;
|
||||
MOZ_ASSERT(!val.isMagic());
|
||||
|
@ -2204,6 +2232,26 @@ ICTypeMonitor_Fallback::addMonitorStubForValue(JSContext* cx, BaselineFrame* fra
|
|||
}
|
||||
}
|
||||
|
||||
if (val.isObject()) {
|
||||
// Check for existing SingleObject/ObjectGroup stubs and discard
|
||||
// stubs if we find one. Ideally we would discard just these stubs,
|
||||
// but unlinking individual type monitor stubs is somewhat
|
||||
// complicated.
|
||||
MOZ_ASSERT(types->unknownObject());
|
||||
bool hasObjectStubs = false;
|
||||
for (ICStubConstIterator iter(firstMonitorStub()); !iter.atEnd(); iter++) {
|
||||
if (iter->isTypeMonitor_SingleObject() || iter->isTypeMonitor_ObjectGroup()) {
|
||||
hasObjectStubs = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasObjectStubs) {
|
||||
resetMonitorStubChain(cx->zone());
|
||||
wasDetachedMonitorChain = (lastMonitorStubPtrAddr_ == nullptr);
|
||||
existingStub = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ICTypeMonitor_PrimitiveSet::Compiler compiler(cx, existingStub, type);
|
||||
ICStub* stub = existingStub
|
||||
? compiler.updateStub()
|
||||
|
@ -2400,16 +2448,8 @@ ICTypeMonitor_PrimitiveSet::Compiler::generateStubCode(MacroAssembler& masm)
|
|||
if (flags_ & TypeToFlag(JSVAL_TYPE_SYMBOL))
|
||||
masm.branchTestSymbol(Assembler::Equal, R0, &success);
|
||||
|
||||
// Currently, we will never generate primitive stub checks for object. However,
|
||||
// when we do get to the point where we want to collapse our monitor chains of
|
||||
// objects and singletons down (when they get too long) to a generic "any object"
|
||||
// in coordination with the typeset doing the same thing, this will need to
|
||||
// be re-enabled.
|
||||
/*
|
||||
if (flags_ & TypeToFlag(JSVAL_TYPE_OBJECT))
|
||||
masm.branchTestObject(Assembler::Equal, R0, &success);
|
||||
*/
|
||||
MOZ_ASSERT(!(flags_ & TypeToFlag(JSVAL_TYPE_OBJECT)));
|
||||
|
||||
if (flags_ & TypeToFlag(JSVAL_TYPE_NULL))
|
||||
masm.branchTestNull(Assembler::Equal, R0, &success);
|
||||
|
@ -2480,6 +2520,13 @@ ICTypeMonitor_ObjectGroup::Compiler::generateStubCode(MacroAssembler& masm)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ICTypeMonitor_AnyValue::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
{
|
||||
EmitReturnFromIC(masm);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ICUpdatedStub::addUpdateStubForValue(JSContext* cx, HandleScript outerScript, HandleObject obj,
|
||||
HandleId id, HandleValue val)
|
||||
|
|
|
@ -1605,6 +1605,29 @@ class ICTypeMonitor_ObjectGroup : public ICStub
|
|||
};
|
||||
};
|
||||
|
||||
class ICTypeMonitor_AnyValue : public ICStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
explicit ICTypeMonitor_AnyValue(JitCode* stubCode)
|
||||
: ICStub(TypeMonitor_AnyValue, stubCode)
|
||||
{}
|
||||
|
||||
public:
|
||||
class Compiler : public ICStubCompiler {
|
||||
protected:
|
||||
MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm);
|
||||
|
||||
public:
|
||||
explicit Compiler(JSContext* cx)
|
||||
: ICStubCompiler(cx, TypeMonitor_AnyValue, Engine::Baseline)
|
||||
{ }
|
||||
|
||||
ICTypeMonitor_AnyValue* getStub(ICStubSpace* space) {
|
||||
return newStub<ICTypeMonitor_AnyValue>(space, getStubCode());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// BinaryArith
|
||||
// JSOP_ADD, JSOP_SUB, JSOP_MUL, JOP_DIV, JSOP_MOD
|
||||
|
|
Загрузка…
Ссылка в новой задаче