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

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

Issue 6902066: Add AST ID to RelocInfo for type-recording ICs. Changes 7644 and 7632, combined. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix an issue where a switch statement label ID could be used for both a load IC and a compare IC. 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/x64/assembler-x64-inl.h ('k') | src/x64/macro-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 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 #define __ ACCESS_MASM(masm_) 44 #define __ ACCESS_MASM(masm_)
45 45
46 46
47 static unsigned GetPropertyId(Property* property) {
48 if (property->is_synthetic()) return AstNode::kNoNumber;
49 return property->id();
50 }
51
52
47 class JumpPatchSite BASE_EMBEDDED { 53 class JumpPatchSite BASE_EMBEDDED {
48 public: 54 public:
49 explicit JumpPatchSite(MacroAssembler* masm) 55 explicit JumpPatchSite(MacroAssembler* masm)
50 : masm_(masm) { 56 : masm_(masm) {
51 #ifdef DEBUG 57 #ifdef DEBUG
52 info_emitted_ = false; 58 info_emitted_ = false;
53 #endif 59 #endif
54 } 60 }
55 61
56 ~JumpPatchSite() { 62 ~JumpPatchSite() {
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 __ movq(rdx, rax); 742 __ movq(rdx, rax);
737 __ LoadRoot(rax, Heap::kTheHoleValueRootIndex); 743 __ LoadRoot(rax, Heap::kTheHoleValueRootIndex);
738 } 744 }
739 ASSERT(prop->key()->AsLiteral() != NULL && 745 ASSERT(prop->key()->AsLiteral() != NULL &&
740 prop->key()->AsLiteral()->handle()->IsSmi()); 746 prop->key()->AsLiteral()->handle()->IsSmi());
741 __ Move(rcx, prop->key()->AsLiteral()->handle()); 747 __ Move(rcx, prop->key()->AsLiteral()->handle());
742 748
743 Handle<Code> ic = is_strict_mode() 749 Handle<Code> ic = is_strict_mode()
744 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 750 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
745 : isolate()->builtins()->KeyedStoreIC_Initialize(); 751 : isolate()->builtins()->KeyedStoreIC_Initialize();
746 EmitCallIC(ic, RelocInfo::CODE_TARGET); 752 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
747 } 753 }
748 } 754 }
749 } 755 }
750 756
751 757
752 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { 758 void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
753 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); 759 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun());
754 } 760 }
755 761
756 762
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
809 __ cmpq(rdx, rax); 815 __ cmpq(rdx, rax);
810 __ j(not_equal, &next_test); 816 __ j(not_equal, &next_test);
811 __ Drop(1); // Switch value is no longer needed. 817 __ Drop(1); // Switch value is no longer needed.
812 __ jmp(clause->body_target()); 818 __ jmp(clause->body_target());
813 __ bind(&slow_case); 819 __ bind(&slow_case);
814 } 820 }
815 821
816 // Record position before stub call for type feedback. 822 // Record position before stub call for type feedback.
817 SetSourcePosition(clause->position()); 823 SetSourcePosition(clause->position());
818 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); 824 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
819 EmitCallIC(ic, &patch_site); 825 EmitCallIC(ic, &patch_site, clause->CompareId());
820 826
821 __ testq(rax, rax); 827 __ testq(rax, rax);
822 __ j(not_equal, &next_test); 828 __ j(not_equal, &next_test);
823 __ Drop(1); // Switch value is no longer needed. 829 __ Drop(1); // Switch value is no longer needed.
824 __ jmp(clause->body_target()); 830 __ jmp(clause->body_target());
825 } 831 }
826 832
827 // Discard the test value and jump to the default if present, otherwise to 833 // Discard the test value and jump to the default if present, otherwise to
828 // the end of the statement. 834 // the end of the statement.
829 __ bind(&next_test); 835 __ bind(&next_test);
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 } 1124 }
1119 1125
1120 // All extension objects were empty and it is safe to use a global 1126 // All extension objects were empty and it is safe to use a global
1121 // load IC call. 1127 // load IC call.
1122 __ movq(rax, GlobalObjectOperand()); 1128 __ movq(rax, GlobalObjectOperand());
1123 __ Move(rcx, slot->var()->name()); 1129 __ Move(rcx, slot->var()->name());
1124 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1130 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1125 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) 1131 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
1126 ? RelocInfo::CODE_TARGET 1132 ? RelocInfo::CODE_TARGET
1127 : RelocInfo::CODE_TARGET_CONTEXT; 1133 : RelocInfo::CODE_TARGET_CONTEXT;
1128 EmitCallIC(ic, mode); 1134 EmitCallIC(ic, mode, AstNode::kNoNumber);
1129 } 1135 }
1130 1136
1131 1137
1132 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( 1138 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(
1133 Slot* slot, 1139 Slot* slot,
1134 Label* slow) { 1140 Label* slow) {
1135 ASSERT(slot->type() == Slot::CONTEXT); 1141 ASSERT(slot->type() == Slot::CONTEXT);
1136 Register context = rsi; 1142 Register context = rsi;
1137 Register temp = rbx; 1143 Register temp = rbx;
1138 1144
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1199 key_literal->handle()->IsSmi()) { 1205 key_literal->handle()->IsSmi()) {
1200 // Load arguments object if there are no eval-introduced 1206 // Load arguments object if there are no eval-introduced
1201 // variables. Then load the argument from the arguments 1207 // variables. Then load the argument from the arguments
1202 // object using keyed load. 1208 // object using keyed load.
1203 __ movq(rdx, 1209 __ movq(rdx,
1204 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), 1210 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
1205 slow)); 1211 slow));
1206 __ Move(rax, key_literal->handle()); 1212 __ Move(rax, key_literal->handle());
1207 Handle<Code> ic = 1213 Handle<Code> ic =
1208 isolate()->builtins()->KeyedLoadIC_Initialize(); 1214 isolate()->builtins()->KeyedLoadIC_Initialize();
1209 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1215 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
1210 __ jmp(done); 1216 __ jmp(done);
1211 } 1217 }
1212 } 1218 }
1213 } 1219 }
1214 } 1220 }
1215 } 1221 }
1216 1222
1217 1223
1218 void FullCodeGenerator::EmitVariableLoad(Variable* var) { 1224 void FullCodeGenerator::EmitVariableLoad(Variable* var) {
1219 // Four cases: non-this global variables, lookup slots, all other 1225 // Four cases: non-this global variables, lookup slots, all other
1220 // types of slots, and parameters that rewrite to explicit property 1226 // types of slots, and parameters that rewrite to explicit property
1221 // accesses on the arguments object. 1227 // accesses on the arguments object.
1222 Slot* slot = var->AsSlot(); 1228 Slot* slot = var->AsSlot();
1223 Property* property = var->AsProperty(); 1229 Property* property = var->AsProperty();
1224 1230
1225 if (var->is_global() && !var->is_this()) { 1231 if (var->is_global() && !var->is_this()) {
1226 Comment cmnt(masm_, "Global variable"); 1232 Comment cmnt(masm_, "Global variable");
1227 // Use inline caching. Variable name is passed in rcx and the global 1233 // Use inline caching. Variable name is passed in rcx and the global
1228 // object on the stack. 1234 // object on the stack.
1229 __ Move(rcx, var->name()); 1235 __ Move(rcx, var->name());
1230 __ movq(rax, GlobalObjectOperand()); 1236 __ movq(rax, GlobalObjectOperand());
1231 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1237 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1232 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); 1238 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber);
1233 context()->Plug(rax); 1239 context()->Plug(rax);
1234 1240
1235 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { 1241 } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
1236 Label done, slow; 1242 Label done, slow;
1237 1243
1238 // Generate code for loading from variables potentially shadowed 1244 // Generate code for loading from variables potentially shadowed
1239 // by eval-introduced variables. 1245 // by eval-introduced variables.
1240 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); 1246 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done);
1241 1247
1242 __ bind(&slow); 1248 __ bind(&slow);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1285 // Assert that the key is a smi. 1291 // Assert that the key is a smi.
1286 Literal* key_literal = property->key()->AsLiteral(); 1292 Literal* key_literal = property->key()->AsLiteral();
1287 ASSERT_NOT_NULL(key_literal); 1293 ASSERT_NOT_NULL(key_literal);
1288 ASSERT(key_literal->handle()->IsSmi()); 1294 ASSERT(key_literal->handle()->IsSmi());
1289 1295
1290 // Load the key. 1296 // Load the key.
1291 __ Move(rax, key_literal->handle()); 1297 __ Move(rax, key_literal->handle());
1292 1298
1293 // Do a keyed property load. 1299 // Do a keyed property load.
1294 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 1300 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
1295 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1301 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
1296 context()->Plug(rax); 1302 context()->Plug(rax);
1297 } 1303 }
1298 } 1304 }
1299 1305
1300 1306
1301 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1307 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1302 Comment cmnt(masm_, "[ RegExpLiteral"); 1308 Comment cmnt(masm_, "[ RegExpLiteral");
1303 Label materialized; 1309 Label materialized;
1304 // Registers will be used as follows: 1310 // Registers will be used as follows:
1305 // rdi = JS function. 1311 // rdi = JS function.
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1396 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1402 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1397 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 1403 ASSERT(!CompileTimeValue::IsCompileTimeValue(value));
1398 // Fall through. 1404 // Fall through.
1399 case ObjectLiteral::Property::COMPUTED: 1405 case ObjectLiteral::Property::COMPUTED:
1400 if (key->handle()->IsSymbol()) { 1406 if (key->handle()->IsSymbol()) {
1401 VisitForAccumulatorValue(value); 1407 VisitForAccumulatorValue(value);
1402 __ Move(rcx, key->handle()); 1408 __ Move(rcx, key->handle());
1403 __ movq(rdx, Operand(rsp, 0)); 1409 __ movq(rdx, Operand(rsp, 0));
1404 if (property->emit_store()) { 1410 if (property->emit_store()) {
1405 Handle<Code> ic = isolate()->builtins()->StoreIC_Initialize(); 1411 Handle<Code> ic = isolate()->builtins()->StoreIC_Initialize();
1406 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1412 EmitCallIC(ic, RelocInfo::CODE_TARGET, key->id());
1407 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1413 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1408 } 1414 }
1409 break; 1415 break;
1410 } 1416 }
1411 // Fall through. 1417 // Fall through.
1412 case ObjectLiteral::Property::PROTOTYPE: 1418 case ObjectLiteral::Property::PROTOTYPE:
1413 __ push(Operand(rsp, 0)); // Duplicate receiver. 1419 __ push(Operand(rsp, 0)); // Duplicate receiver.
1414 VisitForStackValue(key); 1420 VisitForStackValue(key);
1415 VisitForStackValue(value); 1421 VisitForStackValue(value);
1416 if (property->emit_store()) { 1422 if (property->emit_store()) {
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1599 Token::Value op = expr->binary_op(); 1605 Token::Value op = expr->binary_op();
1600 __ push(rax); // Left operand goes on the stack. 1606 __ push(rax); // Left operand goes on the stack.
1601 VisitForAccumulatorValue(expr->value()); 1607 VisitForAccumulatorValue(expr->value());
1602 1608
1603 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() 1609 OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
1604 ? OVERWRITE_RIGHT 1610 ? OVERWRITE_RIGHT
1605 : NO_OVERWRITE; 1611 : NO_OVERWRITE;
1606 SetSourcePosition(expr->position() + 1); 1612 SetSourcePosition(expr->position() + 1);
1607 AccumulatorValueContext context(this); 1613 AccumulatorValueContext context(this);
1608 if (ShouldInlineSmiCase(op)) { 1614 if (ShouldInlineSmiCase(op)) {
1609 EmitInlineSmiBinaryOp(expr, 1615 EmitInlineSmiBinaryOp(expr->binary_operation(),
1610 op, 1616 op,
1611 mode, 1617 mode,
1612 expr->target(), 1618 expr->target(),
1613 expr->value()); 1619 expr->value());
1614 } else { 1620 } else {
1615 EmitBinaryOp(op, mode); 1621 EmitBinaryOp(expr->binary_operation(), op, mode);
1616 } 1622 }
1617 // Deoptimization point in case the binary operation may have side effects. 1623 // Deoptimization point in case the binary operation may have side effects.
1618 PrepareForBailout(expr->binary_operation(), TOS_REG); 1624 PrepareForBailout(expr->binary_operation(), TOS_REG);
1619 } else { 1625 } else {
1620 VisitForAccumulatorValue(expr->value()); 1626 VisitForAccumulatorValue(expr->value());
1621 } 1627 }
1622 1628
1623 // Record source position before possible IC call. 1629 // Record source position before possible IC call.
1624 SetSourcePosition(expr->position()); 1630 SetSourcePosition(expr->position());
1625 1631
(...skipping 13 matching lines...) Expand all
1639 break; 1645 break;
1640 } 1646 }
1641 } 1647 }
1642 1648
1643 1649
1644 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 1650 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1645 SetSourcePosition(prop->position()); 1651 SetSourcePosition(prop->position());
1646 Literal* key = prop->key()->AsLiteral(); 1652 Literal* key = prop->key()->AsLiteral();
1647 __ Move(rcx, key->handle()); 1653 __ Move(rcx, key->handle());
1648 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1654 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1649 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1655 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
1650 } 1656 }
1651 1657
1652 1658
1653 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1659 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1654 SetSourcePosition(prop->position()); 1660 SetSourcePosition(prop->position());
1655 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 1661 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
1656 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1662 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
1657 } 1663 }
1658 1664
1659 1665
1660 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, 1666 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
1661 Token::Value op, 1667 Token::Value op,
1662 OverwriteMode mode, 1668 OverwriteMode mode,
1663 Expression* left, 1669 Expression* left,
1664 Expression* right) { 1670 Expression* right) {
1665 // Do combined smi check of the operands. Left operand is on the 1671 // Do combined smi check of the operands. Left operand is on the
1666 // stack (popped into rdx). Right operand is in rax but moved into 1672 // stack (popped into rdx). Right operand is in rax but moved into
1667 // rcx to make the shifts easier. 1673 // rcx to make the shifts easier.
1668 NearLabel done, stub_call, smi_case; 1674 NearLabel done, stub_call, smi_case;
1669 __ pop(rdx); 1675 __ pop(rdx);
1670 __ movq(rcx, rax); 1676 __ movq(rcx, rax);
1671 __ or_(rax, rdx); 1677 __ or_(rax, rdx);
1672 JumpPatchSite patch_site(masm_); 1678 JumpPatchSite patch_site(masm_);
1673 patch_site.EmitJumpIfSmi(rax, &smi_case); 1679 patch_site.EmitJumpIfSmi(rax, &smi_case);
1674 1680
1675 __ bind(&stub_call); 1681 __ bind(&stub_call);
1676 __ movq(rax, rcx); 1682 __ movq(rax, rcx);
1677 TypeRecordingBinaryOpStub stub(op, mode); 1683 TypeRecordingBinaryOpStub stub(op, mode);
1678 EmitCallIC(stub.GetCode(), &patch_site); 1684 EmitCallIC(stub.GetCode(), &patch_site, expr->id());
1679 __ jmp(&done); 1685 __ jmp(&done);
1680 1686
1681 __ bind(&smi_case); 1687 __ bind(&smi_case);
1682 switch (op) { 1688 switch (op) {
1683 case Token::SAR: 1689 case Token::SAR:
1684 __ SmiShiftArithmeticRight(rax, rdx, rcx); 1690 __ SmiShiftArithmeticRight(rax, rdx, rcx);
1685 break; 1691 break;
1686 case Token::SHL: 1692 case Token::SHL:
1687 __ SmiShiftLeft(rax, rdx, rcx); 1693 __ SmiShiftLeft(rax, rdx, rcx);
1688 break; 1694 break;
(...skipping 21 matching lines...) Expand all
1710 default: 1716 default:
1711 UNREACHABLE(); 1717 UNREACHABLE();
1712 break; 1718 break;
1713 } 1719 }
1714 1720
1715 __ bind(&done); 1721 __ bind(&done);
1716 context()->Plug(rax); 1722 context()->Plug(rax);
1717 } 1723 }
1718 1724
1719 1725
1720 void FullCodeGenerator::EmitBinaryOp(Token::Value op, 1726 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
1727 Token::Value op,
1721 OverwriteMode mode) { 1728 OverwriteMode mode) {
1722 __ pop(rdx); 1729 __ pop(rdx);
1723 TypeRecordingBinaryOpStub stub(op, mode); 1730 TypeRecordingBinaryOpStub stub(op, mode);
1724 EmitCallIC(stub.GetCode(), NULL); // NULL signals no inlined smi code. 1731 // NULL signals no inlined smi code.
1732 EmitCallIC(stub.GetCode(), NULL, expr->id());
1725 context()->Plug(rax); 1733 context()->Plug(rax);
1726 } 1734 }
1727 1735
1728 1736
1729 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { 1737 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
1730 // Invalid left-hand sides are rewritten to have a 'throw 1738 // Invalid left-hand sides are rewritten to have a 'throw
1731 // ReferenceError' on the left-hand side. 1739 // ReferenceError' on the left-hand side.
1732 if (!expr->IsValidLeftHandSide()) { 1740 if (!expr->IsValidLeftHandSide()) {
1733 VisitForEffect(expr); 1741 VisitForEffect(expr);
1734 return; 1742 return;
(...skipping 19 matching lines...) Expand all
1754 } 1762 }
1755 case NAMED_PROPERTY: { 1763 case NAMED_PROPERTY: {
1756 __ push(rax); // Preserve value. 1764 __ push(rax); // Preserve value.
1757 VisitForAccumulatorValue(prop->obj()); 1765 VisitForAccumulatorValue(prop->obj());
1758 __ movq(rdx, rax); 1766 __ movq(rdx, rax);
1759 __ pop(rax); // Restore value. 1767 __ pop(rax); // Restore value.
1760 __ Move(rcx, prop->key()->AsLiteral()->handle()); 1768 __ Move(rcx, prop->key()->AsLiteral()->handle());
1761 Handle<Code> ic = is_strict_mode() 1769 Handle<Code> ic = is_strict_mode()
1762 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1770 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1763 : isolate()->builtins()->StoreIC_Initialize(); 1771 : isolate()->builtins()->StoreIC_Initialize();
1764 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1772 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
1765 break; 1773 break;
1766 } 1774 }
1767 case KEYED_PROPERTY: { 1775 case KEYED_PROPERTY: {
1768 __ push(rax); // Preserve value. 1776 __ push(rax); // Preserve value.
1769 if (prop->is_synthetic()) { 1777 if (prop->is_synthetic()) {
1770 ASSERT(prop->obj()->AsVariableProxy() != NULL); 1778 ASSERT(prop->obj()->AsVariableProxy() != NULL);
1771 ASSERT(prop->key()->AsLiteral() != NULL); 1779 ASSERT(prop->key()->AsLiteral() != NULL);
1772 { AccumulatorValueContext for_object(this); 1780 { AccumulatorValueContext for_object(this);
1773 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); 1781 EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
1774 } 1782 }
1775 __ movq(rdx, rax); 1783 __ movq(rdx, rax);
1776 __ Move(rcx, prop->key()->AsLiteral()->handle()); 1784 __ Move(rcx, prop->key()->AsLiteral()->handle());
1777 } else { 1785 } else {
1778 VisitForStackValue(prop->obj()); 1786 VisitForStackValue(prop->obj());
1779 VisitForAccumulatorValue(prop->key()); 1787 VisitForAccumulatorValue(prop->key());
1780 __ movq(rcx, rax); 1788 __ movq(rcx, rax);
1781 __ pop(rdx); 1789 __ pop(rdx);
1782 } 1790 }
1783 __ pop(rax); // Restore value. 1791 __ pop(rax); // Restore value.
1784 Handle<Code> ic = is_strict_mode() 1792 Handle<Code> ic = is_strict_mode()
1785 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1793 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
1786 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1794 : isolate()->builtins()->KeyedStoreIC_Initialize();
1787 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1795 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
1788 break; 1796 break;
1789 } 1797 }
1790 } 1798 }
1791 PrepareForBailoutForId(bailout_ast_id, TOS_REG); 1799 PrepareForBailoutForId(bailout_ast_id, TOS_REG);
1792 context()->Plug(rax); 1800 context()->Plug(rax);
1793 } 1801 }
1794 1802
1795 1803
1796 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1804 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1797 Token::Value op) { 1805 Token::Value op) {
1798 // Left-hand sides that rewrite to explicit property accesses do not reach 1806 // Left-hand sides that rewrite to explicit property accesses do not reach
1799 // here. 1807 // here.
1800 ASSERT(var != NULL); 1808 ASSERT(var != NULL);
1801 ASSERT(var->is_global() || var->AsSlot() != NULL); 1809 ASSERT(var->is_global() || var->AsSlot() != NULL);
1802 1810
1803 if (var->is_global()) { 1811 if (var->is_global()) {
1804 ASSERT(!var->is_this()); 1812 ASSERT(!var->is_this());
1805 // Assignment to a global variable. Use inline caching for the 1813 // Assignment to a global variable. Use inline caching for the
1806 // assignment. Right-hand-side value is passed in rax, variable name in 1814 // assignment. Right-hand-side value is passed in rax, variable name in
1807 // rcx, and the global object on the stack. 1815 // rcx, and the global object on the stack.
1808 __ Move(rcx, var->name()); 1816 __ Move(rcx, var->name());
1809 __ movq(rdx, GlobalObjectOperand()); 1817 __ movq(rdx, GlobalObjectOperand());
1810 Handle<Code> ic = is_strict_mode() 1818 Handle<Code> ic = is_strict_mode()
1811 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1819 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1812 : isolate()->builtins()->StoreIC_Initialize(); 1820 : isolate()->builtins()->StoreIC_Initialize();
1813 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); 1821 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber);
1814 1822
1815 } else if (op == Token::INIT_CONST) { 1823 } else if (op == Token::INIT_CONST) {
1816 // Like var declarations, const declarations are hoisted to function 1824 // Like var declarations, const declarations are hoisted to function
1817 // scope. However, unlike var initializers, const initializers are able 1825 // scope. However, unlike var initializers, const initializers are able
1818 // to drill a hole to that function context, even from inside a 'with' 1826 // to drill a hole to that function context, even from inside a 'with'
1819 // context. We thus bypass the normal static scope lookup. 1827 // context. We thus bypass the normal static scope lookup.
1820 Slot* slot = var->AsSlot(); 1828 Slot* slot = var->AsSlot();
1821 Label skip; 1829 Label skip;
1822 switch (slot->type()) { 1830 switch (slot->type()) {
1823 case Slot::PARAMETER: 1831 case Slot::PARAMETER:
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1906 SetSourcePosition(expr->position()); 1914 SetSourcePosition(expr->position());
1907 __ Move(rcx, prop->key()->AsLiteral()->handle()); 1915 __ Move(rcx, prop->key()->AsLiteral()->handle());
1908 if (expr->ends_initialization_block()) { 1916 if (expr->ends_initialization_block()) {
1909 __ movq(rdx, Operand(rsp, 0)); 1917 __ movq(rdx, Operand(rsp, 0));
1910 } else { 1918 } else {
1911 __ pop(rdx); 1919 __ pop(rdx);
1912 } 1920 }
1913 Handle<Code> ic = is_strict_mode() 1921 Handle<Code> ic = is_strict_mode()
1914 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1922 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1915 : isolate()->builtins()->StoreIC_Initialize(); 1923 : isolate()->builtins()->StoreIC_Initialize();
1916 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1924 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
1917 1925
1918 // If the assignment ends an initialization block, revert to fast case. 1926 // If the assignment ends an initialization block, revert to fast case.
1919 if (expr->ends_initialization_block()) { 1927 if (expr->ends_initialization_block()) {
1920 __ push(rax); // Result of assignment, saved even if not needed. 1928 __ push(rax); // Result of assignment, saved even if not needed.
1921 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. 1929 __ push(Operand(rsp, kPointerSize)); // Receiver is under value.
1922 __ CallRuntime(Runtime::kToFastProperties, 1); 1930 __ CallRuntime(Runtime::kToFastProperties, 1);
1923 __ pop(rax); 1931 __ pop(rax);
1924 __ Drop(1); 1932 __ Drop(1);
1925 } 1933 }
1926 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1934 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
(...skipping 19 matching lines...) Expand all
1946 if (expr->ends_initialization_block()) { 1954 if (expr->ends_initialization_block()) {
1947 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later. 1955 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later.
1948 } else { 1956 } else {
1949 __ pop(rdx); 1957 __ pop(rdx);
1950 } 1958 }
1951 // Record source code position before IC call. 1959 // Record source code position before IC call.
1952 SetSourcePosition(expr->position()); 1960 SetSourcePosition(expr->position());
1953 Handle<Code> ic = is_strict_mode() 1961 Handle<Code> ic = is_strict_mode()
1954 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1962 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
1955 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1963 : isolate()->builtins()->KeyedStoreIC_Initialize();
1956 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1964 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
1957 1965
1958 // If the assignment ends an initialization block, revert to fast case. 1966 // If the assignment ends an initialization block, revert to fast case.
1959 if (expr->ends_initialization_block()) { 1967 if (expr->ends_initialization_block()) {
1960 __ pop(rdx); 1968 __ pop(rdx);
1961 __ push(rax); // Result of assignment, saved even if not needed. 1969 __ push(rax); // Result of assignment, saved even if not needed.
1962 __ push(rdx); 1970 __ push(rdx);
1963 __ CallRuntime(Runtime::kToFastProperties, 1); 1971 __ CallRuntime(Runtime::kToFastProperties, 1);
1964 __ pop(rax); 1972 __ pop(rax);
1965 } 1973 }
1966 1974
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1998 VisitForStackValue(args->at(i)); 2006 VisitForStackValue(args->at(i));
1999 } 2007 }
2000 __ Move(rcx, name); 2008 __ Move(rcx, name);
2001 } 2009 }
2002 // Record source position for debugger. 2010 // Record source position for debugger.
2003 SetSourcePosition(expr->position()); 2011 SetSourcePosition(expr->position());
2004 // Call the IC initialization code. 2012 // Call the IC initialization code.
2005 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2013 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2006 Handle<Code> ic = 2014 Handle<Code> ic =
2007 ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop); 2015 ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop);
2008 EmitCallIC(ic, mode); 2016 EmitCallIC(ic, mode, expr->id());
2009 RecordJSReturnSite(expr); 2017 RecordJSReturnSite(expr);
2010 // Restore context register. 2018 // Restore context register.
2011 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2019 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2012 context()->Plug(rax); 2020 context()->Plug(rax);
2013 } 2021 }
2014 2022
2015 2023
2016 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2024 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2017 Expression* key, 2025 Expression* key,
2018 RelocInfo::Mode mode) { 2026 RelocInfo::Mode mode) {
(...skipping 14 matching lines...) Expand all
2033 VisitForStackValue(args->at(i)); 2041 VisitForStackValue(args->at(i));
2034 } 2042 }
2035 } 2043 }
2036 // Record source position for debugger. 2044 // Record source position for debugger.
2037 SetSourcePosition(expr->position()); 2045 SetSourcePosition(expr->position());
2038 // Call the IC initialization code. 2046 // Call the IC initialization code.
2039 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2047 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2040 Handle<Code> ic = 2048 Handle<Code> ic =
2041 ISOLATE->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); 2049 ISOLATE->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop);
2042 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. 2050 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key.
2043 EmitCallIC(ic, mode); 2051 EmitCallIC(ic, mode, expr->id());
2044 RecordJSReturnSite(expr); 2052 RecordJSReturnSite(expr);
2045 // Restore context register. 2053 // Restore context register.
2046 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2054 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2047 context()->DropAndPlug(1, rax); // Drop the key still on the stack. 2055 context()->DropAndPlug(1, rax); // Drop the key still on the stack.
2048 } 2056 }
2049 2057
2050 2058
2051 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 2059 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
2052 // Code common for calls using the call stub. 2060 // Code common for calls using the call stub.
2053 ZoneList<Expression*>* args = expr->arguments(); 2061 ZoneList<Expression*>* args = expr->arguments();
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
2225 __ movq(rdx, operand); 2233 __ movq(rdx, operand);
2226 2234
2227 ASSERT(prop->key()->AsLiteral() != NULL); 2235 ASSERT(prop->key()->AsLiteral() != NULL);
2228 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); 2236 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi());
2229 __ Move(rax, prop->key()->AsLiteral()->handle()); 2237 __ Move(rax, prop->key()->AsLiteral()->handle());
2230 2238
2231 // Record source code position for IC call. 2239 // Record source code position for IC call.
2232 SetSourcePosition(prop->position()); 2240 SetSourcePosition(prop->position());
2233 2241
2234 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2242 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2235 EmitCallIC(ic, RelocInfo::CODE_TARGET); 2243 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
2236 // Push result (function). 2244 // Push result (function).
2237 __ push(rax); 2245 __ push(rax);
2238 // Push Global receiver. 2246 // Push Global receiver.
2239 __ movq(rcx, GlobalObjectOperand()); 2247 __ movq(rcx, GlobalObjectOperand());
2240 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); 2248 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset));
2241 EmitCallWithStub(expr); 2249 EmitCallWithStub(expr);
2242 } else { 2250 } else {
2243 { PreservePositionScope scope(masm()->positions_recorder()); 2251 { PreservePositionScope scope(masm()->positions_recorder());
2244 VisitForStackValue(prop->obj()); 2252 VisitForStackValue(prop->obj());
2245 } 2253 }
(...skipping 1339 matching lines...) Expand 10 before | Expand all | Expand 10 after
3585 for (int i = 0; i < arg_count; i++) { 3593 for (int i = 0; i < arg_count; i++) {
3586 VisitForStackValue(args->at(i)); 3594 VisitForStackValue(args->at(i));
3587 } 3595 }
3588 3596
3589 if (expr->is_jsruntime()) { 3597 if (expr->is_jsruntime()) {
3590 // Call the JS runtime function using a call IC. 3598 // Call the JS runtime function using a call IC.
3591 __ Move(rcx, expr->name()); 3599 __ Move(rcx, expr->name());
3592 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 3600 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
3593 Handle<Code> ic = 3601 Handle<Code> ic =
3594 ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop); 3602 ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop);
3595 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3603 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
3596 // Restore context register. 3604 // Restore context register.
3597 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 3605 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
3598 } else { 3606 } else {
3599 __ CallRuntime(expr->function(), arg_count); 3607 __ CallRuntime(expr->function(), arg_count);
3600 } 3608 }
3601 context()->Plug(rax); 3609 context()->Plug(rax);
3602 } 3610 }
3603 3611
3604 3612
3605 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3613 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
3870 SetSourcePosition(expr->position()); 3878 SetSourcePosition(expr->position());
3871 3879
3872 // Call stub for +1/-1. 3880 // Call stub for +1/-1.
3873 TypeRecordingBinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); 3881 TypeRecordingBinaryOpStub stub(expr->binary_op(), NO_OVERWRITE);
3874 if (expr->op() == Token::INC) { 3882 if (expr->op() == Token::INC) {
3875 __ Move(rdx, Smi::FromInt(1)); 3883 __ Move(rdx, Smi::FromInt(1));
3876 } else { 3884 } else {
3877 __ movq(rdx, rax); 3885 __ movq(rdx, rax);
3878 __ Move(rax, Smi::FromInt(1)); 3886 __ Move(rax, Smi::FromInt(1));
3879 } 3887 }
3880 EmitCallIC(stub.GetCode(), &patch_site); 3888 EmitCallIC(stub.GetCode(), &patch_site, expr->CountId());
3881 __ bind(&done); 3889 __ bind(&done);
3882 3890
3883 // Store the value returned in rax. 3891 // Store the value returned in rax.
3884 switch (assign_type) { 3892 switch (assign_type) {
3885 case VARIABLE: 3893 case VARIABLE:
3886 if (expr->is_postfix()) { 3894 if (expr->is_postfix()) {
3887 // Perform the assignment as if via '='. 3895 // Perform the assignment as if via '='.
3888 { EffectContext context(this); 3896 { EffectContext context(this);
3889 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3897 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3890 Token::ASSIGN); 3898 Token::ASSIGN);
(...skipping 12 matching lines...) Expand all
3903 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3911 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3904 context()->Plug(rax); 3912 context()->Plug(rax);
3905 } 3913 }
3906 break; 3914 break;
3907 case NAMED_PROPERTY: { 3915 case NAMED_PROPERTY: {
3908 __ Move(rcx, prop->key()->AsLiteral()->handle()); 3916 __ Move(rcx, prop->key()->AsLiteral()->handle());
3909 __ pop(rdx); 3917 __ pop(rdx);
3910 Handle<Code> ic = is_strict_mode() 3918 Handle<Code> ic = is_strict_mode()
3911 ? isolate()->builtins()->StoreIC_Initialize_Strict() 3919 ? isolate()->builtins()->StoreIC_Initialize_Strict()
3912 : isolate()->builtins()->StoreIC_Initialize(); 3920 : isolate()->builtins()->StoreIC_Initialize();
3913 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3921 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
3914 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3922 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3915 if (expr->is_postfix()) { 3923 if (expr->is_postfix()) {
3916 if (!context()->IsEffect()) { 3924 if (!context()->IsEffect()) {
3917 context()->PlugTOS(); 3925 context()->PlugTOS();
3918 } 3926 }
3919 } else { 3927 } else {
3920 context()->Plug(rax); 3928 context()->Plug(rax);
3921 } 3929 }
3922 break; 3930 break;
3923 } 3931 }
3924 case KEYED_PROPERTY: { 3932 case KEYED_PROPERTY: {
3925 __ pop(rcx); 3933 __ pop(rcx);
3926 __ pop(rdx); 3934 __ pop(rdx);
3927 Handle<Code> ic = is_strict_mode() 3935 Handle<Code> ic = is_strict_mode()
3928 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3936 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3929 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3937 : isolate()->builtins()->KeyedStoreIC_Initialize();
3930 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3938 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
3931 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3939 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3932 if (expr->is_postfix()) { 3940 if (expr->is_postfix()) {
3933 if (!context()->IsEffect()) { 3941 if (!context()->IsEffect()) {
3934 context()->PlugTOS(); 3942 context()->PlugTOS();
3935 } 3943 }
3936 } else { 3944 } else {
3937 context()->Plug(rax); 3945 context()->Plug(rax);
3938 } 3946 }
3939 break; 3947 break;
3940 } 3948 }
3941 } 3949 }
3942 } 3950 }
3943 3951
3944 3952
3945 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 3953 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
3946 VariableProxy* proxy = expr->AsVariableProxy(); 3954 VariableProxy* proxy = expr->AsVariableProxy();
3947 ASSERT(!context()->IsEffect()); 3955 ASSERT(!context()->IsEffect());
3948 ASSERT(!context()->IsTest()); 3956 ASSERT(!context()->IsTest());
3949 3957
3950 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { 3958 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) {
3951 Comment cmnt(masm_, "Global variable"); 3959 Comment cmnt(masm_, "Global variable");
3952 __ Move(rcx, proxy->name()); 3960 __ Move(rcx, proxy->name());
3953 __ movq(rax, GlobalObjectOperand()); 3961 __ movq(rax, GlobalObjectOperand());
3954 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 3962 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
3955 // Use a regular load, not a contextual load, to avoid a reference 3963 // Use a regular load, not a contextual load, to avoid a reference
3956 // error. 3964 // error.
3957 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3965 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
3958 PrepareForBailout(expr, TOS_REG); 3966 PrepareForBailout(expr, TOS_REG);
3959 context()->Plug(rax); 3967 context()->Plug(rax);
3960 } else if (proxy != NULL && 3968 } else if (proxy != NULL &&
3961 proxy->var()->AsSlot() != NULL && 3969 proxy->var()->AsSlot() != NULL &&
3962 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { 3970 proxy->var()->AsSlot()->type() == Slot::LOOKUP) {
3963 Label done, slow; 3971 Label done, slow;
3964 3972
3965 // Generate code for loading from variables potentially shadowed 3973 // Generate code for loading from variables potentially shadowed
3966 // by eval-introduced variables. 3974 // by eval-introduced variables.
3967 Slot* slot = proxy->var()->AsSlot(); 3975 Slot* slot = proxy->var()->AsSlot();
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
4145 __ or_(rcx, rax); 4153 __ or_(rcx, rax);
4146 patch_site.EmitJumpIfNotSmi(rcx, &slow_case); 4154 patch_site.EmitJumpIfNotSmi(rcx, &slow_case);
4147 __ cmpq(rdx, rax); 4155 __ cmpq(rdx, rax);
4148 Split(cc, if_true, if_false, NULL); 4156 Split(cc, if_true, if_false, NULL);
4149 __ bind(&slow_case); 4157 __ bind(&slow_case);
4150 } 4158 }
4151 4159
4152 // Record position and call the compare IC. 4160 // Record position and call the compare IC.
4153 SetSourcePosition(expr->position()); 4161 SetSourcePosition(expr->position());
4154 Handle<Code> ic = CompareIC::GetUninitialized(op); 4162 Handle<Code> ic = CompareIC::GetUninitialized(op);
4155 EmitCallIC(ic, &patch_site); 4163 EmitCallIC(ic, &patch_site, expr->id());
4156 4164
4157 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4165 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4158 __ testq(rax, rax); 4166 __ testq(rax, rax);
4159 Split(cc, if_true, if_false, fall_through); 4167 Split(cc, if_true, if_false, fall_through);
4160 } 4168 }
4161 } 4169 }
4162 4170
4163 // Convert the result of the comparison into one expected for this 4171 // Convert the result of the comparison into one expected for this
4164 // expression's context. 4172 // expression's context.
4165 context()->Plug(if_true, if_false); 4173 context()->Plug(if_true, if_false);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
4205 Register FullCodeGenerator::result_register() { 4213 Register FullCodeGenerator::result_register() {
4206 return rax; 4214 return rax;
4207 } 4215 }
4208 4216
4209 4217
4210 Register FullCodeGenerator::context_register() { 4218 Register FullCodeGenerator::context_register() {
4211 return rsi; 4219 return rsi;
4212 } 4220 }
4213 4221
4214 4222
4215 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { 4223 void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
4224 RelocInfo::Mode mode,
4225 unsigned ast_id) {
4216 ASSERT(mode == RelocInfo::CODE_TARGET || 4226 ASSERT(mode == RelocInfo::CODE_TARGET ||
4217 mode == RelocInfo::CODE_TARGET_CONTEXT); 4227 mode == RelocInfo::CODE_TARGET_CONTEXT);
4218 Counters* counters = isolate()->counters(); 4228 Counters* counters = isolate()->counters();
4219 switch (ic->kind()) { 4229 switch (ic->kind()) {
4220 case Code::LOAD_IC: 4230 case Code::LOAD_IC:
4221 __ IncrementCounter(counters->named_load_full(), 1); 4231 __ IncrementCounter(counters->named_load_full(), 1);
4222 break; 4232 break;
4223 case Code::KEYED_LOAD_IC: 4233 case Code::KEYED_LOAD_IC:
4224 __ IncrementCounter(counters->keyed_load_full(), 1); 4234 __ IncrementCounter(counters->keyed_load_full(), 1);
4225 break; 4235 break;
4226 case Code::STORE_IC: 4236 case Code::STORE_IC:
4227 __ IncrementCounter(counters->named_store_full(), 1); 4237 __ IncrementCounter(counters->named_store_full(), 1);
4228 break; 4238 break;
4229 case Code::KEYED_STORE_IC: 4239 case Code::KEYED_STORE_IC:
4230 __ IncrementCounter(counters->keyed_store_full(), 1); 4240 __ IncrementCounter(counters->keyed_store_full(), 1);
4231 default: 4241 default:
4232 break; 4242 break;
4233 } 4243 }
4234 __ call(ic, mode); 4244 __ call(ic, mode, ast_id);
4235 } 4245 }
4236 4246
4237 4247
4238 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) { 4248 void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
4249 JumpPatchSite* patch_site,
4250 unsigned ast_id) {
4239 Counters* counters = isolate()->counters(); 4251 Counters* counters = isolate()->counters();
4240 switch (ic->kind()) { 4252 switch (ic->kind()) {
4241 case Code::LOAD_IC: 4253 case Code::LOAD_IC:
4242 __ IncrementCounter(counters->named_load_full(), 1); 4254 __ IncrementCounter(counters->named_load_full(), 1);
4243 break; 4255 break;
4244 case Code::KEYED_LOAD_IC: 4256 case Code::KEYED_LOAD_IC:
4245 __ IncrementCounter(counters->keyed_load_full(), 1); 4257 __ IncrementCounter(counters->keyed_load_full(), 1);
4246 break; 4258 break;
4247 case Code::STORE_IC: 4259 case Code::STORE_IC:
4248 __ IncrementCounter(counters->named_store_full(), 1); 4260 __ IncrementCounter(counters->named_store_full(), 1);
4249 break; 4261 break;
4250 case Code::KEYED_STORE_IC: 4262 case Code::KEYED_STORE_IC:
4251 __ IncrementCounter(counters->keyed_store_full(), 1); 4263 __ IncrementCounter(counters->keyed_store_full(), 1);
4252 default: 4264 default:
4253 break; 4265 break;
4254 } 4266 }
4255 __ call(ic, RelocInfo::CODE_TARGET); 4267 __ call(ic, RelocInfo::CODE_TARGET, ast_id);
4256 if (patch_site != NULL && patch_site->is_bound()) { 4268 if (patch_site != NULL && patch_site->is_bound()) {
4257 patch_site->EmitPatchInfo(); 4269 patch_site->EmitPatchInfo();
4258 } else { 4270 } else {
4259 __ nop(); // Signals no inlined code. 4271 __ nop(); // Signals no inlined code.
4260 } 4272 }
4261 } 4273 }
4262 4274
4263 4275
4264 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 4276 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
4265 ASSERT(IsAligned(frame_offset, kPointerSize)); 4277 ASSERT(IsAligned(frame_offset, kPointerSize));
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
4305 __ ret(0); 4317 __ ret(0);
4306 } 4318 }
4307 4319
4308 4320
4309 #undef __ 4321 #undef __
4310 4322
4311 4323
4312 } } // namespace v8::internal 4324 } } // namespace v8::internal
4313 4325
4314 #endif // V8_TARGET_ARCH_X64 4326 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/assembler-x64-inl.h ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698