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

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

Issue 7024047: [Arguments] Port fast arguments creation stubs to X64 and ARM. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/arguments
Patch Set: Address comments. Created 9 years, 6 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
OLDNEW
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 3920 matching lines...) Expand 10 before | Expand all | Expand 10 after
3931 __ Jump(lr); 3931 __ Jump(lr);
3932 3932
3933 // Slow-case: Handle non-smi or out-of-bounds access to arguments 3933 // Slow-case: Handle non-smi or out-of-bounds access to arguments
3934 // by calling the runtime system. 3934 // by calling the runtime system.
3935 __ bind(&slow); 3935 __ bind(&slow);
3936 __ push(r1); 3936 __ push(r1);
3937 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1); 3937 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1);
3938 } 3938 }
3939 3939
3940 3940
3941 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
3942 UNIMPLEMENTED();
3943 }
3944
3945
3946 void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
3947 UNIMPLEMENTED();
3948 }
3949
3950
3951 void ArgumentsAccessStub::GenerateNewNonStrictSlow(MacroAssembler* masm) { 3941 void ArgumentsAccessStub::GenerateNewNonStrictSlow(MacroAssembler* masm) {
3952 // sp[0] : number of parameters 3942 // sp[0] : number of parameters
3953 // sp[4] : receiver displacement 3943 // sp[4] : receiver displacement
3954 // sp[8] : function 3944 // sp[8] : function
3955 3945
3956 // Check if the calling frame is an arguments adaptor frame. 3946 // Check if the calling frame is an arguments adaptor frame.
3947 Label runtime;
3948 __ ldr(r3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
3949 __ ldr(r2, MemOperand(r3, StandardFrameConstants::kContextOffset));
3950 __ cmp(r2, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
3951 __ b(ne, &runtime);
3952
3953 // Patch the arguments.length and the parameters pointer in the current frame.
3954 __ ldr(r2, MemOperand(r3, ArgumentsAdaptorFrameConstants::kLengthOffset));
3955 __ str(r2, MemOperand(sp, 0 * kPointerSize));
3956 __ add(r3, r3, Operand(r2, LSL, 1));
Alexandre 2011/06/15 13:27:56 Here and below, '1' standing for 'kPointerSizeLog2
3957 __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset));
3958 __ str(r3, MemOperand(sp, 1 * kPointerSize));
3959
3960 __ bind(&runtime);
3961 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
3962 }
3963
3964
3965 void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
3966 // Stack layout:
3967 // sp[0] : number of parameters (tagged)
3968 // sp[4] : address of receiver argument
3969 // sp[8] : function
3970 // Registers used over whole function:
3971 // r6 : allocated object (tagged)
3972 // r9 : mapped parameter count (tagged)
3973
3974 __ ldr(r1, MemOperand(sp, 0 * kPointerSize));
3975 // r1 = parameter count (untagged)
Kevin Millikin (Chromium) 2011/06/10 11:51:52 Still says untagged in the change set.
Karl Klose 2011/06/14 12:56:28 Should be done now.
3976
3977 // Check if the calling frame is an arguments adaptor frame.
3978 Label runtime;
3979 Label adaptor_frame, try_allocate;
3980 __ ldr(r3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
3981 __ ldr(r2, MemOperand(r3, StandardFrameConstants::kContextOffset));
3982 __ cmp(r2, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
3983 __ b(eq, &adaptor_frame);
3984
3985 // No adaptor, parameter count = argument count.
3986 __ mov(r2, r1);
3987 __ b(&try_allocate);
3988
3989 // We have an adaptor frame. Patch the parameters pointer.
3990 __ bind(&adaptor_frame);
3991 __ ldr(r2, MemOperand(r3, ArgumentsAdaptorFrameConstants::kLengthOffset));
3992 __ add(r3, r3, Operand(r2, LSL, 1));
3993 __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset));
3994 __ str(r3, MemOperand(sp, 1 * kPointerSize));
3995
3996 // r1 = parameter count (tagged)
3997 // r2 = argument count (tagged)
3998 // Compute the mapped parameter count = min(r1, r2) in r1.
3999 __ cmp(r1, Operand(r2));
4000 __ mov(r1, Operand(r2), LeaveCC, gt);
4001
4002 __ bind(&try_allocate);
4003 // Save mapped parameter count.
4004 __ mov(r9, r1);
Kevin Millikin (Chromium) 2011/06/10 11:51:52 Not a big deal, but you could save the mov(r1, r9)
Karl Klose 2011/06/14 12:56:28 Done.
4005
4006 // Compute the sizes of backing store, parameter map, and arguments object.
4007 // 1. Parameter map, has 2 extra words containing context and backing store.
4008 const int kParameterMapHeaderSize =
4009 FixedArray::kHeaderSize + 2 * kPointerSize;
4010 // If there are no mapped parameters, we do not need the parameter_map.
4011 __ cmp(r1, Operand(Smi::FromInt(0)));
4012 __ mov(r1, Operand(r1, LSL, 1), LeaveCC, ne);
4013 __ add(r1, r1, Operand(kParameterMapHeaderSize), LeaveCC, ne);
4014
4015 // 2. Backing store.
4016 __ add(r1, r1, Operand(r2, LSL, 1));
4017 __ add(r1, r1, Operand(FixedArray::kHeaderSize));
Alexandre 2011/06/15 13:27:56 This add and the following one could be merged int
4018
4019 // 3. Arguments object.
4020 __ add(r1, r1, Operand(Heap::kArgumentsObjectSize));
4021
4022 // Do the allocation of all three objects in one go.
4023 __ AllocateInNewSpace(r1, r0, r3, r4, &runtime, TAG_OBJECT);
4024
4025 // r0 = address of new object(s) (tagged)
4026 // r2 = argument count (tagged)
4027 // Get the arguments boilerplate from the current (global) context into r4.
4028 const int kNormalOffset =
4029 Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX);
4030 const int kAliasedOffset =
4031 Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX);
4032
4033 __ ldr(r4, MemOperand(r8, Context::SlotOffset(Context::GLOBAL_INDEX)));
4034 __ ldr(r4, FieldMemOperand(r4, GlobalObject::kGlobalContextOffset));
4035 __ mov(r1, r9);
4036 __ cmp(r1, Operand(0));
Kevin Millikin (Chromium) 2011/06/10 11:51:52 Operand(Smi::FromInt(0))?
4037 __ ldr(r4, MemOperand(r4, kNormalOffset), eq);
4038 __ ldr(r4, MemOperand(r4, kAliasedOffset), ne);
4039
4040 // r0 = address of new object (tagged)
4041 // r1 = mapped parameter count (tagged)
4042 // r2 = argument count (tagged)
4043 // r4 = address of boilerplate object (tagged)
4044 // Copy the JS object part.
4045 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
4046 __ ldr(r3, FieldMemOperand(r4, i));
4047 __ str(r3, FieldMemOperand(r0, i));
4048 }
4049
4050 // Setup the callee in-object property.
4051 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
4052 __ ldr(r3, MemOperand(sp, 2 * kPointerSize));
4053 const int kCalleeOffset = JSObject::kHeaderSize +
4054 Heap::kArgumentsCalleeIndex * kPointerSize;
4055 __ str(r3, FieldMemOperand(r0, kCalleeOffset));
4056
4057 // Use the length (smi tagged) and set that as an in-object property too.
4058 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
4059 const int kLengthOffset = JSObject::kHeaderSize +
4060 Heap::kArgumentsLengthIndex * kPointerSize;
4061 __ str(r2, FieldMemOperand(r0, kLengthOffset));
4062
4063 // Setup the elements pointer in the allocated arguments object.
4064 // If we allocated a parameter map, r4 will point there, otherwise
4065 // it will point to the backing store.
4066 __ add(r4, r0, Operand(Heap::kArgumentsObjectSize));
4067 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
4068
4069 // r0 = address of new object (tagged)
4070 // r1 = mapped parameter count (tagged)
4071 // r2 = argument count (tagged)
4072 // r4 = address of parameter map or backing store (tagged)
4073
4074 // Initialize parameter map. If there are no mapped arguments, we're done.
4075 Label skip_parameter_map;
4076 __ cmp(r1, Operand(Smi::FromInt(0)));
4077 // Move backing store address to r3, because it is
4078 // expected there when filling in the unmapped arguments.
4079 __ mov(r3, r4, LeaveCC, eq);
4080 __ b(eq, &skip_parameter_map);
4081
4082 __ LoadRoot(r6, Heap::kNonStrictArgumentsElementsMapRootIndex);
4083 __ str(r6, FieldMemOperand(r4, FixedArray::kMapOffset));
4084 __ add(r6, r1, Operand(Smi::FromInt(2)));
4085 __ str(r6, FieldMemOperand(r4, FixedArray::kLengthOffset));
4086 __ str(r8, FieldMemOperand(r4, FixedArray::kHeaderSize + 0 * kPointerSize));
4087 __ add(r6, r4, Operand(r1, LSL, 1));
4088 __ add(r6, r6, Operand(kParameterMapHeaderSize));
4089 __ str(r6, FieldMemOperand(r4, FixedArray::kHeaderSize + 1 * kPointerSize));
4090
4091 // Copy the parameter slots and the holes in the arguments.
4092 // We need to fill in mapped_parameter_count slots. They index the context,
4093 // where parameters are stored in reverse order, at
4094 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1
4095 // The mapped parameter thus need to get indices
4096 // MIN_CONTEXT_SLOTS+parameter_count-1 ..
4097 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count
4098 // We loop from right to left.
4099 Label parameters_loop, parameters_test;
4100 __ mov(r6, r9);
4101 __ ldr(r1, MemOperand(sp, 0 * kPointerSize));
4102 __ add(r1, r1, Operand(Smi::FromInt(Context::MIN_CONTEXT_SLOTS)));
4103 __ sub(r1, r1, Operand(r6));
4104 __ LoadRoot(r7, Heap::kTheHoleValueRootIndex);
4105 __ add(r3, r4, Operand(r6, LSL, 1));
4106 __ add(r3, r3, Operand(kParameterMapHeaderSize));
4107
4108 // r6 = loop variable (tagged)
4109 // r1 = mapping index (tagged)
4110 // r3 = address of backing store (tagged)
4111 // r4 = address of parameter map (tagged)
4112 // r5 = temporary scratch (a.o., for address calculation)
4113 // r7 = the hole value
4114 __ jmp(&parameters_test);
Alexandre 2011/06/15 13:27:56 I don't know how performance sensitive this loop i
4115
4116 __ bind(&parameters_loop);
4117 __ sub(r6, r6, Operand(Smi::FromInt(1)));
4118 __ mov(r5, Operand(r6, LSL, 1));
4119 __ add(r5, r5, Operand(kParameterMapHeaderSize - kHeapObjectTag));
4120 __ str(r1, MemOperand(r4, r5));
4121 __ sub(r5, r5, Operand(kParameterMapHeaderSize - FixedArray::kHeaderSize));
4122 __ str(r7, MemOperand(r3, r5));
4123 __ add(r1, r1, Operand(Smi::FromInt(1)));
4124 __ bind(&parameters_test);
4125 __ cmp(r6, Operand(0));
4126 __ b(ne, &parameters_loop);
4127
4128 __ bind(&skip_parameter_map);
4129 // r2 = argument count (tagged)
4130 // r3 = address of backing store (tagged)
4131 // r5 = scratch
4132 // Copy arguments header and remaining slots (if there are any).
4133 __ LoadRoot(r5, Heap::kFixedArrayMapRootIndex);
4134 __ str(r5, FieldMemOperand(r3, FixedArray::kMapOffset));
4135 __ str(r2, FieldMemOperand(r3, FixedArray::kLengthOffset));
4136
4137 Label arguments_loop, arguments_test;
4138 __ mov(r1, r9);
Alexandre 2011/06/15 13:27:56 If necessary I think this loop could also be refac
4139 __ ldr(r4, MemOperand(sp, 1 * kPointerSize));
4140 __ sub(r4, r4, Operand(r1, LSL, 1));
4141 __ jmp(&arguments_test);
4142
4143 __ bind(&arguments_loop);
4144 __ sub(r4, r4, Operand(kPointerSize));
Alexandre 2011/06/15 13:27:56 The sub can be merged with the ldr using NegPreInd
4145 __ ldr(r6, MemOperand(r4, 0));
4146 __ add(r5, r3, Operand(r1, LSL, 1));
4147 __ str(r6, FieldMemOperand(r5, FixedArray::kHeaderSize));
4148 __ add(r1, r1, Operand(Smi::FromInt(1)));
4149
4150 __ bind(&arguments_test);
4151 __ cmp(r1, Operand(r2));
4152 __ b(lt, &arguments_loop);
4153
4154 // Return and remove the on-stack parameters.
4155 __ add(sp, sp, Operand(3 * kPointerSize));
4156 __ Ret();
4157
4158 // Do the runtime call to allocate the arguments object.
4159 // r2 = argument count (taggged)
4160 __ bind(&runtime);
4161 __ str(r2, MemOperand(sp, 0 * kPointerSize)); // Patch argument count.
4162 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
4163 }
4164
4165
4166 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
4167 // sp[0] : number of parameters
4168 // sp[4] : receiver displacement
4169 // sp[8] : function
4170 // Check if the calling frame is an arguments adaptor frame.
3957 Label adaptor_frame, try_allocate, runtime; 4171 Label adaptor_frame, try_allocate, runtime;
3958 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 4172 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
3959 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); 4173 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset));
3960 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 4174 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
3961 __ b(eq, &adaptor_frame); 4175 __ b(eq, &adaptor_frame);
3962 4176
3963 // Get the length from the frame. 4177 // Get the length from the frame.
3964 __ ldr(r1, MemOperand(sp, 0)); 4178 __ ldr(r1, MemOperand(sp, 0));
3965 __ b(&try_allocate); 4179 __ b(&try_allocate);
3966 4180
3967 // Patch the arguments.length and the parameters pointer. 4181 // Patch the arguments.length and the parameters pointer.
3968 __ bind(&adaptor_frame); 4182 __ bind(&adaptor_frame);
3969 __ ldr(r1, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); 4183 __ ldr(r1, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset));
3970 __ str(r1, MemOperand(sp, 0)); 4184 __ str(r1, MemOperand(sp, 0));
3971 __ add(r3, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize)); 4185 __ add(r3, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize));
3972 __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset)); 4186 __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset));
3973 __ str(r3, MemOperand(sp, 1 * kPointerSize)); 4187 __ str(r3, MemOperand(sp, 1 * kPointerSize));
3974 4188
3975 // Try the new space allocation. Start out with computing the size 4189 // Try the new space allocation. Start out with computing the size
3976 // of the arguments object and the elements array in words. 4190 // of the arguments object and the elements array in words.
3977 Label add_arguments_object; 4191 Label add_arguments_object;
3978 __ bind(&try_allocate); 4192 __ bind(&try_allocate);
3979 if (type_ == NEW_NON_STRICT_SLOW || type_ == NEW_NON_STRICT_FAST) { 4193 __ cmp(r1, Operand(0, RelocInfo::NONE));
3980 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1); 4194 __ b(eq, &add_arguments_object);
3981 } else { 4195 __ mov(r1, Operand(r1, LSR, kSmiTagSize));
3982 __ cmp(r1, Operand(0, RelocInfo::NONE)); 4196 __ add(r1, r1, Operand(FixedArray::kHeaderSize / kPointerSize));
3983 __ b(eq, &add_arguments_object); 4197 __ bind(&add_arguments_object);
3984 __ mov(r1, Operand(r1, LSR, kSmiTagSize)); 4198 __ add(r1, r1, Operand(Heap::kArgumentsObjectSizeStrict / kPointerSize));
3985 __ add(r1, r1, Operand(FixedArray::kHeaderSize / kPointerSize));
3986 __ bind(&add_arguments_object);
3987 __ add(r1, r1, Operand(Heap::kArgumentsObjectSizeStrict / kPointerSize));
3988 4199
3989 // Do the allocation of both objects in one go. 4200 // Do the allocation of both objects in one go.
3990 __ AllocateInNewSpace( 4201 __ AllocateInNewSpace(r1,
3991 r1, 4202 r0,
3992 r0, 4203 r2,
3993 r2, 4204 r3,
3994 r3, 4205 &runtime,
3995 &runtime, 4206 static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS) );
3996 static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS));
3997 4207
3998 // Get the arguments boilerplate from the current (global) context. 4208 // Get the arguments boilerplate from the current (global) context.
3999 __ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); 4209 __ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
4000 __ ldr(r4, FieldMemOperand(r4, GlobalObject::kGlobalContextOffset)); 4210 __ ldr(r4, FieldMemOperand(r4, GlobalObject::kGlobalContextOffset));
4001 __ ldr(r4, MemOperand(r4, Context::SlotOffset( 4211 __ ldr(r4, MemOperand(r4, Context::SlotOffset(
4002 Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX))); 4212 Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX)));
4003 4213
4004 // Copy the JS object part. 4214 // Copy the JS object part.
4005 __ CopyFields(r0, r4, r3.bit(), JSObject::kHeaderSize / kPointerSize); 4215 __ CopyFields(r0, r4, r3.bit(), JSObject::kHeaderSize / kPointerSize);
4006 4216
4007 if (type_ == NEW_NON_STRICT_SLOW || type_ == NEW_NON_STRICT_FAST) { 4217 // Get the length (smi tagged) and set that as an in-object property too.
4008 // Setup the callee in-object property. 4218 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
4009 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); 4219 __ ldr(r1, MemOperand(sp, 0 * kPointerSize));
4010 __ ldr(r3, MemOperand(sp, 2 * kPointerSize)); 4220 __ str(r1, FieldMemOperand(r0, JSObject::kHeaderSize +
4011 const int kCalleeOffset = JSObject::kHeaderSize + 4221 Heap::kArgumentsLengthIndex * kPointerSize));
4012 Heap::kArgumentsCalleeIndex * kPointerSize;
4013 __ str(r3, FieldMemOperand(r0, kCalleeOffset));
4014 }
4015 4222
4016 // Get the length (smi tagged) and set that as an in-object property too. 4223 // If there are no actual arguments, we're done.
4017 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); 4224 Label done;
4018 __ ldr(r1, MemOperand(sp, 0 * kPointerSize)); 4225 __ cmp(r1, Operand(0, RelocInfo::NONE));
4019 __ str(r1, FieldMemOperand(r0, JSObject::kHeaderSize + 4226 __ b(eq, &done);
4020 Heap::kArgumentsLengthIndex * kPointerSize));
4021 4227
4022 // If there are no actual arguments, we're done. 4228 // Get the parameters pointer from the stack.
4023 Label done; 4229 __ ldr(r2, MemOperand(sp, 1 * kPointerSize));
4024 __ cmp(r1, Operand(0, RelocInfo::NONE));
4025 __ b(eq, &done);
4026 4230
4027 // Get the parameters pointer from the stack. 4231 // Setup the elements pointer in the allocated arguments object and
4028 __ ldr(r2, MemOperand(sp, 1 * kPointerSize)); 4232 // initialize the header in the elements fixed array.
4233 __ add(r4, r0, Operand(Heap::kArgumentsObjectSizeStrict));
4234 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
4235 __ LoadRoot(r3, Heap::kFixedArrayMapRootIndex);
4236 __ str(r3, FieldMemOperand(r4, FixedArray::kMapOffset));
4237 __ str(r1, FieldMemOperand(r4, FixedArray::kLengthOffset));
4238 // Untag the length for the loop.
4239 __ mov(r1, Operand(r1, LSR, kSmiTagSize));
Alexandre 2011/06/15 13:27:56 If r1 is only used as a counter and not used later
4029 4240
4030 // Setup the elements pointer in the allocated arguments object and 4241 // Copy the fixed array slots.
4031 // initialize the header in the elements fixed array. 4242 Label loop;
4032 __ add(r4, r0, Operand(Heap::kArgumentsObjectSizeStrict)); 4243 // Setup r4 to point to the first array slot.
4033 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset)); 4244 __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
4034 __ LoadRoot(r3, Heap::kFixedArrayMapRootIndex); 4245 __ bind(&loop);
4035 __ str(r3, FieldMemOperand(r4, FixedArray::kMapOffset)); 4246 // Pre-decrement r2 with kPointerSize on each iteration.
4036 __ str(r1, FieldMemOperand(r4, FixedArray::kLengthOffset)); 4247 // Pre-decrement in order to skip receiver.
4037 // Untag the length for the loop. 4248 __ ldr(r3, MemOperand(r2, kPointerSize, NegPreIndex));
4038 __ mov(r1, Operand(r1, LSR, kSmiTagSize)); 4249 // Post-increment r4 with kPointerSize on each iteration.
4250 __ str(r3, MemOperand(r4, kPointerSize, PostIndex));
4251 __ sub(r1, r1, Operand(1));
4252 __ cmp(r1, Operand(0, RelocInfo::NONE));
Alexandre 2011/06/15 13:27:56 Could merge the 'sub' and 'cmp' instructions into
4253 __ b(ne, &loop);
4039 4254
4040 // Copy the fixed array slots. 4255 // Return and remove the on-stack parameters.
4041 Label loop; 4256 __ bind(&done);
4042 // Setup r4 to point to the first array slot. 4257 __ add(sp, sp, Operand(3 * kPointerSize));
4043 __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 4258 __ Ret();
4044 __ bind(&loop);
4045 // Pre-decrement r2 with kPointerSize on each iteration.
4046 // Pre-decrement in order to skip receiver.
4047 __ ldr(r3, MemOperand(r2, kPointerSize, NegPreIndex));
4048 // Post-increment r4 with kPointerSize on each iteration.
4049 __ str(r3, MemOperand(r4, kPointerSize, PostIndex));
4050 __ sub(r1, r1, Operand(1));
4051 __ cmp(r1, Operand(0, RelocInfo::NONE));
4052 __ b(ne, &loop);
4053 4259
4054 // Return and remove the on-stack parameters. 4260 // Do the runtime call to allocate the arguments object.
4055 __ bind(&done); 4261 __ bind(&runtime);
4056 __ add(sp, sp, Operand(3 * kPointerSize)); 4262 __ TailCallRuntime(Runtime::kNewStrictArgumentsFast, 3, 1);
4057 __ Ret();
4058
4059 // Do the runtime call to allocate the arguments object.
4060 __ bind(&runtime);
4061 __ TailCallRuntime(Runtime::kNewStrictArgumentsFast, 3, 1);
4062 }
4063 } 4263 }
4064 4264
4065 4265
4066 void RegExpExecStub::Generate(MacroAssembler* masm) { 4266 void RegExpExecStub::Generate(MacroAssembler* masm) {
4067 // Just jump directly to runtime if native RegExp is not selected at compile 4267 // Just jump directly to runtime if native RegExp is not selected at compile
4068 // time or if regexp entry in generated code is turned off runtime switch or 4268 // time or if regexp entry in generated code is turned off runtime switch or
4069 // at compilation. 4269 // at compilation.
4070 #ifdef V8_INTERPRETED_REGEXP 4270 #ifdef V8_INTERPRETED_REGEXP
4071 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); 4271 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
4072 #else // V8_INTERPRETED_REGEXP 4272 #else // V8_INTERPRETED_REGEXP
(...skipping 2352 matching lines...) Expand 10 before | Expand all | Expand 10 after
6425 __ mov(result, Operand(0)); 6625 __ mov(result, Operand(0));
6426 __ Ret(); 6626 __ Ret();
6427 } 6627 }
6428 6628
6429 6629
6430 #undef __ 6630 #undef __
6431 6631
6432 } } // namespace v8::internal 6632 } } // namespace v8::internal
6433 6633
6434 #endif // V8_TARGET_ARCH_ARM 6634 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/accessors.cc ('k') | src/arm/full-codegen-arm.cc » ('j') | src/x64/code-stubs-x64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698