Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(442)

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 233293005: Remove hand-written assembly ArrayPush stubs (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix test comments Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.cc ('k') | src/macros.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 3726 matching lines...) Expand 10 before | Expand all | Expand 10 after
3737 __ push(ecx); 3737 __ push(ecx);
3738 GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, edi); 3738 GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, edi);
3739 3739
3740 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 3740 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
3741 // tagged as a small integer. 3741 // tagged as a small integer.
3742 __ bind(&runtime); 3742 __ bind(&runtime);
3743 __ TailCallRuntime(Runtime::kHiddenStringCompare, 2, 1); 3743 __ TailCallRuntime(Runtime::kHiddenStringCompare, 2, 1);
3744 } 3744 }
3745 3745
3746 3746
3747 void ArrayPushStub::Generate(MacroAssembler* masm) {
3748 int argc = arguments_count();
3749
3750 if (argc == 0) {
3751 // Noop, return the length.
3752 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
3753 __ ret((argc + 1) * kPointerSize);
3754 return;
3755 }
3756
3757 Isolate* isolate = masm->isolate();
3758
3759 if (argc != 1) {
3760 __ TailCallExternalReference(
3761 ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
3762 return;
3763 }
3764
3765 Label call_builtin, attempt_to_grow_elements, with_write_barrier;
3766
3767 // Get the elements array of the object.
3768 __ mov(edi, FieldOperand(edx, JSArray::kElementsOffset));
3769
3770 if (IsFastSmiOrObjectElementsKind(elements_kind())) {
3771 // Check that the elements are in fast mode and writable.
3772 __ cmp(FieldOperand(edi, HeapObject::kMapOffset),
3773 isolate->factory()->fixed_array_map());
3774 __ j(not_equal, &call_builtin);
3775 }
3776
3777 // Get the array's length into eax and calculate new length.
3778 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
3779 STATIC_ASSERT(kSmiTagSize == 1);
3780 STATIC_ASSERT(kSmiTag == 0);
3781 __ add(eax, Immediate(Smi::FromInt(argc)));
3782
3783 // Get the elements' length into ecx.
3784 __ mov(ecx, FieldOperand(edi, FixedArray::kLengthOffset));
3785
3786 // Check if we could survive without allocation.
3787 __ cmp(eax, ecx);
3788
3789 if (IsFastSmiOrObjectElementsKind(elements_kind())) {
3790 __ j(greater, &attempt_to_grow_elements);
3791
3792 // Check if value is a smi.
3793 __ mov(ecx, Operand(esp, argc * kPointerSize));
3794 __ JumpIfNotSmi(ecx, &with_write_barrier);
3795
3796 // Store the value.
3797 __ mov(FieldOperand(edi, eax, times_half_pointer_size,
3798 FixedArray::kHeaderSize - argc * kPointerSize),
3799 ecx);
3800 } else {
3801 __ j(greater, &call_builtin);
3802
3803 __ mov(ecx, Operand(esp, argc * kPointerSize));
3804 __ StoreNumberToDoubleElements(
3805 ecx, edi, eax, ecx, xmm0, &call_builtin, true, argc * kDoubleSize);
3806 }
3807
3808 // Save new length.
3809 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
3810 __ ret((argc + 1) * kPointerSize);
3811
3812 if (IsFastDoubleElementsKind(elements_kind())) {
3813 __ bind(&call_builtin);
3814 __ TailCallExternalReference(
3815 ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
3816 return;
3817 }
3818
3819 __ bind(&with_write_barrier);
3820
3821 if (IsFastSmiElementsKind(elements_kind())) {
3822 if (FLAG_trace_elements_transitions) __ jmp(&call_builtin);
3823
3824 __ cmp(FieldOperand(ecx, HeapObject::kMapOffset),
3825 isolate->factory()->heap_number_map());
3826 __ j(equal, &call_builtin);
3827
3828 ElementsKind target_kind = IsHoleyElementsKind(elements_kind())
3829 ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
3830 __ mov(ebx, ContextOperand(esi, Context::GLOBAL_OBJECT_INDEX));
3831 __ mov(ebx, FieldOperand(ebx, GlobalObject::kNativeContextOffset));
3832 __ mov(ebx, ContextOperand(ebx, Context::JS_ARRAY_MAPS_INDEX));
3833 const int header_size = FixedArrayBase::kHeaderSize;
3834 // Verify that the object can be transitioned in place.
3835 const int origin_offset = header_size + elements_kind() * kPointerSize;
3836 __ mov(edi, FieldOperand(ebx, origin_offset));
3837 __ cmp(edi, FieldOperand(edx, HeapObject::kMapOffset));
3838 __ j(not_equal, &call_builtin);
3839
3840 const int target_offset = header_size + target_kind * kPointerSize;
3841 __ mov(ebx, FieldOperand(ebx, target_offset));
3842 ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
3843 masm, DONT_TRACK_ALLOCATION_SITE, NULL);
3844 // Restore edi used as a scratch register for the write barrier used while
3845 // setting the map.
3846 __ mov(edi, FieldOperand(edx, JSArray::kElementsOffset));
3847 }
3848
3849 // Save new length.
3850 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
3851
3852 // Store the value.
3853 __ lea(edx, FieldOperand(edi, eax, times_half_pointer_size,
3854 FixedArray::kHeaderSize - argc * kPointerSize));
3855 __ mov(Operand(edx, 0), ecx);
3856
3857 __ RecordWrite(edi, edx, ecx, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
3858 OMIT_SMI_CHECK);
3859
3860 __ ret((argc + 1) * kPointerSize);
3861
3862 __ bind(&attempt_to_grow_elements);
3863 if (!FLAG_inline_new) {
3864 __ bind(&call_builtin);
3865 __ TailCallExternalReference(
3866 ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
3867 return;
3868 }
3869
3870 __ mov(ebx, Operand(esp, argc * kPointerSize));
3871 // Growing elements that are SMI-only requires special handling in case the
3872 // new element is non-Smi. For now, delegate to the builtin.
3873 if (IsFastSmiElementsKind(elements_kind())) {
3874 __ JumpIfNotSmi(ebx, &call_builtin);
3875 }
3876
3877 // We could be lucky and the elements array could be at the top of new-space.
3878 // In this case we can just grow it in place by moving the allocation pointer
3879 // up.
3880 ExternalReference new_space_allocation_top =
3881 ExternalReference::new_space_allocation_top_address(isolate);
3882 ExternalReference new_space_allocation_limit =
3883 ExternalReference::new_space_allocation_limit_address(isolate);
3884
3885 const int kAllocationDelta = 4;
3886 ASSERT(kAllocationDelta >= argc);
3887 // Load top.
3888 __ mov(ecx, Operand::StaticVariable(new_space_allocation_top));
3889
3890 // Check if it's the end of elements.
3891 __ lea(edx, FieldOperand(edi, eax, times_half_pointer_size,
3892 FixedArray::kHeaderSize - argc * kPointerSize));
3893 __ cmp(edx, ecx);
3894 __ j(not_equal, &call_builtin);
3895 __ add(ecx, Immediate(kAllocationDelta * kPointerSize));
3896 __ cmp(ecx, Operand::StaticVariable(new_space_allocation_limit));
3897 __ j(above, &call_builtin);
3898
3899 // We fit and could grow elements.
3900 __ mov(Operand::StaticVariable(new_space_allocation_top), ecx);
3901
3902 // Push the argument...
3903 __ mov(Operand(edx, 0), ebx);
3904 // ... and fill the rest with holes.
3905 for (int i = 1; i < kAllocationDelta; i++) {
3906 __ mov(Operand(edx, i * kPointerSize),
3907 isolate->factory()->the_hole_value());
3908 }
3909
3910 if (IsFastObjectElementsKind(elements_kind())) {
3911 // We know the elements array is in new space so we don't need the
3912 // remembered set, but we just pushed a value onto it so we may have to tell
3913 // the incremental marker to rescan the object that we just grew. We don't
3914 // need to worry about the holes because they are in old space and already
3915 // marked black.
3916 __ RecordWrite(edi, edx, ebx, kDontSaveFPRegs, OMIT_REMEMBERED_SET);
3917 }
3918
3919 // Restore receiver to edx as finish sequence assumes it's here.
3920 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
3921
3922 // Increment element's and array's sizes.
3923 __ add(FieldOperand(edi, FixedArray::kLengthOffset),
3924 Immediate(Smi::FromInt(kAllocationDelta)));
3925
3926 // NOTE: This only happen in new-space, where we don't care about the
3927 // black-byte-count on pages. Otherwise we should update that too if the
3928 // object is black.
3929
3930 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
3931 __ ret((argc + 1) * kPointerSize);
3932
3933 __ bind(&call_builtin);
3934 __ TailCallExternalReference(
3935 ExternalReference(Builtins::c_ArrayPush, isolate), argc + 1, 1);
3936 }
3937
3938
3939 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { 3747 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
3940 // ----------- S t a t e ------------- 3748 // ----------- S t a t e -------------
3941 // -- edx : left 3749 // -- edx : left
3942 // -- eax : right 3750 // -- eax : right
3943 // -- esp[0] : return address 3751 // -- esp[0] : return address
3944 // ----------------------------------- 3752 // -----------------------------------
3945 Isolate* isolate = masm->isolate(); 3753 Isolate* isolate = masm->isolate();
3946 3754
3947 // Load ecx with the allocation site. We stick an undefined dummy value here 3755 // Load ecx with the allocation site. We stick an undefined dummy value here
3948 // and replace it with the real allocation site later when we instantiate this 3756 // and replace it with the real allocation site later when we instantiate this
(...skipping 1413 matching lines...) Expand 10 before | Expand all | Expand 10 after
5362 Operand(ebp, 7 * kPointerSize), 5170 Operand(ebp, 7 * kPointerSize),
5363 NULL); 5171 NULL);
5364 } 5172 }
5365 5173
5366 5174
5367 #undef __ 5175 #undef __
5368 5176
5369 } } // namespace v8::internal 5177 } } // namespace v8::internal
5370 5178
5371 #endif // V8_TARGET_ARCH_IA32 5179 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/macros.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698