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

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

Issue 6713074: Require an isolate parameter for most external reference creation to (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Further cleanup 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 | « src/x64/builtins-x64.cc ('k') | src/x64/codegen-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 982 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 // Although the operation and the type info are encoded into the key, 993 // Although the operation and the type info are encoded into the key,
994 // the encoding is opaque, so push them too. 994 // the encoding is opaque, so push them too.
995 __ Push(Smi::FromInt(op_)); 995 __ Push(Smi::FromInt(op_));
996 996
997 __ Push(Smi::FromInt(runtime_operands_type_)); 997 __ Push(Smi::FromInt(runtime_operands_type_));
998 998
999 __ push(rcx); // The return address. 999 __ push(rcx); // The return address.
1000 1000
1001 // Perform patching to an appropriate fast case and return the result. 1001 // Perform patching to an appropriate fast case and return the result.
1002 __ TailCallExternalReference( 1002 __ TailCallExternalReference(
1003 ExternalReference(IC_Utility(IC::kBinaryOp_Patch)), 1003 ExternalReference(IC_Utility(IC::kBinaryOp_Patch), masm->isolate()),
1004 5, 1004 5,
1005 1); 1005 1);
1006 } 1006 }
1007 1007
1008 1008
1009 Handle<Code> GetBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) { 1009 Handle<Code> GetBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) {
1010 GenericBinaryOpStub stub(key, type_info); 1010 GenericBinaryOpStub stub(key, type_info);
1011 return stub.GetCode(); 1011 return stub.GetCode();
1012 } 1012 }
1013 1013
(...skipping 15 matching lines...) Expand all
1029 // encoded into the key, the encoding is opaque, so push them too. 1029 // encoded into the key, the encoding is opaque, so push them too.
1030 __ Push(Smi::FromInt(MinorKey())); 1030 __ Push(Smi::FromInt(MinorKey()));
1031 __ Push(Smi::FromInt(op_)); 1031 __ Push(Smi::FromInt(op_));
1032 __ Push(Smi::FromInt(operands_type_)); 1032 __ Push(Smi::FromInt(operands_type_));
1033 1033
1034 __ push(rcx); // Push return address. 1034 __ push(rcx); // Push return address.
1035 1035
1036 // Patch the caller to an appropriate specialized stub and return the 1036 // Patch the caller to an appropriate specialized stub and return the
1037 // operation result to the caller of the stub. 1037 // operation result to the caller of the stub.
1038 __ TailCallExternalReference( 1038 __ TailCallExternalReference(
1039 ExternalReference(IC_Utility(IC::kTypeRecordingBinaryOp_Patch)), 1039 ExternalReference(IC_Utility(IC::kTypeRecordingBinaryOp_Patch),
1040 masm->isolate()),
1040 5, 1041 5,
1041 1); 1042 1);
1042 } 1043 }
1043 1044
1044 1045
1045 void TypeRecordingBinaryOpStub::Generate(MacroAssembler* masm) { 1046 void TypeRecordingBinaryOpStub::Generate(MacroAssembler* masm) {
1046 switch (operands_type_) { 1047 switch (operands_type_) {
1047 case TRBinaryOpIC::UNINITIALIZED: 1048 case TRBinaryOpIC::UNINITIALIZED:
1048 GenerateTypeTransition(masm); 1049 GenerateTypeTransition(masm);
1049 break; 1050 break;
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
1583 __ sarl(rax, Immediate(24)); 1584 __ sarl(rax, Immediate(24));
1584 __ xorl(rcx, rdx); 1585 __ xorl(rcx, rdx);
1585 __ xorl(rax, rdi); 1586 __ xorl(rax, rdi);
1586 __ xorl(rcx, rax); 1587 __ xorl(rcx, rax);
1587 ASSERT(IsPowerOf2(TranscendentalCache::SubCache::kCacheSize)); 1588 ASSERT(IsPowerOf2(TranscendentalCache::SubCache::kCacheSize));
1588 __ andl(rcx, Immediate(TranscendentalCache::SubCache::kCacheSize - 1)); 1589 __ andl(rcx, Immediate(TranscendentalCache::SubCache::kCacheSize - 1));
1589 1590
1590 // ST[0] == double value. 1591 // ST[0] == double value.
1591 // rbx = bits of double value. 1592 // rbx = bits of double value.
1592 // rcx = TranscendentalCache::hash(double value). 1593 // rcx = TranscendentalCache::hash(double value).
1593 __ movq(rax, ExternalReference::transcendental_cache_array_address()); 1594 ExternalReference cache_array =
1594 // rax points to cache array. 1595 ExternalReference::transcendental_cache_array_address(masm->isolate());
1595 __ movq(rax, Operand(rax, type_ * sizeof( 1596 __ movq(rax, cache_array);
1596 Isolate::Current()->transcendental_cache()->caches_[0]))); 1597 int cache_array_index =
1598 type_ * sizeof(Isolate::Current()->transcendental_cache()->caches_[0]);
1599 __ movq(rax, Operand(rax, cache_array_index));
1597 // rax points to the cache for the type type_. 1600 // rax points to the cache for the type type_.
1598 // If NULL, the cache hasn't been initialized yet, so go through runtime. 1601 // If NULL, the cache hasn't been initialized yet, so go through runtime.
1599 __ testq(rax, rax); 1602 __ testq(rax, rax);
1600 __ j(zero, &runtime_call_clear_stack); // Only clears stack if TAGGED. 1603 __ j(zero, &runtime_call_clear_stack); // Only clears stack if TAGGED.
1601 #ifdef DEBUG 1604 #ifdef DEBUG
1602 // Check that the layout of cache elements match expectations. 1605 // Check that the layout of cache elements match expectations.
1603 { // NOLINT - doesn't like a single brace on a line. 1606 { // NOLINT - doesn't like a single brace on a line.
1604 TranscendentalCache::SubCache::Element test_elem[2]; 1607 TranscendentalCache::SubCache::Element test_elem[2];
1605 char* elem_start = reinterpret_cast<char*>(&test_elem[0]); 1608 char* elem_start = reinterpret_cast<char*>(&test_elem[0]);
1606 char* elem2_start = reinterpret_cast<char*>(&test_elem[1]); 1609 char* elem2_start = reinterpret_cast<char*>(&test_elem[1]);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1667 __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace); 1670 __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace);
1668 __ LeaveInternalFrame(); 1671 __ LeaveInternalFrame();
1669 __ Ret(); 1672 __ Ret();
1670 } 1673 }
1671 1674
1672 // Call runtime, doing whatever allocation and cleanup is necessary. 1675 // Call runtime, doing whatever allocation and cleanup is necessary.
1673 if (tagged) { 1676 if (tagged) {
1674 __ bind(&runtime_call_clear_stack); 1677 __ bind(&runtime_call_clear_stack);
1675 __ fstp(0); 1678 __ fstp(0);
1676 __ bind(&runtime_call); 1679 __ bind(&runtime_call);
1677 __ TailCallExternalReference(ExternalReference(RuntimeFunction()), 1, 1); 1680 __ TailCallExternalReference(
1681 ExternalReference(RuntimeFunction(), masm->isolate()), 1, 1);
1678 } else { // UNTAGGED. 1682 } else { // UNTAGGED.
1679 __ bind(&runtime_call_clear_stack); 1683 __ bind(&runtime_call_clear_stack);
1680 __ bind(&runtime_call); 1684 __ bind(&runtime_call);
1681 __ AllocateHeapNumber(rax, rdi, &skip_cache); 1685 __ AllocateHeapNumber(rax, rdi, &skip_cache);
1682 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm1); 1686 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm1);
1683 __ EnterInternalFrame(); 1687 __ EnterInternalFrame();
1684 __ push(rax); 1688 __ push(rax);
1685 __ CallRuntime(RuntimeFunction(), 1); 1689 __ CallRuntime(RuntimeFunction(), 1);
1686 __ LeaveInternalFrame(); 1690 __ LeaveInternalFrame();
1687 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset)); 1691 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset));
(...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after
2433 // rsp[24]: subject string 2437 // rsp[24]: subject string
2434 // rsp[32]: JSRegExp object 2438 // rsp[32]: JSRegExp object
2435 2439
2436 static const int kLastMatchInfoOffset = 1 * kPointerSize; 2440 static const int kLastMatchInfoOffset = 1 * kPointerSize;
2437 static const int kPreviousIndexOffset = 2 * kPointerSize; 2441 static const int kPreviousIndexOffset = 2 * kPointerSize;
2438 static const int kSubjectOffset = 3 * kPointerSize; 2442 static const int kSubjectOffset = 3 * kPointerSize;
2439 static const int kJSRegExpOffset = 4 * kPointerSize; 2443 static const int kJSRegExpOffset = 4 * kPointerSize;
2440 2444
2441 Label runtime; 2445 Label runtime;
2442 // Ensure that a RegExp stack is allocated. 2446 // Ensure that a RegExp stack is allocated.
2447 Isolate* isolate = masm->isolate();
2443 ExternalReference address_of_regexp_stack_memory_address = 2448 ExternalReference address_of_regexp_stack_memory_address =
2444 ExternalReference::address_of_regexp_stack_memory_address(); 2449 ExternalReference::address_of_regexp_stack_memory_address(isolate);
2445 ExternalReference address_of_regexp_stack_memory_size = 2450 ExternalReference address_of_regexp_stack_memory_size =
2446 ExternalReference::address_of_regexp_stack_memory_size(); 2451 ExternalReference::address_of_regexp_stack_memory_size(isolate);
2447 __ movq(kScratchRegister, address_of_regexp_stack_memory_size); 2452 __ movq(kScratchRegister, address_of_regexp_stack_memory_size);
2448 __ movq(kScratchRegister, Operand(kScratchRegister, 0)); 2453 __ movq(kScratchRegister, Operand(kScratchRegister, 0));
2449 __ testq(kScratchRegister, kScratchRegister); 2454 __ testq(kScratchRegister, kScratchRegister);
2450 __ j(zero, &runtime); 2455 __ j(zero, &runtime);
2451 2456
2452 2457
2453 // Check that the first argument is a JSRegExp object. 2458 // Check that the first argument is a JSRegExp object.
2454 __ movq(rax, Operand(rsp, kJSRegExpOffset)); 2459 __ movq(rax, Operand(rsp, kJSRegExpOffset));
2455 __ JumpIfSmi(rax, &runtime); 2460 __ JumpIfSmi(rax, &runtime);
2456 __ CmpObjectType(rax, JS_REGEXP_TYPE, kScratchRegister); 2461 __ CmpObjectType(rax, JS_REGEXP_TYPE, kScratchRegister);
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
2618 __ movq(kScratchRegister, address_of_regexp_stack_memory_address); 2623 __ movq(kScratchRegister, address_of_regexp_stack_memory_address);
2619 __ movq(r9, Operand(kScratchRegister, 0)); 2624 __ movq(r9, Operand(kScratchRegister, 0));
2620 __ movq(kScratchRegister, address_of_regexp_stack_memory_size); 2625 __ movq(kScratchRegister, address_of_regexp_stack_memory_size);
2621 __ addq(r9, Operand(kScratchRegister, 0)); 2626 __ addq(r9, Operand(kScratchRegister, 0));
2622 // Argument 6 passed in r9 on Linux and on the stack on Windows. 2627 // Argument 6 passed in r9 on Linux and on the stack on Windows.
2623 #ifdef _WIN64 2628 #ifdef _WIN64
2624 __ movq(Operand(rsp, (argument_slots_on_stack - 3) * kPointerSize), r9); 2629 __ movq(Operand(rsp, (argument_slots_on_stack - 3) * kPointerSize), r9);
2625 #endif 2630 #endif
2626 2631
2627 // Argument 5: static offsets vector buffer. 2632 // Argument 5: static offsets vector buffer.
2628 __ movq(r8, ExternalReference::address_of_static_offsets_vector()); 2633 __ movq(r8, ExternalReference::address_of_static_offsets_vector(isolate));
2629 // 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.
2630 #ifdef _WIN64 2635 #ifdef _WIN64
2631 __ movq(Operand(rsp, (argument_slots_on_stack - 4) * kPointerSize), r8); 2636 __ movq(Operand(rsp, (argument_slots_on_stack - 4) * kPointerSize), r8);
2632 #endif 2637 #endif
2633 2638
2634 // 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.
2635 #ifdef _WIN64 2640 #ifdef _WIN64
2636 Register arg4 = r9; 2641 Register arg4 = r9;
2637 Register arg3 = r8; 2642 Register arg3 = r8;
2638 Register arg2 = rdx; 2643 Register arg2 = rdx;
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
2722 __ movq(rax, Operand(rsp, kSubjectOffset)); 2727 __ movq(rax, Operand(rsp, kSubjectOffset));
2723 __ movq(FieldOperand(rbx, RegExpImpl::kLastSubjectOffset), rax); 2728 __ movq(FieldOperand(rbx, RegExpImpl::kLastSubjectOffset), rax);
2724 __ movq(rcx, rbx); 2729 __ movq(rcx, rbx);
2725 __ RecordWrite(rcx, RegExpImpl::kLastSubjectOffset, rax, rdi); 2730 __ RecordWrite(rcx, RegExpImpl::kLastSubjectOffset, rax, rdi);
2726 __ movq(rax, Operand(rsp, kSubjectOffset)); 2731 __ movq(rax, Operand(rsp, kSubjectOffset));
2727 __ movq(FieldOperand(rbx, RegExpImpl::kLastInputOffset), rax); 2732 __ movq(FieldOperand(rbx, RegExpImpl::kLastInputOffset), rax);
2728 __ movq(rcx, rbx); 2733 __ movq(rcx, rbx);
2729 __ RecordWrite(rcx, RegExpImpl::kLastInputOffset, rax, rdi); 2734 __ RecordWrite(rcx, RegExpImpl::kLastInputOffset, rax, rdi);
2730 2735
2731 // Get the static offsets vector filled by the native regexp code. 2736 // Get the static offsets vector filled by the native regexp code.
2732 __ movq(rcx, ExternalReference::address_of_static_offsets_vector()); 2737 __ movq(rcx, ExternalReference::address_of_static_offsets_vector(isolate));
2733 2738
2734 // rbx: last_match_info backing store (FixedArray) 2739 // rbx: last_match_info backing store (FixedArray)
2735 // rcx: offsets vector 2740 // rcx: offsets vector
2736 // rdx: number of capture registers 2741 // rdx: number of capture registers
2737 NearLabel next_capture, done; 2742 NearLabel next_capture, done;
2738 // Capture register counter starts from number of capture registers and 2743 // Capture register counter starts from number of capture registers and
2739 // counts down until wraping after zero. 2744 // counts down until wraping after zero.
2740 __ bind(&next_capture); 2745 __ bind(&next_capture);
2741 __ subq(rdx, Immediate(1)); 2746 __ subq(rdx, Immediate(1));
2742 __ j(negative, &done); 2747 __ j(negative, &done);
(...skipping 12 matching lines...) Expand all
2755 // Return last match info. 2760 // Return last match info.
2756 __ movq(rax, Operand(rsp, kLastMatchInfoOffset)); 2761 __ movq(rax, Operand(rsp, kLastMatchInfoOffset));
2757 __ ret(4 * kPointerSize); 2762 __ ret(4 * kPointerSize);
2758 2763
2759 __ bind(&exception); 2764 __ bind(&exception);
2760 // Result must now be exception. If there is no pending exception already a 2765 // 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 2766 // 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. 2767 // haven't created the exception yet. Handle that in the runtime system.
2763 // TODO(592): Rerunning the RegExp to get the stack overflow exception. 2768 // TODO(592): Rerunning the RegExp to get the stack overflow exception.
2764 ExternalReference pending_exception_address( 2769 ExternalReference pending_exception_address(
2765 Isolate::k_pending_exception_address); 2770 Isolate::k_pending_exception_address, isolate);
2766 __ movq(rbx, pending_exception_address); 2771 __ movq(rbx, pending_exception_address);
2767 __ movq(rax, Operand(rbx, 0)); 2772 __ movq(rax, Operand(rbx, 0));
2768 __ LoadRoot(rdx, Heap::kTheHoleValueRootIndex); 2773 __ LoadRoot(rdx, Heap::kTheHoleValueRootIndex);
2769 __ cmpq(rax, rdx); 2774 __ cmpq(rax, rdx);
2770 __ j(equal, &runtime); 2775 __ j(equal, &runtime);
2771 __ movq(Operand(rbx, 0), rdx); 2776 __ movq(Operand(rbx, 0), rdx);
2772 2777
2773 __ CompareRoot(rax, Heap::kTerminationExceptionRootIndex); 2778 __ CompareRoot(rax, Heap::kTerminationExceptionRootIndex);
2774 NearLabel termination_exception; 2779 NearLabel termination_exception;
2775 __ j(equal, &termination_exception); 2780 __ j(equal, &termination_exception);
(...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after
3371 #else // _WIN64 3376 #else // _WIN64
3372 __ movq(rdi, rax); 3377 __ movq(rdi, rax);
3373 #endif 3378 #endif
3374 __ movq(kScratchRegister, 3379 __ movq(kScratchRegister,
3375 FUNCTION_ADDR(Runtime::PerformGC), 3380 FUNCTION_ADDR(Runtime::PerformGC),
3376 RelocInfo::RUNTIME_ENTRY); 3381 RelocInfo::RUNTIME_ENTRY);
3377 __ call(kScratchRegister); 3382 __ call(kScratchRegister);
3378 } 3383 }
3379 3384
3380 ExternalReference scope_depth = 3385 ExternalReference scope_depth =
3381 ExternalReference::heap_always_allocate_scope_depth(); 3386 ExternalReference::heap_always_allocate_scope_depth(masm->isolate());
3382 if (always_allocate_scope) { 3387 if (always_allocate_scope) {
3383 __ movq(kScratchRegister, scope_depth); 3388 __ movq(kScratchRegister, scope_depth);
3384 __ incl(Operand(kScratchRegister, 0)); 3389 __ incl(Operand(kScratchRegister, 0));
3385 } 3390 }
3386 3391
3387 // Call C function. 3392 // Call C function.
3388 #ifdef _WIN64 3393 #ifdef _WIN64
3389 // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9 3394 // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9
3390 // Store Arguments object on stack, below the 4 WIN64 ABI parameter slots. 3395 // Store Arguments object on stack, below the 4 WIN64 ABI parameter slots.
3391 __ movq(StackSpaceOperand(0), r14); // argc. 3396 __ movq(StackSpaceOperand(0), r14); // argc.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
3450 __ testl(rax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); 3455 __ testl(rax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize));
3451 __ j(zero, &retry); 3456 __ j(zero, &retry);
3452 3457
3453 // Special handling of out of memory exceptions. 3458 // Special handling of out of memory exceptions.
3454 __ movq(kScratchRegister, Failure::OutOfMemoryException(), RelocInfo::NONE); 3459 __ movq(kScratchRegister, Failure::OutOfMemoryException(), RelocInfo::NONE);
3455 __ cmpq(rax, kScratchRegister); 3460 __ cmpq(rax, kScratchRegister);
3456 __ j(equal, throw_out_of_memory_exception); 3461 __ j(equal, throw_out_of_memory_exception);
3457 3462
3458 // Retrieve the pending exception and clear the variable. 3463 // Retrieve the pending exception and clear the variable.
3459 ExternalReference pending_exception_address( 3464 ExternalReference pending_exception_address(
3460 Isolate::k_pending_exception_address); 3465 Isolate::k_pending_exception_address, masm->isolate());
3461 __ movq(kScratchRegister, pending_exception_address); 3466 __ movq(kScratchRegister, pending_exception_address);
3462 __ movq(rax, Operand(kScratchRegister, 0)); 3467 __ movq(rax, Operand(kScratchRegister, 0));
3463 __ movq(rdx, ExternalReference::the_hole_value_location()); 3468 __ movq(rdx, ExternalReference::the_hole_value_location(masm->isolate()));
3464 __ movq(rdx, Operand(rdx, 0)); 3469 __ movq(rdx, Operand(rdx, 0));
3465 __ movq(Operand(kScratchRegister, 0), rdx); 3470 __ movq(Operand(kScratchRegister, 0), rdx);
3466 3471
3467 // Special handling of termination exceptions which are uncatchable 3472 // Special handling of termination exceptions which are uncatchable
3468 // by javascript code. 3473 // by javascript code.
3469 __ CompareRoot(rax, Heap::kTerminationExceptionRootIndex); 3474 __ CompareRoot(rax, Heap::kTerminationExceptionRootIndex);
3470 __ j(equal, throw_termination_exception); 3475 __ j(equal, throw_termination_exception);
3471 3476
3472 // Handle normal exception. 3477 // Handle normal exception.
3473 __ jmp(throw_normal_exception); 3478 __ jmp(throw_normal_exception);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
3582 __ push(r14); 3587 __ push(r14);
3583 __ push(r15); 3588 __ push(r15);
3584 #ifdef _WIN64 3589 #ifdef _WIN64
3585 __ push(rdi); // Only callee save in Win64 ABI, argument in AMD64 ABI. 3590 __ 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. 3591 __ push(rsi); // Only callee save in Win64 ABI, argument in AMD64 ABI.
3587 #endif 3592 #endif
3588 __ push(rbx); 3593 __ push(rbx);
3589 // TODO(X64): On Win64, if we ever use XMM6-XMM15, the low low 64 bits are 3594 // TODO(X64): On Win64, if we ever use XMM6-XMM15, the low low 64 bits are
3590 // callee save as well. 3595 // callee save as well.
3591 3596
3597 Isolate* isolate = masm->isolate();
3598
3592 // Save copies of the top frame descriptor on the stack. 3599 // Save copies of the top frame descriptor on the stack.
3593 ExternalReference c_entry_fp(Isolate::k_c_entry_fp_address); 3600 ExternalReference c_entry_fp(Isolate::k_c_entry_fp_address, isolate);
3594 __ load_rax(c_entry_fp); 3601 __ load_rax(c_entry_fp);
3595 __ push(rax); 3602 __ push(rax);
3596 3603
3597 // Set up the roots and smi constant registers. 3604 // Set up the roots and smi constant registers.
3598 // Needs to be done before any further smi loads. 3605 // Needs to be done before any further smi loads.
3599 __ InitializeRootRegister(); 3606 __ InitializeRootRegister();
3600 __ InitializeSmiConstantRegister(); 3607 __ InitializeSmiConstantRegister();
3601 3608
3602 #ifdef ENABLE_LOGGING_AND_PROFILING 3609 #ifdef ENABLE_LOGGING_AND_PROFILING
3603 // If this is the outermost JS call, set js_entry_sp value. 3610 // If this is the outermost JS call, set js_entry_sp value.
3604 ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address); 3611 ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, isolate);
3605 __ load_rax(js_entry_sp); 3612 __ load_rax(js_entry_sp);
3606 __ testq(rax, rax); 3613 __ testq(rax, rax);
3607 __ j(not_zero, &not_outermost_js); 3614 __ j(not_zero, &not_outermost_js);
3608 __ movq(rax, rbp); 3615 __ movq(rax, rbp);
3609 __ store_rax(js_entry_sp); 3616 __ store_rax(js_entry_sp);
3610 __ bind(&not_outermost_js); 3617 __ bind(&not_outermost_js);
3611 #endif 3618 #endif
3612 3619
3613 // Call a faked try-block that does the invoke. 3620 // Call a faked try-block that does the invoke.
3614 __ call(&invoke); 3621 __ call(&invoke);
3615 3622
3616 // Caught exception: Store result (exception) in the pending 3623 // Caught exception: Store result (exception) in the pending
3617 // exception field in the JSEnv and return a failure sentinel. 3624 // exception field in the JSEnv and return a failure sentinel.
3618 ExternalReference pending_exception(Isolate::k_pending_exception_address); 3625 ExternalReference pending_exception(Isolate::k_pending_exception_address,
3626 isolate);
3619 __ store_rax(pending_exception); 3627 __ store_rax(pending_exception);
3620 __ movq(rax, Failure::Exception(), RelocInfo::NONE); 3628 __ movq(rax, Failure::Exception(), RelocInfo::NONE);
3621 __ jmp(&exit); 3629 __ jmp(&exit);
3622 3630
3623 // Invoke: Link this frame into the handler chain. 3631 // Invoke: Link this frame into the handler chain.
3624 __ bind(&invoke); 3632 __ bind(&invoke);
3625 __ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER); 3633 __ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER);
3626 3634
3627 // Clear any pending exceptions. 3635 // Clear any pending exceptions.
3628 __ load_rax(ExternalReference::the_hole_value_location()); 3636 __ load_rax(ExternalReference::the_hole_value_location(isolate));
3629 __ store_rax(pending_exception); 3637 __ store_rax(pending_exception);
3630 3638
3631 // Fake a receiver (NULL). 3639 // Fake a receiver (NULL).
3632 __ push(Immediate(0)); // receiver 3640 __ push(Immediate(0)); // receiver
3633 3641
3634 // Invoke the function by calling through JS entry trampoline 3642 // Invoke the function by calling through JS entry trampoline
3635 // builtin and pop the faked function when we return. We load the address 3643 // 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 3644 // from an external reference instead of inlining the call target address
3637 // directly in the code, because the builtin stubs may not have been 3645 // directly in the code, because the builtin stubs may not have been
3638 // generated yet at the time this code is generated. 3646 // generated yet at the time this code is generated.
3639 if (is_construct) { 3647 if (is_construct) {
3640 ExternalReference construct_entry(Builtins::JSConstructEntryTrampoline); 3648 ExternalReference construct_entry(Builtins::JSConstructEntryTrampoline,
3649 isolate);
3641 __ load_rax(construct_entry); 3650 __ load_rax(construct_entry);
3642 } else { 3651 } else {
3643 ExternalReference entry(Builtins::JSEntryTrampoline); 3652 ExternalReference entry(Builtins::JSEntryTrampoline, isolate);
3644 __ load_rax(entry); 3653 __ load_rax(entry);
3645 } 3654 }
3646 __ lea(kScratchRegister, FieldOperand(rax, Code::kHeaderSize)); 3655 __ lea(kScratchRegister, FieldOperand(rax, Code::kHeaderSize));
3647 __ call(kScratchRegister); 3656 __ call(kScratchRegister);
3648 3657
3649 // Unlink this frame from the handler chain. 3658 // Unlink this frame from the handler chain.
3650 __ movq(kScratchRegister, ExternalReference(Isolate::k_handler_address)); 3659 __ movq(kScratchRegister,
3660 ExternalReference(Isolate::k_handler_address, isolate));
3651 __ pop(Operand(kScratchRegister, 0)); 3661 __ pop(Operand(kScratchRegister, 0));
3652 // Pop next_sp. 3662 // Pop next_sp.
3653 __ addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); 3663 __ addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize));
3654 3664
3655 #ifdef ENABLE_LOGGING_AND_PROFILING 3665 #ifdef ENABLE_LOGGING_AND_PROFILING
3656 // If current RBP value is the same as js_entry_sp value, it means that 3666 // If current RBP value is the same as js_entry_sp value, it means that
3657 // the current function is the outermost. 3667 // the current function is the outermost.
3658 __ movq(kScratchRegister, js_entry_sp); 3668 __ movq(kScratchRegister, js_entry_sp);
3659 __ cmpq(rbp, Operand(kScratchRegister, 0)); 3669 __ cmpq(rbp, Operand(kScratchRegister, 0));
3660 __ j(not_equal, &not_outermost_js_2); 3670 __ j(not_equal, &not_outermost_js_2);
3661 __ movq(Operand(kScratchRegister, 0), Immediate(0)); 3671 __ movq(Operand(kScratchRegister, 0), Immediate(0));
3662 __ bind(&not_outermost_js_2); 3672 __ bind(&not_outermost_js_2);
3663 #endif 3673 #endif
3664 3674
3665 // Restore the top frame descriptor from the stack. 3675 // Restore the top frame descriptor from the stack.
3666 __ bind(&exit); 3676 __ bind(&exit);
3667 __ movq(kScratchRegister, ExternalReference(Isolate::k_c_entry_fp_address)); 3677 __ movq(kScratchRegister,
3678 ExternalReference(Isolate::k_c_entry_fp_address, isolate));
3668 __ pop(Operand(kScratchRegister, 0)); 3679 __ pop(Operand(kScratchRegister, 0));
3669 3680
3670 // Restore callee-saved registers (X64 conventions). 3681 // Restore callee-saved registers (X64 conventions).
3671 __ pop(rbx); 3682 __ pop(rbx);
3672 #ifdef _WIN64 3683 #ifdef _WIN64
3673 // Callee save on in Win64 ABI, arguments/volatile in AMD64 ABI. 3684 // Callee save on in Win64 ABI, arguments/volatile in AMD64 ABI.
3674 __ pop(rsi); 3685 __ pop(rsi);
3675 __ pop(rdi); 3686 __ pop(rdi);
3676 #endif 3687 #endif
3677 __ pop(r15); 3688 __ pop(r15);
(...skipping 1356 matching lines...) Expand 10 before | Expand all | Expand 10 after
5034 5045
5035 5046
5036 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { 5047 void ICCompareStub::GenerateMiss(MacroAssembler* masm) {
5037 // Save the registers. 5048 // Save the registers.
5038 __ pop(rcx); 5049 __ pop(rcx);
5039 __ push(rdx); 5050 __ push(rdx);
5040 __ push(rax); 5051 __ push(rax);
5041 __ push(rcx); 5052 __ push(rcx);
5042 5053
5043 // Call the runtime system in a fresh internal frame. 5054 // Call the runtime system in a fresh internal frame.
5044 ExternalReference miss = ExternalReference(IC_Utility(IC::kCompareIC_Miss)); 5055 ExternalReference miss =
5056 ExternalReference(IC_Utility(IC::kCompareIC_Miss), masm->isolate());
5045 __ EnterInternalFrame(); 5057 __ EnterInternalFrame();
5046 __ push(rdx); 5058 __ push(rdx);
5047 __ push(rax); 5059 __ push(rax);
5048 __ Push(Smi::FromInt(op_)); 5060 __ Push(Smi::FromInt(op_));
5049 __ CallExternalReference(miss, 3); 5061 __ CallExternalReference(miss, 3);
5050 __ LeaveInternalFrame(); 5062 __ LeaveInternalFrame();
5051 5063
5052 // Compute the entry point of the rewritten stub. 5064 // Compute the entry point of the rewritten stub.
5053 __ lea(rdi, FieldOperand(rax, Code::kHeaderSize)); 5065 __ lea(rdi, FieldOperand(rax, Code::kHeaderSize));
5054 5066
5055 // Restore registers. 5067 // Restore registers.
5056 __ pop(rcx); 5068 __ pop(rcx);
5057 __ pop(rax); 5069 __ pop(rax);
5058 __ pop(rdx); 5070 __ pop(rdx);
5059 __ push(rcx); 5071 __ push(rcx);
5060 5072
5061 // Do a tail call to the rewritten stub. 5073 // Do a tail call to the rewritten stub.
5062 __ jmp(rdi); 5074 __ jmp(rdi);
5063 } 5075 }
5064 5076
5065 5077
5066 #undef __ 5078 #undef __
5067 5079
5068 } } // namespace v8::internal 5080 } } // namespace v8::internal
5069 5081
5070 #endif // V8_TARGET_ARCH_X64 5082 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/builtins-x64.cc ('k') | src/x64/codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698