OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 18 matching lines...) Expand all Loading... |
29 | 29 |
30 #if defined(V8_TARGET_ARCH_X64) | 30 #if defined(V8_TARGET_ARCH_X64) |
31 | 31 |
32 #include "code-stubs.h" | 32 #include "code-stubs.h" |
33 #include "codegen-inl.h" | 33 #include "codegen-inl.h" |
34 #include "compiler.h" | 34 #include "compiler.h" |
35 #include "debug.h" | 35 #include "debug.h" |
36 #include "full-codegen.h" | 36 #include "full-codegen.h" |
37 #include "parser.h" | 37 #include "parser.h" |
38 #include "scopes.h" | 38 #include "scopes.h" |
| 39 #include "stub-cache.h" |
39 | 40 |
40 namespace v8 { | 41 namespace v8 { |
41 namespace internal { | 42 namespace internal { |
42 | 43 |
43 #define __ ACCESS_MASM(masm_) | 44 #define __ ACCESS_MASM(masm_) |
44 | 45 |
45 // Generate code for a JS function. On entry to the function the receiver | 46 // Generate code for a JS function. On entry to the function the receiver |
46 // and arguments have been pushed on the stack left to right, with the | 47 // and arguments have been pushed on the stack left to right, with the |
47 // return address on top of them. The actual argument count matches the | 48 // return address on top of them. The actual argument count matches the |
48 // formal parameter count expected by the function. | 49 // formal parameter count expected by the function. |
(...skipping 856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
905 __ j(not_equal, slow); | 906 __ j(not_equal, slow); |
906 // Load next context in chain. | 907 // Load next context in chain. |
907 __ movq(temp, ContextOperand(temp, Context::CLOSURE_INDEX)); | 908 __ movq(temp, ContextOperand(temp, Context::CLOSURE_INDEX)); |
908 __ movq(temp, FieldOperand(temp, JSFunction::kContextOffset)); | 909 __ movq(temp, FieldOperand(temp, JSFunction::kContextOffset)); |
909 __ jmp(&next); | 910 __ jmp(&next); |
910 __ bind(&fast); | 911 __ bind(&fast); |
911 } | 912 } |
912 | 913 |
913 // All extension objects were empty and it is safe to use a global | 914 // All extension objects were empty and it is safe to use a global |
914 // load IC call. | 915 // load IC call. |
915 __ movq(rax, CodeGenerator::GlobalObject()); | 916 __ movq(rax, GlobalObjectOperand()); |
916 __ Move(rcx, slot->var()->name()); | 917 __ Move(rcx, slot->var()->name()); |
917 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 918 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
918 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 919 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
919 ? RelocInfo::CODE_TARGET | 920 ? RelocInfo::CODE_TARGET |
920 : RelocInfo::CODE_TARGET_CONTEXT; | 921 : RelocInfo::CODE_TARGET_CONTEXT; |
921 EmitCallIC(ic, mode); | 922 EmitCallIC(ic, mode); |
922 } | 923 } |
923 | 924 |
924 | 925 |
925 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( | 926 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1009 // types of slots, and parameters that rewrite to explicit property | 1010 // types of slots, and parameters that rewrite to explicit property |
1010 // accesses on the arguments object. | 1011 // accesses on the arguments object. |
1011 Slot* slot = var->AsSlot(); | 1012 Slot* slot = var->AsSlot(); |
1012 Property* property = var->AsProperty(); | 1013 Property* property = var->AsProperty(); |
1013 | 1014 |
1014 if (var->is_global() && !var->is_this()) { | 1015 if (var->is_global() && !var->is_this()) { |
1015 Comment cmnt(masm_, "Global variable"); | 1016 Comment cmnt(masm_, "Global variable"); |
1016 // Use inline caching. Variable name is passed in rcx and the global | 1017 // Use inline caching. Variable name is passed in rcx and the global |
1017 // object on the stack. | 1018 // object on the stack. |
1018 __ Move(rcx, var->name()); | 1019 __ Move(rcx, var->name()); |
1019 __ movq(rax, CodeGenerator::GlobalObject()); | 1020 __ movq(rax, GlobalObjectOperand()); |
1020 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1021 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
1021 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1022 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
1022 context()->Plug(rax); | 1023 context()->Plug(rax); |
1023 | 1024 |
1024 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 1025 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
1025 Label done, slow; | 1026 Label done, slow; |
1026 | 1027 |
1027 // Generate code for loading from variables potentially shadowed | 1028 // Generate code for loading from variables potentially shadowed |
1028 // by eval-introduced variables. | 1029 // by eval-introduced variables. |
1029 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); | 1030 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); |
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1548 // here. | 1549 // here. |
1549 ASSERT(var != NULL); | 1550 ASSERT(var != NULL); |
1550 ASSERT(var->is_global() || var->AsSlot() != NULL); | 1551 ASSERT(var->is_global() || var->AsSlot() != NULL); |
1551 | 1552 |
1552 if (var->is_global()) { | 1553 if (var->is_global()) { |
1553 ASSERT(!var->is_this()); | 1554 ASSERT(!var->is_this()); |
1554 // Assignment to a global variable. Use inline caching for the | 1555 // Assignment to a global variable. Use inline caching for the |
1555 // assignment. Right-hand-side value is passed in rax, variable name in | 1556 // assignment. Right-hand-side value is passed in rax, variable name in |
1556 // rcx, and the global object on the stack. | 1557 // rcx, and the global object on the stack. |
1557 __ Move(rcx, var->name()); | 1558 __ Move(rcx, var->name()); |
1558 __ movq(rdx, CodeGenerator::GlobalObject()); | 1559 __ movq(rdx, GlobalObjectOperand()); |
1559 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1560 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
1560 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1561 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1561 | 1562 |
1562 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { | 1563 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { |
1563 // Perform the assignment for non-const variables and for initialization | 1564 // Perform the assignment for non-const variables and for initialization |
1564 // of const variables. Const assignments are simply skipped. | 1565 // of const variables. Const assignments are simply skipped. |
1565 Label done; | 1566 Label done; |
1566 Slot* slot = var->AsSlot(); | 1567 Slot* slot = var->AsSlot(); |
1567 switch (slot->type()) { | 1568 switch (slot->type()) { |
1568 case Slot::PARAMETER: | 1569 case Slot::PARAMETER: |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1720 { PreserveStatementPositionScope scope(masm()->positions_recorder()); | 1721 { PreserveStatementPositionScope scope(masm()->positions_recorder()); |
1721 for (int i = 0; i < arg_count; i++) { | 1722 for (int i = 0; i < arg_count; i++) { |
1722 VisitForStackValue(args->at(i)); | 1723 VisitForStackValue(args->at(i)); |
1723 } | 1724 } |
1724 __ Move(rcx, name); | 1725 __ Move(rcx, name); |
1725 } | 1726 } |
1726 // Record source position for debugger. | 1727 // Record source position for debugger. |
1727 SetSourcePosition(expr->position(), FORCED_POSITION); | 1728 SetSourcePosition(expr->position(), FORCED_POSITION); |
1728 // Call the IC initialization code. | 1729 // Call the IC initialization code. |
1729 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1730 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
1730 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, | 1731 Handle<Code> ic = StubCache::ComputeCallInitialize(arg_count, in_loop); |
1731 in_loop); | |
1732 EmitCallIC(ic, mode); | 1732 EmitCallIC(ic, mode); |
1733 // Restore context register. | 1733 // Restore context register. |
1734 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 1734 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
1735 context()->Plug(rax); | 1735 context()->Plug(rax); |
1736 } | 1736 } |
1737 | 1737 |
1738 | 1738 |
1739 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 1739 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
1740 Expression* key, | 1740 Expression* key, |
1741 RelocInfo::Mode mode) { | 1741 RelocInfo::Mode mode) { |
1742 // Code common for calls using the IC. | 1742 // Load the key. |
| 1743 VisitForAccumulatorValue(key); |
| 1744 |
| 1745 // Swap the name of the function and the receiver on the stack to follow |
| 1746 // the calling convention for call ICs. |
| 1747 __ pop(rcx); |
| 1748 __ push(rax); |
| 1749 __ push(rcx); |
| 1750 |
| 1751 // Load the arguments. |
1743 ZoneList<Expression*>* args = expr->arguments(); | 1752 ZoneList<Expression*>* args = expr->arguments(); |
1744 int arg_count = args->length(); | 1753 int arg_count = args->length(); |
1745 { PreserveStatementPositionScope scope(masm()->positions_recorder()); | 1754 { PreserveStatementPositionScope scope(masm()->positions_recorder()); |
1746 for (int i = 0; i < arg_count; i++) { | 1755 for (int i = 0; i < arg_count; i++) { |
1747 VisitForStackValue(args->at(i)); | 1756 VisitForStackValue(args->at(i)); |
1748 } | 1757 } |
1749 VisitForAccumulatorValue(key); | |
1750 __ movq(rcx, rax); | |
1751 } | 1758 } |
1752 // Record source position for debugger. | 1759 // Record source position for debugger. |
1753 SetSourcePosition(expr->position(), FORCED_POSITION); | 1760 SetSourcePosition(expr->position(), FORCED_POSITION); |
1754 // Call the IC initialization code. | 1761 // Call the IC initialization code. |
1755 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1762 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
1756 Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count, | 1763 Handle<Code> ic = StubCache::ComputeKeyedCallInitialize(arg_count, in_loop); |
1757 in_loop); | 1764 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. |
1758 EmitCallIC(ic, mode); | 1765 EmitCallIC(ic, mode); |
1759 // Restore context register. | 1766 // Restore context register. |
1760 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 1767 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
1761 context()->Plug(rax); | 1768 context()->DropAndPlug(1, rax); // Drop the key still on the stack. |
1762 } | 1769 } |
1763 | 1770 |
1764 | 1771 |
1765 void FullCodeGenerator::EmitCallWithStub(Call* expr) { | 1772 void FullCodeGenerator::EmitCallWithStub(Call* expr) { |
1766 // Code common for calls using the call stub. | 1773 // Code common for calls using the call stub. |
1767 ZoneList<Expression*>* args = expr->arguments(); | 1774 ZoneList<Expression*>* args = expr->arguments(); |
1768 int arg_count = args->length(); | 1775 int arg_count = args->length(); |
1769 { PreserveStatementPositionScope scope(masm()->positions_recorder()); | 1776 { PreserveStatementPositionScope scope(masm()->positions_recorder()); |
1770 for (int i = 0; i < arg_count; i++) { | 1777 for (int i = 0; i < arg_count; i++) { |
1771 VisitForStackValue(args->at(i)); | 1778 VisitForStackValue(args->at(i)); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1827 SetSourcePosition(expr->position(), FORCED_POSITION); | 1834 SetSourcePosition(expr->position(), FORCED_POSITION); |
1828 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1835 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
1829 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); | 1836 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); |
1830 __ CallStub(&stub); | 1837 __ CallStub(&stub); |
1831 // Restore context register. | 1838 // Restore context register. |
1832 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 1839 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
1833 context()->DropAndPlug(1, rax); | 1840 context()->DropAndPlug(1, rax); |
1834 } else if (var != NULL && !var->is_this() && var->is_global()) { | 1841 } else if (var != NULL && !var->is_this() && var->is_global()) { |
1835 // Call to a global variable. | 1842 // Call to a global variable. |
1836 // Push global object as receiver for the call IC lookup. | 1843 // Push global object as receiver for the call IC lookup. |
1837 __ push(CodeGenerator::GlobalObject()); | 1844 __ push(GlobalObjectOperand()); |
1838 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); | 1845 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); |
1839 } else if (var != NULL && var->AsSlot() != NULL && | 1846 } else if (var != NULL && var->AsSlot() != NULL && |
1840 var->AsSlot()->type() == Slot::LOOKUP) { | 1847 var->AsSlot()->type() == Slot::LOOKUP) { |
1841 // Call to a lookup slot (dynamically introduced variable). | 1848 // Call to a lookup slot (dynamically introduced variable). |
1842 Label slow, done; | 1849 Label slow, done; |
1843 | 1850 |
1844 { PreserveStatementPositionScope scope(masm()->positions_recorder()); | 1851 { PreserveStatementPositionScope scope(masm()->positions_recorder()); |
1845 // Generate code for loading from variables potentially shadowed | 1852 // Generate code for loading from variables potentially shadowed |
1846 // by eval-introduced variables. | 1853 // by eval-introduced variables. |
1847 EmitDynamicLoadFromSlotFastCase(var->AsSlot(), | 1854 EmitDynamicLoadFromSlotFastCase(var->AsSlot(), |
(...skipping 13 matching lines...) Expand all Loading... |
1861 // If fast case code has been generated, emit code to push the | 1868 // If fast case code has been generated, emit code to push the |
1862 // function and receiver and have the slow path jump around this | 1869 // function and receiver and have the slow path jump around this |
1863 // code. | 1870 // code. |
1864 if (done.is_linked()) { | 1871 if (done.is_linked()) { |
1865 NearLabel call; | 1872 NearLabel call; |
1866 __ jmp(&call); | 1873 __ jmp(&call); |
1867 __ bind(&done); | 1874 __ bind(&done); |
1868 // Push function. | 1875 // Push function. |
1869 __ push(rax); | 1876 __ push(rax); |
1870 // Push global receiver. | 1877 // Push global receiver. |
1871 __ movq(rbx, CodeGenerator::GlobalObject()); | 1878 __ movq(rbx, GlobalObjectOperand()); |
1872 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); | 1879 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); |
1873 __ bind(&call); | 1880 __ bind(&call); |
1874 } | 1881 } |
1875 } | 1882 } |
1876 | 1883 |
1877 EmitCallWithStub(expr); | 1884 EmitCallWithStub(expr); |
1878 | 1885 |
1879 } else if (fun->AsProperty() != NULL) { | 1886 } else if (fun->AsProperty() != NULL) { |
1880 // Call to an object property. | 1887 // Call to an object property. |
1881 Property* prop = fun->AsProperty(); | 1888 Property* prop = fun->AsProperty(); |
(...skipping 18 matching lines...) Expand all Loading... |
1900 } | 1907 } |
1901 // Record source code position for IC call. | 1908 // Record source code position for IC call. |
1902 SetSourcePosition(prop->position(), FORCED_POSITION); | 1909 SetSourcePosition(prop->position(), FORCED_POSITION); |
1903 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1910 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
1904 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1911 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1905 // Pop receiver. | 1912 // Pop receiver. |
1906 __ pop(rbx); | 1913 __ pop(rbx); |
1907 // Push result (function). | 1914 // Push result (function). |
1908 __ push(rax); | 1915 __ push(rax); |
1909 // Push receiver object on stack. | 1916 // Push receiver object on stack. |
1910 __ movq(rcx, CodeGenerator::GlobalObject()); | 1917 __ movq(rcx, GlobalObjectOperand()); |
1911 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); | 1918 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); |
1912 EmitCallWithStub(expr); | 1919 EmitCallWithStub(expr); |
1913 } else { | 1920 } else { |
1914 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); | 1921 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); |
1915 } | 1922 } |
1916 } | 1923 } |
1917 } else { | 1924 } else { |
1918 // Call to some other expression. If the expression is an anonymous | 1925 // Call to some other expression. If the expression is an anonymous |
1919 // function literal not called in a loop, mark it as one that should | 1926 // function literal not called in a loop, mark it as one that should |
1920 // also use the fast code generator. | 1927 // also use the fast code generator. |
1921 FunctionLiteral* lit = fun->AsFunctionLiteral(); | 1928 FunctionLiteral* lit = fun->AsFunctionLiteral(); |
1922 if (lit != NULL && | 1929 if (lit != NULL && |
1923 lit->name()->Equals(Heap::empty_string()) && | 1930 lit->name()->Equals(Heap::empty_string()) && |
1924 loop_depth() == 0) { | 1931 loop_depth() == 0) { |
1925 lit->set_try_full_codegen(true); | 1932 lit->set_try_full_codegen(true); |
1926 } | 1933 } |
1927 { PreserveStatementPositionScope scope(masm()->positions_recorder()); | 1934 { PreserveStatementPositionScope scope(masm()->positions_recorder()); |
1928 VisitForStackValue(fun); | 1935 VisitForStackValue(fun); |
1929 } | 1936 } |
1930 // Load global receiver object. | 1937 // Load global receiver object. |
1931 __ movq(rbx, CodeGenerator::GlobalObject()); | 1938 __ movq(rbx, GlobalObjectOperand()); |
1932 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); | 1939 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); |
1933 // Emit function call. | 1940 // Emit function call. |
1934 EmitCallWithStub(expr); | 1941 EmitCallWithStub(expr); |
1935 } | 1942 } |
1936 } | 1943 } |
1937 | 1944 |
1938 | 1945 |
1939 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 1946 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
1940 Comment cmnt(masm_, "[ CallNew"); | 1947 Comment cmnt(masm_, "[ CallNew"); |
1941 // According to ECMA-262, section 11.2.2, page 44, the function | 1948 // According to ECMA-262, section 11.2.2, page 44, the function |
(...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2794 Comment cmnt(masm_, "[ InlineRuntimeCall"); | 2801 Comment cmnt(masm_, "[ InlineRuntimeCall"); |
2795 EmitInlineRuntimeCall(expr); | 2802 EmitInlineRuntimeCall(expr); |
2796 return; | 2803 return; |
2797 } | 2804 } |
2798 | 2805 |
2799 Comment cmnt(masm_, "[ CallRuntime"); | 2806 Comment cmnt(masm_, "[ CallRuntime"); |
2800 ZoneList<Expression*>* args = expr->arguments(); | 2807 ZoneList<Expression*>* args = expr->arguments(); |
2801 | 2808 |
2802 if (expr->is_jsruntime()) { | 2809 if (expr->is_jsruntime()) { |
2803 // Prepare for calling JS runtime function. | 2810 // Prepare for calling JS runtime function. |
2804 __ movq(rax, CodeGenerator::GlobalObject()); | 2811 __ movq(rax, GlobalObjectOperand()); |
2805 __ push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); | 2812 __ push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); |
2806 } | 2813 } |
2807 | 2814 |
2808 // Push the arguments ("left-to-right"). | 2815 // Push the arguments ("left-to-right"). |
2809 int arg_count = args->length(); | 2816 int arg_count = args->length(); |
2810 for (int i = 0; i < arg_count; i++) { | 2817 for (int i = 0; i < arg_count; i++) { |
2811 VisitForStackValue(args->at(i)); | 2818 VisitForStackValue(args->at(i)); |
2812 } | 2819 } |
2813 | 2820 |
2814 if (expr->is_jsruntime()) { | 2821 if (expr->is_jsruntime()) { |
2815 // Call the JS runtime function using a call IC. | 2822 // Call the JS runtime function using a call IC. |
2816 __ Move(rcx, expr->name()); | 2823 __ Move(rcx, expr->name()); |
2817 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2824 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
2818 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop); | 2825 Handle<Code> ic = StubCache::ComputeCallInitialize(arg_count, in_loop); |
2819 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2826 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
2820 // Restore context register. | 2827 // Restore context register. |
2821 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2828 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2822 } else { | 2829 } else { |
2823 __ CallRuntime(expr->function(), arg_count); | 2830 __ CallRuntime(expr->function(), arg_count); |
2824 } | 2831 } |
2825 context()->Plug(rax); | 2832 context()->Plug(rax); |
2826 } | 2833 } |
2827 | 2834 |
2828 | 2835 |
(...skipping 15 matching lines...) Expand all Loading... |
2844 // Result of deleting non-global, non-dynamic variables is false. | 2851 // Result of deleting non-global, non-dynamic variables is false. |
2845 // The subexpression does not have side effects. | 2852 // The subexpression does not have side effects. |
2846 context()->Plug(false); | 2853 context()->Plug(false); |
2847 } else { | 2854 } else { |
2848 // Property or variable reference. Call the delete builtin with | 2855 // Property or variable reference. Call the delete builtin with |
2849 // object and property name as arguments. | 2856 // object and property name as arguments. |
2850 if (prop != NULL) { | 2857 if (prop != NULL) { |
2851 VisitForStackValue(prop->obj()); | 2858 VisitForStackValue(prop->obj()); |
2852 VisitForStackValue(prop->key()); | 2859 VisitForStackValue(prop->key()); |
2853 } else if (var->is_global()) { | 2860 } else if (var->is_global()) { |
2854 __ push(CodeGenerator::GlobalObject()); | 2861 __ push(GlobalObjectOperand()); |
2855 __ Push(var->name()); | 2862 __ Push(var->name()); |
2856 } else { | 2863 } else { |
2857 // Non-global variable. Call the runtime to look up the context | 2864 // Non-global variable. Call the runtime to look up the context |
2858 // where the variable was introduced. | 2865 // where the variable was introduced. |
2859 __ push(context_register()); | 2866 __ push(context_register()); |
2860 __ Push(var->name()); | 2867 __ Push(var->name()); |
2861 __ CallRuntime(Runtime::kLookupContext, 2); | 2868 __ CallRuntime(Runtime::kLookupContext, 2); |
2862 __ push(rax); | 2869 __ push(rax); |
2863 __ Push(var->name()); | 2870 __ Push(var->name()); |
2864 } | 2871 } |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3115 | 3122 |
3116 | 3123 |
3117 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 3124 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
3118 VariableProxy* proxy = expr->AsVariableProxy(); | 3125 VariableProxy* proxy = expr->AsVariableProxy(); |
3119 ASSERT(!context()->IsEffect()); | 3126 ASSERT(!context()->IsEffect()); |
3120 ASSERT(!context()->IsTest()); | 3127 ASSERT(!context()->IsTest()); |
3121 | 3128 |
3122 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { | 3129 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { |
3123 Comment cmnt(masm_, "Global variable"); | 3130 Comment cmnt(masm_, "Global variable"); |
3124 __ Move(rcx, proxy->name()); | 3131 __ Move(rcx, proxy->name()); |
3125 __ movq(rax, CodeGenerator::GlobalObject()); | 3132 __ movq(rax, GlobalObjectOperand()); |
3126 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 3133 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
3127 // Use a regular load, not a contextual load, to avoid a reference | 3134 // Use a regular load, not a contextual load, to avoid a reference |
3128 // error. | 3135 // error. |
3129 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3136 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
3130 context()->Plug(rax); | 3137 context()->Plug(rax); |
3131 } else if (proxy != NULL && | 3138 } else if (proxy != NULL && |
3132 proxy->var()->AsSlot() != NULL && | 3139 proxy->var()->AsSlot() != NULL && |
3133 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { | 3140 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { |
3134 Label done, slow; | 3141 Label done, slow; |
3135 | 3142 |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3453 __ ret(0); | 3460 __ ret(0); |
3454 } | 3461 } |
3455 | 3462 |
3456 | 3463 |
3457 #undef __ | 3464 #undef __ |
3458 | 3465 |
3459 | 3466 |
3460 } } // namespace v8::internal | 3467 } } // namespace v8::internal |
3461 | 3468 |
3462 #endif // V8_TARGET_ARCH_X64 | 3469 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |