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