Bug 826148 - Part 2: TI changes (r=bhackett)

This commit is contained in:
Shu-yu Guo 2013-01-10 13:04:04 -08:00
parent a6c1c544da
commit 6cd8e01d43

View File

@ -689,6 +689,7 @@ class TypeConstraintCall : public TypeConstraint
const char *kind() { return "call"; }
void newType(JSContext *cx, TypeSet *source, Type type);
bool newCallee(JSContext *cx, HandleFunction callee, HandleScript script);
};
void
@ -772,6 +773,7 @@ class TypeConstraintPropagateThis : public TypeConstraint
const char *kind() { return "propagatethis"; }
void newType(JSContext *cx, TypeSet *source, Type type);
bool newCallee(JSContext *cx, HandleFunction callee);
};
void
@ -1256,6 +1258,23 @@ TypeConstraintSetElement::newType(JSContext *cx, TypeSet *source, Type type)
}
}
static inline RawFunction
CloneCallee(JSContext *cx, HandleFunction fun, HandleScript script, jsbytecode *pc)
{
/*
* Clone called functions at appropriate callsites to match interpreter
* behavior.
*/
RawFunction callee = CloneFunctionAtCallsite(cx, fun, script, pc);
if (!callee)
return NULL;
InferSpew(ISpewOps, "callsiteCloneType: #%u:%05u: %s",
script->id(), pc - script->code, TypeString(Type::ObjectType(callee)));
return callee;
}
void
TypeConstraintCall::newType(JSContext *cx, TypeSet *source, Type type)
{
@ -1348,11 +1367,30 @@ TypeConstraintCall::newType(JSContext *cx, TypeSet *source, Type type)
return;
}
RootedScript calleeScript(cx, JSFunction::getOrCreateScript(cx, callee));
if (!calleeScript)
if (callee->isInterpretedLazy() && !JSFunction::getOrCreateScript(cx, callee))
return;
/*
* As callsite cloning is a hint, we must propagate to both the original
* and the clone.
*/
if (callee->isCloneAtCallsite()) {
RootedFunction clone(cx, CloneCallee(cx, callee, script, pc));
if (!clone)
return;
if (!newCallee(cx, clone, script))
return;
}
newCallee(cx, callee, script);
}
bool
TypeConstraintCall::newCallee(JSContext *cx, HandleFunction callee, HandleScript script)
{
RootedScript calleeScript(cx, callee->nonLazyScript());
if (!calleeScript->ensureHasTypes(cx))
return;
return false;
unsigned nargs = callee->nargs;
@ -1360,7 +1398,7 @@ TypeConstraintCall::newType(JSContext *cx, TypeSet *source, Type type)
for (unsigned i = 0; i < callsite->argumentCount && i < nargs; i++) {
StackTypeSet *argTypes = callsite->argumentTypes[i];
StackTypeSet *types = TypeScript::ArgTypes(calleeScript, i);
argTypes->addSubsetBarrier(cx, script, pc, types);
argTypes->addSubsetBarrier(cx, script, callsite->pc, types);
}
/* Add void type for any formals in the callee not supplied at the call site. */
@ -1392,6 +1430,8 @@ TypeConstraintCall::newType(JSContext *cx, TypeSet *source, Type type)
*/
returnTypes->addSubset(cx, callsite->returnTypes);
}
return true;
}
void
@ -1399,6 +1439,7 @@ TypeConstraintPropagateThis::newType(JSContext *cx, TypeSet *source, Type type)
{
AssertCanGC();
RootedScript script(cx, script_);
if (type.isUnknown() || type.isAnyObject()) {
/*
* The callee is unknown, make sure the call is monitored so we pick up
@ -1406,7 +1447,6 @@ TypeConstraintPropagateThis::newType(JSContext *cx, TypeSet *source, Type type)
* CALLPROP, for other calls we are past the type barrier and a
* TypeConstraintCall will also monitor the call.
*/
RootedScript script(cx, script_);
cx->compartment->types.monitorBytecode(cx, script, callpc - script->code);
return;
}
@ -1429,14 +1469,37 @@ TypeConstraintPropagateThis::newType(JSContext *cx, TypeSet *source, Type type)
return;
}
if (!(JSFunction::getOrCreateScript(cx, callee) && callee->nonLazyScript()->ensureHasTypes(cx)))
if (callee->isInterpretedLazy() && !JSFunction::getOrCreateScript(cx, callee))
return;
/*
* As callsite cloning is a hint, we must propagate to both the original
* and the clone.
*/
if (callee->isCloneAtCallsite()) {
RootedFunction clone(cx, CloneCallee(cx, callee, script, callpc));
if (!clone)
return;
if (!newCallee(cx, clone))
return;
}
newCallee(cx, callee);
}
bool
TypeConstraintPropagateThis::newCallee(JSContext *cx, HandleFunction callee)
{
if (!callee->nonLazyScript()->ensureHasTypes(cx))
return false;
TypeSet *thisTypes = TypeScript::ThisTypes(callee->nonLazyScript());
if (this->types)
this->types->addSubset(cx, thisTypes);
else
thisTypes->addType(cx, this->type);
return true;
}
void