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 */ |