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