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