OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 // Restore the arguments count and leave the construct frame. | 369 // Restore the arguments count and leave the construct frame. |
370 __ bind(&exit); | 370 __ bind(&exit); |
371 __ mov(ebx, Operand(esp, kPointerSize)); // get arguments count | 371 __ mov(ebx, Operand(esp, kPointerSize)); // get arguments count |
372 __ LeaveConstructFrame(); | 372 __ LeaveConstructFrame(); |
373 | 373 |
374 // Remove caller arguments from the stack and return. | 374 // Remove caller arguments from the stack and return. |
375 ASSERT(kSmiTagSize == 1 && kSmiTag == 0); | 375 ASSERT(kSmiTagSize == 1 && kSmiTag == 0); |
376 __ pop(ecx); | 376 __ pop(ecx); |
377 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver | 377 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver |
378 __ push(ecx); | 378 __ push(ecx); |
379 __ IncrementCounter(COUNTERS->constructed_objects(), 1); | 379 __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1); |
380 __ ret(0); | 380 __ ret(0); |
381 } | 381 } |
382 | 382 |
383 | 383 |
384 void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) { | 384 void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) { |
385 Generate_JSConstructStubHelper(masm, false, true); | 385 Generate_JSConstructStubHelper(masm, false, true); |
386 } | 386 } |
387 | 387 |
388 | 388 |
389 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { | 389 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { |
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1058 __ bind(&empty_array); | 1058 __ bind(&empty_array); |
1059 // Handle construction of an empty array. | 1059 // Handle construction of an empty array. |
1060 AllocateEmptyJSArray(masm, | 1060 AllocateEmptyJSArray(masm, |
1061 edi, | 1061 edi, |
1062 eax, | 1062 eax, |
1063 ebx, | 1063 ebx, |
1064 ecx, | 1064 ecx, |
1065 edi, | 1065 edi, |
1066 kPreallocatedArrayElements, | 1066 kPreallocatedArrayElements, |
1067 &prepare_generic_code_call); | 1067 &prepare_generic_code_call); |
1068 __ IncrementCounter(COUNTERS->array_function_native(), 1); | 1068 __ IncrementCounter(masm->isolate()->counters()->array_function_native(), 1); |
1069 __ pop(ebx); | 1069 __ pop(ebx); |
1070 if (construct_call) { | 1070 if (construct_call) { |
1071 __ pop(edi); | 1071 __ pop(edi); |
1072 } | 1072 } |
1073 __ ret(kPointerSize); | 1073 __ ret(kPointerSize); |
1074 | 1074 |
1075 // Check for one argument. Bail out if argument is not smi or if it is | 1075 // Check for one argument. Bail out if argument is not smi or if it is |
1076 // negative. | 1076 // negative. |
1077 __ bind(&argc_one_or_more); | 1077 __ bind(&argc_one_or_more); |
1078 __ cmp(eax, 1); | 1078 __ cmp(eax, 1); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1114 // esp[C]: argument | 1114 // esp[C]: argument |
1115 AllocateJSArray(masm, | 1115 AllocateJSArray(masm, |
1116 edi, | 1116 edi, |
1117 ecx, | 1117 ecx, |
1118 ebx, | 1118 ebx, |
1119 eax, | 1119 eax, |
1120 edx, | 1120 edx, |
1121 edi, | 1121 edi, |
1122 true, | 1122 true, |
1123 &prepare_generic_code_call); | 1123 &prepare_generic_code_call); |
1124 __ IncrementCounter(COUNTERS->array_function_native(), 1); | 1124 Counters* counters = masm->isolate()->counters(); |
| 1125 __ IncrementCounter(counters->array_function_native(), 1); |
1125 __ mov(eax, ebx); | 1126 __ mov(eax, ebx); |
1126 __ pop(ebx); | 1127 __ pop(ebx); |
1127 if (construct_call) { | 1128 if (construct_call) { |
1128 __ pop(edi); | 1129 __ pop(edi); |
1129 } | 1130 } |
1130 __ ret(2 * kPointerSize); | 1131 __ ret(2 * kPointerSize); |
1131 | 1132 |
1132 // Handle construction of an array from a list of arguments. | 1133 // Handle construction of an array from a list of arguments. |
1133 __ bind(&argc_two_or_more); | 1134 __ bind(&argc_two_or_more); |
1134 ASSERT(kSmiTag == 0); | 1135 ASSERT(kSmiTag == 0); |
1135 __ SmiTag(eax); // Convet argc to a smi. | 1136 __ SmiTag(eax); // Convet argc to a smi. |
1136 // eax: array_size (smi) | 1137 // eax: array_size (smi) |
1137 // edi: constructor | 1138 // edi: constructor |
1138 // esp[0] : argc | 1139 // esp[0] : argc |
1139 // esp[4]: constructor (only if construct_call) | 1140 // esp[4]: constructor (only if construct_call) |
1140 // esp[8] : return address | 1141 // esp[8] : return address |
1141 // esp[C] : last argument | 1142 // esp[C] : last argument |
1142 AllocateJSArray(masm, | 1143 AllocateJSArray(masm, |
1143 edi, | 1144 edi, |
1144 eax, | 1145 eax, |
1145 ebx, | 1146 ebx, |
1146 ecx, | 1147 ecx, |
1147 edx, | 1148 edx, |
1148 edi, | 1149 edi, |
1149 false, | 1150 false, |
1150 &prepare_generic_code_call); | 1151 &prepare_generic_code_call); |
1151 __ IncrementCounter(COUNTERS->array_function_native(), 1); | 1152 __ IncrementCounter(counters->array_function_native(), 1); |
1152 __ mov(eax, ebx); | 1153 __ mov(eax, ebx); |
1153 __ pop(ebx); | 1154 __ pop(ebx); |
1154 if (construct_call) { | 1155 if (construct_call) { |
1155 __ pop(edi); | 1156 __ pop(edi); |
1156 } | 1157 } |
1157 __ push(eax); | 1158 __ push(eax); |
1158 // eax: JSArray | 1159 // eax: JSArray |
1159 // ebx: argc | 1160 // ebx: argc |
1160 // edx: elements_array_end (untagged) | 1161 // edx: elements_array_end (untagged) |
1161 // esp[0]: JSArray | 1162 // esp[0]: JSArray |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1276 | 1277 |
1277 | 1278 |
1278 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { | 1279 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { |
1279 // ----------- S t a t e ------------- | 1280 // ----------- S t a t e ------------- |
1280 // -- eax : number of arguments | 1281 // -- eax : number of arguments |
1281 // -- edi : constructor function | 1282 // -- edi : constructor function |
1282 // -- esp[0] : return address | 1283 // -- esp[0] : return address |
1283 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1284 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1284 // -- esp[(argc + 1) * 4] : receiver | 1285 // -- esp[(argc + 1) * 4] : receiver |
1285 // ----------------------------------- | 1286 // ----------------------------------- |
1286 __ IncrementCounter(COUNTERS->string_ctor_calls(), 1); | 1287 Counters* counters = masm->isolate()->counters(); |
| 1288 __ IncrementCounter(counters->string_ctor_calls(), 1); |
1287 | 1289 |
1288 if (FLAG_debug_code) { | 1290 if (FLAG_debug_code) { |
1289 __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, ecx); | 1291 __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, ecx); |
1290 __ cmp(edi, Operand(ecx)); | 1292 __ cmp(edi, Operand(ecx)); |
1291 __ Assert(equal, "Unexpected String function"); | 1293 __ Assert(equal, "Unexpected String function"); |
1292 } | 1294 } |
1293 | 1295 |
1294 // Load the first argument into eax and get rid of the rest | 1296 // Load the first argument into eax and get rid of the rest |
1295 // (including the receiver). | 1297 // (including the receiver). |
1296 Label no_arguments; | 1298 Label no_arguments; |
1297 __ test(eax, Operand(eax)); | 1299 __ test(eax, Operand(eax)); |
1298 __ j(zero, &no_arguments); | 1300 __ j(zero, &no_arguments); |
1299 __ mov(ebx, Operand(esp, eax, times_pointer_size, 0)); | 1301 __ mov(ebx, Operand(esp, eax, times_pointer_size, 0)); |
1300 __ pop(ecx); | 1302 __ pop(ecx); |
1301 __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize)); | 1303 __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize)); |
1302 __ push(ecx); | 1304 __ push(ecx); |
1303 __ mov(eax, ebx); | 1305 __ mov(eax, ebx); |
1304 | 1306 |
1305 // Lookup the argument in the number to string cache. | 1307 // Lookup the argument in the number to string cache. |
1306 Label not_cached, argument_is_string; | 1308 Label not_cached, argument_is_string; |
1307 NumberToStringStub::GenerateLookupNumberStringCache( | 1309 NumberToStringStub::GenerateLookupNumberStringCache( |
1308 masm, | 1310 masm, |
1309 eax, // Input. | 1311 eax, // Input. |
1310 ebx, // Result. | 1312 ebx, // Result. |
1311 ecx, // Scratch 1. | 1313 ecx, // Scratch 1. |
1312 edx, // Scratch 2. | 1314 edx, // Scratch 2. |
1313 false, // Input is known to be smi? | 1315 false, // Input is known to be smi? |
1314 ¬_cached); | 1316 ¬_cached); |
1315 __ IncrementCounter(COUNTERS->string_ctor_cached_number(), 1); | 1317 __ IncrementCounter(counters->string_ctor_cached_number(), 1); |
1316 __ bind(&argument_is_string); | 1318 __ bind(&argument_is_string); |
1317 // ----------- S t a t e ------------- | 1319 // ----------- S t a t e ------------- |
1318 // -- ebx : argument converted to string | 1320 // -- ebx : argument converted to string |
1319 // -- edi : constructor function | 1321 // -- edi : constructor function |
1320 // -- esp[0] : return address | 1322 // -- esp[0] : return address |
1321 // ----------------------------------- | 1323 // ----------------------------------- |
1322 | 1324 |
1323 // Allocate a JSValue and put the tagged pointer into eax. | 1325 // Allocate a JSValue and put the tagged pointer into eax. |
1324 Label gc_required; | 1326 Label gc_required; |
1325 __ AllocateInNewSpace(JSValue::kSize, | 1327 __ AllocateInNewSpace(JSValue::kSize, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1357 // The argument was not found in the number to string cache. Check | 1359 // The argument was not found in the number to string cache. Check |
1358 // if it's a string already before calling the conversion builtin. | 1360 // if it's a string already before calling the conversion builtin. |
1359 Label convert_argument; | 1361 Label convert_argument; |
1360 __ bind(¬_cached); | 1362 __ bind(¬_cached); |
1361 STATIC_ASSERT(kSmiTag == 0); | 1363 STATIC_ASSERT(kSmiTag == 0); |
1362 __ test(eax, Immediate(kSmiTagMask)); | 1364 __ test(eax, Immediate(kSmiTagMask)); |
1363 __ j(zero, &convert_argument); | 1365 __ j(zero, &convert_argument); |
1364 Condition is_string = masm->IsObjectStringType(eax, ebx, ecx); | 1366 Condition is_string = masm->IsObjectStringType(eax, ebx, ecx); |
1365 __ j(NegateCondition(is_string), &convert_argument); | 1367 __ j(NegateCondition(is_string), &convert_argument); |
1366 __ mov(ebx, eax); | 1368 __ mov(ebx, eax); |
1367 __ IncrementCounter(COUNTERS->string_ctor_string_value(), 1); | 1369 __ IncrementCounter(counters->string_ctor_string_value(), 1); |
1368 __ jmp(&argument_is_string); | 1370 __ jmp(&argument_is_string); |
1369 | 1371 |
1370 // Invoke the conversion builtin and put the result into ebx. | 1372 // Invoke the conversion builtin and put the result into ebx. |
1371 __ bind(&convert_argument); | 1373 __ bind(&convert_argument); |
1372 __ IncrementCounter(COUNTERS->string_ctor_conversions(), 1); | 1374 __ IncrementCounter(counters->string_ctor_conversions(), 1); |
1373 __ EnterInternalFrame(); | 1375 __ EnterInternalFrame(); |
1374 __ push(edi); // Preserve the function. | 1376 __ push(edi); // Preserve the function. |
1375 __ push(eax); | 1377 __ push(eax); |
1376 __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION); | 1378 __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION); |
1377 __ pop(edi); | 1379 __ pop(edi); |
1378 __ LeaveInternalFrame(); | 1380 __ LeaveInternalFrame(); |
1379 __ mov(ebx, eax); | 1381 __ mov(ebx, eax); |
1380 __ jmp(&argument_is_string); | 1382 __ jmp(&argument_is_string); |
1381 | 1383 |
1382 // Load the empty string into ebx, remove the receiver from the | 1384 // Load the empty string into ebx, remove the receiver from the |
1383 // stack, and jump back to the case where the argument is a string. | 1385 // stack, and jump back to the case where the argument is a string. |
1384 __ bind(&no_arguments); | 1386 __ bind(&no_arguments); |
1385 __ Set(ebx, Immediate(FACTORY->empty_string())); | 1387 __ Set(ebx, Immediate(FACTORY->empty_string())); |
1386 __ pop(ecx); | 1388 __ pop(ecx); |
1387 __ lea(esp, Operand(esp, kPointerSize)); | 1389 __ lea(esp, Operand(esp, kPointerSize)); |
1388 __ push(ecx); | 1390 __ push(ecx); |
1389 __ jmp(&argument_is_string); | 1391 __ jmp(&argument_is_string); |
1390 | 1392 |
1391 // At this point the argument is already a string. Call runtime to | 1393 // At this point the argument is already a string. Call runtime to |
1392 // create a string wrapper. | 1394 // create a string wrapper. |
1393 __ bind(&gc_required); | 1395 __ bind(&gc_required); |
1394 __ IncrementCounter(COUNTERS->string_ctor_gc_required(), 1); | 1396 __ IncrementCounter(counters->string_ctor_gc_required(), 1); |
1395 __ EnterInternalFrame(); | 1397 __ EnterInternalFrame(); |
1396 __ push(ebx); | 1398 __ push(ebx); |
1397 __ CallRuntime(Runtime::kNewStringWrapper, 1); | 1399 __ CallRuntime(Runtime::kNewStringWrapper, 1); |
1398 __ LeaveInternalFrame(); | 1400 __ LeaveInternalFrame(); |
1399 __ ret(0); | 1401 __ ret(0); |
1400 } | 1402 } |
1401 | 1403 |
1402 | 1404 |
1403 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { | 1405 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { |
1404 __ push(ebp); | 1406 __ push(ebp); |
(...skipping 30 matching lines...) Expand all Loading... |
1435 | 1437 |
1436 | 1438 |
1437 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { | 1439 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
1438 // ----------- S t a t e ------------- | 1440 // ----------- S t a t e ------------- |
1439 // -- eax : actual number of arguments | 1441 // -- eax : actual number of arguments |
1440 // -- ebx : expected number of arguments | 1442 // -- ebx : expected number of arguments |
1441 // -- edx : code entry to call | 1443 // -- edx : code entry to call |
1442 // ----------------------------------- | 1444 // ----------------------------------- |
1443 | 1445 |
1444 Label invoke, dont_adapt_arguments; | 1446 Label invoke, dont_adapt_arguments; |
1445 __ IncrementCounter(COUNTERS->arguments_adaptors(), 1); | 1447 __ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1); |
1446 | 1448 |
1447 Label enough, too_few; | 1449 Label enough, too_few; |
1448 __ cmp(eax, Operand(ebx)); | 1450 __ cmp(eax, Operand(ebx)); |
1449 __ j(less, &too_few); | 1451 __ j(less, &too_few); |
1450 __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel); | 1452 __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel); |
1451 __ j(equal, &dont_adapt_arguments); | 1453 __ j(equal, &dont_adapt_arguments); |
1452 | 1454 |
1453 { // Enough parameters: Actual >= expected. | 1455 { // Enough parameters: Actual >= expected. |
1454 __ bind(&enough); | 1456 __ bind(&enough); |
1455 EnterArgumentsAdaptorFrame(masm); | 1457 EnterArgumentsAdaptorFrame(masm); |
(...skipping 27 matching lines...) Expand all Loading... |
1483 __ inc(ecx); | 1485 __ inc(ecx); |
1484 __ push(Operand(edi, 0)); | 1486 __ push(Operand(edi, 0)); |
1485 __ sub(Operand(edi), Immediate(kPointerSize)); | 1487 __ sub(Operand(edi), Immediate(kPointerSize)); |
1486 __ cmp(ecx, Operand(eax)); | 1488 __ cmp(ecx, Operand(eax)); |
1487 __ j(less, ©); | 1489 __ j(less, ©); |
1488 | 1490 |
1489 // Fill remaining expected arguments with undefined values. | 1491 // Fill remaining expected arguments with undefined values. |
1490 Label fill; | 1492 Label fill; |
1491 __ bind(&fill); | 1493 __ bind(&fill); |
1492 __ inc(ecx); | 1494 __ inc(ecx); |
1493 __ push(Immediate(FACTORY->undefined_value())); | 1495 __ push(Immediate(masm->isolate()->factory()->undefined_value())); |
1494 __ cmp(ecx, Operand(ebx)); | 1496 __ cmp(ecx, Operand(ebx)); |
1495 __ j(less, &fill); | 1497 __ j(less, &fill); |
1496 | 1498 |
1497 // Restore function pointer. | 1499 // Restore function pointer. |
1498 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1500 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
1499 } | 1501 } |
1500 | 1502 |
1501 // Call the entry point. | 1503 // Call the entry point. |
1502 __ bind(&invoke); | 1504 __ bind(&invoke); |
1503 __ call(Operand(edx)); | 1505 __ call(Operand(edx)); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1583 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); | 1585 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); |
1584 generator.Generate(); | 1586 generator.Generate(); |
1585 } | 1587 } |
1586 | 1588 |
1587 | 1589 |
1588 #undef __ | 1590 #undef __ |
1589 | 1591 |
1590 } } // namespace v8::internal | 1592 } } // namespace v8::internal |
1591 | 1593 |
1592 #endif // V8_TARGET_ARCH_IA32 | 1594 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |