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 1140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1151 // Patch the receiver on the stack with the global proxy. | 1151 // Patch the receiver on the stack with the global proxy. |
1152 if (object->IsGlobalObject()) { | 1152 if (object->IsGlobalObject()) { |
1153 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 1153 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
1154 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 1154 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
1155 } | 1155 } |
1156 | 1156 |
1157 // Setup the context (function already in edi). | 1157 // Setup the context (function already in edi). |
1158 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 1158 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
1159 | 1159 |
1160 // Jump to the cached code (tail call). | 1160 // Jump to the cached code (tail call). |
1161 __ IncrementCounter(&Counters::call_global_inline, 1); | 1161 __ IncrementCounter(&COUNTER(call_global_inline), 1); |
1162 ASSERT(function->is_compiled()); | 1162 ASSERT(function->is_compiled()); |
1163 Handle<Code> code(function->code()); | 1163 Handle<Code> code(function->code()); |
1164 ParameterCount expected(function->shared()->formal_parameter_count()); | 1164 ParameterCount expected(function->shared()->formal_parameter_count()); |
1165 __ InvokeCode(code, expected, arguments(), | 1165 __ InvokeCode(code, expected, arguments(), |
1166 RelocInfo::CODE_TARGET, JUMP_FUNCTION); | 1166 RelocInfo::CODE_TARGET, JUMP_FUNCTION); |
1167 | 1167 |
1168 // Handle call cache miss. | 1168 // Handle call cache miss. |
1169 __ bind(&miss); | 1169 __ bind(&miss); |
1170 __ IncrementCounter(&Counters::call_global_inline_miss, 1); | 1170 __ IncrementCounter(&COUNTER(call_global_inline_miss), 1); |
1171 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); | 1171 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); |
1172 __ jmp(ic, RelocInfo::CODE_TARGET); | 1172 __ jmp(ic, RelocInfo::CODE_TARGET); |
1173 | 1173 |
1174 // Return the generated code. | 1174 // Return the generated code. |
1175 return GetCode(NORMAL, name); | 1175 return GetCode(NORMAL, name); |
1176 } | 1176 } |
1177 | 1177 |
1178 | 1178 |
1179 Object* StoreStubCompiler::CompileStoreField(JSObject* object, | 1179 Object* StoreStubCompiler::CompileStoreField(JSObject* object, |
1180 int index, | 1180 int index, |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1334 __ mov(ebx, Operand(esp, kPointerSize)); | 1334 __ mov(ebx, Operand(esp, kPointerSize)); |
1335 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), | 1335 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), |
1336 Immediate(Handle<Map>(object->map()))); | 1336 Immediate(Handle<Map>(object->map()))); |
1337 __ j(not_equal, &miss, not_taken); | 1337 __ j(not_equal, &miss, not_taken); |
1338 | 1338 |
1339 // Store the value in the cell. | 1339 // Store the value in the cell. |
1340 __ mov(ecx, Immediate(Handle<JSGlobalPropertyCell>(cell))); | 1340 __ mov(ecx, Immediate(Handle<JSGlobalPropertyCell>(cell))); |
1341 __ mov(FieldOperand(ecx, JSGlobalPropertyCell::kValueOffset), eax); | 1341 __ mov(FieldOperand(ecx, JSGlobalPropertyCell::kValueOffset), eax); |
1342 | 1342 |
1343 // Return the value (register eax). | 1343 // Return the value (register eax). |
1344 __ IncrementCounter(&Counters::named_store_global_inline, 1); | 1344 __ IncrementCounter(&COUNTER(named_store_global_inline), 1); |
1345 __ ret(0); | 1345 __ ret(0); |
1346 | 1346 |
1347 // Handle store cache miss. | 1347 // Handle store cache miss. |
1348 __ bind(&miss); | 1348 __ bind(&miss); |
1349 __ IncrementCounter(&Counters::named_store_global_inline_miss, 1); | 1349 __ IncrementCounter(&COUNTER(named_store_global_inline_miss), 1); |
1350 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); | 1350 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); |
1351 __ jmp(ic, RelocInfo::CODE_TARGET); | 1351 __ jmp(ic, RelocInfo::CODE_TARGET); |
1352 | 1352 |
1353 // Return the generated code. | 1353 // Return the generated code. |
1354 return GetCode(NORMAL, name); | 1354 return GetCode(NORMAL, name); |
1355 } | 1355 } |
1356 | 1356 |
1357 | 1357 |
1358 Object* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, | 1358 Object* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, |
1359 int index, | 1359 int index, |
1360 Map* transition, | 1360 Map* transition, |
1361 String* name) { | 1361 String* name) { |
1362 // ----------- S t a t e ------------- | 1362 // ----------- S t a t e ------------- |
1363 // -- eax : value | 1363 // -- eax : value |
1364 // -- esp[0] : return address | 1364 // -- esp[0] : return address |
1365 // -- esp[4] : key | 1365 // -- esp[4] : key |
1366 // -- esp[8] : receiver | 1366 // -- esp[8] : receiver |
1367 // ----------------------------------- | 1367 // ----------------------------------- |
1368 Label miss; | 1368 Label miss; |
1369 | 1369 |
1370 __ IncrementCounter(&Counters::keyed_store_field, 1); | 1370 __ IncrementCounter(&COUNTER(keyed_store_field), 1); |
1371 | 1371 |
1372 // Get the name from the stack. | 1372 // Get the name from the stack. |
1373 __ mov(ecx, Operand(esp, 1 * kPointerSize)); | 1373 __ mov(ecx, Operand(esp, 1 * kPointerSize)); |
1374 // Check that the name has not changed. | 1374 // Check that the name has not changed. |
1375 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); | 1375 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); |
1376 __ j(not_equal, &miss, not_taken); | 1376 __ j(not_equal, &miss, not_taken); |
1377 | 1377 |
1378 // Get the object from the stack. | 1378 // Get the object from the stack. |
1379 __ mov(ebx, Operand(esp, 2 * kPointerSize)); | 1379 __ mov(ebx, Operand(esp, 2 * kPointerSize)); |
1380 | 1380 |
1381 // Generate store field code. Trashes the name register. | 1381 // Generate store field code. Trashes the name register. |
1382 GenerateStoreField(masm(), | 1382 GenerateStoreField(masm(), |
1383 Builtins::KeyedStoreIC_ExtendStorage, | 1383 Builtins::KeyedStoreIC_ExtendStorage, |
1384 object, | 1384 object, |
1385 index, | 1385 index, |
1386 transition, | 1386 transition, |
1387 ebx, ecx, edx, | 1387 ebx, ecx, edx, |
1388 &miss); | 1388 &miss); |
1389 | 1389 |
1390 // Handle store cache miss. | 1390 // Handle store cache miss. |
1391 __ bind(&miss); | 1391 __ bind(&miss); |
1392 __ DecrementCounter(&Counters::keyed_store_field, 1); | 1392 __ DecrementCounter(&COUNTER(keyed_store_field), 1); |
1393 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); | 1393 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); |
1394 __ jmp(ic, RelocInfo::CODE_TARGET); | 1394 __ jmp(ic, RelocInfo::CODE_TARGET); |
1395 | 1395 |
1396 // Return the generated code. | 1396 // Return the generated code. |
1397 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 1397 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
1398 } | 1398 } |
1399 | 1399 |
1400 | 1400 |
1401 | 1401 |
1402 Object* LoadStubCompiler::CompileLoadField(JSObject* object, | 1402 Object* LoadStubCompiler::CompileLoadField(JSObject* object, |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1529 | 1529 |
1530 // Check for deleted property if property can actually be deleted. | 1530 // Check for deleted property if property can actually be deleted. |
1531 if (!is_dont_delete) { | 1531 if (!is_dont_delete) { |
1532 __ cmp(eax, Factory::the_hole_value()); | 1532 __ cmp(eax, Factory::the_hole_value()); |
1533 __ j(equal, &miss, not_taken); | 1533 __ j(equal, &miss, not_taken); |
1534 } else if (FLAG_debug_code) { | 1534 } else if (FLAG_debug_code) { |
1535 __ cmp(eax, Factory::the_hole_value()); | 1535 __ cmp(eax, Factory::the_hole_value()); |
1536 __ Check(not_equal, "DontDelete cells can't contain the hole"); | 1536 __ Check(not_equal, "DontDelete cells can't contain the hole"); |
1537 } | 1537 } |
1538 | 1538 |
1539 __ IncrementCounter(&Counters::named_load_global_inline, 1); | 1539 __ IncrementCounter(&COUNTER(named_load_global_inline), 1); |
1540 __ ret(0); | 1540 __ ret(0); |
1541 | 1541 |
1542 __ bind(&miss); | 1542 __ bind(&miss); |
1543 __ IncrementCounter(&Counters::named_load_global_inline_miss, 1); | 1543 __ IncrementCounter(&COUNTER(named_load_global_inline_miss), 1); |
1544 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1544 GenerateLoadMiss(masm(), Code::LOAD_IC); |
1545 | 1545 |
1546 // Return the generated code. | 1546 // Return the generated code. |
1547 return GetCode(NORMAL, name); | 1547 return GetCode(NORMAL, name); |
1548 } | 1548 } |
1549 | 1549 |
1550 | 1550 |
1551 Object* KeyedLoadStubCompiler::CompileLoadField(String* name, | 1551 Object* KeyedLoadStubCompiler::CompileLoadField(String* name, |
1552 JSObject* receiver, | 1552 JSObject* receiver, |
1553 JSObject* holder, | 1553 JSObject* holder, |
1554 int index) { | 1554 int index) { |
1555 // ----------- S t a t e ------------- | 1555 // ----------- S t a t e ------------- |
1556 // -- esp[0] : return address | 1556 // -- esp[0] : return address |
1557 // -- esp[4] : name | 1557 // -- esp[4] : name |
1558 // -- esp[8] : receiver | 1558 // -- esp[8] : receiver |
1559 // ----------------------------------- | 1559 // ----------------------------------- |
1560 Label miss; | 1560 Label miss; |
1561 | 1561 |
1562 __ mov(eax, Operand(esp, kPointerSize)); | 1562 __ mov(eax, Operand(esp, kPointerSize)); |
1563 __ mov(ecx, Operand(esp, 2 * kPointerSize)); | 1563 __ mov(ecx, Operand(esp, 2 * kPointerSize)); |
1564 __ IncrementCounter(&Counters::keyed_load_field, 1); | 1564 __ IncrementCounter(&COUNTER(keyed_load_field), 1); |
1565 | 1565 |
1566 // Check that the name has not changed. | 1566 // Check that the name has not changed. |
1567 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 1567 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
1568 __ j(not_equal, &miss, not_taken); | 1568 __ j(not_equal, &miss, not_taken); |
1569 | 1569 |
1570 GenerateLoadField(receiver, holder, ecx, ebx, edx, index, name, &miss); | 1570 GenerateLoadField(receiver, holder, ecx, ebx, edx, index, name, &miss); |
1571 | 1571 |
1572 __ bind(&miss); | 1572 __ bind(&miss); |
1573 __ DecrementCounter(&Counters::keyed_load_field, 1); | 1573 __ DecrementCounter(&COUNTER(keyed_load_field), 1); |
1574 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1574 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1575 | 1575 |
1576 // Return the generated code. | 1576 // Return the generated code. |
1577 return GetCode(FIELD, name); | 1577 return GetCode(FIELD, name); |
1578 } | 1578 } |
1579 | 1579 |
1580 | 1580 |
1581 Object* KeyedLoadStubCompiler::CompileLoadCallback(String* name, | 1581 Object* KeyedLoadStubCompiler::CompileLoadCallback(String* name, |
1582 JSObject* receiver, | 1582 JSObject* receiver, |
1583 JSObject* holder, | 1583 JSObject* holder, |
1584 AccessorInfo* callback) { | 1584 AccessorInfo* callback) { |
1585 // ----------- S t a t e ------------- | 1585 // ----------- S t a t e ------------- |
1586 // -- esp[0] : return address | 1586 // -- esp[0] : return address |
1587 // -- esp[4] : name | 1587 // -- esp[4] : name |
1588 // -- esp[8] : receiver | 1588 // -- esp[8] : receiver |
1589 // ----------------------------------- | 1589 // ----------------------------------- |
1590 Label miss; | 1590 Label miss; |
1591 | 1591 |
1592 __ mov(eax, Operand(esp, kPointerSize)); | 1592 __ mov(eax, Operand(esp, kPointerSize)); |
1593 __ mov(ecx, Operand(esp, 2 * kPointerSize)); | 1593 __ mov(ecx, Operand(esp, 2 * kPointerSize)); |
1594 __ IncrementCounter(&Counters::keyed_load_callback, 1); | 1594 __ IncrementCounter(&COUNTER(keyed_load_callback), 1); |
1595 | 1595 |
1596 // Check that the name has not changed. | 1596 // Check that the name has not changed. |
1597 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 1597 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
1598 __ j(not_equal, &miss, not_taken); | 1598 __ j(not_equal, &miss, not_taken); |
1599 | 1599 |
1600 GenerateLoadCallback(receiver, holder, ecx, eax, ebx, edx, | 1600 GenerateLoadCallback(receiver, holder, ecx, eax, ebx, edx, |
1601 callback, name, &miss); | 1601 callback, name, &miss); |
1602 __ bind(&miss); | 1602 __ bind(&miss); |
1603 __ DecrementCounter(&Counters::keyed_load_callback, 1); | 1603 __ DecrementCounter(&COUNTER(keyed_load_callback), 1); |
1604 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1604 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1605 | 1605 |
1606 // Return the generated code. | 1606 // Return the generated code. |
1607 return GetCode(CALLBACKS, name); | 1607 return GetCode(CALLBACKS, name); |
1608 } | 1608 } |
1609 | 1609 |
1610 | 1610 |
1611 Object* KeyedLoadStubCompiler::CompileLoadConstant(String* name, | 1611 Object* KeyedLoadStubCompiler::CompileLoadConstant(String* name, |
1612 JSObject* receiver, | 1612 JSObject* receiver, |
1613 JSObject* holder, | 1613 JSObject* holder, |
1614 Object* value) { | 1614 Object* value) { |
1615 // ----------- S t a t e ------------- | 1615 // ----------- S t a t e ------------- |
1616 // -- esp[0] : return address | 1616 // -- esp[0] : return address |
1617 // -- esp[4] : name | 1617 // -- esp[4] : name |
1618 // -- esp[8] : receiver | 1618 // -- esp[8] : receiver |
1619 // ----------------------------------- | 1619 // ----------------------------------- |
1620 Label miss; | 1620 Label miss; |
1621 | 1621 |
1622 __ mov(eax, Operand(esp, kPointerSize)); | 1622 __ mov(eax, Operand(esp, kPointerSize)); |
1623 __ mov(ecx, Operand(esp, 2 * kPointerSize)); | 1623 __ mov(ecx, Operand(esp, 2 * kPointerSize)); |
1624 __ IncrementCounter(&Counters::keyed_load_constant_function, 1); | 1624 __ IncrementCounter(&COUNTER(keyed_load_constant_function), 1); |
1625 | 1625 |
1626 // Check that the name has not changed. | 1626 // Check that the name has not changed. |
1627 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 1627 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
1628 __ j(not_equal, &miss, not_taken); | 1628 __ j(not_equal, &miss, not_taken); |
1629 | 1629 |
1630 GenerateLoadConstant(receiver, holder, ecx, ebx, edx, | 1630 GenerateLoadConstant(receiver, holder, ecx, ebx, edx, |
1631 value, name, &miss); | 1631 value, name, &miss); |
1632 __ bind(&miss); | 1632 __ bind(&miss); |
1633 __ DecrementCounter(&Counters::keyed_load_constant_function, 1); | 1633 __ DecrementCounter(&COUNTER(keyed_load_constant_function), 1); |
1634 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1634 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1635 | 1635 |
1636 // Return the generated code. | 1636 // Return the generated code. |
1637 return GetCode(CONSTANT_FUNCTION, name); | 1637 return GetCode(CONSTANT_FUNCTION, name); |
1638 } | 1638 } |
1639 | 1639 |
1640 | 1640 |
1641 Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 1641 Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, |
1642 JSObject* holder, | 1642 JSObject* holder, |
1643 String* name) { | 1643 String* name) { |
1644 // ----------- S t a t e ------------- | 1644 // ----------- S t a t e ------------- |
1645 // -- esp[0] : return address | 1645 // -- esp[0] : return address |
1646 // -- esp[4] : name | 1646 // -- esp[4] : name |
1647 // -- esp[8] : receiver | 1647 // -- esp[8] : receiver |
1648 // ----------------------------------- | 1648 // ----------------------------------- |
1649 Label miss; | 1649 Label miss; |
1650 | 1650 |
1651 __ mov(eax, Operand(esp, kPointerSize)); | 1651 __ mov(eax, Operand(esp, kPointerSize)); |
1652 __ mov(ecx, Operand(esp, 2 * kPointerSize)); | 1652 __ mov(ecx, Operand(esp, 2 * kPointerSize)); |
1653 __ IncrementCounter(&Counters::keyed_load_interceptor, 1); | 1653 __ IncrementCounter(&COUNTER(keyed_load_interceptor), 1); |
1654 | 1654 |
1655 // Check that the name has not changed. | 1655 // Check that the name has not changed. |
1656 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 1656 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
1657 __ j(not_equal, &miss, not_taken); | 1657 __ j(not_equal, &miss, not_taken); |
1658 | 1658 |
1659 LookupResult lookup; | 1659 LookupResult lookup; |
1660 LookupPostInterceptor(holder, name, &lookup); | 1660 LookupPostInterceptor(holder, name, &lookup); |
1661 GenerateLoadInterceptor(receiver, | 1661 GenerateLoadInterceptor(receiver, |
1662 holder, | 1662 holder, |
1663 &lookup, | 1663 &lookup, |
1664 ecx, | 1664 ecx, |
1665 eax, | 1665 eax, |
1666 edx, | 1666 edx, |
1667 ebx, | 1667 ebx, |
1668 name, | 1668 name, |
1669 &miss); | 1669 &miss); |
1670 __ bind(&miss); | 1670 __ bind(&miss); |
1671 __ DecrementCounter(&Counters::keyed_load_interceptor, 1); | 1671 __ DecrementCounter(&COUNTER(keyed_load_interceptor), 1); |
1672 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1672 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1673 | 1673 |
1674 // Return the generated code. | 1674 // Return the generated code. |
1675 return GetCode(INTERCEPTOR, name); | 1675 return GetCode(INTERCEPTOR, name); |
1676 } | 1676 } |
1677 | 1677 |
1678 | 1678 |
1679 | 1679 |
1680 | 1680 |
1681 Object* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { | 1681 Object* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { |
1682 // ----------- S t a t e ------------- | 1682 // ----------- S t a t e ------------- |
1683 // -- esp[0] : return address | 1683 // -- esp[0] : return address |
1684 // -- esp[4] : name | 1684 // -- esp[4] : name |
1685 // -- esp[8] : receiver | 1685 // -- esp[8] : receiver |
1686 // ----------------------------------- | 1686 // ----------------------------------- |
1687 Label miss; | 1687 Label miss; |
1688 | 1688 |
1689 __ mov(eax, Operand(esp, kPointerSize)); | 1689 __ mov(eax, Operand(esp, kPointerSize)); |
1690 __ mov(ecx, Operand(esp, 2 * kPointerSize)); | 1690 __ mov(ecx, Operand(esp, 2 * kPointerSize)); |
1691 __ IncrementCounter(&Counters::keyed_load_array_length, 1); | 1691 __ IncrementCounter(&COUNTER(keyed_load_array_length), 1); |
1692 | 1692 |
1693 // Check that the name has not changed. | 1693 // Check that the name has not changed. |
1694 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 1694 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
1695 __ j(not_equal, &miss, not_taken); | 1695 __ j(not_equal, &miss, not_taken); |
1696 | 1696 |
1697 GenerateLoadArrayLength(masm(), ecx, edx, &miss); | 1697 GenerateLoadArrayLength(masm(), ecx, edx, &miss); |
1698 __ bind(&miss); | 1698 __ bind(&miss); |
1699 __ DecrementCounter(&Counters::keyed_load_array_length, 1); | 1699 __ DecrementCounter(&COUNTER(keyed_load_array_length), 1); |
1700 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1700 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1701 | 1701 |
1702 // Return the generated code. | 1702 // Return the generated code. |
1703 return GetCode(CALLBACKS, name); | 1703 return GetCode(CALLBACKS, name); |
1704 } | 1704 } |
1705 | 1705 |
1706 | 1706 |
1707 Object* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { | 1707 Object* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { |
1708 // ----------- S t a t e ------------- | 1708 // ----------- S t a t e ------------- |
1709 // -- esp[0] : return address | 1709 // -- esp[0] : return address |
1710 // -- esp[4] : name | 1710 // -- esp[4] : name |
1711 // -- esp[8] : receiver | 1711 // -- esp[8] : receiver |
1712 // ----------------------------------- | 1712 // ----------------------------------- |
1713 Label miss; | 1713 Label miss; |
1714 | 1714 |
1715 __ mov(eax, Operand(esp, kPointerSize)); | 1715 __ mov(eax, Operand(esp, kPointerSize)); |
1716 __ mov(ecx, Operand(esp, 2 * kPointerSize)); | 1716 __ mov(ecx, Operand(esp, 2 * kPointerSize)); |
1717 __ IncrementCounter(&Counters::keyed_load_string_length, 1); | 1717 __ IncrementCounter(&COUNTER(keyed_load_string_length), 1); |
1718 | 1718 |
1719 // Check that the name has not changed. | 1719 // Check that the name has not changed. |
1720 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 1720 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
1721 __ j(not_equal, &miss, not_taken); | 1721 __ j(not_equal, &miss, not_taken); |
1722 | 1722 |
1723 GenerateLoadStringLength(masm(), ecx, edx, &miss); | 1723 GenerateLoadStringLength(masm(), ecx, edx, &miss); |
1724 __ bind(&miss); | 1724 __ bind(&miss); |
1725 __ DecrementCounter(&Counters::keyed_load_string_length, 1); | 1725 __ DecrementCounter(&COUNTER(keyed_load_string_length), 1); |
1726 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1726 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1727 | 1727 |
1728 // Return the generated code. | 1728 // Return the generated code. |
1729 return GetCode(CALLBACKS, name); | 1729 return GetCode(CALLBACKS, name); |
1730 } | 1730 } |
1731 | 1731 |
1732 | 1732 |
1733 Object* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { | 1733 Object* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { |
1734 // ----------- S t a t e ------------- | 1734 // ----------- S t a t e ------------- |
1735 // -- esp[0] : return address | 1735 // -- esp[0] : return address |
1736 // -- esp[4] : name | 1736 // -- esp[4] : name |
1737 // -- esp[8] : receiver | 1737 // -- esp[8] : receiver |
1738 // ----------------------------------- | 1738 // ----------------------------------- |
1739 Label miss; | 1739 Label miss; |
1740 | 1740 |
1741 __ mov(eax, Operand(esp, kPointerSize)); | 1741 __ mov(eax, Operand(esp, kPointerSize)); |
1742 __ mov(ecx, Operand(esp, 2 * kPointerSize)); | 1742 __ mov(ecx, Operand(esp, 2 * kPointerSize)); |
1743 __ IncrementCounter(&Counters::keyed_load_function_prototype, 1); | 1743 __ IncrementCounter(&COUNTER(keyed_load_function_prototype), 1); |
1744 | 1744 |
1745 // Check that the name has not changed. | 1745 // Check that the name has not changed. |
1746 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 1746 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
1747 __ j(not_equal, &miss, not_taken); | 1747 __ j(not_equal, &miss, not_taken); |
1748 | 1748 |
1749 GenerateLoadFunctionPrototype(masm(), ecx, edx, ebx, &miss); | 1749 GenerateLoadFunctionPrototype(masm(), ecx, edx, ebx, &miss); |
1750 __ bind(&miss); | 1750 __ bind(&miss); |
1751 __ DecrementCounter(&Counters::keyed_load_function_prototype, 1); | 1751 __ DecrementCounter(&COUNTER(keyed_load_function_prototype), 1); |
1752 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1752 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1753 | 1753 |
1754 // Return the generated code. | 1754 // Return the generated code. |
1755 return GetCode(CALLBACKS, name); | 1755 return GetCode(CALLBACKS, name); |
1756 } | 1756 } |
1757 | 1757 |
1758 | 1758 |
1759 // Specialized stub for constructing objects from functions which only have only | 1759 // Specialized stub for constructing objects from functions which only have only |
1760 // simple assignments of the form this.x = ...; in their body. | 1760 // simple assignments of the form this.x = ...; in their body. |
1761 Object* ConstructStubCompiler::CompileConstructStub( | 1761 Object* ConstructStubCompiler::CompileConstructStub( |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1864 | 1864 |
1865 // Move argc to ebx and retrieve and tag the JSObject to return. | 1865 // Move argc to ebx and retrieve and tag the JSObject to return. |
1866 __ mov(ebx, eax); | 1866 __ mov(ebx, eax); |
1867 __ pop(eax); | 1867 __ pop(eax); |
1868 __ or_(Operand(eax), Immediate(kHeapObjectTag)); | 1868 __ or_(Operand(eax), Immediate(kHeapObjectTag)); |
1869 | 1869 |
1870 // Remove caller arguments and receiver from the stack and return. | 1870 // Remove caller arguments and receiver from the stack and return. |
1871 __ pop(ecx); | 1871 __ pop(ecx); |
1872 __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize)); | 1872 __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize)); |
1873 __ push(ecx); | 1873 __ push(ecx); |
1874 __ IncrementCounter(&Counters::constructed_objects, 1); | 1874 __ IncrementCounter(&COUNTER(constructed_objects), 1); |
1875 __ IncrementCounter(&Counters::constructed_objects_stub, 1); | 1875 __ IncrementCounter(&COUNTER(constructed_objects_stub), 1); |
1876 __ ret(0); | 1876 __ ret(0); |
1877 | 1877 |
1878 // Jump to the generic stub in case the specialized code cannot handle the | 1878 // Jump to the generic stub in case the specialized code cannot handle the |
1879 // construction. | 1879 // construction. |
1880 __ bind(&generic_stub_call); | 1880 __ bind(&generic_stub_call); |
1881 Code* code = Builtins::builtin(Builtins::JSConstructStubGeneric); | 1881 Code* code = Builtins::builtin(Builtins::JSConstructStubGeneric); |
1882 Handle<Code> generic_construct_stub(code); | 1882 Handle<Code> generic_construct_stub(code); |
1883 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); | 1883 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); |
1884 | 1884 |
1885 // Return the generated code. | 1885 // Return the generated code. |
1886 return GetCode(); | 1886 return GetCode(); |
1887 } | 1887 } |
1888 | 1888 |
1889 | 1889 |
1890 #undef __ | 1890 #undef __ |
1891 | 1891 |
1892 } } // namespace v8::internal | 1892 } } // namespace v8::internal |
OLD | NEW |