OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_X87 | 5 #if V8_TARGET_ARCH_X87 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 2125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2136 // ----------- S t a t e ------------- | 2136 // ----------- S t a t e ------------- |
2137 // -- eax : argumentsList | 2137 // -- eax : argumentsList |
2138 // -- edi : target | 2138 // -- edi : target |
2139 // -- edx : new.target (checked to be constructor or undefined) | 2139 // -- edx : new.target (checked to be constructor or undefined) |
2140 // -- esp[0] : return address. | 2140 // -- esp[0] : return address. |
2141 // -- esp[4] : thisArgument | 2141 // -- esp[4] : thisArgument |
2142 // ----------------------------------- | 2142 // ----------------------------------- |
2143 | 2143 |
2144 // Create the list of arguments from the array-like argumentsList. | 2144 // Create the list of arguments from the array-like argumentsList. |
2145 { | 2145 { |
2146 Label create_arguments, create_array, create_runtime, done_create; | 2146 Label create_arguments, create_array, create_holey_array, create_runtime, |
| 2147 done_create; |
2147 __ JumpIfSmi(eax, &create_runtime); | 2148 __ JumpIfSmi(eax, &create_runtime); |
2148 | 2149 |
2149 // Load the map of argumentsList into ecx. | 2150 // Load the map of argumentsList into ecx. |
2150 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); | 2151 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); |
2151 | 2152 |
2152 // Load native context into ebx. | 2153 // Load native context into ebx. |
2153 __ mov(ebx, NativeContextOperand()); | 2154 __ mov(ebx, NativeContextOperand()); |
2154 | 2155 |
2155 // Check if argumentsList is an (unmodified) arguments object. | 2156 // Check if argumentsList is an (unmodified) arguments object. |
2156 __ cmp(ecx, ContextOperand(ebx, Context::SLOPPY_ARGUMENTS_MAP_INDEX)); | 2157 __ cmp(ecx, ContextOperand(ebx, Context::SLOPPY_ARGUMENTS_MAP_INDEX)); |
(...skipping 23 matching lines...) Expand all Loading... |
2180 // Try to create the list from an arguments object. | 2181 // Try to create the list from an arguments object. |
2181 __ bind(&create_arguments); | 2182 __ bind(&create_arguments); |
2182 __ mov(ebx, FieldOperand(eax, JSArgumentsObject::kLengthOffset)); | 2183 __ mov(ebx, FieldOperand(eax, JSArgumentsObject::kLengthOffset)); |
2183 __ mov(ecx, FieldOperand(eax, JSObject::kElementsOffset)); | 2184 __ mov(ecx, FieldOperand(eax, JSObject::kElementsOffset)); |
2184 __ cmp(ebx, FieldOperand(ecx, FixedArray::kLengthOffset)); | 2185 __ cmp(ebx, FieldOperand(ecx, FixedArray::kLengthOffset)); |
2185 __ j(not_equal, &create_runtime); | 2186 __ j(not_equal, &create_runtime); |
2186 __ SmiUntag(ebx); | 2187 __ SmiUntag(ebx); |
2187 __ mov(eax, ecx); | 2188 __ mov(eax, ecx); |
2188 __ jmp(&done_create); | 2189 __ jmp(&done_create); |
2189 | 2190 |
| 2191 // For holey JSArrays we need to check that the array prototype chain |
| 2192 // protector is intact and our prototype is the Array.prototype actually. |
| 2193 __ bind(&create_holey_array); |
| 2194 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); |
| 2195 __ mov(ecx, FieldOperand(ecx, Map::kPrototypeOffset)); |
| 2196 __ cmp(ecx, ContextOperand(ebx, Context::INITIAL_ARRAY_PROTOTYPE_INDEX)); |
| 2197 __ j(not_equal, &create_runtime); |
| 2198 __ LoadRoot(ecx, Heap::kArrayProtectorRootIndex); |
| 2199 __ cmp(FieldOperand(ecx, PropertyCell::kValueOffset), |
| 2200 Immediate(Smi::FromInt(Isolate::kProtectorValid))); |
| 2201 __ j(not_equal, &create_runtime); |
| 2202 __ mov(ebx, FieldOperand(eax, JSArray::kLengthOffset)); |
| 2203 __ SmiUntag(ebx); |
| 2204 __ mov(eax, FieldOperand(eax, JSArray::kElementsOffset)); |
| 2205 __ jmp(&done_create); |
| 2206 |
2190 // Try to create the list from a JSArray object. | 2207 // Try to create the list from a JSArray object. |
2191 __ bind(&create_array); | 2208 __ bind(&create_array); |
2192 __ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset)); | 2209 __ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset)); |
2193 __ DecodeField<Map::ElementsKindBits>(ecx); | 2210 __ DecodeField<Map::ElementsKindBits>(ecx); |
2194 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | 2211 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); |
2195 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | 2212 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
2196 STATIC_ASSERT(FAST_ELEMENTS == 2); | 2213 STATIC_ASSERT(FAST_ELEMENTS == 2); |
2197 __ cmp(ecx, Immediate(FAST_ELEMENTS)); | 2214 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); |
| 2215 __ cmp(ecx, Immediate(FAST_HOLEY_SMI_ELEMENTS)); |
| 2216 __ j(equal, &create_holey_array, Label::kNear); |
| 2217 __ cmp(ecx, Immediate(FAST_HOLEY_ELEMENTS)); |
| 2218 __ j(equal, &create_holey_array, Label::kNear); |
2198 __ j(above, &create_runtime); | 2219 __ j(above, &create_runtime); |
2199 __ cmp(ecx, Immediate(FAST_HOLEY_SMI_ELEMENTS)); | |
2200 __ j(equal, &create_runtime); | |
2201 __ mov(ebx, FieldOperand(eax, JSArray::kLengthOffset)); | 2220 __ mov(ebx, FieldOperand(eax, JSArray::kLengthOffset)); |
2202 __ SmiUntag(ebx); | 2221 __ SmiUntag(ebx); |
2203 __ mov(eax, FieldOperand(eax, JSArray::kElementsOffset)); | 2222 __ mov(eax, FieldOperand(eax, JSArray::kElementsOffset)); |
2204 | 2223 |
2205 __ bind(&done_create); | 2224 __ bind(&done_create); |
2206 } | 2225 } |
2207 | 2226 |
2208 // Check for stack overflow. | 2227 // Check for stack overflow. |
2209 { | 2228 { |
2210 // Check the stack for overflow. We are not trying to catch interruptions | 2229 // Check the stack for overflow. We are not trying to catch interruptions |
(...skipping 18 matching lines...) Expand all Loading... |
2229 // -- edi : target | 2248 // -- edi : target |
2230 // -- eax : args (a FixedArray built from argumentsList) | 2249 // -- eax : args (a FixedArray built from argumentsList) |
2231 // -- ebx : len (number of elements to push from args) | 2250 // -- ebx : len (number of elements to push from args) |
2232 // -- edx : new.target (checked to be constructor or undefined) | 2251 // -- edx : new.target (checked to be constructor or undefined) |
2233 // -- esp[0] : return address. | 2252 // -- esp[0] : return address. |
2234 // -- esp[4] : thisArgument | 2253 // -- esp[4] : thisArgument |
2235 // ----------------------------------- | 2254 // ----------------------------------- |
2236 | 2255 |
2237 // Push arguments onto the stack (thisArgument is already on the stack). | 2256 // Push arguments onto the stack (thisArgument is already on the stack). |
2238 { | 2257 { |
| 2258 // Save edx/edi to stX0/stX1. |
2239 __ push(edx); | 2259 __ push(edx); |
| 2260 __ push(edi); |
2240 __ fld_s(MemOperand(esp, 0)); | 2261 __ fld_s(MemOperand(esp, 0)); |
2241 __ lea(esp, Operand(esp, kFloatSize)); | 2262 __ fld_s(MemOperand(esp, 4)); |
| 2263 __ lea(esp, Operand(esp, 2 * kFloatSize)); |
2242 | 2264 |
2243 __ PopReturnAddressTo(edx); | 2265 __ PopReturnAddressTo(edx); |
2244 __ Move(ecx, Immediate(0)); | 2266 __ Move(ecx, Immediate(0)); |
2245 Label done, loop; | 2267 Label done, push, loop; |
2246 __ bind(&loop); | 2268 __ bind(&loop); |
2247 __ cmp(ecx, ebx); | 2269 __ cmp(ecx, ebx); |
2248 __ j(equal, &done, Label::kNear); | 2270 __ j(equal, &done, Label::kNear); |
2249 __ Push( | 2271 // Turn the hole into undefined as we go. |
2250 FieldOperand(eax, ecx, times_pointer_size, FixedArray::kHeaderSize)); | 2272 __ mov(edi, |
| 2273 FieldOperand(eax, ecx, times_pointer_size, FixedArray::kHeaderSize)); |
| 2274 __ CompareRoot(edi, Heap::kTheHoleValueRootIndex); |
| 2275 __ j(not_equal, &push, Label::kNear); |
| 2276 __ LoadRoot(edi, Heap::kUndefinedValueRootIndex); |
| 2277 __ bind(&push); |
| 2278 __ Push(edi); |
2251 __ inc(ecx); | 2279 __ inc(ecx); |
2252 __ jmp(&loop); | 2280 __ jmp(&loop); |
2253 __ bind(&done); | 2281 __ bind(&done); |
2254 __ PushReturnAddressFrom(edx); | 2282 __ PushReturnAddressFrom(edx); |
2255 | 2283 |
2256 __ lea(esp, Operand(esp, -kFloatSize)); | 2284 // Restore edx/edi from stX0/stX1. |
| 2285 __ lea(esp, Operand(esp, -2 * kFloatSize)); |
2257 __ fstp_s(MemOperand(esp, 0)); | 2286 __ fstp_s(MemOperand(esp, 0)); |
| 2287 __ fstp_s(MemOperand(esp, 4)); |
2258 __ pop(edx); | 2288 __ pop(edx); |
| 2289 __ pop(edi); |
2259 | 2290 |
2260 __ Move(eax, ebx); | 2291 __ Move(eax, ebx); |
2261 } | 2292 } |
2262 | 2293 |
2263 // Dispatch to Call or Construct depending on whether new.target is undefined. | 2294 // Dispatch to Call or Construct depending on whether new.target is undefined. |
2264 { | 2295 { |
2265 __ CompareRoot(edx, Heap::kUndefinedValueRootIndex); | 2296 __ CompareRoot(edx, Heap::kUndefinedValueRootIndex); |
2266 __ j(equal, masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 2297 __ j(equal, masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
2267 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2298 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
2268 } | 2299 } |
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3087 | 3118 |
3088 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { | 3119 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { |
3089 Generate_OnStackReplacementHelper(masm, true); | 3120 Generate_OnStackReplacementHelper(masm, true); |
3090 } | 3121 } |
3091 | 3122 |
3092 #undef __ | 3123 #undef __ |
3093 } // namespace internal | 3124 } // namespace internal |
3094 } // namespace v8 | 3125 } // namespace v8 |
3095 | 3126 |
3096 #endif // V8_TARGET_ARCH_X87 | 3127 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |