LCOV - code coverage report
Current view: top level - src - safepoint-table.h (source / functions) Hit Total Coverage
Test: app.info Lines: 17 17 100.0 %
Date: 2017-10-20 Functions: 1 1 100.0 %

          Line data    Source code
       1             : // Copyright 2011 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_SAFEPOINT_TABLE_H_
       6             : #define V8_SAFEPOINT_TABLE_H_
       7             : 
       8             : #include "src/allocation.h"
       9             : #include "src/assert-scope.h"
      10             : #include "src/utils.h"
      11             : #include "src/v8memory.h"
      12             : #include "src/zone/zone.h"
      13             : 
      14             : namespace v8 {
      15             : namespace internal {
      16             : 
      17             : class Register;
      18             : 
      19             : class SafepointEntry BASE_EMBEDDED {
      20             :  public:
      21    56152064 :   SafepointEntry() : info_(0), bits_(nullptr), trampoline_pc_(-1) {}
      22             : 
      23             :   SafepointEntry(unsigned info, uint8_t* bits, int trampoline_pc)
      24     2758981 :       : info_(info), bits_(bits), trampoline_pc_(trampoline_pc) {
      25             :     DCHECK(is_valid());
      26             :   }
      27             : 
      28             :   bool is_valid() const { return bits_ != nullptr; }
      29             : 
      30             :   bool Equals(const SafepointEntry& other) const {
      31             :     return info_ == other.info_ && bits_ == other.bits_;
      32             :   }
      33             : 
      34             :   void Reset() {
      35     1240235 :     info_ = 0;
      36     1240235 :     bits_ = nullptr;
      37             :   }
      38             : 
      39             :   int deoptimization_index() const {
      40             :     DCHECK(is_valid());
      41             :     return DeoptimizationIndexField::decode(info_);
      42             :   }
      43             : 
      44             :   int trampoline_pc() { return trampoline_pc_; }
      45             : 
      46             :   void set_trampoline_pc(int trampoline_pc) { trampoline_pc_ = trampoline_pc; }
      47             : 
      48             :   static const int kArgumentsFieldBits = 3;
      49             :   static const int kSaveDoublesFieldBits = 1;
      50             :   static const int kDeoptIndexBits =
      51             :       32 - kArgumentsFieldBits - kSaveDoublesFieldBits;
      52             : 
      53             :   class DeoptimizationIndexField:
      54             :     public BitField<int, 0, kDeoptIndexBits> {};  // NOLINT
      55             :   class ArgumentsField:
      56             :     public BitField<unsigned,
      57             :                     kDeoptIndexBits,
      58             :                     kArgumentsFieldBits> {};  // NOLINT
      59             :   class SaveDoublesField:
      60             :     public BitField<bool,
      61             :                     kDeoptIndexBits + kArgumentsFieldBits,
      62             :                     kSaveDoublesFieldBits> { }; // NOLINT
      63             : 
      64             :   int argument_count() const {
      65             :     DCHECK(is_valid());
      66      604927 :     return ArgumentsField::decode(info_);
      67             :   }
      68             : 
      69             :   bool has_doubles() const {
      70             :     DCHECK(is_valid());
      71             :     return SaveDoublesField::decode(info_);
      72             :   }
      73             : 
      74             :   uint8_t* bits() {
      75             :     DCHECK(is_valid());
      76             :     return bits_;
      77             :   }
      78             : 
      79             :   bool HasRegisters() const;
      80             :   bool HasRegisterAt(int reg_index) const;
      81             : 
      82             :  private:
      83             :   unsigned info_;
      84             :   uint8_t* bits_;
      85             :   // It needs to be an integer as it is -1 for eager deoptimizations.
      86             :   int trampoline_pc_;
      87             : };
      88             : 
      89             : 
      90             : class SafepointTable BASE_EMBEDDED {
      91             :  public:
      92             :   explicit SafepointTable(Code* code);
      93             : 
      94             :   int size() const {
      95             :     return kHeaderSize + (length_ * (kFixedEntrySize + entry_size_));
      96             :   }
      97             :   unsigned length() const { return length_; }
      98             :   unsigned entry_size() const { return entry_size_; }
      99             : 
     100    24645321 :   unsigned GetPcOffset(unsigned index) const {
     101             :     DCHECK(index < length_);
     102    24671531 :     return Memory::uint32_at(GetPcOffsetLocation(index));
     103             :   }
     104             : 
     105             :   int GetTrampolinePcOffset(unsigned index) const {
     106             :     DCHECK(index < length_);
     107    22060690 :     return Memory::int_at(GetTrampolineLocation(index));
     108             :   }
     109             : 
     110             :   unsigned find_return_pc(unsigned pc_offset);
     111             : 
     112             :   SafepointEntry GetEntry(unsigned index) const {
     113             :     DCHECK(index < length_);
     114     2758981 :     unsigned info = Memory::uint32_at(GetInfoLocation(index));
     115     2758981 :     uint8_t* bits = &Memory::uint8_at(entries_ + (index * entry_size_));
     116     2758981 :     int trampoline_pc = Memory::int_at(GetTrampolineLocation(index));
     117             :     return SafepointEntry(info, bits, trampoline_pc);
     118             :   }
     119             : 
     120             :   // Returns the entry for the given pc.
     121             :   SafepointEntry FindEntry(Address pc) const;
     122             : 
     123             :   void PrintEntry(unsigned index, std::ostream& os) const;  // NOLINT
     124             : 
     125             :  private:
     126             :   static const uint8_t kNoRegisters = 0xFF;
     127             : 
     128             :   // Layout information
     129             :   static const int kLengthOffset = 0;
     130             :   static const int kEntrySizeOffset = kLengthOffset + kIntSize;
     131             :   static const int kHeaderSize = kEntrySizeOffset + kIntSize;
     132             :   static const int kPcOffset = 0;
     133             :   static const int kDeoptimizationIndexOffset = kPcOffset + kIntSize;
     134             :   static const int kTrampolinePcOffset = kDeoptimizationIndexOffset + kIntSize;
     135             :   static const int kFixedEntrySize = kTrampolinePcOffset + kIntSize;
     136             : 
     137             :   Address GetPcOffsetLocation(unsigned index) const {
     138    24653831 :     return pc_and_deoptimization_indexes_ + (index * kFixedEntrySize);
     139             :   }
     140             : 
     141             :   // TODO(juliana): rename this to GetDeoptimizationIndexLocation
     142        8151 :   Address GetInfoLocation(unsigned index) const {
     143             :     return GetPcOffsetLocation(index) + kDeoptimizationIndexOffset;
     144             :   }
     145             : 
     146       26210 :   Address GetTrampolineLocation(unsigned index) const {
     147             :     return GetPcOffsetLocation(index) + kTrampolinePcOffset;
     148             :   }
     149             : 
     150             :   static void PrintBits(std::ostream& os,  // NOLINT
     151             :                         uint8_t byte, int digits);
     152             : 
     153             :   DisallowHeapAllocation no_allocation_;
     154             :   Code* code_;
     155             :   unsigned length_;
     156             :   unsigned entry_size_;
     157             : 
     158             :   Address pc_and_deoptimization_indexes_;
     159             :   Address entries_;
     160             : 
     161             :   friend class SafepointTableBuilder;
     162             :   friend class SafepointEntry;
     163             : 
     164             :   DISALLOW_COPY_AND_ASSIGN(SafepointTable);
     165             : };
     166             : 
     167             : 
     168             : class Safepoint BASE_EMBEDDED {
     169             :  public:
     170             :   typedef enum {
     171             :     kSimple = 0,
     172             :     kWithRegisters = 1 << 0,
     173             :     kWithDoubles = 1 << 1,
     174             :     kWithRegistersAndDoubles = kWithRegisters | kWithDoubles
     175             :   } Kind;
     176             : 
     177             :   enum DeoptMode {
     178             :     kNoLazyDeopt,
     179             :     kLazyDeopt
     180             :   };
     181             : 
     182             :   static const int kNoDeoptimizationIndex =
     183             :       (1 << (SafepointEntry::kDeoptIndexBits)) - 1;
     184             : 
     185     7504636 :   void DefinePointerSlot(int index, Zone* zone) { indexes_->Add(index, zone); }
     186             :   void DefinePointerRegister(Register reg, Zone* zone);
     187             : 
     188             :  private:
     189             :   Safepoint(ZoneList<int>* indexes, ZoneList<int>* registers)
     190             :       : indexes_(indexes), registers_(registers) {}
     191             :   ZoneList<int>* indexes_;
     192             :   ZoneList<int>* registers_;
     193             : 
     194             :   friend class SafepointTableBuilder;
     195             : };
     196             : 
     197             : 
     198             : class SafepointTableBuilder BASE_EMBEDDED {
     199             :  public:
     200     1301568 :   explicit SafepointTableBuilder(Zone* zone)
     201             :       : deoptimization_info_(32, zone),
     202             :         deopt_index_list_(32, zone),
     203             :         indexes_(32, zone),
     204             :         registers_(32, zone),
     205             :         emitted_(false),
     206             :         last_lazy_safepoint_(0),
     207     1301568 :         zone_(zone) { }
     208             : 
     209             :   // Get the offset of the emitted safepoint table in the code.
     210             :   unsigned GetCodeOffset() const;
     211             : 
     212             :   // Define a new safepoint for the current position in the body.
     213             :   Safepoint DefineSafepoint(Assembler* assembler,
     214             :                             Safepoint::Kind kind,
     215             :                             int arguments,
     216             :                             Safepoint::DeoptMode mode);
     217             : 
     218             :   // Record deoptimization index for lazy deoptimization for the last
     219             :   // outstanding safepoints.
     220             :   void RecordLazyDeoptimizationIndex(int index);
     221             :   void BumpLastLazySafepointIndex() {
     222             :     last_lazy_safepoint_ = deopt_index_list_.length();
     223             :   }
     224             : 
     225             :   // Emit the safepoint table after the body. The number of bits per
     226             :   // entry must be enough to hold all the pointer indexes.
     227             :   void Emit(Assembler* assembler, int bits_per_entry);
     228             : 
     229             :   // Find the Deoptimization Info with pc offset {pc} and update its
     230             :   // trampoline field. Calling this function ensures that the safepoint
     231             :   // table contains the trampoline PC (trampoline} that replaced the
     232             :   // return PC {pc} on the stack.
     233             :   int UpdateDeoptimizationInfo(int pc, int trampoline, int start);
     234             : 
     235             :  private:
     236             :   struct DeoptimizationInfo {
     237             :     unsigned pc;
     238             :     unsigned arguments;
     239             :     bool has_doubles;
     240             :     int trampoline;
     241             :   };
     242             : 
     243             :   uint32_t EncodeExceptPC(const DeoptimizationInfo& info, unsigned index);
     244             : 
     245             :   bool IsIdenticalExceptForPc(int index1, int index2) const;
     246             :   // If all entries are identical, replace them by 1 entry with pc = kMaxUInt32.
     247             :   void RemoveDuplicates();
     248             : 
     249             :   ZoneList<DeoptimizationInfo> deoptimization_info_;
     250             :   ZoneList<unsigned> deopt_index_list_;
     251             :   ZoneList<ZoneList<int>*> indexes_;
     252             :   ZoneList<ZoneList<int>*> registers_;
     253             : 
     254             :   unsigned offset_;
     255             :   bool emitted_;
     256             :   int last_lazy_safepoint_;
     257             : 
     258             :   Zone* zone_;
     259             : 
     260             :   DISALLOW_COPY_AND_ASSIGN(SafepointTableBuilder);
     261             : };
     262             : 
     263             : }  // namespace internal
     264             : }  // namespace v8
     265             : 
     266             : #endif  // V8_SAFEPOINT_TABLE_H_

Generated by: LCOV version 1.10