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