OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
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/codegen.h" | 11 #include "src/codegen.h" |
12 #include "src/isolate.h" | 12 #include "src/isolate.h" |
13 #include "src/jsregexp.h" | 13 #include "src/jsregexp.h" |
14 #include "src/regexp-macro-assembler.h" | 14 #include "src/regexp-macro-assembler.h" |
15 #include "src/runtime.h" | 15 #include "src/runtime.h" |
16 #include "src/runtime.h" | 16 #include "src/runtime.h" |
17 #include "src/stub-cache.h" | 17 #include "src/stub-cache.h" |
18 | 18 |
19 namespace v8 { | 19 namespace v8 { |
20 namespace internal { | 20 namespace internal { |
21 | 21 |
22 | 22 |
23 void FastNewClosureStub::InitializeInterfaceDescriptor( | 23 void FastNewClosureStub::InitializeInterfaceDescriptor( |
24 CodeStubInterfaceDescriptor* descriptor) { | 24 CodeStubInterfaceDescriptor* descriptor) { |
25 static Register registers[] = { ebx }; | 25 static Register registers[] = { ebx }; |
26 descriptor->register_param_count_ = 1; | 26 descriptor->register_param_count_ = 1; |
27 descriptor->register_params_ = registers; | 27 descriptor->register_params_ = registers; |
28 descriptor->deoptimization_handler_ = | 28 descriptor->deoptimization_handler_ = |
29 Runtime::FunctionForId(Runtime::kHiddenNewClosureFromStubFailure)->entry; | 29 Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry; |
30 } | 30 } |
31 | 31 |
32 | 32 |
33 void FastNewContextStub::InitializeInterfaceDescriptor( | 33 void FastNewContextStub::InitializeInterfaceDescriptor( |
34 CodeStubInterfaceDescriptor* descriptor) { | 34 CodeStubInterfaceDescriptor* descriptor) { |
35 static Register registers[] = { edi }; | 35 static Register registers[] = { edi }; |
36 descriptor->register_param_count_ = 1; | 36 descriptor->register_param_count_ = 1; |
37 descriptor->register_params_ = registers; | 37 descriptor->register_params_ = registers; |
38 descriptor->deoptimization_handler_ = NULL; | 38 descriptor->deoptimization_handler_ = NULL; |
39 } | 39 } |
40 | 40 |
41 | 41 |
42 void ToNumberStub::InitializeInterfaceDescriptor( | 42 void ToNumberStub::InitializeInterfaceDescriptor( |
43 CodeStubInterfaceDescriptor* descriptor) { | 43 CodeStubInterfaceDescriptor* descriptor) { |
44 static Register registers[] = { eax }; | 44 static Register registers[] = { eax }; |
45 descriptor->register_param_count_ = 1; | 45 descriptor->register_param_count_ = 1; |
46 descriptor->register_params_ = registers; | 46 descriptor->register_params_ = registers; |
47 descriptor->deoptimization_handler_ = NULL; | 47 descriptor->deoptimization_handler_ = NULL; |
48 } | 48 } |
49 | 49 |
50 | 50 |
51 void NumberToStringStub::InitializeInterfaceDescriptor( | 51 void NumberToStringStub::InitializeInterfaceDescriptor( |
52 CodeStubInterfaceDescriptor* descriptor) { | 52 CodeStubInterfaceDescriptor* descriptor) { |
53 static Register registers[] = { eax }; | 53 static Register registers[] = { eax }; |
54 descriptor->register_param_count_ = 1; | 54 descriptor->register_param_count_ = 1; |
55 descriptor->register_params_ = registers; | 55 descriptor->register_params_ = registers; |
56 descriptor->deoptimization_handler_ = | 56 descriptor->deoptimization_handler_ = |
57 Runtime::FunctionForId(Runtime::kHiddenNumberToString)->entry; | 57 Runtime::FunctionForId(Runtime::kNumberToStringRT)->entry; |
58 } | 58 } |
59 | 59 |
60 | 60 |
61 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( | 61 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( |
62 CodeStubInterfaceDescriptor* descriptor) { | 62 CodeStubInterfaceDescriptor* descriptor) { |
63 static Register registers[] = { eax, ebx, ecx }; | 63 static Register registers[] = { eax, ebx, ecx }; |
64 descriptor->register_param_count_ = 3; | 64 descriptor->register_param_count_ = 3; |
65 descriptor->register_params_ = registers; | 65 descriptor->register_params_ = registers; |
66 static Representation representations[] = { | 66 static Representation representations[] = { |
67 Representation::Tagged(), | 67 Representation::Tagged(), |
68 Representation::Smi(), | 68 Representation::Smi(), |
69 Representation::Tagged() }; | 69 Representation::Tagged() }; |
70 descriptor->register_param_representations_ = representations; | 70 descriptor->register_param_representations_ = representations; |
71 descriptor->deoptimization_handler_ = | 71 descriptor->deoptimization_handler_ = |
72 Runtime::FunctionForId( | 72 Runtime::FunctionForId(Runtime::kCreateArrayLiteralStubBailout)->entry; |
73 Runtime::kHiddenCreateArrayLiteralStubBailout)->entry; | |
74 } | 73 } |
75 | 74 |
76 | 75 |
77 void FastCloneShallowObjectStub::InitializeInterfaceDescriptor( | 76 void FastCloneShallowObjectStub::InitializeInterfaceDescriptor( |
78 CodeStubInterfaceDescriptor* descriptor) { | 77 CodeStubInterfaceDescriptor* descriptor) { |
79 static Register registers[] = { eax, ebx, ecx, edx }; | 78 static Register registers[] = { eax, ebx, ecx, edx }; |
80 descriptor->register_param_count_ = 4; | 79 descriptor->register_param_count_ = 4; |
81 descriptor->register_params_ = registers; | 80 descriptor->register_params_ = registers; |
82 descriptor->deoptimization_handler_ = | 81 descriptor->deoptimization_handler_ = |
83 Runtime::FunctionForId(Runtime::kHiddenCreateObjectLiteral)->entry; | 82 Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry; |
84 } | 83 } |
85 | 84 |
86 | 85 |
87 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( | 86 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( |
88 CodeStubInterfaceDescriptor* descriptor) { | 87 CodeStubInterfaceDescriptor* descriptor) { |
89 static Register registers[] = { ebx, edx }; | 88 static Register registers[] = { ebx, edx }; |
90 descriptor->register_param_count_ = 2; | 89 descriptor->register_param_count_ = 2; |
91 descriptor->register_params_ = registers; | 90 descriptor->register_params_ = registers; |
92 descriptor->deoptimization_handler_ = NULL; | 91 descriptor->deoptimization_handler_ = NULL; |
93 } | 92 } |
(...skipping 18 matching lines...) Expand all Loading... |
112 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure); | 111 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure); |
113 } | 112 } |
114 | 113 |
115 | 114 |
116 void RegExpConstructResultStub::InitializeInterfaceDescriptor( | 115 void RegExpConstructResultStub::InitializeInterfaceDescriptor( |
117 CodeStubInterfaceDescriptor* descriptor) { | 116 CodeStubInterfaceDescriptor* descriptor) { |
118 static Register registers[] = { ecx, ebx, eax }; | 117 static Register registers[] = { ecx, ebx, eax }; |
119 descriptor->register_param_count_ = 3; | 118 descriptor->register_param_count_ = 3; |
120 descriptor->register_params_ = registers; | 119 descriptor->register_params_ = registers; |
121 descriptor->deoptimization_handler_ = | 120 descriptor->deoptimization_handler_ = |
122 Runtime::FunctionForId(Runtime::kHiddenRegExpConstructResult)->entry; | 121 Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry; |
123 } | 122 } |
124 | 123 |
125 | 124 |
126 void KeyedLoadGenericElementStub::InitializeInterfaceDescriptor( | 125 void KeyedLoadGenericElementStub::InitializeInterfaceDescriptor( |
127 CodeStubInterfaceDescriptor* descriptor) { | 126 CodeStubInterfaceDescriptor* descriptor) { |
128 static Register registers[] = { edx, ecx }; | 127 static Register registers[] = { edx, ecx }; |
129 descriptor->register_param_count_ = 2; | 128 descriptor->register_param_count_ = 2; |
130 descriptor->register_params_ = registers; | 129 descriptor->register_params_ = registers; |
131 descriptor->deoptimization_handler_ = | 130 descriptor->deoptimization_handler_ = |
132 Runtime::FunctionForId(Runtime::kKeyedGetProperty)->entry; | 131 Runtime::FunctionForId(Runtime::kKeyedGetProperty)->entry; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 static Representation representations[] = { | 211 static Representation representations[] = { |
213 Representation::Tagged(), | 212 Representation::Tagged(), |
214 Representation::Tagged(), | 213 Representation::Tagged(), |
215 Representation::Integer32() }; | 214 Representation::Integer32() }; |
216 descriptor->register_param_representations_ = representations; | 215 descriptor->register_param_representations_ = representations; |
217 } | 216 } |
218 | 217 |
219 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; | 218 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; |
220 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; | 219 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; |
221 descriptor->deoptimization_handler_ = | 220 descriptor->deoptimization_handler_ = |
222 Runtime::FunctionForId(Runtime::kHiddenArrayConstructor)->entry; | 221 Runtime::FunctionForId(Runtime::kArrayConstructor)->entry; |
223 } | 222 } |
224 | 223 |
225 | 224 |
226 static void InitializeInternalArrayConstructorDescriptor( | 225 static void InitializeInternalArrayConstructorDescriptor( |
227 CodeStubInterfaceDescriptor* descriptor, | 226 CodeStubInterfaceDescriptor* descriptor, |
228 int constant_stack_parameter_count) { | 227 int constant_stack_parameter_count) { |
229 // register state | 228 // register state |
230 // eax -- number of arguments | 229 // eax -- number of arguments |
231 // edi -- constructor function | 230 // edi -- constructor function |
232 static Register registers_variable_args[] = { edi, eax }; | 231 static Register registers_variable_args[] = { edi, eax }; |
(...skipping 10 matching lines...) Expand all Loading... |
243 descriptor->register_params_ = registers_variable_args; | 242 descriptor->register_params_ = registers_variable_args; |
244 static Representation representations[] = { | 243 static Representation representations[] = { |
245 Representation::Tagged(), | 244 Representation::Tagged(), |
246 Representation::Integer32() }; | 245 Representation::Integer32() }; |
247 descriptor->register_param_representations_ = representations; | 246 descriptor->register_param_representations_ = representations; |
248 } | 247 } |
249 | 248 |
250 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; | 249 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; |
251 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; | 250 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; |
252 descriptor->deoptimization_handler_ = | 251 descriptor->deoptimization_handler_ = |
253 Runtime::FunctionForId(Runtime::kHiddenInternalArrayConstructor)->entry; | 252 Runtime::FunctionForId(Runtime::kInternalArrayConstructor)->entry; |
254 } | 253 } |
255 | 254 |
256 | 255 |
257 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( | 256 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( |
258 CodeStubInterfaceDescriptor* descriptor) { | 257 CodeStubInterfaceDescriptor* descriptor) { |
259 InitializeArrayConstructorDescriptor(isolate(), descriptor, 0); | 258 InitializeArrayConstructorDescriptor(isolate(), descriptor, 0); |
260 } | 259 } |
261 | 260 |
262 | 261 |
263 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( | 262 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite); | 352 FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite); |
354 } | 353 } |
355 | 354 |
356 | 355 |
357 void StringAddStub::InitializeInterfaceDescriptor( | 356 void StringAddStub::InitializeInterfaceDescriptor( |
358 CodeStubInterfaceDescriptor* descriptor) { | 357 CodeStubInterfaceDescriptor* descriptor) { |
359 static Register registers[] = { edx, eax }; | 358 static Register registers[] = { edx, eax }; |
360 descriptor->register_param_count_ = 2; | 359 descriptor->register_param_count_ = 2; |
361 descriptor->register_params_ = registers; | 360 descriptor->register_params_ = registers; |
362 descriptor->deoptimization_handler_ = | 361 descriptor->deoptimization_handler_ = |
363 Runtime::FunctionForId(Runtime::kHiddenStringAdd)->entry; | 362 Runtime::FunctionForId(Runtime::kStringAdd)->entry; |
364 } | 363 } |
365 | 364 |
366 | 365 |
367 void CallDescriptors::InitializeForIsolate(Isolate* isolate) { | 366 void CallDescriptors::InitializeForIsolate(Isolate* isolate) { |
368 { | 367 { |
369 CallInterfaceDescriptor* descriptor = | 368 CallInterfaceDescriptor* descriptor = |
370 isolate->call_descriptor(Isolate::ArgumentAdaptorCall); | 369 isolate->call_descriptor(Isolate::ArgumentAdaptorCall); |
371 static Register registers[] = { edi, // JSFunction | 370 static Register registers[] = { edi, // JSFunction |
372 esi, // context | 371 esi, // context |
373 eax, // actual number of arguments | 372 eax, // actual number of arguments |
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
958 // and may not have contained the exponent value in the first place when the | 957 // and may not have contained the exponent value in the first place when the |
959 // exponent is a smi. We reset it with exponent value before bailing out. | 958 // exponent is a smi. We reset it with exponent value before bailing out. |
960 __ j(not_equal, &done); | 959 __ j(not_equal, &done); |
961 __ Cvtsi2sd(double_exponent, exponent); | 960 __ Cvtsi2sd(double_exponent, exponent); |
962 | 961 |
963 // Returning or bailing out. | 962 // Returning or bailing out. |
964 Counters* counters = isolate()->counters(); | 963 Counters* counters = isolate()->counters(); |
965 if (exponent_type_ == ON_STACK) { | 964 if (exponent_type_ == ON_STACK) { |
966 // The arguments are still on the stack. | 965 // The arguments are still on the stack. |
967 __ bind(&call_runtime); | 966 __ bind(&call_runtime); |
968 __ TailCallRuntime(Runtime::kHiddenMathPow, 2, 1); | 967 __ TailCallRuntime(Runtime::kMathPowRT, 2, 1); |
969 | 968 |
970 // The stub is called from non-optimized code, which expects the result | 969 // The stub is called from non-optimized code, which expects the result |
971 // as heap number in exponent. | 970 // as heap number in exponent. |
972 __ bind(&done); | 971 __ bind(&done); |
973 __ AllocateHeapNumber(eax, scratch, base, &call_runtime); | 972 __ AllocateHeapNumber(eax, scratch, base, &call_runtime); |
974 __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), double_result); | 973 __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), double_result); |
975 __ IncrementCounter(counters->math_pow(), 1); | 974 __ IncrementCounter(counters->math_pow(), 1); |
976 __ ret(2 * kPointerSize); | 975 __ ret(2 * kPointerSize); |
977 } else { | 976 } else { |
978 __ bind(&call_runtime); | 977 __ bind(&call_runtime); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1091 __ j(not_equal, &runtime, Label::kNear); | 1090 __ j(not_equal, &runtime, Label::kNear); |
1092 | 1091 |
1093 // Patch the arguments.length and the parameters pointer. | 1092 // Patch the arguments.length and the parameters pointer. |
1094 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 1093 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
1095 __ mov(Operand(esp, 1 * kPointerSize), ecx); | 1094 __ mov(Operand(esp, 1 * kPointerSize), ecx); |
1096 __ lea(edx, Operand(edx, ecx, times_2, | 1095 __ lea(edx, Operand(edx, ecx, times_2, |
1097 StandardFrameConstants::kCallerSPOffset)); | 1096 StandardFrameConstants::kCallerSPOffset)); |
1098 __ mov(Operand(esp, 2 * kPointerSize), edx); | 1097 __ mov(Operand(esp, 2 * kPointerSize), edx); |
1099 | 1098 |
1100 __ bind(&runtime); | 1099 __ bind(&runtime); |
1101 __ TailCallRuntime(Runtime::kHiddenNewSloppyArguments, 3, 1); | 1100 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); |
1102 } | 1101 } |
1103 | 1102 |
1104 | 1103 |
1105 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { | 1104 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { |
1106 // esp[0] : return address | 1105 // esp[0] : return address |
1107 // esp[4] : number of parameters (tagged) | 1106 // esp[4] : number of parameters (tagged) |
1108 // esp[8] : receiver displacement | 1107 // esp[8] : receiver displacement |
1109 // esp[12] : function | 1108 // esp[12] : function |
1110 | 1109 |
1111 // ebx = parameter count (tagged) | 1110 // ebx = parameter count (tagged) |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1314 __ pop(eax); // Address of arguments object. | 1313 __ pop(eax); // Address of arguments object. |
1315 __ pop(ebx); // Parameter count. | 1314 __ pop(ebx); // Parameter count. |
1316 | 1315 |
1317 // Return and remove the on-stack parameters. | 1316 // Return and remove the on-stack parameters. |
1318 __ ret(3 * kPointerSize); | 1317 __ ret(3 * kPointerSize); |
1319 | 1318 |
1320 // Do the runtime call to allocate the arguments object. | 1319 // Do the runtime call to allocate the arguments object. |
1321 __ bind(&runtime); | 1320 __ bind(&runtime); |
1322 __ pop(eax); // Remove saved parameter count. | 1321 __ pop(eax); // Remove saved parameter count. |
1323 __ mov(Operand(esp, 1 * kPointerSize), ecx); // Patch argument count. | 1322 __ mov(Operand(esp, 1 * kPointerSize), ecx); // Patch argument count. |
1324 __ TailCallRuntime(Runtime::kHiddenNewSloppyArguments, 3, 1); | 1323 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); |
1325 } | 1324 } |
1326 | 1325 |
1327 | 1326 |
1328 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { | 1327 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { |
1329 // esp[0] : return address | 1328 // esp[0] : return address |
1330 // esp[4] : number of parameters | 1329 // esp[4] : number of parameters |
1331 // esp[8] : receiver displacement | 1330 // esp[8] : receiver displacement |
1332 // esp[12] : function | 1331 // esp[12] : function |
1333 | 1332 |
1334 // Check if the calling frame is an arguments adaptor frame. | 1333 // Check if the calling frame is an arguments adaptor frame. |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1411 __ sub(edx, Immediate(kPointerSize)); | 1410 __ sub(edx, Immediate(kPointerSize)); |
1412 __ dec(ecx); | 1411 __ dec(ecx); |
1413 __ j(not_zero, &loop); | 1412 __ j(not_zero, &loop); |
1414 | 1413 |
1415 // Return and remove the on-stack parameters. | 1414 // Return and remove the on-stack parameters. |
1416 __ bind(&done); | 1415 __ bind(&done); |
1417 __ ret(3 * kPointerSize); | 1416 __ ret(3 * kPointerSize); |
1418 | 1417 |
1419 // Do the runtime call to allocate the arguments object. | 1418 // Do the runtime call to allocate the arguments object. |
1420 __ bind(&runtime); | 1419 __ bind(&runtime); |
1421 __ TailCallRuntime(Runtime::kHiddenNewStrictArguments, 3, 1); | 1420 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1); |
1422 } | 1421 } |
1423 | 1422 |
1424 | 1423 |
1425 void RegExpExecStub::Generate(MacroAssembler* masm) { | 1424 void RegExpExecStub::Generate(MacroAssembler* masm) { |
1426 // Just jump directly to runtime if native RegExp is not selected at compile | 1425 // Just jump directly to runtime if native RegExp is not selected at compile |
1427 // time or if regexp entry in generated code is turned off runtime switch or | 1426 // time or if regexp entry in generated code is turned off runtime switch or |
1428 // at compilation. | 1427 // at compilation. |
1429 #ifdef V8_INTERPRETED_REGEXP | 1428 #ifdef V8_INTERPRETED_REGEXP |
1430 __ TailCallRuntime(Runtime::kHiddenRegExpExec, 4, 1); | 1429 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); |
1431 #else // V8_INTERPRETED_REGEXP | 1430 #else // V8_INTERPRETED_REGEXP |
1432 | 1431 |
1433 // Stack frame on entry. | 1432 // Stack frame on entry. |
1434 // esp[0]: return address | 1433 // esp[0]: return address |
1435 // esp[4]: last_match_info (expected JSArray) | 1434 // esp[4]: last_match_info (expected JSArray) |
1436 // esp[8]: previous index | 1435 // esp[8]: previous index |
1437 // esp[12]: subject string | 1436 // esp[12]: subject string |
1438 // esp[16]: JSRegExp object | 1437 // esp[16]: JSRegExp object |
1439 | 1438 |
1440 static const int kLastMatchInfoOffset = 1 * kPointerSize; | 1439 static const int kLastMatchInfoOffset = 1 * kPointerSize; |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1803 edi); | 1802 edi); |
1804 __ jmp(&next_capture); | 1803 __ jmp(&next_capture); |
1805 __ bind(&done); | 1804 __ bind(&done); |
1806 | 1805 |
1807 // Return last match info. | 1806 // Return last match info. |
1808 __ mov(eax, Operand(esp, kLastMatchInfoOffset)); | 1807 __ mov(eax, Operand(esp, kLastMatchInfoOffset)); |
1809 __ ret(4 * kPointerSize); | 1808 __ ret(4 * kPointerSize); |
1810 | 1809 |
1811 // Do the runtime call to execute the regexp. | 1810 // Do the runtime call to execute the regexp. |
1812 __ bind(&runtime); | 1811 __ bind(&runtime); |
1813 __ TailCallRuntime(Runtime::kHiddenRegExpExec, 4, 1); | 1812 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1); |
1814 | 1813 |
1815 // Deferred code for string handling. | 1814 // Deferred code for string handling. |
1816 // (7) Not a long external string? If yes, go to (10). | 1815 // (7) Not a long external string? If yes, go to (10). |
1817 __ bind(¬_seq_nor_cons); | 1816 __ bind(¬_seq_nor_cons); |
1818 // Compare flags are still set from (3). | 1817 // Compare flags are still set from (3). |
1819 __ j(greater, ¬_long_external, Label::kNear); // Go to (10). | 1818 __ j(greater, ¬_long_external, Label::kNear); // Go to (10). |
1820 | 1819 |
1821 // (8) External string. Short external strings have been ruled out. | 1820 // (8) External string. Short external strings have been ruled out. |
1822 __ bind(&external_string); | 1821 __ bind(&external_string); |
1823 // Reload instance type. | 1822 // Reload instance type. |
(...skipping 1275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3099 index_not_number_, | 3098 index_not_number_, |
3100 DONT_DO_SMI_CHECK); | 3099 DONT_DO_SMI_CHECK); |
3101 call_helper.BeforeCall(masm); | 3100 call_helper.BeforeCall(masm); |
3102 __ push(object_); | 3101 __ push(object_); |
3103 __ push(index_); // Consumed by runtime conversion function. | 3102 __ push(index_); // Consumed by runtime conversion function. |
3104 if (index_flags_ == STRING_INDEX_IS_NUMBER) { | 3103 if (index_flags_ == STRING_INDEX_IS_NUMBER) { |
3105 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); | 3104 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); |
3106 } else { | 3105 } else { |
3107 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); | 3106 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); |
3108 // NumberToSmi discards numbers that are not exact integers. | 3107 // NumberToSmi discards numbers that are not exact integers. |
3109 __ CallRuntime(Runtime::kHiddenNumberToSmi, 1); | 3108 __ CallRuntime(Runtime::kNumberToSmi, 1); |
3110 } | 3109 } |
3111 if (!index_.is(eax)) { | 3110 if (!index_.is(eax)) { |
3112 // Save the conversion result before the pop instructions below | 3111 // Save the conversion result before the pop instructions below |
3113 // have a chance to overwrite it. | 3112 // have a chance to overwrite it. |
3114 __ mov(index_, eax); | 3113 __ mov(index_, eax); |
3115 } | 3114 } |
3116 __ pop(object_); | 3115 __ pop(object_); |
3117 // Reload the instance type. | 3116 // Reload the instance type. |
3118 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); | 3117 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); |
3119 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); | 3118 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); |
3120 call_helper.AfterCall(masm); | 3119 call_helper.AfterCall(masm); |
3121 // If index is still not a smi, it must be out of range. | 3120 // If index is still not a smi, it must be out of range. |
3122 STATIC_ASSERT(kSmiTag == 0); | 3121 STATIC_ASSERT(kSmiTag == 0); |
3123 __ JumpIfNotSmi(index_, index_out_of_range_); | 3122 __ JumpIfNotSmi(index_, index_out_of_range_); |
3124 // Otherwise, return to the fast path. | 3123 // Otherwise, return to the fast path. |
3125 __ jmp(&got_smi_index_); | 3124 __ jmp(&got_smi_index_); |
3126 | 3125 |
3127 // Call runtime. We get here when the receiver is a string and the | 3126 // Call runtime. We get here when the receiver is a string and the |
3128 // index is a number, but the code of getting the actual character | 3127 // index is a number, but the code of getting the actual character |
3129 // is too complex (e.g., when the string needs to be flattened). | 3128 // is too complex (e.g., when the string needs to be flattened). |
3130 __ bind(&call_runtime_); | 3129 __ bind(&call_runtime_); |
3131 call_helper.BeforeCall(masm); | 3130 call_helper.BeforeCall(masm); |
3132 __ push(object_); | 3131 __ push(object_); |
3133 __ SmiTag(index_); | 3132 __ SmiTag(index_); |
3134 __ push(index_); | 3133 __ push(index_); |
3135 __ CallRuntime(Runtime::kHiddenStringCharCodeAt, 2); | 3134 __ CallRuntime(Runtime::kStringCharCodeAtRT, 2); |
3136 if (!result_.is(eax)) { | 3135 if (!result_.is(eax)) { |
3137 __ mov(result_, eax); | 3136 __ mov(result_, eax); |
3138 } | 3137 } |
3139 call_helper.AfterCall(masm); | 3138 call_helper.AfterCall(masm); |
3140 __ jmp(&exit_); | 3139 __ jmp(&exit_); |
3141 | 3140 |
3142 __ Abort(kUnexpectedFallthroughFromCharCodeAtSlowCase); | 3141 __ Abort(kUnexpectedFallthroughFromCharCodeAtSlowCase); |
3143 } | 3142 } |
3144 | 3143 |
3145 | 3144 |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3490 masm, edi, edx, ecx, ebx, String::TWO_BYTE_ENCODING); | 3489 masm, edi, edx, ecx, ebx, String::TWO_BYTE_ENCODING); |
3491 __ IncrementCounter(counters->sub_string_native(), 1); | 3490 __ IncrementCounter(counters->sub_string_native(), 1); |
3492 __ ret(3 * kPointerSize); | 3491 __ ret(3 * kPointerSize); |
3493 | 3492 |
3494 // Drop pushed values on the stack before tail call. | 3493 // Drop pushed values on the stack before tail call. |
3495 __ bind(&runtime_drop_two); | 3494 __ bind(&runtime_drop_two); |
3496 __ Drop(2); | 3495 __ Drop(2); |
3497 | 3496 |
3498 // Just jump to runtime to create the sub string. | 3497 // Just jump to runtime to create the sub string. |
3499 __ bind(&runtime); | 3498 __ bind(&runtime); |
3500 __ TailCallRuntime(Runtime::kHiddenSubString, 3, 1); | 3499 __ TailCallRuntime(Runtime::kSubString, 3, 1); |
3501 | 3500 |
3502 __ bind(&single_char); | 3501 __ bind(&single_char); |
3503 // eax: string | 3502 // eax: string |
3504 // ebx: instance type | 3503 // ebx: instance type |
3505 // ecx: sub string length (smi) | 3504 // ecx: sub string length (smi) |
3506 // edx: from index (smi) | 3505 // edx: from index (smi) |
3507 StringCharAtGenerator generator( | 3506 StringCharAtGenerator generator( |
3508 eax, edx, ecx, eax, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); | 3507 eax, edx, ecx, eax, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); |
3509 generator.GenerateFast(masm); | 3508 generator.GenerateFast(masm); |
3510 __ ret(3 * kPointerSize); | 3509 __ ret(3 * kPointerSize); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3672 // Compare flat ASCII strings. | 3671 // Compare flat ASCII strings. |
3673 // Drop arguments from the stack. | 3672 // Drop arguments from the stack. |
3674 __ pop(ecx); | 3673 __ pop(ecx); |
3675 __ add(esp, Immediate(2 * kPointerSize)); | 3674 __ add(esp, Immediate(2 * kPointerSize)); |
3676 __ push(ecx); | 3675 __ push(ecx); |
3677 GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, edi); | 3676 GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, edi); |
3678 | 3677 |
3679 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 3678 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
3680 // tagged as a small integer. | 3679 // tagged as a small integer. |
3681 __ bind(&runtime); | 3680 __ bind(&runtime); |
3682 __ TailCallRuntime(Runtime::kHiddenStringCompare, 2, 1); | 3681 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
3683 } | 3682 } |
3684 | 3683 |
3685 | 3684 |
3686 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { | 3685 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { |
3687 // ----------- S t a t e ------------- | 3686 // ----------- S t a t e ------------- |
3688 // -- edx : left | 3687 // -- edx : left |
3689 // -- eax : right | 3688 // -- eax : right |
3690 // -- esp[0] : return address | 3689 // -- esp[0] : return address |
3691 // ----------------------------------- | 3690 // ----------------------------------- |
3692 | 3691 |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3984 | 3983 |
3985 // Handle more complex cases in runtime. | 3984 // Handle more complex cases in runtime. |
3986 __ bind(&runtime); | 3985 __ bind(&runtime); |
3987 __ pop(tmp1); // Return address. | 3986 __ pop(tmp1); // Return address. |
3988 __ push(left); | 3987 __ push(left); |
3989 __ push(right); | 3988 __ push(right); |
3990 __ push(tmp1); | 3989 __ push(tmp1); |
3991 if (equality) { | 3990 if (equality) { |
3992 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); | 3991 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); |
3993 } else { | 3992 } else { |
3994 __ TailCallRuntime(Runtime::kHiddenStringCompare, 2, 1); | 3993 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
3995 } | 3994 } |
3996 | 3995 |
3997 __ bind(&miss); | 3996 __ bind(&miss); |
3998 GenerateMiss(masm); | 3997 GenerateMiss(masm); |
3999 } | 3998 } |
4000 | 3999 |
4001 | 4000 |
4002 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { | 4001 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { |
4003 ASSERT(state_ == CompareIC::OBJECT); | 4002 ASSERT(state_ == CompareIC::OBJECT); |
4004 Label miss; | 4003 Label miss; |
(...skipping 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5085 Operand(ebp, 7 * kPointerSize), | 5084 Operand(ebp, 7 * kPointerSize), |
5086 NULL); | 5085 NULL); |
5087 } | 5086 } |
5088 | 5087 |
5089 | 5088 |
5090 #undef __ | 5089 #undef __ |
5091 | 5090 |
5092 } } // namespace v8::internal | 5091 } } // namespace v8::internal |
5093 | 5092 |
5094 #endif // V8_TARGET_ARCH_IA32 | 5093 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |