LCOV - code coverage report
Current view: top level - src/compiler - functional-list.h (source / functions) Hit Total Coverage
Test: app.info Lines: 31 33 93.9 %
Date: 2019-04-18 Functions: 9 9 100.0 %

          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             : #ifndef V8_COMPILER_FUNCTIONAL_LIST_H_
       6             : #define V8_COMPILER_FUNCTIONAL_LIST_H_
       7             : 
       8             : #include "src/zone/zone.h"
       9             : 
      10             : namespace v8 {
      11             : namespace internal {
      12             : namespace compiler {
      13             : 
      14             : // A generic stack implemented as a purely functional singly-linked list, which
      15             : // results in an O(1) copy operation. It is the equivalent of functional lists
      16             : // in ML-like languages, with the only difference that it also caches the length
      17             : // of the list in each node.
      18             : // TODO(tebbi): Use this implementation also for RedundancyElimination.
      19             : template <class A>
      20             : class FunctionalList {
      21             :  private:
      22             :   struct Cons : ZoneObject {
      23             :     Cons(A top, Cons* rest)
      24     8008658 :         : top(std::move(top)), rest(rest), size(1 + (rest ? rest->size : 0)) {}
      25             :     A const top;
      26             :     Cons* const rest;
      27             :     size_t const size;
      28             :   };
      29             : 
      30             :  public:
      31      927791 :   FunctionalList() : elements_(nullptr) {}
      32             : 
      33    39737039 :   bool operator==(const FunctionalList<A>& other) const {
      34    39737039 :     if (Size() != other.Size()) return false;
      35             :     iterator it = begin();
      36             :     iterator other_it = other.begin();
      37             :     while (true) {
      38    22941897 :       if (it == other_it) return true;
      39         245 :       if (*it != *other_it) return false;
      40             :       ++it;
      41             :       ++other_it;
      42             :     }
      43             :   }
      44             :   bool operator!=(const FunctionalList<A>& other) const {
      45    39737029 :     return !(*this == other);
      46             :   }
      47             : 
      48             :   const A& Front() const {
      49             :     DCHECK_GT(Size(), 0);
      50             :     return elements_->top;
      51             :   }
      52             : 
      53             :   FunctionalList Rest() const {
      54          30 :     FunctionalList result = *this;
      55          30 :     result.DropFront();
      56          30 :     return result;
      57             :   }
      58             : 
      59    13864780 :   void DropFront() {
      60    13864780 :     CHECK_GT(Size(), 0);
      61    13864780 :     elements_ = elements_->rest;
      62    13864780 :   }
      63             : 
      64     8008674 :   void PushFront(A a, Zone* zone) {
      65    24025990 :     elements_ = new (zone) Cons(std::move(a), elements_);
      66     8008658 :   }
      67             : 
      68             :   // If {hint} happens to be exactly what we want to allocate, avoid allocation
      69             :   // by reusing {hint}.
      70     7926705 :   void PushFront(A a, Zone* zone, FunctionalList hint) {
      71    23780147 :     if (hint.Size() == Size() + 1 && hint.Front() == a &&
      72     7926765 :         hint.Rest() == *this) {
      73           0 :       *this = hint;
      74             :     } else {
      75     7926705 :       PushFront(a, zone);
      76             :     }
      77     7926684 :   }
      78             : 
      79             :   // Drop elements until the current stack is equal to the tail shared with
      80             :   // {other}. The shared tail must not only be equal, but also refer to the
      81             :   // same memory.
      82     4635394 :   void ResetToCommonAncestor(FunctionalList other) {
      83    13021663 :     while (other.Size() > Size()) other.DropFront();
      84     5137657 :     while (other.Size() < Size()) DropFront();
      85     2488101 :     while (elements_ != other.elements_) {
      86     2488106 :       DropFront();
      87     2488097 :       other.DropFront();
      88             :     }
      89     4635364 :   }
      90             : 
      91    79687844 :   size_t Size() const { return elements_ ? elements_->size : 0; }
      92             : 
      93             :   class iterator {
      94             :    public:
      95             :     explicit iterator(Cons* cur) : current_(cur) {}
      96             : 
      97             :     const A& operator*() const { return current_->top; }
      98             :     iterator& operator++() {
      99    24206821 :       current_ = current_->rest;
     100             :       return *this;
     101             :     }
     102             :     bool operator==(const iterator& other) const {
     103             :       return this->current_ == other.current_;
     104             :     }
     105             :     bool operator!=(const iterator& other) const { return !(*this == other); }
     106             : 
     107             :    private:
     108             :     Cons* current_;
     109             :   };
     110             : 
     111           0 :   iterator begin() const { return iterator(elements_); }
     112             :   iterator end() const { return iterator(nullptr); }
     113             : 
     114             :  private:
     115             :   Cons* elements_;
     116             : };
     117             : 
     118             : }  // namespace compiler
     119             : }  // namespace internal
     120             : }  // namespace v8
     121             : 
     122             : #endif  // V8_COMPILER_FUNCTIONAL_LIST_H_

Generated by: LCOV version 1.10