LCOV - code coverage report
Current view: top level - src/torque - cfg.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 45 75 60.0 %
Date: 2019-04-17 Functions: 10 14 71.4 %

          Line data    Source code
       1             : // Copyright 2018 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/torque/cfg.h"
       6             : 
       7             : #include "src/torque/type-oracle.h"
       8             : 
       9             : namespace v8 {
      10             : namespace internal {
      11             : namespace torque {
      12             : 
      13        7648 : void Block::SetInputTypes(const Stack<const Type*>& input_types) {
      14        7648 :   if (!input_types_) {
      15             :     input_types_ = input_types;
      16             :     return;
      17        4709 :   } else if (*input_types_ == input_types) {
      18             :     return;
      19             :   }
      20             : 
      21             :   DCHECK_EQ(input_types.Size(), input_types_->Size());
      22             :   Stack<const Type*> merged_types;
      23             :   bool widened = false;
      24             :   auto c2_iterator = input_types.begin();
      25       11876 :   for (const Type* c1 : *input_types_) {
      26        5753 :     const Type* merged_type = TypeOracle::GetUnionType(c1, *c2_iterator++);
      27        5753 :     if (!merged_type->IsSubtypeOf(c1)) {
      28             :       widened = true;
      29             :     }
      30             :     merged_types.Push(merged_type);
      31             :   }
      32         370 :   if (merged_types.Size() == input_types_->Size()) {
      33         370 :     if (widened) {
      34             :       input_types_ = merged_types;
      35         331 :       Retype();
      36             :     }
      37             :     return;
      38             :   }
      39             : 
      40           0 :   std::stringstream error;
      41           0 :   error << "incompatible types at branch:\n";
      42           0 :   for (intptr_t i = std::max(input_types_->Size(), input_types.Size()) - 1;
      43           0 :        i >= 0; --i) {
      44             :     base::Optional<const Type*> left;
      45             :     base::Optional<const Type*> right;
      46           0 :     if (static_cast<size_t>(i) < input_types.Size()) {
      47             :       left = input_types.Peek(BottomOffset{static_cast<size_t>(i)});
      48             :     }
      49           0 :     if (static_cast<size_t>(i) < input_types_->Size()) {
      50             :       right = input_types_->Peek(BottomOffset{static_cast<size_t>(i)});
      51             :     }
      52           0 :     if (left && right && *left == *right) {
      53           0 :       error << **left << "\n";
      54             :     } else {
      55           0 :       if (left) {
      56           0 :         error << **left;
      57             :       } else {
      58           0 :         error << "/*missing*/";
      59             :       }
      60           0 :       error << "   =>   ";
      61           0 :       if (right) {
      62           0 :         error << **right;
      63             :       } else {
      64           0 :         error << "/*missing*/";
      65             :       }
      66           0 :       error << "\n";
      67             :     }
      68             :   }
      69           0 :   ReportError(error.str());
      70             : }
      71             : 
      72        6411 : void CfgAssembler::Bind(Block* block) {
      73             :   DCHECK(current_block_->IsComplete());
      74             :   DCHECK(block->instructions().empty());
      75             :   DCHECK(block->HasInputTypes());
      76        6411 :   current_block_ = block;
      77             :   current_stack_ = block->InputTypes();
      78             :   cfg_.PlaceBlock(block);
      79        6411 : }
      80             : 
      81        2806 : void CfgAssembler::Goto(Block* block) {
      82        2806 :   if (block->HasInputTypes()) {
      83             :     DropTo(block->InputTypes().AboveTop());
      84             :   }
      85        8418 :   Emit(GotoInstruction{block});
      86        2806 : }
      87             : 
      88        1703 : StackRange CfgAssembler::Goto(Block* block, size_t preserved_slots) {
      89             :   DCHECK(block->HasInputTypes());
      90             :   DCHECK_GE(CurrentStack().Size(), block->InputTypes().Size());
      91        5109 :   Emit(DeleteRangeInstruction{
      92             :       StackRange{block->InputTypes().AboveTop() - preserved_slots,
      93        1703 :                  CurrentStack().AboveTop() - preserved_slots}});
      94             :   StackRange preserved_slot_range = TopRange(preserved_slots);
      95        5109 :   Emit(GotoInstruction{block});
      96        1703 :   return preserved_slot_range;
      97             : }
      98             : 
      99         836 : void CfgAssembler::Branch(Block* if_true, Block* if_false) {
     100        2508 :   Emit(BranchInstruction{if_true, if_false});
     101         836 : }
     102             : 
     103             : // Delete the specified range of slots, moving upper slots to fill the gap.
     104       57548 : void CfgAssembler::DeleteRange(StackRange range) {
     105             :   DCHECK_LE(range.end(), current_stack_.AboveTop());
     106       57548 :   if (range.Size() == 0) return;
     107       24018 :   Emit(DeleteRangeInstruction{range});
     108             : }
     109             : 
     110       31242 : void CfgAssembler::DropTo(BottomOffset new_level) {
     111       32222 :   DeleteRange(StackRange{new_level, CurrentStack().AboveTop()});
     112       31242 : }
     113             : 
     114       18790 : StackRange CfgAssembler::Peek(StackRange range,
     115             :                               base::Optional<const Type*> type) {
     116             :   std::vector<const Type*> lowered_types;
     117       18790 :   if (type) {
     118       37580 :     lowered_types = LowerType(*type);
     119             :     DCHECK_EQ(lowered_types.size(), range.Size());
     120             :   }
     121       59820 :   for (size_t i = 0; i < range.Size(); ++i) {
     122      102575 :     Emit(PeekInstruction{
     123             :         range.begin() + i,
     124       20515 :         type ? lowered_types[i] : base::Optional<const Type*>{}});
     125             :   }
     126       18790 :   return TopRange(range.Size());
     127             : }
     128             : 
     129         586 : void CfgAssembler::Poke(StackRange destination, StackRange origin,
     130             :                         base::Optional<const Type*> type) {
     131             :   DCHECK_EQ(destination.Size(), origin.Size());
     132             :   DCHECK_LE(destination.end(), origin.begin());
     133             :   DCHECK_EQ(origin.end(), CurrentStack().AboveTop());
     134             :   std::vector<const Type*> lowered_types;
     135         586 :   if (type) {
     136        1172 :     lowered_types = LowerType(*type);
     137             :     DCHECK_EQ(lowered_types.size(), origin.Size());
     138             :   }
     139        1184 :   for (intptr_t i = origin.Size() - 1; i >= 0; --i) {
     140        3588 :     Emit(PokeInstruction{
     141             :         destination.begin() + i,
     142         598 :         type ? lowered_types[i] : base::Optional<const Type*>{}});
     143             :   }
     144         586 : }
     145             : 
     146           0 : void CfgAssembler::Print(std::string s) {
     147           0 :   Emit(PrintConstantStringInstruction{std::move(s)});
     148           0 : }
     149             : 
     150           0 : void CfgAssembler::AssertionFailure(std::string message) {
     151           0 :   Emit(AbortInstruction{AbortInstruction::Kind::kAssertionFailure,
     152           0 :                         std::move(message)});
     153           0 : }
     154             : 
     155           0 : void CfgAssembler::Unreachable() {
     156           0 :   Emit(AbortInstruction{AbortInstruction::Kind::kUnreachable});
     157           0 : }
     158             : 
     159           0 : void CfgAssembler::DebugBreak() {
     160           0 :   Emit(AbortInstruction{AbortInstruction::Kind::kDebugBreak});
     161           0 : }
     162             : 
     163             : }  // namespace torque
     164             : }  // namespace internal
     165       59456 : }  // namespace v8

Generated by: LCOV version 1.10