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

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: Better ARM code. 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));
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 // r1 = parameter count (untagged)
Kevin Millikin (Chromium) 2011/06/07 13:54:10 (untagged) ==> (tagged)
Karl Klose 2011/06/10 11:32:22 Done.
3975 __ ldr(r1, MemOperand(sp, 0 * kPointerSize));
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);
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(0));
Kevin Millikin (Chromium) 2011/06/07 13:54:10 Since r1 is tagged, can we use Smi::FromInt(0)?
Karl Klose 2011/06/10 11:32:22 Done.
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));
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 __ SmiUntag(r1);
Kevin Millikin (Chromium) 2011/06/07 13:54:10 Hmm, if I correctly follow this, the untagged r1 i
Karl Klose 2011/06/10 11:32:22 Done.
4037 __ cmp(r1, Operand(0));
4038 __ ldr(r4, MemOperand(r4, kNormalOffset), eq);
4039 __ ldr(r4, MemOperand(r4, kAliasedOffset), ne);
4040
4041 // r0 = address of new object (tagged)
4042 // r1 = mapped parameter count (untagged)
4043 // r2 = argument count (untagged)
Kevin Millikin (Chromium) 2011/06/07 13:54:10 (untagged) ==> (tagged)
Karl Klose 2011/06/10 11:32:22 Done.
4044 // r4 = address of boilerplate object (tagged)
4045 // Copy the JS object part.
4046 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
4047 __ ldr(r3, FieldMemOperand(r4, i));
4048 __ str(r3, FieldMemOperand(r0, i));
4049 }
4050
4051 // Setup the callee in-object property.
4052 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
4053 __ ldr(r3, MemOperand(sp, 2 * kPointerSize));
4054 const int kCalleeOffset = JSObject::kHeaderSize +
4055 Heap::kArgumentsCalleeIndex * kPointerSize;
4056 __ str(r3, FieldMemOperand(r0, kCalleeOffset));
4057
4058 // Use the length (smi tagged) and set that as an in-object property too.
4059 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
4060 const int kLengthOffset = JSObject::kHeaderSize +
4061 Heap::kArgumentsLengthIndex * kPointerSize;
4062 __ str(r2, FieldMemOperand(r0, kLengthOffset));
4063
4064 // Setup the elements pointer in the allocated arguments object.
4065 // If we allocated a parameter map, r4 will point there, otherwise
4066 // it will point to the backing store.
4067 __ add(r4, r0, Operand(Heap::kArgumentsObjectSize));
4068 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
4069
4070 // r0 = address of new object (tagged)
4071 // r1 = mapped parameter count (untagged)
4072 // r2 = argument count (tagged)
4073 // r4 = address of parameter map or backing store (tagged)
4074 __ mov(r6, r0);
Kevin Millikin (Chromium) 2011/06/07 13:54:10 This mov might be unnecessary. Can r6 be used ins
4075
4076 // Initialize parameter map. If there are no mapped arguments, we're done.
4077 Label skip_parameter_map;
4078 __ cmp(r1, Operand(0));
4079 __ b(eq, &skip_parameter_map);
4080
4081 __ LoadRoot(r0, Heap::kNonStrictArgumentsElementsMapRootIndex);
4082 __ str(r0, FieldMemOperand(r4, FixedArray::kMapOffset));
4083 __ add(r0, r1, Operand(2));
4084 __ SmiTag(r0);
4085 __ str(r0, FieldMemOperand(r4, FixedArray::kLengthOffset));
4086 __ str(r8, FieldMemOperand(r4, FixedArray::kHeaderSize + 0 * kPointerSize));
4087 __ add(r0, r4, Operand(r1, LSL, 2));
4088 __ add(r0, r0, Operand(kParameterMapHeaderSize));
4089 __ str(r0, 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(r0, r9);
4101 __ ldr(r1, MemOperand(sp, 0 * kPointerSize));
4102 __ add(r1, r1, Operand(Smi::FromInt(Context::MIN_CONTEXT_SLOTS)));
4103 __ sub(r1, r1, Operand(r0));
4104 __ LoadRoot(r7, Heap::kTheHoleValueRootIndex);
4105 __ mov(r3, r4);
Kevin Millikin (Chromium) 2011/06/07 13:54:10 Can we avoid this mov by using r3 instead of r4 be
Karl Klose 2011/06/10 11:32:22 Done. The tricky part is that this code can be jum
4106 __ mov(r5, r0);
4107 __ SmiUntag(r5);
Kevin Millikin (Chromium) 2011/06/07 13:54:10 Is this untagged and retagged at its use? Maybe m
Karl Klose 2011/06/10 11:32:22 You are right, this is unnecessary.
4108 __ add(r4, r4, Operand(r5, LSL, 2));
4109 __ add(r4, r4, Operand(kParameterMapHeaderSize));
4110
4111 // r0 = loop variable (tagged)
4112 // r1 = mapping index (tagged)
4113 // r3 = address of parameter map (tagged)
4114 // r4 = address of backing store (tagged)
4115 // r5 = temporary scratch (a.o., for address calculation)
4116 // r7 = the hole value
4117 __ jmp(&parameters_test);
4118
4119 __ bind(&parameters_loop);
4120 __ sub(r0, r0, Operand(Smi::FromInt(1)));
4121 __ mov(r5, Operand(r0, LSL, 1));
Kevin Millikin (Chromium) 2011/06/07 13:54:10 The computation of this value in r5 is duplicated
Karl Klose 2011/06/10 11:32:22 Done. It makes the code slightly harder to underst
4122 __ add(r5, r5, Operand(kParameterMapHeaderSize - kHeapObjectTag));
4123 __ str(r1, MemOperand(r3, r5));
4124 __ mov(r5, Operand(r0, LSL, 1));
4125 __ add(r5, r5, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
4126 __ str(r7, MemOperand(r4, r5));
4127 __ add(r1, r1, Operand(Smi::FromInt(1)));
4128 __ bind(&parameters_test);
4129 __ cmp(r0, Operand(0));
4130 __ b(ne, &parameters_loop);
4131
4132 __ bind(&skip_parameter_map);
4133 // r2 = argument count (tagged)
4134 // r4 = address of backing store (tagged)
4135 // r5 = scratch
4136 // Copy arguments header and remaining slots (if there are any).
4137 __ LoadRoot(r5, Heap::kFixedArrayMapRootIndex);
4138 __ str(r5, FieldMemOperand(r4, FixedArray::kMapOffset));
4139 __ str(r2, FieldMemOperand(r4, FixedArray::kLengthOffset));
4140
4141 Label arguments_loop, arguments_test;
4142 __ mov(r1, r9);
4143 __ ldr(r3, MemOperand(sp, 1 * kPointerSize));
4144 __ sub(r3, r3, Operand(r1, LSL, 1));
4145 __ jmp(&arguments_test);
4146
4147 __ bind(&arguments_loop);
4148 __ sub(r3, r3, Operand(kPointerSize));
4149 __ ldr(r0, MemOperand(r3, 0));
4150 __ add(r5, r4, Operand(r1, LSL, 1));
4151 __ str(r0, FieldMemOperand(r5, FixedArray::kHeaderSize));
4152 __ add(r1, r1, Operand(Smi::FromInt(1)));
4153
4154 __ bind(&arguments_test);
4155 __ cmp(r1, Operand(r2));
4156 __ b(lt, &arguments_loop);
4157
4158 // Return and remove the on-stack parameters.
4159 __ add(sp, sp, Operand(3 * kPointerSize));
4160 __ mov(r0, r6);
4161 __ Ret();
4162
4163 // Do the runtime call to allocate the arguments object.
4164 // r2 = argument count (taggged)
4165 __ bind(&runtime);
4166 __ str(r2, MemOperand(sp, 0 * kPointerSize)); // Patch argument count.
4167 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
4168 }
4169
4170
4171 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
4172 // sp[0] : number of parameters
4173 // sp[4] : receiver displacement
4174 // sp[8] : function
4175 // Check if the calling frame is an arguments adaptor frame.
3957 Label adaptor_frame, try_allocate, runtime; 4176 Label adaptor_frame, try_allocate, runtime;
3958 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 4177 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
3959 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); 4178 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset));
3960 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 4179 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
3961 __ b(eq, &adaptor_frame); 4180 __ b(eq, &adaptor_frame);
3962 4181
3963 // Get the length from the frame. 4182 // Get the length from the frame.
3964 __ ldr(r1, MemOperand(sp, 0)); 4183 __ ldr(r1, MemOperand(sp, 0));
3965 __ b(&try_allocate); 4184 __ b(&try_allocate);
3966 4185
3967 // Patch the arguments.length and the parameters pointer. 4186 // Patch the arguments.length and the parameters pointer.
3968 __ bind(&adaptor_frame); 4187 __ bind(&adaptor_frame);
3969 __ ldr(r1, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); 4188 __ ldr(r1, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset));
3970 __ str(r1, MemOperand(sp, 0)); 4189 __ str(r1, MemOperand(sp, 0));
3971 __ add(r3, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize)); 4190 __ add(r3, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize));
3972 __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset)); 4191 __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset));
3973 __ str(r3, MemOperand(sp, 1 * kPointerSize)); 4192 __ str(r3, MemOperand(sp, 1 * kPointerSize));
3974 4193
3975 // Try the new space allocation. Start out with computing the size 4194 // Try the new space allocation. Start out with computing the size
3976 // of the arguments object and the elements array in words. 4195 // of the arguments object and the elements array in words.
3977 Label add_arguments_object; 4196 Label add_arguments_object;
3978 __ bind(&try_allocate); 4197 __ bind(&try_allocate);
3979 if (type_ == NEW_NON_STRICT_SLOW || type_ == NEW_NON_STRICT_FAST) { 4198 __ cmp(r1, Operand(0, RelocInfo::NONE));
3980 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1); 4199 __ b(eq, &add_arguments_object);
3981 } else { 4200 __ mov(r1, Operand(r1, LSR, kSmiTagSize));
3982 __ cmp(r1, Operand(0, RelocInfo::NONE)); 4201 __ add(r1, r1, Operand(FixedArray::kHeaderSize / kPointerSize));
3983 __ b(eq, &add_arguments_object); 4202 __ bind(&add_arguments_object);
3984 __ mov(r1, Operand(r1, LSR, kSmiTagSize)); 4203 __ 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 4204
3989 // Do the allocation of both objects in one go. 4205 // Do the allocation of both objects in one go.
3990 __ AllocateInNewSpace( 4206 __ AllocateInNewSpace(r1,
3991 r1, 4207 r0,
3992 r0, 4208 r2,
3993 r2, 4209 r3,
3994 r3, 4210 &runtime,
3995 &runtime, 4211 static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS) );
3996 static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS));
3997 4212
3998 // Get the arguments boilerplate from the current (global) context. 4213 // Get the arguments boilerplate from the current (global) context.
3999 __ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); 4214 __ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
4000 __ ldr(r4, FieldMemOperand(r4, GlobalObject::kGlobalContextOffset)); 4215 __ ldr(r4, FieldMemOperand(r4, GlobalObject::kGlobalContextOffset));
4001 __ ldr(r4, MemOperand(r4, Context::SlotOffset( 4216 __ ldr(r4, MemOperand(r4, Context::SlotOffset(
4002 Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX))); 4217 Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX)));
4003 4218
4004 // Copy the JS object part. 4219 // Copy the JS object part.
4005 __ CopyFields(r0, r4, r3.bit(), JSObject::kHeaderSize / kPointerSize); 4220 __ CopyFields(r0, r4, r3.bit(), JSObject::kHeaderSize / kPointerSize);
4006 4221
4007 if (type_ == NEW_NON_STRICT_SLOW || type_ == NEW_NON_STRICT_FAST) { 4222 // Get the length (smi tagged) and set that as an in-object property too.
4008 // Setup the callee in-object property. 4223 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
4009 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); 4224 __ ldr(r1, MemOperand(sp, 0 * kPointerSize));
4010 __ ldr(r3, MemOperand(sp, 2 * kPointerSize)); 4225 __ str(r1, FieldMemOperand(r0, JSObject::kHeaderSize +
4011 const int kCalleeOffset = JSObject::kHeaderSize + 4226 Heap::kArgumentsLengthIndex * kPointerSize));
4012 Heap::kArgumentsCalleeIndex * kPointerSize;
4013 __ str(r3, FieldMemOperand(r0, kCalleeOffset));
4014 }
4015 4227
4016 // Get the length (smi tagged) and set that as an in-object property too. 4228 // If there are no actual arguments, we're done.
4017 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); 4229 Label done;
4018 __ ldr(r1, MemOperand(sp, 0 * kPointerSize)); 4230 __ cmp(r1, Operand(0, RelocInfo::NONE));
4019 __ str(r1, FieldMemOperand(r0, JSObject::kHeaderSize + 4231 __ b(eq, &done);
4020 Heap::kArgumentsLengthIndex * kPointerSize));
4021 4232
4022 // If there are no actual arguments, we're done. 4233 // Get the parameters pointer from the stack.
4023 Label done; 4234 __ ldr(r2, MemOperand(sp, 1 * kPointerSize));
4024 __ cmp(r1, Operand(0, RelocInfo::NONE));
4025 __ b(eq, &done);
4026 4235
4027 // Get the parameters pointer from the stack. 4236 // Setup the elements pointer in the allocated arguments object and
4028 __ ldr(r2, MemOperand(sp, 1 * kPointerSize)); 4237 // initialize the header in the elements fixed array.
4238 __ add(r4, r0, Operand(Heap::kArgumentsObjectSizeStrict));
4239 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
4240 __ LoadRoot(r3, Heap::kFixedArrayMapRootIndex);
4241 __ str(r3, FieldMemOperand(r4, FixedArray::kMapOffset));
4242 __ str(r1, FieldMemOperand(r4, FixedArray::kLengthOffset));
4243 // Untag the length for the loop.
4244 __ mov(r1, Operand(r1, LSR, kSmiTagSize));
4029 4245
4030 // Setup the elements pointer in the allocated arguments object and 4246 // Copy the fixed array slots.
4031 // initialize the header in the elements fixed array. 4247 Label loop;
4032 __ add(r4, r0, Operand(Heap::kArgumentsObjectSizeStrict)); 4248 // Setup r4 to point to the first array slot.
4033 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset)); 4249 __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
4034 __ LoadRoot(r3, Heap::kFixedArrayMapRootIndex); 4250 __ bind(&loop);
4035 __ str(r3, FieldMemOperand(r4, FixedArray::kMapOffset)); 4251 // Pre-decrement r2 with kPointerSize on each iteration.
4036 __ str(r1, FieldMemOperand(r4, FixedArray::kLengthOffset)); 4252 // Pre-decrement in order to skip receiver.
4037 // Untag the length for the loop. 4253 __ ldr(r3, MemOperand(r2, kPointerSize, NegPreIndex));
4038 __ mov(r1, Operand(r1, LSR, kSmiTagSize)); 4254 // Post-increment r4 with kPointerSize on each iteration.
4255 __ str(r3, MemOperand(r4, kPointerSize, PostIndex));
4256 __ sub(r1, r1, Operand(1));
4257 __ cmp(r1, Operand(0, RelocInfo::NONE));
4258 __ b(ne, &loop);
4039 4259
4040 // Copy the fixed array slots. 4260 // Return and remove the on-stack parameters.
4041 Label loop; 4261 __ bind(&done);
4042 // Setup r4 to point to the first array slot. 4262 __ add(sp, sp, Operand(3 * kPointerSize));
4043 __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 4263 __ 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 4264
4054 // Return and remove the on-stack parameters. 4265 // Do the runtime call to allocate the arguments object.
4055 __ bind(&done); 4266 __ bind(&runtime);
4056 __ add(sp, sp, Operand(3 * kPointerSize)); 4267 __ 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 } 4268 }
4064 4269
4065 4270
4066 void RegExpExecStub::Generate(MacroAssembler* masm) { 4271 void RegExpExecStub::Generate(MacroAssembler* masm) {
4067 // Just jump directly to runtime if native RegExp is not selected at compile 4272 // 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 4273 // time or if regexp entry in generated code is turned off runtime switch or
4069 // at compilation. 4274 // at compilation.
4070 #ifdef V8_INTERPRETED_REGEXP 4275 #ifdef V8_INTERPRETED_REGEXP
4071 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); 4276 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
4072 #else // V8_INTERPRETED_REGEXP 4277 #else // V8_INTERPRETED_REGEXP
(...skipping 2352 matching lines...) Expand 10 before | Expand all | Expand 10 after
6425 __ mov(result, Operand(0)); 6630 __ mov(result, Operand(0));
6426 __ Ret(); 6631 __ Ret();
6427 } 6632 }
6428 6633
6429 6634
6430 #undef __ 6635 #undef __
6431 6636
6432 } } // namespace v8::internal 6637 } } // namespace v8::internal
6433 6638
6434 #endif // V8_TARGET_ARCH_ARM 6639 #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