OLD | NEW |
---|---|
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 1757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1768 jsobject.Branch(hs); | 1768 jsobject.Branch(hs); |
1769 | 1769 |
1770 primitive.Bind(); | 1770 primitive.Bind(); |
1771 frame_->EmitPush(r0); | 1771 frame_->EmitPush(r0); |
1772 Result arg_count(r0); | 1772 Result arg_count(r0); |
1773 __ mov(r0, Operand(0)); | 1773 __ mov(r0, Operand(0)); |
1774 frame_->InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS, &arg_count, 1); | 1774 frame_->InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS, &arg_count, 1); |
1775 | 1775 |
1776 jsobject.Bind(); | 1776 jsobject.Bind(); |
1777 // Get the set of properties (as a FixedArray or Map). | 1777 // Get the set of properties (as a FixedArray or Map). |
1778 frame_->EmitPush(r0); // duplicate the object being enumerated | 1778 // r0: value to be iterated over |
1779 frame_->EmitPush(r0); | 1779 frame_->EmitPush(r0); // push the object being iterated over |
Erik Corry
2009/12/03 08:49:32
!punctuatioN
Mads Ager (chromium)
2009/12/03 10:15:31
Done.
| |
1780 | |
1781 // Check cache validity in generated code. This is a fast case for | |
1782 // the JSObject::IsSimpleEnum cache validity checks. If we cannot | |
1783 // guarantee cache validity, call the runtime system to check cache | |
1784 // validity or get the property names in a fixed array. | |
1785 JumpTarget call_runtime; | |
1786 JumpTarget loop(JumpTarget::BIDIRECTIONAL); | |
1787 JumpTarget check_prototype; | |
1788 JumpTarget use_cache; | |
1789 __ mov(r1, Operand(r0)); | |
1790 loop.Bind(); | |
1791 // Check that there are no elements. | |
1792 __ ldr(r2, FieldMemOperand(r1, JSObject::kElementsOffset)); | |
1793 __ cmp(r2, Operand(Factory::empty_fixed_array())); | |
Erik Corry
2009/12/03 08:49:32
This gets code-generated as a pc-relative load fol
Mads Ager (chromium)
2009/12/03 10:15:31
Done.
| |
1794 call_runtime.Branch(ne); | |
1795 // Check that instance descriptors are not empty so that we can | |
1796 // check for an enum cache. Leave the map in r3 for the subsequent | |
1797 // prototype load. | |
1798 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); | |
1799 __ ldr(r2, FieldMemOperand(r3, Map::kInstanceDescriptorsOffset)); | |
1800 __ cmp(r2, Operand(Factory::empty_descriptor_array())); | |
Erik Corry
2009/12/03 08:49:32
And here.
Mads Ager (chromium)
2009/12/03 10:15:31
Done.
| |
1801 call_runtime.Branch(eq); | |
1802 // Check that there in an enum cache in the non-empty instance | |
1803 // descriptors. This is the case if the next enumeration index | |
1804 // field does not contain a smi. | |
1805 __ ldr(r2, FieldMemOperand(r2, DescriptorArray::kEnumerationIndexOffset)); | |
1806 __ tst(r2, Operand(kSmiTagMask)); | |
1807 call_runtime.Branch(eq); | |
1808 // For all objects but the receiver, check that the cache is empty. | |
1809 __ cmp(r1, r0); | |
1810 check_prototype.Branch(eq); | |
1811 __ ldr(r2, FieldMemOperand(r2, DescriptorArray::kEnumCacheBridgeCacheOffset)); | |
1812 __ cmp(r2, Operand(Factory::empty_fixed_array())); | |
Erik Corry
2009/12/03 08:49:32
And here (perhaps you can reuse the register so yo
Mads Ager (chromium)
2009/12/03 10:15:31
Done.
| |
1813 call_runtime.Branch(ne); | |
1814 check_prototype.Bind(); | |
1815 // Load the prototype from the map and loop if non-null. | |
1816 __ ldr(r1, FieldMemOperand(r3, Map::kPrototypeOffset)); | |
1817 __ cmp(r1, Operand(Factory::null_value())); | |
Erik Corry
2009/12/03 08:49:32
And here.
Mads Ager (chromium)
2009/12/03 10:15:31
Done.
| |
1818 loop.Branch(ne); | |
1819 // The enum cache is valid. Load the map of the object being | |
1820 // iterated over and use the cache for the iteration. | |
1821 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); | |
1822 use_cache.Jump(); | |
1823 | |
1824 call_runtime.Bind(); | |
1825 // Call the runtime to get the property names for the object. | |
1826 frame_->EmitPush(r0); // push the object (slot 4) for the runtime call | |
1780 frame_->CallRuntime(Runtime::kGetPropertyNamesFast, 1); | 1827 frame_->CallRuntime(Runtime::kGetPropertyNamesFast, 1); |
1781 | 1828 |
1782 // If we got a Map, we can do a fast modification check. | 1829 // If we got a map from the runtime call, we can do a fast |
1783 // Otherwise, we got a FixedArray, and we have to do a slow check. | 1830 // modification check. Otherwise, we got a fixed array, and we have |
1831 // to do a slow check. | |
1832 // r0: map or fixed array (result from call to | |
1833 // Runtime::kGetPropertyNamesFast) | |
1784 __ mov(r2, Operand(r0)); | 1834 __ mov(r2, Operand(r0)); |
1785 __ ldr(r1, FieldMemOperand(r2, HeapObject::kMapOffset)); | 1835 __ ldr(r1, FieldMemOperand(r2, HeapObject::kMapOffset)); |
1786 __ LoadRoot(ip, Heap::kMetaMapRootIndex); | 1836 __ LoadRoot(ip, Heap::kMetaMapRootIndex); |
1787 __ cmp(r1, ip); | 1837 __ cmp(r1, ip); |
1788 fixed_array.Branch(ne); | 1838 fixed_array.Branch(ne); |
1789 | 1839 |
1840 use_cache.Bind(); | |
1790 // Get enum cache | 1841 // Get enum cache |
1842 // r0: map (either the result from a call to | |
1843 // Runtime::kGetPropertyNamesFast or has been fetched directly from | |
1844 // the object) | |
1791 __ mov(r1, Operand(r0)); | 1845 __ mov(r1, Operand(r0)); |
Erik Corry
2009/12/03 08:49:32
Unnecessary instruction! (not your fault)
| |
1792 __ ldr(r1, FieldMemOperand(r1, Map::kInstanceDescriptorsOffset)); | 1846 __ ldr(r1, FieldMemOperand(r1, Map::kInstanceDescriptorsOffset)); |
1793 __ ldr(r1, FieldMemOperand(r1, DescriptorArray::kEnumerationIndexOffset)); | 1847 __ ldr(r1, FieldMemOperand(r1, DescriptorArray::kEnumerationIndexOffset)); |
1794 __ ldr(r2, | 1848 __ ldr(r2, |
1795 FieldMemOperand(r1, DescriptorArray::kEnumCacheBridgeCacheOffset)); | 1849 FieldMemOperand(r1, DescriptorArray::kEnumCacheBridgeCacheOffset)); |
1796 | 1850 |
1797 frame_->EmitPush(r0); // map | 1851 frame_->EmitPush(r0); // map |
1798 frame_->EmitPush(r2); // enum cache bridge cache | 1852 frame_->EmitPush(r2); // enum cache bridge cache |
1799 __ ldr(r0, FieldMemOperand(r2, FixedArray::kLengthOffset)); | 1853 __ ldr(r0, FieldMemOperand(r2, FixedArray::kLengthOffset)); |
1800 __ mov(r0, Operand(r0, LSL, kSmiTagSize)); | 1854 __ mov(r0, Operand(r0, LSL, kSmiTagSize)); |
1801 frame_->EmitPush(r0); | 1855 frame_->EmitPush(r0); |
(...skipping 4576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6378 __ BranchOnNotSmi(r1, &slow); | 6432 __ BranchOnNotSmi(r1, &slow); |
6379 | 6433 |
6380 // Check if the calling frame is an arguments adaptor frame. | 6434 // Check if the calling frame is an arguments adaptor frame. |
6381 Label adaptor; | 6435 Label adaptor; |
6382 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 6436 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
6383 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); | 6437 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); |
6384 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 6438 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
6385 __ b(eq, &adaptor); | 6439 __ b(eq, &adaptor); |
6386 | 6440 |
6387 // Check index against formal parameters count limit passed in | 6441 // Check index against formal parameters count limit passed in |
6388 // through register eax. Use unsigned comparison to get negative | 6442 // through register r0. Use unsigned comparison to get negative |
6389 // check for free. | 6443 // check for free. |
6390 __ cmp(r1, r0); | 6444 __ cmp(r1, r0); |
6391 __ b(cs, &slow); | 6445 __ b(cs, &slow); |
6392 | 6446 |
6393 // Read the argument from the stack and return it. | 6447 // Read the argument from the stack and return it. |
6394 __ sub(r3, r0, r1); | 6448 __ sub(r3, r0, r1); |
6395 __ add(r3, fp, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize)); | 6449 __ add(r3, fp, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize)); |
6396 __ ldr(r0, MemOperand(r3, kDisplacement)); | 6450 __ ldr(r0, MemOperand(r3, kDisplacement)); |
6397 __ Jump(lr); | 6451 __ Jump(lr); |
6398 | 6452 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6470 int CompareStub::MinorKey() { | 6524 int CompareStub::MinorKey() { |
6471 // Encode the two parameters in a unique 16 bit value. | 6525 // Encode the two parameters in a unique 16 bit value. |
6472 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15)); | 6526 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15)); |
6473 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0); | 6527 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0); |
6474 } | 6528 } |
6475 | 6529 |
6476 | 6530 |
6477 #undef __ | 6531 #undef __ |
6478 | 6532 |
6479 } } // namespace v8::internal | 6533 } } // namespace v8::internal |
OLD | NEW |