OLD | NEW |
1 // Copyright 2011 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 |
11 // with the distribution. | 11 // with the distribution. |
(...skipping 1293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1305 StrictModeFlag strict_mode) { | 1305 StrictModeFlag strict_mode) { |
1306 // ---------- S t a t e -------------- | 1306 // ---------- S t a t e -------------- |
1307 // -- r0 : value | 1307 // -- r0 : value |
1308 // -- r1 : key | 1308 // -- r1 : key |
1309 // -- r2 : receiver | 1309 // -- r2 : receiver |
1310 // -- lr : return address | 1310 // -- lr : return address |
1311 // ----------------------------------- | 1311 // ----------------------------------- |
1312 Label slow, array, extra, check_if_double_array; | 1312 Label slow, array, extra, check_if_double_array; |
1313 Label fast_object_with_map_check, fast_object_without_map_check; | 1313 Label fast_object_with_map_check, fast_object_without_map_check; |
1314 Label fast_double_with_map_check, fast_double_without_map_check; | 1314 Label fast_double_with_map_check, fast_double_without_map_check; |
| 1315 Label transition_smi_elements, finish_object_store, non_double_value; |
| 1316 Label transition_double_elements; |
1315 | 1317 |
1316 // Register usage. | 1318 // Register usage. |
1317 Register value = r0; | 1319 Register value = r0; |
1318 Register key = r1; | 1320 Register key = r1; |
1319 Register receiver = r2; | 1321 Register receiver = r2; |
1320 Register elements = r3; // Elements array of the receiver. | 1322 Register receiver_map = r3; |
1321 Register elements_map = r6; | 1323 Register elements_map = r6; |
1322 Register receiver_map = r7; | 1324 Register elements = r7; // Elements array of the receiver. |
1323 // r4 and r5 are used as general scratch registers. | 1325 // r4 and r5 are used as general scratch registers. |
1324 | 1326 |
1325 // Check that the key is a smi. | 1327 // Check that the key is a smi. |
1326 __ JumpIfNotSmi(key, &slow); | 1328 __ JumpIfNotSmi(key, &slow); |
1327 // Check that the object isn't a smi. | 1329 // Check that the object isn't a smi. |
1328 __ JumpIfSmi(receiver, &slow); | 1330 __ JumpIfSmi(receiver, &slow); |
1329 // Get the map of the object. | 1331 // Get the map of the object. |
1330 __ ldr(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 1332 __ ldr(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
1331 // Check that the receiver does not require access checks. We need | 1333 // Check that the receiver does not require access checks. We need |
1332 // to do this because this generic stub does not perform map checks. | 1334 // to do this because this generic stub does not perform map checks. |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1410 // Smi stores don't require further checks. | 1412 // Smi stores don't require further checks. |
1411 Label non_smi_value; | 1413 Label non_smi_value; |
1412 __ JumpIfNotSmi(value, &non_smi_value); | 1414 __ JumpIfNotSmi(value, &non_smi_value); |
1413 // It's irrelevant whether array is smi-only or not when writing a smi. | 1415 // It's irrelevant whether array is smi-only or not when writing a smi. |
1414 __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 1416 __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
1415 __ add(address, address, Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize)); | 1417 __ add(address, address, Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize)); |
1416 __ str(value, MemOperand(address)); | 1418 __ str(value, MemOperand(address)); |
1417 __ Ret(); | 1419 __ Ret(); |
1418 | 1420 |
1419 __ bind(&non_smi_value); | 1421 __ bind(&non_smi_value); |
1420 // Escape to slow case when writing non-smi into smi-only array. | 1422 // Escape to elements kind transition case. |
1421 __ CheckFastObjectElements(receiver_map, scratch_value, &slow); | 1423 __ CheckFastObjectElements(receiver_map, scratch_value, |
| 1424 &transition_smi_elements); |
1422 // Fast elements array, store the value to the elements backing store. | 1425 // Fast elements array, store the value to the elements backing store. |
| 1426 __ bind(&finish_object_store); |
1423 __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 1427 __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
1424 __ add(address, address, Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize)); | 1428 __ add(address, address, Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize)); |
1425 __ str(value, MemOperand(address)); | 1429 __ str(value, MemOperand(address)); |
1426 // Update write barrier for the elements array address. | 1430 // Update write barrier for the elements array address. |
1427 __ mov(scratch_value, value); // Preserve the value which is returned. | 1431 __ mov(scratch_value, value); // Preserve the value which is returned. |
1428 __ RecordWrite(elements, | 1432 __ RecordWrite(elements, |
1429 address, | 1433 address, |
1430 scratch_value, | 1434 scratch_value, |
1431 kLRHasNotBeenSaved, | 1435 kLRHasNotBeenSaved, |
1432 kDontSaveFPRegs, | 1436 kDontSaveFPRegs, |
1433 EMIT_REMEMBERED_SET, | 1437 EMIT_REMEMBERED_SET, |
1434 OMIT_SMI_CHECK); | 1438 OMIT_SMI_CHECK); |
1435 __ Ret(); | 1439 __ Ret(); |
1436 | 1440 |
1437 __ bind(&fast_double_with_map_check); | 1441 __ bind(&fast_double_with_map_check); |
1438 // Check for fast double array case. If this fails, call through to the | 1442 // Check for fast double array case. If this fails, call through to the |
1439 // runtime. | 1443 // runtime. |
1440 __ cmp(elements_map, | 1444 __ cmp(elements_map, |
1441 Operand(masm->isolate()->factory()->fixed_double_array_map())); | 1445 Operand(masm->isolate()->factory()->fixed_double_array_map())); |
1442 __ b(ne, &slow); | 1446 __ b(ne, &slow); |
1443 __ bind(&fast_double_without_map_check); | 1447 __ bind(&fast_double_without_map_check); |
1444 __ StoreNumberToDoubleElements(value, | 1448 __ StoreNumberToDoubleElements(value, |
1445 key, | 1449 key, |
1446 receiver, | 1450 receiver, |
1447 elements, | 1451 elements, |
| 1452 r3, |
1448 r4, | 1453 r4, |
1449 r5, | 1454 r5, |
1450 r6, | 1455 r6, |
1451 r7, | 1456 &transition_double_elements); |
1452 &slow); | |
1453 __ Ret(); | 1457 __ Ret(); |
| 1458 |
| 1459 __ bind(&transition_smi_elements); |
| 1460 // Transition the array appropriately depending on the value type. |
| 1461 __ ldr(r4, FieldMemOperand(value, HeapObject::kMapOffset)); |
| 1462 __ CompareRoot(r4, Heap::kHeapNumberMapRootIndex); |
| 1463 __ b(ne, &non_double_value); |
| 1464 |
| 1465 // Value is a double. Transition FAST_SMI_ONLY_ELEMENTS -> |
| 1466 // FAST_DOUBLE_ELEMENTS and complete the store. |
| 1467 __ LoadTransitionedArrayMapConditional(FAST_SMI_ONLY_ELEMENTS, |
| 1468 FAST_DOUBLE_ELEMENTS, |
| 1469 receiver_map, |
| 1470 r4, |
| 1471 &slow); |
| 1472 ASSERT(receiver_map.is(r3)); // Transition code expects map in r3 |
| 1473 ElementsTransitionGenerator::GenerateSmiOnlyToDouble(masm, &slow); |
| 1474 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
| 1475 __ jmp(&fast_double_without_map_check); |
| 1476 |
| 1477 __ bind(&non_double_value); |
| 1478 // Value is not a double, FAST_SMI_ONLY_ELEMENTS -> FAST_ELEMENTS |
| 1479 __ LoadTransitionedArrayMapConditional(FAST_SMI_ONLY_ELEMENTS, |
| 1480 FAST_ELEMENTS, |
| 1481 receiver_map, |
| 1482 r4, |
| 1483 &slow); |
| 1484 ASSERT(receiver_map.is(r3)); // Transition code expects map in r3 |
| 1485 ElementsTransitionGenerator::GenerateSmiOnlyToObject(masm); |
| 1486 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
| 1487 __ jmp(&finish_object_store); |
| 1488 |
| 1489 __ bind(&transition_double_elements); |
| 1490 // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a |
| 1491 // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and |
| 1492 // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS |
| 1493 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, |
| 1494 FAST_ELEMENTS, |
| 1495 receiver_map, |
| 1496 r4, |
| 1497 &slow); |
| 1498 ASSERT(receiver_map.is(r3)); // Transition code expects map in r3 |
| 1499 ElementsTransitionGenerator::GenerateDoubleToObject(masm, &slow); |
| 1500 __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
| 1501 __ jmp(&finish_object_store); |
1454 } | 1502 } |
1455 | 1503 |
1456 | 1504 |
1457 void StoreIC::GenerateMegamorphic(MacroAssembler* masm, | 1505 void StoreIC::GenerateMegamorphic(MacroAssembler* masm, |
1458 StrictModeFlag strict_mode) { | 1506 StrictModeFlag strict_mode) { |
1459 // ----------- S t a t e ------------- | 1507 // ----------- S t a t e ------------- |
1460 // -- r0 : value | 1508 // -- r0 : value |
1461 // -- r1 : receiver | 1509 // -- r1 : receiver |
1462 // -- r2 : name | 1510 // -- r2 : name |
1463 // -- lr : return address | 1511 // -- lr : return address |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1710 Register reg = Assembler::GetRn(instr_at_patch); | 1758 Register reg = Assembler::GetRn(instr_at_patch); |
1711 patcher.masm()->tst(reg, Operand(kSmiTagMask)); | 1759 patcher.masm()->tst(reg, Operand(kSmiTagMask)); |
1712 patcher.EmitCondition(eq); | 1760 patcher.EmitCondition(eq); |
1713 } | 1761 } |
1714 } | 1762 } |
1715 | 1763 |
1716 | 1764 |
1717 } } // namespace v8::internal | 1765 } } // namespace v8::internal |
1718 | 1766 |
1719 #endif // V8_TARGET_ARCH_ARM | 1767 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |