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

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

Issue 1595103006: [Interpreter] Preparation for wide registers. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase. 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
« no previous file with comments | « src/interpreter/bytecode-array-builder.h ('k') | src/interpreter/bytecode-array-iterator.cc » ('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 namespace v8 { 7 namespace v8 {
8 namespace internal { 8 namespace internal {
9 namespace interpreter { 9 namespace interpreter {
10 10
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 } 226 }
227 227
228 228
229 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, 229 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op,
230 Register reg, 230 Register reg,
231 Strength strength) { 231 Strength strength) {
232 if (is_strong(strength)) { 232 if (is_strong(strength)) {
233 UNIMPLEMENTED(); 233 UNIMPLEMENTED();
234 } 234 }
235 235
236 Output(BytecodeForBinaryOperation(op), reg.ToOperand()); 236 Output(BytecodeForBinaryOperation(op), reg.ToRawOperand());
237 return *this; 237 return *this;
238 } 238 }
239 239
240 240
241 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op, 241 BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op,
242 Strength strength) { 242 Strength strength) {
243 if (is_strong(strength)) { 243 if (is_strong(strength)) {
244 UNIMPLEMENTED(); 244 UNIMPLEMENTED();
245 } 245 }
246 246
(...skipping 13 matching lines...) Expand all
260 return *this; 260 return *this;
261 } 261 }
262 262
263 263
264 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation( 264 BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(
265 Token::Value op, Register reg, Strength strength) { 265 Token::Value op, Register reg, Strength strength) {
266 if (is_strong(strength)) { 266 if (is_strong(strength)) {
267 UNIMPLEMENTED(); 267 UNIMPLEMENTED();
268 } 268 }
269 269
270 Output(BytecodeForCompareOperation(op), reg.ToOperand()); 270 Output(BytecodeForCompareOperation(op), reg.ToRawOperand());
271 return *this; 271 return *this;
272 } 272 }
273 273
274 274
275 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( 275 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(
276 v8::internal::Smi* smi) { 276 v8::internal::Smi* smi) {
277 int32_t raw_smi = smi->value(); 277 int32_t raw_smi = smi->value();
278 if (raw_smi == 0) { 278 if (raw_smi == 0) {
279 Output(Bytecode::kLdaZero); 279 Output(Bytecode::kLdaZero);
280 } else if (raw_smi >= -128 && raw_smi <= 127) { 280 } else if (raw_smi >= -128 && raw_smi <= 127) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 } else { 335 } else {
336 LoadFalse(); 336 LoadFalse();
337 } 337 }
338 return *this; 338 return *this;
339 } 339 }
340 340
341 341
342 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( 342 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister(
343 Register reg) { 343 Register reg) {
344 if (!IsRegisterInAccumulator(reg)) { 344 if (!IsRegisterInAccumulator(reg)) {
345 Output(Bytecode::kLdar, reg.ToOperand()); 345 Output(Bytecode::kLdar, reg.ToRawOperand());
346 } 346 }
347 return *this; 347 return *this;
348 } 348 }
349 349
350 350
351 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( 351 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister(
352 Register reg) { 352 Register reg) {
353 // TODO(oth): Avoid storing the accumulator in the register if the
354 // previous bytecode loaded the accumulator with the same register.
355 //
356 // TODO(oth): If the previous bytecode is a MOV into this register,
357 // the previous instruction can be removed. The logic for determining
358 // these redundant MOVs appears complex.
359 Output(Bytecode::kStar, reg.ToOperand());
360 if (!IsRegisterInAccumulator(reg)) { 353 if (!IsRegisterInAccumulator(reg)) {
361 Output(Bytecode::kStar, reg.ToOperand()); 354 Output(Bytecode::kStar, reg.ToRawOperand());
362 } 355 }
363 return *this; 356 return *this;
364 } 357 }
365 358
366 359
367 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from, 360 BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from,
368 Register to) { 361 Register to) {
369 DCHECK(from != to); 362 DCHECK(from != to);
370 Output(Bytecode::kMov, from.ToOperand(), to.ToOperand()); 363 if (FitsInReg8Operand(to) && FitsInReg8Operand(from)) {
371 return *this; 364 Output(Bytecode::kMov, from.ToRawOperand(), to.ToRawOperand());
372 } 365 } else if (FitsInReg16Operand(to) && FitsInReg16Operand(from)) {
373 366 Output(Bytecode::kMovWide, from.ToRawOperand(), to.ToRawOperand());
374
375 BytecodeArrayBuilder& BytecodeArrayBuilder::ExchangeRegisters(Register reg0,
376 Register reg1) {
377 DCHECK(reg0 != reg1);
378 if (FitsInReg8Operand(reg0)) {
379 Output(Bytecode::kExchange, reg0.ToOperand(), reg1.ToWideOperand());
380 } else if (FitsInReg8Operand(reg1)) {
381 Output(Bytecode::kExchange, reg1.ToOperand(), reg0.ToWideOperand());
382 } else { 367 } else {
383 Output(Bytecode::kExchangeWide, reg0.ToWideOperand(), reg1.ToWideOperand()); 368 UNIMPLEMENTED();
384 } 369 }
385 return *this; 370 return *this;
386 } 371 }
387 372
388 373
389 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal( 374 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(
390 const Handle<String> name, int feedback_slot, LanguageMode language_mode, 375 const Handle<String> name, int feedback_slot, LanguageMode language_mode,
391 TypeofMode typeof_mode) { 376 TypeofMode typeof_mode) {
392 // TODO(rmcilroy): Potentially store language and typeof information in an 377 // TODO(rmcilroy): Potentially store language and typeof information in an
393 // operand rather than having extra bytecodes. 378 // operand rather than having extra bytecodes.
(...skipping 28 matching lines...) Expand all
422 UNIMPLEMENTED(); 407 UNIMPLEMENTED();
423 } 408 }
424 return *this; 409 return *this;
425 } 410 }
426 411
427 412
428 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context, 413 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context,
429 int slot_index) { 414 int slot_index) {
430 DCHECK(slot_index >= 0); 415 DCHECK(slot_index >= 0);
431 if (FitsInIdx8Operand(slot_index)) { 416 if (FitsInIdx8Operand(slot_index)) {
432 Output(Bytecode::kLdaContextSlot, context.ToOperand(), 417 Output(Bytecode::kLdaContextSlot, context.ToRawOperand(),
433 static_cast<uint8_t>(slot_index)); 418 static_cast<uint8_t>(slot_index));
434 } else if (FitsInIdx16Operand(slot_index)) { 419 } else if (FitsInIdx16Operand(slot_index)) {
435 Output(Bytecode::kLdaContextSlotWide, context.ToOperand(), 420 Output(Bytecode::kLdaContextSlotWide, context.ToRawOperand(),
436 static_cast<uint16_t>(slot_index)); 421 static_cast<uint16_t>(slot_index));
437 } else { 422 } else {
438 UNIMPLEMENTED(); 423 UNIMPLEMENTED();
439 } 424 }
440 return *this; 425 return *this;
441 } 426 }
442 427
443 428
444 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context, 429 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context,
445 int slot_index) { 430 int slot_index) {
446 DCHECK(slot_index >= 0); 431 DCHECK(slot_index >= 0);
447 if (FitsInIdx8Operand(slot_index)) { 432 if (FitsInIdx8Operand(slot_index)) {
448 Output(Bytecode::kStaContextSlot, context.ToOperand(), 433 Output(Bytecode::kStaContextSlot, context.ToRawOperand(),
449 static_cast<uint8_t>(slot_index)); 434 static_cast<uint8_t>(slot_index));
450 } else if (FitsInIdx16Operand(slot_index)) { 435 } else if (FitsInIdx16Operand(slot_index)) {
451 Output(Bytecode::kStaContextSlotWide, context.ToOperand(), 436 Output(Bytecode::kStaContextSlotWide, context.ToRawOperand(),
452 static_cast<uint16_t>(slot_index)); 437 static_cast<uint16_t>(slot_index));
453 } else { 438 } else {
454 UNIMPLEMENTED(); 439 UNIMPLEMENTED();
455 } 440 }
456 return *this; 441 return *this;
457 } 442 }
458 443
459 444
460 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot( 445 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot(
461 const Handle<String> name, TypeofMode typeof_mode) { 446 const Handle<String> name, TypeofMode typeof_mode) {
(...skipping 28 matching lines...) Expand all
490 return *this; 475 return *this;
491 } 476 }
492 477
493 478
494 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty( 479 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty(
495 Register object, const Handle<String> name, int feedback_slot, 480 Register object, const Handle<String> name, int feedback_slot,
496 LanguageMode language_mode) { 481 LanguageMode language_mode) {
497 Bytecode bytecode = BytecodeForLoadIC(language_mode); 482 Bytecode bytecode = BytecodeForLoadIC(language_mode);
498 size_t name_index = GetConstantPoolEntry(name); 483 size_t name_index = GetConstantPoolEntry(name);
499 if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) { 484 if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) {
500 Output(bytecode, object.ToOperand(), static_cast<uint8_t>(name_index), 485 Output(bytecode, object.ToRawOperand(), static_cast<uint8_t>(name_index),
501 static_cast<uint8_t>(feedback_slot)); 486 static_cast<uint8_t>(feedback_slot));
502 } else if (FitsInIdx16Operand(name_index) && 487 } else if (FitsInIdx16Operand(name_index) &&
503 FitsInIdx16Operand(feedback_slot)) { 488 FitsInIdx16Operand(feedback_slot)) {
504 Output(BytecodeForWideOperands(bytecode), object.ToOperand(), 489 Output(BytecodeForWideOperands(bytecode), object.ToRawOperand(),
505 static_cast<uint16_t>(name_index), 490 static_cast<uint16_t>(name_index),
506 static_cast<uint16_t>(feedback_slot)); 491 static_cast<uint16_t>(feedback_slot));
507 } else { 492 } else {
508 UNIMPLEMENTED(); 493 UNIMPLEMENTED();
509 } 494 }
510 return *this; 495 return *this;
511 } 496 }
512 497
513 498
514 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( 499 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty(
515 Register object, int feedback_slot, LanguageMode language_mode) { 500 Register object, int feedback_slot, LanguageMode language_mode) {
516 Bytecode bytecode = BytecodeForKeyedLoadIC(language_mode); 501 Bytecode bytecode = BytecodeForKeyedLoadIC(language_mode);
517 if (FitsInIdx8Operand(feedback_slot)) { 502 if (FitsInIdx8Operand(feedback_slot)) {
518 Output(bytecode, object.ToOperand(), static_cast<uint8_t>(feedback_slot)); 503 Output(bytecode, object.ToRawOperand(),
504 static_cast<uint8_t>(feedback_slot));
519 } else if (FitsInIdx16Operand(feedback_slot)) { 505 } else if (FitsInIdx16Operand(feedback_slot)) {
520 Output(BytecodeForWideOperands(bytecode), object.ToOperand(), 506 Output(BytecodeForWideOperands(bytecode), object.ToRawOperand(),
521 static_cast<uint16_t>(feedback_slot)); 507 static_cast<uint16_t>(feedback_slot));
522 } else { 508 } else {
523 UNIMPLEMENTED(); 509 UNIMPLEMENTED();
524 } 510 }
525 return *this; 511 return *this;
526 } 512 }
527 513
528 514
529 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty( 515 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
530 Register object, const Handle<String> name, int feedback_slot, 516 Register object, const Handle<String> name, int feedback_slot,
531 LanguageMode language_mode) { 517 LanguageMode language_mode) {
532 Bytecode bytecode = BytecodeForStoreIC(language_mode); 518 Bytecode bytecode = BytecodeForStoreIC(language_mode);
533 size_t name_index = GetConstantPoolEntry(name); 519 size_t name_index = GetConstantPoolEntry(name);
534 if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) { 520 if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) {
535 Output(bytecode, object.ToOperand(), static_cast<uint8_t>(name_index), 521 Output(bytecode, object.ToRawOperand(), static_cast<uint8_t>(name_index),
536 static_cast<uint8_t>(feedback_slot)); 522 static_cast<uint8_t>(feedback_slot));
537 } else if (FitsInIdx16Operand(name_index) && 523 } else if (FitsInIdx16Operand(name_index) &&
538 FitsInIdx16Operand(feedback_slot)) { 524 FitsInIdx16Operand(feedback_slot)) {
539 Output(BytecodeForWideOperands(bytecode), object.ToOperand(), 525 Output(BytecodeForWideOperands(bytecode), object.ToRawOperand(),
540 static_cast<uint16_t>(name_index), 526 static_cast<uint16_t>(name_index),
541 static_cast<uint16_t>(feedback_slot)); 527 static_cast<uint16_t>(feedback_slot));
542 } else { 528 } else {
543 UNIMPLEMENTED(); 529 UNIMPLEMENTED();
544 } 530 }
545 return *this; 531 return *this;
546 } 532 }
547 533
548 534
549 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty( 535 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty(
550 Register object, Register key, int feedback_slot, 536 Register object, Register key, int feedback_slot,
551 LanguageMode language_mode) { 537 LanguageMode language_mode) {
552 Bytecode bytecode = BytecodeForKeyedStoreIC(language_mode); 538 Bytecode bytecode = BytecodeForKeyedStoreIC(language_mode);
553 if (FitsInIdx8Operand(feedback_slot)) { 539 if (FitsInIdx8Operand(feedback_slot)) {
554 Output(bytecode, object.ToOperand(), key.ToOperand(), 540 Output(bytecode, object.ToRawOperand(), key.ToRawOperand(),
555 static_cast<uint8_t>(feedback_slot)); 541 static_cast<uint8_t>(feedback_slot));
556 } else if (FitsInIdx16Operand(feedback_slot)) { 542 } else if (FitsInIdx16Operand(feedback_slot)) {
557 Output(BytecodeForWideOperands(bytecode), object.ToOperand(), 543 Output(BytecodeForWideOperands(bytecode), object.ToRawOperand(),
558 key.ToOperand(), static_cast<uint16_t>(feedback_slot)); 544 key.ToRawOperand(), static_cast<uint16_t>(feedback_slot));
559 } else { 545 } else {
560 UNIMPLEMENTED(); 546 UNIMPLEMENTED();
561 } 547 }
562 return *this; 548 return *this;
563 } 549 }
564 550
565 551
566 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure( 552 BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(
567 Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) { 553 Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) {
568 size_t entry = GetConstantPoolEntry(shared_info); 554 size_t entry = GetConstantPoolEntry(shared_info);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 static_cast<uint16_t>(constant_properties_entry), 632 static_cast<uint16_t>(constant_properties_entry),
647 static_cast<uint16_t>(literal_index), static_cast<uint8_t>(flags)); 633 static_cast<uint16_t>(literal_index), static_cast<uint8_t>(flags));
648 } else { 634 } else {
649 UNIMPLEMENTED(); 635 UNIMPLEMENTED();
650 } 636 }
651 return *this; 637 return *this;
652 } 638 }
653 639
654 640
655 BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) { 641 BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) {
656 Output(Bytecode::kPushContext, context.ToOperand()); 642 Output(Bytecode::kPushContext, context.ToRawOperand());
657 return *this; 643 return *this;
658 } 644 }
659 645
660 646
661 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { 647 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) {
662 Output(Bytecode::kPopContext, context.ToOperand()); 648 Output(Bytecode::kPopContext, context.ToRawOperand());
663 return *this; 649 return *this;
664 } 650 }
665 651
666 652
667 bool BytecodeArrayBuilder::NeedToBooleanCast() { 653 bool BytecodeArrayBuilder::NeedToBooleanCast() {
668 if (!LastBytecodeInSameBlock()) { 654 if (!LastBytecodeInSameBlock()) {
669 return true; 655 return true;
670 } 656 }
671 PreviousBytecodeHelper previous_bytecode(*this); 657 PreviousBytecodeHelper previous_bytecode(*this);
672 switch (previous_bytecode.GetBytecode()) { 658 switch (previous_bytecode.GetBytecode()) {
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
975 961
976 BytecodeArrayBuilder& BytecodeArrayBuilder::Return() { 962 BytecodeArrayBuilder& BytecodeArrayBuilder::Return() {
977 Output(Bytecode::kReturn); 963 Output(Bytecode::kReturn);
978 exit_seen_in_block_ = true; 964 exit_seen_in_block_ = true;
979 return *this; 965 return *this;
980 } 966 }
981 967
982 968
983 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare( 969 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare(
984 Register cache_info_triple) { 970 Register cache_info_triple) {
985 Output(Bytecode::kForInPrepare, cache_info_triple.ToOperand()); 971 if (FitsInReg8Operand(cache_info_triple)) {
972 Output(Bytecode::kForInPrepare, cache_info_triple.ToRawOperand());
973 } else if (FitsInReg16Operand(cache_info_triple)) {
974 Output(Bytecode::kForInPrepareWide, cache_info_triple.ToRawOperand());
975 } else {
976 UNIMPLEMENTED();
977 }
986 return *this; 978 return *this;
987 } 979 }
988 980
989 981
990 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index, 982 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index,
991 Register cache_length) { 983 Register cache_length) {
992 Output(Bytecode::kForInDone, index.ToOperand(), cache_length.ToOperand()); 984 Output(Bytecode::kForInDone, index.ToRawOperand(),
985 cache_length.ToRawOperand());
993 return *this; 986 return *this;
994 } 987 }
995 988
996 989
997 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext( 990 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext(
998 Register receiver, Register index, Register cache_type_array_pair) { 991 Register receiver, Register index, Register cache_type_array_pair) {
999 Output(Bytecode::kForInNext, receiver.ToOperand(), index.ToOperand(), 992 if (FitsInReg8Operand(receiver) && FitsInReg8Operand(index) &&
1000 cache_type_array_pair.ToOperand()); 993 FitsInReg8Operand(cache_type_array_pair)) {
994 Output(Bytecode::kForInNext, receiver.ToRawOperand(), index.ToRawOperand(),
995 cache_type_array_pair.ToRawOperand());
996 } else if (FitsInReg16Operand(receiver) && FitsInReg16Operand(index) &&
997 FitsInReg16Operand(cache_type_array_pair)) {
998 Output(Bytecode::kForInNextWide, receiver.ToRawOperand(),
999 index.ToRawOperand(), cache_type_array_pair.ToRawOperand());
1000 } else {
1001 UNIMPLEMENTED();
1002 }
1001 return *this; 1003 return *this;
1002 } 1004 }
1003 1005
1004 1006
1005 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) { 1007 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) {
1006 Output(Bytecode::kForInStep, index.ToOperand()); 1008 Output(Bytecode::kForInStep, index.ToRawOperand());
1007 return *this; 1009 return *this;
1008 } 1010 }
1009 1011
1010 1012
1011 void BytecodeArrayBuilder::LeaveBasicBlock() { 1013 void BytecodeArrayBuilder::LeaveBasicBlock() {
1012 last_block_end_ = bytecodes()->size(); 1014 last_block_end_ = bytecodes()->size();
1013 exit_seen_in_block_ = false; 1015 exit_seen_in_block_ = false;
1014 } 1016 }
1015 1017
1016 1018
1017 void BytecodeArrayBuilder::EnsureReturn() { 1019 void BytecodeArrayBuilder::EnsureReturn() {
1018 if (!exit_seen_in_block_) { 1020 if (!exit_seen_in_block_) {
1019 LoadUndefined(); 1021 LoadUndefined();
1020 Return(); 1022 Return();
1021 } 1023 }
1022 } 1024 }
1023 1025
1024 1026
1025 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, 1027 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
1026 Register receiver, 1028 Register receiver,
1027 size_t arg_count, 1029 size_t arg_count,
1028 int feedback_slot) { 1030 int feedback_slot) {
1029 if (FitsInIdx8Operand(arg_count) && FitsInIdx8Operand(feedback_slot)) { 1031 if (FitsInReg8Operand(callable) && FitsInReg8Operand(receiver) &&
1030 Output(Bytecode::kCall, callable.ToOperand(), receiver.ToOperand(), 1032 FitsInIdx8Operand(arg_count) && FitsInIdx8Operand(feedback_slot)) {
1033 Output(Bytecode::kCall, callable.ToRawOperand(), receiver.ToRawOperand(),
1031 static_cast<uint8_t>(arg_count), 1034 static_cast<uint8_t>(arg_count),
1032 static_cast<uint8_t>(feedback_slot)); 1035 static_cast<uint8_t>(feedback_slot));
1033 } else if (FitsInIdx16Operand(arg_count) && 1036 } else if (FitsInReg16Operand(callable) && FitsInReg16Operand(receiver) &&
1037 FitsInIdx16Operand(arg_count) &&
1034 FitsInIdx16Operand(feedback_slot)) { 1038 FitsInIdx16Operand(feedback_slot)) {
1035 Output(Bytecode::kCallWide, callable.ToOperand(), receiver.ToOperand(), 1039 Output(Bytecode::kCallWide, callable.ToRawOperand(),
1036 static_cast<uint16_t>(arg_count), 1040 receiver.ToRawOperand(), static_cast<uint16_t>(arg_count),
1037 static_cast<uint16_t>(feedback_slot)); 1041 static_cast<uint16_t>(feedback_slot));
1038 } else { 1042 } else {
1039 UNIMPLEMENTED(); 1043 UNIMPLEMENTED();
1040 } 1044 }
1041 return *this; 1045 return *this;
1042 } 1046 }
1043 1047
1044 1048
1045 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, 1049 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor,
1046 Register first_arg, 1050 Register first_arg,
1047 size_t arg_count) { 1051 size_t arg_count) {
1048 if (!first_arg.is_valid()) { 1052 if (!first_arg.is_valid()) {
1049 DCHECK_EQ(0u, arg_count); 1053 DCHECK_EQ(0u, arg_count);
1050 first_arg = Register(0); 1054 first_arg = Register(0);
1051 } 1055 }
1052 DCHECK(FitsInIdx8Operand(arg_count)); 1056
1053 Output(Bytecode::kNew, constructor.ToOperand(), first_arg.ToOperand(), 1057 if (FitsInReg8Operand(constructor) && FitsInReg8Operand(first_arg) &&
1054 static_cast<uint8_t>(arg_count)); 1058 FitsInIdx8Operand(arg_count)) {
1059 Output(Bytecode::kNew, constructor.ToRawOperand(), first_arg.ToRawOperand(),
1060 static_cast<uint8_t>(arg_count));
1061 } else if (FitsInReg16Operand(constructor) && FitsInReg16Operand(first_arg) &&
1062 FitsInIdx16Operand(arg_count)) {
1063 Output(Bytecode::kNewWide, constructor.ToRawOperand(),
1064 first_arg.ToRawOperand(), static_cast<uint16_t>(arg_count));
1065 } else {
1066 UNIMPLEMENTED();
1067 }
1055 return *this; 1068 return *this;
1056 } 1069 }
1057 1070
1058 1071
1059 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime( 1072 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime(
1060 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) { 1073 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) {
1061 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size); 1074 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size);
1062 DCHECK(FitsInIdx16Operand(function_id)); 1075 DCHECK(FitsInIdx16Operand(function_id));
1063 DCHECK(FitsInIdx8Operand(arg_count));
1064 if (!first_arg.is_valid()) { 1076 if (!first_arg.is_valid()) {
1065 DCHECK_EQ(0u, arg_count); 1077 DCHECK_EQ(0u, arg_count);
1066 first_arg = Register(0); 1078 first_arg = Register(0);
1067 } 1079 }
1068 Output(Bytecode::kCallRuntime, static_cast<uint16_t>(function_id), 1080 if (FitsInReg8Operand(first_arg) && FitsInIdx8Operand(arg_count)) {
1069 first_arg.ToOperand(), static_cast<uint8_t>(arg_count)); 1081 Output(Bytecode::kCallRuntime, static_cast<uint16_t>(function_id),
1082 first_arg.ToRawOperand(), static_cast<uint8_t>(arg_count));
1083 } else if (FitsInReg16Operand(first_arg) && FitsInIdx16Operand(arg_count)) {
1084 Output(Bytecode::kCallRuntimeWide, static_cast<uint16_t>(function_id),
1085 first_arg.ToRawOperand(), static_cast<uint16_t>(arg_count));
1086 } else {
1087 UNIMPLEMENTED();
1088 }
1070 return *this; 1089 return *this;
1071 } 1090 }
1072 1091
1073 1092
1074 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair( 1093 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair(
1075 Runtime::FunctionId function_id, Register first_arg, size_t arg_count, 1094 Runtime::FunctionId function_id, Register first_arg, size_t arg_count,
1076 Register first_return) { 1095 Register first_return) {
1077 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size); 1096 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size);
1078 DCHECK(FitsInIdx16Operand(function_id)); 1097 DCHECK(FitsInIdx16Operand(function_id));
1079 DCHECK(FitsInIdx8Operand(arg_count));
1080 if (!first_arg.is_valid()) { 1098 if (!first_arg.is_valid()) {
1081 DCHECK_EQ(0u, arg_count); 1099 DCHECK_EQ(0u, arg_count);
1082 first_arg = Register(0); 1100 first_arg = Register(0);
1083 } 1101 }
1084 Output(Bytecode::kCallRuntimeForPair, static_cast<uint16_t>(function_id), 1102 if (FitsInReg8Operand(first_arg) && FitsInIdx8Operand(arg_count) &&
1085 first_arg.ToOperand(), static_cast<uint8_t>(arg_count), 1103 FitsInReg8Operand(first_return)) {
1086 first_return.ToOperand()); 1104 Output(Bytecode::kCallRuntimeForPair, static_cast<uint16_t>(function_id),
1105 first_arg.ToRawOperand(), static_cast<uint8_t>(arg_count),
1106 first_return.ToRawOperand());
1107 } else if (FitsInReg16Operand(first_arg) && FitsInIdx16Operand(arg_count) &&
1108 FitsInReg16Operand(first_return)) {
1109 Output(Bytecode::kCallRuntimeForPairWide,
1110 static_cast<uint16_t>(function_id), first_arg.ToRawOperand(),
1111 static_cast<uint16_t>(arg_count), first_return.ToRawOperand());
1112 } else {
1113 UNIMPLEMENTED();
1114 }
1087 return *this; 1115 return *this;
1088 } 1116 }
1089 1117
1090 1118
1091 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(int context_index, 1119 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(int context_index,
1092 Register receiver, 1120 Register receiver,
1093 size_t arg_count) { 1121 size_t arg_count) {
1094 DCHECK(FitsInIdx16Operand(context_index)); 1122 DCHECK(FitsInIdx16Operand(context_index));
1095 DCHECK(FitsInIdx8Operand(arg_count)); 1123 if (FitsInReg8Operand(receiver) && FitsInIdx8Operand(arg_count)) {
1096 Output(Bytecode::kCallJSRuntime, static_cast<uint16_t>(context_index), 1124 Output(Bytecode::kCallJSRuntime, static_cast<uint16_t>(context_index),
1097 receiver.ToOperand(), static_cast<uint8_t>(arg_count)); 1125 receiver.ToRawOperand(), static_cast<uint8_t>(arg_count));
1126 } else if (FitsInReg16Operand(receiver) && FitsInIdx16Operand(arg_count)) {
1127 Output(Bytecode::kCallJSRuntimeWide, static_cast<uint16_t>(context_index),
1128 receiver.ToRawOperand(), static_cast<uint16_t>(arg_count));
1129 } else {
1130 UNIMPLEMENTED();
1131 }
1098 return *this; 1132 return *this;
1099 } 1133 }
1100 1134
1101 1135
1102 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, 1136 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object,
1103 LanguageMode language_mode) { 1137 LanguageMode language_mode) {
1104 Output(BytecodeForDelete(language_mode), object.ToOperand()); 1138 Output(BytecodeForDelete(language_mode), object.ToRawOperand());
1105 return *this; 1139 return *this;
1106 } 1140 }
1107 1141
1108 1142
1109 BytecodeArrayBuilder& BytecodeArrayBuilder::DeleteLookupSlot() { 1143 BytecodeArrayBuilder& BytecodeArrayBuilder::DeleteLookupSlot() {
1110 Output(Bytecode::kDeleteLookupSlot); 1144 Output(Bytecode::kDeleteLookupSlot);
1111 return *this; 1145 return *this;
1112 } 1146 }
1113 1147
1114 1148
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1204 if (temporary_register_count_ > 0) { 1238 if (temporary_register_count_ > 0) {
1205 DCHECK(reg.index() >= first_temporary_register().index() && 1239 DCHECK(reg.index() >= first_temporary_register().index() &&
1206 reg.index() <= last_temporary_register().index()); 1240 reg.index() <= last_temporary_register().index());
1207 return free_temporaries_.find(reg.index()) == free_temporaries_.end(); 1241 return free_temporaries_.find(reg.index()) == free_temporaries_.end();
1208 } else { 1242 } else {
1209 return false; 1243 return false;
1210 } 1244 }
1211 } 1245 }
1212 1246
1213 1247
1214 bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const {
1215 if (reg.is_function_context() || reg.is_function_closure() ||
1216 reg.is_new_target()) {
1217 return true;
1218 } else if (reg.is_parameter()) {
1219 int parameter_index = reg.ToParameterIndex(parameter_count_);
1220 return parameter_index >= 0 && parameter_index < parameter_count_;
1221 } else if (reg.index() < fixed_register_count()) {
1222 return true;
1223 } else {
1224 return TemporaryRegisterIsLive(reg);
1225 }
1226 }
1227
1228
1229 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index, 1248 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index,
1230 uint32_t operand_value) const { 1249 uint32_t operand_value) const {
1231 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index); 1250 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index);
1232 switch (operand_type) { 1251 switch (operand_type) {
1233 case OperandType::kNone: 1252 case OperandType::kNone:
1234 return false; 1253 return false;
1235 case OperandType::kCount16: 1254 case OperandType::kRegCount16:
1236 case OperandType::kIdx16: 1255 case OperandType::kIdx16:
1237 return static_cast<uint16_t>(operand_value) == operand_value; 1256 return static_cast<uint16_t>(operand_value) == operand_value;
1238 case OperandType::kCount8: 1257 case OperandType::kRegCount8:
1239 case OperandType::kImm8: 1258 case OperandType::kImm8:
1240 case OperandType::kIdx8: 1259 case OperandType::kIdx8:
1241 return static_cast<uint8_t>(operand_value) == operand_value; 1260 return static_cast<uint8_t>(operand_value) == operand_value;
1242 case OperandType::kMaybeReg8: 1261 case OperandType::kMaybeReg8:
1243 if (operand_value == 0) { 1262 if (operand_value == 0) {
1244 return true; 1263 return true;
1245 } 1264 }
1246 // Fall-through to kReg8 case. 1265 // Fall-through to kReg8 case.
1247 case OperandType::kReg8: 1266 case OperandType::kReg8:
1248 return RegisterIsValid( 1267 return RegisterIsValid(Register::FromRawOperand(operand_value),
1249 Register::FromOperand(static_cast<uint8_t>(operand_value))); 1268 operand_type);
1250 case OperandType::kRegPair8: { 1269 case OperandType::kRegPair8:
1251 Register reg0 = 1270 case OperandType::kRegPair16: {
1252 Register::FromOperand(static_cast<uint8_t>(operand_value)); 1271 Register reg0 = Register::FromRawOperand(operand_value);
1253 Register reg1 = Register(reg0.index() + 1); 1272 Register reg1 = Register(reg0.index() + 1);
1254 return RegisterIsValid(reg0) && RegisterIsValid(reg1); 1273 return RegisterIsValid(reg0, operand_type) &&
1274 RegisterIsValid(reg1, operand_type);
1255 } 1275 }
1256 case OperandType::kRegTriple8: { 1276 case OperandType::kRegTriple8:
1257 Register reg0 = 1277 case OperandType::kRegTriple16: {
1258 Register::FromOperand(static_cast<uint8_t>(operand_value)); 1278 Register reg0 = Register::FromRawOperand(operand_value);
1259 Register reg1 = Register(reg0.index() + 1); 1279 Register reg1 = Register(reg0.index() + 1);
1260 Register reg2 = Register(reg0.index() + 2); 1280 Register reg2 = Register(reg0.index() + 2);
1261 return RegisterIsValid(reg0) && RegisterIsValid(reg1) && 1281 return RegisterIsValid(reg0, operand_type) &&
1262 RegisterIsValid(reg2); 1282 RegisterIsValid(reg1, operand_type) &&
1283 RegisterIsValid(reg2, operand_type);
1263 } 1284 }
1264 case OperandType::kReg16: 1285 case OperandType::kMaybeReg16:
1265 if (bytecode != Bytecode::kExchange && 1286 if (operand_value == 0) {
1266 bytecode != Bytecode::kExchangeWide) { 1287 return true;
1267 return false;
1268 } 1288 }
1269 return RegisterIsValid( 1289 // Fall-through to kReg16 case.
1270 Register::FromWideOperand(static_cast<uint16_t>(operand_value))); 1290 case OperandType::kReg16: {
1291 Register reg = Register::FromRawOperand(operand_value);
1292 return RegisterIsValid(reg, operand_type);
1293 }
1271 } 1294 }
1272 UNREACHABLE(); 1295 UNREACHABLE();
1273 return false; 1296 return false;
1274 } 1297 }
1275 1298
1276 1299
1300 bool BytecodeArrayBuilder::RegisterIsValid(Register reg,
1301 OperandType reg_type) const {
1302 switch (Bytecodes::SizeOfOperand(reg_type)) {
1303 case OperandSize::kByte:
1304 if (!FitsInReg8Operand(reg)) { return false; }
1305 break;
1306 case OperandSize::kShort:
1307 if (!FitsInReg16Operand(reg)) { return false; }
1308 break;
1309 case OperandSize::kNone:
1310 UNREACHABLE();
1311 return false;
1312 }
1313
1314 if (reg.is_function_context() || reg.is_function_closure() ||
1315 reg.is_new_target()) {
1316 return true;
1317 } else if (reg.is_parameter()) {
1318 int parameter_index = reg.ToParameterIndex(parameter_count_);
1319 return parameter_index >= 0 && parameter_index < parameter_count_;
1320 } else if (reg.index() < fixed_register_count()) {
1321 return true;
1322 } else {
1323 return TemporaryRegisterIsLive(reg);
1324 }
1325 }
1326
1327
1277 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const { 1328 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const {
1278 return last_bytecode_start_ < bytecodes()->size() && 1329 return last_bytecode_start_ < bytecodes()->size() &&
1279 last_bytecode_start_ >= last_block_end_; 1330 last_bytecode_start_ >= last_block_end_;
1280 } 1331 }
1281 1332
1282 1333
1283 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) { 1334 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) {
1284 if (LastBytecodeInSameBlock()) { 1335 if (LastBytecodeInSameBlock()) {
1285 PreviousBytecodeHelper previous_bytecode(*this); 1336 PreviousBytecodeHelper previous_bytecode(*this);
1286 Bytecode bytecode = previous_bytecode.GetBytecode(); 1337 Bytecode bytecode = previous_bytecode.GetBytecode();
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
1604 1655
1605 1656
1606 // static 1657 // static
1607 bool BytecodeArrayBuilder::FitsInReg16Operand(Register value) { 1658 bool BytecodeArrayBuilder::FitsInReg16Operand(Register value) {
1608 return kMinInt16 <= value.index() && value.index() <= kMaxInt16; 1659 return kMinInt16 <= value.index() && value.index() <= kMaxInt16;
1609 } 1660 }
1610 1661
1611 } // namespace interpreter 1662 } // namespace interpreter
1612 } // namespace internal 1663 } // namespace internal
1613 } // namespace v8 1664 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-array-builder.h ('k') | src/interpreter/bytecode-array-iterator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698