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_X87 | 7 #if V8_TARGET_ARCH_X87 |
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/stub-cache.h" | 16 #include "src/stub-cache.h" |
17 | 17 |
18 namespace v8 { | 18 namespace v8 { |
19 namespace internal { | 19 namespace internal { |
20 | 20 |
21 | 21 |
22 void FastNewClosureStub::InitializeInterfaceDescriptor( | 22 void FastNewClosureStub::InitializeInterfaceDescriptor( |
23 CodeStubInterfaceDescriptor* descriptor) { | 23 CodeStubInterfaceDescriptor* descriptor) { |
24 static Register registers[] = { ebx }; | 24 static Register registers[] = { ebx }; |
25 descriptor->register_param_count_ = 1; | 25 descriptor->register_param_count_ = 1; |
26 descriptor->register_params_ = registers; | 26 descriptor->register_params_ = registers; |
27 descriptor->deoptimization_handler_ = | 27 descriptor->deoptimization_handler_ = |
28 Runtime::FunctionForId(Runtime::kHiddenNewClosureFromStubFailure)->entry; | 28 Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry; |
29 } | 29 } |
30 | 30 |
31 | 31 |
32 void FastNewContextStub::InitializeInterfaceDescriptor( | 32 void FastNewContextStub::InitializeInterfaceDescriptor( |
33 CodeStubInterfaceDescriptor* descriptor) { | 33 CodeStubInterfaceDescriptor* descriptor) { |
34 static Register registers[] = { edi }; | 34 static Register registers[] = { edi }; |
35 descriptor->register_param_count_ = 1; | 35 descriptor->register_param_count_ = 1; |
36 descriptor->register_params_ = registers; | 36 descriptor->register_params_ = registers; |
37 descriptor->deoptimization_handler_ = NULL; | 37 descriptor->deoptimization_handler_ = NULL; |
38 } | 38 } |
39 | 39 |
40 | 40 |
41 void ToNumberStub::InitializeInterfaceDescriptor( | 41 void ToNumberStub::InitializeInterfaceDescriptor( |
42 CodeStubInterfaceDescriptor* descriptor) { | 42 CodeStubInterfaceDescriptor* descriptor) { |
43 static Register registers[] = { eax }; | 43 static Register registers[] = { eax }; |
44 descriptor->register_param_count_ = 1; | 44 descriptor->register_param_count_ = 1; |
45 descriptor->register_params_ = registers; | 45 descriptor->register_params_ = registers; |
46 descriptor->deoptimization_handler_ = NULL; | 46 descriptor->deoptimization_handler_ = NULL; |
47 } | 47 } |
48 | 48 |
49 | 49 |
50 void NumberToStringStub::InitializeInterfaceDescriptor( | 50 void NumberToStringStub::InitializeInterfaceDescriptor( |
51 CodeStubInterfaceDescriptor* descriptor) { | 51 CodeStubInterfaceDescriptor* descriptor) { |
52 static Register registers[] = { eax }; | 52 static Register registers[] = { eax }; |
53 descriptor->register_param_count_ = 1; | 53 descriptor->register_param_count_ = 1; |
54 descriptor->register_params_ = registers; | 54 descriptor->register_params_ = registers; |
55 descriptor->deoptimization_handler_ = | 55 descriptor->deoptimization_handler_ = |
56 Runtime::FunctionForId(Runtime::kHiddenNumberToString)->entry; | 56 Runtime::FunctionForId(Runtime::kNumberToString)->entry; |
57 } | 57 } |
58 | 58 |
59 | 59 |
60 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( | 60 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( |
61 CodeStubInterfaceDescriptor* descriptor) { | 61 CodeStubInterfaceDescriptor* descriptor) { |
62 static Register registers[] = { eax, ebx, ecx }; | 62 static Register registers[] = { eax, ebx, ecx }; |
63 descriptor->register_param_count_ = 3; | 63 descriptor->register_param_count_ = 3; |
64 descriptor->register_params_ = registers; | 64 descriptor->register_params_ = registers; |
65 static Representation representations[] = { | 65 static Representation representations[] = { |
66 Representation::Tagged(), | 66 Representation::Tagged(), |
67 Representation::Smi(), | 67 Representation::Smi(), |
68 Representation::Tagged() }; | 68 Representation::Tagged() }; |
69 descriptor->register_param_representations_ = representations; | 69 descriptor->register_param_representations_ = representations; |
70 descriptor->deoptimization_handler_ = | 70 descriptor->deoptimization_handler_ = |
71 Runtime::FunctionForId( | 71 Runtime::FunctionForId( |
72 Runtime::kHiddenCreateArrayLiteralStubBailout)->entry; | 72 Runtime::kCreateArrayLiteralStubBailout)->entry; |
73 } | 73 } |
74 | 74 |
75 | 75 |
76 void FastCloneShallowObjectStub::InitializeInterfaceDescriptor( | 76 void FastCloneShallowObjectStub::InitializeInterfaceDescriptor( |
77 CodeStubInterfaceDescriptor* descriptor) { | 77 CodeStubInterfaceDescriptor* descriptor) { |
78 static Register registers[] = { eax, ebx, ecx, edx }; | 78 static Register registers[] = { eax, ebx, ecx, edx }; |
79 descriptor->register_param_count_ = 4; | 79 descriptor->register_param_count_ = 4; |
80 descriptor->register_params_ = registers; | 80 descriptor->register_params_ = registers; |
81 descriptor->deoptimization_handler_ = | 81 descriptor->deoptimization_handler_ = |
82 Runtime::FunctionForId(Runtime::kHiddenCreateObjectLiteral)->entry; | 82 Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry; |
83 } | 83 } |
84 | 84 |
85 | 85 |
86 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( | 86 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( |
87 CodeStubInterfaceDescriptor* descriptor) { | 87 CodeStubInterfaceDescriptor* descriptor) { |
88 static Register registers[] = { ebx, edx }; | 88 static Register registers[] = { ebx, edx }; |
89 descriptor->register_param_count_ = 2; | 89 descriptor->register_param_count_ = 2; |
90 descriptor->register_params_ = registers; | 90 descriptor->register_params_ = registers; |
91 descriptor->deoptimization_handler_ = NULL; | 91 descriptor->deoptimization_handler_ = NULL; |
92 } | 92 } |
(...skipping 18 matching lines...) Expand all Loading... |
111 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure); | 111 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure); |
112 } | 112 } |
113 | 113 |
114 | 114 |
115 void RegExpConstructResultStub::InitializeInterfaceDescriptor( | 115 void RegExpConstructResultStub::InitializeInterfaceDescriptor( |
116 CodeStubInterfaceDescriptor* descriptor) { | 116 CodeStubInterfaceDescriptor* descriptor) { |
117 static Register registers[] = { ecx, ebx, eax }; | 117 static Register registers[] = { ecx, ebx, eax }; |
118 descriptor->register_param_count_ = 3; | 118 descriptor->register_param_count_ = 3; |
119 descriptor->register_params_ = registers; | 119 descriptor->register_params_ = registers; |
120 descriptor->deoptimization_handler_ = | 120 descriptor->deoptimization_handler_ = |
121 Runtime::FunctionForId(Runtime::kHiddenRegExpConstructResult)->entry; | 121 Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry; |
122 } | 122 } |
123 | 123 |
124 | 124 |
125 void KeyedLoadGenericElementStub::InitializeInterfaceDescriptor( | 125 void KeyedLoadGenericElementStub::InitializeInterfaceDescriptor( |
126 CodeStubInterfaceDescriptor* descriptor) { | 126 CodeStubInterfaceDescriptor* descriptor) { |
127 static Register registers[] = { edx, ecx }; | 127 static Register registers[] = { edx, ecx }; |
128 descriptor->register_param_count_ = 2; | 128 descriptor->register_param_count_ = 2; |
129 descriptor->register_params_ = registers; | 129 descriptor->register_params_ = registers; |
130 descriptor->deoptimization_handler_ = | 130 descriptor->deoptimization_handler_ = |
131 Runtime::FunctionForId(Runtime::kKeyedGetProperty)->entry; | 131 Runtime::FunctionForId(Runtime::kKeyedGetProperty)->entry; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 static Representation representations[] = { | 211 static Representation representations[] = { |
212 Representation::Tagged(), | 212 Representation::Tagged(), |
213 Representation::Tagged(), | 213 Representation::Tagged(), |
214 Representation::Integer32() }; | 214 Representation::Integer32() }; |
215 descriptor->register_param_representations_ = representations; | 215 descriptor->register_param_representations_ = representations; |
216 } | 216 } |
217 | 217 |
218 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; | 218 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; |
219 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; | 219 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; |
220 descriptor->deoptimization_handler_ = | 220 descriptor->deoptimization_handler_ = |
221 Runtime::FunctionForId(Runtime::kHiddenArrayConstructor)->entry; | 221 Runtime::FunctionForId(Runtime::kArrayConstructor)->entry; |
222 } | 222 } |
223 | 223 |
224 | 224 |
225 static void InitializeInternalArrayConstructorDescriptor( | 225 static void InitializeInternalArrayConstructorDescriptor( |
226 CodeStubInterfaceDescriptor* descriptor, | 226 CodeStubInterfaceDescriptor* descriptor, |
227 int constant_stack_parameter_count) { | 227 int constant_stack_parameter_count) { |
228 // register state | 228 // register state |
229 // eax -- number of arguments | 229 // eax -- number of arguments |
230 // edi -- constructor function | 230 // edi -- constructor function |
231 static Register registers_variable_args[] = { edi, eax }; | 231 static Register registers_variable_args[] = { edi, eax }; |
(...skipping 10 matching lines...) Expand all Loading... |
242 descriptor->register_params_ = registers_variable_args; | 242 descriptor->register_params_ = registers_variable_args; |
243 static Representation representations[] = { | 243 static Representation representations[] = { |
244 Representation::Tagged(), | 244 Representation::Tagged(), |
245 Representation::Integer32() }; | 245 Representation::Integer32() }; |
246 descriptor->register_param_representations_ = representations; | 246 descriptor->register_param_representations_ = representations; |
247 } | 247 } |
248 | 248 |
249 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; | 249 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; |
250 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; | 250 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; |
251 descriptor->deoptimization_handler_ = | 251 descriptor->deoptimization_handler_ = |
252 Runtime::FunctionForId(Runtime::kHiddenInternalArrayConstructor)->entry; | 252 Runtime::FunctionForId(Runtime::kInternalArrayConstructor)->entry; |
253 } | 253 } |
254 | 254 |
255 | 255 |
256 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( | 256 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( |
257 CodeStubInterfaceDescriptor* descriptor) { | 257 CodeStubInterfaceDescriptor* descriptor) { |
258 InitializeArrayConstructorDescriptor(isolate(), descriptor, 0); | 258 InitializeArrayConstructorDescriptor(isolate(), descriptor, 0); |
259 } | 259 } |
260 | 260 |
261 | 261 |
262 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( | 262 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite); | 352 FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite); |
353 } | 353 } |
354 | 354 |
355 | 355 |
356 void StringAddStub::InitializeInterfaceDescriptor( | 356 void StringAddStub::InitializeInterfaceDescriptor( |
357 CodeStubInterfaceDescriptor* descriptor) { | 357 CodeStubInterfaceDescriptor* descriptor) { |
358 static Register registers[] = { edx, eax }; | 358 static Register registers[] = { edx, eax }; |
359 descriptor->register_param_count_ = 2; | 359 descriptor->register_param_count_ = 2; |
360 descriptor->register_params_ = registers; | 360 descriptor->register_params_ = registers; |
361 descriptor->deoptimization_handler_ = | 361 descriptor->deoptimization_handler_ = |
362 Runtime::FunctionForId(Runtime::kHiddenStringAdd)->entry; | 362 Runtime::FunctionForId(Runtime::kStringAdd)->entry; |
363 } | 363 } |
364 | 364 |
365 | 365 |
366 void CallDescriptors::InitializeForIsolate(Isolate* isolate) { | 366 void CallDescriptors::InitializeForIsolate(Isolate* isolate) { |
367 { | 367 { |
368 CallInterfaceDescriptor* descriptor = | 368 CallInterfaceDescriptor* descriptor = |
369 isolate->call_descriptor(Isolate::ArgumentAdaptorCall); | 369 isolate->call_descriptor(Isolate::ArgumentAdaptorCall); |
370 static Register registers[] = { edi, // JSFunction | 370 static Register registers[] = { edi, // JSFunction |
371 esi, // context | 371 esi, // context |
372 eax, // actual number of arguments | 372 eax, // actual number of arguments |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
763 __ j(not_equal, &runtime, Label::kNear); | 763 __ j(not_equal, &runtime, Label::kNear); |
764 | 764 |
765 // Patch the arguments.length and the parameters pointer. | 765 // Patch the arguments.length and the parameters pointer. |
766 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 766 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
767 __ mov(Operand(esp, 1 * kPointerSize), ecx); | 767 __ mov(Operand(esp, 1 * kPointerSize), ecx); |
768 __ lea(edx, Operand(edx, ecx, times_2, | 768 __ lea(edx, Operand(edx, ecx, times_2, |
769 StandardFrameConstants::kCallerSPOffset)); | 769 StandardFrameConstants::kCallerSPOffset)); |
770 __ mov(Operand(esp, 2 * kPointerSize), edx); | 770 __ mov(Operand(esp, 2 * kPointerSize), edx); |
771 | 771 |
772 __ bind(&runtime); | 772 __ bind(&runtime); |
773 __ TailCallRuntime(Runtime::kHiddenNewSloppyArguments, 3, 1); | 773 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); |
774 } | 774 } |
775 | 775 |
776 | 776 |
777 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { | 777 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { |
778 // esp[0] : return address | 778 // esp[0] : return address |
779 // esp[4] : number of parameters (tagged) | 779 // esp[4] : number of parameters (tagged) |
780 // esp[8] : receiver displacement | 780 // esp[8] : receiver displacement |
781 // esp[12] : function | 781 // esp[12] : function |
782 | 782 |
783 // ebx = parameter count (tagged) | 783 // ebx = parameter count (tagged) |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
986 __ pop(eax); // Address of arguments object. | 986 __ pop(eax); // Address of arguments object. |
987 __ pop(ebx); // Parameter count. | 987 __ pop(ebx); // Parameter count. |
988 | 988 |
989 // Return and remove the on-stack parameters. | 989 // Return and remove the on-stack parameters. |
990 __ ret(3 * kPointerSize); | 990 __ ret(3 * kPointerSize); |
991 | 991 |
992 // Do the runtime call to allocate the arguments object. | 992 // Do the runtime call to allocate the arguments object. |
993 __ bind(&runtime); | 993 __ bind(&runtime); |
994 __ pop(eax); // Remove saved parameter count. | 994 __ pop(eax); // Remove saved parameter count. |
995 __ mov(Operand(esp, 1 * kPointerSize), ecx); // Patch argument count. | 995 __ mov(Operand(esp, 1 * kPointerSize), ecx); // Patch argument count. |
996 __ TailCallRuntime(Runtime::kHiddenNewSloppyArguments, 3, 1); | 996 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); |
997 } | 997 } |
998 | 998 |
999 | 999 |
1000 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { | 1000 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { |
1001 // esp[0] : return address | 1001 // esp[0] : return address |
1002 // esp[4] : number of parameters | 1002 // esp[4] : number of parameters |
1003 // esp[8] : receiver displacement | 1003 // esp[8] : receiver displacement |
1004 // esp[12] : function | 1004 // esp[12] : function |
1005 | 1005 |
1006 // Check if the calling frame is an arguments adaptor frame. | 1006 // Check if the calling frame is an arguments adaptor frame. |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1083 __ sub(edx, Immediate(kPointerSize)); | 1083 __ sub(edx, Immediate(kPointerSize)); |
1084 __ dec(ecx); | 1084 __ dec(ecx); |
1085 __ j(not_zero, &loop); | 1085 __ j(not_zero, &loop); |
1086 | 1086 |
1087 // Return and remove the on-stack parameters. | 1087 // Return and remove the on-stack parameters. |
1088 __ bind(&done); | 1088 __ bind(&done); |
1089 __ ret(3 * kPointerSize); | 1089 __ ret(3 * kPointerSize); |
1090 | 1090 |
1091 // Do the runtime call to allocate the arguments object. | 1091 // Do the runtime call to allocate the arguments object. |
1092 __ bind(&runtime); | 1092 __ bind(&runtime); |
1093 __ TailCallRuntime(Runtime::kHiddenNewStrictArguments, 3, 1); | 1093 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1); |
1094 } | 1094 } |
1095 | 1095 |
1096 | 1096 |
1097 void RegExpExecStub::Generate(MacroAssembler* masm) { | 1097 void RegExpExecStub::Generate(MacroAssembler* masm) { |
1098 // Just jump directly to runtime if native RegExp is not selected at compile | 1098 // Just jump directly to runtime if native RegExp is not selected at compile |
1099 // time or if regexp entry in generated code is turned off runtime switch or | 1099 // time or if regexp entry in generated code is turned off runtime switch or |
1100 // at compilation. | 1100 // at compilation. |
1101 #ifdef V8_INTERPRETED_REGEXP | 1101 #ifdef V8_INTERPRETED_REGEXP |
1102 __ TailCallRuntime(Runtime::kHiddenRegExpExec, 4, 1); | 1102 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); |
1103 #else // V8_INTERPRETED_REGEXP | 1103 #else // V8_INTERPRETED_REGEXP |
1104 | 1104 |
1105 // Stack frame on entry. | 1105 // Stack frame on entry. |
1106 // esp[0]: return address | 1106 // esp[0]: return address |
1107 // esp[4]: last_match_info (expected JSArray) | 1107 // esp[4]: last_match_info (expected JSArray) |
1108 // esp[8]: previous index | 1108 // esp[8]: previous index |
1109 // esp[12]: subject string | 1109 // esp[12]: subject string |
1110 // esp[16]: JSRegExp object | 1110 // esp[16]: JSRegExp object |
1111 | 1111 |
1112 static const int kLastMatchInfoOffset = 1 * kPointerSize; | 1112 static const int kLastMatchInfoOffset = 1 * kPointerSize; |
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1473 edi); | 1473 edi); |
1474 __ jmp(&next_capture); | 1474 __ jmp(&next_capture); |
1475 __ bind(&done); | 1475 __ bind(&done); |
1476 | 1476 |
1477 // Return last match info. | 1477 // Return last match info. |
1478 __ mov(eax, Operand(esp, kLastMatchInfoOffset)); | 1478 __ mov(eax, Operand(esp, kLastMatchInfoOffset)); |
1479 __ ret(4 * kPointerSize); | 1479 __ ret(4 * kPointerSize); |
1480 | 1480 |
1481 // Do the runtime call to execute the regexp. | 1481 // Do the runtime call to execute the regexp. |
1482 __ bind(&runtime); | 1482 __ bind(&runtime); |
1483 __ TailCallRuntime(Runtime::kHiddenRegExpExec, 4, 1); | 1483 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); |
1484 | 1484 |
1485 // Deferred code for string handling. | 1485 // Deferred code for string handling. |
1486 // (7) Not a long external string? If yes, go to (10). | 1486 // (7) Not a long external string? If yes, go to (10). |
1487 __ bind(¬_seq_nor_cons); | 1487 __ bind(¬_seq_nor_cons); |
1488 // Compare flags are still set from (3). | 1488 // Compare flags are still set from (3). |
1489 __ j(greater, ¬_long_external, Label::kNear); // Go to (10). | 1489 __ j(greater, ¬_long_external, Label::kNear); // Go to (10). |
1490 | 1490 |
1491 // (8) External string. Short external strings have been ruled out. | 1491 // (8) External string. Short external strings have been ruled out. |
1492 __ bind(&external_string); | 1492 __ bind(&external_string); |
1493 // Reload instance type. | 1493 // Reload instance type. |
(...skipping 1279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2773 index_not_number_, | 2773 index_not_number_, |
2774 DONT_DO_SMI_CHECK); | 2774 DONT_DO_SMI_CHECK); |
2775 call_helper.BeforeCall(masm); | 2775 call_helper.BeforeCall(masm); |
2776 __ push(object_); | 2776 __ push(object_); |
2777 __ push(index_); // Consumed by runtime conversion function. | 2777 __ push(index_); // Consumed by runtime conversion function. |
2778 if (index_flags_ == STRING_INDEX_IS_NUMBER) { | 2778 if (index_flags_ == STRING_INDEX_IS_NUMBER) { |
2779 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); | 2779 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); |
2780 } else { | 2780 } else { |
2781 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); | 2781 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); |
2782 // NumberToSmi discards numbers that are not exact integers. | 2782 // NumberToSmi discards numbers that are not exact integers. |
2783 __ CallRuntime(Runtime::kHiddenNumberToSmi, 1); | 2783 __ CallRuntime(Runtime::kNumberToSmi, 1); |
2784 } | 2784 } |
2785 if (!index_.is(eax)) { | 2785 if (!index_.is(eax)) { |
2786 // Save the conversion result before the pop instructions below | 2786 // Save the conversion result before the pop instructions below |
2787 // have a chance to overwrite it. | 2787 // have a chance to overwrite it. |
2788 __ mov(index_, eax); | 2788 __ mov(index_, eax); |
2789 } | 2789 } |
2790 __ pop(object_); | 2790 __ pop(object_); |
2791 // Reload the instance type. | 2791 // Reload the instance type. |
2792 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); | 2792 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); |
2793 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); | 2793 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); |
2794 call_helper.AfterCall(masm); | 2794 call_helper.AfterCall(masm); |
2795 // If index is still not a smi, it must be out of range. | 2795 // If index is still not a smi, it must be out of range. |
2796 STATIC_ASSERT(kSmiTag == 0); | 2796 STATIC_ASSERT(kSmiTag == 0); |
2797 __ JumpIfNotSmi(index_, index_out_of_range_); | 2797 __ JumpIfNotSmi(index_, index_out_of_range_); |
2798 // Otherwise, return to the fast path. | 2798 // Otherwise, return to the fast path. |
2799 __ jmp(&got_smi_index_); | 2799 __ jmp(&got_smi_index_); |
2800 | 2800 |
2801 // Call runtime. We get here when the receiver is a string and the | 2801 // Call runtime. We get here when the receiver is a string and the |
2802 // index is a number, but the code of getting the actual character | 2802 // index is a number, but the code of getting the actual character |
2803 // is too complex (e.g., when the string needs to be flattened). | 2803 // is too complex (e.g., when the string needs to be flattened). |
2804 __ bind(&call_runtime_); | 2804 __ bind(&call_runtime_); |
2805 call_helper.BeforeCall(masm); | 2805 call_helper.BeforeCall(masm); |
2806 __ push(object_); | 2806 __ push(object_); |
2807 __ SmiTag(index_); | 2807 __ SmiTag(index_); |
2808 __ push(index_); | 2808 __ push(index_); |
2809 __ CallRuntime(Runtime::kHiddenStringCharCodeAt, 2); | 2809 __ CallRuntime(Runtime::kStringCharCodeAt, 2); |
2810 if (!result_.is(eax)) { | 2810 if (!result_.is(eax)) { |
2811 __ mov(result_, eax); | 2811 __ mov(result_, eax); |
2812 } | 2812 } |
2813 call_helper.AfterCall(masm); | 2813 call_helper.AfterCall(masm); |
2814 __ jmp(&exit_); | 2814 __ jmp(&exit_); |
2815 | 2815 |
2816 __ Abort(kUnexpectedFallthroughFromCharCodeAtSlowCase); | 2816 __ Abort(kUnexpectedFallthroughFromCharCodeAtSlowCase); |
2817 } | 2817 } |
2818 | 2818 |
2819 | 2819 |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3164 masm, edi, edx, ecx, ebx, String::TWO_BYTE_ENCODING); | 3164 masm, edi, edx, ecx, ebx, String::TWO_BYTE_ENCODING); |
3165 __ IncrementCounter(counters->sub_string_native(), 1); | 3165 __ IncrementCounter(counters->sub_string_native(), 1); |
3166 __ ret(3 * kPointerSize); | 3166 __ ret(3 * kPointerSize); |
3167 | 3167 |
3168 // Drop pushed values on the stack before tail call. | 3168 // Drop pushed values on the stack before tail call. |
3169 __ bind(&runtime_drop_two); | 3169 __ bind(&runtime_drop_two); |
3170 __ Drop(2); | 3170 __ Drop(2); |
3171 | 3171 |
3172 // Just jump to runtime to create the sub string. | 3172 // Just jump to runtime to create the sub string. |
3173 __ bind(&runtime); | 3173 __ bind(&runtime); |
3174 __ TailCallRuntime(Runtime::kHiddenSubString, 3, 1); | 3174 __ TailCallRuntime(Runtime::kSubString, 3, 1); |
3175 | 3175 |
3176 __ bind(&single_char); | 3176 __ bind(&single_char); |
3177 // eax: string | 3177 // eax: string |
3178 // ebx: instance type | 3178 // ebx: instance type |
3179 // ecx: sub string length (smi) | 3179 // ecx: sub string length (smi) |
3180 // edx: from index (smi) | 3180 // edx: from index (smi) |
3181 StringCharAtGenerator generator( | 3181 StringCharAtGenerator generator( |
3182 eax, edx, ecx, eax, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); | 3182 eax, edx, ecx, eax, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); |
3183 generator.GenerateFast(masm); | 3183 generator.GenerateFast(masm); |
3184 __ ret(3 * kPointerSize); | 3184 __ ret(3 * kPointerSize); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3346 // Compare flat ASCII strings. | 3346 // Compare flat ASCII strings. |
3347 // Drop arguments from the stack. | 3347 // Drop arguments from the stack. |
3348 __ pop(ecx); | 3348 __ pop(ecx); |
3349 __ add(esp, Immediate(2 * kPointerSize)); | 3349 __ add(esp, Immediate(2 * kPointerSize)); |
3350 __ push(ecx); | 3350 __ push(ecx); |
3351 GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, edi); | 3351 GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, edi); |
3352 | 3352 |
3353 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 3353 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
3354 // tagged as a small integer. | 3354 // tagged as a small integer. |
3355 __ bind(&runtime); | 3355 __ bind(&runtime); |
3356 __ TailCallRuntime(Runtime::kHiddenStringCompare, 2, 1); | 3356 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
3357 } | 3357 } |
3358 | 3358 |
3359 | 3359 |
3360 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { | 3360 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { |
3361 // ----------- S t a t e ------------- | 3361 // ----------- S t a t e ------------- |
3362 // -- edx : left | 3362 // -- edx : left |
3363 // -- eax : right | 3363 // -- eax : right |
3364 // -- esp[0] : return address | 3364 // -- esp[0] : return address |
3365 // ----------------------------------- | 3365 // ----------------------------------- |
3366 | 3366 |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3630 | 3630 |
3631 // Handle more complex cases in runtime. | 3631 // Handle more complex cases in runtime. |
3632 __ bind(&runtime); | 3632 __ bind(&runtime); |
3633 __ pop(tmp1); // Return address. | 3633 __ pop(tmp1); // Return address. |
3634 __ push(left); | 3634 __ push(left); |
3635 __ push(right); | 3635 __ push(right); |
3636 __ push(tmp1); | 3636 __ push(tmp1); |
3637 if (equality) { | 3637 if (equality) { |
3638 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); | 3638 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); |
3639 } else { | 3639 } else { |
3640 __ TailCallRuntime(Runtime::kHiddenStringCompare, 2, 1); | 3640 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
3641 } | 3641 } |
3642 | 3642 |
3643 __ bind(&miss); | 3643 __ bind(&miss); |
3644 GenerateMiss(masm); | 3644 GenerateMiss(masm); |
3645 } | 3645 } |
3646 | 3646 |
3647 | 3647 |
3648 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { | 3648 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { |
3649 ASSERT(state_ == CompareIC::OBJECT); | 3649 ASSERT(state_ == CompareIC::OBJECT); |
3650 Label miss; | 3650 Label miss; |
(...skipping 1073 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4724 Operand(ebp, 7 * kPointerSize), | 4724 Operand(ebp, 7 * kPointerSize), |
4725 NULL); | 4725 NULL); |
4726 } | 4726 } |
4727 | 4727 |
4728 | 4728 |
4729 #undef __ | 4729 #undef __ |
4730 | 4730 |
4731 } } // namespace v8::internal | 4731 } } // namespace v8::internal |
4732 | 4732 |
4733 #endif // V8_TARGET_ARCH_X87 | 4733 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |