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

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

Issue 2101002: Cardmarking writebarrier. (Closed)
Patch Set: fixed review comments 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
« no previous file with comments | « src/arm/codegen-arm.cc ('k') | src/arm/macro-assembler-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 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 Register key, 154 Register key,
155 Register t0, 155 Register t0,
156 Register t1, 156 Register t1,
157 Register t2) { 157 Register t2) {
158 // Register use: 158 // Register use:
159 // 159 //
160 // elements - holds the slow-case elements of the receiver and is unchanged. 160 // elements - holds the slow-case elements of the receiver and is unchanged.
161 // 161 //
162 // key - holds the smi key on entry and is unchanged if a branch is 162 // key - holds the smi key on entry and is unchanged if a branch is
163 // performed to the miss label. 163 // performed to the miss label.
164 // Holds the result on exit if the load succeeded.
164 // 165 //
165 // Scratch registers: 166 // Scratch registers:
166 // 167 //
167 // t0 - holds the untagged key on entry and holds the hash once computed. 168 // t0 - holds the untagged key on entry and holds the hash once computed.
168 // Holds the result on exit if the load succeeded.
169 // 169 //
170 // t1 - used to hold the capacity mask of the dictionary 170 // t1 - used to hold the capacity mask of the dictionary
171 // 171 //
172 // t2 - used for the index into the dictionary. 172 // t2 - used for the index into the dictionary.
173 Label done; 173 Label done;
174 174
175 // Compute the hash code from the untagged key. This must be kept in sync 175 // Compute the hash code from the untagged key. This must be kept in sync
176 // with ComputeIntegerHash in utils.h. 176 // with ComputeIntegerHash in utils.h.
177 // 177 //
178 // hash = ~hash + (hash << 15); 178 // hash = ~hash + (hash << 15);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 // t2: elements + (index * kPointerSize) 226 // t2: elements + (index * kPointerSize)
227 const int kDetailsOffset = 227 const int kDetailsOffset =
228 NumberDictionary::kElementsStartOffset + 2 * kPointerSize; 228 NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
229 __ ldr(t1, FieldMemOperand(t2, kDetailsOffset)); 229 __ ldr(t1, FieldMemOperand(t2, kDetailsOffset));
230 __ tst(t1, Operand(Smi::FromInt(PropertyDetails::TypeField::mask()))); 230 __ tst(t1, Operand(Smi::FromInt(PropertyDetails::TypeField::mask())));
231 __ b(ne, miss); 231 __ b(ne, miss);
232 232
233 // Get the value at the masked, scaled index and return. 233 // Get the value at the masked, scaled index and return.
234 const int kValueOffset = 234 const int kValueOffset =
235 NumberDictionary::kElementsStartOffset + kPointerSize; 235 NumberDictionary::kElementsStartOffset + kPointerSize;
236 __ ldr(t0, FieldMemOperand(t2, kValueOffset)); 236 __ ldr(key, FieldMemOperand(t2, kValueOffset));
237 } 237 }
238 238
239 239
240 void LoadIC::GenerateArrayLength(MacroAssembler* masm) { 240 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
241 // ----------- S t a t e ------------- 241 // ----------- S t a t e -------------
242 // -- r2 : name 242 // -- r2 : name
243 // -- lr : return address 243 // -- lr : return address
244 // -- r0 : receiver 244 // -- r0 : receiver
245 // -- sp[0] : receiver 245 // -- sp[0] : receiver
246 // ----------------------------------- 246 // -----------------------------------
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after
732 // In the case that the object is a value-wrapper object, 732 // In the case that the object is a value-wrapper object,
733 // we enter the runtime system to make sure that indexing into string 733 // we enter the runtime system to make sure that indexing into string
734 // objects work as intended. 734 // objects work as intended.
735 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); 735 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE);
736 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); 736 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset));
737 __ cmp(r2, Operand(JS_OBJECT_TYPE)); 737 __ cmp(r2, Operand(JS_OBJECT_TYPE));
738 __ b(lt, &slow); 738 __ b(lt, &slow);
739 739
740 // Check that the key is a smi. 740 // Check that the key is a smi.
741 __ BranchOnNotSmi(key, &slow); 741 __ BranchOnNotSmi(key, &slow);
742 // Untag key into r2..
743 __ mov(r2, Operand(key, ASR, kSmiTagSize));
744
745 // Get the elements array of the object. 742 // Get the elements array of the object.
746 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset)); 743 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset));
747 // Check that the object is in fast mode (not dictionary). 744 // Check that the object is in fast mode (not dictionary).
748 __ ldr(r3, FieldMemOperand(r4, HeapObject::kMapOffset)); 745 __ ldr(r3, FieldMemOperand(r4, HeapObject::kMapOffset));
749 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); 746 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
750 __ cmp(r3, ip); 747 __ cmp(r3, ip);
751 __ b(ne, &check_pixel_array); 748 __ b(ne, &check_pixel_array);
752 // Check that the key (index) is within bounds. 749 // Check that the key (index) is within bounds.
753 __ ldr(r3, FieldMemOperand(r4, Array::kLengthOffset)); 750 __ ldr(r3, FieldMemOperand(r4, FixedArray::kLengthOffset));
754 __ cmp(r2, r3); 751 __ cmp(key, Operand(r3));
755 __ b(hs, &slow); 752 __ b(hs, &slow);
756 // Fast case: Do the load. 753 // Fast case: Do the load.
757 __ add(r3, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 754 __ add(r3, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
758 __ ldr(r2, MemOperand(r3, r2, LSL, kPointerSizeLog2)); 755 // The key is a smi.
756 ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
757 __ ldr(r2, MemOperand(r3, key, LSL, kPointerSizeLog2 - kSmiTagSize));
759 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 758 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
760 __ cmp(r2, ip); 759 __ cmp(r2, ip);
761 // In case the loaded value is the_hole we have to consult GetProperty 760 // In case the loaded value is the_hole we have to consult GetProperty
762 // to ensure the prototype chain is searched. 761 // to ensure the prototype chain is searched.
763 __ b(eq, &slow); 762 __ b(eq, &slow);
764 __ mov(r0, r2); 763 __ mov(r0, r2);
765 __ Ret(); 764 __ Ret();
766 765
767 // Check whether the elements is a pixel array. 766 // Check whether the elements is a pixel array.
768 // r0: key 767 // r0: key
769 // r2: untagged index
770 // r3: elements map 768 // r3: elements map
771 // r4: elements 769 // r4: elements
772 __ bind(&check_pixel_array); 770 __ bind(&check_pixel_array);
773 __ LoadRoot(ip, Heap::kPixelArrayMapRootIndex); 771 __ LoadRoot(ip, Heap::kPixelArrayMapRootIndex);
774 __ cmp(r3, ip); 772 __ cmp(r3, ip);
775 __ b(ne, &check_number_dictionary); 773 __ b(ne, &check_number_dictionary);
776 __ ldr(ip, FieldMemOperand(r4, PixelArray::kLengthOffset)); 774 __ ldr(ip, FieldMemOperand(r4, PixelArray::kLengthOffset));
775 __ mov(r2, Operand(key, ASR, kSmiTagSize));
777 __ cmp(r2, ip); 776 __ cmp(r2, ip);
778 __ b(hs, &slow); 777 __ b(hs, &slow);
779 __ ldr(ip, FieldMemOperand(r4, PixelArray::kExternalPointerOffset)); 778 __ ldr(ip, FieldMemOperand(r4, PixelArray::kExternalPointerOffset));
780 __ ldrb(r2, MemOperand(ip, r2)); 779 __ ldrb(r2, MemOperand(ip, r2));
781 __ mov(r0, Operand(r2, LSL, kSmiTagSize)); // Tag result as smi. 780 __ mov(r0, Operand(r2, LSL, kSmiTagSize)); // Tag result as smi.
782 __ Ret(); 781 __ Ret();
783 782
784 __ bind(&check_number_dictionary); 783 __ bind(&check_number_dictionary);
785 // Check whether the elements is a number dictionary. 784 // Check whether the elements is a number dictionary.
786 // r0: key 785 // r0: key
787 // r2: untagged index
788 // r3: elements map 786 // r3: elements map
789 // r4: elements 787 // r4: elements
790 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); 788 __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
791 __ cmp(r3, ip); 789 __ cmp(r3, ip);
792 __ b(ne, &slow); 790 __ b(ne, &slow);
791 __ mov(r2, Operand(r0, ASR, kSmiTagSize));
793 GenerateNumberDictionaryLoad(masm, &slow, r4, r0, r2, r3, r5); 792 GenerateNumberDictionaryLoad(masm, &slow, r4, r0, r2, r3, r5);
794 __ mov(r0, r2);
795 __ Ret(); 793 __ Ret();
796 794
797 // Slow case, key and receiver still in r0 and r1. 795 // Slow case, key and receiver still in r0 and r1.
798 __ bind(&slow); 796 __ bind(&slow);
799 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1, r2, r3); 797 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1, r2, r3);
800 GenerateRuntimeGetProperty(masm); 798 GenerateRuntimeGetProperty(masm);
801 } 799 }
802 800
803 801
804 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { 802 void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
1268 __ b(lt, &slow); 1266 __ b(lt, &slow);
1269 1267
1270 1268
1271 // Object case: Check key against length in the elements array. 1269 // Object case: Check key against length in the elements array.
1272 __ ldr(r3, FieldMemOperand(r3, JSObject::kElementsOffset)); 1270 __ ldr(r3, FieldMemOperand(r3, JSObject::kElementsOffset));
1273 // Check that the object is in fast mode (not dictionary). 1271 // Check that the object is in fast mode (not dictionary).
1274 __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset)); 1272 __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset));
1275 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); 1273 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
1276 __ cmp(r2, ip); 1274 __ cmp(r2, ip);
1277 __ b(ne, &check_pixel_array); 1275 __ b(ne, &check_pixel_array);
1278 // Untag the key (for checking against untagged length in the fixed array).
1279 __ mov(r1, Operand(r1, ASR, kSmiTagSize));
1280 // Compute address to store into and check array bounds. 1276 // Compute address to store into and check array bounds.
1281 __ add(r2, r3, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 1277 __ add(r2, r3, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
1282 __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2)); 1278 // The key is a smi. Assert we can shift left by 1 to use it as a
1279 // byte offset.
1280 ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
1281 __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize));
1283 __ ldr(ip, FieldMemOperand(r3, FixedArray::kLengthOffset)); 1282 __ ldr(ip, FieldMemOperand(r3, FixedArray::kLengthOffset));
1284 __ cmp(r1, Operand(ip)); 1283 __ cmp(r1, Operand(ip));
1285 __ b(lo, &fast); 1284 __ b(lo, &fast);
1286 1285
1287 1286
1288 // Slow case: 1287 // Slow case:
1289 __ bind(&slow); 1288 __ bind(&slow);
1290 GenerateRuntimeSetProperty(masm); 1289 GenerateRuntimeSetProperty(masm);
1291 1290
1292 // Check whether the elements is a pixel array. 1291 // Check whether the elements is a pixel array.
(...skipping 26 matching lines...) Expand all
1319 __ mov(r0, Operand(r4)); // Return the original value. 1318 __ mov(r0, Operand(r4)); // Return the original value.
1320 __ Ret(); 1319 __ Ret();
1321 1320
1322 1321
1323 // Extra capacity case: Check if there is extra capacity to 1322 // Extra capacity case: Check if there is extra capacity to
1324 // perform the store and update the length. Used for adding one 1323 // perform the store and update the length. Used for adding one
1325 // element to the array by writing to array[array.length]. 1324 // element to the array by writing to array[array.length].
1326 // r0 == value, r1 == key, r2 == elements, r3 == object 1325 // r0 == value, r1 == key, r2 == elements, r3 == object
1327 __ bind(&extra); 1326 __ bind(&extra);
1328 __ b(ne, &slow); // do not leave holes in the array 1327 __ b(ne, &slow); // do not leave holes in the array
1329 __ mov(r1, Operand(r1, ASR, kSmiTagSize)); // untag 1328 __ ldr(ip, FieldMemOperand(r2, FixedArray::kLengthOffset));
1330 __ ldr(ip, FieldMemOperand(r2, Array::kLengthOffset));
1331 __ cmp(r1, Operand(ip)); 1329 __ cmp(r1, Operand(ip));
1332 __ b(hs, &slow); 1330 __ b(hs, &slow);
1333 __ mov(r1, Operand(r1, LSL, kSmiTagSize)); // restore tag 1331 // Increment the key to get the new length.
1334 __ add(r1, r1, Operand(1 << kSmiTagSize)); // and increment 1332 __ add(r1, r1, Operand(Smi::FromInt(1)));
1335 __ str(r1, FieldMemOperand(r3, JSArray::kLengthOffset)); 1333 __ str(r1, FieldMemOperand(r3, JSArray::kLengthOffset));
1336 __ mov(r3, Operand(r2)); 1334 __ mov(r3, Operand(r2));
1337 // NOTE: Computing the address to store into must take the fact 1335 // NOTE: Computing the address to store into must take the fact
1338 // that the key has been incremented into account. 1336 // that the key has been incremented into account.
1339 int displacement = FixedArray::kHeaderSize - kHeapObjectTag - 1337 int displacement = FixedArray::kHeaderSize - kHeapObjectTag -
1340 ((1 << kSmiTagSize) * 2); 1338 ((1 << kSmiTagSize) * 2);
1341 __ add(r2, r2, Operand(displacement)); 1339 __ add(r2, r2, Operand(displacement));
1340 // The key is a smi. Assert we can shift left by 1 to use it as a
1341 // byte offset.
1342 ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
1342 __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize)); 1343 __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize));
1343 __ b(&fast); 1344 __ b(&fast);
1344 1345
1345 1346
1346 // Array case: Get the length and the elements array from the JS 1347 // 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 1348 // array. Check that the array is in fast mode; if it is the
1348 // length is always a smi. 1349 // length is always a smi.
1349 // r0 == value, r3 == object 1350 // r0 == value, r3 == object
1350 __ bind(&array); 1351 __ bind(&array);
1351 __ ldr(r2, FieldMemOperand(r3, JSObject::kElementsOffset)); 1352 __ ldr(r2, FieldMemOperand(r3, JSObject::kElementsOffset));
1352 __ ldr(r1, FieldMemOperand(r2, HeapObject::kMapOffset)); 1353 __ ldr(r1, FieldMemOperand(r2, HeapObject::kMapOffset));
1353 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); 1354 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
1354 __ cmp(r1, ip); 1355 __ cmp(r1, ip);
1355 __ b(ne, &slow); 1356 __ b(ne, &slow);
1356 1357
1357 // Check the key against the length in the array, compute the 1358 // Check the key against the length in the array, compute the
1358 // address to store into and fall through to fast case. 1359 // address to store into and fall through to fast case.
1359 __ ldr(r1, MemOperand(sp)); // restore key 1360 __ ldr(r1, MemOperand(sp)); // restore key
1360 // r0 == value, r1 == key, r2 == elements, r3 == object. 1361 // r0 == value, r1 == key, r2 == elements, r3 == object.
1361 __ ldr(ip, FieldMemOperand(r3, JSArray::kLengthOffset)); 1362 __ ldr(ip, FieldMemOperand(r3, JSArray::kLengthOffset));
1362 __ cmp(r1, Operand(ip)); 1363 __ cmp(r1, Operand(ip));
1363 __ b(hs, &extra); 1364 __ b(hs, &extra);
1364 __ mov(r3, Operand(r2)); 1365 __ mov(r3, Operand(r2));
1365 __ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 1366 __ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
1367 // The key is a smi. Assert we can shift left by 1 to use it as a
1368 // byte offset.
1369 ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
1366 __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize)); 1370 __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize));
1367 1371
1368 1372
1369 // Fast case: Do the store. 1373 // Fast case: Do the store.
1370 // r0 == value, r2 == address to store into, r3 == elements 1374 // r0 == value, r2 == address to store into, r3 == elements
1371 __ bind(&fast); 1375 __ bind(&fast);
1372 __ str(r0, MemOperand(r2)); 1376 __ str(r0, MemOperand(r2));
1373 // Skip write barrier if the written value is a smi. 1377 // Skip write barrier if the written value is a smi.
1374 __ tst(r0, Operand(kSmiTagMask)); 1378 __ tst(r0, Operand(kSmiTagMask));
1375 __ b(eq, &exit); 1379 __ b(eq, &exit);
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
1834 __ bind(&miss); 1838 __ bind(&miss);
1835 1839
1836 GenerateMiss(masm); 1840 GenerateMiss(masm);
1837 } 1841 }
1838 1842
1839 1843
1840 #undef __ 1844 #undef __
1841 1845
1842 1846
1843 } } // namespace v8::internal 1847 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/codegen-arm.cc ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698