1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
// Copyright 2015 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_ARRAY_WRITER_H_
#define V8_INTERPRETER_BYTECODE_ARRAY_WRITER_H_
#include "src/base/compiler-specific.h"
#include "src/codegen/source-position-table.h"
#include "src/common/globals.h"
#include "src/interpreter/bytecodes.h"
namespace v8 {
namespace internal {
class BytecodeArray;
class SourcePositionTableBuilder;
namespace interpreter {
class BytecodeLabel;
class BytecodeLoopHeader;
class BytecodeNode;
class BytecodeJumpTable;
class ConstantArrayBuilder;
class HandlerTableBuilder;
namespace bytecode_array_writer_unittest {
class BytecodeArrayWriterUnittest;
} // namespace bytecode_array_writer_unittest
// Class for emitting bytecode as the final stage of the bytecode
// generation pipeline.
class V8_EXPORT_PRIVATE BytecodeArrayWriter final {
public:
BytecodeArrayWriter(
Zone* zone, ConstantArrayBuilder* constant_array_builder,
SourcePositionTableBuilder::RecordingMode source_position_mode);
void Write(BytecodeNode* node);
void WriteJump(BytecodeNode* node, BytecodeLabel* label);
void WriteJumpLoop(BytecodeNode* node, BytecodeLoopHeader* loop_header);
void WriteSwitch(BytecodeNode* node, BytecodeJumpTable* jump_table);
void BindLabel(BytecodeLabel* label);
void BindLoopHeader(BytecodeLoopHeader* loop_header);
void BindJumpTableEntry(BytecodeJumpTable* jump_table, int case_value);
void BindHandlerTarget(HandlerTableBuilder* handler_table_builder,
int handler_id);
void BindTryRegionStart(HandlerTableBuilder* handler_table_builder,
int handler_id);
void BindTryRegionEnd(HandlerTableBuilder* handler_table_builder,
int handler_id);
void SetFunctionEntrySourcePosition(int position);
template <typename LocalIsolate>
EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
Handle<BytecodeArray> ToBytecodeArray(LocalIsolate* isolate,
int register_count, int parameter_count,
Handle<ByteArray> handler_table);
template <typename LocalIsolate>
EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
Handle<ByteArray> ToSourcePositionTable(LocalIsolate* isolate);
#ifdef DEBUG
// Returns -1 if they match or the offset of the first mismatching byte.
int CheckBytecodeMatches(BytecodeArray bytecode);
#endif
bool RemainderOfBlockIsDead() const { return exit_seen_in_block_; }
private:
// Maximum sized packed bytecode is comprised of a prefix bytecode,
// plus the actual bytecode, plus the maximum number of operands times
// the maximum operand size.
static const size_t kMaxSizeOfPackedBytecode =
2 * sizeof(Bytecode) +
Bytecodes::kMaxOperands * static_cast<size_t>(OperandSize::kLast);
// Constants that act as placeholders for jump operands to be
// patched. These have operand sizes that match the sizes of
// reserved constant pool entries.
const uint32_t k8BitJumpPlaceholder = 0x7f;
const uint32_t k16BitJumpPlaceholder =
k8BitJumpPlaceholder | (k8BitJumpPlaceholder << 8);
const uint32_t k32BitJumpPlaceholder =
k16BitJumpPlaceholder | (k16BitJumpPlaceholder << 16);
void PatchJump(size_t jump_target, size_t jump_location);
void PatchJumpWith8BitOperand(size_t jump_location, int delta);
void PatchJumpWith16BitOperand(size_t jump_location, int delta);
void PatchJumpWith32BitOperand(size_t jump_location, int delta);
void EmitBytecode(const BytecodeNode* const node);
void EmitJump(BytecodeNode* node, BytecodeLabel* label);
void EmitJumpLoop(BytecodeNode* node, BytecodeLoopHeader* loop_header);
void EmitSwitch(BytecodeNode* node, BytecodeJumpTable* jump_table);
void UpdateSourcePositionTable(const BytecodeNode* const node);
void UpdateExitSeenInBlock(Bytecode bytecode);
void MaybeElideLastBytecode(Bytecode next_bytecode, bool has_source_info);
void InvalidateLastBytecode();
void StartBasicBlock();
ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; }
SourcePositionTableBuilder* source_position_table_builder() {
return &source_position_table_builder_;
}
ConstantArrayBuilder* constant_array_builder() {
return constant_array_builder_;
}
ZoneVector<uint8_t> bytecodes_;
int unbound_jumps_;
SourcePositionTableBuilder source_position_table_builder_;
ConstantArrayBuilder* constant_array_builder_;
Bytecode last_bytecode_;
size_t last_bytecode_offset_;
bool last_bytecode_had_source_info_;
bool elide_noneffectful_bytecodes_;
bool exit_seen_in_block_;
friend class bytecode_array_writer_unittest::BytecodeArrayWriterUnittest;
DISALLOW_COPY_AND_ASSIGN(BytecodeArrayWriter);
};
} // namespace interpreter
} // namespace internal
} // namespace v8
#endif // V8_INTERPRETER_BYTECODE_ARRAY_WRITER_H_
|