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

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

Powered by Google App Engine
This is Rietveld 408576698