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