Chromium Code Reviews| 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 1202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1213 | 1213 |
| 1214 | 1214 |
| 1215 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { | 1215 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { |
| 1216 if (kind_ == Code::KEYED_CALL_IC) { | 1216 if (kind_ == Code::KEYED_CALL_IC) { |
| 1217 __ cmp(r2, Operand(Handle<String>(name))); | 1217 __ cmp(r2, Operand(Handle<String>(name))); |
| 1218 __ b(ne, miss); | 1218 __ b(ne, miss); |
| 1219 } | 1219 } |
| 1220 } | 1220 } |
| 1221 | 1221 |
| 1222 | 1222 |
| 1223 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, | |
| 1224 JSObject* holder, | |
|
antonm
2010/09/08 15:26:05
is it true that holder is always a global object?
| |
| 1225 String* name, | |
| 1226 Label* miss) { | |
| 1227 // Get the number of arguments. | |
| 1228 const int argc = arguments().immediate(); | |
| 1229 | |
| 1230 // Get the receiver from the stack. | |
| 1231 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | |
| 1232 | |
| 1233 // If the object is the holder then we know that it's a global | |
| 1234 // object which can only happen for contextual calls. In this case, | |
| 1235 // the receiver cannot be a smi. | |
| 1236 if (object != holder) { | |
| 1237 __ tst(r0, Operand(kSmiTagMask)); | |
| 1238 __ b(eq, miss); | |
| 1239 } | |
| 1240 | |
| 1241 // Check that the maps haven't changed. | |
| 1242 CheckPrototypes(object, r0, holder, r3, r1, r4, name, miss); | |
| 1243 } | |
| 1244 | |
| 1245 | |
| 1246 void CallStubCompiler::GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell, | |
| 1247 JSFunction* function, | |
| 1248 Label* miss) { | |
| 1249 // Get the value from the cell. | |
| 1250 __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell))); | |
| 1251 __ ldr(r1, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); | |
| 1252 | |
| 1253 // Check that the cell contains the same function. | |
| 1254 if (Heap::InNewSpace(function)) { | |
| 1255 // We can't embed a pointer to a function in new space so we have | |
| 1256 // to verify that the shared function info is unchanged. This has | |
| 1257 // the nice side effect that multiple closures based on the same | |
| 1258 // function can all use this call IC. Before we load through the | |
| 1259 // function, we have to verify that it still is a function. | |
| 1260 __ tst(r1, Operand(kSmiTagMask)); | |
| 1261 __ b(eq, miss); | |
| 1262 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE); | |
| 1263 __ b(ne, miss); | |
| 1264 | |
| 1265 // Check the shared function info. Make sure it hasn't changed. | |
| 1266 __ mov(r3, Operand(Handle<SharedFunctionInfo>(function->shared()))); | |
|
antonm
2010/09/08 15:26:05
maybe __ Move(r3, Handle<...). But I don't know i
| |
| 1267 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | |
| 1268 __ cmp(r4, r3); | |
| 1269 __ b(ne, miss); | |
| 1270 } else { | |
| 1271 __ cmp(r1, Operand(Handle<JSFunction>(function))); | |
| 1272 __ b(ne, miss); | |
| 1273 } | |
| 1274 } | |
| 1275 | |
| 1276 | |
| 1223 Object* CallStubCompiler::GenerateMissBranch() { | 1277 Object* CallStubCompiler::GenerateMissBranch() { |
| 1224 Object* obj = StubCache::ComputeCallMiss(arguments().immediate(), kind_); | 1278 Object* obj = StubCache::ComputeCallMiss(arguments().immediate(), kind_); |
| 1225 if (obj->IsFailure()) return obj; | 1279 if (obj->IsFailure()) return obj; |
| 1226 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 1280 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); |
| 1227 return obj; | 1281 return obj; |
| 1228 } | 1282 } |
| 1229 | 1283 |
| 1230 | 1284 |
| 1231 Object* CallStubCompiler::CompileCallField(JSObject* object, | 1285 Object* CallStubCompiler::CompileCallField(JSObject* object, |
| 1232 JSObject* holder, | 1286 JSObject* holder, |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 1259 Object* obj = GenerateMissBranch(); | 1313 Object* obj = GenerateMissBranch(); |
| 1260 if (obj->IsFailure()) return obj; | 1314 if (obj->IsFailure()) return obj; |
| 1261 | 1315 |
| 1262 // Return the generated code. | 1316 // Return the generated code. |
| 1263 return GetCode(FIELD, name); | 1317 return GetCode(FIELD, name); |
| 1264 } | 1318 } |
| 1265 | 1319 |
| 1266 | 1320 |
| 1267 Object* CallStubCompiler::CompileArrayPushCall(Object* object, | 1321 Object* CallStubCompiler::CompileArrayPushCall(Object* object, |
| 1268 JSObject* holder, | 1322 JSObject* holder, |
| 1323 JSGlobalPropertyCell* cell, | |
| 1269 JSFunction* function, | 1324 JSFunction* function, |
| 1270 String* name, | 1325 String* name) { |
| 1271 CheckType check) { | |
| 1272 // ----------- S t a t e ------------- | 1326 // ----------- S t a t e ------------- |
| 1273 // -- r2 : name | 1327 // -- r2 : name |
| 1274 // -- lr : return address | 1328 // -- lr : return address |
| 1275 // ----------------------------------- | 1329 // ----------------------------------- |
| 1276 | 1330 |
| 1331 // TODO(639): faster implementation. | |
| 1332 | |
| 1277 // If object is not an array, bail out to regular call. | 1333 // If object is not an array, bail out to regular call. |
| 1278 if (!object->IsJSArray()) { | 1334 if (!object->IsJSArray() || cell != NULL) return Heap::undefined_value(); |
| 1279 return Heap::undefined_value(); | |
| 1280 } | |
| 1281 | |
| 1282 // TODO(639): faster implementation. | |
| 1283 ASSERT(check == RECEIVER_MAP_CHECK); | |
| 1284 | 1335 |
| 1285 Label miss; | 1336 Label miss; |
| 1286 | 1337 |
| 1287 GenerateNameCheck(name, &miss); | 1338 GenerateNameCheck(name, &miss); |
| 1288 | 1339 |
| 1289 // Get the receiver from the stack | 1340 // Get the receiver from the stack |
| 1290 const int argc = arguments().immediate(); | 1341 const int argc = arguments().immediate(); |
| 1291 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 1342 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
| 1292 | 1343 |
| 1293 // Check that the receiver isn't a smi. | 1344 // Check that the receiver isn't a smi. |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1306 Object* obj = GenerateMissBranch(); | 1357 Object* obj = GenerateMissBranch(); |
| 1307 if (obj->IsFailure()) return obj; | 1358 if (obj->IsFailure()) return obj; |
| 1308 | 1359 |
| 1309 // Return the generated code. | 1360 // Return the generated code. |
| 1310 return GetCode(function); | 1361 return GetCode(function); |
| 1311 } | 1362 } |
| 1312 | 1363 |
| 1313 | 1364 |
| 1314 Object* CallStubCompiler::CompileArrayPopCall(Object* object, | 1365 Object* CallStubCompiler::CompileArrayPopCall(Object* object, |
| 1315 JSObject* holder, | 1366 JSObject* holder, |
| 1367 JSGlobalPropertyCell* cell, | |
| 1316 JSFunction* function, | 1368 JSFunction* function, |
| 1317 String* name, | 1369 String* name) { |
| 1318 CheckType check) { | |
| 1319 // ----------- S t a t e ------------- | 1370 // ----------- S t a t e ------------- |
| 1320 // -- r2 : name | 1371 // -- r2 : name |
| 1321 // -- lr : return address | 1372 // -- lr : return address |
| 1322 // ----------------------------------- | 1373 // ----------------------------------- |
| 1323 | 1374 |
| 1375 // TODO(642): faster implementation. | |
| 1376 | |
| 1324 // If object is not an array, bail out to regular call. | 1377 // If object is not an array, bail out to regular call. |
| 1325 if (!object->IsJSArray()) { | 1378 if (!object->IsJSArray() || cell != NULL) return Heap::undefined_value(); |
| 1326 return Heap::undefined_value(); | |
| 1327 } | |
| 1328 | |
| 1329 // TODO(642): faster implementation. | |
| 1330 ASSERT(check == RECEIVER_MAP_CHECK); | |
| 1331 | 1379 |
| 1332 Label miss; | 1380 Label miss; |
| 1333 | 1381 |
| 1334 GenerateNameCheck(name, &miss); | 1382 GenerateNameCheck(name, &miss); |
| 1335 | 1383 |
| 1336 // Get the receiver from the stack | 1384 // Get the receiver from the stack |
| 1337 const int argc = arguments().immediate(); | 1385 const int argc = arguments().immediate(); |
| 1338 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 1386 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
| 1339 | 1387 |
| 1340 // Check that the receiver isn't a smi. | 1388 // Check that the receiver isn't a smi. |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1351 // Handle call cache miss. | 1399 // Handle call cache miss. |
| 1352 __ bind(&miss); | 1400 __ bind(&miss); |
| 1353 Object* obj = GenerateMissBranch(); | 1401 Object* obj = GenerateMissBranch(); |
| 1354 if (obj->IsFailure()) return obj; | 1402 if (obj->IsFailure()) return obj; |
| 1355 | 1403 |
| 1356 // Return the generated code. | 1404 // Return the generated code. |
| 1357 return GetCode(function); | 1405 return GetCode(function); |
| 1358 } | 1406 } |
| 1359 | 1407 |
| 1360 | 1408 |
| 1361 Object* CallStubCompiler::CompileStringCharCodeAtCall(Object* object, | 1409 Object* CallStubCompiler::CompileStringCharCodeAtCall( |
| 1362 JSObject* holder, | 1410 Object* object, |
| 1363 JSFunction* function, | 1411 JSObject* holder, |
| 1364 String* name, | 1412 JSGlobalPropertyCell* cell, |
| 1365 CheckType check) { | 1413 JSFunction* function, |
| 1414 String* name) { | |
| 1366 // ----------- S t a t e ------------- | 1415 // ----------- S t a t e ------------- |
| 1367 // -- r2 : function name | 1416 // -- r2 : function name |
| 1368 // -- lr : return address | 1417 // -- lr : return address |
| 1369 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 1418 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
| 1370 // -- ... | 1419 // -- ... |
| 1371 // -- sp[argc * 4] : receiver | 1420 // -- sp[argc * 4] : receiver |
| 1372 // ----------------------------------- | 1421 // ----------------------------------- |
| 1373 | 1422 |
| 1374 // If object is not a string, bail out to regular call. | 1423 // If object is not a string, bail out to regular call. |
| 1375 if (!object->IsString()) return Heap::undefined_value(); | 1424 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); |
| 1376 | 1425 |
| 1377 const int argc = arguments().immediate(); | 1426 const int argc = arguments().immediate(); |
| 1378 | 1427 |
| 1379 Label miss; | 1428 Label miss; |
| 1380 Label index_out_of_range; | 1429 Label index_out_of_range; |
| 1381 GenerateNameCheck(name, &miss); | 1430 GenerateNameCheck(name, &miss); |
| 1382 | 1431 |
| 1383 // Check that the maps starting from the prototype haven't changed. | 1432 // Check that the maps starting from the prototype haven't changed. |
| 1384 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1433 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
| 1385 Context::STRING_FUNCTION_INDEX, | 1434 Context::STRING_FUNCTION_INDEX, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1423 Object* obj = GenerateMissBranch(); | 1472 Object* obj = GenerateMissBranch(); |
| 1424 if (obj->IsFailure()) return obj; | 1473 if (obj->IsFailure()) return obj; |
| 1425 | 1474 |
| 1426 // Return the generated code. | 1475 // Return the generated code. |
| 1427 return GetCode(function); | 1476 return GetCode(function); |
| 1428 } | 1477 } |
| 1429 | 1478 |
| 1430 | 1479 |
| 1431 Object* CallStubCompiler::CompileStringCharAtCall(Object* object, | 1480 Object* CallStubCompiler::CompileStringCharAtCall(Object* object, |
| 1432 JSObject* holder, | 1481 JSObject* holder, |
| 1482 JSGlobalPropertyCell* cell, | |
| 1433 JSFunction* function, | 1483 JSFunction* function, |
| 1434 String* name, | 1484 String* name) { |
| 1435 CheckType check) { | |
| 1436 // ----------- S t a t e ------------- | 1485 // ----------- S t a t e ------------- |
| 1437 // -- r2 : function name | 1486 // -- r2 : function name |
| 1438 // -- lr : return address | 1487 // -- lr : return address |
| 1439 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 1488 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
| 1440 // -- ... | 1489 // -- ... |
| 1441 // -- sp[argc * 4] : receiver | 1490 // -- sp[argc * 4] : receiver |
| 1442 // ----------------------------------- | 1491 // ----------------------------------- |
| 1443 | 1492 |
| 1444 // If object is not a string, bail out to regular call. | 1493 // If object is not a string, bail out to regular call. |
| 1445 if (!object->IsString()) return Heap::undefined_value(); | 1494 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); |
| 1446 | 1495 |
| 1447 const int argc = arguments().immediate(); | 1496 const int argc = arguments().immediate(); |
| 1448 | 1497 |
| 1449 Label miss; | 1498 Label miss; |
| 1450 Label index_out_of_range; | 1499 Label index_out_of_range; |
| 1451 | 1500 |
| 1452 GenerateNameCheck(name, &miss); | 1501 GenerateNameCheck(name, &miss); |
| 1453 | 1502 |
| 1454 // Check that the maps starting from the prototype haven't changed. | 1503 // Check that the maps starting from the prototype haven't changed. |
| 1455 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1504 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1494 | 1543 |
| 1495 __ bind(&miss); | 1544 __ bind(&miss); |
| 1496 Object* obj = GenerateMissBranch(); | 1545 Object* obj = GenerateMissBranch(); |
| 1497 if (obj->IsFailure()) return obj; | 1546 if (obj->IsFailure()) return obj; |
| 1498 | 1547 |
| 1499 // Return the generated code. | 1548 // Return the generated code. |
| 1500 return GetCode(function); | 1549 return GetCode(function); |
| 1501 } | 1550 } |
| 1502 | 1551 |
| 1503 | 1552 |
| 1553 Object* CallStubCompiler::CompileStringFromCharCodeCall( | |
| 1554 Object* object, | |
| 1555 JSObject* holder, | |
| 1556 JSGlobalPropertyCell* cell, | |
| 1557 JSFunction* function, | |
| 1558 String* name) { | |
| 1559 // ----------- S t a t e ------------- | |
| 1560 // -- r2 : function name | |
| 1561 // -- lr : return address | |
| 1562 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | |
| 1563 // -- ... | |
| 1564 // -- sp[argc * 4] : receiver | |
| 1565 // ----------------------------------- | |
| 1566 | |
| 1567 const int argc = arguments().immediate(); | |
| 1568 | |
| 1569 // If the object is not a JSObject or we got an unexpected number of | |
| 1570 // arguments, bail out to the regular call. | |
| 1571 if (!object->IsJSObject() || argc != 1) return Heap::undefined_value(); | |
| 1572 | |
| 1573 Label miss; | |
| 1574 GenerateNameCheck(name, &miss); | |
| 1575 | |
| 1576 if (cell == NULL) { | |
| 1577 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); | |
| 1578 | |
| 1579 STATIC_ASSERT(kSmiTag == 0); | |
| 1580 __ tst(r1, Operand(kSmiTagMask)); | |
| 1581 __ b(eq, &miss); | |
| 1582 | |
| 1583 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, | |
| 1584 &miss); | |
| 1585 } else { | |
| 1586 ASSERT(cell->value() == function); | |
| 1587 GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss); | |
| 1588 GenerateLoadFunctionFromCell(cell, function, &miss); | |
| 1589 } | |
| 1590 | |
| 1591 // Load the char code argument. | |
| 1592 Register code = r1; | |
|
antonm
2010/09/08 15:26:05
sorry, that's probably only me, but could you rena
| |
| 1593 __ ldr(code, MemOperand(sp, 0 * kPointerSize)); | |
| 1594 | |
| 1595 // Check the code is a smi. | |
| 1596 Label slow; | |
| 1597 STATIC_ASSERT(kSmiTag == 0); | |
| 1598 __ tst(code, Operand(kSmiTagMask)); | |
| 1599 __ b(ne, &slow); | |
| 1600 | |
| 1601 // Convert the smi code to uint16. | |
| 1602 __ and_(code, code, Operand(Smi::FromInt(0xffff))); | |
| 1603 | |
| 1604 StringCharFromCodeGenerator char_from_code_generator(code, r0); | |
| 1605 char_from_code_generator.GenerateFast(masm()); | |
| 1606 __ Drop(argc + 1); | |
| 1607 __ Ret(); | |
| 1608 | |
| 1609 ICRuntimeCallHelper call_helper; | |
| 1610 char_from_code_generator.GenerateSlow(masm(), call_helper); | |
|
antonm
2010/09/08 15:26:05
just to double check: that is necessary for ::Gene
| |
| 1611 | |
| 1612 // Tail call the full function. | |
| 1613 __ bind(&slow); | |
| 1614 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); | |
| 1615 | |
| 1616 __ bind(&miss); | |
| 1617 // r2: function name. | |
| 1618 Object* obj = GenerateMissBranch(); | |
| 1619 if (obj->IsFailure()) return obj; | |
| 1620 | |
| 1621 // Return the generated code. | |
| 1622 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | |
| 1623 } | |
| 1624 | |
| 1625 | |
| 1504 Object* CallStubCompiler::CompileCallConstant(Object* object, | 1626 Object* CallStubCompiler::CompileCallConstant(Object* object, |
| 1505 JSObject* holder, | 1627 JSObject* holder, |
| 1506 JSFunction* function, | 1628 JSFunction* function, |
| 1507 String* name, | 1629 String* name, |
| 1508 CheckType check) { | 1630 CheckType check) { |
| 1509 // ----------- S t a t e ------------- | 1631 // ----------- S t a t e ------------- |
| 1510 // -- r2 : name | 1632 // -- r2 : name |
| 1511 // -- lr : return address | 1633 // -- lr : return address |
| 1512 // ----------------------------------- | 1634 // ----------------------------------- |
| 1513 SharedFunctionInfo* function_info = function->shared(); | 1635 SharedFunctionInfo* function_info = function->shared(); |
| 1514 if (function_info->HasCustomCallGenerator()) { | 1636 if (function_info->HasCustomCallGenerator()) { |
| 1515 const int id = function_info->custom_call_generator_id(); | 1637 const int id = function_info->custom_call_generator_id(); |
| 1516 Object* result = | 1638 Object* result = CompileCustomCall( |
| 1517 CompileCustomCall(id, object, holder, function, name, check); | 1639 id, object, holder, NULL, function, name); |
| 1518 // undefined means bail out to regular compiler. | 1640 // undefined means bail out to regular compiler. |
| 1519 if (!result->IsUndefined()) { | 1641 if (!result->IsUndefined()) { |
| 1520 return result; | 1642 return result; |
| 1521 } | 1643 } |
| 1522 } | 1644 } |
| 1523 | 1645 |
| 1524 Label miss_in_smi_check; | 1646 Label miss_in_smi_check; |
| 1525 | 1647 |
| 1526 GenerateNameCheck(name, &miss_in_smi_check); | 1648 GenerateNameCheck(name, &miss_in_smi_check); |
| 1527 | 1649 |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1707 | 1829 |
| 1708 Object* CallStubCompiler::CompileCallGlobal(JSObject* object, | 1830 Object* CallStubCompiler::CompileCallGlobal(JSObject* object, |
| 1709 GlobalObject* holder, | 1831 GlobalObject* holder, |
| 1710 JSGlobalPropertyCell* cell, | 1832 JSGlobalPropertyCell* cell, |
| 1711 JSFunction* function, | 1833 JSFunction* function, |
| 1712 String* name) { | 1834 String* name) { |
| 1713 // ----------- S t a t e ------------- | 1835 // ----------- S t a t e ------------- |
| 1714 // -- r2 : name | 1836 // -- r2 : name |
| 1715 // -- lr : return address | 1837 // -- lr : return address |
| 1716 // ----------------------------------- | 1838 // ----------------------------------- |
| 1839 | |
| 1840 SharedFunctionInfo* function_info = function->shared(); | |
| 1841 if (function_info->HasCustomCallGenerator()) { | |
| 1842 const int id = function_info->custom_call_generator_id(); | |
| 1843 Object* result = CompileCustomCall( | |
| 1844 id, object, holder, cell, function, name); | |
| 1845 // undefined means bail out to regular compiler. | |
| 1846 if (!result->IsUndefined()) return result; | |
| 1847 } | |
| 1848 | |
| 1717 Label miss; | 1849 Label miss; |
| 1718 | 1850 |
| 1719 GenerateNameCheck(name, &miss); | 1851 GenerateNameCheck(name, &miss); |
| 1720 | 1852 |
| 1721 // Get the number of arguments. | 1853 // Get the number of arguments. |
| 1722 const int argc = arguments().immediate(); | 1854 const int argc = arguments().immediate(); |
| 1723 | 1855 |
| 1724 // Get the receiver from the stack. | 1856 GenerateGlobalReceiverCheck(object, holder, name, &miss); |
|
antonm
2010/09/08 15:26:05
aha, looks like holder must be a global object, ma
| |
| 1725 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | |
| 1726 | 1857 |
| 1727 // If the object is the holder then we know that it's a global | 1858 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 1728 // object which can only happen for contextual calls. In this case, | |
| 1729 // the receiver cannot be a smi. | |
| 1730 if (object != holder) { | |
| 1731 __ tst(r0, Operand(kSmiTagMask)); | |
| 1732 __ b(eq, &miss); | |
| 1733 } | |
| 1734 | |
| 1735 // Check that the maps haven't changed. | |
| 1736 CheckPrototypes(object, r0, holder, r3, r1, r4, name, &miss); | |
| 1737 | |
| 1738 // Get the value from the cell. | |
| 1739 __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell))); | |
| 1740 __ ldr(r1, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); | |
| 1741 | |
| 1742 // Check that the cell contains the same function. | |
| 1743 if (Heap::InNewSpace(function)) { | |
| 1744 // We can't embed a pointer to a function in new space so we have | |
| 1745 // to verify that the shared function info is unchanged. This has | |
| 1746 // the nice side effect that multiple closures based on the same | |
| 1747 // function can all use this call IC. Before we load through the | |
| 1748 // function, we have to verify that it still is a function. | |
| 1749 __ tst(r1, Operand(kSmiTagMask)); | |
| 1750 __ b(eq, &miss); | |
| 1751 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE); | |
| 1752 __ b(ne, &miss); | |
| 1753 | |
| 1754 // Check the shared function info. Make sure it hasn't changed. | |
| 1755 __ mov(r3, Operand(Handle<SharedFunctionInfo>(function->shared()))); | |
| 1756 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | |
| 1757 __ cmp(r4, r3); | |
| 1758 __ b(ne, &miss); | |
| 1759 } else { | |
| 1760 __ cmp(r1, Operand(Handle<JSFunction>(function))); | |
| 1761 __ b(ne, &miss); | |
| 1762 } | |
| 1763 | 1859 |
| 1764 // Patch the receiver on the stack with the global proxy if | 1860 // Patch the receiver on the stack with the global proxy if |
| 1765 // necessary. | 1861 // necessary. |
| 1766 if (object->IsGlobalObject()) { | 1862 if (object->IsGlobalObject()) { |
| 1767 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); | 1863 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); |
| 1768 __ str(r3, MemOperand(sp, argc * kPointerSize)); | 1864 __ str(r3, MemOperand(sp, argc * kPointerSize)); |
| 1769 } | 1865 } |
| 1770 | 1866 |
| 1771 // Setup the context (function already in r1). | 1867 // Setup the context (function already in r1). |
| 1772 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | 1868 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
| (...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2467 // Return the generated code. | 2563 // Return the generated code. |
| 2468 return GetCode(); | 2564 return GetCode(); |
| 2469 } | 2565 } |
| 2470 | 2566 |
| 2471 | 2567 |
| 2472 #undef __ | 2568 #undef __ |
| 2473 | 2569 |
| 2474 } } // namespace v8::internal | 2570 } } // namespace v8::internal |
| 2475 | 2571 |
| 2476 #endif // V8_TARGET_ARCH_ARM | 2572 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |