mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 15:23:51 +00:00
Back out 41607c9f0d26 (bug 900849) on suspicion of making Gu interval_tree_test.js time out
CLOSED TREE
This commit is contained in:
parent
6334294144
commit
62d8506443
@ -722,14 +722,9 @@ CodeGenerator::visitFunctionDispatch(LFunctionDispatch *lir)
|
||||
// Compare function pointers, except for the last case.
|
||||
for (size_t i = 0; i < casesWithFallback - 1; i++) {
|
||||
MOZ_ASSERT(i < mir->numCases());
|
||||
LBlock *target = skipTrivialBlocks(mir->getCaseBlock(i))->lir();
|
||||
JSFunction *func = mir->getCase(i);
|
||||
if (types::TypeObject *funcType = mir->getCaseTypeObject(i)) {
|
||||
masm.branchPtr(Assembler::Equal, Address(input, JSObject::offsetOfType()),
|
||||
ImmGCPtr(funcType), target->label());
|
||||
} else {
|
||||
masm.branchPtr(Assembler::Equal, input, ImmGCPtr(func), target->label());
|
||||
}
|
||||
LBlock *target = skipTrivialBlocks(mir->getCaseBlock(i))->lir();
|
||||
masm.branchPtr(Assembler::Equal, input, ImmGCPtr(func), target->label());
|
||||
}
|
||||
|
||||
// Jump to the last case.
|
||||
|
@ -271,9 +271,11 @@ IonBuilder::getSingleCallTarget(types::TemporaryTypeSet *calleeTypes)
|
||||
|
||||
bool
|
||||
IonBuilder::getPolyCallTargets(types::TemporaryTypeSet *calleeTypes, bool constructing,
|
||||
ObjectVector &targets, uint32_t maxTargets)
|
||||
ObjectVector &targets, uint32_t maxTargets, bool *gotLambda)
|
||||
{
|
||||
MOZ_ASSERT(targets.empty());
|
||||
MOZ_ASSERT(gotLambda);
|
||||
*gotLambda = false;
|
||||
|
||||
if (!calleeTypes)
|
||||
return true;
|
||||
@ -288,11 +290,9 @@ IonBuilder::getPolyCallTargets(types::TemporaryTypeSet *calleeTypes, bool constr
|
||||
|
||||
if (!targets.reserve(objCount))
|
||||
return false;
|
||||
for (unsigned i = 0; i < objCount; i++) {
|
||||
for(unsigned i = 0; i < objCount; i++) {
|
||||
JSObject *obj = calleeTypes->getSingleObject(i);
|
||||
if (obj) {
|
||||
MOZ_ASSERT(obj->hasSingletonType());
|
||||
} else {
|
||||
if (!obj) {
|
||||
types::TypeObject *typeObj = calleeTypes->getTypeObject(i);
|
||||
if (!typeObj)
|
||||
continue;
|
||||
@ -303,7 +303,7 @@ IonBuilder::getPolyCallTargets(types::TemporaryTypeSet *calleeTypes, bool constr
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!obj->hasSingletonType());
|
||||
*gotLambda = true;
|
||||
}
|
||||
|
||||
// Don't optimize if the callee is not callable or constructable per
|
||||
@ -317,6 +317,10 @@ IonBuilder::getPolyCallTargets(types::TemporaryTypeSet *calleeTypes, bool constr
|
||||
targets.infallibleAppend(obj);
|
||||
}
|
||||
|
||||
// For now, only inline "singleton" lambda calls
|
||||
if (*gotLambda && targets.length() > 1)
|
||||
targets.clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -4829,7 +4833,7 @@ IonBuilder::inlineSingleCall(CallInfo &callInfo, JSObject *targetArg)
|
||||
|
||||
IonBuilder::InliningStatus
|
||||
IonBuilder::inlineCallsite(const ObjectVector &targets, ObjectVector &originals,
|
||||
CallInfo &callInfo)
|
||||
bool lambda, CallInfo &callInfo)
|
||||
{
|
||||
if (targets.empty())
|
||||
return InliningStatus_NotInlined;
|
||||
@ -4864,7 +4868,7 @@ IonBuilder::inlineCallsite(const ObjectVector &targets, ObjectVector &originals,
|
||||
// If the callee is not going to be a lambda (which may vary across
|
||||
// different invocations), then the callee definition can be replaced by a
|
||||
// constant.
|
||||
if (target->hasSingletonType()) {
|
||||
if (!lambda) {
|
||||
// Replace the function with an MConstant.
|
||||
MConstant *constFun = constant(ObjectValue(*target));
|
||||
callInfo.setFun(constFun);
|
||||
@ -5107,25 +5111,21 @@ IonBuilder::inlineCalls(CallInfo &callInfo, const ObjectVector &targets,
|
||||
return false;
|
||||
|
||||
// Create a function MConstant to use in the entry ResumePoint.
|
||||
MConstant *funcDef = nullptr;
|
||||
if (target->hasSingletonType()) {
|
||||
funcDef = MConstant::New(alloc(), ObjectValue(*target), constraints());
|
||||
funcDef->setImplicitlyUsedUnchecked();
|
||||
dispatchBlock->add(funcDef);
|
||||
MConstant *funcDef = MConstant::New(alloc(), ObjectValue(*target), constraints());
|
||||
funcDef->setImplicitlyUsedUnchecked();
|
||||
dispatchBlock->add(funcDef);
|
||||
|
||||
// Use the MConstant in the inline resume point and on stack.
|
||||
int funIndex = inlineBlock->entryResumePoint()->stackDepth() - callInfo.numFormals();
|
||||
inlineBlock->entryResumePoint()->replaceOperand(funIndex, funcDef);
|
||||
inlineBlock->rewriteSlot(funIndex, funcDef);
|
||||
}
|
||||
// Use the MConstant in the inline resume point and on stack.
|
||||
int funIndex = inlineBlock->entryResumePoint()->stackDepth() - callInfo.numFormals();
|
||||
inlineBlock->entryResumePoint()->replaceOperand(funIndex, funcDef);
|
||||
inlineBlock->rewriteSlot(funIndex, funcDef);
|
||||
|
||||
// Create a new CallInfo to track modified state within the inline block.
|
||||
CallInfo inlineInfo(alloc(), callInfo.constructing());
|
||||
if (!inlineInfo.init(callInfo))
|
||||
return false;
|
||||
inlineInfo.popFormals(inlineBlock);
|
||||
if (funcDef)
|
||||
inlineInfo.setFun(funcDef);
|
||||
inlineInfo.setFun(funcDef);
|
||||
|
||||
if (maybeCache) {
|
||||
MOZ_ASSERT(callInfo.thisArg() == maybeCache->object());
|
||||
@ -5160,8 +5160,7 @@ IonBuilder::inlineCalls(CallInfo &callInfo, const ObjectVector &targets,
|
||||
//
|
||||
// Note that guarding is on the original function pointer even
|
||||
// if there is a clone, since cloning occurs at the callsite.
|
||||
types::TypeObject *funType = original->hasSingletonType() ? nullptr : original->type();
|
||||
dispatch->addCase(original, funType, inlineBlock);
|
||||
dispatch->addCase(original, inlineBlock);
|
||||
|
||||
MDefinition *retVal = inlineReturnBlock->peek(-1);
|
||||
retPhi->addInput(retVal);
|
||||
@ -5212,11 +5211,8 @@ IonBuilder::inlineCalls(CallInfo &callInfo, const ObjectVector &targets,
|
||||
MOZ_ASSERT(!remaining);
|
||||
|
||||
if (targets[i]->is<JSFunction>()) {
|
||||
JSFunction *target = &targets[i]->as<JSFunction>();
|
||||
if (target->hasSingletonType()) {
|
||||
remaining = target;
|
||||
clonedAtCallsite = target != originals[i];
|
||||
}
|
||||
remaining = &targets[i]->as<JSFunction>();
|
||||
clonedAtCallsite = targets[i] != originals[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -5645,9 +5641,13 @@ IonBuilder::jsop_call(uint32_t argc, bool constructing)
|
||||
|
||||
// Acquire known call target if existent.
|
||||
ObjectVector originals(alloc());
|
||||
bool gotLambda = false;
|
||||
types::TemporaryTypeSet *calleeTypes = current->peek(calleeDepth)->resultTypeSet();
|
||||
if (calleeTypes && !getPolyCallTargets(calleeTypes, constructing, originals, 4))
|
||||
return false;
|
||||
if (calleeTypes) {
|
||||
if (!getPolyCallTargets(calleeTypes, constructing, originals, 4, &gotLambda))
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT_IF(gotLambda, originals.length() <= 1);
|
||||
|
||||
// If any call targets need to be cloned, look for existing clones to use.
|
||||
// Keep track of the originals as we need to case on them for poly inline.
|
||||
@ -5676,7 +5676,7 @@ IonBuilder::jsop_call(uint32_t argc, bool constructing)
|
||||
return false;
|
||||
|
||||
// Try inlining
|
||||
InliningStatus status = inlineCallsite(targets, originals, callInfo);
|
||||
InliningStatus status = inlineCallsite(targets, originals, gotLambda, callInfo);
|
||||
if (status == InliningStatus_Inlined)
|
||||
return true;
|
||||
if (status == InliningStatus_Error)
|
||||
|
@ -238,7 +238,7 @@ class IonBuilder
|
||||
|
||||
JSFunction *getSingleCallTarget(types::TemporaryTypeSet *calleeTypes);
|
||||
bool getPolyCallTargets(types::TemporaryTypeSet *calleeTypes, bool constructing,
|
||||
ObjectVector &targets, uint32_t maxTargets);
|
||||
ObjectVector &targets, uint32_t maxTargets, bool *gotLambda);
|
||||
|
||||
void popCfgStack();
|
||||
DeferredEdge *filterDeadDeferredEdges(DeferredEdge *edge);
|
||||
@ -817,7 +817,7 @@ class IonBuilder
|
||||
|
||||
// Call functions
|
||||
InliningStatus inlineCallsite(const ObjectVector &targets, ObjectVector &originals,
|
||||
CallInfo &callInfo);
|
||||
bool lambda, CallInfo &callInfo);
|
||||
bool inlineCalls(CallInfo &callInfo, const ObjectVector &targets, ObjectVector &originals,
|
||||
BoolVector &choiceSet, MGetPropertyCache *maybeCache);
|
||||
|
||||
|
@ -9384,14 +9384,10 @@ class MDispatchInstruction
|
||||
// Map from JSFunction* -> MBasicBlock.
|
||||
struct Entry {
|
||||
JSFunction *func;
|
||||
// If |func| has a singleton type, |funcType| is null. Otherwise,
|
||||
// |funcType| holds the TypeObject for |func|, and dispatch guards
|
||||
// on the type instead of directly on the function.
|
||||
types::TypeObject *funcType;
|
||||
MBasicBlock *block;
|
||||
|
||||
Entry(JSFunction *func, types::TypeObject *funcType, MBasicBlock *block)
|
||||
: func(func), funcType(funcType), block(block)
|
||||
Entry(JSFunction *func, MBasicBlock *block)
|
||||
: func(func), block(block)
|
||||
{ }
|
||||
};
|
||||
Vector<Entry, 4, JitAllocPolicy> map_;
|
||||
@ -9459,8 +9455,8 @@ class MDispatchInstruction
|
||||
}
|
||||
|
||||
public:
|
||||
void addCase(JSFunction *func, types::TypeObject *funcType, MBasicBlock *block) {
|
||||
map_.append(Entry(func, funcType, block));
|
||||
void addCase(JSFunction *func, MBasicBlock *block) {
|
||||
map_.append(Entry(func, block));
|
||||
}
|
||||
uint32_t numCases() const {
|
||||
return map_.length();
|
||||
@ -9468,9 +9464,6 @@ class MDispatchInstruction
|
||||
JSFunction *getCase(uint32_t i) const {
|
||||
return map_[i].func;
|
||||
}
|
||||
types::TypeObject *getCaseTypeObject(uint32_t i) const {
|
||||
return map_[i].funcType;
|
||||
}
|
||||
MBasicBlock *getCaseBlock(uint32_t i) const {
|
||||
return map_[i].block;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user