Chromium Code Reviews| 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 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 735 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, | 735 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, |
| 736 Label* label, | 736 Label* label, |
| 737 Handle<Name> name) { | 737 Handle<Name> name) { |
| 738 if (!label->is_unused()) { | 738 if (!label->is_unused()) { |
| 739 __ bind(label); | 739 __ bind(label); |
| 740 __ mov(this->name(), Operand(name)); | 740 __ mov(this->name(), Operand(name)); |
| 741 } | 741 } |
| 742 } | 742 } |
| 743 | 743 |
| 744 | 744 |
| 745 static void GenerateCallFunction(MacroAssembler* masm, | |
| 746 Handle<Object> object, | |
| 747 const ParameterCount& arguments, | |
| 748 Label* miss, | |
| 749 Code::ExtraICState extra_ic_state) { | |
| 750 // ----------- S t a t e ------------- | |
| 751 // -- r0: receiver | |
| 752 // -- r1: function to call | |
| 753 // ----------------------------------- | |
| 754 | |
| 755 // Check that the function really is a function. | |
| 756 __ JumpIfSmi(r1, miss); | |
| 757 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE); | |
| 758 __ b(ne, miss); | |
| 759 | |
| 760 if (object->IsGlobalObject()) { | |
| 761 const int argc = arguments.immediate(); | |
| 762 const int receiver_offset = argc * kPointerSize; | |
| 763 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); | |
| 764 __ str(r3, MemOperand(sp, receiver_offset)); | |
| 765 } | |
| 766 | |
| 767 // Invoke the function. | |
| 768 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state) | |
| 769 ? CALL_AS_FUNCTION | |
| 770 : CALL_AS_METHOD; | |
| 771 __ InvokeFunction(r1, arguments, JUMP_FUNCTION, NullCallWrapper(), call_kind); | |
| 772 } | |
| 773 | |
| 774 | |
| 775 static void PushInterceptorArguments(MacroAssembler* masm, | 745 static void PushInterceptorArguments(MacroAssembler* masm, |
| 776 Register receiver, | 746 Register receiver, |
| 777 Register holder, | 747 Register holder, |
| 778 Register name, | 748 Register name, |
| 779 Handle<JSObject> holder_obj) { | 749 Handle<JSObject> holder_obj) { |
| 780 STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0); | 750 STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0); |
| 781 STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1); | 751 STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1); |
| 782 STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2); | 752 STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2); |
| 783 STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3); | 753 STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3); |
| 784 STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4); | 754 STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4); |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 953 ASSERT(!scratch.is(values[i])); | 923 ASSERT(!scratch.is(values[i])); |
| 954 __ str(receiver, MemOperand(sp, index-- * kPointerSize)); | 924 __ str(receiver, MemOperand(sp, index-- * kPointerSize)); |
| 955 } | 925 } |
| 956 | 926 |
| 957 GenerateFastApiDirectCall(masm, optimization, argc, true); | 927 GenerateFastApiDirectCall(masm, optimization, argc, true); |
| 958 } | 928 } |
| 959 | 929 |
| 960 | 930 |
| 961 class CallInterceptorCompiler BASE_EMBEDDED { | 931 class CallInterceptorCompiler BASE_EMBEDDED { |
| 962 public: | 932 public: |
| 963 CallInterceptorCompiler(StubCompiler* stub_compiler, | 933 CallInterceptorCompiler(CallStubCompiler* stub_compiler, |
| 964 const ParameterCount& arguments, | 934 const ParameterCount& arguments, |
| 965 Register name, | 935 Register name, |
| 966 Code::ExtraICState extra_ic_state) | 936 Code::ExtraICState extra_ic_state) |
| 967 : stub_compiler_(stub_compiler), | 937 : stub_compiler_(stub_compiler), |
| 968 arguments_(arguments), | 938 arguments_(arguments), |
| 969 name_(name), | 939 name_(name), |
| 970 extra_ic_state_(extra_ic_state) {} | 940 extra_ic_state_(extra_ic_state) {} |
| 971 | 941 |
| 972 void Compile(MacroAssembler* masm, | 942 void Compile(MacroAssembler* masm, |
| 973 Handle<JSObject> object, | 943 Handle<JSObject> object, |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1065 // safe to omit it here, as if present, it should be fetched | 1035 // safe to omit it here, as if present, it should be fetched |
| 1066 // by the previous CheckPrototypes. | 1036 // by the previous CheckPrototypes. |
| 1067 ASSERT(depth2 == kInvalidProtoDepth); | 1037 ASSERT(depth2 == kInvalidProtoDepth); |
| 1068 } | 1038 } |
| 1069 | 1039 |
| 1070 // Invoke function. | 1040 // Invoke function. |
| 1071 if (can_do_fast_api_call) { | 1041 if (can_do_fast_api_call) { |
| 1072 GenerateFastApiDirectCall( | 1042 GenerateFastApiDirectCall( |
| 1073 masm, optimization, arguments_.immediate(), false); | 1043 masm, optimization, arguments_.immediate(), false); |
| 1074 } else { | 1044 } else { |
| 1075 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | |
| 1076 ? CALL_AS_FUNCTION | |
| 1077 : CALL_AS_METHOD; | |
| 1078 Handle<JSFunction> function = optimization.constant_function(); | 1045 Handle<JSFunction> function = optimization.constant_function(); |
| 1079 ParameterCount expected(function); | 1046 stub_compiler_->GenerateCallFunction(object, function); |
| 1080 __ InvokeFunction(function, expected, arguments_, | |
| 1081 JUMP_FUNCTION, NullCallWrapper(), call_kind); | |
| 1082 } | 1047 } |
| 1083 | 1048 |
| 1084 // Deferred code for fast API call case---clean preallocated space. | 1049 // Deferred code for fast API call case---clean preallocated space. |
| 1085 if (can_do_fast_api_call) { | 1050 if (can_do_fast_api_call) { |
| 1086 __ bind(&miss_cleanup); | 1051 __ bind(&miss_cleanup); |
| 1087 FreeSpaceForFastApiCall(masm); | 1052 FreeSpaceForFastApiCall(masm); |
| 1088 __ b(miss_label); | 1053 __ b(miss_label); |
| 1089 } | 1054 } |
| 1090 | 1055 |
| 1091 // Invoke a regular function. | 1056 // Invoke a regular function. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1139 holder_obj); | 1104 holder_obj); |
| 1140 __ pop(name_); // Restore the name. | 1105 __ pop(name_); // Restore the name. |
| 1141 __ pop(receiver); // Restore the holder. | 1106 __ pop(receiver); // Restore the holder. |
| 1142 } | 1107 } |
| 1143 // If interceptor returns no-result sentinel, call the constant function. | 1108 // If interceptor returns no-result sentinel, call the constant function. |
| 1144 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex); | 1109 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex); |
| 1145 __ cmp(r0, scratch); | 1110 __ cmp(r0, scratch); |
| 1146 __ b(ne, interceptor_succeeded); | 1111 __ b(ne, interceptor_succeeded); |
| 1147 } | 1112 } |
| 1148 | 1113 |
| 1149 StubCompiler* stub_compiler_; | 1114 CallStubCompiler* stub_compiler_; |
| 1150 const ParameterCount& arguments_; | 1115 const ParameterCount& arguments_; |
| 1151 Register name_; | 1116 Register name_; |
| 1152 Code::ExtraICState extra_ic_state_; | 1117 Code::ExtraICState extra_ic_state_; |
| 1153 }; | 1118 }; |
| 1154 | 1119 |
| 1155 | 1120 |
| 1156 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { | 1121 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { |
| 1157 __ Jump(code, RelocInfo::CODE_TARGET); | 1122 __ Jump(code, RelocInfo::CODE_TARGET); |
| 1158 } | 1123 } |
| 1159 | 1124 |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1542 | 1507 |
| 1543 | 1508 |
| 1544 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { | 1509 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { |
| 1545 if (kind_ == Code::KEYED_CALL_IC) { | 1510 if (kind_ == Code::KEYED_CALL_IC) { |
| 1546 __ cmp(r2, Operand(name)); | 1511 __ cmp(r2, Operand(name)); |
| 1547 __ b(ne, miss); | 1512 __ b(ne, miss); |
| 1548 } | 1513 } |
| 1549 } | 1514 } |
| 1550 | 1515 |
| 1551 | 1516 |
| 1517 void CallStubCompiler::GenerateFunctionCheck(Register function, | |
| 1518 Register scratch, | |
| 1519 Label* miss) { | |
| 1520 __ JumpIfSmi(function, miss); | |
| 1521 __ CompareObjectType(function, scratch, scratch, JS_FUNCTION_TYPE); | |
| 1522 __ b(ne, miss); | |
| 1523 } | |
| 1524 | |
| 1525 | |
| 1552 void CallStubCompiler::GenerateLoadFunctionFromCell( | 1526 void CallStubCompiler::GenerateLoadFunctionFromCell( |
| 1553 Handle<Cell> cell, | 1527 Handle<Cell> cell, |
| 1554 Handle<JSFunction> function, | 1528 Handle<JSFunction> function, |
| 1555 Label* miss) { | 1529 Label* miss) { |
| 1556 // Get the value from the cell. | 1530 // Get the value from the cell. |
| 1557 __ mov(r3, Operand(cell)); | 1531 __ mov(r3, Operand(cell)); |
| 1558 __ ldr(r1, FieldMemOperand(r3, Cell::kValueOffset)); | 1532 __ ldr(r1, FieldMemOperand(r3, Cell::kValueOffset)); |
| 1559 | 1533 |
| 1560 // Check that the cell contains the same function. | 1534 // Check that the cell contains the same function. |
| 1561 if (heap()->InNewSpace(*function)) { | 1535 if (heap()->InNewSpace(*function)) { |
| 1562 // We can't embed a pointer to a function in new space so we have | 1536 // We can't embed a pointer to a function in new space so we have |
| 1563 // to verify that the shared function info is unchanged. This has | 1537 // to verify that the shared function info is unchanged. This has |
| 1564 // the nice side effect that multiple closures based on the same | 1538 // the nice side effect that multiple closures based on the same |
| 1565 // function can all use this call IC. Before we load through the | 1539 // function can all use this call IC. Before we load through the |
| 1566 // function, we have to verify that it still is a function. | 1540 // function, we have to verify that it still is a function. |
| 1567 __ JumpIfSmi(r1, miss); | 1541 GenerateFunctionCheck(r1, r3, miss); |
| 1568 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE); | |
| 1569 __ b(ne, miss); | |
| 1570 | 1542 |
| 1571 // Check the shared function info. Make sure it hasn't changed. | 1543 // Check the shared function info. Make sure it hasn't changed. |
| 1572 __ Move(r3, Handle<SharedFunctionInfo>(function->shared())); | 1544 __ Move(r3, Handle<SharedFunctionInfo>(function->shared())); |
| 1573 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 1545 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
| 1574 __ cmp(r4, r3); | 1546 __ cmp(r4, r3); |
| 1575 } else { | 1547 } else { |
| 1576 __ cmp(r1, Operand(function)); | 1548 __ cmp(r1, Operand(function)); |
| 1577 } | 1549 } |
| 1578 __ b(ne, miss); | 1550 __ b(ne, miss); |
| 1579 } | 1551 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1591 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, | 1563 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, |
| 1592 Handle<JSObject> holder, | 1564 Handle<JSObject> holder, |
| 1593 PropertyIndex index, | 1565 PropertyIndex index, |
| 1594 Handle<Name> name) { | 1566 Handle<Name> name) { |
| 1595 Label miss; | 1567 Label miss; |
| 1596 | 1568 |
| 1597 Register reg = HandlerFrontendHeader( | 1569 Register reg = HandlerFrontendHeader( |
| 1598 object, holder, name, RECEIVER_MAP_CHECK, &miss); | 1570 object, holder, name, RECEIVER_MAP_CHECK, &miss); |
| 1599 GenerateFastPropertyLoad(masm(), r1, reg, index.is_inobject(holder), | 1571 GenerateFastPropertyLoad(masm(), r1, reg, index.is_inobject(holder), |
| 1600 index.translate(holder), Representation::Tagged()); | 1572 index.translate(holder), Representation::Tagged()); |
| 1601 | 1573 GenerateCallFunction(object, r1, &miss); |
| 1602 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | |
| 1603 | 1574 |
| 1604 HandlerFrontendFooter(&miss); | 1575 HandlerFrontendFooter(&miss); |
| 1605 | 1576 |
| 1606 // Return the generated code. | 1577 // Return the generated code. |
| 1607 return GetCode(Code::FAST, name); | 1578 return GetCode(Code::FAST, name); |
| 1608 } | 1579 } |
| 1609 | 1580 |
| 1610 | 1581 |
| 1611 Handle<Code> CallStubCompiler::CompileArrayCodeCall( | 1582 Handle<Code> CallStubCompiler::CompileArrayCodeCall( |
| 1612 Handle<Object> object, | 1583 Handle<Object> object, |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2007 if (index_out_of_range.is_linked()) { | 1978 if (index_out_of_range.is_linked()) { |
| 2008 __ bind(&index_out_of_range); | 1979 __ bind(&index_out_of_range); |
| 2009 __ LoadRoot(r0, Heap::kNanValueRootIndex); | 1980 __ LoadRoot(r0, Heap::kNanValueRootIndex); |
| 2010 __ Drop(argc + 1); | 1981 __ Drop(argc + 1); |
| 2011 __ Ret(); | 1982 __ Ret(); |
| 2012 } | 1983 } |
| 2013 | 1984 |
| 2014 __ bind(&miss); | 1985 __ bind(&miss); |
| 2015 // Restore function name in r2. | 1986 // Restore function name in r2. |
| 2016 __ Move(r2, name); | 1987 __ Move(r2, name); |
| 2017 __ bind(&name_miss); | 1988 HandlerFrontendFooter(&name_miss); |
| 2018 GenerateMissBranch(); | |
| 2019 | 1989 |
| 2020 // Return the generated code. | 1990 // Return the generated code. |
| 2021 return GetCode(type, name); | 1991 return GetCode(type, name); |
| 2022 } | 1992 } |
| 2023 | 1993 |
| 2024 | 1994 |
| 2025 Handle<Code> CallStubCompiler::CompileStringCharAtCall( | 1995 Handle<Code> CallStubCompiler::CompileStringCharAtCall( |
| 2026 Handle<Object> object, | 1996 Handle<Object> object, |
| 2027 Handle<JSObject> holder, | 1997 Handle<JSObject> holder, |
| 2028 Handle<Cell> cell, | 1998 Handle<Cell> cell, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2074 if (index_out_of_range.is_linked()) { | 2044 if (index_out_of_range.is_linked()) { |
| 2075 __ bind(&index_out_of_range); | 2045 __ bind(&index_out_of_range); |
| 2076 __ LoadRoot(r0, Heap::kempty_stringRootIndex); | 2046 __ LoadRoot(r0, Heap::kempty_stringRootIndex); |
| 2077 __ Drop(argc + 1); | 2047 __ Drop(argc + 1); |
| 2078 __ Ret(); | 2048 __ Ret(); |
| 2079 } | 2049 } |
| 2080 | 2050 |
| 2081 __ bind(&miss); | 2051 __ bind(&miss); |
| 2082 // Restore function name in r2. | 2052 // Restore function name in r2. |
| 2083 __ Move(r2, name); | 2053 __ Move(r2, name); |
| 2084 __ bind(&name_miss); | 2054 HandlerFrontendFooter(&name_miss); |
| 2085 GenerateMissBranch(); | |
| 2086 | 2055 |
| 2087 // Return the generated code. | 2056 // Return the generated code. |
| 2088 return GetCode(type, name); | 2057 return GetCode(type, name); |
| 2089 } | 2058 } |
| 2090 | 2059 |
| 2091 | 2060 |
| 2092 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( | 2061 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( |
| 2093 Handle<Object> object, | 2062 Handle<Object> object, |
| 2094 Handle<JSObject> holder, | 2063 Handle<JSObject> holder, |
| 2095 Handle<Cell> cell, | 2064 Handle<Cell> cell, |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 2122 __ and_(code, code, Operand(Smi::FromInt(0xffff))); | 2091 __ and_(code, code, Operand(Smi::FromInt(0xffff))); |
| 2123 | 2092 |
| 2124 StringCharFromCodeGenerator generator(code, r0); | 2093 StringCharFromCodeGenerator generator(code, r0); |
| 2125 generator.GenerateFast(masm()); | 2094 generator.GenerateFast(masm()); |
| 2126 __ Drop(argc + 1); | 2095 __ Drop(argc + 1); |
| 2127 __ Ret(); | 2096 __ Ret(); |
| 2128 | 2097 |
| 2129 StubRuntimeCallHelper call_helper; | 2098 StubRuntimeCallHelper call_helper; |
| 2130 generator.GenerateSlow(masm(), call_helper); | 2099 generator.GenerateSlow(masm(), call_helper); |
| 2131 | 2100 |
| 2132 // Tail call the full function. We do not have to patch the receiver | |
| 2133 // because the function makes no use of it. | |
| 2134 __ bind(&slow); | 2101 __ bind(&slow); |
| 2135 ParameterCount expected(function); | 2102 // We do not have to patch the receiver because the function makes no use of |
| 2136 __ InvokeFunction(function, expected, arguments(), | 2103 // it. |
| 2137 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2104 GenerateCallFunction(Handle<Object>::null(), function); |
|
Igor Sheludko
2013/11/28 13:06:08
Consider introducing different function for such a
Toon Verwaest
2013/11/28 15:24:09
Done.
| |
| 2138 | 2105 |
| 2139 HandlerFrontendFooter(&miss); | 2106 HandlerFrontendFooter(&miss); |
| 2140 | 2107 |
| 2141 // Return the generated code. | 2108 // Return the generated code. |
| 2142 return GetCode(type, name); | 2109 return GetCode(type, name); |
| 2143 } | 2110 } |
| 2144 | 2111 |
| 2145 | 2112 |
| 2146 Handle<Code> CallStubCompiler::CompileMathFloorCall( | 2113 Handle<Code> CallStubCompiler::CompileMathFloorCall( |
| 2147 Handle<Object> object, | 2114 Handle<Object> object, |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2215 // the result is either 0x80000000 or 0x7FFFFFFF and won't fit into an smi. | 2182 // the result is either 0x80000000 or 0x7FFFFFFF and won't fit into an smi. |
| 2216 // If result doesn't fit into an smi, branch to slow. | 2183 // If result doesn't fit into an smi, branch to slow. |
| 2217 __ SmiTag(r0, SetCC); | 2184 __ SmiTag(r0, SetCC); |
| 2218 __ b(vs, &slow); | 2185 __ b(vs, &slow); |
| 2219 | 2186 |
| 2220 __ bind(&just_return); | 2187 __ bind(&just_return); |
| 2221 __ Drop(argc + 1); | 2188 __ Drop(argc + 1); |
| 2222 __ Ret(); | 2189 __ Ret(); |
| 2223 | 2190 |
| 2224 __ bind(&slow); | 2191 __ bind(&slow); |
| 2225 // Tail call the full function. We do not have to patch the receiver | 2192 // We do not have to patch the receiver because the function makes no use of |
| 2226 // because the function makes no use of it. | 2193 // it. |
| 2227 ParameterCount expected(function); | 2194 GenerateCallFunction(Handle<Object>::null(), function); |
| 2228 __ InvokeFunction(function, expected, arguments(), | |
| 2229 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | |
| 2230 | 2195 |
| 2231 HandlerFrontendFooter(&miss); | 2196 HandlerFrontendFooter(&miss); |
| 2232 | 2197 |
| 2233 // Return the generated code. | 2198 // Return the generated code. |
| 2234 return GetCode(type, name); | 2199 return GetCode(type, name); |
| 2235 } | 2200 } |
| 2236 | 2201 |
| 2237 | 2202 |
| 2238 Handle<Code> CallStubCompiler::CompileMathAbsCall( | 2203 Handle<Code> CallStubCompiler::CompileMathAbsCall( |
| 2239 Handle<Object> object, | 2204 Handle<Object> object, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2297 __ bind(&negative_sign); | 2262 __ bind(&negative_sign); |
| 2298 __ eor(r1, r1, Operand(HeapNumber::kSignMask)); | 2263 __ eor(r1, r1, Operand(HeapNumber::kSignMask)); |
| 2299 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); | 2264 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); |
| 2300 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); | 2265 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); |
| 2301 __ AllocateHeapNumber(r0, r4, r5, r6, &slow); | 2266 __ AllocateHeapNumber(r0, r4, r5, r6, &slow); |
| 2302 __ str(r1, FieldMemOperand(r0, HeapNumber::kExponentOffset)); | 2267 __ str(r1, FieldMemOperand(r0, HeapNumber::kExponentOffset)); |
| 2303 __ str(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); | 2268 __ str(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); |
| 2304 __ Drop(argc + 1); | 2269 __ Drop(argc + 1); |
| 2305 __ Ret(); | 2270 __ Ret(); |
| 2306 | 2271 |
| 2307 // Tail call the full function. We do not have to patch the receiver | |
| 2308 // because the function makes no use of it. | |
| 2309 __ bind(&slow); | 2272 __ bind(&slow); |
| 2310 ParameterCount expected(function); | 2273 // We do not have to patch the receiver because the function makes no use of |
| 2311 __ InvokeFunction(function, expected, arguments(), | 2274 // it. |
| 2312 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2275 GenerateCallFunction(Handle<Object>::null(), function); |
| 2313 | 2276 |
| 2314 HandlerFrontendFooter(&miss); | 2277 HandlerFrontendFooter(&miss); |
| 2315 | 2278 |
| 2316 // Return the generated code. | 2279 // Return the generated code. |
| 2317 return GetCode(type, name); | 2280 return GetCode(type, name); |
| 2318 } | 2281 } |
| 2319 | 2282 |
| 2320 | 2283 |
| 2321 Handle<Code> CallStubCompiler::CompileFastApiCall( | 2284 Handle<Code> CallStubCompiler::CompileFastApiCall( |
| 2322 const CallOptimization& optimization, | 2285 const CallOptimization& optimization, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2355 // Check that the maps haven't changed and find a Holder as a side effect. | 2318 // Check that the maps haven't changed and find a Holder as a side effect. |
| 2356 CheckPrototypes( | 2319 CheckPrototypes( |
| 2357 IC::CurrentTypeOf(object, isolate()), | 2320 IC::CurrentTypeOf(object, isolate()), |
| 2358 r1, holder, r0, r3, r4, name, depth, &miss); | 2321 r1, holder, r0, r3, r4, name, depth, &miss); |
| 2359 | 2322 |
| 2360 GenerateFastApiDirectCall(masm(), optimization, argc, false); | 2323 GenerateFastApiDirectCall(masm(), optimization, argc, false); |
| 2361 | 2324 |
| 2362 __ bind(&miss); | 2325 __ bind(&miss); |
| 2363 FreeSpaceForFastApiCall(masm()); | 2326 FreeSpaceForFastApiCall(masm()); |
| 2364 | 2327 |
| 2365 __ bind(&miss_before_stack_reserved); | 2328 HandlerFrontendFooter(&miss_before_stack_reserved); |
| 2366 GenerateMissBranch(); | |
| 2367 | 2329 |
| 2368 // Return the generated code. | 2330 // Return the generated code. |
| 2369 return GetCode(function); | 2331 return GetCode(function); |
| 2370 } | 2332 } |
| 2371 | 2333 |
| 2372 | 2334 |
| 2373 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { | 2335 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { |
| 2374 Label success; | 2336 Label success; |
| 2375 // Check that the object is a boolean. | 2337 // Check that the object is a boolean. |
| 2376 __ LoadRoot(ip, Heap::kTrueValueRootIndex); | 2338 __ LoadRoot(ip, Heap::kTrueValueRootIndex); |
| 2377 __ cmp(object, ip); | 2339 __ cmp(object, ip); |
| 2378 __ b(eq, &success); | 2340 __ b(eq, &success); |
| 2379 __ LoadRoot(ip, Heap::kFalseValueRootIndex); | 2341 __ LoadRoot(ip, Heap::kFalseValueRootIndex); |
| 2380 __ cmp(object, ip); | 2342 __ cmp(object, ip); |
| 2381 __ b(ne, miss); | 2343 __ b(ne, miss); |
| 2382 __ bind(&success); | 2344 __ bind(&success); |
| 2383 } | 2345 } |
| 2384 | 2346 |
| 2385 | 2347 |
| 2386 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) { | 2348 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) { |
| 2387 if (object->IsGlobalObject()) { | 2349 if (!object.is_null() && object->IsGlobalObject()) { |
| 2388 const int argc = arguments().immediate(); | 2350 const int argc = arguments().immediate(); |
| 2389 const int receiver_offset = argc * kPointerSize; | 2351 const int receiver_offset = argc * kPointerSize; |
| 2390 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); | 2352 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); |
| 2391 __ str(r3, MemOperand(sp, receiver_offset)); | 2353 __ str(r3, MemOperand(sp, receiver_offset)); |
| 2392 } | 2354 } |
| 2393 } | 2355 } |
| 2394 | 2356 |
| 2395 | 2357 |
| 2396 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object, | 2358 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object, |
| 2397 Handle<JSObject> holder, | 2359 Handle<JSObject> holder, |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2473 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); | 2435 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
| 2474 reg = CheckPrototypes( | 2436 reg = CheckPrototypes( |
| 2475 IC::CurrentTypeOf(prototype, isolate()), | 2437 IC::CurrentTypeOf(prototype, isolate()), |
| 2476 r1, holder, r1, r3, r4, name, miss); | 2438 r1, holder, r1, r3, r4, name, miss); |
| 2477 } | 2439 } |
| 2478 | 2440 |
| 2479 return reg; | 2441 return reg; |
| 2480 } | 2442 } |
| 2481 | 2443 |
| 2482 | 2444 |
| 2483 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { | 2445 void CallStubCompiler::GenerateCallFunction(Handle<Object> object, |
| 2484 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2446 Register function, |
| 2485 ? CALL_AS_FUNCTION | 2447 Label* miss) { |
| 2486 : CALL_AS_METHOD; | 2448 ASSERT(function.is(r1)); |
| 2487 ParameterCount expected(function); | 2449 // Check that the function really is a function. |
| 2488 __ InvokeFunction(function, expected, arguments(), | 2450 GenerateFunctionCheck(function, r3, miss); |
| 2489 JUMP_FUNCTION, NullCallWrapper(), call_kind); | 2451 if (!function.is(r1)) __ mov(r1, function); |
| 2452 PatchGlobalProxy(object); | |
| 2453 | |
| 2454 // Invoke the function. | |
| 2455 __ InvokeFunction(r1, arguments(), JUMP_FUNCTION, | |
| 2456 NullCallWrapper(), call_kind()); | |
| 2490 } | 2457 } |
| 2491 | 2458 |
| 2492 | 2459 |
| 2493 Handle<Code> CallStubCompiler::CompileCallConstant( | |
| 2494 Handle<Object> object, | |
| 2495 Handle<JSObject> holder, | |
| 2496 Handle<Name> name, | |
| 2497 CheckType check, | |
| 2498 Handle<JSFunction> function) { | |
| 2499 if (HasCustomCallGenerator(function)) { | |
| 2500 Handle<Code> code = CompileCustomCall(object, holder, | |
| 2501 Handle<Cell>::null(), | |
| 2502 function, Handle<String>::cast(name), | |
| 2503 Code::FAST); | |
| 2504 // A null handle means bail out to the regular compiler code below. | |
| 2505 if (!code.is_null()) return code; | |
| 2506 } | |
| 2507 | |
| 2508 Label miss; | |
| 2509 HandlerFrontendHeader(object, holder, name, check, &miss); | |
| 2510 PatchGlobalProxy(object); | |
| 2511 CompileHandlerBackend(function); | |
| 2512 HandlerFrontendFooter(&miss); | |
| 2513 | |
| 2514 // Return the generated code. | |
| 2515 return GetCode(function); | |
| 2516 } | |
| 2517 | |
| 2518 | |
| 2519 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, | 2460 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, |
| 2520 Handle<JSObject> holder, | 2461 Handle<JSObject> holder, |
| 2521 Handle<Name> name) { | 2462 Handle<Name> name) { |
| 2522 Label miss; | 2463 Label miss; |
| 2523 GenerateNameCheck(name, &miss); | 2464 GenerateNameCheck(name, &miss); |
| 2524 | 2465 |
| 2525 // Get the number of arguments. | 2466 // Get the number of arguments. |
| 2526 const int argc = arguments().immediate(); | 2467 const int argc = arguments().immediate(); |
| 2527 LookupResult lookup(isolate()); | 2468 LookupResult lookup(isolate()); |
| 2528 LookupPostInterceptor(holder, name, &lookup); | 2469 LookupPostInterceptor(holder, name, &lookup); |
| 2529 | 2470 |
| 2530 // Get the receiver from the stack. | 2471 // Get the receiver from the stack. |
| 2531 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2472 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
| 2532 | 2473 |
| 2533 CallInterceptorCompiler compiler(this, arguments(), r2, extra_state_); | 2474 CallInterceptorCompiler compiler(this, arguments(), r2, extra_state_); |
| 2534 compiler.Compile(masm(), object, holder, name, &lookup, r1, r3, r4, r0, | 2475 compiler.Compile(masm(), object, holder, name, &lookup, r1, r3, r4, r0, |
| 2535 &miss); | 2476 &miss); |
| 2536 | 2477 |
| 2537 // Move returned value, the function to call, to r1. | 2478 // Move returned value, the function to call, to r1. |
| 2538 __ mov(r1, r0); | 2479 __ mov(r1, r0); |
| 2539 // Restore receiver. | 2480 // Restore receiver. |
| 2540 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 2481 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
| 2541 | 2482 |
| 2542 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | 2483 GenerateCallFunction(object, r0, &miss); |
| 2543 | 2484 |
| 2544 // Handle call cache miss. | 2485 HandlerFrontendFooter(&miss); |
| 2545 __ bind(&miss); | |
| 2546 GenerateMissBranch(); | |
| 2547 | 2486 |
| 2548 // Return the generated code. | 2487 // Return the generated code. |
| 2549 return GetCode(Code::FAST, name); | 2488 return GetCode(Code::FAST, name); |
| 2550 } | 2489 } |
| 2551 | 2490 |
| 2552 | 2491 |
| 2553 Handle<Code> CallStubCompiler::CompileCallGlobal( | 2492 Handle<Code> CallStubCompiler::CompileCallGlobal( |
| 2554 Handle<JSObject> object, | 2493 Handle<JSObject> object, |
| 2555 Handle<GlobalObject> holder, | 2494 Handle<GlobalObject> holder, |
| 2556 Handle<PropertyCell> cell, | 2495 Handle<PropertyCell> cell, |
| 2557 Handle<JSFunction> function, | 2496 Handle<JSFunction> function, |
| 2558 Handle<Name> name) { | 2497 Handle<Name> name) { |
| 2559 if (HasCustomCallGenerator(function)) { | 2498 if (HasCustomCallGenerator(function)) { |
| 2560 Handle<Code> code = CompileCustomCall( | 2499 Handle<Code> code = CompileCustomCall( |
| 2561 object, holder, cell, function, Handle<String>::cast(name), | 2500 object, holder, cell, function, Handle<String>::cast(name), |
| 2562 Code::NORMAL); | 2501 Code::NORMAL); |
| 2563 // A null handle means bail out to the regular compiler code below. | 2502 // A null handle means bail out to the regular compiler code below. |
| 2564 if (!code.is_null()) return code; | 2503 if (!code.is_null()) return code; |
| 2565 } | 2504 } |
| 2566 | 2505 |
| 2567 Label miss; | 2506 Label miss; |
| 2568 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); | 2507 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); |
| 2508 // Potentially loads a closure that matches the shared function info of the | |
| 2509 // function, rather than function. | |
| 2569 GenerateLoadFunctionFromCell(cell, function, &miss); | 2510 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2570 PatchGlobalProxy(object); | |
| 2571 | 2511 |
| 2572 // Set up the context (function already in r1). | |
| 2573 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | |
| 2574 | |
| 2575 // Jump to the cached code (tail call). | |
| 2576 Counters* counters = isolate()->counters(); | 2512 Counters* counters = isolate()->counters(); |
| 2577 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4); | 2513 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4); |
| 2578 ParameterCount expected(function->shared()->formal_parameter_count()); | 2514 GenerateCallFunction(object, r1, function); |
| 2579 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | |
| 2580 ? CALL_AS_FUNCTION | |
| 2581 : CALL_AS_METHOD; | |
| 2582 // We call indirectly through the code field in the function to | |
| 2583 // allow recompilation to take effect without changing any of the | |
| 2584 // call sites. | |
| 2585 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); | |
| 2586 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION, | |
| 2587 NullCallWrapper(), call_kind); | |
| 2588 | |
| 2589 HandlerFrontendFooter(&miss); | 2515 HandlerFrontendFooter(&miss); |
| 2590 | 2516 |
| 2591 // Return the generated code. | 2517 // Return the generated code. |
| 2592 return GetCode(Code::NORMAL, name); | 2518 return GetCode(Code::NORMAL, name); |
| 2593 } | 2519 } |
| 2594 | 2520 |
| 2595 | 2521 |
| 2596 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2522 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
| 2597 Handle<JSObject> object, | 2523 Handle<JSObject> object, |
| 2598 Handle<JSObject> holder, | 2524 Handle<JSObject> holder, |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2973 // ----------------------------------- | 2899 // ----------------------------------- |
| 2974 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 2900 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
| 2975 } | 2901 } |
| 2976 | 2902 |
| 2977 | 2903 |
| 2978 #undef __ | 2904 #undef __ |
| 2979 | 2905 |
| 2980 } } // namespace v8::internal | 2906 } } // namespace v8::internal |
| 2981 | 2907 |
| 2982 #endif // V8_TARGET_ARCH_ARM | 2908 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |