1bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved. 2bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch// found in the LICENSE file. 4bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 5bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#ifndef V8_INTERPRETER_BYTECODE_ARRAY_WRITER_H_ 6bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#define V8_INTERPRETER_BYTECODE_ARRAY_WRITER_H_ 7bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 8c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/base/compiler-specific.h" 9c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/globals.h" 10bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/interpreter/bytecode-pipeline.h" 11f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/source-position-table.h" 12bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 13bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochnamespace v8 { 14bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochnamespace internal { 15f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 16f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass SourcePositionTableBuilder; 17f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 18bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochnamespace interpreter { 19bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 2013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochclass BytecodeLabel; 2113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochclass ConstantArrayBuilder; 22bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 23bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch// Class for emitting bytecode as the final stage of the bytecode 24bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch// generation pipeline. 25c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass V8_EXPORT_PRIVATE BytecodeArrayWriter final 26c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch : public NON_EXPORTED_BASE(BytecodePipelineStage) { 27bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch public: 28f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BytecodeArrayWriter( 29f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Zone* zone, ConstantArrayBuilder* constant_array_builder, 30f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch SourcePositionTableBuilder::RecordingMode source_position_mode); 31bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch virtual ~BytecodeArrayWriter(); 32bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 3313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // BytecodePipelineStage interface. 34bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void Write(BytecodeNode* node) override; 3513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void WriteJump(BytecodeNode* node, BytecodeLabel* label) override; 3613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void BindLabel(BytecodeLabel* label) override; 3713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void BindLabel(const BytecodeLabel& target, BytecodeLabel* label) override; 3813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Handle<BytecodeArray> ToBytecodeArray( 39f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Isolate* isolate, int register_count, int parameter_count, 4013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Handle<FixedArray> handler_table) override; 41bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 4213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch private: 43f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Maximum sized packed bytecode is comprised of a prefix bytecode, 44f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // plus the actual bytecode, plus the maximum number of operands times 45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // the maximum operand size. 46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static const size_t kMaxSizeOfPackedBytecode = 47f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2 * sizeof(Bytecode) + 48f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Bytecodes::kMaxOperands * static_cast<size_t>(OperandSize::kLast); 49f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 5013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Constants that act as placeholders for jump operands to be 5113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // patched. These have operand sizes that match the sizes of 5213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // reserved constant pool entries. 5313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch const uint32_t k8BitJumpPlaceholder = 0x7f; 5413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch const uint32_t k16BitJumpPlaceholder = 5513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch k8BitJumpPlaceholder | (k8BitJumpPlaceholder << 8); 5613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch const uint32_t k32BitJumpPlaceholder = 5713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch k16BitJumpPlaceholder | (k16BitJumpPlaceholder << 16); 58bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 5913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void PatchJump(size_t jump_target, size_t jump_location); 6013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void PatchJumpWith8BitOperand(size_t jump_location, int delta); 6113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void PatchJumpWith16BitOperand(size_t jump_location, int delta); 6213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void PatchJumpWith32BitOperand(size_t jump_location, int delta); 63bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 64bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void EmitBytecode(const BytecodeNode* const node); 6513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void EmitJump(BytecodeNode* node, BytecodeLabel* label); 66bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void UpdateSourcePositionTable(const BytecodeNode* const node); 67bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 6813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; } 6913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SourcePositionTableBuilder* source_position_table_builder() { 7013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return &source_position_table_builder_; 7113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 7213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ConstantArrayBuilder* constant_array_builder() { 7313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return constant_array_builder_; 7413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 7513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 76bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ZoneVector<uint8_t> bytecodes_; 7713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch int unbound_jumps_; 7813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SourcePositionTableBuilder source_position_table_builder_; 7913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ConstantArrayBuilder* constant_array_builder_; 80bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 8113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch friend class BytecodeArrayWriterUnittest; 82bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DISALLOW_COPY_AND_ASSIGN(BytecodeArrayWriter); 83bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}; 84bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 85bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} // namespace interpreter 86bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} // namespace internal 87bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} // namespace v8 88bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 89bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#endif // V8_INTERPRETER_BYTECODE_ARRAY_WRITER_H_ 90