LCOV - code coverage report
Current view: top level - src - handler-table.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 73 79 92.4 %
Date: 2019-01-20 Functions: 20 24 83.3 %

          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/handler-table.h"
       6             : 
       7             : #include <iomanip>
       8             : 
       9             : #include "src/assembler-inl.h"
      10             : #include "src/objects-inl.h"
      11             : #include "src/objects/code-inl.h"
      12             : 
      13             : namespace v8 {
      14             : namespace internal {
      15             : 
      16     3595984 : HandlerTable::HandlerTable(Code code)
      17     7191968 :     : HandlerTable(code->InstructionStart(), code->handler_table_offset()) {}
      18             : 
      19    35865116 : HandlerTable::HandlerTable(BytecodeArray bytecode_array)
      20    35865116 :     : HandlerTable(bytecode_array->handler_table()) {}
      21             : 
      22    37970924 : HandlerTable::HandlerTable(ByteArray byte_array)
      23    37970938 :     : number_of_entries_(byte_array->length() / kRangeEntrySize /
      24             :                          sizeof(int32_t)),
      25             : #ifdef DEBUG
      26             :       mode_(kRangeBasedEncoding),
      27             : #endif
      28             :       raw_encoded_data_(
      29    75941876 :           reinterpret_cast<Address>(byte_array->GetDataStartAddress())) {
      30    37970938 : }
      31             : 
      32         792 : HandlerTable::HandlerTable(Address instruction_start,
      33             :                            size_t handler_table_offset)
      34             :     : number_of_entries_(0),
      35             : #ifdef DEBUG
      36             :       mode_(kReturnAddressBasedEncoding),
      37             : #endif
      38     3596776 :       raw_encoded_data_(instruction_start + handler_table_offset) {
      39     3596776 :   if (handler_table_offset > 0) {
      40      619330 :     number_of_entries_ = Memory<int32_t>(raw_encoded_data_);
      41      619330 :     raw_encoded_data_ += sizeof(int32_t);
      42             :   }
      43         792 : }
      44             : 
      45     1342141 : int HandlerTable::GetRangeStart(int index) const {
      46             :   DCHECK_EQ(kRangeBasedEncoding, mode_);
      47             :   DCHECK_LT(index, NumberOfRangeEntries());
      48    11183474 :   int offset = index * kRangeEntrySize + kRangeStartIndex;
      49    22366948 :   return Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t));
      50             : }
      51             : 
      52       29825 : int HandlerTable::GetRangeEnd(int index) const {
      53             :   DCHECK_EQ(kRangeBasedEncoding, mode_);
      54             :   DCHECK_LT(index, NumberOfRangeEntries());
      55     9871158 :   int offset = index * kRangeEntrySize + kRangeEndIndex;
      56    19742316 :   return Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t));
      57             : }
      58             : 
      59       29825 : int HandlerTable::GetRangeHandler(int index) const {
      60             :   DCHECK_EQ(kRangeBasedEncoding, mode_);
      61             :   DCHECK_LT(index, NumberOfRangeEntries());
      62     9871158 :   int offset = index * kRangeEntrySize + kRangeHandlerIndex;
      63             :   return HandlerOffsetField::decode(
      64    19772141 :       Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t)));
      65             : }
      66             : 
      67       29490 : int HandlerTable::GetRangeData(int index) const {
      68             :   DCHECK_EQ(kRangeBasedEncoding, mode_);
      69             :   DCHECK_LT(index, NumberOfRangeEntries());
      70     9870823 :   int offset = index * kRangeEntrySize + kRangeDataIndex;
      71    19741646 :   return Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t));
      72             : }
      73             : 
      74           0 : HandlerTable::CatchPrediction HandlerTable::GetRangePrediction(
      75             :     int index) const {
      76             :   DCHECK_EQ(kRangeBasedEncoding, mode_);
      77             :   DCHECK_LT(index, NumberOfRangeEntries());
      78           0 :   int offset = index * kRangeEntrySize + kRangeHandlerIndex;
      79             :   return HandlerPredictionField::decode(
      80           0 :       Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t)));
      81             : }
      82             : 
      83           0 : int HandlerTable::GetReturnOffset(int index) const {
      84             :   DCHECK_EQ(kReturnAddressBasedEncoding, mode_);
      85             :   DCHECK_LT(index, NumberOfReturnEntries());
      86     1344183 :   int offset = index * kReturnEntrySize + kReturnOffsetIndex;
      87     2688366 :   return Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t));
      88             : }
      89             : 
      90           0 : int HandlerTable::GetReturnHandler(int index) const {
      91             :   DCHECK_EQ(kReturnAddressBasedEncoding, mode_);
      92             :   DCHECK_LT(index, NumberOfReturnEntries());
      93      518355 :   int offset = index * kReturnEntrySize + kReturnHandlerIndex;
      94             :   return HandlerOffsetField::decode(
      95     1036710 :       Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t)));
      96             : }
      97             : 
      98      147032 : void HandlerTable::SetRangeStart(int index, int value) {
      99      147032 :   int offset = index * kRangeEntrySize + kRangeStartIndex;
     100      294064 :   Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t)) = value;
     101      147032 : }
     102             : 
     103      147033 : void HandlerTable::SetRangeEnd(int index, int value) {
     104      147033 :   int offset = index * kRangeEntrySize + kRangeEndIndex;
     105      294066 :   Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t)) = value;
     106      147033 : }
     107             : 
     108      147035 : void HandlerTable::SetRangeHandler(int index, int handler_offset,
     109             :                                    CatchPrediction prediction) {
     110      147035 :   int value = HandlerOffsetField::encode(handler_offset) |
     111      147035 :               HandlerPredictionField::encode(prediction);
     112      147035 :   int offset = index * kRangeEntrySize + kRangeHandlerIndex;
     113      294070 :   Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t)) = value;
     114      147035 : }
     115             : 
     116      147036 : void HandlerTable::SetRangeData(int index, int value) {
     117      147036 :   int offset = index * kRangeEntrySize + kRangeDataIndex;
     118      294072 :   Memory<int32_t>(raw_encoded_data_ + offset * sizeof(int32_t)) = value;
     119      147036 : }
     120             : 
     121             : // static
     122     2105786 : int HandlerTable::LengthForRange(int entries) {
     123     2105786 :   return entries * kRangeEntrySize * sizeof(int32_t);
     124             : }
     125             : 
     126             : // static
     127       19881 : int HandlerTable::EmitReturnTableStart(Assembler* masm, int entries) {
     128       19881 :   masm->DataAlign(sizeof(int32_t));  // Make sure entries are aligned.
     129       19881 :   masm->RecordComment(";;; Exception handler table.");
     130             :   int table_start = masm->pc_offset();
     131       19881 :   masm->dd(entries);
     132       19881 :   return table_start;
     133             : }
     134             : 
     135             : // static
     136      189558 : void HandlerTable::EmitReturnEntry(Assembler* masm, int offset, int handler) {
     137      189558 :   masm->dd(offset);
     138      189559 :   masm->dd(HandlerOffsetField::encode(handler));
     139      189560 : }
     140             : 
     141    15556352 : int HandlerTable::NumberOfRangeEntries() const {
     142             :   DCHECK_EQ(kRangeBasedEncoding, mode_);
     143    45706470 :   return number_of_entries_;
     144             : }
     145             : 
     146           0 : int HandlerTable::NumberOfReturnEntries() const {
     147             :   DCHECK_EQ(kReturnAddressBasedEncoding, mode_);
     148     4422604 :   return number_of_entries_;
     149             : }
     150             : 
     151    20308785 : int HandlerTable::LookupRange(int pc_offset, int* data_out,
     152             :                               CatchPrediction* prediction_out) {
     153             :   int innermost_handler = -1;
     154             : #ifdef DEBUG
     155             :   // Assuming that ranges are well nested, we don't need to track the innermost
     156             :   // offsets. This is just to verify that the table is actually well nested.
     157             :   int innermost_start = std::numeric_limits<int>::min();
     158             :   int innermost_end = std::numeric_limits<int>::max();
     159             : #endif
     160    60300236 :   for (int i = 0; i < NumberOfRangeEntries(); ++i) {
     161             :     int start_offset = GetRangeStart(i);
     162             :     int end_offset = GetRangeEnd(i);
     163             :     int handler_offset = GetRangeHandler(i);
     164             :     int handler_data = GetRangeData(i);
     165             :     CatchPrediction prediction = GetRangePrediction(i);
     166     9841333 :     if (pc_offset >= start_offset && pc_offset < end_offset) {
     167             :       DCHECK_GE(start_offset, innermost_start);
     168             :       DCHECK_LT(end_offset, innermost_end);
     169             :       innermost_handler = handler_offset;
     170             : #ifdef DEBUG
     171             :       innermost_start = start_offset;
     172             :       innermost_end = end_offset;
     173             : #endif
     174     1410842 :       if (data_out) *data_out = handler_data;
     175     1410842 :       if (prediction_out) *prediction_out = prediction;
     176             :     }
     177             :   }
     178    20308785 :   return innermost_handler;
     179             : }
     180             : 
     181             : // TODO(turbofan): Make sure table is sorted and use binary search.
     182     3596776 : int HandlerTable::LookupReturn(int pc_offset) {
     183     8845208 :   for (int i = 0; i < NumberOfReturnEntries(); ++i) {
     184             :     int return_offset = GetReturnOffset(i);
     185     1344183 :     if (pc_offset == return_offset) {
     186      518355 :       return GetReturnHandler(i);
     187             :     }
     188             :   }
     189             :   return -1;
     190             : }
     191             : 
     192             : #ifdef ENABLE_DISASSEMBLER
     193             : 
     194             : void HandlerTable::HandlerTableRangePrint(std::ostream& os) {
     195             :   os << "   from   to       hdlr (prediction,   data)\n";
     196             :   for (int i = 0; i < NumberOfRangeEntries(); ++i) {
     197             :     int pc_start = GetRangeStart(i);
     198             :     int pc_end = GetRangeEnd(i);
     199             :     int handler_offset = GetRangeHandler(i);
     200             :     int handler_data = GetRangeData(i);
     201             :     CatchPrediction prediction = GetRangePrediction(i);
     202             :     os << "  (" << std::setw(4) << pc_start << "," << std::setw(4) << pc_end
     203             :        << ")  ->  " << std::setw(4) << handler_offset
     204             :        << " (prediction=" << prediction << ", data=" << handler_data << ")\n";
     205             :   }
     206             : }
     207             : 
     208             : void HandlerTable::HandlerTableReturnPrint(std::ostream& os) {
     209             :   os << "  offset   handler\n";
     210             :   for (int i = 0; i < NumberOfReturnEntries(); ++i) {
     211             :     int pc_offset = GetReturnOffset(i);
     212             :     int handler_offset = GetReturnHandler(i);
     213             :     os << std::hex << "    " << std::setw(4) << pc_offset << "  ->  "
     214             :        << std::setw(4) << handler_offset << std::dec << "\n";
     215             :   }
     216             : }
     217             : 
     218             : #endif  // ENABLE_DISASSEMBLER
     219             : 
     220             : }  // namespace internal
     221      183867 : }  // namespace v8

Generated by: LCOV version 1.10