blob: 029688ea58f4ec60e489c45743983a781fcf649b [file] [log] [blame]
Ben Murdochc5610432016-08-08 18:44:38 +01001// Copyright 2015 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#include "src/interpreter/bytecode-array-writer.h"
6
7#include <iomanip>
8#include "src/interpreter/source-position-table.h"
9
10namespace v8 {
11namespace internal {
12namespace interpreter {
13
14BytecodeArrayWriter::BytecodeArrayWriter(
15 Zone* zone, SourcePositionTableBuilder* source_position_table_builder)
16 : bytecodes_(zone),
17 max_register_count_(0),
18 source_position_table_builder_(source_position_table_builder) {}
19
20// override
21BytecodeArrayWriter::~BytecodeArrayWriter() {}
22
23// override
24size_t BytecodeArrayWriter::FlushForOffset() { return bytecodes()->size(); }
25
26// override
27void BytecodeArrayWriter::Write(BytecodeNode* node) {
28 UpdateSourcePositionTable(node);
29 EmitBytecode(node);
30}
31
32void BytecodeArrayWriter::UpdateSourcePositionTable(
33 const BytecodeNode* const node) {
34 int bytecode_offset = static_cast<int>(bytecodes()->size());
35 const BytecodeSourceInfo& source_info = node->source_info();
36 if (source_info.is_valid()) {
37 source_position_table_builder_->AddPosition(bytecode_offset,
38 source_info.source_position(),
39 source_info.is_statement());
40 }
41}
42
43void BytecodeArrayWriter::EmitBytecode(const BytecodeNode* const node) {
44 DCHECK_NE(node->bytecode(), Bytecode::kIllegal);
45
46 OperandScale operand_scale = node->operand_scale();
47 if (operand_scale != OperandScale::kSingle) {
48 Bytecode prefix = Bytecodes::OperandScaleToPrefixBytecode(operand_scale);
49 bytecodes()->push_back(Bytecodes::ToByte(prefix));
50 }
51
52 Bytecode bytecode = node->bytecode();
53 bytecodes()->push_back(Bytecodes::ToByte(bytecode));
54
55 int register_operand_bitmap = Bytecodes::GetRegisterOperandBitmap(bytecode);
56 const uint32_t* const operands = node->operands();
57 const OperandType* operand_types = Bytecodes::GetOperandTypes(bytecode);
58 for (int i = 0; operand_types[i] != OperandType::kNone; ++i) {
59 OperandType operand_type = operand_types[i];
60 switch (Bytecodes::SizeOfOperand(operand_type, operand_scale)) {
61 case OperandSize::kNone:
62 UNREACHABLE();
63 break;
64 case OperandSize::kByte:
65 bytecodes()->push_back(static_cast<uint8_t>(operands[i]));
66 break;
67 case OperandSize::kShort: {
68 uint8_t operand_bytes[2];
69 WriteUnalignedUInt16(operand_bytes, operands[i]);
70 bytecodes()->insert(bytecodes()->end(), operand_bytes,
71 operand_bytes + 2);
72 break;
73 }
74 case OperandSize::kQuad: {
75 uint8_t operand_bytes[4];
76 WriteUnalignedUInt32(operand_bytes, operands[i]);
77 bytecodes()->insert(bytecodes()->end(), operand_bytes,
78 operand_bytes + 4);
79 break;
80 }
81 }
82
83 if ((register_operand_bitmap >> i) & 1) {
84 int count;
85 if (operand_types[i + 1] == OperandType::kRegCount) {
86 count = static_cast<int>(operands[i + 1]);
87 } else {
88 count = Bytecodes::GetNumberOfRegistersRepresentedBy(operand_type);
89 }
90 Register reg = Register::FromOperand(static_cast<int32_t>(operands[i]));
91 max_register_count_ = std::max(max_register_count_, reg.index() + count);
92 }
93 }
94}
95
96// override
97void BytecodeArrayWriter::FlushBasicBlock() {}
98
99int BytecodeArrayWriter::GetMaximumFrameSizeUsed() {
100 return max_register_count_ * kPointerSize;
101}
102
103} // namespace interpreter
104} // namespace internal
105} // namespace v8