Revision: 16046
Author: [email protected]
Date: Mon Aug 5 02:53:12 2013
Log: Merge 15827, 15842, and 15912 into 3.19
Unify SoftDeoptimize and Deoptimize hydrogen instructions
Fix assert/crash in HandlePolymorphicCallNamed caused by 15827
Add regression test for chromium:258519
BUG=chromium:258519
TEST=test/mjsunit/regress/regress-crbug-258519.js
[email protected]
Review URL: https://codereview.chromium.org/20767002
http://code.google.com/p/v8/source/detail?r=16046
Added:
/branches/3.19/test/mjsunit/regress/regress-crbug-258519.js
Modified:
/branches/3.19/src/arm/lithium-arm.cc
/branches/3.19/src/arm/lithium-arm.h
/branches/3.19/src/arm/lithium-codegen-arm.cc
/branches/3.19/src/arm/lithium-codegen-arm.h
/branches/3.19/src/code-stubs-hydrogen.cc
/branches/3.19/src/hydrogen-environment-liveness.cc
/branches/3.19/src/hydrogen-gvn.cc
/branches/3.19/src/hydrogen-instructions.cc
/branches/3.19/src/hydrogen-instructions.h
/branches/3.19/src/hydrogen.cc
/branches/3.19/src/hydrogen.h
/branches/3.19/src/ia32/lithium-codegen-ia32.cc
/branches/3.19/src/ia32/lithium-codegen-ia32.h
/branches/3.19/src/ia32/lithium-ia32.cc
/branches/3.19/src/ia32/lithium-ia32.h
/branches/3.19/src/mips/lithium-codegen-mips.cc
/branches/3.19/src/mips/lithium-codegen-mips.h
/branches/3.19/src/mips/lithium-mips.cc
/branches/3.19/src/mips/lithium-mips.h
/branches/3.19/src/x64/lithium-codegen-x64.cc
/branches/3.19/src/x64/lithium-codegen-x64.h
/branches/3.19/src/x64/lithium-x64.cc
/branches/3.19/src/x64/lithium-x64.h
=======================================
--- /dev/null
+++ /branches/3.19/test/mjsunit/regress/regress-crbug-258519.js Mon Aug 5
02:53:12 2013
@@ -0,0 +1,45 @@
+// Copyright 2013 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
+
+var a = {
+ compare_null: function(x) { return null != x; },
+ kaboom: function() {}
+}
+
+function crash(x) {
+ var b = a;
+ b.compare_null(x) && b.kaboom();
+ return "ok";
+}
+
+assertEquals("ok", crash(null));
+assertEquals("ok", crash(null));
+%OptimizeFunctionOnNextCall(crash);
+// Used to throw: "TypeError: Cannot call method 'kaboom' of undefined".
+assertEquals("ok", crash(1));
=======================================
--- /branches/3.19/src/arm/lithium-arm.cc Tue Jun 18 04:54:54 2013
+++ /branches/3.19/src/arm/lithium-arm.cc Mon Aug 5 02:53:12 2013
@@ -709,11 +709,6 @@
UNREACHABLE();
return NULL;
}
-
-
-LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
- return AssignEnvironment(new(zone()) LDeoptimize);
-}
LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
=======================================
--- /branches/3.19/src/arm/lithium-arm.h Tue Jun 18 04:54:54 2013
+++ /branches/3.19/src/arm/lithium-arm.h Mon Aug 5 02:53:12 2013
@@ -434,6 +434,7 @@
class LDeoptimize: public LTemplateInstruction<0, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
+ DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
};
=======================================
--- /branches/3.19/src/arm/lithium-codegen-arm.cc Thu Jul 25 04:04:49 2013
+++ /branches/3.19/src/arm/lithium-codegen-arm.cc Mon Aug 5 02:53:12 2013
@@ -863,12 +863,6 @@
: Deoptimizer::EAGER;
DeoptimizeIf(cc, environment, bailout_type);
}
-
-
-void LCodeGen::SoftDeoptimize(LEnvironment* environment) {
- ASSERT(!info()->IsStub());
- DeoptimizeIf(al, environment, Deoptimizer::SOFT);
-}
void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) {
@@ -5677,11 +5671,15 @@
void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
- if (instr->hydrogen_value()->IsSoftDeoptimize()) {
- SoftDeoptimize(instr->environment());
- } else {
- DeoptimizeIf(al, instr->environment());
+ Deoptimizer::BailoutType type = instr->hydrogen()->type();
+ // TODO(danno): Stubs expect all deopts to be lazy for historical
reasons (the
+ // needed return address), even though the implementation of LAZY and
EAGER is
+ // now identical. When LAZY is eventually completely folded into EAGER,
remove
+ // the special case below.
+ if (info()->IsStub() && type == Deoptimizer::EAGER) {
+ type = Deoptimizer::LAZY;
}
+ DeoptimizeIf(al, instr->environment(), type);
}
=======================================
--- /branches/3.19/src/arm/lithium-codegen-arm.h Tue Jun 18 04:54:54 2013
+++ /branches/3.19/src/arm/lithium-codegen-arm.h Mon Aug 5 02:53:12 2013
@@ -285,7 +285,6 @@
LEnvironment* environment,
Deoptimizer::BailoutType bailout_type);
void DeoptimizeIf(Condition cc, LEnvironment* environment);
- void SoftDeoptimize(LEnvironment* environment);
void AddToTranslation(Translation* translation,
LOperand* op,
=======================================
--- /branches/3.19/src/code-stubs-hydrogen.cc Tue Jun 18 04:54:54 2013
+++ /branches/3.19/src/code-stubs-hydrogen.cc Mon Aug 5 02:53:12 2013
@@ -177,7 +177,7 @@
AddInstruction(context_);
start_environment->BindContext(context_);
- AddSimulate(BailoutId::StubEntry());
+ Add<HSimulate>(BailoutId::StubEntry());
NoObservableSideEffectsScope no_effects(this);
@@ -360,9 +360,10 @@
length));
}
- HValue* result = environment()->Pop();
checker.ElseDeopt();
- return result;
+ checker.End();
+
+ return environment()->Pop();
}
@@ -409,8 +410,11 @@
AddStore(object, access, AddLoad(boilerplate, access));
}
+ environment()->Push(object);
checker.ElseDeopt();
- return object;
+ checker.End();
+
+ return environment()->Pop();
}
=======================================
--- /branches/3.19/src/hydrogen-environment-liveness.cc Wed Jun 5 06:39:03
2013
+++ /branches/3.19/src/hydrogen-environment-liveness.cc Mon Aug 5 02:53:12
2013
@@ -181,15 +181,6 @@
last_simulate_ = NULL;
break;
}
- case HValue::kDeoptimize: {
- // Keep all environment slots alive.
- HDeoptimize* deopt = HDeoptimize::cast(instr);
- for (int i = deopt->first_local_index();
- i < deopt->first_expression_index(); ++i) {
- live->Add(i);
- }
- break;
- }
case HValue::kSimulate:
last_simulate_ = HSimulate::cast(instr);
went_live_since_last_simulate_->Clear();
=======================================
--- /branches/3.19/src/hydrogen-gvn.cc Mon Jun 3 08:43:46 2013
+++ /branches/3.19/src/hydrogen-gvn.cc Mon Aug 5 02:53:12 2013
@@ -401,7 +401,7 @@
GVNFlagSet side_effects;
while (instr != NULL) {
side_effects.Add(instr->ChangesFlags());
- if (instr->IsSoftDeoptimize()) {
+ if (instr->IsDeoptimize()) {
block_side_effects_[id].RemoveAll();
side_effects.RemoveAll();
break;
=======================================
--- /branches/3.19/src/hydrogen-instructions.cc Mon Jul 22 04:32:11 2013
+++ /branches/3.19/src/hydrogen-instructions.cc Mon Aug 5 02:53:12 2013
@@ -2118,16 +2118,6 @@
}
}
}
-
-
-void HDeoptimize::PrintDataTo(StringStream* stream) {
- if (OperandCount() == 0) return;
- OperandAt(0)->PrintNameTo(stream);
- for (int i = 1; i < OperandCount(); ++i) {
- stream->Add(" ");
- OperandAt(i)->PrintNameTo(stream);
- }
-}
void HEnterInlined::RegisterReturnTarget(HBasicBlock* return_target,
=======================================
--- /branches/3.19/src/hydrogen-instructions.h Tue Jun 18 04:54:54 2013
+++ /branches/3.19/src/hydrogen-instructions.h Mon Aug 5 02:53:12 2013
@@ -33,6 +33,7 @@
#include "allocation.h"
#include "code-stubs.h"
#include "data-flow.h"
+#include "deoptimizer.h"
#include "small-pointer-list.h"
#include "string-stream.h"
#include "v8conversions.h"
@@ -162,7 +163,6 @@
V(Shl) \
V(Shr) \
V(Simulate) \
- V(SoftDeoptimize) \
V(StackCheck) \
V(StoreContextSlot) \
V(StoreGlobalCell) \
@@ -1482,16 +1482,20 @@
};
-// We insert soft-deoptimize when we hit code with unknown typefeedback,
-// so that we get a chance of re-optimizing with useful typefeedback.
-// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
-class HSoftDeoptimize: public HTemplateInstruction<0> {
+class HDeoptimize: public HTemplateInstruction<0> {
public:
+ explicit HDeoptimize(Deoptimizer::BailoutType type) : type_(type) {}
+
virtual Representation RequiredInputRepresentation(int index) {
return Representation::None();
}
- DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
+ Deoptimizer::BailoutType type() { return type_; }
+
+ DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
+
+ private:
+ Deoptimizer::BailoutType type_;
};
@@ -1506,59 +1510,6 @@
};
-class HDeoptimize: public HControlInstruction {
- public:
- HDeoptimize(int environment_length,
- int first_local_index,
- int first_expression_index,
- Zone* zone)
- : values_(environment_length, zone),
- first_local_index_(first_local_index),
- first_expression_index_(first_expression_index) { }
-
- virtual Representation RequiredInputRepresentation(int index) {
- return Representation::None();
- }
-
- virtual int OperandCount() { return values_.length(); }
- virtual HValue* OperandAt(int index) const { return values_[index]; }
- virtual void PrintDataTo(StringStream* stream);
-
- virtual int SuccessorCount() { return 0; }
- virtual HBasicBlock* SuccessorAt(int i) {
- UNREACHABLE();
- return NULL;
- }
- virtual void SetSuccessorAt(int i, HBasicBlock* block) {
- UNREACHABLE();
- }
-
- void AddEnvironmentValue(HValue* value, Zone* zone) {
- values_.Add(NULL, zone);
- SetOperandAt(values_.length() - 1, value);
- }
- int first_local_index() { return first_local_index_; }
- int first_expression_index() { return first_expression_index_; }
-
- DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
-
- enum UseEnvironment {
- kNoUses,
- kUseAll
- };
-
- protected:
- virtual void InternalSetOperandAt(int index, HValue* value) {
- values_[index] = value;
- }
-
- private:
- ZoneList<HValue*> values_;
- int first_local_index_;
- int first_expression_index_;
-};
-
-
class HGoto: public HTemplateControlInstruction<1, 0> {
public:
explicit HGoto(HBasicBlock* target) {
=======================================
--- /branches/3.19/src/hydrogen.cc Mon Jul 22 04:32:11 2013
+++ /branches/3.19/src/hydrogen.cc Mon Aug 5 02:53:12 2013
@@ -128,26 +128,6 @@
}
instr->InsertAfter(last_);
}
-
-
-HDeoptimize* HBasicBlock::CreateDeoptimize(
- HDeoptimize::UseEnvironment has_uses) {
- ASSERT(HasEnvironment());
- if (has_uses == HDeoptimize::kNoUses)
- return new(zone()) HDeoptimize(0, 0, 0, zone());
-
- HEnvironment* environment = last_environment();
- int first_local_index = environment->first_local_index();
- int first_expression_index = environment->first_expression_index();
- HDeoptimize* instr = new(zone()) HDeoptimize(
- environment->length(), first_local_index, first_expression_index,
zone());
- for (int i = 0; i < environment->length(); i++) {
- HValue* val = environment->values()->at(i);
- instr->AddEnvironmentValue(val, zone());
- }
-
- return instr;
-}
HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id,
@@ -670,13 +650,16 @@
: builder_(builder),
position_(position),
finished_(false),
+ deopt_then_(false),
+ deopt_else_(false),
did_then_(false),
did_else_(false),
did_and_(false),
did_or_(false),
captured_(false),
needs_compare_(true),
- split_edge_merge_block_(NULL) {
+ split_edge_merge_block_(NULL),
+ merge_block_(NULL) {
HEnvironment* env = builder->environment();
first_true_block_ = builder->CreateBasicBlock(env->Copy());
last_true_block_ = NULL;
@@ -690,6 +673,8 @@
: builder_(builder),
position_(RelocInfo::kNoPosition),
finished_(false),
+ deopt_then_(false),
+ deopt_else_(false),
did_then_(false),
did_else_(false),
did_and_(false),
@@ -826,14 +811,13 @@
void HGraphBuilder::IfBuilder::Deopt() {
- HBasicBlock* block = builder_->current_block();
- block->FinishExitWithDeoptimization(HDeoptimize::kUseAll);
- builder_->set_current_block(NULL);
+ ASSERT(did_then_);
if (did_else_) {
- first_false_block_ = NULL;
+ deopt_else_ = true;
} else {
- first_true_block_ = NULL;
+ deopt_then_ = true;
}
+ builder_->Add<HDeoptimize>(Deoptimizer::EAGER);
}
@@ -858,20 +842,30 @@
last_true_block_ = builder_->current_block();
}
if (first_true_block_ == NULL) {
- // Deopt on true. Nothing to do, just continue the false block.
+ // Return on true. Nothing to do, just continue the false block.
} else if (first_false_block_ == NULL) {
// Deopt on false. Nothing to do except switching to the true block.
builder_->set_current_block(last_true_block_);
} else {
- HEnvironment* merge_env =
last_true_block_->last_environment()->Copy();
- merge_block_ = builder_->CreateBasicBlock(merge_env);
+ merge_block_ = builder_->graph()->CreateBasicBlock();
ASSERT(!finished_);
if (!did_else_) Else();
ASSERT(!last_true_block_->IsFinished());
HBasicBlock* last_false_block = builder_->current_block();
ASSERT(!last_false_block->IsFinished());
- last_true_block_->GotoNoSimulate(merge_block_);
- last_false_block->GotoNoSimulate(merge_block_);
+ if (deopt_then_) {
+ last_false_block->GotoNoSimulate(merge_block_);
+ builder_->PadEnvironmentForContinuation(last_true_block_,
+ merge_block_);
+ last_true_block_->GotoNoSimulate(merge_block_);
+ } else {
+ last_true_block_->GotoNoSimulate(merge_block_);
+ if (deopt_else_) {
+ builder_->PadEnvironmentForContinuation(last_false_block,
+ merge_block_);
+ }
+ last_false_block->GotoNoSimulate(merge_block_);
+ }
builder_->set_current_block(merge_block_);
}
}
@@ -979,14 +973,6 @@
}
return instr;
}
-
-
-void HGraphBuilder::AddSimulate(BailoutId id,
- RemovableSimulate removable) {
- ASSERT(current_block() != NULL);
- ASSERT(no_side_effects_scope_count_ == 0);
- current_block()->AddSimulate(id, removable);
-}
HBoundsCheck* HGraphBuilder::AddBoundsCheck(HValue* index, HValue* length)
{
@@ -994,18 +980,6 @@
AddInstruction(result);
return result;
}
-
-
-HReturn* HGraphBuilder::AddReturn(HValue* value) {
- HValue* context = environment()->LookupContext();
- int num_parameters = graph()->info()->num_parameters();
- HValue* params = AddInstruction(new(graph()->zone())
- HConstant(num_parameters));
- HReturn* return_instruction = new(graph()->zone())
- HReturn(value, context, params);
- current_block()->FinishExit(return_instruction);
- return return_instruction;
-}
HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) {
@@ -1030,10 +1004,43 @@
AddInstruction(check);
return check;
}
+
+
+void HGraphBuilder::FinishExitWithHardDeoptimization(
+ HBasicBlock* continuation) {
+ PadEnvironmentForContinuation(current_block(), continuation);
+ Add<HDeoptimize>(Deoptimizer::EAGER);
+ if (no_side_effects_scope_count_ > 0) {
+ current_block()->GotoNoSimulate(continuation);
+ } else {
+ current_block()->Goto(continuation);
+ }
+}
+
+
+void HGraphBuilder::PadEnvironmentForContinuation(
+ HBasicBlock* from,
+ HBasicBlock* continuation) {
+ if (continuation->last_environment() != NULL) {
+ // When merging from a deopt block to a continuation, resolve
differences in
+ // environment by pushing undefined and popping extra values so that
the
+ // environments match during the join.
+ int continuation_env_length =
continuation->last_environment()->length();
+ while (continuation_env_length != from->last_environment()->length()) {
+ if (continuation_env_length > from->last_environment()->length()) {
+ from->last_environment()->Push(graph()->GetConstantUndefined());
+ } else {
+ from->last_environment()->Pop();
+ }
+ }
+ } else {
+ ASSERT(continuation->predecessors()->length() == 0);
+ }
+}
HValue* HGraphBuilder::BuildCheckMap(HValue* obj,
- Handle<Map> map) {
+ Handle<Map> map) {
HCheckMaps* check = HCheckMaps::New(obj, map, zone());
AddInstruction(check);
return check;
@@ -2494,7 +2501,7 @@
instr->DeleteAndReplaceWith(last_dummy);
continue;
}
- if (instr->IsSoftDeoptimize()) {
+ if (instr->IsDeoptimize()) {
ASSERT(block->IsDeoptimizing());
nullify = true;
}
@@ -3624,7 +3631,7 @@
ASSERT(!instr->IsControlInstruction());
owner()->AddInstruction(instr);
if (instr->HasObservableSideEffects()) {
- owner()->AddSimulate(ast_id, REMOVABLE_SIMULATE);
+ owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
}
}
@@ -3666,7 +3673,7 @@
owner()->AddInstruction(instr);
owner()->Push(instr);
if (instr->HasObservableSideEffects()) {
- owner()->AddSimulate(ast_id, REMOVABLE_SIMULATE);
+ owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
}
}
@@ -3722,7 +3729,7 @@
// this one isn't actually needed (and wouldn't work if it were
targeted).
if (instr->HasObservableSideEffects()) {
builder->Push(instr);
- builder->AddSimulate(ast_id, REMOVABLE_SIMULATE);
+ builder->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
builder->Pop();
}
BuildBranch(instr);
@@ -3910,7 +3917,7 @@
VisitVariableDeclaration(scope->function());
}
VisitDeclarations(scope->declarations());
- AddSimulate(BailoutId::Declarations());
+ Add<HSimulate>(BailoutId::Declarations());
HValue* context = environment()->LookupContext();
AddInstruction(
@@ -3920,7 +3927,7 @@
if (HasStackOverflow()) return false;
if (current_block() != NULL) {
- AddReturn(graph()->GetConstantUndefined());
+ Add<HReturn>(graph()->GetConstantUndefined());
set_current_block(NULL);
}
@@ -4657,15 +4664,6 @@
Push(instr);
AddInstruction(instr);
}
-
-
-void HOptimizedGraphBuilder::AddSoftDeoptimize() {
- if (FLAG_always_opt) return;
- if (current_block()->IsDeoptimizing()) return;
- AddInstruction(new(zone()) HSoftDeoptimize());
- current_block()->MarkAsDeoptimizing();
- graph()->set_has_soft_deoptimize(true);
-}
template <class Instruction>
@@ -4774,10 +4772,10 @@
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
if (stmt->condition()->ToBooleanIsTrue()) {
- AddSimulate(stmt->ThenId());
+ Add<HSimulate>(stmt->ThenId());
Visit(stmt->then_statement());
} else if (stmt->condition()->ToBooleanIsFalse()) {
- AddSimulate(stmt->ElseId());
+ Add<HSimulate>(stmt->ElseId());
Visit(stmt->else_statement());
} else {
HBasicBlock* cond_true = graph()->CreateBasicBlock();
@@ -4884,7 +4882,7 @@
// Not an inlined return, so an actual one.
CHECK_ALIVE(VisitForValue(stmt->expression()));
HValue* result = environment()->Pop();
- AddReturn(result);
+ Add<HReturn>(result);
} else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) {
// Return from an inlined construct call. In a test context the return
value
// will always evaluate to true, in a value context the return value
needs
@@ -4976,7 +4974,7 @@
HValue* context = environment()->LookupContext();
CHECK_ALIVE(VisitForValue(stmt->tag()));
- AddSimulate(stmt->EntryId());
+ Add<HSimulate>(stmt->EntryId());
HValue* tag_value = Pop();
HBasicBlock* first_test_block = current_block();
@@ -5016,7 +5014,7 @@
if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) {
if (!clause->compare_type()->Is(Type::Integer31())) {
- AddSoftDeoptimize();
+ Add<HDeoptimize>(Deoptimizer::SOFT);
}
HCompareIDAndBranch* compare_ =
@@ -5066,7 +5064,7 @@
normal_block = last_block;
last_block = NULL; // Cleared to indicate we've handled it.
}
- } else if (!curr_test_block->end()->IsDeoptimize()) {
+ } else {
normal_block = curr_test_block->end()->FirstSuccessor();
curr_test_block = curr_test_block->end()->SecondSuccessor();
}
@@ -5160,7 +5158,7 @@
graph()->set_osr_values(osr_values);
- AddSimulate(osr_entry_id);
+ Add<HSimulate>(osr_entry_id);
AddInstruction(new(zone()) HOsrEntry(osr_entry_id));
HContext* context = new(zone()) HContext;
AddInstruction(context);
@@ -5176,7 +5174,7 @@
HBasicBlock* loop_entry,
BreakAndContinueInfo*
break_info) {
BreakAndContinueScope push(break_info, this);
- AddSimulate(stmt->StackCheckId());
+ Add<HSimulate>(stmt->StackCheckId());
HValue* context = environment()->LookupContext();
HStackCheck* stack_check =
new(zone()) HStackCheck(context, HStackCheck::kBackwardsBranch);
@@ -5351,7 +5349,7 @@
HInstruction* map = AddInstruction(new(zone()) HForInPrepareMap(
environment()->LookupContext(), enumerable));
- AddSimulate(stmt->PrepareId());
+ Add<HSimulate>(stmt->PrepareId());
HInstruction* array = AddInstruction(
new(zone()) HForInCacheArray(
@@ -5955,7 +5953,7 @@
}
AddInstruction(store);
if (store->HasObservableSideEffects()) {
- AddSimulate(key->id(), REMOVABLE_SIMULATE);
+ Add<HSimulate>(key->id(), REMOVABLE_SIMULATE);
}
} else {
CHECK_ALIVE(VisitForEffect(value));
@@ -6131,7 +6129,7 @@
break;
}
- AddSimulate(expr->GetIdForElement(i));
+ Add<HSimulate>(expr->GetIdForElement(i));
}
Drop(1); // array literal index
@@ -6435,7 +6433,7 @@
Push(value);
store->set_position(position);
AddInstruction(store);
- AddSimulate(assignment_id);
+ Add<HSimulate>(assignment_id);
ast_context()->ReturnValue(Pop());
return true;
}
@@ -6492,7 +6490,7 @@
// know about and do not want to handle ones we've never seen. Otherwise
// use a generic IC.
if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
- current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
+ FinishExitWithHardDeoptimization(join);
} else {
HInstruction* instr = BuildStoreNamedGeneric(object, name, value);
instr->set_position(position);
@@ -6507,10 +6505,10 @@
// unoptimized code).
if (instr->HasObservableSideEffects()) {
if (ast_context()->IsEffect()) {
- AddSimulate(id, REMOVABLE_SIMULATE);
+ Add<HSimulate>(id, REMOVABLE_SIMULATE);
} else {
Push(value);
- AddSimulate(id, REMOVABLE_SIMULATE);
+ Add<HSimulate>(id, REMOVABLE_SIMULATE);
Drop(1);
}
}
@@ -6552,7 +6550,7 @@
&has_side_effects);
Drop(3);
Push(value);
- AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
+ Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
return ast_context()->ReturnValue(Pop());
}
}
@@ -6576,7 +6574,7 @@
instr->set_position(position);
AddInstruction(instr);
if (instr->HasObservableSideEffects()) {
- AddSimulate(ast_id, REMOVABLE_SIMULATE);
+ Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
}
} else {
HValue* context = environment()->LookupContext();
@@ -6591,7 +6589,7 @@
instr->set_position(position);
AddInstruction(instr);
ASSERT(instr->HasObservableSideEffects());
- AddSimulate(ast_id, REMOVABLE_SIMULATE);
+ Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
}
}
@@ -6649,7 +6647,7 @@
instr->set_position(position);
AddInstruction(instr);
if (instr->HasObservableSideEffects()) {
- AddSimulate(assignment_id, REMOVABLE_SIMULATE);
+ Add<HSimulate>(assignment_id, REMOVABLE_SIMULATE);
}
return ast_context()->ReturnValue(Pop());
}
@@ -6727,7 +6725,7 @@
new(zone()) HStoreContextSlot(context, var->index(), mode,
Top());
AddInstruction(instr);
if (instr->HasObservableSideEffects()) {
- AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
+ Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
}
break;
}
@@ -6768,7 +6766,7 @@
if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop);
PushAndAdd(load);
if (load->HasObservableSideEffects()) {
- AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
+ Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE);
}
CHECK_ALIVE(VisitForValue(expr->value()));
@@ -6778,7 +6776,7 @@
HInstruction* instr = BuildBinaryOperation(operation, left, right);
PushAndAdd(instr);
if (instr->HasObservableSideEffects()) {
- AddSimulate(operation->id(), REMOVABLE_SIMULATE);
+ Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE);
}
return BuildStoreNamed(prop, expr->id(), expr->position(),
@@ -6796,7 +6794,7 @@
false, // is_store
&has_side_effects);
Push(load);
- if (has_side_effects) AddSimulate(prop->LoadId(),
REMOVABLE_SIMULATE);
+ if (has_side_effects) Add<HSimulate>(prop->LoadId(),
REMOVABLE_SIMULATE);
CHECK_ALIVE(VisitForValue(expr->value()));
HValue* right = Pop();
@@ -6805,7 +6803,7 @@
HInstruction* instr = BuildBinaryOperation(operation, left, right);
PushAndAdd(instr);
if (instr->HasObservableSideEffects()) {
- AddSimulate(operation->id(), REMOVABLE_SIMULATE);
+ Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE);
}
HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(),
@@ -6817,7 +6815,7 @@
Drop(3);
Push(instr);
ASSERT(has_side_effects); // Stores always have side effects.
- AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
+ Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
return ast_context()->ReturnValue(Pop());
}
@@ -6940,7 +6938,7 @@
context, var->index(), mode, Top());
AddInstruction(instr);
if (instr->HasObservableSideEffects()) {
- AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
+ Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
}
return ast_context()->ReturnValue(Pop());
}
@@ -6975,7 +6973,7 @@
HThrow* instr = new(zone()) HThrow(context, value);
instr->set_position(expr->position());
AddInstruction(instr);
- AddSimulate(expr->id());
+ Add<HSimulate>(expr->id());
current_block()->FinishExit(new(zone()) HAbnormalExit);
set_current_block(NULL);
}
@@ -7007,7 +7005,7 @@
Handle<String> name,
Property* expr) {
if (expr->IsUninitialized()) {
- AddSoftDeoptimize();
+ Add<HDeoptimize>(Deoptimizer::SOFT);
} else {
// OS::DebugBreak();
}
@@ -7400,7 +7398,8 @@
}
// Deopt if none of the cases matched.
- current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
+ NoObservableSideEffectsScope scope(this);
+ FinishExitWithHardDeoptimization(join);
set_current_block(join);
return is_store ? NULL : Pop();
}
@@ -7618,10 +7617,10 @@
&has_side_effects);
if (has_side_effects) {
if (ast_context()->IsEffect()) {
- AddSimulate(expr->id(), REMOVABLE_SIMULATE);
+ Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
} else {
Push(load);
- AddSimulate(expr->id(), REMOVABLE_SIMULATE);
+ Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
Drop(1);
}
}
@@ -7810,7 +7809,11 @@
// know about and do not want to handle ones we've never seen. Otherwise
// use a generic IC.
if (ordered_functions == types->length() &&
FLAG_deoptimize_uncommon_cases) {
- current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
+ // Because the deopt may be the only path in the polymorphic call,
make sure
+ // that the environment stack matches the depth on deopt that it
otherwise
+ // would have had after a successful call.
+ Drop(argument_count - (ast_context()->IsEffect() ? 0 : 1));
+ FinishExitWithHardDeoptimization(join);
} else {
HValue* context = environment()->LookupContext();
HCallNamed* call = new(zone()) HCallNamed(context, name,
argument_count);
@@ -8070,7 +8073,7 @@
inner_env->BindContext(context);
#endif
- AddSimulate(return_id);
+ Add<HSimulate>(return_id);
current_block()->UpdateEnvironment(inner_env);
HArgumentsObject* arguments_object = NULL;
@@ -9109,7 +9112,7 @@
Handle<Type> type = expr->type();
Representation rep = ToRepresentation(type);
if (type->Is(Type::None())) {
- AddSoftDeoptimize();
+ Add<HDeoptimize>(Deoptimizer::SOFT);
type = handle(Type::Any(), isolate());
}
if (instr->IsBinaryOperation()) {
@@ -9125,7 +9128,7 @@
HValue* value = Pop();
Handle<Type> info = expr->type();
if (info->Is(Type::None())) {
- AddSoftDeoptimize();
+ Add<HDeoptimize>(Deoptimizer::SOFT);
}
HInstruction* instr = new(zone()) HBitNot(value);
return ast_context()->ReturnInstruction(instr, expr->id());
@@ -9282,7 +9285,7 @@
new(zone()) HStoreContextSlot(context, var->index(), mode,
after);
AddInstruction(instr);
if (instr->HasObservableSideEffects()) {
- AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
+ Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
}
break;
}
@@ -9325,7 +9328,7 @@
if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop);
PushAndAdd(load);
if (load->HasObservableSideEffects()) {
- AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
+ Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE);
}
after = BuildIncrement(returns_original_input, expr);
@@ -9355,7 +9358,7 @@
environment()->SetExpressionStackAt(0, after);
if (returns_original_input) environment()->SetExpressionStackAt(1,
input);
if (store->HasObservableSideEffects()) {
- AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
+ Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
}
} else {
@@ -9373,7 +9376,7 @@
false, // is_store
&has_side_effects);
Push(load);
- if (has_side_effects) AddSimulate(prop->LoadId(),
REMOVABLE_SIMULATE);
+ if (has_side_effects) Add<HSimulate>(prop->LoadId(),
REMOVABLE_SIMULATE);
after = BuildIncrement(returns_original_input, expr);
input = environment()->ExpressionStackAt(0);
@@ -9390,7 +9393,7 @@
environment()->SetExpressionStackAt(0, after);
if (returns_original_input) environment()->SetExpressionStackAt(1,
input);
ASSERT(has_side_effects); // Stores always have side effects.
- AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
+ Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
}
}
@@ -9495,11 +9498,11 @@
Representation right_rep = ToRepresentation(right_type);
Representation result_rep = ToRepresentation(result_type);
if (left_type->Is(Type::None())) {
- AddSoftDeoptimize();
+ Add<HDeoptimize>(Deoptimizer::SOFT);
left_type = handle(Type::Any(), isolate());
}
if (right_type->Is(Type::None())) {
- AddSoftDeoptimize();
+ Add<HDeoptimize>(Deoptimizer::SOFT);
right_type = handle(Type::Any(), isolate());
}
HInstruction* instr = NULL;
@@ -9807,7 +9810,7 @@
// Check if this expression was ever executed according to type feedback.
// Note that for the special typeof/null/undefined cases we get unknown
here.
if (overall_type->Is(Type::None())) {
- AddSoftDeoptimize();
+ Add<HDeoptimize>(Deoptimizer::SOFT);
overall_type = left_type = right_type = handle(Type::Any(), isolate());
}
@@ -10317,7 +10320,7 @@
context, variable->index(), HStoreContextSlot::kNoCheck,
value);
AddInstruction(store);
if (store->HasObservableSideEffects()) {
- AddSimulate(proxy->id(), REMOVABLE_SIMULATE);
+ Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE);
}
}
break;
@@ -10356,7 +10359,7 @@
context, variable->index(), HStoreContextSlot::kNoCheck, value);
AddInstruction(store);
if (store->HasObservableSideEffects()) {
- AddSimulate(proxy->id(), REMOVABLE_SIMULATE);
+ Add<HSimulate>(proxy->id(), REMOVABLE_SIMULATE);
}
break;
}
=======================================
--- /branches/3.19/src/hydrogen.h Mon Jul 22 04:32:11 2013
+++ /branches/3.19/src/hydrogen.h Mon Aug 5 02:53:12 2013
@@ -136,17 +136,15 @@
}
int PredecessorIndexOf(HBasicBlock* predecessor) const;
- void AddSimulate(BailoutId ast_id,
- RemovableSimulate removable = FIXED_SIMULATE) {
- AddInstruction(CreateSimulate(ast_id, removable));
+ HSimulate* AddSimulate(BailoutId ast_id,
+ RemovableSimulate removable = FIXED_SIMULATE) {
+ HSimulate* instr = CreateSimulate(ast_id, removable);
+ AddInstruction(instr);
+ return instr;
}
void AssignCommonDominator(HBasicBlock* other);
void AssignLoopSuccessorDominators();
- void FinishExitWithDeoptimization(HDeoptimize::UseEnvironment has_uses) {
- FinishExit(CreateDeoptimize(has_uses));
- }
-
// Add the inlined function exit sequence, adding an HLeaveInlined
// instruction and updating the bailout environment.
void AddLeaveInlined(HValue* return_value, FunctionState* state);
@@ -181,11 +179,12 @@
#endif
private:
+ friend class HGraphBuilder;
+
void RegisterPredecessor(HBasicBlock* pred);
void AddDominatedBlock(HBasicBlock* block);
HSimulate* CreateSimulate(BailoutId ast_id, RemovableSimulate removable);
- HDeoptimize* CreateDeoptimize(HDeoptimize::UseEnvironment has_uses);
int block_id_;
HGraph* graph_;
@@ -991,8 +990,6 @@
// Adding instructions.
HInstruction* AddInstruction(HInstruction* instr);
- void AddSimulate(BailoutId id,
- RemovableSimulate removable = FIXED_SIMULATE);
HBoundsCheck* AddBoundsCheck(HValue* index, HValue* length);
HReturn* AddReturn(HValue* value);
@@ -1004,6 +1001,18 @@
void DecrementInNoSideEffectsScope() {
no_side_effects_scope_count_--;
}
+
+ void FinishExitWithHardDeoptimization(HBasicBlock* continuation);
+
+ template<class I, class P1>
+ I* Add(P1 p1) {
+ return I::cast(AddInstruction(new (zone()) I(p1)));
+ }
+
+ template<class I, class P1, class P2>
+ I* Add(P1 p1, P2 p2) {
+ return I::cast(AddInstruction(new (zone()) I(p1, p2)));
+ }
protected:
virtual bool BuildGraph() = 0;
@@ -1183,7 +1192,6 @@
void ElseDeopt() {
Else();
Deopt();
- End();
}
void Return(HValue* value);
@@ -1196,6 +1204,8 @@
HGraphBuilder* builder_;
int position_;
bool finished_ : 1;
+ bool deopt_then_ : 1;
+ bool deopt_else_ : 1;
bool did_then_ : 1;
bool did_else_ : 1;
bool did_and_ : 1;
@@ -1374,11 +1384,64 @@
private:
HGraphBuilder();
+
+ void PadEnvironmentForContinuation(HBasicBlock* from,
+ HBasicBlock* continuation);
+
CompilationInfo* info_;
HGraph* graph_;
HBasicBlock* current_block_;
int no_side_effects_scope_count_;
};
+
+
+template<>
+inline HDeoptimize* HGraphBuilder::Add(Deoptimizer::BailoutType type) {
+ if (type == Deoptimizer::SOFT) {
+ if (FLAG_always_opt) return NULL;
+ }
+ if (current_block()->IsDeoptimizing()) return NULL;
+ HDeoptimize* instr = new(zone()) HDeoptimize(type);
+ AddInstruction(instr);
+ if (type == Deoptimizer::SOFT) {
+ graph()->set_has_soft_deoptimize(true);
+ }
+ current_block()->MarkAsDeoptimizing();
+ return instr;
+}
+
+
+template<>
+inline HSimulate* HGraphBuilder::Add(BailoutId id,
+ RemovableSimulate removable) {
+ HSimulate* instr = current_block()->CreateSimulate(id, removable);
+ AddInstruction(instr);
+ return instr;
+}
+
+
+template<>
+inline HSimulate* HGraphBuilder::Add(BailoutId id) {
+ return Add<HSimulate>(id, FIXED_SIMULATE);
+}
+
+
+template<>
+inline HReturn* HGraphBuilder::Add(HValue* value) {
+ HValue* context = environment()->LookupContext();
+ int num_parameters = graph()->info()->num_parameters();
+ HValue* params = Add<HConstant>(num_parameters);
+ HReturn* return_instruction = new(graph()->zone())
+ HReturn(value, context, params);
+ current_block()->FinishExit(return_instruction);
+ return return_instruction;
+}
+
+
+template<>
+inline HReturn* HGraphBuilder::Add(HConstant* p1) {
+ return Add<HReturn>(static_cast<HValue*>(p1));
+}
class HOptimizedGraphBuilder: public HGraphBuilder, public AstVisitor {
@@ -1445,8 +1508,6 @@
void set_break_scope(BreakAndContinueScope* head) { break_scope_ = head;
}
bool inline_bailout() { return inline_bailout_; }
-
- void AddSoftDeoptimize();
void Bailout(const char* reason);
=======================================
--- /branches/3.19/src/ia32/lithium-codegen-ia32.cc Tue Jul 23 08:29:32 2013
+++ /branches/3.19/src/ia32/lithium-codegen-ia32.cc Mon Aug 5 02:53:12 2013
@@ -945,12 +945,6 @@
: Deoptimizer::EAGER;
DeoptimizeIf(cc, environment, bailout_type);
}
-
-
-void LCodeGen::SoftDeoptimize(LEnvironment* environment) {
- ASSERT(!info()->IsStub());
- DeoptimizeIf(no_condition, environment, Deoptimizer::SOFT);
-}
void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) {
@@ -6295,11 +6289,15 @@
void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
- if (instr->hydrogen_value()->IsSoftDeoptimize()) {
- SoftDeoptimize(instr->environment());
- } else {
- DeoptimizeIf(no_condition, instr->environment());
+ Deoptimizer::BailoutType type = instr->hydrogen()->type();
+ // TODO(danno): Stubs expect all deopts to be lazy for historical
reasons (the
+ // needed return address), even though the implementation of LAZY and
EAGER is
+ // now identical. When LAZY is eventually completely folded into EAGER,
remove
+ // the special case below.
+ if (info()->IsStub() && type == Deoptimizer::EAGER) {
+ type = Deoptimizer::LAZY;
}
+ DeoptimizeIf(no_condition, instr->environment(), type);
}
=======================================
--- /branches/3.19/src/ia32/lithium-codegen-ia32.h Tue Jun 18 04:54:54 2013
+++ /branches/3.19/src/ia32/lithium-codegen-ia32.h Mon Aug 5 02:53:12 2013
@@ -277,7 +277,6 @@
LEnvironment* environment,
Deoptimizer::BailoutType bailout_type);
void DeoptimizeIf(Condition cc, LEnvironment* environment);
- void SoftDeoptimize(LEnvironment* environment);
void AddToTranslation(Translation* translation,
LOperand* op,
=======================================
--- /branches/3.19/src/ia32/lithium-ia32.cc Tue Jul 23 08:29:32 2013
+++ /branches/3.19/src/ia32/lithium-ia32.cc Mon Aug 5 02:53:12 2013
@@ -768,11 +768,6 @@
UNREACHABLE();
return NULL;
}
-
-
-LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
- return AssignEnvironment(new(zone()) LDeoptimize);
-}
LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
=======================================
--- /branches/3.19/src/ia32/lithium-ia32.h Tue Jul 23 08:29:32 2013
+++ /branches/3.19/src/ia32/lithium-ia32.h Mon Aug 5 02:53:12 2013
@@ -421,6 +421,7 @@
class LDeoptimize: public LTemplateInstruction<0, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
+ DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
};
=======================================
--- /branches/3.19/src/mips/lithium-codegen-mips.cc Thu Jul 25 04:04:49 2013
+++ /branches/3.19/src/mips/lithium-codegen-mips.cc Mon Aug 5 02:53:12 2013
@@ -841,14 +841,6 @@
: Deoptimizer::EAGER;
DeoptimizeIf(cc, environment, bailout_type, src1, src2);
}
-
-
-void LCodeGen::SoftDeoptimize(LEnvironment* environment,
- Register src1,
- const Operand& src2) {
- ASSERT(!info()->IsStub());
- DeoptimizeIf(al, environment, Deoptimizer::SOFT, src1, src2);
-}
void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) {
@@ -5651,11 +5643,15 @@
void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
- if (instr->hydrogen_value()->IsSoftDeoptimize()) {
- SoftDeoptimize(instr->environment(), zero_reg, Operand(zero_reg));
- } else {
- DeoptimizeIf(al, instr->environment(), zero_reg, Operand(zero_reg));
+ Deoptimizer::BailoutType type = instr->hydrogen()->type();
+ // TODO(danno): Stubs expect all deopts to be lazy for historical
reasons (the
+ // needed return address), even though the implementation of LAZY and
EAGER is
+ // now identical. When LAZY is eventually completely folded into EAGER,
remove
+ // the special case below.
+ if (info()->IsStub() && type == Deoptimizer::EAGER) {
+ type = Deoptimizer::LAZY;
}
+ DeoptimizeIf(al, instr->environment(), type, zero_reg,
Operand(zero_reg));
}
=======================================
--- /branches/3.19/src/mips/lithium-codegen-mips.h Tue Jun 18 04:54:54 2013
+++ /branches/3.19/src/mips/lithium-codegen-mips.h Mon Aug 5 02:53:12 2013
@@ -285,9 +285,6 @@
LEnvironment* environment,
Register src1 = zero_reg,
const Operand& src2 = Operand(zero_reg));
- void SoftDeoptimize(LEnvironment* environment,
- Register src1 = zero_reg,
- const Operand& src2 = Operand(zero_reg));
void AddToTranslation(Translation* translation,
LOperand* op,
=======================================
--- /branches/3.19/src/mips/lithium-mips.cc Tue Jun 18 04:54:54 2013
+++ /branches/3.19/src/mips/lithium-mips.cc Mon Aug 5 02:53:12 2013
@@ -713,11 +713,6 @@
UNREACHABLE();
return NULL;
}
-
-
-LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
- return AssignEnvironment(new(zone()) LDeoptimize);
-}
LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
=======================================
--- /branches/3.19/src/mips/lithium-mips.h Tue Jun 18 04:54:54 2013
+++ /branches/3.19/src/mips/lithium-mips.h Mon Aug 5 02:53:12 2013
@@ -432,6 +432,7 @@
class LDeoptimize: public LTemplateInstruction<0, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
+ DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
};
=======================================
--- /branches/3.19/src/x64/lithium-codegen-x64.cc Wed Jun 19 11:17:45 2013
+++ /branches/3.19/src/x64/lithium-codegen-x64.cc Mon Aug 5 02:53:12 2013
@@ -751,12 +751,6 @@
: Deoptimizer::EAGER;
DeoptimizeIf(cc, environment, bailout_type);
}
-
-
-void LCodeGen::SoftDeoptimize(LEnvironment* environment) {
- ASSERT(!info()->IsStub());
- DeoptimizeIf(no_condition, environment, Deoptimizer::SOFT);
-}
void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) {
@@ -5399,11 +5393,15 @@
void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
- if (instr->hydrogen_value()->IsSoftDeoptimize()) {
- SoftDeoptimize(instr->environment());
- } else {
- DeoptimizeIf(no_condition, instr->environment());
+ Deoptimizer::BailoutType type = instr->hydrogen()->type();
+ // TODO(danno): Stubs expect all deopts to be lazy for historical
reasons (the
+ // needed return address), even though the implementation of LAZY and
EAGER is
+ // now identical. When LAZY is eventually completely folded into EAGER,
remove
+ // the special case below.
+ if (info()->IsStub() && type == Deoptimizer::EAGER) {
+ type = Deoptimizer::LAZY;
}
+ DeoptimizeIf(no_condition, instr->environment(), type);
}
=======================================
--- /branches/3.19/src/x64/lithium-codegen-x64.h Tue Jun 18 04:54:54 2013
+++ /branches/3.19/src/x64/lithium-codegen-x64.h Mon Aug 5 02:53:12 2013
@@ -246,7 +246,6 @@
LEnvironment* environment,
Deoptimizer::BailoutType bailout_type);
void DeoptimizeIf(Condition cc, LEnvironment* environment);
- void SoftDeoptimize(LEnvironment* environment);
void AddToTranslation(Translation* translation,
LOperand* op,
bool is_tagged,
=======================================
--- /branches/3.19/src/x64/lithium-x64.cc Tue Jun 18 04:54:54 2013
+++ /branches/3.19/src/x64/lithium-x64.cc Mon Aug 5 02:53:12 2013
@@ -717,11 +717,6 @@
UNREACHABLE();
return NULL;
}
-
-
-LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
- return AssignEnvironment(new(zone()) LDeoptimize);
-}
LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
=======================================
--- /branches/3.19/src/x64/lithium-x64.h Tue Jun 18 04:54:54 2013
+++ /branches/3.19/src/x64/lithium-x64.h Mon Aug 5 02:53:12 2013
@@ -434,6 +434,7 @@
class LDeoptimize: public LTemplateInstruction<0, 0, 0> {
public:
DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
+ DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
};
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.