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

Side by Side Diff: src/ia32/ic-ia32.cc

Issue 6697023: Merge 6800:7180 from the bleeding edge branch to the experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 9 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
« no previous file with comments | « src/ia32/full-codegen-ia32.cc ('k') | src/ia32/lithium-codegen-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 } 523 }
524 524
525 525
526 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { 526 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
527 // ----------- S t a t e ------------- 527 // ----------- S t a t e -------------
528 // -- eax : key 528 // -- eax : key
529 // -- edx : receiver 529 // -- edx : receiver
530 // -- esp[0] : return address 530 // -- esp[0] : return address
531 // ----------------------------------- 531 // -----------------------------------
532 Label slow, check_string, index_smi, index_string, property_array_property; 532 Label slow, check_string, index_smi, index_string, property_array_property;
533 Label check_pixel_array, probe_dictionary, check_number_dictionary; 533 Label probe_dictionary, check_number_dictionary;
534 534
535 // Check that the key is a smi. 535 // Check that the key is a smi.
536 __ test(eax, Immediate(kSmiTagMask)); 536 __ test(eax, Immediate(kSmiTagMask));
537 __ j(not_zero, &check_string, not_taken); 537 __ j(not_zero, &check_string, not_taken);
538 __ bind(&index_smi); 538 __ bind(&index_smi);
539 // Now the key is known to be a smi. This place is also jumped to from 539 // Now the key is known to be a smi. This place is also jumped to from
540 // where a numeric string is converted to a smi. 540 // where a numeric string is converted to a smi.
541 541
542 GenerateKeyedLoadReceiverCheck( 542 GenerateKeyedLoadReceiverCheck(
543 masm, edx, ecx, Map::kHasIndexedInterceptor, &slow); 543 masm, edx, ecx, Map::kHasIndexedInterceptor, &slow);
544 544
545 // Check the "has fast elements" bit in the receiver's map which is 545 // Check the "has fast elements" bit in the receiver's map which is
546 // now in ecx. 546 // now in ecx.
547 __ test_b(FieldOperand(ecx, Map::kBitField2Offset), 547 __ test_b(FieldOperand(ecx, Map::kBitField2Offset),
548 1 << Map::kHasFastElements); 548 1 << Map::kHasFastElements);
549 __ j(zero, &check_pixel_array, not_taken); 549 __ j(zero, &check_number_dictionary, not_taken);
550 550
551 GenerateFastArrayLoad(masm, 551 GenerateFastArrayLoad(masm,
552 edx, 552 edx,
553 eax, 553 eax,
554 ecx, 554 ecx,
555 eax, 555 eax,
556 NULL, 556 NULL,
557 &slow); 557 &slow);
558 __ IncrementCounter(&Counters::keyed_load_generic_smi, 1); 558 __ IncrementCounter(&Counters::keyed_load_generic_smi, 1);
559 __ ret(0); 559 __ ret(0);
560 560
561 __ bind(&check_pixel_array); 561 __ bind(&check_number_dictionary);
562 GenerateFastPixelArrayLoad(masm, 562 __ mov(ebx, eax);
563 edx, 563 __ SmiUntag(ebx);
564 eax, 564 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
565 ecx,
566 ebx,
567 eax,
568 &check_number_dictionary,
569 NULL,
570 &slow);
571 565
572 __ bind(&check_number_dictionary);
573 // Check whether the elements is a number dictionary. 566 // Check whether the elements is a number dictionary.
574 // edx: receiver 567 // edx: receiver
575 // ebx: untagged index 568 // ebx: untagged index
576 // eax: key 569 // eax: key
577 // ecx: elements 570 // ecx: elements
578 __ CheckMap(ecx, Factory::hash_table_map(), &slow, true); 571 __ CheckMap(ecx, Factory::hash_table_map(), &slow, true);
579 Label slow_pop_receiver; 572 Label slow_pop_receiver;
580 // Push receiver on the stack to free up a register for the dictionary 573 // Push receiver on the stack to free up a register for the dictionary
581 // probing. 574 // probing.
582 __ push(edx); 575 __ push(edx);
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 // Perform tail call to the entry. 747 // Perform tail call to the entry.
755 ExternalReference ref = ExternalReference( 748 ExternalReference ref = ExternalReference(
756 IC_Utility(kKeyedLoadPropertyWithInterceptor)); 749 IC_Utility(kKeyedLoadPropertyWithInterceptor));
757 __ TailCallExternalReference(ref, 2, 1); 750 __ TailCallExternalReference(ref, 2, 1);
758 751
759 __ bind(&slow); 752 __ bind(&slow);
760 GenerateMiss(masm); 753 GenerateMiss(masm);
761 } 754 }
762 755
763 756
764 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) { 757 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
758 StrictModeFlag strict_mode) {
765 // ----------- S t a t e ------------- 759 // ----------- S t a t e -------------
766 // -- eax : value 760 // -- eax : value
767 // -- ecx : key 761 // -- ecx : key
768 // -- edx : receiver 762 // -- edx : receiver
769 // -- esp[0] : return address 763 // -- esp[0] : return address
770 // ----------------------------------- 764 // -----------------------------------
771 Label slow, fast, array, extra, check_pixel_array; 765 Label slow, fast, array, extra;
772 766
773 // Check that the object isn't a smi. 767 // Check that the object isn't a smi.
774 __ test(edx, Immediate(kSmiTagMask)); 768 __ test(edx, Immediate(kSmiTagMask));
775 __ j(zero, &slow, not_taken); 769 __ j(zero, &slow, not_taken);
776 // Get the map from the receiver. 770 // Get the map from the receiver.
777 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); 771 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
778 // Check that the receiver does not require access checks. We need 772 // Check that the receiver does not require access checks. We need
779 // to do this because this generic stub does not perform map checks. 773 // to do this because this generic stub does not perform map checks.
780 __ test_b(FieldOperand(edi, Map::kBitFieldOffset), 774 __ test_b(FieldOperand(edi, Map::kBitFieldOffset),
781 1 << Map::kIsAccessCheckNeeded); 775 1 << Map::kIsAccessCheckNeeded);
782 __ j(not_zero, &slow, not_taken); 776 __ j(not_zero, &slow, not_taken);
783 // Check that the key is a smi. 777 // Check that the key is a smi.
784 __ test(ecx, Immediate(kSmiTagMask)); 778 __ test(ecx, Immediate(kSmiTagMask));
785 __ j(not_zero, &slow, not_taken); 779 __ j(not_zero, &slow, not_taken);
786 __ CmpInstanceType(edi, JS_ARRAY_TYPE); 780 __ CmpInstanceType(edi, JS_ARRAY_TYPE);
787 __ j(equal, &array); 781 __ j(equal, &array);
788 // Check that the object is some kind of JS object. 782 // Check that the object is some kind of JS object.
789 __ CmpInstanceType(edi, FIRST_JS_OBJECT_TYPE); 783 __ CmpInstanceType(edi, FIRST_JS_OBJECT_TYPE);
790 __ j(below, &slow, not_taken); 784 __ j(below, &slow, not_taken);
791 785
792 // Object case: Check key against length in the elements array. 786 // Object case: Check key against length in the elements array.
793 // eax: value 787 // eax: value
794 // edx: JSObject 788 // edx: JSObject
795 // ecx: key (a smi) 789 // ecx: key (a smi)
796 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 790 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
797 // Check that the object is in fast mode and writable. 791 // Check that the object is in fast mode and writable.
798 __ CheckMap(edi, Factory::fixed_array_map(), &check_pixel_array, true); 792 __ CheckMap(edi, Factory::fixed_array_map(), &slow, true);
799 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); 793 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset));
800 __ j(below, &fast, taken); 794 __ j(below, &fast, taken);
801 795
802 // Slow case: call runtime. 796 // Slow case: call runtime.
803 __ bind(&slow); 797 __ bind(&slow);
804 GenerateRuntimeSetProperty(masm); 798 GenerateRuntimeSetProperty(masm, strict_mode);
805
806 // Check whether the elements is a pixel array.
807 __ bind(&check_pixel_array);
808 // eax: value
809 // ecx: key (a smi)
810 // edx: receiver
811 // edi: elements array
812 GenerateFastPixelArrayStore(masm,
813 edx,
814 ecx,
815 eax,
816 edi,
817 ebx,
818 false,
819 NULL,
820 &slow,
821 &slow,
822 &slow);
823 799
824 // Extra capacity case: Check if there is extra capacity to 800 // Extra capacity case: Check if there is extra capacity to
825 // perform the store and update the length. Used for adding one 801 // perform the store and update the length. Used for adding one
826 // element to the array by writing to array[array.length]. 802 // element to the array by writing to array[array.length].
827 __ bind(&extra); 803 __ bind(&extra);
828 // eax: value 804 // eax: value
829 // edx: receiver, a JSArray 805 // edx: receiver, a JSArray
830 // ecx: key, a smi. 806 // ecx: key, a smi.
831 // edi: receiver->elements, a FixedArray 807 // edi: receiver->elements, a FixedArray
832 // flags: compare (ecx, edx.length()) 808 // flags: compare (ecx, edx.length())
833 __ j(not_equal, &slow, not_taken); // do not leave holes in the array 809 __ j(not_equal, &slow, not_taken); // do not leave holes in the array
834 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); 810 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset));
835 __ j(above_equal, &slow, not_taken); 811 __ j(above_equal, &slow, not_taken);
836 // Add 1 to receiver->length, and go to fast array write. 812 // Add 1 to receiver->length, and go to fast array write.
837 __ add(FieldOperand(edx, JSArray::kLengthOffset), 813 __ add(FieldOperand(edx, JSArray::kLengthOffset),
838 Immediate(Smi::FromInt(1))); 814 Immediate(Smi::FromInt(1)));
839 __ jmp(&fast); 815 __ jmp(&fast);
840 816
841 // Array case: Get the length and the elements array from the JS 817 // Array case: Get the length and the elements array from the JS
842 // array. Check that the array is in fast mode (and writable); if it 818 // array. Check that the array is in fast mode (and writable); if it
843 // is the length is always a smi. 819 // is the length is always a smi.
844 __ bind(&array); 820 __ bind(&array);
845 // eax: value 821 // eax: value
846 // edx: receiver, a JSArray 822 // edx: receiver, a JSArray
847 // ecx: key, a smi. 823 // ecx: key, a smi.
848 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 824 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
849 __ CheckMap(edi, Factory::fixed_array_map(), &check_pixel_array, true); 825 __ CheckMap(edi, Factory::fixed_array_map(), &slow, true);
850 826
851 // Check the key against the length in the array, compute the 827 // Check the key against the length in the array, compute the
852 // address to store into and fall through to fast case. 828 // address to store into and fall through to fast case.
853 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis. 829 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis.
854 __ j(above_equal, &extra, not_taken); 830 __ j(above_equal, &extra, not_taken);
855 831
856 // Fast case: Do the store. 832 // Fast case: Do the store.
857 __ bind(&fast); 833 __ bind(&fast);
858 // eax: value 834 // eax: value
859 // ecx: key (a smi) 835 // ecx: key (a smi)
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after
1482 __ push(edx); // receiver 1458 __ push(edx); // receiver
1483 __ push(eax); // name 1459 __ push(eax); // name
1484 __ push(ebx); // return address 1460 __ push(ebx); // return address
1485 1461
1486 // Perform tail call to the entry. 1462 // Perform tail call to the entry.
1487 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); 1463 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
1488 } 1464 }
1489 1465
1490 1466
1491 void StoreIC::GenerateMegamorphic(MacroAssembler* masm, 1467 void StoreIC::GenerateMegamorphic(MacroAssembler* masm,
1492 Code::ExtraICState extra_ic_state) { 1468 StrictModeFlag strict_mode) {
1493 // ----------- S t a t e ------------- 1469 // ----------- S t a t e -------------
1494 // -- eax : value 1470 // -- eax : value
1495 // -- ecx : name 1471 // -- ecx : name
1496 // -- edx : receiver 1472 // -- edx : receiver
1497 // -- esp[0] : return address 1473 // -- esp[0] : return address
1498 // ----------------------------------- 1474 // -----------------------------------
1499 1475
1500 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, 1476 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
1501 NOT_IN_LOOP, 1477 NOT_IN_LOOP,
1502 MONOMORPHIC, 1478 MONOMORPHIC,
1503 extra_ic_state); 1479 strict_mode);
1504 StubCache::GenerateProbe(masm, flags, edx, ecx, ebx, no_reg); 1480 StubCache::GenerateProbe(masm, flags, edx, ecx, ebx, no_reg);
1505 1481
1506 // Cache miss: Jump to runtime. 1482 // Cache miss: Jump to runtime.
1507 GenerateMiss(masm); 1483 GenerateMiss(masm);
1508 } 1484 }
1509 1485
1510 1486
1511 void StoreIC::GenerateMiss(MacroAssembler* masm) { 1487 void StoreIC::GenerateMiss(MacroAssembler* masm) {
1512 // ----------- S t a t e ------------- 1488 // ----------- S t a t e -------------
1513 // -- eax : value 1489 // -- eax : value
(...skipping 22 matching lines...) Expand all
1536 1512
1537 void StoreIC::GenerateArrayLength(MacroAssembler* masm) { 1513 void StoreIC::GenerateArrayLength(MacroAssembler* masm) {
1538 // ----------- S t a t e ------------- 1514 // ----------- S t a t e -------------
1539 // -- eax : value 1515 // -- eax : value
1540 // -- ecx : name 1516 // -- ecx : name
1541 // -- edx : receiver 1517 // -- edx : receiver
1542 // -- esp[0] : return address 1518 // -- esp[0] : return address
1543 // ----------------------------------- 1519 // -----------------------------------
1544 // 1520 //
1545 // This accepts as a receiver anything JSObject::SetElementsLength accepts 1521 // This accepts as a receiver anything JSObject::SetElementsLength accepts
1546 // (currently anything except for external and pixel arrays which means 1522 // (currently anything except for external arrays which means anything with
1547 // anything with elements of FixedArray type.), but currently is restricted 1523 // elements of FixedArray type.), but currently is restricted to JSArray.
1548 // to JSArray.
1549 // Value must be a number, but only smis are accepted as the most common case. 1524 // Value must be a number, but only smis are accepted as the most common case.
1550 1525
1551 Label miss; 1526 Label miss;
1552 1527
1553 Register receiver = edx; 1528 Register receiver = edx;
1554 Register value = eax; 1529 Register value = eax;
1555 Register scratch = ebx; 1530 Register scratch = ebx;
1556 1531
1557 // Check that the receiver isn't a smi. 1532 // Check that the receiver isn't a smi.
1558 __ test(receiver, Immediate(kSmiTagMask)); 1533 __ test(receiver, Immediate(kSmiTagMask));
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1611 1586
1612 __ bind(&restore_miss); 1587 __ bind(&restore_miss);
1613 __ pop(edx); 1588 __ pop(edx);
1614 1589
1615 __ bind(&miss); 1590 __ bind(&miss);
1616 __ IncrementCounter(&Counters::store_normal_miss, 1); 1591 __ IncrementCounter(&Counters::store_normal_miss, 1);
1617 GenerateMiss(masm); 1592 GenerateMiss(masm);
1618 } 1593 }
1619 1594
1620 1595
1621 void StoreIC::GenerateGlobalProxy(MacroAssembler* masm) { 1596 void StoreIC::GenerateGlobalProxy(MacroAssembler* masm,
1597 StrictModeFlag strict_mode) {
1622 // ----------- S t a t e ------------- 1598 // ----------- S t a t e -------------
1623 // -- eax : value 1599 // -- eax : value
1624 // -- ecx : name 1600 // -- ecx : name
1625 // -- edx : receiver 1601 // -- edx : receiver
1626 // -- esp[0] : return address 1602 // -- esp[0] : return address
1627 // ----------------------------------- 1603 // -----------------------------------
1628 __ pop(ebx); 1604 __ pop(ebx);
1629 __ push(edx); 1605 __ push(edx);
1630 __ push(ecx); 1606 __ push(ecx);
1631 __ push(eax); 1607 __ push(eax);
1632 __ push(ebx); 1608 __ push(Immediate(Smi::FromInt(NONE))); // PropertyAttributes
1609 __ push(Immediate(Smi::FromInt(strict_mode)));
1610 __ push(ebx); // return address
1633 1611
1634 // Do tail-call to runtime routine. 1612 // Do tail-call to runtime routine.
1635 __ TailCallRuntime(Runtime::kSetProperty, 3, 1); 1613 __ TailCallRuntime(Runtime::kSetProperty, 5, 1);
1636 } 1614 }
1637 1615
1638 1616
1639 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) { 1617 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
1618 StrictModeFlag strict_mode) {
1640 // ----------- S t a t e ------------- 1619 // ----------- S t a t e -------------
1641 // -- eax : value 1620 // -- eax : value
1642 // -- ecx : key 1621 // -- ecx : key
1643 // -- edx : receiver 1622 // -- edx : receiver
1644 // -- esp[0] : return address 1623 // -- esp[0] : return address
1645 // ----------------------------------- 1624 // -----------------------------------
1646 1625
1647 __ pop(ebx); 1626 __ pop(ebx);
1648 __ push(edx); 1627 __ push(edx);
1649 __ push(ecx); 1628 __ push(ecx);
1650 __ push(eax); 1629 __ push(eax);
1651 __ push(ebx); 1630 __ push(Immediate(Smi::FromInt(NONE))); // PropertyAttributes
1631 __ push(Immediate(Smi::FromInt(strict_mode))); // Strict mode.
1632 __ push(ebx); // return address
1652 1633
1653 // Do tail-call to runtime routine. 1634 // Do tail-call to runtime routine.
1654 __ TailCallRuntime(Runtime::kSetProperty, 3, 1); 1635 __ TailCallRuntime(Runtime::kSetProperty, 5, 1);
1655 } 1636 }
1656 1637
1657 1638
1658 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { 1639 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
1659 // ----------- S t a t e ------------- 1640 // ----------- S t a t e -------------
1660 // -- eax : value 1641 // -- eax : value
1661 // -- ecx : key 1642 // -- ecx : key
1662 // -- edx : receiver 1643 // -- edx : receiver
1663 // -- esp[0] : return address 1644 // -- esp[0] : return address
1664 // ----------------------------------- 1645 // -----------------------------------
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1771 Condition cc = *jmp_address == Assembler::kJncShortOpcode 1752 Condition cc = *jmp_address == Assembler::kJncShortOpcode
1772 ? not_zero 1753 ? not_zero
1773 : zero; 1754 : zero;
1774 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); 1755 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
1775 } 1756 }
1776 1757
1777 1758
1778 } } // namespace v8::internal 1759 } } // namespace v8::internal
1779 1760
1780 #endif // V8_TARGET_ARCH_IA32 1761 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/full-codegen-ia32.cc ('k') | src/ia32/lithium-codegen-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698