Mercurial > hg > truffle
comparison src/share/vm/runtime/sharedRuntime.cpp @ 742:45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
Summary: Use CodeCache buffer blob instead of static buffer in AdapterHandlerLibrary.
Reviewed-by: never
author | kvn |
---|---|
date | Wed, 29 Apr 2009 12:58:09 -0700 |
parents | e5b0439ef4ae |
children | df6caf649ff7 |
comparison
equal
deleted
inserted
replaced
732:fb4c18a2ec66 | 742:45463a04ca27 |
---|---|
1774 // Implementation of AdapterHandlerLibrary | 1774 // Implementation of AdapterHandlerLibrary |
1775 const char* AdapterHandlerEntry::name = "I2C/C2I adapters"; | 1775 const char* AdapterHandlerEntry::name = "I2C/C2I adapters"; |
1776 GrowableArray<uint64_t>* AdapterHandlerLibrary::_fingerprints = NULL; | 1776 GrowableArray<uint64_t>* AdapterHandlerLibrary::_fingerprints = NULL; |
1777 GrowableArray<AdapterHandlerEntry* >* AdapterHandlerLibrary::_handlers = NULL; | 1777 GrowableArray<AdapterHandlerEntry* >* AdapterHandlerLibrary::_handlers = NULL; |
1778 const int AdapterHandlerLibrary_size = 16*K; | 1778 const int AdapterHandlerLibrary_size = 16*K; |
1779 u_char AdapterHandlerLibrary::_buffer[AdapterHandlerLibrary_size + 32]; | 1779 BufferBlob* AdapterHandlerLibrary::_buffer = NULL; |
1780 | |
1781 BufferBlob* AdapterHandlerLibrary::buffer_blob() { | |
1782 // Should be called only when AdapterHandlerLibrary_lock is active. | |
1783 if (_buffer == NULL) // Initialize lazily | |
1784 _buffer = BufferBlob::create("adapters", AdapterHandlerLibrary_size); | |
1785 return _buffer; | |
1786 } | |
1780 | 1787 |
1781 void AdapterHandlerLibrary::initialize() { | 1788 void AdapterHandlerLibrary::initialize() { |
1782 if (_fingerprints != NULL) return; | 1789 if (_fingerprints != NULL) return; |
1783 _fingerprints = new(ResourceObj::C_HEAP)GrowableArray<uint64_t>(32, true); | 1790 _fingerprints = new(ResourceObj::C_HEAP)GrowableArray<uint64_t>(32, true); |
1784 _handlers = new(ResourceObj::C_HEAP)GrowableArray<AdapterHandlerEntry*>(32, true); | 1791 _handlers = new(ResourceObj::C_HEAP)GrowableArray<AdapterHandlerEntry*>(32, true); |
1810 // earlier. | 1817 // earlier. |
1811 address ic_miss = SharedRuntime::get_ic_miss_stub(); | 1818 address ic_miss = SharedRuntime::get_ic_miss_stub(); |
1812 assert(ic_miss != NULL, "must have handler"); | 1819 assert(ic_miss != NULL, "must have handler"); |
1813 | 1820 |
1814 int result; | 1821 int result; |
1822 NOT_PRODUCT(int code_size); | |
1815 BufferBlob *B = NULL; | 1823 BufferBlob *B = NULL; |
1824 AdapterHandlerEntry* entry = NULL; | |
1816 uint64_t fingerprint; | 1825 uint64_t fingerprint; |
1817 { | 1826 { |
1818 MutexLocker mu(AdapterHandlerLibrary_lock); | 1827 MutexLocker mu(AdapterHandlerLibrary_lock); |
1819 // make sure data structure is initialized | 1828 // make sure data structure is initialized |
1820 initialize(); | 1829 initialize(); |
1848 // adapters). | 1857 // adapters). |
1849 } | 1858 } |
1850 | 1859 |
1851 // Create I2C & C2I handlers | 1860 // Create I2C & C2I handlers |
1852 ResourceMark rm; | 1861 ResourceMark rm; |
1853 // Improve alignment slightly | 1862 |
1854 u_char *buf = (u_char*)(((intptr_t)_buffer + CodeEntryAlignment-1) & ~(CodeEntryAlignment-1)); | 1863 BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache |
1855 CodeBuffer buffer(buf, AdapterHandlerLibrary_size); | 1864 if (buf != NULL) { |
1856 short buffer_locs[20]; | 1865 CodeBuffer buffer(buf->instructions_begin(), buf->instructions_size()); |
1857 buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs, | 1866 short buffer_locs[20]; |
1858 sizeof(buffer_locs)/sizeof(relocInfo)); | 1867 buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs, |
1859 MacroAssembler _masm(&buffer); | 1868 sizeof(buffer_locs)/sizeof(relocInfo)); |
1860 | 1869 MacroAssembler _masm(&buffer); |
1861 // Fill in the signature array, for the calling-convention call. | 1870 |
1862 int total_args_passed = method->size_of_parameters(); // All args on stack | 1871 // Fill in the signature array, for the calling-convention call. |
1863 | 1872 int total_args_passed = method->size_of_parameters(); // All args on stack |
1864 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType,total_args_passed); | 1873 |
1865 VMRegPair * regs = NEW_RESOURCE_ARRAY(VMRegPair ,total_args_passed); | 1874 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType,total_args_passed); |
1866 int i=0; | 1875 VMRegPair * regs = NEW_RESOURCE_ARRAY(VMRegPair ,total_args_passed); |
1867 if( !method->is_static() ) // Pass in receiver first | 1876 int i=0; |
1868 sig_bt[i++] = T_OBJECT; | 1877 if( !method->is_static() ) // Pass in receiver first |
1869 for( SignatureStream ss(method->signature()); !ss.at_return_type(); ss.next()) { | 1878 sig_bt[i++] = T_OBJECT; |
1870 sig_bt[i++] = ss.type(); // Collect remaining bits of signature | 1879 for( SignatureStream ss(method->signature()); !ss.at_return_type(); ss.next()) { |
1871 if( ss.type() == T_LONG || ss.type() == T_DOUBLE ) | 1880 sig_bt[i++] = ss.type(); // Collect remaining bits of signature |
1872 sig_bt[i++] = T_VOID; // Longs & doubles take 2 Java slots | 1881 if( ss.type() == T_LONG || ss.type() == T_DOUBLE ) |
1873 } | 1882 sig_bt[i++] = T_VOID; // Longs & doubles take 2 Java slots |
1874 assert( i==total_args_passed, "" ); | 1883 } |
1875 | 1884 assert( i==total_args_passed, "" ); |
1876 // Now get the re-packed compiled-Java layout. | 1885 |
1877 int comp_args_on_stack; | 1886 // Now get the re-packed compiled-Java layout. |
1878 | 1887 int comp_args_on_stack; |
1879 // Get a description of the compiled java calling convention and the largest used (VMReg) stack slot usage | 1888 |
1880 comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false); | 1889 // Get a description of the compiled java calling convention and the largest used (VMReg) stack slot usage |
1881 | 1890 comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false); |
1882 AdapterHandlerEntry* entry = SharedRuntime::generate_i2c2i_adapters(&_masm, | 1891 |
1883 total_args_passed, | 1892 entry = SharedRuntime::generate_i2c2i_adapters(&_masm, |
1884 comp_args_on_stack, | 1893 total_args_passed, |
1885 sig_bt, | 1894 comp_args_on_stack, |
1886 regs); | 1895 sig_bt, |
1887 | 1896 regs); |
1888 B = BufferBlob::create(AdapterHandlerEntry::name, &buffer); | 1897 |
1898 B = BufferBlob::create(AdapterHandlerEntry::name, &buffer); | |
1899 NOT_PRODUCT(code_size = buffer.code_size()); | |
1900 } | |
1889 if (B == NULL) { | 1901 if (B == NULL) { |
1890 // CodeCache is full, disable compilation | 1902 // CodeCache is full, disable compilation |
1891 // Ought to log this but compile log is only per compile thread | 1903 // Ought to log this but compile log is only per compile thread |
1892 // and we're some non descript Java thread. | 1904 // and we're some non descript Java thread. |
1893 UseInterpreter = true; | 1905 UseInterpreter = true; |
1910 // debugging suppport | 1922 // debugging suppport |
1911 if (PrintAdapterHandlers) { | 1923 if (PrintAdapterHandlers) { |
1912 tty->cr(); | 1924 tty->cr(); |
1913 tty->print_cr("i2c argument handler #%d for: %s %s (fingerprint = 0x%llx, %d bytes generated)", | 1925 tty->print_cr("i2c argument handler #%d for: %s %s (fingerprint = 0x%llx, %d bytes generated)", |
1914 _handlers->length(), (method->is_static() ? "static" : "receiver"), | 1926 _handlers->length(), (method->is_static() ? "static" : "receiver"), |
1915 method->signature()->as_C_string(), fingerprint, buffer.code_size() ); | 1927 method->signature()->as_C_string(), fingerprint, code_size ); |
1916 tty->print_cr("c2i argument handler starts at %p",entry->get_c2i_entry()); | 1928 tty->print_cr("c2i argument handler starts at %p",entry->get_c2i_entry()); |
1917 Disassembler::decode(entry->get_i2c_entry(), entry->get_i2c_entry() + buffer.code_size()); | 1929 Disassembler::decode(entry->get_i2c_entry(), entry->get_i2c_entry() + code_size); |
1918 } | 1930 } |
1919 #endif | 1931 #endif |
1920 | 1932 |
1921 // add handlers to library | 1933 // add handlers to library |
1922 _fingerprints->append(fingerprint); | 1934 _fingerprints->append(fingerprint); |
1980 nm = method->code(); | 1992 nm = method->code(); |
1981 if (nm) { | 1993 if (nm) { |
1982 return nm; | 1994 return nm; |
1983 } | 1995 } |
1984 | 1996 |
1985 // Improve alignment slightly | 1997 ResourceMark rm; |
1986 u_char* buf = (u_char*)(((intptr_t)_buffer + CodeEntryAlignment-1) & ~(CodeEntryAlignment-1)); | 1998 |
1987 CodeBuffer buffer(buf, AdapterHandlerLibrary_size); | 1999 BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache |
1988 // Need a few relocation entries | 2000 if (buf != NULL) { |
1989 double locs_buf[20]; | 2001 CodeBuffer buffer(buf->instructions_begin(), buf->instructions_size()); |
1990 buffer.insts()->initialize_shared_locs((relocInfo*)locs_buf, sizeof(locs_buf) / sizeof(relocInfo)); | 2002 double locs_buf[20]; |
1991 MacroAssembler _masm(&buffer); | 2003 buffer.insts()->initialize_shared_locs((relocInfo*)locs_buf, sizeof(locs_buf) / sizeof(relocInfo)); |
1992 | 2004 MacroAssembler _masm(&buffer); |
1993 // Fill in the signature array, for the calling-convention call. | 2005 |
1994 int total_args_passed = method->size_of_parameters(); | 2006 // Fill in the signature array, for the calling-convention call. |
1995 | 2007 int total_args_passed = method->size_of_parameters(); |
1996 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType,total_args_passed); | 2008 |
1997 VMRegPair * regs = NEW_RESOURCE_ARRAY(VMRegPair ,total_args_passed); | 2009 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType,total_args_passed); |
1998 int i=0; | 2010 VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair,total_args_passed); |
1999 if( !method->is_static() ) // Pass in receiver first | 2011 int i=0; |
2000 sig_bt[i++] = T_OBJECT; | 2012 if( !method->is_static() ) // Pass in receiver first |
2001 SignatureStream ss(method->signature()); | 2013 sig_bt[i++] = T_OBJECT; |
2002 for( ; !ss.at_return_type(); ss.next()) { | 2014 SignatureStream ss(method->signature()); |
2003 sig_bt[i++] = ss.type(); // Collect remaining bits of signature | 2015 for( ; !ss.at_return_type(); ss.next()) { |
2004 if( ss.type() == T_LONG || ss.type() == T_DOUBLE ) | 2016 sig_bt[i++] = ss.type(); // Collect remaining bits of signature |
2005 sig_bt[i++] = T_VOID; // Longs & doubles take 2 Java slots | 2017 if( ss.type() == T_LONG || ss.type() == T_DOUBLE ) |
2006 } | 2018 sig_bt[i++] = T_VOID; // Longs & doubles take 2 Java slots |
2007 assert( i==total_args_passed, "" ); | 2019 } |
2008 BasicType ret_type = ss.type(); | 2020 assert( i==total_args_passed, "" ); |
2009 | 2021 BasicType ret_type = ss.type(); |
2010 // Now get the compiled-Java layout as input arguments | 2022 |
2011 int comp_args_on_stack; | 2023 // Now get the compiled-Java layout as input arguments |
2012 comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false); | 2024 int comp_args_on_stack; |
2013 | 2025 comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false); |
2014 // Generate the compiled-to-native wrapper code | 2026 |
2015 nm = SharedRuntime::generate_native_wrapper(&_masm, | 2027 // Generate the compiled-to-native wrapper code |
2016 method, | 2028 nm = SharedRuntime::generate_native_wrapper(&_masm, |
2017 total_args_passed, | 2029 method, |
2018 comp_args_on_stack, | 2030 total_args_passed, |
2019 sig_bt,regs, | 2031 comp_args_on_stack, |
2020 ret_type); | 2032 sig_bt,regs, |
2033 ret_type); | |
2034 } | |
2021 } | 2035 } |
2022 | 2036 |
2023 // Must unlock before calling set_code | 2037 // Must unlock before calling set_code |
2024 // Install the generated code. | 2038 // Install the generated code. |
2025 if (nm != NULL) { | 2039 if (nm != NULL) { |
2075 nm = method->code(); | 2089 nm = method->code(); |
2076 if (nm) { | 2090 if (nm) { |
2077 return nm; | 2091 return nm; |
2078 } | 2092 } |
2079 | 2093 |
2080 // Improve alignment slightly | 2094 ResourceMark rm; |
2081 u_char* buf = (u_char*) | 2095 |
2082 (((intptr_t)_buffer + CodeEntryAlignment-1) & ~(CodeEntryAlignment-1)); | 2096 BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache |
2083 CodeBuffer buffer(buf, AdapterHandlerLibrary_size); | 2097 if (buf != NULL) { |
2084 // Need a few relocation entries | 2098 CodeBuffer buffer(buf->instructions_begin(), buf->instructions_size()); |
2085 double locs_buf[20]; | 2099 // Need a few relocation entries |
2086 buffer.insts()->initialize_shared_locs( | 2100 double locs_buf[20]; |
2101 buffer.insts()->initialize_shared_locs( | |
2087 (relocInfo*)locs_buf, sizeof(locs_buf) / sizeof(relocInfo)); | 2102 (relocInfo*)locs_buf, sizeof(locs_buf) / sizeof(relocInfo)); |
2088 MacroAssembler _masm(&buffer); | 2103 MacroAssembler _masm(&buffer); |
2089 | 2104 |
2090 // Generate the compiled-to-native wrapper code | 2105 // Generate the compiled-to-native wrapper code |
2091 nm = SharedRuntime::generate_dtrace_nmethod(&_masm, method); | 2106 nm = SharedRuntime::generate_dtrace_nmethod(&_masm, method); |
2107 } | |
2092 } | 2108 } |
2093 return nm; | 2109 return nm; |
2094 } | 2110 } |
2095 | 2111 |
2096 // the dtrace method needs to convert java lang string to utf8 string. | 2112 // the dtrace method needs to convert java lang string to utf8 string. |