Back out e6f337d218b4 (bug 768288) for bug648747.js jit-test failures

CLOSED TREE
This commit is contained in:
Phil Ringnalda 2013-04-15 12:22:31 -07:00
parent 3bced0e559
commit c4a632f701
5 changed files with 36 additions and 90 deletions

View File

@ -202,8 +202,7 @@ IonBuilder::canInlineTarget(JSFunction *target, CallInfo &callInfo)
RootedScript inlineScript(cx, target->nonLazyScript());
ExecutionMode executionMode = info().executionMode();
if (!CanIonCompile(inlineScript, executionMode)) {
IonSpew(IonSpew_Inlining, "%s:%d Cannot inline due to disable Ion compilation",
inlineScript->filename(), inlineScript->lineno);
IonSpew(IonSpew_Inlining, "Cannot inline due to disable Ion compilation");
return false;
}
@ -212,8 +211,7 @@ IonBuilder::canInlineTarget(JSFunction *target, CallInfo &callInfo)
ion::IsBaselineEnabled(cx) &&
!inlineScript->hasBaselineScript())
{
IonSpew(IonSpew_Inlining, "%s:%d Cannot inline target with no baseline jitcode",
inlineScript->filename(), inlineScript->lineno);
IonSpew(IonSpew_Inlining, "Cannot inline target with no baseline jitcode");
return false;
}
@ -221,8 +219,7 @@ IonBuilder::canInlineTarget(JSFunction *target, CallInfo &callInfo)
IonBuilder *builder = callerBuilder_;
while (builder) {
if (builder->script() == inlineScript) {
IonSpew(IonSpew_Inlining, "%s:%d Not inlining recursive call",
inlineScript->filename(), inlineScript->lineno);
IonSpew(IonSpew_Inlining, "Not inlining recursive call");
return false;
}
builder = builder->callerBuilder_;
@ -231,15 +228,12 @@ IonBuilder::canInlineTarget(JSFunction *target, CallInfo &callInfo)
RootedScript callerScript(cx, script());
if (!oracle->canEnterInlinedFunction(target)) {
IonSpew(IonSpew_Inlining, "%s:%d Cannot inline due to oracle veto %d",
inlineScript->filename(), inlineScript->lineno,
script()->lineno);
IonSpew(IonSpew_Inlining, "Cannot inline due to oracle veto %d", script()->lineno);
return false;
}
if (!oracle->callReturnTypeSetMatches(callerScript, pc, target)) {
IonSpew(IonSpew_Inlining, "%s:%d Cannot inline due to return typeset mismatch",
inlineScript->filename(), inlineScript->lineno);
IonSpew(IonSpew_Inlining, "Cannot inline due to return typeset mismatch");
return false;
}
@ -248,8 +242,7 @@ IonBuilder::canInlineTarget(JSFunction *target, CallInfo &callInfo)
// For constructing calls the typeset of caller should intersect the callee's typeset.
// Except for the |this| type, because that is created during execution depending on target.
if (!oracle->callArgsTypeSetIntersects(NULL, callInfo.argvType(), target)) {
IonSpew(IonSpew_Inlining, "%s:%d Cannot inline due to arguments typeset mismatch",
inlineScript->filename(), inlineScript->lineno);
IonSpew(IonSpew_Inlining, "Cannot inline due to arguments typeset mismatch");
return false;
}
} else if (JSOp(*pc) == JSOP_FUNAPPLY) {
@ -258,25 +251,18 @@ IonBuilder::canInlineTarget(JSFunction *target, CallInfo &callInfo)
// of fun.apply. Seeing a new type will only be noticed in the inlined call and
// result in missed types in TI.
if (!oracle->callArgsTypeSetMatches(callInfo.thisType(), callInfo.argvType(), target)) {
IonSpew(IonSpew_Inlining, "%s:%d Cannot inline due to arguments typeset mismatch",
inlineScript->filename(), inlineScript->lineno);
IonSpew(IonSpew_Inlining, "Cannot inline due to arguments typeset mismatch");
return false;
}
} else {
// For normal calls the typeset of caller should intersect the callee's typeset.
if (!oracle->callArgsTypeSetIntersects(callInfo.thisType(), callInfo.argvType(), target)) {
IonSpew(IonSpew_Inlining, "%s:%d Cannot inline due to arguments typeset mismatch",
inlineScript->filename(), inlineScript->lineno);
IonSpew(IonSpew_Inlining, "Cannot inline due to arguments typeset mismatch");
return false;
}
}
if (inlineScript->hasIonScript() && inlineScript->ionScript()->bailoutExpected()) {
IonSpew(IonSpew_Inlining, "%s:%d Cannot inline due to known bailing script",
inlineScript->filename(), inlineScript->lineno);
return false;
}
IonSpew(IonSpew_Inlining, "Inlining good to go!");
return true;
}
@ -3239,17 +3225,24 @@ IonBuilder::makeInliningDecision(JSFunction *target, CallInfo &callInfo)
// Heuristics!
IonBuilder *baseBuilder = this;
while (baseBuilder->callerBuilder_)
baseBuilder = baseBuilder->callerBuilder_;
// Cap the inlining depth.
if (IsSmallFunction(targetScript)) {
if (inliningDepth_ >= js_IonOptions.smallFunctionMaxInlineDepth) {
IonSpew(IonSpew_Inlining, "%s:%d - Vetoed: exceeding allowed inline depth",
targetScript->filename(), targetScript->lineno);
return false;
}
} else {
if (inliningDepth_ >= js_IonOptions.maxInlineDepth) {
IonSpew(IonSpew_Inlining, "%s:%d - Vetoed: exceeding allowed inline depth",
targetScript->filename(), targetScript->lineno);
return false;
}
}
// When caller is excessively large only inline small functions.
if (script()->length > js_IonOptions.inlineMaxTotalBytecodeLength &&
!IsSmallFunction(targetScript)) {
IonSpew(IonSpew_Inlining, "%s:%d - Vetoed: caller excessively large.",
targetScript->filename(), targetScript->lineno);
return false;
}
// Always inline the empty script up to the inlining depth.
if (targetScript->length == 1)
return true;
// Callee must not be excessively large.
// This heuristic also applies to the callsite as a whole.
@ -3274,36 +3267,6 @@ IonBuilder::makeInliningDecision(JSFunction *target, CallInfo &callInfo)
return false;
}
// Cap the inlining depth.
uint32_t scriptMaxInlineDepth = targetScript->maxInlineDepth();
uint32_t globalMaxInlineDepth = js_IonOptions.maxInlineDepth;
if (IsSmallFunction(targetScript))
globalMaxInlineDepth = js_IonOptions.smallFunctionMaxInlineDepth;
// Cap the global inline depth.
if (inliningDepth_ >= globalMaxInlineDepth) {
IonSpew(IonSpew_Inlining, "%s:%d - Vetoed: exceeding global inline depth",
targetScript->filename(), targetScript->lineno);
baseBuilder->script()->disableInlineDepthCheck();
return false;
}
// Cap on scripts inline depth.
if (inliningDepth_ >= scriptMaxInlineDepth)
{
IonSpew(IonSpew_Inlining, "%s:%d - Vetoed: exceeding script inline depth.",
targetScript->filename(), targetScript->lineno);
return false;
}
// Update scripts max inline depth
// I.e. make sure that all known scripts that get inlined by this script still get inlined.
if (!baseBuilder->script()->isInlineDepthCheckDisabled()) {
uint32_t updatedInlineDepth = globalMaxInlineDepth - inliningDepth_ - 1;
if (updatedInlineDepth < baseBuilder->script()->maxInlineDepth())
baseBuilder->script()->setMaxInlineDepth(updatedInlineDepth);
}
return true;
}

