| // Copyright 2017 the V8 project authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef V8_INTERPRETER_BYTECODE_JUMP_TABLE_H_ | |
| #define V8_INTERPRETER_BYTECODE_JUMP_TABLE_H_ | |
| #include "src/bit-vector.h" | |
| #include "src/zone/zone.h" | |
| namespace v8 { | |
| namespace internal { | |
| namespace interpreter { | |
| class ConstantArrayBuilder; | |
| // A jump table for a set of targets in a bytecode array. When an entry in the | |
| // table is bound, it represents a known position in the bytecode array. If no | |
| // entries match, the switch falls through. | |
| class V8_EXPORT_PRIVATE BytecodeJumpTable final : public ZoneObject { | |
| public: | |
| // Constructs a new BytecodeJumpTable starting at |constant_pool_index|, with | |
| // the given |size|, where the case values of the table start at | |
| // |case_value_base|. | |
| BytecodeJumpTable(size_t constant_pool_index, int size, int case_value_base, | |
| Zone* zone) | |
| : | |
| #ifdef DEBUG | |
| bound_(size, zone), | |
| #endif | |
| constant_pool_index_(constant_pool_index), | |
| switch_bytecode_offset_(kInvalidOffset), | |
| size_(size), | |
| case_value_base_(case_value_base) { | |
| } | |
| size_t constant_pool_index() const { return constant_pool_index_; } | |
| size_t switch_bytecode_offset() const { return switch_bytecode_offset_; } | |
| int case_value_base() const { return case_value_base_; } | |
| int size() const { return size_; } | |
| #ifdef DEBUG | |
| bool is_bound(int case_value) const { | |
| DCHECK_GE(case_value, case_value_base_); | |
| DCHECK_LT(case_value, case_value_base_ + size()); | |
| return bound_.Contains(case_value - case_value_base_); | |
| } | |
| #endif | |
| size_t ConstantPoolEntryFor(int case_value) { | |
| DCHECK_GE(case_value, case_value_base_); | |
| return constant_pool_index_ + case_value - case_value_base_; | |
| } | |
| private: | |
| static const size_t kInvalidIndex = static_cast<size_t>(-1); | |
| static const size_t kInvalidOffset = static_cast<size_t>(-1); | |
| void mark_bound(int case_value) { | |
| #ifdef DEBUG | |
| DCHECK_GE(case_value, case_value_base_); | |
| DCHECK_LT(case_value, case_value_base_ + size()); | |
| bound_.Add(case_value - case_value_base_); | |
| #endif | |
| } | |
| void set_switch_bytecode_offset(size_t offset) { | |
| DCHECK_EQ(switch_bytecode_offset_, kInvalidOffset); | |
| switch_bytecode_offset_ = offset; | |
| } | |
| #ifdef DEBUG | |
| // This bit vector is only used for DCHECKS, so only store the field in debug | |
| // builds. | |
| BitVector bound_; | |
| #endif | |
| size_t constant_pool_index_; | |
| size_t switch_bytecode_offset_; | |
| int size_; | |
| int case_value_base_; | |
| friend class BytecodeArrayWriter; | |
| }; | |
| } // namespace interpreter | |
| } // namespace internal | |
| } // namespace v8 | |
| #endif // V8_INTERPRETER_BYTECODE_JUMP_TABLE_H_ |