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