Back out 41607c9f0d26 (bug 900849) on suspicion of making Gu interval_tree_test.js time out

CLOSED TREE
This commit is contained in:
Phil Ringnalda 2015-01-17 10:03:16 -08:00
parent 6334294144
commit 62d8506443
4 changed files with 38 additions and 50 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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);

View File

@ -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;
}