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 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
725 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, | 725 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, |
726 Label* label, | 726 Label* label, |
727 Handle<Name> name) { | 727 Handle<Name> name) { |
728 if (!label->is_unused()) { | 728 if (!label->is_unused()) { |
729 __ bind(label); | 729 __ bind(label); |
730 __ li(this->name(), Operand(name)); | 730 __ li(this->name(), Operand(name)); |
731 } | 731 } |
732 } | 732 } |
733 | 733 |
734 | 734 |
735 static void GenerateCallFunction(MacroAssembler* masm, | |
736 Handle<Object> object, | |
737 const ParameterCount& arguments, | |
738 Label* miss, | |
739 ExtraICState extra_ic_state) { | |
740 // ----------- S t a t e ------------- | |
741 // -- a0: receiver | |
742 // -- a1: function to call | |
743 // ----------------------------------- | |
744 // Check that the function really is a function. | |
745 __ JumpIfSmi(a1, miss); | |
746 __ GetObjectType(a1, a3, a3); | |
747 __ Branch(miss, ne, a3, Operand(JS_FUNCTION_TYPE)); | |
748 | |
749 if (object->IsGlobalObject()) { | |
750 const int argc = arguments.immediate(); | |
751 const int receiver_offset = argc * kPointerSize; | |
752 __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset)); | |
753 __ sw(a3, MemOperand(sp, receiver_offset)); | |
754 } | |
755 | |
756 // Invoke the function. | |
757 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state) | |
758 ? CALL_AS_FUNCTION | |
759 : CALL_AS_METHOD; | |
760 __ InvokeFunction(a1, arguments, JUMP_FUNCTION, NullCallWrapper(), call_kind); | |
761 } | |
762 | |
763 | |
764 static void PushInterceptorArguments(MacroAssembler* masm, | 735 static void PushInterceptorArguments(MacroAssembler* masm, |
765 Register receiver, | 736 Register receiver, |
766 Register holder, | 737 Register holder, |
767 Register name, | 738 Register name, |
768 Handle<JSObject> holder_obj) { | 739 Handle<JSObject> holder_obj) { |
769 STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0); | 740 STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0); |
770 STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1); | 741 STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1); |
771 STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2); | 742 STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2); |
772 STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3); | 743 STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3); |
773 STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4); | 744 STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
935 ASSERT(!scratch.is(values[i])); | 906 ASSERT(!scratch.is(values[i])); |
936 __ sw(receiver, MemOperand(sp, index-- * kPointerSize)); | 907 __ sw(receiver, MemOperand(sp, index-- * kPointerSize)); |
937 } | 908 } |
938 | 909 |
939 GenerateFastApiDirectCall(masm, optimization, argc, true); | 910 GenerateFastApiDirectCall(masm, optimization, argc, true); |
940 } | 911 } |
941 | 912 |
942 | 913 |
943 class CallInterceptorCompiler BASE_EMBEDDED { | 914 class CallInterceptorCompiler BASE_EMBEDDED { |
944 public: | 915 public: |
945 CallInterceptorCompiler(StubCompiler* stub_compiler, | 916 CallInterceptorCompiler(CallStubCompiler* stub_compiler, |
946 const ParameterCount& arguments, | 917 const ParameterCount& arguments, |
947 Register name, | 918 Register name, |
948 ExtraICState extra_ic_state) | 919 ExtraICState extra_ic_state) |
949 : stub_compiler_(stub_compiler), | 920 : stub_compiler_(stub_compiler), |
950 arguments_(arguments), | 921 arguments_(arguments), |
951 name_(name), | 922 name_(name), |
952 extra_ic_state_(extra_ic_state) {} | 923 extra_ic_state_(extra_ic_state) {} |
953 | 924 |
954 void Compile(MacroAssembler* masm, | 925 void Compile(MacroAssembler* masm, |
955 Handle<JSObject> object, | 926 Handle<JSObject> object, |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1047 // safe to omit it here, as if present, it should be fetched | 1018 // safe to omit it here, as if present, it should be fetched |
1048 // by the previous CheckPrototypes. | 1019 // by the previous CheckPrototypes. |
1049 ASSERT(depth2 == kInvalidProtoDepth); | 1020 ASSERT(depth2 == kInvalidProtoDepth); |
1050 } | 1021 } |
1051 | 1022 |
1052 // Invoke function. | 1023 // Invoke function. |
1053 if (can_do_fast_api_call) { | 1024 if (can_do_fast_api_call) { |
1054 GenerateFastApiDirectCall( | 1025 GenerateFastApiDirectCall( |
1055 masm, optimization, arguments_.immediate(), false); | 1026 masm, optimization, arguments_.immediate(), false); |
1056 } else { | 1027 } else { |
1057 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | |
1058 ? CALL_AS_FUNCTION | |
1059 : CALL_AS_METHOD; | |
1060 Handle<JSFunction> function = optimization.constant_function(); | 1028 Handle<JSFunction> function = optimization.constant_function(); |
1061 ParameterCount expected(function); | 1029 stub_compiler_->GenerateJumpFunction(object, function); |
Igor Sheludko
2013/11/29 12:39:42
JumpIgnoreReceiver?
| |
1062 __ InvokeFunction(function, expected, arguments_, | |
1063 JUMP_FUNCTION, NullCallWrapper(), call_kind); | |
1064 } | 1030 } |
1065 | 1031 |
1066 // Deferred code for fast API call case---clean preallocated space. | 1032 // Deferred code for fast API call case---clean preallocated space. |
1067 if (can_do_fast_api_call) { | 1033 if (can_do_fast_api_call) { |
1068 __ bind(&miss_cleanup); | 1034 __ bind(&miss_cleanup); |
1069 FreeSpaceForFastApiCall(masm); | 1035 FreeSpaceForFastApiCall(masm); |
1070 __ Branch(miss_label); | 1036 __ Branch(miss_label); |
1071 } | 1037 } |
1072 | 1038 |
1073 // Invoke a regular function. | 1039 // Invoke a regular function. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1119 masm, receiver, holder, name_, holder_obj, | 1085 masm, receiver, holder, name_, holder_obj, |
1120 IC::kLoadPropertyWithInterceptorOnly); | 1086 IC::kLoadPropertyWithInterceptorOnly); |
1121 __ pop(name_); // Restore the name. | 1087 __ pop(name_); // Restore the name. |
1122 __ pop(receiver); // Restore the holder. | 1088 __ pop(receiver); // Restore the holder. |
1123 } | 1089 } |
1124 // If interceptor returns no-result sentinel, call the constant function. | 1090 // If interceptor returns no-result sentinel, call the constant function. |
1125 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex); | 1091 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex); |
1126 __ Branch(interceptor_succeeded, ne, v0, Operand(scratch)); | 1092 __ Branch(interceptor_succeeded, ne, v0, Operand(scratch)); |
1127 } | 1093 } |
1128 | 1094 |
1129 StubCompiler* stub_compiler_; | 1095 CallStubCompiler* stub_compiler_; |
1130 const ParameterCount& arguments_; | 1096 const ParameterCount& arguments_; |
1131 Register name_; | 1097 Register name_; |
1132 ExtraICState extra_ic_state_; | 1098 ExtraICState extra_ic_state_; |
1133 }; | 1099 }; |
1134 | 1100 |
1135 | 1101 |
1136 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { | 1102 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { |
1137 __ Jump(code, RelocInfo::CODE_TARGET); | 1103 __ Jump(code, RelocInfo::CODE_TARGET); |
1138 } | 1104 } |
1139 | 1105 |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1520 } | 1486 } |
1521 | 1487 |
1522 | 1488 |
1523 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { | 1489 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { |
1524 if (kind_ == Code::KEYED_CALL_IC) { | 1490 if (kind_ == Code::KEYED_CALL_IC) { |
1525 __ Branch(miss, ne, a2, Operand(name)); | 1491 __ Branch(miss, ne, a2, Operand(name)); |
1526 } | 1492 } |
1527 } | 1493 } |
1528 | 1494 |
1529 | 1495 |
1496 void CallStubCompiler::GenerateFunctionCheck(Register function, | |
1497 Register scratch, | |
1498 Label* miss) { | |
1499 __ JumpIfSmi(function, miss); | |
1500 __ GetObjectType(function, scratch, scratch); | |
1501 __ Branch(miss, ne, scratch, Operand(JS_FUNCTION_TYPE)); | |
1502 } | |
1503 | |
1504 | |
1530 void CallStubCompiler::GenerateLoadFunctionFromCell( | 1505 void CallStubCompiler::GenerateLoadFunctionFromCell( |
1531 Handle<Cell> cell, | 1506 Handle<Cell> cell, |
1532 Handle<JSFunction> function, | 1507 Handle<JSFunction> function, |
1533 Label* miss) { | 1508 Label* miss) { |
1534 // Get the value from the cell. | 1509 // Get the value from the cell. |
1535 __ li(a3, Operand(cell)); | 1510 __ li(a3, Operand(cell)); |
1536 __ lw(a1, FieldMemOperand(a3, Cell::kValueOffset)); | 1511 __ lw(a1, FieldMemOperand(a3, Cell::kValueOffset)); |
1537 | 1512 |
1538 // Check that the cell contains the same function. | 1513 // Check that the cell contains the same function. |
1539 if (heap()->InNewSpace(*function)) { | 1514 if (heap()->InNewSpace(*function)) { |
1540 // We can't embed a pointer to a function in new space so we have | 1515 // We can't embed a pointer to a function in new space so we have |
1541 // to verify that the shared function info is unchanged. This has | 1516 // to verify that the shared function info is unchanged. This has |
1542 // the nice side effect that multiple closures based on the same | 1517 // the nice side effect that multiple closures based on the same |
1543 // function can all use this call IC. Before we load through the | 1518 // function can all use this call IC. Before we load through the |
1544 // function, we have to verify that it still is a function. | 1519 // function, we have to verify that it still is a function. |
1545 __ JumpIfSmi(a1, miss); | 1520 GenerateFunctionCheck(a1, a3, miss); |
1546 __ GetObjectType(a1, a3, a3); | |
1547 __ Branch(miss, ne, a3, Operand(JS_FUNCTION_TYPE)); | |
1548 | 1521 |
1549 // Check the shared function info. Make sure it hasn't changed. | 1522 // Check the shared function info. Make sure it hasn't changed. |
1550 __ li(a3, Handle<SharedFunctionInfo>(function->shared())); | 1523 __ li(a3, Handle<SharedFunctionInfo>(function->shared())); |
1551 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 1524 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
1552 __ Branch(miss, ne, t0, Operand(a3)); | 1525 __ Branch(miss, ne, t0, Operand(a3)); |
1553 } else { | 1526 } else { |
1554 __ Branch(miss, ne, a1, Operand(function)); | 1527 __ Branch(miss, ne, a1, Operand(function)); |
1555 } | 1528 } |
1556 } | 1529 } |
1557 | 1530 |
(...skipping 10 matching lines...) Expand all Loading... | |
1568 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, | 1541 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, |
1569 Handle<JSObject> holder, | 1542 Handle<JSObject> holder, |
1570 PropertyIndex index, | 1543 PropertyIndex index, |
1571 Handle<Name> name) { | 1544 Handle<Name> name) { |
1572 Label miss; | 1545 Label miss; |
1573 | 1546 |
1574 Register reg = HandlerFrontendHeader( | 1547 Register reg = HandlerFrontendHeader( |
1575 object, holder, name, RECEIVER_MAP_CHECK, &miss); | 1548 object, holder, name, RECEIVER_MAP_CHECK, &miss); |
1576 GenerateFastPropertyLoad(masm(), a1, reg, index.is_inobject(holder), | 1549 GenerateFastPropertyLoad(masm(), a1, reg, index.is_inobject(holder), |
1577 index.translate(holder), Representation::Tagged()); | 1550 index.translate(holder), Representation::Tagged()); |
1578 | 1551 GenerateJumpFunction(object, a1, &miss); |
1579 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | |
1580 | 1552 |
1581 HandlerFrontendFooter(&miss); | 1553 HandlerFrontendFooter(&miss); |
1582 | 1554 |
1583 // Return the generated code. | 1555 // Return the generated code. |
1584 return GetCode(Code::FAST, name); | 1556 return GetCode(Code::FAST, name); |
1585 } | 1557 } |
1586 | 1558 |
1587 | 1559 |
1588 Handle<Code> CallStubCompiler::CompileArrayCodeCall( | 1560 Handle<Code> CallStubCompiler::CompileArrayCodeCall( |
1589 Handle<Object> object, | 1561 Handle<Object> object, |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1981 | 1953 |
1982 if (index_out_of_range.is_linked()) { | 1954 if (index_out_of_range.is_linked()) { |
1983 __ bind(&index_out_of_range); | 1955 __ bind(&index_out_of_range); |
1984 __ LoadRoot(v0, Heap::kNanValueRootIndex); | 1956 __ LoadRoot(v0, Heap::kNanValueRootIndex); |
1985 __ DropAndRet(argc + 1); | 1957 __ DropAndRet(argc + 1); |
1986 } | 1958 } |
1987 | 1959 |
1988 __ bind(&miss); | 1960 __ bind(&miss); |
1989 // Restore function name in a2. | 1961 // Restore function name in a2. |
1990 __ li(a2, name); | 1962 __ li(a2, name); |
1991 __ bind(&name_miss); | 1963 HandlerFrontendFooter(&name_miss); |
1992 GenerateMissBranch(); | |
1993 | 1964 |
1994 // Return the generated code. | 1965 // Return the generated code. |
1995 return GetCode(type, name); | 1966 return GetCode(type, name); |
1996 } | 1967 } |
1997 | 1968 |
1998 | 1969 |
1999 Handle<Code> CallStubCompiler::CompileStringCharAtCall( | 1970 Handle<Code> CallStubCompiler::CompileStringCharAtCall( |
2000 Handle<Object> object, | 1971 Handle<Object> object, |
2001 Handle<JSObject> holder, | 1972 Handle<JSObject> holder, |
2002 Handle<Cell> cell, | 1973 Handle<Cell> cell, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2046 | 2017 |
2047 if (index_out_of_range.is_linked()) { | 2018 if (index_out_of_range.is_linked()) { |
2048 __ bind(&index_out_of_range); | 2019 __ bind(&index_out_of_range); |
2049 __ LoadRoot(v0, Heap::kempty_stringRootIndex); | 2020 __ LoadRoot(v0, Heap::kempty_stringRootIndex); |
2050 __ DropAndRet(argc + 1); | 2021 __ DropAndRet(argc + 1); |
2051 } | 2022 } |
2052 | 2023 |
2053 __ bind(&miss); | 2024 __ bind(&miss); |
2054 // Restore function name in a2. | 2025 // Restore function name in a2. |
2055 __ li(a2, name); | 2026 __ li(a2, name); |
2056 __ bind(&name_miss); | 2027 HandlerFrontendFooter(&name_miss); |
2057 GenerateMissBranch(); | |
2058 | 2028 |
2059 // Return the generated code. | 2029 // Return the generated code. |
2060 return GetCode(type, name); | 2030 return GetCode(type, name); |
2061 } | 2031 } |
2062 | 2032 |
2063 | 2033 |
2064 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( | 2034 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( |
2065 Handle<Object> object, | 2035 Handle<Object> object, |
2066 Handle<JSObject> holder, | 2036 Handle<JSObject> holder, |
2067 Handle<Cell> cell, | 2037 Handle<Cell> cell, |
(...skipping 25 matching lines...) Expand all Loading... | |
2093 // Convert the smi code to uint16. | 2063 // Convert the smi code to uint16. |
2094 __ And(code, code, Operand(Smi::FromInt(0xffff))); | 2064 __ And(code, code, Operand(Smi::FromInt(0xffff))); |
2095 | 2065 |
2096 StringCharFromCodeGenerator generator(code, v0); | 2066 StringCharFromCodeGenerator generator(code, v0); |
2097 generator.GenerateFast(masm()); | 2067 generator.GenerateFast(masm()); |
2098 __ DropAndRet(argc + 1); | 2068 __ DropAndRet(argc + 1); |
2099 | 2069 |
2100 StubRuntimeCallHelper call_helper; | 2070 StubRuntimeCallHelper call_helper; |
2101 generator.GenerateSlow(masm(), call_helper); | 2071 generator.GenerateSlow(masm(), call_helper); |
2102 | 2072 |
2103 // Tail call the full function. We do not have to patch the receiver | |
2104 // because the function makes no use of it. | |
2105 __ bind(&slow); | 2073 __ bind(&slow); |
2106 ParameterCount expected(function); | 2074 // We do not have to patch the receiver because the function makes no use of |
2107 __ InvokeFunction(function, expected, arguments(), | 2075 // it. |
2108 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2076 GenerateJumpFunctionIgnoreReceiver(function); |
2109 | 2077 |
2110 HandlerFrontendFooter(&miss); | 2078 HandlerFrontendFooter(&miss); |
2111 | 2079 |
2112 // Return the generated code. | 2080 // Return the generated code. |
2113 return GetCode(type, name); | 2081 return GetCode(type, name); |
2114 } | 2082 } |
2115 | 2083 |
2116 | 2084 |
2117 Handle<Code> CallStubCompiler::CompileMathFloorCall( | 2085 Handle<Code> CallStubCompiler::CompileMathFloorCall( |
2118 Handle<Object> object, | 2086 Handle<Object> object, |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2204 // Restore FCSR and return. | 2172 // Restore FCSR and return. |
2205 __ ctc1(a3, FCSR); | 2173 __ ctc1(a3, FCSR); |
2206 | 2174 |
2207 __ DropAndRet(argc + 1); | 2175 __ DropAndRet(argc + 1); |
2208 | 2176 |
2209 __ bind(&wont_fit_smi); | 2177 __ bind(&wont_fit_smi); |
2210 // Restore FCSR and fall to slow case. | 2178 // Restore FCSR and fall to slow case. |
2211 __ ctc1(a3, FCSR); | 2179 __ ctc1(a3, FCSR); |
2212 | 2180 |
2213 __ bind(&slow); | 2181 __ bind(&slow); |
2214 // Tail call the full function. We do not have to patch the receiver | 2182 // We do not have to patch the receiver because the function makes no use of |
2215 // because the function makes no use of it. | 2183 // it. |
2216 ParameterCount expected(function); | 2184 GenerateJumpFunctionIgnoreReceiver(function); |
2217 __ InvokeFunction(function, expected, arguments(), | |
2218 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | |
2219 | 2185 |
2220 HandlerFrontendFooter(&miss); | 2186 HandlerFrontendFooter(&miss); |
2221 | 2187 |
2222 // Return the generated code. | 2188 // Return the generated code. |
2223 return GetCode(type, name); | 2189 return GetCode(type, name); |
2224 } | 2190 } |
2225 | 2191 |
2226 | 2192 |
2227 Handle<Code> CallStubCompiler::CompileMathAbsCall( | 2193 Handle<Code> CallStubCompiler::CompileMathAbsCall( |
2228 Handle<Object> object, | 2194 Handle<Object> object, |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2285 // number. | 2251 // number. |
2286 __ bind(&negative_sign); | 2252 __ bind(&negative_sign); |
2287 __ Xor(a1, a1, Operand(HeapNumber::kSignMask)); | 2253 __ Xor(a1, a1, Operand(HeapNumber::kSignMask)); |
2288 __ lw(a3, FieldMemOperand(v0, HeapNumber::kMantissaOffset)); | 2254 __ lw(a3, FieldMemOperand(v0, HeapNumber::kMantissaOffset)); |
2289 __ LoadRoot(t2, Heap::kHeapNumberMapRootIndex); | 2255 __ LoadRoot(t2, Heap::kHeapNumberMapRootIndex); |
2290 __ AllocateHeapNumber(v0, t0, t1, t2, &slow); | 2256 __ AllocateHeapNumber(v0, t0, t1, t2, &slow); |
2291 __ sw(a1, FieldMemOperand(v0, HeapNumber::kExponentOffset)); | 2257 __ sw(a1, FieldMemOperand(v0, HeapNumber::kExponentOffset)); |
2292 __ sw(a3, FieldMemOperand(v0, HeapNumber::kMantissaOffset)); | 2258 __ sw(a3, FieldMemOperand(v0, HeapNumber::kMantissaOffset)); |
2293 __ DropAndRet(argc + 1); | 2259 __ DropAndRet(argc + 1); |
2294 | 2260 |
2295 // Tail call the full function. We do not have to patch the receiver | |
2296 // because the function makes no use of it. | |
2297 __ bind(&slow); | 2261 __ bind(&slow); |
2298 ParameterCount expected(function); | 2262 // We do not have to patch the receiver because the function makes no use of |
2299 __ InvokeFunction(function, expected, arguments(), | 2263 // it. |
2300 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2264 GenerateJumpFunctionIgnoreReceiver(function); |
2301 | 2265 |
2302 HandlerFrontendFooter(&miss); | 2266 HandlerFrontendFooter(&miss); |
2303 | 2267 |
2304 // Return the generated code. | 2268 // Return the generated code. |
2305 return GetCode(type, name); | 2269 return GetCode(type, name); |
2306 } | 2270 } |
2307 | 2271 |
2308 | 2272 |
2309 Handle<Code> CallStubCompiler::CompileFastApiCall( | 2273 Handle<Code> CallStubCompiler::CompileFastApiCall( |
2310 const CallOptimization& optimization, | 2274 const CallOptimization& optimization, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2345 // Check that the maps haven't changed and find a Holder as a side effect. | 2309 // Check that the maps haven't changed and find a Holder as a side effect. |
2346 CheckPrototypes( | 2310 CheckPrototypes( |
2347 IC::CurrentTypeOf(object, isolate()), | 2311 IC::CurrentTypeOf(object, isolate()), |
2348 a1, holder, a0, a3, t0, name, depth, &miss); | 2312 a1, holder, a0, a3, t0, name, depth, &miss); |
2349 | 2313 |
2350 GenerateFastApiDirectCall(masm(), optimization, argc, false); | 2314 GenerateFastApiDirectCall(masm(), optimization, argc, false); |
2351 | 2315 |
2352 __ bind(&miss); | 2316 __ bind(&miss); |
2353 FreeSpaceForFastApiCall(masm()); | 2317 FreeSpaceForFastApiCall(masm()); |
2354 | 2318 |
2355 __ bind(&miss_before_stack_reserved); | 2319 HandlerFrontendFooter(&miss_before_stack_reserved); |
2356 GenerateMissBranch(); | |
2357 | 2320 |
2358 // Return the generated code. | 2321 // Return the generated code. |
2359 return GetCode(function); | 2322 return GetCode(function); |
2360 } | 2323 } |
2361 | 2324 |
2362 | 2325 |
2363 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { | 2326 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { |
2364 Label success; | 2327 Label success; |
2365 // Check that the object is a boolean. | 2328 // Check that the object is a boolean. |
2366 __ LoadRoot(at, Heap::kTrueValueRootIndex); | 2329 __ LoadRoot(at, Heap::kTrueValueRootIndex); |
2367 __ Branch(&success, eq, object, Operand(at)); | 2330 __ Branch(&success, eq, object, Operand(at)); |
2368 __ LoadRoot(at, Heap::kFalseValueRootIndex); | 2331 __ LoadRoot(at, Heap::kFalseValueRootIndex); |
2369 __ Branch(miss, ne, object, Operand(at)); | 2332 __ Branch(miss, ne, object, Operand(at)); |
2370 __ bind(&success); | 2333 __ bind(&success); |
2371 } | 2334 } |
2372 | 2335 |
2373 | 2336 |
2374 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) { | 2337 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) { |
2375 if (object->IsGlobalObject()) { | 2338 if (!object.is_null() && object->IsGlobalObject()) { |
2376 const int argc = arguments().immediate(); | 2339 const int argc = arguments().immediate(); |
2377 const int receiver_offset = argc * kPointerSize; | 2340 const int receiver_offset = argc * kPointerSize; |
2378 __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset)); | 2341 __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset)); |
2379 __ sw(a3, MemOperand(sp, receiver_offset)); | 2342 __ sw(a3, MemOperand(sp, receiver_offset)); |
2380 } | 2343 } |
2381 } | 2344 } |
2382 | 2345 |
2383 | 2346 |
2384 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object, | 2347 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object, |
2385 Handle<JSObject> holder, | 2348 Handle<JSObject> holder, |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2461 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); | 2424 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
2462 reg = CheckPrototypes( | 2425 reg = CheckPrototypes( |
2463 IC::CurrentTypeOf(prototype, isolate()), | 2426 IC::CurrentTypeOf(prototype, isolate()), |
2464 a1, holder, a1, a3, t0, name, miss); | 2427 a1, holder, a1, a3, t0, name, miss); |
2465 } | 2428 } |
2466 | 2429 |
2467 return reg; | 2430 return reg; |
2468 } | 2431 } |
2469 | 2432 |
2470 | 2433 |
2471 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { | 2434 void CallStubCompiler::GenerateJumpFunction(Handle<Object> object, |
2472 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2435 Register function, |
2473 ? CALL_AS_FUNCTION | 2436 Label* miss) { |
2474 : CALL_AS_METHOD; | 2437 ASSERT(function.is(a1)); |
2475 ParameterCount expected(function); | 2438 // Check that the function really is a function. |
2476 __ InvokeFunction(function, expected, arguments(), | 2439 GenerateFunctionCheck(function, a3, miss); |
2477 JUMP_FUNCTION, NullCallWrapper(), call_kind); | 2440 if (!function.is(a1)) __ mov(a1, function); |
2441 PatchGlobalProxy(object); | |
2442 // Invoke the function. | |
2443 __ InvokeFunction(a1, arguments(), JUMP_FUNCTION, | |
2444 NullCallWrapper(), call_kind()); | |
2478 } | 2445 } |
2479 | 2446 |
2480 | 2447 |
2481 Handle<Code> CallStubCompiler::CompileCallConstant( | |
2482 Handle<Object> object, | |
2483 Handle<JSObject> holder, | |
2484 Handle<Name> name, | |
2485 CheckType check, | |
2486 Handle<JSFunction> function) { | |
2487 if (HasCustomCallGenerator(function)) { | |
2488 Handle<Code> code = CompileCustomCall(object, holder, | |
2489 Handle<Cell>::null(), | |
2490 function, Handle<String>::cast(name), | |
2491 Code::FAST); | |
2492 // A null handle means bail out to the regular compiler code below. | |
2493 if (!code.is_null()) return code; | |
2494 } | |
2495 | |
2496 Label miss; | |
2497 HandlerFrontendHeader(object, holder, name, check, &miss); | |
2498 PatchGlobalProxy(object); | |
2499 CompileHandlerBackend(function); | |
2500 HandlerFrontendFooter(&miss); | |
2501 | |
2502 // Return the generated code. | |
2503 return GetCode(function); | |
2504 } | |
2505 | |
2506 | |
2507 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, | 2448 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, |
2508 Handle<JSObject> holder, | 2449 Handle<JSObject> holder, |
2509 Handle<Name> name) { | 2450 Handle<Name> name) { |
2510 Label miss; | 2451 Label miss; |
2511 | 2452 |
2512 GenerateNameCheck(name, &miss); | 2453 GenerateNameCheck(name, &miss); |
2513 | 2454 |
2514 // Get the number of arguments. | 2455 // Get the number of arguments. |
2515 const int argc = arguments().immediate(); | 2456 const int argc = arguments().immediate(); |
2516 LookupResult lookup(isolate()); | 2457 LookupResult lookup(isolate()); |
2517 LookupPostInterceptor(holder, name, &lookup); | 2458 LookupPostInterceptor(holder, name, &lookup); |
2518 | 2459 |
2519 // Get the receiver from the stack. | 2460 // Get the receiver from the stack. |
2520 __ lw(a1, MemOperand(sp, argc * kPointerSize)); | 2461 __ lw(a1, MemOperand(sp, argc * kPointerSize)); |
2521 | 2462 |
2522 CallInterceptorCompiler compiler(this, arguments(), a2, extra_state_); | 2463 CallInterceptorCompiler compiler(this, arguments(), a2, extra_state_); |
2523 compiler.Compile(masm(), object, holder, name, &lookup, a1, a3, t0, a0, | 2464 compiler.Compile(masm(), object, holder, name, &lookup, a1, a3, t0, a0, |
2524 &miss); | 2465 &miss); |
2525 | 2466 |
2526 // Move returned value, the function to call, to a1. | 2467 // Move returned value, the function to call, to a1. |
2527 __ mov(a1, v0); | 2468 __ mov(a1, v0); |
2528 // Restore receiver. | 2469 // Restore receiver. |
2529 __ lw(a0, MemOperand(sp, argc * kPointerSize)); | 2470 __ lw(a0, MemOperand(sp, argc * kPointerSize)); |
2530 | 2471 |
2531 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | 2472 GenerateJumpFunction(object, a1, &miss); |
2532 | 2473 |
2533 // Handle call cache miss. | 2474 HandlerFrontendFooter(&miss); |
2534 __ bind(&miss); | |
2535 GenerateMissBranch(); | |
2536 | 2475 |
2537 // Return the generated code. | 2476 // Return the generated code. |
2538 return GetCode(Code::FAST, name); | 2477 return GetCode(Code::FAST, name); |
2539 } | 2478 } |
2540 | 2479 |
2541 | 2480 |
2542 Handle<Code> CallStubCompiler::CompileCallGlobal( | 2481 Handle<Code> CallStubCompiler::CompileCallGlobal( |
2543 Handle<JSObject> object, | 2482 Handle<JSObject> object, |
2544 Handle<GlobalObject> holder, | 2483 Handle<GlobalObject> holder, |
2545 Handle<PropertyCell> cell, | 2484 Handle<PropertyCell> cell, |
2546 Handle<JSFunction> function, | 2485 Handle<JSFunction> function, |
2547 Handle<Name> name) { | 2486 Handle<Name> name) { |
2548 if (HasCustomCallGenerator(function)) { | 2487 if (HasCustomCallGenerator(function)) { |
2549 Handle<Code> code = CompileCustomCall( | 2488 Handle<Code> code = CompileCustomCall( |
2550 object, holder, cell, function, Handle<String>::cast(name), | 2489 object, holder, cell, function, Handle<String>::cast(name), |
2551 Code::NORMAL); | 2490 Code::NORMAL); |
2552 // A null handle means bail out to the regular compiler code below. | 2491 // A null handle means bail out to the regular compiler code below. |
2553 if (!code.is_null()) return code; | 2492 if (!code.is_null()) return code; |
2554 } | 2493 } |
2555 | 2494 |
2556 Label miss; | 2495 Label miss; |
2557 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); | 2496 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); |
2497 // Potentially loads a closure that matches the shared function info of the | |
2498 // function, rather than function. | |
2558 GenerateLoadFunctionFromCell(cell, function, &miss); | 2499 GenerateLoadFunctionFromCell(cell, function, &miss); |
2559 PatchGlobalProxy(object); | |
2560 | |
2561 // Set up the context (function already in r1). | |
2562 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | |
2563 | |
2564 // Jump to the cached code (tail call). | |
2565 Counters* counters = isolate()->counters(); | 2500 Counters* counters = isolate()->counters(); |
2566 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); | 2501 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); |
2567 ParameterCount expected(function->shared()->formal_parameter_count()); | 2502 GenerateJumpFunction(object, a1, function); |
2568 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | |
2569 ? CALL_AS_FUNCTION | |
2570 : CALL_AS_METHOD; | |
2571 // We call indirectly through the code field in the function to | |
2572 // allow recompilation to take effect without changing any of the | |
2573 // call sites. | |
2574 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | |
2575 __ InvokeCode(a3, expected, arguments(), JUMP_FUNCTION, | |
2576 NullCallWrapper(), call_kind); | |
2577 | |
2578 HandlerFrontendFooter(&miss); | 2503 HandlerFrontendFooter(&miss); |
2579 | 2504 |
2580 // Return the generated code. | 2505 // Return the generated code. |
2581 return GetCode(Code::NORMAL, name); | 2506 return GetCode(Code::NORMAL, name); |
2582 } | 2507 } |
2583 | 2508 |
2584 | 2509 |
2585 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2510 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
2586 Handle<JSObject> object, | 2511 Handle<JSObject> object, |
2587 Handle<JSObject> holder, | 2512 Handle<JSObject> holder, |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2957 // ----------------------------------- | 2882 // ----------------------------------- |
2958 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 2883 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
2959 } | 2884 } |
2960 | 2885 |
2961 | 2886 |
2962 #undef __ | 2887 #undef __ |
2963 | 2888 |
2964 } } // namespace v8::internal | 2889 } } // namespace v8::internal |
2965 | 2890 |
2966 #endif // V8_TARGET_ARCH_MIPS | 2891 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |