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 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 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 948 ASSERT(!scratch.is(values[i])); | 918 ASSERT(!scratch.is(values[i])); |
| 949 __ str(receiver, MemOperand(sp, index-- * kPointerSize)); | 919 __ str(receiver, MemOperand(sp, index-- * kPointerSize)); |
| 950 } | 920 } |
| 951 | 921 |
| 952 GenerateFastApiDirectCall(masm, optimization, argc, true); | 922 GenerateFastApiDirectCall(masm, optimization, argc, true); |
| 953 } | 923 } |
| 954 | 924 |
| 955 | 925 |
| 956 class CallInterceptorCompiler BASE_EMBEDDED { | 926 class CallInterceptorCompiler BASE_EMBEDDED { |
| 957 public: | 927 public: |
| 958 CallInterceptorCompiler(StubCompiler* stub_compiler, | 928 CallInterceptorCompiler(CallStubCompiler* stub_compiler, |
| 959 const ParameterCount& arguments, | 929 const ParameterCount& arguments, |
| 960 Register name, | 930 Register name, |
| 961 ExtraICState extra_ic_state) | 931 ExtraICState extra_ic_state) |
| 962 : stub_compiler_(stub_compiler), | 932 : stub_compiler_(stub_compiler), |
| 963 arguments_(arguments), | 933 arguments_(arguments), |
| 964 name_(name), | 934 name_(name), |
| 965 extra_ic_state_(extra_ic_state) {} | 935 extra_ic_state_(extra_ic_state) {} |
| 966 | 936 |
| 967 void Compile(MacroAssembler* masm, | 937 void Compile(MacroAssembler* masm, |
| 968 Handle<JSObject> object, | 938 Handle<JSObject> object, |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1060 // safe to omit it here, as if present, it should be fetched | 1030 // safe to omit it here, as if present, it should be fetched |
| 1061 // by the previous CheckPrototypes. | 1031 // by the previous CheckPrototypes. |
| 1062 ASSERT(depth2 == kInvalidProtoDepth); | 1032 ASSERT(depth2 == kInvalidProtoDepth); |
| 1063 } | 1033 } |
| 1064 | 1034 |
| 1065 // Invoke function. | 1035 // Invoke function. |
| 1066 if (can_do_fast_api_call) { | 1036 if (can_do_fast_api_call) { |
| 1067 GenerateFastApiDirectCall( | 1037 GenerateFastApiDirectCall( |
| 1068 masm, optimization, arguments_.immediate(), false); | 1038 masm, optimization, arguments_.immediate(), false); |
| 1069 } else { | 1039 } else { |
| 1070 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | |
| 1071 ? CALL_AS_FUNCTION | |
| 1072 : CALL_AS_METHOD; | |
| 1073 Handle<JSFunction> function = optimization.constant_function(); | 1040 Handle<JSFunction> function = optimization.constant_function(); |
| 1074 ParameterCount expected(function); | 1041 stub_compiler_->GenerateJumpFunctionIgnoreReceiver(function); |
| 1075 __ InvokeFunction(function, expected, arguments_, | |
| 1076 JUMP_FUNCTION, NullCallWrapper(), call_kind); | |
| 1077 } | 1042 } |
| 1078 | 1043 |
| 1079 // Deferred code for fast API call case---clean preallocated space. | 1044 // Deferred code for fast API call case---clean preallocated space. |
| 1080 if (can_do_fast_api_call) { | 1045 if (can_do_fast_api_call) { |
| 1081 __ bind(&miss_cleanup); | 1046 __ bind(&miss_cleanup); |
| 1082 FreeSpaceForFastApiCall(masm); | 1047 FreeSpaceForFastApiCall(masm); |
| 1083 __ b(miss_label); | 1048 __ b(miss_label); |
| 1084 } | 1049 } |
| 1085 | 1050 |
| 1086 // Invoke a regular function. | 1051 // Invoke a regular function. |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1132 IC::kLoadPropertyWithInterceptorOnly); | 1097 IC::kLoadPropertyWithInterceptorOnly); |
| 1133 __ pop(name_); // Restore the name. | 1098 __ pop(name_); // Restore the name. |
| 1134 __ pop(receiver); // Restore the holder. | 1099 __ pop(receiver); // Restore the holder. |
| 1135 } | 1100 } |
| 1136 // If interceptor returns no-result sentinel, call the constant function. | 1101 // If interceptor returns no-result sentinel, call the constant function. |
| 1137 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex); | 1102 __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex); |
| 1138 __ cmp(r0, scratch); | 1103 __ cmp(r0, scratch); |
| 1139 __ b(ne, interceptor_succeeded); | 1104 __ b(ne, interceptor_succeeded); |
| 1140 } | 1105 } |
| 1141 | 1106 |
| 1142 StubCompiler* stub_compiler_; | 1107 CallStubCompiler* stub_compiler_; |
| 1143 const ParameterCount& arguments_; | 1108 const ParameterCount& arguments_; |
| 1144 Register name_; | 1109 Register name_; |
| 1145 ExtraICState extra_ic_state_; | 1110 ExtraICState extra_ic_state_; |
| 1146 }; | 1111 }; |
| 1147 | 1112 |
| 1148 | 1113 |
| 1149 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { | 1114 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { |
| 1150 __ Jump(code, RelocInfo::CODE_TARGET); | 1115 __ Jump(code, RelocInfo::CODE_TARGET); |
| 1151 } | 1116 } |
| 1152 | 1117 |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1534 | 1499 |
| 1535 | 1500 |
| 1536 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { | 1501 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { |
| 1537 if (kind_ == Code::KEYED_CALL_IC) { | 1502 if (kind_ == Code::KEYED_CALL_IC) { |
| 1538 __ cmp(r2, Operand(name)); | 1503 __ cmp(r2, Operand(name)); |
| 1539 __ b(ne, miss); | 1504 __ b(ne, miss); |
| 1540 } | 1505 } |
| 1541 } | 1506 } |
| 1542 | 1507 |
| 1543 | 1508 |
| 1509 void CallStubCompiler::GenerateFunctionCheck(Register function, | |
| 1510 Register scratch, | |
| 1511 Label* miss) { | |
| 1512 __ JumpIfSmi(function, miss); | |
| 1513 __ CompareObjectType(function, scratch, scratch, JS_FUNCTION_TYPE); | |
| 1514 __ b(ne, miss); | |
| 1515 } | |
| 1516 | |
| 1517 | |
| 1544 void CallStubCompiler::GenerateLoadFunctionFromCell( | 1518 void CallStubCompiler::GenerateLoadFunctionFromCell( |
| 1545 Handle<Cell> cell, | 1519 Handle<Cell> cell, |
| 1546 Handle<JSFunction> function, | 1520 Handle<JSFunction> function, |
| 1547 Label* miss) { | 1521 Label* miss) { |
| 1548 // Get the value from the cell. | 1522 // Get the value from the cell. |
| 1549 __ mov(r3, Operand(cell)); | 1523 __ mov(r3, Operand(cell)); |
| 1550 __ ldr(r1, FieldMemOperand(r3, Cell::kValueOffset)); | 1524 __ ldr(r1, FieldMemOperand(r3, Cell::kValueOffset)); |
| 1551 | 1525 |
| 1552 // Check that the cell contains the same function. | 1526 // Check that the cell contains the same function. |
| 1553 if (heap()->InNewSpace(*function)) { | 1527 if (heap()->InNewSpace(*function)) { |
| 1554 // We can't embed a pointer to a function in new space so we have | 1528 // We can't embed a pointer to a function in new space so we have |
| 1555 // to verify that the shared function info is unchanged. This has | 1529 // to verify that the shared function info is unchanged. This has |
| 1556 // the nice side effect that multiple closures based on the same | 1530 // the nice side effect that multiple closures based on the same |
| 1557 // function can all use this call IC. Before we load through the | 1531 // function can all use this call IC. Before we load through the |
| 1558 // function, we have to verify that it still is a function. | 1532 // function, we have to verify that it still is a function. |
| 1559 __ JumpIfSmi(r1, miss); | 1533 GenerateFunctionCheck(r1, r3, miss); |
| 1560 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE); | |
| 1561 __ b(ne, miss); | |
| 1562 | 1534 |
| 1563 // Check the shared function info. Make sure it hasn't changed. | 1535 // Check the shared function info. Make sure it hasn't changed. |
| 1564 __ Move(r3, Handle<SharedFunctionInfo>(function->shared())); | 1536 __ Move(r3, Handle<SharedFunctionInfo>(function->shared())); |
| 1565 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 1537 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
| 1566 __ cmp(r4, r3); | 1538 __ cmp(r4, r3); |
| 1567 } else { | 1539 } else { |
| 1568 __ cmp(r1, Operand(function)); | 1540 __ cmp(r1, Operand(function)); |
| 1569 } | 1541 } |
| 1570 __ b(ne, miss); | 1542 __ b(ne, miss); |
| 1571 } | 1543 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1583 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, | 1555 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, |
| 1584 Handle<JSObject> holder, | 1556 Handle<JSObject> holder, |
| 1585 PropertyIndex index, | 1557 PropertyIndex index, |
| 1586 Handle<Name> name) { | 1558 Handle<Name> name) { |
| 1587 Label miss; | 1559 Label miss; |
| 1588 | 1560 |
| 1589 Register reg = HandlerFrontendHeader( | 1561 Register reg = HandlerFrontendHeader( |
| 1590 object, holder, name, RECEIVER_MAP_CHECK, &miss); | 1562 object, holder, name, RECEIVER_MAP_CHECK, &miss); |
| 1591 GenerateFastPropertyLoad(masm(), r1, reg, index.is_inobject(holder), | 1563 GenerateFastPropertyLoad(masm(), r1, reg, index.is_inobject(holder), |
| 1592 index.translate(holder), Representation::Tagged()); | 1564 index.translate(holder), Representation::Tagged()); |
| 1593 | 1565 GenerateJumpFunction(object, r1, &miss); |
| 1594 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | |
| 1595 | 1566 |
| 1596 HandlerFrontendFooter(&miss); | 1567 HandlerFrontendFooter(&miss); |
| 1597 | 1568 |
| 1598 // Return the generated code. | 1569 // Return the generated code. |
| 1599 return GetCode(Code::FAST, name); | 1570 return GetCode(Code::FAST, name); |
| 1600 } | 1571 } |
| 1601 | 1572 |
| 1602 | 1573 |
| 1603 Handle<Code> CallStubCompiler::CompileArrayCodeCall( | 1574 Handle<Code> CallStubCompiler::CompileArrayCodeCall( |
| 1604 Handle<Object> object, | 1575 Handle<Object> object, |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1999 if (index_out_of_range.is_linked()) { | 1970 if (index_out_of_range.is_linked()) { |
| 2000 __ bind(&index_out_of_range); | 1971 __ bind(&index_out_of_range); |
| 2001 __ LoadRoot(r0, Heap::kNanValueRootIndex); | 1972 __ LoadRoot(r0, Heap::kNanValueRootIndex); |
| 2002 __ Drop(argc + 1); | 1973 __ Drop(argc + 1); |
| 2003 __ Ret(); | 1974 __ Ret(); |
| 2004 } | 1975 } |
| 2005 | 1976 |
| 2006 __ bind(&miss); | 1977 __ bind(&miss); |
| 2007 // Restore function name in r2. | 1978 // Restore function name in r2. |
| 2008 __ Move(r2, name); | 1979 __ Move(r2, name); |
| 2009 __ bind(&name_miss); | 1980 HandlerFrontendFooter(&name_miss); |
| 2010 GenerateMissBranch(); | |
| 2011 | 1981 |
| 2012 // Return the generated code. | 1982 // Return the generated code. |
| 2013 return GetCode(type, name); | 1983 return GetCode(type, name); |
| 2014 } | 1984 } |
| 2015 | 1985 |
| 2016 | 1986 |
| 2017 Handle<Code> CallStubCompiler::CompileStringCharAtCall( | 1987 Handle<Code> CallStubCompiler::CompileStringCharAtCall( |
| 2018 Handle<Object> object, | 1988 Handle<Object> object, |
| 2019 Handle<JSObject> holder, | 1989 Handle<JSObject> holder, |
| 2020 Handle<Cell> cell, | 1990 Handle<Cell> cell, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2066 if (index_out_of_range.is_linked()) { | 2036 if (index_out_of_range.is_linked()) { |
| 2067 __ bind(&index_out_of_range); | 2037 __ bind(&index_out_of_range); |
| 2068 __ LoadRoot(r0, Heap::kempty_stringRootIndex); | 2038 __ LoadRoot(r0, Heap::kempty_stringRootIndex); |
| 2069 __ Drop(argc + 1); | 2039 __ Drop(argc + 1); |
| 2070 __ Ret(); | 2040 __ Ret(); |
| 2071 } | 2041 } |
| 2072 | 2042 |
| 2073 __ bind(&miss); | 2043 __ bind(&miss); |
| 2074 // Restore function name in r2. | 2044 // Restore function name in r2. |
| 2075 __ Move(r2, name); | 2045 __ Move(r2, name); |
| 2076 __ bind(&name_miss); | 2046 HandlerFrontendFooter(&name_miss); |
| 2077 GenerateMissBranch(); | |
| 2078 | 2047 |
| 2079 // Return the generated code. | 2048 // Return the generated code. |
| 2080 return GetCode(type, name); | 2049 return GetCode(type, name); |
| 2081 } | 2050 } |
| 2082 | 2051 |
| 2083 | 2052 |
| 2084 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( | 2053 Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( |
| 2085 Handle<Object> object, | 2054 Handle<Object> object, |
| 2086 Handle<JSObject> holder, | 2055 Handle<JSObject> holder, |
| 2087 Handle<Cell> cell, | 2056 Handle<Cell> cell, |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 2114 __ and_(code, code, Operand(Smi::FromInt(0xffff))); | 2083 __ and_(code, code, Operand(Smi::FromInt(0xffff))); |
| 2115 | 2084 |
| 2116 StringCharFromCodeGenerator generator(code, r0); | 2085 StringCharFromCodeGenerator generator(code, r0); |
| 2117 generator.GenerateFast(masm()); | 2086 generator.GenerateFast(masm()); |
| 2118 __ Drop(argc + 1); | 2087 __ Drop(argc + 1); |
| 2119 __ Ret(); | 2088 __ Ret(); |
| 2120 | 2089 |
| 2121 StubRuntimeCallHelper call_helper; | 2090 StubRuntimeCallHelper call_helper; |
| 2122 generator.GenerateSlow(masm(), call_helper); | 2091 generator.GenerateSlow(masm(), call_helper); |
| 2123 | 2092 |
| 2124 // Tail call the full function. We do not have to patch the receiver | |
| 2125 // because the function makes no use of it. | |
| 2126 __ bind(&slow); | 2093 __ bind(&slow); |
| 2127 ParameterCount expected(function); | 2094 // We do not have to patch the receiver because the function makes no use of |
| 2128 __ InvokeFunction(function, expected, arguments(), | 2095 // it. |
| 2129 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2096 GenerateJumpFunctionIgnoreReceiver(function); |
| 2130 | 2097 |
| 2131 HandlerFrontendFooter(&miss); | 2098 HandlerFrontendFooter(&miss); |
| 2132 | 2099 |
| 2133 // Return the generated code. | 2100 // Return the generated code. |
| 2134 return GetCode(type, name); | 2101 return GetCode(type, name); |
| 2135 } | 2102 } |
| 2136 | 2103 |
| 2137 | 2104 |
| 2138 Handle<Code> CallStubCompiler::CompileMathFloorCall( | 2105 Handle<Code> CallStubCompiler::CompileMathFloorCall( |
| 2139 Handle<Object> object, | 2106 Handle<Object> object, |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2207 // the result is either 0x80000000 or 0x7FFFFFFF and won't fit into an smi. | 2174 // the result is either 0x80000000 or 0x7FFFFFFF and won't fit into an smi. |
| 2208 // If result doesn't fit into an smi, branch to slow. | 2175 // If result doesn't fit into an smi, branch to slow. |
| 2209 __ SmiTag(r0, SetCC); | 2176 __ SmiTag(r0, SetCC); |
| 2210 __ b(vs, &slow); | 2177 __ b(vs, &slow); |
| 2211 | 2178 |
| 2212 __ bind(&just_return); | 2179 __ bind(&just_return); |
| 2213 __ Drop(argc + 1); | 2180 __ Drop(argc + 1); |
| 2214 __ Ret(); | 2181 __ Ret(); |
| 2215 | 2182 |
| 2216 __ bind(&slow); | 2183 __ bind(&slow); |
| 2217 // Tail call the full function. We do not have to patch the receiver | 2184 // We do not have to patch the receiver because the function makes no use of |
| 2218 // because the function makes no use of it. | 2185 // it. |
| 2219 ParameterCount expected(function); | 2186 GenerateJumpFunctionIgnoreReceiver(function); |
| 2220 __ InvokeFunction(function, expected, arguments(), | |
| 2221 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | |
| 2222 | 2187 |
| 2223 HandlerFrontendFooter(&miss); | 2188 HandlerFrontendFooter(&miss); |
| 2224 | 2189 |
| 2225 // Return the generated code. | 2190 // Return the generated code. |
| 2226 return GetCode(type, name); | 2191 return GetCode(type, name); |
| 2227 } | 2192 } |
| 2228 | 2193 |
| 2229 | 2194 |
| 2230 Handle<Code> CallStubCompiler::CompileMathAbsCall( | 2195 Handle<Code> CallStubCompiler::CompileMathAbsCall( |
| 2231 Handle<Object> object, | 2196 Handle<Object> object, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2289 __ bind(&negative_sign); | 2254 __ bind(&negative_sign); |
| 2290 __ eor(r1, r1, Operand(HeapNumber::kSignMask)); | 2255 __ eor(r1, r1, Operand(HeapNumber::kSignMask)); |
| 2291 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); | 2256 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); |
| 2292 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); | 2257 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); |
| 2293 __ AllocateHeapNumber(r0, r4, r5, r6, &slow); | 2258 __ AllocateHeapNumber(r0, r4, r5, r6, &slow); |
| 2294 __ str(r1, FieldMemOperand(r0, HeapNumber::kExponentOffset)); | 2259 __ str(r1, FieldMemOperand(r0, HeapNumber::kExponentOffset)); |
| 2295 __ str(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); | 2260 __ str(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); |
| 2296 __ Drop(argc + 1); | 2261 __ Drop(argc + 1); |
| 2297 __ Ret(); | 2262 __ Ret(); |
| 2298 | 2263 |
| 2299 // Tail call the full function. We do not have to patch the receiver | |
| 2300 // because the function makes no use of it. | |
| 2301 __ bind(&slow); | 2264 __ bind(&slow); |
| 2302 ParameterCount expected(function); | 2265 // We do not have to patch the receiver because the function makes no use of |
| 2303 __ InvokeFunction(function, expected, arguments(), | 2266 // it. |
| 2304 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2267 GenerateJumpFunctionIgnoreReceiver(function); |
| 2305 | 2268 |
| 2306 HandlerFrontendFooter(&miss); | 2269 HandlerFrontendFooter(&miss); |
| 2307 | 2270 |
| 2308 // Return the generated code. | 2271 // Return the generated code. |
| 2309 return GetCode(type, name); | 2272 return GetCode(type, name); |
| 2310 } | 2273 } |
| 2311 | 2274 |
| 2312 | 2275 |
| 2313 Handle<Code> CallStubCompiler::CompileFastApiCall( | 2276 Handle<Code> CallStubCompiler::CompileFastApiCall( |
| 2314 const CallOptimization& optimization, | 2277 const CallOptimization& optimization, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2347 // Check that the maps haven't changed and find a Holder as a side effect. | 2310 // Check that the maps haven't changed and find a Holder as a side effect. |
| 2348 CheckPrototypes( | 2311 CheckPrototypes( |
| 2349 IC::CurrentTypeOf(object, isolate()), | 2312 IC::CurrentTypeOf(object, isolate()), |
| 2350 r1, holder, r0, r3, r4, name, depth, &miss); | 2313 r1, holder, r0, r3, r4, name, depth, &miss); |
| 2351 | 2314 |
| 2352 GenerateFastApiDirectCall(masm(), optimization, argc, false); | 2315 GenerateFastApiDirectCall(masm(), optimization, argc, false); |
| 2353 | 2316 |
| 2354 __ bind(&miss); | 2317 __ bind(&miss); |
| 2355 FreeSpaceForFastApiCall(masm()); | 2318 FreeSpaceForFastApiCall(masm()); |
| 2356 | 2319 |
| 2357 __ bind(&miss_before_stack_reserved); | 2320 HandlerFrontendFooter(&miss_before_stack_reserved); |
| 2358 GenerateMissBranch(); | |
| 2359 | 2321 |
| 2360 // Return the generated code. | 2322 // Return the generated code. |
| 2361 return GetCode(function); | 2323 return GetCode(function); |
| 2362 } | 2324 } |
| 2363 | 2325 |
| 2364 | 2326 |
| 2365 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { | 2327 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { |
| 2366 Label success; | 2328 Label success; |
| 2367 // Check that the object is a boolean. | 2329 // Check that the object is a boolean. |
| 2368 __ LoadRoot(ip, Heap::kTrueValueRootIndex); | 2330 __ LoadRoot(ip, Heap::kTrueValueRootIndex); |
| 2369 __ cmp(object, ip); | 2331 __ cmp(object, ip); |
| 2370 __ b(eq, &success); | 2332 __ b(eq, &success); |
| 2371 __ LoadRoot(ip, Heap::kFalseValueRootIndex); | 2333 __ LoadRoot(ip, Heap::kFalseValueRootIndex); |
| 2372 __ cmp(object, ip); | 2334 __ cmp(object, ip); |
| 2373 __ b(ne, miss); | 2335 __ b(ne, miss); |
| 2374 __ bind(&success); | 2336 __ bind(&success); |
| 2375 } | 2337 } |
| 2376 | 2338 |
| 2377 | 2339 |
| 2378 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) { | 2340 void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) { |
| 2379 if (object->IsGlobalObject()) { | 2341 if (!object.is_null() && object->IsGlobalObject()) { |
|
Igor Sheludko
2013/11/29 12:39:42
Do we still need is_null() check here? (same note
| |
| 2380 const int argc = arguments().immediate(); | 2342 const int argc = arguments().immediate(); |
| 2381 const int receiver_offset = argc * kPointerSize; | 2343 const int receiver_offset = argc * kPointerSize; |
| 2382 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); | 2344 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); |
| 2383 __ str(r3, MemOperand(sp, receiver_offset)); | 2345 __ str(r3, MemOperand(sp, receiver_offset)); |
| 2384 } | 2346 } |
| 2385 } | 2347 } |
| 2386 | 2348 |
| 2387 | 2349 |
| 2388 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object, | 2350 Register CallStubCompiler::HandlerFrontendHeader(Handle<Object> object, |
| 2389 Handle<JSObject> holder, | 2351 Handle<JSObject> holder, |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2465 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); | 2427 Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); |
| 2466 reg = CheckPrototypes( | 2428 reg = CheckPrototypes( |
| 2467 IC::CurrentTypeOf(prototype, isolate()), | 2429 IC::CurrentTypeOf(prototype, isolate()), |
| 2468 r1, holder, r1, r3, r4, name, miss); | 2430 r1, holder, r1, r3, r4, name, miss); |
| 2469 } | 2431 } |
| 2470 | 2432 |
| 2471 return reg; | 2433 return reg; |
| 2472 } | 2434 } |
| 2473 | 2435 |
| 2474 | 2436 |
| 2475 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { | 2437 void CallStubCompiler::GenerateJumpFunction(Handle<Object> object, |
| 2476 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2438 Register function, |
| 2477 ? CALL_AS_FUNCTION | 2439 Label* miss) { |
| 2478 : CALL_AS_METHOD; | 2440 ASSERT(function.is(r1)); |
| 2479 ParameterCount expected(function); | 2441 // Check that the function really is a function. |
| 2480 __ InvokeFunction(function, expected, arguments(), | 2442 GenerateFunctionCheck(function, r3, miss); |
| 2481 JUMP_FUNCTION, NullCallWrapper(), call_kind); | 2443 PatchGlobalProxy(object); |
| 2444 | |
| 2445 // Invoke the function. | |
| 2446 __ InvokeFunction(r1, arguments(), JUMP_FUNCTION, | |
| 2447 NullCallWrapper(), call_kind()); | |
| 2482 } | 2448 } |
| 2483 | 2449 |
| 2484 | 2450 |
| 2485 Handle<Code> CallStubCompiler::CompileCallConstant( | |
| 2486 Handle<Object> object, | |
| 2487 Handle<JSObject> holder, | |
| 2488 Handle<Name> name, | |
| 2489 CheckType check, | |
| 2490 Handle<JSFunction> function) { | |
| 2491 if (HasCustomCallGenerator(function)) { | |
| 2492 Handle<Code> code = CompileCustomCall(object, holder, | |
| 2493 Handle<Cell>::null(), | |
| 2494 function, Handle<String>::cast(name), | |
| 2495 Code::FAST); | |
| 2496 // A null handle means bail out to the regular compiler code below. | |
| 2497 if (!code.is_null()) return code; | |
| 2498 } | |
| 2499 | |
| 2500 Label miss; | |
| 2501 HandlerFrontendHeader(object, holder, name, check, &miss); | |
| 2502 PatchGlobalProxy(object); | |
| 2503 CompileHandlerBackend(function); | |
| 2504 HandlerFrontendFooter(&miss); | |
| 2505 | |
| 2506 // Return the generated code. | |
| 2507 return GetCode(function); | |
| 2508 } | |
| 2509 | |
| 2510 | |
| 2511 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, | 2451 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, |
| 2512 Handle<JSObject> holder, | 2452 Handle<JSObject> holder, |
| 2513 Handle<Name> name) { | 2453 Handle<Name> name) { |
| 2514 Label miss; | 2454 Label miss; |
| 2515 GenerateNameCheck(name, &miss); | 2455 GenerateNameCheck(name, &miss); |
| 2516 | 2456 |
| 2517 // Get the number of arguments. | 2457 // Get the number of arguments. |
| 2518 const int argc = arguments().immediate(); | 2458 const int argc = arguments().immediate(); |
| 2519 LookupResult lookup(isolate()); | 2459 LookupResult lookup(isolate()); |
| 2520 LookupPostInterceptor(holder, name, &lookup); | 2460 LookupPostInterceptor(holder, name, &lookup); |
| 2521 | 2461 |
| 2522 // Get the receiver from the stack. | 2462 // Get the receiver from the stack. |
| 2523 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2463 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
| 2524 | 2464 |
| 2525 CallInterceptorCompiler compiler(this, arguments(), r2, extra_state_); | 2465 CallInterceptorCompiler compiler(this, arguments(), r2, extra_state_); |
| 2526 compiler.Compile(masm(), object, holder, name, &lookup, r1, r3, r4, r0, | 2466 compiler.Compile(masm(), object, holder, name, &lookup, r1, r3, r4, r0, |
| 2527 &miss); | 2467 &miss); |
| 2528 | 2468 |
| 2529 // Move returned value, the function to call, to r1. | 2469 // Move returned value, the function to call, to r1. |
| 2530 __ mov(r1, r0); | 2470 __ mov(r1, r0); |
| 2531 // Restore receiver. | 2471 // Restore receiver. |
| 2532 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 2472 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
| 2533 | 2473 |
| 2534 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | 2474 GenerateJumpFunction(object, r1, &miss); |
| 2535 | 2475 |
| 2536 // Handle call cache miss. | 2476 HandlerFrontendFooter(&miss); |
| 2537 __ bind(&miss); | |
| 2538 GenerateMissBranch(); | |
| 2539 | 2477 |
| 2540 // Return the generated code. | 2478 // Return the generated code. |
| 2541 return GetCode(Code::FAST, name); | 2479 return GetCode(Code::FAST, name); |
| 2542 } | 2480 } |
| 2543 | 2481 |
| 2544 | 2482 |
| 2545 Handle<Code> CallStubCompiler::CompileCallGlobal( | 2483 Handle<Code> CallStubCompiler::CompileCallGlobal( |
| 2546 Handle<JSObject> object, | 2484 Handle<JSObject> object, |
| 2547 Handle<GlobalObject> holder, | 2485 Handle<GlobalObject> holder, |
| 2548 Handle<PropertyCell> cell, | 2486 Handle<PropertyCell> cell, |
| 2549 Handle<JSFunction> function, | 2487 Handle<JSFunction> function, |
| 2550 Handle<Name> name) { | 2488 Handle<Name> name) { |
| 2551 if (HasCustomCallGenerator(function)) { | 2489 if (HasCustomCallGenerator(function)) { |
| 2552 Handle<Code> code = CompileCustomCall( | 2490 Handle<Code> code = CompileCustomCall( |
| 2553 object, holder, cell, function, Handle<String>::cast(name), | 2491 object, holder, cell, function, Handle<String>::cast(name), |
| 2554 Code::NORMAL); | 2492 Code::NORMAL); |
| 2555 // A null handle means bail out to the regular compiler code below. | 2493 // A null handle means bail out to the regular compiler code below. |
| 2556 if (!code.is_null()) return code; | 2494 if (!code.is_null()) return code; |
| 2557 } | 2495 } |
| 2558 | 2496 |
| 2559 Label miss; | 2497 Label miss; |
| 2560 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); | 2498 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); |
| 2499 // Potentially loads a closure that matches the shared function info of the | |
| 2500 // function, rather than function. | |
| 2561 GenerateLoadFunctionFromCell(cell, function, &miss); | 2501 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2562 PatchGlobalProxy(object); | |
| 2563 | 2502 |
| 2564 // Set up the context (function already in r1). | |
| 2565 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | |
| 2566 | |
| 2567 // Jump to the cached code (tail call). | |
| 2568 Counters* counters = isolate()->counters(); | 2503 Counters* counters = isolate()->counters(); |
| 2569 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4); | 2504 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4); |
| 2570 ParameterCount expected(function->shared()->formal_parameter_count()); | 2505 GenerateJumpFunction(object, r1, function); |
| 2571 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | |
| 2572 ? CALL_AS_FUNCTION | |
| 2573 : CALL_AS_METHOD; | |
| 2574 // We call indirectly through the code field in the function to | |
| 2575 // allow recompilation to take effect without changing any of the | |
| 2576 // call sites. | |
| 2577 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); | |
| 2578 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION, | |
| 2579 NullCallWrapper(), call_kind); | |
| 2580 | |
| 2581 HandlerFrontendFooter(&miss); | 2506 HandlerFrontendFooter(&miss); |
| 2582 | 2507 |
| 2583 // Return the generated code. | 2508 // Return the generated code. |
| 2584 return GetCode(Code::NORMAL, name); | 2509 return GetCode(Code::NORMAL, name); |
| 2585 } | 2510 } |
| 2586 | 2511 |
| 2587 | 2512 |
| 2588 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2513 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
| 2589 Handle<JSObject> object, | 2514 Handle<JSObject> object, |
| 2590 Handle<JSObject> holder, | 2515 Handle<JSObject> holder, |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2962 // ----------------------------------- | 2887 // ----------------------------------- |
| 2963 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 2888 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
| 2964 } | 2889 } |
| 2965 | 2890 |
| 2966 | 2891 |
| 2967 #undef __ | 2892 #undef __ |
| 2968 | 2893 |
| 2969 } } // namespace v8::internal | 2894 } } // namespace v8::internal |
| 2970 | 2895 |
| 2971 #endif // V8_TARGET_ARCH_ARM | 2896 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |