OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/interpreter/bytecode-array-builder.h" | 5 #include "src/interpreter/bytecode-array-builder.h" |
| 6 |
6 #include "src/compiler.h" | 7 #include "src/compiler.h" |
| 8 #include "src/interpreter/bytecode-array-writer.h" |
| 9 #include "src/interpreter/bytecode-peephole-optimizer.h" |
7 #include "src/interpreter/interpreter-intrinsics.h" | 10 #include "src/interpreter/interpreter-intrinsics.h" |
8 | 11 |
9 namespace v8 { | 12 namespace v8 { |
10 namespace internal { | 13 namespace internal { |
11 namespace interpreter { | 14 namespace interpreter { |
12 | 15 |
13 class BytecodeArrayBuilder::PreviousBytecodeHelper BASE_EMBEDDED { | |
14 public: | |
15 explicit PreviousBytecodeHelper(const BytecodeArrayBuilder& array_builder) | |
16 : array_builder_(array_builder), | |
17 previous_bytecode_start_(array_builder_.last_bytecode_start_) { | |
18 // This helper is expected to be instantiated only when the last bytecode is | |
19 // in the same basic block. | |
20 DCHECK(array_builder_.LastBytecodeInSameBlock()); | |
21 bytecode_ = Bytecodes::FromByte( | |
22 array_builder_.bytecodes()->at(previous_bytecode_start_)); | |
23 operand_scale_ = OperandScale::kSingle; | |
24 if (Bytecodes::IsPrefixScalingBytecode(bytecode_)) { | |
25 operand_scale_ = Bytecodes::PrefixBytecodeToOperandScale(bytecode_); | |
26 bytecode_ = Bytecodes::FromByte( | |
27 array_builder_.bytecodes()->at(previous_bytecode_start_ + 1)); | |
28 } | |
29 } | |
30 | |
31 // Returns the previous bytecode in the same basic block. | |
32 MUST_USE_RESULT Bytecode GetBytecode() const { | |
33 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_); | |
34 return bytecode_; | |
35 } | |
36 | |
37 MUST_USE_RESULT Register GetRegisterOperand(int operand_index) const { | |
38 return Register::FromOperand(GetSignedOperand(operand_index)); | |
39 } | |
40 | |
41 MUST_USE_RESULT uint32_t GetIndexOperand(int operand_index) const { | |
42 return GetUnsignedOperand(operand_index); | |
43 } | |
44 | |
45 Handle<Object> GetConstantForIndexOperand(int operand_index) const { | |
46 return array_builder_.constant_array_builder()->At( | |
47 GetIndexOperand(operand_index)); | |
48 } | |
49 | |
50 private: | |
51 // Returns the signed operand at operand_index for the previous | |
52 // bytecode in the same basic block. | |
53 MUST_USE_RESULT int32_t GetSignedOperand(int operand_index) const { | |
54 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_); | |
55 OperandType operand_type = | |
56 Bytecodes::GetOperandType(bytecode_, operand_index); | |
57 DCHECK(!Bytecodes::IsUnsignedOperandType(operand_type)); | |
58 const uint8_t* operand_start = GetOperandStart(operand_index); | |
59 return Bytecodes::DecodeSignedOperand(operand_start, operand_type, | |
60 operand_scale_); | |
61 } | |
62 | |
63 // Returns the unsigned operand at operand_index for the previous | |
64 // bytecode in the same basic block. | |
65 MUST_USE_RESULT uint32_t GetUnsignedOperand(int operand_index) const { | |
66 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_); | |
67 OperandType operand_type = | |
68 Bytecodes::GetOperandType(bytecode_, operand_index); | |
69 DCHECK(Bytecodes::IsUnsignedOperandType(operand_type)); | |
70 const uint8_t* operand_start = GetOperandStart(operand_index); | |
71 return Bytecodes::DecodeUnsignedOperand(operand_start, operand_type, | |
72 operand_scale_); | |
73 } | |
74 | |
75 const uint8_t* GetOperandStart(int operand_index) const { | |
76 size_t operand_offset = | |
77 previous_bytecode_start_ + prefix_offset() + | |
78 Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale_); | |
79 return &(*array_builder_.bytecodes())[0] + operand_offset; | |
80 } | |
81 | |
82 int prefix_offset() const { | |
83 return Bytecodes::OperandScaleRequiresPrefixBytecode(operand_scale_) ? 1 | |
84 : 0; | |
85 } | |
86 | |
87 const BytecodeArrayBuilder& array_builder_; | |
88 OperandScale operand_scale_; | |
89 Bytecode bytecode_; | |
90 size_t previous_bytecode_start_; | |
91 | |
92 DISALLOW_COPY_AND_ASSIGN(PreviousBytecodeHelper); | |
93 }; | |
94 | |
95 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone, | 16 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone, |
96 int parameter_count, | 17 int parameter_count, |
97 int context_count, int locals_count, | 18 int context_count, int locals_count, |
98 FunctionLiteral* literal) | 19 FunctionLiteral* literal) |
99 : isolate_(isolate), | 20 : isolate_(isolate), |
100 zone_(zone), | 21 zone_(zone), |
101 bytecodes_(zone), | |
102 bytecode_generated_(false), | 22 bytecode_generated_(false), |
103 constant_array_builder_(isolate, zone), | 23 constant_array_builder_(isolate, zone), |
104 handler_table_builder_(isolate, zone), | 24 handler_table_builder_(isolate, zone), |
105 source_position_table_builder_(isolate, zone), | 25 source_position_table_builder_(isolate, zone), |
106 last_block_end_(0), | |
107 last_bytecode_start_(~0), | |
108 exit_seen_in_block_(false), | 26 exit_seen_in_block_(false), |
109 unbound_jumps_(0), | 27 unbound_jumps_(0), |
110 parameter_count_(parameter_count), | 28 parameter_count_(parameter_count), |
111 local_register_count_(locals_count), | 29 local_register_count_(locals_count), |
112 context_register_count_(context_count), | 30 context_register_count_(context_count), |
113 temporary_allocator_(zone, fixed_register_count()) { | 31 temporary_allocator_(zone, fixed_register_count()), |
| 32 bytecode_array_writer_(zone, &source_position_table_builder_), |
| 33 pipeline_(&bytecode_array_writer_) { |
114 DCHECK_GE(parameter_count_, 0); | 34 DCHECK_GE(parameter_count_, 0); |
115 DCHECK_GE(context_register_count_, 0); | 35 DCHECK_GE(context_register_count_, 0); |
116 DCHECK_GE(local_register_count_, 0); | 36 DCHECK_GE(local_register_count_, 0); |
| 37 |
| 38 if (FLAG_ignition_peephole) { |
| 39 pipeline_ = new (zone) |
| 40 BytecodePeepholeOptimizer(&constant_array_builder_, pipeline_); |
| 41 } |
| 42 |
117 return_position_ = | 43 return_position_ = |
118 literal ? std::max(literal->start_position(), literal->end_position() - 1) | 44 literal ? std::max(literal->start_position(), literal->end_position() - 1) |
119 : RelocInfo::kNoPosition; | 45 : RelocInfo::kNoPosition; |
120 LOG_CODE_EVENT(isolate_, CodeStartLinePosInfoRecordEvent( | 46 LOG_CODE_EVENT(isolate_, CodeStartLinePosInfoRecordEvent( |
121 source_position_table_builder())); | 47 source_position_table_builder())); |
122 } | 48 } |
123 | 49 |
124 Register BytecodeArrayBuilder::first_context_register() const { | 50 Register BytecodeArrayBuilder::first_context_register() const { |
125 DCHECK_GT(context_register_count_, 0); | 51 DCHECK_GT(context_register_count_, 0); |
126 return Register(local_register_count_); | 52 return Register(local_register_count_); |
(...skipping 15 matching lines...) Expand all Loading... |
142 bool BytecodeArrayBuilder::RegisterIsParameterOrLocal(Register reg) const { | 68 bool BytecodeArrayBuilder::RegisterIsParameterOrLocal(Register reg) const { |
143 return reg.is_parameter() || reg.index() < locals_count(); | 69 return reg.is_parameter() || reg.index() < locals_count(); |
144 } | 70 } |
145 | 71 |
146 | 72 |
147 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { | 73 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { |
148 DCHECK_EQ(0, unbound_jumps_); | 74 DCHECK_EQ(0, unbound_jumps_); |
149 DCHECK_EQ(bytecode_generated_, false); | 75 DCHECK_EQ(bytecode_generated_, false); |
150 DCHECK(exit_seen_in_block_); | 76 DCHECK(exit_seen_in_block_); |
151 | 77 |
152 int bytecode_size = static_cast<int>(bytecodes_.size()); | 78 pipeline()->FlushBasicBlock(); |
153 int register_count = fixed_and_temporary_register_count(); | 79 const ZoneVector<uint8_t>* bytecodes = bytecode_array_writer()->bytecodes(); |
154 int frame_size = register_count * kPointerSize; | 80 |
| 81 int bytecode_size = static_cast<int>(bytecodes->size()); |
| 82 |
| 83 // All locals need a frame slot for the debugger, but may not be |
| 84 // present in generated code. |
| 85 int frame_size_for_locals = fixed_register_count() * kPointerSize; |
| 86 int frame_size_used = bytecode_array_writer()->GetMaximumFrameSizeUsed(); |
| 87 int frame_size = std::max(frame_size_for_locals, frame_size_used); |
155 Handle<FixedArray> constant_pool = constant_array_builder()->ToFixedArray(); | 88 Handle<FixedArray> constant_pool = constant_array_builder()->ToFixedArray(); |
156 Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable(); | 89 Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable(); |
157 Handle<ByteArray> source_position_table = | 90 Handle<ByteArray> source_position_table = |
158 source_position_table_builder()->ToSourcePositionTable(); | 91 source_position_table_builder()->ToSourcePositionTable(); |
159 Handle<BytecodeArray> bytecode_array = isolate_->factory()->NewBytecodeArray( | 92 Handle<BytecodeArray> bytecode_array = isolate_->factory()->NewBytecodeArray( |
160 bytecode_size, &bytecodes_.front(), frame_size, parameter_count(), | 93 bytecode_size, &bytecodes->front(), frame_size, parameter_count(), |
161 constant_pool); | 94 constant_pool); |
162 bytecode_array->set_handler_table(*handler_table); | 95 bytecode_array->set_handler_table(*handler_table); |
163 bytecode_array->set_source_position_table(*source_position_table); | 96 bytecode_array->set_source_position_table(*source_position_table); |
164 | 97 |
165 void* line_info = source_position_table_builder()->DetachJITHandlerData(); | 98 void* line_info = source_position_table_builder()->DetachJITHandlerData(); |
166 LOG_CODE_EVENT(isolate_, CodeEndLinePosInfoRecordEvent( | 99 LOG_CODE_EVENT(isolate_, CodeEndLinePosInfoRecordEvent( |
167 AbstractCode::cast(*bytecode_array), line_info)); | 100 AbstractCode::cast(*bytecode_array), line_info)); |
168 | 101 |
169 bytecode_generated_ = true; | 102 bytecode_generated_ = true; |
170 return bytecode_array; | 103 return bytecode_array; |
171 } | 104 } |
172 | 105 |
173 template <size_t N> | 106 void BytecodeArrayBuilder::AttachSourceInfo(BytecodeNode* node) { |
174 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t (&operands)[N], | 107 if (latest_source_info_.is_valid()) { |
175 OperandScale operand_scale) { | 108 node->source_info().Update(latest_source_info_); |
176 // Don't output dead code. | 109 latest_source_info_.set_invalid(); |
177 if (exit_seen_in_block_) return; | |
178 | |
179 int operand_count = static_cast<int>(N); | |
180 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count); | |
181 | |
182 last_bytecode_start_ = bytecodes()->size(); | |
183 // Emit prefix bytecode for scale if required. | |
184 if (Bytecodes::OperandScaleRequiresPrefixBytecode(operand_scale)) { | |
185 bytecodes()->push_back(Bytecodes::ToByte( | |
186 Bytecodes::OperandScaleToPrefixBytecode(operand_scale))); | |
187 } | |
188 | |
189 // Emit bytecode. | |
190 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); | |
191 | |
192 // Emit operands. | |
193 for (int i = 0; i < operand_count; i++) { | |
194 DCHECK(OperandIsValid(bytecode, operand_scale, i, operands[i])); | |
195 switch (Bytecodes::GetOperandSize(bytecode, i, operand_scale)) { | |
196 case OperandSize::kNone: | |
197 UNREACHABLE(); | |
198 break; | |
199 case OperandSize::kByte: | |
200 bytecodes()->push_back(static_cast<uint8_t>(operands[i])); | |
201 break; | |
202 case OperandSize::kShort: { | |
203 uint8_t operand_bytes[2]; | |
204 WriteUnalignedUInt16(operand_bytes, operands[i]); | |
205 bytecodes()->insert(bytecodes()->end(), operand_bytes, | |
206 operand_bytes + 2); | |
207 break; | |
208 } | |
209 case OperandSize::kQuad: { | |
210 uint8_t operand_bytes[4]; | |
211 WriteUnalignedUInt32(operand_bytes, operands[i]); | |
212 bytecodes()->insert(bytecodes()->end(), operand_bytes, | |
213 operand_bytes + 4); | |
214 break; | |
215 } | |
216 } | |
217 } | 110 } |
218 } | 111 } |
219 | 112 |
220 void BytecodeArrayBuilder::Output(Bytecode bytecode) { | 113 void BytecodeArrayBuilder::Output(Bytecode bytecode) { |
221 // Don't output dead code. | 114 // Don't output dead code. |
222 if (exit_seen_in_block_) return; | 115 if (exit_seen_in_block_) return; |
223 | 116 |
224 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); | 117 BytecodeNode node(bytecode); |
225 last_bytecode_start_ = bytecodes()->size(); | 118 AttachSourceInfo(&node); |
226 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); | 119 pipeline()->Write(&node); |
227 } | 120 } |
228 | 121 |
229 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, | 122 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, |
230 OperandScale operand_scale, | 123 OperandScale operand_scale, |
231 uint32_t operand0, uint32_t operand1, | 124 uint32_t operand0, uint32_t operand1, |
232 uint32_t operand2, uint32_t operand3) { | 125 uint32_t operand2, uint32_t operand3) { |
233 uint32_t operands[] = {operand0, operand1, operand2, operand3}; | 126 // Don't output dead code. |
234 Output(bytecode, operands, operand_scale); | 127 if (exit_seen_in_block_) return; |
| 128 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0)); |
| 129 DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1)); |
| 130 DCHECK(OperandIsValid(bytecode, operand_scale, 2, operand2)); |
| 131 DCHECK(OperandIsValid(bytecode, operand_scale, 3, operand3)); |
| 132 BytecodeNode node(bytecode, operand0, operand1, operand2, operand3, |
| 133 operand_scale); |
| 134 AttachSourceInfo(&node); |
| 135 pipeline()->Write(&node); |
235 } | 136 } |
236 | 137 |
237 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, | 138 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, |
238 OperandScale operand_scale, | 139 OperandScale operand_scale, |
239 uint32_t operand0, uint32_t operand1, | 140 uint32_t operand0, uint32_t operand1, |
240 uint32_t operand2) { | 141 uint32_t operand2) { |
241 uint32_t operands[] = {operand0, operand1, operand2}; | 142 // Don't output dead code. |
242 Output(bytecode, operands, operand_scale); | 143 if (exit_seen_in_block_) return; |
| 144 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0)); |
| 145 DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1)); |
| 146 DCHECK(OperandIsValid(bytecode, operand_scale, 2, operand2)); |
| 147 BytecodeNode node(bytecode, operand0, operand1, operand2, operand_scale); |
| 148 AttachSourceInfo(&node); |
| 149 pipeline()->Write(&node); |
243 } | 150 } |
244 | 151 |
245 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, | 152 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, |
246 OperandScale operand_scale, | 153 OperandScale operand_scale, |
247 uint32_t operand0, uint32_t operand1) { | 154 uint32_t operand0, uint32_t operand1) { |
248 uint32_t operands[] = {operand0, operand1}; | 155 // Don't output dead code. |
249 Output(bytecode, operands, operand_scale); | 156 if (exit_seen_in_block_) return; |
| 157 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0)); |
| 158 DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1)); |
| 159 BytecodeNode node(bytecode, operand0, operand1, operand_scale); |
| 160 AttachSourceInfo(&node); |
| 161 pipeline()->Write(&node); |
250 } | 162 } |
251 | 163 |
252 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, | 164 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, |
253 OperandScale operand_scale, | 165 OperandScale operand_scale, |
254 uint32_t operand0) { | 166 uint32_t operand0) { |
255 uint32_t operands[] = {operand0}; | 167 // Don't output dead code. |
256 Output(bytecode, operands, operand_scale); | 168 if (exit_seen_in_block_) return; |
| 169 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0)); |
| 170 BytecodeNode node(bytecode, operand0, operand_scale); |
| 171 AttachSourceInfo(&node); |
| 172 pipeline()->Write(&node); |
257 } | 173 } |
258 | 174 |
259 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, | 175 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, |
260 Register reg) { | 176 Register reg) { |
261 OperandScale operand_scale = OperandSizesToScale(reg.SizeOfOperand()); | 177 OperandScale operand_scale = |
| 178 Bytecodes::OperandSizesToScale(reg.SizeOfOperand()); |
262 OutputScaled(BytecodeForBinaryOperation(op), operand_scale, | 179 OutputScaled(BytecodeForBinaryOperation(op), operand_scale, |
263 RegisterOperand(reg)); | 180 RegisterOperand(reg)); |
264 return *this; | 181 return *this; |
265 } | 182 } |
266 | 183 |
267 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op) { | 184 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op) { |
268 Output(BytecodeForCountOperation(op)); | 185 Output(BytecodeForCountOperation(op)); |
269 return *this; | 186 return *this; |
270 } | 187 } |
271 | 188 |
272 | 189 |
273 BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() { | 190 BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() { |
274 Output(Bytecode::kLogicalNot); | 191 Output(Bytecode::kLogicalNot); |
275 return *this; | 192 return *this; |
276 } | 193 } |
277 | 194 |
278 | 195 |
279 BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() { | 196 BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() { |
280 Output(Bytecode::kTypeOf); | 197 Output(Bytecode::kTypeOf); |
281 return *this; | 198 return *this; |
282 } | 199 } |
283 | 200 |
284 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(Token::Value op, | 201 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(Token::Value op, |
285 Register reg) { | 202 Register reg) { |
286 OperandScale operand_scale = OperandSizesToScale(reg.SizeOfOperand()); | 203 OperandScale operand_scale = |
| 204 Bytecodes::OperandSizesToScale(reg.SizeOfOperand()); |
287 OutputScaled(BytecodeForCompareOperation(op), operand_scale, | 205 OutputScaled(BytecodeForCompareOperation(op), operand_scale, |
288 RegisterOperand(reg)); | 206 RegisterOperand(reg)); |
289 return *this; | 207 return *this; |
290 } | 208 } |
291 | 209 |
292 | 210 |
293 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( | 211 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( |
294 v8::internal::Smi* smi) { | 212 v8::internal::Smi* smi) { |
295 int32_t raw_smi = smi->value(); | 213 int32_t raw_smi = smi->value(); |
296 if (raw_smi == 0) { | 214 if (raw_smi == 0) { |
297 Output(Bytecode::kLdaZero); | 215 Output(Bytecode::kLdaZero); |
298 } else { | 216 } else { |
299 OperandSize operand_size = SizeForSignedOperand(raw_smi); | 217 OperandSize operand_size = Bytecodes::SizeForSignedOperand(raw_smi); |
300 OperandScale operand_scale = OperandSizesToScale(operand_size); | 218 OperandScale operand_scale = Bytecodes::OperandSizesToScale(operand_size); |
301 OutputScaled(Bytecode::kLdaSmi, operand_scale, | 219 OutputScaled(Bytecode::kLdaSmi, operand_scale, |
302 SignedOperand(raw_smi, operand_size)); | 220 SignedOperand(raw_smi, operand_size)); |
303 } | 221 } |
304 return *this; | 222 return *this; |
305 } | 223 } |
306 | 224 |
307 | 225 |
308 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(Handle<Object> object) { | 226 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(Handle<Object> object) { |
309 size_t entry = GetConstantPoolEntry(object); | 227 size_t entry = GetConstantPoolEntry(object); |
310 OperandScale operand_scale = | 228 OperandScale operand_scale = |
311 OperandSizesToScale(SizeForUnsignedOperand(entry)); | 229 Bytecodes::OperandSizesToScale(Bytecodes::SizeForUnsignedOperand(entry)); |
312 OutputScaled(Bytecode::kLdaConstant, operand_scale, UnsignedOperand(entry)); | 230 OutputScaled(Bytecode::kLdaConstant, operand_scale, UnsignedOperand(entry)); |
313 return *this; | 231 return *this; |
314 } | 232 } |
315 | 233 |
316 | 234 |
317 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadUndefined() { | 235 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadUndefined() { |
318 Output(Bytecode::kLdaUndefined); | 236 Output(Bytecode::kLdaUndefined); |
319 return *this; | 237 return *this; |
320 } | 238 } |
321 | 239 |
(...skipping 16 matching lines...) Expand all Loading... |
338 } | 256 } |
339 | 257 |
340 | 258 |
341 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() { | 259 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() { |
342 Output(Bytecode::kLdaFalse); | 260 Output(Bytecode::kLdaFalse); |
343 return *this; | 261 return *this; |
344 } | 262 } |
345 | 263 |
346 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( | 264 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( |
347 Register reg) { | 265 Register reg) { |
348 if (!IsRegisterInAccumulator(reg)) { | 266 OperandScale operand_scale = |
349 OperandScale operand_scale = OperandSizesToScale(reg.SizeOfOperand()); | 267 Bytecodes::OperandSizesToScale(reg.SizeOfOperand()); |
350 OutputScaled(Bytecode::kLdar, operand_scale, RegisterOperand(reg)); | 268 OutputScaled(Bytecode::kLdar, operand_scale, RegisterOperand(reg)); |
351 } | |
352 return *this; | 269 return *this; |
353 } | 270 } |
354 | 271 |
355 | 272 |
356 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( | 273 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( |
357 Register reg) { | 274 Register reg) { |
358 if (!IsRegisterInAccumulator(reg)) { | 275 OperandScale operand_scale = |
359 OperandScale operand_scale = OperandSizesToScale(reg.SizeOfOperand()); | 276 Bytecodes::OperandSizesToScale(reg.SizeOfOperand()); |
360 OutputScaled(Bytecode::kStar, operand_scale, RegisterOperand(reg)); | 277 OutputScaled(Bytecode::kStar, operand_scale, RegisterOperand(reg)); |
361 } | |
362 return *this; | 278 return *this; |
363 } | 279 } |
364 | 280 |
365 | 281 |
366 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, | 282 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, |
367 Register to) { | 283 Register to) { |
368 DCHECK(from != to); | 284 DCHECK(from != to); |
369 OperandScale operand_scale = | 285 OperandScale operand_scale = |
370 OperandSizesToScale(from.SizeOfOperand(), to.SizeOfOperand()); | 286 Bytecodes::OperandSizesToScale(from.SizeOfOperand(), to.SizeOfOperand()); |
371 OutputScaled(Bytecode::kMov, operand_scale, RegisterOperand(from), | 287 OutputScaled(Bytecode::kMov, operand_scale, RegisterOperand(from), |
372 RegisterOperand(to)); | 288 RegisterOperand(to)); |
373 return *this; | 289 return *this; |
374 } | 290 } |
375 | 291 |
376 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal( | 292 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal( |
377 const Handle<String> name, int feedback_slot, TypeofMode typeof_mode) { | 293 const Handle<String> name, int feedback_slot, TypeofMode typeof_mode) { |
378 // TODO(rmcilroy): Potentially store typeof information in an | 294 // TODO(rmcilroy): Potentially store typeof information in an |
379 // operand rather than having extra bytecodes. | 295 // operand rather than having extra bytecodes. |
380 Bytecode bytecode = BytecodeForLoadGlobal(typeof_mode); | 296 Bytecode bytecode = BytecodeForLoadGlobal(typeof_mode); |
381 size_t name_index = GetConstantPoolEntry(name); | 297 size_t name_index = GetConstantPoolEntry(name); |
382 OperandScale operand_scale = | 298 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
383 OperandSizesToScale(SizeForUnsignedOperand(name_index), | 299 Bytecodes::SizeForUnsignedOperand(name_index), |
384 SizeForUnsignedOperand(feedback_slot)); | 300 Bytecodes::SizeForUnsignedOperand(feedback_slot)); |
385 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index), | 301 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index), |
386 UnsignedOperand(feedback_slot)); | 302 UnsignedOperand(feedback_slot)); |
387 return *this; | 303 return *this; |
388 } | 304 } |
389 | 305 |
390 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal( | 306 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal( |
391 const Handle<String> name, int feedback_slot, LanguageMode language_mode) { | 307 const Handle<String> name, int feedback_slot, LanguageMode language_mode) { |
392 Bytecode bytecode = BytecodeForStoreGlobal(language_mode); | 308 Bytecode bytecode = BytecodeForStoreGlobal(language_mode); |
393 size_t name_index = GetConstantPoolEntry(name); | 309 size_t name_index = GetConstantPoolEntry(name); |
394 OperandScale operand_scale = | 310 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
395 OperandSizesToScale(SizeForUnsignedOperand(name_index), | 311 Bytecodes::SizeForUnsignedOperand(name_index), |
396 SizeForUnsignedOperand(feedback_slot)); | 312 Bytecodes::SizeForUnsignedOperand(feedback_slot)); |
397 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index), | 313 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index), |
398 UnsignedOperand(feedback_slot)); | 314 UnsignedOperand(feedback_slot)); |
399 return *this; | 315 return *this; |
400 } | 316 } |
401 | 317 |
402 | 318 |
403 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, | 319 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, |
404 int slot_index) { | 320 int slot_index) { |
405 OperandScale operand_scale = OperandSizesToScale( | 321 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
406 context.SizeOfOperand(), SizeForUnsignedOperand(slot_index)); | 322 context.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(slot_index)); |
407 OutputScaled(Bytecode::kLdaContextSlot, operand_scale, | 323 OutputScaled(Bytecode::kLdaContextSlot, operand_scale, |
408 RegisterOperand(context), UnsignedOperand(slot_index)); | 324 RegisterOperand(context), UnsignedOperand(slot_index)); |
409 return *this; | 325 return *this; |
410 } | 326 } |
411 | 327 |
412 | 328 |
413 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, | 329 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, |
414 int slot_index) { | 330 int slot_index) { |
415 OperandScale operand_scale = OperandSizesToScale( | 331 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
416 context.SizeOfOperand(), SizeForUnsignedOperand(slot_index)); | 332 context.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(slot_index)); |
417 OutputScaled(Bytecode::kStaContextSlot, operand_scale, | 333 OutputScaled(Bytecode::kStaContextSlot, operand_scale, |
418 RegisterOperand(context), UnsignedOperand(slot_index)); | 334 RegisterOperand(context), UnsignedOperand(slot_index)); |
419 return *this; | 335 return *this; |
420 } | 336 } |
421 | 337 |
422 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( | 338 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( |
423 const Handle<String> name, TypeofMode typeof_mode) { | 339 const Handle<String> name, TypeofMode typeof_mode) { |
424 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) | 340 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) |
425 ? Bytecode::kLdaLookupSlotInsideTypeof | 341 ? Bytecode::kLdaLookupSlotInsideTypeof |
426 : Bytecode::kLdaLookupSlot; | 342 : Bytecode::kLdaLookupSlot; |
427 size_t name_index = GetConstantPoolEntry(name); | 343 size_t name_index = GetConstantPoolEntry(name); |
428 OperandScale operand_scale = | 344 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
429 OperandSizesToScale(SizeForUnsignedOperand(name_index)); | 345 Bytecodes::SizeForUnsignedOperand(name_index)); |
430 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index)); | 346 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index)); |
431 return *this; | 347 return *this; |
432 } | 348 } |
433 | 349 |
434 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot( | 350 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot( |
435 const Handle<String> name, LanguageMode language_mode) { | 351 const Handle<String> name, LanguageMode language_mode) { |
436 Bytecode bytecode = BytecodeForStoreLookupSlot(language_mode); | 352 Bytecode bytecode = BytecodeForStoreLookupSlot(language_mode); |
437 size_t name_index = GetConstantPoolEntry(name); | 353 size_t name_index = GetConstantPoolEntry(name); |
438 OperandScale operand_scale = | 354 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
439 OperandSizesToScale(SizeForUnsignedOperand(name_index)); | 355 Bytecodes::SizeForUnsignedOperand(name_index)); |
440 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index)); | 356 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index)); |
441 return *this; | 357 return *this; |
442 } | 358 } |
443 | 359 |
444 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( | 360 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( |
445 Register object, const Handle<Name> name, int feedback_slot) { | 361 Register object, const Handle<Name> name, int feedback_slot) { |
446 size_t name_index = GetConstantPoolEntry(name); | 362 size_t name_index = GetConstantPoolEntry(name); |
447 OperandScale operand_scale = OperandSizesToScale( | 363 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
448 object.SizeOfOperand(), SizeForUnsignedOperand(name_index), | 364 object.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(name_index), |
449 SizeForUnsignedOperand(feedback_slot)); | 365 Bytecodes::SizeForUnsignedOperand(feedback_slot)); |
450 OutputScaled(Bytecode::kLoadIC, operand_scale, RegisterOperand(object), | 366 OutputScaled(Bytecode::kLoadIC, operand_scale, RegisterOperand(object), |
451 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); | 367 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); |
452 return *this; | 368 return *this; |
453 } | 369 } |
454 | 370 |
455 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( | 371 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( |
456 Register object, int feedback_slot) { | 372 Register object, int feedback_slot) { |
457 OperandScale operand_scale = OperandSizesToScale( | 373 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
458 object.SizeOfOperand(), SizeForUnsignedOperand(feedback_slot)); | 374 object.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(feedback_slot)); |
459 OutputScaled(Bytecode::kKeyedLoadIC, operand_scale, RegisterOperand(object), | 375 OutputScaled(Bytecode::kKeyedLoadIC, operand_scale, RegisterOperand(object), |
460 UnsignedOperand(feedback_slot)); | 376 UnsignedOperand(feedback_slot)); |
461 return *this; | 377 return *this; |
462 } | 378 } |
463 | 379 |
464 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( | 380 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( |
465 Register object, const Handle<Name> name, int feedback_slot, | 381 Register object, const Handle<Name> name, int feedback_slot, |
466 LanguageMode language_mode) { | 382 LanguageMode language_mode) { |
467 Bytecode bytecode = BytecodeForStoreIC(language_mode); | 383 Bytecode bytecode = BytecodeForStoreIC(language_mode); |
468 size_t name_index = GetConstantPoolEntry(name); | 384 size_t name_index = GetConstantPoolEntry(name); |
469 OperandScale operand_scale = OperandSizesToScale( | 385 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
470 object.SizeOfOperand(), SizeForUnsignedOperand(name_index), | 386 object.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(name_index), |
471 SizeForUnsignedOperand(feedback_slot)); | 387 Bytecodes::SizeForUnsignedOperand(feedback_slot)); |
472 OutputScaled(bytecode, operand_scale, RegisterOperand(object), | 388 OutputScaled(bytecode, operand_scale, RegisterOperand(object), |
473 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); | 389 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); |
474 return *this; | 390 return *this; |
475 } | 391 } |
476 | 392 |
477 | 393 |
478 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( | 394 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( |
479 Register object, Register key, int feedback_slot, | 395 Register object, Register key, int feedback_slot, |
480 LanguageMode language_mode) { | 396 LanguageMode language_mode) { |
481 Bytecode bytecode = BytecodeForKeyedStoreIC(language_mode); | 397 Bytecode bytecode = BytecodeForKeyedStoreIC(language_mode); |
482 OperandScale operand_scale = | 398 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
483 OperandSizesToScale(object.SizeOfOperand(), key.SizeOfOperand(), | 399 object.SizeOfOperand(), key.SizeOfOperand(), |
484 SizeForUnsignedOperand(feedback_slot)); | 400 Bytecodes::SizeForUnsignedOperand(feedback_slot)); |
485 OutputScaled(bytecode, operand_scale, RegisterOperand(object), | 401 OutputScaled(bytecode, operand_scale, RegisterOperand(object), |
486 RegisterOperand(key), UnsignedOperand(feedback_slot)); | 402 RegisterOperand(key), UnsignedOperand(feedback_slot)); |
487 return *this; | 403 return *this; |
488 } | 404 } |
489 | 405 |
490 | 406 |
491 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure( | 407 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure( |
492 Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) { | 408 Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) { |
493 size_t entry = GetConstantPoolEntry(shared_info); | 409 size_t entry = GetConstantPoolEntry(shared_info); |
494 OperandScale operand_scale = | 410 OperandScale operand_scale = |
495 OperandSizesToScale(SizeForUnsignedOperand(entry)); | 411 Bytecodes::OperandSizesToScale(Bytecodes::SizeForUnsignedOperand(entry)); |
496 OutputScaled(Bytecode::kCreateClosure, operand_scale, UnsignedOperand(entry), | 412 OutputScaled(Bytecode::kCreateClosure, operand_scale, UnsignedOperand(entry), |
497 UnsignedOperand(static_cast<size_t>(tenured))); | 413 UnsignedOperand(static_cast<size_t>(tenured))); |
498 return *this; | 414 return *this; |
499 } | 415 } |
500 | 416 |
501 | 417 |
502 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments( | 418 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments( |
503 CreateArgumentsType type) { | 419 CreateArgumentsType type) { |
504 // TODO(rmcilroy): Consider passing the type as a bytecode operand rather | 420 // TODO(rmcilroy): Consider passing the type as a bytecode operand rather |
505 // than having two different bytecodes once we have better support for | 421 // than having two different bytecodes once we have better support for |
506 // branches in the InterpreterAssembler. | 422 // branches in the InterpreterAssembler. |
507 Bytecode bytecode = BytecodeForCreateArguments(type); | 423 Bytecode bytecode = BytecodeForCreateArguments(type); |
508 Output(bytecode); | 424 Output(bytecode); |
509 return *this; | 425 return *this; |
510 } | 426 } |
511 | 427 |
512 | 428 |
513 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral( | 429 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral( |
514 Handle<String> pattern, int literal_index, int flags) { | 430 Handle<String> pattern, int literal_index, int flags) { |
515 size_t pattern_entry = GetConstantPoolEntry(pattern); | 431 size_t pattern_entry = GetConstantPoolEntry(pattern); |
516 OperandScale operand_scale = OperandSizesToScale( | 432 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
517 SizeForUnsignedOperand(pattern_entry), | 433 Bytecodes::SizeForUnsignedOperand(pattern_entry), |
518 SizeForUnsignedOperand(literal_index), SizeForUnsignedOperand(flags)); | 434 Bytecodes::SizeForUnsignedOperand(literal_index), |
| 435 Bytecodes::SizeForUnsignedOperand(flags)); |
519 OutputScaled(Bytecode::kCreateRegExpLiteral, operand_scale, | 436 OutputScaled(Bytecode::kCreateRegExpLiteral, operand_scale, |
520 UnsignedOperand(pattern_entry), UnsignedOperand(literal_index), | 437 UnsignedOperand(pattern_entry), UnsignedOperand(literal_index), |
521 UnsignedOperand(flags)); | 438 UnsignedOperand(flags)); |
522 return *this; | 439 return *this; |
523 } | 440 } |
524 | 441 |
525 | 442 |
526 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral( | 443 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral( |
527 Handle<FixedArray> constant_elements, int literal_index, int flags) { | 444 Handle<FixedArray> constant_elements, int literal_index, int flags) { |
528 size_t constant_elements_entry = GetConstantPoolEntry(constant_elements); | 445 size_t constant_elements_entry = GetConstantPoolEntry(constant_elements); |
529 OperandScale operand_scale = OperandSizesToScale( | 446 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
530 SizeForUnsignedOperand(constant_elements_entry), | 447 Bytecodes::SizeForUnsignedOperand(constant_elements_entry), |
531 SizeForUnsignedOperand(literal_index), SizeForUnsignedOperand(flags)); | 448 Bytecodes::SizeForUnsignedOperand(literal_index), |
| 449 Bytecodes::SizeForUnsignedOperand(flags)); |
532 OutputScaled(Bytecode::kCreateArrayLiteral, operand_scale, | 450 OutputScaled(Bytecode::kCreateArrayLiteral, operand_scale, |
533 UnsignedOperand(constant_elements_entry), | 451 UnsignedOperand(constant_elements_entry), |
534 UnsignedOperand(literal_index), UnsignedOperand(flags)); | 452 UnsignedOperand(literal_index), UnsignedOperand(flags)); |
535 return *this; | 453 return *this; |
536 } | 454 } |
537 | 455 |
538 | 456 |
539 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral( | 457 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral( |
540 Handle<FixedArray> constant_properties, int literal_index, int flags) { | 458 Handle<FixedArray> constant_properties, int literal_index, int flags) { |
541 size_t constant_properties_entry = GetConstantPoolEntry(constant_properties); | 459 size_t constant_properties_entry = GetConstantPoolEntry(constant_properties); |
542 OperandScale operand_scale = OperandSizesToScale( | 460 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
543 SizeForUnsignedOperand(constant_properties_entry), | 461 Bytecodes::SizeForUnsignedOperand(constant_properties_entry), |
544 SizeForUnsignedOperand(literal_index), SizeForUnsignedOperand(flags)); | 462 Bytecodes::SizeForUnsignedOperand(literal_index), |
| 463 Bytecodes::SizeForUnsignedOperand(flags)); |
545 OutputScaled(Bytecode::kCreateObjectLiteral, operand_scale, | 464 OutputScaled(Bytecode::kCreateObjectLiteral, operand_scale, |
546 UnsignedOperand(constant_properties_entry), | 465 UnsignedOperand(constant_properties_entry), |
547 UnsignedOperand(literal_index), UnsignedOperand(flags)); | 466 UnsignedOperand(literal_index), UnsignedOperand(flags)); |
548 return *this; | 467 return *this; |
549 } | 468 } |
550 | 469 |
551 | 470 |
552 BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) { | 471 BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) { |
553 OperandScale operand_scale = OperandSizesToScale(context.SizeOfOperand()); | 472 OperandScale operand_scale = |
| 473 Bytecodes::OperandSizesToScale(context.SizeOfOperand()); |
554 OutputScaled(Bytecode::kPushContext, operand_scale, RegisterOperand(context)); | 474 OutputScaled(Bytecode::kPushContext, operand_scale, RegisterOperand(context)); |
555 return *this; | 475 return *this; |
556 } | 476 } |
557 | 477 |
558 | 478 |
559 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { | 479 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { |
560 OperandScale operand_scale = OperandSizesToScale(context.SizeOfOperand()); | 480 OperandScale operand_scale = |
| 481 Bytecodes::OperandSizesToScale(context.SizeOfOperand()); |
561 OutputScaled(Bytecode::kPopContext, operand_scale, RegisterOperand(context)); | 482 OutputScaled(Bytecode::kPopContext, operand_scale, RegisterOperand(context)); |
562 return *this; | 483 return *this; |
563 } | 484 } |
564 | 485 |
565 | 486 |
566 bool BytecodeArrayBuilder::NeedToBooleanCast() { | |
567 if (!LastBytecodeInSameBlock()) { | |
568 return true; | |
569 } | |
570 PreviousBytecodeHelper previous_bytecode(*this); | |
571 switch (previous_bytecode.GetBytecode()) { | |
572 // If the previous bytecode puts a boolean in the accumulator return true. | |
573 case Bytecode::kLdaTrue: | |
574 case Bytecode::kLdaFalse: | |
575 case Bytecode::kLogicalNot: | |
576 case Bytecode::kTestEqual: | |
577 case Bytecode::kTestNotEqual: | |
578 case Bytecode::kTestEqualStrict: | |
579 case Bytecode::kTestLessThan: | |
580 case Bytecode::kTestLessThanOrEqual: | |
581 case Bytecode::kTestGreaterThan: | |
582 case Bytecode::kTestGreaterThanOrEqual: | |
583 case Bytecode::kTestInstanceOf: | |
584 case Bytecode::kTestIn: | |
585 case Bytecode::kForInDone: | |
586 return false; | |
587 default: | |
588 return true; | |
589 } | |
590 } | |
591 | |
592 | |
593 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() { | 487 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() { |
594 Output(Bytecode::kToObject); | 488 Output(Bytecode::kToObject); |
595 return *this; | 489 return *this; |
596 } | 490 } |
597 | 491 |
598 | 492 |
599 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() { | 493 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() { |
600 if (LastBytecodeInSameBlock()) { | |
601 PreviousBytecodeHelper previous_bytecode(*this); | |
602 switch (previous_bytecode.GetBytecode()) { | |
603 case Bytecode::kToName: | |
604 case Bytecode::kTypeOf: | |
605 return *this; | |
606 case Bytecode::kLdaConstant: { | |
607 Handle<Object> object = previous_bytecode.GetConstantForIndexOperand(0); | |
608 if (object->IsName()) return *this; | |
609 break; | |
610 } | |
611 default: | |
612 break; | |
613 } | |
614 } | |
615 Output(Bytecode::kToName); | 494 Output(Bytecode::kToName); |
616 return *this; | 495 return *this; |
617 } | 496 } |
618 | 497 |
619 | |
620 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToNumber() { | 498 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToNumber() { |
621 // TODO(rmcilroy): consider omitting if the preceeding bytecode always returns | |
622 // a number. | |
623 Output(Bytecode::kToNumber); | 499 Output(Bytecode::kToNumber); |
624 return *this; | 500 return *this; |
625 } | 501 } |
626 | 502 |
627 | 503 |
628 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) { | 504 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) { |
| 505 size_t current_offset = pipeline()->FlushForOffset(); |
629 if (label->is_forward_target()) { | 506 if (label->is_forward_target()) { |
630 // An earlier jump instruction refers to this label. Update it's location. | 507 // An earlier jump instruction refers to this label. Update it's location. |
631 PatchJump(bytecodes()->end(), bytecodes()->begin() + label->offset()); | 508 PatchJump(current_offset, label->offset()); |
632 // Now treat as if the label will only be back referred to. | 509 // Now treat as if the label will only be back referred to. |
633 } | 510 } |
634 label->bind_to(bytecodes()->size()); | 511 label->bind_to(current_offset); |
635 LeaveBasicBlock(); | 512 LeaveBasicBlock(); |
636 return *this; | 513 return *this; |
637 } | 514 } |
638 | 515 |
639 | 516 |
640 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target, | 517 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target, |
641 BytecodeLabel* label) { | 518 BytecodeLabel* label) { |
642 DCHECK(!label->is_bound()); | 519 DCHECK(!label->is_bound()); |
643 DCHECK(target.is_bound()); | 520 DCHECK(target.is_bound()); |
| 521 // There is no need to flush the pipeline here, it will have been |
| 522 // flushed when |target| was bound. |
644 if (label->is_forward_target()) { | 523 if (label->is_forward_target()) { |
645 // An earlier jump instruction refers to this label. Update it's location. | 524 // An earlier jump instruction refers to this label. Update it's location. |
646 PatchJump(bytecodes()->begin() + target.offset(), | 525 PatchJump(target.offset(), label->offset()); |
647 bytecodes()->begin() + label->offset()); | |
648 // Now treat as if the label will only be back referred to. | 526 // Now treat as if the label will only be back referred to. |
649 } | 527 } |
650 label->bind_to(target.offset()); | 528 label->bind_to(target.offset()); |
651 LeaveBasicBlock(); | 529 LeaveBasicBlock(); |
652 return *this; | 530 return *this; |
653 } | 531 } |
654 | 532 |
655 | 533 |
656 // static | 534 // static |
657 Bytecode BytecodeArrayBuilder::GetJumpWithConstantOperand( | 535 Bytecode BytecodeArrayBuilder::GetJumpWithConstantOperand( |
(...skipping 14 matching lines...) Expand all Loading... |
672 case Bytecode::kJumpIfNull: | 550 case Bytecode::kJumpIfNull: |
673 return Bytecode::kJumpIfNullConstant; | 551 return Bytecode::kJumpIfNullConstant; |
674 case Bytecode::kJumpIfUndefined: | 552 case Bytecode::kJumpIfUndefined: |
675 return Bytecode::kJumpIfUndefinedConstant; | 553 return Bytecode::kJumpIfUndefinedConstant; |
676 default: | 554 default: |
677 UNREACHABLE(); | 555 UNREACHABLE(); |
678 return Bytecode::kIllegal; | 556 return Bytecode::kIllegal; |
679 } | 557 } |
680 } | 558 } |
681 | 559 |
682 // static | 560 void BytecodeArrayBuilder::PatchJumpWith8BitOperand( |
683 Bytecode BytecodeArrayBuilder::GetJumpWithToBoolean(Bytecode jump_bytecode) { | 561 ZoneVector<uint8_t>* bytecodes, size_t jump_location, int delta) { |
684 switch (jump_bytecode) { | 562 Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes->at(jump_location)); |
685 case Bytecode::kJump: | |
686 case Bytecode::kJumpIfNull: | |
687 case Bytecode::kJumpIfUndefined: | |
688 case Bytecode::kJumpIfNotHole: | |
689 return jump_bytecode; | |
690 case Bytecode::kJumpIfTrue: | |
691 return Bytecode::kJumpIfToBooleanTrue; | |
692 case Bytecode::kJumpIfFalse: | |
693 return Bytecode::kJumpIfToBooleanFalse; | |
694 default: | |
695 UNREACHABLE(); | |
696 } | |
697 return Bytecode::kIllegal; | |
698 } | |
699 | |
700 | |
701 void BytecodeArrayBuilder::PatchIndirectJumpWith8BitOperand( | |
702 const ZoneVector<uint8_t>::iterator& jump_location, int delta) { | |
703 Bytecode jump_bytecode = Bytecodes::FromByte(*jump_location); | |
704 DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode)); | 563 DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode)); |
705 ZoneVector<uint8_t>::iterator operand_location = jump_location + 1; | 564 size_t operand_location = jump_location + 1; |
706 DCHECK_EQ(*operand_location, 0); | 565 DCHECK_EQ(bytecodes->at(operand_location), 0); |
707 if (SizeForSignedOperand(delta) == OperandSize::kByte) { | 566 if (Bytecodes::SizeForSignedOperand(delta) == OperandSize::kByte) { |
708 // The jump fits within the range of an Imm operand, so cancel | 567 // The jump fits within the range of an Imm operand, so cancel |
709 // the reservation and jump directly. | 568 // the reservation and jump directly. |
710 constant_array_builder()->DiscardReservedEntry(OperandSize::kByte); | 569 constant_array_builder()->DiscardReservedEntry(OperandSize::kByte); |
711 *operand_location = static_cast<uint8_t>(delta); | 570 bytecodes->at(operand_location) = static_cast<uint8_t>(delta); |
712 } else { | 571 } else { |
713 // The jump does not fit within the range of an Imm operand, so | 572 // The jump does not fit within the range of an Imm operand, so |
714 // commit reservation putting the offset into the constant pool, | 573 // commit reservation putting the offset into the constant pool, |
715 // and update the jump instruction and operand. | 574 // and update the jump instruction and operand. |
716 size_t entry = constant_array_builder()->CommitReservedEntry( | 575 size_t entry = constant_array_builder()->CommitReservedEntry( |
717 OperandSize::kByte, handle(Smi::FromInt(delta), isolate())); | 576 OperandSize::kByte, handle(Smi::FromInt(delta), isolate())); |
718 DCHECK(SizeForUnsignedOperand(entry) == OperandSize::kByte); | 577 DCHECK(Bytecodes::SizeForUnsignedOperand(entry) == OperandSize::kByte); |
719 jump_bytecode = GetJumpWithConstantOperand(jump_bytecode); | 578 jump_bytecode = GetJumpWithConstantOperand(jump_bytecode); |
720 *jump_location = Bytecodes::ToByte(jump_bytecode); | 579 bytecodes->at(jump_location) = Bytecodes::ToByte(jump_bytecode); |
721 *operand_location = static_cast<uint8_t>(entry); | 580 bytecodes->at(operand_location) = static_cast<uint8_t>(entry); |
722 } | 581 } |
723 } | 582 } |
724 | 583 |
725 void BytecodeArrayBuilder::PatchIndirectJumpWith16BitOperand( | 584 void BytecodeArrayBuilder::PatchJumpWith16BitOperand( |
726 const ZoneVector<uint8_t>::iterator& jump_location, int delta) { | 585 ZoneVector<uint8_t>* bytecodes, size_t jump_location, int delta) { |
727 Bytecode jump_bytecode = Bytecodes::FromByte(*jump_location); | 586 Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes->at(jump_location)); |
728 DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode)); | 587 DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode)); |
729 ZoneVector<uint8_t>::iterator operand_location = jump_location + 1; | 588 size_t operand_location = jump_location + 1; |
730 uint8_t operand_bytes[2]; | 589 uint8_t operand_bytes[2]; |
731 if (SizeForSignedOperand(delta) <= OperandSize::kShort) { | 590 if (Bytecodes::SizeForSignedOperand(delta) <= OperandSize::kShort) { |
732 constant_array_builder()->DiscardReservedEntry(OperandSize::kShort); | 591 constant_array_builder()->DiscardReservedEntry(OperandSize::kShort); |
733 WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(delta)); | 592 WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(delta)); |
734 } else { | 593 } else { |
735 jump_bytecode = GetJumpWithConstantOperand(jump_bytecode); | 594 jump_bytecode = GetJumpWithConstantOperand(jump_bytecode); |
736 *jump_location = Bytecodes::ToByte(jump_bytecode); | 595 bytecodes->at(jump_location) = Bytecodes::ToByte(jump_bytecode); |
737 size_t entry = constant_array_builder()->CommitReservedEntry( | 596 size_t entry = constant_array_builder()->CommitReservedEntry( |
738 OperandSize::kShort, handle(Smi::FromInt(delta), isolate())); | 597 OperandSize::kShort, handle(Smi::FromInt(delta), isolate())); |
739 WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(entry)); | 598 WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(entry)); |
740 } | 599 } |
741 DCHECK(*operand_location == 0 && *(operand_location + 1) == 0); | 600 DCHECK(bytecodes->at(operand_location) == 0 && |
742 *operand_location++ = operand_bytes[0]; | 601 bytecodes->at(operand_location + 1) == 0); |
743 *operand_location = operand_bytes[1]; | 602 bytecodes->at(operand_location++) = operand_bytes[0]; |
| 603 bytecodes->at(operand_location) = operand_bytes[1]; |
744 } | 604 } |
745 | 605 |
746 void BytecodeArrayBuilder::PatchIndirectJumpWith32BitOperand( | 606 void BytecodeArrayBuilder::PatchJumpWith32BitOperand( |
747 const ZoneVector<uint8_t>::iterator& jump_location, int delta) { | 607 ZoneVector<uint8_t>* bytecodes, size_t jump_location, int delta) { |
748 DCHECK(Bytecodes::IsJumpImmediate(Bytecodes::FromByte(*jump_location))); | 608 DCHECK(Bytecodes::IsJumpImmediate( |
| 609 Bytecodes::FromByte(bytecodes->at(jump_location)))); |
749 constant_array_builder()->DiscardReservedEntry(OperandSize::kQuad); | 610 constant_array_builder()->DiscardReservedEntry(OperandSize::kQuad); |
750 ZoneVector<uint8_t>::iterator operand_location = jump_location + 1; | |
751 uint8_t operand_bytes[4]; | 611 uint8_t operand_bytes[4]; |
752 WriteUnalignedUInt32(operand_bytes, static_cast<uint32_t>(delta)); | 612 WriteUnalignedUInt32(operand_bytes, static_cast<uint32_t>(delta)); |
753 DCHECK(*operand_location == 0 && *(operand_location + 1) == 0 && | 613 size_t operand_location = jump_location + 1; |
754 *(operand_location + 2) == 0 && *(operand_location + 3) == 0); | 614 DCHECK(bytecodes->at(operand_location) == 0 && |
755 *operand_location++ = operand_bytes[0]; | 615 bytecodes->at(operand_location + 1) == 0 && |
756 *operand_location++ = operand_bytes[1]; | 616 bytecodes->at(operand_location + 2) == 0 && |
757 *operand_location++ = operand_bytes[2]; | 617 bytecodes->at(operand_location + 3) == 0); |
758 *operand_location = operand_bytes[3]; | 618 bytecodes->at(operand_location++) = operand_bytes[0]; |
| 619 bytecodes->at(operand_location++) = operand_bytes[1]; |
| 620 bytecodes->at(operand_location++) = operand_bytes[2]; |
| 621 bytecodes->at(operand_location) = operand_bytes[3]; |
759 } | 622 } |
760 | 623 |
761 void BytecodeArrayBuilder::PatchJump( | 624 void BytecodeArrayBuilder::PatchJump(size_t jump_target, size_t jump_location) { |
762 const ZoneVector<uint8_t>::iterator& jump_target, | 625 ZoneVector<uint8_t>* bytecodes = bytecode_array_writer()->bytecodes(); |
763 const ZoneVector<uint8_t>::iterator& jump_location) { | 626 Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes->at(jump_location)); |
764 int delta = static_cast<int>(jump_target - jump_location); | 627 int delta = static_cast<int>(jump_target - jump_location); |
765 Bytecode jump_bytecode = Bytecodes::FromByte(*jump_location); | |
766 int prefix_offset = 0; | 628 int prefix_offset = 0; |
767 OperandScale operand_scale = OperandScale::kSingle; | 629 OperandScale operand_scale = OperandScale::kSingle; |
768 if (Bytecodes::IsPrefixScalingBytecode(jump_bytecode)) { | 630 if (Bytecodes::IsPrefixScalingBytecode(jump_bytecode)) { |
769 // If a prefix scaling bytecode is emitted the target offset is one | 631 // If a prefix scaling bytecode is emitted the target offset is one |
770 // less than the case of no prefix scaling bytecode. | 632 // less than the case of no prefix scaling bytecode. |
771 delta -= 1; | 633 delta -= 1; |
772 prefix_offset = 1; | 634 prefix_offset = 1; |
773 operand_scale = Bytecodes::PrefixBytecodeToOperandScale(jump_bytecode); | 635 operand_scale = Bytecodes::PrefixBytecodeToOperandScale(jump_bytecode); |
774 jump_bytecode = Bytecodes::FromByte(*(jump_location + prefix_offset)); | 636 jump_bytecode = |
| 637 Bytecodes::FromByte(bytecodes->at(jump_location + prefix_offset)); |
775 } | 638 } |
776 | 639 |
777 DCHECK(Bytecodes::IsJump(jump_bytecode)); | 640 DCHECK(Bytecodes::IsJump(jump_bytecode)); |
778 switch (operand_scale) { | 641 switch (operand_scale) { |
779 case OperandScale::kSingle: | 642 case OperandScale::kSingle: |
780 PatchIndirectJumpWith8BitOperand(jump_location, delta); | 643 PatchJumpWith8BitOperand(bytecodes, jump_location, delta); |
781 break; | 644 break; |
782 case OperandScale::kDouble: | 645 case OperandScale::kDouble: |
783 PatchIndirectJumpWith16BitOperand(jump_location + prefix_offset, delta); | 646 PatchJumpWith16BitOperand(bytecodes, jump_location + prefix_offset, |
| 647 delta); |
784 break; | 648 break; |
785 case OperandScale::kQuadruple: | 649 case OperandScale::kQuadruple: |
786 PatchIndirectJumpWith32BitOperand(jump_location + prefix_offset, delta); | 650 PatchJumpWith32BitOperand(bytecodes, jump_location + prefix_offset, |
| 651 delta); |
787 break; | 652 break; |
788 default: | 653 default: |
789 UNREACHABLE(); | 654 UNREACHABLE(); |
790 } | 655 } |
791 unbound_jumps_--; | 656 unbound_jumps_--; |
792 } | 657 } |
793 | 658 |
794 | 659 |
795 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, | 660 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, |
796 BytecodeLabel* label) { | 661 BytecodeLabel* label) { |
797 // Don't emit dead code. | 662 // Don't emit dead code. |
798 if (exit_seen_in_block_) return *this; | 663 if (exit_seen_in_block_) return *this; |
799 | 664 |
800 // Check if the value in accumulator is boolean, if not choose an | |
801 // appropriate JumpIfToBoolean bytecode. | |
802 if (NeedToBooleanCast()) { | |
803 jump_bytecode = GetJumpWithToBoolean(jump_bytecode); | |
804 } | |
805 | |
806 if (label->is_bound()) { | 665 if (label->is_bound()) { |
807 // Label has been bound already so this is a backwards jump. | 666 // Label has been bound already so this is a backwards jump. |
808 CHECK_GE(bytecodes()->size(), label->offset()); | 667 size_t current_offset = pipeline()->FlushForOffset(); |
809 CHECK_LE(bytecodes()->size(), static_cast<size_t>(kMaxInt)); | 668 CHECK_GE(current_offset, label->offset()); |
810 size_t abs_delta = bytecodes()->size() - label->offset(); | 669 CHECK_LE(current_offset, static_cast<size_t>(kMaxInt)); |
| 670 size_t abs_delta = current_offset - label->offset(); |
811 int delta = -static_cast<int>(abs_delta); | 671 int delta = -static_cast<int>(abs_delta); |
812 OperandSize operand_size = SizeForSignedOperand(delta); | 672 OperandSize operand_size = Bytecodes::SizeForSignedOperand(delta); |
813 if (operand_size > OperandSize::kByte) { | 673 if (operand_size > OperandSize::kByte) { |
814 // Adjust for scaling byte prefix for wide jump offset. | 674 // Adjust for scaling byte prefix for wide jump offset. |
815 DCHECK_LE(delta, 0); | 675 DCHECK_LE(delta, 0); |
816 delta -= 1; | 676 delta -= 1; |
817 } | 677 } |
818 OutputScaled(jump_bytecode, OperandSizesToScale(operand_size), | 678 OutputScaled(jump_bytecode, Bytecodes::OperandSizesToScale(operand_size), |
819 SignedOperand(delta, operand_size)); | 679 SignedOperand(delta, operand_size)); |
820 } else { | 680 } else { |
821 // The label has not yet been bound so this is a forward reference | 681 // The label has not yet been bound so this is a forward reference |
822 // that will be patched when the label is bound. We create a | 682 // that will be patched when the label is bound. We create a |
823 // reservation in the constant pool so the jump can be patched | 683 // reservation in the constant pool so the jump can be patched |
824 // when the label is bound. The reservation means the maximum size | 684 // when the label is bound. The reservation means the maximum size |
825 // of the operand for the constant is known and the jump can | 685 // of the operand for the constant is known and the jump can |
826 // be emitted into the bytecode stream with space for the operand. | 686 // be emitted into the bytecode stream with space for the operand. |
827 label->set_referrer(bytecodes()->size()); | |
828 unbound_jumps_++; | 687 unbound_jumps_++; |
829 OperandSize reserved_operand_size = | 688 OperandSize reserved_operand_size = |
830 constant_array_builder()->CreateReservedEntry(); | 689 constant_array_builder()->CreateReservedEntry(); |
831 OutputScaled(jump_bytecode, OperandSizesToScale(reserved_operand_size), 0); | 690 OutputScaled(jump_bytecode, |
| 691 Bytecodes::OperandSizesToScale(reserved_operand_size), 0); |
| 692 |
| 693 // Calculate the label position by flushing for offset after emitting the |
| 694 // jump bytecode. |
| 695 size_t offset = pipeline()->FlushForOffset(); |
| 696 OperandScale operand_scale = |
| 697 Bytecodes::OperandSizesToScale(reserved_operand_size); |
| 698 offset -= Bytecodes::Size(jump_bytecode, operand_scale); |
| 699 if (Bytecodes::OperandScaleRequiresPrefixBytecode(operand_scale)) { |
| 700 offset -= 1; |
| 701 } |
| 702 label->set_referrer(offset); |
832 } | 703 } |
833 LeaveBasicBlock(); | 704 LeaveBasicBlock(); |
834 return *this; | 705 return *this; |
835 } | 706 } |
836 | 707 |
837 | |
838 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { | 708 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { |
839 return OutputJump(Bytecode::kJump, label); | 709 return OutputJump(Bytecode::kJump, label); |
840 } | 710 } |
841 | 711 |
842 | |
843 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) { | 712 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) { |
844 return OutputJump(Bytecode::kJumpIfTrue, label); | 713 // The peephole optimizer attempts to simplify JumpIfToBooleanTrue |
| 714 // to JumpIfTrue. |
| 715 return OutputJump(Bytecode::kJumpIfToBooleanTrue, label); |
845 } | 716 } |
846 | 717 |
847 | |
848 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) { | 718 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) { |
849 return OutputJump(Bytecode::kJumpIfFalse, label); | 719 // The peephole optimizer attempts to simplify JumpIfToBooleanFalse |
| 720 // to JumpIfFalse. |
| 721 return OutputJump(Bytecode::kJumpIfToBooleanFalse, label); |
850 } | 722 } |
851 | 723 |
852 | |
853 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) { | 724 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) { |
854 return OutputJump(Bytecode::kJumpIfNull, label); | 725 return OutputJump(Bytecode::kJumpIfNull, label); |
855 } | 726 } |
856 | 727 |
857 | |
858 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined( | 728 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined( |
859 BytecodeLabel* label) { | 729 BytecodeLabel* label) { |
860 return OutputJump(Bytecode::kJumpIfUndefined, label); | 730 return OutputJump(Bytecode::kJumpIfUndefined, label); |
861 } | 731 } |
862 | 732 |
863 BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) { | 733 BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) { |
864 if (position != RelocInfo::kNoPosition) { | 734 if (position != RelocInfo::kNoPosition) { |
865 // We need to attach a non-breakable source position to a stack check, | 735 // We need to attach a non-breakable source position to a stack check, |
866 // so we simply add it as expression position. | 736 // so we simply add it as expression position. |
867 source_position_table_builder_.AddExpressionPosition(bytecodes_.size(), | 737 latest_source_info_.Update({position, false}); |
868 position); | |
869 } | 738 } |
870 Output(Bytecode::kStackCheck); | 739 Output(Bytecode::kStackCheck); |
871 return *this; | 740 return *this; |
872 } | 741 } |
873 | 742 |
874 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole( | 743 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole( |
875 BytecodeLabel* label) { | 744 BytecodeLabel* label) { |
876 return OutputJump(Bytecode::kJumpIfNotHole, label); | 745 return OutputJump(Bytecode::kJumpIfNotHole, label); |
877 } | 746 } |
878 | 747 |
(...skipping 24 matching lines...) Expand all Loading... |
903 } | 772 } |
904 | 773 |
905 BytecodeArrayBuilder& BytecodeArrayBuilder::Debugger() { | 774 BytecodeArrayBuilder& BytecodeArrayBuilder::Debugger() { |
906 Output(Bytecode::kDebugger); | 775 Output(Bytecode::kDebugger); |
907 return *this; | 776 return *this; |
908 } | 777 } |
909 | 778 |
910 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare( | 779 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare( |
911 Register cache_info_triple) { | 780 Register cache_info_triple) { |
912 OperandScale operand_scale = | 781 OperandScale operand_scale = |
913 OperandSizesToScale(cache_info_triple.SizeOfOperand()); | 782 Bytecodes::OperandSizesToScale(cache_info_triple.SizeOfOperand()); |
914 OutputScaled(Bytecode::kForInPrepare, operand_scale, | 783 OutputScaled(Bytecode::kForInPrepare, operand_scale, |
915 RegisterOperand(cache_info_triple)); | 784 RegisterOperand(cache_info_triple)); |
916 return *this; | 785 return *this; |
917 } | 786 } |
918 | 787 |
919 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index, | 788 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index, |
920 Register cache_length) { | 789 Register cache_length) { |
921 OperandScale operand_scale = | 790 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
922 OperandSizesToScale(index.SizeOfOperand(), cache_length.SizeOfOperand()); | 791 index.SizeOfOperand(), cache_length.SizeOfOperand()); |
923 OutputScaled(Bytecode::kForInDone, operand_scale, RegisterOperand(index), | 792 OutputScaled(Bytecode::kForInDone, operand_scale, RegisterOperand(index), |
924 RegisterOperand(cache_length)); | 793 RegisterOperand(cache_length)); |
925 return *this; | 794 return *this; |
926 } | 795 } |
927 | 796 |
928 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext( | 797 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext( |
929 Register receiver, Register index, Register cache_type_array_pair, | 798 Register receiver, Register index, Register cache_type_array_pair, |
930 int feedback_slot) { | 799 int feedback_slot) { |
931 OperandScale operand_scale = | 800 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
932 OperandSizesToScale(receiver.SizeOfOperand(), index.SizeOfOperand(), | 801 receiver.SizeOfOperand(), index.SizeOfOperand(), |
933 cache_type_array_pair.SizeOfOperand(), | 802 cache_type_array_pair.SizeOfOperand(), |
934 SizeForUnsignedOperand(feedback_slot)); | 803 Bytecodes::SizeForUnsignedOperand(feedback_slot)); |
935 OutputScaled(Bytecode::kForInNext, operand_scale, RegisterOperand(receiver), | 804 OutputScaled(Bytecode::kForInNext, operand_scale, RegisterOperand(receiver), |
936 RegisterOperand(index), RegisterOperand(cache_type_array_pair), | 805 RegisterOperand(index), RegisterOperand(cache_type_array_pair), |
937 UnsignedOperand(feedback_slot)); | 806 UnsignedOperand(feedback_slot)); |
938 return *this; | 807 return *this; |
939 } | 808 } |
940 | 809 |
941 | 810 |
942 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) { | 811 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) { |
943 OperandScale operand_scale = OperandSizesToScale(index.SizeOfOperand()); | 812 OperandScale operand_scale = |
| 813 Bytecodes::OperandSizesToScale(index.SizeOfOperand()); |
944 OutputScaled(Bytecode::kForInStep, operand_scale, RegisterOperand(index)); | 814 OutputScaled(Bytecode::kForInStep, operand_scale, RegisterOperand(index)); |
945 return *this; | 815 return *this; |
946 } | 816 } |
947 | 817 |
948 | 818 |
949 BytecodeArrayBuilder& BytecodeArrayBuilder::SuspendGenerator( | 819 BytecodeArrayBuilder& BytecodeArrayBuilder::SuspendGenerator( |
950 Register generator) { | 820 Register generator) { |
951 OperandScale operand_scale = OperandSizesToScale(generator.SizeOfOperand()); | 821 OperandScale operand_scale = |
| 822 Bytecodes::OperandSizesToScale(generator.SizeOfOperand()); |
952 OutputScaled(Bytecode::kSuspendGenerator, operand_scale, | 823 OutputScaled(Bytecode::kSuspendGenerator, operand_scale, |
953 RegisterOperand(generator)); | 824 RegisterOperand(generator)); |
954 return *this; | 825 return *this; |
955 } | 826 } |
956 | 827 |
957 | 828 |
958 BytecodeArrayBuilder& BytecodeArrayBuilder::ResumeGenerator( | 829 BytecodeArrayBuilder& BytecodeArrayBuilder::ResumeGenerator( |
959 Register generator) { | 830 Register generator) { |
960 OperandScale operand_scale = OperandSizesToScale(generator.SizeOfOperand()); | 831 OperandScale operand_scale = |
| 832 Bytecodes::OperandSizesToScale(generator.SizeOfOperand()); |
961 OutputScaled(Bytecode::kResumeGenerator, operand_scale, | 833 OutputScaled(Bytecode::kResumeGenerator, operand_scale, |
962 RegisterOperand(generator)); | 834 RegisterOperand(generator)); |
963 return *this; | 835 return *this; |
964 } | 836 } |
965 | 837 |
966 | 838 |
967 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(int handler_id, | 839 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(int handler_id, |
968 bool will_catch) { | 840 bool will_catch) { |
969 handler_table_builder()->SetHandlerTarget(handler_id, bytecodes()->size()); | 841 size_t offset = pipeline()->FlushForOffset(); |
| 842 handler_table_builder()->SetHandlerTarget(handler_id, offset); |
970 handler_table_builder()->SetPrediction(handler_id, will_catch); | 843 handler_table_builder()->SetPrediction(handler_id, will_catch); |
971 return *this; | 844 return *this; |
972 } | 845 } |
973 | 846 |
974 | 847 |
975 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryBegin(int handler_id, | 848 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryBegin(int handler_id, |
976 Register context) { | 849 Register context) { |
977 handler_table_builder()->SetTryRegionStart(handler_id, bytecodes()->size()); | 850 size_t offset = pipeline()->FlushForOffset(); |
| 851 handler_table_builder()->SetTryRegionStart(handler_id, offset); |
978 handler_table_builder()->SetContextRegister(handler_id, context); | 852 handler_table_builder()->SetContextRegister(handler_id, context); |
979 return *this; | 853 return *this; |
980 } | 854 } |
981 | 855 |
982 | 856 |
983 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryEnd(int handler_id) { | 857 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryEnd(int handler_id) { |
984 handler_table_builder()->SetTryRegionEnd(handler_id, bytecodes()->size()); | 858 size_t offset = pipeline()->FlushForOffset(); |
| 859 handler_table_builder()->SetTryRegionEnd(handler_id, offset); |
985 return *this; | 860 return *this; |
986 } | 861 } |
987 | 862 |
988 | 863 |
989 void BytecodeArrayBuilder::LeaveBasicBlock() { | 864 void BytecodeArrayBuilder::LeaveBasicBlock() { |
990 last_block_end_ = bytecodes()->size(); | |
991 exit_seen_in_block_ = false; | 865 exit_seen_in_block_ = false; |
| 866 pipeline()->FlushBasicBlock(); |
992 } | 867 } |
993 | 868 |
994 void BytecodeArrayBuilder::EnsureReturn() { | 869 void BytecodeArrayBuilder::EnsureReturn() { |
995 if (!exit_seen_in_block_) { | 870 if (!exit_seen_in_block_) { |
996 LoadUndefined(); | 871 LoadUndefined(); |
997 Return(); | 872 Return(); |
998 } | 873 } |
999 DCHECK(exit_seen_in_block_); | 874 DCHECK(exit_seen_in_block_); |
1000 } | 875 } |
1001 | 876 |
1002 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, | 877 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, |
1003 Register receiver_args, | 878 Register receiver_args, |
1004 size_t receiver_args_count, | 879 size_t receiver_args_count, |
1005 int feedback_slot, | 880 int feedback_slot, |
1006 TailCallMode tail_call_mode) { | 881 TailCallMode tail_call_mode) { |
1007 Bytecode bytecode = BytecodeForCall(tail_call_mode); | 882 Bytecode bytecode = BytecodeForCall(tail_call_mode); |
1008 OperandScale operand_scale = OperandSizesToScale( | 883 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
1009 callable.SizeOfOperand(), receiver_args.SizeOfOperand(), | 884 callable.SizeOfOperand(), receiver_args.SizeOfOperand(), |
1010 SizeForUnsignedOperand(receiver_args_count), | 885 Bytecodes::SizeForUnsignedOperand(receiver_args_count), |
1011 SizeForUnsignedOperand(feedback_slot)); | 886 Bytecodes::SizeForUnsignedOperand(feedback_slot)); |
1012 OutputScaled(bytecode, operand_scale, RegisterOperand(callable), | 887 OutputScaled(bytecode, operand_scale, RegisterOperand(callable), |
1013 RegisterOperand(receiver_args), | 888 RegisterOperand(receiver_args), |
1014 UnsignedOperand(receiver_args_count), | 889 UnsignedOperand(receiver_args_count), |
1015 UnsignedOperand(feedback_slot)); | 890 UnsignedOperand(feedback_slot)); |
1016 return *this; | 891 return *this; |
1017 } | 892 } |
1018 | 893 |
1019 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, | 894 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, |
1020 Register first_arg, | 895 Register first_arg, |
1021 size_t arg_count) { | 896 size_t arg_count) { |
1022 if (!first_arg.is_valid()) { | 897 if (!first_arg.is_valid()) { |
1023 DCHECK_EQ(0u, arg_count); | 898 DCHECK_EQ(0u, arg_count); |
1024 first_arg = Register(0); | 899 first_arg = Register(0); |
1025 } | 900 } |
1026 OperandScale operand_scale = OperandSizesToScale( | 901 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
1027 constructor.SizeOfOperand(), first_arg.SizeOfOperand(), | 902 constructor.SizeOfOperand(), first_arg.SizeOfOperand(), |
1028 SizeForUnsignedOperand(arg_count)); | 903 Bytecodes::SizeForUnsignedOperand(arg_count)); |
1029 OutputScaled(Bytecode::kNew, operand_scale, RegisterOperand(constructor), | 904 OutputScaled(Bytecode::kNew, operand_scale, RegisterOperand(constructor), |
1030 RegisterOperand(first_arg), UnsignedOperand(arg_count)); | 905 RegisterOperand(first_arg), UnsignedOperand(arg_count)); |
1031 return *this; | 906 return *this; |
1032 } | 907 } |
1033 | 908 |
1034 | 909 |
1035 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime( | 910 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime( |
1036 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) { | 911 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) { |
1037 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size); | 912 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size); |
1038 DCHECK(SizeForUnsignedOperand(function_id) <= OperandSize::kShort); | 913 DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort); |
1039 if (!first_arg.is_valid()) { | 914 if (!first_arg.is_valid()) { |
1040 DCHECK_EQ(0u, arg_count); | 915 DCHECK_EQ(0u, arg_count); |
1041 first_arg = Register(0); | 916 first_arg = Register(0); |
1042 } | 917 } |
1043 Bytecode bytecode = IntrinsicsHelper::IsSupported(function_id) | 918 Bytecode bytecode = IntrinsicsHelper::IsSupported(function_id) |
1044 ? Bytecode::kInvokeIntrinsic | 919 ? Bytecode::kInvokeIntrinsic |
1045 : Bytecode::kCallRuntime; | 920 : Bytecode::kCallRuntime; |
1046 OperandScale operand_scale = OperandSizesToScale( | 921 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
1047 first_arg.SizeOfOperand(), SizeForUnsignedOperand(arg_count)); | 922 first_arg.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(arg_count)); |
1048 OutputScaled(bytecode, operand_scale, static_cast<uint16_t>(function_id), | 923 OutputScaled(bytecode, operand_scale, static_cast<uint16_t>(function_id), |
1049 RegisterOperand(first_arg), UnsignedOperand(arg_count)); | 924 RegisterOperand(first_arg), UnsignedOperand(arg_count)); |
1050 return *this; | 925 return *this; |
1051 } | 926 } |
1052 | 927 |
1053 | 928 |
1054 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair( | 929 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair( |
1055 Runtime::FunctionId function_id, Register first_arg, size_t arg_count, | 930 Runtime::FunctionId function_id, Register first_arg, size_t arg_count, |
1056 Register first_return) { | 931 Register first_return) { |
1057 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size); | 932 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size); |
1058 DCHECK(SizeForUnsignedOperand(function_id) <= OperandSize::kShort); | 933 DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort); |
1059 if (!first_arg.is_valid()) { | 934 if (!first_arg.is_valid()) { |
1060 DCHECK_EQ(0u, arg_count); | 935 DCHECK_EQ(0u, arg_count); |
1061 first_arg = Register(0); | 936 first_arg = Register(0); |
1062 } | 937 } |
1063 OperandScale operand_scale = OperandSizesToScale( | 938 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
1064 first_arg.SizeOfOperand(), SizeForUnsignedOperand(arg_count), | 939 first_arg.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(arg_count), |
1065 first_return.SizeOfOperand()); | 940 first_return.SizeOfOperand()); |
1066 OutputScaled(Bytecode::kCallRuntimeForPair, operand_scale, | 941 OutputScaled(Bytecode::kCallRuntimeForPair, operand_scale, |
1067 static_cast<uint16_t>(function_id), RegisterOperand(first_arg), | 942 static_cast<uint16_t>(function_id), RegisterOperand(first_arg), |
1068 UnsignedOperand(arg_count), RegisterOperand(first_return)); | 943 UnsignedOperand(arg_count), RegisterOperand(first_return)); |
1069 return *this; | 944 return *this; |
1070 } | 945 } |
1071 | 946 |
1072 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime( | 947 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime( |
1073 int context_index, Register receiver_args, size_t receiver_args_count) { | 948 int context_index, Register receiver_args, size_t receiver_args_count) { |
1074 OperandScale operand_scale = OperandSizesToScale( | 949 OperandScale operand_scale = Bytecodes::OperandSizesToScale( |
1075 SizeForUnsignedOperand(context_index), receiver_args.SizeOfOperand(), | 950 Bytecodes::SizeForUnsignedOperand(context_index), |
1076 SizeForUnsignedOperand(receiver_args_count)); | 951 receiver_args.SizeOfOperand(), |
| 952 Bytecodes::SizeForUnsignedOperand(receiver_args_count)); |
1077 OutputScaled(Bytecode::kCallJSRuntime, operand_scale, | 953 OutputScaled(Bytecode::kCallJSRuntime, operand_scale, |
1078 UnsignedOperand(context_index), RegisterOperand(receiver_args), | 954 UnsignedOperand(context_index), RegisterOperand(receiver_args), |
1079 UnsignedOperand(receiver_args_count)); | 955 UnsignedOperand(receiver_args_count)); |
1080 return *this; | 956 return *this; |
1081 } | 957 } |
1082 | 958 |
1083 | 959 |
1084 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, | 960 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, |
1085 LanguageMode language_mode) { | 961 LanguageMode language_mode) { |
1086 OperandScale operand_scale = OperandSizesToScale(object.SizeOfOperand()); | 962 OperandScale operand_scale = |
| 963 Bytecodes::OperandSizesToScale(object.SizeOfOperand()); |
1087 OutputScaled(BytecodeForDelete(language_mode), operand_scale, | 964 OutputScaled(BytecodeForDelete(language_mode), operand_scale, |
1088 RegisterOperand(object)); | 965 RegisterOperand(object)); |
1089 return *this; | 966 return *this; |
1090 } | 967 } |
1091 | 968 |
1092 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { | 969 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { |
1093 return constant_array_builder()->Insert(object); | 970 return constant_array_builder()->Insert(object); |
1094 } | 971 } |
1095 | 972 |
1096 void BytecodeArrayBuilder::SetReturnPosition() { | 973 void BytecodeArrayBuilder::SetReturnPosition() { |
1097 if (return_position_ == RelocInfo::kNoPosition) return; | 974 if (return_position_ == RelocInfo::kNoPosition) return; |
1098 if (exit_seen_in_block_) return; | 975 if (exit_seen_in_block_) return; |
1099 source_position_table_builder_.AddStatementPosition(bytecodes_.size(), | 976 latest_source_info_.Update({return_position_, true}); |
1100 return_position_); | |
1101 } | 977 } |
1102 | 978 |
1103 void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) { | 979 void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) { |
1104 if (stmt->position() == RelocInfo::kNoPosition) return; | 980 if (stmt->position() == RelocInfo::kNoPosition) return; |
1105 if (exit_seen_in_block_) return; | 981 if (exit_seen_in_block_) return; |
1106 source_position_table_builder_.AddStatementPosition(bytecodes_.size(), | 982 latest_source_info_.Update({stmt->position(), true}); |
1107 stmt->position()); | |
1108 } | 983 } |
1109 | 984 |
1110 void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) { | 985 void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) { |
1111 if (expr->position() == RelocInfo::kNoPosition) return; | 986 if (expr->position() == RelocInfo::kNoPosition) return; |
1112 if (exit_seen_in_block_) return; | 987 if (exit_seen_in_block_) return; |
1113 source_position_table_builder_.AddExpressionPosition(bytecodes_.size(), | 988 latest_source_info_.Update({expr->position(), false}); |
1114 expr->position()); | |
1115 } | 989 } |
1116 | 990 |
1117 void BytecodeArrayBuilder::SetExpressionAsStatementPosition(Expression* expr) { | 991 void BytecodeArrayBuilder::SetExpressionAsStatementPosition(Expression* expr) { |
1118 if (expr->position() == RelocInfo::kNoPosition) return; | 992 if (expr->position() == RelocInfo::kNoPosition) return; |
1119 if (exit_seen_in_block_) return; | 993 if (exit_seen_in_block_) return; |
1120 source_position_table_builder_.AddStatementPosition(bytecodes_.size(), | 994 latest_source_info_.Update({expr->position(), true}); |
1121 expr->position()); | |
1122 } | 995 } |
1123 | 996 |
1124 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { | 997 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { |
1125 return temporary_register_allocator()->RegisterIsLive(reg); | 998 return temporary_register_allocator()->RegisterIsLive(reg); |
1126 } | 999 } |
1127 | 1000 |
1128 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, | 1001 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, |
1129 OperandScale operand_scale, | 1002 OperandScale operand_scale, |
1130 int operand_index, | 1003 int operand_index, |
1131 uint32_t operand_value) const { | 1004 uint32_t operand_value) const { |
(...skipping 11 matching lines...) Expand all Loading... |
1143 previous_operand_type != OperandType::kReg) { | 1016 previous_operand_type != OperandType::kReg) { |
1144 return false; | 1017 return false; |
1145 } | 1018 } |
1146 } | 1019 } |
1147 } // Fall-through | 1020 } // Fall-through |
1148 case OperandType::kFlag8: | 1021 case OperandType::kFlag8: |
1149 case OperandType::kIdx: | 1022 case OperandType::kIdx: |
1150 case OperandType::kRuntimeId: | 1023 case OperandType::kRuntimeId: |
1151 case OperandType::kImm: { | 1024 case OperandType::kImm: { |
1152 size_t unsigned_value = static_cast<size_t>(operand_value); | 1025 size_t unsigned_value = static_cast<size_t>(operand_value); |
1153 return SizeForUnsignedOperand(unsigned_value) <= operand_size; | 1026 return Bytecodes::SizeForUnsignedOperand(unsigned_value) <= operand_size; |
1154 } | 1027 } |
1155 case OperandType::kMaybeReg: | 1028 case OperandType::kMaybeReg: |
1156 if (RegisterFromOperand(operand_value) == Register(0)) { | 1029 if (RegisterFromOperand(operand_value) == Register(0)) { |
1157 return true; | 1030 return true; |
1158 } | 1031 } |
1159 // Fall-through to kReg case. | 1032 // Fall-through to kReg case. |
1160 case OperandType::kReg: | 1033 case OperandType::kReg: |
1161 case OperandType::kRegOut: { | 1034 case OperandType::kRegOut: { |
1162 Register reg = RegisterFromOperand(operand_value); | 1035 Register reg = RegisterFromOperand(operand_value); |
1163 return RegisterIsValid(reg, operand_size); | 1036 return RegisterIsValid(reg, operand_size); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1200 } else if (reg.is_parameter()) { | 1073 } else if (reg.is_parameter()) { |
1201 int parameter_index = reg.ToParameterIndex(parameter_count()); | 1074 int parameter_index = reg.ToParameterIndex(parameter_count()); |
1202 return parameter_index >= 0 && parameter_index < parameter_count(); | 1075 return parameter_index >= 0 && parameter_index < parameter_count(); |
1203 } else if (reg.index() < fixed_register_count()) { | 1076 } else if (reg.index() < fixed_register_count()) { |
1204 return true; | 1077 return true; |
1205 } else { | 1078 } else { |
1206 return TemporaryRegisterIsLive(reg); | 1079 return TemporaryRegisterIsLive(reg); |
1207 } | 1080 } |
1208 } | 1081 } |
1209 | 1082 |
1210 | |
1211 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const { | |
1212 return last_bytecode_start_ < bytecodes()->size() && | |
1213 last_bytecode_start_ >= last_block_end_; | |
1214 } | |
1215 | |
1216 | |
1217 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) { | |
1218 if (LastBytecodeInSameBlock()) { | |
1219 PreviousBytecodeHelper previous_bytecode(*this); | |
1220 Bytecode bytecode = previous_bytecode.GetBytecode(); | |
1221 if (bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar) { | |
1222 return previous_bytecode.GetRegisterOperand(0) == reg; | |
1223 } | |
1224 } | |
1225 return false; | |
1226 } | |
1227 | |
1228 | |
1229 // static | 1083 // static |
1230 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { | 1084 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { |
1231 switch (op) { | 1085 switch (op) { |
1232 case Token::Value::ADD: | 1086 case Token::Value::ADD: |
1233 return Bytecode::kAdd; | 1087 return Bytecode::kAdd; |
1234 case Token::Value::SUB: | 1088 case Token::Value::SUB: |
1235 return Bytecode::kSub; | 1089 return Bytecode::kSub; |
1236 case Token::Value::MUL: | 1090 case Token::Value::MUL: |
1237 return Bytecode::kMul; | 1091 return Bytecode::kMul; |
1238 case Token::Value::DIV: | 1092 case Token::Value::DIV: |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1400 case TailCallMode::kDisallow: | 1254 case TailCallMode::kDisallow: |
1401 return Bytecode::kCall; | 1255 return Bytecode::kCall; |
1402 case TailCallMode::kAllow: | 1256 case TailCallMode::kAllow: |
1403 return Bytecode::kTailCall; | 1257 return Bytecode::kTailCall; |
1404 default: | 1258 default: |
1405 UNREACHABLE(); | 1259 UNREACHABLE(); |
1406 } | 1260 } |
1407 return Bytecode::kIllegal; | 1261 return Bytecode::kIllegal; |
1408 } | 1262 } |
1409 | 1263 |
1410 // static | |
1411 OperandSize BytecodeArrayBuilder::SizeForSignedOperand(int value) { | |
1412 if (kMinInt8 <= value && value <= kMaxInt8) { | |
1413 return OperandSize::kByte; | |
1414 } else if (kMinInt16 <= value && value <= kMaxInt16) { | |
1415 return OperandSize::kShort; | |
1416 } else { | |
1417 return OperandSize::kQuad; | |
1418 } | |
1419 } | |
1420 | |
1421 // static | |
1422 OperandSize BytecodeArrayBuilder::SizeForUnsignedOperand(int value) { | |
1423 DCHECK_GE(value, 0); | |
1424 if (value <= kMaxUInt8) { | |
1425 return OperandSize::kByte; | |
1426 } else if (value <= kMaxUInt16) { | |
1427 return OperandSize::kShort; | |
1428 } else { | |
1429 return OperandSize::kQuad; | |
1430 } | |
1431 } | |
1432 | |
1433 OperandSize BytecodeArrayBuilder::SizeForUnsignedOperand(size_t value) { | |
1434 if (value <= static_cast<size_t>(kMaxUInt8)) { | |
1435 return OperandSize::kByte; | |
1436 } else if (value <= static_cast<size_t>(kMaxUInt16)) { | |
1437 return OperandSize::kShort; | |
1438 } else if (value <= kMaxUInt32) { | |
1439 return OperandSize::kQuad; | |
1440 } else { | |
1441 UNREACHABLE(); | |
1442 return OperandSize::kQuad; | |
1443 } | |
1444 } | |
1445 | |
1446 OperandScale BytecodeArrayBuilder::OperandSizesToScale(OperandSize size0, | |
1447 OperandSize size1, | |
1448 OperandSize size2, | |
1449 OperandSize size3) { | |
1450 OperandSize upper = std::max(size0, size1); | |
1451 OperandSize lower = std::max(size2, size3); | |
1452 OperandSize result = std::max(upper, lower); | |
1453 // Operand sizes have been scaled before calling this function. | |
1454 // Currently all scalable operands are byte sized at | |
1455 // OperandScale::kSingle. | |
1456 STATIC_ASSERT(static_cast<int>(OperandSize::kByte) == | |
1457 static_cast<int>(OperandScale::kSingle) && | |
1458 static_cast<int>(OperandSize::kShort) == | |
1459 static_cast<int>(OperandScale::kDouble) && | |
1460 static_cast<int>(OperandSize::kQuad) == | |
1461 static_cast<int>(OperandScale::kQuadruple)); | |
1462 OperandScale operand_scale = static_cast<OperandScale>(result); | |
1463 DCHECK(operand_scale == OperandScale::kSingle || | |
1464 operand_scale == OperandScale::kDouble || | |
1465 operand_scale == OperandScale::kQuadruple); | |
1466 return operand_scale; | |
1467 } | |
1468 | |
1469 uint32_t BytecodeArrayBuilder::RegisterOperand(Register reg) { | 1264 uint32_t BytecodeArrayBuilder::RegisterOperand(Register reg) { |
1470 return static_cast<uint32_t>(reg.ToOperand()); | 1265 return static_cast<uint32_t>(reg.ToOperand()); |
1471 } | 1266 } |
1472 | 1267 |
1473 Register BytecodeArrayBuilder::RegisterFromOperand(uint32_t operand) { | 1268 Register BytecodeArrayBuilder::RegisterFromOperand(uint32_t operand) { |
1474 return Register::FromOperand(static_cast<int32_t>(operand)); | 1269 return Register::FromOperand(static_cast<int32_t>(operand)); |
1475 } | 1270 } |
1476 | 1271 |
1477 uint32_t BytecodeArrayBuilder::SignedOperand(int value, OperandSize size) { | 1272 uint32_t BytecodeArrayBuilder::SignedOperand(int value, OperandSize size) { |
1478 switch (size) { | 1273 switch (size) { |
(...skipping 15 matching lines...) Expand all Loading... |
1494 } | 1289 } |
1495 | 1290 |
1496 uint32_t BytecodeArrayBuilder::UnsignedOperand(size_t value) { | 1291 uint32_t BytecodeArrayBuilder::UnsignedOperand(size_t value) { |
1497 DCHECK_LE(value, kMaxUInt32); | 1292 DCHECK_LE(value, kMaxUInt32); |
1498 return static_cast<uint32_t>(value); | 1293 return static_cast<uint32_t>(value); |
1499 } | 1294 } |
1500 | 1295 |
1501 } // namespace interpreter | 1296 } // namespace interpreter |
1502 } // namespace internal | 1297 } // namespace internal |
1503 } // namespace v8 | 1298 } // namespace v8 |
OLD | NEW |