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

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

Issue 7283042: Nuke EmitCallIC, it is a plain call now. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 5 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.h ('k') | src/x64/assembler-x64.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 738 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 VisitForAccumulatorValue(function); 749 VisitForAccumulatorValue(function);
750 __ pop(edx); 750 __ pop(edx);
751 751
752 ASSERT(prop->key()->AsLiteral() != NULL && 752 ASSERT(prop->key()->AsLiteral() != NULL &&
753 prop->key()->AsLiteral()->handle()->IsSmi()); 753 prop->key()->AsLiteral()->handle()->IsSmi());
754 __ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle())); 754 __ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle()));
755 755
756 Handle<Code> ic = is_strict_mode() 756 Handle<Code> ic = is_strict_mode()
757 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 757 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
758 : isolate()->builtins()->KeyedStoreIC_Initialize(); 758 : isolate()->builtins()->KeyedStoreIC_Initialize();
759 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 759 __ call(ic);
760 } 760 }
761 } 761 }
762 } 762 }
763 763
764 764
765 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { 765 void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
766 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); 766 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun());
767 } 767 }
768 768
769 769
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
822 __ cmp(edx, Operand(eax)); 822 __ cmp(edx, Operand(eax));
823 __ j(not_equal, &next_test); 823 __ j(not_equal, &next_test);
824 __ Drop(1); // Switch value is no longer needed. 824 __ Drop(1); // Switch value is no longer needed.
825 __ jmp(clause->body_target()); 825 __ jmp(clause->body_target());
826 __ bind(&slow_case); 826 __ bind(&slow_case);
827 } 827 }
828 828
829 // Record position before stub call for type feedback. 829 // Record position before stub call for type feedback.
830 SetSourcePosition(clause->position()); 830 SetSourcePosition(clause->position());
831 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); 831 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
832 EmitCallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId()); 832 __ call(ic, RelocInfo::CODE_TARGET, clause->CompareId());
833 patch_site.EmitPatchInfo(); 833 patch_site.EmitPatchInfo();
834 __ test(eax, Operand(eax)); 834 __ test(eax, Operand(eax));
835 __ j(not_equal, &next_test); 835 __ j(not_equal, &next_test);
836 __ Drop(1); // Switch value is no longer needed. 836 __ Drop(1); // Switch value is no longer needed.
837 __ jmp(clause->body_target()); 837 __ jmp(clause->body_target());
838 } 838 }
839 839
840 // Discard the test value and jump to the default if present, otherwise to 840 // Discard the test value and jump to the default if present, otherwise to
841 // the end of the statement. 841 // the end of the statement.
842 __ bind(&next_test); 842 __ bind(&next_test);
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 } 1116 }
1117 1117
1118 // All extension objects were empty and it is safe to use a global 1118 // All extension objects were empty and it is safe to use a global
1119 // load IC call. 1119 // load IC call.
1120 __ mov(eax, GlobalObjectOperand()); 1120 __ mov(eax, GlobalObjectOperand());
1121 __ mov(ecx, slot->var()->name()); 1121 __ mov(ecx, slot->var()->name());
1122 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1122 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1123 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) 1123 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
1124 ? RelocInfo::CODE_TARGET 1124 ? RelocInfo::CODE_TARGET
1125 : RelocInfo::CODE_TARGET_CONTEXT; 1125 : RelocInfo::CODE_TARGET_CONTEXT;
1126 EmitCallIC(ic, mode, AstNode::kNoNumber); 1126 __ call(ic, mode);
1127 } 1127 }
1128 1128
1129 1129
1130 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( 1130 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(
1131 Slot* slot, 1131 Slot* slot,
1132 Label* slow) { 1132 Label* slow) {
1133 ASSERT(slot->type() == Slot::CONTEXT); 1133 ASSERT(slot->type() == Slot::CONTEXT);
1134 Register context = esi; 1134 Register context = esi;
1135 Register temp = ebx; 1135 Register temp = ebx;
1136 1136
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 key_literal->handle()->IsSmi()) { 1196 key_literal->handle()->IsSmi()) {
1197 // Load arguments object if there are no eval-introduced 1197 // Load arguments object if there are no eval-introduced
1198 // variables. Then load the argument from the arguments 1198 // variables. Then load the argument from the arguments
1199 // object using keyed load. 1199 // object using keyed load.
1200 __ mov(edx, 1200 __ mov(edx,
1201 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), 1201 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
1202 slow)); 1202 slow));
1203 __ SafeSet(eax, Immediate(key_literal->handle())); 1203 __ SafeSet(eax, Immediate(key_literal->handle()));
1204 Handle<Code> ic = 1204 Handle<Code> ic =
1205 isolate()->builtins()->KeyedLoadIC_Initialize(); 1205 isolate()->builtins()->KeyedLoadIC_Initialize();
1206 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); 1206 __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
1207 __ jmp(done); 1207 __ jmp(done);
1208 } 1208 }
1209 } 1209 }
1210 } 1210 }
1211 } 1211 }
1212 } 1212 }
1213 1213
1214 1214
1215 void FullCodeGenerator::EmitVariableLoad(Variable* var) { 1215 void FullCodeGenerator::EmitVariableLoad(Variable* var) {
1216 // Three cases: non-this global variables, lookup slots, and all other 1216 // Three cases: non-this global variables, lookup slots, and all other
1217 // types of slots. 1217 // types of slots.
1218 Slot* slot = var->AsSlot(); 1218 Slot* slot = var->AsSlot();
1219 ASSERT((var->is_global() && !var->is_this()) == (slot == NULL)); 1219 ASSERT((var->is_global() && !var->is_this()) == (slot == NULL));
1220 1220
1221 if (slot == NULL) { 1221 if (slot == NULL) {
1222 Comment cmnt(masm_, "Global variable"); 1222 Comment cmnt(masm_, "Global variable");
1223 // Use inline caching. Variable name is passed in ecx and the global 1223 // Use inline caching. Variable name is passed in ecx and the global
1224 // object on the stack. 1224 // object on the stack.
1225 __ mov(eax, GlobalObjectOperand()); 1225 __ mov(eax, GlobalObjectOperand());
1226 __ mov(ecx, var->name()); 1226 __ mov(ecx, var->name());
1227 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1227 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1228 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber); 1228 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
1229 context()->Plug(eax); 1229 context()->Plug(eax);
1230 1230
1231 } else if (slot->type() == Slot::LOOKUP) { 1231 } else if (slot->type() == Slot::LOOKUP) {
1232 Label done, slow; 1232 Label done, slow;
1233 1233
1234 // Generate code for loading from variables potentially shadowed 1234 // Generate code for loading from variables potentially shadowed
1235 // by eval-introduced variables. 1235 // by eval-introduced variables.
1236 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); 1236 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done);
1237 1237
1238 __ bind(&slow); 1238 __ bind(&slow);
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1364 // Fall through. 1364 // Fall through.
1365 case ObjectLiteral::Property::COMPUTED: 1365 case ObjectLiteral::Property::COMPUTED:
1366 if (key->handle()->IsSymbol()) { 1366 if (key->handle()->IsSymbol()) {
1367 if (property->emit_store()) { 1367 if (property->emit_store()) {
1368 VisitForAccumulatorValue(value); 1368 VisitForAccumulatorValue(value);
1369 __ mov(ecx, Immediate(key->handle())); 1369 __ mov(ecx, Immediate(key->handle()));
1370 __ mov(edx, Operand(esp, 0)); 1370 __ mov(edx, Operand(esp, 0));
1371 Handle<Code> ic = is_strict_mode() 1371 Handle<Code> ic = is_strict_mode()
1372 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1372 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1373 : isolate()->builtins()->StoreIC_Initialize(); 1373 : isolate()->builtins()->StoreIC_Initialize();
1374 EmitCallIC(ic, RelocInfo::CODE_TARGET, key->id()); 1374 __ call(ic, RelocInfo::CODE_TARGET, key->id());
1375 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1375 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1376 } else { 1376 } else {
1377 VisitForEffect(value); 1377 VisitForEffect(value);
1378 } 1378 }
1379 break; 1379 break;
1380 } 1380 }
1381 // Fall through. 1381 // Fall through.
1382 case ObjectLiteral::Property::PROTOTYPE: 1382 case ObjectLiteral::Property::PROTOTYPE:
1383 __ push(Operand(esp, 0)); // Duplicate receiver. 1383 __ push(Operand(esp, 0)); // Duplicate receiver.
1384 VisitForStackValue(key); 1384 VisitForStackValue(key);
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1597 } 1597 }
1598 } 1598 }
1599 1599
1600 1600
1601 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 1601 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1602 SetSourcePosition(prop->position()); 1602 SetSourcePosition(prop->position());
1603 Literal* key = prop->key()->AsLiteral(); 1603 Literal* key = prop->key()->AsLiteral();
1604 ASSERT(!key->handle()->IsSmi()); 1604 ASSERT(!key->handle()->IsSmi());
1605 __ mov(ecx, Immediate(key->handle())); 1605 __ mov(ecx, Immediate(key->handle()));
1606 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1606 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1607 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); 1607 __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
1608 } 1608 }
1609 1609
1610 1610
1611 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1611 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1612 SetSourcePosition(prop->position()); 1612 SetSourcePosition(prop->position());
1613 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 1613 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
1614 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); 1614 __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
1615 } 1615 }
1616 1616
1617 1617
1618 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 1618 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
1619 Token::Value op, 1619 Token::Value op,
1620 OverwriteMode mode, 1620 OverwriteMode mode,
1621 Expression* left, 1621 Expression* left,
1622 Expression* right) { 1622 Expression* right) {
1623 // Do combined smi check of the operands. Left operand is on the 1623 // Do combined smi check of the operands. Left operand is on the
1624 // stack. Right operand is in eax. 1624 // stack. Right operand is in eax.
1625 Label smi_case, done, stub_call; 1625 Label smi_case, done, stub_call;
1626 __ pop(edx); 1626 __ pop(edx);
1627 __ mov(ecx, eax); 1627 __ mov(ecx, eax);
1628 __ or_(eax, Operand(edx)); 1628 __ or_(eax, Operand(edx));
1629 JumpPatchSite patch_site(masm_); 1629 JumpPatchSite patch_site(masm_);
1630 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); 1630 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear);
1631 1631
1632 __ bind(&stub_call); 1632 __ bind(&stub_call);
1633 __ mov(eax, ecx); 1633 __ mov(eax, ecx);
1634 BinaryOpStub stub(op, mode); 1634 BinaryOpStub stub(op, mode);
1635 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); 1635 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
1636 patch_site.EmitPatchInfo(); 1636 patch_site.EmitPatchInfo();
1637 __ jmp(&done, Label::kNear); 1637 __ jmp(&done, Label::kNear);
1638 1638
1639 // Smi case. 1639 // Smi case.
1640 __ bind(&smi_case); 1640 __ bind(&smi_case);
1641 __ mov(eax, edx); // Copy left operand in case of a stub call. 1641 __ mov(eax, edx); // Copy left operand in case of a stub call.
1642 1642
1643 switch (op) { 1643 switch (op) {
1644 case Token::SAR: 1644 case Token::SAR:
1645 __ SmiUntag(eax); 1645 __ SmiUntag(eax);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1710 context()->Plug(eax); 1710 context()->Plug(eax);
1711 } 1711 }
1712 1712
1713 1713
1714 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, 1714 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
1715 Token::Value op, 1715 Token::Value op,
1716 OverwriteMode mode) { 1716 OverwriteMode mode) {
1717 __ pop(edx); 1717 __ pop(edx);
1718 BinaryOpStub stub(op, mode); 1718 BinaryOpStub stub(op, mode);
1719 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 1719 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
1720 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); 1720 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
1721 patch_site.EmitPatchInfo(); 1721 patch_site.EmitPatchInfo();
1722 context()->Plug(eax); 1722 context()->Plug(eax);
1723 } 1723 }
1724 1724
1725 1725
1726 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { 1726 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
1727 // Invalid left-hand sides are rewritten to have a 'throw 1727 // Invalid left-hand sides are rewritten to have a 'throw
1728 // ReferenceError' on the left-hand side. 1728 // ReferenceError' on the left-hand side.
1729 if (!expr->IsValidLeftHandSide()) { 1729 if (!expr->IsValidLeftHandSide()) {
1730 VisitForEffect(expr); 1730 VisitForEffect(expr);
(...skipping 20 matching lines...) Expand all
1751 } 1751 }
1752 case NAMED_PROPERTY: { 1752 case NAMED_PROPERTY: {
1753 __ push(eax); // Preserve value. 1753 __ push(eax); // Preserve value.
1754 VisitForAccumulatorValue(prop->obj()); 1754 VisitForAccumulatorValue(prop->obj());
1755 __ mov(edx, eax); 1755 __ mov(edx, eax);
1756 __ pop(eax); // Restore value. 1756 __ pop(eax); // Restore value.
1757 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1757 __ mov(ecx, prop->key()->AsLiteral()->handle());
1758 Handle<Code> ic = is_strict_mode() 1758 Handle<Code> ic = is_strict_mode()
1759 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1759 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1760 : isolate()->builtins()->StoreIC_Initialize(); 1760 : isolate()->builtins()->StoreIC_Initialize();
1761 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 1761 __ call(ic);
1762 break; 1762 break;
1763 } 1763 }
1764 case KEYED_PROPERTY: { 1764 case KEYED_PROPERTY: {
1765 __ push(eax); // Preserve value. 1765 __ push(eax); // Preserve value.
1766 if (prop->is_synthetic()) { 1766 if (prop->is_synthetic()) {
1767 ASSERT(prop->obj()->AsVariableProxy() != NULL); 1767 ASSERT(prop->obj()->AsVariableProxy() != NULL);
1768 ASSERT(prop->key()->AsLiteral() != NULL); 1768 ASSERT(prop->key()->AsLiteral() != NULL);
1769 { AccumulatorValueContext for_object(this); 1769 { AccumulatorValueContext for_object(this);
1770 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); 1770 EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
1771 } 1771 }
1772 __ mov(edx, eax); 1772 __ mov(edx, eax);
1773 __ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle())); 1773 __ SafeSet(ecx, Immediate(prop->key()->AsLiteral()->handle()));
1774 } else { 1774 } else {
1775 VisitForStackValue(prop->obj()); 1775 VisitForStackValue(prop->obj());
1776 VisitForAccumulatorValue(prop->key()); 1776 VisitForAccumulatorValue(prop->key());
1777 __ mov(ecx, eax); 1777 __ mov(ecx, eax);
1778 __ pop(edx); 1778 __ pop(edx);
1779 } 1779 }
1780 __ pop(eax); // Restore value. 1780 __ pop(eax); // Restore value.
1781 Handle<Code> ic = is_strict_mode() 1781 Handle<Code> ic = is_strict_mode()
1782 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1782 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
1783 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1783 : isolate()->builtins()->KeyedStoreIC_Initialize();
1784 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 1784 __ call(ic);
1785 break; 1785 break;
1786 } 1786 }
1787 } 1787 }
1788 PrepareForBailoutForId(bailout_ast_id, TOS_REG); 1788 PrepareForBailoutForId(bailout_ast_id, TOS_REG);
1789 context()->Plug(eax); 1789 context()->Plug(eax);
1790 } 1790 }
1791 1791
1792 1792
1793 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1793 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1794 Token::Value op) { 1794 Token::Value op) {
1795 ASSERT(var != NULL); 1795 ASSERT(var != NULL);
1796 ASSERT(var->is_global() || var->AsSlot() != NULL); 1796 ASSERT(var->is_global() || var->AsSlot() != NULL);
1797 1797
1798 if (var->is_global()) { 1798 if (var->is_global()) {
1799 ASSERT(!var->is_this()); 1799 ASSERT(!var->is_this());
1800 // Assignment to a global variable. Use inline caching for the 1800 // Assignment to a global variable. Use inline caching for the
1801 // assignment. Right-hand-side value is passed in eax, variable name in 1801 // assignment. Right-hand-side value is passed in eax, variable name in
1802 // ecx, and the global object on the stack. 1802 // ecx, and the global object on the stack.
1803 __ mov(ecx, var->name()); 1803 __ mov(ecx, var->name());
1804 __ mov(edx, GlobalObjectOperand()); 1804 __ mov(edx, GlobalObjectOperand());
1805 Handle<Code> ic = is_strict_mode() 1805 Handle<Code> ic = is_strict_mode()
1806 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1806 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1807 : isolate()->builtins()->StoreIC_Initialize(); 1807 : isolate()->builtins()->StoreIC_Initialize();
1808 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber); 1808 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
1809 1809
1810 } else if (op == Token::INIT_CONST) { 1810 } else if (op == Token::INIT_CONST) {
1811 // Like var declarations, const declarations are hoisted to function 1811 // Like var declarations, const declarations are hoisted to function
1812 // scope. However, unlike var initializers, const initializers are able 1812 // scope. However, unlike var initializers, const initializers are able
1813 // to drill a hole to that function context, even from inside a 'with' 1813 // to drill a hole to that function context, even from inside a 'with'
1814 // context. We thus bypass the normal static scope lookup. 1814 // context. We thus bypass the normal static scope lookup.
1815 Slot* slot = var->AsSlot(); 1815 Slot* slot = var->AsSlot();
1816 Label skip; 1816 Label skip;
1817 switch (slot->type()) { 1817 switch (slot->type()) {
1818 case Slot::PARAMETER: 1818 case Slot::PARAMETER:
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1891 SetSourcePosition(expr->position()); 1891 SetSourcePosition(expr->position());
1892 __ mov(ecx, prop->key()->AsLiteral()->handle()); 1892 __ mov(ecx, prop->key()->AsLiteral()->handle());
1893 if (expr->ends_initialization_block()) { 1893 if (expr->ends_initialization_block()) {
1894 __ mov(edx, Operand(esp, 0)); 1894 __ mov(edx, Operand(esp, 0));
1895 } else { 1895 } else {
1896 __ pop(edx); 1896 __ pop(edx);
1897 } 1897 }
1898 Handle<Code> ic = is_strict_mode() 1898 Handle<Code> ic = is_strict_mode()
1899 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1899 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1900 : isolate()->builtins()->StoreIC_Initialize(); 1900 : isolate()->builtins()->StoreIC_Initialize();
1901 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); 1901 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
1902 1902
1903 // If the assignment ends an initialization block, revert to fast case. 1903 // If the assignment ends an initialization block, revert to fast case.
1904 if (expr->ends_initialization_block()) { 1904 if (expr->ends_initialization_block()) {
1905 __ push(eax); // Result of assignment, saved even if not needed. 1905 __ push(eax); // Result of assignment, saved even if not needed.
1906 __ push(Operand(esp, kPointerSize)); // Receiver is under value. 1906 __ push(Operand(esp, kPointerSize)); // Receiver is under value.
1907 __ CallRuntime(Runtime::kToFastProperties, 1); 1907 __ CallRuntime(Runtime::kToFastProperties, 1);
1908 __ pop(eax); 1908 __ pop(eax);
1909 __ Drop(1); 1909 __ Drop(1);
1910 } 1910 }
1911 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1911 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
(...skipping 19 matching lines...) Expand all
1931 if (expr->ends_initialization_block()) { 1931 if (expr->ends_initialization_block()) {
1932 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. 1932 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later.
1933 } else { 1933 } else {
1934 __ pop(edx); 1934 __ pop(edx);
1935 } 1935 }
1936 // Record source code position before IC call. 1936 // Record source code position before IC call.
1937 SetSourcePosition(expr->position()); 1937 SetSourcePosition(expr->position());
1938 Handle<Code> ic = is_strict_mode() 1938 Handle<Code> ic = is_strict_mode()
1939 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1939 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
1940 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1940 : isolate()->builtins()->KeyedStoreIC_Initialize();
1941 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); 1941 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
1942 1942
1943 // If the assignment ends an initialization block, revert to fast case. 1943 // If the assignment ends an initialization block, revert to fast case.
1944 if (expr->ends_initialization_block()) { 1944 if (expr->ends_initialization_block()) {
1945 __ pop(edx); 1945 __ pop(edx);
1946 __ push(eax); // Result of assignment, saved even if not needed. 1946 __ push(eax); // Result of assignment, saved even if not needed.
1947 __ push(edx); 1947 __ push(edx);
1948 __ CallRuntime(Runtime::kToFastProperties, 1); 1948 __ CallRuntime(Runtime::kToFastProperties, 1);
1949 __ pop(eax); 1949 __ pop(eax);
1950 } 1950 }
1951 1951
(...skipping 30 matching lines...) Expand all
1982 for (int i = 0; i < arg_count; i++) { 1982 for (int i = 0; i < arg_count; i++) {
1983 VisitForStackValue(args->at(i)); 1983 VisitForStackValue(args->at(i));
1984 } 1984 }
1985 __ Set(ecx, Immediate(name)); 1985 __ Set(ecx, Immediate(name));
1986 } 1986 }
1987 // Record source position of the IC call. 1987 // Record source position of the IC call.
1988 SetSourcePosition(expr->position()); 1988 SetSourcePosition(expr->position());
1989 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 1989 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1990 Handle<Code> ic = 1990 Handle<Code> ic =
1991 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); 1991 isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode);
1992 EmitCallIC(ic, mode, expr->id()); 1992 __ call(ic, mode, expr->id());
1993 RecordJSReturnSite(expr); 1993 RecordJSReturnSite(expr);
1994 // Restore context register. 1994 // Restore context register.
1995 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 1995 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
1996 context()->Plug(eax); 1996 context()->Plug(eax);
1997 } 1997 }
1998 1998
1999 1999
2000 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2000 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2001 Expression* key) { 2001 Expression* key) {
2002 // Load the key. 2002 // Load the key.
(...skipping 12 matching lines...) Expand all
2015 for (int i = 0; i < arg_count; i++) { 2015 for (int i = 0; i < arg_count; i++) {
2016 VisitForStackValue(args->at(i)); 2016 VisitForStackValue(args->at(i));
2017 } 2017 }
2018 } 2018 }
2019 // Record source position of the IC call. 2019 // Record source position of the IC call.
2020 SetSourcePosition(expr->position()); 2020 SetSourcePosition(expr->position());
2021 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2021 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2022 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize( 2022 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(
2023 arg_count, in_loop); 2023 arg_count, in_loop);
2024 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. 2024 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key.
2025 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); 2025 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
2026 RecordJSReturnSite(expr); 2026 RecordJSReturnSite(expr);
2027 // Restore context register. 2027 // Restore context register.
2028 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2028 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2029 context()->DropAndPlug(1, eax); // Drop the key still on the stack. 2029 context()->DropAndPlug(1, eax); // Drop the key still on the stack.
2030 } 2030 }
2031 2031
2032 2032
2033 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { 2033 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
2034 // Code common for calls using the call stub. 2034 // Code common for calls using the call stub.
2035 ZoneList<Expression*>* args = expr->arguments(); 2035 ZoneList<Expression*>* args = expr->arguments();
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
2191 Literal* key = prop->key()->AsLiteral(); 2191 Literal* key = prop->key()->AsLiteral();
2192 if (key != NULL && key->handle()->IsSymbol()) { 2192 if (key != NULL && key->handle()->IsSymbol()) {
2193 // Call to a named property, use call IC. 2193 // Call to a named property, use call IC.
2194 { PreservePositionScope scope(masm()->positions_recorder()); 2194 { PreservePositionScope scope(masm()->positions_recorder());
2195 VisitForStackValue(prop->obj()); 2195 VisitForStackValue(prop->obj());
2196 } 2196 }
2197 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); 2197 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
2198 } else { 2198 } else {
2199 // Call to a keyed property. 2199 // Call to a keyed property.
2200 // For a synthetic property use keyed load IC followed by function call, 2200 // For a synthetic property use keyed load IC followed by function call,
2201 // for a regular property use keyed EmitCallIC. 2201 // for a regular property use EmitKeyedCallWithIC.
2202 if (prop->is_synthetic()) { 2202 if (prop->is_synthetic()) {
2203 // Do not visit the object and key subexpressions (they are shared 2203 // Do not visit the object and key subexpressions (they are shared
2204 // by all occurrences of the same rewritten parameter). 2204 // by all occurrences of the same rewritten parameter).
2205 ASSERT(prop->obj()->AsVariableProxy() != NULL); 2205 ASSERT(prop->obj()->AsVariableProxy() != NULL);
2206 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL); 2206 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL);
2207 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot(); 2207 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot();
2208 MemOperand operand = EmitSlotSearch(slot, edx); 2208 MemOperand operand = EmitSlotSearch(slot, edx);
2209 __ mov(edx, operand); 2209 __ mov(edx, operand);
2210 2210
2211 ASSERT(prop->key()->AsLiteral() != NULL); 2211 ASSERT(prop->key()->AsLiteral() != NULL);
2212 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); 2212 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi());
2213 __ mov(eax, prop->key()->AsLiteral()->handle()); 2213 __ mov(eax, prop->key()->AsLiteral()->handle());
2214 2214
2215 // Record source code position for IC call. 2215 // Record source code position for IC call.
2216 SetSourcePosition(prop->position()); 2216 SetSourcePosition(prop->position());
2217 2217
2218 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2218 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2219 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); 2219 __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
2220 // Push result (function). 2220 // Push result (function).
2221 __ push(eax); 2221 __ push(eax);
2222 // Push Global receiver. 2222 // Push Global receiver.
2223 __ mov(ecx, GlobalObjectOperand()); 2223 __ mov(ecx, GlobalObjectOperand());
2224 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset)); 2224 __ push(FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset));
2225 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); 2225 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS);
2226 } else { 2226 } else {
2227 { PreservePositionScope scope(masm()->positions_recorder()); 2227 { PreservePositionScope scope(masm()->positions_recorder());
2228 VisitForStackValue(prop->obj()); 2228 VisitForStackValue(prop->obj());
2229 } 2229 }
(...skipping 1325 matching lines...) Expand 10 before | Expand all | Expand 10 after
3555 VisitForStackValue(args->at(i)); 3555 VisitForStackValue(args->at(i));
3556 } 3556 }
3557 3557
3558 if (expr->is_jsruntime()) { 3558 if (expr->is_jsruntime()) {
3559 // Call the JS runtime function via a call IC. 3559 // Call the JS runtime function via a call IC.
3560 __ Set(ecx, Immediate(expr->name())); 3560 __ Set(ecx, Immediate(expr->name()));
3561 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 3561 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
3562 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; 3562 RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
3563 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize( 3563 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(
3564 arg_count, in_loop, mode); 3564 arg_count, in_loop, mode);
3565 EmitCallIC(ic, mode, expr->id()); 3565 __ call(ic, mode, expr->id());
3566 // Restore context register. 3566 // Restore context register.
3567 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3567 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3568 } else { 3568 } else {
3569 // Call the C runtime function. 3569 // Call the C runtime function.
3570 __ CallRuntime(expr->function(), arg_count); 3570 __ CallRuntime(expr->function(), arg_count);
3571 } 3571 }
3572 context()->Plug(eax); 3572 context()->Plug(eax);
3573 } 3573 }
3574 3574
3575 3575
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
3694 // TODO(svenpanne): Allowing format strings in Comment would be nice here... 3694 // TODO(svenpanne): Allowing format strings in Comment would be nice here...
3695 Comment cmt(masm_, comment); 3695 Comment cmt(masm_, comment);
3696 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); 3696 bool can_overwrite = expr->expression()->ResultOverwriteAllowed();
3697 UnaryOverwriteMode overwrite = 3697 UnaryOverwriteMode overwrite =
3698 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; 3698 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE;
3699 UnaryOpStub stub(expr->op(), overwrite); 3699 UnaryOpStub stub(expr->op(), overwrite);
3700 // UnaryOpStub expects the argument to be in the 3700 // UnaryOpStub expects the argument to be in the
3701 // accumulator register eax. 3701 // accumulator register eax.
3702 VisitForAccumulatorValue(expr->expression()); 3702 VisitForAccumulatorValue(expr->expression());
3703 SetSourcePosition(expr->position()); 3703 SetSourcePosition(expr->position());
3704 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); 3704 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
3705 context()->Plug(eax); 3705 context()->Plug(eax);
3706 } 3706 }
3707 3707
3708 3708
3709 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { 3709 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
3710 Comment cmnt(masm_, "[ CountOperation"); 3710 Comment cmnt(masm_, "[ CountOperation");
3711 SetSourcePosition(expr->position()); 3711 SetSourcePosition(expr->position());
3712 3712
3713 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' 3713 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
3714 // as the left-hand side. 3714 // as the left-hand side.
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
3814 } 3814 }
3815 } 3815 }
3816 3816
3817 // Record position before stub call. 3817 // Record position before stub call.
3818 SetSourcePosition(expr->position()); 3818 SetSourcePosition(expr->position());
3819 3819
3820 // Call stub for +1/-1. 3820 // Call stub for +1/-1.
3821 __ mov(edx, eax); 3821 __ mov(edx, eax);
3822 __ mov(eax, Immediate(Smi::FromInt(1))); 3822 __ mov(eax, Immediate(Smi::FromInt(1)));
3823 BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); 3823 BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE);
3824 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId()); 3824 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
3825 patch_site.EmitPatchInfo(); 3825 patch_site.EmitPatchInfo();
3826 __ bind(&done); 3826 __ bind(&done);
3827 3827
3828 // Store the value returned in eax. 3828 // Store the value returned in eax.
3829 switch (assign_type) { 3829 switch (assign_type) {
3830 case VARIABLE: 3830 case VARIABLE:
3831 if (expr->is_postfix()) { 3831 if (expr->is_postfix()) {
3832 // Perform the assignment as if via '='. 3832 // Perform the assignment as if via '='.
3833 { EffectContext context(this); 3833 { EffectContext context(this);
3834 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3834 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
(...skipping 13 matching lines...) Expand all
3848 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3848 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3849 context()->Plug(eax); 3849 context()->Plug(eax);
3850 } 3850 }
3851 break; 3851 break;
3852 case NAMED_PROPERTY: { 3852 case NAMED_PROPERTY: {
3853 __ mov(ecx, prop->key()->AsLiteral()->handle()); 3853 __ mov(ecx, prop->key()->AsLiteral()->handle());
3854 __ pop(edx); 3854 __ pop(edx);
3855 Handle<Code> ic = is_strict_mode() 3855 Handle<Code> ic = is_strict_mode()
3856 ? isolate()->builtins()->StoreIC_Initialize_Strict() 3856 ? isolate()->builtins()->StoreIC_Initialize_Strict()
3857 : isolate()->builtins()->StoreIC_Initialize(); 3857 : isolate()->builtins()->StoreIC_Initialize();
3858 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); 3858 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
3859 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3859 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3860 if (expr->is_postfix()) { 3860 if (expr->is_postfix()) {
3861 if (!context()->IsEffect()) { 3861 if (!context()->IsEffect()) {
3862 context()->PlugTOS(); 3862 context()->PlugTOS();
3863 } 3863 }
3864 } else { 3864 } else {
3865 context()->Plug(eax); 3865 context()->Plug(eax);
3866 } 3866 }
3867 break; 3867 break;
3868 } 3868 }
3869 case KEYED_PROPERTY: { 3869 case KEYED_PROPERTY: {
3870 __ pop(ecx); 3870 __ pop(ecx);
3871 __ pop(edx); 3871 __ pop(edx);
3872 Handle<Code> ic = is_strict_mode() 3872 Handle<Code> ic = is_strict_mode()
3873 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3873 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3874 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3874 : isolate()->builtins()->KeyedStoreIC_Initialize();
3875 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); 3875 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
3876 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3876 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3877 if (expr->is_postfix()) { 3877 if (expr->is_postfix()) {
3878 // Result is on the stack 3878 // Result is on the stack
3879 if (!context()->IsEffect()) { 3879 if (!context()->IsEffect()) {
3880 context()->PlugTOS(); 3880 context()->PlugTOS();
3881 } 3881 }
3882 } else { 3882 } else {
3883 context()->Plug(eax); 3883 context()->Plug(eax);
3884 } 3884 }
3885 break; 3885 break;
3886 } 3886 }
3887 } 3887 }
3888 } 3888 }
3889 3889
3890 3890
3891 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 3891 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
3892 VariableProxy* proxy = expr->AsVariableProxy(); 3892 VariableProxy* proxy = expr->AsVariableProxy();
3893 ASSERT(!context()->IsEffect()); 3893 ASSERT(!context()->IsEffect());
3894 ASSERT(!context()->IsTest()); 3894 ASSERT(!context()->IsTest());
3895 3895
3896 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { 3896 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) {
3897 Comment cmnt(masm_, "Global variable"); 3897 Comment cmnt(masm_, "Global variable");
3898 __ mov(eax, GlobalObjectOperand()); 3898 __ mov(eax, GlobalObjectOperand());
3899 __ mov(ecx, Immediate(proxy->name())); 3899 __ mov(ecx, Immediate(proxy->name()));
3900 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 3900 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
3901 // Use a regular load, not a contextual load, to avoid a reference 3901 // Use a regular load, not a contextual load, to avoid a reference
3902 // error. 3902 // error.
3903 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 3903 __ call(ic);
3904 PrepareForBailout(expr, TOS_REG); 3904 PrepareForBailout(expr, TOS_REG);
3905 context()->Plug(eax); 3905 context()->Plug(eax);
3906 } else if (proxy != NULL && 3906 } else if (proxy != NULL &&
3907 proxy->var()->AsSlot() != NULL && 3907 proxy->var()->AsSlot() != NULL &&
3908 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { 3908 proxy->var()->AsSlot()->type() == Slot::LOOKUP) {
3909 Label done, slow; 3909 Label done, slow;
3910 3910
3911 // Generate code for loading from variables potentially shadowed 3911 // Generate code for loading from variables potentially shadowed
3912 // by eval-introduced variables. 3912 // by eval-introduced variables.
3913 Slot* slot = proxy->var()->AsSlot(); 3913 Slot* slot = proxy->var()->AsSlot();
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
4088 __ or_(ecx, Operand(eax)); 4088 __ or_(ecx, Operand(eax));
4089 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); 4089 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear);
4090 __ cmp(edx, Operand(eax)); 4090 __ cmp(edx, Operand(eax));
4091 Split(cc, if_true, if_false, NULL); 4091 Split(cc, if_true, if_false, NULL);
4092 __ bind(&slow_case); 4092 __ bind(&slow_case);
4093 } 4093 }
4094 4094
4095 // Record position and call the compare IC. 4095 // Record position and call the compare IC.
4096 SetSourcePosition(expr->position()); 4096 SetSourcePosition(expr->position());
4097 Handle<Code> ic = CompareIC::GetUninitialized(op); 4097 Handle<Code> ic = CompareIC::GetUninitialized(op);
4098 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); 4098 __ call(ic, RelocInfo::CODE_TARGET, expr->id());
4099 patch_site.EmitPatchInfo(); 4099 patch_site.EmitPatchInfo();
4100 4100
4101 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4101 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4102 __ test(eax, Operand(eax)); 4102 __ test(eax, Operand(eax));
4103 Split(cc, if_true, if_false, fall_through); 4103 Split(cc, if_true, if_false, fall_through);
4104 } 4104 }
4105 } 4105 }
4106 4106
4107 // Convert the result of the comparison into one expected for this 4107 // Convert the result of the comparison into one expected for this
4108 // expression's context. 4108 // expression's context.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
4148 Register FullCodeGenerator::result_register() { 4148 Register FullCodeGenerator::result_register() {
4149 return eax; 4149 return eax;
4150 } 4150 }
4151 4151
4152 4152
4153 Register FullCodeGenerator::context_register() { 4153 Register FullCodeGenerator::context_register() {
4154 return esi; 4154 return esi;
4155 } 4155 }
4156 4156
4157 4157
4158 void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
4159 RelocInfo::Mode mode,
4160 unsigned ast_id) {
4161 ASSERT(mode == RelocInfo::CODE_TARGET ||
4162 mode == RelocInfo::CODE_TARGET_CONTEXT);
4163 __ call(ic, mode, ast_id);
4164 }
4165
4166
4167 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 4158 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
4168 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); 4159 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
4169 __ mov(Operand(ebp, frame_offset), value); 4160 __ mov(Operand(ebp, frame_offset), value);
4170 } 4161 }
4171 4162
4172 4163
4173 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { 4164 void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
4174 __ mov(dst, ContextOperand(esi, context_index)); 4165 __ mov(dst, ContextOperand(esi, context_index));
4175 } 4166 }
4176 4167
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
4223 // And return. 4214 // And return.
4224 __ ret(0); 4215 __ ret(0);
4225 } 4216 }
4226 4217
4227 4218
4228 #undef __ 4219 #undef __
4229 4220
4230 } } // namespace v8::internal 4221 } } // namespace v8::internal
4231 4222
4232 #endif // V8_TARGET_ARCH_IA32 4223 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/assembler-ia32.h ('k') | src/x64/assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698