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

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 6716018: X64: Optimize access to external references. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Merge with tip of bleeding edge. Created 9 years, 9 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
« no previous file with comments | « no previous file | src/x64/deoptimizer-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 2431 matching lines...) Expand 10 before | Expand all | Expand 10 after
2442 static const int kSubjectOffset = 3 * kPointerSize; 2442 static const int kSubjectOffset = 3 * kPointerSize;
2443 static const int kJSRegExpOffset = 4 * kPointerSize; 2443 static const int kJSRegExpOffset = 4 * kPointerSize;
2444 2444
2445 Label runtime; 2445 Label runtime;
2446 // Ensure that a RegExp stack is allocated. 2446 // Ensure that a RegExp stack is allocated.
2447 Isolate* isolate = masm->isolate(); 2447 Isolate* isolate = masm->isolate();
2448 ExternalReference address_of_regexp_stack_memory_address = 2448 ExternalReference address_of_regexp_stack_memory_address =
2449 ExternalReference::address_of_regexp_stack_memory_address(isolate); 2449 ExternalReference::address_of_regexp_stack_memory_address(isolate);
2450 ExternalReference address_of_regexp_stack_memory_size = 2450 ExternalReference address_of_regexp_stack_memory_size =
2451 ExternalReference::address_of_regexp_stack_memory_size(isolate); 2451 ExternalReference::address_of_regexp_stack_memory_size(isolate);
2452 __ movq(kScratchRegister, address_of_regexp_stack_memory_size); 2452 __ Load(kScratchRegister, address_of_regexp_stack_memory_size);
2453 __ movq(kScratchRegister, Operand(kScratchRegister, 0));
2454 __ testq(kScratchRegister, kScratchRegister); 2453 __ testq(kScratchRegister, kScratchRegister);
2455 __ j(zero, &runtime); 2454 __ j(zero, &runtime);
2456 2455
2457 2456
2458 // Check that the first argument is a JSRegExp object. 2457 // Check that the first argument is a JSRegExp object.
2459 __ movq(rax, Operand(rsp, kJSRegExpOffset)); 2458 __ movq(rax, Operand(rsp, kJSRegExpOffset));
2460 __ JumpIfSmi(rax, &runtime); 2459 __ JumpIfSmi(rax, &runtime);
2461 __ CmpObjectType(rax, JS_REGEXP_TYPE, kScratchRegister); 2460 __ CmpObjectType(rax, JS_REGEXP_TYPE, kScratchRegister);
2462 __ j(not_equal, &runtime); 2461 __ j(not_equal, &runtime);
2463 // Check that the RegExp has been compiled (data contains a fixed array). 2462 // Check that the RegExp has been compiled (data contains a fixed array).
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
2604 2603
2605 // Isolates: note we add an additional parameter here (isolate pointer). 2604 // Isolates: note we add an additional parameter here (isolate pointer).
2606 static const int kRegExpExecuteArguments = 8; 2605 static const int kRegExpExecuteArguments = 8;
2607 int argument_slots_on_stack = 2606 int argument_slots_on_stack =
2608 masm->ArgumentStackSlotsForCFunctionCall(kRegExpExecuteArguments); 2607 masm->ArgumentStackSlotsForCFunctionCall(kRegExpExecuteArguments);
2609 __ EnterApiExitFrame(argument_slots_on_stack); 2608 __ EnterApiExitFrame(argument_slots_on_stack);
2610 2609
2611 // Argument 8: Pass current isolate address. 2610 // Argument 8: Pass current isolate address.
2612 // __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize), 2611 // __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize),
2613 // Immediate(ExternalReference::isolate_address())); 2612 // Immediate(ExternalReference::isolate_address()));
2614 __ movq(kScratchRegister, ExternalReference::isolate_address()); 2613 __ LoadAddress(kScratchRegister, ExternalReference::isolate_address());
2615 __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize), 2614 __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize),
2616 kScratchRegister); 2615 kScratchRegister);
2617 2616
2618 // Argument 7: Indicate that this is a direct call from JavaScript. 2617 // Argument 7: Indicate that this is a direct call from JavaScript.
2619 __ movq(Operand(rsp, (argument_slots_on_stack - 2) * kPointerSize), 2618 __ movq(Operand(rsp, (argument_slots_on_stack - 2) * kPointerSize),
2620 Immediate(1)); 2619 Immediate(1));
2621 2620
2622 // Argument 6: Start (high end) of backtracking stack memory area. 2621 // Argument 6: Start (high end) of backtracking stack memory area.
2623 __ movq(kScratchRegister, address_of_regexp_stack_memory_address); 2622 __ movq(kScratchRegister, address_of_regexp_stack_memory_address);
2624 __ movq(r9, Operand(kScratchRegister, 0)); 2623 __ movq(r9, Operand(kScratchRegister, 0));
2625 __ movq(kScratchRegister, address_of_regexp_stack_memory_size); 2624 __ movq(kScratchRegister, address_of_regexp_stack_memory_size);
2626 __ addq(r9, Operand(kScratchRegister, 0)); 2625 __ addq(r9, Operand(kScratchRegister, 0));
2627 // Argument 6 passed in r9 on Linux and on the stack on Windows. 2626 // Argument 6 passed in r9 on Linux and on the stack on Windows.
2628 #ifdef _WIN64 2627 #ifdef _WIN64
2629 __ movq(Operand(rsp, (argument_slots_on_stack - 3) * kPointerSize), r9); 2628 __ movq(Operand(rsp, (argument_slots_on_stack - 3) * kPointerSize), r9);
2630 #endif 2629 #endif
2631 2630
2632 // Argument 5: static offsets vector buffer. 2631 // Argument 5: static offsets vector buffer.
2633 __ movq(r8, ExternalReference::address_of_static_offsets_vector(isolate)); 2632 __ LoadAddress(r8,
2633 ExternalReference::address_of_static_offsets_vector(isolate));
2634 // Argument 5 passed in r8 on Linux and on the stack on Windows. 2634 // Argument 5 passed in r8 on Linux and on the stack on Windows.
2635 #ifdef _WIN64 2635 #ifdef _WIN64
2636 __ movq(Operand(rsp, (argument_slots_on_stack - 4) * kPointerSize), r8); 2636 __ movq(Operand(rsp, (argument_slots_on_stack - 4) * kPointerSize), r8);
2637 #endif 2637 #endif
2638 2638
2639 // First four arguments are passed in registers on both Linux and Windows. 2639 // First four arguments are passed in registers on both Linux and Windows.
2640 #ifdef _WIN64 2640 #ifdef _WIN64
2641 Register arg4 = r9; 2641 Register arg4 = r9;
2642 Register arg3 = r8; 2642 Register arg3 = r8;
2643 Register arg2 = rdx; 2643 Register arg2 = rdx;
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
2727 __ movq(rax, Operand(rsp, kSubjectOffset)); 2727 __ movq(rax, Operand(rsp, kSubjectOffset));
2728 __ movq(FieldOperand(rbx, RegExpImpl::kLastSubjectOffset), rax); 2728 __ movq(FieldOperand(rbx, RegExpImpl::kLastSubjectOffset), rax);
2729 __ movq(rcx, rbx); 2729 __ movq(rcx, rbx);
2730 __ RecordWrite(rcx, RegExpImpl::kLastSubjectOffset, rax, rdi); 2730 __ RecordWrite(rcx, RegExpImpl::kLastSubjectOffset, rax, rdi);
2731 __ movq(rax, Operand(rsp, kSubjectOffset)); 2731 __ movq(rax, Operand(rsp, kSubjectOffset));
2732 __ movq(FieldOperand(rbx, RegExpImpl::kLastInputOffset), rax); 2732 __ movq(FieldOperand(rbx, RegExpImpl::kLastInputOffset), rax);
2733 __ movq(rcx, rbx); 2733 __ movq(rcx, rbx);
2734 __ RecordWrite(rcx, RegExpImpl::kLastInputOffset, rax, rdi); 2734 __ RecordWrite(rcx, RegExpImpl::kLastInputOffset, rax, rdi);
2735 2735
2736 // Get the static offsets vector filled by the native regexp code. 2736 // Get the static offsets vector filled by the native regexp code.
2737 __ movq(rcx, ExternalReference::address_of_static_offsets_vector(isolate)); 2737 __ LoadAddress(rcx,
2738 ExternalReference::address_of_static_offsets_vector(isolate));
2738 2739
2739 // rbx: last_match_info backing store (FixedArray) 2740 // rbx: last_match_info backing store (FixedArray)
2740 // rcx: offsets vector 2741 // rcx: offsets vector
2741 // rdx: number of capture registers 2742 // rdx: number of capture registers
2742 NearLabel next_capture, done; 2743 NearLabel next_capture, done;
2743 // Capture register counter starts from number of capture registers and 2744 // Capture register counter starts from number of capture registers and
2744 // counts down until wraping after zero. 2745 // counts down until wraping after zero.
2745 __ bind(&next_capture); 2746 __ bind(&next_capture);
2746 __ subq(rdx, Immediate(1)); 2747 __ subq(rdx, Immediate(1));
2747 __ j(negative, &done); 2748 __ j(negative, &done);
(...skipping 13 matching lines...) Expand all
2761 __ movq(rax, Operand(rsp, kLastMatchInfoOffset)); 2762 __ movq(rax, Operand(rsp, kLastMatchInfoOffset));
2762 __ ret(4 * kPointerSize); 2763 __ ret(4 * kPointerSize);
2763 2764
2764 __ bind(&exception); 2765 __ bind(&exception);
2765 // Result must now be exception. If there is no pending exception already a 2766 // Result must now be exception. If there is no pending exception already a
2766 // stack overflow (on the backtrack stack) was detected in RegExp code but 2767 // stack overflow (on the backtrack stack) was detected in RegExp code but
2767 // haven't created the exception yet. Handle that in the runtime system. 2768 // haven't created the exception yet. Handle that in the runtime system.
2768 // TODO(592): Rerunning the RegExp to get the stack overflow exception. 2769 // TODO(592): Rerunning the RegExp to get the stack overflow exception.
2769 ExternalReference pending_exception_address( 2770 ExternalReference pending_exception_address(
2770 Isolate::k_pending_exception_address, isolate); 2771 Isolate::k_pending_exception_address, isolate);
2771 __ movq(rbx, pending_exception_address); 2772 Operand pending_exception_operand =
2772 __ movq(rax, Operand(rbx, 0)); 2773 masm->ExternalOperand(pending_exception_address, rbx);
2774 __ movq(rax, pending_exception_operand);
2773 __ LoadRoot(rdx, Heap::kTheHoleValueRootIndex); 2775 __ LoadRoot(rdx, Heap::kTheHoleValueRootIndex);
2774 __ cmpq(rax, rdx); 2776 __ cmpq(rax, rdx);
2775 __ j(equal, &runtime); 2777 __ j(equal, &runtime);
2776 __ movq(Operand(rbx, 0), rdx); 2778 __ movq(pending_exception_operand, rdx);
2777 2779
2778 __ CompareRoot(rax, Heap::kTerminationExceptionRootIndex); 2780 __ CompareRoot(rax, Heap::kTerminationExceptionRootIndex);
2779 NearLabel termination_exception; 2781 NearLabel termination_exception;
2780 __ j(equal, &termination_exception); 2782 __ j(equal, &termination_exception);
2781 __ Throw(rax); 2783 __ Throw(rax);
2782 2784
2783 __ bind(&termination_exception); 2785 __ bind(&termination_exception);
2784 __ ThrowUncatchable(TERMINATION, rax); 2786 __ ThrowUncatchable(TERMINATION, rax);
2785 2787
2786 // Do the runtime call to execute the regexp. 2788 // Do the runtime call to execute the regexp.
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after
3378 #endif 3380 #endif
3379 __ movq(kScratchRegister, 3381 __ movq(kScratchRegister,
3380 FUNCTION_ADDR(Runtime::PerformGC), 3382 FUNCTION_ADDR(Runtime::PerformGC),
3381 RelocInfo::RUNTIME_ENTRY); 3383 RelocInfo::RUNTIME_ENTRY);
3382 __ call(kScratchRegister); 3384 __ call(kScratchRegister);
3383 } 3385 }
3384 3386
3385 ExternalReference scope_depth = 3387 ExternalReference scope_depth =
3386 ExternalReference::heap_always_allocate_scope_depth(masm->isolate()); 3388 ExternalReference::heap_always_allocate_scope_depth(masm->isolate());
3387 if (always_allocate_scope) { 3389 if (always_allocate_scope) {
3388 __ movq(kScratchRegister, scope_depth); 3390 Operand scope_depth_operand = masm->ExternalOperand(scope_depth);
3389 __ incl(Operand(kScratchRegister, 0)); 3391 __ incl(scope_depth_operand);
3390 } 3392 }
3391 3393
3392 // Call C function. 3394 // Call C function.
3393 #ifdef _WIN64 3395 #ifdef _WIN64
3394 // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9 3396 // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9
3395 // Store Arguments object on stack, below the 4 WIN64 ABI parameter slots. 3397 // Store Arguments object on stack, below the 4 WIN64 ABI parameter slots.
3396 __ movq(StackSpaceOperand(0), r14); // argc. 3398 __ movq(StackSpaceOperand(0), r14); // argc.
3397 __ movq(StackSpaceOperand(1), r15); // argv. 3399 __ movq(StackSpaceOperand(1), r15); // argv.
3398 if (result_size_ < 2) { 3400 if (result_size_ < 2) {
3399 // Pass a pointer to the Arguments object as the first argument. 3401 // Pass a pointer to the Arguments object as the first argument.
3400 // Return result in single register (rax). 3402 // Return result in single register (rax).
3401 __ lea(rcx, StackSpaceOperand(0)); 3403 __ lea(rcx, StackSpaceOperand(0));
3402 __ movq(rdx, ExternalReference::isolate_address()); 3404 __ LoadAddress(rdx, ExternalReference::isolate_address());
3403 } else { 3405 } else {
3404 ASSERT_EQ(2, result_size_); 3406 ASSERT_EQ(2, result_size_);
3405 // Pass a pointer to the result location as the first argument. 3407 // Pass a pointer to the result location as the first argument.
3406 __ lea(rcx, StackSpaceOperand(2)); 3408 __ lea(rcx, StackSpaceOperand(2));
3407 // Pass a pointer to the Arguments object as the second argument. 3409 // Pass a pointer to the Arguments object as the second argument.
3408 __ lea(rdx, StackSpaceOperand(0)); 3410 __ lea(rdx, StackSpaceOperand(0));
3409 __ movq(r8, ExternalReference::isolate_address()); 3411 __ LoadAddress(r8, ExternalReference::isolate_address());
3410 } 3412 }
3411 3413
3412 #else // _WIN64 3414 #else // _WIN64
3413 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9. 3415 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9.
3414 __ movq(rdi, r14); // argc. 3416 __ movq(rdi, r14); // argc.
3415 __ movq(rsi, r15); // argv. 3417 __ movq(rsi, r15); // argv.
3416 __ movq(rdx, ExternalReference::isolate_address()); 3418 __ movq(rdx, ExternalReference::isolate_address());
3417 #endif 3419 #endif
3418 __ call(rbx); 3420 __ call(rbx);
3419 // Result is in rax - do not destroy this register! 3421 // Result is in rax - do not destroy this register!
3420 3422
3421 if (always_allocate_scope) { 3423 if (always_allocate_scope) {
3422 __ movq(kScratchRegister, scope_depth); 3424 Operand scope_depth_operand = masm->ExternalOperand(scope_depth);
3423 __ decl(Operand(kScratchRegister, 0)); 3425 __ decl(scope_depth_operand);
3424 } 3426 }
3425 3427
3426 // Check for failure result. 3428 // Check for failure result.
3427 Label failure_returned; 3429 Label failure_returned;
3428 STATIC_ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0); 3430 STATIC_ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0);
3429 #ifdef _WIN64 3431 #ifdef _WIN64
3430 // If return value is on the stack, pop it to registers. 3432 // If return value is on the stack, pop it to registers.
3431 if (result_size_ > 1) { 3433 if (result_size_ > 1) {
3432 ASSERT_EQ(2, result_size_); 3434 ASSERT_EQ(2, result_size_);
3433 // Read result values stored on stack. Result is stored 3435 // Read result values stored on stack. Result is stored
(...skipping 22 matching lines...) Expand all
3456 __ j(zero, &retry); 3458 __ j(zero, &retry);
3457 3459
3458 // Special handling of out of memory exceptions. 3460 // Special handling of out of memory exceptions.
3459 __ movq(kScratchRegister, Failure::OutOfMemoryException(), RelocInfo::NONE); 3461 __ movq(kScratchRegister, Failure::OutOfMemoryException(), RelocInfo::NONE);
3460 __ cmpq(rax, kScratchRegister); 3462 __ cmpq(rax, kScratchRegister);
3461 __ j(equal, throw_out_of_memory_exception); 3463 __ j(equal, throw_out_of_memory_exception);
3462 3464
3463 // Retrieve the pending exception and clear the variable. 3465 // Retrieve the pending exception and clear the variable.
3464 ExternalReference pending_exception_address( 3466 ExternalReference pending_exception_address(
3465 Isolate::k_pending_exception_address, masm->isolate()); 3467 Isolate::k_pending_exception_address, masm->isolate());
3466 __ movq(kScratchRegister, pending_exception_address); 3468 Operand pending_exception_operand =
3467 __ movq(rax, Operand(kScratchRegister, 0)); 3469 masm->ExternalOperand(pending_exception_address);
3468 __ movq(rdx, ExternalReference::the_hole_value_location(masm->isolate())); 3470 __ movq(rax, pending_exception_operand);
3469 __ movq(rdx, Operand(rdx, 0)); 3471 __ LoadRoot(rdx, Heap::kTheHoleValueRootIndex);
3470 __ movq(Operand(kScratchRegister, 0), rdx); 3472 __ movq(pending_exception_operand, rdx);
3471 3473
3472 // Special handling of termination exceptions which are uncatchable 3474 // Special handling of termination exceptions which are uncatchable
3473 // by javascript code. 3475 // by javascript code.
3474 __ CompareRoot(rax, Heap::kTerminationExceptionRootIndex); 3476 __ CompareRoot(rax, Heap::kTerminationExceptionRootIndex);
3475 __ j(equal, throw_termination_exception); 3477 __ j(equal, throw_termination_exception);
3476 3478
3477 // Handle normal exception. 3479 // Handle normal exception.
3478 __ jmp(throw_normal_exception); 3480 __ jmp(throw_normal_exception);
3479 3481
3480 // Retry. 3482 // Retry.
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
3559 __ bind(&throw_normal_exception); 3561 __ bind(&throw_normal_exception);
3560 GenerateThrowTOS(masm); 3562 GenerateThrowTOS(masm);
3561 } 3563 }
3562 3564
3563 3565
3564 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { 3566 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
3565 Label invoke, exit; 3567 Label invoke, exit;
3566 #ifdef ENABLE_LOGGING_AND_PROFILING 3568 #ifdef ENABLE_LOGGING_AND_PROFILING
3567 Label not_outermost_js, not_outermost_js_2; 3569 Label not_outermost_js, not_outermost_js_2;
3568 #endif 3570 #endif
3571 { // NOLINT. Scope block confuses linter.
3572 MacroAssembler::NoRootArrayScope uninitialized_root_register(masm);
3573 // Setup frame.
3574 __ push(rbp);
3575 __ movq(rbp, rsp);
3569 3576
3570 // Setup frame. 3577 // Push the stack frame type marker twice.
3571 __ push(rbp); 3578 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
3572 __ movq(rbp, rsp); 3579 // Scratch register is neither callee-save, nor an argument register on any
3580 // platform. It's free to use at this point.
3581 // Cannot use smi-register for loading yet.
3582 __ movq(kScratchRegister,
3583 reinterpret_cast<uint64_t>(Smi::FromInt(marker)),
3584 RelocInfo::NONE);
3585 __ push(kScratchRegister); // context slot
3586 __ push(kScratchRegister); // function slot
3587 // Save callee-saved registers (X64/Win64 calling conventions).
3588 __ push(r12);
3589 __ push(r13);
3590 __ push(r14);
3591 __ push(r15);
3592 #ifdef _WIN64
3593 __ push(rdi); // Only callee save in Win64 ABI, argument in AMD64 ABI.
3594 __ push(rsi); // Only callee save in Win64 ABI, argument in AMD64 ABI.
3595 #endif
3596 __ push(rbx);
3597 // TODO(X64): On Win64, if we ever use XMM6-XMM15, the low low 64 bits are
3598 // callee save as well.
3573 3599
3574 // Push the stack frame type marker twice. 3600 // Set up the roots and smi constant registers.
3575 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; 3601 // Needs to be done before any further smi loads.
3576 // Scratch register is neither callee-save, nor an argument register on any 3602 __ InitializeSmiConstantRegister();
3577 // platform. It's free to use at this point. 3603 __ InitializeRootRegister();
3578 // Cannot use smi-register for loading yet. 3604 }
3579 __ movq(kScratchRegister,
3580 reinterpret_cast<uint64_t>(Smi::FromInt(marker)),
3581 RelocInfo::NONE);
3582 __ push(kScratchRegister); // context slot
3583 __ push(kScratchRegister); // function slot
3584 // Save callee-saved registers (X64/Win64 calling conventions).
3585 __ push(r12);
3586 __ push(r13);
3587 __ push(r14);
3588 __ push(r15);
3589 #ifdef _WIN64
3590 __ push(rdi); // Only callee save in Win64 ABI, argument in AMD64 ABI.
3591 __ push(rsi); // Only callee save in Win64 ABI, argument in AMD64 ABI.
3592 #endif
3593 __ push(rbx);
3594 // TODO(X64): On Win64, if we ever use XMM6-XMM15, the low low 64 bits are
3595 // callee save as well.
3596 3605
3597 Isolate* isolate = masm->isolate(); 3606 Isolate* isolate = masm->isolate();
3598 3607
3599 // Save copies of the top frame descriptor on the stack. 3608 // Save copies of the top frame descriptor on the stack.
3600 ExternalReference c_entry_fp(Isolate::k_c_entry_fp_address, isolate); 3609 ExternalReference c_entry_fp(Isolate::k_c_entry_fp_address, isolate);
3601 __ load_rax(c_entry_fp); 3610 {
3602 __ push(rax); 3611 Operand c_entry_fp_operand = masm->ExternalOperand(c_entry_fp);
3603 3612 __ push(c_entry_fp_operand);
3604 // Set up the roots and smi constant registers. 3613 }
3605 // Needs to be done before any further smi loads.
3606 __ InitializeRootRegister();
3607 __ InitializeSmiConstantRegister();
3608 3614
3609 #ifdef ENABLE_LOGGING_AND_PROFILING 3615 #ifdef ENABLE_LOGGING_AND_PROFILING
3610 // If this is the outermost JS call, set js_entry_sp value. 3616 // If this is the outermost JS call, set js_entry_sp value.
3611 ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, isolate); 3617 ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, isolate);
3612 __ load_rax(js_entry_sp); 3618 __ Load(rax, js_entry_sp);
3613 __ testq(rax, rax); 3619 __ testq(rax, rax);
3614 __ j(not_zero, &not_outermost_js); 3620 __ j(not_zero, &not_outermost_js);
3615 __ movq(rax, rbp); 3621 __ movq(rax, rbp);
3616 __ store_rax(js_entry_sp); 3622 __ Store(js_entry_sp, rax);
3617 __ bind(&not_outermost_js); 3623 __ bind(&not_outermost_js);
3618 #endif 3624 #endif
3619 3625
3620 // Call a faked try-block that does the invoke. 3626 // Call a faked try-block that does the invoke.
3621 __ call(&invoke); 3627 __ call(&invoke);
3622 3628
3623 // Caught exception: Store result (exception) in the pending 3629 // Caught exception: Store result (exception) in the pending
3624 // exception field in the JSEnv and return a failure sentinel. 3630 // exception field in the JSEnv and return a failure sentinel.
3625 ExternalReference pending_exception(Isolate::k_pending_exception_address, 3631 ExternalReference pending_exception(Isolate::k_pending_exception_address,
3626 isolate); 3632 isolate);
3627 __ store_rax(pending_exception); 3633 __ Store(pending_exception, rax);
3628 __ movq(rax, Failure::Exception(), RelocInfo::NONE); 3634 __ movq(rax, Failure::Exception(), RelocInfo::NONE);
3629 __ jmp(&exit); 3635 __ jmp(&exit);
3630 3636
3631 // Invoke: Link this frame into the handler chain. 3637 // Invoke: Link this frame into the handler chain.
3632 __ bind(&invoke); 3638 __ bind(&invoke);
3633 __ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER); 3639 __ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER);
3634 3640
3635 // Clear any pending exceptions. 3641 // Clear any pending exceptions.
3636 __ load_rax(ExternalReference::the_hole_value_location(isolate)); 3642 __ LoadRoot(rax, Heap::kTheHoleValueRootIndex);
3637 __ store_rax(pending_exception); 3643 __ Store(pending_exception, rax);
3638 3644
3639 // Fake a receiver (NULL). 3645 // Fake a receiver (NULL).
3640 __ push(Immediate(0)); // receiver 3646 __ push(Immediate(0)); // receiver
3641 3647
3642 // Invoke the function by calling through JS entry trampoline 3648 // Invoke the function by calling through JS entry trampoline
3643 // builtin and pop the faked function when we return. We load the address 3649 // builtin and pop the faked function when we return. We load the address
3644 // from an external reference instead of inlining the call target address 3650 // from an external reference instead of inlining the call target address
3645 // directly in the code, because the builtin stubs may not have been 3651 // directly in the code, because the builtin stubs may not have been
3646 // generated yet at the time this code is generated. 3652 // generated yet at the time this code is generated.
3647 if (is_construct) { 3653 if (is_construct) {
3648 ExternalReference construct_entry(Builtins::JSConstructEntryTrampoline, 3654 ExternalReference construct_entry(Builtins::JSConstructEntryTrampoline,
3649 isolate); 3655 isolate);
3650 __ load_rax(construct_entry); 3656 __ Load(rax, construct_entry);
3651 } else { 3657 } else {
3652 ExternalReference entry(Builtins::JSEntryTrampoline, isolate); 3658 ExternalReference entry(Builtins::JSEntryTrampoline, isolate);
3653 __ load_rax(entry); 3659 __ Load(rax, entry);
3654 } 3660 }
3655 __ lea(kScratchRegister, FieldOperand(rax, Code::kHeaderSize)); 3661 __ lea(kScratchRegister, FieldOperand(rax, Code::kHeaderSize));
3656 __ call(kScratchRegister); 3662 __ call(kScratchRegister);
3657 3663
3658 // Unlink this frame from the handler chain. 3664 // Unlink this frame from the handler chain.
3659 __ movq(kScratchRegister, 3665 Operand handler_operand =
3660 ExternalReference(Isolate::k_handler_address, isolate)); 3666 masm->ExternalOperand(ExternalReference(Isolate::k_handler_address,
3661 __ pop(Operand(kScratchRegister, 0)); 3667 isolate));
3668 __ pop(handler_operand);
3662 // Pop next_sp. 3669 // Pop next_sp.
3663 __ addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); 3670 __ addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize));
3664 3671
3665 #ifdef ENABLE_LOGGING_AND_PROFILING 3672 #ifdef ENABLE_LOGGING_AND_PROFILING
3666 // If current RBP value is the same as js_entry_sp value, it means that 3673 // If current RBP value is the same as js_entry_sp value, it means that
3667 // the current function is the outermost. 3674 // the current function is the outermost.
3668 __ movq(kScratchRegister, js_entry_sp); 3675 __ movq(kScratchRegister, js_entry_sp);
3669 __ cmpq(rbp, Operand(kScratchRegister, 0)); 3676 __ cmpq(rbp, Operand(kScratchRegister, 0));
3670 __ j(not_equal, &not_outermost_js_2); 3677 __ j(not_equal, &not_outermost_js_2);
3671 __ movq(Operand(kScratchRegister, 0), Immediate(0)); 3678 __ movq(Operand(kScratchRegister, 0), Immediate(0));
3672 __ bind(&not_outermost_js_2); 3679 __ bind(&not_outermost_js_2);
3673 #endif 3680 #endif
3674 3681
3675 // Restore the top frame descriptor from the stack. 3682 // Restore the top frame descriptor from the stack.
3676 __ bind(&exit); 3683 __ bind(&exit);
3677 __ movq(kScratchRegister, 3684 {
3678 ExternalReference(Isolate::k_c_entry_fp_address, isolate)); 3685 Operand c_entry_fp_operand = masm->ExternalOperand(c_entry_fp);
3679 __ pop(Operand(kScratchRegister, 0)); 3686 __ pop(c_entry_fp_operand);
3687 }
3680 3688
3681 // Restore callee-saved registers (X64 conventions). 3689 // Restore callee-saved registers (X64 conventions).
3682 __ pop(rbx); 3690 __ pop(rbx);
3683 #ifdef _WIN64 3691 #ifdef _WIN64
3684 // Callee save on in Win64 ABI, arguments/volatile in AMD64 ABI. 3692 // Callee save on in Win64 ABI, arguments/volatile in AMD64 ABI.
3685 __ pop(rsi); 3693 __ pop(rsi);
3686 __ pop(rdi); 3694 __ pop(rdi);
3687 #endif 3695 #endif
3688 __ pop(r15); 3696 __ pop(r15);
3689 __ pop(r14); 3697 __ pop(r14);
(...skipping 1383 matching lines...) Expand 10 before | Expand all | Expand 10 after
5073 // Do a tail call to the rewritten stub. 5081 // Do a tail call to the rewritten stub.
5074 __ jmp(rdi); 5082 __ jmp(rdi);
5075 } 5083 }
5076 5084
5077 5085
5078 #undef __ 5086 #undef __
5079 5087
5080 } } // namespace v8::internal 5088 } } // namespace v8::internal
5081 5089
5082 #endif // V8_TARGET_ARCH_X64 5090 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « no previous file | src/x64/deoptimizer-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698