LCOV - code coverage report
Current view: top level - src - safepoint-table.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 78 95 82.1 %
Date: 2017-04-26 Functions: 9 12 75.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             : #include "src/safepoint-table.h"
       6             : 
       7             : #include "src/assembler-inl.h"
       8             : #include "src/deoptimizer.h"
       9             : #include "src/disasm.h"
      10             : #include "src/frames-inl.h"
      11             : #include "src/macro-assembler.h"
      12             : #include "src/ostreams.h"
      13             : 
      14             : namespace v8 {
      15             : namespace internal {
      16             : 
      17             : 
      18     1665019 : bool SafepointEntry::HasRegisters() const {
      19             :   DCHECK(is_valid());
      20             :   DCHECK(IsAligned(kNumSafepointRegisters, kBitsPerByte));
      21             :   const int num_reg_bytes = kNumSafepointRegisters >> kBitsPerByteLog2;
      22     4964817 :   for (int i = 0; i < num_reg_bytes; i++) {
      23     3314918 :     if (bits_[i] != SafepointTable::kNoRegisters) return true;
      24             :   }
      25             :   return false;
      26             : }
      27             : 
      28             : 
      29      241920 : bool SafepointEntry::HasRegisterAt(int reg_index) const {
      30             :   DCHECK(is_valid());
      31             :   DCHECK(reg_index >= 0 && reg_index < kNumSafepointRegisters);
      32      241920 :   int byte_index = reg_index >> kBitsPerByteLog2;
      33      241920 :   int bit_index = reg_index & (kBitsPerByte - 1);
      34      241920 :   return (bits_[byte_index] & (1 << bit_index)) != 0;
      35             : }
      36             : 
      37             : 
      38     1732479 : SafepointTable::SafepointTable(Code* code) {
      39             :   DCHECK(code->is_crankshafted());
      40     1732479 :   code_ = code;
      41     3464958 :   Address header = code->instruction_start() + code->safepoint_table_offset();
      42     1732479 :   length_ = Memory::uint32_at(header + kLengthOffset);
      43     1732479 :   entry_size_ = Memory::uint32_at(header + kEntrySizeOffset);
      44     1732479 :   pc_and_deoptimization_indexes_ = header + kHeaderSize;
      45     1732479 :   entries_ = pc_and_deoptimization_indexes_ +
      46     3464958 :              (length_ * kPcAndDeoptimizationIndexSize);
      47             :   DCHECK(entry_size_ > 0);
      48             :   STATIC_ASSERT(SafepointEntry::DeoptimizationIndexField::kMax ==
      49             :                 Safepoint::kNoDeoptimizationIndex);
      50     1732479 : }
      51             : 
      52             : 
      53    27605757 : SafepointEntry SafepointTable::FindEntry(Address pc) const {
      54     1732479 :   unsigned pc_offset = static_cast<unsigned>(pc - code_->instruction_start());
      55    51746556 :   for (unsigned i = 0; i < length(); i++) {
      56             :     // TODO(kasperl): Replace the linear search with binary search.
      57    25873278 :     if (GetPcOffset(i) == pc_offset) return GetEntry(i);
      58             :   }
      59           0 :   return SafepointEntry();
      60             : }
      61             : 
      62             : 
      63           0 : void SafepointTable::PrintEntry(unsigned index,
      64             :                                 std::ostream& os) const {  // NOLINT
      65             :   disasm::NameConverter converter;
      66             :   SafepointEntry entry = GetEntry(index);
      67             :   uint8_t* bits = entry.bits();
      68             : 
      69             :   // Print the stack slot bits.
      70           0 :   if (entry_size_ > 0) {
      71             :     DCHECK(IsAligned(kNumSafepointRegisters, kBitsPerByte));
      72             :     const int first = kNumSafepointRegisters >> kBitsPerByteLog2;
      73           0 :     int last = entry_size_ - 1;
      74           0 :     for (int i = first; i < last; i++) PrintBits(os, bits[i], kBitsPerByte);
      75           0 :     int last_bits = code_->stack_slots() - ((last - first) * kBitsPerByte);
      76           0 :     PrintBits(os, bits[last], last_bits);
      77             : 
      78             :     // Print the registers (if any).
      79           0 :     if (!entry.HasRegisters()) return;
      80           0 :     for (int j = 0; j < kNumSafepointRegisters; j++) {
      81           0 :       if (entry.HasRegisterAt(j)) {
      82           0 :         os << " | " << converter.NameOfCPURegister(j);
      83             :       }
      84             :     }
      85             :   }
      86             : }
      87             : 
      88             : 
      89           0 : void SafepointTable::PrintBits(std::ostream& os,  // NOLINT
      90             :                                uint8_t byte, int digits) {
      91             :   DCHECK(digits >= 0 && digits <= kBitsPerByte);
      92           0 :   for (int i = 0; i < digits; i++) {
      93           0 :     os << (((byte & (1 << i)) == 0) ? "0" : "1");
      94             :   }
      95           0 : }
      96             : 
      97             : 
      98      159432 : void Safepoint::DefinePointerRegister(Register reg, Zone* zone) {
      99      318864 :   registers_->Add(reg.code(), zone);
     100      159432 : }
     101             : 
     102             : 
     103     5154056 : Safepoint SafepointTableBuilder::DefineSafepoint(
     104             :     Assembler* assembler,
     105             :     Safepoint::Kind kind,
     106             :     int arguments,
     107             :     Safepoint::DeoptMode deopt_mode) {
     108             :   DCHECK(arguments >= 0);
     109             :   DeoptimizationInfo info;
     110    10308112 :   info.pc = assembler->pc_offset();
     111     5154056 :   info.arguments = arguments;
     112     5154056 :   info.has_doubles = (kind & Safepoint::kWithDoubles);
     113     5154056 :   deoptimization_info_.Add(info, zone_);
     114    10308118 :   deopt_index_list_.Add(Safepoint::kNoDeoptimizationIndex, zone_);
     115     5154059 :   if (deopt_mode == Safepoint::kNoLazyDeopt) {
     116     1049679 :     last_lazy_safepoint_ = deopt_index_list_.length();
     117             :   }
     118    10308118 :   indexes_.Add(new(zone_) ZoneList<int>(8, zone_), zone_);
     119     5154056 :   registers_.Add((kind & Safepoint::kWithRegisters)
     120       84995 :       ? new(zone_) ZoneList<int>(4, zone_)
     121             :       : NULL,
     122    10308112 :       zone_);
     123    10308110 :   return Safepoint(indexes_.last(), registers_.last());
     124             : }
     125             : 
     126             : 
     127     4106719 : void SafepointTableBuilder::RecordLazyDeoptimizationIndex(int index) {
     128    20524135 :   while (last_lazy_safepoint_ < deopt_index_list_.length()) {
     129    16412686 :     deopt_index_list_[last_lazy_safepoint_++] = index;
     130             :   }
     131     4106719 : }
     132             : 
     133     1191440 : unsigned SafepointTableBuilder::GetCodeOffset() const {
     134             :   DCHECK(emitted_);
     135     1191440 :   return offset_;
     136             : }
     137             : 
     138             : 
     139     1191440 : void SafepointTableBuilder::Emit(Assembler* assembler, int bits_per_entry) {
     140             :   // Make sure the safepoint table is properly aligned. Pad with nops.
     141     1191440 :   assembler->Align(kIntSize);
     142     1191439 :   assembler->RecordComment(";;; Safepoint table.");
     143     2382880 :   offset_ = assembler->pc_offset();
     144             : 
     145             :   // Take the register bits into account.
     146     1191440 :   bits_per_entry += kNumSafepointRegisters;
     147             : 
     148             :   // Compute the number of bytes per safepoint entry.
     149             :   int bytes_per_entry =
     150     1191440 :       RoundUp(bits_per_entry, kBitsPerByte) >> kBitsPerByteLog2;
     151             : 
     152             :   // Emit the table header.
     153    11499232 :   int length = deoptimization_info_.length();
     154     1191440 :   assembler->dd(length);
     155     1191438 :   assembler->dd(bytes_per_entry);
     156             : 
     157             :   // Emit sorted table of pc offsets together with deoptimization indexes.
     158     6345335 :   for (int i = 0; i < length; i++) {
     159     5153895 :     assembler->dd(deoptimization_info_[i].pc);
     160             :     assembler->dd(EncodeExceptPC(deoptimization_info_[i],
     161    15461691 :                                  deopt_index_list_[i]));
     162             :   }
     163             : 
     164             :   // Emit table of bitmaps.
     165     1191440 :   ZoneList<uint8_t> bits(bytes_per_entry, zone_);
     166     6345339 :   for (int i = 0; i < length; i++) {
     167    10307798 :     ZoneList<int>* indexes = indexes_[i];
     168    10307798 :     ZoneList<int>* registers = registers_[i];
     169             :     bits.Clear();
     170     5153899 :     bits.AddBlock(0, bytes_per_entry, zone_);
     171             : 
     172             :     // Run through the registers (if any).
     173             :     DCHECK(IsAligned(kNumSafepointRegisters, kBitsPerByte));
     174     5153898 :     if (registers == NULL) {
     175             :       const int num_reg_bytes = kNumSafepointRegisters >> kBitsPerByteLog2;
     176    10137806 :       for (int j = 0; j < num_reg_bytes; j++) {
     177    20275612 :         bits[j] = SafepointTable::kNoRegisters;
     178             :       }
     179             :     } else {
     180      403860 :       for (int j = 0; j < registers->length(); j++) {
     181      403860 :         int index = registers->at(j);
     182             :         DCHECK(index >= 0 && index < kNumSafepointRegisters);
     183      159432 :         int byte_index = index >> kBitsPerByteLog2;
     184      159432 :         int bit_index = index & (kBitsPerByte - 1);
     185      318864 :         bits[byte_index] |= (1 << bit_index);
     186             :       }
     187             :     }
     188             : 
     189             :     // Run through the indexes and build a bitmap.
     190    26517032 :     for (int j = 0; j < indexes->length(); j++) {
     191    37198599 :       int index = bits_per_entry - 1 - indexes->at(j);
     192    10681567 :       int byte_index = index >> kBitsPerByteLog2;
     193    10681567 :       int bit_index = index & (kBitsPerByte - 1);
     194    21363134 :       bits[byte_index] |= (1U << bit_index);
     195             :     }
     196             : 
     197             :     // Emit the bitmap for the current entry.
     198    37967845 :     for (int k = 0; k < bytes_per_entry; k++) {
     199    75935688 :       assembler->db(bits[k]);
     200             :     }
     201             :   }
     202     1191440 :   emitted_ = true;
     203     1191440 : }
     204             : 
     205             : 
     206           0 : uint32_t SafepointTableBuilder::EncodeExceptPC(const DeoptimizationInfo& info,
     207             :                                                unsigned index) {
     208             :   uint32_t encoding = SafepointEntry::DeoptimizationIndexField::encode(index);
     209    10307794 :   encoding |= SafepointEntry::ArgumentsField::encode(info.arguments);
     210    10307794 :   encoding |= SafepointEntry::SaveDoublesField::encode(info.has_doubles);
     211           0 :   return encoding;
     212             : }
     213             : 
     214             : 
     215             : }  // namespace internal
     216             : }  // namespace v8

Generated by: LCOV version 1.10