Reviewers: Jakob,
Description:
Fix lost arguments dropping in HLeaveInlined.
This fixes HleaveInlined to correctly drop pushed arguments on all code
paths and addresses a corner case where the arguments stack height
mismatched at an OSR entry point.
[email protected]
BUG=chromium:150545
TEST=mjsunit/regress/regress-crbug-150545
Please review this at https://chromiumcodereview.appspot.com/10938016/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/arm/lithium-arm.cc
M src/hydrogen-instructions.h
M src/hydrogen.cc
M src/ia32/lithium-ia32.cc
M src/mips/lithium-mips.cc
M src/x64/lithium-x64.cc
A + test/mjsunit/regress/regress-crbug-150545.js
Index: src/arm/lithium-arm.cc
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index
b7a513cc0cc1a2d98caabbf6c57dc95cbc9720e6..1b313c153951ee6ec18b2a1e3bb3ef12be6c0e60
100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -2125,6 +2125,7 @@ LInstruction*
LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
+ ASSERT(argument_count_ == 0);
allocator_->MarkAsOsrEntry();
current_block_->last_environment()->set_ast_id(instr->ast_id());
return AssignEnvironment(new(zone()) LOsrEntry);
@@ -2264,7 +2265,7 @@ LInstruction*
LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
HEnvironment* env = current_block_->last_environment();
- if (instr->arguments_pushed()) {
+ if (env->entry()->arguments_pushed()) {
int argument_count = env->arguments_environment()->parameter_count();
pop = new(zone()) LDrop(argument_count);
argument_count_ -= argument_count;
Index: src/hydrogen-instructions.h
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index
ebc86a97f18cb6c61a3f5c9d94c25ca59e2da4ee..c87bb553b11b96e2790b63d96e8d428f853abc6d
100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -1472,21 +1472,13 @@ class HEnterInlined: public HTemplateInstruction<0>
{
class HLeaveInlined: public HTemplateInstruction<0> {
public:
- explicit HLeaveInlined(bool arguments_pushed)
- : arguments_pushed_(arguments_pushed) { }
+ HLeaveInlined() { }
virtual Representation RequiredInputRepresentation(int index) {
return Representation::None();
}
- bool arguments_pushed() {
- return arguments_pushed_;
- }
-
DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
-
- private:
- bool arguments_pushed_;
};
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index
c30a88bf1224c711be718430530fa5d8292bbd67..44f9b8a64be51c79fd50bb24d569d57c5730ebc2
100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -168,10 +168,9 @@ void HBasicBlock::Finish(HControlInstruction* end) {
void HBasicBlock::Goto(HBasicBlock* block, FunctionState* state) {
bool drop_extra = state != NULL &&
state->inlining_kind() == DROP_EXTRA_ON_RETURN;
- bool arguments_pushed = state != NULL && state->arguments_pushed();
if (block->IsInlineReturnTarget()) {
- AddInstruction(new(zone()) HLeaveInlined(arguments_pushed));
+ AddInstruction(new(zone()) HLeaveInlined());
last_environment_ = last_environment()->DiscardInlined(drop_extra);
}
@@ -185,11 +184,10 @@ void HBasicBlock::AddLeaveInlined(HValue*
return_value,
FunctionState* state) {
HBasicBlock* target = state->function_return();
bool drop_extra = state->inlining_kind() == DROP_EXTRA_ON_RETURN;
- bool arguments_pushed = state->arguments_pushed();
ASSERT(target->IsInlineReturnTarget());
ASSERT(return_value != NULL);
- AddInstruction(new(zone()) HLeaveInlined(arguments_pushed));
+ AddInstruction(new(zone()) HLeaveInlined());
last_environment_ = last_environment()->DiscardInlined(drop_extra);
last_environment()->Push(return_value);
AddSimulate(BailoutId::None());
Index: src/ia32/lithium-ia32.cc
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index
f843f3bc4eb4919ce96d41ca2c33cc970b79286d..38e7480d3df87c3222972c67dbb26ae1f590eb06
100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -2238,6 +2238,7 @@ LInstruction*
LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
+ ASSERT(argument_count_ == 0);
allocator_->MarkAsOsrEntry();
current_block_->last_environment()->set_ast_id(instr->ast_id());
return AssignEnvironment(new(zone()) LOsrEntry);
@@ -2385,7 +2386,7 @@ LInstruction*
LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
HEnvironment* env = current_block_->last_environment();
- if (instr->arguments_pushed()) {
+ if (env->entry()->arguments_pushed()) {
int argument_count = env->arguments_environment()->parameter_count();
pop = new(zone()) LDrop(argument_count);
argument_count_ -= argument_count;
Index: src/mips/lithium-mips.cc
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index
2ad64524826d5e685e7fb354a7df0f0d196743eb..e9edd48b9ef04381f5530f27459639ee328d44a0
100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -2069,6 +2069,7 @@ LInstruction*
LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
+ ASSERT(argument_count_ == 0);
allocator_->MarkAsOsrEntry();
current_block_->last_environment()->set_ast_id(instr->ast_id());
return AssignEnvironment(new(zone()) LOsrEntry);
@@ -2208,7 +2209,7 @@ LInstruction*
LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
HEnvironment* env = current_block_->last_environment();
- if (instr->arguments_pushed()) {
+ if (env->entry()->arguments_pushed()) {
int argument_count = env->arguments_environment()->parameter_count();
pop = new(zone()) LDrop(argument_count);
argument_count_ -= argument_count;
Index: src/x64/lithium-x64.cc
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index
177e7349ade6e91ad0fa237d228b2755bb78eb8d..dd3054f2da620dd245db260826510a6d9b69d940
100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -2128,6 +2128,7 @@ LInstruction*
LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
+ ASSERT(argument_count_ == 0);
allocator_->MarkAsOsrEntry();
current_block_->last_environment()->set_ast_id(instr->ast_id());
return AssignEnvironment(new(zone()) LOsrEntry);
@@ -2267,7 +2268,7 @@ LInstruction*
LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
HEnvironment* env = current_block_->last_environment();
- if (instr->arguments_pushed()) {
+ if (env->entry()->arguments_pushed()) {
int argument_count = env->arguments_environment()->parameter_count();
pop = new(zone()) LDrop(argument_count);
argument_count_ -= argument_count;
Index: test/mjsunit/regress/regress-crbug-150545.js
diff --git a/test/mjsunit/regress/regress-crbug-135066.js
b/test/mjsunit/regress/regress-crbug-150545.js
similarity index 74%
copy from test/mjsunit/regress/regress-crbug-135066.js
copy to test/mjsunit/regress/regress-crbug-150545.js
index
1aeca8b1a32d678ba7274c60230a77fdda97f6aa..a748af14cd0247836783e221d5d1bb9bdf1ad080
100644
--- a/test/mjsunit/regress/regress-crbug-135066.js
+++ b/test/mjsunit/regress/regress-crbug-150545.js
@@ -25,29 +25,28 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Filler long enough to trigger lazy parsing.
-var filler = "//" + new Array(1024).join('x');
+// Test that we do not generate OSR entry points that have an arguments
+// stack height different from zero. The OSR machinery cannot generate
+// frames for that.
-// Test strict eval in global context.
-eval(
- "'use strict';" +
- "var x = 23;" +
- "var f = function bozo1() {" +
- " return x;" +
- "};" +
- "assertSame(23, f());" +
- filler
-);
-
-// Test default eval in strict context.
(function() {
"use strict";
- eval(
- "var y = 42;" +
- "var g = function bozo2() {" +
- " return y;" +
- "};" +
- "assertSame(42, g());" +
- filler
- );
+
+ var instantReturn = false;
+ function inner() {
+ if (instantReturn) return;
+ assertSame(3, arguments.length);
+ assertSame(1, arguments[0]);
+ assertSame(2, arguments[1]);
+ assertSame(3, arguments[2]);
+ }
+
+ function outer(iterations) {
+ inner(1,2,3);
+ while (--iterations > 0);
+ assertSame(0, iterations);
+ }
+
+ // This function should be optimized via OSR.
+ outer(100000);
})();
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev