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