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

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

Issue 2114015: Cardmarking writebarrier. (Closed)
Patch Set: Created 10 years, 7 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
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 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 Register key, 156 Register key,
157 Register t0, 157 Register t0,
158 Register t1, 158 Register t1,
159 Register t2) { 159 Register t2) {
160 // Register use: 160 // Register use:
161 // 161 //
162 // elements - holds the slow-case elements of the receiver and is unchanged. 162 // elements - holds the slow-case elements of the receiver and is unchanged.
163 // 163 //
164 // key - holds the smi key on entry and is unchanged if a branch is 164 // key - holds the smi key on entry and is unchanged if a branch is
165 // performed to the miss label. 165 // performed to the miss label.
166 // Holds the result on exit if the load succeeded.
166 // 167 //
167 // Scratch registers: 168 // Scratch registers:
168 // 169 //
169 // t0 - holds the untagged key on entry and holds the hash once computed. 170 // t0 - holds the untagged key on entry and holds the hash once computed.
170 // Holds the result on exit if the load succeeded.
171 // 171 //
172 // t1 - used to hold the capacity mask of the dictionary 172 // t1 - used to hold the capacity mask of the dictionary
173 // 173 //
174 // t2 - used for the index into the dictionary. 174 // t2 - used for the index into the dictionary.
175 Label done; 175 Label done;
176 176
177 // Compute the hash code from the untagged key. This must be kept in sync 177 // Compute the hash code from the untagged key. This must be kept in sync
178 // with ComputeIntegerHash in utils.h. 178 // with ComputeIntegerHash in utils.h.
179 // 179 //
180 // hash = ~hash + (hash << 15); 180 // hash = ~hash + (hash << 15);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 // t2: elements + (index * kPointerSize) 228 // t2: elements + (index * kPointerSize)
229 const int kDetailsOffset = 229 const int kDetailsOffset =
230 NumberDictionary::kElementsStartOffset + 2 * kPointerSize; 230 NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
231 __ ldr(t1, FieldMemOperand(t2, kDetailsOffset)); 231 __ ldr(t1, FieldMemOperand(t2, kDetailsOffset));
232 __ tst(t1, Operand(Smi::FromInt(PropertyDetails::TypeField::mask()))); 232 __ tst(t1, Operand(Smi::FromInt(PropertyDetails::TypeField::mask())));
233 __ b(ne, miss); 233 __ b(ne, miss);
234 234
235 // Get the value at the masked, scaled index and return. 235 // Get the value at the masked, scaled index and return.
236 const int kValueOffset = 236 const int kValueOffset =
237 NumberDictionary::kElementsStartOffset + kPointerSize; 237 NumberDictionary::kElementsStartOffset + kPointerSize;
238 __ ldr(t0, FieldMemOperand(t2, kValueOffset)); 238 __ ldr(key, FieldMemOperand(t2, kValueOffset));
239 } 239 }
240 240
241 241
242 void LoadIC::GenerateArrayLength(MacroAssembler* masm) { 242 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
243 // ----------- S t a t e ------------- 243 // ----------- S t a t e -------------
244 // -- r2 : name 244 // -- r2 : name
245 // -- lr : return address 245 // -- lr : return address
246 // -- r0 : receiver 246 // -- r0 : receiver
247 // -- sp[0] : receiver 247 // -- sp[0] : receiver
248 // ----------------------------------- 248 // -----------------------------------
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 // In the case that the object is a value-wrapper object, 736 // In the case that the object is a value-wrapper object,
737 // we enter the runtime system to make sure that indexing into string 737 // we enter the runtime system to make sure that indexing into string
738 // objects work as intended. 738 // objects work as intended.
739 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); 739 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE);
740 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); 740 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset));
741 __ cmp(r2, Operand(JS_OBJECT_TYPE)); 741 __ cmp(r2, Operand(JS_OBJECT_TYPE));
742 __ b(lt, &slow); 742 __ b(lt, &slow);
743 743
744 // Check that the key is a smi. 744 // Check that the key is a smi.
745 __ BranchOnNotSmi(key, &slow); 745 __ BranchOnNotSmi(key, &slow);
746 // Untag key into r2..
747 __ mov(r2, Operand(key, ASR, kSmiTagSize));
748
749 // Get the elements array of the object. 746 // Get the elements array of the object.
750 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset)); 747 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset));
751 // Check that the object is in fast mode (not dictionary). 748 // Check that the object is in fast mode (not dictionary).
752 __ ldr(r3, FieldMemOperand(r4, HeapObject::kMapOffset)); 749 __ ldr(r3, FieldMemOperand(r4, HeapObject::kMapOffset));
753 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); 750 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
754 __ cmp(r3, ip); 751 __ cmp(r3, ip);
755 __ b(ne, &check_pixel_array); 752 __ b(ne, &check_pixel_array);
756 // Check that the key (index) is within bounds. 753 // Check that the key (index) is within bounds.
757 __ ldr(r3, FieldMemOperand(r4, Array::kLengthOffset)); 754 __ ldr(r3, FieldMemOperand(r4, FixedArray::kLengthOffset));
758 __ cmp(r2, r3); 755 __ cmp(key, Operand(r3));
759 __ b(hs, &slow); 756 __ b(hs, &slow);
760 // Fast case: Do the load. 757 // Fast case: Do the load.
761 __ add(r3, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 758 __ add(r3, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
762 __ ldr(r2, MemOperand(r3, r2, LSL, kPointerSizeLog2)); 759 // The key is a smi.
760 ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
761 __ ldr(r2, MemOperand(r3, key, LSL, kPointerSizeLog2 - kSmiTagSize));
763 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 762 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
764 __ cmp(r2, ip); 763 __ cmp(r2, ip);
765 // In case the loaded value is the_hole we have to consult GetProperty 764 // In case the loaded value is the_hole we have to consult GetProperty
766 // to ensure the prototype chain is searched. 765 // to ensure the prototype chain is searched.
767 __ b(eq, &slow); 766 __ b(eq, &slow);
768 __ mov(r0, r2); 767 __ mov(r0, r2);
769 __ Ret(); 768 __ Ret();
770 769
771 // Check whether the elements is a pixel array. 770 // Check whether the elements is a pixel array.
772 // r0: key 771 // r0: key
773 // r2: untagged index
774 // r3: elements map 772 // r3: elements map
775 // r4: elements 773 // r4: elements
776 __ bind(&check_pixel_array); 774 __ bind(&check_pixel_array);
777 __ LoadRoot(ip, Heap::kPixelArrayMapRootIndex); 775 __ LoadRoot(ip, Heap::kPixelArrayMapRootIndex);
778 __ cmp(r3, ip); 776 __ cmp(r3, ip);
779 __ b(ne, &check_number_dictionary); 777 __ b(ne, &check_number_dictionary);
780 __ ldr(ip, FieldMemOperand(r4, PixelArray::kLengthOffset)); 778 __ ldr(ip, FieldMemOperand(r4, PixelArray::kLengthOffset));
779 __ mov(r2, Operand(key, ASR, kSmiTagSize));
781 __ cmp(r2, ip); 780 __ cmp(r2, ip);
782 __ b(hs, &slow); 781 __ b(hs, &slow);
783 __ ldr(ip, FieldMemOperand(r4, PixelArray::kExternalPointerOffset)); 782 __ ldr(ip, FieldMemOperand(r4, PixelArray::kExternalPointerOffset));
784 __ ldrb(r2, MemOperand(ip, r2)); 783 __ ldrb(r2, MemOperand(ip, r2));
785 __ mov(r0, Operand(r2, LSL, kSmiTagSize)); // Tag result as smi. 784 __ mov(r0, Operand(r2, LSL, kSmiTagSize)); // Tag result as smi.
786 __ Ret(); 785 __ Ret();
787 786
788 __ bind(&check_number_dictionary); 787 __ bind(&check_number_dictionary);
789 // Check whether the elements is a number dictionary. 788 // Check whether the elements is a number dictionary.
790 // r0: key 789 // r0: key
791 // r2: untagged index
792 // r3: elements map 790 // r3: elements map
793 // r4: elements 791 // r4: elements
794 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); 792 __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
795 __ cmp(r3, ip); 793 __ cmp(r3, ip);
796 __ b(ne, &slow); 794 __ b(ne, &slow);
795 __ mov(r2, Operand(r0, ASR, kSmiTagSize));
797 GenerateNumberDictionaryLoad(masm, &slow, r4, r0, r2, r3, r5); 796 GenerateNumberDictionaryLoad(masm, &slow, r4, r0, r2, r3, r5);
798 __ mov(r0, r2);
799 __ Ret(); 797 __ Ret();
800 798
801 // Slow case, key and receiver still in r0 and r1. 799 // Slow case, key and receiver still in r0 and r1.
802 __ bind(&slow); 800 __ bind(&slow);
803 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1, r2, r3); 801 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1, r2, r3);
804 GenerateRuntimeGetProperty(masm); 802 GenerateRuntimeGetProperty(masm);
805 } 803 }
806 804
807 805
808 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { 806 void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
1276 __ cmp(r4, Operand(FIRST_JS_OBJECT_TYPE)); 1274 __ cmp(r4, Operand(FIRST_JS_OBJECT_TYPE));
1277 __ b(lt, &slow); 1275 __ b(lt, &slow);
1278 1276
1279 // Object case: Check key against length in the elements array. 1277 // Object case: Check key against length in the elements array.
1280 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); 1278 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
1281 // Check that the object is in fast mode (not dictionary). 1279 // Check that the object is in fast mode (not dictionary).
1282 __ ldr(r4, FieldMemOperand(elements, HeapObject::kMapOffset)); 1280 __ ldr(r4, FieldMemOperand(elements, HeapObject::kMapOffset));
1283 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); 1281 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
1284 __ cmp(r4, ip); 1282 __ cmp(r4, ip);
1285 __ b(ne, &check_pixel_array); 1283 __ b(ne, &check_pixel_array);
1286 // Untag the key (for checking against untagged length in the fixed array). 1284 // Check array bounds. Both the key and the length of FixedArray are smis.
1287 __ mov(r4, Operand(key, ASR, kSmiTagSize));
1288 // Compute address to store into and check array bounds.
1289 __ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1285 __ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset));
1290 __ cmp(r4, Operand(ip)); 1286 __ cmp(key, Operand(ip));
1291 __ b(lo, &fast); 1287 __ b(lo, &fast);
1292 1288
1293 // Slow case, handle jump to runtime. 1289 // Slow case, handle jump to runtime.
1294 __ bind(&slow); 1290 __ bind(&slow);
1295 // Entry registers are intact. 1291 // Entry registers are intact.
1296 // r0: value. 1292 // r0: value.
1297 // r1: key. 1293 // r1: key.
1298 // r2: receiver. 1294 // r2: receiver.
1299 GenerateRuntimeSetProperty(masm); 1295 GenerateRuntimeSetProperty(masm);
1300 1296
(...skipping 25 matching lines...) Expand all
1326 __ strb(r5, MemOperand(elements, r4)); // Elements is now external array. 1322 __ strb(r5, MemOperand(elements, r4)); // Elements is now external array.
1327 __ Ret(); 1323 __ Ret();
1328 1324
1329 // Extra capacity case: Check if there is extra capacity to 1325 // Extra capacity case: Check if there is extra capacity to
1330 // perform the store and update the length. Used for adding one 1326 // perform the store and update the length. Used for adding one
1331 // element to the array by writing to array[array.length]. 1327 // element to the array by writing to array[array.length].
1332 __ bind(&extra); 1328 __ bind(&extra);
1333 // Condition code from comparing key and array length is still available. 1329 // Condition code from comparing key and array length is still available.
1334 __ b(ne, &slow); // Only support writing to writing to array[array.length]. 1330 __ b(ne, &slow); // Only support writing to writing to array[array.length].
1335 // Check for room in the elements backing store. 1331 // Check for room in the elements backing store.
1336 __ mov(r4, Operand(key, ASR, kSmiTagSize)); // Untag key. 1332 // Both the key and the length of FixedArray are smis.
1337 __ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1333 __ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset));
1338 __ cmp(r4, Operand(ip)); 1334 __ cmp(key, Operand(ip));
1339 __ b(hs, &slow); 1335 __ b(hs, &slow);
1340 // Calculate key + 1 as smi. 1336 // Calculate key + 1 as smi.
1341 ASSERT_EQ(0, kSmiTag); 1337 ASSERT_EQ(0, kSmiTag);
1342 __ add(r4, key, Operand(Smi::FromInt(1))); 1338 __ add(r4, key, Operand(Smi::FromInt(1)));
1343 __ str(r4, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1339 __ str(r4, FieldMemOperand(receiver, JSArray::kLengthOffset));
1344 __ b(&fast); 1340 __ b(&fast);
1345 1341
1346 // Array case: Get the length and the elements array from the JS 1342 // Array case: Get the length and the elements array from the JS
1347 // array. Check that the array is in fast mode; if it is the 1343 // array. Check that the array is in fast mode; if it is the
1348 // length is always a smi. 1344 // length is always a smi.
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
1836 GenerateMiss(masm); 1832 GenerateMiss(masm);
1837 } 1833 }
1838 1834
1839 1835
1840 #undef __ 1836 #undef __
1841 1837
1842 1838
1843 } } // namespace v8::internal 1839 } } // namespace v8::internal
1844 1840
1845 #endif // V8_TARGET_ARCH_ARM 1841 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/codegen-arm.cc ('k') | src/arm/macro-assembler-arm.h » ('j') | src/heap.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698