View File

@ -702,6 +702,12 @@ TypeInferenceOracle::canEnterInlinedFunction(RawFunction target)
{
RootedScript targetScript(cx, target->nonLazyScript());
// Make sure empty script has type information, to allow inlining in more cases.
if (targetScript->length == 1) {
if (!targetScript->ensureRanInference(cx))
return false;
}
if (!targetScript->hasAnalysis() ||
!targetScript->analysis()->ranInference() ||
!targetScript->analysis()->ranSSA())

View File

@ -77,7 +77,7 @@ ScriptAnalysis::addJump(JSContext *cx, unsigned offset,
if (offset < *currentOffset) {
/* Scripts containing loops are never inlined. */
isJaegerInlineable = false;
isJaegerInlineable = isIonInlineable = false;
hasLoops_ = true;
if (code->analyzed) {

View File

@ -1687,7 +1687,6 @@ JSScript::Create(JSContext *cx, HandleObject enclosingScope, bool savedCallerFun
script->sourceStart = bufStart;
script->sourceEnd = bufEnd;
script->userBit = options.userBit;
script->maxInlineDepth_ = uint8_t(-1);
return script;
}

View File

@ -426,6 +426,9 @@ class JSScript : public js::gc::Cell
// 16-bit fields.
private:
uint16_t PADDING16;
uint16_t version; /* JS version under which script was compiled */
public:
@ -441,11 +444,6 @@ class JSScript : public js::gc::Cell
uint16_t staticLevel;/* static level for display maintenance */
// 8-bit fields.
private:
uint8_t maxInlineDepth_; /* script max inline depth (IonMonkey)
uint8_t(-1): unitialized
uint8_t(-2): disabled */
uint8_t PADDING8;
public:
// The kinds of the optional arrays.
@ -809,26 +807,6 @@ class JSScript : public js::gc::Cell
return maxLoopCount;
}
void setMaxInlineDepth(uint32_t maxInlineDepth) {
if (maxInlineDepth >= uint8_t(-2)) {
disableInlineDepthCheck();
return;
}
maxInlineDepth_ = maxInlineDepth;
}
uint8_t maxInlineDepth() const {
return maxInlineDepth_;
}
void disableInlineDepthCheck() {
maxInlineDepth_ = uint8_t(-2);
}
bool isInlineDepthCheckDisabled() {
return maxInlineDepth_ == uint8_t(-2);
}
/*
* Size of the JITScript and all sections. If |mallocSizeOf| is NULL, the
* size is computed analytically. (This method is implemented in