OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
11 #include "src/regexp-macro-assembler.h" | 11 #include "src/regexp-macro-assembler.h" |
12 #include "src/runtime.h" | 12 #include "src/runtime.h" |
13 #include "src/stub-cache.h" | 13 #include "src/stub-cache.h" |
14 | 14 |
15 namespace v8 { | 15 namespace v8 { |
16 namespace internal { | 16 namespace internal { |
17 | 17 |
18 | 18 |
19 void FastNewClosureStub::InitializeInterfaceDescriptor( | 19 void FastNewClosureStub::InitializeInterfaceDescriptor( |
20 CodeStubInterfaceDescriptor* descriptor) { | 20 CodeStubInterfaceDescriptor* descriptor) { |
21 static Register registers[] = { rbx }; | 21 static Register registers[] = { rbx }; |
22 descriptor->register_param_count_ = 1; | 22 descriptor->register_param_count_ = 1; |
23 descriptor->register_params_ = registers; | 23 descriptor->register_params_ = registers; |
24 descriptor->deoptimization_handler_ = | 24 descriptor->deoptimization_handler_ = |
25 Runtime::FunctionForId(Runtime::kHiddenNewClosureFromStubFailure)->entry; | 25 Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry; |
26 } | 26 } |
27 | 27 |
28 | 28 |
29 void FastNewContextStub::InitializeInterfaceDescriptor( | 29 void FastNewContextStub::InitializeInterfaceDescriptor( |
30 CodeStubInterfaceDescriptor* descriptor) { | 30 CodeStubInterfaceDescriptor* descriptor) { |
31 static Register registers[] = { rdi }; | 31 static Register registers[] = { rdi }; |
32 descriptor->register_param_count_ = 1; | 32 descriptor->register_param_count_ = 1; |
33 descriptor->register_params_ = registers; | 33 descriptor->register_params_ = registers; |
34 descriptor->deoptimization_handler_ = NULL; | 34 descriptor->deoptimization_handler_ = NULL; |
35 } | 35 } |
36 | 36 |
37 | 37 |
38 void ToNumberStub::InitializeInterfaceDescriptor( | 38 void ToNumberStub::InitializeInterfaceDescriptor( |
39 CodeStubInterfaceDescriptor* descriptor) { | 39 CodeStubInterfaceDescriptor* descriptor) { |
40 static Register registers[] = { rax }; | 40 static Register registers[] = { rax }; |
41 descriptor->register_param_count_ = 1; | 41 descriptor->register_param_count_ = 1; |
42 descriptor->register_params_ = registers; | 42 descriptor->register_params_ = registers; |
43 descriptor->deoptimization_handler_ = NULL; | 43 descriptor->deoptimization_handler_ = NULL; |
44 } | 44 } |
45 | 45 |
46 | 46 |
47 void NumberToStringStub::InitializeInterfaceDescriptor( | 47 void NumberToStringStub::InitializeInterfaceDescriptor( |
48 CodeStubInterfaceDescriptor* descriptor) { | 48 CodeStubInterfaceDescriptor* descriptor) { |
49 static Register registers[] = { rax }; | 49 static Register registers[] = { rax }; |
50 descriptor->register_param_count_ = 1; | 50 descriptor->register_param_count_ = 1; |
51 descriptor->register_params_ = registers; | 51 descriptor->register_params_ = registers; |
52 descriptor->deoptimization_handler_ = | 52 descriptor->deoptimization_handler_ = |
53 Runtime::FunctionForId(Runtime::kHiddenNumberToString)->entry; | 53 Runtime::FunctionForId(Runtime::kNumberToStringRT)->entry; |
54 } | 54 } |
55 | 55 |
56 | 56 |
57 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( | 57 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( |
58 CodeStubInterfaceDescriptor* descriptor) { | 58 CodeStubInterfaceDescriptor* descriptor) { |
59 static Register registers[] = { rax, rbx, rcx }; | 59 static Register registers[] = { rax, rbx, rcx }; |
60 descriptor->register_param_count_ = 3; | 60 descriptor->register_param_count_ = 3; |
61 descriptor->register_params_ = registers; | 61 descriptor->register_params_ = registers; |
62 static Representation representations[] = { | 62 static Representation representations[] = { |
63 Representation::Tagged(), | 63 Representation::Tagged(), |
64 Representation::Smi(), | 64 Representation::Smi(), |
65 Representation::Tagged() }; | 65 Representation::Tagged() }; |
66 descriptor->register_param_representations_ = representations; | 66 descriptor->register_param_representations_ = representations; |
67 descriptor->deoptimization_handler_ = | 67 descriptor->deoptimization_handler_ = |
68 Runtime::FunctionForId( | 68 Runtime::FunctionForId(Runtime::kCreateArrayLiteralStubBailout)->entry; |
69 Runtime::kHiddenCreateArrayLiteralStubBailout)->entry; | |
70 } | 69 } |
71 | 70 |
72 | 71 |
73 void FastCloneShallowObjectStub::InitializeInterfaceDescriptor( | 72 void FastCloneShallowObjectStub::InitializeInterfaceDescriptor( |
74 CodeStubInterfaceDescriptor* descriptor) { | 73 CodeStubInterfaceDescriptor* descriptor) { |
75 static Register registers[] = { rax, rbx, rcx, rdx }; | 74 static Register registers[] = { rax, rbx, rcx, rdx }; |
76 descriptor->register_param_count_ = 4; | 75 descriptor->register_param_count_ = 4; |
77 descriptor->register_params_ = registers; | 76 descriptor->register_params_ = registers; |
78 descriptor->deoptimization_handler_ = | 77 descriptor->deoptimization_handler_ = |
79 Runtime::FunctionForId(Runtime::kHiddenCreateObjectLiteral)->entry; | 78 Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry; |
80 } | 79 } |
81 | 80 |
82 | 81 |
83 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( | 82 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( |
84 CodeStubInterfaceDescriptor* descriptor) { | 83 CodeStubInterfaceDescriptor* descriptor) { |
85 static Register registers[] = { rbx, rdx }; | 84 static Register registers[] = { rbx, rdx }; |
86 descriptor->register_param_count_ = 2; | 85 descriptor->register_param_count_ = 2; |
87 descriptor->register_params_ = registers; | 86 descriptor->register_params_ = registers; |
88 descriptor->deoptimization_handler_ = NULL; | 87 descriptor->deoptimization_handler_ = NULL; |
89 } | 88 } |
(...skipping 18 matching lines...) Expand all Loading... |
108 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure); | 107 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure); |
109 } | 108 } |
110 | 109 |
111 | 110 |
112 void RegExpConstructResultStub::InitializeInterfaceDescriptor( | 111 void RegExpConstructResultStub::InitializeInterfaceDescriptor( |
113 CodeStubInterfaceDescriptor* descriptor) { | 112 CodeStubInterfaceDescriptor* descriptor) { |
114 static Register registers[] = { rcx, rbx, rax }; | 113 static Register registers[] = { rcx, rbx, rax }; |
115 descriptor->register_param_count_ = 3; | 114 descriptor->register_param_count_ = 3; |
116 descriptor->register_params_ = registers; | 115 descriptor->register_params_ = registers; |
117 descriptor->deoptimization_handler_ = | 116 descriptor->deoptimization_handler_ = |
118 Runtime::FunctionForId(Runtime::kHiddenRegExpConstructResult)->entry; | 117 Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry; |
119 } | 118 } |
120 | 119 |
121 | 120 |
122 void KeyedLoadGenericElementStub::InitializeInterfaceDescriptor( | 121 void KeyedLoadGenericElementStub::InitializeInterfaceDescriptor( |
123 CodeStubInterfaceDescriptor* descriptor) { | 122 CodeStubInterfaceDescriptor* descriptor) { |
124 static Register registers[] = { rdx, rax }; | 123 static Register registers[] = { rdx, rax }; |
125 descriptor->register_param_count_ = 2; | 124 descriptor->register_param_count_ = 2; |
126 descriptor->register_params_ = registers; | 125 descriptor->register_params_ = registers; |
127 descriptor->deoptimization_handler_ = | 126 descriptor->deoptimization_handler_ = |
128 Runtime::FunctionForId(Runtime::kKeyedGetProperty)->entry; | 127 Runtime::FunctionForId(Runtime::kKeyedGetProperty)->entry; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 Representation::Tagged(), | 206 Representation::Tagged(), |
208 Representation::Tagged(), | 207 Representation::Tagged(), |
209 Representation::Integer32() }; | 208 Representation::Integer32() }; |
210 descriptor->register_param_representations_ = representations; | 209 descriptor->register_param_representations_ = representations; |
211 descriptor->register_params_ = registers_variable_args; | 210 descriptor->register_params_ = registers_variable_args; |
212 } | 211 } |
213 | 212 |
214 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; | 213 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; |
215 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; | 214 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; |
216 descriptor->deoptimization_handler_ = | 215 descriptor->deoptimization_handler_ = |
217 Runtime::FunctionForId(Runtime::kHiddenArrayConstructor)->entry; | 216 Runtime::FunctionForId(Runtime::kArrayConstructor)->entry; |
218 } | 217 } |
219 | 218 |
220 | 219 |
221 static void InitializeInternalArrayConstructorDescriptor( | 220 static void InitializeInternalArrayConstructorDescriptor( |
222 CodeStubInterfaceDescriptor* descriptor, | 221 CodeStubInterfaceDescriptor* descriptor, |
223 int constant_stack_parameter_count) { | 222 int constant_stack_parameter_count) { |
224 // register state | 223 // register state |
225 // rax -- number of arguments | 224 // rax -- number of arguments |
226 // rdi -- constructor function | 225 // rdi -- constructor function |
227 static Register registers_variable_args[] = { rdi, rax }; | 226 static Register registers_variable_args[] = { rdi, rax }; |
(...skipping 10 matching lines...) Expand all Loading... |
238 descriptor->register_params_ = registers_variable_args; | 237 descriptor->register_params_ = registers_variable_args; |
239 static Representation representations[] = { | 238 static Representation representations[] = { |
240 Representation::Tagged(), | 239 Representation::Tagged(), |
241 Representation::Integer32() }; | 240 Representation::Integer32() }; |
242 descriptor->register_param_representations_ = representations; | 241 descriptor->register_param_representations_ = representations; |
243 } | 242 } |
244 | 243 |
245 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; | 244 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; |
246 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; | 245 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; |
247 descriptor->deoptimization_handler_ = | 246 descriptor->deoptimization_handler_ = |
248 Runtime::FunctionForId(Runtime::kHiddenInternalArrayConstructor)->entry; | 247 Runtime::FunctionForId(Runtime::kInternalArrayConstructor)->entry; |
249 } | 248 } |
250 | 249 |
251 | 250 |
252 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( | 251 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( |
253 CodeStubInterfaceDescriptor* descriptor) { | 252 CodeStubInterfaceDescriptor* descriptor) { |
254 InitializeArrayConstructorDescriptor(descriptor, 0); | 253 InitializeArrayConstructorDescriptor(descriptor, 0); |
255 } | 254 } |
256 | 255 |
257 | 256 |
258 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( | 257 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite); | 348 FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite); |
350 } | 349 } |
351 | 350 |
352 | 351 |
353 void StringAddStub::InitializeInterfaceDescriptor( | 352 void StringAddStub::InitializeInterfaceDescriptor( |
354 CodeStubInterfaceDescriptor* descriptor) { | 353 CodeStubInterfaceDescriptor* descriptor) { |
355 static Register registers[] = { rdx, rax }; | 354 static Register registers[] = { rdx, rax }; |
356 descriptor->register_param_count_ = 2; | 355 descriptor->register_param_count_ = 2; |
357 descriptor->register_params_ = registers; | 356 descriptor->register_params_ = registers; |
358 descriptor->deoptimization_handler_ = | 357 descriptor->deoptimization_handler_ = |
359 Runtime::FunctionForId(Runtime::kHiddenStringAdd)->entry; | 358 Runtime::FunctionForId(Runtime::kStringAdd)->entry; |
360 } | 359 } |
361 | 360 |
362 | 361 |
363 void CallDescriptors::InitializeForIsolate(Isolate* isolate) { | 362 void CallDescriptors::InitializeForIsolate(Isolate* isolate) { |
364 { | 363 { |
365 CallInterfaceDescriptor* descriptor = | 364 CallInterfaceDescriptor* descriptor = |
366 isolate->call_descriptor(Isolate::ArgumentAdaptorCall); | 365 isolate->call_descriptor(Isolate::ArgumentAdaptorCall); |
367 static Register registers[] = { rdi, // JSFunction | 366 static Register registers[] = { rdi, // JSFunction |
368 rsi, // context | 367 rsi, // context |
369 rax, // actual number of arguments | 368 rax, // actual number of arguments |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
837 // and may not have contained the exponent value in the first place when the | 836 // and may not have contained the exponent value in the first place when the |
838 // input was a smi. We reset it with exponent value before bailing out. | 837 // input was a smi. We reset it with exponent value before bailing out. |
839 __ j(not_equal, &done); | 838 __ j(not_equal, &done); |
840 __ Cvtlsi2sd(double_exponent, exponent); | 839 __ Cvtlsi2sd(double_exponent, exponent); |
841 | 840 |
842 // Returning or bailing out. | 841 // Returning or bailing out. |
843 Counters* counters = isolate()->counters(); | 842 Counters* counters = isolate()->counters(); |
844 if (exponent_type_ == ON_STACK) { | 843 if (exponent_type_ == ON_STACK) { |
845 // The arguments are still on the stack. | 844 // The arguments are still on the stack. |
846 __ bind(&call_runtime); | 845 __ bind(&call_runtime); |
847 __ TailCallRuntime(Runtime::kHiddenMathPow, 2, 1); | 846 __ TailCallRuntime(Runtime::kMathPowRT, 2, 1); |
848 | 847 |
849 // The stub is called from non-optimized code, which expects the result | 848 // The stub is called from non-optimized code, which expects the result |
850 // as heap number in rax. | 849 // as heap number in rax. |
851 __ bind(&done); | 850 __ bind(&done); |
852 __ AllocateHeapNumber(rax, rcx, &call_runtime); | 851 __ AllocateHeapNumber(rax, rcx, &call_runtime); |
853 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), double_result); | 852 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), double_result); |
854 __ IncrementCounter(counters->math_pow(), 1); | 853 __ IncrementCounter(counters->math_pow(), 1); |
855 __ ret(2 * kPointerSize); | 854 __ ret(2 * kPointerSize); |
856 } else { | 855 } else { |
857 __ bind(&call_runtime); | 856 __ bind(&call_runtime); |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1166 __ j(less, &arguments_loop, Label::kNear); | 1165 __ j(less, &arguments_loop, Label::kNear); |
1167 | 1166 |
1168 // Return and remove the on-stack parameters. | 1167 // Return and remove the on-stack parameters. |
1169 __ ret(3 * kPointerSize); | 1168 __ ret(3 * kPointerSize); |
1170 | 1169 |
1171 // Do the runtime call to allocate the arguments object. | 1170 // Do the runtime call to allocate the arguments object. |
1172 // rcx = argument count (untagged) | 1171 // rcx = argument count (untagged) |
1173 __ bind(&runtime); | 1172 __ bind(&runtime); |
1174 __ Integer32ToSmi(rcx, rcx); | 1173 __ Integer32ToSmi(rcx, rcx); |
1175 __ movp(args.GetArgumentOperand(2), rcx); // Patch argument count. | 1174 __ movp(args.GetArgumentOperand(2), rcx); // Patch argument count. |
1176 __ TailCallRuntime(Runtime::kHiddenNewSloppyArguments, 3, 1); | 1175 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); |
1177 } | 1176 } |
1178 | 1177 |
1179 | 1178 |
1180 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { | 1179 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { |
1181 // rsp[0] : return address | 1180 // rsp[0] : return address |
1182 // rsp[8] : number of parameters | 1181 // rsp[8] : number of parameters |
1183 // rsp[16] : receiver displacement | 1182 // rsp[16] : receiver displacement |
1184 // rsp[24] : function | 1183 // rsp[24] : function |
1185 | 1184 |
1186 // Check if the calling frame is an arguments adaptor frame. | 1185 // Check if the calling frame is an arguments adaptor frame. |
1187 Label runtime; | 1186 Label runtime; |
1188 __ movp(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 1187 __ movp(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
1189 __ movp(rcx, Operand(rdx, StandardFrameConstants::kContextOffset)); | 1188 __ movp(rcx, Operand(rdx, StandardFrameConstants::kContextOffset)); |
1190 __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 1189 __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
1191 __ j(not_equal, &runtime); | 1190 __ j(not_equal, &runtime); |
1192 | 1191 |
1193 // Patch the arguments.length and the parameters pointer. | 1192 // Patch the arguments.length and the parameters pointer. |
1194 StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER); | 1193 StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER); |
1195 __ movp(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 1194 __ movp(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
1196 __ movp(args.GetArgumentOperand(2), rcx); | 1195 __ movp(args.GetArgumentOperand(2), rcx); |
1197 __ SmiToInteger64(rcx, rcx); | 1196 __ SmiToInteger64(rcx, rcx); |
1198 __ leap(rdx, Operand(rdx, rcx, times_pointer_size, | 1197 __ leap(rdx, Operand(rdx, rcx, times_pointer_size, |
1199 StandardFrameConstants::kCallerSPOffset)); | 1198 StandardFrameConstants::kCallerSPOffset)); |
1200 __ movp(args.GetArgumentOperand(1), rdx); | 1199 __ movp(args.GetArgumentOperand(1), rdx); |
1201 | 1200 |
1202 __ bind(&runtime); | 1201 __ bind(&runtime); |
1203 __ TailCallRuntime(Runtime::kHiddenNewSloppyArguments, 3, 1); | 1202 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); |
1204 } | 1203 } |
1205 | 1204 |
1206 | 1205 |
1207 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { | 1206 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { |
1208 // rsp[0] : return address | 1207 // rsp[0] : return address |
1209 // rsp[8] : number of parameters | 1208 // rsp[8] : number of parameters |
1210 // rsp[16] : receiver displacement | 1209 // rsp[16] : receiver displacement |
1211 // rsp[24] : function | 1210 // rsp[24] : function |
1212 | 1211 |
1213 // Check if the calling frame is an arguments adaptor frame. | 1212 // Check if the calling frame is an arguments adaptor frame. |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1294 __ subp(rdx, Immediate(kPointerSize)); | 1293 __ subp(rdx, Immediate(kPointerSize)); |
1295 __ decp(rcx); | 1294 __ decp(rcx); |
1296 __ j(not_zero, &loop); | 1295 __ j(not_zero, &loop); |
1297 | 1296 |
1298 // Return and remove the on-stack parameters. | 1297 // Return and remove the on-stack parameters. |
1299 __ bind(&done); | 1298 __ bind(&done); |
1300 __ ret(3 * kPointerSize); | 1299 __ ret(3 * kPointerSize); |
1301 | 1300 |
1302 // Do the runtime call to allocate the arguments object. | 1301 // Do the runtime call to allocate the arguments object. |
1303 __ bind(&runtime); | 1302 __ bind(&runtime); |
1304 __ TailCallRuntime(Runtime::kHiddenNewStrictArguments, 3, 1); | 1303 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1); |
1305 } | 1304 } |
1306 | 1305 |
1307 | 1306 |
1308 void RegExpExecStub::Generate(MacroAssembler* masm) { | 1307 void RegExpExecStub::Generate(MacroAssembler* masm) { |
1309 // Just jump directly to runtime if native RegExp is not selected at compile | 1308 // Just jump directly to runtime if native RegExp is not selected at compile |
1310 // time or if regexp entry in generated code is turned off runtime switch or | 1309 // time or if regexp entry in generated code is turned off runtime switch or |
1311 // at compilation. | 1310 // at compilation. |
1312 #ifdef V8_INTERPRETED_REGEXP | 1311 #ifdef V8_INTERPRETED_REGEXP |
1313 __ TailCallRuntime(Runtime::kHiddenRegExpExec, 4, 1); | 1312 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); |
1314 #else // V8_INTERPRETED_REGEXP | 1313 #else // V8_INTERPRETED_REGEXP |
1315 | 1314 |
1316 // Stack frame on entry. | 1315 // Stack frame on entry. |
1317 // rsp[0] : return address | 1316 // rsp[0] : return address |
1318 // rsp[8] : last_match_info (expected JSArray) | 1317 // rsp[8] : last_match_info (expected JSArray) |
1319 // rsp[16] : previous index | 1318 // rsp[16] : previous index |
1320 // rsp[24] : subject string | 1319 // rsp[24] : subject string |
1321 // rsp[32] : JSRegExp object | 1320 // rsp[32] : JSRegExp object |
1322 | 1321 |
1323 enum RegExpExecStubArgumentIndices { | 1322 enum RegExpExecStubArgumentIndices { |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1696 __ CompareRoot(rax, Heap::kTerminationExceptionRootIndex); | 1695 __ CompareRoot(rax, Heap::kTerminationExceptionRootIndex); |
1697 Label termination_exception; | 1696 Label termination_exception; |
1698 __ j(equal, &termination_exception, Label::kNear); | 1697 __ j(equal, &termination_exception, Label::kNear); |
1699 __ Throw(rax); | 1698 __ Throw(rax); |
1700 | 1699 |
1701 __ bind(&termination_exception); | 1700 __ bind(&termination_exception); |
1702 __ ThrowUncatchable(rax); | 1701 __ ThrowUncatchable(rax); |
1703 | 1702 |
1704 // Do the runtime call to execute the regexp. | 1703 // Do the runtime call to execute the regexp. |
1705 __ bind(&runtime); | 1704 __ bind(&runtime); |
1706 __ TailCallRuntime(Runtime::kHiddenRegExpExec, 4, 1); | 1705 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1); |
1707 | 1706 |
1708 // Deferred code for string handling. | 1707 // Deferred code for string handling. |
1709 // (7) Not a long external string? If yes, go to (10). | 1708 // (7) Not a long external string? If yes, go to (10). |
1710 __ bind(¬_seq_nor_cons); | 1709 __ bind(¬_seq_nor_cons); |
1711 // Compare flags are still set from (3). | 1710 // Compare flags are still set from (3). |
1712 __ j(greater, ¬_long_external, Label::kNear); // Go to (10). | 1711 __ j(greater, ¬_long_external, Label::kNear); // Go to (10). |
1713 | 1712 |
1714 // (8) External string. Short external strings have been ruled out. | 1713 // (8) External string. Short external strings have been ruled out. |
1715 __ bind(&external_string); | 1714 __ bind(&external_string); |
1716 __ movp(rbx, FieldOperand(rdi, HeapObject::kMapOffset)); | 1715 __ movp(rbx, FieldOperand(rdi, HeapObject::kMapOffset)); |
(...skipping 1346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3063 index_not_number_, | 3062 index_not_number_, |
3064 DONT_DO_SMI_CHECK); | 3063 DONT_DO_SMI_CHECK); |
3065 call_helper.BeforeCall(masm); | 3064 call_helper.BeforeCall(masm); |
3066 __ Push(object_); | 3065 __ Push(object_); |
3067 __ Push(index_); // Consumed by runtime conversion function. | 3066 __ Push(index_); // Consumed by runtime conversion function. |
3068 if (index_flags_ == STRING_INDEX_IS_NUMBER) { | 3067 if (index_flags_ == STRING_INDEX_IS_NUMBER) { |
3069 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); | 3068 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); |
3070 } else { | 3069 } else { |
3071 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); | 3070 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); |
3072 // NumberToSmi discards numbers that are not exact integers. | 3071 // NumberToSmi discards numbers that are not exact integers. |
3073 __ CallRuntime(Runtime::kHiddenNumberToSmi, 1); | 3072 __ CallRuntime(Runtime::kNumberToSmi, 1); |
3074 } | 3073 } |
3075 if (!index_.is(rax)) { | 3074 if (!index_.is(rax)) { |
3076 // Save the conversion result before the pop instructions below | 3075 // Save the conversion result before the pop instructions below |
3077 // have a chance to overwrite it. | 3076 // have a chance to overwrite it. |
3078 __ movp(index_, rax); | 3077 __ movp(index_, rax); |
3079 } | 3078 } |
3080 __ Pop(object_); | 3079 __ Pop(object_); |
3081 // Reload the instance type. | 3080 // Reload the instance type. |
3082 __ movp(result_, FieldOperand(object_, HeapObject::kMapOffset)); | 3081 __ movp(result_, FieldOperand(object_, HeapObject::kMapOffset)); |
3083 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); | 3082 __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); |
3084 call_helper.AfterCall(masm); | 3083 call_helper.AfterCall(masm); |
3085 // If index is still not a smi, it must be out of range. | 3084 // If index is still not a smi, it must be out of range. |
3086 __ JumpIfNotSmi(index_, index_out_of_range_); | 3085 __ JumpIfNotSmi(index_, index_out_of_range_); |
3087 // Otherwise, return to the fast path. | 3086 // Otherwise, return to the fast path. |
3088 __ jmp(&got_smi_index_); | 3087 __ jmp(&got_smi_index_); |
3089 | 3088 |
3090 // Call runtime. We get here when the receiver is a string and the | 3089 // Call runtime. We get here when the receiver is a string and the |
3091 // index is a number, but the code of getting the actual character | 3090 // index is a number, but the code of getting the actual character |
3092 // is too complex (e.g., when the string needs to be flattened). | 3091 // is too complex (e.g., when the string needs to be flattened). |
3093 __ bind(&call_runtime_); | 3092 __ bind(&call_runtime_); |
3094 call_helper.BeforeCall(masm); | 3093 call_helper.BeforeCall(masm); |
3095 __ Push(object_); | 3094 __ Push(object_); |
3096 __ Integer32ToSmi(index_, index_); | 3095 __ Integer32ToSmi(index_, index_); |
3097 __ Push(index_); | 3096 __ Push(index_); |
3098 __ CallRuntime(Runtime::kHiddenStringCharCodeAt, 2); | 3097 __ CallRuntime(Runtime::kStringCharCodeAtRT, 2); |
3099 if (!result_.is(rax)) { | 3098 if (!result_.is(rax)) { |
3100 __ movp(result_, rax); | 3099 __ movp(result_, rax); |
3101 } | 3100 } |
3102 call_helper.AfterCall(masm); | 3101 call_helper.AfterCall(masm); |
3103 __ jmp(&exit_); | 3102 __ jmp(&exit_); |
3104 | 3103 |
3105 __ Abort(kUnexpectedFallthroughFromCharCodeAtSlowCase); | 3104 __ Abort(kUnexpectedFallthroughFromCharCodeAtSlowCase); |
3106 } | 3105 } |
3107 | 3106 |
3108 | 3107 |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3432 // rcx: result length | 3431 // rcx: result length |
3433 // rdi: first character of result | 3432 // rdi: first character of result |
3434 // r14: character of sub string start | 3433 // r14: character of sub string start |
3435 StringHelper::GenerateCopyCharacters( | 3434 StringHelper::GenerateCopyCharacters( |
3436 masm, rdi, r14, rcx, String::TWO_BYTE_ENCODING); | 3435 masm, rdi, r14, rcx, String::TWO_BYTE_ENCODING); |
3437 __ IncrementCounter(counters->sub_string_native(), 1); | 3436 __ IncrementCounter(counters->sub_string_native(), 1); |
3438 __ ret(SUB_STRING_ARGUMENT_COUNT * kPointerSize); | 3437 __ ret(SUB_STRING_ARGUMENT_COUNT * kPointerSize); |
3439 | 3438 |
3440 // Just jump to runtime to create the sub string. | 3439 // Just jump to runtime to create the sub string. |
3441 __ bind(&runtime); | 3440 __ bind(&runtime); |
3442 __ TailCallRuntime(Runtime::kHiddenSubString, 3, 1); | 3441 __ TailCallRuntime(Runtime::kSubString, 3, 1); |
3443 | 3442 |
3444 __ bind(&single_char); | 3443 __ bind(&single_char); |
3445 // rax: string | 3444 // rax: string |
3446 // rbx: instance type | 3445 // rbx: instance type |
3447 // rcx: sub string length (smi) | 3446 // rcx: sub string length (smi) |
3448 // rdx: from index (smi) | 3447 // rdx: from index (smi) |
3449 StringCharAtGenerator generator( | 3448 StringCharAtGenerator generator( |
3450 rax, rdx, rcx, rax, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); | 3449 rax, rdx, rcx, rax, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); |
3451 generator.GenerateFast(masm); | 3450 generator.GenerateFast(masm); |
3452 __ ret(SUB_STRING_ARGUMENT_COUNT * kPointerSize); | 3451 __ ret(SUB_STRING_ARGUMENT_COUNT * kPointerSize); |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3629 __ IncrementCounter(counters->string_compare_native(), 1); | 3628 __ IncrementCounter(counters->string_compare_native(), 1); |
3630 // Drop arguments from the stack | 3629 // Drop arguments from the stack |
3631 __ PopReturnAddressTo(rcx); | 3630 __ PopReturnAddressTo(rcx); |
3632 __ addp(rsp, Immediate(2 * kPointerSize)); | 3631 __ addp(rsp, Immediate(2 * kPointerSize)); |
3633 __ PushReturnAddressFrom(rcx); | 3632 __ PushReturnAddressFrom(rcx); |
3634 GenerateCompareFlatAsciiStrings(masm, rdx, rax, rcx, rbx, rdi, r8); | 3633 GenerateCompareFlatAsciiStrings(masm, rdx, rax, rcx, rbx, rdi, r8); |
3635 | 3634 |
3636 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 3635 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
3637 // tagged as a small integer. | 3636 // tagged as a small integer. |
3638 __ bind(&runtime); | 3637 __ bind(&runtime); |
3639 __ TailCallRuntime(Runtime::kHiddenStringCompare, 2, 1); | 3638 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
3640 } | 3639 } |
3641 | 3640 |
3642 | 3641 |
3643 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { | 3642 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { |
3644 // ----------- S t a t e ------------- | 3643 // ----------- S t a t e ------------- |
3645 // -- rdx : left | 3644 // -- rdx : left |
3646 // -- rax : right | 3645 // -- rax : right |
3647 // -- rsp[0] : return address | 3646 // -- rsp[0] : return address |
3648 // ----------------------------------- | 3647 // ----------------------------------- |
3649 | 3648 |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3927 | 3926 |
3928 // Handle more complex cases in runtime. | 3927 // Handle more complex cases in runtime. |
3929 __ bind(&runtime); | 3928 __ bind(&runtime); |
3930 __ PopReturnAddressTo(tmp1); | 3929 __ PopReturnAddressTo(tmp1); |
3931 __ Push(left); | 3930 __ Push(left); |
3932 __ Push(right); | 3931 __ Push(right); |
3933 __ PushReturnAddressFrom(tmp1); | 3932 __ PushReturnAddressFrom(tmp1); |
3934 if (equality) { | 3933 if (equality) { |
3935 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); | 3934 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); |
3936 } else { | 3935 } else { |
3937 __ TailCallRuntime(Runtime::kHiddenStringCompare, 2, 1); | 3936 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
3938 } | 3937 } |
3939 | 3938 |
3940 __ bind(&miss); | 3939 __ bind(&miss); |
3941 GenerateMiss(masm); | 3940 GenerateMiss(masm); |
3942 } | 3941 } |
3943 | 3942 |
3944 | 3943 |
3945 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { | 3944 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { |
3946 ASSERT(state_ == CompareIC::OBJECT); | 3945 ASSERT(state_ == CompareIC::OBJECT); |
3947 Label miss; | 3946 Label miss; |
(...skipping 1098 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5046 return_value_operand, | 5045 return_value_operand, |
5047 NULL); | 5046 NULL); |
5048 } | 5047 } |
5049 | 5048 |
5050 | 5049 |
5051 #undef __ | 5050 #undef __ |
5052 | 5051 |
5053 } } // namespace v8::internal | 5052 } } // namespace v8::internal |
5054 | 5053 |
5055 #endif // V8_TARGET_ARCH_X64 | 5054 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |