LCOV - code coverage report
Current view: top level - src/interpreter - control-flow-builders.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 92 97 94.8 %
Date: 2017-10-20 Functions: 26 32 81.2 %

          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             : #include "src/interpreter/control-flow-builders.h"
       6             : #include "src/objects-inl.h"
       7             : 
       8             : namespace v8 {
       9             : namespace internal {
      10             : namespace interpreter {
      11             : 
      12             : 
      13     5404332 : BreakableControlFlowBuilder::~BreakableControlFlowBuilder() {
      14             :   BindBreakTarget();
      15             :   DCHECK(break_labels_.empty() || break_labels_.is_bound());
      16     5404332 :   if (block_coverage_builder_ != nullptr && needs_continuation_counter()) {
      17             :     block_coverage_builder_->IncrementBlockCounter(
      18         846 :         node_, SourceRangeKind::kContinuation);
      19             :   }
      20     5402251 : }
      21             : 
      22           0 : void BreakableControlFlowBuilder::BindBreakTarget() {
      23     5402251 :   break_labels_.Bind(builder());
      24           0 : }
      25             : 
      26       86049 : void BreakableControlFlowBuilder::EmitJump(BytecodeLabels* sites) {
      27       86049 :   builder()->Jump(sites->New());
      28       86049 : }
      29             : 
      30       24663 : void BreakableControlFlowBuilder::EmitJumpIfTrue(
      31             :     BytecodeArrayBuilder::ToBooleanMode mode, BytecodeLabels* sites) {
      32       24663 :   builder()->JumpIfTrue(mode, sites->New());
      33       24663 : }
      34             : 
      35        6072 : void BreakableControlFlowBuilder::EmitJumpIfFalse(
      36             :     BytecodeArrayBuilder::ToBooleanMode mode, BytecodeLabels* sites) {
      37        6072 :   builder()->JumpIfFalse(mode, sites->New());
      38        6072 : }
      39             : 
      40        6072 : void BreakableControlFlowBuilder::EmitJumpIfUndefined(BytecodeLabels* sites) {
      41        6072 :   builder()->JumpIfUndefined(sites->New());
      42        6072 : }
      43             : 
      44           0 : void BreakableControlFlowBuilder::EmitJumpIfNull(BytecodeLabels* sites) {
      45           0 :   builder()->JumpIfNull(sites->New());
      46           0 : }
      47             : 
      48      477626 : LoopBuilder::~LoopBuilder() {
      49             :   DCHECK(continue_labels_.empty() || continue_labels_.is_bound());
      50             :   // Restore the parent jump table.
      51      238813 :   if (generator_jump_table_location_ != nullptr) {
      52        1086 :     *generator_jump_table_location_ = parent_generator_jump_table_;
      53             :   }
      54      238813 : }
      55             : 
      56      221790 : void LoopBuilder::LoopHeader() {
      57             :   // Jumps from before the loop header into the loop violate ordering
      58             :   // requirements of bytecode basic blocks. The only entry into a loop
      59             :   // must be the loop header. Surely breaks is okay? Not if nested
      60             :   // and misplaced between the headers.
      61             :   DCHECK(break_labels_.empty() && continue_labels_.empty());
      62      222876 :   builder()->Bind(&loop_header_);
      63      221790 : }
      64             : 
      65        1086 : void LoopBuilder::LoopHeaderInGenerator(
      66             :     BytecodeJumpTable** generator_jump_table, int first_resume_id,
      67             :     int resume_count) {
      68             :   // Bind all the resume points that are inside the loop to be at the loop
      69             :   // header.
      70        2345 :   for (int id = first_resume_id; id < first_resume_id + resume_count; ++id) {
      71        2345 :     builder()->Bind(*generator_jump_table, id);
      72             :   }
      73             : 
      74             :   // Create the loop header.
      75             :   LoopHeader();
      76             : 
      77             :   // Create a new jump table for after the loop header for only these
      78             :   // resume points.
      79        1086 :   generator_jump_table_location_ = generator_jump_table;
      80        1086 :   parent_generator_jump_table_ = *generator_jump_table;
      81             :   *generator_jump_table =
      82        1086 :       builder()->AllocateJumpTable(resume_count, first_resume_id);
      83        1086 : }
      84             : 
      85      222999 : void LoopBuilder::LoopBody() {
      86      222999 :   if (block_coverage_builder_ != nullptr) {
      87         318 :     block_coverage_builder_->IncrementBlockCounter(block_coverage_body_slot_);
      88             :   }
      89      222999 : }
      90             : 
      91      222876 : void LoopBuilder::JumpToHeader(int loop_depth) {
      92             :   // Pass the proper loop nesting level to the backwards branch, to trigger
      93             :   // on-stack replacement when armed for the given loop nesting depth.
      94             :   int level = Min(loop_depth, AbstractCode::kMaxLoopNestingMarker - 1);
      95             :   // Loop must have closed form, i.e. all loop elements are within the loop,
      96             :   // the loop header precedes the body and next elements in the loop.
      97             :   DCHECK(loop_header_.is_bound());
      98      222876 :   builder()->JumpLoop(&loop_header_, level);
      99      222876 : }
     100             : 
     101      223246 : void LoopBuilder::BindContinueTarget() { continue_labels_.Bind(builder()); }
     102             : 
     103       16671 : SwitchBuilder::~SwitchBuilder() {
     104             : #ifdef DEBUG
     105             :   for (auto site : case_sites_) {
     106             :     DCHECK(site.is_bound());
     107             :   }
     108             : #endif
     109       16671 : }
     110             : 
     111      100608 : void SwitchBuilder::SetCaseTarget(int index, CaseClause* clause) {
     112      100608 :   BytecodeLabel& site = case_sites_.at(index);
     113      100608 :   builder()->Bind(&site);
     114      100608 :   if (block_coverage_builder_) {
     115             :     block_coverage_builder_->IncrementBlockCounter(clause,
     116          36 :                                                    SourceRangeKind::kBody);
     117             :   }
     118      100608 : }
     119             : 
     120             : 
     121      102123 : void TryCatchBuilder::BeginTry(Register context) {
     122      102123 :   builder()->MarkTryBegin(handler_id_, context);
     123      102123 : }
     124             : 
     125             : 
     126      102123 : void TryCatchBuilder::EndTry() {
     127      408492 :   builder()->MarkTryEnd(handler_id_);
     128      204246 :   builder()->Jump(&exit_);
     129      204246 :   builder()->Bind(&handler_);
     130      204246 :   builder()->MarkHandler(handler_id_, catch_prediction_);
     131      102123 : }
     132             : 
     133             : 
     134      102123 : void TryCatchBuilder::EndCatch() { builder()->Bind(&exit_); }
     135             : 
     136             : 
     137       36312 : void TryFinallyBuilder::BeginTry(Register context) {
     138       36312 :   builder()->MarkTryBegin(handler_id_, context);
     139       36312 : }
     140             : 
     141             : 
     142       53844 : void TryFinallyBuilder::LeaveTry() {
     143       53844 :   builder()->Jump(finalization_sites_.New());
     144       53844 : }
     145             : 
     146             : 
     147       36312 : void TryFinallyBuilder::EndTry() {
     148       36312 :   builder()->MarkTryEnd(handler_id_);
     149       36312 : }
     150             : 
     151             : 
     152       36312 : void TryFinallyBuilder::BeginHandler() {
     153       72624 :   builder()->Bind(&handler_);
     154       72624 :   builder()->MarkHandler(handler_id_, catch_prediction_);
     155       36312 : }
     156             : 
     157       36312 : void TryFinallyBuilder::BeginFinally() { finalization_sites_.Bind(builder()); }
     158             : 
     159       36312 : void TryFinallyBuilder::EndFinally() {
     160             :   // Nothing to be done here.
     161       36312 : }
     162             : 
     163     1015593 : ConditionalControlFlowBuilder::~ConditionalControlFlowBuilder() {
     164     1015593 :   if (!else_labels_.is_bound()) else_labels_.Bind(builder());
     165     1015593 :   end_labels_.Bind(builder());
     166             : 
     167             :   DCHECK(end_labels_.empty() || end_labels_.is_bound());
     168             :   DCHECK(then_labels_.empty() || then_labels_.is_bound());
     169             :   DCHECK(else_labels_.empty() || else_labels_.is_bound());
     170             : 
     171             :   // IfStatement requires a continuation counter, Conditional does not (as it
     172             :   // can only contain expressions).
     173     1016367 :   if (block_coverage_builder_ != nullptr && node_->IsIfStatement()) {
     174             :     block_coverage_builder_->IncrementBlockCounter(
     175         685 :         node_, SourceRangeKind::kContinuation);
     176             :   }
     177     1015594 : }
     178             : 
     179      288846 : void ConditionalControlFlowBuilder::JumpToEnd() {
     180             :   DCHECK(end_labels_.empty());  // May only be called once.
     181      288846 :   builder()->Jump(end_labels_.New());
     182      288846 : }
     183             : 
     184     1007125 : void ConditionalControlFlowBuilder::Then() {
     185     1007125 :   then_labels()->Bind(builder());
     186     1007125 :   if (block_coverage_builder_ != nullptr) {
     187         755 :     block_coverage_builder_->IncrementBlockCounter(block_coverage_then_slot_);
     188             :   }
     189     1007125 : }
     190             : 
     191      296017 : void ConditionalControlFlowBuilder::Else() {
     192      296017 :   else_labels()->Bind(builder());
     193      296017 :   if (block_coverage_builder_ != nullptr) {
     194         292 :     block_coverage_builder_->IncrementBlockCounter(block_coverage_else_slot_);
     195             :   }
     196      296017 : }
     197             : 
     198             : }  // namespace interpreter
     199             : }  // namespace internal
     200             : }  // namespace v8

Generated by: LCOV version 1.10