OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 26 matching lines...) Expand all Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |