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_X64 | 5 #if V8_TARGET_ARCH_X64 |
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 2274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2285 // ----------- S t a t e ------------- | 2285 // ----------- S t a t e ------------- |
2286 // -- rax : argumentsList | 2286 // -- rax : argumentsList |
2287 // -- rdi : target | 2287 // -- rdi : target |
2288 // -- rdx : new.target (checked to be constructor or undefined) | 2288 // -- rdx : new.target (checked to be constructor or undefined) |
2289 // -- rsp[0] : return address. | 2289 // -- rsp[0] : return address. |
2290 // -- rsp[8] : thisArgument | 2290 // -- rsp[8] : thisArgument |
2291 // ----------------------------------- | 2291 // ----------------------------------- |
2292 | 2292 |
2293 // Create the list of arguments from the array-like argumentsList. | 2293 // Create the list of arguments from the array-like argumentsList. |
2294 { | 2294 { |
2295 Label create_arguments, create_array, create_runtime, done_create; | 2295 Label create_arguments, create_array, create_holey_array, create_runtime, |
| 2296 done_create; |
2296 __ JumpIfSmi(rax, &create_runtime); | 2297 __ JumpIfSmi(rax, &create_runtime); |
2297 | 2298 |
2298 // Load the map of argumentsList into rcx. | 2299 // Load the map of argumentsList into rcx. |
2299 __ movp(rcx, FieldOperand(rax, HeapObject::kMapOffset)); | 2300 __ movp(rcx, FieldOperand(rax, HeapObject::kMapOffset)); |
2300 | 2301 |
2301 // Load native context into rbx. | 2302 // Load native context into rbx. |
2302 __ movp(rbx, NativeContextOperand()); | 2303 __ movp(rbx, NativeContextOperand()); |
2303 | 2304 |
2304 // Check if argumentsList is an (unmodified) arguments object. | 2305 // Check if argumentsList is an (unmodified) arguments object. |
2305 __ cmpp(rcx, ContextOperand(rbx, Context::SLOPPY_ARGUMENTS_MAP_INDEX)); | 2306 __ cmpp(rcx, ContextOperand(rbx, Context::SLOPPY_ARGUMENTS_MAP_INDEX)); |
(...skipping 22 matching lines...) Expand all Loading... |
2328 // Try to create the list from an arguments object. | 2329 // Try to create the list from an arguments object. |
2329 __ bind(&create_arguments); | 2330 __ bind(&create_arguments); |
2330 __ movp(rbx, FieldOperand(rax, JSArgumentsObject::kLengthOffset)); | 2331 __ movp(rbx, FieldOperand(rax, JSArgumentsObject::kLengthOffset)); |
2331 __ movp(rcx, FieldOperand(rax, JSObject::kElementsOffset)); | 2332 __ movp(rcx, FieldOperand(rax, JSObject::kElementsOffset)); |
2332 __ cmpp(rbx, FieldOperand(rcx, FixedArray::kLengthOffset)); | 2333 __ cmpp(rbx, FieldOperand(rcx, FixedArray::kLengthOffset)); |
2333 __ j(not_equal, &create_runtime); | 2334 __ j(not_equal, &create_runtime); |
2334 __ SmiToInteger32(rbx, rbx); | 2335 __ SmiToInteger32(rbx, rbx); |
2335 __ movp(rax, rcx); | 2336 __ movp(rax, rcx); |
2336 __ jmp(&done_create); | 2337 __ jmp(&done_create); |
2337 | 2338 |
| 2339 __ bind(&create_holey_array); |
| 2340 // For holey JSArrays we need to check that the array prototype chain |
| 2341 // protector is intact and our prototype is the Array.prototype actually. |
| 2342 __ movp(rcx, FieldOperand(rax, HeapObject::kMapOffset)); |
| 2343 __ movp(rcx, FieldOperand(rcx, Map::kPrototypeOffset)); |
| 2344 __ cmpp(rcx, ContextOperand(rbx, Context::INITIAL_ARRAY_PROTOTYPE_INDEX)); |
| 2345 __ j(not_equal, &create_runtime); |
| 2346 __ LoadRoot(rcx, Heap::kArrayProtectorRootIndex); |
| 2347 __ Cmp(FieldOperand(rcx, PropertyCell::kValueOffset), |
| 2348 Smi::FromInt(Isolate::kProtectorValid)); |
| 2349 __ j(not_equal, &create_runtime); |
| 2350 __ SmiToInteger32(rbx, FieldOperand(rax, JSArray::kLengthOffset)); |
| 2351 __ movp(rax, FieldOperand(rax, JSArray::kElementsOffset)); |
| 2352 __ jmp(&done_create); |
| 2353 |
2338 // Try to create the list from a JSArray object. | 2354 // Try to create the list from a JSArray object. |
2339 __ bind(&create_array); | 2355 __ bind(&create_array); |
2340 __ movzxbp(rcx, FieldOperand(rcx, Map::kBitField2Offset)); | 2356 __ movzxbp(rcx, FieldOperand(rcx, Map::kBitField2Offset)); |
2341 __ DecodeField<Map::ElementsKindBits>(rcx); | 2357 __ DecodeField<Map::ElementsKindBits>(rcx); |
2342 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | 2358 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); |
2343 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | 2359 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
2344 STATIC_ASSERT(FAST_ELEMENTS == 2); | 2360 STATIC_ASSERT(FAST_ELEMENTS == 2); |
2345 __ cmpl(rcx, Immediate(FAST_ELEMENTS)); | 2361 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); |
| 2362 __ cmpl(rcx, Immediate(FAST_HOLEY_SMI_ELEMENTS)); |
| 2363 __ j(equal, &create_holey_array); |
| 2364 __ cmpl(rcx, Immediate(FAST_HOLEY_ELEMENTS)); |
| 2365 __ j(equal, &create_holey_array); |
2346 __ j(above, &create_runtime); | 2366 __ j(above, &create_runtime); |
2347 __ cmpl(rcx, Immediate(FAST_HOLEY_SMI_ELEMENTS)); | |
2348 __ j(equal, &create_runtime); | |
2349 __ SmiToInteger32(rbx, FieldOperand(rax, JSArray::kLengthOffset)); | 2367 __ SmiToInteger32(rbx, FieldOperand(rax, JSArray::kLengthOffset)); |
2350 __ movp(rax, FieldOperand(rax, JSArray::kElementsOffset)); | 2368 __ movp(rax, FieldOperand(rax, JSArray::kElementsOffset)); |
2351 | 2369 |
2352 __ bind(&done_create); | 2370 __ bind(&done_create); |
2353 } | 2371 } |
2354 | 2372 |
2355 // Check for stack overflow. | 2373 // Check for stack overflow. |
2356 { | 2374 { |
2357 // Check the stack for overflow. We are not trying to catch interruptions | 2375 // Check the stack for overflow. We are not trying to catch interruptions |
2358 // (i.e. debug break and preemption) here, so check the "real stack limit". | 2376 // (i.e. debug break and preemption) here, so check the "real stack limit". |
(...skipping 17 matching lines...) Expand all Loading... |
2376 // -- rbx : len (number of elements to push from args) | 2394 // -- rbx : len (number of elements to push from args) |
2377 // -- rdx : new.target (checked to be constructor or undefined) | 2395 // -- rdx : new.target (checked to be constructor or undefined) |
2378 // -- rsp[0] : return address. | 2396 // -- rsp[0] : return address. |
2379 // -- rsp[8] : thisArgument | 2397 // -- rsp[8] : thisArgument |
2380 // ----------------------------------- | 2398 // ----------------------------------- |
2381 | 2399 |
2382 // Push arguments onto the stack (thisArgument is already on the stack). | 2400 // Push arguments onto the stack (thisArgument is already on the stack). |
2383 { | 2401 { |
2384 __ PopReturnAddressTo(r8); | 2402 __ PopReturnAddressTo(r8); |
2385 __ Set(rcx, 0); | 2403 __ Set(rcx, 0); |
2386 Label done, loop; | 2404 Label done, push, loop; |
2387 __ bind(&loop); | 2405 __ bind(&loop); |
2388 __ cmpl(rcx, rbx); | 2406 __ cmpl(rcx, rbx); |
2389 __ j(equal, &done, Label::kNear); | 2407 __ j(equal, &done, Label::kNear); |
2390 __ Push( | 2408 // Turn the hole into undefined as we go. |
2391 FieldOperand(rax, rcx, times_pointer_size, FixedArray::kHeaderSize)); | 2409 __ movp(r9, FieldOperand(rax, rcx, times_pointer_size, |
| 2410 FixedArray::kHeaderSize)); |
| 2411 __ CompareRoot(r9, Heap::kTheHoleValueRootIndex); |
| 2412 __ j(not_equal, &push, Label::kNear); |
| 2413 __ LoadRoot(r9, Heap::kUndefinedValueRootIndex); |
| 2414 __ bind(&push); |
| 2415 __ Push(r9); |
2392 __ incl(rcx); | 2416 __ incl(rcx); |
2393 __ jmp(&loop); | 2417 __ jmp(&loop); |
2394 __ bind(&done); | 2418 __ bind(&done); |
2395 __ PushReturnAddressFrom(r8); | 2419 __ PushReturnAddressFrom(r8); |
2396 __ Move(rax, rcx); | 2420 __ Move(rax, rcx); |
2397 } | 2421 } |
2398 | 2422 |
2399 // Dispatch to Call or Construct depending on whether new.target is undefined. | 2423 // Dispatch to Call or Construct depending on whether new.target is undefined. |
2400 { | 2424 { |
2401 __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex); | 2425 __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex); |
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3077 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { | 3101 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { |
3078 Generate_OnStackReplacementHelper(masm, true); | 3102 Generate_OnStackReplacementHelper(masm, true); |
3079 } | 3103 } |
3080 | 3104 |
3081 #undef __ | 3105 #undef __ |
3082 | 3106 |
3083 } // namespace internal | 3107 } // namespace internal |
3084 } // namespace v8 | 3108 } // namespace v8 |
3085 | 3109 |
3086 #endif // V8_TARGET_ARCH_X64 | 3110 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |