Mercurial > hg > truffle
comparison src/share/vm/runtime/sharedRuntime.cpp @ 1187:cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
Reviewed-by: kvn, jrose
author | never |
---|---|
date | Wed, 20 Jan 2010 22:10:33 -0800 |
parents | 4ce7240d622c |
children | ba263cfb7611 6deeaebad47a |
comparison
equal
deleted
inserted
replaced
1179:3d6016e040d6 | 1187:cf0685d550f1 |
---|---|
1 /* | 1 /* |
2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. | 2 * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
1678 if( _generic_array_copy_ctr ) tty->print_cr("%5d generic array copies", _generic_array_copy_ctr ); | 1678 if( _generic_array_copy_ctr ) tty->print_cr("%5d generic array copies", _generic_array_copy_ctr ); |
1679 if( _slow_array_copy_ctr ) tty->print_cr("%5d slow array copies", _slow_array_copy_ctr ); | 1679 if( _slow_array_copy_ctr ) tty->print_cr("%5d slow array copies", _slow_array_copy_ctr ); |
1680 if( _find_handler_ctr ) tty->print_cr("%5d find exception handler", _find_handler_ctr ); | 1680 if( _find_handler_ctr ) tty->print_cr("%5d find exception handler", _find_handler_ctr ); |
1681 if( _rethrow_ctr ) tty->print_cr("%5d rethrow handler", _rethrow_ctr ); | 1681 if( _rethrow_ctr ) tty->print_cr("%5d rethrow handler", _rethrow_ctr ); |
1682 | 1682 |
1683 AdapterHandlerLibrary::print_statistics(); | |
1684 | |
1683 if (xtty != NULL) xtty->tail("statistics"); | 1685 if (xtty != NULL) xtty->tail("statistics"); |
1684 } | 1686 } |
1685 | 1687 |
1686 inline double percent(int x, int y) { | 1688 inline double percent(int x, int y) { |
1687 return 100.0 * x / MAX2(y, 1); | 1689 return 100.0 * x / MAX2(y, 1); |
1778 MethodArityHistogram h; | 1780 MethodArityHistogram h; |
1779 } | 1781 } |
1780 #endif | 1782 #endif |
1781 | 1783 |
1782 | 1784 |
1785 // A simple wrapper class around the calling convention information | |
1786 // that allows sharing of adapters for the same calling convention. | |
1787 class AdapterFingerPrint : public CHeapObj { | |
1788 private: | |
1789 union { | |
1790 signed char _compact[12]; | |
1791 int _compact_int[3]; | |
1792 intptr_t* _fingerprint; | |
1793 } _value; | |
1794 int _length; // A negative length indicates that _value._fingerprint is the array. | |
1795 // Otherwise it's in the compact form. | |
1796 | |
1797 public: | |
1798 AdapterFingerPrint(int total_args_passed, VMRegPair* regs) { | |
1799 assert(sizeof(_value._compact) == sizeof(_value._compact_int), "must match"); | |
1800 _length = total_args_passed * 2; | |
1801 if (_length < (int)sizeof(_value._compact)) { | |
1802 _value._compact_int[0] = _value._compact_int[1] = _value._compact_int[2] = 0; | |
1803 // Storing the signature encoded as signed chars hits about 98% | |
1804 // of the time. | |
1805 signed char* ptr = _value._compact; | |
1806 int o = 0; | |
1807 for (int i = 0; i < total_args_passed; i++) { | |
1808 VMRegPair pair = regs[i]; | |
1809 intptr_t v1 = pair.first()->value(); | |
1810 intptr_t v2 = pair.second()->value(); | |
1811 if (v1 == (signed char) v1 && | |
1812 v2 == (signed char) v2) { | |
1813 _value._compact[o++] = v1; | |
1814 _value._compact[o++] = v2; | |
1815 } else { | |
1816 goto big; | |
1817 } | |
1818 } | |
1819 _length = -_length; | |
1820 return; | |
1821 } | |
1822 big: | |
1823 _value._fingerprint = NEW_C_HEAP_ARRAY(intptr_t, _length); | |
1824 int o = 0; | |
1825 for (int i = 0; i < total_args_passed; i++) { | |
1826 VMRegPair pair = regs[i]; | |
1827 intptr_t v1 = pair.first()->value(); | |
1828 intptr_t v2 = pair.second()->value(); | |
1829 _value._fingerprint[o++] = v1; | |
1830 _value._fingerprint[o++] = v2; | |
1831 } | |
1832 } | |
1833 | |
1834 AdapterFingerPrint(AdapterFingerPrint* orig) { | |
1835 _length = orig->_length; | |
1836 _value = orig->_value; | |
1837 // take ownership of any storage by destroying the length | |
1838 orig->_length = 0; | |
1839 } | |
1840 | |
1841 ~AdapterFingerPrint() { | |
1842 if (_length > 0) { | |
1843 FREE_C_HEAP_ARRAY(int, _value._fingerprint); | |
1844 } | |
1845 } | |
1846 | |
1847 AdapterFingerPrint* allocate() { | |
1848 return new AdapterFingerPrint(this); | |
1849 } | |
1850 | |
1851 intptr_t value(int index) { | |
1852 if (_length < 0) { | |
1853 return _value._compact[index]; | |
1854 } | |
1855 return _value._fingerprint[index]; | |
1856 } | |
1857 int length() { | |
1858 if (_length < 0) return -_length; | |
1859 return _length; | |
1860 } | |
1861 | |
1862 bool is_compact() { | |
1863 return _length <= 0; | |
1864 } | |
1865 | |
1866 unsigned int compute_hash() { | |
1867 intptr_t hash = 0; | |
1868 for (int i = 0; i < length(); i++) { | |
1869 intptr_t v = value(i); | |
1870 hash = (hash << 8) ^ v ^ (hash >> 5); | |
1871 } | |
1872 return (unsigned int)hash; | |
1873 } | |
1874 | |
1875 const char* as_string() { | |
1876 stringStream st; | |
1877 for (int i = 0; i < length(); i++) { | |
1878 st.print(PTR_FORMAT, value(i)); | |
1879 } | |
1880 return st.as_string(); | |
1881 } | |
1882 | |
1883 bool equals(AdapterFingerPrint* other) { | |
1884 if (other->_length != _length) { | |
1885 return false; | |
1886 } | |
1887 if (_length < 0) { | |
1888 return _value._compact_int[0] == other->_value._compact_int[0] && | |
1889 _value._compact_int[1] == other->_value._compact_int[1] && | |
1890 _value._compact_int[2] == other->_value._compact_int[2]; | |
1891 } else { | |
1892 for (int i = 0; i < _length; i++) { | |
1893 if (_value._fingerprint[i] != other->_value._fingerprint[i]) { | |
1894 return false; | |
1895 } | |
1896 } | |
1897 } | |
1898 return true; | |
1899 } | |
1900 }; | |
1901 | |
1902 | |
1903 // A hashtable mapping from AdapterFingerPrints to AdapterHandlerEntries | |
1904 class AdapterHandlerTable : public BasicHashtable { | |
1905 friend class AdapterHandlerTableIterator; | |
1906 | |
1907 private: | |
1908 | |
1909 #ifdef ASSERT | |
1910 static int _lookups; // number of calls to lookup | |
1911 static int _buckets; // number of buckets checked | |
1912 static int _equals; // number of buckets checked with matching hash | |
1913 static int _hits; // number of successful lookups | |
1914 static int _compact; // number of equals calls with compact signature | |
1915 #endif | |
1916 | |
1917 AdapterHandlerEntry* bucket(int i) { | |
1918 return (AdapterHandlerEntry*)BasicHashtable::bucket(i); | |
1919 } | |
1920 | |
1921 public: | |
1922 AdapterHandlerTable() | |
1923 : BasicHashtable(293, sizeof(AdapterHandlerEntry)) { } | |
1924 | |
1925 // Create a new entry suitable for insertion in the table | |
1926 AdapterHandlerEntry* new_entry(AdapterFingerPrint* fingerprint, address i2c_entry, address c2i_entry, address c2i_unverified_entry) { | |
1927 AdapterHandlerEntry* entry = (AdapterHandlerEntry*)BasicHashtable::new_entry(fingerprint->compute_hash()); | |
1928 entry->init(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry); | |
1929 return entry; | |
1930 } | |
1931 | |
1932 // Insert an entry into the table | |
1933 void add(AdapterHandlerEntry* entry) { | |
1934 int index = hash_to_index(entry->hash()); | |
1935 add_entry(index, entry); | |
1936 } | |
1937 | |
1938 // Find a entry with the same fingerprint if it exists | |
1939 AdapterHandlerEntry* lookup(int total_args_passed, VMRegPair* regs) { | |
1940 debug_only(_lookups++); | |
1941 AdapterFingerPrint fp(total_args_passed, regs); | |
1942 unsigned int hash = fp.compute_hash(); | |
1943 int index = hash_to_index(hash); | |
1944 for (AdapterHandlerEntry* e = bucket(index); e != NULL; e = e->next()) { | |
1945 debug_only(_buckets++); | |
1946 if (e->hash() == hash) { | |
1947 debug_only(_equals++); | |
1948 if (fp.equals(e->fingerprint())) { | |
1949 #ifdef ASSERT | |
1950 if (fp.is_compact()) _compact++; | |
1951 _hits++; | |
1952 #endif | |
1953 return e; | |
1954 } | |
1955 } | |
1956 } | |
1957 return NULL; | |
1958 } | |
1959 | |
1960 void print_statistics() { | |
1961 ResourceMark rm; | |
1962 int longest = 0; | |
1963 int empty = 0; | |
1964 int total = 0; | |
1965 int nonempty = 0; | |
1966 for (int index = 0; index < table_size(); index++) { | |
1967 int count = 0; | |
1968 for (AdapterHandlerEntry* e = bucket(index); e != NULL; e = e->next()) { | |
1969 count++; | |
1970 } | |
1971 if (count != 0) nonempty++; | |
1972 if (count == 0) empty++; | |
1973 if (count > longest) longest = count; | |
1974 total += count; | |
1975 } | |
1976 tty->print_cr("AdapterHandlerTable: empty %d longest %d total %d average %f", | |
1977 empty, longest, total, total / (double)nonempty); | |
1978 #ifdef ASSERT | |
1979 tty->print_cr("AdapterHandlerTable: lookups %d buckets %d equals %d hits %d compact %d", | |
1980 _lookups, _buckets, _equals, _hits, _compact); | |
1981 #endif | |
1982 } | |
1983 }; | |
1984 | |
1985 | |
1986 #ifdef ASSERT | |
1987 | |
1988 int AdapterHandlerTable::_lookups; | |
1989 int AdapterHandlerTable::_buckets; | |
1990 int AdapterHandlerTable::_equals; | |
1991 int AdapterHandlerTable::_hits; | |
1992 int AdapterHandlerTable::_compact; | |
1993 | |
1994 class AdapterHandlerTableIterator : public StackObj { | |
1995 private: | |
1996 AdapterHandlerTable* _table; | |
1997 int _index; | |
1998 AdapterHandlerEntry* _current; | |
1999 | |
2000 void scan() { | |
2001 while (_index < _table->table_size()) { | |
2002 AdapterHandlerEntry* a = _table->bucket(_index); | |
2003 if (a != NULL) { | |
2004 _current = a; | |
2005 return; | |
2006 } | |
2007 _index++; | |
2008 } | |
2009 } | |
2010 | |
2011 public: | |
2012 AdapterHandlerTableIterator(AdapterHandlerTable* table): _table(table), _index(0), _current(NULL) { | |
2013 scan(); | |
2014 } | |
2015 bool has_next() { | |
2016 return _current != NULL; | |
2017 } | |
2018 AdapterHandlerEntry* next() { | |
2019 if (_current != NULL) { | |
2020 AdapterHandlerEntry* result = _current; | |
2021 _current = _current->next(); | |
2022 if (_current == NULL) scan(); | |
2023 return result; | |
2024 } else { | |
2025 return NULL; | |
2026 } | |
2027 } | |
2028 }; | |
2029 #endif | |
2030 | |
2031 | |
1783 // --------------------------------------------------------------------------- | 2032 // --------------------------------------------------------------------------- |
1784 // Implementation of AdapterHandlerLibrary | 2033 // Implementation of AdapterHandlerLibrary |
1785 const char* AdapterHandlerEntry::name = "I2C/C2I adapters"; | 2034 const char* AdapterHandlerEntry::name = "I2C/C2I adapters"; |
1786 GrowableArray<uint64_t>* AdapterHandlerLibrary::_fingerprints = NULL; | 2035 AdapterHandlerTable* AdapterHandlerLibrary::_adapters = NULL; |
1787 GrowableArray<AdapterHandlerEntry* >* AdapterHandlerLibrary::_handlers = NULL; | 2036 AdapterHandlerEntry* AdapterHandlerLibrary::_abstract_method_handler = NULL; |
1788 const int AdapterHandlerLibrary_size = 16*K; | 2037 const int AdapterHandlerLibrary_size = 16*K; |
1789 BufferBlob* AdapterHandlerLibrary::_buffer = NULL; | 2038 BufferBlob* AdapterHandlerLibrary::_buffer = NULL; |
1790 | 2039 |
1791 BufferBlob* AdapterHandlerLibrary::buffer_blob() { | 2040 BufferBlob* AdapterHandlerLibrary::buffer_blob() { |
1792 // Should be called only when AdapterHandlerLibrary_lock is active. | 2041 // Should be called only when AdapterHandlerLibrary_lock is active. |
1794 _buffer = BufferBlob::create("adapters", AdapterHandlerLibrary_size); | 2043 _buffer = BufferBlob::create("adapters", AdapterHandlerLibrary_size); |
1795 return _buffer; | 2044 return _buffer; |
1796 } | 2045 } |
1797 | 2046 |
1798 void AdapterHandlerLibrary::initialize() { | 2047 void AdapterHandlerLibrary::initialize() { |
1799 if (_fingerprints != NULL) return; | 2048 if (_adapters != NULL) return; |
1800 _fingerprints = new(ResourceObj::C_HEAP)GrowableArray<uint64_t>(32, true); | 2049 _adapters = new AdapterHandlerTable(); |
1801 _handlers = new(ResourceObj::C_HEAP)GrowableArray<AdapterHandlerEntry*>(32, true); | |
1802 // Index 0 reserved for the slow path handler | |
1803 _fingerprints->append(0/*the never-allowed 0 fingerprint*/); | |
1804 _handlers->append(NULL); | |
1805 | 2050 |
1806 // Create a special handler for abstract methods. Abstract methods | 2051 // Create a special handler for abstract methods. Abstract methods |
1807 // are never compiled so an i2c entry is somewhat meaningless, but | 2052 // are never compiled so an i2c entry is somewhat meaningless, but |
1808 // fill it in with something appropriate just in case. Pass handle | 2053 // fill it in with something appropriate just in case. Pass handle |
1809 // wrong method for the c2i transitions. | 2054 // wrong method for the c2i transitions. |
1810 address wrong_method = SharedRuntime::get_handle_wrong_method_stub(); | 2055 address wrong_method = SharedRuntime::get_handle_wrong_method_stub(); |
1811 _fingerprints->append(0/*the never-allowed 0 fingerprint*/); | 2056 _abstract_method_handler = AdapterHandlerLibrary::new_entry(new AdapterFingerPrint(0, NULL), |
1812 assert(_handlers->length() == AbstractMethodHandler, "in wrong slot"); | 2057 StubRoutines::throw_AbstractMethodError_entry(), |
1813 _handlers->append(new AdapterHandlerEntry(StubRoutines::throw_AbstractMethodError_entry(), | 2058 wrong_method, wrong_method); |
1814 wrong_method, wrong_method)); | 2059 } |
1815 } | 2060 |
1816 | 2061 AdapterHandlerEntry* AdapterHandlerLibrary::new_entry(AdapterFingerPrint* fingerprint, |
1817 int AdapterHandlerLibrary::get_create_adapter_index(methodHandle method) { | 2062 address i2c_entry, |
1818 // Use customized signature handler. Need to lock around updates to the | 2063 address c2i_entry, |
1819 // _fingerprints array (it is not safe for concurrent readers and a single | 2064 address c2i_unverified_entry) { |
1820 // writer: this can be fixed if it becomes a problem). | 2065 return _adapters->new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry); |
2066 } | |
2067 | |
2068 AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(methodHandle method) { | |
2069 // Use customized signature handler. Need to lock around updates to | |
2070 // the AdapterHandlerTable (it is not safe for concurrent readers | |
2071 // and a single writer: this could be fixed if it becomes a | |
2072 // problem). | |
1821 | 2073 |
1822 // Get the address of the ic_miss handlers before we grab the | 2074 // Get the address of the ic_miss handlers before we grab the |
1823 // AdapterHandlerLibrary_lock. This fixes bug 6236259 which | 2075 // AdapterHandlerLibrary_lock. This fixes bug 6236259 which |
1824 // was caused by the initialization of the stubs happening | 2076 // was caused by the initialization of the stubs happening |
1825 // while we held the lock and then notifying jvmti while | 2077 // while we held the lock and then notifying jvmti while |
1826 // holding it. This just forces the initialization to be a little | 2078 // holding it. This just forces the initialization to be a little |
1827 // earlier. | 2079 // earlier. |
1828 address ic_miss = SharedRuntime::get_ic_miss_stub(); | 2080 address ic_miss = SharedRuntime::get_ic_miss_stub(); |
1829 assert(ic_miss != NULL, "must have handler"); | 2081 assert(ic_miss != NULL, "must have handler"); |
1830 | 2082 |
1831 int result; | 2083 ResourceMark rm; |
2084 | |
1832 NOT_PRODUCT(int code_size); | 2085 NOT_PRODUCT(int code_size); |
1833 BufferBlob *B = NULL; | 2086 BufferBlob *B = NULL; |
1834 AdapterHandlerEntry* entry = NULL; | 2087 AdapterHandlerEntry* entry = NULL; |
1835 uint64_t fingerprint; | 2088 AdapterFingerPrint* fingerprint = NULL; |
1836 { | 2089 { |
1837 MutexLocker mu(AdapterHandlerLibrary_lock); | 2090 MutexLocker mu(AdapterHandlerLibrary_lock); |
1838 // make sure data structure is initialized | 2091 // make sure data structure is initialized |
1839 initialize(); | 2092 initialize(); |
1840 | 2093 |
1841 if (method->is_abstract()) { | 2094 if (method->is_abstract()) { |
1842 return AbstractMethodHandler; | 2095 return _abstract_method_handler; |
1843 } | 2096 } |
2097 | |
2098 // Fill in the signature array, for the calling-convention call. | |
2099 int total_args_passed = method->size_of_parameters(); // All args on stack | |
2100 | |
2101 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed); | |
2102 VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed); | |
2103 int i = 0; | |
2104 if (!method->is_static()) // Pass in receiver first | |
2105 sig_bt[i++] = T_OBJECT; | |
2106 for (SignatureStream ss(method->signature()); !ss.at_return_type(); ss.next()) { | |
2107 sig_bt[i++] = ss.type(); // Collect remaining bits of signature | |
2108 if (ss.type() == T_LONG || ss.type() == T_DOUBLE) | |
2109 sig_bt[i++] = T_VOID; // Longs & doubles take 2 Java slots | |
2110 } | |
2111 assert(i == total_args_passed, ""); | |
2112 | |
2113 // Get a description of the compiled java calling convention and the largest used (VMReg) stack slot usage | |
2114 int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false); | |
1844 | 2115 |
1845 // Lookup method signature's fingerprint | 2116 // Lookup method signature's fingerprint |
1846 fingerprint = Fingerprinter(method).fingerprint(); | 2117 entry = _adapters->lookup(total_args_passed, regs); |
1847 assert( fingerprint != CONST64( 0), "no zero fingerprints allowed" ); | 2118 if (entry != NULL) { |
1848 // Fingerprints are small fixed-size condensed representations of | 2119 return entry; |
1849 // signatures. If the signature is too large, it won't fit in a | 2120 } |
1850 // fingerprint. Signatures which cannot support a fingerprint get a new i2c | 2121 |
1851 // adapter gen'd each time, instead of searching the cache for one. This -1 | 2122 // Make a C heap allocated version of the fingerprint to store in the adapter |
1852 // game can be avoided if I compared signatures instead of using | 2123 fingerprint = new AdapterFingerPrint(total_args_passed, regs); |
1853 // fingerprints. However, -1 fingerprints are very rare. | |
1854 if( fingerprint != UCONST64(-1) ) { // If this is a cache-able fingerprint | |
1855 // Turns out i2c adapters do not care what the return value is. Mask it | |
1856 // out so signatures that only differ in return type will share the same | |
1857 // adapter. | |
1858 fingerprint &= ~(SignatureIterator::result_feature_mask << SignatureIterator::static_feature_size); | |
1859 // Search for a prior existing i2c/c2i adapter | |
1860 int index = _fingerprints->find(fingerprint); | |
1861 if( index >= 0 ) return index; // Found existing handlers? | |
1862 } else { | |
1863 // Annoyingly, I end up adding -1 fingerprints to the array of handlers, | |
1864 // because I need a unique handler index. It cannot be scanned for | |
1865 // because all -1's look alike. Instead, the matching index is passed out | |
1866 // and immediately used to collect the 2 return values (the c2i and i2c | |
1867 // adapters). | |
1868 } | |
1869 | 2124 |
1870 // Create I2C & C2I handlers | 2125 // Create I2C & C2I handlers |
1871 ResourceMark rm; | |
1872 | 2126 |
1873 BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache | 2127 BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache |
1874 if (buf != NULL) { | 2128 if (buf != NULL) { |
1875 CodeBuffer buffer(buf->instructions_begin(), buf->instructions_size()); | 2129 CodeBuffer buffer(buf->instructions_begin(), buf->instructions_size()); |
1876 short buffer_locs[20]; | 2130 short buffer_locs[20]; |
1877 buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs, | 2131 buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs, |
1878 sizeof(buffer_locs)/sizeof(relocInfo)); | 2132 sizeof(buffer_locs)/sizeof(relocInfo)); |
1879 MacroAssembler _masm(&buffer); | 2133 MacroAssembler _masm(&buffer); |
1880 | 2134 |
1881 // Fill in the signature array, for the calling-convention call. | |
1882 int total_args_passed = method->size_of_parameters(); // All args on stack | |
1883 | |
1884 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType,total_args_passed); | |
1885 VMRegPair * regs = NEW_RESOURCE_ARRAY(VMRegPair ,total_args_passed); | |
1886 int i=0; | |
1887 if( !method->is_static() ) // Pass in receiver first | |
1888 sig_bt[i++] = T_OBJECT; | |
1889 for( SignatureStream ss(method->signature()); !ss.at_return_type(); ss.next()) { | |
1890 sig_bt[i++] = ss.type(); // Collect remaining bits of signature | |
1891 if( ss.type() == T_LONG || ss.type() == T_DOUBLE ) | |
1892 sig_bt[i++] = T_VOID; // Longs & doubles take 2 Java slots | |
1893 } | |
1894 assert( i==total_args_passed, "" ); | |
1895 | |
1896 // Now get the re-packed compiled-Java layout. | |
1897 int comp_args_on_stack; | |
1898 | |
1899 // Get a description of the compiled java calling convention and the largest used (VMReg) stack slot usage | |
1900 comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false); | |
1901 | |
1902 entry = SharedRuntime::generate_i2c2i_adapters(&_masm, | 2135 entry = SharedRuntime::generate_i2c2i_adapters(&_masm, |
1903 total_args_passed, | 2136 total_args_passed, |
1904 comp_args_on_stack, | 2137 comp_args_on_stack, |
1905 sig_bt, | 2138 sig_bt, |
1906 regs); | 2139 regs, |
2140 fingerprint); | |
1907 | 2141 |
1908 B = BufferBlob::create(AdapterHandlerEntry::name, &buffer); | 2142 B = BufferBlob::create(AdapterHandlerEntry::name, &buffer); |
1909 NOT_PRODUCT(code_size = buffer.code_size()); | 2143 NOT_PRODUCT(code_size = buffer.code_size()); |
1910 } | 2144 } |
1911 if (B == NULL) { | 2145 if (B == NULL) { |
1923 } | 2157 } |
1924 #endif | 2158 #endif |
1925 UseCompiler = false; | 2159 UseCompiler = false; |
1926 AlwaysCompileLoopMethods = false; | 2160 AlwaysCompileLoopMethods = false; |
1927 } | 2161 } |
1928 return 0; // Out of CodeCache space (_handlers[0] == NULL) | 2162 return NULL; // Out of CodeCache space |
1929 } | 2163 } |
1930 entry->relocate(B->instructions_begin()); | 2164 entry->relocate(B->instructions_begin()); |
1931 #ifndef PRODUCT | 2165 #ifndef PRODUCT |
1932 // debugging suppport | 2166 // debugging suppport |
1933 if (PrintAdapterHandlers) { | 2167 if (PrintAdapterHandlers) { |
1934 tty->cr(); | 2168 tty->cr(); |
1935 tty->print_cr("i2c argument handler #%d for: %s %s (fingerprint = 0x%llx, %d bytes generated)", | 2169 tty->print_cr("i2c argument handler #%d for: %s %s (fingerprint = %s, %d bytes generated)", |
1936 _handlers->length(), (method->is_static() ? "static" : "receiver"), | 2170 _adapters->number_of_entries(), (method->is_static() ? "static" : "receiver"), |
1937 method->signature()->as_C_string(), fingerprint, code_size ); | 2171 method->signature()->as_C_string(), fingerprint->as_string(), code_size ); |
1938 tty->print_cr("c2i argument handler starts at %p",entry->get_c2i_entry()); | 2172 tty->print_cr("c2i argument handler starts at %p",entry->get_c2i_entry()); |
1939 Disassembler::decode(entry->get_i2c_entry(), entry->get_i2c_entry() + code_size); | 2173 Disassembler::decode(entry->get_i2c_entry(), entry->get_i2c_entry() + code_size); |
1940 } | 2174 } |
1941 #endif | 2175 #endif |
1942 | 2176 |
1943 // add handlers to library | 2177 _adapters->add(entry); |
1944 _fingerprints->append(fingerprint); | |
1945 _handlers->append(entry); | |
1946 // set handler index | |
1947 assert(_fingerprints->length() == _handlers->length(), "sanity check"); | |
1948 result = _fingerprints->length() - 1; | |
1949 } | 2178 } |
1950 // Outside of the lock | 2179 // Outside of the lock |
1951 if (B != NULL) { | 2180 if (B != NULL) { |
1952 char blob_id[256]; | 2181 char blob_id[256]; |
1953 jio_snprintf(blob_id, | 2182 jio_snprintf(blob_id, |
1954 sizeof(blob_id), | 2183 sizeof(blob_id), |
1955 "%s(" PTR64_FORMAT ")@" PTR_FORMAT, | 2184 "%s(%s)@" PTR_FORMAT, |
1956 AdapterHandlerEntry::name, | 2185 AdapterHandlerEntry::name, |
1957 fingerprint, | 2186 fingerprint->as_string(), |
1958 B->instructions_begin()); | 2187 B->instructions_begin()); |
1959 VTune::register_stub(blob_id, B->instructions_begin(), B->instructions_end()); | 2188 VTune::register_stub(blob_id, B->instructions_begin(), B->instructions_end()); |
1960 Forte::register_stub(blob_id, B->instructions_begin(), B->instructions_end()); | 2189 Forte::register_stub(blob_id, B->instructions_begin(), B->instructions_end()); |
1961 | 2190 |
1962 if (JvmtiExport::should_post_dynamic_code_generated()) { | 2191 if (JvmtiExport::should_post_dynamic_code_generated()) { |
1963 JvmtiExport::post_dynamic_code_generated(blob_id, | 2192 JvmtiExport::post_dynamic_code_generated(blob_id, |
1964 B->instructions_begin(), | 2193 B->instructions_begin(), |
1965 B->instructions_end()); | 2194 B->instructions_end()); |
1966 } | 2195 } |
1967 } | 2196 } |
1968 return result; | 2197 return entry; |
1969 } | 2198 } |
1970 | 2199 |
1971 void AdapterHandlerEntry::relocate(address new_base) { | 2200 void AdapterHandlerEntry::relocate(address new_base) { |
1972 ptrdiff_t delta = new_base - _i2c_entry; | 2201 ptrdiff_t delta = new_base - _i2c_entry; |
1973 _i2c_entry += delta; | 2202 _i2c_entry += delta; |
2306 FREE_C_HEAP_ARRAY(intptr_t,buf); | 2535 FREE_C_HEAP_ARRAY(intptr_t,buf); |
2307 JRT_END | 2536 JRT_END |
2308 | 2537 |
2309 #ifndef PRODUCT | 2538 #ifndef PRODUCT |
2310 bool AdapterHandlerLibrary::contains(CodeBlob* b) { | 2539 bool AdapterHandlerLibrary::contains(CodeBlob* b) { |
2311 | 2540 AdapterHandlerTableIterator iter(_adapters); |
2312 if (_handlers == NULL) return false; | 2541 while (iter.has_next()) { |
2313 | 2542 AdapterHandlerEntry* a = iter.next(); |
2314 for (int i = 0 ; i < _handlers->length() ; i++) { | 2543 if ( b == CodeCache::find_blob(a->get_i2c_entry()) ) return true; |
2315 AdapterHandlerEntry* a = get_entry(i); | |
2316 if ( a != NULL && b == CodeCache::find_blob(a->get_i2c_entry()) ) return true; | |
2317 } | 2544 } |
2318 return false; | 2545 return false; |
2319 } | 2546 } |
2320 | 2547 |
2321 void AdapterHandlerLibrary::print_handler(CodeBlob* b) { | 2548 void AdapterHandlerLibrary::print_handler(CodeBlob* b) { |
2322 | 2549 AdapterHandlerTableIterator iter(_adapters); |
2323 for (int i = 0 ; i < _handlers->length() ; i++) { | 2550 while (iter.has_next()) { |
2324 AdapterHandlerEntry* a = get_entry(i); | 2551 AdapterHandlerEntry* a = iter.next(); |
2325 if ( a != NULL && b == CodeCache::find_blob(a->get_i2c_entry()) ) { | 2552 if ( b == CodeCache::find_blob(a->get_i2c_entry()) ) { |
2326 tty->print("Adapter for signature: "); | 2553 tty->print("Adapter for signature: "); |
2327 // Fingerprinter::print(_fingerprints->at(i)); | 2554 tty->print_cr("%s i2c: " INTPTR_FORMAT " c2i: " INTPTR_FORMAT " c2iUV: " INTPTR_FORMAT, |
2328 tty->print("0x%" FORMAT64_MODIFIER "x", _fingerprints->at(i)); | 2555 a->fingerprint()->as_string(), |
2329 tty->print_cr(" i2c: " INTPTR_FORMAT " c2i: " INTPTR_FORMAT " c2iUV: " INTPTR_FORMAT, | |
2330 a->get_i2c_entry(), a->get_c2i_entry(), a->get_c2i_unverified_entry()); | 2556 a->get_i2c_entry(), a->get_c2i_entry(), a->get_c2i_unverified_entry()); |
2331 | |
2332 return; | 2557 return; |
2333 } | 2558 } |
2334 } | 2559 } |
2335 assert(false, "Should have found handler"); | 2560 assert(false, "Should have found handler"); |
2336 } | 2561 } |
2562 | |
2563 void AdapterHandlerLibrary::print_statistics() { | |
2564 _adapters->print_statistics(); | |
2565 } | |
2566 | |
2337 #endif /* PRODUCT */ | 2567 #endif /* PRODUCT */ |