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

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

Issue 1613163002: [interpreter] Wide register support. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Added tests, fixed off-by-one error in register indicies. Created 4 years, 11 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
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 namespace v8 { 7 namespace v8 {
8 namespace internal { 8 namespace internal {
9 namespace interpreter { 9 namespace interpreter {
10 10
11 class BytecodeArrayBuilder::PreviousBytecodeHelper { 11 class BytecodeArrayBuilder::PreviousBytecodeHelper BASE_EMBEDDED {
12 public: 12 public:
13 explicit PreviousBytecodeHelper(const BytecodeArrayBuilder& array_builder) 13 explicit PreviousBytecodeHelper(const BytecodeArrayBuilder& array_builder)
14 : array_builder_(array_builder), 14 : array_builder_(array_builder),
15 previous_bytecode_start_(array_builder_.last_bytecode_start_) { 15 previous_bytecode_start_(array_builder_.last_bytecode_start_) {
16 // This helper is expected to be instantiated only when the last bytecode is 16 // This helper is expected to be instantiated only when the last bytecode is
17 // in the same basic block. 17 // in the same basic block.
18 DCHECK(array_builder_.LastBytecodeInSameBlock()); 18 DCHECK(array_builder_.LastBytecodeInSameBlock());
19 } 19 }
20 20
21 // Returns the previous bytecode in the same basic block. 21 // Returns the previous bytecode in the same basic block.
22 MUST_USE_RESULT Bytecode GetBytecode() const { 22 MUST_USE_RESULT Bytecode GetBytecode() const {
23 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_); 23 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_);
24 return Bytecodes::FromByte( 24 return Bytecodes::FromByte(
25 array_builder_.bytecodes()->at(previous_bytecode_start_)); 25 array_builder_.bytecodes()->at(previous_bytecode_start_));
26 } 26 }
27 27
28 // Returns the operand at operand_index for the previous bytecode in the 28 // Returns the operand at operand_index for the previous bytecode in the
29 // same basic block. 29 // same basic block.
30 MUST_USE_RESULT uint32_t GetOperand(int operand_index) const { 30 MUST_USE_RESULT uint32_t GetOperand(int operand_index) const {
31 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_); 31 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_);
32 Bytecode bytecode = GetBytecode(); 32 Bytecode bytecode = GetBytecode();
33 DCHECK_GE(operand_index, 0); 33 DCHECK_GE(operand_index, 0);
34 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode)); 34 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode));
35 size_t operand_offset = 35 size_t operand_offset =
36 previous_bytecode_start_ + 36 previous_bytecode_start_ +
37 Bytecodes::GetOperandOffset(bytecode, operand_index); 37 Bytecodes::GetOperandOffset(bytecode, operand_index);
38 OperandSize size = Bytecodes::GetOperandSize(bytecode, operand_index); 38 OperandSize size = Bytecodes::GetOperandSize(bytecode, operand_index);
39 switch (size) { 39 switch (size) {
40 default:
41 case OperandSize::kNone: 40 case OperandSize::kNone:
42 UNREACHABLE(); 41 UNREACHABLE();
42 break;
43 case OperandSize::kByte: 43 case OperandSize::kByte:
44 return static_cast<uint32_t>( 44 return static_cast<uint32_t>(
45 array_builder_.bytecodes()->at(operand_offset)); 45 array_builder_.bytecodes()->at(operand_offset));
46 case OperandSize::kShort: 46 case OperandSize::kShort:
47 uint16_t operand = 47 uint16_t operand =
48 (array_builder_.bytecodes()->at(operand_offset) << 8) + 48 (array_builder_.bytecodes()->at(operand_offset) << 8) +
49 array_builder_.bytecodes()->at(operand_offset + 1); 49 array_builder_.bytecodes()->at(operand_offset + 1);
50 return static_cast<uint32_t>(operand); 50 return static_cast<uint32_t>(operand);
51 } 51 }
52 return 0;
52 } 53 }
53 54
54 Handle<Object> GetConstantForIndexOperand(int operand_index) const { 55 Handle<Object> GetConstantForIndexOperand(int operand_index) const {
55 return array_builder_.constant_array_builder()->At( 56 return array_builder_.constant_array_builder()->At(
56 GetOperand(operand_index)); 57 GetOperand(operand_index));
57 } 58 }
58 59
59 private: 60 private:
60 const BytecodeArrayBuilder& array_builder_; 61 const BytecodeArrayBuilder& array_builder_;
61 size_t previous_bytecode_start_; 62 size_t previous_bytecode_start_;
62 63
63 DISALLOW_COPY_AND_ASSIGN(PreviousBytecodeHelper); 64 DISALLOW_COPY_AND_ASSIGN(PreviousBytecodeHelper);
64 }; 65 };
65 66
66 67
68 class BytecodeArrayBuilder::RegisterTranslationScope BASE_EMBEDDED {
69 public:
70 static const Bytecode kInvalidBytecode = static_cast<Bytecode>(-1);
71
72 RegisterTranslationScope(BytecodeArrayBuilder* builder,
73 Bytecode bytecode = kInvalidBytecode)
74 : builder_(builder), bytecode_(bytecode) {
75 builder->set_register_translation_scope(this);
rmcilroy 2016/01/22 17:50:56 DCHECK_EQ(nullptr, builder()->register_translation
76 }
77
78 ~RegisterTranslationScope() {
79 translator()->CompleteTranslations();
80 builder()->set_register_translation_scope(nullptr);
81 }
82
83 Register Translate(Register reg) {
84 return translator()->Translate(bytecode(), reg);
85 }
86
87 void set_bytecode(Bytecode bytecode) { bytecode_ = bytecode; }
88 Bytecode bytecode() const { return bytecode_; }
89
90 private:
91 BytecodeArrayBuilder* builder() const { return builder_; }
92 RegisterTranslator* translator() { return builder()->register_translator(); }
93
94 BytecodeArrayBuilder* builder_;
95 Bytecode bytecode_;
96
97 DISALLOW_COPY_AND_ASSIGN(RegisterTranslationScope);
98 };
99
100
67 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone) 101 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone)
68 : isolate_(isolate), 102 : isolate_(isolate),
69 zone_(zone), 103 zone_(zone),
70 bytecodes_(zone), 104 bytecodes_(zone),
71 bytecode_generated_(false), 105 bytecode_generated_(false),
72 constant_array_builder_(isolate, zone), 106 constant_array_builder_(isolate, zone),
73 handler_table_builder_(isolate, zone), 107 handler_table_builder_(isolate, zone),
74 last_block_end_(0), 108 last_block_end_(0),
75 last_bytecode_start_(~0), 109 last_bytecode_start_(~0),
76 exit_seen_in_block_(false), 110 exit_seen_in_block_(false),
77 unbound_jumps_(0), 111 unbound_jumps_(0),
78 parameter_count_(-1), 112 parameter_count_(-1),
79 local_register_count_(-1), 113 local_register_count_(-1),
80 context_register_count_(-1), 114 context_register_count_(-1),
81 temporary_register_count_(0), 115 temporary_register_count_(0),
82 free_temporaries_(zone) {} 116 free_temporaries_(zone),
117 register_translator_(this),
118 register_translation_scope_(nullptr) {}
83 119
84 120
85 BytecodeArrayBuilder::~BytecodeArrayBuilder() { DCHECK_EQ(0, unbound_jumps_); } 121 BytecodeArrayBuilder::~BytecodeArrayBuilder() { DCHECK_EQ(0, unbound_jumps_); }
86 122
87 123
88 void BytecodeArrayBuilder::set_locals_count(int number_of_locals) { 124 void BytecodeArrayBuilder::set_locals_count(int number_of_locals) {
89 local_register_count_ = number_of_locals; 125 local_register_count_ = number_of_locals;
90 DCHECK_LE(context_register_count_, 0); 126 DCHECK_LE(context_register_count_, 0);
91 } 127 }
92 128
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 return temporary_register_count_ > 0 && first_temporary_register() <= reg && 177 return temporary_register_count_ > 0 && first_temporary_register() <= reg &&
142 reg <= last_temporary_register(); 178 reg <= last_temporary_register();
143 } 179 }
144 180
145 181
146 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { 182 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() {
147 DCHECK_EQ(bytecode_generated_, false); 183 DCHECK_EQ(bytecode_generated_, false);
148 EnsureReturn(); 184 EnsureReturn();
149 185
150 int bytecode_size = static_cast<int>(bytecodes_.size()); 186 int bytecode_size = static_cast<int>(bytecodes_.size());
151 int register_count = fixed_register_count() + temporary_register_count_; 187 int register_count =
188 fixed_and_temporary_register_count() + translation_register_count();
152 int frame_size = register_count * kPointerSize; 189 int frame_size = register_count * kPointerSize;
153 Handle<FixedArray> constant_pool = constant_array_builder()->ToFixedArray(); 190 Handle<FixedArray> constant_pool = constant_array_builder()->ToFixedArray();
154 Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable(); 191 Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable();
155 Handle<BytecodeArray> output = isolate_->factory()->NewBytecodeArray( 192 Handle<BytecodeArray> output = isolate_->factory()->NewBytecodeArray(
156 bytecode_size, &bytecodes_.front(), frame_size, parameter_count(), 193 bytecode_size, &bytecodes_.front(), frame_size, parameter_count(),
157 constant_pool); 194 constant_pool);
158 output->set_handler_table(*handler_table); 195 output->set_handler_table(*handler_table);
159 bytecode_generated_ = true; 196 bytecode_generated_ = true;
160 return output; 197 return output;
161 } 198 }
162 199
163 200
164 template <size_t N> 201 template <size_t N>
165 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) { 202 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) {
166 // Don't output dead code. 203 // Don't output dead code.
167 if (exit_seen_in_block_) return; 204 if (exit_seen_in_block_) return;
168 205
169 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), static_cast<int>(N)); 206 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), static_cast<int>(N));
207 DCHECK((register_translation_scope() == nullptr &&
208 Bytecodes::NumberOfRegisterOperands(bytecode) == 0) ||
209 (register_translation_scope() != nullptr &&
210 Bytecodes::NumberOfRegisterOperands(bytecode) > 0));
211 DCHECK(register_translator()->RegisterOperandsValid(bytecode, operands,
212 static_cast<int>(N)));
213
170 last_bytecode_start_ = bytecodes()->size(); 214 last_bytecode_start_ = bytecodes()->size();
171 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); 215 bytecodes()->push_back(Bytecodes::ToByte(bytecode));
172 for (int i = 0; i < static_cast<int>(N); i++) { 216 for (int i = 0; i < static_cast<int>(N); i++) {
173 DCHECK(OperandIsValid(bytecode, i, operands[i])); 217 DCHECK(OperandIsValid(bytecode, i, operands[i]));
174 switch (Bytecodes::GetOperandSize(bytecode, i)) { 218 switch (Bytecodes::GetOperandSize(bytecode, i)) {
175 case OperandSize::kNone: 219 case OperandSize::kNone:
176 UNREACHABLE(); 220 UNREACHABLE();
221 break;
177 case OperandSize::kByte: 222 case OperandSize::kByte:
178 bytecodes()->push_back(static_cast<uint8_t>(operands[i])); 223 bytecodes()->push_back(static_cast<uint8_t>(operands[i]));
179 break; 224 break;
180 case OperandSize::kShort: { 225 case OperandSize::kShort: {
181 uint8_t operand_bytes[2]; 226 uint8_t operand_bytes[2];
182 WriteUnalignedUInt16(operand_bytes, operands[i]); 227 WriteUnalignedUInt16(operand_bytes, operands[i]);
183 bytecodes()->insert(bytecodes()->end(), operand_bytes, 228 bytecodes()->insert(bytecodes()->end(), operand_bytes,
184 operand_bytes + 2); 229 operand_bytes + 2);
185 break; 230 break;
186 } 231 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 } 272 }
228 273
229 274
230 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, 275 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op,
231 Register reg, 276 Register reg,
232 Strength strength) { 277 Strength strength) {
233 if (is_strong(strength)) { 278 if (is_strong(strength)) {
234 UNIMPLEMENTED(); 279 UNIMPLEMENTED();
235 } 280 }
236 281
237 Output(BytecodeForBinaryOperation(op), reg.ToRawOperand()); 282 RegisterTranslationScope translator(this, BytecodeForBinaryOperation(op));
283 reg = translator.Translate(reg);
284 Output(translator.bytecode(), reg.ToRawOperand());
rmcilroy 2016/01/22 17:50:56 To avoid the extra translate call, could we write
238 return *this; 285 return *this;
239 } 286 }
240 287
241 288
242 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op, 289 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op,
243 Strength strength) { 290 Strength strength) {
244 if (is_strong(strength)) { 291 if (is_strong(strength)) {
245 UNIMPLEMENTED(); 292 UNIMPLEMENTED();
246 } 293 }
247 294
(...skipping 13 matching lines...) Expand all
261 return *this; 308 return *this;
262 } 309 }
263 310
264 311
265 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation( 312 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(
266 Token::Value op, Register reg, Strength strength) { 313 Token::Value op, Register reg, Strength strength) {
267 if (is_strong(strength)) { 314 if (is_strong(strength)) {
268 UNIMPLEMENTED(); 315 UNIMPLEMENTED();
269 } 316 }
270 317
271 Output(BytecodeForCompareOperation(op), reg.ToRawOperand()); 318 RegisterTranslationScope translator(this, BytecodeForCompareOperation(op));
319 reg = translator.Translate(reg);
320 Output(translator.bytecode(), reg.ToRawOperand());
272 return *this; 321 return *this;
273 } 322 }
274 323
275 324
276 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( 325 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(
277 v8::internal::Smi* smi) { 326 v8::internal::Smi* smi) {
278 int32_t raw_smi = smi->value(); 327 int32_t raw_smi = smi->value();
279 if (raw_smi == 0) { 328 if (raw_smi == 0) {
280 Output(Bytecode::kLdaZero); 329 Output(Bytecode::kLdaZero);
281 } else if (raw_smi >= -128 && raw_smi <= 127) { 330 } else if (raw_smi >= -128 && raw_smi <= 127) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 LoadTrue(); 384 LoadTrue();
336 } else { 385 } else {
337 LoadFalse(); 386 LoadFalse();
338 } 387 }
339 return *this; 388 return *this;
340 } 389 }
341 390
342 391
343 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( 392 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister(
344 Register reg) { 393 Register reg) {
394 RegisterTranslationScope translator(this, Bytecode::kLdar);
395 reg = translator.Translate(reg);
345 if (!IsRegisterInAccumulator(reg)) { 396 if (!IsRegisterInAccumulator(reg)) {
346 Output(Bytecode::kLdar, reg.ToRawOperand()); 397 Output(translator.bytecode(), reg.ToRawOperand());
347 } 398 }
348 return *this; 399 return *this;
349 } 400 }
350 401
351 402
352 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( 403 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister(
353 Register reg) { 404 Register reg) {
405 RegisterTranslationScope translator(this, Bytecode::kStar);
406 reg = translator.Translate(reg);
354 if (!IsRegisterInAccumulator(reg)) { 407 if (!IsRegisterInAccumulator(reg)) {
355 Output(Bytecode::kStar, reg.ToRawOperand()); 408 Output(translator.bytecode(), reg.ToRawOperand());
356 } 409 }
357 return *this; 410 return *this;
358 } 411 }
359 412
360 413
361 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, 414 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from,
362 Register to) { 415 Register to) {
363 DCHECK(from != to); 416 DCHECK(from != to);
364 if (FitsInReg8Operand(to) && FitsInReg8Operand(from)) { 417 RegisterTranslationScope translator(this);
rmcilroy 2016/01/22 17:50:56 Personally I would prefer that the RegisterTransla
365 Output(Bytecode::kMov, from.ToRawOperand(), to.ToRawOperand()); 418 if (FitsInReg8Operand(from) && FitsInReg8Operand(to)) {
366 } else if (FitsInReg16Operand(to) && FitsInReg16Operand(from)) { 419 translator.set_bytecode(Bytecode::kMov);
367 Output(Bytecode::kMovWide, from.ToRawOperand(), to.ToRawOperand()); 420 } else if (FitsInReg16Operand(from) && FitsInReg16Operand(to)) {
421 translator.set_bytecode(Bytecode::kMovWide);
368 } else { 422 } else {
369 UNIMPLEMENTED(); 423 UNIMPLEMENTED();
370 } 424 }
425 from = translator.Translate(from);
426 to = translator.Translate(to);
427 Output(translator.bytecode(), from.ToRawOperand(), to.ToRawOperand());
371 return *this; 428 return *this;
372 } 429 }
373 430
374 431
432 bool BytecodeArrayBuilder::MoveRegisterUntranslated(Register from,
433 Register to) {
434 if (!from.is_valid() || !to.is_valid()) {
rmcilroy 2016/01/22 17:50:56 Just DCHECK(from.is_valid() && to.is_valid)) ?
435 UNIMPLEMENTED();
436 return false;
437 }
438
439 DCHECK(FitsInReg8OperandUntranslated(from) ||
440 FitsInReg8OperandUntranslated(to));
441 DCHECK(from != to);
442 if (FitsInReg16OperandUntranslated(from) &&
443 FitsInReg16OperandUntranslated(to)) {
444 Output(Bytecode::kMovWide, from.ToRawOperand(), to.ToRawOperand());
445 return true;
446 } else {
447 UNIMPLEMENTED();
448 return false;
449 }
450 }
451
452
375 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal( 453 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(
376 const Handle<String> name, int feedback_slot, LanguageMode language_mode, 454 const Handle<String> name, int feedback_slot, LanguageMode language_mode,
377 TypeofMode typeof_mode) { 455 TypeofMode typeof_mode) {
378 // TODO(rmcilroy): Potentially store language and typeof information in an 456 // TODO(rmcilroy): Potentially store language and typeof information in an
379 // operand rather than having extra bytecodes. 457 // operand rather than having extra bytecodes.
380 Bytecode bytecode = BytecodeForLoadGlobal(language_mode, typeof_mode); 458 Bytecode bytecode = BytecodeForLoadGlobal(language_mode, typeof_mode);
381 size_t name_index = GetConstantPoolEntry(name); 459 size_t name_index = GetConstantPoolEntry(name);
382 if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) { 460 if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) {
383 Output(bytecode, static_cast<uint8_t>(name_index), 461 Output(bytecode, static_cast<uint8_t>(name_index),
384 static_cast<uint8_t>(feedback_slot)); 462 static_cast<uint8_t>(feedback_slot));
(...skipping 22 matching lines...) Expand all
407 } else { 485 } else {
408 UNIMPLEMENTED(); 486 UNIMPLEMENTED();
409 } 487 }
410 return *this; 488 return *this;
411 } 489 }
412 490
413 491
414 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, 492 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context,
415 int slot_index) { 493 int slot_index) {
416 DCHECK(slot_index >= 0); 494 DCHECK(slot_index >= 0);
495 RegisterTranslationScope translator(this);
417 if (FitsInIdx8Operand(slot_index)) { 496 if (FitsInIdx8Operand(slot_index)) {
418 Output(Bytecode::kLdaContextSlot, context.ToRawOperand(), 497 translator.set_bytecode(Bytecode::kLdaContextSlot);
419 static_cast<uint8_t>(slot_index));
420 } else if (FitsInIdx16Operand(slot_index)) { 498 } else if (FitsInIdx16Operand(slot_index)) {
421 Output(Bytecode::kLdaContextSlotWide, context.ToRawOperand(), 499 translator.set_bytecode(Bytecode::kLdaContextSlotWide);
422 static_cast<uint16_t>(slot_index));
423 } else { 500 } else {
424 UNIMPLEMENTED(); 501 UNIMPLEMENTED();
425 } 502 }
503 context = translator.Translate(context);
504 Output(translator.bytecode(), context.ToRawOperand(),
505 static_cast<uint16_t>(slot_index));
426 return *this; 506 return *this;
427 } 507 }
428 508
429 509
430 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, 510 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context,
431 int slot_index) { 511 int slot_index) {
432 DCHECK(slot_index >= 0); 512 DCHECK(slot_index >= 0);
513 RegisterTranslationScope translator(this);
433 if (FitsInIdx8Operand(slot_index)) { 514 if (FitsInIdx8Operand(slot_index)) {
434 Output(Bytecode::kStaContextSlot, context.ToRawOperand(), 515 translator.set_bytecode(Bytecode::kStaContextSlot);
435 static_cast<uint8_t>(slot_index));
436 } else if (FitsInIdx16Operand(slot_index)) { 516 } else if (FitsInIdx16Operand(slot_index)) {
437 Output(Bytecode::kStaContextSlotWide, context.ToRawOperand(), 517 translator.set_bytecode(Bytecode::kStaContextSlotWide);
438 static_cast<uint16_t>(slot_index));
439 } else { 518 } else {
440 UNIMPLEMENTED(); 519 UNIMPLEMENTED();
441 } 520 }
521 context = translator.Translate(context);
522 Output(translator.bytecode(), context.ToRawOperand(),
523 static_cast<uint16_t>(slot_index));
442 return *this; 524 return *this;
443 } 525 }
444 526
445 527
446 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( 528 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot(
447 const Handle<String> name, TypeofMode typeof_mode) { 529 const Handle<String> name, TypeofMode typeof_mode) {
448 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF) 530 Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF)
449 ? Bytecode::kLdaLookupSlotInsideTypeof 531 ? Bytecode::kLdaLookupSlotInsideTypeof
450 : Bytecode::kLdaLookupSlot; 532 : Bytecode::kLdaLookupSlot;
451 size_t name_index = GetConstantPoolEntry(name); 533 size_t name_index = GetConstantPoolEntry(name);
(...skipping 21 matching lines...) Expand all
473 } else { 555 } else {
474 UNIMPLEMENTED(); 556 UNIMPLEMENTED();
475 } 557 }
476 return *this; 558 return *this;
477 } 559 }
478 560
479 561
480 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( 562 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty(
481 Register object, const Handle<String> name, int feedback_slot, 563 Register object, const Handle<String> name, int feedback_slot,
482 LanguageMode language_mode) { 564 LanguageMode language_mode) {
483 Bytecode bytecode = BytecodeForLoadIC(language_mode); 565 RegisterTranslationScope translator(this);
484 size_t name_index = GetConstantPoolEntry(name); 566 size_t name_index = GetConstantPoolEntry(name);
485 if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) { 567 if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) {
486 Output(bytecode, object.ToRawOperand(), static_cast<uint8_t>(name_index), 568 translator.set_bytecode(BytecodeForLoadIC(language_mode));
487 static_cast<uint8_t>(feedback_slot));
488 } else if (FitsInIdx16Operand(name_index) && 569 } else if (FitsInIdx16Operand(name_index) &&
489 FitsInIdx16Operand(feedback_slot)) { 570 FitsInIdx16Operand(feedback_slot)) {
490 Output(BytecodeForWideOperands(bytecode), object.ToRawOperand(), 571 translator.set_bytecode(
491 static_cast<uint16_t>(name_index), 572 BytecodeForWideOperands(BytecodeForLoadIC(language_mode)));
492 static_cast<uint16_t>(feedback_slot));
493 } else { 573 } else {
494 UNIMPLEMENTED(); 574 UNIMPLEMENTED();
495 } 575 }
576 object = translator.Translate(object);
577 Output(translator.bytecode(), object.ToRawOperand(),
578 static_cast<uint16_t>(name_index),
579 static_cast<uint16_t>(feedback_slot));
rmcilroy 2016/01/22 17:50:56 Maybe just cast directly to uint32_t now so that w
496 return *this; 580 return *this;
497 } 581 }
498 582
499 583
500 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( 584 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty(
501 Register object, int feedback_slot, LanguageMode language_mode) { 585 Register object, int feedback_slot, LanguageMode language_mode) {
502 Bytecode bytecode = BytecodeForKeyedLoadIC(language_mode); 586 RegisterTranslationScope translator(this);
503 if (FitsInIdx8Operand(feedback_slot)) { 587 if (FitsInIdx8Operand(feedback_slot)) {
504 Output(bytecode, object.ToRawOperand(), 588 translator.set_bytecode(BytecodeForKeyedLoadIC(language_mode));
505 static_cast<uint8_t>(feedback_slot));
506 } else if (FitsInIdx16Operand(feedback_slot)) { 589 } else if (FitsInIdx16Operand(feedback_slot)) {
507 Output(BytecodeForWideOperands(bytecode), object.ToRawOperand(), 590 translator.set_bytecode(
508 static_cast<uint16_t>(feedback_slot)); 591 BytecodeForWideOperands(BytecodeForKeyedLoadIC(language_mode)));
509 } else { 592 } else {
510 UNIMPLEMENTED(); 593 UNIMPLEMENTED();
511 } 594 }
595 object = translator.Translate(object);
596 Output(translator.bytecode(), object.ToRawOperand(),
597 static_cast<uint16_t>(feedback_slot));
512 return *this; 598 return *this;
513 } 599 }
514 600
515 601
516 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( 602 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
517 Register object, const Handle<String> name, int feedback_slot, 603 Register object, const Handle<String> name, int feedback_slot,
518 LanguageMode language_mode) { 604 LanguageMode language_mode) {
519 Bytecode bytecode = BytecodeForStoreIC(language_mode);
520 size_t name_index = GetConstantPoolEntry(name); 605 size_t name_index = GetConstantPoolEntry(name);
606 RegisterTranslationScope translator(this);
521 if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) { 607 if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) {
522 Output(bytecode, object.ToRawOperand(), static_cast<uint8_t>(name_index), 608 translator.set_bytecode(BytecodeForStoreIC(language_mode));
523 static_cast<uint8_t>(feedback_slot));
524 } else if (FitsInIdx16Operand(name_index) && 609 } else if (FitsInIdx16Operand(name_index) &&
525 FitsInIdx16Operand(feedback_slot)) { 610 FitsInIdx16Operand(feedback_slot)) {
526 Output(BytecodeForWideOperands(bytecode), object.ToRawOperand(), 611 translator.set_bytecode(
527 static_cast<uint16_t>(name_index), 612 BytecodeForWideOperands(BytecodeForStoreIC(language_mode)));
528 static_cast<uint16_t>(feedback_slot));
529 } else { 613 } else {
530 UNIMPLEMENTED(); 614 UNIMPLEMENTED();
531 } 615 }
616 object = translator.Translate(object);
617 Output(translator.bytecode(), object.ToRawOperand(),
618 static_cast<uint16_t>(name_index),
619 static_cast<uint16_t>(feedback_slot));
532 return *this; 620 return *this;
533 } 621 }
534 622
535 623
536 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( 624 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty(
537 Register object, Register key, int feedback_slot, 625 Register object, Register key, int feedback_slot,
538 LanguageMode language_mode) { 626 LanguageMode language_mode) {
539 Bytecode bytecode = BytecodeForKeyedStoreIC(language_mode); 627 RegisterTranslationScope translator(this);
540 if (FitsInIdx8Operand(feedback_slot)) { 628 if (FitsInIdx8Operand(feedback_slot)) {
541 Output(bytecode, object.ToRawOperand(), key.ToRawOperand(), 629 translator.set_bytecode(BytecodeForKeyedStoreIC(language_mode));
542 static_cast<uint8_t>(feedback_slot));
543 } else if (FitsInIdx16Operand(feedback_slot)) { 630 } else if (FitsInIdx16Operand(feedback_slot)) {
544 Output(BytecodeForWideOperands(bytecode), object.ToRawOperand(), 631 translator.set_bytecode(
545 key.ToRawOperand(), static_cast<uint16_t>(feedback_slot)); 632 BytecodeForWideOperands(BytecodeForKeyedStoreIC(language_mode)));
546 } else { 633 } else {
547 UNIMPLEMENTED(); 634 UNIMPLEMENTED();
548 } 635 }
636 object = translator.Translate(object);
637 key = translator.Translate(key);
638 Output(translator.bytecode(), object.ToRawOperand(), key.ToRawOperand(),
639 static_cast<uint16_t>(feedback_slot));
549 return *this; 640 return *this;
550 } 641 }
551 642
552 643
553 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure( 644 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(
554 Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) { 645 Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) {
555 size_t entry = GetConstantPoolEntry(shared_info); 646 size_t entry = GetConstantPoolEntry(shared_info);
556 DCHECK(FitsInImm8Operand(tenured)); 647 DCHECK(FitsInImm8Operand(tenured));
557 if (FitsInIdx8Operand(entry)) { 648 if (FitsInIdx8Operand(entry)) {
558 Output(Bytecode::kCreateClosure, static_cast<uint8_t>(entry), 649 Output(Bytecode::kCreateClosure, static_cast<uint8_t>(entry),
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 static_cast<uint16_t>(constant_properties_entry), 724 static_cast<uint16_t>(constant_properties_entry),
634 static_cast<uint16_t>(literal_index), static_cast<uint8_t>(flags)); 725 static_cast<uint16_t>(literal_index), static_cast<uint8_t>(flags));
635 } else { 726 } else {
636 UNIMPLEMENTED(); 727 UNIMPLEMENTED();
637 } 728 }
638 return *this; 729 return *this;
639 } 730 }
640 731
641 732
642 BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) { 733 BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) {
643 Output(Bytecode::kPushContext, context.ToRawOperand()); 734 RegisterTranslationScope translator(this, Bytecode::kPushContext);
735 context = translator.Translate(context);
736 Output(translator.bytecode(), context.ToRawOperand());
644 return *this; 737 return *this;
645 } 738 }
646 739
647 740
648 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { 741 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) {
649 Output(Bytecode::kPopContext, context.ToRawOperand()); 742 RegisterTranslationScope translator(this, Bytecode::kPopContext);
743 context = translator.Translate(context);
744 Output(translator.bytecode(), context.ToRawOperand());
650 return *this; 745 return *this;
651 } 746 }
652 747
653 748
654 bool BytecodeArrayBuilder::NeedToBooleanCast() { 749 bool BytecodeArrayBuilder::NeedToBooleanCast() {
655 if (!LastBytecodeInSameBlock()) { 750 if (!LastBytecodeInSameBlock()) {
656 return true; 751 return true;
657 } 752 }
658 PreviousBytecodeHelper previous_bytecode(*this); 753 PreviousBytecodeHelper previous_bytecode(*this);
659 switch (previous_bytecode.GetBytecode()) { 754 switch (previous_bytecode.GetBytecode()) {
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 1057
963 BytecodeArrayBuilder& BytecodeArrayBuilder::Return() { 1058 BytecodeArrayBuilder& BytecodeArrayBuilder::Return() {
964 Output(Bytecode::kReturn); 1059 Output(Bytecode::kReturn);
965 exit_seen_in_block_ = true; 1060 exit_seen_in_block_ = true;
966 return *this; 1061 return *this;
967 } 1062 }
968 1063
969 1064
970 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare( 1065 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare(
971 Register cache_info_triple) { 1066 Register cache_info_triple) {
1067 RegisterTranslationScope translator(this);
972 if (FitsInReg8Operand(cache_info_triple)) { 1068 if (FitsInReg8Operand(cache_info_triple)) {
973 Output(Bytecode::kForInPrepare, cache_info_triple.ToRawOperand()); 1069 translator.set_bytecode(Bytecode::kForInPrepare);
974 } else if (FitsInReg16Operand(cache_info_triple)) { 1070 } else if (FitsInReg16Operand(cache_info_triple)) {
975 Output(Bytecode::kForInPrepareWide, cache_info_triple.ToRawOperand()); 1071 translator.set_bytecode(Bytecode::kForInPrepareWide);
976 } else { 1072 } else {
977 UNIMPLEMENTED(); 1073 UNIMPLEMENTED();
978 } 1074 }
1075 cache_info_triple = translator.Translate(cache_info_triple);
1076 Output(translator.bytecode(), cache_info_triple.ToRawOperand());
979 return *this; 1077 return *this;
980 } 1078 }
981 1079
982 1080
983 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index, 1081 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index,
984 Register cache_length) { 1082 Register cache_length) {
985 Output(Bytecode::kForInDone, index.ToRawOperand(), 1083 RegisterTranslationScope translator(this, Bytecode::kForInDone);
1084 index = translator.Translate(index);
1085 cache_length = translator.Translate(cache_length);
1086 Output(translator.bytecode(), index.ToRawOperand(),
986 cache_length.ToRawOperand()); 1087 cache_length.ToRawOperand());
987 return *this; 1088 return *this;
988 } 1089 }
989 1090
990 1091
991 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext( 1092 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext(
992 Register receiver, Register index, Register cache_type_array_pair) { 1093 Register receiver, Register index, Register cache_type_array_pair) {
1094 RegisterTranslationScope translator(this);
993 if (FitsInReg8Operand(receiver) && FitsInReg8Operand(index) && 1095 if (FitsInReg8Operand(receiver) && FitsInReg8Operand(index) &&
994 FitsInReg8Operand(cache_type_array_pair)) { 1096 FitsInReg8Operand(cache_type_array_pair)) {
995 Output(Bytecode::kForInNext, receiver.ToRawOperand(), index.ToRawOperand(), 1097 translator.set_bytecode(Bytecode::kForInNext);
996 cache_type_array_pair.ToRawOperand());
997 } else if (FitsInReg16Operand(receiver) && FitsInReg16Operand(index) && 1098 } else if (FitsInReg16Operand(receiver) && FitsInReg16Operand(index) &&
998 FitsInReg16Operand(cache_type_array_pair)) { 1099 FitsInReg16Operand(cache_type_array_pair)) {
999 Output(Bytecode::kForInNextWide, receiver.ToRawOperand(), 1100 translator.set_bytecode(Bytecode::kForInNextWide);
1000 index.ToRawOperand(), cache_type_array_pair.ToRawOperand());
1001 } else { 1101 } else {
1002 UNIMPLEMENTED(); 1102 UNIMPLEMENTED();
1003 } 1103 }
1104 receiver = translator.Translate(receiver);
1105 index = translator.Translate(index);
1106 cache_type_array_pair = translator.Translate(cache_type_array_pair);
1107 Output(translator.bytecode(), receiver.ToRawOperand(), index.ToRawOperand(),
1108 cache_type_array_pair.ToRawOperand());
1004 return *this; 1109 return *this;
1005 } 1110 }
1006 1111
1007 1112
1008 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) { 1113 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) {
1009 Output(Bytecode::kForInStep, index.ToRawOperand()); 1114 RegisterTranslationScope translator(this, Bytecode::kForInStep);
1115 index = translator.Translate(index);
1116 Output(translator.bytecode(), index.ToRawOperand());
1010 return *this; 1117 return *this;
1011 } 1118 }
1012 1119
1013 1120
1014 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(int handler_id, 1121 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(int handler_id,
1015 bool will_catch) { 1122 bool will_catch) {
1016 handler_table_builder()->SetHandlerTarget(handler_id, bytecodes()->size()); 1123 handler_table_builder()->SetHandlerTarget(handler_id, bytecodes()->size());
1017 handler_table_builder()->SetPrediction(handler_id, will_catch); 1124 handler_table_builder()->SetPrediction(handler_id, will_catch);
1018 return *this; 1125 return *this;
1019 } 1126 }
(...skipping 24 matching lines...) Expand all
1044 LoadUndefined(); 1151 LoadUndefined();
1045 Return(); 1152 Return();
1046 } 1153 }
1047 } 1154 }
1048 1155
1049 1156
1050 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, 1157 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
1051 Register receiver, 1158 Register receiver,
1052 size_t arg_count, 1159 size_t arg_count,
1053 int feedback_slot) { 1160 int feedback_slot) {
1161 RegisterTranslationScope translator(this);
1054 if (FitsInReg8Operand(callable) && FitsInReg8Operand(receiver) && 1162 if (FitsInReg8Operand(callable) && FitsInReg8Operand(receiver) &&
1055 FitsInIdx8Operand(arg_count) && FitsInIdx8Operand(feedback_slot)) { 1163 FitsInIdx8Operand(arg_count) && FitsInIdx8Operand(feedback_slot)) {
1056 Output(Bytecode::kCall, callable.ToRawOperand(), receiver.ToRawOperand(), 1164 translator.set_bytecode(Bytecode::kCall);
1057 static_cast<uint8_t>(arg_count),
1058 static_cast<uint8_t>(feedback_slot));
1059 } else if (FitsInReg16Operand(callable) && FitsInReg16Operand(receiver) && 1165 } else if (FitsInReg16Operand(callable) && FitsInReg16Operand(receiver) &&
1060 FitsInIdx16Operand(arg_count) && 1166 FitsInIdx16Operand(arg_count) &&
1061 FitsInIdx16Operand(feedback_slot)) { 1167 FitsInIdx16Operand(feedback_slot)) {
1062 Output(Bytecode::kCallWide, callable.ToRawOperand(), 1168 translator.set_bytecode(Bytecode::kCallWide);
1063 receiver.ToRawOperand(), static_cast<uint16_t>(arg_count),
1064 static_cast<uint16_t>(feedback_slot));
1065 } else { 1169 } else {
1066 UNIMPLEMENTED(); 1170 UNIMPLEMENTED();
1067 } 1171 }
1172 callable = translator.Translate(callable);
1173 receiver = translator.Translate(receiver);
1174 Output(translator.bytecode(), callable.ToRawOperand(),
1175 receiver.ToRawOperand(), static_cast<uint16_t>(arg_count),
1176 static_cast<uint16_t>(feedback_slot));
1068 return *this; 1177 return *this;
1069 } 1178 }
1070 1179
1071 1180
1072 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, 1181 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor,
1073 Register first_arg, 1182 Register first_arg,
1074 size_t arg_count) { 1183 size_t arg_count) {
1075 if (!first_arg.is_valid()) { 1184 if (!first_arg.is_valid()) {
1076 DCHECK_EQ(0u, arg_count); 1185 DCHECK_EQ(0u, arg_count);
1077 first_arg = Register(0); 1186 first_arg = Register(0);
1078 } 1187 }
1079 1188
1189 RegisterTranslationScope translator(this);
1080 if (FitsInReg8Operand(constructor) && FitsInReg8Operand(first_arg) && 1190 if (FitsInReg8Operand(constructor) && FitsInReg8Operand(first_arg) &&
1081 FitsInIdx8Operand(arg_count)) { 1191 FitsInIdx8Operand(arg_count)) {
1082 Output(Bytecode::kNew, constructor.ToRawOperand(), first_arg.ToRawOperand(), 1192 translator.set_bytecode(Bytecode::kNew);
1083 static_cast<uint8_t>(arg_count));
1084 } else if (FitsInReg16Operand(constructor) && FitsInReg16Operand(first_arg) && 1193 } else if (FitsInReg16Operand(constructor) && FitsInReg16Operand(first_arg) &&
1085 FitsInIdx16Operand(arg_count)) { 1194 FitsInIdx16Operand(arg_count)) {
1086 Output(Bytecode::kNewWide, constructor.ToRawOperand(), 1195 translator.set_bytecode(Bytecode::kNewWide);
1087 first_arg.ToRawOperand(), static_cast<uint16_t>(arg_count));
1088 } else { 1196 } else {
1089 UNIMPLEMENTED(); 1197 UNIMPLEMENTED();
1090 } 1198 }
1199 constructor = translator.Translate(constructor);
1200 first_arg = translator.Translate(first_arg);
1201 Output(translator.bytecode(), constructor.ToRawOperand(),
1202 first_arg.ToRawOperand(), static_cast<uint16_t>(arg_count));
1091 return *this; 1203 return *this;
1092 } 1204 }
1093 1205
1094 1206
1095 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime( 1207 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime(
1096 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) { 1208 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) {
1097 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size); 1209 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size);
1098 DCHECK(FitsInIdx16Operand(function_id)); 1210 DCHECK(FitsInIdx16Operand(function_id));
1099 if (!first_arg.is_valid()) { 1211 if (!first_arg.is_valid()) {
1100 DCHECK_EQ(0u, arg_count); 1212 DCHECK_EQ(0u, arg_count);
1101 first_arg = Register(0); 1213 first_arg = Register(0);
1102 } 1214 }
1215
1216 RegisterTranslationScope translator(this);
1103 if (FitsInReg8Operand(first_arg) && FitsInIdx8Operand(arg_count)) { 1217 if (FitsInReg8Operand(first_arg) && FitsInIdx8Operand(arg_count)) {
1104 Output(Bytecode::kCallRuntime, static_cast<uint16_t>(function_id), 1218 translator.set_bytecode(Bytecode::kCallRuntime);
1105 first_arg.ToRawOperand(), static_cast<uint8_t>(arg_count));
1106 } else if (FitsInReg16Operand(first_arg) && FitsInIdx16Operand(arg_count)) { 1219 } else if (FitsInReg16Operand(first_arg) && FitsInIdx16Operand(arg_count)) {
1107 Output(Bytecode::kCallRuntimeWide, static_cast<uint16_t>(function_id), 1220 translator.set_bytecode(Bytecode::kCallRuntimeWide);
1108 first_arg.ToRawOperand(), static_cast<uint16_t>(arg_count));
1109 } else { 1221 } else {
1110 UNIMPLEMENTED(); 1222 UNIMPLEMENTED();
1111 } 1223 }
1224 first_arg = translator.Translate(first_arg);
1225 Output(translator.bytecode(), static_cast<uint16_t>(function_id),
1226 first_arg.ToRawOperand(), static_cast<uint16_t>(arg_count));
1112 return *this; 1227 return *this;
1113 } 1228 }
1114 1229
1115 1230
1116 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair( 1231 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair(
1117 Runtime::FunctionId function_id, Register first_arg, size_t arg_count, 1232 Runtime::FunctionId function_id, Register first_arg, size_t arg_count,
1118 Register first_return) { 1233 Register first_return) {
1119 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size); 1234 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size);
1120 DCHECK(FitsInIdx16Operand(function_id)); 1235 DCHECK(FitsInIdx16Operand(function_id));
1121 if (!first_arg.is_valid()) { 1236 if (!first_arg.is_valid()) {
1122 DCHECK_EQ(0u, arg_count); 1237 DCHECK_EQ(0u, arg_count);
1123 first_arg = Register(0); 1238 first_arg = Register(0);
1124 } 1239 }
1240
1241 RegisterTranslationScope translator(this);
1125 if (FitsInReg8Operand(first_arg) && FitsInIdx8Operand(arg_count) && 1242 if (FitsInReg8Operand(first_arg) && FitsInIdx8Operand(arg_count) &&
1126 FitsInReg8Operand(first_return)) { 1243 FitsInReg8Operand(first_return)) {
1127 Output(Bytecode::kCallRuntimeForPair, static_cast<uint16_t>(function_id), 1244 translator.set_bytecode(Bytecode::kCallRuntimeForPair);
1128 first_arg.ToRawOperand(), static_cast<uint8_t>(arg_count),
1129 first_return.ToRawOperand());
1130 } else if (FitsInReg16Operand(first_arg) && FitsInIdx16Operand(arg_count) && 1245 } else if (FitsInReg16Operand(first_arg) && FitsInIdx16Operand(arg_count) &&
1131 FitsInReg16Operand(first_return)) { 1246 FitsInReg16Operand(first_return)) {
1132 Output(Bytecode::kCallRuntimeForPairWide, 1247 translator.set_bytecode(Bytecode::kCallRuntimeForPairWide);
1133 static_cast<uint16_t>(function_id), first_arg.ToRawOperand(),
1134 static_cast<uint16_t>(arg_count), first_return.ToRawOperand());
1135 } else { 1248 } else {
1136 UNIMPLEMENTED(); 1249 UNIMPLEMENTED();
1137 } 1250 }
1251 first_arg = translator.Translate(first_arg);
1252 first_return = translator.Translate(first_return);
1253 Output(translator.bytecode(), static_cast<uint16_t>(function_id),
1254 first_arg.ToRawOperand(), static_cast<uint16_t>(arg_count),
1255 first_return.ToRawOperand());
1138 return *this; 1256 return *this;
1139 } 1257 }
1140 1258
1141 1259
1142 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(int context_index, 1260 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(int context_index,
1143 Register receiver, 1261 Register receiver,
1144 size_t arg_count) { 1262 size_t arg_count) {
1145 DCHECK(FitsInIdx16Operand(context_index)); 1263 DCHECK(FitsInIdx16Operand(context_index));
1264
1265 RegisterTranslationScope translator(this);
1146 if (FitsInReg8Operand(receiver) && FitsInIdx8Operand(arg_count)) { 1266 if (FitsInReg8Operand(receiver) && FitsInIdx8Operand(arg_count)) {
1147 Output(Bytecode::kCallJSRuntime, static_cast<uint16_t>(context_index), 1267 translator.set_bytecode(Bytecode::kCallJSRuntime);
1148 receiver.ToRawOperand(), static_cast<uint8_t>(arg_count));
1149 } else if (FitsInReg16Operand(receiver) && FitsInIdx16Operand(arg_count)) { 1268 } else if (FitsInReg16Operand(receiver) && FitsInIdx16Operand(arg_count)) {
1150 Output(Bytecode::kCallJSRuntimeWide, static_cast<uint16_t>(context_index), 1269 translator.set_bytecode(Bytecode::kCallJSRuntimeWide);
1151 receiver.ToRawOperand(), static_cast<uint16_t>(arg_count));
1152 } else { 1270 } else {
1153 UNIMPLEMENTED(); 1271 UNIMPLEMENTED();
1154 } 1272 }
1273 receiver = translator.Translate(receiver);
1274 Output(translator.bytecode(), static_cast<uint16_t>(context_index),
1275 receiver.ToRawOperand(), static_cast<uint16_t>(arg_count));
1155 return *this; 1276 return *this;
1156 } 1277 }
1157 1278
1158 1279
1159 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, 1280 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object,
1160 LanguageMode language_mode) { 1281 LanguageMode language_mode) {
1161 Output(BytecodeForDelete(language_mode), object.ToRawOperand()); 1282 RegisterTranslationScope translator(this, BytecodeForDelete(language_mode));
1283 object = translator.Translate(object);
1284 Output(translator.bytecode(), object.ToRawOperand());
1162 return *this; 1285 return *this;
1163 } 1286 }
1164 1287
1165 1288
1166 BytecodeArrayBuilder& BytecodeArrayBuilder::DeleteLookupSlot() { 1289 BytecodeArrayBuilder& BytecodeArrayBuilder::DeleteLookupSlot() {
1167 Output(Bytecode::kDeleteLookupSlot); 1290 Output(Bytecode::kDeleteLookupSlot);
1168 return *this; 1291 return *this;
1169 } 1292 }
1170 1293
1171 1294
1172 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { 1295 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) {
1173 return constant_array_builder()->Insert(object); 1296 return constant_array_builder()->Insert(object);
1174 } 1297 }
1175 1298
1176 1299
1300 void BytecodeArrayBuilder::ForgeTemporaryRegister() {
1301 temporary_register_count_++;
1302 }
1303
1304
1177 int BytecodeArrayBuilder::BorrowTemporaryRegister() { 1305 int BytecodeArrayBuilder::BorrowTemporaryRegister() {
1178 if (free_temporaries_.empty()) { 1306 if (free_temporaries_.empty()) {
1179 temporary_register_count_ += 1; 1307 ForgeTemporaryRegister();
1180 return last_temporary_register().index(); 1308 return last_temporary_register().index();
1181 } else { 1309 } else {
1182 auto pos = free_temporaries_.begin(); 1310 auto pos = free_temporaries_.begin();
1183 int retval = *pos; 1311 int retval = *pos;
1184 free_temporaries_.erase(pos); 1312 free_temporaries_.erase(pos);
1185 return retval; 1313 return retval;
1186 } 1314 }
1187 } 1315 }
1188 1316
1189 1317
1190 int BytecodeArrayBuilder::BorrowTemporaryRegisterNotInRange(int start_index, 1318 int BytecodeArrayBuilder::BorrowTemporaryRegisterNotInRange(int start_index,
1191 int end_index) { 1319 int end_index) {
1192 auto index = free_temporaries_.lower_bound(start_index); 1320 auto index = free_temporaries_.lower_bound(start_index);
1193 if (index == free_temporaries_.begin()) { 1321 if (index == free_temporaries_.begin()) {
1194 // If start_index is the first free register, check for a register 1322 // If start_index is the first free register, check for a register
1195 // greater than end_index. 1323 // greater than end_index.
1196 index = free_temporaries_.upper_bound(end_index); 1324 index = free_temporaries_.upper_bound(end_index);
1197 if (index == free_temporaries_.end()) { 1325 if (index == free_temporaries_.end()) {
1198 temporary_register_count_ += 1; 1326 ForgeTemporaryRegister();
1199 return last_temporary_register().index(); 1327 return last_temporary_register().index();
1200 } 1328 }
1201 } else { 1329 } else {
1202 // If there is a free register < start_index 1330 // If there is a free register < start_index
1203 index--; 1331 index--;
1204 } 1332 }
1205 1333
1206 int retval = *index; 1334 int retval = *index;
1207 free_temporaries_.erase(index); 1335 free_temporaries_.erase(index);
1208 return retval; 1336 return retval;
(...skipping 11 matching lines...) Expand all
1220 free_temporaries_.insert(reg_index); 1348 free_temporaries_.insert(reg_index);
1221 } 1349 }
1222 1350
1223 1351
1224 int BytecodeArrayBuilder::PrepareForConsecutiveTemporaryRegisters( 1352 int BytecodeArrayBuilder::PrepareForConsecutiveTemporaryRegisters(
1225 size_t count) { 1353 size_t count) {
1226 if (count == 0) { 1354 if (count == 0) {
1227 return -1; 1355 return -1;
1228 } 1356 }
1229 1357
1358 // TODO(oth): replace use of set<> here for free_temporaries with a
1359 // more efficient structure. And/or partition into two searches -
1360 // one before the translation window and one after.
1361 if (free_temporaries_.empty()) {
rmcilroy 2016/01/22 17:50:56 Please add a comment on why you are having to forg
1362 ForgeTemporaryRegister();
1363 free_temporaries_.insert(last_temporary_register().index());
1364 }
1365
1230 // Search within existing temporaries for a run. 1366 // Search within existing temporaries for a run.
1231 auto start = free_temporaries_.begin(); 1367 auto start = free_temporaries_.begin();
1232 size_t run_length = 0; 1368 size_t run_length = 0;
1233 for (auto run_end = start; run_end != free_temporaries_.end(); run_end++) { 1369 for (auto run_end = start; run_end != free_temporaries_.end(); run_end++) {
1234 if (*run_end != *start + static_cast<int>(run_length)) { 1370 int expected = *start + static_cast<int>(run_length);
1371 if (*run_end != expected) {
1235 start = run_end; 1372 start = run_end;
1236 run_length = 0; 1373 run_length = 0;
1237 } 1374 }
1375 Register reg_start(*start);
1376 Register reg_expected(expected);
1377 if (RegisterTranslator::DistanceToTranslationWindow(reg_start) > 0 &&
1378 RegisterTranslator::DistanceToTranslationWindow(reg_expected) <= 0) {
1379 // Run straddles the translation window boundary where there is
1380 // a hidden discontinuity.
rmcilroy 2016/01/22 17:50:56 /s/discontinuity/hole in allocatable registers ?
1381 start = run_end;
1382 run_length = 0;
1383 }
1238 if (++run_length == count) { 1384 if (++run_length == count) {
1239 return *start; 1385 return *start;
1240 } 1386 }
1241 } 1387 }
1242 1388
1243 // Continue run if possible across existing last temporary. 1389 // Continue run if possible across existing last temporary.
1244 if (temporary_register_count_ > 0 && 1390 if (temporary_register_count_ > 0 &&
1245 (start == free_temporaries_.end() || 1391 (start == free_temporaries_.end() ||
1246 *start + static_cast<int>(run_length) != 1392 *start + static_cast<int>(run_length) !=
1247 last_temporary_register().index() + 1)) { 1393 last_temporary_register().index() + 1)) {
1248 run_length = 0; 1394 run_length = 0;
1249 } 1395 }
1250 1396
1397 // Pad temporaries if extended run would cross translation boundary.
1398 Register reg_first(*start);
1399 Register reg_last(*start + static_cast<int>(count) - 1);
1400 DCHECK_GT(RegisterTranslator::DistanceToTranslationWindow(reg_first),
1401 RegisterTranslator::DistanceToTranslationWindow(reg_last));
1402 while (RegisterTranslator::DistanceToTranslationWindow(reg_first) > 0 &&
1403 RegisterTranslator::DistanceToTranslationWindow(reg_last) <= 0) {
1404 ForgeTemporaryRegister();
1405 free_temporaries_.insert(last_temporary_register().index());
1406 start = --free_temporaries_.end();
1407 reg_first = Register(*start);
1408 reg_last = Register(*start + static_cast<int>(count) - 1);
1409 run_length = 0;
1410 }
1411
1251 // Ensure enough registers for run. 1412 // Ensure enough registers for run.
1252 while (run_length++ < count) { 1413 while (run_length++ < count) {
1253 temporary_register_count_++; 1414 ForgeTemporaryRegister();
1254 free_temporaries_.insert(last_temporary_register().index()); 1415 free_temporaries_.insert(last_temporary_register().index());
1255 } 1416 }
1256 return last_temporary_register().index() - static_cast<int>(count) + 1; 1417
1418 int run_start =
1419 last_temporary_register().index() - static_cast<int>(count) + 1;
1420 DCHECK(RegisterTranslator::DistanceToTranslationWindow(Register(run_start)) <=
1421 0 ||
1422 RegisterTranslator::DistanceToTranslationWindow(
1423 Register(run_start + static_cast<int>(count) - 1)) > 0);
1424 return run_start;
1257 } 1425 }
1258 1426
1259 1427
1260 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { 1428 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const {
1261 if (temporary_register_count_ > 0) { 1429 if (temporary_register_count_ > 0) {
1262 DCHECK(reg.index() >= first_temporary_register().index() && 1430 DCHECK(reg.index() >= first_temporary_register().index() &&
1263 reg.index() <= last_temporary_register().index()); 1431 reg.index() <= last_temporary_register().index());
1264 return free_temporaries_.find(reg.index()) == free_temporaries_.end(); 1432 return free_temporaries_.find(reg.index()) == free_temporaries_.end();
1265 } else { 1433 } else {
1266 return false; 1434 return false;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1317 } 1485 }
1318 UNREACHABLE(); 1486 UNREACHABLE();
1319 return false; 1487 return false;
1320 } 1488 }
1321 1489
1322 1490
1323 bool BytecodeArrayBuilder::RegisterIsValid(Register reg, 1491 bool BytecodeArrayBuilder::RegisterIsValid(Register reg,
1324 OperandType reg_type) const { 1492 OperandType reg_type) const {
1325 switch (Bytecodes::SizeOfOperand(reg_type)) { 1493 switch (Bytecodes::SizeOfOperand(reg_type)) {
1326 case OperandSize::kByte: 1494 case OperandSize::kByte:
1327 if (!FitsInReg8Operand(reg)) { return false; } 1495 if (!FitsInReg8OperandUntranslated(reg)) {
1496 return false;
1497 }
1328 break; 1498 break;
1329 case OperandSize::kShort: 1499 case OperandSize::kShort:
1330 if (!FitsInReg16Operand(reg)) { return false; } 1500 if (!FitsInReg16OperandUntranslated(reg)) {
1501 return false;
1502 }
1331 break; 1503 break;
1332 case OperandSize::kNone: 1504 case OperandSize::kNone:
1333 UNREACHABLE(); 1505 UNREACHABLE();
1334 return false; 1506 return false;
1335 } 1507 }
1336 1508
1337 if (reg.is_function_context() || reg.is_function_closure() || 1509 if (reg.is_function_context() || reg.is_function_closure() ||
1338 reg.is_new_target()) { 1510 reg.is_new_target()) {
1339 return true; 1511 return true;
1340 } else if (reg.is_parameter()) { 1512 } else if (reg.is_parameter()) {
1341 int parameter_index = reg.ToParameterIndex(parameter_count_); 1513 int parameter_index = reg.ToParameterIndex(parameter_count_);
1342 return parameter_index >= 0 && parameter_index < parameter_count_; 1514 return parameter_index >= 0 && parameter_index < parameter_count_;
1343 } else if (reg.index() < fixed_register_count()) { 1515 } else if (translation_register_count() == 0) {
1344 return true; 1516 if (reg.index() < fixed_register_count()) {
1517 return true;
1518 } else {
1519 return TemporaryRegisterIsLive(reg);
1520 }
1345 } else { 1521 } else {
1346 return TemporaryRegisterIsLive(reg); 1522 return reg.index() < (fixed_and_temporary_register_count() +
1523 translation_register_count());
rmcilroy 2016/01/22 17:50:56 Does this not check for the temp being live. Could
1347 } 1524 }
1348 } 1525 }
1349 1526
1350 1527
1351 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const { 1528 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const {
1352 return last_bytecode_start_ < bytecodes()->size() && 1529 return last_bytecode_start_ < bytecodes()->size() &&
1353 last_bytecode_start_ >= last_block_end_; 1530 last_bytecode_start_ >= last_block_end_;
1354 } 1531 }
1355 1532
1356 1533
1357 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) { 1534 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) {
1358 if (LastBytecodeInSameBlock()) { 1535 if (LastBytecodeInSameBlock()) {
1359 PreviousBytecodeHelper previous_bytecode(*this); 1536 PreviousBytecodeHelper previous_bytecode(*this);
1360 Bytecode bytecode = previous_bytecode.GetBytecode(); 1537 Bytecode bytecode = previous_bytecode.GetBytecode();
1361 if ((bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar) && 1538 if (bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar) {
1362 (reg == Register::FromOperand(previous_bytecode.GetOperand(0)))) { 1539 Register previous =
rmcilroy 2016/01/22 17:50:56 nit - previous_reg
1363 return true; 1540 Register::FromOperand(previous_bytecode.GetOperand(0));
1541 return previous == reg;
1364 } 1542 }
1365 } 1543 }
1366 return false; 1544 return false;
1367 } 1545 }
1368 1546
1369 1547
1370 // static 1548 // static
1371 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { 1549 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) {
1372 switch (op) { 1550 switch (op) {
1373 case Token::Value::ADD: 1551 case Token::Value::ADD:
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
1666 1844
1667 1845
1668 // static 1846 // static
1669 bool BytecodeArrayBuilder::FitsInIdx16Operand(size_t value) { 1847 bool BytecodeArrayBuilder::FitsInIdx16Operand(size_t value) {
1670 return value <= static_cast<size_t>(kMaxUInt16); 1848 return value <= static_cast<size_t>(kMaxUInt16);
1671 } 1849 }
1672 1850
1673 1851
1674 // static 1852 // static
1675 bool BytecodeArrayBuilder::FitsInReg8Operand(Register value) { 1853 bool BytecodeArrayBuilder::FitsInReg8Operand(Register value) {
1676 return kMinInt8 <= value.index() && value.index() <= kMaxInt8; 1854 return RegisterTranslator::FitsInReg8Operand(value);
1855 }
1856
1857
1858 // static
1859 bool BytecodeArrayBuilder::FitsInReg8OperandUntranslated(Register value) {
1860 return value.is_byte_operand();
1677 } 1861 }
1678 1862
1679 1863
1680 // static 1864 // static
1681 bool BytecodeArrayBuilder::FitsInReg16Operand(Register value) { 1865 bool BytecodeArrayBuilder::FitsInReg16Operand(Register value) {
1682 return kMinInt16 <= value.index() && value.index() <= kMaxInt16; 1866 return RegisterTranslator::FitsInReg16Operand(value);
1867 }
1868
1869
1870 // static
1871 bool BytecodeArrayBuilder::FitsInReg16OperandUntranslated(Register value) {
1872 return value.is_short_operand();
1683 } 1873 }
1684 1874
1685 } // namespace interpreter 1875 } // namespace interpreter
1686 } // namespace internal 1876 } // namespace internal
1687 } // namespace v8 1877 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698