| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 624 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 635       thunk_address, | 635       thunk_address, | 
| 636       callback_arg, | 636       callback_arg, | 
| 637       argc + kFastApiCallArguments + 1, | 637       argc + kFastApiCallArguments + 1, | 
| 638       return_value_operand, | 638       return_value_operand, | 
| 639       restore_context ? &context_restore_operand : NULL); | 639       restore_context ? &context_restore_operand : NULL); | 
| 640 } | 640 } | 
| 641 | 641 | 
| 642 | 642 | 
| 643 class CallInterceptorCompiler BASE_EMBEDDED { | 643 class CallInterceptorCompiler BASE_EMBEDDED { | 
| 644  public: | 644  public: | 
| 645   CallInterceptorCompiler(StubCompiler* stub_compiler, | 645   CallInterceptorCompiler(CallStubCompiler* stub_compiler, | 
| 646                           const ParameterCount& arguments, | 646                           const ParameterCount& arguments, | 
| 647                           Register name, | 647                           Register name, | 
| 648                           Code::ExtraICState extra_ic_state) | 648                           Code::ExtraICState extra_ic_state) | 
| 649       : stub_compiler_(stub_compiler), | 649       : stub_compiler_(stub_compiler), | 
| 650         arguments_(arguments), | 650         arguments_(arguments), | 
| 651         name_(name), | 651         name_(name), | 
| 652         extra_ic_state_(extra_ic_state) {} | 652         extra_ic_state_(extra_ic_state) {} | 
| 653 | 653 | 
| 654   void Compile(MacroAssembler* masm, | 654   void Compile(MacroAssembler* masm, | 
| 655                Handle<JSObject> object, | 655                Handle<JSObject> object, | 
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 746       // for API (object which is instanceof for the signature).  It's | 746       // for API (object which is instanceof for the signature).  It's | 
| 747       // safe to omit it here, as if present, it should be fetched | 747       // safe to omit it here, as if present, it should be fetched | 
| 748       // by the previous CheckPrototypes. | 748       // by the previous CheckPrototypes. | 
| 749       ASSERT(depth2 == kInvalidProtoDepth); | 749       ASSERT(depth2 == kInvalidProtoDepth); | 
| 750     } | 750     } | 
| 751 | 751 | 
| 752     // Invoke function. | 752     // Invoke function. | 
| 753     if (can_do_fast_api_call) { | 753     if (can_do_fast_api_call) { | 
| 754       GenerateFastApiCall(masm, optimization, arguments_.immediate()); | 754       GenerateFastApiCall(masm, optimization, arguments_.immediate()); | 
| 755     } else { | 755     } else { | 
| 756       CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) |  | 
| 757           ? CALL_AS_FUNCTION |  | 
| 758           : CALL_AS_METHOD; |  | 
| 759       Handle<JSFunction> fun = optimization.constant_function(); | 756       Handle<JSFunction> fun = optimization.constant_function(); | 
| 760       ParameterCount expected(fun); | 757       stub_compiler_->GenerateCallFunction(object, fun); | 
| 761       __ InvokeFunction(fun, expected, arguments_, |  | 
| 762                         JUMP_FUNCTION, NullCallWrapper(), call_kind); |  | 
| 763     } | 758     } | 
| 764 | 759 | 
| 765     // Deferred code for fast API call case---clean preallocated space. | 760     // Deferred code for fast API call case---clean preallocated space. | 
| 766     if (can_do_fast_api_call) { | 761     if (can_do_fast_api_call) { | 
| 767       __ bind(&miss_cleanup); | 762       __ bind(&miss_cleanup); | 
| 768       FreeSpaceForFastApiCall(masm, scratch1); | 763       FreeSpaceForFastApiCall(masm, scratch1); | 
| 769       __ jmp(miss_label); | 764       __ jmp(miss_label); | 
| 770     } | 765     } | 
| 771 | 766 | 
| 772     // Invoke a regular function. | 767     // Invoke a regular function. | 
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 825 | 820 | 
| 826       __ pop(name_);  // Restore the name. | 821       __ pop(name_);  // Restore the name. | 
| 827       __ pop(receiver);  // Restore the holder. | 822       __ pop(receiver);  // Restore the holder. | 
| 828       // Leave the internal frame. | 823       // Leave the internal frame. | 
| 829     } | 824     } | 
| 830 | 825 | 
| 831     __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); | 826     __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); | 
| 832     __ j(not_equal, interceptor_succeeded); | 827     __ j(not_equal, interceptor_succeeded); | 
| 833   } | 828   } | 
| 834 | 829 | 
| 835   StubCompiler* stub_compiler_; | 830   CallStubCompiler* stub_compiler_; | 
| 836   const ParameterCount& arguments_; | 831   const ParameterCount& arguments_; | 
| 837   Register name_; | 832   Register name_; | 
| 838   Code::ExtraICState extra_ic_state_; | 833   Code::ExtraICState extra_ic_state_; | 
| 839 }; | 834 }; | 
| 840 | 835 | 
| 841 | 836 | 
| 842 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, | 837 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, | 
| 843                                             Label* label, | 838                                             Label* label, | 
| 844                                             Handle<Name> name) { | 839                                             Handle<Name> name) { | 
| 845   if (!label->is_unused()) { | 840   if (!label->is_unused()) { | 
| (...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1542 | 1537 | 
| 1543 | 1538 | 
| 1544 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { | 1539 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { | 
| 1545   if (kind_ == Code::KEYED_CALL_IC) { | 1540   if (kind_ == Code::KEYED_CALL_IC) { | 
| 1546     __ Cmp(rcx, name); | 1541     __ Cmp(rcx, name); | 
| 1547     __ j(not_equal, miss); | 1542     __ j(not_equal, miss); | 
| 1548   } | 1543   } | 
| 1549 } | 1544 } | 
| 1550 | 1545 | 
| 1551 | 1546 | 
|  | 1547 void CallStubCompiler::GenerateFunctionCheck(Register function, | 
|  | 1548                                              Register scratch, | 
|  | 1549                                              Label* miss) { | 
|  | 1550   __ JumpIfSmi(function, miss); | 
|  | 1551   __ CmpObjectType(function, JS_FUNCTION_TYPE, scratch); | 
|  | 1552   __ j(not_equal, miss); | 
|  | 1553 } | 
|  | 1554 | 
|  | 1555 | 
| 1552 void CallStubCompiler::GenerateLoadFunctionFromCell( | 1556 void CallStubCompiler::GenerateLoadFunctionFromCell( | 
| 1553     Handle<Cell> cell, | 1557     Handle<Cell> cell, | 
| 1554     Handle<JSFunction> function, | 1558     Handle<JSFunction> function, | 
| 1555     Label* miss) { | 1559     Label* miss) { | 
| 1556   // Get the value from the cell. | 1560   // Get the value from the cell. | 
| 1557   __ Move(rdi, cell); | 1561   __ Move(rdi, cell); | 
| 1558   __ movq(rdi, FieldOperand(rdi, Cell::kValueOffset)); | 1562   __ movq(rdi, FieldOperand(rdi, Cell::kValueOffset)); | 
| 1559 | 1563 | 
| 1560   // Check that the cell contains the same function. | 1564   // Check that the cell contains the same function. | 
| 1561   if (heap()->InNewSpace(*function)) { | 1565   if (heap()->InNewSpace(*function)) { | 
| 1562     // We can't embed a pointer to a function in new space so we have | 1566     // We can't embed a pointer to a function in new space so we have | 
| 1563     // to verify that the shared function info is unchanged. This has | 1567     // to verify that the shared function info is unchanged. This has | 
| 1564     // the nice side effect that multiple closures based on the same | 1568     // the nice side effect that multiple closures based on the same | 
| 1565     // function can all use this call IC. Before we load through the | 1569     // function can all use this call IC. Before we load through the | 
| 1566     // function, we have to verify that it still is a function. | 1570     // function, we have to verify that it still is a function. | 
| 1567     __ JumpIfSmi(rdi, miss); | 1571     GenerateFunctionCheck(rdi, rax, miss); | 
| 1568     __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rax); |  | 
| 1569     __ j(not_equal, miss); |  | 
| 1570 | 1572 | 
| 1571     // Check the shared function info. Make sure it hasn't changed. | 1573     // Check the shared function info. Make sure it hasn't changed. | 
| 1572     __ Move(rax, Handle<SharedFunctionInfo>(function->shared())); | 1574     __ Move(rax, Handle<SharedFunctionInfo>(function->shared())); | 
| 1573     __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax); | 1575     __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax); | 
| 1574   } else { | 1576   } else { | 
| 1575     __ Cmp(rdi, function); | 1577     __ Cmp(rdi, function); | 
| 1576   } | 1578   } | 
| 1577   __ j(not_equal, miss); | 1579   __ j(not_equal, miss); | 
| 1578 } | 1580 } | 
| 1579 | 1581 | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 1591                                                 Handle<JSObject> holder, | 1593                                                 Handle<JSObject> holder, | 
| 1592                                                 PropertyIndex index, | 1594                                                 PropertyIndex index, | 
| 1593                                                 Handle<Name> name) { | 1595                                                 Handle<Name> name) { | 
| 1594   Label miss; | 1596   Label miss; | 
| 1595 | 1597 | 
| 1596   Register reg = HandlerFrontendHeader( | 1598   Register reg = HandlerFrontendHeader( | 
| 1597       object, holder, name, RECEIVER_MAP_CHECK, &miss); | 1599       object, holder, name, RECEIVER_MAP_CHECK, &miss); | 
| 1598 | 1600 | 
| 1599   GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder), | 1601   GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder), | 
| 1600                            index.translate(holder), Representation::Tagged()); | 1602                            index.translate(holder), Representation::Tagged()); | 
| 1601 | 1603   GenerateCallFunction(object, rdi, &miss); | 
| 1602   // Check that the function really is a function. |  | 
| 1603   __ JumpIfSmi(rdi, &miss); |  | 
| 1604   __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx); |  | 
| 1605   __ j(not_equal, &miss); |  | 
| 1606 |  | 
| 1607   PatchGlobalProxy(object); |  | 
| 1608 |  | 
| 1609   // Invoke the function. |  | 
| 1610   CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |  | 
| 1611       ? CALL_AS_FUNCTION |  | 
| 1612       : CALL_AS_METHOD; |  | 
| 1613   __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, |  | 
| 1614                     NullCallWrapper(), call_kind); |  | 
| 1615 | 1604 | 
| 1616   HandlerFrontendFooter(&miss); | 1605   HandlerFrontendFooter(&miss); | 
| 1617 | 1606 | 
| 1618   // Return the generated code. | 1607   // Return the generated code. | 
| 1619   return GetCode(Code::FAST, name); | 1608   return GetCode(Code::FAST, name); | 
| 1620 } | 1609 } | 
| 1621 | 1610 | 
| 1622 | 1611 | 
| 1623 Handle<Code> CallStubCompiler::CompileArrayCodeCall( | 1612 Handle<Code> CallStubCompiler::CompileArrayCodeCall( | 
| 1624     Handle<Object> object, | 1613     Handle<Object> object, | 
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2019 | 2008 | 
| 2020   if (index_out_of_range.is_linked()) { | 2009   if (index_out_of_range.is_linked()) { | 
| 2021     __ bind(&index_out_of_range); | 2010     __ bind(&index_out_of_range); | 
| 2022     __ LoadRoot(rax, Heap::kNanValueRootIndex); | 2011     __ LoadRoot(rax, Heap::kNanValueRootIndex); | 
| 2023     __ ret((argc + 1) * kPointerSize); | 2012     __ ret((argc + 1) * kPointerSize); | 
| 2024   } | 2013   } | 
| 2025 | 2014 | 
| 2026   __ bind(&miss); | 2015   __ bind(&miss); | 
| 2027   // Restore function name in rcx. | 2016   // Restore function name in rcx. | 
| 2028   __ Move(rcx, name); | 2017   __ Move(rcx, name); | 
| 2029   __ bind(&name_miss); | 2018   HandlerFrontendFooter(&name_miss); | 
| 2030   GenerateMissBranch(); |  | 
| 2031 | 2019 | 
| 2032   // Return the generated code. | 2020   // Return the generated code. | 
| 2033   return GetCode(type, name); | 2021   return GetCode(type, name); | 
| 2034 } | 2022 } | 
| 2035 | 2023 | 
| 2036 | 2024 | 
| 2037 Handle<Code> CallStubCompiler::CompileStringCharAtCall( | 2025 Handle<Code> CallStubCompiler::CompileStringCharAtCall( | 
| 2038     Handle<Object> object, | 2026     Handle<Object> object, | 
| 2039     Handle<JSObject> holder, | 2027     Handle<JSObject> holder, | 
| 2040     Handle<Cell> cell, | 2028     Handle<Cell> cell, | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2085   generator.GenerateSlow(masm(), call_helper); | 2073   generator.GenerateSlow(masm(), call_helper); | 
| 2086 | 2074 | 
| 2087   if (index_out_of_range.is_linked()) { | 2075   if (index_out_of_range.is_linked()) { | 
| 2088     __ bind(&index_out_of_range); | 2076     __ bind(&index_out_of_range); | 
| 2089     __ LoadRoot(rax, Heap::kempty_stringRootIndex); | 2077     __ LoadRoot(rax, Heap::kempty_stringRootIndex); | 
| 2090     __ ret((argc + 1) * kPointerSize); | 2078     __ ret((argc + 1) * kPointerSize); | 
| 2091   } | 2079   } | 
| 2092   __ bind(&miss); | 2080   __ bind(&miss); | 
| 2093   // Restore function name in rcx. | 2081   // Restore function name in rcx. | 
| 2094   __ Move(rcx, name); | 2082   __ Move(rcx, name); | 
| 2095   __ bind(&name_miss); | 2083   HandlerFrontendFooter(&name_miss); | 
| 2096   GenerateMissBranch(); |  | 
| 2097 | 2084 | 
| 2098   // Return the generated code. | 2085   // Return the generated code. | 
| 2099   return GetCode(type, name); | 2086   return GetCode(type, name); | 
| 2100 } | 2087 } | 
| 2101 | 2088 | 
| 2102 | 2089 | 
| 2103 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( | 2090 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( | 
| 2104     Handle<Object> object, | 2091     Handle<Object> object, | 
| 2105     Handle<JSObject> holder, | 2092     Handle<JSObject> holder, | 
| 2106     Handle<Cell> cell, | 2093     Handle<Cell> cell, | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 2132   // Convert the smi code to uint16. | 2119   // Convert the smi code to uint16. | 
| 2133   __ SmiAndConstant(code, code, Smi::FromInt(0xffff)); | 2120   __ SmiAndConstant(code, code, Smi::FromInt(0xffff)); | 
| 2134 | 2121 | 
| 2135   StringCharFromCodeGenerator generator(code, rax); | 2122   StringCharFromCodeGenerator generator(code, rax); | 
| 2136   generator.GenerateFast(masm()); | 2123   generator.GenerateFast(masm()); | 
| 2137   __ ret(2 * kPointerSize); | 2124   __ ret(2 * kPointerSize); | 
| 2138 | 2125 | 
| 2139   StubRuntimeCallHelper call_helper; | 2126   StubRuntimeCallHelper call_helper; | 
| 2140   generator.GenerateSlow(masm(), call_helper); | 2127   generator.GenerateSlow(masm(), call_helper); | 
| 2141 | 2128 | 
| 2142   // Tail call the full function. We do not have to patch the receiver |  | 
| 2143   // because the function makes no use of it. |  | 
| 2144   __ bind(&slow); | 2129   __ bind(&slow); | 
| 2145   CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2130   // We do not have to patch the receiver because the function makes no use of | 
| 2146       ? CALL_AS_FUNCTION | 2131   // it. | 
| 2147       : CALL_AS_METHOD; | 2132   GenerateCallFunction(Handle<Object>::null(), function); | 
| 2148   ParameterCount expected(function); |  | 
| 2149   __ InvokeFunction(function, expected, arguments(), |  | 
| 2150                     JUMP_FUNCTION, NullCallWrapper(), call_kind); |  | 
| 2151 | 2133 | 
| 2152   HandlerFrontendFooter(&miss); | 2134   HandlerFrontendFooter(&miss); | 
| 2153 | 2135 | 
| 2154   // Return the generated code. | 2136   // Return the generated code. | 
| 2155   return GetCode(type, name); | 2137   return GetCode(type, name); | 
| 2156 } | 2138 } | 
| 2157 | 2139 | 
| 2158 | 2140 | 
| 2159 Handle<Code> CallStubCompiler::CompileMathFloorCall( | 2141 Handle<Code> CallStubCompiler::CompileMathFloorCall( | 
| 2160     Handle<Object> object, | 2142     Handle<Object> object, | 
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2243   // Return a new heap number. | 2225   // Return a new heap number. | 
| 2244   __ AllocateHeapNumber(rax, rbx, &slow); | 2226   __ AllocateHeapNumber(rax, rbx, &slow); | 
| 2245   __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0); | 2227   __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0); | 
| 2246   __ ret(2 * kPointerSize); | 2228   __ ret(2 * kPointerSize); | 
| 2247 | 2229 | 
| 2248   // Return the argument (when it's an already round heap number). | 2230   // Return the argument (when it's an already round heap number). | 
| 2249   __ bind(&already_round); | 2231   __ bind(&already_round); | 
| 2250   __ movq(rax, args.GetArgumentOperand(1)); | 2232   __ movq(rax, args.GetArgumentOperand(1)); | 
| 2251   __ ret(2 * kPointerSize); | 2233   __ ret(2 * kPointerSize); | 
| 2252 | 2234 | 
| 2253   // Tail call the full function. We do not have to patch the receiver |  | 
| 2254   // because the function makes no use of it. |  | 
| 2255   __ bind(&slow); | 2235   __ bind(&slow); | 
| 2256   ParameterCount expected(function); | 2236   // We do not have to patch the receiver because the function makes no use of | 
| 2257   __ InvokeFunction(function, expected, arguments(), | 2237   // it. | 
| 2258                     JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2238   GenerateCallFunction(Handle<Object>::null(), function); | 
| 2259 | 2239 | 
| 2260   HandlerFrontendFooter(&miss); | 2240   HandlerFrontendFooter(&miss); | 
| 2261 | 2241 | 
| 2262   // Return the generated code. | 2242   // Return the generated code. | 
| 2263   return GetCode(type, name); | 2243   return GetCode(type, name); | 
| 2264 } | 2244 } | 
| 2265 | 2245 | 
| 2266 | 2246 | 
| 2267 Handle<Code> CallStubCompiler::CompileMathAbsCall( | 2247 Handle<Code> CallStubCompiler::CompileMathAbsCall( | 
| 2268     Handle<Object> object, | 2248     Handle<Object> object, | 
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2329   __ ret(2 * kPointerSize); | 2309   __ ret(2 * kPointerSize); | 
| 2330 | 2310 | 
| 2331   // If the argument is negative, clear the sign, and return a new | 2311   // If the argument is negative, clear the sign, and return a new | 
| 2332   // number. We still have the sign mask in rdi. | 2312   // number. We still have the sign mask in rdi. | 
| 2333   __ bind(&negative_sign); | 2313   __ bind(&negative_sign); | 
| 2334   __ xor_(rbx, rdi); | 2314   __ xor_(rbx, rdi); | 
| 2335   __ AllocateHeapNumber(rax, rdx, &slow); | 2315   __ AllocateHeapNumber(rax, rdx, &slow); | 
| 2336   __ MoveDouble(FieldOperand(rax, HeapNumber::kValueOffset), rbx); | 2316   __ MoveDouble(FieldOperand(rax, HeapNumber::kValueOffset), rbx); | 
| 2337   __ ret(2 * kPointerSize); | 2317   __ ret(2 * kPointerSize); | 
| 2338 | 2318 | 
| 2339   // Tail call the full function. We do not have to patch the receiver |  | 
| 2340   // because the function makes no use of it. |  | 
| 2341   __ bind(&slow); | 2319   __ bind(&slow); | 
| 2342   CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2320   // We do not have to patch the receiver because the function makes no use of | 
| 2343       ? CALL_AS_FUNCTION | 2321   // it. | 
| 2344       : CALL_AS_METHOD; | 2322   GenerateCallFunction(Handle<Object>::null(), function); | 
| 2345   ParameterCount expected(function); |  | 
| 2346   __ InvokeFunction(function, expected, arguments(), |  | 
| 2347                     JUMP_FUNCTION, NullCallWrapper(), call_kind); |  | 
| 2348 | 2323 | 
| 2349   HandlerFrontendFooter(&miss); | 2324   HandlerFrontendFooter(&miss); | 
| 2350 | 2325 | 
| 2351   // Return the generated code. | 2326   // Return the generated code. | 
| 2352   return GetCode(type, name); | 2327   return GetCode(type, name); | 
| 2353 } | 2328 } | 
| 2354 | 2329 | 
| 2355 | 2330 | 
| 2356 Handle<Code> CallStubCompiler::CompileFastApiCall( | 2331 Handle<Code> CallStubCompiler::CompileFastApiCall( | 
| 2357     const CallOptimization& optimization, | 2332     const CallOptimization& optimization, | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2395   // Move the return address on top of the stack. | 2370   // Move the return address on top of the stack. | 
| 2396   __ movq(rax, | 2371   __ movq(rax, | 
| 2397           StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize)); | 2372           StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize)); | 
| 2398   __ movq(StackOperandForReturnAddress(0), rax); | 2373   __ movq(StackOperandForReturnAddress(0), rax); | 
| 2399 | 2374 | 
| 2400   GenerateFastApiCall(masm(), optimization, argc); | 2375   GenerateFastApiCall(masm(), optimization, argc); | 
| 2401 | 2376 | 
| 2402   __ bind(&miss); | 2377   __ bind(&miss); | 
| 2403   __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); | 2378   __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); | 
| 2404 | 2379 | 
| 2405   __ bind(&miss_before_stack_reserved); | 2380   HandlerFrontendFooter(&miss_before_stack_reserved); | 
| 2406   GenerateMissBranch(); |  | 
| 2407 | 2381 | 
| 2408   // Return the generated code. | 2382   // Return the generated code. | 
| 2409   return GetCode(function); | 2383   return GetCode(function); | 
| 2410 } | 2384 } | 
| 2411 | 2385 | 
| 2412 | 2386 | 
| 2413 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { | 2387 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { | 
| 2414   Label success; | 2388   Label success; | 
| 2415   // Check that the object is a boolean. | 2389   // Check that the object is a boolean. | 
| 2416   __ CompareRoot(object, Heap::kTrueValueRootIndex); | 2390   __ CompareRoot(object, Heap::kTrueValueRootIndex); | 
| 2417   __ j(equal, &success); | 2391   __ j(equal, &success); | 
| 2418   __ CompareRoot(object, Heap::kFalseValueRootIndex); | 2392   __ CompareRoot(object, Heap::kFalseValueRootIndex); | 
| 2419   __ j(not_equal, miss); | 2393   __ j(not_equal, miss); | 
| 2420   __ bind(&success); | 2394   __ bind(&success); | 
| 2421 } | 2395 } | 
| 2422 | 2396 | 
| 2423 | 2397 | 
| 2424 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) { | 2398 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) { | 
| 2425   if (object->IsGlobalObject()) { | 2399   if (!object.is_null() && object->IsGlobalObject()) { | 
| 2426     StackArgumentsAccessor args(rsp, arguments()); | 2400     StackArgumentsAccessor args(rsp, arguments()); | 
| 2427     __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | 2401     __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | 
| 2428     __ movq(args.GetReceiverOperand(), rdx); | 2402     __ movq(args.GetReceiverOperand(), rdx); | 
| 2429   } | 2403   } | 
| 2430 } | 2404 } | 
| 2431 | 2405 | 
| 2432 | 2406 | 
| 2433 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object, | 2407 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object, | 
| 2434                                                  Handle<JSObject> holder, | 2408                                                  Handle<JSObject> holder, | 
| 2435                                                  Handle<Name> name, | 2409                                                  Handle<Name> name, | 
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2504     Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); | 2478     Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); | 
| 2505     reg = CheckPrototypes( | 2479     reg = CheckPrototypes( | 
| 2506         IC::CurrentTypeOf(prototype, isolate()), | 2480         IC::CurrentTypeOf(prototype, isolate()), | 
| 2507         rax, holder, rbx, rdx, rdi, name, miss); | 2481         rax, holder, rbx, rdx, rdi, name, miss); | 
| 2508   } | 2482   } | 
| 2509 | 2483 | 
| 2510   return reg; | 2484   return reg; | 
| 2511 } | 2485 } | 
| 2512 | 2486 | 
| 2513 | 2487 | 
| 2514 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { | 2488 void CallStubCompiler::GenerateCallFunction(Handle<Object> object, | 
| 2515   CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2489                                             Register function, | 
| 2516       ? CALL_AS_FUNCTION | 2490                                             Label* miss) { | 
| 2517       : CALL_AS_METHOD; | 2491   // Check that the function really is a function. | 
| 2518   ParameterCount expected(function); | 2492   GenerateFunctionCheck(function, rbx, miss); | 
| 2519   __ InvokeFunction(function, expected, arguments(), | 2493 | 
| 2520                     JUMP_FUNCTION, NullCallWrapper(), call_kind); | 2494   if (!function.is(rdi)) __ movq(rdi, function); | 
|  | 2495   PatchGlobalProxy(object); | 
|  | 2496 | 
|  | 2497   // Invoke the function. | 
|  | 2498   __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, | 
|  | 2499                     NullCallWrapper(), call_kind()); | 
| 2521 } | 2500 } | 
| 2522 | 2501 | 
| 2523 | 2502 | 
| 2524 Handle<Code> CallStubCompiler::CompileCallConstant( |  | 
| 2525     Handle<Object> object, |  | 
| 2526     Handle<JSObject> holder, |  | 
| 2527     Handle<Name> name, |  | 
| 2528     CheckType check, |  | 
| 2529     Handle<JSFunction> function) { |  | 
| 2530   if (HasCustomCallGenerator(function)) { |  | 
| 2531     Handle<Code> code = CompileCustomCall(object, holder, |  | 
| 2532                                           Handle<PropertyCell>::null(), |  | 
| 2533                                           function, Handle<String>::cast(name), |  | 
| 2534                                           Code::FAST); |  | 
| 2535     // A null handle means bail out to the regular compiler code below. |  | 
| 2536     if (!code.is_null()) return code; |  | 
| 2537   } |  | 
| 2538 |  | 
| 2539   Label miss; |  | 
| 2540   HandlerFrontendHeader(object, holder, name, check, &miss); |  | 
| 2541   PatchGlobalProxy(object); |  | 
| 2542   CompileHandlerBackend(function); |  | 
| 2543   HandlerFrontendFooter(&miss); |  | 
| 2544 |  | 
| 2545   // Return the generated code. |  | 
| 2546   return GetCode(function); |  | 
| 2547 } |  | 
| 2548 |  | 
| 2549 |  | 
| 2550 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, | 2503 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, | 
| 2551                                                       Handle<JSObject> holder, | 2504                                                       Handle<JSObject> holder, | 
| 2552                                                       Handle<Name> name) { | 2505                                                       Handle<Name> name) { | 
| 2553   Label miss; | 2506   Label miss; | 
| 2554   GenerateNameCheck(name, &miss); | 2507   GenerateNameCheck(name, &miss); | 
| 2555 | 2508 | 
| 2556   LookupResult lookup(isolate()); | 2509   LookupResult lookup(isolate()); | 
| 2557   LookupPostInterceptor(holder, name, &lookup); | 2510   LookupPostInterceptor(holder, name, &lookup); | 
| 2558 | 2511 | 
| 2559   // Get the receiver from the stack. | 2512   // Get the receiver from the stack. | 
| 2560   StackArgumentsAccessor args(rsp, arguments()); | 2513   StackArgumentsAccessor args(rsp, arguments()); | 
| 2561   __ movq(rdx, args.GetReceiverOperand()); | 2514   __ movq(rdx, args.GetReceiverOperand()); | 
| 2562 | 2515 | 
| 2563   CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_); | 2516   CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_); | 
| 2564   compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax, | 2517   compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax, | 
| 2565                    &miss); | 2518                    &miss); | 
| 2566 | 2519 | 
| 2567   // Restore receiver. | 2520   // Restore receiver. | 
| 2568   __ movq(rdx, args.GetReceiverOperand()); | 2521   __ movq(rdx, args.GetReceiverOperand()); | 
| 2569 | 2522 | 
| 2570   // Check that the function really is a function. | 2523   GenerateCallFunction(object, rax, &miss); | 
| 2571   __ JumpIfSmi(rax, &miss); |  | 
| 2572   __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); |  | 
| 2573   __ j(not_equal, &miss); |  | 
| 2574 | 2524 | 
| 2575   // Patch the receiver on the stack with the global proxy if | 2525   HandlerFrontendFooter(&miss); | 
| 2576   // necessary. |  | 
| 2577   if (object->IsGlobalObject()) { |  | 
| 2578     __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |  | 
| 2579     __ movq(args.GetReceiverOperand(), rdx); |  | 
| 2580   } |  | 
| 2581 |  | 
| 2582   // Invoke the function. |  | 
| 2583   __ movq(rdi, rax); |  | 
| 2584   CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |  | 
| 2585       ? CALL_AS_FUNCTION |  | 
| 2586       : CALL_AS_METHOD; |  | 
| 2587   __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, |  | 
| 2588                     NullCallWrapper(), call_kind); |  | 
| 2589 |  | 
| 2590   // Handle load cache miss. |  | 
| 2591   __ bind(&miss); |  | 
| 2592   GenerateMissBranch(); |  | 
| 2593 | 2526 | 
| 2594   // Return the generated code. | 2527   // Return the generated code. | 
| 2595   return GetCode(Code::FAST, name); | 2528   return GetCode(Code::FAST, name); | 
| 2596 } | 2529 } | 
| 2597 | 2530 | 
| 2598 | 2531 | 
| 2599 Handle<Code> CallStubCompiler::CompileCallGlobal( | 2532 Handle<Code> CallStubCompiler::CompileCallGlobal( | 
| 2600     Handle<JSObject> object, | 2533     Handle<JSObject> object, | 
| 2601     Handle<GlobalObject> holder, | 2534     Handle<GlobalObject> holder, | 
| 2602     Handle<PropertyCell> cell, | 2535     Handle<PropertyCell> cell, | 
| 2603     Handle<JSFunction> function, | 2536     Handle<JSFunction> function, | 
| 2604     Handle<Name> name) { | 2537     Handle<Name> name) { | 
| 2605   if (HasCustomCallGenerator(function)) { | 2538   if (HasCustomCallGenerator(function)) { | 
| 2606     Handle<Code> code = CompileCustomCall( | 2539     Handle<Code> code = CompileCustomCall( | 
| 2607         object, holder, cell, function, Handle<String>::cast(name), | 2540         object, holder, cell, function, Handle<String>::cast(name), | 
| 2608         Code::NORMAL); | 2541         Code::NORMAL); | 
| 2609     // A null handle means bail out to the regular compiler code below. | 2542     // A null handle means bail out to the regular compiler code below. | 
| 2610     if (!code.is_null()) return code; | 2543     if (!code.is_null()) return code; | 
| 2611   } | 2544   } | 
| 2612 | 2545 | 
| 2613   Label miss; | 2546   Label miss; | 
| 2614   HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); | 2547   HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); | 
|  | 2548   // Potentially loads a closure that matches the shared function info of the | 
|  | 2549   // function, rather than function. | 
| 2615   GenerateLoadFunctionFromCell(cell, function, &miss); | 2550   GenerateLoadFunctionFromCell(cell, function, &miss); | 
| 2616   PatchGlobalProxy(object); |  | 
| 2617 |  | 
| 2618   // Set up the context (function already in rdi). |  | 
| 2619   __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |  | 
| 2620 |  | 
| 2621   // Jump to the cached code (tail call). |  | 
| 2622   Counters* counters = isolate()->counters(); | 2551   Counters* counters = isolate()->counters(); | 
| 2623   __ IncrementCounter(counters->call_global_inline(), 1); | 2552   __ IncrementCounter(counters->call_global_inline(), 1); | 
| 2624   ParameterCount expected(function->shared()->formal_parameter_count()); | 2553   GenerateCallFunction(object, rdi, function); | 
| 2625   CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |  | 
| 2626       ? CALL_AS_FUNCTION |  | 
| 2627       : CALL_AS_METHOD; |  | 
| 2628   // We call indirectly through the code field in the function to |  | 
| 2629   // allow recompilation to take effect without changing any of the |  | 
| 2630   // call sites. |  | 
| 2631   __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |  | 
| 2632   __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION, |  | 
| 2633                 NullCallWrapper(), call_kind); |  | 
| 2634 |  | 
| 2635   HandlerFrontendFooter(&miss); | 2554   HandlerFrontendFooter(&miss); | 
| 2636 | 2555 | 
| 2637   // Return the generated code. | 2556   // Return the generated code. | 
| 2638   return GetCode(Code::NORMAL, name); | 2557   return GetCode(Code::NORMAL, name); | 
| 2639 } | 2558 } | 
| 2640 | 2559 | 
| 2641 | 2560 | 
| 2642 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2561 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 
| 2643     Handle<JSObject> object, | 2562     Handle<JSObject> object, | 
| 2644     Handle<JSObject> holder, | 2563     Handle<JSObject> holder, | 
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3009   // ----------------------------------- | 2928   // ----------------------------------- | 
| 3010   TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 2929   TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 
| 3011 } | 2930 } | 
| 3012 | 2931 | 
| 3013 | 2932 | 
| 3014 #undef __ | 2933 #undef __ | 
| 3015 | 2934 | 
| 3016 } }  // namespace v8::internal | 2935 } }  // namespace v8::internal | 
| 3017 | 2936 | 
| 3018 #endif  // V8_TARGET_ARCH_X64 | 2937 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW | 
|---|