| OLD | NEW |
| 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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 // |done| label if a property with the given name is found leaving the | 101 // |done| label if a property with the given name is found leaving the |
| 102 // index into the dictionary in |r0|. Jump to the |miss| label | 102 // index into the dictionary in |r0|. Jump to the |miss| label |
| 103 // otherwise. | 103 // otherwise. |
| 104 static void GenerateStringDictionaryProbes(MacroAssembler* masm, | 104 static void GenerateStringDictionaryProbes(MacroAssembler* masm, |
| 105 Label* miss, | 105 Label* miss, |
| 106 Label* done, | 106 Label* done, |
| 107 Register elements, | 107 Register elements, |
| 108 Register name, | 108 Register name, |
| 109 Register r0, | 109 Register r0, |
| 110 Register r1) { | 110 Register r1) { |
| 111 // Assert that name contains a string. |
| 112 if (FLAG_debug_code) __ AbortIfNotString(name); |
| 113 |
| 111 // Compute the capacity mask. | 114 // Compute the capacity mask. |
| 112 const int kCapacityOffset = | 115 const int kCapacityOffset = |
| 113 StringDictionary::kHeaderSize + | 116 StringDictionary::kHeaderSize + |
| 114 StringDictionary::kCapacityIndex * kPointerSize; | 117 StringDictionary::kCapacityIndex * kPointerSize; |
| 115 __ mov(r1, FieldOperand(elements, kCapacityOffset)); | 118 __ mov(r1, FieldOperand(elements, kCapacityOffset)); |
| 116 __ shr(r1, kSmiTagSize); // convert smi to int | 119 __ shr(r1, kSmiTagSize); // convert smi to int |
| 117 __ dec(r1); | 120 __ dec(r1); |
| 118 | 121 |
| 119 // Generate an unrolled loop that performs a few probes before | 122 // Generate an unrolled loop that performs a few probes before |
| 120 // giving up. Measurements done on Gmail indicate that 2 probes | 123 // giving up. Measurements done on Gmail indicate that 2 probes |
| (...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 // Perform tail call to the entry. | 754 // Perform tail call to the entry. |
| 752 ExternalReference ref = ExternalReference( | 755 ExternalReference ref = ExternalReference( |
| 753 IC_Utility(kKeyedLoadPropertyWithInterceptor)); | 756 IC_Utility(kKeyedLoadPropertyWithInterceptor)); |
| 754 __ TailCallExternalReference(ref, 2, 1); | 757 __ TailCallExternalReference(ref, 2, 1); |
| 755 | 758 |
| 756 __ bind(&slow); | 759 __ bind(&slow); |
| 757 GenerateMiss(masm); | 760 GenerateMiss(masm); |
| 758 } | 761 } |
| 759 | 762 |
| 760 | 763 |
| 761 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) { | 764 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, |
| 765 StrictModeFlag strict_mode) { |
| 762 // ----------- S t a t e ------------- | 766 // ----------- S t a t e ------------- |
| 763 // -- eax : value | 767 // -- eax : value |
| 764 // -- ecx : key | 768 // -- ecx : key |
| 765 // -- edx : receiver | 769 // -- edx : receiver |
| 766 // -- esp[0] : return address | 770 // -- esp[0] : return address |
| 767 // ----------------------------------- | 771 // ----------------------------------- |
| 768 Label slow, fast, array, extra, check_pixel_array; | 772 Label slow, fast, array, extra, check_pixel_array; |
| 769 | 773 |
| 770 // Check that the object isn't a smi. | 774 // Check that the object isn't a smi. |
| 771 __ test(edx, Immediate(kSmiTagMask)); | 775 __ test(edx, Immediate(kSmiTagMask)); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 791 // edx: JSObject | 795 // edx: JSObject |
| 792 // ecx: key (a smi) | 796 // ecx: key (a smi) |
| 793 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); | 797 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); |
| 794 // Check that the object is in fast mode and writable. | 798 // Check that the object is in fast mode and writable. |
| 795 __ CheckMap(edi, FACTORY->fixed_array_map(), &check_pixel_array, true); | 799 __ CheckMap(edi, FACTORY->fixed_array_map(), &check_pixel_array, true); |
| 796 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); | 800 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); |
| 797 __ j(below, &fast, taken); | 801 __ j(below, &fast, taken); |
| 798 | 802 |
| 799 // Slow case: call runtime. | 803 // Slow case: call runtime. |
| 800 __ bind(&slow); | 804 __ bind(&slow); |
| 801 GenerateRuntimeSetProperty(masm); | 805 GenerateRuntimeSetProperty(masm, strict_mode); |
| 802 | 806 |
| 803 // Check whether the elements is a pixel array. | 807 // Check whether the elements is a pixel array. |
| 804 __ bind(&check_pixel_array); | 808 __ bind(&check_pixel_array); |
| 805 // eax: value | 809 // eax: value |
| 806 // ecx: key (a smi) | 810 // ecx: key (a smi) |
| 807 // edx: receiver | 811 // edx: receiver |
| 808 // edi: elements array | 812 // edi: elements array |
| 809 __ CheckMap(edi, FACTORY->pixel_array_map(), &slow, true); | 813 GenerateFastPixelArrayStore(masm, |
| 810 // Check that the value is a smi. If a conversion is needed call into the | 814 edx, |
| 811 // runtime to convert and clamp. | 815 ecx, |
| 812 __ test(eax, Immediate(kSmiTagMask)); | 816 eax, |
| 813 __ j(not_zero, &slow); | 817 edi, |
| 814 __ mov(ebx, ecx); | 818 ebx, |
| 815 __ SmiUntag(ebx); | 819 false, |
| 816 __ cmp(ebx, FieldOperand(edi, PixelArray::kLengthOffset)); | 820 NULL, |
| 817 __ j(above_equal, &slow); | 821 &slow, |
| 818 __ mov(ecx, eax); // Save the value. Key is not longer needed. | 822 &slow, |
| 819 __ SmiUntag(ecx); | 823 &slow); |
| 820 { // Clamp the value to [0..255]. | |
| 821 Label done; | |
| 822 __ test(ecx, Immediate(0xFFFFFF00)); | |
| 823 __ j(zero, &done); | |
| 824 __ setcc(negative, ecx); // 1 if negative, 0 if positive. | |
| 825 __ dec_b(ecx); // 0 if negative, 255 if positive. | |
| 826 __ bind(&done); | |
| 827 } | |
| 828 __ mov(edi, FieldOperand(edi, PixelArray::kExternalPointerOffset)); | |
| 829 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); | |
| 830 __ ret(0); // Return value in eax. | |
| 831 | 824 |
| 832 // Extra capacity case: Check if there is extra capacity to | 825 // Extra capacity case: Check if there is extra capacity to |
| 833 // perform the store and update the length. Used for adding one | 826 // perform the store and update the length. Used for adding one |
| 834 // element to the array by writing to array[array.length]. | 827 // element to the array by writing to array[array.length]. |
| 835 __ bind(&extra); | 828 __ bind(&extra); |
| 836 // eax: value | 829 // eax: value |
| 837 // edx: receiver, a JSArray | 830 // edx: receiver, a JSArray |
| 838 // ecx: key, a smi. | 831 // ecx: key, a smi. |
| 839 // edi: receiver->elements, a FixedArray | 832 // edi: receiver->elements, a FixedArray |
| 840 // flags: compare (ecx, edx.length()) | 833 // flags: compare (ecx, edx.length()) |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1203 | 1196 |
| 1204 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { | 1197 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { |
| 1205 // ----------- S t a t e ------------- | 1198 // ----------- S t a t e ------------- |
| 1206 // -- ecx : name | 1199 // -- ecx : name |
| 1207 // -- esp[0] : return address | 1200 // -- esp[0] : return address |
| 1208 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1201 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 1209 // -- ... | 1202 // -- ... |
| 1210 // -- esp[(argc + 1) * 4] : receiver | 1203 // -- esp[(argc + 1) * 4] : receiver |
| 1211 // ----------------------------------- | 1204 // ----------------------------------- |
| 1212 | 1205 |
| 1206 // Check if the name is a string. |
| 1207 Label miss; |
| 1208 __ test(ecx, Immediate(kSmiTagMask)); |
| 1209 __ j(zero, &miss); |
| 1210 Condition cond = masm->IsObjectStringType(ecx, eax, eax); |
| 1211 __ j(NegateCondition(cond), &miss); |
| 1213 GenerateCallNormal(masm, argc); | 1212 GenerateCallNormal(masm, argc); |
| 1213 __ bind(&miss); |
| 1214 GenerateMiss(masm, argc); | 1214 GenerateMiss(masm, argc); |
| 1215 } | 1215 } |
| 1216 | 1216 |
| 1217 | 1217 |
| 1218 void KeyedCallIC::GenerateMiss(MacroAssembler* masm, int argc) { | 1218 void KeyedCallIC::GenerateMiss(MacroAssembler* masm, int argc) { |
| 1219 // ----------- S t a t e ------------- | 1219 // ----------- S t a t e ------------- |
| 1220 // -- ecx : name | 1220 // -- ecx : name |
| 1221 // -- esp[0] : return address | 1221 // -- esp[0] : return address |
| 1222 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1222 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 1223 // -- ... | 1223 // -- ... |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1484 __ pop(ebx); | 1484 __ pop(ebx); |
| 1485 __ push(edx); // receiver | 1485 __ push(edx); // receiver |
| 1486 __ push(eax); // name | 1486 __ push(eax); // name |
| 1487 __ push(ebx); // return address | 1487 __ push(ebx); // return address |
| 1488 | 1488 |
| 1489 // Perform tail call to the entry. | 1489 // Perform tail call to the entry. |
| 1490 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); | 1490 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); |
| 1491 } | 1491 } |
| 1492 | 1492 |
| 1493 | 1493 |
| 1494 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { | 1494 void StoreIC::GenerateMegamorphic(MacroAssembler* masm, |
| 1495 StrictModeFlag strict_mode) { |
| 1495 // ----------- S t a t e ------------- | 1496 // ----------- S t a t e ------------- |
| 1496 // -- eax : value | 1497 // -- eax : value |
| 1497 // -- ecx : name | 1498 // -- ecx : name |
| 1498 // -- edx : receiver | 1499 // -- edx : receiver |
| 1499 // -- esp[0] : return address | 1500 // -- esp[0] : return address |
| 1500 // ----------------------------------- | 1501 // ----------------------------------- |
| 1501 | 1502 |
| 1502 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, | 1503 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, |
| 1503 NOT_IN_LOOP, | 1504 NOT_IN_LOOP, |
| 1504 MONOMORPHIC); | 1505 MONOMORPHIC, |
| 1506 strict_mode); |
| 1505 Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, | 1507 Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, |
| 1506 no_reg); | 1508 no_reg); |
| 1507 | 1509 |
| 1508 // Cache miss: Jump to runtime. | 1510 // Cache miss: Jump to runtime. |
| 1509 GenerateMiss(masm); | 1511 GenerateMiss(masm); |
| 1510 } | 1512 } |
| 1511 | 1513 |
| 1512 | 1514 |
| 1513 void StoreIC::GenerateMiss(MacroAssembler* masm) { | 1515 void StoreIC::GenerateMiss(MacroAssembler* masm) { |
| 1514 // ----------- S t a t e ------------- | 1516 // ----------- S t a t e ------------- |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1613 | 1615 |
| 1614 __ bind(&restore_miss); | 1616 __ bind(&restore_miss); |
| 1615 __ pop(edx); | 1617 __ pop(edx); |
| 1616 | 1618 |
| 1617 __ bind(&miss); | 1619 __ bind(&miss); |
| 1618 __ IncrementCounter(COUNTERS->store_normal_miss(), 1); | 1620 __ IncrementCounter(COUNTERS->store_normal_miss(), 1); |
| 1619 GenerateMiss(masm); | 1621 GenerateMiss(masm); |
| 1620 } | 1622 } |
| 1621 | 1623 |
| 1622 | 1624 |
| 1623 void StoreIC::GenerateGlobalProxy(MacroAssembler* masm) { | 1625 void StoreIC::GenerateGlobalProxy(MacroAssembler* masm, |
| 1626 StrictModeFlag strict_mode) { |
| 1624 // ----------- S t a t e ------------- | 1627 // ----------- S t a t e ------------- |
| 1625 // -- eax : value | 1628 // -- eax : value |
| 1626 // -- ecx : name | 1629 // -- ecx : name |
| 1627 // -- edx : receiver | 1630 // -- edx : receiver |
| 1628 // -- esp[0] : return address | 1631 // -- esp[0] : return address |
| 1629 // ----------------------------------- | 1632 // ----------------------------------- |
| 1630 __ pop(ebx); | 1633 __ pop(ebx); |
| 1631 __ push(edx); | 1634 __ push(edx); |
| 1632 __ push(ecx); | 1635 __ push(ecx); |
| 1633 __ push(eax); | 1636 __ push(eax); |
| 1634 __ push(ebx); | 1637 __ push(Immediate(Smi::FromInt(NONE))); // PropertyAttributes |
| 1638 __ push(Immediate(Smi::FromInt(strict_mode))); |
| 1639 __ push(ebx); // return address |
| 1635 | 1640 |
| 1636 // Do tail-call to runtime routine. | 1641 // Do tail-call to runtime routine. |
| 1637 __ TailCallRuntime(Runtime::kSetProperty, 3, 1); | 1642 __ TailCallRuntime(Runtime::kSetProperty, 5, 1); |
| 1638 } | 1643 } |
| 1639 | 1644 |
| 1640 | 1645 |
| 1641 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) { | 1646 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm, |
| 1647 StrictModeFlag strict_mode) { |
| 1642 // ----------- S t a t e ------------- | 1648 // ----------- S t a t e ------------- |
| 1643 // -- eax : value | 1649 // -- eax : value |
| 1644 // -- ecx : key | 1650 // -- ecx : key |
| 1645 // -- edx : receiver | 1651 // -- edx : receiver |
| 1646 // -- esp[0] : return address | 1652 // -- esp[0] : return address |
| 1647 // ----------------------------------- | 1653 // ----------------------------------- |
| 1648 | 1654 |
| 1649 __ pop(ebx); | 1655 __ pop(ebx); |
| 1650 __ push(edx); | 1656 __ push(edx); |
| 1651 __ push(ecx); | 1657 __ push(ecx); |
| 1652 __ push(eax); | 1658 __ push(eax); |
| 1653 __ push(ebx); | 1659 __ push(Immediate(Smi::FromInt(NONE))); // PropertyAttributes |
| 1660 __ push(Immediate(Smi::FromInt(strict_mode))); // Strict mode. |
| 1661 __ push(ebx); // return address |
| 1654 | 1662 |
| 1655 // Do tail-call to runtime routine. | 1663 // Do tail-call to runtime routine. |
| 1656 __ TailCallRuntime(Runtime::kSetProperty, 3, 1); | 1664 __ TailCallRuntime(Runtime::kSetProperty, 5, 1); |
| 1657 } | 1665 } |
| 1658 | 1666 |
| 1659 | 1667 |
| 1660 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { | 1668 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { |
| 1661 // ----------- S t a t e ------------- | 1669 // ----------- S t a t e ------------- |
| 1662 // -- eax : value | 1670 // -- eax : value |
| 1663 // -- ecx : key | 1671 // -- ecx : key |
| 1664 // -- edx : receiver | 1672 // -- edx : receiver |
| 1665 // -- esp[0] : return address | 1673 // -- esp[0] : return address |
| 1666 // ----------------------------------- | 1674 // ----------------------------------- |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1773 Condition cc = *jmp_address == Assembler::kJncShortOpcode | 1781 Condition cc = *jmp_address == Assembler::kJncShortOpcode |
| 1774 ? not_zero | 1782 ? not_zero |
| 1775 : zero; | 1783 : zero; |
| 1776 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1784 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
| 1777 } | 1785 } |
| 1778 | 1786 |
| 1779 | 1787 |
| 1780 } } // namespace v8::internal | 1788 } } // namespace v8::internal |
| 1781 | 1789 |
| 1782 #endif // V8_TARGET_ARCH_IA32 | 1790 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |