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

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

Issue 464002: Move for-in cache validity check to generated code. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years 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 | « no previous file | src/ia32/codegen-ia32.cc » ('j') | src/x64/codegen-x64.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | src/ia32/codegen-ia32.cc » ('j') | src/x64/codegen-x64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698