| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 Isolate* isolate, | 295 Isolate* isolate, |
| 296 CodeStubInterfaceDescriptor* descriptor) { | 296 CodeStubInterfaceDescriptor* descriptor) { |
| 297 static Register registers[] = { rax, rbx, rcx, rdx }; | 297 static Register registers[] = { rax, rbx, rcx, rdx }; |
| 298 descriptor->register_param_count_ = 4; | 298 descriptor->register_param_count_ = 4; |
| 299 descriptor->register_params_ = registers; | 299 descriptor->register_params_ = registers; |
| 300 descriptor->deoptimization_handler_ = | 300 descriptor->deoptimization_handler_ = |
| 301 FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss); | 301 FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss); |
| 302 } | 302 } |
| 303 | 303 |
| 304 | 304 |
| 305 void NewStringAddStub::InitializeInterfaceDescriptor( |
| 306 Isolate* isolate, |
| 307 CodeStubInterfaceDescriptor* descriptor) { |
| 308 static Register registers[] = { rdx, rax }; |
| 309 descriptor->register_param_count_ = 2; |
| 310 descriptor->register_params_ = registers; |
| 311 descriptor->deoptimization_handler_ = |
| 312 Runtime::FunctionForId(Runtime::kStringAdd)->entry; |
| 313 } |
| 314 |
| 315 |
| 305 #define __ ACCESS_MASM(masm) | 316 #define __ ACCESS_MASM(masm) |
| 306 | 317 |
| 307 | 318 |
| 308 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { | 319 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { |
| 309 // Update the static counter each time a new code stub is generated. | 320 // Update the static counter each time a new code stub is generated. |
| 310 Isolate* isolate = masm->isolate(); | 321 Isolate* isolate = masm->isolate(); |
| 311 isolate->counters()->code_stubs()->Increment(); | 322 isolate->counters()->code_stubs()->Increment(); |
| 312 | 323 |
| 313 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate); | 324 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate); |
| 314 int param_count = descriptor->register_param_count_; | 325 int param_count = descriptor->register_param_count_; |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 624 __ xorl(rax, rdi); | 635 __ xorl(rax, rdi); |
| 625 __ xorl(rcx, rax); | 636 __ xorl(rcx, rax); |
| 626 ASSERT(IsPowerOf2(TranscendentalCache::SubCache::kCacheSize)); | 637 ASSERT(IsPowerOf2(TranscendentalCache::SubCache::kCacheSize)); |
| 627 __ andl(rcx, Immediate(TranscendentalCache::SubCache::kCacheSize - 1)); | 638 __ andl(rcx, Immediate(TranscendentalCache::SubCache::kCacheSize - 1)); |
| 628 | 639 |
| 629 // ST[0] == double value. | 640 // ST[0] == double value. |
| 630 // rbx = bits of double value. | 641 // rbx = bits of double value. |
| 631 // rcx = TranscendentalCache::hash(double value). | 642 // rcx = TranscendentalCache::hash(double value). |
| 632 ExternalReference cache_array = | 643 ExternalReference cache_array = |
| 633 ExternalReference::transcendental_cache_array_address(masm->isolate()); | 644 ExternalReference::transcendental_cache_array_address(masm->isolate()); |
| 634 __ movq(rax, cache_array); | 645 __ Move(rax, cache_array); |
| 635 int cache_array_index = | 646 int cache_array_index = |
| 636 type_ * sizeof(masm->isolate()->transcendental_cache()->caches_[0]); | 647 type_ * sizeof(masm->isolate()->transcendental_cache()->caches_[0]); |
| 637 __ movq(rax, Operand(rax, cache_array_index)); | 648 __ movq(rax, Operand(rax, cache_array_index)); |
| 638 // rax points to the cache for the type type_. | 649 // rax points to the cache for the type type_. |
| 639 // If NULL, the cache hasn't been initialized yet, so go through runtime. | 650 // If NULL, the cache hasn't been initialized yet, so go through runtime. |
| 640 __ testq(rax, rax); | 651 __ testq(rax, rax); |
| 641 __ j(zero, &runtime_call_clear_stack); // Only clears stack if TAGGED. | 652 __ j(zero, &runtime_call_clear_stack); // Only clears stack if TAGGED. |
| 642 #ifdef DEBUG | 653 #ifdef DEBUG |
| 643 // Check that the layout of cache elements match expectations. | 654 // Check that the layout of cache elements match expectations. |
| 644 { // NOLINT - doesn't like a single brace on a line. | 655 { // NOLINT - doesn't like a single brace on a line. |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 952 __ cmpl(exponent, Immediate(0x80000000u)); | 963 __ cmpl(exponent, Immediate(0x80000000u)); |
| 953 __ j(equal, &call_runtime); | 964 __ j(equal, &call_runtime); |
| 954 | 965 |
| 955 if (exponent_type_ == ON_STACK) { | 966 if (exponent_type_ == ON_STACK) { |
| 956 // Detect square root case. Crankshaft detects constant +/-0.5 at | 967 // Detect square root case. Crankshaft detects constant +/-0.5 at |
| 957 // compile time and uses DoMathPowHalf instead. We then skip this check | 968 // compile time and uses DoMathPowHalf instead. We then skip this check |
| 958 // for non-constant cases of +/-0.5 as these hardly occur. | 969 // for non-constant cases of +/-0.5 as these hardly occur. |
| 959 Label continue_sqrt, continue_rsqrt, not_plus_half; | 970 Label continue_sqrt, continue_rsqrt, not_plus_half; |
| 960 // Test for 0.5. | 971 // Test for 0.5. |
| 961 // Load double_scratch with 0.5. | 972 // Load double_scratch with 0.5. |
| 962 __ movq(scratch, V8_UINT64_C(0x3FE0000000000000), RelocInfo::NONE64); | 973 __ movq(scratch, V8_UINT64_C(0x3FE0000000000000)); |
| 963 __ movq(double_scratch, scratch); | 974 __ movq(double_scratch, scratch); |
| 964 // Already ruled out NaNs for exponent. | 975 // Already ruled out NaNs for exponent. |
| 965 __ ucomisd(double_scratch, double_exponent); | 976 __ ucomisd(double_scratch, double_exponent); |
| 966 __ j(not_equal, ¬_plus_half, Label::kNear); | 977 __ j(not_equal, ¬_plus_half, Label::kNear); |
| 967 | 978 |
| 968 // Calculates square root of base. Check for the special case of | 979 // Calculates square root of base. Check for the special case of |
| 969 // Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13). | 980 // Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13). |
| 970 // According to IEEE-754, double-precision -Infinity has the highest | 981 // According to IEEE-754, double-precision -Infinity has the highest |
| 971 // 12 bits set and the lowest 52 bits cleared. | 982 // 12 bits set and the lowest 52 bits cleared. |
| 972 __ movq(scratch, V8_UINT64_C(0xFFF0000000000000), RelocInfo::NONE64); | 983 __ movq(scratch, V8_UINT64_C(0xFFF0000000000000)); |
| 973 __ movq(double_scratch, scratch); | 984 __ movq(double_scratch, scratch); |
| 974 __ ucomisd(double_scratch, double_base); | 985 __ ucomisd(double_scratch, double_base); |
| 975 // Comparing -Infinity with NaN results in "unordered", which sets the | 986 // Comparing -Infinity with NaN results in "unordered", which sets the |
| 976 // zero flag as if both were equal. However, it also sets the carry flag. | 987 // zero flag as if both were equal. However, it also sets the carry flag. |
| 977 __ j(not_equal, &continue_sqrt, Label::kNear); | 988 __ j(not_equal, &continue_sqrt, Label::kNear); |
| 978 __ j(carry, &continue_sqrt, Label::kNear); | 989 __ j(carry, &continue_sqrt, Label::kNear); |
| 979 | 990 |
| 980 // Set result to Infinity in the special case. | 991 // Set result to Infinity in the special case. |
| 981 __ xorps(double_result, double_result); | 992 __ xorps(double_result, double_result); |
| 982 __ subsd(double_result, double_scratch); | 993 __ subsd(double_result, double_scratch); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 994 // Load double_scratch with -0.5 by substracting 1. | 1005 // Load double_scratch with -0.5 by substracting 1. |
| 995 __ subsd(double_scratch, double_result); | 1006 __ subsd(double_scratch, double_result); |
| 996 // Already ruled out NaNs for exponent. | 1007 // Already ruled out NaNs for exponent. |
| 997 __ ucomisd(double_scratch, double_exponent); | 1008 __ ucomisd(double_scratch, double_exponent); |
| 998 __ j(not_equal, &fast_power, Label::kNear); | 1009 __ j(not_equal, &fast_power, Label::kNear); |
| 999 | 1010 |
| 1000 // Calculates reciprocal of square root of base. Check for the special | 1011 // Calculates reciprocal of square root of base. Check for the special |
| 1001 // case of Math.pow(-Infinity, -0.5) == 0 (ECMA spec, 15.8.2.13). | 1012 // case of Math.pow(-Infinity, -0.5) == 0 (ECMA spec, 15.8.2.13). |
| 1002 // According to IEEE-754, double-precision -Infinity has the highest | 1013 // According to IEEE-754, double-precision -Infinity has the highest |
| 1003 // 12 bits set and the lowest 52 bits cleared. | 1014 // 12 bits set and the lowest 52 bits cleared. |
| 1004 __ movq(scratch, V8_UINT64_C(0xFFF0000000000000), RelocInfo::NONE64); | 1015 __ movq(scratch, V8_UINT64_C(0xFFF0000000000000)); |
| 1005 __ movq(double_scratch, scratch); | 1016 __ movq(double_scratch, scratch); |
| 1006 __ ucomisd(double_scratch, double_base); | 1017 __ ucomisd(double_scratch, double_base); |
| 1007 // Comparing -Infinity with NaN results in "unordered", which sets the | 1018 // Comparing -Infinity with NaN results in "unordered", which sets the |
| 1008 // zero flag as if both were equal. However, it also sets the carry flag. | 1019 // zero flag as if both were equal. However, it also sets the carry flag. |
| 1009 __ j(not_equal, &continue_rsqrt, Label::kNear); | 1020 __ j(not_equal, &continue_rsqrt, Label::kNear); |
| 1010 __ j(carry, &continue_rsqrt, Label::kNear); | 1021 __ j(carry, &continue_rsqrt, Label::kNear); |
| 1011 | 1022 |
| 1012 // Set result to 0 in the special case. | 1023 // Set result to 0 in the special case. |
| 1013 __ xorps(double_result, double_result); | 1024 __ xorps(double_result, double_result); |
| 1014 __ jmp(&done); | 1025 __ jmp(&done); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1129 __ movsd(xmm0, double_base); | 1140 __ movsd(xmm0, double_base); |
| 1130 ASSERT(double_exponent.is(xmm1)); | 1141 ASSERT(double_exponent.is(xmm1)); |
| 1131 { | 1142 { |
| 1132 AllowExternalCallThatCantCauseGC scope(masm); | 1143 AllowExternalCallThatCantCauseGC scope(masm); |
| 1133 __ PrepareCallCFunction(2); | 1144 __ PrepareCallCFunction(2); |
| 1134 __ CallCFunction( | 1145 __ CallCFunction( |
| 1135 ExternalReference::power_double_double_function(masm->isolate()), 2); | 1146 ExternalReference::power_double_double_function(masm->isolate()), 2); |
| 1136 } | 1147 } |
| 1137 // Return value is in xmm0. | 1148 // Return value is in xmm0. |
| 1138 __ movsd(double_result, xmm0); | 1149 __ movsd(double_result, xmm0); |
| 1139 // Restore context register. | |
| 1140 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | |
| 1141 | 1150 |
| 1142 __ bind(&done); | 1151 __ bind(&done); |
| 1143 __ IncrementCounter(counters->math_pow(), 1); | 1152 __ IncrementCounter(counters->math_pow(), 1); |
| 1144 __ ret(0); | 1153 __ ret(0); |
| 1145 } | 1154 } |
| 1146 } | 1155 } |
| 1147 | 1156 |
| 1148 | 1157 |
| 1149 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { | 1158 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { |
| 1150 Label miss; | 1159 Label miss; |
| (...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1866 __ LoadAddress(kScratchRegister, | 1875 __ LoadAddress(kScratchRegister, |
| 1867 ExternalReference::isolate_address(masm->isolate())); | 1876 ExternalReference::isolate_address(masm->isolate())); |
| 1868 __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize), | 1877 __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize), |
| 1869 kScratchRegister); | 1878 kScratchRegister); |
| 1870 | 1879 |
| 1871 // Argument 8: Indicate that this is a direct call from JavaScript. | 1880 // Argument 8: Indicate that this is a direct call from JavaScript. |
| 1872 __ movq(Operand(rsp, (argument_slots_on_stack - 2) * kPointerSize), | 1881 __ movq(Operand(rsp, (argument_slots_on_stack - 2) * kPointerSize), |
| 1873 Immediate(1)); | 1882 Immediate(1)); |
| 1874 | 1883 |
| 1875 // Argument 7: Start (high end) of backtracking stack memory area. | 1884 // Argument 7: Start (high end) of backtracking stack memory area. |
| 1876 __ movq(kScratchRegister, address_of_regexp_stack_memory_address); | 1885 __ Move(kScratchRegister, address_of_regexp_stack_memory_address); |
| 1877 __ movq(r9, Operand(kScratchRegister, 0)); | 1886 __ movq(r9, Operand(kScratchRegister, 0)); |
| 1878 __ movq(kScratchRegister, address_of_regexp_stack_memory_size); | 1887 __ Move(kScratchRegister, address_of_regexp_stack_memory_size); |
| 1879 __ addq(r9, Operand(kScratchRegister, 0)); | 1888 __ addq(r9, Operand(kScratchRegister, 0)); |
| 1880 __ movq(Operand(rsp, (argument_slots_on_stack - 3) * kPointerSize), r9); | 1889 __ movq(Operand(rsp, (argument_slots_on_stack - 3) * kPointerSize), r9); |
| 1881 | 1890 |
| 1882 // Argument 6: Set the number of capture registers to zero to force global | 1891 // Argument 6: Set the number of capture registers to zero to force global |
| 1883 // regexps to behave as non-global. This does not affect non-global regexps. | 1892 // regexps to behave as non-global. This does not affect non-global regexps. |
| 1884 // Argument 6 is passed in r9 on Linux and on the stack on Windows. | 1893 // Argument 6 is passed in r9 on Linux and on the stack on Windows. |
| 1885 #ifdef _WIN64 | 1894 #ifdef _WIN64 |
| 1886 __ movq(Operand(rsp, (argument_slots_on_stack - 4) * kPointerSize), | 1895 __ movq(Operand(rsp, (argument_slots_on_stack - 4) * kPointerSize), |
| 1887 Immediate(0)); | 1896 Immediate(0)); |
| 1888 #else | 1897 #else |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2215 | 2224 |
| 2216 static void CheckInputType(MacroAssembler* masm, | 2225 static void CheckInputType(MacroAssembler* masm, |
| 2217 Register input, | 2226 Register input, |
| 2218 CompareIC::State expected, | 2227 CompareIC::State expected, |
| 2219 Label* fail) { | 2228 Label* fail) { |
| 2220 Label ok; | 2229 Label ok; |
| 2221 if (expected == CompareIC::SMI) { | 2230 if (expected == CompareIC::SMI) { |
| 2222 __ JumpIfNotSmi(input, fail); | 2231 __ JumpIfNotSmi(input, fail); |
| 2223 } else if (expected == CompareIC::NUMBER) { | 2232 } else if (expected == CompareIC::NUMBER) { |
| 2224 __ JumpIfSmi(input, &ok); | 2233 __ JumpIfSmi(input, &ok); |
| 2225 __ CompareMap(input, masm->isolate()->factory()->heap_number_map(), NULL); | 2234 __ CompareMap(input, masm->isolate()->factory()->heap_number_map()); |
| 2226 __ j(not_equal, fail); | 2235 __ j(not_equal, fail); |
| 2227 } | 2236 } |
| 2228 // We could be strict about internalized/non-internalized here, but as long as | 2237 // We could be strict about internalized/non-internalized here, but as long as |
| 2229 // hydrogen doesn't care, the stub doesn't have to care either. | 2238 // hydrogen doesn't care, the stub doesn't have to care either. |
| 2230 __ bind(&ok); | 2239 __ bind(&ok); |
| 2231 } | 2240 } |
| 2232 | 2241 |
| 2233 | 2242 |
| 2234 static void BranchIfNotInternalizedString(MacroAssembler* masm, | 2243 static void BranchIfNotInternalizedString(MacroAssembler* masm, |
| 2235 Label* label, | 2244 Label* label, |
| (...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2803 // Check stack alignment. | 2812 // Check stack alignment. |
| 2804 if (FLAG_debug_code) { | 2813 if (FLAG_debug_code) { |
| 2805 __ CheckStackAlignment(); | 2814 __ CheckStackAlignment(); |
| 2806 } | 2815 } |
| 2807 | 2816 |
| 2808 if (do_gc) { | 2817 if (do_gc) { |
| 2809 // Pass failure code returned from last attempt as first argument to | 2818 // Pass failure code returned from last attempt as first argument to |
| 2810 // PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the | 2819 // PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the |
| 2811 // stack is known to be aligned. This function takes one argument which is | 2820 // stack is known to be aligned. This function takes one argument which is |
| 2812 // passed in register. | 2821 // passed in register. |
| 2813 __ movq(arg_reg_2, ExternalReference::isolate_address(masm->isolate())); | 2822 __ Move(arg_reg_2, ExternalReference::isolate_address(masm->isolate())); |
| 2814 __ movq(arg_reg_1, rax); | 2823 __ movq(arg_reg_1, rax); |
| 2815 __ movq(kScratchRegister, | 2824 __ Move(kScratchRegister, |
| 2816 ExternalReference::perform_gc_function(masm->isolate())); | 2825 ExternalReference::perform_gc_function(masm->isolate())); |
| 2817 __ call(kScratchRegister); | 2826 __ call(kScratchRegister); |
| 2818 } | 2827 } |
| 2819 | 2828 |
| 2820 ExternalReference scope_depth = | 2829 ExternalReference scope_depth = |
| 2821 ExternalReference::heap_always_allocate_scope_depth(masm->isolate()); | 2830 ExternalReference::heap_always_allocate_scope_depth(masm->isolate()); |
| 2822 if (always_allocate_scope) { | 2831 if (always_allocate_scope) { |
| 2823 Operand scope_depth_operand = masm->ExternalOperand(scope_depth); | 2832 Operand scope_depth_operand = masm->ExternalOperand(scope_depth); |
| 2824 __ incl(scope_depth_operand); | 2833 __ incl(scope_depth_operand); |
| 2825 } | 2834 } |
| 2826 | 2835 |
| 2827 // Call C function. | 2836 // Call C function. |
| 2828 #ifdef _WIN64 | 2837 #ifdef _WIN64 |
| 2829 // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9. | 2838 // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9. |
| 2830 // Pass argv and argc as two parameters. The arguments object will | 2839 // Pass argv and argc as two parameters. The arguments object will |
| 2831 // be created by stubs declared by DECLARE_RUNTIME_FUNCTION(). | 2840 // be created by stubs declared by DECLARE_RUNTIME_FUNCTION(). |
| 2832 if (result_size_ < 2) { | 2841 if (result_size_ < 2) { |
| 2833 // Pass a pointer to the Arguments object as the first argument. | 2842 // Pass a pointer to the Arguments object as the first argument. |
| 2834 // Return result in single register (rax). | 2843 // Return result in single register (rax). |
| 2835 __ movq(rcx, r14); // argc. | 2844 __ movq(rcx, r14); // argc. |
| 2836 __ movq(rdx, r15); // argv. | 2845 __ movq(rdx, r15); // argv. |
| 2837 __ movq(r8, ExternalReference::isolate_address(masm->isolate())); | 2846 __ Move(r8, ExternalReference::isolate_address(masm->isolate())); |
| 2838 } else { | 2847 } else { |
| 2839 ASSERT_EQ(2, result_size_); | 2848 ASSERT_EQ(2, result_size_); |
| 2840 // Pass a pointer to the result location as the first argument. | 2849 // Pass a pointer to the result location as the first argument. |
| 2841 __ lea(rcx, StackSpaceOperand(2)); | 2850 __ lea(rcx, StackSpaceOperand(2)); |
| 2842 // Pass a pointer to the Arguments object as the second argument. | 2851 // Pass a pointer to the Arguments object as the second argument. |
| 2843 __ movq(rdx, r14); // argc. | 2852 __ movq(rdx, r14); // argc. |
| 2844 __ movq(r8, r15); // argv. | 2853 __ movq(r8, r15); // argv. |
| 2845 __ movq(r9, ExternalReference::isolate_address(masm->isolate())); | 2854 __ Move(r9, ExternalReference::isolate_address(masm->isolate())); |
| 2846 } | 2855 } |
| 2847 | 2856 |
| 2848 #else // _WIN64 | 2857 #else // _WIN64 |
| 2849 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9. | 2858 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9. |
| 2850 __ movq(rdi, r14); // argc. | 2859 __ movq(rdi, r14); // argc. |
| 2851 __ movq(rsi, r15); // argv. | 2860 __ movq(rsi, r15); // argv. |
| 2852 __ movq(rdx, ExternalReference::isolate_address(masm->isolate())); | 2861 __ Move(rdx, ExternalReference::isolate_address(masm->isolate())); |
| 2853 #endif | 2862 #endif |
| 2854 __ call(rbx); | 2863 __ call(rbx); |
| 2855 // Result is in rax - do not destroy this register! | 2864 // Result is in rax - do not destroy this register! |
| 2856 | 2865 |
| 2857 if (always_allocate_scope) { | 2866 if (always_allocate_scope) { |
| 2858 Operand scope_depth_operand = masm->ExternalOperand(scope_depth); | 2867 Operand scope_depth_operand = masm->ExternalOperand(scope_depth); |
| 2859 __ decl(scope_depth_operand); | 2868 __ decl(scope_depth_operand); |
| 2860 } | 2869 } |
| 2861 | 2870 |
| 2862 // Check for failure result. | 2871 // Check for failure result. |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3023 MacroAssembler::NoRootArrayScope uninitialized_root_register(masm); | 3032 MacroAssembler::NoRootArrayScope uninitialized_root_register(masm); |
| 3024 // Set up frame. | 3033 // Set up frame. |
| 3025 __ push(rbp); | 3034 __ push(rbp); |
| 3026 __ movq(rbp, rsp); | 3035 __ movq(rbp, rsp); |
| 3027 | 3036 |
| 3028 // Push the stack frame type marker twice. | 3037 // Push the stack frame type marker twice. |
| 3029 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; | 3038 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; |
| 3030 // Scratch register is neither callee-save, nor an argument register on any | 3039 // Scratch register is neither callee-save, nor an argument register on any |
| 3031 // platform. It's free to use at this point. | 3040 // platform. It's free to use at this point. |
| 3032 // Cannot use smi-register for loading yet. | 3041 // Cannot use smi-register for loading yet. |
| 3033 __ movq(kScratchRegister, | 3042 __ movq(kScratchRegister, Smi::FromInt(marker), RelocInfo::NONE64); |
| 3034 reinterpret_cast<uint64_t>(Smi::FromInt(marker)), | |
| 3035 RelocInfo::NONE64); | |
| 3036 __ push(kScratchRegister); // context slot | 3043 __ push(kScratchRegister); // context slot |
| 3037 __ push(kScratchRegister); // function slot | 3044 __ push(kScratchRegister); // function slot |
| 3038 // Save callee-saved registers (X64/Win64 calling conventions). | 3045 // Save callee-saved registers (X64/Win64 calling conventions). |
| 3039 __ push(r12); | 3046 __ push(r12); |
| 3040 __ push(r13); | 3047 __ push(r13); |
| 3041 __ push(r14); | 3048 __ push(r14); |
| 3042 __ push(r15); | 3049 __ push(r15); |
| 3043 #ifdef _WIN64 | 3050 #ifdef _WIN64 |
| 3044 __ push(rdi); // Only callee save in Win64 ABI, argument in AMD64 ABI. | 3051 __ push(rdi); // Only callee save in Win64 ABI, argument in AMD64 ABI. |
| 3045 __ push(rsi); // Only callee save in Win64 ABI, argument in AMD64 ABI. | 3052 __ push(rsi); // Only callee save in Win64 ABI, argument in AMD64 ABI. |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3132 __ call(kScratchRegister); | 3139 __ call(kScratchRegister); |
| 3133 | 3140 |
| 3134 // Unlink this frame from the handler chain. | 3141 // Unlink this frame from the handler chain. |
| 3135 __ PopTryHandler(); | 3142 __ PopTryHandler(); |
| 3136 | 3143 |
| 3137 __ bind(&exit); | 3144 __ bind(&exit); |
| 3138 // Check if the current stack frame is marked as the outermost JS frame. | 3145 // Check if the current stack frame is marked as the outermost JS frame. |
| 3139 __ pop(rbx); | 3146 __ pop(rbx); |
| 3140 __ Cmp(rbx, Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)); | 3147 __ Cmp(rbx, Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)); |
| 3141 __ j(not_equal, ¬_outermost_js_2); | 3148 __ j(not_equal, ¬_outermost_js_2); |
| 3142 __ movq(kScratchRegister, js_entry_sp); | 3149 __ Move(kScratchRegister, js_entry_sp); |
| 3143 __ movq(Operand(kScratchRegister, 0), Immediate(0)); | 3150 __ movq(Operand(kScratchRegister, 0), Immediate(0)); |
| 3144 __ bind(¬_outermost_js_2); | 3151 __ bind(¬_outermost_js_2); |
| 3145 | 3152 |
| 3146 // Restore the top frame descriptor from the stack. | 3153 // Restore the top frame descriptor from the stack. |
| 3147 { Operand c_entry_fp_operand = masm->ExternalOperand(c_entry_fp); | 3154 { Operand c_entry_fp_operand = masm->ExternalOperand(c_entry_fp); |
| 3148 __ pop(c_entry_fp_operand); | 3155 __ pop(c_entry_fp_operand); |
| 3149 } | 3156 } |
| 3150 | 3157 |
| 3151 // Restore callee-saved registers (X64 conventions). | 3158 // Restore callee-saved registers (X64 conventions). |
| 3152 #ifdef _WIN64 | 3159 #ifdef _WIN64 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3201 static const int kOffsetToResultValue = 18; | 3208 static const int kOffsetToResultValue = 18; |
| 3202 // The last 4 bytes of the instruction sequence | 3209 // The last 4 bytes of the instruction sequence |
| 3203 // movq(rdi, FieldOperand(rax, HeapObject::kMapOffset)) | 3210 // movq(rdi, FieldOperand(rax, HeapObject::kMapOffset)) |
| 3204 // Move(kScratchRegister, Factory::the_hole_value()) | 3211 // Move(kScratchRegister, Factory::the_hole_value()) |
| 3205 // in front of the hole value address. | 3212 // in front of the hole value address. |
| 3206 static const unsigned int kWordBeforeMapCheckValue = 0xBA49FF78; | 3213 static const unsigned int kWordBeforeMapCheckValue = 0xBA49FF78; |
| 3207 // The last 4 bytes of the instruction sequence | 3214 // The last 4 bytes of the instruction sequence |
| 3208 // __ j(not_equal, &cache_miss); | 3215 // __ j(not_equal, &cache_miss); |
| 3209 // __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex); | 3216 // __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex); |
| 3210 // before the offset of the hole value in the root array. | 3217 // before the offset of the hole value in the root array. |
| 3211 static const unsigned int kWordBeforeResultValue = 0x458B4909; | 3218 static const unsigned int kWordBeforeResultValue = 0x458B4906; |
| 3212 // Only the inline check flag is supported on X64. | 3219 // Only the inline check flag is supported on X64. |
| 3213 ASSERT(flags_ == kNoFlags || HasCallSiteInlineCheck()); | 3220 ASSERT(flags_ == kNoFlags || HasCallSiteInlineCheck()); |
| 3214 int extra_argument_offset = HasCallSiteInlineCheck() ? 1 : 0; | 3221 int extra_argument_offset = HasCallSiteInlineCheck() ? 1 : 0; |
| 3215 | 3222 |
| 3216 // Get the object - go slow case if it's a smi. | 3223 // Get the object - go slow case if it's a smi. |
| 3217 Label slow; | 3224 Label slow; |
| 3218 StackArgumentsAccessor args(rsp, 2 + extra_argument_offset, | 3225 StackArgumentsAccessor args(rsp, 2 + extra_argument_offset, |
| 3219 ARGUMENTS_DONT_CONTAIN_RECEIVER); | 3226 ARGUMENTS_DONT_CONTAIN_RECEIVER); |
| 3220 __ movq(rax, args.GetArgumentOperand(0)); | 3227 __ movq(rax, args.GetArgumentOperand(0)); |
| 3221 __ JumpIfSmi(rax, &slow); | 3228 __ JumpIfSmi(rax, &slow); |
| (...skipping 1316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4538 if (left_ == CompareIC::SMI) { | 4545 if (left_ == CompareIC::SMI) { |
| 4539 __ JumpIfNotSmi(rdx, &miss); | 4546 __ JumpIfNotSmi(rdx, &miss); |
| 4540 } | 4547 } |
| 4541 if (right_ == CompareIC::SMI) { | 4548 if (right_ == CompareIC::SMI) { |
| 4542 __ JumpIfNotSmi(rax, &miss); | 4549 __ JumpIfNotSmi(rax, &miss); |
| 4543 } | 4550 } |
| 4544 | 4551 |
| 4545 // Load left and right operand. | 4552 // Load left and right operand. |
| 4546 Label done, left, left_smi, right_smi; | 4553 Label done, left, left_smi, right_smi; |
| 4547 __ JumpIfSmi(rax, &right_smi, Label::kNear); | 4554 __ JumpIfSmi(rax, &right_smi, Label::kNear); |
| 4548 __ CompareMap(rax, masm->isolate()->factory()->heap_number_map(), NULL); | 4555 __ CompareMap(rax, masm->isolate()->factory()->heap_number_map()); |
| 4549 __ j(not_equal, &maybe_undefined1, Label::kNear); | 4556 __ j(not_equal, &maybe_undefined1, Label::kNear); |
| 4550 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset)); | 4557 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset)); |
| 4551 __ jmp(&left, Label::kNear); | 4558 __ jmp(&left, Label::kNear); |
| 4552 __ bind(&right_smi); | 4559 __ bind(&right_smi); |
| 4553 __ SmiToInteger32(rcx, rax); // Can't clobber rax yet. | 4560 __ SmiToInteger32(rcx, rax); // Can't clobber rax yet. |
| 4554 __ Cvtlsi2sd(xmm1, rcx); | 4561 __ Cvtlsi2sd(xmm1, rcx); |
| 4555 | 4562 |
| 4556 __ bind(&left); | 4563 __ bind(&left); |
| 4557 __ JumpIfSmi(rdx, &left_smi, Label::kNear); | 4564 __ JumpIfSmi(rdx, &left_smi, Label::kNear); |
| 4558 __ CompareMap(rdx, masm->isolate()->factory()->heap_number_map(), NULL); | 4565 __ CompareMap(rdx, masm->isolate()->factory()->heap_number_map()); |
| 4559 __ j(not_equal, &maybe_undefined2, Label::kNear); | 4566 __ j(not_equal, &maybe_undefined2, Label::kNear); |
| 4560 __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset)); | 4567 __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset)); |
| 4561 __ jmp(&done); | 4568 __ jmp(&done); |
| 4562 __ bind(&left_smi); | 4569 __ bind(&left_smi); |
| 4563 __ SmiToInteger32(rcx, rdx); // Can't clobber rdx yet. | 4570 __ SmiToInteger32(rcx, rdx); // Can't clobber rdx yet. |
| 4564 __ Cvtlsi2sd(xmm0, rcx); | 4571 __ Cvtlsi2sd(xmm0, rcx); |
| 4565 | 4572 |
| 4566 __ bind(&done); | 4573 __ bind(&done); |
| 4567 // Compare operands | 4574 // Compare operands |
| 4568 __ ucomisd(xmm0, xmm1); | 4575 __ ucomisd(xmm0, xmm1); |
| (...skipping 1246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5815 __ bind(&fast_elements_case); | 5822 __ bind(&fast_elements_case); |
| 5816 GenerateCase(masm, FAST_ELEMENTS); | 5823 GenerateCase(masm, FAST_ELEMENTS); |
| 5817 } | 5824 } |
| 5818 | 5825 |
| 5819 | 5826 |
| 5820 #undef __ | 5827 #undef __ |
| 5821 | 5828 |
| 5822 } } // namespace v8::internal | 5829 } } // namespace v8::internal |
| 5823 | 5830 |
| 5824 #endif // V8_TARGET_ARCH_X64 | 5831 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |