Commit b2ed47b9 authored by Creddy's avatar Creddy Committed by Commit Bot

[interpreter] Restrict one-shot optimizations to only top-level IIFEs

IIFE`s within a function are not guaranteed to be executed only once.
They can be called multiple times and compiler can inline them.
Do the one-shot optimizations only for IIFE`s from top-level code.

Bug: v8:8072, chromium:886580
Change-Id: I02370681cc3eab270edcc75ee120ca7ad768ed52
Reviewed-on: https://chromium-review.googlesource.com/1231174
Commit-Queue: Chandan Reddy <chandanreddy@google.com>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56024}
parent deee2c2d
......@@ -1820,7 +1820,11 @@ bool BytecodeGenerator::ShouldOptimizeAsOneShot() const {
if (loop_depth_ > 0) return false;
return info()->literal()->is_top_level() || info()->literal()->is_iife();
// non-top-level iife is likely to be executed multiple times and so
// shouldn`t be optimized as one-shot
bool is_top_level_iife = info()->literal()->is_iife() &&
current_scope()->outer_scope()->is_script_scope();
return info()->literal()->is_top_level() || is_top_level_iife;
}
void BytecodeGenerator::BuildClassLiteral(ClassLiteral* expr) {
......
......@@ -627,3 +627,118 @@ constant pool: [
handlers: [
]
---
snippet: "
var t = 0;
function f2() {};
if (t == 0) {
(function(){
l = {};
l.a = 3;
l.b = 4;
f2();
return arguments.callee;
})();
}
"
frame size: 6
parameter count: 1
bytecode array length: 80
bytecodes: [
B(CreateMappedArguments),
B(Star), R(0),
/* 79 E> */ B(StackCheck),
/* 93 S> */ B(CreateEmptyObjectLiteral),
/* 95 E> */ B(StaGlobal), U8(0), U8(0),
/* 111 S> */ B(LdaGlobal), U8(0), U8(2),
B(Star), R(1),
B(LdaSmi), I8(3),
B(Star), R(4),
B(LdaConstant), U8(1),
B(Star), R(3),
B(LdaZero),
B(Star), R(5),
B(Mov), R(1), R(2),
/* 115 E> */ B(CallRuntime), U16(Runtime::kSetNamedProperty), R(2), U8(4),
/* 130 S> */ B(LdaGlobal), U8(0), U8(2),
B(Star), R(1),
B(LdaSmi), I8(4),
B(Star), R(4),
B(LdaConstant), U8(2),
B(Star), R(3),
B(LdaZero),
B(Star), R(5),
B(Mov), R(1), R(2),
/* 134 E> */ B(CallRuntime), U16(Runtime::kSetNamedProperty), R(2), U8(4),
/* 149 S> */ B(LdaUndefined),
B(Star), R(2),
B(LdaGlobal), U8(3), U8(4),
B(Star), R(1),
/* 149 E> */ B(CallNoFeedback), R(1), R(2), U8(1),
/* 165 S> */ B(LdaConstant), U8(4),
B(Star), R(3),
B(Mov), R(0), R(2),
/* 182 E> */ B(InvokeIntrinsic), U8(Runtime::k_GetProperty), R(2), U8(2),
/* 189 S> */ B(Return),
]
constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["l"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["a"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["b"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["f2"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["callee"],
]
handlers: [
]
---
snippet: "
function f2() {};
function f() {
return (function(){
l = {};
l.a = 3;
l.b = 4;
f2();
return arguments.callee;
})();
}
f();
"
frame size: 2
parameter count: 1
bytecode array length: 43
bytecodes: [
B(CreateMappedArguments),
B(Star), R(0),
/* 76 E> */ B(StackCheck),
/* 92 S> */ B(CreateEmptyObjectLiteral),
/* 94 E> */ B(StaGlobal), U8(0), U8(0),
/* 112 S> */ B(LdaGlobal), U8(0), U8(2),
B(Star), R(1),
B(LdaSmi), I8(3),
/* 116 E> */ B(StaNamedProperty), R(1), U8(1), U8(4),
/* 133 S> */ B(LdaGlobal), U8(0), U8(2),
B(Star), R(1),
B(LdaSmi), I8(4),
/* 137 E> */ B(StaNamedProperty), R(1), U8(2), U8(6),
/* 154 S> */ B(LdaGlobal), U8(3), U8(8),
B(Star), R(1),
/* 154 E> */ B(CallUndefinedReceiver0), R(1), U8(10),
/* 189 S> */ B(LdaNamedProperty), R(0), U8(4), U8(12),
/* 196 S> */ B(Return),
]
constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["l"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["a"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["b"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["f2"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["callee"],
]
handlers: [
]
......@@ -663,6 +663,33 @@ TEST(IIFEWithOneshotOpt) {
return arguments.callee;
})();
)",
R"(
var t = 0;
function f2() {};
if (t == 0) {
(function(){
l = {};
l.a = 3;
l.b = 4;
f2();
return arguments.callee;
})();
}
)",
// No one-shot opt for IIFE`s within a function
R"(
function f2() {};
function f() {
return (function(){
l = {};
l.a = 3;
l.b = 4;
f2();
return arguments.callee;
})();
}
f();
)",
};
CHECK(CompareTexts(BuildActual(printer, snippets),
LoadGolden("IIFEWithOneshotOpt.golden")));
......
......@@ -584,9 +584,9 @@ TEST(LogAll) {
CHECK(logger.ContainsLine({"api,v8::Script::Run"}));
CHECK(logger.ContainsLine({"code-creation,LazyCompile,", "testAddFn"}));
if (i::FLAG_opt && !i::FLAG_always_opt) {
CHECK(logger.ContainsLine({"code-deopt,", "eager"}));
CHECK(logger.ContainsLine({"code-deopt,", "not a Smi"}));
if (i::FLAG_enable_one_shot_optimization)
CHECK(logger.ContainsLine({"code-deopt,", "soft"}));
CHECK(logger.ContainsLine({"code-deopt,", "DeoptimizeNow"}));
CHECK(logger.ContainsLine({"timer-event-start", "V8.DeoptimizeCode"}));
CHECK(logger.ContainsLine({"timer-event-end", "V8.DeoptimizeCode"}));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment