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 894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
905 __ j(not_equal, slow); | 905 __ j(not_equal, slow); |
906 // Load next context in chain. | 906 // Load next context in chain. |
907 __ movq(temp, ContextOperand(temp, Context::CLOSURE_INDEX)); | 907 __ movq(temp, ContextOperand(temp, Context::CLOSURE_INDEX)); |
908 __ movq(temp, FieldOperand(temp, JSFunction::kContextOffset)); | 908 __ movq(temp, FieldOperand(temp, JSFunction::kContextOffset)); |
909 __ jmp(&next); | 909 __ jmp(&next); |
910 __ bind(&fast); | 910 __ bind(&fast); |
911 } | 911 } |
912 | 912 |
913 // All extension objects were empty and it is safe to use a global | 913 // All extension objects were empty and it is safe to use a global |
914 // load IC call. | 914 // load IC call. |
915 __ movq(rax, CodeGenerator::GlobalObject()); | 915 __ movq(rax, GlobalObjectOperand()); |
916 __ Move(rcx, slot->var()->name()); | 916 __ Move(rcx, slot->var()->name()); |
917 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 917 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
918 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 918 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
919 ? RelocInfo::CODE_TARGET | 919 ? RelocInfo::CODE_TARGET |
920 : RelocInfo::CODE_TARGET_CONTEXT; | 920 : RelocInfo::CODE_TARGET_CONTEXT; |
921 EmitCallIC(ic, mode); | 921 EmitCallIC(ic, mode); |
922 } | 922 } |
923 | 923 |
924 | 924 |
925 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( | 925 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 | 1009 // types of slots, and parameters that rewrite to explicit property |
1010 // accesses on the arguments object. | 1010 // accesses on the arguments object. |
1011 Slot* slot = var->AsSlot(); | 1011 Slot* slot = var->AsSlot(); |
1012 Property* property = var->AsProperty(); | 1012 Property* property = var->AsProperty(); |
1013 | 1013 |
1014 if (var->is_global() && !var->is_this()) { | 1014 if (var->is_global() && !var->is_this()) { |
1015 Comment cmnt(masm_, "Global variable"); | 1015 Comment cmnt(masm_, "Global variable"); |
1016 // Use inline caching. Variable name is passed in rcx and the global | 1016 // Use inline caching. Variable name is passed in rcx and the global |
1017 // object on the stack. | 1017 // object on the stack. |
1018 __ Move(rcx, var->name()); | 1018 __ Move(rcx, var->name()); |
1019 __ movq(rax, CodeGenerator::GlobalObject()); | 1019 __ movq(rax, GlobalObjectOperand()); |
1020 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1020 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
1021 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1021 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
1022 context()->Plug(rax); | 1022 context()->Plug(rax); |
1023 | 1023 |
1024 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 1024 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
1025 Label done, slow; | 1025 Label done, slow; |
1026 | 1026 |
1027 // Generate code for loading from variables potentially shadowed | 1027 // Generate code for loading from variables potentially shadowed |
1028 // by eval-introduced variables. | 1028 // by eval-introduced variables. |
1029 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); | 1029 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); |
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1548 // here. | 1548 // here. |
1549 ASSERT(var != NULL); | 1549 ASSERT(var != NULL); |
1550 ASSERT(var->is_global() || var->AsSlot() != NULL); | 1550 ASSERT(var->is_global() || var->AsSlot() != NULL); |
1551 | 1551 |
1552 if (var->is_global()) { | 1552 if (var->is_global()) { |
1553 ASSERT(!var->is_this()); | 1553 ASSERT(!var->is_this()); |
1554 // Assignment to a global variable. Use inline caching for the | 1554 // Assignment to a global variable. Use inline caching for the |
1555 // assignment. Right-hand-side value is passed in rax, variable name in | 1555 // assignment. Right-hand-side value is passed in rax, variable name in |
1556 // rcx, and the global object on the stack. | 1556 // rcx, and the global object on the stack. |
1557 __ Move(rcx, var->name()); | 1557 __ Move(rcx, var->name()); |
1558 __ movq(rdx, CodeGenerator::GlobalObject()); | 1558 __ movq(rdx, GlobalObjectOperand()); |
1559 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1559 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
1560 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1560 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1561 | 1561 |
1562 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { | 1562 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { |
1563 // Perform the assignment for non-const variables and for initialization | 1563 // Perform the assignment for non-const variables and for initialization |
1564 // of const variables. Const assignments are simply skipped. | 1564 // of const variables. Const assignments are simply skipped. |
1565 Label done; | 1565 Label done; |
1566 Slot* slot = var->AsSlot(); | 1566 Slot* slot = var->AsSlot(); |
1567 switch (slot->type()) { | 1567 switch (slot->type()) { |
1568 case Slot::PARAMETER: | 1568 case Slot::PARAMETER: |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1827 SetSourcePosition(expr->position(), FORCED_POSITION); | 1827 SetSourcePosition(expr->position(), FORCED_POSITION); |
1828 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1828 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
1829 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); | 1829 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); |
1830 __ CallStub(&stub); | 1830 __ CallStub(&stub); |
1831 // Restore context register. | 1831 // Restore context register. |
1832 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 1832 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
1833 context()->DropAndPlug(1, rax); | 1833 context()->DropAndPlug(1, rax); |
1834 } else if (var != NULL && !var->is_this() && var->is_global()) { | 1834 } else if (var != NULL && !var->is_this() && var->is_global()) { |
1835 // Call to a global variable. | 1835 // Call to a global variable. |
1836 // Push global object as receiver for the call IC lookup. | 1836 // Push global object as receiver for the call IC lookup. |
1837 __ push(CodeGenerator::GlobalObject()); | 1837 __ push(GlobalObjectOperand()); |
1838 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); | 1838 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); |
1839 } else if (var != NULL && var->AsSlot() != NULL && | 1839 } else if (var != NULL && var->AsSlot() != NULL && |
1840 var->AsSlot()->type() == Slot::LOOKUP) { | 1840 var->AsSlot()->type() == Slot::LOOKUP) { |
1841 // Call to a lookup slot (dynamically introduced variable). | 1841 // Call to a lookup slot (dynamically introduced variable). |
1842 Label slow, done; | 1842 Label slow, done; |
1843 | 1843 |
1844 { PreserveStatementPositionScope scope(masm()->positions_recorder()); | 1844 { PreserveStatementPositionScope scope(masm()->positions_recorder()); |
1845 // Generate code for loading from variables potentially shadowed | 1845 // Generate code for loading from variables potentially shadowed |
1846 // by eval-introduced variables. | 1846 // by eval-introduced variables. |
1847 EmitDynamicLoadFromSlotFastCase(var->AsSlot(), | 1847 EmitDynamicLoadFromSlotFastCase(var->AsSlot(), |
(...skipping 13 matching lines...) Expand all Loading... |
1861 // If fast case code has been generated, emit code to push the | 1861 // If fast case code has been generated, emit code to push the |
1862 // function and receiver and have the slow path jump around this | 1862 // function and receiver and have the slow path jump around this |
1863 // code. | 1863 // code. |
1864 if (done.is_linked()) { | 1864 if (done.is_linked()) { |
1865 NearLabel call; | 1865 NearLabel call; |
1866 __ jmp(&call); | 1866 __ jmp(&call); |
1867 __ bind(&done); | 1867 __ bind(&done); |
1868 // Push function. | 1868 // Push function. |
1869 __ push(rax); | 1869 __ push(rax); |
1870 // Push global receiver. | 1870 // Push global receiver. |
1871 __ movq(rbx, CodeGenerator::GlobalObject()); | 1871 __ movq(rbx, GlobalObjectOperand()); |
1872 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); | 1872 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); |
1873 __ bind(&call); | 1873 __ bind(&call); |
1874 } | 1874 } |
1875 } | 1875 } |
1876 | 1876 |
1877 EmitCallWithStub(expr); | 1877 EmitCallWithStub(expr); |
1878 | 1878 |
1879 } else if (fun->AsProperty() != NULL) { | 1879 } else if (fun->AsProperty() != NULL) { |
1880 // Call to an object property. | 1880 // Call to an object property. |
1881 Property* prop = fun->AsProperty(); | 1881 Property* prop = fun->AsProperty(); |
(...skipping 18 matching lines...) Expand all Loading... |
1900 } | 1900 } |
1901 // Record source code position for IC call. | 1901 // Record source code position for IC call. |
1902 SetSourcePosition(prop->position(), FORCED_POSITION); | 1902 SetSourcePosition(prop->position(), FORCED_POSITION); |
1903 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1903 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
1904 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1904 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1905 // Pop receiver. | 1905 // Pop receiver. |
1906 __ pop(rbx); | 1906 __ pop(rbx); |
1907 // Push result (function). | 1907 // Push result (function). |
1908 __ push(rax); | 1908 __ push(rax); |
1909 // Push receiver object on stack. | 1909 // Push receiver object on stack. |
1910 __ movq(rcx, CodeGenerator::GlobalObject()); | 1910 __ movq(rcx, GlobalObjectOperand()); |
1911 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); | 1911 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); |
1912 EmitCallWithStub(expr); | 1912 EmitCallWithStub(expr); |
1913 } else { | 1913 } else { |
1914 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); | 1914 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); |
1915 } | 1915 } |
1916 } | 1916 } |
1917 } else { | 1917 } else { |
1918 // Call to some other expression. If the expression is an anonymous | 1918 // 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 | 1919 // function literal not called in a loop, mark it as one that should |
1920 // also use the fast code generator. | 1920 // also use the fast code generator. |
1921 FunctionLiteral* lit = fun->AsFunctionLiteral(); | 1921 FunctionLiteral* lit = fun->AsFunctionLiteral(); |
1922 if (lit != NULL && | 1922 if (lit != NULL && |
1923 lit->name()->Equals(Heap::empty_string()) && | 1923 lit->name()->Equals(Heap::empty_string()) && |
1924 loop_depth() == 0) { | 1924 loop_depth() == 0) { |
1925 lit->set_try_full_codegen(true); | 1925 lit->set_try_full_codegen(true); |
1926 } | 1926 } |
1927 { PreserveStatementPositionScope scope(masm()->positions_recorder()); | 1927 { PreserveStatementPositionScope scope(masm()->positions_recorder()); |
1928 VisitForStackValue(fun); | 1928 VisitForStackValue(fun); |
1929 } | 1929 } |
1930 // Load global receiver object. | 1930 // Load global receiver object. |
1931 __ movq(rbx, CodeGenerator::GlobalObject()); | 1931 __ movq(rbx, GlobalObjectOperand()); |
1932 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); | 1932 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); |
1933 // Emit function call. | 1933 // Emit function call. |
1934 EmitCallWithStub(expr); | 1934 EmitCallWithStub(expr); |
1935 } | 1935 } |
1936 } | 1936 } |
1937 | 1937 |
1938 | 1938 |
1939 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 1939 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
1940 Comment cmnt(masm_, "[ CallNew"); | 1940 Comment cmnt(masm_, "[ CallNew"); |
1941 // According to ECMA-262, section 11.2.2, page 44, the function | 1941 // 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"); | 2794 Comment cmnt(masm_, "[ InlineRuntimeCall"); |
2795 EmitInlineRuntimeCall(expr); | 2795 EmitInlineRuntimeCall(expr); |
2796 return; | 2796 return; |
2797 } | 2797 } |
2798 | 2798 |
2799 Comment cmnt(masm_, "[ CallRuntime"); | 2799 Comment cmnt(masm_, "[ CallRuntime"); |
2800 ZoneList<Expression*>* args = expr->arguments(); | 2800 ZoneList<Expression*>* args = expr->arguments(); |
2801 | 2801 |
2802 if (expr->is_jsruntime()) { | 2802 if (expr->is_jsruntime()) { |
2803 // Prepare for calling JS runtime function. | 2803 // Prepare for calling JS runtime function. |
2804 __ movq(rax, CodeGenerator::GlobalObject()); | 2804 __ movq(rax, GlobalObjectOperand()); |
2805 __ push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); | 2805 __ push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); |
2806 } | 2806 } |
2807 | 2807 |
2808 // Push the arguments ("left-to-right"). | 2808 // Push the arguments ("left-to-right"). |
2809 int arg_count = args->length(); | 2809 int arg_count = args->length(); |
2810 for (int i = 0; i < arg_count; i++) { | 2810 for (int i = 0; i < arg_count; i++) { |
2811 VisitForStackValue(args->at(i)); | 2811 VisitForStackValue(args->at(i)); |
2812 } | 2812 } |
2813 | 2813 |
2814 if (expr->is_jsruntime()) { | 2814 if (expr->is_jsruntime()) { |
(...skipping 29 matching lines...) Expand all Loading... |
2844 // Result of deleting non-global, non-dynamic variables is false. | 2844 // Result of deleting non-global, non-dynamic variables is false. |
2845 // The subexpression does not have side effects. | 2845 // The subexpression does not have side effects. |
2846 context()->Plug(false); | 2846 context()->Plug(false); |
2847 } else { | 2847 } else { |
2848 // Property or variable reference. Call the delete builtin with | 2848 // Property or variable reference. Call the delete builtin with |
2849 // object and property name as arguments. | 2849 // object and property name as arguments. |
2850 if (prop != NULL) { | 2850 if (prop != NULL) { |
2851 VisitForStackValue(prop->obj()); | 2851 VisitForStackValue(prop->obj()); |
2852 VisitForStackValue(prop->key()); | 2852 VisitForStackValue(prop->key()); |
2853 } else if (var->is_global()) { | 2853 } else if (var->is_global()) { |
2854 __ push(CodeGenerator::GlobalObject()); | 2854 __ push(GlobalObjectOperand()); |
2855 __ Push(var->name()); | 2855 __ Push(var->name()); |
2856 } else { | 2856 } else { |
2857 // Non-global variable. Call the runtime to look up the context | 2857 // Non-global variable. Call the runtime to look up the context |
2858 // where the variable was introduced. | 2858 // where the variable was introduced. |
2859 __ push(context_register()); | 2859 __ push(context_register()); |
2860 __ Push(var->name()); | 2860 __ Push(var->name()); |
2861 __ CallRuntime(Runtime::kLookupContext, 2); | 2861 __ CallRuntime(Runtime::kLookupContext, 2); |
2862 __ push(rax); | 2862 __ push(rax); |
2863 __ Push(var->name()); | 2863 __ Push(var->name()); |
2864 } | 2864 } |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3115 | 3115 |
3116 | 3116 |
3117 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 3117 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
3118 VariableProxy* proxy = expr->AsVariableProxy(); | 3118 VariableProxy* proxy = expr->AsVariableProxy(); |
3119 ASSERT(!context()->IsEffect()); | 3119 ASSERT(!context()->IsEffect()); |
3120 ASSERT(!context()->IsTest()); | 3120 ASSERT(!context()->IsTest()); |
3121 | 3121 |
3122 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { | 3122 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { |
3123 Comment cmnt(masm_, "Global variable"); | 3123 Comment cmnt(masm_, "Global variable"); |
3124 __ Move(rcx, proxy->name()); | 3124 __ Move(rcx, proxy->name()); |
3125 __ movq(rax, CodeGenerator::GlobalObject()); | 3125 __ movq(rax, GlobalObjectOperand()); |
3126 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 3126 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
3127 // Use a regular load, not a contextual load, to avoid a reference | 3127 // Use a regular load, not a contextual load, to avoid a reference |
3128 // error. | 3128 // error. |
3129 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3129 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
3130 context()->Plug(rax); | 3130 context()->Plug(rax); |
3131 } else if (proxy != NULL && | 3131 } else if (proxy != NULL && |
3132 proxy->var()->AsSlot() != NULL && | 3132 proxy->var()->AsSlot() != NULL && |
3133 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { | 3133 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { |
3134 Label done, slow; | 3134 Label done, slow; |
3135 | 3135 |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3453 __ ret(0); | 3453 __ ret(0); |
3454 } | 3454 } |
3455 | 3455 |
3456 | 3456 |
3457 #undef __ | 3457 #undef __ |
3458 | 3458 |
3459 | 3459 |
3460 } } // namespace v8::internal | 3460 } } // namespace v8::internal |
3461 | 3461 |
3462 #endif // V8_TARGET_ARCH_X64 | 3462 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |