| 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 |