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