From: mstarzinger@chromium.org Date: Wed, 19 Sep 2012 08:13:46 +0000 (+0000) Subject: Fix lost arguments dropping in HLeaveInlined. X-Git-Tag: upstream/4.7.83~15977 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f0dcaf9a196a294b48bf7f3dcc4a7bc5b101d12b;p=platform%2Fupstream%2Fv8.git 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. R=jkummerow@chromium.org BUG=chromium:150545 TEST=mjsunit/regress/regress-crbug-150545 Review URL: https://codereview.chromium.org/10938016 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12543 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index b7a513c..1b313c1 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; diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index ebc86a9..c87bb55 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_; }; diff --git a/src/hydrogen.cc b/src/hydrogen.cc index c30a88b..44f9b8a 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()); diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index f843f3b..38e7480 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; diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc index 2ad6452..e9edd48 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; diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index 177e734..dd3054f 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; diff --git a/test/mjsunit/regress/regress-crbug-150545.js b/test/mjsunit/regress/regress-crbug-150545.js new file mode 100644 index 0000000..68efdbf --- /dev/null +++ b/test/mjsunit/regress/regress-crbug-150545.js @@ -0,0 +1,53 @@ +// Copyright 2012 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +// 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. + +(function() { + "use strict"; + + 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() { + inner(1,2,3); + // Trigger OSR. + while (%GetOptimizationStatus(outer) == 2) {} + } + + outer(); +})();