OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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, ¬_outermost_js); | 3614 __ j(not_zero, ¬_outermost_js); |
3608 __ movq(rax, rbp); | 3615 __ movq(rax, rbp); |
3609 __ store_rax(js_entry_sp); | 3616 __ store_rax(js_entry_sp); |
3610 __ bind(¬_outermost_js); | 3617 __ bind(¬_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, ¬_outermost_js_2); | 3670 __ j(not_equal, ¬_outermost_js_2); |
3661 __ movq(Operand(kScratchRegister, 0), Immediate(0)); | 3671 __ movq(Operand(kScratchRegister, 0), Immediate(0)); |
3662 __ bind(¬_outermost_js_2); | 3672 __ bind(¬_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 Loading... |
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 |
OLD | NEW |