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

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

Issue 6614010: [Isolates] Merge 6700:7030 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
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/arm/full-codegen-arm.cc ('k') | src/arm/lithium-arm.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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 // Probe the string dictionary in the |elements| register. Jump to the 108 // Probe the string dictionary in the |elements| register. Jump to the
109 // |done| label if a property with the given name is found. Jump to 109 // |done| label if a property with the given name is found. Jump to
110 // the |miss| label otherwise. 110 // the |miss| label otherwise.
111 static void GenerateStringDictionaryProbes(MacroAssembler* masm, 111 static void GenerateStringDictionaryProbes(MacroAssembler* masm,
112 Label* miss, 112 Label* miss,
113 Label* done, 113 Label* done,
114 Register elements, 114 Register elements,
115 Register name, 115 Register name,
116 Register scratch1, 116 Register scratch1,
117 Register scratch2) { 117 Register scratch2) {
118 // Assert that name contains a string.
119 if (FLAG_debug_code) __ AbortIfNotString(name);
120
118 // Compute the capacity mask. 121 // Compute the capacity mask.
119 const int kCapacityOffset = StringDictionary::kHeaderSize + 122 const int kCapacityOffset = StringDictionary::kHeaderSize +
120 StringDictionary::kCapacityIndex * kPointerSize; 123 StringDictionary::kCapacityIndex * kPointerSize;
121 __ ldr(scratch1, FieldMemOperand(elements, kCapacityOffset)); 124 __ ldr(scratch1, FieldMemOperand(elements, kCapacityOffset));
122 __ mov(scratch1, Operand(scratch1, ASR, kSmiTagSize)); // convert smi to int 125 __ mov(scratch1, Operand(scratch1, ASR, kSmiTagSize)); // convert smi to int
123 __ sub(scratch1, scratch1, Operand(1)); 126 __ sub(scratch1, scratch1, Operand(1));
124 127
125 const int kElementsStartOffset = StringDictionary::kHeaderSize + 128 const int kElementsStartOffset = StringDictionary::kHeaderSize +
126 StringDictionary::kElementsStartIndex * kPointerSize; 129 StringDictionary::kElementsStartIndex * kPointerSize;
127 130
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 __ jmp(&index_smi); 841 __ jmp(&index_smi);
839 } 842 }
840 843
841 844
842 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { 845 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) {
843 // ----------- S t a t e ------------- 846 // ----------- S t a t e -------------
844 // -- r2 : name 847 // -- r2 : name
845 // -- lr : return address 848 // -- lr : return address
846 // ----------------------------------- 849 // -----------------------------------
847 850
851 // Check if the name is a string.
852 Label miss;
853 __ tst(r2, Operand(kSmiTagMask));
854 __ b(eq, &miss);
855 __ IsObjectJSStringType(r2, r0, &miss);
856
848 GenerateCallNormal(masm, argc); 857 GenerateCallNormal(masm, argc);
858 __ bind(&miss);
849 GenerateMiss(masm, argc); 859 GenerateMiss(masm, argc);
850 } 860 }
851 861
852 862
853 // Defined in ic.cc. 863 // Defined in ic.cc.
854 Object* LoadIC_Miss(Arguments args); 864 Object* LoadIC_Miss(Arguments args);
855 865
856 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { 866 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
857 // ----------- S t a t e ------------- 867 // ----------- S t a t e -------------
858 // -- r2 : name 868 // -- r2 : name
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after
1386 // ----------------------------------- 1396 // -----------------------------------
1387 1397
1388 // Push receiver, key and value for runtime call. 1398 // Push receiver, key and value for runtime call.
1389 __ Push(r2, r1, r0); 1399 __ Push(r2, r1, r0);
1390 1400
1391 ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss)); 1401 ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss));
1392 __ TailCallExternalReference(ref, 3, 1); 1402 __ TailCallExternalReference(ref, 3, 1);
1393 } 1403 }
1394 1404
1395 1405
1396 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) { 1406 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
1407 StrictModeFlag strict_mode) {
1397 // ---------- S t a t e -------------- 1408 // ---------- S t a t e --------------
1398 // -- r0 : value 1409 // -- r0 : value
1399 // -- r1 : key 1410 // -- r1 : key
1400 // -- r2 : receiver 1411 // -- r2 : receiver
1401 // -- lr : return address 1412 // -- lr : return address
1402 // ----------------------------------- 1413 // -----------------------------------
1403 1414
1404 // Push receiver, key and value for runtime call. 1415 // Push receiver, key and value for runtime call.
1405 __ Push(r2, r1, r0); 1416 __ Push(r2, r1, r0);
1406 1417
1407 __ TailCallRuntime(Runtime::kSetProperty, 3, 1); 1418 __ mov(r1, Operand(Smi::FromInt(NONE))); // PropertyAttributes
1419 __ mov(r0, Operand(Smi::FromInt(strict_mode))); // Strict mode.
1420 __ Push(r1, r0);
1421
1422 __ TailCallRuntime(Runtime::kSetProperty, 5, 1);
1408 } 1423 }
1409 1424
1410 1425
1411 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) { 1426 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
1427 StrictModeFlag strict_mode) {
1412 // ---------- S t a t e -------------- 1428 // ---------- S t a t e --------------
1413 // -- r0 : value 1429 // -- r0 : value
1414 // -- r1 : key 1430 // -- r1 : key
1415 // -- r2 : receiver 1431 // -- r2 : receiver
1416 // -- lr : return address 1432 // -- lr : return address
1417 // ----------------------------------- 1433 // -----------------------------------
1418 Label slow, fast, array, extra, check_pixel_array; 1434 Label slow, fast, array, extra, check_pixel_array;
1419 1435
1420 // Register usage. 1436 // Register usage.
1421 Register value = r0; 1437 Register value = r0;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1456 __ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1472 __ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset));
1457 __ cmp(key, Operand(ip)); 1473 __ cmp(key, Operand(ip));
1458 __ b(lo, &fast); 1474 __ b(lo, &fast);
1459 1475
1460 // Slow case, handle jump to runtime. 1476 // Slow case, handle jump to runtime.
1461 __ bind(&slow); 1477 __ bind(&slow);
1462 // Entry registers are intact. 1478 // Entry registers are intact.
1463 // r0: value. 1479 // r0: value.
1464 // r1: key. 1480 // r1: key.
1465 // r2: receiver. 1481 // r2: receiver.
1466 GenerateRuntimeSetProperty(masm); 1482 GenerateRuntimeSetProperty(masm, strict_mode);
1467 1483
1468 // Check whether the elements is a pixel array. 1484 // Check whether the elements is a pixel array.
1469 // r4: elements map. 1485 // r4: elements map.
1470 __ bind(&check_pixel_array); 1486 __ bind(&check_pixel_array);
1471 __ LoadRoot(ip, Heap::kPixelArrayMapRootIndex); 1487 GenerateFastPixelArrayStore(masm,
1472 __ cmp(r4, ip); 1488 r2,
1473 __ b(ne, &slow); 1489 r1,
1474 // Check that the value is a smi. If a conversion is needed call into the 1490 r0,
1475 // runtime to convert and clamp. 1491 elements,
1476 __ JumpIfNotSmi(value, &slow); 1492 r4,
1477 __ mov(r4, Operand(key, ASR, kSmiTagSize)); // Untag the key. 1493 r5,
1478 __ ldr(ip, FieldMemOperand(elements, PixelArray::kLengthOffset)); 1494 r6,
1479 __ cmp(r4, Operand(ip)); 1495 false,
1480 __ b(hs, &slow); 1496 false,
1481 __ mov(r5, Operand(value, ASR, kSmiTagSize)); // Untag the value. 1497 NULL,
1482 __ Usat(r5, 8, Operand(r5)); // Clamp the value to [0..255]. 1498 &slow,
1483 1499 &slow,
1484 // Get the pointer to the external array. This clobbers elements. 1500 &slow);
1485 __ ldr(elements,
1486 FieldMemOperand(elements, PixelArray::kExternalPointerOffset));
1487 __ strb(r5, MemOperand(elements, r4)); // Elements is now external array.
1488 __ Ret();
1489 1501
1490 // Extra capacity case: Check if there is extra capacity to 1502 // Extra capacity case: Check if there is extra capacity to
1491 // perform the store and update the length. Used for adding one 1503 // perform the store and update the length. Used for adding one
1492 // element to the array by writing to array[array.length]. 1504 // element to the array by writing to array[array.length].
1493 __ bind(&extra); 1505 __ bind(&extra);
1494 // Condition code from comparing key and array length is still available. 1506 // Condition code from comparing key and array length is still available.
1495 __ b(ne, &slow); // Only support writing to writing to array[array.length]. 1507 __ b(ne, &slow); // Only support writing to writing to array[array.length].
1496 // Check for room in the elements backing store. 1508 // Check for room in the elements backing store.
1497 // Both the key and the length of FixedArray are smis. 1509 // Both the key and the length of FixedArray are smis.
1498 __ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1510 __ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset));
(...skipping 30 matching lines...) Expand all
1529 __ tst(value, Operand(kSmiTagMask)); 1541 __ tst(value, Operand(kSmiTagMask));
1530 __ Ret(eq); 1542 __ Ret(eq);
1531 // Update write barrier for the elements array address. 1543 // Update write barrier for the elements array address.
1532 __ sub(r4, r5, Operand(elements)); 1544 __ sub(r4, r5, Operand(elements));
1533 __ RecordWrite(elements, Operand(r4), r5, r6); 1545 __ RecordWrite(elements, Operand(r4), r5, r6);
1534 1546
1535 __ Ret(); 1547 __ Ret();
1536 } 1548 }
1537 1549
1538 1550
1539 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { 1551 void StoreIC::GenerateMegamorphic(MacroAssembler* masm,
1552 StrictModeFlag strict_mode) {
1540 // ----------- S t a t e ------------- 1553 // ----------- S t a t e -------------
1541 // -- r0 : value 1554 // -- r0 : value
1542 // -- r1 : receiver 1555 // -- r1 : receiver
1543 // -- r2 : name 1556 // -- r2 : name
1544 // -- lr : return address 1557 // -- lr : return address
1545 // ----------------------------------- 1558 // -----------------------------------
1546 1559
1547 // Get the receiver from the stack and probe the stub cache. 1560 // Get the receiver from the stack and probe the stub cache.
1548 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, 1561 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
1549 NOT_IN_LOOP, 1562 NOT_IN_LOOP,
1550 MONOMORPHIC); 1563 MONOMORPHIC,
1564 strict_mode);
1551 1565
1552 Isolate::Current()->stub_cache()->GenerateProbe( 1566 Isolate::Current()->stub_cache()->GenerateProbe(
1553 masm, flags, r1, r2, r3, r4, r5); 1567 masm, flags, r1, r2, r3, r4, r5);
1554 1568
1555 // Cache miss: Jump to runtime. 1569 // Cache miss: Jump to runtime.
1556 GenerateMiss(masm); 1570 GenerateMiss(masm);
1557 } 1571 }
1558 1572
1559 1573
1560 void StoreIC::GenerateMiss(MacroAssembler* masm) { 1574 void StoreIC::GenerateMiss(MacroAssembler* masm) {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1636 GenerateDictionaryStore(masm, &miss, r3, r2, r0, r4, r5); 1650 GenerateDictionaryStore(masm, &miss, r3, r2, r0, r4, r5);
1637 __ IncrementCounter(COUNTERS->store_normal_hit(), 1, r4, r5); 1651 __ IncrementCounter(COUNTERS->store_normal_hit(), 1, r4, r5);
1638 __ Ret(); 1652 __ Ret();
1639 1653
1640 __ bind(&miss); 1654 __ bind(&miss);
1641 __ IncrementCounter(COUNTERS->store_normal_miss(), 1, r4, r5); 1655 __ IncrementCounter(COUNTERS->store_normal_miss(), 1, r4, r5);
1642 GenerateMiss(masm); 1656 GenerateMiss(masm);
1643 } 1657 }
1644 1658
1645 1659
1646 void StoreIC::GenerateGlobalProxy(MacroAssembler* masm) { 1660 void StoreIC::GenerateGlobalProxy(MacroAssembler* masm,
1661 StrictModeFlag strict_mode) {
1647 // ----------- S t a t e ------------- 1662 // ----------- S t a t e -------------
1648 // -- r0 : value 1663 // -- r0 : value
1649 // -- r1 : receiver 1664 // -- r1 : receiver
1650 // -- r2 : name 1665 // -- r2 : name
1651 // -- lr : return address 1666 // -- lr : return address
1652 // ----------------------------------- 1667 // -----------------------------------
1653 1668
1654 __ Push(r1, r2, r0); 1669 __ Push(r1, r2, r0);
1655 1670
1671 __ mov(r1, Operand(Smi::FromInt(NONE))); // PropertyAttributes
1672 __ mov(r0, Operand(Smi::FromInt(strict_mode)));
1673 __ Push(r1, r0);
1674
1656 // Do tail-call to runtime routine. 1675 // Do tail-call to runtime routine.
1657 __ TailCallRuntime(Runtime::kSetProperty, 3, 1); 1676 __ TailCallRuntime(Runtime::kSetProperty, 5, 1);
1658 } 1677 }
1659 1678
1660 1679
1661 #undef __ 1680 #undef __
1662 1681
1663 1682
1664 Condition CompareIC::ComputeCondition(Token::Value op) { 1683 Condition CompareIC::ComputeCondition(Token::Value op) {
1665 switch (op) { 1684 switch (op) {
1666 case Token::EQ_STRICT: 1685 case Token::EQ_STRICT:
1667 case Token::EQ: 1686 case Token::EQ:
(...skipping 30 matching lines...) Expand all
1698 set_target(*rewritten); 1717 set_target(*rewritten);
1699 1718
1700 #ifdef DEBUG 1719 #ifdef DEBUG
1701 if (FLAG_trace_ic) { 1720 if (FLAG_trace_ic) {
1702 PrintF("[CompareIC (%s->%s)#%s]\n", 1721 PrintF("[CompareIC (%s->%s)#%s]\n",
1703 GetStateName(previous_state), 1722 GetStateName(previous_state),
1704 GetStateName(state), 1723 GetStateName(state),
1705 Token::Name(op_)); 1724 Token::Name(op_));
1706 } 1725 }
1707 #endif 1726 #endif
1727
1728 // Activate inlined smi code.
1729 if (previous_state == UNINITIALIZED) {
1730 PatchInlinedSmiCode(address());
1731 }
1708 } 1732 }
1709 1733
1710 1734
1711 void PatchInlinedSmiCode(Address address) { 1735 void PatchInlinedSmiCode(Address address) {
1712 // Currently there is no smi inlining in the ARM full code generator. 1736 Address cmp_instruction_address =
1737 address + Assembler::kCallTargetAddressOffset;
1738
1739 // If the instruction following the call is not a cmp rx, #yyy, nothing
1740 // was inlined.
1741 Instr instr = Assembler::instr_at(cmp_instruction_address);
1742 if (!Assembler::IsCmpImmediate(instr)) {
1743 return;
1744 }
1745
1746 // The delta to the start of the map check instruction and the
1747 // condition code uses at the patched jump.
1748 int delta = Assembler::GetCmpImmediateRawImmediate(instr);
1749 delta +=
1750 Assembler::GetCmpImmediateRegister(instr).code() * kOff12Mask;
1751 // If the delta is 0 the instruction is cmp r0, #0 which also signals that
1752 // nothing was inlined.
1753 if (delta == 0) {
1754 return;
1755 }
1756
1757 #ifdef DEBUG
1758 if (FLAG_trace_ic) {
1759 PrintF("[ patching ic at %p, cmp=%p, delta=%d\n",
1760 address, cmp_instruction_address, delta);
1761 }
1762 #endif
1763
1764 Address patch_address =
1765 cmp_instruction_address - delta * Instruction::kInstrSize;
1766 Instr instr_at_patch = Assembler::instr_at(patch_address);
1767 Instr branch_instr =
1768 Assembler::instr_at(patch_address + Instruction::kInstrSize);
1769 ASSERT(Assembler::IsCmpRegister(instr_at_patch));
1770 ASSERT_EQ(Assembler::GetRn(instr_at_patch).code(),
1771 Assembler::GetRm(instr_at_patch).code());
1772 ASSERT(Assembler::IsBranch(branch_instr));
1773 if (Assembler::GetCondition(branch_instr) == eq) {
1774 // This is patching a "jump if not smi" site to be active.
1775 // Changing
1776 // cmp rx, rx
1777 // b eq, <target>
1778 // to
1779 // tst rx, #kSmiTagMask
1780 // b ne, <target>
1781 CodePatcher patcher(patch_address, 2);
1782 Register reg = Assembler::GetRn(instr_at_patch);
1783 patcher.masm()->tst(reg, Operand(kSmiTagMask));
1784 patcher.EmitCondition(ne);
1785 } else {
1786 ASSERT(Assembler::GetCondition(branch_instr) == ne);
1787 // This is patching a "jump if smi" site to be active.
1788 // Changing
1789 // cmp rx, rx
1790 // b ne, <target>
1791 // to
1792 // tst rx, #kSmiTagMask
1793 // b eq, <target>
1794 CodePatcher patcher(patch_address, 2);
1795 Register reg = Assembler::GetRn(instr_at_patch);
1796 patcher.masm()->tst(reg, Operand(kSmiTagMask));
1797 patcher.EmitCondition(eq);
1798 }
1713 } 1799 }
1714 1800
1715 1801
1716 } } // namespace v8::internal 1802 } } // namespace v8::internal
1717 1803
1718 #endif // V8_TARGET_ARCH_ARM 1804 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/full-codegen-arm.cc ('k') | src/arm/lithium-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698