| 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 } | 71 } |
| 72 | 72 |
| 73 | 73 |
| 74 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( | 74 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( |
| 75 Isolate* isolate, | 75 Isolate* isolate, |
| 76 CodeStubInterfaceDescriptor* descriptor) { | 76 CodeStubInterfaceDescriptor* descriptor) { |
| 77 static Register registers[] = { rax, rbx, rcx }; | 77 static Register registers[] = { rax, rbx, rcx }; |
| 78 descriptor->register_param_count_ = 3; | 78 descriptor->register_param_count_ = 3; |
| 79 descriptor->register_params_ = registers; | 79 descriptor->register_params_ = registers; |
| 80 descriptor->deoptimization_handler_ = | 80 descriptor->deoptimization_handler_ = |
| 81 Runtime::FunctionForId(Runtime::kCreateArrayLiteralShallow)->entry; | 81 Runtime::FunctionForId(Runtime::kCreateArrayLiteral)->entry; |
| 82 } | 82 } |
| 83 | 83 |
| 84 | 84 |
| 85 void FastCloneShallowObjectStub::InitializeInterfaceDescriptor( | 85 void FastCloneShallowObjectStub::InitializeInterfaceDescriptor( |
| 86 Isolate* isolate, | 86 Isolate* isolate, |
| 87 CodeStubInterfaceDescriptor* descriptor) { | 87 CodeStubInterfaceDescriptor* descriptor) { |
| 88 static Register registers[] = { rax, rbx, rcx, rdx }; | 88 static Register registers[] = { rax, rbx, rcx, rdx }; |
| 89 descriptor->register_param_count_ = 4; | 89 descriptor->register_param_count_ = 4; |
| 90 descriptor->register_params_ = registers; | 90 descriptor->register_params_ = registers; |
| 91 descriptor->deoptimization_handler_ = | 91 descriptor->deoptimization_handler_ = |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 | 169 |
| 170 | 170 |
| 171 static void InitializeArrayConstructorDescriptor( | 171 static void InitializeArrayConstructorDescriptor( |
| 172 Isolate* isolate, | 172 Isolate* isolate, |
| 173 CodeStubInterfaceDescriptor* descriptor, | 173 CodeStubInterfaceDescriptor* descriptor, |
| 174 int constant_stack_parameter_count) { | 174 int constant_stack_parameter_count) { |
| 175 // register state | 175 // register state |
| 176 // rax -- number of arguments | 176 // rax -- number of arguments |
| 177 // rdi -- function | 177 // rdi -- function |
| 178 // rbx -- type info cell with elements kind | 178 // rbx -- type info cell with elements kind |
| 179 static Register registers[] = { rdi, rbx }; | 179 static Register registers_variable_args[] = { rdi, rbx, rax }; |
| 180 descriptor->register_param_count_ = 2; | 180 static Register registers_no_args[] = { rdi, rbx }; |
| 181 if (constant_stack_parameter_count != 0) { | 181 |
| 182 if (constant_stack_parameter_count == 0) { |
| 183 descriptor->register_param_count_ = 2; |
| 184 descriptor->register_params_ = registers_no_args; |
| 185 } else { |
| 182 // stack param count needs (constructor pointer, and single argument) | 186 // stack param count needs (constructor pointer, and single argument) |
| 187 descriptor->handler_arguments_mode_ = PASS_ARGUMENTS; |
| 183 descriptor->stack_parameter_count_ = rax; | 188 descriptor->stack_parameter_count_ = rax; |
| 189 descriptor->register_param_count_ = 3; |
| 190 descriptor->register_params_ = registers_variable_args; |
| 184 } | 191 } |
| 192 |
| 185 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; | 193 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; |
| 186 descriptor->register_params_ = registers; | |
| 187 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; | 194 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; |
| 188 descriptor->deoptimization_handler_ = | 195 descriptor->deoptimization_handler_ = |
| 189 Runtime::FunctionForId(Runtime::kArrayConstructor)->entry; | 196 Runtime::FunctionForId(Runtime::kArrayConstructor)->entry; |
| 190 } | 197 } |
| 191 | 198 |
| 192 | 199 |
| 193 static void InitializeInternalArrayConstructorDescriptor( | 200 static void InitializeInternalArrayConstructorDescriptor( |
| 194 Isolate* isolate, | 201 Isolate* isolate, |
| 195 CodeStubInterfaceDescriptor* descriptor, | 202 CodeStubInterfaceDescriptor* descriptor, |
| 196 int constant_stack_parameter_count) { | 203 int constant_stack_parameter_count) { |
| 197 // register state | 204 // register state |
| 198 // rax -- number of arguments | 205 // rax -- number of arguments |
| 199 // rdi -- constructor function | 206 // rdi -- constructor function |
| 200 static Register registers[] = { rdi }; | 207 static Register registers_variable_args[] = { rdi, rax }; |
| 201 descriptor->register_param_count_ = 1; | 208 static Register registers_no_args[] = { rdi }; |
| 202 | 209 |
| 203 if (constant_stack_parameter_count != 0) { | 210 if (constant_stack_parameter_count == 0) { |
| 211 descriptor->register_param_count_ = 1; |
| 212 descriptor->register_params_ = registers_no_args; |
| 213 } else { |
| 204 // stack param count needs (constructor pointer, and single argument) | 214 // stack param count needs (constructor pointer, and single argument) |
| 215 descriptor->handler_arguments_mode_ = PASS_ARGUMENTS; |
| 205 descriptor->stack_parameter_count_ = rax; | 216 descriptor->stack_parameter_count_ = rax; |
| 217 descriptor->register_param_count_ = 2; |
| 218 descriptor->register_params_ = registers_variable_args; |
| 206 } | 219 } |
| 220 |
| 207 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; | 221 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; |
| 208 descriptor->register_params_ = registers; | |
| 209 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; | 222 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; |
| 210 descriptor->deoptimization_handler_ = | 223 descriptor->deoptimization_handler_ = |
| 211 Runtime::FunctionForId(Runtime::kInternalArrayConstructor)->entry; | 224 Runtime::FunctionForId(Runtime::kInternalArrayConstructor)->entry; |
| 212 } | 225 } |
| 213 | 226 |
| 214 | 227 |
| 215 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( | 228 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( |
| 216 Isolate* isolate, | 229 Isolate* isolate, |
| 217 CodeStubInterfaceDescriptor* descriptor) { | 230 CodeStubInterfaceDescriptor* descriptor) { |
| 218 InitializeArrayConstructorDescriptor(isolate, descriptor, 0); | 231 InitializeArrayConstructorDescriptor(isolate, descriptor, 0); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 Isolate* isolate, | 308 Isolate* isolate, |
| 296 CodeStubInterfaceDescriptor* descriptor) { | 309 CodeStubInterfaceDescriptor* descriptor) { |
| 297 static Register registers[] = { rax, rbx, rcx, rdx }; | 310 static Register registers[] = { rax, rbx, rcx, rdx }; |
| 298 descriptor->register_param_count_ = 4; | 311 descriptor->register_param_count_ = 4; |
| 299 descriptor->register_params_ = registers; | 312 descriptor->register_params_ = registers; |
| 300 descriptor->deoptimization_handler_ = | 313 descriptor->deoptimization_handler_ = |
| 301 FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss); | 314 FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss); |
| 302 } | 315 } |
| 303 | 316 |
| 304 | 317 |
| 318 void NewStringAddStub::InitializeInterfaceDescriptor( |
| 319 Isolate* isolate, |
| 320 CodeStubInterfaceDescriptor* descriptor) { |
| 321 static Register registers[] = { rdx, rax }; |
| 322 descriptor->register_param_count_ = 2; |
| 323 descriptor->register_params_ = registers; |
| 324 descriptor->deoptimization_handler_ = |
| 325 Runtime::FunctionForId(Runtime::kStringAdd)->entry; |
| 326 } |
| 327 |
| 328 |
| 305 #define __ ACCESS_MASM(masm) | 329 #define __ ACCESS_MASM(masm) |
| 306 | 330 |
| 307 | 331 |
| 308 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { | 332 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { |
| 309 // Update the static counter each time a new code stub is generated. | 333 // Update the static counter each time a new code stub is generated. |
| 310 Isolate* isolate = masm->isolate(); | 334 Isolate* isolate = masm->isolate(); |
| 311 isolate->counters()->code_stubs()->Increment(); | 335 isolate->counters()->code_stubs()->Increment(); |
| 312 | 336 |
| 313 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate); | 337 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate); |
| 314 int param_count = descriptor->register_param_count_; | 338 int param_count = descriptor->register_param_count_; |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 __ jmp(&loaded, Label::kNear); | 611 __ jmp(&loaded, Label::kNear); |
| 588 | 612 |
| 589 __ bind(&input_not_smi); | 613 __ bind(&input_not_smi); |
| 590 // Check if input is a HeapNumber. | 614 // Check if input is a HeapNumber. |
| 591 __ LoadRoot(rbx, Heap::kHeapNumberMapRootIndex); | 615 __ LoadRoot(rbx, Heap::kHeapNumberMapRootIndex); |
| 592 __ cmpq(rbx, FieldOperand(rax, HeapObject::kMapOffset)); | 616 __ cmpq(rbx, FieldOperand(rax, HeapObject::kMapOffset)); |
| 593 __ j(not_equal, &runtime_call); | 617 __ j(not_equal, &runtime_call); |
| 594 // Input is a HeapNumber. Push it on the FPU stack and load its | 618 // Input is a HeapNumber. Push it on the FPU stack and load its |
| 595 // bits into rbx. | 619 // bits into rbx. |
| 596 __ fld_d(FieldOperand(rax, HeapNumber::kValueOffset)); | 620 __ fld_d(FieldOperand(rax, HeapNumber::kValueOffset)); |
| 597 __ movq(rbx, FieldOperand(rax, HeapNumber::kValueOffset)); | 621 __ MoveDouble(rbx, FieldOperand(rax, HeapNumber::kValueOffset)); |
| 598 __ movq(rdx, rbx); | 622 __ movq(rdx, rbx); |
| 599 | 623 |
| 600 __ bind(&loaded); | 624 __ bind(&loaded); |
| 601 } else { // UNTAGGED. | 625 } else { // UNTAGGED. |
| 602 __ movq(rbx, xmm1); | 626 __ movq(rbx, xmm1); |
| 603 __ movq(rdx, xmm1); | 627 __ movq(rdx, xmm1); |
| 604 } | 628 } |
| 605 | 629 |
| 606 // ST[0] == double value, if TAGGED. | 630 // ST[0] == double value, if TAGGED. |
| 607 // rbx = bits of double value. | 631 // rbx = bits of double value. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 624 __ xorl(rax, rdi); | 648 __ xorl(rax, rdi); |
| 625 __ xorl(rcx, rax); | 649 __ xorl(rcx, rax); |
| 626 ASSERT(IsPowerOf2(TranscendentalCache::SubCache::kCacheSize)); | 650 ASSERT(IsPowerOf2(TranscendentalCache::SubCache::kCacheSize)); |
| 627 __ andl(rcx, Immediate(TranscendentalCache::SubCache::kCacheSize - 1)); | 651 __ andl(rcx, Immediate(TranscendentalCache::SubCache::kCacheSize - 1)); |
| 628 | 652 |
| 629 // ST[0] == double value. | 653 // ST[0] == double value. |
| 630 // rbx = bits of double value. | 654 // rbx = bits of double value. |
| 631 // rcx = TranscendentalCache::hash(double value). | 655 // rcx = TranscendentalCache::hash(double value). |
| 632 ExternalReference cache_array = | 656 ExternalReference cache_array = |
| 633 ExternalReference::transcendental_cache_array_address(masm->isolate()); | 657 ExternalReference::transcendental_cache_array_address(masm->isolate()); |
| 634 __ movq(rax, cache_array); | 658 __ Move(rax, cache_array); |
| 635 int cache_array_index = | 659 int cache_array_index = |
| 636 type_ * sizeof(masm->isolate()->transcendental_cache()->caches_[0]); | 660 type_ * sizeof(masm->isolate()->transcendental_cache()->caches_[0]); |
| 637 __ movq(rax, Operand(rax, cache_array_index)); | 661 __ movq(rax, Operand(rax, cache_array_index)); |
| 638 // rax points to the cache for the type type_. | 662 // rax points to the cache for the type type_. |
| 639 // If NULL, the cache hasn't been initialized yet, so go through runtime. | 663 // If NULL, the cache hasn't been initialized yet, so go through runtime. |
| 640 __ testq(rax, rax); | 664 __ testq(rax, rax); |
| 641 __ j(zero, &runtime_call_clear_stack); // Only clears stack if TAGGED. | 665 __ j(zero, &runtime_call_clear_stack); // Only clears stack if TAGGED. |
| 642 #ifdef DEBUG | 666 #ifdef DEBUG |
| 643 // Check that the layout of cache elements match expectations. | 667 // Check that the layout of cache elements match expectations. |
| 644 { // NOLINT - doesn't like a single brace on a line. | 668 { // 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)); | 976 __ cmpl(exponent, Immediate(0x80000000u)); |
| 953 __ j(equal, &call_runtime); | 977 __ j(equal, &call_runtime); |
| 954 | 978 |
| 955 if (exponent_type_ == ON_STACK) { | 979 if (exponent_type_ == ON_STACK) { |
| 956 // Detect square root case. Crankshaft detects constant +/-0.5 at | 980 // Detect square root case. Crankshaft detects constant +/-0.5 at |
| 957 // compile time and uses DoMathPowHalf instead. We then skip this check | 981 // compile time and uses DoMathPowHalf instead. We then skip this check |
| 958 // for non-constant cases of +/-0.5 as these hardly occur. | 982 // for non-constant cases of +/-0.5 as these hardly occur. |
| 959 Label continue_sqrt, continue_rsqrt, not_plus_half; | 983 Label continue_sqrt, continue_rsqrt, not_plus_half; |
| 960 // Test for 0.5. | 984 // Test for 0.5. |
| 961 // Load double_scratch with 0.5. | 985 // Load double_scratch with 0.5. |
| 962 __ movq(scratch, V8_UINT64_C(0x3FE0000000000000), RelocInfo::NONE64); | 986 __ movq(scratch, V8_UINT64_C(0x3FE0000000000000)); |
| 963 __ movq(double_scratch, scratch); | 987 __ movq(double_scratch, scratch); |
| 964 // Already ruled out NaNs for exponent. | 988 // Already ruled out NaNs for exponent. |
| 965 __ ucomisd(double_scratch, double_exponent); | 989 __ ucomisd(double_scratch, double_exponent); |
| 966 __ j(not_equal, ¬_plus_half, Label::kNear); | 990 __ j(not_equal, ¬_plus_half, Label::kNear); |
| 967 | 991 |
| 968 // Calculates square root of base. Check for the special case of | 992 // Calculates square root of base. Check for the special case of |
| 969 // Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13). | 993 // Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13). |
| 970 // According to IEEE-754, double-precision -Infinity has the highest | 994 // According to IEEE-754, double-precision -Infinity has the highest |
| 971 // 12 bits set and the lowest 52 bits cleared. | 995 // 12 bits set and the lowest 52 bits cleared. |
| 972 __ movq(scratch, V8_UINT64_C(0xFFF0000000000000), RelocInfo::NONE64); | 996 __ movq(scratch, V8_UINT64_C(0xFFF0000000000000)); |
| 973 __ movq(double_scratch, scratch); | 997 __ movq(double_scratch, scratch); |
| 974 __ ucomisd(double_scratch, double_base); | 998 __ ucomisd(double_scratch, double_base); |
| 975 // Comparing -Infinity with NaN results in "unordered", which sets the | 999 // 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. | 1000 // zero flag as if both were equal. However, it also sets the carry flag. |
| 977 __ j(not_equal, &continue_sqrt, Label::kNear); | 1001 __ j(not_equal, &continue_sqrt, Label::kNear); |
| 978 __ j(carry, &continue_sqrt, Label::kNear); | 1002 __ j(carry, &continue_sqrt, Label::kNear); |
| 979 | 1003 |
| 980 // Set result to Infinity in the special case. | 1004 // Set result to Infinity in the special case. |
| 981 __ xorps(double_result, double_result); | 1005 __ xorps(double_result, double_result); |
| 982 __ subsd(double_result, double_scratch); | 1006 __ subsd(double_result, double_scratch); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 994 // Load double_scratch with -0.5 by substracting 1. | 1018 // Load double_scratch with -0.5 by substracting 1. |
| 995 __ subsd(double_scratch, double_result); | 1019 __ subsd(double_scratch, double_result); |
| 996 // Already ruled out NaNs for exponent. | 1020 // Already ruled out NaNs for exponent. |
| 997 __ ucomisd(double_scratch, double_exponent); | 1021 __ ucomisd(double_scratch, double_exponent); |
| 998 __ j(not_equal, &fast_power, Label::kNear); | 1022 __ j(not_equal, &fast_power, Label::kNear); |
| 999 | 1023 |
| 1000 // Calculates reciprocal of square root of base. Check for the special | 1024 // 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). | 1025 // 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 | 1026 // According to IEEE-754, double-precision -Infinity has the highest |
| 1003 // 12 bits set and the lowest 52 bits cleared. | 1027 // 12 bits set and the lowest 52 bits cleared. |
| 1004 __ movq(scratch, V8_UINT64_C(0xFFF0000000000000), RelocInfo::NONE64); | 1028 __ movq(scratch, V8_UINT64_C(0xFFF0000000000000)); |
| 1005 __ movq(double_scratch, scratch); | 1029 __ movq(double_scratch, scratch); |
| 1006 __ ucomisd(double_scratch, double_base); | 1030 __ ucomisd(double_scratch, double_base); |
| 1007 // Comparing -Infinity with NaN results in "unordered", which sets the | 1031 // 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. | 1032 // zero flag as if both were equal. However, it also sets the carry flag. |
| 1009 __ j(not_equal, &continue_rsqrt, Label::kNear); | 1033 __ j(not_equal, &continue_rsqrt, Label::kNear); |
| 1010 __ j(carry, &continue_rsqrt, Label::kNear); | 1034 __ j(carry, &continue_rsqrt, Label::kNear); |
| 1011 | 1035 |
| 1012 // Set result to 0 in the special case. | 1036 // Set result to 0 in the special case. |
| 1013 __ xorps(double_result, double_result); | 1037 __ xorps(double_result, double_result); |
| 1014 __ jmp(&done); | 1038 __ jmp(&done); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1129 __ movsd(xmm0, double_base); | 1153 __ movsd(xmm0, double_base); |
| 1130 ASSERT(double_exponent.is(xmm1)); | 1154 ASSERT(double_exponent.is(xmm1)); |
| 1131 { | 1155 { |
| 1132 AllowExternalCallThatCantCauseGC scope(masm); | 1156 AllowExternalCallThatCantCauseGC scope(masm); |
| 1133 __ PrepareCallCFunction(2); | 1157 __ PrepareCallCFunction(2); |
| 1134 __ CallCFunction( | 1158 __ CallCFunction( |
| 1135 ExternalReference::power_double_double_function(masm->isolate()), 2); | 1159 ExternalReference::power_double_double_function(masm->isolate()), 2); |
| 1136 } | 1160 } |
| 1137 // Return value is in xmm0. | 1161 // Return value is in xmm0. |
| 1138 __ movsd(double_result, xmm0); | 1162 __ movsd(double_result, xmm0); |
| 1139 // Restore context register. | |
| 1140 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | |
| 1141 | 1163 |
| 1142 __ bind(&done); | 1164 __ bind(&done); |
| 1143 __ IncrementCounter(counters->math_pow(), 1); | 1165 __ IncrementCounter(counters->math_pow(), 1); |
| 1144 __ ret(0); | 1166 __ ret(0); |
| 1145 } | 1167 } |
| 1146 } | 1168 } |
| 1147 | 1169 |
| 1148 | 1170 |
| 1149 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { | 1171 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { |
| 1150 Label miss; | 1172 Label miss; |
| (...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1866 __ LoadAddress(kScratchRegister, | 1888 __ LoadAddress(kScratchRegister, |
| 1867 ExternalReference::isolate_address(masm->isolate())); | 1889 ExternalReference::isolate_address(masm->isolate())); |
| 1868 __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize), | 1890 __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize), |
| 1869 kScratchRegister); | 1891 kScratchRegister); |
| 1870 | 1892 |
| 1871 // Argument 8: Indicate that this is a direct call from JavaScript. | 1893 // Argument 8: Indicate that this is a direct call from JavaScript. |
| 1872 __ movq(Operand(rsp, (argument_slots_on_stack - 2) * kPointerSize), | 1894 __ movq(Operand(rsp, (argument_slots_on_stack - 2) * kPointerSize), |
| 1873 Immediate(1)); | 1895 Immediate(1)); |
| 1874 | 1896 |
| 1875 // Argument 7: Start (high end) of backtracking stack memory area. | 1897 // Argument 7: Start (high end) of backtracking stack memory area. |
| 1876 __ movq(kScratchRegister, address_of_regexp_stack_memory_address); | 1898 __ Move(kScratchRegister, address_of_regexp_stack_memory_address); |
| 1877 __ movq(r9, Operand(kScratchRegister, 0)); | 1899 __ movq(r9, Operand(kScratchRegister, 0)); |
| 1878 __ movq(kScratchRegister, address_of_regexp_stack_memory_size); | 1900 __ Move(kScratchRegister, address_of_regexp_stack_memory_size); |
| 1879 __ addq(r9, Operand(kScratchRegister, 0)); | 1901 __ addq(r9, Operand(kScratchRegister, 0)); |
| 1880 __ movq(Operand(rsp, (argument_slots_on_stack - 3) * kPointerSize), r9); | 1902 __ movq(Operand(rsp, (argument_slots_on_stack - 3) * kPointerSize), r9); |
| 1881 | 1903 |
| 1882 // Argument 6: Set the number of capture registers to zero to force global | 1904 // 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. | 1905 // 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. | 1906 // Argument 6 is passed in r9 on Linux and on the stack on Windows. |
| 1885 #ifdef _WIN64 | 1907 #ifdef _WIN64 |
| 1886 __ movq(Operand(rsp, (argument_slots_on_stack - 4) * kPointerSize), | 1908 __ movq(Operand(rsp, (argument_slots_on_stack - 4) * kPointerSize), |
| 1887 Immediate(0)); | 1909 Immediate(0)); |
| 1888 #else | 1910 #else |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2215 | 2237 |
| 2216 static void CheckInputType(MacroAssembler* masm, | 2238 static void CheckInputType(MacroAssembler* masm, |
| 2217 Register input, | 2239 Register input, |
| 2218 CompareIC::State expected, | 2240 CompareIC::State expected, |
| 2219 Label* fail) { | 2241 Label* fail) { |
| 2220 Label ok; | 2242 Label ok; |
| 2221 if (expected == CompareIC::SMI) { | 2243 if (expected == CompareIC::SMI) { |
| 2222 __ JumpIfNotSmi(input, fail); | 2244 __ JumpIfNotSmi(input, fail); |
| 2223 } else if (expected == CompareIC::NUMBER) { | 2245 } else if (expected == CompareIC::NUMBER) { |
| 2224 __ JumpIfSmi(input, &ok); | 2246 __ JumpIfSmi(input, &ok); |
| 2225 __ CompareMap(input, masm->isolate()->factory()->heap_number_map(), NULL); | 2247 __ CompareMap(input, masm->isolate()->factory()->heap_number_map()); |
| 2226 __ j(not_equal, fail); | 2248 __ j(not_equal, fail); |
| 2227 } | 2249 } |
| 2228 // We could be strict about internalized/non-internalized here, but as long as | 2250 // 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. | 2251 // hydrogen doesn't care, the stub doesn't have to care either. |
| 2230 __ bind(&ok); | 2252 __ bind(&ok); |
| 2231 } | 2253 } |
| 2232 | 2254 |
| 2233 | 2255 |
| 2234 static void BranchIfNotInternalizedString(MacroAssembler* masm, | 2256 static void BranchIfNotInternalizedString(MacroAssembler* masm, |
| 2235 Label* label, | 2257 Label* label, |
| (...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2803 // Check stack alignment. | 2825 // Check stack alignment. |
| 2804 if (FLAG_debug_code) { | 2826 if (FLAG_debug_code) { |
| 2805 __ CheckStackAlignment(); | 2827 __ CheckStackAlignment(); |
| 2806 } | 2828 } |
| 2807 | 2829 |
| 2808 if (do_gc) { | 2830 if (do_gc) { |
| 2809 // Pass failure code returned from last attempt as first argument to | 2831 // Pass failure code returned from last attempt as first argument to |
| 2810 // PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the | 2832 // PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the |
| 2811 // stack is known to be aligned. This function takes one argument which is | 2833 // stack is known to be aligned. This function takes one argument which is |
| 2812 // passed in register. | 2834 // passed in register. |
| 2813 __ movq(arg_reg_2, ExternalReference::isolate_address(masm->isolate())); | 2835 __ Move(arg_reg_2, ExternalReference::isolate_address(masm->isolate())); |
| 2814 __ movq(arg_reg_1, rax); | 2836 __ movq(arg_reg_1, rax); |
| 2815 __ movq(kScratchRegister, | 2837 __ Move(kScratchRegister, |
| 2816 ExternalReference::perform_gc_function(masm->isolate())); | 2838 ExternalReference::perform_gc_function(masm->isolate())); |
| 2817 __ call(kScratchRegister); | 2839 __ call(kScratchRegister); |
| 2818 } | 2840 } |
| 2819 | 2841 |
| 2820 ExternalReference scope_depth = | 2842 ExternalReference scope_depth = |
| 2821 ExternalReference::heap_always_allocate_scope_depth(masm->isolate()); | 2843 ExternalReference::heap_always_allocate_scope_depth(masm->isolate()); |
| 2822 if (always_allocate_scope) { | 2844 if (always_allocate_scope) { |
| 2823 Operand scope_depth_operand = masm->ExternalOperand(scope_depth); | 2845 Operand scope_depth_operand = masm->ExternalOperand(scope_depth); |
| 2824 __ incl(scope_depth_operand); | 2846 __ incl(scope_depth_operand); |
| 2825 } | 2847 } |
| 2826 | 2848 |
| 2827 // Call C function. | 2849 // Call C function. |
| 2828 #ifdef _WIN64 | 2850 #ifdef _WIN64 |
| 2829 // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9. | 2851 // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9. |
| 2830 // Pass argv and argc as two parameters. The arguments object will | 2852 // Pass argv and argc as two parameters. The arguments object will |
| 2831 // be created by stubs declared by DECLARE_RUNTIME_FUNCTION(). | 2853 // be created by stubs declared by DECLARE_RUNTIME_FUNCTION(). |
| 2832 if (result_size_ < 2) { | 2854 if (result_size_ < 2) { |
| 2833 // Pass a pointer to the Arguments object as the first argument. | 2855 // Pass a pointer to the Arguments object as the first argument. |
| 2834 // Return result in single register (rax). | 2856 // Return result in single register (rax). |
| 2835 __ movq(rcx, r14); // argc. | 2857 __ movq(rcx, r14); // argc. |
| 2836 __ movq(rdx, r15); // argv. | 2858 __ movq(rdx, r15); // argv. |
| 2837 __ movq(r8, ExternalReference::isolate_address(masm->isolate())); | 2859 __ Move(r8, ExternalReference::isolate_address(masm->isolate())); |
| 2838 } else { | 2860 } else { |
| 2839 ASSERT_EQ(2, result_size_); | 2861 ASSERT_EQ(2, result_size_); |
| 2840 // Pass a pointer to the result location as the first argument. | 2862 // Pass a pointer to the result location as the first argument. |
| 2841 __ lea(rcx, StackSpaceOperand(2)); | 2863 __ lea(rcx, StackSpaceOperand(2)); |
| 2842 // Pass a pointer to the Arguments object as the second argument. | 2864 // Pass a pointer to the Arguments object as the second argument. |
| 2843 __ movq(rdx, r14); // argc. | 2865 __ movq(rdx, r14); // argc. |
| 2844 __ movq(r8, r15); // argv. | 2866 __ movq(r8, r15); // argv. |
| 2845 __ movq(r9, ExternalReference::isolate_address(masm->isolate())); | 2867 __ Move(r9, ExternalReference::isolate_address(masm->isolate())); |
| 2846 } | 2868 } |
| 2847 | 2869 |
| 2848 #else // _WIN64 | 2870 #else // _WIN64 |
| 2849 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9. | 2871 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9. |
| 2850 __ movq(rdi, r14); // argc. | 2872 __ movq(rdi, r14); // argc. |
| 2851 __ movq(rsi, r15); // argv. | 2873 __ movq(rsi, r15); // argv. |
| 2852 __ movq(rdx, ExternalReference::isolate_address(masm->isolate())); | 2874 __ Move(rdx, ExternalReference::isolate_address(masm->isolate())); |
| 2853 #endif | 2875 #endif |
| 2854 __ call(rbx); | 2876 __ call(rbx); |
| 2855 // Result is in rax - do not destroy this register! | 2877 // Result is in rax - do not destroy this register! |
| 2856 | 2878 |
| 2857 if (always_allocate_scope) { | 2879 if (always_allocate_scope) { |
| 2858 Operand scope_depth_operand = masm->ExternalOperand(scope_depth); | 2880 Operand scope_depth_operand = masm->ExternalOperand(scope_depth); |
| 2859 __ decl(scope_depth_operand); | 2881 __ decl(scope_depth_operand); |
| 2860 } | 2882 } |
| 2861 | 2883 |
| 2862 // Check for failure result. | 2884 // Check for failure result. |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3023 MacroAssembler::NoRootArrayScope uninitialized_root_register(masm); | 3045 MacroAssembler::NoRootArrayScope uninitialized_root_register(masm); |
| 3024 // Set up frame. | 3046 // Set up frame. |
| 3025 __ push(rbp); | 3047 __ push(rbp); |
| 3026 __ movq(rbp, rsp); | 3048 __ movq(rbp, rsp); |
| 3027 | 3049 |
| 3028 // Push the stack frame type marker twice. | 3050 // Push the stack frame type marker twice. |
| 3029 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; | 3051 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; |
| 3030 // Scratch register is neither callee-save, nor an argument register on any | 3052 // Scratch register is neither callee-save, nor an argument register on any |
| 3031 // platform. It's free to use at this point. | 3053 // platform. It's free to use at this point. |
| 3032 // Cannot use smi-register for loading yet. | 3054 // Cannot use smi-register for loading yet. |
| 3033 __ movq(kScratchRegister, | 3055 __ movq(kScratchRegister, Smi::FromInt(marker), RelocInfo::NONE64); |
| 3034 reinterpret_cast<uint64_t>(Smi::FromInt(marker)), | |
| 3035 RelocInfo::NONE64); | |
| 3036 __ push(kScratchRegister); // context slot | 3056 __ push(kScratchRegister); // context slot |
| 3037 __ push(kScratchRegister); // function slot | 3057 __ push(kScratchRegister); // function slot |
| 3038 // Save callee-saved registers (X64/Win64 calling conventions). | 3058 // Save callee-saved registers (X64/Win64 calling conventions). |
| 3039 __ push(r12); | 3059 __ push(r12); |
| 3040 __ push(r13); | 3060 __ push(r13); |
| 3041 __ push(r14); | 3061 __ push(r14); |
| 3042 __ push(r15); | 3062 __ push(r15); |
| 3043 #ifdef _WIN64 | 3063 #ifdef _WIN64 |
| 3044 __ push(rdi); // Only callee save in Win64 ABI, argument in AMD64 ABI. | 3064 __ 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. | 3065 __ 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); | 3152 __ call(kScratchRegister); |
| 3133 | 3153 |
| 3134 // Unlink this frame from the handler chain. | 3154 // Unlink this frame from the handler chain. |
| 3135 __ PopTryHandler(); | 3155 __ PopTryHandler(); |
| 3136 | 3156 |
| 3137 __ bind(&exit); | 3157 __ bind(&exit); |
| 3138 // Check if the current stack frame is marked as the outermost JS frame. | 3158 // Check if the current stack frame is marked as the outermost JS frame. |
| 3139 __ pop(rbx); | 3159 __ pop(rbx); |
| 3140 __ Cmp(rbx, Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)); | 3160 __ Cmp(rbx, Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)); |
| 3141 __ j(not_equal, ¬_outermost_js_2); | 3161 __ j(not_equal, ¬_outermost_js_2); |
| 3142 __ movq(kScratchRegister, js_entry_sp); | 3162 __ Move(kScratchRegister, js_entry_sp); |
| 3143 __ movq(Operand(kScratchRegister, 0), Immediate(0)); | 3163 __ movq(Operand(kScratchRegister, 0), Immediate(0)); |
| 3144 __ bind(¬_outermost_js_2); | 3164 __ bind(¬_outermost_js_2); |
| 3145 | 3165 |
| 3146 // Restore the top frame descriptor from the stack. | 3166 // Restore the top frame descriptor from the stack. |
| 3147 { Operand c_entry_fp_operand = masm->ExternalOperand(c_entry_fp); | 3167 { Operand c_entry_fp_operand = masm->ExternalOperand(c_entry_fp); |
| 3148 __ pop(c_entry_fp_operand); | 3168 __ pop(c_entry_fp_operand); |
| 3149 } | 3169 } |
| 3150 | 3170 |
| 3151 // Restore callee-saved registers (X64 conventions). | 3171 // Restore callee-saved registers (X64 conventions). |
| 3152 #ifdef _WIN64 | 3172 #ifdef _WIN64 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3201 static const int kOffsetToResultValue = 18; | 3221 static const int kOffsetToResultValue = 18; |
| 3202 // The last 4 bytes of the instruction sequence | 3222 // The last 4 bytes of the instruction sequence |
| 3203 // movq(rdi, FieldOperand(rax, HeapObject::kMapOffset)) | 3223 // movq(rdi, FieldOperand(rax, HeapObject::kMapOffset)) |
| 3204 // Move(kScratchRegister, Factory::the_hole_value()) | 3224 // Move(kScratchRegister, Factory::the_hole_value()) |
| 3205 // in front of the hole value address. | 3225 // in front of the hole value address. |
| 3206 static const unsigned int kWordBeforeMapCheckValue = 0xBA49FF78; | 3226 static const unsigned int kWordBeforeMapCheckValue = 0xBA49FF78; |
| 3207 // The last 4 bytes of the instruction sequence | 3227 // The last 4 bytes of the instruction sequence |
| 3208 // __ j(not_equal, &cache_miss); | 3228 // __ j(not_equal, &cache_miss); |
| 3209 // __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex); | 3229 // __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex); |
| 3210 // before the offset of the hole value in the root array. | 3230 // before the offset of the hole value in the root array. |
| 3211 static const unsigned int kWordBeforeResultValue = 0x458B4909; | 3231 static const unsigned int kWordBeforeResultValue = 0x458B4906; |
| 3212 // Only the inline check flag is supported on X64. | 3232 // Only the inline check flag is supported on X64. |
| 3213 ASSERT(flags_ == kNoFlags || HasCallSiteInlineCheck()); | 3233 ASSERT(flags_ == kNoFlags || HasCallSiteInlineCheck()); |
| 3214 int extra_argument_offset = HasCallSiteInlineCheck() ? 1 : 0; | 3234 int extra_argument_offset = HasCallSiteInlineCheck() ? 1 : 0; |
| 3215 | 3235 |
| 3216 // Get the object - go slow case if it's a smi. | 3236 // Get the object - go slow case if it's a smi. |
| 3217 Label slow; | 3237 Label slow; |
| 3218 StackArgumentsAccessor args(rsp, 2 + extra_argument_offset, | 3238 StackArgumentsAccessor args(rsp, 2 + extra_argument_offset, |
| 3219 ARGUMENTS_DONT_CONTAIN_RECEIVER); | 3239 ARGUMENTS_DONT_CONTAIN_RECEIVER); |
| 3220 __ movq(rax, args.GetArgumentOperand(0)); | 3240 __ movq(rax, args.GetArgumentOperand(0)); |
| 3221 __ JumpIfSmi(rax, &slow); | 3241 __ JumpIfSmi(rax, &slow); |
| (...skipping 1316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4538 if (left_ == CompareIC::SMI) { | 4558 if (left_ == CompareIC::SMI) { |
| 4539 __ JumpIfNotSmi(rdx, &miss); | 4559 __ JumpIfNotSmi(rdx, &miss); |
| 4540 } | 4560 } |
| 4541 if (right_ == CompareIC::SMI) { | 4561 if (right_ == CompareIC::SMI) { |
| 4542 __ JumpIfNotSmi(rax, &miss); | 4562 __ JumpIfNotSmi(rax, &miss); |
| 4543 } | 4563 } |
| 4544 | 4564 |
| 4545 // Load left and right operand. | 4565 // Load left and right operand. |
| 4546 Label done, left, left_smi, right_smi; | 4566 Label done, left, left_smi, right_smi; |
| 4547 __ JumpIfSmi(rax, &right_smi, Label::kNear); | 4567 __ JumpIfSmi(rax, &right_smi, Label::kNear); |
| 4548 __ CompareMap(rax, masm->isolate()->factory()->heap_number_map(), NULL); | 4568 __ CompareMap(rax, masm->isolate()->factory()->heap_number_map()); |
| 4549 __ j(not_equal, &maybe_undefined1, Label::kNear); | 4569 __ j(not_equal, &maybe_undefined1, Label::kNear); |
| 4550 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset)); | 4570 __ movsd(xmm1, FieldOperand(rax, HeapNumber::kValueOffset)); |
| 4551 __ jmp(&left, Label::kNear); | 4571 __ jmp(&left, Label::kNear); |
| 4552 __ bind(&right_smi); | 4572 __ bind(&right_smi); |
| 4553 __ SmiToInteger32(rcx, rax); // Can't clobber rax yet. | 4573 __ SmiToInteger32(rcx, rax); // Can't clobber rax yet. |
| 4554 __ Cvtlsi2sd(xmm1, rcx); | 4574 __ Cvtlsi2sd(xmm1, rcx); |
| 4555 | 4575 |
| 4556 __ bind(&left); | 4576 __ bind(&left); |
| 4557 __ JumpIfSmi(rdx, &left_smi, Label::kNear); | 4577 __ JumpIfSmi(rdx, &left_smi, Label::kNear); |
| 4558 __ CompareMap(rdx, masm->isolate()->factory()->heap_number_map(), NULL); | 4578 __ CompareMap(rdx, masm->isolate()->factory()->heap_number_map()); |
| 4559 __ j(not_equal, &maybe_undefined2, Label::kNear); | 4579 __ j(not_equal, &maybe_undefined2, Label::kNear); |
| 4560 __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset)); | 4580 __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset)); |
| 4561 __ jmp(&done); | 4581 __ jmp(&done); |
| 4562 __ bind(&left_smi); | 4582 __ bind(&left_smi); |
| 4563 __ SmiToInteger32(rcx, rdx); // Can't clobber rdx yet. | 4583 __ SmiToInteger32(rcx, rdx); // Can't clobber rdx yet. |
| 4564 __ Cvtlsi2sd(xmm0, rcx); | 4584 __ Cvtlsi2sd(xmm0, rcx); |
| 4565 | 4585 |
| 4566 __ bind(&done); | 4586 __ bind(&done); |
| 4567 // Compare operands | 4587 // Compare operands |
| 4568 __ ucomisd(xmm0, xmm1); | 4588 __ ucomisd(xmm0, xmm1); |
| (...skipping 1246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5815 __ bind(&fast_elements_case); | 5835 __ bind(&fast_elements_case); |
| 5816 GenerateCase(masm, FAST_ELEMENTS); | 5836 GenerateCase(masm, FAST_ELEMENTS); |
| 5817 } | 5837 } |
| 5818 | 5838 |
| 5819 | 5839 |
| 5820 #undef __ | 5840 #undef __ |
| 5821 | 5841 |
| 5822 } } // namespace v8::internal | 5842 } } // namespace v8::internal |
| 5823 | 5843 |
| 5824 #endif // V8_TARGET_ARCH_X64 | 5844 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |