| 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 | 
|---|