| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_X87 |
| 8 | 8 |
| 9 #include "ic-inl.h" | 9 #include "ic-inl.h" |
| 10 #include "codegen.h" | 10 #include "codegen.h" |
| 11 #include "stub-cache.h" | 11 #include "stub-cache.h" |
| 12 | 12 |
| 13 namespace v8 { | 13 namespace v8 { |
| 14 namespace internal { | 14 namespace internal { |
| 15 | 15 |
| 16 #define __ ACCESS_MASM(masm) | 16 #define __ ACCESS_MASM(masm) |
| 17 | 17 |
| (...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 __ j(equal, &do_store, Label::kNear); | 520 __ j(equal, &do_store, Label::kNear); |
| 521 } | 521 } |
| 522 __ bind(&do_store); | 522 __ bind(&do_store); |
| 523 } | 523 } |
| 524 } else if (representation.IsDouble()) { | 524 } else if (representation.IsDouble()) { |
| 525 Label do_store, heap_number; | 525 Label do_store, heap_number; |
| 526 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, slow); | 526 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, slow); |
| 527 | 527 |
| 528 __ JumpIfNotSmi(value_reg, &heap_number); | 528 __ JumpIfNotSmi(value_reg, &heap_number); |
| 529 __ SmiUntag(value_reg); | 529 __ SmiUntag(value_reg); |
| 530 __ Cvtsi2sd(xmm0, value_reg); | 530 __ push(value_reg); |
| 531 __ fild_s(Operand(esp, 0)); |
| 532 __ pop(value_reg); |
| 531 __ SmiTag(value_reg); | 533 __ SmiTag(value_reg); |
| 532 __ jmp(&do_store); | 534 __ jmp(&do_store); |
| 533 | 535 |
| 534 __ bind(&heap_number); | 536 __ bind(&heap_number); |
| 535 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), | 537 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), |
| 536 miss_label, DONT_DO_SMI_CHECK); | 538 miss_label, DONT_DO_SMI_CHECK); |
| 537 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); | 539 __ fld_d(FieldOperand(value_reg, HeapNumber::kValueOffset)); |
| 538 | 540 |
| 539 __ bind(&do_store); | 541 __ bind(&do_store); |
| 540 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0); | 542 __ fstp_d(FieldOperand(storage_reg, HeapNumber::kValueOffset)); |
| 541 } | 543 } |
| 542 | 544 |
| 543 // Stub never generated for non-global objects that require access | 545 // Stub never generated for non-global objects that require access |
| 544 // checks. | 546 // checks. |
| 545 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 547 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
| 546 | 548 |
| 547 // Perform map transition for the receiver if necessary. | 549 // Perform map transition for the receiver if necessary. |
| 548 if (details.type() == FIELD && | 550 if (details.type() == FIELD && |
| 549 object->map()->unused_property_fields() == 0) { | 551 object->map()->unused_property_fields() == 0) { |
| 550 // The properties must be extended before we can store the value. | 552 // The properties must be extended before we can store the value. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 564 | 566 |
| 565 // Update the map of the object. | 567 // Update the map of the object. |
| 566 __ mov(scratch1, Immediate(transition)); | 568 __ mov(scratch1, Immediate(transition)); |
| 567 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1); | 569 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1); |
| 568 | 570 |
| 569 // Update the write barrier for the map field. | 571 // Update the write barrier for the map field. |
| 570 __ RecordWriteField(receiver_reg, | 572 __ RecordWriteField(receiver_reg, |
| 571 HeapObject::kMapOffset, | 573 HeapObject::kMapOffset, |
| 572 scratch1, | 574 scratch1, |
| 573 scratch2, | 575 scratch2, |
| 574 kDontSaveFPRegs, | |
| 575 OMIT_REMEMBERED_SET, | 576 OMIT_REMEMBERED_SET, |
| 576 OMIT_SMI_CHECK); | 577 OMIT_SMI_CHECK); |
| 577 | 578 |
| 578 if (details.type() == CONSTANT) { | 579 if (details.type() == CONSTANT) { |
| 579 ASSERT(value_reg.is(eax)); | 580 ASSERT(value_reg.is(eax)); |
| 580 __ ret(0); | 581 __ ret(0); |
| 581 return; | 582 return; |
| 582 } | 583 } |
| 583 | 584 |
| 584 int index = transition->instance_descriptors()->GetFieldIndex( | 585 int index = transition->instance_descriptors()->GetFieldIndex( |
| (...skipping 18 matching lines...) Expand all Loading... |
| 603 | 604 |
| 604 if (!representation.IsSmi()) { | 605 if (!representation.IsSmi()) { |
| 605 // Update the write barrier for the array address. | 606 // Update the write barrier for the array address. |
| 606 if (!representation.IsDouble()) { | 607 if (!representation.IsDouble()) { |
| 607 __ mov(storage_reg, value_reg); | 608 __ mov(storage_reg, value_reg); |
| 608 } | 609 } |
| 609 __ RecordWriteField(receiver_reg, | 610 __ RecordWriteField(receiver_reg, |
| 610 offset, | 611 offset, |
| 611 storage_reg, | 612 storage_reg, |
| 612 scratch1, | 613 scratch1, |
| 613 kDontSaveFPRegs, | |
| 614 EMIT_REMEMBERED_SET, | 614 EMIT_REMEMBERED_SET, |
| 615 smi_check); | 615 smi_check); |
| 616 } | 616 } |
| 617 } else { | 617 } else { |
| 618 // Write to the properties array. | 618 // Write to the properties array. |
| 619 int offset = index * kPointerSize + FixedArray::kHeaderSize; | 619 int offset = index * kPointerSize + FixedArray::kHeaderSize; |
| 620 // Get the properties array (optimistically). | 620 // Get the properties array (optimistically). |
| 621 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); | 621 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); |
| 622 if (representation.IsDouble()) { | 622 if (representation.IsDouble()) { |
| 623 __ mov(FieldOperand(scratch1, offset), storage_reg); | 623 __ mov(FieldOperand(scratch1, offset), storage_reg); |
| 624 } else { | 624 } else { |
| 625 __ mov(FieldOperand(scratch1, offset), value_reg); | 625 __ mov(FieldOperand(scratch1, offset), value_reg); |
| 626 } | 626 } |
| 627 | 627 |
| 628 if (!representation.IsSmi()) { | 628 if (!representation.IsSmi()) { |
| 629 // Update the write barrier for the array address. | 629 // Update the write barrier for the array address. |
| 630 if (!representation.IsDouble()) { | 630 if (!representation.IsDouble()) { |
| 631 __ mov(storage_reg, value_reg); | 631 __ mov(storage_reg, value_reg); |
| 632 } | 632 } |
| 633 __ RecordWriteField(scratch1, | 633 __ RecordWriteField(scratch1, |
| 634 offset, | 634 offset, |
| 635 storage_reg, | 635 storage_reg, |
| 636 receiver_reg, | 636 receiver_reg, |
| 637 kDontSaveFPRegs, | |
| 638 EMIT_REMEMBERED_SET, | 637 EMIT_REMEMBERED_SET, |
| 639 smi_check); | 638 smi_check); |
| 640 } | 639 } |
| 641 } | 640 } |
| 642 | 641 |
| 643 // Return the value (register eax). | 642 // Return the value (register eax). |
| 644 ASSERT(value_reg.is(eax)); | 643 ASSERT(value_reg.is(eax)); |
| 645 __ ret(0); | 644 __ ret(0); |
| 646 } | 645 } |
| 647 | 646 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 697 } else { | 696 } else { |
| 698 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); | 697 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); |
| 699 int offset = index * kPointerSize + FixedArray::kHeaderSize; | 698 int offset = index * kPointerSize + FixedArray::kHeaderSize; |
| 700 __ mov(scratch1, FieldOperand(scratch1, offset)); | 699 __ mov(scratch1, FieldOperand(scratch1, offset)); |
| 701 } | 700 } |
| 702 | 701 |
| 703 // Store the value into the storage. | 702 // Store the value into the storage. |
| 704 Label do_store, heap_number; | 703 Label do_store, heap_number; |
| 705 __ JumpIfNotSmi(value_reg, &heap_number); | 704 __ JumpIfNotSmi(value_reg, &heap_number); |
| 706 __ SmiUntag(value_reg); | 705 __ SmiUntag(value_reg); |
| 707 __ Cvtsi2sd(xmm0, value_reg); | 706 __ push(value_reg); |
| 707 __ fild_s(Operand(esp, 0)); |
| 708 __ pop(value_reg); |
| 708 __ SmiTag(value_reg); | 709 __ SmiTag(value_reg); |
| 709 __ jmp(&do_store); | 710 __ jmp(&do_store); |
| 710 __ bind(&heap_number); | 711 __ bind(&heap_number); |
| 711 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), | 712 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), |
| 712 miss_label, DONT_DO_SMI_CHECK); | 713 miss_label, DONT_DO_SMI_CHECK); |
| 713 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); | 714 __ fld_d(FieldOperand(value_reg, HeapNumber::kValueOffset)); |
| 714 __ bind(&do_store); | 715 __ bind(&do_store); |
| 715 __ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0); | 716 __ fstp_d(FieldOperand(scratch1, HeapNumber::kValueOffset)); |
| 716 // Return the value (register eax). | 717 // Return the value (register eax). |
| 717 ASSERT(value_reg.is(eax)); | 718 ASSERT(value_reg.is(eax)); |
| 718 __ ret(0); | 719 __ ret(0); |
| 719 return; | 720 return; |
| 720 } | 721 } |
| 721 | 722 |
| 722 ASSERT(!representation.IsDouble()); | 723 ASSERT(!representation.IsDouble()); |
| 723 // TODO(verwaest): Share this code as a code stub. | 724 // TODO(verwaest): Share this code as a code stub. |
| 724 SmiCheck smi_check = representation.IsTagged() | 725 SmiCheck smi_check = representation.IsTagged() |
| 725 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; | 726 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; |
| 726 if (index < 0) { | 727 if (index < 0) { |
| 727 // Set the property straight into the object. | 728 // Set the property straight into the object. |
| 728 int offset = object->map()->instance_size() + (index * kPointerSize); | 729 int offset = object->map()->instance_size() + (index * kPointerSize); |
| 729 __ mov(FieldOperand(receiver_reg, offset), value_reg); | 730 __ mov(FieldOperand(receiver_reg, offset), value_reg); |
| 730 | 731 |
| 731 if (!representation.IsSmi()) { | 732 if (!representation.IsSmi()) { |
| 732 // Update the write barrier for the array address. | 733 // Update the write barrier for the array address. |
| 733 // Pass the value being stored in the now unused name_reg. | 734 // Pass the value being stored in the now unused name_reg. |
| 734 __ mov(name_reg, value_reg); | 735 __ mov(name_reg, value_reg); |
| 735 __ RecordWriteField(receiver_reg, | 736 __ RecordWriteField(receiver_reg, |
| 736 offset, | 737 offset, |
| 737 name_reg, | 738 name_reg, |
| 738 scratch1, | 739 scratch1, |
| 739 kDontSaveFPRegs, | |
| 740 EMIT_REMEMBERED_SET, | 740 EMIT_REMEMBERED_SET, |
| 741 smi_check); | 741 smi_check); |
| 742 } | 742 } |
| 743 } else { | 743 } else { |
| 744 // Write to the properties array. | 744 // Write to the properties array. |
| 745 int offset = index * kPointerSize + FixedArray::kHeaderSize; | 745 int offset = index * kPointerSize + FixedArray::kHeaderSize; |
| 746 // Get the properties array (optimistically). | 746 // Get the properties array (optimistically). |
| 747 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); | 747 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); |
| 748 __ mov(FieldOperand(scratch1, offset), value_reg); | 748 __ mov(FieldOperand(scratch1, offset), value_reg); |
| 749 | 749 |
| 750 if (!representation.IsSmi()) { | 750 if (!representation.IsSmi()) { |
| 751 // Update the write barrier for the array address. | 751 // Update the write barrier for the array address. |
| 752 // Pass the value being stored in the now unused name_reg. | 752 // Pass the value being stored in the now unused name_reg. |
| 753 __ mov(name_reg, value_reg); | 753 __ mov(name_reg, value_reg); |
| 754 __ RecordWriteField(scratch1, | 754 __ RecordWriteField(scratch1, |
| 755 offset, | 755 offset, |
| 756 name_reg, | 756 name_reg, |
| 757 receiver_reg, | 757 receiver_reg, |
| 758 kDontSaveFPRegs, | |
| 759 EMIT_REMEMBERED_SET, | 758 EMIT_REMEMBERED_SET, |
| 760 smi_check); | 759 smi_check); |
| 761 } | 760 } |
| 762 } | 761 } |
| 763 | 762 |
| 764 // Return the value (register eax). | 763 // Return the value (register eax). |
| 765 ASSERT(value_reg.is(eax)); | 764 ASSERT(value_reg.is(eax)); |
| 766 __ ret(0); | 765 __ ret(0); |
| 767 } | 766 } |
| 768 | 767 |
| (...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1499 // -- esp[0] : return address | 1498 // -- esp[0] : return address |
| 1500 // ----------------------------------- | 1499 // ----------------------------------- |
| 1501 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 1500 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
| 1502 } | 1501 } |
| 1503 | 1502 |
| 1504 | 1503 |
| 1505 #undef __ | 1504 #undef __ |
| 1506 | 1505 |
| 1507 } } // namespace v8::internal | 1506 } } // namespace v8::internal |
| 1508 | 1507 |
| 1509 #endif // V8_TARGET_ARCH_IA32 | 1508 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |