LCOV - code coverage report
Current view: top level - src/interpreter - control-flow-builders.h (source / functions) Hit Total Coverage
Test: app.info Lines: 23 25 92.0 %
Date: 2017-04-26 Functions: 3 11 27.3 %

          Line data    Source code
       1             : // Copyright 2015 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_INTERPRETER_CONTROL_FLOW_BUILDERS_H_
       6             : #define V8_INTERPRETER_CONTROL_FLOW_BUILDERS_H_
       7             : 
       8             : #include "src/interpreter/bytecode-array-builder.h"
       9             : 
      10             : #include "src/interpreter/bytecode-label.h"
      11             : #include "src/zone/zone-containers.h"
      12             : 
      13             : namespace v8 {
      14             : namespace internal {
      15             : namespace interpreter {
      16             : 
      17             : class V8_EXPORT_PRIVATE ControlFlowBuilder BASE_EMBEDDED {
      18             :  public:
      19             :   explicit ControlFlowBuilder(BytecodeArrayBuilder* builder)
      20     5619873 :       : builder_(builder) {}
      21     5443346 :   virtual ~ControlFlowBuilder() {}
      22             : 
      23             :  protected:
      24             :   BytecodeArrayBuilder* builder() const { return builder_; }
      25             : 
      26             :  private:
      27             :   BytecodeArrayBuilder* builder_;
      28             : 
      29             :   DISALLOW_COPY_AND_ASSIGN(ControlFlowBuilder);
      30             : };
      31             : 
      32             : class V8_EXPORT_PRIVATE BreakableControlFlowBuilder
      33             :     : public ControlFlowBuilder {
      34             :  public:
      35     5443341 :   explicit BreakableControlFlowBuilder(BytecodeArrayBuilder* builder)
      36     5443341 :       : ControlFlowBuilder(builder), break_labels_(builder->zone()) {}
      37             :   virtual ~BreakableControlFlowBuilder();
      38             : 
      39             :   // This method should be called by the control flow owner before
      40             :   // destruction to update sites that emit jumps for break.
      41             :   void BindBreakTarget();
      42             : 
      43             :   // This method is called when visiting break statements in the AST.
      44             :   // Inserts a jump to an unbound label that is patched when the corresponding
      45             :   // BindBreakTarget is called.
      46       88395 :   void Break() { EmitJump(&break_labels_); }
      47             :   void BreakIfTrue(BytecodeArrayBuilder::ToBooleanMode mode) {
      48       31823 :     EmitJumpIfTrue(mode, &break_labels_);
      49             :   }
      50             :   void BreakIfFalse(BytecodeArrayBuilder::ToBooleanMode mode) {
      51        5764 :     EmitJumpIfFalse(mode, &break_labels_);
      52             :   }
      53             :   void BreakIfUndefined() { EmitJumpIfUndefined(&break_labels_); }
      54             :   void BreakIfNull() { EmitJumpIfNull(&break_labels_); }
      55             : 
      56             :   BytecodeLabels* break_labels() { return &break_labels_; }
      57             : 
      58             :  protected:
      59             :   void EmitJump(BytecodeLabels* labels);
      60             :   void EmitJumpIfTrue(BytecodeArrayBuilder::ToBooleanMode mode,
      61             :                       BytecodeLabels* labels);
      62             :   void EmitJumpIfFalse(BytecodeArrayBuilder::ToBooleanMode mode,
      63             :                        BytecodeLabels* labels);
      64             :   void EmitJumpIfUndefined(BytecodeLabels* labels);
      65             :   void EmitJumpIfNull(BytecodeLabels* labels);
      66             : 
      67             :   // Unbound labels that identify jumps for break statements in the code.
      68             :   BytecodeLabels break_labels_;
      69             : };
      70             : 
      71             : 
      72             : // Class to track control flow for block statements (which can break in JS).
      73     5183159 : class V8_EXPORT_PRIVATE BlockBuilder final
      74             :     : public BreakableControlFlowBuilder {
      75             :  public:
      76             :   explicit BlockBuilder(BytecodeArrayBuilder* builder)
      77     5183158 :       : BreakableControlFlowBuilder(builder) {}
      78             : 
      79             :   void EndBlock();
      80             : 
      81             :  private:
      82             :   BytecodeLabel block_end_;
      83             : };
      84             : 
      85             : 
      86             : // A class to help with co-ordinating break and continue statements with
      87             : // their loop.
      88             : class V8_EXPORT_PRIVATE LoopBuilder final : public BreakableControlFlowBuilder {
      89             :  public:
      90             :   explicit LoopBuilder(BytecodeArrayBuilder* builder)
      91             :       : BreakableControlFlowBuilder(builder),
      92             :         continue_labels_(builder->zone()),
      93      193044 :         header_labels_(builder->zone()) {}
      94             :   ~LoopBuilder();
      95             : 
      96             :   void LoopHeader(ZoneVector<BytecodeLabel>* additional_labels = nullptr);
      97             :   void JumpToHeader(int loop_depth);
      98             :   void BindContinueTarget();
      99             :   void EndLoop();
     100             : 
     101             :   // This method is called when visiting continue statements in the AST.
     102             :   // Inserts a jump to an unbound label that is patched when BindContinueTarget
     103             :   // is called.
     104       11886 :   void Continue() { EmitJump(&continue_labels_); }
     105        5764 :   void ContinueIfUndefined() { EmitJumpIfUndefined(&continue_labels_); }
     106             :   void ContinueIfNull() { EmitJumpIfNull(&continue_labels_); }
     107             : 
     108             :  private:
     109             :   BytecodeLabel loop_header_;
     110             : 
     111             :   // Unbound labels that identify jumps for continue statements in the code and
     112             :   // jumps from checking the loop condition to the header for do-while loops.
     113             :   BytecodeLabels continue_labels_;
     114             :   BytecodeLabels header_labels_;
     115             : };
     116             : 
     117             : 
     118             : // A class to help with co-ordinating break statements with their switch.
     119             : class V8_EXPORT_PRIVATE SwitchBuilder final
     120             :     : public BreakableControlFlowBuilder {
     121             :  public:
     122       67139 :   explicit SwitchBuilder(BytecodeArrayBuilder* builder, int number_of_cases)
     123             :       : BreakableControlFlowBuilder(builder),
     124       67139 :         case_sites_(builder->zone()) {
     125       67139 :     case_sites_.resize(number_of_cases);
     126       67139 :   }
     127             :   ~SwitchBuilder();
     128             : 
     129             :   // This method should be called by the SwitchBuilder owner when the case
     130             :   // statement with |index| is emitted to update the case jump site.
     131             :   void SetCaseTarget(int index);
     132             : 
     133             :   // This method is called when visiting case comparison operation for |index|.
     134             :   // Inserts a JumpIfTrue with ToBooleanMode |mode| to a unbound label that is
     135             :   // patched when the corresponding SetCaseTarget is called.
     136      195686 :   void Case(BytecodeArrayBuilder::ToBooleanMode mode, int index) {
     137      391372 :     builder()->JumpIfTrue(mode, &case_sites_.at(index));
     138      195685 :   }
     139             : 
     140             :   // This method is called when all cases comparisons have been emitted if there
     141             :   // is a default case statement. Inserts a Jump to a unbound label that is
     142             :   // patched when the corresponding SetCaseTarget is called.
     143      110166 :   void DefaultAt(int index) { builder()->Jump(&case_sites_.at(index)); }
     144             : 
     145             :  private:
     146             :   // Unbound labels that identify jumps for case statements in the code.
     147             :   ZoneVector<BytecodeLabel> case_sites_;
     148             : };
     149             : 
     150             : 
     151             : // A class to help with co-ordinating control flow in try-catch statements.
     152           0 : class V8_EXPORT_PRIVATE TryCatchBuilder final : public ControlFlowBuilder {
     153             :  public:
     154             :   explicit TryCatchBuilder(BytecodeArrayBuilder* builder,
     155             :                            HandlerTable::CatchPrediction catch_prediction)
     156             :       : ControlFlowBuilder(builder),
     157             :         handler_id_(builder->NewHandlerEntry()),
     158      256532 :         catch_prediction_(catch_prediction) {}
     159             : 
     160             :   void BeginTry(Register context);
     161             :   void EndTry();
     162             :   void EndCatch();
     163             : 
     164             :  private:
     165             :   int handler_id_;
     166             :   HandlerTable::CatchPrediction catch_prediction_;
     167             :   BytecodeLabel handler_;
     168             :   BytecodeLabel exit_;
     169             : };
     170             : 
     171             : 
     172             : // A class to help with co-ordinating control flow in try-finally statements.
     173           0 : class V8_EXPORT_PRIVATE TryFinallyBuilder final : public ControlFlowBuilder {
     174             :  public:
     175       48266 :   explicit TryFinallyBuilder(BytecodeArrayBuilder* builder,
     176             :                              HandlerTable::CatchPrediction catch_prediction)
     177             :       : ControlFlowBuilder(builder),
     178             :         handler_id_(builder->NewHandlerEntry()),
     179             :         catch_prediction_(catch_prediction),
     180       96532 :         finalization_sites_(builder->zone()) {}
     181             : 
     182             :   void BeginTry(Register context);
     183             :   void LeaveTry();
     184             :   void EndTry();
     185             :   void BeginHandler();
     186             :   void BeginFinally();
     187             :   void EndFinally();
     188             : 
     189             :  private:
     190             :   int handler_id_;
     191             :   HandlerTable::CatchPrediction catch_prediction_;
     192             :   BytecodeLabel handler_;
     193             : 
     194             :   // Unbound labels that identify jumps to the finally block in the code.
     195             :   BytecodeLabels finalization_sites_;
     196             : };
     197             : 
     198             : }  // namespace interpreter
     199             : }  // namespace internal
     200             : }  // namespace v8
     201             : 
     202             : #endif  // V8_INTERPRETER_CONTROL_FLOW_BUILDERS_H_

Generated by: LCOV version 1.10