OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 __ b(ne, not_fast_array); | 283 __ b(ne, not_fast_array); |
284 } else { | 284 } else { |
285 __ AssertFastElements(elements); | 285 __ AssertFastElements(elements); |
286 } | 286 } |
287 // Check that the key (index) is within bounds. | 287 // Check that the key (index) is within bounds. |
288 __ ldr(scratch1, FieldMemOperand(elements, FixedArray::kLengthOffset)); | 288 __ ldr(scratch1, FieldMemOperand(elements, FixedArray::kLengthOffset)); |
289 __ cmp(key, Operand(scratch1)); | 289 __ cmp(key, Operand(scratch1)); |
290 __ b(hs, out_of_range); | 290 __ b(hs, out_of_range); |
291 // Fast case: Do the load. | 291 // Fast case: Do the load. |
292 __ add(scratch1, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 292 __ add(scratch1, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
293 // The key is a smi. | 293 __ ldr(scratch2, MemOperand::PointerAddressFromSmiKey(scratch1, key)); |
294 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); | |
295 __ ldr(scratch2, | |
296 MemOperand(scratch1, key, LSL, kPointerSizeLog2 - kSmiTagSize)); | |
297 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 294 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
298 __ cmp(scratch2, ip); | 295 __ cmp(scratch2, ip); |
299 // In case the loaded value is the_hole we have to consult GetProperty | 296 // In case the loaded value is the_hole we have to consult GetProperty |
300 // to ensure the prototype chain is searched. | 297 // to ensure the prototype chain is searched. |
301 __ b(eq, out_of_range); | 298 __ b(eq, out_of_range); |
302 __ mov(result, scratch2); | 299 __ mov(result, scratch2); |
303 } | 300 } |
304 | 301 |
305 | 302 |
306 // Checks whether a key is an array index string or a unique name. | 303 // Checks whether a key is an array index string or a unique name. |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 GenerateFunctionTailCall(masm, argc, &slow_call, r0); | 557 GenerateFunctionTailCall(masm, argc, &slow_call, r0); |
561 | 558 |
562 __ bind(&check_number_dictionary); | 559 __ bind(&check_number_dictionary); |
563 // r2: key | 560 // r2: key |
564 // r3: elements map | 561 // r3: elements map |
565 // r4: elements | 562 // r4: elements |
566 // Check whether the elements is a number dictionary. | 563 // Check whether the elements is a number dictionary. |
567 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); | 564 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); |
568 __ cmp(r3, ip); | 565 __ cmp(r3, ip); |
569 __ b(ne, &slow_load); | 566 __ b(ne, &slow_load); |
570 __ mov(r0, Operand(r2, ASR, kSmiTagSize)); | 567 __ SmiUntag(r0, r2); |
571 // r0: untagged index | 568 // r0: untagged index |
572 __ LoadFromNumberDictionary(&slow_load, r4, r2, r1, r0, r3, r5); | 569 __ LoadFromNumberDictionary(&slow_load, r4, r2, r1, r0, r3, r5); |
573 __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1, r0, r3); | 570 __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1, r0, r3); |
574 __ jmp(&do_call); | 571 __ jmp(&do_call); |
575 | 572 |
576 __ bind(&slow_load); | 573 __ bind(&slow_load); |
577 // This branch is taken when calling KeyedCallIC_Miss is neither required | 574 // This branch is taken when calling KeyedCallIC_Miss is neither required |
578 // nor beneficial. | 575 // nor beneficial. |
579 __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1, r0, r3); | 576 __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1, r0, r3); |
580 { | 577 { |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
953 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset)); | 950 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
954 __ ldr(r3, FieldMemOperand(r4, JSObject::kMapOffset)); | 951 __ ldr(r3, FieldMemOperand(r4, JSObject::kMapOffset)); |
955 | 952 |
956 // Check whether the elements is a number dictionary. | 953 // Check whether the elements is a number dictionary. |
957 // r0: key | 954 // r0: key |
958 // r3: elements map | 955 // r3: elements map |
959 // r4: elements | 956 // r4: elements |
960 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); | 957 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); |
961 __ cmp(r3, ip); | 958 __ cmp(r3, ip); |
962 __ b(ne, &slow); | 959 __ b(ne, &slow); |
963 __ mov(r2, Operand(r0, ASR, kSmiTagSize)); | 960 __ SmiUntag(r2, r0); |
964 __ LoadFromNumberDictionary(&slow, r4, r0, r0, r2, r3, r5); | 961 __ LoadFromNumberDictionary(&slow, r4, r0, r0, r2, r3, r5); |
965 __ Ret(); | 962 __ Ret(); |
966 | 963 |
967 // Slow case, key and receiver still in r0 and r1. | 964 // Slow case, key and receiver still in r0 and r1. |
968 __ bind(&slow); | 965 __ bind(&slow); |
969 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), | 966 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), |
970 1, r2, r3); | 967 1, r2, r3); |
971 GenerateRuntimeGetProperty(masm); | 968 GenerateRuntimeGetProperty(masm); |
972 | 969 |
973 __ bind(&check_name); | 970 __ bind(&check_name); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1126 // -- lr : return address | 1123 // -- lr : return address |
1127 // -- r0 : key | 1124 // -- r0 : key |
1128 // -- r1 : receiver | 1125 // -- r1 : receiver |
1129 // ----------------------------------- | 1126 // ----------------------------------- |
1130 Label slow; | 1127 Label slow; |
1131 | 1128 |
1132 // Check that the receiver isn't a smi. | 1129 // Check that the receiver isn't a smi. |
1133 __ JumpIfSmi(r1, &slow); | 1130 __ JumpIfSmi(r1, &slow); |
1134 | 1131 |
1135 // Check that the key is an array index, that is Uint32. | 1132 // Check that the key is an array index, that is Uint32. |
1136 __ tst(r0, Operand(kSmiTagMask | kSmiSignMask)); | 1133 __ NonNegativeSmiTst(r0); |
1137 __ b(ne, &slow); | 1134 __ b(ne, &slow); |
1138 | 1135 |
1139 // Get the map of the receiver. | 1136 // Get the map of the receiver. |
1140 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); | 1137 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); |
1141 | 1138 |
1142 // Check that it has indexed interceptor and access checks | 1139 // Check that it has indexed interceptor and access checks |
1143 // are not enabled for this object. | 1140 // are not enabled for this object. |
1144 __ ldrb(r3, FieldMemOperand(r2, Map::kBitFieldOffset)); | 1141 __ ldrb(r3, FieldMemOperand(r2, Map::kBitFieldOffset)); |
1145 __ and_(r3, r3, Operand(kSlowCaseBitFieldMask)); | 1142 __ and_(r3, r3, Operand(kSlowCaseBitFieldMask)); |
1146 __ cmp(r3, Operand(1 << Map::kHasIndexedInterceptor)); | 1143 __ cmp(r3, Operand(1 << Map::kHasIndexedInterceptor)); |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1314 Label non_smi_value; | 1311 Label non_smi_value; |
1315 __ JumpIfNotSmi(value, &non_smi_value); | 1312 __ JumpIfNotSmi(value, &non_smi_value); |
1316 | 1313 |
1317 if (increment_length == kIncrementLength) { | 1314 if (increment_length == kIncrementLength) { |
1318 // Add 1 to receiver->length. | 1315 // Add 1 to receiver->length. |
1319 __ add(scratch_value, key, Operand(Smi::FromInt(1))); | 1316 __ add(scratch_value, key, Operand(Smi::FromInt(1))); |
1320 __ str(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1317 __ str(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
1321 } | 1318 } |
1322 // It's irrelevant whether array is smi-only or not when writing a smi. | 1319 // It's irrelevant whether array is smi-only or not when writing a smi. |
1323 __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 1320 __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
1324 __ add(address, address, Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize)); | 1321 __ str(value, MemOperand::PointerAddressFromSmiKey(address, key)); |
1325 __ str(value, MemOperand(address)); | |
1326 __ Ret(); | 1322 __ Ret(); |
1327 | 1323 |
1328 __ bind(&non_smi_value); | 1324 __ bind(&non_smi_value); |
1329 // Escape to elements kind transition case. | 1325 // Escape to elements kind transition case. |
1330 __ CheckFastObjectElements(receiver_map, scratch_value, | 1326 __ CheckFastObjectElements(receiver_map, scratch_value, |
1331 &transition_smi_elements); | 1327 &transition_smi_elements); |
1332 | 1328 |
1333 // Fast elements array, store the value to the elements backing store. | 1329 // Fast elements array, store the value to the elements backing store. |
1334 __ bind(&finish_object_store); | 1330 __ bind(&finish_object_store); |
1335 if (increment_length == kIncrementLength) { | 1331 if (increment_length == kIncrementLength) { |
1336 // Add 1 to receiver->length. | 1332 // Add 1 to receiver->length. |
1337 __ add(scratch_value, key, Operand(Smi::FromInt(1))); | 1333 __ add(scratch_value, key, Operand(Smi::FromInt(1))); |
1338 __ str(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1334 __ str(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
1339 } | 1335 } |
1340 __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 1336 __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
1341 __ add(address, address, Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize)); | 1337 __ add(address, address, Operand::PointerOffsetFromSmiKey(key)); |
1342 __ str(value, MemOperand(address)); | 1338 __ str(value, MemOperand(address)); |
1343 // Update write barrier for the elements array address. | 1339 // Update write barrier for the elements array address. |
1344 __ mov(scratch_value, value); // Preserve the value which is returned. | 1340 __ mov(scratch_value, value); // Preserve the value which is returned. |
1345 __ RecordWrite(elements, | 1341 __ RecordWrite(elements, |
1346 address, | 1342 address, |
1347 scratch_value, | 1343 scratch_value, |
1348 kLRHasNotBeenSaved, | 1344 kLRHasNotBeenSaved, |
1349 kDontSaveFPRegs, | 1345 kDontSaveFPRegs, |
1350 EMIT_REMEMBERED_SET, | 1346 EMIT_REMEMBERED_SET, |
1351 OMIT_SMI_CHECK); | 1347 OMIT_SMI_CHECK); |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1695 } else { | 1691 } else { |
1696 ASSERT(Assembler::GetCondition(branch_instr) == ne); | 1692 ASSERT(Assembler::GetCondition(branch_instr) == ne); |
1697 patcher.EmitCondition(eq); | 1693 patcher.EmitCondition(eq); |
1698 } | 1694 } |
1699 } | 1695 } |
1700 | 1696 |
1701 | 1697 |
1702 } } // namespace v8::internal | 1698 } } // namespace v8::internal |
1703 | 1699 |
1704 #endif // V8_TARGET_ARCH_ARM | 1700 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |