| 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 627 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 638                               ApiParameterOperand(1), | 638                               ApiParameterOperand(1), | 
| 639                               argc + kFastApiCallArguments + 1, | 639                               argc + kFastApiCallArguments + 1, | 
| 640                               return_value_operand, | 640                               return_value_operand, | 
| 641                               restore_context ? | 641                               restore_context ? | 
| 642                                   &context_restore_operand : NULL); | 642                                   &context_restore_operand : NULL); | 
| 643 } | 643 } | 
| 644 | 644 | 
| 645 | 645 | 
| 646 class CallInterceptorCompiler BASE_EMBEDDED { | 646 class CallInterceptorCompiler BASE_EMBEDDED { | 
| 647  public: | 647  public: | 
| 648   CallInterceptorCompiler(StubCompiler* stub_compiler, | 648   CallInterceptorCompiler(CallStubCompiler* stub_compiler, | 
| 649                           const ParameterCount& arguments, | 649                           const ParameterCount& arguments, | 
| 650                           Register name, | 650                           Register name, | 
| 651                           ExtraICState extra_state) | 651                           ExtraICState extra_state) | 
| 652       : stub_compiler_(stub_compiler), | 652       : stub_compiler_(stub_compiler), | 
| 653         arguments_(arguments), | 653         arguments_(arguments), | 
| 654         name_(name), | 654         name_(name), | 
| 655         extra_state_(extra_state) {} | 655         extra_state_(extra_state) {} | 
| 656 | 656 | 
| 657   void Compile(MacroAssembler* masm, | 657   void Compile(MacroAssembler* masm, | 
| 658                Handle<JSObject> object, | 658                Handle<JSObject> object, | 
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 749       // for API (object which is instanceof for the signature).  It's | 749       // for API (object which is instanceof for the signature).  It's | 
| 750       // safe to omit it here, as if present, it should be fetched | 750       // safe to omit it here, as if present, it should be fetched | 
| 751       // by the previous CheckPrototypes. | 751       // by the previous CheckPrototypes. | 
| 752       ASSERT(depth2 == kInvalidProtoDepth); | 752       ASSERT(depth2 == kInvalidProtoDepth); | 
| 753     } | 753     } | 
| 754 | 754 | 
| 755     // Invoke function. | 755     // Invoke function. | 
| 756     if (can_do_fast_api_call) { | 756     if (can_do_fast_api_call) { | 
| 757       GenerateFastApiCall(masm, optimization, arguments_.immediate()); | 757       GenerateFastApiCall(masm, optimization, arguments_.immediate()); | 
| 758     } else { | 758     } else { | 
| 759       CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 759       Handle<JSFunction> fun = optimization.constant_function(); | 
| 760           ? CALL_AS_FUNCTION | 760       stub_compiler_->GenerateJumpFunctionIgnoreReceiver(fun); | 
| 761           : CALL_AS_METHOD; |  | 
| 762       Handle<JSFunction> function = optimization.constant_function(); |  | 
| 763       ParameterCount expected(function); |  | 
| 764       __ InvokeFunction(function, expected, arguments_, |  | 
| 765                         JUMP_FUNCTION, NullCallWrapper(), call_kind); |  | 
| 766     } | 761     } | 
| 767 | 762 | 
| 768     // Deferred code for fast API call case---clean preallocated space. | 763     // Deferred code for fast API call case---clean preallocated space. | 
| 769     if (can_do_fast_api_call) { | 764     if (can_do_fast_api_call) { | 
| 770       __ bind(&miss_cleanup); | 765       __ bind(&miss_cleanup); | 
| 771       FreeSpaceForFastApiCall(masm, scratch1); | 766       FreeSpaceForFastApiCall(masm, scratch1); | 
| 772       __ jmp(miss_label); | 767       __ jmp(miss_label); | 
| 773     } | 768     } | 
| 774 | 769 | 
| 775     // Invoke a regular function. | 770     // Invoke a regular function. | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 823 | 818 | 
| 824       __ pop(name_);  // Restore the name. | 819       __ pop(name_);  // Restore the name. | 
| 825       __ pop(receiver);  // Restore the holder. | 820       __ pop(receiver);  // Restore the holder. | 
| 826       // Leave the internal frame. | 821       // Leave the internal frame. | 
| 827     } | 822     } | 
| 828 | 823 | 
| 829     __ cmp(eax, masm->isolate()->factory()->no_interceptor_result_sentinel()); | 824     __ cmp(eax, masm->isolate()->factory()->no_interceptor_result_sentinel()); | 
| 830     __ j(not_equal, interceptor_succeeded); | 825     __ j(not_equal, interceptor_succeeded); | 
| 831   } | 826   } | 
| 832 | 827 | 
| 833   StubCompiler* stub_compiler_; | 828   CallStubCompiler* stub_compiler_; | 
| 834   const ParameterCount& arguments_; | 829   const ParameterCount& arguments_; | 
| 835   Register name_; | 830   Register name_; | 
| 836   ExtraICState extra_state_; | 831   ExtraICState extra_state_; | 
| 837 }; | 832 }; | 
| 838 | 833 | 
| 839 | 834 | 
| 840 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, | 835 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, | 
| 841                                             Label* label, | 836                                             Label* label, | 
| 842                                             Handle<Name> name) { | 837                                             Handle<Name> name) { | 
| 843   if (!label->is_unused()) { | 838   if (!label->is_unused()) { | 
| (...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1595 | 1590 | 
| 1596 | 1591 | 
| 1597 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { | 1592 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { | 
| 1598   if (kind_ == Code::KEYED_CALL_IC) { | 1593   if (kind_ == Code::KEYED_CALL_IC) { | 
| 1599     __ cmp(ecx, Immediate(name)); | 1594     __ cmp(ecx, Immediate(name)); | 
| 1600     __ j(not_equal, miss); | 1595     __ j(not_equal, miss); | 
| 1601   } | 1596   } | 
| 1602 } | 1597 } | 
| 1603 | 1598 | 
| 1604 | 1599 | 
|  | 1600 void CallStubCompiler::GenerateFunctionCheck(Register function, | 
|  | 1601                                              Register scratch, | 
|  | 1602                                              Label* miss) { | 
|  | 1603   __ JumpIfSmi(function, miss); | 
|  | 1604   __ CmpObjectType(function, JS_FUNCTION_TYPE, scratch); | 
|  | 1605   __ j(not_equal, miss); | 
|  | 1606 } | 
|  | 1607 | 
|  | 1608 | 
| 1605 void CallStubCompiler::GenerateLoadFunctionFromCell( | 1609 void CallStubCompiler::GenerateLoadFunctionFromCell( | 
| 1606     Handle<Cell> cell, | 1610     Handle<Cell> cell, | 
| 1607     Handle<JSFunction> function, | 1611     Handle<JSFunction> function, | 
| 1608     Label* miss) { | 1612     Label* miss) { | 
| 1609   // Get the value from the cell. | 1613   // Get the value from the cell. | 
| 1610   if (Serializer::enabled()) { | 1614   if (Serializer::enabled()) { | 
| 1611     __ mov(edi, Immediate(cell)); | 1615     __ mov(edi, Immediate(cell)); | 
| 1612     __ mov(edi, FieldOperand(edi, Cell::kValueOffset)); | 1616     __ mov(edi, FieldOperand(edi, Cell::kValueOffset)); | 
| 1613   } else { | 1617   } else { | 
| 1614     __ mov(edi, Operand::ForCell(cell)); | 1618     __ mov(edi, Operand::ForCell(cell)); | 
| 1615   } | 1619   } | 
| 1616 | 1620 | 
| 1617   // Check that the cell contains the same function. | 1621   // Check that the cell contains the same function. | 
| 1618   if (isolate()->heap()->InNewSpace(*function)) { | 1622   if (isolate()->heap()->InNewSpace(*function)) { | 
| 1619     // We can't embed a pointer to a function in new space so we have | 1623     // We can't embed a pointer to a function in new space so we have | 
| 1620     // to verify that the shared function info is unchanged. This has | 1624     // to verify that the shared function info is unchanged. This has | 
| 1621     // the nice side effect that multiple closures based on the same | 1625     // the nice side effect that multiple closures based on the same | 
| 1622     // function can all use this call IC. Before we load through the | 1626     // function can all use this call IC. Before we load through the | 
| 1623     // function, we have to verify that it still is a function. | 1627     // function, we have to verify that it still is a function. | 
| 1624     __ JumpIfSmi(edi, miss); | 1628     GenerateFunctionCheck(edi, ebx, miss); | 
| 1625     __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); |  | 
| 1626     __ j(not_equal, miss); |  | 
| 1627 | 1629 | 
| 1628     // Check the shared function info. Make sure it hasn't changed. | 1630     // Check the shared function info. Make sure it hasn't changed. | 
| 1629     __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset), | 1631     __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset), | 
| 1630            Immediate(Handle<SharedFunctionInfo>(function->shared()))); | 1632            Immediate(Handle<SharedFunctionInfo>(function->shared()))); | 
| 1631   } else { | 1633   } else { | 
| 1632     __ cmp(edi, Immediate(function)); | 1634     __ cmp(edi, Immediate(function)); | 
| 1633   } | 1635   } | 
| 1634   __ j(not_equal, miss); | 1636   __ j(not_equal, miss); | 
| 1635 } | 1637 } | 
| 1636 | 1638 | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
| 1649                                                 PropertyIndex index, | 1651                                                 PropertyIndex index, | 
| 1650                                                 Handle<Name> name) { | 1652                                                 Handle<Name> name) { | 
| 1651   Label miss; | 1653   Label miss; | 
| 1652 | 1654 | 
| 1653   Register reg = HandlerFrontendHeader( | 1655   Register reg = HandlerFrontendHeader( | 
| 1654       object, holder, name, RECEIVER_MAP_CHECK, &miss); | 1656       object, holder, name, RECEIVER_MAP_CHECK, &miss); | 
| 1655 | 1657 | 
| 1656   GenerateFastPropertyLoad( | 1658   GenerateFastPropertyLoad( | 
| 1657       masm(), edi, reg, index.is_inobject(holder), | 1659       masm(), edi, reg, index.is_inobject(holder), | 
| 1658       index.translate(holder), Representation::Tagged()); | 1660       index.translate(holder), Representation::Tagged()); | 
| 1659 | 1661   GenerateJumpFunction(object, edi, &miss); | 
| 1660   // Check that the function really is a function. |  | 
| 1661   __ JumpIfSmi(edi, &miss); |  | 
| 1662   __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); |  | 
| 1663   __ j(not_equal, &miss); |  | 
| 1664 |  | 
| 1665   PatchGlobalProxy(object); |  | 
| 1666 |  | 
| 1667   // Invoke the function. |  | 
| 1668   CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |  | 
| 1669       ? CALL_AS_FUNCTION |  | 
| 1670       : CALL_AS_METHOD; |  | 
| 1671   __ InvokeFunction(edi, arguments(), JUMP_FUNCTION, |  | 
| 1672                     NullCallWrapper(), call_kind); |  | 
| 1673 | 1662 | 
| 1674   HandlerFrontendFooter(&miss); | 1663   HandlerFrontendFooter(&miss); | 
| 1675 | 1664 | 
| 1676   // Return the generated code. | 1665   // Return the generated code. | 
| 1677   return GetCode(Code::FAST, name); | 1666   return GetCode(Code::FAST, name); | 
| 1678 } | 1667 } | 
| 1679 | 1668 | 
| 1680 | 1669 | 
| 1681 Handle<Code> CallStubCompiler::CompileArrayCodeCall( | 1670 Handle<Code> CallStubCompiler::CompileArrayCodeCall( | 
| 1682     Handle<Object> object, | 1671     Handle<Object> object, | 
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2074 | 2063 | 
| 2075   if (index_out_of_range.is_linked()) { | 2064   if (index_out_of_range.is_linked()) { | 
| 2076     __ bind(&index_out_of_range); | 2065     __ bind(&index_out_of_range); | 
| 2077     __ Set(eax, Immediate(factory()->nan_value())); | 2066     __ Set(eax, Immediate(factory()->nan_value())); | 
| 2078     __ ret((argc + 1) * kPointerSize); | 2067     __ ret((argc + 1) * kPointerSize); | 
| 2079   } | 2068   } | 
| 2080 | 2069 | 
| 2081   __ bind(&miss); | 2070   __ bind(&miss); | 
| 2082   // Restore function name in ecx. | 2071   // Restore function name in ecx. | 
| 2083   __ Set(ecx, Immediate(name)); | 2072   __ Set(ecx, Immediate(name)); | 
| 2084   __ bind(&name_miss); | 2073   HandlerFrontendFooter(&name_miss); | 
| 2085   GenerateMissBranch(); |  | 
| 2086 | 2074 | 
| 2087   // Return the generated code. | 2075   // Return the generated code. | 
| 2088   return GetCode(type, name); | 2076   return GetCode(type, name); | 
| 2089 } | 2077 } | 
| 2090 | 2078 | 
| 2091 | 2079 | 
| 2092 Handle<Code> CallStubCompiler::CompileStringCharAtCall( | 2080 Handle<Code> CallStubCompiler::CompileStringCharAtCall( | 
| 2093     Handle<Object> object, | 2081     Handle<Object> object, | 
| 2094     Handle<JSObject> holder, | 2082     Handle<JSObject> holder, | 
| 2095     Handle<Cell> cell, | 2083     Handle<Cell> cell, | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2143 | 2131 | 
| 2144   if (index_out_of_range.is_linked()) { | 2132   if (index_out_of_range.is_linked()) { | 
| 2145     __ bind(&index_out_of_range); | 2133     __ bind(&index_out_of_range); | 
| 2146     __ Set(eax, Immediate(factory()->empty_string())); | 2134     __ Set(eax, Immediate(factory()->empty_string())); | 
| 2147     __ ret((argc + 1) * kPointerSize); | 2135     __ ret((argc + 1) * kPointerSize); | 
| 2148   } | 2136   } | 
| 2149 | 2137 | 
| 2150   __ bind(&miss); | 2138   __ bind(&miss); | 
| 2151   // Restore function name in ecx. | 2139   // Restore function name in ecx. | 
| 2152   __ Set(ecx, Immediate(name)); | 2140   __ Set(ecx, Immediate(name)); | 
| 2153   __ bind(&name_miss); | 2141   HandlerFrontendFooter(&name_miss); | 
| 2154   GenerateMissBranch(); |  | 
| 2155 | 2142 | 
| 2156   // Return the generated code. | 2143   // Return the generated code. | 
| 2157   return GetCode(type, name); | 2144   return GetCode(type, name); | 
| 2158 } | 2145 } | 
| 2159 | 2146 | 
| 2160 | 2147 | 
| 2161 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( | 2148 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( | 
| 2162     Handle<Object> object, | 2149     Handle<Object> object, | 
| 2163     Handle<JSObject> holder, | 2150     Handle<JSObject> holder, | 
| 2164     Handle<Cell> cell, | 2151     Handle<Cell> cell, | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
| 2193   // Convert the smi code to uint16. | 2180   // Convert the smi code to uint16. | 
| 2194   __ and_(code, Immediate(Smi::FromInt(0xffff))); | 2181   __ and_(code, Immediate(Smi::FromInt(0xffff))); | 
| 2195 | 2182 | 
| 2196   StringCharFromCodeGenerator generator(code, eax); | 2183   StringCharFromCodeGenerator generator(code, eax); | 
| 2197   generator.GenerateFast(masm()); | 2184   generator.GenerateFast(masm()); | 
| 2198   __ ret(2 * kPointerSize); | 2185   __ ret(2 * kPointerSize); | 
| 2199 | 2186 | 
| 2200   StubRuntimeCallHelper call_helper; | 2187   StubRuntimeCallHelper call_helper; | 
| 2201   generator.GenerateSlow(masm(), call_helper); | 2188   generator.GenerateSlow(masm(), call_helper); | 
| 2202 | 2189 | 
| 2203   // Tail call the full function. We do not have to patch the receiver |  | 
| 2204   // because the function makes no use of it. |  | 
| 2205   __ bind(&slow); | 2190   __ bind(&slow); | 
| 2206   CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2191   // We do not have to patch the receiver because the function makes no use of | 
| 2207       ? CALL_AS_FUNCTION | 2192   // it. | 
| 2208       : CALL_AS_METHOD; | 2193   GenerateJumpFunctionIgnoreReceiver(function); | 
| 2209   ParameterCount expected(function); |  | 
| 2210   __ InvokeFunction(function, expected, arguments(), |  | 
| 2211                     JUMP_FUNCTION, NullCallWrapper(), call_kind); |  | 
| 2212 | 2194 | 
| 2213   HandlerFrontendFooter(&miss); | 2195   HandlerFrontendFooter(&miss); | 
| 2214 | 2196 | 
| 2215   // Return the generated code. | 2197   // Return the generated code. | 
| 2216   return GetCode(type, name); | 2198   return GetCode(type, name); | 
| 2217 } | 2199 } | 
| 2218 | 2200 | 
| 2219 | 2201 | 
| 2220 Handle<Code> CallStubCompiler::CompileMathFloorCall( | 2202 Handle<Code> CallStubCompiler::CompileMathFloorCall( | 
| 2221     Handle<Object> object, | 2203     Handle<Object> object, | 
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2308   // Return a new heap number. | 2290   // Return a new heap number. | 
| 2309   __ AllocateHeapNumber(eax, ebx, edx, &slow); | 2291   __ AllocateHeapNumber(eax, ebx, edx, &slow); | 
| 2310   __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); | 2292   __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); | 
| 2311   __ ret(2 * kPointerSize); | 2293   __ ret(2 * kPointerSize); | 
| 2312 | 2294 | 
| 2313   // Return the argument (when it's an already round heap number). | 2295   // Return the argument (when it's an already round heap number). | 
| 2314   __ bind(&already_round); | 2296   __ bind(&already_round); | 
| 2315   __ mov(eax, Operand(esp, 1 * kPointerSize)); | 2297   __ mov(eax, Operand(esp, 1 * kPointerSize)); | 
| 2316   __ ret(2 * kPointerSize); | 2298   __ ret(2 * kPointerSize); | 
| 2317 | 2299 | 
| 2318   // Tail call the full function. We do not have to patch the receiver |  | 
| 2319   // because the function makes no use of it. |  | 
| 2320   __ bind(&slow); | 2300   __ bind(&slow); | 
| 2321   ParameterCount expected(function); | 2301   // We do not have to patch the receiver because the function makes no use of | 
| 2322   __ InvokeFunction(function, expected, arguments(), | 2302   // it. | 
| 2323                     JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2303   GenerateJumpFunctionIgnoreReceiver(function); | 
| 2324 | 2304 | 
| 2325   HandlerFrontendFooter(&miss); | 2305   HandlerFrontendFooter(&miss); | 
| 2326 | 2306 | 
| 2327   // Return the generated code. | 2307   // Return the generated code. | 
| 2328   return GetCode(type, name); | 2308   return GetCode(type, name); | 
| 2329 } | 2309 } | 
| 2330 | 2310 | 
| 2331 | 2311 | 
| 2332 Handle<Code> CallStubCompiler::CompileMathAbsCall( | 2312 Handle<Code> CallStubCompiler::CompileMathAbsCall( | 
| 2333     Handle<Object> object, | 2313     Handle<Object> object, | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2397   // If the argument is negative, clear the sign, and return a new | 2377   // If the argument is negative, clear the sign, and return a new | 
| 2398   // number. | 2378   // number. | 
| 2399   __ bind(&negative_sign); | 2379   __ bind(&negative_sign); | 
| 2400   __ and_(ebx, ~HeapNumber::kSignMask); | 2380   __ and_(ebx, ~HeapNumber::kSignMask); | 
| 2401   __ mov(ecx, FieldOperand(eax, HeapNumber::kMantissaOffset)); | 2381   __ mov(ecx, FieldOperand(eax, HeapNumber::kMantissaOffset)); | 
| 2402   __ AllocateHeapNumber(eax, edi, edx, &slow); | 2382   __ AllocateHeapNumber(eax, edi, edx, &slow); | 
| 2403   __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ebx); | 2383   __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ebx); | 
| 2404   __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx); | 2384   __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx); | 
| 2405   __ ret(2 * kPointerSize); | 2385   __ ret(2 * kPointerSize); | 
| 2406 | 2386 | 
| 2407   // Tail call the full function. We do not have to patch the receiver |  | 
| 2408   // because the function makes no use of it. |  | 
| 2409   __ bind(&slow); | 2387   __ bind(&slow); | 
| 2410   ParameterCount expected(function); | 2388   // We do not have to patch the receiver because the function makes no use of | 
| 2411   __ InvokeFunction(function, expected, arguments(), | 2389   // it. | 
| 2412                     JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2390   GenerateJumpFunctionIgnoreReceiver(function); | 
| 2413 | 2391 | 
| 2414   HandlerFrontendFooter(&miss); | 2392   HandlerFrontendFooter(&miss); | 
| 2415 | 2393 | 
| 2416   // Return the generated code. | 2394   // Return the generated code. | 
| 2417   return GetCode(type, name); | 2395   return GetCode(type, name); | 
| 2418 } | 2396 } | 
| 2419 | 2397 | 
| 2420 | 2398 | 
| 2421 Handle<Code> CallStubCompiler::CompileFastApiCall( | 2399 Handle<Code> CallStubCompiler::CompileFastApiCall( | 
| 2422     const CallOptimization& optimization, | 2400     const CallOptimization& optimization, | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2462   __ mov(eax, Operand(esp, kFastApiCallArguments * kPointerSize)); | 2440   __ mov(eax, Operand(esp, kFastApiCallArguments * kPointerSize)); | 
| 2463   __ mov(Operand(esp, 0 * kPointerSize), eax); | 2441   __ mov(Operand(esp, 0 * kPointerSize), eax); | 
| 2464 | 2442 | 
| 2465   // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains | 2443   // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains | 
| 2466   // duplicate of return address and will be overwritten. | 2444   // duplicate of return address and will be overwritten. | 
| 2467   GenerateFastApiCall(masm(), optimization, argc); | 2445   GenerateFastApiCall(masm(), optimization, argc); | 
| 2468 | 2446 | 
| 2469   __ bind(&miss); | 2447   __ bind(&miss); | 
| 2470   __ add(esp, Immediate(kFastApiCallArguments * kPointerSize)); | 2448   __ add(esp, Immediate(kFastApiCallArguments * kPointerSize)); | 
| 2471 | 2449 | 
| 2472   __ bind(&miss_before_stack_reserved); | 2450   HandlerFrontendFooter(&miss_before_stack_reserved); | 
| 2473   GenerateMissBranch(); |  | 
| 2474 | 2451 | 
| 2475   // Return the generated code. | 2452   // Return the generated code. | 
| 2476   return GetCode(function); | 2453   return GetCode(function); | 
| 2477 } | 2454 } | 
| 2478 | 2455 | 
| 2479 | 2456 | 
| 2480 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { | 2457 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { | 
| 2481   Label success; | 2458   Label success; | 
| 2482   // Check that the object is a boolean. | 2459   // Check that the object is a boolean. | 
| 2483   __ cmp(object, factory()->true_value()); | 2460   __ cmp(object, factory()->true_value()); | 
| 2484   __ j(equal, &success); | 2461   __ j(equal, &success); | 
| 2485   __ cmp(object, factory()->false_value()); | 2462   __ cmp(object, factory()->false_value()); | 
| 2486   __ j(not_equal, miss); | 2463   __ j(not_equal, miss); | 
| 2487   __ bind(&success); | 2464   __ bind(&success); | 
| 2488 } | 2465 } | 
| 2489 | 2466 | 
| 2490 | 2467 | 
| 2491 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) { | 2468 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) { | 
| 2492   if (object->IsGlobalObject()) { | 2469   if (!object.is_null() && object->IsGlobalObject()) { | 
| 2493     const int argc = arguments().immediate(); | 2470     const int argc = arguments().immediate(); | 
| 2494     const int receiver_offset = (argc + 1) * kPointerSize; | 2471     const int receiver_offset = (argc + 1) * kPointerSize; | 
| 2495     __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 2472     __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 
| 2496     __ mov(Operand(esp, receiver_offset), edx); | 2473     __ mov(Operand(esp, receiver_offset), edx); | 
| 2497   } | 2474   } | 
| 2498 } | 2475 } | 
| 2499 | 2476 | 
| 2500 | 2477 | 
| 2501 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object, | 2478 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object, | 
| 2502                                                  Handle<JSObject> holder, | 2479                                                  Handle<JSObject> holder, | 
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2572     Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); | 2549     Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); | 
| 2573     reg = CheckPrototypes( | 2550     reg = CheckPrototypes( | 
| 2574         IC::CurrentTypeOf(prototype, isolate()), | 2551         IC::CurrentTypeOf(prototype, isolate()), | 
| 2575         eax, holder, ebx, edx, edi, name, miss); | 2552         eax, holder, ebx, edx, edi, name, miss); | 
| 2576   } | 2553   } | 
| 2577 | 2554 | 
| 2578   return reg; | 2555   return reg; | 
| 2579 } | 2556 } | 
| 2580 | 2557 | 
| 2581 | 2558 | 
| 2582 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { | 2559 void CallStubCompiler::GenerateJumpFunction(Handle<Object> object, | 
| 2583   CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2560                                             Register function, | 
| 2584       ? CALL_AS_FUNCTION | 2561                                             Label* miss) { | 
| 2585       : CALL_AS_METHOD; | 2562   // Check that the function really is a function. | 
| 2586   ParameterCount expected(function); | 2563   GenerateFunctionCheck(function, ebx, miss); | 
| 2587   __ InvokeFunction(function, expected, arguments(), | 2564 | 
| 2588                     JUMP_FUNCTION, NullCallWrapper(), call_kind); | 2565   if (!function.is(edi)) __ mov(edi, function); | 
|  | 2566   PatchGlobalProxy(object); | 
|  | 2567 | 
|  | 2568   // Invoke the function. | 
|  | 2569   __ InvokeFunction(edi, arguments(), JUMP_FUNCTION, | 
|  | 2570                     NullCallWrapper(), call_kind()); | 
| 2589 } | 2571 } | 
| 2590 | 2572 | 
| 2591 | 2573 | 
| 2592 Handle<Code> CallStubCompiler::CompileCallConstant( |  | 
| 2593     Handle<Object> object, |  | 
| 2594     Handle<JSObject> holder, |  | 
| 2595     Handle<Name> name, |  | 
| 2596     CheckType check, |  | 
| 2597     Handle<JSFunction> function) { |  | 
| 2598 |  | 
| 2599   if (HasCustomCallGenerator(function)) { |  | 
| 2600     Handle<Code> code = CompileCustomCall(object, holder, |  | 
| 2601                                           Handle<Cell>::null(), |  | 
| 2602                                           function, Handle<String>::cast(name), |  | 
| 2603                                           Code::FAST); |  | 
| 2604     // A null handle means bail out to the regular compiler code below. |  | 
| 2605     if (!code.is_null()) return code; |  | 
| 2606   } |  | 
| 2607 |  | 
| 2608   Label miss; |  | 
| 2609   HandlerFrontendHeader(object, holder, name, check, &miss); |  | 
| 2610   PatchGlobalProxy(object); |  | 
| 2611   CompileHandlerBackend(function); |  | 
| 2612   HandlerFrontendFooter(&miss); |  | 
| 2613 |  | 
| 2614   // Return the generated code. |  | 
| 2615   return GetCode(function); |  | 
| 2616 } |  | 
| 2617 |  | 
| 2618 |  | 
| 2619 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, | 2574 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, | 
| 2620                                                       Handle<JSObject> holder, | 2575                                                       Handle<JSObject> holder, | 
| 2621                                                       Handle<Name> name) { | 2576                                                       Handle<Name> name) { | 
| 2622   Label miss; | 2577   Label miss; | 
| 2623 | 2578 | 
| 2624   GenerateNameCheck(name, &miss); | 2579   GenerateNameCheck(name, &miss); | 
| 2625 | 2580 | 
| 2626   // Get the number of arguments. | 2581   // Get the number of arguments. | 
| 2627   const int argc = arguments().immediate(); | 2582   const int argc = arguments().immediate(); | 
| 2628 | 2583 | 
| 2629   LookupResult lookup(isolate()); | 2584   LookupResult lookup(isolate()); | 
| 2630   LookupPostInterceptor(holder, name, &lookup); | 2585   LookupPostInterceptor(holder, name, &lookup); | 
| 2631 | 2586 | 
| 2632   // Get the receiver from the stack. | 2587   // Get the receiver from the stack. | 
| 2633   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 2588   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 
| 2634 | 2589 | 
| 2635   CallInterceptorCompiler compiler(this, arguments(), ecx, extra_state_); | 2590   CallInterceptorCompiler compiler(this, arguments(), ecx, extra_state_); | 
| 2636   compiler.Compile(masm(), object, holder, name, &lookup, edx, ebx, edi, eax, | 2591   compiler.Compile(masm(), object, holder, name, &lookup, edx, ebx, edi, eax, | 
| 2637                    &miss); | 2592                    &miss); | 
| 2638 | 2593 | 
| 2639   // Restore receiver. | 2594   // Restore receiver. | 
| 2640   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 2595   __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 
| 2641 | 2596 | 
| 2642   // Check that the function really is a function. | 2597   GenerateJumpFunction(object, eax, &miss); | 
| 2643   __ JumpIfSmi(eax, &miss); |  | 
| 2644   __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx); |  | 
| 2645   __ j(not_equal, &miss); |  | 
| 2646 | 2598 | 
| 2647   // Patch the receiver on the stack with the global proxy if | 2599   HandlerFrontendFooter(&miss); | 
| 2648   // necessary. |  | 
| 2649   if (object->IsGlobalObject()) { |  | 
| 2650     __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |  | 
| 2651     __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |  | 
| 2652   } |  | 
| 2653 |  | 
| 2654   // Invoke the function. |  | 
| 2655   __ mov(edi, eax); |  | 
| 2656   CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |  | 
| 2657       ? CALL_AS_FUNCTION |  | 
| 2658       : CALL_AS_METHOD; |  | 
| 2659   __ InvokeFunction(edi, arguments(), JUMP_FUNCTION, |  | 
| 2660                     NullCallWrapper(), call_kind); |  | 
| 2661 |  | 
| 2662   // Handle load cache miss. |  | 
| 2663   __ bind(&miss); |  | 
| 2664   GenerateMissBranch(); |  | 
| 2665 | 2600 | 
| 2666   // Return the generated code. | 2601   // Return the generated code. | 
| 2667   return GetCode(Code::FAST, name); | 2602   return GetCode(Code::FAST, name); | 
| 2668 } | 2603 } | 
| 2669 | 2604 | 
| 2670 | 2605 | 
| 2671 Handle<Code> CallStubCompiler::CompileCallGlobal( | 2606 Handle<Code> CallStubCompiler::CompileCallGlobal( | 
| 2672     Handle<JSObject> object, | 2607     Handle<JSObject> object, | 
| 2673     Handle<GlobalObject> holder, | 2608     Handle<GlobalObject> holder, | 
| 2674     Handle<PropertyCell> cell, | 2609     Handle<PropertyCell> cell, | 
| 2675     Handle<JSFunction> function, | 2610     Handle<JSFunction> function, | 
| 2676     Handle<Name> name) { | 2611     Handle<Name> name) { | 
| 2677   if (HasCustomCallGenerator(function)) { | 2612   if (HasCustomCallGenerator(function)) { | 
| 2678     Handle<Code> code = CompileCustomCall( | 2613     Handle<Code> code = CompileCustomCall( | 
| 2679         object, holder, cell, function, Handle<String>::cast(name), | 2614         object, holder, cell, function, Handle<String>::cast(name), | 
| 2680         Code::NORMAL); | 2615         Code::NORMAL); | 
| 2681     // A null handle means bail out to the regular compiler code below. | 2616     // A null handle means bail out to the regular compiler code below. | 
| 2682     if (!code.is_null()) return code; | 2617     if (!code.is_null()) return code; | 
| 2683   } | 2618   } | 
| 2684 | 2619 | 
| 2685   Label miss; | 2620   Label miss; | 
| 2686   HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); | 2621   HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); | 
|  | 2622   // Potentially loads a closure that matches the shared function info of the | 
|  | 2623   // function, rather than function. | 
| 2687   GenerateLoadFunctionFromCell(cell, function, &miss); | 2624   GenerateLoadFunctionFromCell(cell, function, &miss); | 
| 2688   PatchGlobalProxy(object); | 2625   GenerateJumpFunction(object, edi, function); | 
| 2689 |  | 
| 2690   // Set up the context (function already in edi). |  | 
| 2691   __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |  | 
| 2692 |  | 
| 2693   // Jump to the cached code (tail call). |  | 
| 2694   Counters* counters = isolate()->counters(); |  | 
| 2695   __ IncrementCounter(counters->call_global_inline(), 1); |  | 
| 2696   ParameterCount expected(function->shared()->formal_parameter_count()); |  | 
| 2697   CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |  | 
| 2698       ? CALL_AS_FUNCTION |  | 
| 2699       : CALL_AS_METHOD; |  | 
| 2700   // We call indirectly through the code field in the function to |  | 
| 2701   // allow recompilation to take effect without changing any of the |  | 
| 2702   // call sites. |  | 
| 2703   __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), |  | 
| 2704                 expected, arguments(), JUMP_FUNCTION, |  | 
| 2705                 NullCallWrapper(), call_kind); |  | 
| 2706 | 2626 | 
| 2707   HandlerFrontendFooter(&miss); | 2627   HandlerFrontendFooter(&miss); | 
| 2708 | 2628 | 
| 2709   // Return the generated code. | 2629   // Return the generated code. | 
| 2710   return GetCode(Code::NORMAL, name); | 2630   return GetCode(Code::NORMAL, name); | 
| 2711 } | 2631 } | 
| 2712 | 2632 | 
| 2713 | 2633 | 
| 2714 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2634 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 
| 2715     Handle<JSObject> object, | 2635     Handle<JSObject> object, | 
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3070   // ----------------------------------- | 2990   // ----------------------------------- | 
| 3071   TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 2991   TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 
| 3072 } | 2992 } | 
| 3073 | 2993 | 
| 3074 | 2994 | 
| 3075 #undef __ | 2995 #undef __ | 
| 3076 | 2996 | 
| 3077 } }  // namespace v8::internal | 2997 } }  // namespace v8::internal | 
| 3078 | 2998 | 
| 3079 #endif  // V8_TARGET_ARCH_IA32 | 2999 #endif  // V8_TARGET_ARCH_IA32 | 
| OLD | NEW | 
|---|