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.