Home | History | Annotate | Download | only in interpreter
      1 // Copyright 2017 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_INTERPRETER_BYTECODE_JUMP_TABLE_H_
      6 #define V8_INTERPRETER_BYTECODE_JUMP_TABLE_H_
      7 
      8 #include "src/bit-vector.h"
      9 #include "src/zone/zone.h"
     10 
     11 namespace v8 {
     12 namespace internal {
     13 namespace interpreter {
     14 
     15 class ConstantArrayBuilder;
     16 
     17 // A jump table for a set of targets in a bytecode array. When an entry in the
     18 // table is bound, it represents a known position in the bytecode array. If no
     19 // entries match, the switch falls through.
     20 class V8_EXPORT_PRIVATE BytecodeJumpTable final : public ZoneObject {
     21  public:
     22   // Constructs a new BytecodeJumpTable starting at |constant_pool_index|, with
     23   // the given |size|, where the case values of the table start at
     24   // |case_value_base|.
     25   BytecodeJumpTable(size_t constant_pool_index, int size, int case_value_base,
     26                     Zone* zone)
     27       :
     28 #ifdef DEBUG
     29         bound_(size, zone),
     30 #endif
     31         constant_pool_index_(constant_pool_index),
     32         switch_bytecode_offset_(kInvalidOffset),
     33         size_(size),
     34         case_value_base_(case_value_base) {
     35   }
     36 
     37   size_t constant_pool_index() const { return constant_pool_index_; }
     38   size_t switch_bytecode_offset() const { return switch_bytecode_offset_; }
     39   int case_value_base() const { return case_value_base_; }
     40   int size() const { return size_; }
     41 #ifdef DEBUG
     42   bool is_bound(int case_value) const {
     43     DCHECK_GE(case_value, case_value_base_);
     44     DCHECK_LT(case_value, case_value_base_ + size());
     45     return bound_.Contains(case_value - case_value_base_);
     46   }
     47 #endif
     48 
     49   size_t ConstantPoolEntryFor(int case_value) {
     50     DCHECK_GE(case_value, case_value_base_);
     51     return constant_pool_index_ + case_value - case_value_base_;
     52   }
     53 
     54  private:
     55   static const size_t kInvalidIndex = static_cast<size_t>(-1);
     56   static const size_t kInvalidOffset = static_cast<size_t>(-1);
     57 
     58   void mark_bound(int case_value) {
     59 #ifdef DEBUG
     60     DCHECK_GE(case_value, case_value_base_);
     61     DCHECK_LT(case_value, case_value_base_ + size());
     62     bound_.Add(case_value - case_value_base_);
     63 #endif
     64   }
     65 
     66   void set_switch_bytecode_offset(size_t offset) {
     67     DCHECK_EQ(switch_bytecode_offset_, kInvalidOffset);
     68     switch_bytecode_offset_ = offset;
     69   }
     70 
     71 #ifdef DEBUG
     72   // This bit vector is only used for DCHECKS, so only store the field in debug
     73   // builds.
     74   BitVector bound_;
     75 #endif
     76   size_t constant_pool_index_;
     77   size_t switch_bytecode_offset_;
     78   int size_;
     79   int case_value_base_;
     80 
     81   friend class BytecodeArrayWriter;
     82 };
     83 
     84 }  // namespace interpreter
     85 }  // namespace internal
     86 }  // namespace v8
     87 
     88 #endif  // V8_INTERPRETER_BYTECODE_JUMP_TABLE_H_
     89