OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 1011 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1022 __ LeaveInternalFrame(); | 1022 __ LeaveInternalFrame(); |
1023 | 1023 |
1024 // Do a tail-call of the compiled function. | 1024 // Do a tail-call of the compiled function. |
1025 __ lea(ecx, FieldOperand(eax, Code::kHeaderSize)); | 1025 __ lea(ecx, FieldOperand(eax, Code::kHeaderSize)); |
1026 __ jmp(Operand(ecx)); | 1026 __ jmp(Operand(ecx)); |
1027 | 1027 |
1028 return GetCodeWithFlags(flags, "LazyCompileStub"); | 1028 return GetCodeWithFlags(flags, "LazyCompileStub"); |
1029 } | 1029 } |
1030 | 1030 |
1031 | 1031 |
| 1032 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { |
| 1033 if (kind_ == Code::KEYED_CALL_IC) { |
| 1034 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); |
| 1035 __ j(not_equal, miss, not_taken); |
| 1036 } |
| 1037 } |
| 1038 |
| 1039 |
| 1040 void CallStubCompiler::GenerateMissBranch() { |
| 1041 Handle<Code> ic = ComputeCallMiss(arguments().immediate(), kind_); |
| 1042 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 1043 } |
| 1044 |
| 1045 |
1032 Object* CallStubCompiler::CompileCallField(JSObject* object, | 1046 Object* CallStubCompiler::CompileCallField(JSObject* object, |
1033 JSObject* holder, | 1047 JSObject* holder, |
1034 int index, | 1048 int index, |
1035 String* name) { | 1049 String* name) { |
1036 // ----------- S t a t e ------------- | 1050 // ----------- S t a t e ------------- |
1037 // -- ecx : name | 1051 // -- ecx : name |
1038 // -- esp[0] : return address | 1052 // -- esp[0] : return address |
1039 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1053 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1040 // -- ... | 1054 // -- ... |
1041 // -- esp[(argc + 1) * 4] : receiver | 1055 // -- esp[(argc + 1) * 4] : receiver |
1042 // ----------------------------------- | 1056 // ----------------------------------- |
1043 Label miss; | 1057 Label miss; |
1044 | 1058 |
| 1059 GenerateNameCheck(name, &miss); |
| 1060 |
1045 // Get the receiver from the stack. | 1061 // Get the receiver from the stack. |
1046 const int argc = arguments().immediate(); | 1062 const int argc = arguments().immediate(); |
1047 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1063 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
1048 | 1064 |
1049 // Check that the receiver isn't a smi. | 1065 // Check that the receiver isn't a smi. |
1050 __ test(edx, Immediate(kSmiTagMask)); | 1066 __ test(edx, Immediate(kSmiTagMask)); |
1051 __ j(zero, &miss, not_taken); | 1067 __ j(zero, &miss, not_taken); |
1052 | 1068 |
1053 // Do the right check and compute the holder register. | 1069 // Do the right check and compute the holder register. |
1054 Register reg = CheckPrototypes(object, edx, holder, ebx, eax, name, &miss); | 1070 Register reg = CheckPrototypes(object, edx, holder, ebx, eax, name, &miss); |
(...skipping 11 matching lines...) Expand all Loading... |
1066 if (object->IsGlobalObject()) { | 1082 if (object->IsGlobalObject()) { |
1067 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 1083 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
1068 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 1084 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
1069 } | 1085 } |
1070 | 1086 |
1071 // Invoke the function. | 1087 // Invoke the function. |
1072 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION); | 1088 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION); |
1073 | 1089 |
1074 // Handle call cache miss. | 1090 // Handle call cache miss. |
1075 __ bind(&miss); | 1091 __ bind(&miss); |
1076 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); | 1092 GenerateMissBranch(); |
1077 __ jmp(ic, RelocInfo::CODE_TARGET); | |
1078 | 1093 |
1079 // Return the generated code. | 1094 // Return the generated code. |
1080 return GetCode(FIELD, name); | 1095 return GetCode(FIELD, name); |
1081 } | 1096 } |
1082 | 1097 |
1083 | 1098 |
1084 Object* CallStubCompiler::CompileArrayPushCall(Object* object, | 1099 Object* CallStubCompiler::CompileArrayPushCall(Object* object, |
1085 JSObject* holder, | 1100 JSObject* holder, |
1086 JSFunction* function, | 1101 JSFunction* function, |
1087 String* name, | 1102 String* name, |
1088 CheckType check) { | 1103 CheckType check) { |
1089 // ----------- S t a t e ------------- | 1104 // ----------- S t a t e ------------- |
1090 // -- ecx : name | 1105 // -- ecx : name |
1091 // -- esp[0] : return address | 1106 // -- esp[0] : return address |
1092 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1107 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1093 // -- ... | 1108 // -- ... |
1094 // -- esp[(argc + 1) * 4] : receiver | 1109 // -- esp[(argc + 1) * 4] : receiver |
1095 // ----------------------------------- | 1110 // ----------------------------------- |
1096 ASSERT(check == RECEIVER_MAP_CHECK); | 1111 ASSERT(check == RECEIVER_MAP_CHECK); |
1097 | 1112 |
1098 // If object is not an array, bail out to regular call. | 1113 // If object is not an array, bail out to regular call. |
1099 if (!object->IsJSArray()) { | 1114 if (!object->IsJSArray()) { |
1100 return Heap::undefined_value(); | 1115 return Heap::undefined_value(); |
1101 } | 1116 } |
1102 | 1117 |
1103 Label miss; | 1118 Label miss; |
1104 | 1119 |
| 1120 GenerateNameCheck(name, &miss); |
| 1121 |
1105 // Get the receiver from the stack. | 1122 // Get the receiver from the stack. |
1106 const int argc = arguments().immediate(); | 1123 const int argc = arguments().immediate(); |
1107 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1124 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
1108 | 1125 |
1109 // Check that the receiver isn't a smi. | 1126 // Check that the receiver isn't a smi. |
1110 __ test(edx, Immediate(kSmiTagMask)); | 1127 __ test(edx, Immediate(kSmiTagMask)); |
1111 __ j(zero, &miss); | 1128 __ j(zero, &miss); |
1112 | 1129 |
1113 CheckPrototypes(JSObject::cast(object), edx, | 1130 CheckPrototypes(JSObject::cast(object), edx, |
1114 holder, ebx, | 1131 holder, ebx, |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1212 | 1229 |
1213 __ bind(&call_builtin); | 1230 __ bind(&call_builtin); |
1214 } | 1231 } |
1215 | 1232 |
1216 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush), | 1233 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush), |
1217 argc + 1, | 1234 argc + 1, |
1218 1); | 1235 1); |
1219 } | 1236 } |
1220 | 1237 |
1221 __ bind(&miss); | 1238 __ bind(&miss); |
1222 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); | 1239 GenerateMissBranch(); |
1223 __ jmp(ic, RelocInfo::CODE_TARGET); | |
1224 | 1240 |
1225 // Return the generated code. | 1241 // Return the generated code. |
1226 return GetCode(function); | 1242 return GetCode(function); |
1227 } | 1243 } |
1228 | 1244 |
1229 | 1245 |
1230 Object* CallStubCompiler::CompileArrayPopCall(Object* object, | 1246 Object* CallStubCompiler::CompileArrayPopCall(Object* object, |
1231 JSObject* holder, | 1247 JSObject* holder, |
1232 JSFunction* function, | 1248 JSFunction* function, |
1233 String* name, | 1249 String* name, |
1234 CheckType check) { | 1250 CheckType check) { |
1235 // ----------- S t a t e ------------- | 1251 // ----------- S t a t e ------------- |
1236 // -- ecx : name | 1252 // -- ecx : name |
1237 // -- esp[0] : return address | 1253 // -- esp[0] : return address |
1238 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1254 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1239 // -- ... | 1255 // -- ... |
1240 // -- esp[(argc + 1) * 4] : receiver | 1256 // -- esp[(argc + 1) * 4] : receiver |
1241 // ----------------------------------- | 1257 // ----------------------------------- |
1242 ASSERT(check == RECEIVER_MAP_CHECK); | 1258 ASSERT(check == RECEIVER_MAP_CHECK); |
1243 | 1259 |
1244 // If object is not an array, bail out to regular call. | 1260 // If object is not an array, bail out to regular call. |
1245 if (!object->IsJSArray()) { | 1261 if (!object->IsJSArray()) { |
1246 return Heap::undefined_value(); | 1262 return Heap::undefined_value(); |
1247 } | 1263 } |
1248 | 1264 |
1249 Label miss, return_undefined, call_builtin; | 1265 Label miss, return_undefined, call_builtin; |
1250 | 1266 |
| 1267 GenerateNameCheck(name, &miss); |
| 1268 |
1251 // Get the receiver from the stack. | 1269 // Get the receiver from the stack. |
1252 const int argc = arguments().immediate(); | 1270 const int argc = arguments().immediate(); |
1253 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1271 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
1254 | 1272 |
1255 // Check that the receiver isn't a smi. | 1273 // Check that the receiver isn't a smi. |
1256 __ test(edx, Immediate(kSmiTagMask)); | 1274 __ test(edx, Immediate(kSmiTagMask)); |
1257 __ j(zero, &miss); | 1275 __ j(zero, &miss); |
1258 CheckPrototypes(JSObject::cast(object), edx, | 1276 CheckPrototypes(JSObject::cast(object), edx, |
1259 holder, ebx, | 1277 holder, ebx, |
1260 eax, name, &miss); | 1278 eax, name, &miss); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1294 __ bind(&return_undefined); | 1312 __ bind(&return_undefined); |
1295 __ mov(eax, Immediate(Factory::undefined_value())); | 1313 __ mov(eax, Immediate(Factory::undefined_value())); |
1296 __ ret((argc + 1) * kPointerSize); | 1314 __ ret((argc + 1) * kPointerSize); |
1297 | 1315 |
1298 __ bind(&call_builtin); | 1316 __ bind(&call_builtin); |
1299 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop), | 1317 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop), |
1300 argc + 1, | 1318 argc + 1, |
1301 1); | 1319 1); |
1302 | 1320 |
1303 __ bind(&miss); | 1321 __ bind(&miss); |
1304 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); | 1322 GenerateMissBranch(); |
1305 __ jmp(ic, RelocInfo::CODE_TARGET); | |
1306 | 1323 |
1307 // Return the generated code. | 1324 // Return the generated code. |
1308 return GetCode(function); | 1325 return GetCode(function); |
1309 } | 1326 } |
1310 | 1327 |
1311 | 1328 |
1312 Object* CallStubCompiler::CompileStringCharCodeAtCall(Object* object, | 1329 Object* CallStubCompiler::CompileStringCharCodeAtCall(Object* object, |
1313 JSObject* holder, | 1330 JSObject* holder, |
1314 JSFunction* function, | 1331 JSFunction* function, |
1315 String* name, | 1332 String* name, |
1316 CheckType check) { | 1333 CheckType check) { |
1317 // ----------- S t a t e ------------- | 1334 // ----------- S t a t e ------------- |
1318 // -- ecx : function name | 1335 // -- ecx : function name |
1319 // -- esp[0] : return address | 1336 // -- esp[0] : return address |
1320 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1337 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1321 // -- ... | 1338 // -- ... |
1322 // -- esp[(argc + 1) * 4] : receiver | 1339 // -- esp[(argc + 1) * 4] : receiver |
1323 // ----------------------------------- | 1340 // ----------------------------------- |
1324 | 1341 |
1325 const int argc = arguments().immediate(); | 1342 const int argc = arguments().immediate(); |
1326 | 1343 |
1327 Label miss; | 1344 Label miss; |
1328 Label index_out_of_range; | 1345 Label index_out_of_range; |
| 1346 GenerateNameCheck(name, &miss); |
1329 | 1347 |
1330 // Check that the maps starting from the prototype haven't changed. | 1348 // Check that the maps starting from the prototype haven't changed. |
1331 GenerateLoadGlobalFunctionPrototype(masm(), | 1349 GenerateLoadGlobalFunctionPrototype(masm(), |
1332 Context::STRING_FUNCTION_INDEX, | 1350 Context::STRING_FUNCTION_INDEX, |
1333 eax); | 1351 eax); |
1334 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, | 1352 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, |
1335 ebx, edx, name, &miss); | 1353 ebx, edx, name, &miss); |
1336 | 1354 |
1337 Register receiver = ebx; | 1355 Register receiver = ebx; |
1338 Register index = ecx; | 1356 Register index = edi; |
1339 Register scratch = edx; | 1357 Register scratch = edx; |
1340 Register result = eax; | 1358 Register result = eax; |
1341 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); | 1359 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); |
1342 if (argc > 0) { | 1360 if (argc > 0) { |
1343 __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); | 1361 __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); |
1344 } else { | 1362 } else { |
1345 __ Set(index, Immediate(Factory::undefined_value())); | 1363 __ Set(index, Immediate(Factory::undefined_value())); |
1346 } | 1364 } |
1347 | 1365 |
1348 StringCharCodeAtGenerator char_code_at_generator(receiver, | 1366 StringCharCodeAtGenerator char_code_at_generator(receiver, |
1349 index, | 1367 index, |
1350 scratch, | 1368 scratch, |
1351 result, | 1369 result, |
1352 &miss, // When not a string. | 1370 &miss, // When not a string. |
1353 &miss, // When not a number. | 1371 &miss, // When not a number. |
1354 &index_out_of_range, | 1372 &index_out_of_range, |
1355 STRING_INDEX_IS_NUMBER); | 1373 STRING_INDEX_IS_NUMBER); |
1356 char_code_at_generator.GenerateFast(masm()); | 1374 char_code_at_generator.GenerateFast(masm()); |
1357 __ ret((argc + 1) * kPointerSize); | 1375 __ ret((argc + 1) * kPointerSize); |
1358 | 1376 |
1359 ICRuntimeCallHelper call_helper; | 1377 ICRuntimeCallHelper call_helper; |
1360 char_code_at_generator.GenerateSlow(masm(), call_helper); | 1378 char_code_at_generator.GenerateSlow(masm(), call_helper); |
1361 | 1379 |
1362 __ bind(&index_out_of_range); | 1380 __ bind(&index_out_of_range); |
1363 __ Set(eax, Immediate(Factory::nan_value())); | 1381 __ Set(eax, Immediate(Factory::nan_value())); |
1364 __ ret((argc + 1) * kPointerSize); | 1382 __ ret((argc + 1) * kPointerSize); |
1365 | 1383 |
1366 __ bind(&miss); | 1384 __ bind(&miss); |
1367 // Restore function name in ecx. | |
1368 __ Set(ecx, Immediate(Handle<String>(name))); | |
1369 | 1385 |
1370 Handle<Code> ic = ComputeCallMiss(argc); | 1386 GenerateMissBranch(); |
1371 __ jmp(ic, RelocInfo::CODE_TARGET); | |
1372 | 1387 |
1373 // Return the generated code. | 1388 // Return the generated code. |
1374 return GetCode(function); | 1389 return GetCode(function); |
1375 } | 1390 } |
1376 | 1391 |
1377 | 1392 |
1378 Object* CallStubCompiler::CompileStringCharAtCall(Object* object, | 1393 Object* CallStubCompiler::CompileStringCharAtCall(Object* object, |
1379 JSObject* holder, | 1394 JSObject* holder, |
1380 JSFunction* function, | 1395 JSFunction* function, |
1381 String* name, | 1396 String* name, |
1382 CheckType check) { | 1397 CheckType check) { |
1383 // ----------- S t a t e ------------- | 1398 // ----------- S t a t e ------------- |
1384 // -- ecx : function name | 1399 // -- ecx : function name |
1385 // -- esp[0] : return address | 1400 // -- esp[0] : return address |
1386 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1401 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1387 // -- ... | 1402 // -- ... |
1388 // -- esp[(argc + 1) * 4] : receiver | 1403 // -- esp[(argc + 1) * 4] : receiver |
1389 // ----------------------------------- | 1404 // ----------------------------------- |
1390 | 1405 |
1391 const int argc = arguments().immediate(); | 1406 const int argc = arguments().immediate(); |
1392 | 1407 |
1393 Label miss; | 1408 Label miss; |
1394 Label index_out_of_range; | 1409 Label index_out_of_range; |
1395 | 1410 |
| 1411 GenerateNameCheck(name, &miss); |
| 1412 |
1396 // Check that the maps starting from the prototype haven't changed. | 1413 // Check that the maps starting from the prototype haven't changed. |
1397 GenerateLoadGlobalFunctionPrototype(masm(), | 1414 GenerateLoadGlobalFunctionPrototype(masm(), |
1398 Context::STRING_FUNCTION_INDEX, | 1415 Context::STRING_FUNCTION_INDEX, |
1399 eax); | 1416 eax); |
1400 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, | 1417 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, |
1401 ebx, edx, name, &miss); | 1418 ebx, edx, name, &miss); |
1402 | 1419 |
1403 Register receiver = eax; | 1420 Register receiver = eax; |
1404 Register index = ecx; | 1421 Register index = edi; |
1405 Register scratch1 = ebx; | 1422 Register scratch1 = ebx; |
1406 Register scratch2 = edx; | 1423 Register scratch2 = edx; |
1407 Register result = eax; | 1424 Register result = eax; |
1408 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); | 1425 __ mov(receiver, Operand(esp, (argc + 1) * kPointerSize)); |
1409 if (argc > 0) { | 1426 if (argc > 0) { |
1410 __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); | 1427 __ mov(index, Operand(esp, (argc - 0) * kPointerSize)); |
1411 } else { | 1428 } else { |
1412 __ Set(index, Immediate(Factory::undefined_value())); | 1429 __ Set(index, Immediate(Factory::undefined_value())); |
1413 } | 1430 } |
1414 | 1431 |
(...skipping 11 matching lines...) Expand all Loading... |
1426 | 1443 |
1427 ICRuntimeCallHelper call_helper; | 1444 ICRuntimeCallHelper call_helper; |
1428 char_at_generator.GenerateSlow(masm(), call_helper); | 1445 char_at_generator.GenerateSlow(masm(), call_helper); |
1429 | 1446 |
1430 __ bind(&index_out_of_range); | 1447 __ bind(&index_out_of_range); |
1431 __ Set(eax, Immediate(Factory::empty_string())); | 1448 __ Set(eax, Immediate(Factory::empty_string())); |
1432 __ ret((argc + 1) * kPointerSize); | 1449 __ ret((argc + 1) * kPointerSize); |
1433 | 1450 |
1434 __ bind(&miss); | 1451 __ bind(&miss); |
1435 // Restore function name in ecx. | 1452 // Restore function name in ecx. |
1436 __ Set(ecx, Immediate(Handle<String>(name))); | |
1437 | 1453 |
1438 Handle<Code> ic = ComputeCallMiss(argc); | 1454 GenerateMissBranch(); |
1439 __ jmp(ic, RelocInfo::CODE_TARGET); | |
1440 | 1455 |
1441 // Return the generated code. | 1456 // Return the generated code. |
1442 return GetCode(function); | 1457 return GetCode(function); |
1443 } | 1458 } |
1444 | 1459 |
1445 | 1460 |
1446 Object* CallStubCompiler::CompileCallConstant(Object* object, | 1461 Object* CallStubCompiler::CompileCallConstant(Object* object, |
1447 JSObject* holder, | 1462 JSObject* holder, |
1448 JSFunction* function, | 1463 JSFunction* function, |
1449 String* name, | 1464 String* name, |
(...skipping 12 matching lines...) Expand all Loading... |
1462 Object* result = | 1477 Object* result = |
1463 CompileCustomCall(id, object, holder, function, name, check); | 1478 CompileCustomCall(id, object, holder, function, name, check); |
1464 // undefined means bail out to regular compiler. | 1479 // undefined means bail out to regular compiler. |
1465 if (!result->IsUndefined()) { | 1480 if (!result->IsUndefined()) { |
1466 return result; | 1481 return result; |
1467 } | 1482 } |
1468 } | 1483 } |
1469 | 1484 |
1470 Label miss_in_smi_check; | 1485 Label miss_in_smi_check; |
1471 | 1486 |
| 1487 GenerateNameCheck(name, &miss_in_smi_check); |
| 1488 |
1472 // Get the receiver from the stack. | 1489 // Get the receiver from the stack. |
1473 const int argc = arguments().immediate(); | 1490 const int argc = arguments().immediate(); |
1474 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1491 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
1475 | 1492 |
1476 // Check that the receiver isn't a smi. | 1493 // Check that the receiver isn't a smi. |
1477 if (check != NUMBER_CHECK) { | 1494 if (check != NUMBER_CHECK) { |
1478 __ test(edx, Immediate(kSmiTagMask)); | 1495 __ test(edx, Immediate(kSmiTagMask)); |
1479 __ j(zero, &miss_in_smi_check, not_taken); | 1496 __ j(zero, &miss_in_smi_check, not_taken); |
1480 } | 1497 } |
1481 | 1498 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1586 } else { | 1603 } else { |
1587 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); | 1604 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); |
1588 } | 1605 } |
1589 | 1606 |
1590 // Handle call cache miss. | 1607 // Handle call cache miss. |
1591 __ bind(&miss); | 1608 __ bind(&miss); |
1592 if (depth != kInvalidProtoDepth) { | 1609 if (depth != kInvalidProtoDepth) { |
1593 FreeSpaceForFastApiCall(masm(), eax); | 1610 FreeSpaceForFastApiCall(masm(), eax); |
1594 } | 1611 } |
1595 __ bind(&miss_in_smi_check); | 1612 __ bind(&miss_in_smi_check); |
1596 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); | 1613 GenerateMissBranch(); |
1597 __ jmp(ic, RelocInfo::CODE_TARGET); | |
1598 | 1614 |
1599 // Return the generated code. | 1615 // Return the generated code. |
1600 return GetCode(function); | 1616 return GetCode(function); |
1601 } | 1617 } |
1602 | 1618 |
1603 | 1619 |
1604 Object* CallStubCompiler::CompileCallInterceptor(JSObject* object, | 1620 Object* CallStubCompiler::CompileCallInterceptor(JSObject* object, |
1605 JSObject* holder, | 1621 JSObject* holder, |
1606 String* name) { | 1622 String* name) { |
1607 // ----------- S t a t e ------------- | 1623 // ----------- S t a t e ------------- |
1608 // -- ecx : name | 1624 // -- ecx : name |
1609 // -- esp[0] : return address | 1625 // -- esp[0] : return address |
1610 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1626 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1611 // -- ... | 1627 // -- ... |
1612 // -- esp[(argc + 1) * 4] : receiver | 1628 // -- esp[(argc + 1) * 4] : receiver |
1613 // ----------------------------------- | 1629 // ----------------------------------- |
1614 Label miss; | 1630 Label miss; |
1615 | 1631 |
| 1632 GenerateNameCheck(name, &miss); |
| 1633 |
1616 // Get the number of arguments. | 1634 // Get the number of arguments. |
1617 const int argc = arguments().immediate(); | 1635 const int argc = arguments().immediate(); |
1618 | 1636 |
1619 LookupResult lookup; | 1637 LookupResult lookup; |
1620 LookupPostInterceptor(holder, name, &lookup); | 1638 LookupPostInterceptor(holder, name, &lookup); |
1621 | 1639 |
1622 // Get the receiver from the stack. | 1640 // Get the receiver from the stack. |
1623 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1641 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
1624 | 1642 |
1625 CallInterceptorCompiler compiler(this, arguments(), ecx); | 1643 CallInterceptorCompiler compiler(this, arguments(), ecx); |
(...skipping 22 matching lines...) Expand all Loading... |
1648 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 1666 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
1649 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 1667 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
1650 } | 1668 } |
1651 | 1669 |
1652 // Invoke the function. | 1670 // Invoke the function. |
1653 __ mov(edi, eax); | 1671 __ mov(edi, eax); |
1654 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION); | 1672 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION); |
1655 | 1673 |
1656 // Handle load cache miss. | 1674 // Handle load cache miss. |
1657 __ bind(&miss); | 1675 __ bind(&miss); |
1658 Handle<Code> ic = ComputeCallMiss(argc); | 1676 GenerateMissBranch(); |
1659 __ jmp(ic, RelocInfo::CODE_TARGET); | |
1660 | 1677 |
1661 // Return the generated code. | 1678 // Return the generated code. |
1662 return GetCode(INTERCEPTOR, name); | 1679 return GetCode(INTERCEPTOR, name); |
1663 } | 1680 } |
1664 | 1681 |
1665 | 1682 |
1666 Object* CallStubCompiler::CompileCallGlobal(JSObject* object, | 1683 Object* CallStubCompiler::CompileCallGlobal(JSObject* object, |
1667 GlobalObject* holder, | 1684 GlobalObject* holder, |
1668 JSGlobalPropertyCell* cell, | 1685 JSGlobalPropertyCell* cell, |
1669 JSFunction* function, | 1686 JSFunction* function, |
1670 String* name) { | 1687 String* name) { |
1671 // ----------- S t a t e ------------- | 1688 // ----------- S t a t e ------------- |
1672 // -- ecx : name | 1689 // -- ecx : name |
1673 // -- esp[0] : return address | 1690 // -- esp[0] : return address |
1674 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1691 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1675 // -- ... | 1692 // -- ... |
1676 // -- esp[(argc + 1) * 4] : receiver | 1693 // -- esp[(argc + 1) * 4] : receiver |
1677 // ----------------------------------- | 1694 // ----------------------------------- |
1678 Label miss; | 1695 Label miss; |
1679 | 1696 |
| 1697 GenerateNameCheck(name, &miss); |
| 1698 |
1680 // Get the number of arguments. | 1699 // Get the number of arguments. |
1681 const int argc = arguments().immediate(); | 1700 const int argc = arguments().immediate(); |
1682 | 1701 |
1683 // Get the receiver from the stack. | 1702 // Get the receiver from the stack. |
1684 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1703 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
1685 | 1704 |
1686 // If the object is the holder then we know that it's a global | 1705 // If the object is the holder then we know that it's a global |
1687 // object which can only happen for contextual calls. In this case, | 1706 // object which can only happen for contextual calls. In this case, |
1688 // the receiver cannot be a smi. | 1707 // the receiver cannot be a smi. |
1689 if (object != holder) { | 1708 if (object != holder) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1732 __ IncrementCounter(&Counters::call_global_inline, 1); | 1751 __ IncrementCounter(&Counters::call_global_inline, 1); |
1733 ASSERT(function->is_compiled()); | 1752 ASSERT(function->is_compiled()); |
1734 Handle<Code> code(function->code()); | 1753 Handle<Code> code(function->code()); |
1735 ParameterCount expected(function->shared()->formal_parameter_count()); | 1754 ParameterCount expected(function->shared()->formal_parameter_count()); |
1736 __ InvokeCode(code, expected, arguments(), | 1755 __ InvokeCode(code, expected, arguments(), |
1737 RelocInfo::CODE_TARGET, JUMP_FUNCTION); | 1756 RelocInfo::CODE_TARGET, JUMP_FUNCTION); |
1738 | 1757 |
1739 // Handle call cache miss. | 1758 // Handle call cache miss. |
1740 __ bind(&miss); | 1759 __ bind(&miss); |
1741 __ IncrementCounter(&Counters::call_global_inline_miss, 1); | 1760 __ IncrementCounter(&Counters::call_global_inline_miss, 1); |
1742 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); | 1761 GenerateMissBranch(); |
1743 __ jmp(ic, RelocInfo::CODE_TARGET); | |
1744 | 1762 |
1745 // Return the generated code. | 1763 // Return the generated code. |
1746 return GetCode(NORMAL, name); | 1764 return GetCode(NORMAL, name); |
1747 } | 1765 } |
1748 | 1766 |
1749 | 1767 |
1750 Object* StoreStubCompiler::CompileStoreField(JSObject* object, | 1768 Object* StoreStubCompiler::CompileStoreField(JSObject* object, |
1751 int index, | 1769 int index, |
1752 Map* transition, | 1770 Map* transition, |
1753 String* name) { | 1771 String* name) { |
(...skipping 717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2471 // Return the generated code. | 2489 // Return the generated code. |
2472 return GetCode(); | 2490 return GetCode(); |
2473 } | 2491 } |
2474 | 2492 |
2475 | 2493 |
2476 #undef __ | 2494 #undef __ |
2477 | 2495 |
2478 } } // namespace v8::internal | 2496 } } // namespace v8::internal |
2479 | 2497 |
2480 #endif // V8_TARGET_ARCH_IA32 | 2498 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |