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

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 7063017: Rename TypeRecording...Stub into ...Stub. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 // As the then-branch, but move double-value to result before shifting. 399 // As the then-branch, but move double-value to result before shifting.
400 __ xorl(result, double_value); 400 __ xorl(result, double_value);
401 __ leal(rcx, Operand(double_exponent, -HeapNumber::kMantissaBits - 1)); 401 __ leal(rcx, Operand(double_exponent, -HeapNumber::kMantissaBits - 1));
402 __ shll_cl(result); 402 __ shll_cl(result);
403 } 403 }
404 404
405 __ bind(&done); 405 __ bind(&done);
406 } 406 }
407 407
408 408
409 Handle<Code> GetTypeRecordingUnaryOpStub(int key, 409 Handle<Code> GetUnaryOpStub(int key,
Søren Thygesen Gjesse 2011/05/24 11:33:11 Indentation.
fschneider 2011/05/24 12:16:41 Done.
410 TRUnaryOpIC::TypeInfo type_info) { 410 UnaryOpIC::TypeInfo type_info) {
411 TypeRecordingUnaryOpStub stub(key, type_info); 411 UnaryOpStub stub(key, type_info);
412 return stub.GetCode(); 412 return stub.GetCode();
413 } 413 }
414 414
415 415
416 void TypeRecordingUnaryOpStub::Generate(MacroAssembler* masm) { 416 void UnaryOpStub::Generate(MacroAssembler* masm) {
417 switch (operand_type_) { 417 switch (operand_type_) {
418 case TRUnaryOpIC::UNINITIALIZED: 418 case UnaryOpIC::UNINITIALIZED:
419 GenerateTypeTransition(masm); 419 GenerateTypeTransition(masm);
420 break; 420 break;
421 case TRUnaryOpIC::SMI: 421 case UnaryOpIC::SMI:
422 GenerateSmiStub(masm); 422 GenerateSmiStub(masm);
423 break; 423 break;
424 case TRUnaryOpIC::HEAP_NUMBER: 424 case UnaryOpIC::HEAP_NUMBER:
425 GenerateHeapNumberStub(masm); 425 GenerateHeapNumberStub(masm);
426 break; 426 break;
427 case TRUnaryOpIC::GENERIC: 427 case UnaryOpIC::GENERIC:
428 GenerateGenericStub(masm); 428 GenerateGenericStub(masm);
429 break; 429 break;
430 } 430 }
431 } 431 }
432 432
433 433
434 void TypeRecordingUnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) { 434 void UnaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
435 __ pop(rcx); // Save return address. 435 __ pop(rcx); // Save return address.
436 __ push(rax); 436 __ push(rax);
437 // Left and right arguments are now on top. 437 // Left and right arguments are now on top.
438 // Push this stub's key. Although the operation and the type info are 438 // Push this stub's key. Although the operation and the type info are
439 // encoded into the key, the encoding is opaque, so push them too. 439 // encoded into the key, the encoding is opaque, so push them too.
440 __ Push(Smi::FromInt(MinorKey())); 440 __ Push(Smi::FromInt(MinorKey()));
441 __ Push(Smi::FromInt(op_)); 441 __ Push(Smi::FromInt(op_));
442 __ Push(Smi::FromInt(operand_type_)); 442 __ Push(Smi::FromInt(operand_type_));
443 443
444 __ push(rcx); // Push return address. 444 __ push(rcx); // Push return address.
445 445
446 // Patch the caller to an appropriate specialized stub and return the 446 // Patch the caller to an appropriate specialized stub and return the
447 // operation result to the caller of the stub. 447 // operation result to the caller of the stub.
448 __ TailCallExternalReference( 448 __ TailCallExternalReference(
449 ExternalReference(IC_Utility(IC::kTypeRecordingUnaryOp_Patch), 449 ExternalReference(IC_Utility(IC::kUnaryOp_Patch),
450 masm->isolate()), 450 masm->isolate()),
451 4, 451 4,
452 1); 452 1);
453 } 453 }
454 454
455 455
456 // TODO(svenpanne): Use virtual functions instead of switch. 456 // TODO(svenpanne): Use virtual functions instead of switch.
457 void TypeRecordingUnaryOpStub::GenerateSmiStub(MacroAssembler* masm) { 457 void UnaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
458 switch (op_) { 458 switch (op_) {
459 case Token::SUB: 459 case Token::SUB:
460 GenerateSmiStubSub(masm); 460 GenerateSmiStubSub(masm);
461 break; 461 break;
462 case Token::BIT_NOT: 462 case Token::BIT_NOT:
463 GenerateSmiStubBitNot(masm); 463 GenerateSmiStubBitNot(masm);
464 break; 464 break;
465 default: 465 default:
466 UNREACHABLE(); 466 UNREACHABLE();
467 } 467 }
468 } 468 }
469 469
470 470
471 void TypeRecordingUnaryOpStub::GenerateSmiStubSub(MacroAssembler* masm) { 471 void UnaryOpStub::GenerateSmiStubSub(MacroAssembler* masm) {
472 Label slow; 472 Label slow;
473 GenerateSmiCodeSub(masm, &slow, &slow, Label::kNear, Label::kNear); 473 GenerateSmiCodeSub(masm, &slow, &slow, Label::kNear, Label::kNear);
474 __ bind(&slow); 474 __ bind(&slow);
475 GenerateTypeTransition(masm); 475 GenerateTypeTransition(masm);
476 } 476 }
477 477
478 478
479 void TypeRecordingUnaryOpStub::GenerateSmiStubBitNot(MacroAssembler* masm) { 479 void UnaryOpStub::GenerateSmiStubBitNot(MacroAssembler* masm) {
480 Label non_smi; 480 Label non_smi;
481 GenerateSmiCodeBitNot(masm, &non_smi, Label::kNear); 481 GenerateSmiCodeBitNot(masm, &non_smi, Label::kNear);
482 __ bind(&non_smi); 482 __ bind(&non_smi);
483 GenerateTypeTransition(masm); 483 GenerateTypeTransition(masm);
484 } 484 }
485 485
486 486
487 void TypeRecordingUnaryOpStub::GenerateSmiCodeSub(MacroAssembler* masm, 487 void UnaryOpStub::GenerateSmiCodeSub(MacroAssembler* masm,
Søren Thygesen Gjesse 2011/05/24 11:33:11 Indentation.
fschneider 2011/05/24 12:16:41 Done.
488 Label* non_smi, 488 Label* non_smi,
489 Label* slow, 489 Label* slow,
490 Label::Distance non_smi_near, 490 Label::Distance non_smi_near,
491 Label::Distance slow_near) { 491 Label::Distance slow_near) {
492 Label done; 492 Label done;
493 __ JumpIfNotSmi(rax, non_smi, non_smi_near); 493 __ JumpIfNotSmi(rax, non_smi, non_smi_near);
494 __ SmiNeg(rax, rax, &done, Label::kNear); 494 __ SmiNeg(rax, rax, &done, Label::kNear);
495 __ jmp(slow, slow_near); 495 __ jmp(slow, slow_near);
496 __ bind(&done); 496 __ bind(&done);
497 __ ret(0); 497 __ ret(0);
498 } 498 }
499 499
500 500
501 void TypeRecordingUnaryOpStub::GenerateSmiCodeBitNot( 501 void UnaryOpStub::GenerateSmiCodeBitNot(
Søren Thygesen Gjesse 2011/05/24 11:33:11 Fits full intentation?
fschneider 2011/05/24 12:16:41 Done.
502 MacroAssembler* masm, 502 MacroAssembler* masm,
503 Label* non_smi, 503 Label* non_smi,
504 Label::Distance non_smi_near) { 504 Label::Distance non_smi_near) {
505 __ JumpIfNotSmi(rax, non_smi, non_smi_near); 505 __ JumpIfNotSmi(rax, non_smi, non_smi_near);
506 __ SmiNot(rax, rax); 506 __ SmiNot(rax, rax);
507 __ ret(0); 507 __ ret(0);
508 } 508 }
509 509
510 510
511 // TODO(svenpanne): Use virtual functions instead of switch. 511 // TODO(svenpanne): Use virtual functions instead of switch.
512 void TypeRecordingUnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { 512 void UnaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
513 switch (op_) { 513 switch (op_) {
514 case Token::SUB: 514 case Token::SUB:
515 GenerateHeapNumberStubSub(masm); 515 GenerateHeapNumberStubSub(masm);
516 break; 516 break;
517 case Token::BIT_NOT: 517 case Token::BIT_NOT:
518 GenerateHeapNumberStubBitNot(masm); 518 GenerateHeapNumberStubBitNot(masm);
519 break; 519 break;
520 default: 520 default:
521 UNREACHABLE(); 521 UNREACHABLE();
522 } 522 }
523 } 523 }
524 524
525 525
526 void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) { 526 void UnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
527 Label non_smi, slow, call_builtin; 527 Label non_smi, slow, call_builtin;
528 GenerateSmiCodeSub(masm, &non_smi, &call_builtin, Label::kNear); 528 GenerateSmiCodeSub(masm, &non_smi, &call_builtin, Label::kNear);
529 __ bind(&non_smi); 529 __ bind(&non_smi);
530 GenerateHeapNumberCodeSub(masm, &slow); 530 GenerateHeapNumberCodeSub(masm, &slow);
531 __ bind(&slow); 531 __ bind(&slow);
532 GenerateTypeTransition(masm); 532 GenerateTypeTransition(masm);
533 __ bind(&call_builtin); 533 __ bind(&call_builtin);
534 GenerateGenericCodeFallback(masm); 534 GenerateGenericCodeFallback(masm);
535 } 535 }
536 536
537 537
538 void TypeRecordingUnaryOpStub::GenerateHeapNumberStubBitNot( 538 void UnaryOpStub::GenerateHeapNumberStubBitNot(
539 MacroAssembler* masm) { 539 MacroAssembler* masm) {
540 Label non_smi, slow; 540 Label non_smi, slow;
541 GenerateSmiCodeBitNot(masm, &non_smi, Label::kNear); 541 GenerateSmiCodeBitNot(masm, &non_smi, Label::kNear);
542 __ bind(&non_smi); 542 __ bind(&non_smi);
543 GenerateHeapNumberCodeBitNot(masm, &slow); 543 GenerateHeapNumberCodeBitNot(masm, &slow);
544 __ bind(&slow); 544 __ bind(&slow);
545 GenerateTypeTransition(masm); 545 GenerateTypeTransition(masm);
546 } 546 }
547 547
548 548
549 void TypeRecordingUnaryOpStub::GenerateHeapNumberCodeSub(MacroAssembler* masm, 549 void UnaryOpStub::GenerateHeapNumberCodeSub(MacroAssembler* masm,
Søren Thygesen Gjesse 2011/05/24 11:33:11 Indentation.
fschneider 2011/05/24 12:16:41 Done.
550 Label* slow) { 550 Label* slow) {
551 // Check if the operand is a heap number. 551 // Check if the operand is a heap number.
552 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), 552 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
553 Heap::kHeapNumberMapRootIndex); 553 Heap::kHeapNumberMapRootIndex);
554 __ j(not_equal, slow); 554 __ j(not_equal, slow);
555 555
556 // Operand is a float, negate its value by flipping the sign bit. 556 // Operand is a float, negate its value by flipping the sign bit.
557 if (mode_ == UNARY_OVERWRITE) { 557 if (mode_ == UNARY_OVERWRITE) {
558 __ Set(kScratchRegister, 0x01); 558 __ Set(kScratchRegister, 0x01);
559 __ shl(kScratchRegister, Immediate(63)); 559 __ shl(kScratchRegister, Immediate(63));
(...skipping 20 matching lines...) Expand all
580 __ Set(kScratchRegister, 0x01); 580 __ Set(kScratchRegister, 0x01);
581 __ shl(kScratchRegister, Immediate(63)); 581 __ shl(kScratchRegister, Immediate(63));
582 __ xor_(rdx, kScratchRegister); // Flip sign. 582 __ xor_(rdx, kScratchRegister); // Flip sign.
583 __ movq(FieldOperand(rcx, HeapNumber::kValueOffset), rdx); 583 __ movq(FieldOperand(rcx, HeapNumber::kValueOffset), rdx);
584 __ movq(rax, rcx); 584 __ movq(rax, rcx);
585 } 585 }
586 __ ret(0); 586 __ ret(0);
587 } 587 }
588 588
589 589
590 void TypeRecordingUnaryOpStub::GenerateHeapNumberCodeBitNot( 590 void UnaryOpStub::GenerateHeapNumberCodeBitNot(
Søren Thygesen Gjesse 2011/05/24 11:33:11 Fits full indentation?
fschneider 2011/05/24 12:16:41 Done.
591 MacroAssembler* masm, 591 MacroAssembler* masm,
592 Label* slow) { 592 Label* slow) {
593 // Check if the operand is a heap number. 593 // Check if the operand is a heap number.
594 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), 594 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
595 Heap::kHeapNumberMapRootIndex); 595 Heap::kHeapNumberMapRootIndex);
596 __ j(not_equal, slow); 596 __ j(not_equal, slow);
597 597
598 // Convert the heap number in rax to an untagged integer in rcx. 598 // Convert the heap number in rax to an untagged integer in rcx.
599 IntegerConvert(masm, rax, rax); 599 IntegerConvert(masm, rax, rax);
600 600
601 // Do the bitwise operation and smi tag the result. 601 // Do the bitwise operation and smi tag the result.
602 __ notl(rax); 602 __ notl(rax);
603 __ Integer32ToSmi(rax, rax); 603 __ Integer32ToSmi(rax, rax);
604 __ ret(0); 604 __ ret(0);
605 } 605 }
606 606
607 607
608 // TODO(svenpanne): Use virtual functions instead of switch. 608 // TODO(svenpanne): Use virtual functions instead of switch.
609 void TypeRecordingUnaryOpStub::GenerateGenericStub(MacroAssembler* masm) { 609 void UnaryOpStub::GenerateGenericStub(MacroAssembler* masm) {
610 switch (op_) { 610 switch (op_) {
611 case Token::SUB: 611 case Token::SUB:
612 GenerateGenericStubSub(masm); 612 GenerateGenericStubSub(masm);
613 break; 613 break;
614 case Token::BIT_NOT: 614 case Token::BIT_NOT:
615 GenerateGenericStubBitNot(masm); 615 GenerateGenericStubBitNot(masm);
616 break; 616 break;
617 default: 617 default:
618 UNREACHABLE(); 618 UNREACHABLE();
619 } 619 }
620 } 620 }
621 621
622 622
623 void TypeRecordingUnaryOpStub::GenerateGenericStubSub(MacroAssembler* masm) { 623 void UnaryOpStub::GenerateGenericStubSub(MacroAssembler* masm) {
624 Label non_smi, slow; 624 Label non_smi, slow;
625 GenerateSmiCodeSub(masm, &non_smi, &slow, Label::kNear); 625 GenerateSmiCodeSub(masm, &non_smi, &slow, Label::kNear);
626 __ bind(&non_smi); 626 __ bind(&non_smi);
627 GenerateHeapNumberCodeSub(masm, &slow); 627 GenerateHeapNumberCodeSub(masm, &slow);
628 __ bind(&slow); 628 __ bind(&slow);
629 GenerateGenericCodeFallback(masm); 629 GenerateGenericCodeFallback(masm);
630 } 630 }
631 631
632 632
633 void TypeRecordingUnaryOpStub::GenerateGenericStubBitNot(MacroAssembler* masm) { 633 void UnaryOpStub::GenerateGenericStubBitNot(MacroAssembler* masm) {
634 Label non_smi, slow; 634 Label non_smi, slow;
635 GenerateSmiCodeBitNot(masm, &non_smi, Label::kNear); 635 GenerateSmiCodeBitNot(masm, &non_smi, Label::kNear);
636 __ bind(&non_smi); 636 __ bind(&non_smi);
637 GenerateHeapNumberCodeBitNot(masm, &slow); 637 GenerateHeapNumberCodeBitNot(masm, &slow);
638 __ bind(&slow); 638 __ bind(&slow);
639 GenerateGenericCodeFallback(masm); 639 GenerateGenericCodeFallback(masm);
640 } 640 }
641 641
642 642
643 void TypeRecordingUnaryOpStub::GenerateGenericCodeFallback( 643 void UnaryOpStub::GenerateGenericCodeFallback(
Søren Thygesen Gjesse 2011/05/24 11:33:11 Fits one line?
fschneider 2011/05/24 12:16:41 Done.
644 MacroAssembler* masm) { 644 MacroAssembler* masm) {
645 // Handle the slow case by jumping to the JavaScript builtin. 645 // Handle the slow case by jumping to the JavaScript builtin.
646 __ pop(rcx); // pop return address 646 __ pop(rcx); // pop return address
647 __ push(rax); 647 __ push(rax);
648 __ push(rcx); // push return address 648 __ push(rcx); // push return address
649 switch (op_) { 649 switch (op_) {
650 case Token::SUB: 650 case Token::SUB:
651 __ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_FUNCTION); 651 __ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_FUNCTION);
652 break; 652 break;
653 case Token::BIT_NOT: 653 case Token::BIT_NOT:
654 __ InvokeBuiltin(Builtins::BIT_NOT, JUMP_FUNCTION); 654 __ InvokeBuiltin(Builtins::BIT_NOT, JUMP_FUNCTION);
655 break; 655 break;
656 default: 656 default:
657 UNREACHABLE(); 657 UNREACHABLE();
658 } 658 }
659 } 659 }
660 660
661 661
662 const char* TypeRecordingUnaryOpStub::GetName() { 662 const char* UnaryOpStub::GetName() {
663 if (name_ != NULL) return name_; 663 if (name_ != NULL) return name_;
664 const int kMaxNameLength = 100; 664 const int kMaxNameLength = 100;
665 name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray( 665 name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
666 kMaxNameLength); 666 kMaxNameLength);
667 if (name_ == NULL) return "OOM"; 667 if (name_ == NULL) return "OOM";
668 const char* op_name = Token::Name(op_); 668 const char* op_name = Token::Name(op_);
669 const char* overwrite_name = NULL; // Make g++ happy. 669 const char* overwrite_name = NULL; // Make g++ happy.
670 switch (mode_) { 670 switch (mode_) {
671 case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break; 671 case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break;
672 case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break; 672 case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break;
673 } 673 }
674 674
675 OS::SNPrintF(Vector<char>(name_, kMaxNameLength), 675 OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
676 "TypeRecordingUnaryOpStub_%s_%s_%s", 676 "UnaryOpStub_%s_%s_%s",
677 op_name, 677 op_name,
678 overwrite_name, 678 overwrite_name,
679 TRUnaryOpIC::GetName(operand_type_)); 679 UnaryOpIC::GetName(operand_type_));
680 return name_; 680 return name_;
681 } 681 }
682 682
683 683
684 Handle<Code> GetTypeRecordingBinaryOpStub(int key, 684 Handle<Code> GetBinaryOpStub(int key,
Søren Thygesen Gjesse 2011/05/24 11:33:11 Full intentation or int key on separate line.
fschneider 2011/05/24 12:16:41 Done.
685 TRBinaryOpIC::TypeInfo type_info, 685 BinaryOpIC::TypeInfo type_info,
686 TRBinaryOpIC::TypeInfo result_type_info) { 686 BinaryOpIC::TypeInfo result_type_info) {
687 TypeRecordingBinaryOpStub stub(key, type_info, result_type_info); 687 BinaryOpStub stub(key, type_info, result_type_info);
688 return stub.GetCode(); 688 return stub.GetCode();
689 } 689 }
690 690
691 691
692 void TypeRecordingBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) { 692 void BinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
693 __ pop(rcx); // Save return address. 693 __ pop(rcx); // Save return address.
694 __ push(rdx); 694 __ push(rdx);
695 __ push(rax); 695 __ push(rax);
696 // Left and right arguments are now on top. 696 // Left and right arguments are now on top.
697 // Push this stub's key. Although the operation and the type info are 697 // Push this stub's key. Although the operation and the type info are
698 // encoded into the key, the encoding is opaque, so push them too. 698 // encoded into the key, the encoding is opaque, so push them too.
699 __ Push(Smi::FromInt(MinorKey())); 699 __ Push(Smi::FromInt(MinorKey()));
700 __ Push(Smi::FromInt(op_)); 700 __ Push(Smi::FromInt(op_));
701 __ Push(Smi::FromInt(operands_type_)); 701 __ Push(Smi::FromInt(operands_type_));
702 702
703 __ push(rcx); // Push return address. 703 __ push(rcx); // Push return address.
704 704
705 // Patch the caller to an appropriate specialized stub and return the 705 // Patch the caller to an appropriate specialized stub and return the
706 // operation result to the caller of the stub. 706 // operation result to the caller of the stub.
707 __ TailCallExternalReference( 707 __ TailCallExternalReference(
708 ExternalReference(IC_Utility(IC::kTypeRecordingBinaryOp_Patch), 708 ExternalReference(IC_Utility(IC::kBinaryOp_Patch),
709 masm->isolate()), 709 masm->isolate()),
710 5, 710 5,
711 1); 711 1);
712 } 712 }
713 713
714 714
715 void TypeRecordingBinaryOpStub::Generate(MacroAssembler* masm) { 715 void BinaryOpStub::Generate(MacroAssembler* masm) {
716 switch (operands_type_) { 716 switch (operands_type_) {
717 case TRBinaryOpIC::UNINITIALIZED: 717 case BinaryOpIC::UNINITIALIZED:
718 GenerateTypeTransition(masm); 718 GenerateTypeTransition(masm);
719 break; 719 break;
720 case TRBinaryOpIC::SMI: 720 case BinaryOpIC::SMI:
721 GenerateSmiStub(masm); 721 GenerateSmiStub(masm);
722 break; 722 break;
723 case TRBinaryOpIC::INT32: 723 case BinaryOpIC::INT32:
724 UNREACHABLE(); 724 UNREACHABLE();
725 // The int32 case is identical to the Smi case. We avoid creating this 725 // The int32 case is identical to the Smi case. We avoid creating this
726 // ic state on x64. 726 // ic state on x64.
727 break; 727 break;
728 case TRBinaryOpIC::HEAP_NUMBER: 728 case BinaryOpIC::HEAP_NUMBER:
729 GenerateHeapNumberStub(masm); 729 GenerateHeapNumberStub(masm);
730 break; 730 break;
731 case TRBinaryOpIC::ODDBALL: 731 case BinaryOpIC::ODDBALL:
732 GenerateOddballStub(masm); 732 GenerateOddballStub(masm);
733 break; 733 break;
734 case TRBinaryOpIC::BOTH_STRING: 734 case BinaryOpIC::BOTH_STRING:
735 GenerateBothStringStub(masm); 735 GenerateBothStringStub(masm);
736 break; 736 break;
737 case TRBinaryOpIC::STRING: 737 case BinaryOpIC::STRING:
738 GenerateStringStub(masm); 738 GenerateStringStub(masm);
739 break; 739 break;
740 case TRBinaryOpIC::GENERIC: 740 case BinaryOpIC::GENERIC:
741 GenerateGeneric(masm); 741 GenerateGeneric(masm);
742 break; 742 break;
743 default: 743 default:
744 UNREACHABLE(); 744 UNREACHABLE();
745 } 745 }
746 } 746 }
747 747
748 748
749 const char* TypeRecordingBinaryOpStub::GetName() { 749 const char* BinaryOpStub::GetName() {
750 if (name_ != NULL) return name_; 750 if (name_ != NULL) return name_;
751 const int kMaxNameLength = 100; 751 const int kMaxNameLength = 100;
752 name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray( 752 name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
753 kMaxNameLength); 753 kMaxNameLength);
754 if (name_ == NULL) return "OOM"; 754 if (name_ == NULL) return "OOM";
755 const char* op_name = Token::Name(op_); 755 const char* op_name = Token::Name(op_);
756 const char* overwrite_name; 756 const char* overwrite_name;
757 switch (mode_) { 757 switch (mode_) {
758 case NO_OVERWRITE: overwrite_name = "Alloc"; break; 758 case NO_OVERWRITE: overwrite_name = "Alloc"; break;
759 case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break; 759 case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break;
760 case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break; 760 case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break;
761 default: overwrite_name = "UnknownOverwrite"; break; 761 default: overwrite_name = "UnknownOverwrite"; break;
762 } 762 }
763 763
764 OS::SNPrintF(Vector<char>(name_, kMaxNameLength), 764 OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
765 "TypeRecordingBinaryOpStub_%s_%s_%s", 765 "BinaryOpStub_%s_%s_%s",
766 op_name, 766 op_name,
767 overwrite_name, 767 overwrite_name,
768 TRBinaryOpIC::GetName(operands_type_)); 768 BinaryOpIC::GetName(operands_type_));
769 return name_; 769 return name_;
770 } 770 }
771 771
772 772
773 void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, 773 void BinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
Søren Thygesen Gjesse 2011/05/24 11:33:11 MacroAssembler* masm, on separate line.
fschneider 2011/05/24 12:16:41 Done.
774 Label* slow, 774 Label* slow,
775 SmiCodeGenerateHeapNumberResults allow_heapnumber_results) { 775 SmiCodeGenerateHeapNumberResults allow_heapnumber_results) {
776 776
777 // Arguments to TypeRecordingBinaryOpStub are in rdx and rax. 777 // Arguments to BinaryOpStub are in rdx and rax.
778 Register left = rdx; 778 Register left = rdx;
779 Register right = rax; 779 Register right = rax;
780 780
781 // We only generate heapnumber answers for overflowing calculations 781 // We only generate heapnumber answers for overflowing calculations
782 // for the four basic arithmetic operations and logical right shift by 0. 782 // for the four basic arithmetic operations and logical right shift by 0.
783 bool generate_inline_heapnumber_results = 783 bool generate_inline_heapnumber_results =
784 (allow_heapnumber_results == ALLOW_HEAPNUMBER_RESULTS) && 784 (allow_heapnumber_results == ALLOW_HEAPNUMBER_RESULTS) &&
785 (op_ == Token::ADD || op_ == Token::SUB || 785 (op_ == Token::ADD || op_ == Token::SUB ||
786 op_ == Token::MUL || op_ == Token::DIV || op_ == Token::SHR); 786 op_ == Token::MUL || op_ == Token::DIV || op_ == Token::SHR);
787 787
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 // values that could be smi. 913 // values that could be smi.
914 __ bind(&not_smis); 914 __ bind(&not_smis);
915 Comment done_comment(masm, "-- Enter non-smi code"); 915 Comment done_comment(masm, "-- Enter non-smi code");
916 FloatingPointHelper::NumbersToSmis(masm, left, right, rbx, rdi, rcx, 916 FloatingPointHelper::NumbersToSmis(masm, left, right, rbx, rdi, rcx,
917 &smi_values, &fail); 917 &smi_values, &fail);
918 __ jmp(&smi_values); 918 __ jmp(&smi_values);
919 __ bind(&fail); 919 __ bind(&fail);
920 } 920 }
921 921
922 922
923 void TypeRecordingBinaryOpStub::GenerateFloatingPointCode( 923 void BinaryOpStub::GenerateFloatingPointCode(
Søren Thygesen Gjesse 2011/05/24 11:33:11 Fits full indentation?
fschneider 2011/05/24 12:16:41 Done.
924 MacroAssembler* masm, 924 MacroAssembler* masm,
925 Label* allocation_failure, 925 Label* allocation_failure,
926 Label* non_numeric_failure) { 926 Label* non_numeric_failure) {
927 switch (op_) { 927 switch (op_) {
928 case Token::ADD: 928 case Token::ADD:
929 case Token::SUB: 929 case Token::SUB:
930 case Token::MUL: 930 case Token::MUL:
931 case Token::DIV: { 931 case Token::DIV: {
932 FloatingPointHelper::LoadSSE2UnknownOperands(masm, non_numeric_failure); 932 FloatingPointHelper::LoadSSE2UnknownOperands(masm, non_numeric_failure);
933 933
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 __ Integer32ToSmi(rdx, rbx); 1015 __ Integer32ToSmi(rdx, rbx);
1016 __ jmp(allocation_failure); 1016 __ jmp(allocation_failure);
1017 } 1017 }
1018 break; 1018 break;
1019 } 1019 }
1020 default: UNREACHABLE(); break; 1020 default: UNREACHABLE(); break;
1021 } 1021 }
1022 // No fall-through from this generated code. 1022 // No fall-through from this generated code.
1023 if (FLAG_debug_code) { 1023 if (FLAG_debug_code) {
1024 __ Abort("Unexpected fall-through in " 1024 __ Abort("Unexpected fall-through in "
1025 "TypeRecordingBinaryStub::GenerateFloatingPointCode."); 1025 "BinaryStub::GenerateFloatingPointCode.");
1026 } 1026 }
1027 } 1027 }
1028 1028
1029 1029
1030 void TypeRecordingBinaryOpStub::GenerateStringAddCode(MacroAssembler* masm) { 1030 void BinaryOpStub::GenerateStringAddCode(MacroAssembler* masm) {
1031 ASSERT(op_ == Token::ADD); 1031 ASSERT(op_ == Token::ADD);
1032 Label left_not_string, call_runtime; 1032 Label left_not_string, call_runtime;
1033 1033
1034 // Registers containing left and right operands respectively. 1034 // Registers containing left and right operands respectively.
1035 Register left = rdx; 1035 Register left = rdx;
1036 Register right = rax; 1036 Register right = rax;
1037 1037
1038 // Test if left operand is a string. 1038 // Test if left operand is a string.
1039 __ JumpIfSmi(left, &left_not_string, Label::kNear); 1039 __ JumpIfSmi(left, &left_not_string, Label::kNear);
1040 __ CmpObjectType(left, FIRST_NONSTRING_TYPE, rcx); 1040 __ CmpObjectType(left, FIRST_NONSTRING_TYPE, rcx);
(...skipping 10 matching lines...) Expand all
1051 1051
1052 StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB); 1052 StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB);
1053 GenerateRegisterArgsPush(masm); 1053 GenerateRegisterArgsPush(masm);
1054 __ TailCallStub(&string_add_right_stub); 1054 __ TailCallStub(&string_add_right_stub);
1055 1055
1056 // Neither argument is a string. 1056 // Neither argument is a string.
1057 __ bind(&call_runtime); 1057 __ bind(&call_runtime);
1058 } 1058 }
1059 1059
1060 1060
1061 void TypeRecordingBinaryOpStub::GenerateCallRuntimeCode(MacroAssembler* masm) { 1061 void BinaryOpStub::GenerateCallRuntimeCode(MacroAssembler* masm) {
1062 GenerateRegisterArgsPush(masm); 1062 GenerateRegisterArgsPush(masm);
1063 switch (op_) { 1063 switch (op_) {
1064 case Token::ADD: 1064 case Token::ADD:
1065 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION); 1065 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION);
1066 break; 1066 break;
1067 case Token::SUB: 1067 case Token::SUB:
1068 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION); 1068 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION);
1069 break; 1069 break;
1070 case Token::MUL: 1070 case Token::MUL:
1071 __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION); 1071 __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION);
(...skipping 21 matching lines...) Expand all
1093 break; 1093 break;
1094 case Token::SHR: 1094 case Token::SHR:
1095 __ InvokeBuiltin(Builtins::SHR, JUMP_FUNCTION); 1095 __ InvokeBuiltin(Builtins::SHR, JUMP_FUNCTION);
1096 break; 1096 break;
1097 default: 1097 default:
1098 UNREACHABLE(); 1098 UNREACHABLE();
1099 } 1099 }
1100 } 1100 }
1101 1101
1102 1102
1103 void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) { 1103 void BinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
1104 Label call_runtime; 1104 Label call_runtime;
1105 if (result_type_ == TRBinaryOpIC::UNINITIALIZED || 1105 if (result_type_ == BinaryOpIC::UNINITIALIZED ||
1106 result_type_ == TRBinaryOpIC::SMI) { 1106 result_type_ == BinaryOpIC::SMI) {
1107 // Only allow smi results. 1107 // Only allow smi results.
1108 GenerateSmiCode(masm, NULL, NO_HEAPNUMBER_RESULTS); 1108 GenerateSmiCode(masm, NULL, NO_HEAPNUMBER_RESULTS);
1109 } else { 1109 } else {
1110 // Allow heap number result and don't make a transition if a heap number 1110 // Allow heap number result and don't make a transition if a heap number
1111 // cannot be allocated. 1111 // cannot be allocated.
1112 GenerateSmiCode(masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS); 1112 GenerateSmiCode(masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS);
1113 } 1113 }
1114 1114
1115 // Code falls through if the result is not returned as either a smi or heap 1115 // Code falls through if the result is not returned as either a smi or heap
1116 // number. 1116 // number.
1117 GenerateTypeTransition(masm); 1117 GenerateTypeTransition(masm);
1118 1118
1119 if (call_runtime.is_linked()) { 1119 if (call_runtime.is_linked()) {
1120 __ bind(&call_runtime); 1120 __ bind(&call_runtime);
1121 GenerateCallRuntimeCode(masm); 1121 GenerateCallRuntimeCode(masm);
1122 } 1122 }
1123 } 1123 }
1124 1124
1125 1125
1126 void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) { 1126 void BinaryOpStub::GenerateStringStub(MacroAssembler* masm) {
1127 ASSERT(operands_type_ == TRBinaryOpIC::STRING); 1127 ASSERT(operands_type_ == BinaryOpIC::STRING);
1128 ASSERT(op_ == Token::ADD); 1128 ASSERT(op_ == Token::ADD);
1129 GenerateStringAddCode(masm); 1129 GenerateStringAddCode(masm);
1130 // Try to add arguments as strings, otherwise, transition to the generic 1130 // Try to add arguments as strings, otherwise, transition to the generic
1131 // TRBinaryOpIC type. 1131 // BinaryOpIC type.
1132 GenerateTypeTransition(masm); 1132 GenerateTypeTransition(masm);
1133 } 1133 }
1134 1134
1135 1135
1136 void TypeRecordingBinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) { 1136 void BinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) {
1137 Label call_runtime; 1137 Label call_runtime;
1138 ASSERT(operands_type_ == TRBinaryOpIC::BOTH_STRING); 1138 ASSERT(operands_type_ == BinaryOpIC::BOTH_STRING);
1139 ASSERT(op_ == Token::ADD); 1139 ASSERT(op_ == Token::ADD);
1140 // If both arguments are strings, call the string add stub. 1140 // If both arguments are strings, call the string add stub.
1141 // Otherwise, do a transition. 1141 // Otherwise, do a transition.
1142 1142
1143 // Registers containing left and right operands respectively. 1143 // Registers containing left and right operands respectively.
1144 Register left = rdx; 1144 Register left = rdx;
1145 Register right = rax; 1145 Register right = rax;
1146 1146
1147 // Test if left operand is a string. 1147 // Test if left operand is a string.
1148 __ JumpIfSmi(left, &call_runtime); 1148 __ JumpIfSmi(left, &call_runtime);
1149 __ CmpObjectType(left, FIRST_NONSTRING_TYPE, rcx); 1149 __ CmpObjectType(left, FIRST_NONSTRING_TYPE, rcx);
1150 __ j(above_equal, &call_runtime); 1150 __ j(above_equal, &call_runtime);
1151 1151
1152 // Test if right operand is a string. 1152 // Test if right operand is a string.
1153 __ JumpIfSmi(right, &call_runtime); 1153 __ JumpIfSmi(right, &call_runtime);
1154 __ CmpObjectType(right, FIRST_NONSTRING_TYPE, rcx); 1154 __ CmpObjectType(right, FIRST_NONSTRING_TYPE, rcx);
1155 __ j(above_equal, &call_runtime); 1155 __ j(above_equal, &call_runtime);
1156 1156
1157 StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB); 1157 StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB);
1158 GenerateRegisterArgsPush(masm); 1158 GenerateRegisterArgsPush(masm);
1159 __ TailCallStub(&string_add_stub); 1159 __ TailCallStub(&string_add_stub);
1160 1160
1161 __ bind(&call_runtime); 1161 __ bind(&call_runtime);
1162 GenerateTypeTransition(masm); 1162 GenerateTypeTransition(masm);
1163 } 1163 }
1164 1164
1165 1165
1166 void TypeRecordingBinaryOpStub::GenerateOddballStub(MacroAssembler* masm) { 1166 void BinaryOpStub::GenerateOddballStub(MacroAssembler* masm) {
1167 Label call_runtime; 1167 Label call_runtime;
1168 1168
1169 if (op_ == Token::ADD) { 1169 if (op_ == Token::ADD) {
1170 // Handle string addition here, because it is the only operation 1170 // Handle string addition here, because it is the only operation
1171 // that does not do a ToNumber conversion on the operands. 1171 // that does not do a ToNumber conversion on the operands.
1172 GenerateStringAddCode(masm); 1172 GenerateStringAddCode(masm);
1173 } 1173 }
1174 1174
1175 // Convert oddball arguments to numbers. 1175 // Convert oddball arguments to numbers.
1176 Label check, done; 1176 Label check, done;
(...skipping 12 matching lines...) Expand all
1189 __ xor_(rax, rax); 1189 __ xor_(rax, rax);
1190 } else { 1190 } else {
1191 __ LoadRoot(rax, Heap::kNanValueRootIndex); 1191 __ LoadRoot(rax, Heap::kNanValueRootIndex);
1192 } 1192 }
1193 __ bind(&done); 1193 __ bind(&done);
1194 1194
1195 GenerateHeapNumberStub(masm); 1195 GenerateHeapNumberStub(masm);
1196 } 1196 }
1197 1197
1198 1198
1199 void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { 1199 void BinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
1200 Label gc_required, not_number; 1200 Label gc_required, not_number;
1201 GenerateFloatingPointCode(masm, &gc_required, &not_number); 1201 GenerateFloatingPointCode(masm, &gc_required, &not_number);
1202 1202
1203 __ bind(&not_number); 1203 __ bind(&not_number);
1204 GenerateTypeTransition(masm); 1204 GenerateTypeTransition(masm);
1205 1205
1206 __ bind(&gc_required); 1206 __ bind(&gc_required);
1207 GenerateCallRuntimeCode(masm); 1207 GenerateCallRuntimeCode(masm);
1208 } 1208 }
1209 1209
1210 1210
1211 void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) { 1211 void BinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
1212 Label call_runtime, call_string_add_or_runtime; 1212 Label call_runtime, call_string_add_or_runtime;
1213 1213
1214 GenerateSmiCode(masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS); 1214 GenerateSmiCode(masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS);
1215 1215
1216 GenerateFloatingPointCode(masm, &call_runtime, &call_string_add_or_runtime); 1216 GenerateFloatingPointCode(masm, &call_runtime, &call_string_add_or_runtime);
1217 1217
1218 __ bind(&call_string_add_or_runtime); 1218 __ bind(&call_string_add_or_runtime);
1219 if (op_ == Token::ADD) { 1219 if (op_ == Token::ADD) {
1220 GenerateStringAddCode(masm); 1220 GenerateStringAddCode(masm);
1221 } 1221 }
1222 1222
1223 __ bind(&call_runtime); 1223 __ bind(&call_runtime);
1224 GenerateCallRuntimeCode(masm); 1224 GenerateCallRuntimeCode(masm);
1225 } 1225 }
1226 1226
1227 1227
1228 void TypeRecordingBinaryOpStub::GenerateHeapResultAllocation( 1228 void BinaryOpStub::GenerateHeapResultAllocation(
Søren Thygesen Gjesse 2011/05/24 11:33:11 Fits full indentation?
fschneider 2011/05/24 12:16:41 Done.
1229 MacroAssembler* masm, 1229 MacroAssembler* masm,
1230 Label* alloc_failure) { 1230 Label* alloc_failure) {
1231 Label skip_allocation; 1231 Label skip_allocation;
1232 OverwriteMode mode = mode_; 1232 OverwriteMode mode = mode_;
1233 switch (mode) { 1233 switch (mode) {
1234 case OVERWRITE_LEFT: { 1234 case OVERWRITE_LEFT: {
1235 // If the argument in rdx is already an object, we skip the 1235 // If the argument in rdx is already an object, we skip the
1236 // allocation of a heap number. 1236 // allocation of a heap number.
1237 __ JumpIfNotSmi(rdx, &skip_allocation); 1237 __ JumpIfNotSmi(rdx, &skip_allocation);
1238 // Allocate a heap number for the result. Keep eax and edx intact 1238 // Allocate a heap number for the result. Keep eax and edx intact
(...skipping 19 matching lines...) Expand all
1258 // Now rax can be overwritten losing one of the arguments as we are 1258 // Now rax can be overwritten losing one of the arguments as we are
1259 // now done and will not need it any more. 1259 // now done and will not need it any more.
1260 __ movq(rax, rbx); 1260 __ movq(rax, rbx);
1261 __ bind(&skip_allocation); 1261 __ bind(&skip_allocation);
1262 break; 1262 break;
1263 default: UNREACHABLE(); 1263 default: UNREACHABLE();
1264 } 1264 }
1265 } 1265 }
1266 1266
1267 1267
1268 void TypeRecordingBinaryOpStub::GenerateRegisterArgsPush(MacroAssembler* masm) { 1268 void BinaryOpStub::GenerateRegisterArgsPush(MacroAssembler* masm) {
1269 __ pop(rcx); 1269 __ pop(rcx);
1270 __ push(rdx); 1270 __ push(rdx);
1271 __ push(rax); 1271 __ push(rax);
1272 __ push(rcx); 1272 __ push(rcx);
1273 } 1273 }
1274 1274
1275 1275
1276 void TranscendentalCacheStub::Generate(MacroAssembler* masm) { 1276 void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
1277 // TAGGED case: 1277 // TAGGED case:
1278 // Input: 1278 // Input:
(...skipping 3845 matching lines...) Expand 10 before | Expand all | Expand 10 after
5124 __ Drop(1); 5124 __ Drop(1);
5125 __ ret(2 * kPointerSize); 5125 __ ret(2 * kPointerSize);
5126 } 5126 }
5127 5127
5128 5128
5129 #undef __ 5129 #undef __
5130 5130
5131 } } // namespace v8::internal 5131 } } // namespace v8::internal
5132 5132
5133 #endif // V8_TARGET_ARCH_X64 5133 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698