Chromium Code Reviews| 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 3920 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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(¶meters_test); | |
| 4118 | |
| 4119 __ bind(¶meters_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(¶meters_test); | |
| 4129 __ cmp(r0, Operand(0)); | |
| 4130 __ b(ne, ¶meters_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 Loading... | |
| 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 |
| OLD | NEW |