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

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

Issue 6793016: Record AST ids in relocation info at spots where we collect dynamic type feedback. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add ARM port 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
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->label()->id());
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 369 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
(...skipping 65 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 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 1340 matching lines...) Expand 10 before | Expand all | Expand 10 after
3586 for (int i = 0; i < arg_count; i++) { 3594 for (int i = 0; i < arg_count; i++) {
3587 VisitForStackValue(args->at(i)); 3595 VisitForStackValue(args->at(i));
3588 } 3596 }
3589 3597
3590 if (expr->is_jsruntime()) { 3598 if (expr->is_jsruntime()) {
3591 // Call the JS runtime function using a call IC. 3599 // Call the JS runtime function using a call IC.
3592 __ Move(rcx, expr->name()); 3600 __ Move(rcx, expr->name());
3593 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 3601 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
3594 Handle<Code> ic = 3602 Handle<Code> ic =
3595 ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop); 3603 ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop);
3596 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3604 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
3597 // Restore context register. 3605 // Restore context register.
3598 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 3606 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
3599 } else { 3607 } else {
3600 __ CallRuntime(expr->function(), arg_count); 3608 __ CallRuntime(expr->function(), arg_count);
3601 } 3609 }
3602 context()->Plug(rax); 3610 context()->Plug(rax);
3603 } 3611 }
3604 3612
3605 3613
3606 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3614 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
3871 SetSourcePosition(expr->position()); 3879 SetSourcePosition(expr->position());
3872 3880
3873 // Call stub for +1/-1. 3881 // Call stub for +1/-1.
3874 TypeRecordingBinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); 3882 TypeRecordingBinaryOpStub stub(expr->binary_op(), NO_OVERWRITE);
3875 if (expr->op() == Token::INC) { 3883 if (expr->op() == Token::INC) {
3876 __ Move(rdx, Smi::FromInt(1)); 3884 __ Move(rdx, Smi::FromInt(1));
3877 } else { 3885 } else {
3878 __ movq(rdx, rax); 3886 __ movq(rdx, rax);
3879 __ Move(rax, Smi::FromInt(1)); 3887 __ Move(rax, Smi::FromInt(1));
3880 } 3888 }
3881 EmitCallIC(stub.GetCode(), &patch_site); 3889 EmitCallIC(stub.GetCode(), &patch_site, expr->CountId());
3882 __ bind(&done); 3890 __ bind(&done);
3883 3891
3884 // Store the value returned in rax. 3892 // Store the value returned in rax.
3885 switch (assign_type) { 3893 switch (assign_type) {
3886 case VARIABLE: 3894 case VARIABLE:
3887 if (expr->is_postfix()) { 3895 if (expr->is_postfix()) {
3888 // Perform the assignment as if via '='. 3896 // Perform the assignment as if via '='.
3889 { EffectContext context(this); 3897 { EffectContext context(this);
3890 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3898 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3891 Token::ASSIGN); 3899 Token::ASSIGN);
(...skipping 12 matching lines...) Expand all
3904 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3912 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3905 context()->Plug(rax); 3913 context()->Plug(rax);
3906 } 3914 }
3907 break; 3915 break;
3908 case NAMED_PROPERTY: { 3916 case NAMED_PROPERTY: {
3909 __ Move(rcx, prop->key()->AsLiteral()->handle()); 3917 __ Move(rcx, prop->key()->AsLiteral()->handle());
3910 __ pop(rdx); 3918 __ pop(rdx);
3911 Handle<Code> ic = is_strict_mode() 3919 Handle<Code> ic = is_strict_mode()
3912 ? isolate()->builtins()->StoreIC_Initialize_Strict() 3920 ? isolate()->builtins()->StoreIC_Initialize_Strict()
3913 : isolate()->builtins()->StoreIC_Initialize(); 3921 : isolate()->builtins()->StoreIC_Initialize();
3914 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3922 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
3915 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3923 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3916 if (expr->is_postfix()) { 3924 if (expr->is_postfix()) {
3917 if (!context()->IsEffect()) { 3925 if (!context()->IsEffect()) {
3918 context()->PlugTOS(); 3926 context()->PlugTOS();
3919 } 3927 }
3920 } else { 3928 } else {
3921 context()->Plug(rax); 3929 context()->Plug(rax);
3922 } 3930 }
3923 break; 3931 break;
3924 } 3932 }
3925 case KEYED_PROPERTY: { 3933 case KEYED_PROPERTY: {
3926 __ pop(rcx); 3934 __ pop(rcx);
3927 __ pop(rdx); 3935 __ pop(rdx);
3928 Handle<Code> ic = is_strict_mode() 3936 Handle<Code> ic = is_strict_mode()
3929 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3937 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3930 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3938 : isolate()->builtins()->KeyedStoreIC_Initialize();
3931 EmitCallIC(ic, RelocInfo::CODE_TARGET); 3939 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id());
3932 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3940 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3933 if (expr->is_postfix()) { 3941 if (expr->is_postfix()) {
3934 if (!context()->IsEffect()) { 3942 if (!context()->IsEffect()) {
3935 context()->PlugTOS(); 3943 context()->PlugTOS();
3936 } 3944 }
3937 } else { 3945 } else {
3938 context()->Plug(rax); 3946 context()->Plug(rax);
3939 } 3947 }
3940 break; 3948 break;
3941 } 3949 }
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
4146 __ or_(rcx, rax); 4154 __ or_(rcx, rax);
4147 patch_site.EmitJumpIfNotSmi(rcx, &slow_case); 4155 patch_site.EmitJumpIfNotSmi(rcx, &slow_case);
4148 __ cmpq(rdx, rax); 4156 __ cmpq(rdx, rax);
4149 Split(cc, if_true, if_false, NULL); 4157 Split(cc, if_true, if_false, NULL);
4150 __ bind(&slow_case); 4158 __ bind(&slow_case);
4151 } 4159 }
4152 4160
4153 // Record position and call the compare IC. 4161 // Record position and call the compare IC.
4154 SetSourcePosition(expr->position()); 4162 SetSourcePosition(expr->position());
4155 Handle<Code> ic = CompareIC::GetUninitialized(op); 4163 Handle<Code> ic = CompareIC::GetUninitialized(op);
4156 EmitCallIC(ic, &patch_site); 4164 EmitCallIC(ic, &patch_site, expr->id());
4157 4165
4158 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4166 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4159 __ testq(rax, rax); 4167 __ testq(rax, rax);
4160 Split(cc, if_true, if_false, fall_through); 4168 Split(cc, if_true, if_false, fall_through);
4161 } 4169 }
4162 } 4170 }
4163 4171
4164 // Convert the result of the comparison into one expected for this 4172 // Convert the result of the comparison into one expected for this
4165 // expression's context. 4173 // expression's context.
4166 context()->Plug(if_true, if_false); 4174 context()->Plug(if_true, if_false);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
4206 Register FullCodeGenerator::result_register() { 4214 Register FullCodeGenerator::result_register() {
4207 return rax; 4215 return rax;
4208 } 4216 }
4209 4217
4210 4218
4211 Register FullCodeGenerator::context_register() { 4219 Register FullCodeGenerator::context_register() {
4212 return rsi; 4220 return rsi;
4213 } 4221 }
4214 4222
4215 4223
4216 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { 4224 void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
4225 RelocInfo::Mode mode,
4226 unsigned ast_id) {
4217 ASSERT(mode == RelocInfo::CODE_TARGET || 4227 ASSERT(mode == RelocInfo::CODE_TARGET ||
4218 mode == RelocInfo::CODE_TARGET_CONTEXT); 4228 mode == RelocInfo::CODE_TARGET_CONTEXT);
4219 Counters* counters = isolate()->counters(); 4229 Counters* counters = isolate()->counters();
4220 switch (ic->kind()) { 4230 switch (ic->kind()) {
4221 case Code::LOAD_IC: 4231 case Code::LOAD_IC:
4222 __ IncrementCounter(counters->named_load_full(), 1); 4232 __ IncrementCounter(counters->named_load_full(), 1);
4223 break; 4233 break;
4224 case Code::KEYED_LOAD_IC: 4234 case Code::KEYED_LOAD_IC:
4225 __ IncrementCounter(counters->keyed_load_full(), 1); 4235 __ IncrementCounter(counters->keyed_load_full(), 1);
4226 break; 4236 break;
4227 case Code::STORE_IC: 4237 case Code::STORE_IC:
4228 __ IncrementCounter(counters->named_store_full(), 1); 4238 __ IncrementCounter(counters->named_store_full(), 1);
4229 break; 4239 break;
4230 case Code::KEYED_STORE_IC: 4240 case Code::KEYED_STORE_IC:
4231 __ IncrementCounter(counters->keyed_store_full(), 1); 4241 __ IncrementCounter(counters->keyed_store_full(), 1);
4232 default: 4242 default:
4233 break; 4243 break;
4234 } 4244 }
4235 4245
4236 __ call(ic, mode); 4246 __ call(ic, mode, ast_id);
4237 4247
4238 // Crankshaft doesn't need patching of inlined loads and stores. 4248 // Crankshaft doesn't need patching of inlined loads and stores.
4239 // When compiling the snapshot we need to produce code that works 4249 // When compiling the snapshot we need to produce code that works
4240 // with and without Crankshaft. 4250 // with and without Crankshaft.
4241 if (V8::UseCrankshaft() && !Serializer::enabled()) { 4251 if (V8::UseCrankshaft() && !Serializer::enabled()) {
4242 return; 4252 return;
4243 } 4253 }
4244 4254
4245 // If we're calling a (keyed) load or store stub, we have to mark 4255 // If we're calling a (keyed) load or store stub, we have to mark
4246 // the call as containing no inlined code so we will not attempt to 4256 // the call as containing no inlined code so we will not attempt to
4247 // patch it. 4257 // patch it.
4248 switch (ic->kind()) { 4258 switch (ic->kind()) {
4249 case Code::LOAD_IC: 4259 case Code::LOAD_IC:
4250 case Code::KEYED_LOAD_IC: 4260 case Code::KEYED_LOAD_IC:
4251 case Code::STORE_IC: 4261 case Code::STORE_IC:
4252 case Code::KEYED_STORE_IC: 4262 case Code::KEYED_STORE_IC:
4253 __ nop(); // Signals no inlined code. 4263 __ nop(); // Signals no inlined code.
4254 break; 4264 break;
4255 default: 4265 default:
4256 // Do nothing. 4266 // Do nothing.
4257 break; 4267 break;
4258 } 4268 }
4259 } 4269 }
4260 4270
4261 4271
4262 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) { 4272 void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
4273 JumpPatchSite* patch_site,
4274 unsigned ast_id) {
4263 Counters* counters = isolate()->counters(); 4275 Counters* counters = isolate()->counters();
4264 switch (ic->kind()) { 4276 switch (ic->kind()) {
4265 case Code::LOAD_IC: 4277 case Code::LOAD_IC:
4266 __ IncrementCounter(counters->named_load_full(), 1); 4278 __ IncrementCounter(counters->named_load_full(), 1);
4267 break; 4279 break;
4268 case Code::KEYED_LOAD_IC: 4280 case Code::KEYED_LOAD_IC:
4269 __ IncrementCounter(counters->keyed_load_full(), 1); 4281 __ IncrementCounter(counters->keyed_load_full(), 1);
4270 break; 4282 break;
4271 case Code::STORE_IC: 4283 case Code::STORE_IC:
4272 __ IncrementCounter(counters->named_store_full(), 1); 4284 __ IncrementCounter(counters->named_store_full(), 1);
4273 break; 4285 break;
4274 case Code::KEYED_STORE_IC: 4286 case Code::KEYED_STORE_IC:
4275 __ IncrementCounter(counters->keyed_store_full(), 1); 4287 __ IncrementCounter(counters->keyed_store_full(), 1);
4276 default: 4288 default:
4277 break; 4289 break;
4278 } 4290 }
4279 4291
4280 __ call(ic, RelocInfo::CODE_TARGET); 4292 __ call(ic, RelocInfo::CODE_TARGET, ast_id);
4281 if (patch_site != NULL && patch_site->is_bound()) { 4293 if (patch_site != NULL && patch_site->is_bound()) {
4282 patch_site->EmitPatchInfo(); 4294 patch_site->EmitPatchInfo();
4283 } else { 4295 } else {
4284 __ nop(); // Signals no inlined code. 4296 __ nop(); // Signals no inlined code.
4285 } 4297 }
4286 } 4298 }
4287 4299
4288 4300
4289 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 4301 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
4290 ASSERT(IsAligned(frame_offset, kPointerSize)); 4302 ASSERT(IsAligned(frame_offset, kPointerSize));
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
4330 __ ret(0); 4342 __ ret(0);
4331 } 4343 }
4332 4344
4333 4345
4334 #undef __ 4346 #undef __
4335 4347
4336 4348
4337 } } // namespace v8::internal 4349 } } // namespace v8::internal
4338 4350
4339 #endif // V8_TARGET_ARCH_X64 4351 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698