Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/ia32/full-codegen-ia32.cc

Issue 6880036: Merge revision 7664 (revert of 7644 and 7632) to trunk. (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/assembler-ia32-inl.h ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 26 matching lines...) Expand all
37 #include "parser.h" 37 #include "parser.h"
38 #include "scopes.h" 38 #include "scopes.h"
39 #include "stub-cache.h" 39 #include "stub-cache.h"
40 40
41 namespace v8 { 41 namespace v8 {
42 namespace internal { 42 namespace internal {
43 43
44 44
45 #define __ ACCESS_MASM(masm_) 45 #define __ ACCESS_MASM(masm_)
46 46
47 static unsigned GetPropertyId(Property* property) {
48 if (property->is_synthetic()) return AstNode::kNoNumber;
49 return property->id();
50 }
51
52 47
53 class JumpPatchSite BASE_EMBEDDED { 48 class JumpPatchSite BASE_EMBEDDED {
54 public: 49 public:
55 explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) { 50 explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) {
56 #ifdef DEBUG 51 #ifdef DEBUG
57 info_emitted_ = false; 52 info_emitted_ = false;
58 #endif 53 #endif
59 } 54 }
60 55
61 ~JumpPatchSite() { 56 ~JumpPatchSite() {
(...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 __ mov(edx, eax); 728 __ mov(edx, eax);
734 __ mov(eax, isolate()->factory()->the_hole_value()); 729 __ mov(eax, isolate()->factory()->the_hole_value());
735 } 730 }
736 ASSERT(prop->key()->AsLiteral() != NULL && 731 ASSERT(prop->key()->AsLiteral() != NULL &&
737 prop->key()->AsLiteral()->handle()->IsSmi()); 732 prop->key()->AsLiteral()->handle()->IsSmi());
738 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); 733 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle()));
739 734
740 Handle<Code> ic = is_strict_mode() 735 Handle<Code> ic = is_strict_mode()
741 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 736 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
742 : isolate()->builtins()->KeyedStoreIC_Initialize(); 737 : isolate()->builtins()->KeyedStoreIC_Initialize();
743 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 738 EmitCallIC(ic, RelocInfo::CODE_TARGET);
744 } 739 }
745 } 740 }
746 } 741 }
747 742
748 743
749 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { 744 void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
750 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); 745 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun());
751 } 746 }
752 747
753 748
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 __ cmp(edx, Operand(eax)); 801 __ cmp(edx, Operand(eax));
807 __ j(not_equal, &next_test); 802 __ j(not_equal, &next_test);
808 __ Drop(1); // Switch value is no longer needed. 803 __ Drop(1); // Switch value is no longer needed.
809 __ jmp(clause->body_target()); 804 __ jmp(clause->body_target());
810 __ bind(&slow_case); 805 __ bind(&slow_case);
811 } 806 }
812 807
813 // Record position before stub call for type feedback. 808 // Record position before stub call for type feedback.
814 SetSourcePosition(clause->position()); 809 SetSourcePosition(clause->position());
815 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); 810 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
816 EmitCallIC(ic, &patch_site, clause->label()->id()); 811 EmitCallIC(ic, &patch_site);
817 __ test(eax, Operand(eax)); 812 __ test(eax, Operand(eax));
818 __ j(not_equal, &next_test); 813 __ j(not_equal, &next_test);
819 __ Drop(1); // Switch value is no longer needed. 814 __ Drop(1); // Switch value is no longer needed.
820 __ jmp(clause->body_target()); 815 __ jmp(clause->body_target());
821 } 816 }
822 817
823 // Discard the test value and jump to the default if present, otherwise to 818 // Discard the test value and jump to the default if present, otherwise to
824 // the end of the statement. 819 // the end of the statement.
825 __ bind(&next_test); 820 __ bind(&next_test);
826 __ Drop(1); // Switch value is no longer needed. 821 __ Drop(1); // Switch value is no longer needed.
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
1104 } 1099 }
1105 1100
1106 // All extension objects were empty and it is safe to use a global 1101 // All extension objects were empty and it is safe to use a global
1107 // load IC call. 1102 // load IC call.
1108 __ mov(eax, GlobalObjectOperand()); 1103 __ mov(eax, GlobalObjectOperand());
1109 __ mov(ecx, slot->var()->name()); 1104 __ mov(ecx, slot->var()->name());
1110 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1105 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1111 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) 1106 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
1112 ? RelocInfo::CODE_TARGET 1107 ? RelocInfo::CODE_TARGET
1113 : RelocInfo::CODE_TARGET_CONTEXT; 1108 : RelocInfo::CODE_TARGET_CONTEXT;
1114 EmitCallIC(ic, mode, AstNode::kNoNumber); 1109 EmitCallIC(ic, mode);
1115 } 1110 }
1116 1111
1117 1112
1118 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( 1113 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(
1119 Slot* slot, 1114 Slot* slot,
1120 Label* slow) { 1115 Label* slow) {
1121 ASSERT(slot->type() == Slot::CONTEXT); 1116 ASSERT(slot->type() == Slot::CONTEXT);
1122 Register context = esi; 1117 Register context = esi;
1123 Register temp = ebx; 1118 Register temp = ebx;
1124 1119
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1185 key_literal->handle()->IsSmi()) { 1180 key_literal->handle()->IsSmi()) {
1186 // Load arguments object if there are no eval-introduced 1181 // Load arguments object if there are no eval-introduced
1187 // variables. Then load the argument from the arguments 1182 // variables. Then load the argument from the arguments
1188 // object using keyed load. 1183 // object using keyed load.
1189 __ mov(edx, 1184 __ mov(edx,
1190 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), 1185 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
1191 slow)); 1186 slow));
1192 __ mov(eax, Immediate(key_literal->handle())); 1187 __ mov(eax, Immediate(key_literal->handle()));
1193 Handle<Code> ic = 1188 Handle<Code> ic =
1194 isolate()->builtins()->KeyedLoadIC_Initialize(); 1189 isolate()->builtins()->KeyedLoadIC_Initialize();
1195 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); 1190 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1196 __ jmp(done); 1191 __ jmp(done);
1197 } 1192 }
1198 } 1193 }
1199 } 1194 }
1200 } 1195 }
1201 } 1196 }
1202 1197
1203 1198
1204 void FullCodeGenerator::EmitVariableLoad(Variable* var) { 1199 void FullCodeGenerator::EmitVariableLoad(Variable* var) {
1205 // Four cases: non-this global variables, lookup slots, all other 1200 // Four cases: non-this global variables, lookup slots, all other
1206 // types of slots, and parameters that rewrite to explicit property 1201 // types of slots, and parameters that rewrite to explicit property
1207 // accesses on the arguments object. 1202 // accesses on the arguments object.
1208 Slot* slot = var->AsSlot(); 1203 Slot* slot = var->AsSlot();
1209 Property* property = var->AsProperty(); 1204 Property* property = var->AsProperty();
1210 1205
1211 if (var->is_global() && !var->is_this()) { 1206 if (var->is_global() && !var->is_this()) {
1212 Comment cmnt(masm_, "Global variable"); 1207 Comment cmnt(masm_, "Global variable");
1213 // Use inline caching. Variable name is passed in ecx and the global 1208 // Use inline caching. Variable name is passed in ecx and the global
1214 // object on the stack. 1209 // object on the stack.
1215 __ mov(eax, GlobalObjectOperand()); 1210 __ mov(eax, GlobalObjectOperand());
1216 __ mov(ecx, var->name()); 1211 __ mov(ecx, var->name());
1217 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1212 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1218 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber); 1213 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
1219 context()->Plug(eax); 1214 context()->Plug(eax);
1220 1215
1221 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { 1216 } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
1222 Label done, slow; 1217 Label done, slow;
1223 1218
1224 // Generate code for loading from variables potentially shadowed 1219 // Generate code for loading from variables potentially shadowed
1225 // by eval-introduced variables. 1220 // by eval-introduced variables.
1226 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); 1221 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done);
1227 1222
1228 __ bind(&slow); 1223 __ bind(&slow);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 // Assert that the key is a smi. 1266 // Assert that the key is a smi.
1272 Literal* key_literal = property->key()->AsLiteral(); 1267 Literal* key_literal = property->key()->AsLiteral();
1273 ASSERT_NOT_NULL(key_literal); 1268 ASSERT_NOT_NULL(key_literal);
1274 ASSERT(key_literal->handle()->IsSmi()); 1269 ASSERT(key_literal->handle()->IsSmi());
1275 1270
1276 // Load the key. 1271 // Load the key.
1277 __ mov(eax, Immediate(key_literal->handle())); 1272 __ mov(eax, Immediate(key_literal->handle()));
1278 1273
1279 // Do a keyed property load. 1274 // Do a keyed property load.
1280 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 1275 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
1281 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); 1276 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1282 1277
1283 // Drop key and object left on the stack by IC. 1278 // Drop key and object left on the stack by IC.
1284 context()->Plug(eax); 1279 context()->Plug(eax);
1285 } 1280 }
1286 } 1281 }
1287 1282
1288 1283
1289 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1284 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1290 Comment cmnt(masm_, "[ RegExpLiteral"); 1285 Comment cmnt(masm_, "[ RegExpLiteral");
1291 NearLabel materialized; 1286 NearLabel materialized;
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1384 // Fall through. 1379 // Fall through.
1385 case ObjectLiteral::Property::COMPUTED: 1380 case ObjectLiteral::Property::COMPUTED:
1386 if (key->handle()->IsSymbol()) { 1381 if (key->handle()->IsSymbol()) {
1387 if (property->emit_store()) { 1382 if (property->emit_store()) {
1388 VisitForAccumulatorValue(value); 1383 VisitForAccumulatorValue(value);
1389 __ mov(ecx, Immediate(key->handle())); 1384 __ mov(ecx, Immediate(key->handle()));
1390 __ mov(edx, Operand(esp, 0)); 1385 __ mov(edx, Operand(esp, 0));
1391 Handle<Code> ic = is_strict_mode() 1386 Handle<Code> ic = is_strict_mode()
1392 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1387 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1393 : isolate()->builtins()->StoreIC_Initialize(); 1388 : isolate()->builtins()->StoreIC_Initialize();
1394 EmitCallIC(ic, RelocInfo::CODE_TARGET, key->id()); 1389 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1395 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1390 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1396 } else { 1391 } else {
1397 VisitForEffect(value); 1392 VisitForEffect(value);
1398 } 1393 }
1399 break; 1394 break;
1400 } 1395 }
1401 // Fall through. 1396 // Fall through.
1402 case ObjectLiteral::Property::PROTOTYPE: 1397 case ObjectLiteral::Property::PROTOTYPE:
1403 __ push(Operand(esp, 0)); // Duplicate receiver. 1398 __ push(Operand(esp, 0)); // Duplicate receiver.
1404 VisitForStackValue(key); 1399 VisitForStackValue(key);
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1591 Token::Value op = expr->binary_op(); 1586 Token::Value op = expr->binary_op();
1592 __ push(eax); // Left operand goes on the stack. 1587 __ push(eax); // Left operand goes on the stack.
1593 VisitForAccumulatorValue(expr->value()); 1588 VisitForAccumulatorValue(expr->value());
1594 1589
1595 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() 1590 OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
1596 ? OVERWRITE_RIGHT 1591 ? OVERWRITE_RIGHT
1597 : NO_OVERWRITE; 1592 : NO_OVERWRITE;
1598 SetSourcePosition(expr->position() + 1); 1593 SetSourcePosition(expr->position() + 1);
1599 AccumulatorValueContext context(this); 1594 AccumulatorValueContext context(this);
1600 if (ShouldInlineSmiCase(op)) { 1595 if (ShouldInlineSmiCase(op)) {
1601 EmitInlineSmiBinaryOp(expr->binary_operation(), 1596 EmitInlineSmiBinaryOp(expr,
1602 op, 1597 op,
1603 mode, 1598 mode,
1604 expr->target(), 1599 expr->target(),
1605 expr->value()); 1600 expr->value());
1606 } else { 1601 } else {
1607 EmitBinaryOp(expr->binary_operation(), op, mode); 1602 EmitBinaryOp(op, mode);
1608 } 1603 }
1609 1604
1610 // Deoptimization point in case the binary operation may have side effects. 1605 // Deoptimization point in case the binary operation may have side effects.
1611 PrepareForBailout(expr->binary_operation(), TOS_REG); 1606 PrepareForBailout(expr->binary_operation(), TOS_REG);
1612 } else { 1607 } else {
1613 VisitForAccumulatorValue(expr->value()); 1608 VisitForAccumulatorValue(expr->value());
1614 } 1609 }
1615 1610
1616 // Record source position before possible IC call. 1611 // Record source position before possible IC call.
1617 SetSourcePosition(expr->position()); 1612 SetSourcePosition(expr->position());
(...skipping 14 matching lines...) Expand all
1632 break; 1627 break;
1633 } 1628 }
1634 } 1629 }
1635 1630
1636 1631
1637 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 1632 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1638 SetSourcePosition(prop->position()); 1633 SetSourcePosition(prop->position());
1639 Literal* key = prop->key()->AsLiteral(); 1634 Literal* key = prop->key()->AsLiteral();
1640 __ mov(ecx, Immediate(key->handle())); 1635 __ mov(ecx, Immediate(key->handle()));
1641 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1636 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1642 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); 1637 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1643 } 1638 }
1644 1639
1645 1640
1646 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1641 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1647 SetSourcePosition(prop->position()); 1642 SetSourcePosition(prop->position());
1648 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 1643 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
1649 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); 1644 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1650 } 1645 }
1651 1646
1652 1647
1653 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 1648 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr,
1654 Token::Value op, 1649 Token::Value op,
1655 OverwriteMode mode, 1650 OverwriteMode mode,
1656 Expression* left, 1651 Expression* left,
1657 Expression* right) { 1652 Expression* right) {
1658 // Do combined smi check of the operands. Left operand is on the 1653 // Do combined smi check of the operands. Left operand is on the
1659 // stack. Right operand is in eax. 1654 // stack. Right operand is in eax.
1660 NearLabel done, smi_case, stub_call; 1655 NearLabel done, smi_case, stub_call;
1661 __ pop(edx); 1656 __ pop(edx);
1662 __ mov(ecx, eax); 1657 __ mov(ecx, eax);
1663 __ or_(eax, Operand(edx)); 1658 __ or_(eax, Operand(edx));
1664 JumpPatchSite patch_site(masm_); 1659 JumpPatchSite patch_site(masm_);
1665 patch_site.EmitJumpIfSmi(eax, &smi_case); 1660 patch_site.EmitJumpIfSmi(eax, &smi_case);
1666 1661
1667 __ bind(&stub_call); 1662 __ bind(&stub_call);
1668 __ mov(eax, ecx); 1663 __ mov(eax, ecx);
1669 TypeRecordingBinaryOpStub stub(op, mode); 1664 TypeRecordingBinaryOpStub stub(op, mode);
1670 EmitCallIC(stub.GetCode(), &patch_site, expr->id()); 1665 EmitCallIC(stub.GetCode(), &patch_site);
1671 __ jmp(&done); 1666 __ jmp(&done);
1672 1667
1673 // Smi case. 1668 // Smi case.
1674 __ bind(&smi_case); 1669 __ bind(&smi_case);
1675 __ mov(eax, edx); // Copy left operand in case of a stub call. 1670 __ mov(eax, edx); // Copy left operand in case of a stub call.
1676 1671
1677 switch (op) { 1672 switch (op) {
1678 case Token::SAR: 1673 case Token::SAR:
1679 __ SmiUntag(eax); 1674 __ SmiUntag(eax);
1680 __ SmiUntag(ecx); 1675 __ SmiUntag(ecx);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1738 break; 1733 break;
1739 default: 1734 default:
1740 UNREACHABLE(); 1735 UNREACHABLE();
1741 } 1736 }
1742 1737
1743 __ bind(&done); 1738 __ bind(&done);
1744 context()->Plug(eax); 1739 context()->Plug(eax);
1745 } 1740 }
1746 1741
1747 1742
1748 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, 1743 void FullCodeGenerator::EmitBinaryOp(Token::Value op,
1749 Token::Value op,
1750 OverwriteMode mode) { 1744 OverwriteMode mode) {
1751 __ pop(edx); 1745 __ pop(edx);
1752 TypeRecordingBinaryOpStub stub(op, mode); 1746 TypeRecordingBinaryOpStub stub(op, mode);
1753 // NULL signals no inlined smi code. 1747 EmitCallIC(stub.GetCode(), NULL); // NULL signals no inlined smi code.
1754 EmitCallIC(stub.GetCode(), NULL, expr->id());
1755 context()->Plug(eax); 1748 context()->Plug(eax);
1756 } 1749 }
1757 1750
1758 1751
1759 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { 1752 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
1760 // Invalid left-hand sides are rewritten to have a 'throw 1753 // Invalid left-hand sides are rewritten to have a 'throw
1761 // ReferenceError' on the left-hand side. 1754 // ReferenceError' on the left-hand side.
1762 if (!expr->IsValidLeftHandSide()) { 1755 if (!expr->IsValidLeftHandSide()) {
1763 VisitForEffect(expr); 1756 VisitForEffect(expr);
1764 return; 1757 return;
(...skipping 19 matching lines...) Expand all
1784 } 1777 }
1785 case NAMED_PROPERTY: { 1778 case NAMED_PROPERTY: {
1786 __ push(eax); // Preserve value. 1779 __ push(eax); // Preserve value.
1787 VisitForAccumulatorValue(prop->obj()); 1780 VisitForAccumulatorValue(prop->obj());
1788 __ mov(edx, eax); 1781 __ mov(edx, eax);
1789 __ pop(eax); // Restore value. 1782 __ pop(eax); // Restore value.
1790 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1783 __ mov(ecx, prop->key()->AsLiteral()->handle());
1791 Handle<Code> ic = is_strict_mode() 1784 Handle<Code> ic = is_strict_mode()
1792 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1785 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1793 : isolate()->builtins()->StoreIC_Initialize(); 1786 : isolate()->builtins()->StoreIC_Initialize();
1794 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 1787 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1795 break; 1788 break;
1796 } 1789 }
1797 case KEYED_PROPERTY: { 1790 case KEYED_PROPERTY: {
1798 __ push(eax); // Preserve value. 1791 __ push(eax); // Preserve value.
1799 if (prop->is_synthetic()) { 1792 if (prop->is_synthetic()) {
1800 ASSERT(prop->obj()->AsVariableProxy() != NULL); 1793 ASSERT(prop->obj()->AsVariableProxy() != NULL);
1801 ASSERT(prop->key()->AsLiteral() != NULL); 1794 ASSERT(prop->key()->AsLiteral() != NULL);
1802 { AccumulatorValueContext for_object(this); 1795 { AccumulatorValueContext for_object(this);
1803 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); 1796 EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
1804 } 1797 }
1805 __ mov(edx, eax); 1798 __ mov(edx, eax);
1806 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); 1799 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle()));
1807 } else { 1800 } else {
1808 VisitForStackValue(prop->obj()); 1801 VisitForStackValue(prop->obj());
1809 VisitForAccumulatorValue(prop->key()); 1802 VisitForAccumulatorValue(prop->key());
1810 __ mov(ecx, eax); 1803 __ mov(ecx, eax);
1811 __ pop(edx); 1804 __ pop(edx);
1812 } 1805 }
1813 __ pop(eax); // Restore value. 1806 __ pop(eax); // Restore value.
1814 Handle<Code> ic = is_strict_mode() 1807 Handle<Code> ic = is_strict_mode()
1815 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1808 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
1816 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1809 : isolate()->builtins()->KeyedStoreIC_Initialize();
1817 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 1810 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1818 break; 1811 break;
1819 } 1812 }
1820 } 1813 }
1821 PrepareForBailoutForId(bailout_ast_id, TOS_REG); 1814 PrepareForBailoutForId(bailout_ast_id, TOS_REG);
1822 context()->Plug(eax); 1815 context()->Plug(eax);
1823 } 1816 }
1824 1817
1825 1818
1826 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1819 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1827 Token::Value op) { 1820 Token::Value op) {
1828 // Left-hand sides that rewrite to explicit property accesses do not reach 1821 // Left-hand sides that rewrite to explicit property accesses do not reach
1829 // here. 1822 // here.
1830 ASSERT(var != NULL); 1823 ASSERT(var != NULL);
1831 ASSERT(var->is_global() || var->AsSlot() != NULL); 1824 ASSERT(var->is_global() || var->AsSlot() != NULL);
1832 1825
1833 if (var->is_global()) { 1826 if (var->is_global()) {
1834 ASSERT(!var->is_this()); 1827 ASSERT(!var->is_this());
1835 // Assignment to a global variable. Use inline caching for the 1828 // Assignment to a global variable. Use inline caching for the
1836 // assignment. Right-hand-side value is passed in eax, variable name in 1829 // assignment. Right-hand-side value is passed in eax, variable name in
1837 // ecx, and the global object on the stack. 1830 // ecx, and the global object on the stack.
1838 __ mov(ecx, var->name()); 1831 __ mov(ecx, var->name());
1839 __ mov(edx, GlobalObjectOperand()); 1832 __ mov(edx, GlobalObjectOperand());
1840 Handle<Code> ic = is_strict_mode() 1833 Handle<Code> ic = is_strict_mode()
1841 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1834 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1842 : isolate()->builtins()->StoreIC_Initialize(); 1835 : isolate()->builtins()->StoreIC_Initialize();
1843 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber); 1836 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
1844 1837
1845 } else if (op == Token::INIT_CONST) { 1838 } else if (op == Token::INIT_CONST) {
1846 // Like var declarations, const declarations are hoisted to function 1839 // Like var declarations, const declarations are hoisted to function
1847 // scope. However, unlike var initializers, const initializers are able 1840 // scope. However, unlike var initializers, const initializers are able
1848 // to drill a hole to that function context, even from inside a 'with' 1841 // to drill a hole to that function context, even from inside a 'with'
1849 // context. We thus bypass the normal static scope lookup. 1842 // context. We thus bypass the normal static scope lookup.
1850 Slot* slot = var->AsSlot(); 1843 Slot* slot = var->AsSlot();
1851 Label skip; 1844 Label skip;
1852 switch (slot->type()) { 1845 switch (slot->type()) {
1853 case Slot::PARAMETER: 1846 case Slot::PARAMETER:
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1936 SetSourcePosition(expr->position()); 1929 SetSourcePosition(expr->position());
1937 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1930 __ mov(ecx, prop->key()->AsLiteral()->handle());
1938 if (expr->ends_initialization_block()) { 1931 if (expr->ends_initialization_block()) {
1939 __ mov(edx, Operand(esp, 0)); 1932 __ mov(edx, Operand(esp, 0));
1940 } else { 1933 } else {
1941 __ pop(edx); 1934 __ pop(edx);
1942 } 1935 }
1943 Handle<Code> ic = is_strict_mode() 1936 Handle<Code> ic = is_strict_mode()
1944 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1937 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1945 : isolate()->builtins()->StoreIC_Initialize(); 1938 : isolate()->builtins()->StoreIC_Initialize();
1946 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); 1939 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1947 1940
1948 // If the assignment ends an initialization block, revert to fast case. 1941 // If the assignment ends an initialization block, revert to fast case.
1949 if (expr->ends_initialization_block()) { 1942 if (expr->ends_initialization_block()) {
1950 __ push(eax); // Result of assignment, saved even if not needed. 1943 __ push(eax); // Result of assignment, saved even if not needed.
1951 __ push(Operand(esp, kPointerSize)); // Receiver is under value. 1944 __ push(Operand(esp, kPointerSize)); // Receiver is under value.
1952 __ CallRuntime(Runtime::kToFastProperties, 1); 1945 __ CallRuntime(Runtime::kToFastProperties, 1);
1953 __ pop(eax); 1946 __ pop(eax);
1954 __ Drop(1); 1947 __ Drop(1);
1955 } 1948 }
1956 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1949 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
(...skipping 19 matching lines...) Expand all
1976 if (expr->ends_initialization_block()) { 1969 if (expr->ends_initialization_block()) {
1977 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. 1970 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later.
1978 } else { 1971 } else {
1979 __ pop(edx); 1972 __ pop(edx);
1980 } 1973 }
1981 // Record source code position before IC call. 1974 // Record source code position before IC call.
1982 SetSourcePosition(expr->position()); 1975 SetSourcePosition(expr->position());
1983 Handle<Code> ic = is_strict_mode() 1976 Handle<Code> ic = is_strict_mode()
1984 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1977 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
1985 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1978 : isolate()->builtins()->KeyedStoreIC_Initialize();
1986 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); 1979 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1987 1980
1988 // If the assignment ends an initialization block, revert to fast case. 1981 // If the assignment ends an initialization block, revert to fast case.
1989 if (expr->ends_initialization_block()) { 1982 if (expr->ends_initialization_block()) {
1990 __ pop(edx); 1983 __ pop(edx);
1991 __ push(eax); // Result of assignment, saved even if not needed. 1984 __ push(eax); // Result of assignment, saved even if not needed.
1992 __ push(edx); 1985 __ push(edx);
1993 __ CallRuntime(Runtime::kToFastProperties, 1); 1986 __ CallRuntime(Runtime::kToFastProperties, 1);
1994 __ pop(eax); 1987 __ pop(eax);
1995 } 1988 }
1996 1989
(...skipping 30 matching lines...) Expand all
2027 for (int i = 0; i < arg_count; i++) { 2020 for (int i = 0; i < arg_count; i++) {
2028 VisitForStackValue(args->at(i)); 2021 VisitForStackValue(args->at(i));
2029 } 2022 }
2030 __ Set(ecx, Immediate(name)); 2023 __ Set(ecx, Immediate(name));
2031 } 2024 }
2032 // Record source position of the IC call. 2025 // Record source position of the IC call.
2033 SetSourcePosition(expr->position()); 2026 SetSourcePosition(expr->position());
2034 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2027 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2035 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize( 2028 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(
2036 arg_count, in_loop); 2029 arg_count, in_loop);
2037 EmitCallIC(ic, mode, expr->id()); 2030 EmitCallIC(ic, mode);
2038 RecordJSReturnSite(expr); 2031 RecordJSReturnSite(expr);
2039 // Restore context register. 2032 // Restore context register.
2040 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2033 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2041 context()->Plug(eax); 2034 context()->Plug(eax);
2042 } 2035 }
2043 2036
2044 2037
2045 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2038 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2046 Expression* key, 2039 Expression* key,
2047 RelocInfo::Mode mode) { 2040 RelocInfo::Mode mode) {
(...skipping 13 matching lines...) Expand all
2061 for (int i = 0; i < arg_count; i++) { 2054 for (int i = 0; i < arg_count; i++) {
2062 VisitForStackValue(args->at(i)); 2055 VisitForStackValue(args->at(i));
2063 } 2056 }
2064 } 2057 }
2065 // Record source position of the IC call. 2058 // Record source position of the IC call.
2066 SetSourcePosition(expr->position()); 2059 SetSourcePosition(expr->position());
2067 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2060 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2068 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize( 2061 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(
2069 arg_count, in_loop); 2062 arg_count, in_loop);
2070 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. 2063 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key.
2071 EmitCallIC(ic, mode, expr->id()); 2064 EmitCallIC(ic, mode);
2072 RecordJSReturnSite(expr); 2065 RecordJSReturnSite(expr);
2073 // Restore context register. 2066 // Restore context register.
2074 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2067 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2075 context()->DropAndPlug(1, eax); // Drop the key still on the stack. 2068 context()->DropAndPlug(1, eax); // Drop the key still on the stack.
2076 } 2069 }
2077 2070
2078 2071
2079 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 2072 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
2080 // Code common for calls using the call stub. 2073 // Code common for calls using the call stub.
2081 ZoneList<Expression*>* args = expr->arguments(); 2074 ZoneList<Expression*>* args = expr->arguments();
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
2252 __ mov(edx, operand); 2245 __ mov(edx, operand);
2253 2246
2254 ASSERT(prop->key()->AsLiteral() != NULL); 2247 ASSERT(prop->key()->AsLiteral() != NULL);
2255 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); 2248 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi());
2256 __ mov(eax, prop->key()->AsLiteral()->handle()); 2249 __ mov(eax, prop->key()->AsLiteral()->handle());
2257 2250
2258 // Record source code position for IC call. 2251 // Record source code position for IC call.
2259 SetSourcePosition(prop->position()); 2252 SetSourcePosition(prop->position());
2260 2253
2261 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2254 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2262 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); 2255 EmitCallIC(ic, RelocInfo::CODE_TARGET);
2263 // Push result (function). 2256 // Push result (function).
2264 __ push(eax); 2257 __ push(eax);
2265 // Push Global receiver. 2258 // Push Global receiver.
2266 __ mov(ecx, GlobalObjectOperand()); 2259 __ mov(ecx, GlobalObjectOperand());
2267 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset)); 2260 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset));
2268 EmitCallWithStub(expr); 2261 EmitCallWithStub(expr);
2269 } else { 2262 } else {
2270 { PreservePositionScope scope(masm()->positions_recorder()); 2263 { PreservePositionScope scope(masm()->positions_recorder());
2271 VisitForStackValue(prop->obj()); 2264 VisitForStackValue(prop->obj());
2272 } 2265 }
(...skipping 1338 matching lines...) Expand 10 before | Expand all | Expand 10 after
3611 for (int i = 0; i < arg_count; i++) { 3604 for (int i = 0; i < arg_count; i++) {
3612 VisitForStackValue(args->at(i)); 3605 VisitForStackValue(args->at(i));
3613 } 3606 }
3614 3607
3615 if (expr->is_jsruntime()) { 3608 if (expr->is_jsruntime()) {
3616 // Call the JS runtime function via a call IC. 3609 // Call the JS runtime function via a call IC.
3617 __ Set(ecx, Immediate(expr->name())); 3610 __ Set(ecx, Immediate(expr->name()));
3618 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 3611 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
3619 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize( 3612 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(
3620 arg_count, in_loop); 3613 arg_count, in_loop);
3621 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); 3614 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3622 // Restore context register. 3615 // Restore context register.
3623 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3616 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3624 } else { 3617 } else {
3625 // Call the C runtime function. 3618 // Call the C runtime function.
3626 __ CallRuntime(expr->function(), arg_count); 3619 __ CallRuntime(expr->function(), arg_count);
3627 } 3620 }
3628 context()->Plug(eax); 3621 context()->Plug(eax);
3629 } 3622 }
3630 3623
3631 3624
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
3898 } 3891 }
3899 } 3892 }
3900 3893
3901 // Record position before stub call. 3894 // Record position before stub call.
3902 SetSourcePosition(expr->position()); 3895 SetSourcePosition(expr->position());
3903 3896
3904 // Call stub for +1/-1. 3897 // Call stub for +1/-1.
3905 __ mov(edx, eax); 3898 __ mov(edx, eax);
3906 __ mov(eax, Immediate(Smi::FromInt(1))); 3899 __ mov(eax, Immediate(Smi::FromInt(1)));
3907 TypeRecordingBinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); 3900 TypeRecordingBinaryOpStub stub(expr->binary_op(), NO_OVERWRITE);
3908 EmitCallIC(stub.GetCode(), &patch_site, expr->CountId()); 3901 EmitCallIC(stub.GetCode(), &patch_site);
3909 __ bind(&done); 3902 __ bind(&done);
3910 3903
3911 // Store the value returned in eax. 3904 // Store the value returned in eax.
3912 switch (assign_type) { 3905 switch (assign_type) {
3913 case VARIABLE: 3906 case VARIABLE:
3914 if (expr->is_postfix()) { 3907 if (expr->is_postfix()) {
3915 // Perform the assignment as if via '='. 3908 // Perform the assignment as if via '='.
3916 { EffectContext context(this); 3909 { EffectContext context(this);
3917 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3910 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3918 Token::ASSIGN); 3911 Token::ASSIGN);
(...skipping 12 matching lines...) Expand all
3931 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3924 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3932 context()->Plug(eax); 3925 context()->Plug(eax);
3933 } 3926 }
3934 break; 3927 break;
3935 case NAMED_PROPERTY: { 3928 case NAMED_PROPERTY: {
3936 __ mov(ecx, prop->key()->AsLiteral()->handle()); 3929 __ mov(ecx, prop->key()->AsLiteral()->handle());
3937 __ pop(edx); 3930 __ pop(edx);
3938 Handle<Code> ic = is_strict_mode() 3931 Handle<Code> ic = is_strict_mode()
3939 ? isolate()->builtins()->StoreIC_Initialize_Strict() 3932 ? isolate()->builtins()->StoreIC_Initialize_Strict()
3940 : isolate()->builtins()->StoreIC_Initialize(); 3933 : isolate()->builtins()->StoreIC_Initialize();
3941 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); 3934 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3942 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3935 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3943 if (expr->is_postfix()) { 3936 if (expr->is_postfix()) {
3944 if (!context()->IsEffect()) { 3937 if (!context()->IsEffect()) {
3945 context()->PlugTOS(); 3938 context()->PlugTOS();
3946 } 3939 }
3947 } else { 3940 } else {
3948 context()->Plug(eax); 3941 context()->Plug(eax);
3949 } 3942 }
3950 break; 3943 break;
3951 } 3944 }
3952 case KEYED_PROPERTY: { 3945 case KEYED_PROPERTY: {
3953 __ pop(ecx); 3946 __ pop(ecx);
3954 __ pop(edx); 3947 __ pop(edx);
3955 Handle<Code> ic = is_strict_mode() 3948 Handle<Code> ic = is_strict_mode()
3956 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3949 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3957 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3950 : isolate()->builtins()->KeyedStoreIC_Initialize();
3958 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); 3951 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3959 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3952 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3960 if (expr->is_postfix()) { 3953 if (expr->is_postfix()) {
3961 // Result is on the stack 3954 // Result is on the stack
3962 if (!context()->IsEffect()) { 3955 if (!context()->IsEffect()) {
3963 context()->PlugTOS(); 3956 context()->PlugTOS();
3964 } 3957 }
3965 } else { 3958 } else {
3966 context()->Plug(eax); 3959 context()->Plug(eax);
3967 } 3960 }
3968 break; 3961 break;
3969 } 3962 }
3970 } 3963 }
3971 } 3964 }
3972 3965
3973 3966
3974 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 3967 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
3975 VariableProxy* proxy = expr->AsVariableProxy(); 3968 VariableProxy* proxy = expr->AsVariableProxy();
3976 ASSERT(!context()->IsEffect()); 3969 ASSERT(!context()->IsEffect());
3977 ASSERT(!context()->IsTest()); 3970 ASSERT(!context()->IsTest());
3978 3971
3979 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { 3972 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) {
3980 Comment cmnt(masm_, "Global variable"); 3973 Comment cmnt(masm_, "Global variable");
3981 __ mov(eax, GlobalObjectOperand()); 3974 __ mov(eax, GlobalObjectOperand());
3982 __ mov(ecx, Immediate(proxy->name())); 3975 __ mov(ecx, Immediate(proxy->name()));
3983 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 3976 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
3984 // Use a regular load, not a contextual load, to avoid a reference 3977 // Use a regular load, not a contextual load, to avoid a reference
3985 // error. 3978 // error.
3986 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 3979 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3987 PrepareForBailout(expr, TOS_REG); 3980 PrepareForBailout(expr, TOS_REG);
3988 context()->Plug(eax); 3981 context()->Plug(eax);
3989 } else if (proxy != NULL && 3982 } else if (proxy != NULL &&
3990 proxy->var()->AsSlot() != NULL && 3983 proxy->var()->AsSlot() != NULL &&
3991 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { 3984 proxy->var()->AsSlot()->type() == Slot::LOOKUP) {
3992 Label done, slow; 3985 Label done, slow;
3993 3986
3994 // Generate code for loading from variables potentially shadowed 3987 // Generate code for loading from variables potentially shadowed
3995 // by eval-introduced variables. 3988 // by eval-introduced variables.
3996 Slot* slot = proxy->var()->AsSlot(); 3989 Slot* slot = proxy->var()->AsSlot();
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
4175 __ or_(ecx, Operand(eax)); 4168 __ or_(ecx, Operand(eax));
4176 patch_site.EmitJumpIfNotSmi(ecx, &slow_case); 4169 patch_site.EmitJumpIfNotSmi(ecx, &slow_case);
4177 __ cmp(edx, Operand(eax)); 4170 __ cmp(edx, Operand(eax));
4178 Split(cc, if_true, if_false, NULL); 4171 Split(cc, if_true, if_false, NULL);
4179 __ bind(&slow_case); 4172 __ bind(&slow_case);
4180 } 4173 }
4181 4174
4182 // Record position and call the compare IC. 4175 // Record position and call the compare IC.
4183 SetSourcePosition(expr->position()); 4176 SetSourcePosition(expr->position());
4184 Handle<Code> ic = CompareIC::GetUninitialized(op); 4177 Handle<Code> ic = CompareIC::GetUninitialized(op);
4185 EmitCallIC(ic, &patch_site, expr->id()); 4178 EmitCallIC(ic, &patch_site);
4186 4179
4187 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4180 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4188 __ test(eax, Operand(eax)); 4181 __ test(eax, Operand(eax));
4189 Split(cc, if_true, if_false, fall_through); 4182 Split(cc, if_true, if_false, fall_through);
4190 } 4183 }
4191 } 4184 }
4192 4185
4193 // Convert the result of the comparison into one expected for this 4186 // Convert the result of the comparison into one expected for this
4194 // expression's context. 4187 // expression's context.
4195 context()->Plug(if_true, if_false); 4188 context()->Plug(if_true, if_false);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
4235 Register FullCodeGenerator::result_register() { 4228 Register FullCodeGenerator::result_register() {
4236 return eax; 4229 return eax;
4237 } 4230 }
4238 4231
4239 4232
4240 Register FullCodeGenerator::context_register() { 4233 Register FullCodeGenerator::context_register() {
4241 return esi; 4234 return esi;
4242 } 4235 }
4243 4236
4244 4237
4245 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, 4238 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) {
4246 RelocInfo::Mode mode,
4247 unsigned ast_id) {
4248 ASSERT(mode == RelocInfo::CODE_TARGET || 4239 ASSERT(mode == RelocInfo::CODE_TARGET ||
4249 mode == RelocInfo::CODE_TARGET_CONTEXT); 4240 mode == RelocInfo::CODE_TARGET_CONTEXT);
4250 switch (ic->kind()) { 4241 switch (ic->kind()) {
4251 case Code::LOAD_IC: 4242 case Code::LOAD_IC:
4252 __ IncrementCounter(isolate()->counters()->named_load_full(), 1); 4243 __ IncrementCounter(isolate()->counters()->named_load_full(), 1);
4253 break; 4244 break;
4254 case Code::KEYED_LOAD_IC: 4245 case Code::KEYED_LOAD_IC:
4255 __ IncrementCounter(isolate()->counters()->keyed_load_full(), 1); 4246 __ IncrementCounter(isolate()->counters()->keyed_load_full(), 1);
4256 break; 4247 break;
4257 case Code::STORE_IC: 4248 case Code::STORE_IC:
4258 __ IncrementCounter(isolate()->counters()->named_store_full(), 1); 4249 __ IncrementCounter(isolate()->counters()->named_store_full(), 1);
4259 break; 4250 break;
4260 case Code::KEYED_STORE_IC: 4251 case Code::KEYED_STORE_IC:
4261 __ IncrementCounter(isolate()->counters()->keyed_store_full(), 1); 4252 __ IncrementCounter(isolate()->counters()->keyed_store_full(), 1);
4262 default: 4253 default:
4263 break; 4254 break;
4264 } 4255 }
4265 __ call(ic, mode, ast_id); 4256 __ call(ic, mode);
4266 } 4257 }
4267 4258
4268 4259
4269 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, 4260 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) {
4270 JumpPatchSite* patch_site,
4271 unsigned ast_id) {
4272 Counters* counters = isolate()->counters(); 4261 Counters* counters = isolate()->counters();
4273 switch (ic->kind()) { 4262 switch (ic->kind()) {
4274 case Code::LOAD_IC: 4263 case Code::LOAD_IC:
4275 __ IncrementCounter(counters->named_load_full(), 1); 4264 __ IncrementCounter(counters->named_load_full(), 1);
4276 break; 4265 break;
4277 case Code::KEYED_LOAD_IC: 4266 case Code::KEYED_LOAD_IC:
4278 __ IncrementCounter(counters->keyed_load_full(), 1); 4267 __ IncrementCounter(counters->keyed_load_full(), 1);
4279 break; 4268 break;
4280 case Code::STORE_IC: 4269 case Code::STORE_IC:
4281 __ IncrementCounter(counters->named_store_full(), 1); 4270 __ IncrementCounter(counters->named_store_full(), 1);
4282 break; 4271 break;
4283 case Code::KEYED_STORE_IC: 4272 case Code::KEYED_STORE_IC:
4284 __ IncrementCounter(counters->keyed_store_full(), 1); 4273 __ IncrementCounter(counters->keyed_store_full(), 1);
4285 default: 4274 default:
4286 break; 4275 break;
4287 } 4276 }
4288 __ call(ic, RelocInfo::CODE_TARGET, ast_id); 4277 __ call(ic, RelocInfo::CODE_TARGET);
4289 if (patch_site != NULL && patch_site->is_bound()) { 4278 if (patch_site != NULL && patch_site->is_bound()) {
4290 patch_site->EmitPatchInfo(); 4279 patch_site->EmitPatchInfo();
4291 } else { 4280 } else {
4292 __ nop(); // Signals no inlined code. 4281 __ nop(); // Signals no inlined code.
4293 } 4282 }
4294 } 4283 }
4295 4284
4296 4285
4297 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 4286 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
4298 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); 4287 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
4334 // And return. 4323 // And return.
4335 __ ret(0); 4324 __ ret(0);
4336 } 4325 }
4337 4326
4338 4327
4339 #undef __ 4328 #undef __
4340 4329
4341 } } // namespace v8::internal 4330 } } // namespace v8::internal
4342 4331
4343 #endif // V8_TARGET_ARCH_IA32 4332 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/assembler-ia32-inl.h ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698