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)); | |
|
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(¶meters_test); | |
|
Alexandre
2011/06/15 13:27:56
I don't know how performance sensitive this loop i
| |
| 4115 | |
| 4116 __ bind(¶meters_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(¶meters_test); | |
| 4125 __ cmp(r6, Operand(0)); | |
| 4126 __ b(ne, ¶meters_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 Loading... | |
| 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 |
| OLD | NEW |