| 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_->GenerateJumpFunctionIgnoreReceiver(function); |
| 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); |
| (...skipping 94 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 PatchGlobalProxy(object); |
| 2441 // Invoke the function. |
| 2442 __ InvokeFunction(a1, arguments(), JUMP_FUNCTION, |
| 2443 NullCallWrapper(), call_kind()); |
| 2478 } | 2444 } |
| 2479 | 2445 |
| 2480 | 2446 |
| 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, | 2447 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, |
| 2508 Handle<JSObject> holder, | 2448 Handle<JSObject> holder, |
| 2509 Handle<Name> name) { | 2449 Handle<Name> name) { |
| 2510 Label miss; | 2450 Label miss; |
| 2511 | 2451 |
| 2512 GenerateNameCheck(name, &miss); | 2452 GenerateNameCheck(name, &miss); |
| 2513 | 2453 |
| 2514 // Get the number of arguments. | 2454 // Get the number of arguments. |
| 2515 const int argc = arguments().immediate(); | 2455 const int argc = arguments().immediate(); |
| 2516 LookupResult lookup(isolate()); | 2456 LookupResult lookup(isolate()); |
| 2517 LookupPostInterceptor(holder, name, &lookup); | 2457 LookupPostInterceptor(holder, name, &lookup); |
| 2518 | 2458 |
| 2519 // Get the receiver from the stack. | 2459 // Get the receiver from the stack. |
| 2520 __ lw(a1, MemOperand(sp, argc * kPointerSize)); | 2460 __ lw(a1, MemOperand(sp, argc * kPointerSize)); |
| 2521 | 2461 |
| 2522 CallInterceptorCompiler compiler(this, arguments(), a2, extra_state_); | 2462 CallInterceptorCompiler compiler(this, arguments(), a2, extra_state_); |
| 2523 compiler.Compile(masm(), object, holder, name, &lookup, a1, a3, t0, a0, | 2463 compiler.Compile(masm(), object, holder, name, &lookup, a1, a3, t0, a0, |
| 2524 &miss); | 2464 &miss); |
| 2525 | 2465 |
| 2526 // Move returned value, the function to call, to a1. | 2466 // Move returned value, the function to call, to a1. |
| 2527 __ mov(a1, v0); | 2467 __ mov(a1, v0); |
| 2528 // Restore receiver. | 2468 // Restore receiver. |
| 2529 __ lw(a0, MemOperand(sp, argc * kPointerSize)); | 2469 __ lw(a0, MemOperand(sp, argc * kPointerSize)); |
| 2530 | 2470 |
| 2531 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | 2471 GenerateJumpFunction(object, a1, &miss); |
| 2532 | 2472 |
| 2533 // Handle call cache miss. | 2473 HandlerFrontendFooter(&miss); |
| 2534 __ bind(&miss); | |
| 2535 GenerateMissBranch(); | |
| 2536 | 2474 |
| 2537 // Return the generated code. | 2475 // Return the generated code. |
| 2538 return GetCode(Code::FAST, name); | 2476 return GetCode(Code::FAST, name); |
| 2539 } | 2477 } |
| 2540 | 2478 |
| 2541 | 2479 |
| 2542 Handle<Code> CallStubCompiler::CompileCallGlobal( | 2480 Handle<Code> CallStubCompiler::CompileCallGlobal( |
| 2543 Handle<JSObject> object, | 2481 Handle<JSObject> object, |
| 2544 Handle<GlobalObject> holder, | 2482 Handle<GlobalObject> holder, |
| 2545 Handle<PropertyCell> cell, | 2483 Handle<PropertyCell> cell, |
| 2546 Handle<JSFunction> function, | 2484 Handle<JSFunction> function, |
| 2547 Handle<Name> name) { | 2485 Handle<Name> name) { |
| 2548 if (HasCustomCallGenerator(function)) { | 2486 if (HasCustomCallGenerator(function)) { |
| 2549 Handle<Code> code = CompileCustomCall( | 2487 Handle<Code> code = CompileCustomCall( |
| 2550 object, holder, cell, function, Handle<String>::cast(name), | 2488 object, holder, cell, function, Handle<String>::cast(name), |
| 2551 Code::NORMAL); | 2489 Code::NORMAL); |
| 2552 // A null handle means bail out to the regular compiler code below. | 2490 // A null handle means bail out to the regular compiler code below. |
| 2553 if (!code.is_null()) return code; | 2491 if (!code.is_null()) return code; |
| 2554 } | 2492 } |
| 2555 | 2493 |
| 2556 Label miss; | 2494 Label miss; |
| 2557 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); | 2495 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); |
| 2496 // Potentially loads a closure that matches the shared function info of the |
| 2497 // function, rather than function. |
| 2558 GenerateLoadFunctionFromCell(cell, function, &miss); | 2498 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(); | 2499 Counters* counters = isolate()->counters(); |
| 2566 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); | 2500 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); |
| 2567 ParameterCount expected(function->shared()->formal_parameter_count()); | 2501 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); | 2502 HandlerFrontendFooter(&miss); |
| 2579 | 2503 |
| 2580 // Return the generated code. | 2504 // Return the generated code. |
| 2581 return GetCode(Code::NORMAL, name); | 2505 return GetCode(Code::NORMAL, name); |
| 2582 } | 2506 } |
| 2583 | 2507 |
| 2584 | 2508 |
| 2585 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2509 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
| 2586 Handle<JSObject> object, | 2510 Handle<JSObject> object, |
| 2587 Handle<JSObject> holder, | 2511 Handle<JSObject> holder, |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2957 // ----------------------------------- | 2881 // ----------------------------------- |
| 2958 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 2882 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
| 2959 } | 2883 } |
| 2960 | 2884 |
| 2961 | 2885 |
| 2962 #undef __ | 2886 #undef __ |
| 2963 | 2887 |
| 2964 } } // namespace v8::internal | 2888 } } // namespace v8::internal |
| 2965 | 2889 |
| 2966 #endif // V8_TARGET_ARCH_MIPS | 2890 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |