| 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 |