OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 1755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1766 case Token::SHR: | 1766 case Token::SHR: |
1767 GenerateTypeTransitionWithSavedArgs(masm); | 1767 GenerateTypeTransitionWithSavedArgs(masm); |
1768 break; | 1768 break; |
1769 default: | 1769 default: |
1770 UNREACHABLE(); | 1770 UNREACHABLE(); |
1771 } | 1771 } |
1772 } | 1772 } |
1773 | 1773 |
1774 | 1774 |
1775 void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) { | 1775 void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) { |
1776 Label call_runtime; | |
1777 ASSERT(operands_type_ == TRBinaryOpIC::STRING); | 1776 ASSERT(operands_type_ == TRBinaryOpIC::STRING); |
1778 ASSERT(op_ == Token::ADD); | 1777 ASSERT(op_ == Token::ADD); |
1779 // If one of the arguments is a string, call the string add stub. | |
1780 // Otherwise, transition to the generic TRBinaryOpIC type. | |
1781 | 1778 |
1782 // Registers containing left and right operands respectively. | 1779 // Try to add arguments as strings, otherwise, transition to the generic |
1783 Register left = edx; | 1780 // TRBinaryOpIC type. |
1784 Register right = eax; | 1781 GenerateAddStrings(masm); |
1785 | |
1786 // Test if left operand is a string. | |
1787 NearLabel left_not_string; | |
1788 __ test(left, Immediate(kSmiTagMask)); | |
1789 __ j(zero, &left_not_string); | |
1790 __ CmpObjectType(left, FIRST_NONSTRING_TYPE, ecx); | |
1791 __ j(above_equal, &left_not_string); | |
1792 | |
1793 StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB); | |
1794 GenerateRegisterArgsPush(masm); | |
1795 __ TailCallStub(&string_add_left_stub); | |
1796 | |
1797 // Left operand is not a string, test right. | |
1798 __ bind(&left_not_string); | |
1799 __ test(right, Immediate(kSmiTagMask)); | |
1800 __ j(zero, &call_runtime); | |
1801 __ CmpObjectType(right, FIRST_NONSTRING_TYPE, ecx); | |
1802 __ j(above_equal, &call_runtime); | |
1803 | |
1804 StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB); | |
1805 GenerateRegisterArgsPush(masm); | |
1806 __ TailCallStub(&string_add_right_stub); | |
1807 | |
1808 // Neither argument is a string. | |
1809 __ bind(&call_runtime); | |
1810 GenerateTypeTransition(masm); | 1782 GenerateTypeTransition(masm); |
1811 } | 1783 } |
1812 | 1784 |
1813 | 1785 |
1814 void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { | 1786 void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { |
1815 Label call_runtime; | 1787 Label call_runtime; |
1816 ASSERT(operands_type_ == TRBinaryOpIC::INT32); | 1788 ASSERT(operands_type_ == TRBinaryOpIC::INT32); |
1817 | 1789 |
1818 // Floating point case. | 1790 // Floating point case. |
1819 switch (op_) { | 1791 switch (op_) { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1960 __ bind(¬_int32); | 1932 __ bind(¬_int32); |
1961 GenerateTypeTransitionWithSavedArgs(masm); | 1933 GenerateTypeTransitionWithSavedArgs(masm); |
1962 break; | 1934 break; |
1963 } | 1935 } |
1964 default: UNREACHABLE(); break; | 1936 default: UNREACHABLE(); break; |
1965 } | 1937 } |
1966 | 1938 |
1967 // If an allocation fails, or SHR or MOD hit a hard case, | 1939 // If an allocation fails, or SHR or MOD hit a hard case, |
1968 // use the runtime system to get the correct result. | 1940 // use the runtime system to get the correct result. |
1969 __ bind(&call_runtime); | 1941 __ bind(&call_runtime); |
1970 | 1942 GenerateCallRuntime(masm); |
1971 switch (op_) { | |
1972 case Token::ADD: | |
1973 GenerateRegisterArgsPush(masm); | |
1974 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION); | |
1975 break; | |
1976 case Token::SUB: | |
1977 GenerateRegisterArgsPush(masm); | |
1978 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION); | |
1979 break; | |
1980 case Token::MUL: | |
1981 GenerateRegisterArgsPush(masm); | |
1982 __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION); | |
1983 break; | |
1984 case Token::DIV: | |
1985 GenerateRegisterArgsPush(masm); | |
1986 __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION); | |
1987 break; | |
1988 case Token::MOD: | |
1989 GenerateRegisterArgsPush(masm); | |
1990 __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION); | |
1991 break; | |
1992 case Token::BIT_OR: | |
1993 __ InvokeBuiltin(Builtins::BIT_OR, JUMP_FUNCTION); | |
1994 break; | |
1995 case Token::BIT_AND: | |
1996 __ InvokeBuiltin(Builtins::BIT_AND, JUMP_FUNCTION); | |
1997 break; | |
1998 case Token::BIT_XOR: | |
1999 __ InvokeBuiltin(Builtins::BIT_XOR, JUMP_FUNCTION); | |
2000 break; | |
2001 case Token::SAR: | |
2002 __ InvokeBuiltin(Builtins::SAR, JUMP_FUNCTION); | |
2003 break; | |
2004 case Token::SHL: | |
2005 __ InvokeBuiltin(Builtins::SHL, JUMP_FUNCTION); | |
2006 break; | |
2007 case Token::SHR: | |
2008 __ InvokeBuiltin(Builtins::SHR, JUMP_FUNCTION); | |
2009 break; | |
2010 default: | |
2011 UNREACHABLE(); | |
2012 } | |
2013 } | 1943 } |
2014 | 1944 |
2015 | 1945 |
2016 void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { | 1946 void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { |
2017 Label call_runtime; | 1947 Label call_runtime; |
2018 ASSERT(operands_type_ == TRBinaryOpIC::HEAP_NUMBER); | 1948 ASSERT(operands_type_ == TRBinaryOpIC::HEAP_NUMBER); |
2019 | 1949 |
2020 // Floating point case. | 1950 // Floating point case. |
2021 switch (op_) { | 1951 switch (op_) { |
2022 case Token::ADD: | 1952 case Token::ADD: |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2142 __ bind(¬_floats); | 2072 __ bind(¬_floats); |
2143 GenerateTypeTransitionWithSavedArgs(masm); | 2073 GenerateTypeTransitionWithSavedArgs(masm); |
2144 break; | 2074 break; |
2145 } | 2075 } |
2146 default: UNREACHABLE(); break; | 2076 default: UNREACHABLE(); break; |
2147 } | 2077 } |
2148 | 2078 |
2149 // If an allocation fails, or SHR or MOD hit a hard case, | 2079 // If an allocation fails, or SHR or MOD hit a hard case, |
2150 // use the runtime system to get the correct result. | 2080 // use the runtime system to get the correct result. |
2151 __ bind(&call_runtime); | 2081 __ bind(&call_runtime); |
2152 | 2082 GenerateCallRuntime(masm); |
2153 switch (op_) { | |
2154 case Token::ADD: | |
2155 GenerateRegisterArgsPush(masm); | |
2156 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION); | |
2157 break; | |
2158 case Token::SUB: | |
2159 GenerateRegisterArgsPush(masm); | |
2160 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION); | |
2161 break; | |
2162 case Token::MUL: | |
2163 GenerateRegisterArgsPush(masm); | |
2164 __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION); | |
2165 break; | |
2166 case Token::DIV: | |
2167 GenerateRegisterArgsPush(masm); | |
2168 __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION); | |
2169 break; | |
2170 case Token::MOD: | |
2171 GenerateRegisterArgsPush(masm); | |
2172 __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION); | |
2173 break; | |
2174 case Token::BIT_OR: | |
2175 __ InvokeBuiltin(Builtins::BIT_OR, JUMP_FUNCTION); | |
2176 break; | |
2177 case Token::BIT_AND: | |
2178 __ InvokeBuiltin(Builtins::BIT_AND, JUMP_FUNCTION); | |
2179 break; | |
2180 case Token::BIT_XOR: | |
2181 __ InvokeBuiltin(Builtins::BIT_XOR, JUMP_FUNCTION); | |
2182 break; | |
2183 case Token::SAR: | |
2184 __ InvokeBuiltin(Builtins::SAR, JUMP_FUNCTION); | |
2185 break; | |
2186 case Token::SHL: | |
2187 __ InvokeBuiltin(Builtins::SHL, JUMP_FUNCTION); | |
2188 break; | |
2189 case Token::SHR: | |
2190 __ InvokeBuiltin(Builtins::SHR, JUMP_FUNCTION); | |
2191 break; | |
2192 default: | |
2193 UNREACHABLE(); | |
2194 } | |
2195 } | 2083 } |
2196 | 2084 |
2197 | 2085 |
2198 void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) { | 2086 void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) { |
2199 Label call_runtime; | 2087 Label call_runtime; |
2200 | 2088 |
2201 __ IncrementCounter(&Counters::generic_binary_stub_calls, 1); | 2089 __ IncrementCounter(&Counters::generic_binary_stub_calls, 1); |
2202 | 2090 |
2203 switch (op_) { | 2091 switch (op_) { |
2204 case Token::ADD: | 2092 case Token::ADD: |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2338 __ ret(2 * kPointerSize); | 2226 __ ret(2 * kPointerSize); |
2339 } | 2227 } |
2340 break; | 2228 break; |
2341 } | 2229 } |
2342 default: UNREACHABLE(); break; | 2230 default: UNREACHABLE(); break; |
2343 } | 2231 } |
2344 | 2232 |
2345 // If all else fails, use the runtime system to get the correct | 2233 // If all else fails, use the runtime system to get the correct |
2346 // result. | 2234 // result. |
2347 __ bind(&call_runtime); | 2235 __ bind(&call_runtime); |
| 2236 |
| 2237 // Try to add strings before calling runtime. |
| 2238 if (op_ == Token::ADD) { |
| 2239 GenerateAddStrings(masm); |
| 2240 } |
| 2241 |
| 2242 // Generate the runtime call. |
| 2243 GenerateCallRuntime(masm); |
| 2244 } |
| 2245 |
| 2246 |
| 2247 void TypeRecordingBinaryOpStub::GenerateAddStrings(MacroAssembler* masm) { |
| 2248 // If one of the arguments is a string, call the string add stub. |
| 2249 // Registers containing left and right operands respectively. |
| 2250 NearLabel left_not_string, neither_string; |
| 2251 Register left = edx; |
| 2252 Register right = eax; |
| 2253 |
| 2254 // Test if left operand is a string. |
| 2255 __ test(left, Immediate(kSmiTagMask)); |
| 2256 __ j(zero, &left_not_string); |
| 2257 __ CmpObjectType(left, FIRST_NONSTRING_TYPE, ecx); |
| 2258 __ j(above_equal, &left_not_string); |
| 2259 |
| 2260 StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB); |
| 2261 GenerateRegisterArgsPush(masm); |
| 2262 __ TailCallStub(&string_add_left_stub); |
| 2263 |
| 2264 // Left operand is not a string, test right. |
| 2265 __ bind(&left_not_string); |
| 2266 __ test(right, Immediate(kSmiTagMask)); |
| 2267 __ j(zero, &neither_string); |
| 2268 __ CmpObjectType(right, FIRST_NONSTRING_TYPE, ecx); |
| 2269 __ j(above_equal, &neither_string); |
| 2270 |
| 2271 StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB); |
| 2272 GenerateRegisterArgsPush(masm); |
| 2273 __ TailCallStub(&string_add_right_stub); |
| 2274 |
| 2275 // Neither argument is a string. |
| 2276 __ bind(&neither_string); |
| 2277 } |
| 2278 |
| 2279 |
| 2280 void TypeRecordingBinaryOpStub::GenerateCallRuntime(MacroAssembler* masm) { |
2348 switch (op_) { | 2281 switch (op_) { |
2349 case Token::ADD: { | 2282 case Token::ADD: |
2350 GenerateRegisterArgsPush(masm); | 2283 GenerateRegisterArgsPush(masm); |
2351 // Test for string arguments before calling runtime. | |
2352 // Registers containing left and right operands respectively. | |
2353 Register lhs, rhs; | |
2354 lhs = edx; | |
2355 rhs = eax; | |
2356 | |
2357 // Test if left operand is a string. | |
2358 NearLabel lhs_not_string; | |
2359 __ test(lhs, Immediate(kSmiTagMask)); | |
2360 __ j(zero, &lhs_not_string); | |
2361 __ CmpObjectType(lhs, FIRST_NONSTRING_TYPE, ecx); | |
2362 __ j(above_equal, &lhs_not_string); | |
2363 | |
2364 StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB); | |
2365 __ TailCallStub(&string_add_left_stub); | |
2366 | |
2367 NearLabel call_add_runtime; | |
2368 // Left operand is not a string, test right. | |
2369 __ bind(&lhs_not_string); | |
2370 __ test(rhs, Immediate(kSmiTagMask)); | |
2371 __ j(zero, &call_add_runtime); | |
2372 __ CmpObjectType(rhs, FIRST_NONSTRING_TYPE, ecx); | |
2373 __ j(above_equal, &call_add_runtime); | |
2374 | |
2375 StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB); | |
2376 __ TailCallStub(&string_add_right_stub); | |
2377 | |
2378 // Neither argument is a string. | |
2379 __ bind(&call_add_runtime); | |
2380 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION); | 2284 __ InvokeBuiltin(Builtins::ADD, JUMP_FUNCTION); |
2381 break; | 2285 break; |
2382 } | |
2383 case Token::SUB: | 2286 case Token::SUB: |
2384 GenerateRegisterArgsPush(masm); | 2287 GenerateRegisterArgsPush(masm); |
2385 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION); | 2288 __ InvokeBuiltin(Builtins::SUB, JUMP_FUNCTION); |
2386 break; | 2289 break; |
2387 case Token::MUL: | 2290 case Token::MUL: |
2388 GenerateRegisterArgsPush(masm); | 2291 GenerateRegisterArgsPush(masm); |
2389 __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION); | 2292 __ InvokeBuiltin(Builtins::MUL, JUMP_FUNCTION); |
2390 break; | 2293 break; |
2391 case Token::DIV: | 2294 case Token::DIV: |
2392 GenerateRegisterArgsPush(masm); | 2295 GenerateRegisterArgsPush(masm); |
2393 __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION); | 2296 __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION); |
2394 break; | 2297 break; |
2395 case Token::MOD: | 2298 case Token::MOD: |
| 2299 GenerateRegisterArgsPush(masm); |
2396 __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION); | 2300 __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION); |
2397 break; | 2301 break; |
2398 case Token::BIT_OR: | 2302 case Token::BIT_OR: |
2399 __ InvokeBuiltin(Builtins::BIT_OR, JUMP_FUNCTION); | 2303 __ InvokeBuiltin(Builtins::BIT_OR, JUMP_FUNCTION); |
2400 break; | 2304 break; |
2401 case Token::BIT_AND: | 2305 case Token::BIT_AND: |
2402 __ InvokeBuiltin(Builtins::BIT_AND, JUMP_FUNCTION); | 2306 __ InvokeBuiltin(Builtins::BIT_AND, JUMP_FUNCTION); |
2403 break; | 2307 break; |
2404 case Token::BIT_XOR: | 2308 case Token::BIT_XOR: |
2405 __ InvokeBuiltin(Builtins::BIT_XOR, JUMP_FUNCTION); | 2309 __ InvokeBuiltin(Builtins::BIT_XOR, JUMP_FUNCTION); |
(...skipping 4101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6507 // Do a tail call to the rewritten stub. | 6411 // Do a tail call to the rewritten stub. |
6508 __ jmp(Operand(edi)); | 6412 __ jmp(Operand(edi)); |
6509 } | 6413 } |
6510 | 6414 |
6511 | 6415 |
6512 #undef __ | 6416 #undef __ |
6513 | 6417 |
6514 } } // namespace v8::internal | 6418 } } // namespace v8::internal |
6515 | 6419 |
6516 #endif // V8_TARGET_ARCH_IA32 | 6420 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |