Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/interpreter/bytecode-array-builder.cc

Issue 2035813002: [Interpreter] Move jump processing to bytecode array writer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@int_fix_bytecode
Patch Set: Address comments Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/interpreter/bytecode-array-builder.h ('k') | src/interpreter/bytecode-array-writer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
7 #include "src/compiler.h" 7 #include "src/compiler.h"
8 #include "src/interpreter/bytecode-array-writer.h" 8 #include "src/interpreter/bytecode-array-writer.h"
9 #include "src/interpreter/bytecode-label.h"
9 #include "src/interpreter/bytecode-peephole-optimizer.h" 10 #include "src/interpreter/bytecode-peephole-optimizer.h"
10 #include "src/interpreter/bytecode-register-optimizer.h" 11 #include "src/interpreter/bytecode-register-optimizer.h"
11 #include "src/interpreter/interpreter-intrinsics.h" 12 #include "src/interpreter/interpreter-intrinsics.h"
12 13
13 namespace v8 { 14 namespace v8 {
14 namespace internal { 15 namespace internal {
15 namespace interpreter { 16 namespace interpreter {
16 17
17 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone, 18 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone,
18 int parameter_count, 19 int parameter_count,
19 int context_count, int locals_count, 20 int context_count, int locals_count,
20 FunctionLiteral* literal) 21 FunctionLiteral* literal)
21 : isolate_(isolate), 22 : isolate_(isolate),
22 zone_(zone), 23 zone_(zone),
23 bytecode_generated_(false), 24 bytecode_generated_(false),
24 constant_array_builder_(isolate, zone), 25 constant_array_builder_(isolate, zone),
25 handler_table_builder_(isolate, zone), 26 handler_table_builder_(isolate, zone),
26 source_position_table_builder_(isolate, zone),
27 return_seen_in_block_(false), 27 return_seen_in_block_(false),
28 unbound_jumps_(0),
29 parameter_count_(parameter_count), 28 parameter_count_(parameter_count),
30 local_register_count_(locals_count), 29 local_register_count_(locals_count),
31 context_register_count_(context_count), 30 context_register_count_(context_count),
32 temporary_allocator_(zone, fixed_register_count()), 31 temporary_allocator_(zone, fixed_register_count()),
33 bytecode_array_writer_(zone, &source_position_table_builder_), 32 bytecode_array_writer_(isolate, zone, &constant_array_builder_),
34 pipeline_(&bytecode_array_writer_) { 33 pipeline_(&bytecode_array_writer_) {
35 DCHECK_GE(parameter_count_, 0); 34 DCHECK_GE(parameter_count_, 0);
36 DCHECK_GE(context_register_count_, 0); 35 DCHECK_GE(context_register_count_, 0);
37 DCHECK_GE(local_register_count_, 0); 36 DCHECK_GE(local_register_count_, 0);
38 37
39 if (FLAG_ignition_peephole) { 38 if (FLAG_ignition_peephole) {
40 pipeline_ = new (zone) 39 pipeline_ = new (zone)
41 BytecodePeepholeOptimizer(&constant_array_builder_, pipeline_); 40 BytecodePeepholeOptimizer(&constant_array_builder_, pipeline_);
42 } 41 }
43 42
44 if (FLAG_ignition_reo) { 43 if (FLAG_ignition_reo) {
45 pipeline_ = new (zone) BytecodeRegisterOptimizer( 44 pipeline_ = new (zone) BytecodeRegisterOptimizer(
46 zone, &temporary_allocator_, parameter_count, pipeline_); 45 zone, &temporary_allocator_, parameter_count, pipeline_);
47 } 46 }
48 47
49 return_position_ = 48 return_position_ =
50 literal ? std::max(literal->start_position(), literal->end_position() - 1) 49 literal ? std::max(literal->start_position(), literal->end_position() - 1)
51 : RelocInfo::kNoPosition; 50 : RelocInfo::kNoPosition;
52 LOG_CODE_EVENT(isolate_, CodeStartLinePosInfoRecordEvent(
53 source_position_table_builder()));
54 } 51 }
55 52
56 Register BytecodeArrayBuilder::first_context_register() const { 53 Register BytecodeArrayBuilder::first_context_register() const {
57 DCHECK_GT(context_register_count_, 0); 54 DCHECK_GT(context_register_count_, 0);
58 return Register(local_register_count_); 55 return Register(local_register_count_);
59 } 56 }
60 57
61
62 Register BytecodeArrayBuilder::last_context_register() const { 58 Register BytecodeArrayBuilder::last_context_register() const {
63 DCHECK_GT(context_register_count_, 0); 59 DCHECK_GT(context_register_count_, 0);
64 return Register(local_register_count_ + context_register_count_ - 1); 60 return Register(local_register_count_ + context_register_count_ - 1);
65 } 61 }
66 62
67
68 Register BytecodeArrayBuilder::Parameter(int parameter_index) const { 63 Register BytecodeArrayBuilder::Parameter(int parameter_index) const {
69 DCHECK_GE(parameter_index, 0); 64 DCHECK_GE(parameter_index, 0);
70 return Register::FromParameterIndex(parameter_index, parameter_count()); 65 return Register::FromParameterIndex(parameter_index, parameter_count());
71 } 66 }
72 67
73
74 bool BytecodeArrayBuilder::RegisterIsParameterOrLocal(Register reg) const { 68 bool BytecodeArrayBuilder::RegisterIsParameterOrLocal(Register reg) const {
75 return reg.is_parameter() || reg.index() < locals_count(); 69 return reg.is_parameter() || reg.index() < locals_count();
76 } 70 }
77 71
72 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() {
73 DCHECK(return_seen_in_block_);
74 DCHECK(!bytecode_generated_);
75 bytecode_generated_ = true;
78 76
79 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() {
80 DCHECK_EQ(0, unbound_jumps_);
81 DCHECK_EQ(bytecode_generated_, false);
82 DCHECK(return_seen_in_block_);
83
84 pipeline()->FlushBasicBlock();
85 const ZoneVector<uint8_t>* bytecodes = bytecode_array_writer()->bytecodes();
86
87 int bytecode_size = static_cast<int>(bytecodes->size());
88
89 // All locals need a frame slot for the debugger, but may not be
90 // present in generated code.
91 int frame_size_for_locals = fixed_register_count() * kPointerSize;
92 int frame_size_used = bytecode_array_writer()->GetMaximumFrameSizeUsed();
93 int frame_size = std::max(frame_size_for_locals, frame_size_used);
94 Handle<FixedArray> constant_pool = constant_array_builder()->ToFixedArray();
95 Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable(); 77 Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable();
96 Handle<ByteArray> source_position_table = 78 return pipeline_->ToBytecodeArray(fixed_register_count(), parameter_count(),
97 source_position_table_builder()->ToSourcePositionTable(); 79 handler_table);
98 Handle<BytecodeArray> bytecode_array = isolate_->factory()->NewBytecodeArray(
99 bytecode_size, &bytecodes->front(), frame_size, parameter_count(),
100 constant_pool);
101 bytecode_array->set_handler_table(*handler_table);
102 bytecode_array->set_source_position_table(*source_position_table);
103
104 void* line_info = source_position_table_builder()->DetachJITHandlerData();
105 LOG_CODE_EVENT(isolate_, CodeEndLinePosInfoRecordEvent(
106 AbstractCode::cast(*bytecode_array), line_info));
107
108 bytecode_generated_ = true;
109 return bytecode_array;
110 } 80 }
111 81
112 void BytecodeArrayBuilder::AttachSourceInfo(BytecodeNode* node) { 82 void BytecodeArrayBuilder::AttachSourceInfo(BytecodeNode* node) {
113 if (latest_source_info_.is_valid()) { 83 if (latest_source_info_.is_valid()) {
114 node->source_info().Update(latest_source_info_); 84 node->source_info().Update(latest_source_info_);
115 latest_source_info_.set_invalid(); 85 latest_source_info_.set_invalid();
116 } 86 }
117 } 87 }
118 88
119 void BytecodeArrayBuilder::Output(Bytecode bytecode) { 89 void BytecodeArrayBuilder::Output(Bytecode bytecode) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 OutputScaled(BytecodeForBinaryOperation(op), operand_scale, 144 OutputScaled(BytecodeForBinaryOperation(op), operand_scale,
175 RegisterOperand(reg)); 145 RegisterOperand(reg));
176 return *this; 146 return *this;
177 } 147 }
178 148
179 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op) { 149 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op) {
180 Output(BytecodeForCountOperation(op)); 150 Output(BytecodeForCountOperation(op));
181 return *this; 151 return *this;
182 } 152 }
183 153
184
185 BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() { 154 BytecodeArrayBuilder& BytecodeArrayBuilder::LogicalNot() {
186 Output(Bytecode::kToBooleanLogicalNot); 155 Output(Bytecode::kToBooleanLogicalNot);
187 return *this; 156 return *this;
188 } 157 }
189 158
190 159
191 BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() { 160 BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() {
192 Output(Bytecode::kTypeOf); 161 Output(Bytecode::kTypeOf);
193 return *this; 162 return *this;
194 } 163 }
195 164
196 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(Token::Value op, 165 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(Token::Value op,
197 Register reg) { 166 Register reg) {
198 OperandScale operand_scale = 167 OperandScale operand_scale =
199 Bytecodes::OperandSizesToScale(reg.SizeOfOperand()); 168 Bytecodes::OperandSizesToScale(reg.SizeOfOperand());
200 OutputScaled(BytecodeForCompareOperation(op), operand_scale, 169 OutputScaled(BytecodeForCompareOperation(op), operand_scale,
201 RegisterOperand(reg)); 170 RegisterOperand(reg));
202 return *this; 171 return *this;
203 } 172 }
204 173
205
206 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( 174 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(
207 v8::internal::Smi* smi) { 175 v8::internal::Smi* smi) {
208 int32_t raw_smi = smi->value(); 176 int32_t raw_smi = smi->value();
209 if (raw_smi == 0) { 177 if (raw_smi == 0) {
210 Output(Bytecode::kLdaZero); 178 Output(Bytecode::kLdaZero);
211 } else { 179 } else {
212 OperandSize operand_size = Bytecodes::SizeForSignedOperand(raw_smi); 180 OperandSize operand_size = Bytecodes::SizeForSignedOperand(raw_smi);
213 OperandScale operand_scale = Bytecodes::OperandSizesToScale(operand_size); 181 OperandScale operand_scale = Bytecodes::OperandSizesToScale(operand_size);
214 OutputScaled(Bytecode::kLdaSmi, operand_scale, 182 OutputScaled(Bytecode::kLdaSmi, operand_scale,
215 SignedOperand(raw_smi, operand_size)); 183 SignedOperand(raw_smi, operand_size));
216 } 184 }
217 return *this; 185 return *this;
218 } 186 }
219 187
220
221 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(Handle<Object> object) { 188 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(Handle<Object> object) {
222 size_t entry = GetConstantPoolEntry(object); 189 size_t entry = GetConstantPoolEntry(object);
223 OperandScale operand_scale = 190 OperandScale operand_scale =
224 Bytecodes::OperandSizesToScale(Bytecodes::SizeForUnsignedOperand(entry)); 191 Bytecodes::OperandSizesToScale(Bytecodes::SizeForUnsignedOperand(entry));
225 OutputScaled(Bytecode::kLdaConstant, operand_scale, UnsignedOperand(entry)); 192 OutputScaled(Bytecode::kLdaConstant, operand_scale, UnsignedOperand(entry));
226 return *this; 193 return *this;
227 } 194 }
228 195
229
230 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadUndefined() { 196 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadUndefined() {
231 Output(Bytecode::kLdaUndefined); 197 Output(Bytecode::kLdaUndefined);
232 return *this; 198 return *this;
233 } 199 }
234 200
235
236 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNull() { 201 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNull() {
237 Output(Bytecode::kLdaNull); 202 Output(Bytecode::kLdaNull);
238 return *this; 203 return *this;
239 } 204 }
240 205
241
242 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTheHole() { 206 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTheHole() {
243 Output(Bytecode::kLdaTheHole); 207 Output(Bytecode::kLdaTheHole);
244 return *this; 208 return *this;
245 } 209 }
246 210
247
248 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTrue() { 211 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadTrue() {
249 Output(Bytecode::kLdaTrue); 212 Output(Bytecode::kLdaTrue);
250 return *this; 213 return *this;
251 } 214 }
252 215
253
254 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() { 216 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() {
255 Output(Bytecode::kLdaFalse); 217 Output(Bytecode::kLdaFalse);
256 return *this; 218 return *this;
257 } 219 }
258 220
259 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( 221 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister(
260 Register reg) { 222 Register reg) {
261 OperandScale operand_scale = 223 OperandScale operand_scale =
262 Bytecodes::OperandSizesToScale(reg.SizeOfOperand()); 224 Bytecodes::OperandSizesToScale(reg.SizeOfOperand());
263 OutputScaled(Bytecode::kLdar, operand_scale, RegisterOperand(reg)); 225 OutputScaled(Bytecode::kLdar, operand_scale, RegisterOperand(reg));
264 return *this; 226 return *this;
265 } 227 }
266 228
267
268 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( 229 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister(
269 Register reg) { 230 Register reg) {
270 OperandScale operand_scale = 231 OperandScale operand_scale =
271 Bytecodes::OperandSizesToScale(reg.SizeOfOperand()); 232 Bytecodes::OperandSizesToScale(reg.SizeOfOperand());
272 OutputScaled(Bytecode::kStar, operand_scale, RegisterOperand(reg)); 233 OutputScaled(Bytecode::kStar, operand_scale, RegisterOperand(reg));
273 return *this; 234 return *this;
274 } 235 }
275 236
276
277 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, 237 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from,
278 Register to) { 238 Register to) {
279 DCHECK(from != to); 239 DCHECK(from != to);
280 OperandScale operand_scale = 240 OperandScale operand_scale =
281 Bytecodes::OperandSizesToScale(from.SizeOfOperand(), to.SizeOfOperand()); 241 Bytecodes::OperandSizesToScale(from.SizeOfOperand(), to.SizeOfOperand());
282 OutputScaled(Bytecode::kMov, operand_scale, RegisterOperand(from), 242 OutputScaled(Bytecode::kMov, operand_scale, RegisterOperand(from),
283 RegisterOperand(to)); 243 RegisterOperand(to));
284 return *this; 244 return *this;
285 } 245 }
286 246
(...skipping 16 matching lines...) Expand all
303 Bytecode bytecode = BytecodeForStoreGlobal(language_mode); 263 Bytecode bytecode = BytecodeForStoreGlobal(language_mode);
304 size_t name_index = GetConstantPoolEntry(name); 264 size_t name_index = GetConstantPoolEntry(name);
305 OperandScale operand_scale = Bytecodes::OperandSizesToScale( 265 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
306 Bytecodes::SizeForUnsignedOperand(name_index), 266 Bytecodes::SizeForUnsignedOperand(name_index),
307 Bytecodes::SizeForUnsignedOperand(feedback_slot)); 267 Bytecodes::SizeForUnsignedOperand(feedback_slot));
308 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index), 268 OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index),
309 UnsignedOperand(feedback_slot)); 269 UnsignedOperand(feedback_slot));
310 return *this; 270 return *this;
311 } 271 }
312 272
313
314 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, 273 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context,
315 int slot_index) { 274 int slot_index) {
316 OperandScale operand_scale = Bytecodes::OperandSizesToScale( 275 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
317 context.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(slot_index)); 276 context.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(slot_index));
318 OutputScaled(Bytecode::kLdaContextSlot, operand_scale, 277 OutputScaled(Bytecode::kLdaContextSlot, operand_scale,
319 RegisterOperand(context), UnsignedOperand(slot_index)); 278 RegisterOperand(context), UnsignedOperand(slot_index));
320 return *this; 279 return *this;
321 } 280 }
322 281
323
324 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, 282 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context,
325 int slot_index) { 283 int slot_index) {
326 OperandScale operand_scale = Bytecodes::OperandSizesToScale( 284 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
327 context.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(slot_index)); 285 context.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(slot_index));
328 OutputScaled(Bytecode::kStaContextSlot, operand_scale, 286 OutputScaled(Bytecode::kStaContextSlot, operand_scale,
329 RegisterOperand(context), UnsignedOperand(slot_index)); 287 RegisterOperand(context), UnsignedOperand(slot_index));
330 return *this; 288 return *this;
331 } 289 }
332 290
333 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( 291 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot(
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 Bytecode bytecode = BytecodeForStoreNamedProperty(language_mode); 337 Bytecode bytecode = BytecodeForStoreNamedProperty(language_mode);
380 size_t name_index = GetConstantPoolEntry(name); 338 size_t name_index = GetConstantPoolEntry(name);
381 OperandScale operand_scale = Bytecodes::OperandSizesToScale( 339 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
382 object.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(name_index), 340 object.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(name_index),
383 Bytecodes::SizeForUnsignedOperand(feedback_slot)); 341 Bytecodes::SizeForUnsignedOperand(feedback_slot));
384 OutputScaled(bytecode, operand_scale, RegisterOperand(object), 342 OutputScaled(bytecode, operand_scale, RegisterOperand(object),
385 UnsignedOperand(name_index), UnsignedOperand(feedback_slot)); 343 UnsignedOperand(name_index), UnsignedOperand(feedback_slot));
386 return *this; 344 return *this;
387 } 345 }
388 346
389
390 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( 347 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty(
391 Register object, Register key, int feedback_slot, 348 Register object, Register key, int feedback_slot,
392 LanguageMode language_mode) { 349 LanguageMode language_mode) {
393 Bytecode bytecode = BytecodeForStoreKeyedProperty(language_mode); 350 Bytecode bytecode = BytecodeForStoreKeyedProperty(language_mode);
394 OperandScale operand_scale = Bytecodes::OperandSizesToScale( 351 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
395 object.SizeOfOperand(), key.SizeOfOperand(), 352 object.SizeOfOperand(), key.SizeOfOperand(),
396 Bytecodes::SizeForUnsignedOperand(feedback_slot)); 353 Bytecodes::SizeForUnsignedOperand(feedback_slot));
397 OutputScaled(bytecode, operand_scale, RegisterOperand(object), 354 OutputScaled(bytecode, operand_scale, RegisterOperand(object),
398 RegisterOperand(key), UnsignedOperand(feedback_slot)); 355 RegisterOperand(key), UnsignedOperand(feedback_slot));
399 return *this; 356 return *this;
400 } 357 }
401 358
402
403 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure( 359 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(
404 Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) { 360 Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) {
405 size_t entry = GetConstantPoolEntry(shared_info); 361 size_t entry = GetConstantPoolEntry(shared_info);
406 OperandScale operand_scale = 362 OperandScale operand_scale =
407 Bytecodes::OperandSizesToScale(Bytecodes::SizeForUnsignedOperand(entry)); 363 Bytecodes::OperandSizesToScale(Bytecodes::SizeForUnsignedOperand(entry));
408 OutputScaled(Bytecode::kCreateClosure, operand_scale, UnsignedOperand(entry), 364 OutputScaled(Bytecode::kCreateClosure, operand_scale, UnsignedOperand(entry),
409 UnsignedOperand(static_cast<size_t>(tenured))); 365 UnsignedOperand(static_cast<size_t>(tenured)));
410 return *this; 366 return *this;
411 } 367 }
412 368
413
414 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments( 369 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments(
415 CreateArgumentsType type) { 370 CreateArgumentsType type) {
416 // TODO(rmcilroy): Consider passing the type as a bytecode operand rather 371 // TODO(rmcilroy): Consider passing the type as a bytecode operand rather
417 // than having two different bytecodes once we have better support for 372 // than having two different bytecodes once we have better support for
418 // branches in the InterpreterAssembler. 373 // branches in the InterpreterAssembler.
419 Bytecode bytecode = BytecodeForCreateArguments(type); 374 Bytecode bytecode = BytecodeForCreateArguments(type);
420 Output(bytecode); 375 Output(bytecode);
421 return *this; 376 return *this;
422 } 377 }
423 378
424
425 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral( 379 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral(
426 Handle<String> pattern, int literal_index, int flags) { 380 Handle<String> pattern, int literal_index, int flags) {
427 size_t pattern_entry = GetConstantPoolEntry(pattern); 381 size_t pattern_entry = GetConstantPoolEntry(pattern);
428 OperandScale operand_scale = Bytecodes::OperandSizesToScale( 382 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
429 Bytecodes::SizeForUnsignedOperand(pattern_entry), 383 Bytecodes::SizeForUnsignedOperand(pattern_entry),
430 Bytecodes::SizeForUnsignedOperand(literal_index), 384 Bytecodes::SizeForUnsignedOperand(literal_index),
431 Bytecodes::SizeForUnsignedOperand(flags)); 385 Bytecodes::SizeForUnsignedOperand(flags));
432 OutputScaled(Bytecode::kCreateRegExpLiteral, operand_scale, 386 OutputScaled(Bytecode::kCreateRegExpLiteral, operand_scale,
433 UnsignedOperand(pattern_entry), UnsignedOperand(literal_index), 387 UnsignedOperand(pattern_entry), UnsignedOperand(literal_index),
434 UnsignedOperand(flags)); 388 UnsignedOperand(flags));
435 return *this; 389 return *this;
436 } 390 }
437 391
438
439 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral( 392 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral(
440 Handle<FixedArray> constant_elements, int literal_index, int flags) { 393 Handle<FixedArray> constant_elements, int literal_index, int flags) {
441 size_t constant_elements_entry = GetConstantPoolEntry(constant_elements); 394 size_t constant_elements_entry = GetConstantPoolEntry(constant_elements);
442 OperandScale operand_scale = Bytecodes::OperandSizesToScale( 395 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
443 Bytecodes::SizeForUnsignedOperand(constant_elements_entry), 396 Bytecodes::SizeForUnsignedOperand(constant_elements_entry),
444 Bytecodes::SizeForUnsignedOperand(literal_index), 397 Bytecodes::SizeForUnsignedOperand(literal_index),
445 Bytecodes::SizeForUnsignedOperand(flags)); 398 Bytecodes::SizeForUnsignedOperand(flags));
446 OutputScaled(Bytecode::kCreateArrayLiteral, operand_scale, 399 OutputScaled(Bytecode::kCreateArrayLiteral, operand_scale,
447 UnsignedOperand(constant_elements_entry), 400 UnsignedOperand(constant_elements_entry),
448 UnsignedOperand(literal_index), UnsignedOperand(flags)); 401 UnsignedOperand(literal_index), UnsignedOperand(flags));
449 return *this; 402 return *this;
450 } 403 }
451 404
452
453 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral( 405 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral(
454 Handle<FixedArray> constant_properties, int literal_index, int flags) { 406 Handle<FixedArray> constant_properties, int literal_index, int flags) {
455 size_t constant_properties_entry = GetConstantPoolEntry(constant_properties); 407 size_t constant_properties_entry = GetConstantPoolEntry(constant_properties);
456 OperandScale operand_scale = Bytecodes::OperandSizesToScale( 408 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
457 Bytecodes::SizeForUnsignedOperand(constant_properties_entry), 409 Bytecodes::SizeForUnsignedOperand(constant_properties_entry),
458 Bytecodes::SizeForUnsignedOperand(literal_index), 410 Bytecodes::SizeForUnsignedOperand(literal_index),
459 Bytecodes::SizeForUnsignedOperand(flags)); 411 Bytecodes::SizeForUnsignedOperand(flags));
460 OutputScaled(Bytecode::kCreateObjectLiteral, operand_scale, 412 OutputScaled(Bytecode::kCreateObjectLiteral, operand_scale,
461 UnsignedOperand(constant_properties_entry), 413 UnsignedOperand(constant_properties_entry),
462 UnsignedOperand(literal_index), UnsignedOperand(flags)); 414 UnsignedOperand(literal_index), UnsignedOperand(flags));
463 return *this; 415 return *this;
464 } 416 }
465 417
466
467 BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) { 418 BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) {
468 OperandScale operand_scale = 419 OperandScale operand_scale =
469 Bytecodes::OperandSizesToScale(context.SizeOfOperand()); 420 Bytecodes::OperandSizesToScale(context.SizeOfOperand());
470 OutputScaled(Bytecode::kPushContext, operand_scale, RegisterOperand(context)); 421 OutputScaled(Bytecode::kPushContext, operand_scale, RegisterOperand(context));
471 return *this; 422 return *this;
472 } 423 }
473 424
474
475 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { 425 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) {
476 OperandScale operand_scale = 426 OperandScale operand_scale =
477 Bytecodes::OperandSizesToScale(context.SizeOfOperand()); 427 Bytecodes::OperandSizesToScale(context.SizeOfOperand());
478 OutputScaled(Bytecode::kPopContext, operand_scale, RegisterOperand(context)); 428 OutputScaled(Bytecode::kPopContext, operand_scale, RegisterOperand(context));
479 return *this; 429 return *this;
480 } 430 }
481 431
482
483 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() { 432 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() {
484 Output(Bytecode::kToObject); 433 Output(Bytecode::kToObject);
485 return *this; 434 return *this;
486 } 435 }
487 436
488
489 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() { 437 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() {
490 Output(Bytecode::kToName); 438 Output(Bytecode::kToName);
491 return *this; 439 return *this;
492 } 440 }
493 441
494 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToNumber() { 442 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToNumber() {
495 Output(Bytecode::kToNumber); 443 Output(Bytecode::kToNumber);
496 return *this; 444 return *this;
497 } 445 }
498 446
499
500 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) { 447 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) {
501 size_t current_offset = pipeline()->FlushForOffset(); 448 pipeline_->BindLabel(label);
502 if (label->is_forward_target()) {
503 // An earlier jump instruction refers to this label. Update it's location.
504 PatchJump(current_offset, label->offset());
505 // Now treat as if the label will only be back referred to.
506 }
507 label->bind_to(current_offset);
508 LeaveBasicBlock(); 449 LeaveBasicBlock();
509 return *this; 450 return *this;
510 } 451 }
511 452
512
513 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target, 453 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target,
514 BytecodeLabel* label) { 454 BytecodeLabel* label) {
515 DCHECK(!label->is_bound()); 455 pipeline_->BindLabel(target, label);
516 DCHECK(target.is_bound());
517 // There is no need to flush the pipeline here, it will have been
518 // flushed when |target| was bound.
519 if (label->is_forward_target()) {
520 // An earlier jump instruction refers to this label. Update it's location.
521 PatchJump(target.offset(), label->offset());
522 // Now treat as if the label will only be back referred to.
523 }
524 label->bind_to(target.offset());
525 LeaveBasicBlock(); 456 LeaveBasicBlock();
526 return *this; 457 return *this;
527 } 458 }
528 459
529
530 // static
531 Bytecode BytecodeArrayBuilder::GetJumpWithConstantOperand(
532 Bytecode jump_bytecode) {
533 switch (jump_bytecode) {
534 case Bytecode::kJump:
535 return Bytecode::kJumpConstant;
536 case Bytecode::kJumpIfTrue:
537 return Bytecode::kJumpIfTrueConstant;
538 case Bytecode::kJumpIfFalse:
539 return Bytecode::kJumpIfFalseConstant;
540 case Bytecode::kJumpIfToBooleanTrue:
541 return Bytecode::kJumpIfToBooleanTrueConstant;
542 case Bytecode::kJumpIfToBooleanFalse:
543 return Bytecode::kJumpIfToBooleanFalseConstant;
544 case Bytecode::kJumpIfNotHole:
545 return Bytecode::kJumpIfNotHoleConstant;
546 case Bytecode::kJumpIfNull:
547 return Bytecode::kJumpIfNullConstant;
548 case Bytecode::kJumpIfUndefined:
549 return Bytecode::kJumpIfUndefinedConstant;
550 default:
551 UNREACHABLE();
552 return Bytecode::kIllegal;
553 }
554 }
555
556 void BytecodeArrayBuilder::PatchJumpWith8BitOperand(
557 ZoneVector<uint8_t>* bytecodes, size_t jump_location, int delta) {
558 Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes->at(jump_location));
559 DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode));
560 size_t operand_location = jump_location + 1;
561 DCHECK_EQ(bytecodes->at(operand_location), 0);
562 if (Bytecodes::SizeForSignedOperand(delta) == OperandSize::kByte) {
563 // The jump fits within the range of an Imm operand, so cancel
564 // the reservation and jump directly.
565 constant_array_builder()->DiscardReservedEntry(OperandSize::kByte);
566 bytecodes->at(operand_location) = static_cast<uint8_t>(delta);
567 } else {
568 // The jump does not fit within the range of an Imm operand, so
569 // commit reservation putting the offset into the constant pool,
570 // and update the jump instruction and operand.
571 size_t entry = constant_array_builder()->CommitReservedEntry(
572 OperandSize::kByte, handle(Smi::FromInt(delta), isolate()));
573 DCHECK(Bytecodes::SizeForUnsignedOperand(entry) == OperandSize::kByte);
574 jump_bytecode = GetJumpWithConstantOperand(jump_bytecode);
575 bytecodes->at(jump_location) = Bytecodes::ToByte(jump_bytecode);
576 bytecodes->at(operand_location) = static_cast<uint8_t>(entry);
577 }
578 }
579
580 void BytecodeArrayBuilder::PatchJumpWith16BitOperand(
581 ZoneVector<uint8_t>* bytecodes, size_t jump_location, int delta) {
582 Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes->at(jump_location));
583 DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode));
584 size_t operand_location = jump_location + 1;
585 uint8_t operand_bytes[2];
586 if (Bytecodes::SizeForSignedOperand(delta) <= OperandSize::kShort) {
587 constant_array_builder()->DiscardReservedEntry(OperandSize::kShort);
588 WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(delta));
589 } else {
590 jump_bytecode = GetJumpWithConstantOperand(jump_bytecode);
591 bytecodes->at(jump_location) = Bytecodes::ToByte(jump_bytecode);
592 size_t entry = constant_array_builder()->CommitReservedEntry(
593 OperandSize::kShort, handle(Smi::FromInt(delta), isolate()));
594 WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(entry));
595 }
596 DCHECK(bytecodes->at(operand_location) == 0 &&
597 bytecodes->at(operand_location + 1) == 0);
598 bytecodes->at(operand_location++) = operand_bytes[0];
599 bytecodes->at(operand_location) = operand_bytes[1];
600 }
601
602 void BytecodeArrayBuilder::PatchJumpWith32BitOperand(
603 ZoneVector<uint8_t>* bytecodes, size_t jump_location, int delta) {
604 DCHECK(Bytecodes::IsJumpImmediate(
605 Bytecodes::FromByte(bytecodes->at(jump_location))));
606 constant_array_builder()->DiscardReservedEntry(OperandSize::kQuad);
607 uint8_t operand_bytes[4];
608 WriteUnalignedUInt32(operand_bytes, static_cast<uint32_t>(delta));
609 size_t operand_location = jump_location + 1;
610 DCHECK(bytecodes->at(operand_location) == 0 &&
611 bytecodes->at(operand_location + 1) == 0 &&
612 bytecodes->at(operand_location + 2) == 0 &&
613 bytecodes->at(operand_location + 3) == 0);
614 bytecodes->at(operand_location++) = operand_bytes[0];
615 bytecodes->at(operand_location++) = operand_bytes[1];
616 bytecodes->at(operand_location++) = operand_bytes[2];
617 bytecodes->at(operand_location) = operand_bytes[3];
618 }
619
620 void BytecodeArrayBuilder::PatchJump(size_t jump_target, size_t jump_location) {
621 ZoneVector<uint8_t>* bytecodes = bytecode_array_writer()->bytecodes();
622 Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes->at(jump_location));
623 int delta = static_cast<int>(jump_target - jump_location);
624 int prefix_offset = 0;
625 OperandScale operand_scale = OperandScale::kSingle;
626 if (Bytecodes::IsPrefixScalingBytecode(jump_bytecode)) {
627 // If a prefix scaling bytecode is emitted the target offset is one
628 // less than the case of no prefix scaling bytecode.
629 delta -= 1;
630 prefix_offset = 1;
631 operand_scale = Bytecodes::PrefixBytecodeToOperandScale(jump_bytecode);
632 jump_bytecode =
633 Bytecodes::FromByte(bytecodes->at(jump_location + prefix_offset));
634 }
635
636 DCHECK(Bytecodes::IsJump(jump_bytecode));
637 switch (operand_scale) {
638 case OperandScale::kSingle:
639 PatchJumpWith8BitOperand(bytecodes, jump_location, delta);
640 break;
641 case OperandScale::kDouble:
642 PatchJumpWith16BitOperand(bytecodes, jump_location + prefix_offset,
643 delta);
644 break;
645 case OperandScale::kQuadruple:
646 PatchJumpWith32BitOperand(bytecodes, jump_location + prefix_offset,
647 delta);
648 break;
649 default:
650 UNREACHABLE();
651 }
652 unbound_jumps_--;
653 }
654
655
656 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, 460 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode,
657 BytecodeLabel* label) { 461 BytecodeLabel* label) {
658 if (label->is_bound()) { 462 BytecodeNode node(jump_bytecode, 0, OperandScale::kSingle);
659 // Label has been bound already so this is a backwards jump. 463 AttachSourceInfo(&node);
660 size_t current_offset = pipeline()->FlushForOffset(); 464 pipeline_->WriteJump(&node, label);
661 CHECK_GE(current_offset, label->offset());
662 CHECK_LE(current_offset, static_cast<size_t>(kMaxInt));
663 size_t abs_delta = current_offset - label->offset();
664 int delta = -static_cast<int>(abs_delta);
665 OperandSize operand_size = Bytecodes::SizeForSignedOperand(delta);
666 if (operand_size > OperandSize::kByte) {
667 // Adjust for scaling byte prefix for wide jump offset.
668 DCHECK_LE(delta, 0);
669 delta -= 1;
670 }
671 OutputScaled(jump_bytecode, Bytecodes::OperandSizesToScale(operand_size),
672 SignedOperand(delta, operand_size));
673 } else {
674 // The label has not yet been bound so this is a forward reference
675 // that will be patched when the label is bound. We create a
676 // reservation in the constant pool so the jump can be patched
677 // when the label is bound. The reservation means the maximum size
678 // of the operand for the constant is known and the jump can
679 // be emitted into the bytecode stream with space for the operand.
680 unbound_jumps_++;
681 OperandSize reserved_operand_size =
682 constant_array_builder()->CreateReservedEntry();
683 OutputScaled(jump_bytecode,
684 Bytecodes::OperandSizesToScale(reserved_operand_size), 0);
685
686 // Calculate the label position by flushing for offset after emitting the
687 // jump bytecode.
688 size_t offset = pipeline()->FlushForOffset();
689 OperandScale operand_scale =
690 Bytecodes::OperandSizesToScale(reserved_operand_size);
691 offset -= Bytecodes::Size(jump_bytecode, operand_scale);
692 if (Bytecodes::OperandScaleRequiresPrefixBytecode(operand_scale)) {
693 offset -= 1;
694 }
695 label->set_referrer(offset);
696 }
697 LeaveBasicBlock(); 465 LeaveBasicBlock();
698 return *this; 466 return *this;
699 } 467 }
700 468
701 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { 469 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) {
702 return OutputJump(Bytecode::kJump, label); 470 return OutputJump(Bytecode::kJump, label);
703 } 471 }
704 472
705 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) { 473 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) {
706 // The peephole optimizer attempts to simplify JumpIfToBooleanTrue 474 // The peephole optimizer attempts to simplify JumpIfToBooleanTrue
707 // to JumpIfTrue. 475 // to JumpIfTrue.
708 return OutputJump(Bytecode::kJumpIfToBooleanTrue, label); 476 return OutputJump(Bytecode::kJumpIfToBooleanTrue, label);
709 } 477 }
710 478
711 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) { 479 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfFalse(BytecodeLabel* label) {
712 // The peephole optimizer attempts to simplify JumpIfToBooleanFalse 480 // The peephole optimizer attempts to simplify JumpIfToBooleanFalse
713 // to JumpIfFalse. 481 // to JumpIfFalse.
714 return OutputJump(Bytecode::kJumpIfToBooleanFalse, label); 482 return OutputJump(Bytecode::kJumpIfToBooleanFalse, label);
715 } 483 }
716 484
717 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) { 485 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNull(BytecodeLabel* label) {
718 return OutputJump(Bytecode::kJumpIfNull, label); 486 return OutputJump(Bytecode::kJumpIfNull, label);
719 } 487 }
720 488
721 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined( 489 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfUndefined(
722 BytecodeLabel* label) { 490 BytecodeLabel* label) {
723 return OutputJump(Bytecode::kJumpIfUndefined, label); 491 return OutputJump(Bytecode::kJumpIfUndefined, label);
724 } 492 }
725 493
494 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole(
495 BytecodeLabel* label) {
496 return OutputJump(Bytecode::kJumpIfNotHole, label);
497 }
498
726 BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) { 499 BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) {
727 if (position != RelocInfo::kNoPosition) { 500 if (position != RelocInfo::kNoPosition) {
728 // We need to attach a non-breakable source position to a stack check, 501 // We need to attach a non-breakable source position to a stack check,
729 // so we simply add it as expression position. 502 // so we simply add it as expression position.
730 latest_source_info_.Update({position, false}); 503 latest_source_info_.Update({position, false});
731 } 504 }
732 Output(Bytecode::kStackCheck); 505 Output(Bytecode::kStackCheck);
733 return *this; 506 return *this;
734 } 507 }
735 508
736 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole(
737 BytecodeLabel* label) {
738 return OutputJump(Bytecode::kJumpIfNotHole, label);
739 }
740
741 BytecodeArrayBuilder& BytecodeArrayBuilder::Throw() { 509 BytecodeArrayBuilder& BytecodeArrayBuilder::Throw() {
742 Output(Bytecode::kThrow); 510 Output(Bytecode::kThrow);
743 return *this; 511 return *this;
744 } 512 }
745 513
746
747 BytecodeArrayBuilder& BytecodeArrayBuilder::ReThrow() { 514 BytecodeArrayBuilder& BytecodeArrayBuilder::ReThrow() {
748 Output(Bytecode::kReThrow); 515 Output(Bytecode::kReThrow);
749 return *this; 516 return *this;
750 } 517 }
751 518
752
753 BytecodeArrayBuilder& BytecodeArrayBuilder::Return() { 519 BytecodeArrayBuilder& BytecodeArrayBuilder::Return() {
754 Output(Bytecode::kReturn); 520 Output(Bytecode::kReturn);
755 return_seen_in_block_ = true; 521 return_seen_in_block_ = true;
756 return *this; 522 return *this;
757 } 523 }
758 524
759 BytecodeArrayBuilder& BytecodeArrayBuilder::Debugger() { 525 BytecodeArrayBuilder& BytecodeArrayBuilder::Debugger() {
760 Output(Bytecode::kDebugger); 526 Output(Bytecode::kDebugger);
761 return *this; 527 return *this;
762 } 528 }
(...skipping 22 matching lines...) Expand all
785 OperandScale operand_scale = Bytecodes::OperandSizesToScale( 551 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
786 receiver.SizeOfOperand(), index.SizeOfOperand(), 552 receiver.SizeOfOperand(), index.SizeOfOperand(),
787 cache_type_array_pair.SizeOfOperand(), 553 cache_type_array_pair.SizeOfOperand(),
788 Bytecodes::SizeForUnsignedOperand(feedback_slot)); 554 Bytecodes::SizeForUnsignedOperand(feedback_slot));
789 OutputScaled(Bytecode::kForInNext, operand_scale, RegisterOperand(receiver), 555 OutputScaled(Bytecode::kForInNext, operand_scale, RegisterOperand(receiver),
790 RegisterOperand(index), RegisterOperand(cache_type_array_pair), 556 RegisterOperand(index), RegisterOperand(cache_type_array_pair),
791 UnsignedOperand(feedback_slot)); 557 UnsignedOperand(feedback_slot));
792 return *this; 558 return *this;
793 } 559 }
794 560
795
796 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) { 561 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) {
797 OperandScale operand_scale = 562 OperandScale operand_scale =
798 Bytecodes::OperandSizesToScale(index.SizeOfOperand()); 563 Bytecodes::OperandSizesToScale(index.SizeOfOperand());
799 OutputScaled(Bytecode::kForInStep, operand_scale, RegisterOperand(index)); 564 OutputScaled(Bytecode::kForInStep, operand_scale, RegisterOperand(index));
800 return *this; 565 return *this;
801 } 566 }
802 567
803
804 BytecodeArrayBuilder& BytecodeArrayBuilder::SuspendGenerator( 568 BytecodeArrayBuilder& BytecodeArrayBuilder::SuspendGenerator(
805 Register generator) { 569 Register generator) {
806 OperandScale operand_scale = 570 OperandScale operand_scale =
807 Bytecodes::OperandSizesToScale(generator.SizeOfOperand()); 571 Bytecodes::OperandSizesToScale(generator.SizeOfOperand());
808 OutputScaled(Bytecode::kSuspendGenerator, operand_scale, 572 OutputScaled(Bytecode::kSuspendGenerator, operand_scale,
809 RegisterOperand(generator)); 573 RegisterOperand(generator));
810 return *this; 574 return *this;
811 } 575 }
812 576
813
814 BytecodeArrayBuilder& BytecodeArrayBuilder::ResumeGenerator( 577 BytecodeArrayBuilder& BytecodeArrayBuilder::ResumeGenerator(
815 Register generator) { 578 Register generator) {
816 OperandScale operand_scale = 579 OperandScale operand_scale =
817 Bytecodes::OperandSizesToScale(generator.SizeOfOperand()); 580 Bytecodes::OperandSizesToScale(generator.SizeOfOperand());
818 OutputScaled(Bytecode::kResumeGenerator, operand_scale, 581 OutputScaled(Bytecode::kResumeGenerator, operand_scale,
819 RegisterOperand(generator)); 582 RegisterOperand(generator));
820 return *this; 583 return *this;
821 } 584 }
822 585
823
824 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(int handler_id, 586 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(int handler_id,
825 bool will_catch) { 587 bool will_catch) {
826 size_t offset = pipeline()->FlushForOffset(); 588 BytecodeLabel handler;
827 handler_table_builder()->SetHandlerTarget(handler_id, offset); 589 Bind(&handler);
590 handler_table_builder()->SetHandlerTarget(handler_id, handler.offset());
828 handler_table_builder()->SetPrediction(handler_id, will_catch); 591 handler_table_builder()->SetPrediction(handler_id, will_catch);
829 return *this; 592 return *this;
830 } 593 }
831 594
832
833 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryBegin(int handler_id, 595 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryBegin(int handler_id,
834 Register context) { 596 Register context) {
835 size_t offset = pipeline()->FlushForOffset(); 597 BytecodeLabel try_begin;
836 handler_table_builder()->SetTryRegionStart(handler_id, offset); 598 Bind(&try_begin);
599 handler_table_builder()->SetTryRegionStart(handler_id, try_begin.offset());
837 handler_table_builder()->SetContextRegister(handler_id, context); 600 handler_table_builder()->SetContextRegister(handler_id, context);
838 return *this; 601 return *this;
839 } 602 }
840 603
841
842 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryEnd(int handler_id) { 604 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryEnd(int handler_id) {
843 size_t offset = pipeline()->FlushForOffset(); 605 BytecodeLabel try_end;
844 handler_table_builder()->SetTryRegionEnd(handler_id, offset); 606 Bind(&try_end);
607 handler_table_builder()->SetTryRegionEnd(handler_id, try_end.offset());
845 return *this; 608 return *this;
846 } 609 }
847 610
848
849 void BytecodeArrayBuilder::LeaveBasicBlock() {
850 pipeline()->FlushBasicBlock();
851 return_seen_in_block_ = false;
852 }
853
854 void BytecodeArrayBuilder::EnsureReturn() { 611 void BytecodeArrayBuilder::EnsureReturn() {
855 if (!return_seen_in_block_) { 612 if (!return_seen_in_block_) {
856 LoadUndefined(); 613 LoadUndefined();
857 SetReturnPosition(); 614 SetReturnPosition();
858 Return(); 615 Return();
859 } 616 }
860 DCHECK(return_seen_in_block_); 617 DCHECK(return_seen_in_block_);
861 } 618 }
862 619
863 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, 620 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
(...skipping 21 matching lines...) Expand all
885 first_arg = Register(0); 642 first_arg = Register(0);
886 } 643 }
887 OperandScale operand_scale = Bytecodes::OperandSizesToScale( 644 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
888 constructor.SizeOfOperand(), first_arg.SizeOfOperand(), 645 constructor.SizeOfOperand(), first_arg.SizeOfOperand(),
889 Bytecodes::SizeForUnsignedOperand(arg_count)); 646 Bytecodes::SizeForUnsignedOperand(arg_count));
890 OutputScaled(Bytecode::kNew, operand_scale, RegisterOperand(constructor), 647 OutputScaled(Bytecode::kNew, operand_scale, RegisterOperand(constructor),
891 RegisterOperand(first_arg), UnsignedOperand(arg_count)); 648 RegisterOperand(first_arg), UnsignedOperand(arg_count));
892 return *this; 649 return *this;
893 } 650 }
894 651
895
896 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime( 652 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime(
897 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) { 653 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) {
898 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size); 654 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size);
899 DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort); 655 DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort);
900 if (!first_arg.is_valid()) { 656 if (!first_arg.is_valid()) {
901 DCHECK_EQ(0u, arg_count); 657 DCHECK_EQ(0u, arg_count);
902 first_arg = Register(0); 658 first_arg = Register(0);
903 } 659 }
904 Bytecode bytecode = IntrinsicsHelper::IsSupported(function_id) 660 Bytecode bytecode = IntrinsicsHelper::IsSupported(function_id)
905 ? Bytecode::kInvokeIntrinsic 661 ? Bytecode::kInvokeIntrinsic
906 : Bytecode::kCallRuntime; 662 : Bytecode::kCallRuntime;
907 OperandScale operand_scale = Bytecodes::OperandSizesToScale( 663 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
908 first_arg.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(arg_count)); 664 first_arg.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(arg_count));
909 OutputScaled(bytecode, operand_scale, static_cast<uint16_t>(function_id), 665 OutputScaled(bytecode, operand_scale, static_cast<uint16_t>(function_id),
910 RegisterOperand(first_arg), UnsignedOperand(arg_count)); 666 RegisterOperand(first_arg), UnsignedOperand(arg_count));
911 return *this; 667 return *this;
912 } 668 }
913 669
914
915 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair( 670 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair(
916 Runtime::FunctionId function_id, Register first_arg, size_t arg_count, 671 Runtime::FunctionId function_id, Register first_arg, size_t arg_count,
917 Register first_return) { 672 Register first_return) {
918 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size); 673 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size);
919 DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort); 674 DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort);
920 if (!first_arg.is_valid()) { 675 if (!first_arg.is_valid()) {
921 DCHECK_EQ(0u, arg_count); 676 DCHECK_EQ(0u, arg_count);
922 first_arg = Register(0); 677 first_arg = Register(0);
923 } 678 }
924 OperandScale operand_scale = Bytecodes::OperandSizesToScale( 679 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
(...skipping 10 matching lines...) Expand all
935 OperandScale operand_scale = Bytecodes::OperandSizesToScale( 690 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
936 Bytecodes::SizeForUnsignedOperand(context_index), 691 Bytecodes::SizeForUnsignedOperand(context_index),
937 receiver_args.SizeOfOperand(), 692 receiver_args.SizeOfOperand(),
938 Bytecodes::SizeForUnsignedOperand(receiver_args_count)); 693 Bytecodes::SizeForUnsignedOperand(receiver_args_count));
939 OutputScaled(Bytecode::kCallJSRuntime, operand_scale, 694 OutputScaled(Bytecode::kCallJSRuntime, operand_scale,
940 UnsignedOperand(context_index), RegisterOperand(receiver_args), 695 UnsignedOperand(context_index), RegisterOperand(receiver_args),
941 UnsignedOperand(receiver_args_count)); 696 UnsignedOperand(receiver_args_count));
942 return *this; 697 return *this;
943 } 698 }
944 699
945
946 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, 700 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object,
947 LanguageMode language_mode) { 701 LanguageMode language_mode) {
948 OperandScale operand_scale = 702 OperandScale operand_scale =
949 Bytecodes::OperandSizesToScale(object.SizeOfOperand()); 703 Bytecodes::OperandSizesToScale(object.SizeOfOperand());
950 OutputScaled(BytecodeForDelete(language_mode), operand_scale, 704 OutputScaled(BytecodeForDelete(language_mode), operand_scale,
951 RegisterOperand(object)); 705 RegisterOperand(object));
952 return *this; 706 return *this;
953 } 707 }
954 708
955 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { 709 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) {
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1086 case Token::Value::SAR: 840 case Token::Value::SAR:
1087 return Bytecode::kShiftRight; 841 return Bytecode::kShiftRight;
1088 case Token::Value::SHR: 842 case Token::Value::SHR:
1089 return Bytecode::kShiftRightLogical; 843 return Bytecode::kShiftRightLogical;
1090 default: 844 default:
1091 UNREACHABLE(); 845 UNREACHABLE();
1092 return Bytecode::kIllegal; 846 return Bytecode::kIllegal;
1093 } 847 }
1094 } 848 }
1095 849
1096
1097 // static 850 // static
1098 Bytecode BytecodeArrayBuilder::BytecodeForCountOperation(Token::Value op) { 851 Bytecode BytecodeArrayBuilder::BytecodeForCountOperation(Token::Value op) {
1099 switch (op) { 852 switch (op) {
1100 case Token::Value::ADD: 853 case Token::Value::ADD:
1101 return Bytecode::kInc; 854 return Bytecode::kInc;
1102 case Token::Value::SUB: 855 case Token::Value::SUB:
1103 return Bytecode::kDec; 856 return Bytecode::kDec;
1104 default: 857 default:
1105 UNREACHABLE(); 858 UNREACHABLE();
1106 return Bytecode::kIllegal; 859 return Bytecode::kIllegal;
1107 } 860 }
1108 } 861 }
1109 862
1110
1111 // static 863 // static
1112 Bytecode BytecodeArrayBuilder::BytecodeForCompareOperation(Token::Value op) { 864 Bytecode BytecodeArrayBuilder::BytecodeForCompareOperation(Token::Value op) {
1113 switch (op) { 865 switch (op) {
1114 case Token::Value::EQ: 866 case Token::Value::EQ:
1115 return Bytecode::kTestEqual; 867 return Bytecode::kTestEqual;
1116 case Token::Value::NE: 868 case Token::Value::NE:
1117 return Bytecode::kTestNotEqual; 869 return Bytecode::kTestNotEqual;
1118 case Token::Value::EQ_STRICT: 870 case Token::Value::EQ_STRICT:
1119 return Bytecode::kTestEqualStrict; 871 return Bytecode::kTestEqualStrict;
1120 case Token::Value::LT: 872 case Token::Value::LT:
1121 return Bytecode::kTestLessThan; 873 return Bytecode::kTestLessThan;
1122 case Token::Value::GT: 874 case Token::Value::GT:
1123 return Bytecode::kTestGreaterThan; 875 return Bytecode::kTestGreaterThan;
1124 case Token::Value::LTE: 876 case Token::Value::LTE:
1125 return Bytecode::kTestLessThanOrEqual; 877 return Bytecode::kTestLessThanOrEqual;
1126 case Token::Value::GTE: 878 case Token::Value::GTE:
1127 return Bytecode::kTestGreaterThanOrEqual; 879 return Bytecode::kTestGreaterThanOrEqual;
1128 case Token::Value::INSTANCEOF: 880 case Token::Value::INSTANCEOF:
1129 return Bytecode::kTestInstanceOf; 881 return Bytecode::kTestInstanceOf;
1130 case Token::Value::IN: 882 case Token::Value::IN:
1131 return Bytecode::kTestIn; 883 return Bytecode::kTestIn;
1132 default: 884 default:
1133 UNREACHABLE(); 885 UNREACHABLE();
1134 return Bytecode::kIllegal; 886 return Bytecode::kIllegal;
1135 } 887 }
1136 } 888 }
1137 889
1138
1139 // static 890 // static
1140 Bytecode BytecodeArrayBuilder::BytecodeForStoreNamedProperty( 891 Bytecode BytecodeArrayBuilder::BytecodeForStoreNamedProperty(
1141 LanguageMode language_mode) { 892 LanguageMode language_mode) {
1142 switch (language_mode) { 893 switch (language_mode) {
1143 case SLOPPY: 894 case SLOPPY:
1144 return Bytecode::kStaNamedPropertySloppy; 895 return Bytecode::kStaNamedPropertySloppy;
1145 case STRICT: 896 case STRICT:
1146 return Bytecode::kStaNamedPropertyStrict; 897 return Bytecode::kStaNamedPropertyStrict;
1147 default: 898 default:
1148 UNREACHABLE(); 899 UNREACHABLE();
1149 } 900 }
1150 return Bytecode::kIllegal; 901 return Bytecode::kIllegal;
1151 } 902 }
1152 903
1153
1154 // static 904 // static
1155 Bytecode BytecodeArrayBuilder::BytecodeForStoreKeyedProperty( 905 Bytecode BytecodeArrayBuilder::BytecodeForStoreKeyedProperty(
1156 LanguageMode language_mode) { 906 LanguageMode language_mode) {
1157 switch (language_mode) { 907 switch (language_mode) {
1158 case SLOPPY: 908 case SLOPPY:
1159 return Bytecode::kStaKeyedPropertySloppy; 909 return Bytecode::kStaKeyedPropertySloppy;
1160 case STRICT: 910 case STRICT:
1161 return Bytecode::kStaKeyedPropertyStrict; 911 return Bytecode::kStaKeyedPropertyStrict;
1162 default: 912 default:
1163 UNREACHABLE(); 913 UNREACHABLE();
1164 } 914 }
1165 return Bytecode::kIllegal; 915 return Bytecode::kIllegal;
1166 } 916 }
1167 917
1168
1169 // static 918 // static
1170 Bytecode BytecodeArrayBuilder::BytecodeForLoadGlobal(TypeofMode typeof_mode) { 919 Bytecode BytecodeArrayBuilder::BytecodeForLoadGlobal(TypeofMode typeof_mode) {
1171 return typeof_mode == INSIDE_TYPEOF ? Bytecode::kLdaGlobalInsideTypeof 920 return typeof_mode == INSIDE_TYPEOF ? Bytecode::kLdaGlobalInsideTypeof
1172 : Bytecode::kLdaGlobal; 921 : Bytecode::kLdaGlobal;
1173 } 922 }
1174 923
1175
1176 // static 924 // static
1177 Bytecode BytecodeArrayBuilder::BytecodeForStoreGlobal( 925 Bytecode BytecodeArrayBuilder::BytecodeForStoreGlobal(
1178 LanguageMode language_mode) { 926 LanguageMode language_mode) {
1179 switch (language_mode) { 927 switch (language_mode) {
1180 case SLOPPY: 928 case SLOPPY:
1181 return Bytecode::kStaGlobalSloppy; 929 return Bytecode::kStaGlobalSloppy;
1182 case STRICT: 930 case STRICT:
1183 return Bytecode::kStaGlobalStrict; 931 return Bytecode::kStaGlobalStrict;
1184 default: 932 default:
1185 UNREACHABLE(); 933 UNREACHABLE();
1186 } 934 }
1187 return Bytecode::kIllegal; 935 return Bytecode::kIllegal;
1188 } 936 }
1189 937
1190
1191 // static 938 // static
1192 Bytecode BytecodeArrayBuilder::BytecodeForStoreLookupSlot( 939 Bytecode BytecodeArrayBuilder::BytecodeForStoreLookupSlot(
1193 LanguageMode language_mode) { 940 LanguageMode language_mode) {
1194 switch (language_mode) { 941 switch (language_mode) {
1195 case SLOPPY: 942 case SLOPPY:
1196 return Bytecode::kStaLookupSlotSloppy; 943 return Bytecode::kStaLookupSlotSloppy;
1197 case STRICT: 944 case STRICT:
1198 return Bytecode::kStaLookupSlotStrict; 945 return Bytecode::kStaLookupSlotStrict;
1199 default: 946 default:
1200 UNREACHABLE(); 947 UNREACHABLE();
1201 } 948 }
1202 return Bytecode::kIllegal; 949 return Bytecode::kIllegal;
1203 } 950 }
1204 951
1205 // static 952 // static
1206 Bytecode BytecodeArrayBuilder::BytecodeForCreateArguments( 953 Bytecode BytecodeArrayBuilder::BytecodeForCreateArguments(
1207 CreateArgumentsType type) { 954 CreateArgumentsType type) {
1208 switch (type) { 955 switch (type) {
1209 case CreateArgumentsType::kMappedArguments: 956 case CreateArgumentsType::kMappedArguments:
1210 return Bytecode::kCreateMappedArguments; 957 return Bytecode::kCreateMappedArguments;
1211 case CreateArgumentsType::kUnmappedArguments: 958 case CreateArgumentsType::kUnmappedArguments:
1212 return Bytecode::kCreateUnmappedArguments; 959 return Bytecode::kCreateUnmappedArguments;
1213 case CreateArgumentsType::kRestParameter: 960 case CreateArgumentsType::kRestParameter:
1214 return Bytecode::kCreateRestParameter; 961 return Bytecode::kCreateRestParameter;
1215 } 962 }
1216 UNREACHABLE(); 963 UNREACHABLE();
1217 return Bytecode::kIllegal; 964 return Bytecode::kIllegal;
1218 } 965 }
1219 966
1220
1221 // static 967 // static
1222 Bytecode BytecodeArrayBuilder::BytecodeForDelete(LanguageMode language_mode) { 968 Bytecode BytecodeArrayBuilder::BytecodeForDelete(LanguageMode language_mode) {
1223 switch (language_mode) { 969 switch (language_mode) {
1224 case SLOPPY: 970 case SLOPPY:
1225 return Bytecode::kDeletePropertySloppy; 971 return Bytecode::kDeletePropertySloppy;
1226 case STRICT: 972 case STRICT:
1227 return Bytecode::kDeletePropertyStrict; 973 return Bytecode::kDeletePropertyStrict;
1228 default: 974 default:
1229 UNREACHABLE(); 975 UNREACHABLE();
1230 } 976 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1272 } 1018 }
1273 1019
1274 uint32_t BytecodeArrayBuilder::UnsignedOperand(size_t value) { 1020 uint32_t BytecodeArrayBuilder::UnsignedOperand(size_t value) {
1275 DCHECK_LE(value, kMaxUInt32); 1021 DCHECK_LE(value, kMaxUInt32);
1276 return static_cast<uint32_t>(value); 1022 return static_cast<uint32_t>(value);
1277 } 1023 }
1278 1024
1279 } // namespace interpreter 1025 } // namespace interpreter
1280 } // namespace internal 1026 } // namespace internal
1281 } // namespace v8 1027 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-array-builder.h ('k') | src/interpreter/bytecode-array-writer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698