| 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 |