11cb0ef41Sopenharmony_ci// Copyright 2015 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_INTERPRETER_BYTECODE_ARRAY_WRITER_H_ 61cb0ef41Sopenharmony_ci#define V8_INTERPRETER_BYTECODE_ARRAY_WRITER_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "src/base/compiler-specific.h" 91cb0ef41Sopenharmony_ci#include "src/codegen/source-position-table.h" 101cb0ef41Sopenharmony_ci#include "src/common/globals.h" 111cb0ef41Sopenharmony_ci#include "src/interpreter/bytecodes.h" 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_cinamespace v8 { 141cb0ef41Sopenharmony_cinamespace internal { 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ciclass BytecodeArray; 171cb0ef41Sopenharmony_ciclass SourcePositionTableBuilder; 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_cinamespace interpreter { 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ciclass BytecodeLabel; 221cb0ef41Sopenharmony_ciclass BytecodeLoopHeader; 231cb0ef41Sopenharmony_ciclass BytecodeNode; 241cb0ef41Sopenharmony_ciclass BytecodeJumpTable; 251cb0ef41Sopenharmony_ciclass ConstantArrayBuilder; 261cb0ef41Sopenharmony_ciclass HandlerTableBuilder; 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_cinamespace bytecode_array_writer_unittest { 291cb0ef41Sopenharmony_ciclass BytecodeArrayWriterUnittest; 301cb0ef41Sopenharmony_ci} // namespace bytecode_array_writer_unittest 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci// Class for emitting bytecode as the final stage of the bytecode 331cb0ef41Sopenharmony_ci// generation pipeline. 341cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE BytecodeArrayWriter final { 351cb0ef41Sopenharmony_ci public: 361cb0ef41Sopenharmony_ci BytecodeArrayWriter( 371cb0ef41Sopenharmony_ci Zone* zone, ConstantArrayBuilder* constant_array_builder, 381cb0ef41Sopenharmony_ci SourcePositionTableBuilder::RecordingMode source_position_mode); 391cb0ef41Sopenharmony_ci BytecodeArrayWriter(const BytecodeArrayWriter&) = delete; 401cb0ef41Sopenharmony_ci BytecodeArrayWriter& operator=(const BytecodeArrayWriter&) = delete; 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci void Write(BytecodeNode* node); 431cb0ef41Sopenharmony_ci void WriteJump(BytecodeNode* node, BytecodeLabel* label); 441cb0ef41Sopenharmony_ci void WriteJumpLoop(BytecodeNode* node, BytecodeLoopHeader* loop_header); 451cb0ef41Sopenharmony_ci void WriteSwitch(BytecodeNode* node, BytecodeJumpTable* jump_table); 461cb0ef41Sopenharmony_ci void BindLabel(BytecodeLabel* label); 471cb0ef41Sopenharmony_ci void BindLoopHeader(BytecodeLoopHeader* loop_header); 481cb0ef41Sopenharmony_ci void BindJumpTableEntry(BytecodeJumpTable* jump_table, int case_value); 491cb0ef41Sopenharmony_ci void BindHandlerTarget(HandlerTableBuilder* handler_table_builder, 501cb0ef41Sopenharmony_ci int handler_id); 511cb0ef41Sopenharmony_ci void BindTryRegionStart(HandlerTableBuilder* handler_table_builder, 521cb0ef41Sopenharmony_ci int handler_id); 531cb0ef41Sopenharmony_ci void BindTryRegionEnd(HandlerTableBuilder* handler_table_builder, 541cb0ef41Sopenharmony_ci int handler_id); 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci void SetFunctionEntrySourcePosition(int position); 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci template <typename IsolateT> 591cb0ef41Sopenharmony_ci EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) 601cb0ef41Sopenharmony_ci Handle<BytecodeArray> ToBytecodeArray(IsolateT* isolate, int register_count, 611cb0ef41Sopenharmony_ci int parameter_count, 621cb0ef41Sopenharmony_ci Handle<ByteArray> handler_table); 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci template <typename IsolateT> 651cb0ef41Sopenharmony_ci EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) 661cb0ef41Sopenharmony_ci Handle<ByteArray> ToSourcePositionTable(IsolateT* isolate); 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci#ifdef DEBUG 691cb0ef41Sopenharmony_ci // Returns -1 if they match or the offset of the first mismatching byte. 701cb0ef41Sopenharmony_ci int CheckBytecodeMatches(BytecodeArray bytecode); 711cb0ef41Sopenharmony_ci#endif 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci bool RemainderOfBlockIsDead() const { return exit_seen_in_block_; } 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci private: 761cb0ef41Sopenharmony_ci // Maximum sized packed bytecode is comprised of a prefix bytecode, 771cb0ef41Sopenharmony_ci // plus the actual bytecode, plus the maximum number of operands times 781cb0ef41Sopenharmony_ci // the maximum operand size. 791cb0ef41Sopenharmony_ci static const size_t kMaxSizeOfPackedBytecode = 801cb0ef41Sopenharmony_ci 2 * sizeof(Bytecode) + 811cb0ef41Sopenharmony_ci Bytecodes::kMaxOperands * static_cast<size_t>(OperandSize::kLast); 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci // Constants that act as placeholders for jump operands to be 841cb0ef41Sopenharmony_ci // patched. These have operand sizes that match the sizes of 851cb0ef41Sopenharmony_ci // reserved constant pool entries. 861cb0ef41Sopenharmony_ci const uint32_t k8BitJumpPlaceholder = 0x7f; 871cb0ef41Sopenharmony_ci const uint32_t k16BitJumpPlaceholder = 881cb0ef41Sopenharmony_ci k8BitJumpPlaceholder | (k8BitJumpPlaceholder << 8); 891cb0ef41Sopenharmony_ci const uint32_t k32BitJumpPlaceholder = 901cb0ef41Sopenharmony_ci k16BitJumpPlaceholder | (k16BitJumpPlaceholder << 16); 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci void PatchJump(size_t jump_target, size_t jump_location); 931cb0ef41Sopenharmony_ci void PatchJumpWith8BitOperand(size_t jump_location, int delta); 941cb0ef41Sopenharmony_ci void PatchJumpWith16BitOperand(size_t jump_location, int delta); 951cb0ef41Sopenharmony_ci void PatchJumpWith32BitOperand(size_t jump_location, int delta); 961cb0ef41Sopenharmony_ci 971cb0ef41Sopenharmony_ci void EmitBytecode(const BytecodeNode* const node); 981cb0ef41Sopenharmony_ci void EmitJump(BytecodeNode* node, BytecodeLabel* label); 991cb0ef41Sopenharmony_ci void EmitJumpLoop(BytecodeNode* node, BytecodeLoopHeader* loop_header); 1001cb0ef41Sopenharmony_ci void EmitSwitch(BytecodeNode* node, BytecodeJumpTable* jump_table); 1011cb0ef41Sopenharmony_ci void UpdateSourcePositionTable(const BytecodeNode* const node); 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ci void UpdateExitSeenInBlock(Bytecode bytecode); 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ci void MaybeElideLastBytecode(Bytecode next_bytecode, bool has_source_info); 1061cb0ef41Sopenharmony_ci void InvalidateLastBytecode(); 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci void StartBasicBlock(); 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; } 1111cb0ef41Sopenharmony_ci SourcePositionTableBuilder* source_position_table_builder() { 1121cb0ef41Sopenharmony_ci return &source_position_table_builder_; 1131cb0ef41Sopenharmony_ci } 1141cb0ef41Sopenharmony_ci ConstantArrayBuilder* constant_array_builder() { 1151cb0ef41Sopenharmony_ci return constant_array_builder_; 1161cb0ef41Sopenharmony_ci } 1171cb0ef41Sopenharmony_ci 1181cb0ef41Sopenharmony_ci ZoneVector<uint8_t> bytecodes_; 1191cb0ef41Sopenharmony_ci int unbound_jumps_; 1201cb0ef41Sopenharmony_ci SourcePositionTableBuilder source_position_table_builder_; 1211cb0ef41Sopenharmony_ci ConstantArrayBuilder* constant_array_builder_; 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ci Bytecode last_bytecode_; 1241cb0ef41Sopenharmony_ci size_t last_bytecode_offset_; 1251cb0ef41Sopenharmony_ci bool last_bytecode_had_source_info_; 1261cb0ef41Sopenharmony_ci bool elide_noneffectful_bytecodes_; 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_ci bool exit_seen_in_block_; 1291cb0ef41Sopenharmony_ci 1301cb0ef41Sopenharmony_ci friend class bytecode_array_writer_unittest::BytecodeArrayWriterUnittest; 1311cb0ef41Sopenharmony_ci}; 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ci} // namespace interpreter 1341cb0ef41Sopenharmony_ci} // namespace internal 1351cb0ef41Sopenharmony_ci} // namespace v8 1361cb0ef41Sopenharmony_ci 1371cb0ef41Sopenharmony_ci#endif // V8_INTERPRETER_BYTECODE_ARRAY_WRITER_H_ 138