126 127 // Check if method has been redefined while taking out ResolvedMethodTable_lock, if so 128 // use new method. 129 Method* method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(resolved_method_name()); 130 assert(method->is_method(), "must be method"); 131 if (method->is_old()) { 132 // Replace method with redefined version 133 InstanceKlass* holder = method->method_holder(); 134 method = holder->method_with_idnum(method->method_idnum()); 135 java_lang_invoke_ResolvedMethodName::set_vmtarget(resolved_method_name(), method); 136 } 137 // Set flag in class to indicate this InstanceKlass has entries in the table 138 // to avoid walking table during redefinition if none of the redefined classes 139 // have any membernames in the table. 140 method->method_holder()->set_has_resolved_methods(); 141 142 return _the_table->basic_add(method, resolved_method_name); 143 } 144 145 // Removing entries 146 int ResolvedMethodTable::_oops_removed = 0; 147 int ResolvedMethodTable::_oops_counted = 0; 148 149 // There are no dead entries at start 150 bool ResolvedMethodTable::_dead_entries = false; 151 152 void ResolvedMethodTable::trigger_cleanup() { 153 MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); 154 _dead_entries = true; 155 Service_lock->notify_all(); 156 } 157 158 // Serially invoke removed unused oops from the table. 159 // This is done by the ServiceThread after being notified on class unloading 160 void ResolvedMethodTable::unlink() { 161 MutexLocker ml(ResolvedMethodTable_lock); 162 _oops_removed = 0; 163 _oops_counted = 0; 164 for (int i = 0; i < _the_table->table_size(); ++i) { 165 ResolvedMethodEntry** p = _the_table->bucket_addr(i); 166 ResolvedMethodEntry* entry = _the_table->bucket(i); 167 while (entry != NULL) { 168 _oops_counted++; 169 oop l = entry->object_no_keepalive(); 170 if (l != NULL) { 171 p = entry->next_addr(); 172 } else { 173 // Entry has been removed. 174 _oops_removed++; 175 if (log_is_enabled(Debug, membername, table)) { 176 log_debug(membername, table) ("ResolvedMethod entry removed for index %d", i); 177 } 178 entry->literal().release(); 179 *p = entry->next(); 180 _the_table->free_entry(entry); 181 } 182 // get next entry 183 entry = (ResolvedMethodEntry*)HashtableEntry<ClassLoaderWeakHandle, mtClass>::make_ptr(*p); 184 } 185 } 186 log_debug(membername, table) ("ResolvedMethod entries counted %d removed %d", 187 _oops_counted, _oops_removed); 188 _dead_entries = false; 189 } 190 191 #ifndef PRODUCT 192 void ResolvedMethodTable::print() { 193 MutexLocker ml(ResolvedMethodTable_lock); 194 for (int i = 0; i < table_size(); ++i) { 195 ResolvedMethodEntry* entry = bucket(i); 196 while (entry != NULL) { 197 tty->print("%d : ", i); 198 oop rmethod_name = entry->object_no_keepalive(); 199 if (rmethod_name != NULL) { 200 rmethod_name->print(); 201 Method* m = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(rmethod_name); 202 m->print(); 203 } 204 entry = entry->next(); 205 } 206 } 207 } | 126 127 // Check if method has been redefined while taking out ResolvedMethodTable_lock, if so 128 // use new method. 129 Method* method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(resolved_method_name()); 130 assert(method->is_method(), "must be method"); 131 if (method->is_old()) { 132 // Replace method with redefined version 133 InstanceKlass* holder = method->method_holder(); 134 method = holder->method_with_idnum(method->method_idnum()); 135 java_lang_invoke_ResolvedMethodName::set_vmtarget(resolved_method_name(), method); 136 } 137 // Set flag in class to indicate this InstanceKlass has entries in the table 138 // to avoid walking table during redefinition if none of the redefined classes 139 // have any membernames in the table. 140 method->method_holder()->set_has_resolved_methods(); 141 142 return _the_table->basic_add(method, resolved_method_name); 143 } 144 145 // Removing entries 146 int ResolvedMethodTable::total_oops_removed = 0; 147 148 // There are no dead entries at start 149 bool ResolvedMethodTable::_dead_entries = false; 150 151 void ResolvedMethodTable::trigger_cleanup() { 152 MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); 153 _dead_entries = true; 154 Service_lock->notify_all(); 155 } 156 157 // Serially invoke removed unused oops from the table. 158 // This is done by the ServiceThread after being notified on class unloading 159 void ResolvedMethodTable::unlink() { 160 MutexLocker ml(ResolvedMethodTable_lock); 161 int _oops_removed = 0; 162 int _oops_counted = 0; 163 for (int i = 0; i < _the_table->table_size(); ++i) { 164 ResolvedMethodEntry** p = _the_table->bucket_addr(i); 165 ResolvedMethodEntry* entry = _the_table->bucket(i); 166 while (entry != NULL) { 167 _oops_counted++; 168 oop l = entry->object_no_keepalive(); 169 if (l != NULL) { 170 p = entry->next_addr(); 171 } else { 172 // Entry has been removed. 173 _oops_removed++; 174 if (log_is_enabled(Debug, membername, table)) { 175 log_debug(membername, table) ("ResolvedMethod entry removed for index %d", i); 176 } 177 entry->literal().release(); 178 *p = entry->next(); 179 _the_table->free_entry(entry); 180 } 181 // get next entry 182 entry = (ResolvedMethodEntry*)HashtableEntry<ClassLoaderWeakHandle, mtClass>::make_ptr(*p); 183 } 184 } 185 log_debug(membername, table) ("ResolvedMethod entries counted %d removed %d", 186 _oops_counted, _oops_removed); 187 total_oops_removed += _oops_removed; 188 _dead_entries = false; 189 } 190 191 #ifndef PRODUCT 192 void ResolvedMethodTable::print() { 193 MutexLocker ml(ResolvedMethodTable_lock); 194 for (int i = 0; i < table_size(); ++i) { 195 ResolvedMethodEntry* entry = bucket(i); 196 while (entry != NULL) { 197 tty->print("%d : ", i); 198 oop rmethod_name = entry->object_no_keepalive(); 199 if (rmethod_name != NULL) { 200 rmethod_name->print(); 201 Method* m = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(rmethod_name); 202 m->print(); 203 } 204 entry = entry->next(); 205 } 206 } 207 } |