OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
850 __ cmp(r1, r0); | 850 __ cmp(r1, r0); |
851 __ b(ne, &next_test); | 851 __ b(ne, &next_test); |
852 __ Drop(1); // Switch value is no longer needed. | 852 __ Drop(1); // Switch value is no longer needed. |
853 __ b(clause->body_target()); | 853 __ b(clause->body_target()); |
854 __ bind(&slow_case); | 854 __ bind(&slow_case); |
855 } | 855 } |
856 | 856 |
857 // Record position before stub call for type feedback. | 857 // Record position before stub call for type feedback. |
858 SetSourcePosition(clause->position()); | 858 SetSourcePosition(clause->position()); |
859 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); | 859 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); |
860 EmitCallIC(ic, &patch_site); | 860 EmitCallIC(ic, &patch_site, clause->label()->id()); |
861 __ cmp(r0, Operand(0)); | 861 __ cmp(r0, Operand(0)); |
862 __ b(ne, &next_test); | 862 __ b(ne, &next_test); |
863 __ Drop(1); // Switch value is no longer needed. | 863 __ Drop(1); // Switch value is no longer needed. |
864 __ b(clause->body_target()); | 864 __ b(clause->body_target()); |
865 } | 865 } |
866 | 866 |
867 // Discard the test value and jump to the default if present, otherwise to | 867 // Discard the test value and jump to the default if present, otherwise to |
868 // the end of the statement. | 868 // the end of the statement. |
869 __ bind(&next_test); | 869 __ bind(&next_test); |
870 __ Drop(1); // Switch value is no longer needed. | 870 __ Drop(1); // Switch value is no longer needed. |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1102 context()->Plug(r0); | 1102 context()->Plug(r0); |
1103 } | 1103 } |
1104 | 1104 |
1105 | 1105 |
1106 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | 1106 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
1107 Comment cmnt(masm_, "[ VariableProxy"); | 1107 Comment cmnt(masm_, "[ VariableProxy"); |
1108 EmitVariableLoad(expr->var()); | 1108 EmitVariableLoad(expr->var()); |
1109 } | 1109 } |
1110 | 1110 |
1111 | 1111 |
| 1112 void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions( |
| 1113 Slot* slot, |
| 1114 TypeofState typeof_state, |
| 1115 Label* slow) { |
| 1116 Register current = cp; |
| 1117 Register next = r1; |
| 1118 Register temp = r2; |
| 1119 |
| 1120 Scope* s = scope(); |
| 1121 while (s != NULL) { |
| 1122 if (s->num_heap_slots() > 0) { |
| 1123 if (s->calls_eval()) { |
| 1124 // Check that extension is NULL. |
| 1125 __ ldr(temp, ContextOperand(current, Context::EXTENSION_INDEX)); |
| 1126 __ tst(temp, temp); |
| 1127 __ b(ne, slow); |
| 1128 } |
| 1129 // Load next context in chain. |
| 1130 __ ldr(next, ContextOperand(current, Context::CLOSURE_INDEX)); |
| 1131 __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset)); |
| 1132 // Walk the rest of the chain without clobbering cp. |
| 1133 current = next; |
| 1134 } |
| 1135 // If no outer scope calls eval, we do not need to check more |
| 1136 // context extensions. |
| 1137 if (!s->outer_scope_calls_eval() || s->is_eval_scope()) break; |
| 1138 s = s->outer_scope(); |
| 1139 } |
| 1140 |
| 1141 if (s->is_eval_scope()) { |
| 1142 Label loop, fast; |
| 1143 if (!current.is(next)) { |
| 1144 __ Move(next, current); |
| 1145 } |
| 1146 __ bind(&loop); |
| 1147 // Terminate at global context. |
| 1148 __ ldr(temp, FieldMemOperand(next, HeapObject::kMapOffset)); |
| 1149 __ LoadRoot(ip, Heap::kGlobalContextMapRootIndex); |
| 1150 __ cmp(temp, ip); |
| 1151 __ b(eq, &fast); |
| 1152 // Check that extension is NULL. |
| 1153 __ ldr(temp, ContextOperand(next, Context::EXTENSION_INDEX)); |
| 1154 __ tst(temp, temp); |
| 1155 __ b(ne, slow); |
| 1156 // Load next context in chain. |
| 1157 __ ldr(next, ContextOperand(next, Context::CLOSURE_INDEX)); |
| 1158 __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset)); |
| 1159 __ b(&loop); |
| 1160 __ bind(&fast); |
| 1161 } |
| 1162 |
| 1163 __ ldr(r0, GlobalObjectOperand()); |
| 1164 __ mov(r2, Operand(slot->var()->name())); |
| 1165 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
| 1166 ? RelocInfo::CODE_TARGET |
| 1167 : RelocInfo::CODE_TARGET_CONTEXT; |
| 1168 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 1169 EmitCallIC(ic, mode); |
| 1170 } |
| 1171 |
| 1172 |
1112 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( | 1173 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( |
1113 Slot* slot, | 1174 Slot* slot, |
1114 Label* slow) { | 1175 Label* slow) { |
1115 ASSERT(slot->type() == Slot::CONTEXT); | 1176 ASSERT(slot->type() == Slot::CONTEXT); |
1116 Register context = cp; | 1177 Register context = cp; |
1117 Register next = r3; | 1178 Register next = r3; |
1118 Register temp = r4; | 1179 Register temp = r4; |
1119 | 1180 |
1120 for (Scope* s = scope(); s != slot->var()->scope(); s = s->outer_scope()) { | 1181 for (Scope* s = scope(); s != slot->var()->scope(); s = s->outer_scope()) { |
1121 if (s->num_heap_slots() > 0) { | 1182 if (s->num_heap_slots() > 0) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1189 isolate()->builtins()->KeyedLoadIC_Initialize(); | 1250 isolate()->builtins()->KeyedLoadIC_Initialize(); |
1190 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1251 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1191 __ jmp(done); | 1252 __ jmp(done); |
1192 } | 1253 } |
1193 } | 1254 } |
1194 } | 1255 } |
1195 } | 1256 } |
1196 } | 1257 } |
1197 | 1258 |
1198 | 1259 |
1199 void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions( | |
1200 Slot* slot, | |
1201 TypeofState typeof_state, | |
1202 Label* slow) { | |
1203 Register current = cp; | |
1204 Register next = r1; | |
1205 Register temp = r2; | |
1206 | |
1207 Scope* s = scope(); | |
1208 while (s != NULL) { | |
1209 if (s->num_heap_slots() > 0) { | |
1210 if (s->calls_eval()) { | |
1211 // Check that extension is NULL. | |
1212 __ ldr(temp, ContextOperand(current, Context::EXTENSION_INDEX)); | |
1213 __ tst(temp, temp); | |
1214 __ b(ne, slow); | |
1215 } | |
1216 // Load next context in chain. | |
1217 __ ldr(next, ContextOperand(current, Context::CLOSURE_INDEX)); | |
1218 __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset)); | |
1219 // Walk the rest of the chain without clobbering cp. | |
1220 current = next; | |
1221 } | |
1222 // If no outer scope calls eval, we do not need to check more | |
1223 // context extensions. | |
1224 if (!s->outer_scope_calls_eval() || s->is_eval_scope()) break; | |
1225 s = s->outer_scope(); | |
1226 } | |
1227 | |
1228 if (s->is_eval_scope()) { | |
1229 Label loop, fast; | |
1230 if (!current.is(next)) { | |
1231 __ Move(next, current); | |
1232 } | |
1233 __ bind(&loop); | |
1234 // Terminate at global context. | |
1235 __ ldr(temp, FieldMemOperand(next, HeapObject::kMapOffset)); | |
1236 __ LoadRoot(ip, Heap::kGlobalContextMapRootIndex); | |
1237 __ cmp(temp, ip); | |
1238 __ b(eq, &fast); | |
1239 // Check that extension is NULL. | |
1240 __ ldr(temp, ContextOperand(next, Context::EXTENSION_INDEX)); | |
1241 __ tst(temp, temp); | |
1242 __ b(ne, slow); | |
1243 // Load next context in chain. | |
1244 __ ldr(next, ContextOperand(next, Context::CLOSURE_INDEX)); | |
1245 __ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset)); | |
1246 __ b(&loop); | |
1247 __ bind(&fast); | |
1248 } | |
1249 | |
1250 __ ldr(r0, GlobalObjectOperand()); | |
1251 __ mov(r2, Operand(slot->var()->name())); | |
1252 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | |
1253 ? RelocInfo::CODE_TARGET | |
1254 : RelocInfo::CODE_TARGET_CONTEXT; | |
1255 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | |
1256 EmitCallIC(ic, mode); | |
1257 } | |
1258 | |
1259 | |
1260 void FullCodeGenerator::EmitVariableLoad(Variable* var) { | 1260 void FullCodeGenerator::EmitVariableLoad(Variable* var) { |
1261 // Four cases: non-this global variables, lookup slots, all other | 1261 // Four cases: non-this global variables, lookup slots, all other |
1262 // types of slots, and parameters that rewrite to explicit property | 1262 // types of slots, and parameters that rewrite to explicit property |
1263 // accesses on the arguments object. | 1263 // accesses on the arguments object. |
1264 Slot* slot = var->AsSlot(); | 1264 Slot* slot = var->AsSlot(); |
1265 Property* property = var->AsProperty(); | 1265 Property* property = var->AsProperty(); |
1266 | 1266 |
1267 if (var->is_global() && !var->is_this()) { | 1267 if (var->is_global() && !var->is_this()) { |
1268 Comment cmnt(masm_, "Global variable"); | 1268 Comment cmnt(masm_, "Global variable"); |
1269 // Use inline caching. Variable name is passed in r2 and the global | 1269 // Use inline caching. Variable name is passed in r2 and the global |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1431 UNREACHABLE(); | 1431 UNREACHABLE(); |
1432 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1432 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1433 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1433 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); |
1434 // Fall through. | 1434 // Fall through. |
1435 case ObjectLiteral::Property::COMPUTED: | 1435 case ObjectLiteral::Property::COMPUTED: |
1436 if (key->handle()->IsSymbol()) { | 1436 if (key->handle()->IsSymbol()) { |
1437 if (property->emit_store()) { | 1437 if (property->emit_store()) { |
1438 VisitForAccumulatorValue(value); | 1438 VisitForAccumulatorValue(value); |
1439 __ mov(r2, Operand(key->handle())); | 1439 __ mov(r2, Operand(key->handle())); |
1440 __ ldr(r1, MemOperand(sp)); | 1440 __ ldr(r1, MemOperand(sp)); |
1441 Handle<Code> ic = isolate()->builtins()->StoreIC_Initialize(); | 1441 Handle<Code> ic = is_strict_mode() |
1442 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1442 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 1443 : isolate()->builtins()->StoreIC_Initialize(); |
| 1444 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, key->id()); |
1443 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1445 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
1444 } else { | 1446 } else { |
1445 VisitForEffect(value); | 1447 VisitForEffect(value); |
1446 } | 1448 } |
1447 break; | 1449 break; |
1448 } | 1450 } |
1449 // Fall through. | 1451 // Fall through. |
1450 case ObjectLiteral::Property::PROTOTYPE: | 1452 case ObjectLiteral::Property::PROTOTYPE: |
1451 // Duplicate receiver on stack. | 1453 // Duplicate receiver on stack. |
1452 __ ldr(r0, MemOperand(sp)); | 1454 __ ldr(r0, MemOperand(sp)); |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1644 Token::Value op = expr->binary_op(); | 1646 Token::Value op = expr->binary_op(); |
1645 __ push(r0); // Left operand goes on the stack. | 1647 __ push(r0); // Left operand goes on the stack. |
1646 VisitForAccumulatorValue(expr->value()); | 1648 VisitForAccumulatorValue(expr->value()); |
1647 | 1649 |
1648 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() | 1650 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() |
1649 ? OVERWRITE_RIGHT | 1651 ? OVERWRITE_RIGHT |
1650 : NO_OVERWRITE; | 1652 : NO_OVERWRITE; |
1651 SetSourcePosition(expr->position() + 1); | 1653 SetSourcePosition(expr->position() + 1); |
1652 AccumulatorValueContext context(this); | 1654 AccumulatorValueContext context(this); |
1653 if (ShouldInlineSmiCase(op)) { | 1655 if (ShouldInlineSmiCase(op)) { |
1654 EmitInlineSmiBinaryOp(expr, | 1656 EmitInlineSmiBinaryOp(expr->binary_operation(), |
1655 op, | 1657 op, |
1656 mode, | 1658 mode, |
1657 expr->target(), | 1659 expr->target(), |
1658 expr->value()); | 1660 expr->value()); |
1659 } else { | 1661 } else { |
1660 EmitBinaryOp(op, mode); | 1662 EmitBinaryOp(expr->binary_operation(), op, mode); |
1661 } | 1663 } |
1662 | 1664 |
1663 // Deoptimization point in case the binary operation may have side effects. | 1665 // Deoptimization point in case the binary operation may have side effects. |
1664 PrepareForBailout(expr->binary_operation(), TOS_REG); | 1666 PrepareForBailout(expr->binary_operation(), TOS_REG); |
1665 } else { | 1667 } else { |
1666 VisitForAccumulatorValue(expr->value()); | 1668 VisitForAccumulatorValue(expr->value()); |
1667 } | 1669 } |
1668 | 1670 |
1669 // Record source position before possible IC call. | 1671 // Record source position before possible IC call. |
1670 SetSourcePosition(expr->position()); | 1672 SetSourcePosition(expr->position()); |
(...skipping 15 matching lines...) Expand all Loading... |
1686 } | 1688 } |
1687 } | 1689 } |
1688 | 1690 |
1689 | 1691 |
1690 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1692 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
1691 SetSourcePosition(prop->position()); | 1693 SetSourcePosition(prop->position()); |
1692 Literal* key = prop->key()->AsLiteral(); | 1694 Literal* key = prop->key()->AsLiteral(); |
1693 __ mov(r2, Operand(key->handle())); | 1695 __ mov(r2, Operand(key->handle())); |
1694 // Call load IC. It has arguments receiver and property name r0 and r2. | 1696 // Call load IC. It has arguments receiver and property name r0 and r2. |
1695 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1697 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
1696 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1698 if (prop->is_synthetic()) { |
| 1699 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1700 } else { |
| 1701 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, prop->id()); |
| 1702 } |
1697 } | 1703 } |
1698 | 1704 |
1699 | 1705 |
1700 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1706 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
1701 SetSourcePosition(prop->position()); | 1707 SetSourcePosition(prop->position()); |
1702 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1708 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
1703 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 1709 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
1704 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1710 if (prop->is_synthetic()) { |
| 1711 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
| 1712 } else { |
| 1713 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, prop->id()); |
| 1714 } |
1705 } | 1715 } |
1706 | 1716 |
1707 | 1717 |
1708 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, | 1718 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
1709 Token::Value op, | 1719 Token::Value op, |
1710 OverwriteMode mode, | 1720 OverwriteMode mode, |
1711 Expression* left_expr, | 1721 Expression* left_expr, |
1712 Expression* right_expr) { | 1722 Expression* right_expr) { |
1713 Label done, smi_case, stub_call; | 1723 Label done, smi_case, stub_call; |
1714 | 1724 |
1715 Register scratch1 = r2; | 1725 Register scratch1 = r2; |
1716 Register scratch2 = r3; | 1726 Register scratch2 = r3; |
1717 | 1727 |
1718 // Get the arguments. | 1728 // Get the arguments. |
1719 Register left = r1; | 1729 Register left = r1; |
1720 Register right = r0; | 1730 Register right = r0; |
1721 __ pop(left); | 1731 __ pop(left); |
1722 | 1732 |
1723 // Perform combined smi check on both operands. | 1733 // Perform combined smi check on both operands. |
1724 __ orr(scratch1, left, Operand(right)); | 1734 __ orr(scratch1, left, Operand(right)); |
1725 STATIC_ASSERT(kSmiTag == 0); | 1735 STATIC_ASSERT(kSmiTag == 0); |
1726 JumpPatchSite patch_site(masm_); | 1736 JumpPatchSite patch_site(masm_); |
1727 patch_site.EmitJumpIfSmi(scratch1, &smi_case); | 1737 patch_site.EmitJumpIfSmi(scratch1, &smi_case); |
1728 | 1738 |
1729 __ bind(&stub_call); | 1739 __ bind(&stub_call); |
1730 TypeRecordingBinaryOpStub stub(op, mode); | 1740 TypeRecordingBinaryOpStub stub(op, mode); |
1731 EmitCallIC(stub.GetCode(), &patch_site); | 1741 EmitCallIC(stub.GetCode(), &patch_site, expr->id()); |
1732 __ jmp(&done); | 1742 __ jmp(&done); |
1733 | 1743 |
1734 __ bind(&smi_case); | 1744 __ bind(&smi_case); |
1735 // Smi case. This code works the same way as the smi-smi case in the type | 1745 // Smi case. This code works the same way as the smi-smi case in the type |
1736 // recording binary operation stub, see | 1746 // recording binary operation stub, see |
1737 // TypeRecordingBinaryOpStub::GenerateSmiSmiOperation for comments. | 1747 // TypeRecordingBinaryOpStub::GenerateSmiSmiOperation for comments. |
1738 switch (op) { | 1748 switch (op) { |
1739 case Token::SAR: | 1749 case Token::SAR: |
1740 __ b(&stub_call); | 1750 __ b(&stub_call); |
1741 __ GetLeastBitsFromSmi(scratch1, right, 5); | 1751 __ GetLeastBitsFromSmi(scratch1, right, 5); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1797 break; | 1807 break; |
1798 default: | 1808 default: |
1799 UNREACHABLE(); | 1809 UNREACHABLE(); |
1800 } | 1810 } |
1801 | 1811 |
1802 __ bind(&done); | 1812 __ bind(&done); |
1803 context()->Plug(r0); | 1813 context()->Plug(r0); |
1804 } | 1814 } |
1805 | 1815 |
1806 | 1816 |
1807 void FullCodeGenerator::EmitBinaryOp(Token::Value op, | 1817 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
| 1818 Token::Value op, |
1808 OverwriteMode mode) { | 1819 OverwriteMode mode) { |
1809 __ pop(r1); | 1820 __ pop(r1); |
1810 TypeRecordingBinaryOpStub stub(op, mode); | 1821 TypeRecordingBinaryOpStub stub(op, mode); |
1811 EmitCallIC(stub.GetCode(), NULL); | 1822 EmitCallIC(stub.GetCode(), NULL, expr->id()); |
1812 context()->Plug(r0); | 1823 context()->Plug(r0); |
1813 } | 1824 } |
1814 | 1825 |
1815 | 1826 |
1816 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { | 1827 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { |
1817 // Invalid left-hand sides are rewritten to have a 'throw | 1828 // Invalid left-hand sides are rewritten to have a 'throw |
1818 // ReferenceError' on the left-hand side. | 1829 // ReferenceError' on the left-hand side. |
1819 if (!expr->IsValidLeftHandSide()) { | 1830 if (!expr->IsValidLeftHandSide()) { |
1820 VisitForEffect(expr); | 1831 VisitForEffect(expr); |
1821 return; | 1832 return; |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1999 // receiver into fast case. | 2010 // receiver into fast case. |
2000 if (expr->ends_initialization_block()) { | 2011 if (expr->ends_initialization_block()) { |
2001 __ ldr(r1, MemOperand(sp)); | 2012 __ ldr(r1, MemOperand(sp)); |
2002 } else { | 2013 } else { |
2003 __ pop(r1); | 2014 __ pop(r1); |
2004 } | 2015 } |
2005 | 2016 |
2006 Handle<Code> ic = is_strict_mode() | 2017 Handle<Code> ic = is_strict_mode() |
2007 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 2018 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
2008 : isolate()->builtins()->StoreIC_Initialize(); | 2019 : isolate()->builtins()->StoreIC_Initialize(); |
2009 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2020 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id()); |
2010 | 2021 |
2011 // If the assignment ends an initialization block, revert to fast case. | 2022 // If the assignment ends an initialization block, revert to fast case. |
2012 if (expr->ends_initialization_block()) { | 2023 if (expr->ends_initialization_block()) { |
2013 __ push(r0); // Result of assignment, saved even if not needed. | 2024 __ push(r0); // Result of assignment, saved even if not needed. |
2014 // Receiver is under the result value. | 2025 // Receiver is under the result value. |
2015 __ ldr(ip, MemOperand(sp, kPointerSize)); | 2026 __ ldr(ip, MemOperand(sp, kPointerSize)); |
2016 __ push(ip); | 2027 __ push(ip); |
2017 __ CallRuntime(Runtime::kToFastProperties, 1); | 2028 __ CallRuntime(Runtime::kToFastProperties, 1); |
2018 __ pop(r0); | 2029 __ pop(r0); |
2019 __ Drop(1); | 2030 __ Drop(1); |
(...skipping 25 matching lines...) Expand all Loading... |
2045 // receiver into fast case. | 2056 // receiver into fast case. |
2046 if (expr->ends_initialization_block()) { | 2057 if (expr->ends_initialization_block()) { |
2047 __ ldr(r2, MemOperand(sp)); | 2058 __ ldr(r2, MemOperand(sp)); |
2048 } else { | 2059 } else { |
2049 __ pop(r2); | 2060 __ pop(r2); |
2050 } | 2061 } |
2051 | 2062 |
2052 Handle<Code> ic = is_strict_mode() | 2063 Handle<Code> ic = is_strict_mode() |
2053 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 2064 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
2054 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 2065 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
2055 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2066 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id()); |
2056 | 2067 |
2057 // If the assignment ends an initialization block, revert to fast case. | 2068 // If the assignment ends an initialization block, revert to fast case. |
2058 if (expr->ends_initialization_block()) { | 2069 if (expr->ends_initialization_block()) { |
2059 __ push(r0); // Result of assignment, saved even if not needed. | 2070 __ push(r0); // Result of assignment, saved even if not needed. |
2060 // Receiver is under the result value. | 2071 // Receiver is under the result value. |
2061 __ ldr(ip, MemOperand(sp, kPointerSize)); | 2072 __ ldr(ip, MemOperand(sp, kPointerSize)); |
2062 __ push(ip); | 2073 __ push(ip); |
2063 __ CallRuntime(Runtime::kToFastProperties, 1); | 2074 __ CallRuntime(Runtime::kToFastProperties, 1); |
2064 __ pop(r0); | 2075 __ pop(r0); |
2065 __ Drop(1); | 2076 __ Drop(1); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2097 VisitForStackValue(args->at(i)); | 2108 VisitForStackValue(args->at(i)); |
2098 } | 2109 } |
2099 __ mov(r2, Operand(name)); | 2110 __ mov(r2, Operand(name)); |
2100 } | 2111 } |
2101 // Record source position for debugger. | 2112 // Record source position for debugger. |
2102 SetSourcePosition(expr->position()); | 2113 SetSourcePosition(expr->position()); |
2103 // Call the IC initialization code. | 2114 // Call the IC initialization code. |
2104 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2115 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
2105 Handle<Code> ic = | 2116 Handle<Code> ic = |
2106 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop); | 2117 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop); |
2107 EmitCallIC(ic, mode); | 2118 unsigned ast_id = |
| 2119 (mode == RelocInfo::CODE_TARGET_WITH_ID) ? expr->id() : kNoASTId; |
| 2120 EmitCallIC(ic, mode, ast_id); |
2108 RecordJSReturnSite(expr); | 2121 RecordJSReturnSite(expr); |
2109 // Restore context register. | 2122 // Restore context register. |
2110 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2123 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2111 context()->Plug(r0); | 2124 context()->Plug(r0); |
2112 } | 2125 } |
2113 | 2126 |
2114 | 2127 |
2115 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2128 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
2116 Expression* key, | 2129 Expression* key, |
2117 RelocInfo::Mode mode) { | 2130 RelocInfo::Mode mode) { |
(...skipping 14 matching lines...) Expand all Loading... |
2132 VisitForStackValue(args->at(i)); | 2145 VisitForStackValue(args->at(i)); |
2133 } | 2146 } |
2134 } | 2147 } |
2135 // Record source position for debugger. | 2148 // Record source position for debugger. |
2136 SetSourcePosition(expr->position()); | 2149 SetSourcePosition(expr->position()); |
2137 // Call the IC initialization code. | 2150 // Call the IC initialization code. |
2138 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2151 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
2139 Handle<Code> ic = | 2152 Handle<Code> ic = |
2140 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); | 2153 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); |
2141 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. | 2154 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. |
2142 EmitCallIC(ic, mode); | 2155 EmitCallIC(ic, mode, expr->id()); |
2143 RecordJSReturnSite(expr); | 2156 RecordJSReturnSite(expr); |
2144 // Restore context register. | 2157 // Restore context register. |
2145 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2158 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2146 context()->DropAndPlug(1, r0); // Drop the key still on the stack. | 2159 context()->DropAndPlug(1, r0); // Drop the key still on the stack. |
2147 } | 2160 } |
2148 | 2161 |
2149 | 2162 |
2150 void FullCodeGenerator::EmitCallWithStub(Call* expr) { | 2163 void FullCodeGenerator::EmitCallWithStub(Call* expr) { |
2151 // Code common for calls using the call stub. | 2164 // Code common for calls using the call stub. |
2152 ZoneList<Expression*>* args = expr->arguments(); | 2165 ZoneList<Expression*>* args = expr->arguments(); |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2308 EmitCallWithStub(expr); | 2321 EmitCallWithStub(expr); |
2309 } else if (fun->AsProperty() != NULL) { | 2322 } else if (fun->AsProperty() != NULL) { |
2310 // Call to an object property. | 2323 // Call to an object property. |
2311 Property* prop = fun->AsProperty(); | 2324 Property* prop = fun->AsProperty(); |
2312 Literal* key = prop->key()->AsLiteral(); | 2325 Literal* key = prop->key()->AsLiteral(); |
2313 if (key != NULL && key->handle()->IsSymbol()) { | 2326 if (key != NULL && key->handle()->IsSymbol()) { |
2314 // Call to a named property, use call IC. | 2327 // Call to a named property, use call IC. |
2315 { PreservePositionScope scope(masm()->positions_recorder()); | 2328 { PreservePositionScope scope(masm()->positions_recorder()); |
2316 VisitForStackValue(prop->obj()); | 2329 VisitForStackValue(prop->obj()); |
2317 } | 2330 } |
2318 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); | 2331 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET_WITH_ID); |
2319 } else { | 2332 } else { |
2320 // Call to a keyed property. | 2333 // Call to a keyed property. |
2321 // For a synthetic property use keyed load IC followed by function call, | 2334 // For a synthetic property use keyed load IC followed by function call, |
2322 // for a regular property use keyed CallIC. | 2335 // for a regular property use keyed EmitCallIC. |
2323 if (prop->is_synthetic()) { | 2336 if (prop->is_synthetic()) { |
2324 // Do not visit the object and key subexpressions (they are shared | 2337 // Do not visit the object and key subexpressions (they are shared |
2325 // by all occurrences of the same rewritten parameter). | 2338 // by all occurrences of the same rewritten parameter). |
2326 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 2339 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
2327 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL); | 2340 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL); |
2328 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot(); | 2341 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot(); |
2329 MemOperand operand = EmitSlotSearch(slot, r1); | 2342 MemOperand operand = EmitSlotSearch(slot, r1); |
2330 __ ldr(r1, operand); | 2343 __ ldr(r1, operand); |
2331 | 2344 |
2332 ASSERT(prop->key()->AsLiteral() != NULL); | 2345 ASSERT(prop->key()->AsLiteral() != NULL); |
2333 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); | 2346 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); |
2334 __ mov(r0, Operand(prop->key()->AsLiteral()->handle())); | 2347 __ mov(r0, Operand(prop->key()->AsLiteral()->handle())); |
2335 | 2348 |
2336 // Record source code position for IC call. | 2349 // Record source code position for IC call. |
2337 SetSourcePosition(prop->position()); | 2350 SetSourcePosition(prop->position()); |
2338 | 2351 |
2339 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2352 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2340 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2353 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
2341 __ ldr(r1, GlobalObjectOperand()); | 2354 __ ldr(r1, GlobalObjectOperand()); |
2342 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2355 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
2343 __ Push(r0, r1); // Function, receiver. | 2356 __ Push(r0, r1); // Function, receiver. |
2344 EmitCallWithStub(expr); | 2357 EmitCallWithStub(expr); |
2345 } else { | 2358 } else { |
2346 { PreservePositionScope scope(masm()->positions_recorder()); | 2359 { PreservePositionScope scope(masm()->positions_recorder()); |
2347 VisitForStackValue(prop->obj()); | 2360 VisitForStackValue(prop->obj()); |
2348 } | 2361 } |
2349 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); | 2362 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET_WITH_ID); |
2350 } | 2363 } |
2351 } | 2364 } |
2352 } else { | 2365 } else { |
2353 { PreservePositionScope scope(masm()->positions_recorder()); | 2366 { PreservePositionScope scope(masm()->positions_recorder()); |
2354 VisitForStackValue(fun); | 2367 VisitForStackValue(fun); |
2355 } | 2368 } |
2356 // Load global receiver object. | 2369 // Load global receiver object. |
2357 __ ldr(r1, GlobalObjectOperand()); | 2370 __ ldr(r1, GlobalObjectOperand()); |
2358 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2371 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
2359 __ push(r1); | 2372 __ push(r1); |
(...skipping 1290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3650 int arg_count = args->length(); | 3663 int arg_count = args->length(); |
3651 for (int i = 0; i < arg_count; i++) { | 3664 for (int i = 0; i < arg_count; i++) { |
3652 VisitForStackValue(args->at(i)); | 3665 VisitForStackValue(args->at(i)); |
3653 } | 3666 } |
3654 | 3667 |
3655 if (expr->is_jsruntime()) { | 3668 if (expr->is_jsruntime()) { |
3656 // Call the JS runtime function. | 3669 // Call the JS runtime function. |
3657 __ mov(r2, Operand(expr->name())); | 3670 __ mov(r2, Operand(expr->name())); |
3658 Handle<Code> ic = | 3671 Handle<Code> ic = |
3659 isolate()->stub_cache()->ComputeCallInitialize(arg_count, NOT_IN_LOOP); | 3672 isolate()->stub_cache()->ComputeCallInitialize(arg_count, NOT_IN_LOOP); |
3660 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3673 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id()); |
3661 // Restore context register. | 3674 // Restore context register. |
3662 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3675 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3663 } else { | 3676 } else { |
3664 // Call the C runtime function. | 3677 // Call the C runtime function. |
3665 __ CallRuntime(expr->function(), arg_count); | 3678 __ CallRuntime(expr->function(), arg_count); |
3666 } | 3679 } |
3667 context()->Plug(r0); | 3680 context()->Plug(r0); |
3668 } | 3681 } |
3669 | 3682 |
3670 | 3683 |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3929 __ bind(&stub_call); | 3942 __ bind(&stub_call); |
3930 // Call stub. Undo operation first. | 3943 // Call stub. Undo operation first. |
3931 __ sub(r0, r0, Operand(Smi::FromInt(count_value))); | 3944 __ sub(r0, r0, Operand(Smi::FromInt(count_value))); |
3932 } | 3945 } |
3933 __ mov(r1, Operand(Smi::FromInt(count_value))); | 3946 __ mov(r1, Operand(Smi::FromInt(count_value))); |
3934 | 3947 |
3935 // Record position before stub call. | 3948 // Record position before stub call. |
3936 SetSourcePosition(expr->position()); | 3949 SetSourcePosition(expr->position()); |
3937 | 3950 |
3938 TypeRecordingBinaryOpStub stub(Token::ADD, NO_OVERWRITE); | 3951 TypeRecordingBinaryOpStub stub(Token::ADD, NO_OVERWRITE); |
3939 EmitCallIC(stub.GetCode(), &patch_site); | 3952 EmitCallIC(stub.GetCode(), &patch_site, expr->CountId()); |
3940 __ bind(&done); | 3953 __ bind(&done); |
3941 | 3954 |
3942 // Store the value returned in r0. | 3955 // Store the value returned in r0. |
3943 switch (assign_type) { | 3956 switch (assign_type) { |
3944 case VARIABLE: | 3957 case VARIABLE: |
3945 if (expr->is_postfix()) { | 3958 if (expr->is_postfix()) { |
3946 { EffectContext context(this); | 3959 { EffectContext context(this); |
3947 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3960 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
3948 Token::ASSIGN); | 3961 Token::ASSIGN); |
3949 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3962 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
(...skipping 10 matching lines...) Expand all Loading... |
3960 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3973 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3961 context()->Plug(r0); | 3974 context()->Plug(r0); |
3962 } | 3975 } |
3963 break; | 3976 break; |
3964 case NAMED_PROPERTY: { | 3977 case NAMED_PROPERTY: { |
3965 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 3978 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
3966 __ pop(r1); | 3979 __ pop(r1); |
3967 Handle<Code> ic = is_strict_mode() | 3980 Handle<Code> ic = is_strict_mode() |
3968 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 3981 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
3969 : isolate()->builtins()->StoreIC_Initialize(); | 3982 : isolate()->builtins()->StoreIC_Initialize(); |
3970 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3983 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id()); |
3971 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3984 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3972 if (expr->is_postfix()) { | 3985 if (expr->is_postfix()) { |
3973 if (!context()->IsEffect()) { | 3986 if (!context()->IsEffect()) { |
3974 context()->PlugTOS(); | 3987 context()->PlugTOS(); |
3975 } | 3988 } |
3976 } else { | 3989 } else { |
3977 context()->Plug(r0); | 3990 context()->Plug(r0); |
3978 } | 3991 } |
3979 break; | 3992 break; |
3980 } | 3993 } |
3981 case KEYED_PROPERTY: { | 3994 case KEYED_PROPERTY: { |
3982 __ pop(r1); // Key. | 3995 __ pop(r1); // Key. |
3983 __ pop(r2); // Receiver. | 3996 __ pop(r2); // Receiver. |
3984 Handle<Code> ic = is_strict_mode() | 3997 Handle<Code> ic = is_strict_mode() |
3985 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 3998 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
3986 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 3999 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
3987 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 4000 EmitCallIC(ic, RelocInfo::CODE_TARGET_WITH_ID, expr->id()); |
3988 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4001 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3989 if (expr->is_postfix()) { | 4002 if (expr->is_postfix()) { |
3990 if (!context()->IsEffect()) { | 4003 if (!context()->IsEffect()) { |
3991 context()->PlugTOS(); | 4004 context()->PlugTOS(); |
3992 } | 4005 } |
3993 } else { | 4006 } else { |
3994 context()->Plug(r0); | 4007 context()->Plug(r0); |
3995 } | 4008 } |
3996 break; | 4009 break; |
3997 } | 4010 } |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4206 __ orr(r2, r0, Operand(r1)); | 4219 __ orr(r2, r0, Operand(r1)); |
4207 patch_site.EmitJumpIfNotSmi(r2, &slow_case); | 4220 patch_site.EmitJumpIfNotSmi(r2, &slow_case); |
4208 __ cmp(r1, r0); | 4221 __ cmp(r1, r0); |
4209 Split(cond, if_true, if_false, NULL); | 4222 Split(cond, if_true, if_false, NULL); |
4210 __ bind(&slow_case); | 4223 __ bind(&slow_case); |
4211 } | 4224 } |
4212 | 4225 |
4213 // Record position and call the compare IC. | 4226 // Record position and call the compare IC. |
4214 SetSourcePosition(expr->position()); | 4227 SetSourcePosition(expr->position()); |
4215 Handle<Code> ic = CompareIC::GetUninitialized(op); | 4228 Handle<Code> ic = CompareIC::GetUninitialized(op); |
4216 EmitCallIC(ic, &patch_site); | 4229 EmitCallIC(ic, &patch_site, expr->id()); |
4217 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 4230 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
4218 __ cmp(r0, Operand(0)); | 4231 __ cmp(r0, Operand(0)); |
4219 Split(cond, if_true, if_false, fall_through); | 4232 Split(cond, if_true, if_false, fall_through); |
4220 } | 4233 } |
4221 } | 4234 } |
4222 | 4235 |
4223 // Convert the result of the comparison into one expected for this | 4236 // Convert the result of the comparison into one expected for this |
4224 // expression's context. | 4237 // expression's context. |
4225 context()->Plug(if_true, if_false); | 4238 context()->Plug(if_true, if_false); |
4226 } | 4239 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4268 Register FullCodeGenerator::result_register() { | 4281 Register FullCodeGenerator::result_register() { |
4269 return r0; | 4282 return r0; |
4270 } | 4283 } |
4271 | 4284 |
4272 | 4285 |
4273 Register FullCodeGenerator::context_register() { | 4286 Register FullCodeGenerator::context_register() { |
4274 return cp; | 4287 return cp; |
4275 } | 4288 } |
4276 | 4289 |
4277 | 4290 |
4278 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { | 4291 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, |
| 4292 RelocInfo::Mode mode, |
| 4293 unsigned ast_id) { |
4279 ASSERT(mode == RelocInfo::CODE_TARGET || | 4294 ASSERT(mode == RelocInfo::CODE_TARGET || |
4280 mode == RelocInfo::CODE_TARGET_CONTEXT); | 4295 mode == RelocInfo::CODE_TARGET_CONTEXT || |
| 4296 mode == RelocInfo::CODE_TARGET_WITH_ID); |
4281 Counters* counters = isolate()->counters(); | 4297 Counters* counters = isolate()->counters(); |
4282 switch (ic->kind()) { | 4298 switch (ic->kind()) { |
4283 case Code::LOAD_IC: | 4299 case Code::LOAD_IC: |
4284 __ IncrementCounter(counters->named_load_full(), 1, r1, r2); | 4300 __ IncrementCounter(counters->named_load_full(), 1, r1, r2); |
4285 break; | 4301 break; |
4286 case Code::KEYED_LOAD_IC: | 4302 case Code::KEYED_LOAD_IC: |
4287 __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2); | 4303 __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2); |
4288 break; | 4304 break; |
4289 case Code::STORE_IC: | 4305 case Code::STORE_IC: |
4290 __ IncrementCounter(counters->named_store_full(), 1, r1, r2); | 4306 __ IncrementCounter(counters->named_store_full(), 1, r1, r2); |
4291 break; | 4307 break; |
4292 case Code::KEYED_STORE_IC: | 4308 case Code::KEYED_STORE_IC: |
4293 __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2); | 4309 __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2); |
4294 default: | 4310 default: |
4295 break; | 4311 break; |
4296 } | 4312 } |
4297 __ Call(ic, mode); | 4313 if (mode == RelocInfo::CODE_TARGET_WITH_ID) { |
| 4314 ASSERT(ast_id != kNoASTId); |
| 4315 __ CallWithAstId(ic, mode, ast_id); |
| 4316 } else { |
| 4317 ASSERT(ast_id == kNoASTId); |
| 4318 __ Call(ic, mode); |
| 4319 } |
4298 } | 4320 } |
4299 | 4321 |
4300 | 4322 |
4301 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) { | 4323 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, |
| 4324 JumpPatchSite* patch_site, |
| 4325 unsigned ast_id) { |
4302 Counters* counters = isolate()->counters(); | 4326 Counters* counters = isolate()->counters(); |
4303 switch (ic->kind()) { | 4327 switch (ic->kind()) { |
4304 case Code::LOAD_IC: | 4328 case Code::LOAD_IC: |
4305 __ IncrementCounter(counters->named_load_full(), 1, r1, r2); | 4329 __ IncrementCounter(counters->named_load_full(), 1, r1, r2); |
4306 break; | 4330 break; |
4307 case Code::KEYED_LOAD_IC: | 4331 case Code::KEYED_LOAD_IC: |
4308 __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2); | 4332 __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2); |
4309 break; | 4333 break; |
4310 case Code::STORE_IC: | 4334 case Code::STORE_IC: |
4311 __ IncrementCounter(counters->named_store_full(), 1, r1, r2); | 4335 __ IncrementCounter(counters->named_store_full(), 1, r1, r2); |
4312 break; | 4336 break; |
4313 case Code::KEYED_STORE_IC: | 4337 case Code::KEYED_STORE_IC: |
4314 __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2); | 4338 __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2); |
4315 default: | 4339 default: |
4316 break; | 4340 break; |
4317 } | 4341 } |
4318 __ Call(ic, RelocInfo::CODE_TARGET); | 4342 |
| 4343 if (ast_id != kNoASTId) { |
| 4344 __ CallWithAstId(ic, RelocInfo::CODE_TARGET_WITH_ID, ast_id); |
| 4345 } else { |
| 4346 __ Call(ic, RelocInfo::CODE_TARGET); |
| 4347 } |
4319 if (patch_site != NULL && patch_site->is_bound()) { | 4348 if (patch_site != NULL && patch_site->is_bound()) { |
4320 patch_site->EmitPatchInfo(); | 4349 patch_site->EmitPatchInfo(); |
4321 } else { | 4350 } else { |
4322 __ nop(); // Signals no inlined code. | 4351 __ nop(); // Signals no inlined code. |
4323 } | 4352 } |
4324 } | 4353 } |
4325 | 4354 |
4326 | 4355 |
4327 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { | 4356 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { |
4328 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); | 4357 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4361 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 4390 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
4362 __ add(pc, r1, Operand(masm_->CodeObject())); | 4391 __ add(pc, r1, Operand(masm_->CodeObject())); |
4363 } | 4392 } |
4364 | 4393 |
4365 | 4394 |
4366 #undef __ | 4395 #undef __ |
4367 | 4396 |
4368 } } // namespace v8::internal | 4397 } } // namespace v8::internal |
4369 | 4398 |
4370 #endif // V8_TARGET_ARCH_ARM | 4399 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |