comparison src/cpu/x86/vm/c1_Runtime1_x86.cpp @ 1434:72cfb36c6bb2

* enabled all jtt tests * added proxy that counts jni calls * honor hotspot stackshadowpages * constant pool caching * monitor enter/exit * arithmetic stubs (frem, drem, ...) * create stack values for debug info * some doc
author Lukas Stadler <lukas.stadler@oracle.com>
date Thu, 30 Sep 2010 17:19:48 -0700
parents abc670a709dc
children 8cfe3537a0d3
comparison
equal deleted inserted replaced
1433:efba53f86c4f 1434:72cfb36c6bb2
1828 1828
1829 } 1829 }
1830 break; 1830 break;
1831 #endif // !SERIALGC 1831 #endif // !SERIALGC
1832 1832
1833 case c1x_unwind_exception_call_id: 1833 case c1x_unwind_exception_call_id: {
1834 // remove the frame from the stack
1835 __ movptr(rsp, rbp);
1836 __ pop(rbp);
1837 // exception_oop is passed using ordinary java calling conventions
1838 __ movptr(rax, j_rarg0);
1839
1840 Label nonNullExceptionOop;
1841 __ testptr(rax, rax);
1842 __ jcc(Assembler::notZero, nonNullExceptionOop);
1834 { 1843 {
1835 // remove the frame from the stack 1844 __ enter();
1836 __ movptr(rsp, rbp);
1837 __ pop(rbp);
1838 // exception_oop is passed using ordinary java calling conventions
1839 __ movptr(rax, j_rarg0);
1840
1841 Label nonNullExceptionOop;
1842 __ testptr(rax, rax);
1843 __ jcc(Assembler::notZero, nonNullExceptionOop);
1844 {
1845 __ enter();
1846 oop_maps = new OopMapSet();
1847 OopMap* oop_map = save_live_registers(sasm, 0);
1848 int call_offset = __ call_RT(rax, noreg, (address)c1x_create_null_exception, 0);
1849 oop_maps->add_gc_map(call_offset, oop_map);
1850 __ leave();
1851 }
1852 __ bind(nonNullExceptionOop);
1853
1854 __ set_info("unwind_exception", dont_gc_arguments);
1855 // note: no stubframe since we are about to leave the current
1856 // activation and we are calling a leaf VM function only.
1857 generate_unwind_exception(sasm);
1858 __ should_not_reach_here();
1859 }
1860 break;
1861
1862 case c1x_handle_exception_id:
1863 { StubFrame f(sasm, "c1x_handle_exception", dont_gc_arguments);
1864 oop_maps = new OopMapSet(); 1845 oop_maps = new OopMapSet();
1865 OopMap* oop_map = save_live_registers(sasm, 1, false); 1846 OopMap* oop_map = save_live_registers(sasm, 0);
1866 c1x_generate_handle_exception(sasm, oop_maps, oop_map); 1847 int call_offset = __ call_RT(rax, noreg, (address)c1x_create_null_exception, 0);
1867 } 1848 oop_maps->add_gc_map(call_offset, oop_map);
1868 break; 1849 __ leave();
1869 1850 }
1870 case c1x_global_implicit_null_id: 1851 __ bind(nonNullExceptionOop);
1852
1853 __ set_info("unwind_exception", dont_gc_arguments);
1854 // note: no stubframe since we are about to leave the current
1855 // activation and we are calling a leaf VM function only.
1856 generate_unwind_exception(sasm);
1857 __ should_not_reach_here();
1858 break;
1859 }
1860
1861 case c1x_handle_exception_id: {
1862 StubFrame f(sasm, "c1x_handle_exception", dont_gc_arguments);
1863 oop_maps = new OopMapSet();
1864 OopMap* oop_map = save_live_registers(sasm, 1, false);
1865 c1x_generate_handle_exception(sasm, oop_maps, oop_map);
1866 break;
1867 }
1868
1869 case c1x_global_implicit_null_id: {
1870 __ push(rax);
1871 __ push(rax);
1872 // move saved fp to make space for the inserted return address
1873 __ get_thread(rax);
1874 __ movptr(rax, Address(rax, JavaThread::saved_exception_pc_offset()));
1875 __ movptr(Address(rsp, HeapWordSize), rax);
1876 __ pop(rax);
1877
1878 { StubFrame f(sasm, "c1x_global_implicit_null_id", dont_gc_arguments);
1879 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception), false);
1880 }
1881 break;
1882 }
1883
1884 case c1x_throw_div0_exception_id: {
1885 __ push(rax);
1886 __ push(rax);
1887 // move saved fp to make space for the inserted return address
1888 __ get_thread(rax);
1889 __ movptr(rax, Address(rax, JavaThread::saved_exception_pc_offset()));
1890 __ movptr(Address(rsp, HeapWordSize), rax);
1891 __ pop(rax);
1892
1893 { StubFrame f(sasm, "throw_div0_exception", dont_gc_arguments);
1894 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_div0_exception), false);
1895 }
1896 break;
1897 }
1898
1899 case c1x_slow_subtype_check_id: {
1900 Label success;
1901 Label miss;
1902
1903 // TODO this should really be within the XirSnippets
1904 __ check_klass_subtype_fast_path(j_rarg0, j_rarg1, j_rarg2, &success, &miss, NULL);
1905 __ check_klass_subtype_slow_path(j_rarg0, j_rarg1, j_rarg2, j_rarg3, NULL, &miss);
1906
1907 // fallthrough on success:
1908 __ bind(success);
1909 __ movptr(rax, 1);
1910 __ ret(0);
1911
1912 __ bind(miss);
1913 __ movptr(rax, NULL_WORD);
1914 __ ret(0);
1915 break;
1916 }
1917
1918 case c1x_arithmetic_frem_id: {
1919 __ subptr(rsp, 8);
1920 __ movflt(Address(rsp, 0), xmm1);
1921 __ fld_s(Address(rsp, 0));
1922 __ movflt(Address(rsp, 0), xmm0);
1923 __ fld_s(Address(rsp, 0));
1924 Label L;
1925 __ bind(L);
1926 __ fprem();
1927 __ fwait();
1928 __ fnstsw_ax();
1929 __ testl(rax, 0x400);
1930 __ jcc(Assembler::notZero, L);
1931 __ fxch(1);
1932 __ fpop();
1933 __ fstp_s(Address(rsp, 0));
1934 __ movflt(xmm0, Address(rsp, 0));
1935 __ addptr(rsp, 8);
1936 __ ret(0);
1937 break;
1938 }
1939 case c1x_arithmetic_drem_id: {
1940 __ subptr(rsp, 8);
1941 __ movdbl(Address(rsp, 0), xmm1);
1942 __ fld_d(Address(rsp, 0));
1943 __ movdbl(Address(rsp, 0), xmm0);
1944 __ fld_d(Address(rsp, 0));
1945 Label L;
1946 __ bind(L);
1947 __ fprem();
1948 __ fwait();
1949 __ fnstsw_ax();
1950 __ testl(rax, 0x400);
1951 __ jcc(Assembler::notZero, L);
1952 __ fxch(1);
1953 __ fpop();
1954 __ fstp_d(Address(rsp, 0));
1955 __ movdbl(xmm0, Address(rsp, 0));
1956 __ addptr(rsp, 8);
1957 __ ret(0);
1958 break;
1959 }
1960 case c1x_monitorenter_id: {
1961 Label slow_case;
1962
1963 Register obj = j_rarg0;
1964 Register lock = j_rarg1;
1965
1966 Register scratch1 = rax;
1967 Register scratch2 = rbx;
1968
1969 // copied from LIR_Assembler::emit_lock
1970 if (UseFastLocking) {
1971 assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
1972 __ lock_object(scratch1, obj, lock, scratch2, slow_case);
1973 __ ret(0);
1974 }
1975
1976 __ bind(slow_case);
1871 { 1977 {
1872 __ push(rax); 1978 StubFrame f(sasm, "c1x_monitorenter", dont_gc_arguments);
1873 __ push(rax); 1979 OopMap* map = save_live_registers(sasm, 1, save_fpu_registers);
1874 // move saved fp to make space for the inserted return address 1980
1875 __ get_thread(rax); 1981 // Called with store_parameter and not C abi
1876 __ movptr(rax, Address(rax, JavaThread::saved_exception_pc_offset())); 1982 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorenter), obj, lock);
1877 __ movptr(Address(rsp, HeapWordSize), rax); 1983
1878 __ pop(rax); 1984 oop_maps = new OopMapSet();
1879 1985 oop_maps->add_gc_map(call_offset, map);
1880 { StubFrame f(sasm, "c1x_global_implicit_null_id", dont_gc_arguments); 1986 restore_live_registers(sasm, save_fpu_registers);
1881 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception), false); 1987 }
1882 } 1988 __ ret(0);
1883 } 1989 break;
1884 break; 1990 }
1885 1991 case c1x_monitorexit_id: {
1886 case c1x_throw_div0_exception_id: 1992 Label slow_case;
1993
1994 Register obj = j_rarg0;
1995 Register lock = j_rarg1;
1996
1997 // needed in rax later on...
1998 Register lock2 = rax;
1999 __ mov(lock2, lock);
2000 Register scratch1 = rbx;
2001
2002 // copied from LIR_Assembler::emit_lock
2003 if (UseFastLocking) {
2004 assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
2005 __ unlock_object(scratch1, obj, lock2, slow_case);
2006 __ ret(0);
2007 }
2008
2009 __ bind(slow_case);
1887 { 2010 {
1888 __ push(rax); 2011 StubFrame f(sasm, "c1x_monitorexit", dont_gc_arguments);
1889 __ push(rax); 2012 OopMap* map = save_live_registers(sasm, 2, save_fpu_registers);
1890 // move saved fp to make space for the inserted return address 2013
1891 __ get_thread(rax); 2014 // note: really a leaf routine but must setup last java sp
1892 __ movptr(rax, Address(rax, JavaThread::saved_exception_pc_offset())); 2015 // => use call_RT for now (speed can be improved by
1893 __ movptr(Address(rsp, HeapWordSize), rax); 2016 // doing last java sp setup manually)
1894 __ pop(rax); 2017 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorexit), lock);
1895 2018
1896 { StubFrame f(sasm, "throw_div0_exception", dont_gc_arguments); 2019 oop_maps = new OopMapSet();
1897 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_div0_exception), false); 2020 oop_maps->add_gc_map(call_offset, map);
1898 } 2021 restore_live_registers(sasm, save_fpu_registers);
1899 } 2022 }
1900 break; 2023 __ ret(0);
1901 2024 break;
1902 case c1x_slow_subtype_check_id: 2025 }
1903 { 2026
1904 Label success; 2027
1905 Label miss; 2028
1906 2029
1907 // TODO this should really be within the XirSnippets
1908 __ check_klass_subtype_fast_path(j_rarg0, j_rarg1, j_rarg2, &success, &miss, NULL);
1909 __ check_klass_subtype_slow_path(j_rarg0, j_rarg1, j_rarg2, j_rarg3, NULL, &miss);
1910
1911 // fallthrough on success:
1912 __ bind(success);
1913 __ movptr(rax, 1);
1914 __ ret(0);
1915
1916 __ bind(miss);
1917 __ movptr(rax, NULL_WORD);
1918 __ ret(0);
1919 }
1920 break;
1921 default: 2030 default:
1922 { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments); 2031 { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments);
1923 __ movptr(rax, (int)id); 2032 __ movptr(rax, (int)id);
1924 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), rax); 2033 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), rax);
1925 __ should_not_reach_here(); 2034 __ should_not_reach_here();