| Index: src/hydrogen.h
|
| diff --git a/src/hydrogen.h b/src/hydrogen.h
|
| index a95424a1c9e455ffa4a9664770844aee75b28b7d..8443e928684be6c41c41712f0c914a97a61a65b7 100644
|
| --- a/src/hydrogen.h
|
| +++ b/src/hydrogen.h
|
| @@ -934,11 +934,17 @@ class HGraphBuilder {
|
| : info_(info),
|
| graph_(NULL),
|
| current_block_(NULL),
|
| + no_side_effects_scope_environment_push_pop_delta_(0),
|
| no_side_effects_scope_count_(0) {}
|
| virtual ~HGraphBuilder() {}
|
|
|
| HBasicBlock* current_block() const { return current_block_; }
|
| - void set_current_block(HBasicBlock* block) { current_block_ = block; }
|
| + void set_current_block(HBasicBlock* block) {
|
| + // Conservatively disalow adding phis by disallowing changing the block
|
| + // as this class has no other bottlenecks for adding phis.
|
| + ASSERT(SafeToAddPhiInNoSideEffectsScope());
|
| + current_block_ = block;
|
| + }
|
| HEnvironment* environment() const {
|
| return current_block()->last_environment();
|
| }
|
| @@ -965,11 +971,31 @@ class HGraphBuilder {
|
| HReturn* AddReturn(HValue* value);
|
|
|
| void IncrementInNoSideEffectsScope() {
|
| + if (no_side_effects_scope_count_ == 0) {
|
| + no_side_effects_scope_environment_push_pop_delta_ =
|
| + environment()->push_count() - environment()->pop_count();
|
| + }
|
| no_side_effects_scope_count_++;
|
| }
|
|
|
| void DecrementInNoSideEffectsScope() {
|
| no_side_effects_scope_count_--;
|
| + if (no_side_effects_scope_count_ == 0) {
|
| + // No-side-effects scope should not change push-pop delta.
|
| + ASSERT_EQ(no_side_effects_scope_environment_push_pop_delta_,
|
| + environment()->push_count() - environment()->pop_count());
|
| + no_side_effects_scope_environment_push_pop_delta_ = 0;
|
| + }
|
| + }
|
| +
|
| + bool SafeToAddPhiInNoSideEffectsScope() {
|
| + // Pops and pushes after a simulate are not visible in LChunkBuilder.
|
| + // If the number of pops is greater than the number pushes then the
|
| + // environment in HGraphBuilder is shorter then the corresponding
|
| + // environment in LChunkBuilder. This causes non-observable phis
|
| + // to be pushed in the environment, which breaks deoptimization.
|
| + return no_side_effects_scope_count_ == 0 ||
|
| + no_side_effects_scope_environment_push_pop_delta_ >= 0;
|
| }
|
|
|
| protected:
|
| @@ -1332,6 +1358,7 @@ class HGraphBuilder {
|
| CompilationInfo* info_;
|
| HGraph* graph_;
|
| HBasicBlock* current_block_;
|
| + int no_side_effects_scope_environment_push_pop_delta_;
|
| int no_side_effects_scope_count_;
|
| };
|
|
|
|
|