Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: src/ia32/stub-cache-ia32.cc

Issue 3327022: Custom call IC for Math.floor. (Closed)
Patch Set: Oops, forgot to upload the test Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 1795 matching lines...) Expand 10 before | Expand all | Expand 10 after
1806 __ bind(&miss); 1806 __ bind(&miss);
1807 // ecx: function name. 1807 // ecx: function name.
1808 Object* obj = GenerateMissBranch(); 1808 Object* obj = GenerateMissBranch();
1809 if (obj->IsFailure()) return obj; 1809 if (obj->IsFailure()) return obj;
1810 1810
1811 // Return the generated code. 1811 // Return the generated code.
1812 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 1812 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name);
1813 } 1813 }
1814 1814
1815 1815
1816 Object* CallStubCompiler::CompileMathFloorCall(Object* object,
1817 JSObject* holder,
1818 JSGlobalPropertyCell* cell,
1819 JSFunction* function,
1820 String* name) {
1821 // ----------- S t a t e -------------
1822 // -- ecx : name
1823 // -- esp[0] : return address
1824 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1825 // -- ...
1826 // -- esp[(argc + 1) * 4] : receiver
1827 // -----------------------------------
1828
1829 if (!CpuFeatures::IsSupported(SSE2)) return Heap::undefined_value();
1830 CpuFeatures::Scope use_sse2(SSE2);
1831
1832 const int argc = arguments().immediate();
1833
1834 // If the object is not a JSObject or we got an unexpected number of
1835 // arguments, bail out to the regular call.
1836 if (!object->IsJSObject() || argc != 1) return Heap::undefined_value();
1837
1838 Label miss;
1839 GenerateNameCheck(name, &miss);
1840
1841 if (cell == NULL) {
1842 __ mov(edx, Operand(esp, 2 * kPointerSize));
1843
1844 STATIC_ASSERT(kSmiTag == 0);
1845 __ test(edx, Immediate(kSmiTagMask));
1846 __ j(zero, &miss);
1847
1848 CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name,
1849 &miss);
1850 } else {
1851 ASSERT(cell->value() == function);
1852 GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss);
1853 GenerateLoadFunctionFromCell(cell, function, &miss);
1854 }
1855
1856 // Load the (only) argument into eax.
1857 __ mov(eax, Operand(esp, 1 * kPointerSize));
1858
1859 // Check if the argument is a smi.
1860 Label smi;
1861 STATIC_ASSERT(kSmiTag == 0);
1862 __ test(eax, Immediate(kSmiTagMask));
1863 __ j(zero, &smi);
1864
1865 // Check if the argument is a heap number and load its value into xmm0.
1866 Label slow;
1867 __ CheckMap(eax, Factory::heap_number_map(), &slow, true);
1868 __ movdbl(xmm0, FieldOperand(eax, HeapNumber::kValueOffset));
1869
1870 // Check if the argument is strictly positive. Note this also
1871 // discards NaN.
Erik Corry 2010/09/20 11:56:50 It might be nice to detect +- zero and pass it thr
Vitaly Repeshko 2010/09/21 12:54:49 I filed a bug to consider extending it.
1872 __ xorpd(xmm1, xmm1);
1873 __ ucomisd(xmm0, xmm1);
1874 __ j(below_equal, &slow);
1875
1876 // Do a truncating conversion.
1877 __ cvttsd2si(eax, Operand(xmm0));
1878
1879 // Check if the result fits into a smi. Note this also checks for
1880 // 0x80000000 which signals a failed conversion.
1881 Label wont_fit_into_smi;
1882 __ test(eax, Immediate(0xc0000000));
1883 __ j(not_zero, &wont_fit_into_smi);
1884
1885 // Smi tag and return.
1886 __ SmiTag(eax);
1887 __ bind(&smi);
1888 __ ret(2 * kPointerSize);
1889
1890 // Check if the argument is < 2^kMantissaBits.
1891 Label already_round;
1892 __ bind(&wont_fit_into_smi);
1893 __ LoadPowerOf2(xmm1, ebx, HeapNumber::kMantissaBits);
1894 __ ucomisd(xmm0, xmm1);
1895 __ j(above_equal, &already_round);
1896
1897 // Save a copy of the argument.
1898 __ movaps(xmm2, Operand(xmm0));
1899
1900 // Compute (argument + 2^kMantissaBits) - 2^kMantissaBits.
1901 __ addsd(xmm0, xmm1);
1902 __ subsd(xmm0, xmm1);
1903
1904 // Compare the argument and the tentative result to get the right mask:
1905 // if xmm2 < xmm0:
1906 // xmm2 = 1...1
1907 // else:
1908 // xmm2 = 0...0
1909 __ cmpltsd(xmm2, xmm0);
1910
1911 // Subtract 1 if the argument was less than the tentative result.
1912 __ LoadPowerOf2(xmm1, ebx, 0);
1913 __ andpd(xmm1, Operand(xmm2));
1914 __ subsd(xmm0, xmm1);
1915
1916 // Return a new heap number.
1917 __ AllocateHeapNumber(eax, ebx, edx, &slow);
1918 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
1919 __ ret(2 * kPointerSize);
1920
1921 // Return the argument (when it's an already round heap number).
1922 __ bind(&already_round);
1923 __ mov(eax, Operand(esp, 1 * kPointerSize));
1924 __ ret(2 * kPointerSize);
1925
1926 // Tail call the full function. We do not have to patch the receiver
1927 // because the function makes no use of it.
1928 __ bind(&slow);
1929 __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
1930
1931 __ bind(&miss);
1932 // ecx: function name.
1933 Object* obj = GenerateMissBranch();
1934 if (obj->IsFailure()) return obj;
1935
1936 // Return the generated code.
1937 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name);
1938 }
1939
1940
1816 Object* CallStubCompiler::CompileCallConstant(Object* object, 1941 Object* CallStubCompiler::CompileCallConstant(Object* object,
1817 JSObject* holder, 1942 JSObject* holder,
1818 JSFunction* function, 1943 JSFunction* function,
1819 String* name, 1944 String* name,
1820 CheckType check) { 1945 CheckType check) {
1821 // ----------- S t a t e ------------- 1946 // ----------- S t a t e -------------
1822 // -- ecx : name 1947 // -- ecx : name
1823 // -- esp[0] : return address 1948 // -- esp[0] : return address
1824 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1949 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1825 // -- ... 1950 // -- ...
(...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after
2820 // Return the generated code. 2945 // Return the generated code.
2821 return GetCode(); 2946 return GetCode();
2822 } 2947 }
2823 2948
2824 2949
2825 #undef __ 2950 #undef __
2826 2951
2827 } } // namespace v8::internal 2952 } } // namespace v8::internal
2828 2953
2829 #endif // V8_TARGET_ARCH_IA32 2954 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698