OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 if (index < 0) { | 424 if (index < 0) { |
425 // Set the property straight into the object. | 425 // Set the property straight into the object. |
426 int offset = object->map()->instance_size() + (index * kPointerSize); | 426 int offset = object->map()->instance_size() + (index * kPointerSize); |
427 __ str(r0, FieldMemOperand(receiver_reg, offset)); | 427 __ str(r0, FieldMemOperand(receiver_reg, offset)); |
428 | 428 |
429 // Skip updating write barrier if storing a smi. | 429 // Skip updating write barrier if storing a smi. |
430 __ JumpIfSmi(r0, &exit); | 430 __ JumpIfSmi(r0, &exit); |
431 | 431 |
432 // Update the write barrier for the array address. | 432 // Update the write barrier for the array address. |
433 // Pass the now unused name_reg as a scratch register. | 433 // Pass the now unused name_reg as a scratch register. |
434 __ RecordWrite(receiver_reg, Operand(offset), name_reg, scratch); | 434 __ mov(name_reg, r0); |
| 435 __ RecordWriteField(receiver_reg, |
| 436 offset, |
| 437 name_reg, |
| 438 scratch, |
| 439 kLRHasNotBeenSaved, |
| 440 kDontSaveFPRegs); |
435 } else { | 441 } else { |
436 // Write to the properties array. | 442 // Write to the properties array. |
437 int offset = index * kPointerSize + FixedArray::kHeaderSize; | 443 int offset = index * kPointerSize + FixedArray::kHeaderSize; |
438 // Get the properties array | 444 // Get the properties array |
439 __ ldr(scratch, FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); | 445 __ ldr(scratch, FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); |
440 __ str(r0, FieldMemOperand(scratch, offset)); | 446 __ str(r0, FieldMemOperand(scratch, offset)); |
441 | 447 |
442 // Skip updating write barrier if storing a smi. | 448 // Skip updating write barrier if storing a smi. |
443 __ JumpIfSmi(r0, &exit); | 449 __ JumpIfSmi(r0, &exit); |
444 | 450 |
445 // Update the write barrier for the array address. | 451 // Update the write barrier for the array address. |
446 // Ok to clobber receiver_reg and name_reg, since we return. | 452 // Ok to clobber receiver_reg and name_reg, since we return. |
447 __ RecordWrite(scratch, Operand(offset), name_reg, receiver_reg); | 453 __ mov(name_reg, r0); |
| 454 __ RecordWriteField(scratch, |
| 455 offset, |
| 456 name_reg, |
| 457 receiver_reg, |
| 458 kLRHasNotBeenSaved, |
| 459 kDontSaveFPRegs); |
448 } | 460 } |
449 | 461 |
450 // Return the value (register r0). | 462 // Return the value (register r0). |
451 __ bind(&exit); | 463 __ bind(&exit); |
452 __ Ret(); | 464 __ Ret(); |
453 } | 465 } |
454 | 466 |
455 | 467 |
456 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { | 468 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { |
457 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); | 469 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); |
(...skipping 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1561 __ ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); | 1573 __ ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); |
1562 | 1574 |
1563 // Check that the elements are in fast mode and writable. | 1575 // Check that the elements are in fast mode and writable. |
1564 __ CheckMap(elements, | 1576 __ CheckMap(elements, |
1565 r0, | 1577 r0, |
1566 Heap::kFixedArrayMapRootIndex, | 1578 Heap::kFixedArrayMapRootIndex, |
1567 &call_builtin, | 1579 &call_builtin, |
1568 DONT_DO_SMI_CHECK); | 1580 DONT_DO_SMI_CHECK); |
1569 | 1581 |
1570 if (argc == 1) { // Otherwise fall through to call the builtin. | 1582 if (argc == 1) { // Otherwise fall through to call the builtin. |
1571 Label exit, with_write_barrier, attempt_to_grow_elements; | 1583 Label exit, attempt_to_grow_elements; |
1572 | 1584 |
1573 // Get the array's length into r0 and calculate new length. | 1585 // Get the array's length into r0 and calculate new length. |
1574 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1586 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
1575 STATIC_ASSERT(kSmiTagSize == 1); | 1587 STATIC_ASSERT(kSmiTagSize == 1); |
1576 STATIC_ASSERT(kSmiTag == 0); | 1588 STATIC_ASSERT(kSmiTag == 0); |
1577 __ add(r0, r0, Operand(Smi::FromInt(argc))); | 1589 __ add(r0, r0, Operand(Smi::FromInt(argc))); |
1578 | 1590 |
1579 // Get the element's length. | 1591 // Get the element's length. |
1580 __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset)); | 1592 __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset)); |
1581 | 1593 |
1582 // Check if we could survive without allocation. | 1594 // Check if we could survive without allocation. |
1583 __ cmp(r0, r4); | 1595 __ cmp(r0, r4); |
1584 __ b(gt, &attempt_to_grow_elements); | 1596 __ b(gt, &attempt_to_grow_elements); |
1585 | 1597 |
1586 // Save new length. | 1598 // Save new length. |
1587 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1599 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
1588 | 1600 |
1589 // Push the element. | 1601 // Push the element. |
1590 __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize)); | 1602 __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize)); |
1591 // We may need a register containing the address end_elements below, | 1603 // We may need a register containing the address end_elements below, |
1592 // so write back the value in end_elements. | 1604 // so write back the value in end_elements. |
1593 __ add(end_elements, elements, | 1605 __ add(end_elements, elements, |
1594 Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); | 1606 Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); |
1595 const int kEndElementsOffset = | 1607 const int kEndElementsOffset = |
1596 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize; | 1608 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize; |
1597 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex)); | 1609 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex)); |
1598 | 1610 |
1599 // Check for a smi. | 1611 // Check for a smi. |
| 1612 Label with_write_barrier; |
1600 __ JumpIfNotSmi(r4, &with_write_barrier); | 1613 __ JumpIfNotSmi(r4, &with_write_barrier); |
1601 __ bind(&exit); | 1614 __ bind(&exit); |
1602 __ Drop(argc + 1); | 1615 __ Drop(argc + 1); |
1603 __ Ret(); | 1616 __ Ret(); |
1604 | 1617 |
1605 __ bind(&with_write_barrier); | 1618 __ bind(&with_write_barrier); |
1606 __ InNewSpace(elements, r4, eq, &exit); | 1619 __ RecordWrite(elements, |
1607 __ RecordWriteHelper(elements, end_elements, r4); | 1620 end_elements, |
| 1621 r4, |
| 1622 kLRHasNotBeenSaved, |
| 1623 kDontSaveFPRegs, |
| 1624 EMIT_REMEMBERED_SET, |
| 1625 OMIT_SMI_CHECK); |
1608 __ Drop(argc + 1); | 1626 __ Drop(argc + 1); |
1609 __ Ret(); | 1627 __ Ret(); |
1610 | 1628 |
1611 __ bind(&attempt_to_grow_elements); | 1629 __ bind(&attempt_to_grow_elements); |
1612 // r0: array's length + 1. | 1630 // r0: array's length + 1. |
1613 // r4: elements' length. | 1631 // r4: elements' length. |
1614 | 1632 |
1615 if (!FLAG_inline_new) { | 1633 if (!FLAG_inline_new) { |
1616 __ b(&call_builtin); | 1634 __ b(&call_builtin); |
1617 } | 1635 } |
(...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2718 // global object. We bail out to the runtime system to do that. | 2736 // global object. We bail out to the runtime system to do that. |
2719 __ mov(r4, Operand(Handle<JSGlobalPropertyCell>(cell))); | 2737 __ mov(r4, Operand(Handle<JSGlobalPropertyCell>(cell))); |
2720 __ LoadRoot(r5, Heap::kTheHoleValueRootIndex); | 2738 __ LoadRoot(r5, Heap::kTheHoleValueRootIndex); |
2721 __ ldr(r6, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset)); | 2739 __ ldr(r6, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset)); |
2722 __ cmp(r5, r6); | 2740 __ cmp(r5, r6); |
2723 __ b(eq, &miss); | 2741 __ b(eq, &miss); |
2724 | 2742 |
2725 // Store the value in the cell. | 2743 // Store the value in the cell. |
2726 __ str(r0, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset)); | 2744 __ str(r0, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset)); |
2727 | 2745 |
| 2746 __ mov(r1, r0); |
| 2747 __ RecordWriteField(r4, |
| 2748 JSGlobalPropertyCell::kValueOffset, |
| 2749 r1, |
| 2750 r2, |
| 2751 kLRHasNotBeenSaved, |
| 2752 kDontSaveFPRegs, |
| 2753 OMIT_REMEMBERED_SET); |
| 2754 |
2728 Counters* counters = masm()->isolate()->counters(); | 2755 Counters* counters = masm()->isolate()->counters(); |
2729 __ IncrementCounter(counters->named_store_global_inline(), 1, r4, r3); | 2756 __ IncrementCounter(counters->named_store_global_inline(), 1, r4, r3); |
2730 __ Ret(); | 2757 __ Ret(); |
2731 | 2758 |
2732 // Handle store cache miss. | 2759 // Handle store cache miss. |
2733 __ bind(&miss); | 2760 __ bind(&miss); |
2734 __ IncrementCounter(counters->named_store_global_inline_miss(), 1, r4, r3); | 2761 __ IncrementCounter(counters->named_store_global_inline_miss(), 1, r4, r3); |
2735 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); | 2762 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); |
2736 __ Jump(ic, RelocInfo::CODE_TARGET); | 2763 __ Jump(ic, RelocInfo::CODE_TARGET); |
2737 | 2764 |
(...skipping 1547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4285 } else { | 4312 } else { |
4286 __ ldr(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); | 4313 __ ldr(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); |
4287 } | 4314 } |
4288 // Compare smis. | 4315 // Compare smis. |
4289 __ cmp(key_reg, scratch); | 4316 __ cmp(key_reg, scratch); |
4290 __ b(hs, &miss_force_generic); | 4317 __ b(hs, &miss_force_generic); |
4291 | 4318 |
4292 __ add(scratch, | 4319 __ add(scratch, |
4293 elements_reg, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 4320 elements_reg, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
4294 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); | 4321 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); |
4295 __ str(value_reg, | 4322 __ add(scratch, |
4296 MemOperand(scratch, key_reg, LSL, kPointerSizeLog2 - kSmiTagSize)); | 4323 scratch, |
4297 __ RecordWrite(scratch, | 4324 Operand(key_reg, LSL, kPointerSizeLog2 - kSmiTagSize)); |
4298 Operand(key_reg, LSL, kPointerSizeLog2 - kSmiTagSize), | 4325 __ str(value_reg, MemOperand(scratch)); |
4299 receiver_reg , elements_reg); | 4326 __ mov(receiver_reg, value_reg); |
| 4327 __ RecordWrite(elements_reg, // Object. |
| 4328 scratch, // Address. |
| 4329 receiver_reg, // Value. |
| 4330 kLRHasNotBeenSaved, |
| 4331 kDontSaveFPRegs); |
4300 | 4332 |
4301 // value_reg (r0) is preserved. | 4333 // value_reg (r0) is preserved. |
4302 // Done. | 4334 // Done. |
4303 __ Ret(); | 4335 __ Ret(); |
4304 | 4336 |
4305 __ bind(&miss_force_generic); | 4337 __ bind(&miss_force_generic); |
4306 Handle<Code> ic = | 4338 Handle<Code> ic = |
4307 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 4339 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
4308 __ Jump(ic, RelocInfo::CODE_TARGET); | 4340 __ Jump(ic, RelocInfo::CODE_TARGET); |
4309 } | 4341 } |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4433 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 4465 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
4434 __ Jump(ic, RelocInfo::CODE_TARGET); | 4466 __ Jump(ic, RelocInfo::CODE_TARGET); |
4435 } | 4467 } |
4436 | 4468 |
4437 | 4469 |
4438 #undef __ | 4470 #undef __ |
4439 | 4471 |
4440 } } // namespace v8::internal | 4472 } } // namespace v8::internal |
4441 | 4473 |
4442 #endif // V8_TARGET_ARCH_ARM | 4474 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |