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|. BytecodeJumpTable(size_t constant_pool_index,int size,int case_value_base,Zone * zone)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 constant_pool_index()37 size_t constant_pool_index() const { return constant_pool_index_; } switch_bytecode_offset()38 size_t switch_bytecode_offset() const { return switch_bytecode_offset_; } case_value_base()39 int case_value_base() const { return case_value_base_; } size()40 int size() const { return size_; } 41 #ifdef DEBUG is_bound(int case_value)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 ConstantPoolEntryFor(int case_value)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 mark_bound(int case_value)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 set_switch_bytecode_offset(size_t offset)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