404 } 405 } 406 } 407 408 MethodCounters* Method::build_method_counters(Method* m, TRAPS) { 409 // Do not profile the method if metaspace has hit an OOM previously 410 if (ClassLoaderDataGraph::has_metaspace_oom()) { 411 return NULL; 412 } 413 414 methodHandle mh(m); 415 MethodCounters* counters = MethodCounters::allocate(mh, THREAD); 416 if (HAS_PENDING_EXCEPTION) { 417 CompileBroker::log_metaspace_failure(); 418 ClassLoaderDataGraph::set_metaspace_oom(true); 419 return NULL; // return the exception (which is cleared) 420 } 421 if (!mh->init_method_counters(counters)) { 422 MetadataFactory::free_metadata(mh->method_holder()->class_loader_data(), counters); 423 } 424 return mh->method_counters(); 425 } 426 427 void Method::cleanup_inline_caches() { 428 // The current system doesn't use inline caches in the interpreter 429 // => nothing to do (keep this method around for future use) 430 } 431 432 433 int Method::extra_stack_words() { 434 // not an inline function, to avoid a header dependency on Interpreter 435 return extra_stack_entries() * Interpreter::stackElementSize; 436 } 437 438 439 void Method::compute_size_of_parameters(Thread *thread) { 440 ArgumentSizeComputer asc(signature()); 441 set_size_of_parameters(asc.size() + (is_static() ? 0 : 1)); 442 } 443 2112 if (WizardMode && code() != NULL) st->print(" ((nmethod*)%p)", code()); 2113 } 2114 2115 #if INCLUDE_SERVICES 2116 // Size Statistics 2117 void Method::collect_statistics(KlassSizeStats *sz) const { 2118 int mysize = sz->count(this); 2119 sz->_method_bytes += mysize; 2120 sz->_method_all_bytes += mysize; 2121 sz->_rw_bytes += mysize; 2122 2123 if (constMethod()) { 2124 constMethod()->collect_statistics(sz); 2125 } 2126 if (method_data()) { 2127 method_data()->collect_statistics(sz); 2128 } 2129 } 2130 #endif // INCLUDE_SERVICES 2131 2132 // Verification 2133 2134 void Method::verify_on(outputStream* st) { 2135 guarantee(is_method(), "object must be method"); 2136 guarantee(constants()->is_constantPool(), "should be constant pool"); 2137 guarantee(constMethod()->is_constMethod(), "should be ConstMethod*"); 2138 MethodData* md = method_data(); 2139 guarantee(md == NULL || 2140 md->is_methodData(), "should be method data"); 2141 } | 404 } 405 } 406 } 407 408 MethodCounters* Method::build_method_counters(Method* m, TRAPS) { 409 // Do not profile the method if metaspace has hit an OOM previously 410 if (ClassLoaderDataGraph::has_metaspace_oom()) { 411 return NULL; 412 } 413 414 methodHandle mh(m); 415 MethodCounters* counters = MethodCounters::allocate(mh, THREAD); 416 if (HAS_PENDING_EXCEPTION) { 417 CompileBroker::log_metaspace_failure(); 418 ClassLoaderDataGraph::set_metaspace_oom(true); 419 return NULL; // return the exception (which is cleared) 420 } 421 if (!mh->init_method_counters(counters)) { 422 MetadataFactory::free_metadata(mh->method_holder()->class_loader_data(), counters); 423 } 424 if (TraceMethodUsage) { 425 mh->trace_usage(CHECK_NULL); 426 } 427 return mh->method_counters(); 428 } 429 430 void Method::cleanup_inline_caches() { 431 // The current system doesn't use inline caches in the interpreter 432 // => nothing to do (keep this method around for future use) 433 } 434 435 436 int Method::extra_stack_words() { 437 // not an inline function, to avoid a header dependency on Interpreter 438 return extra_stack_entries() * Interpreter::stackElementSize; 439 } 440 441 442 void Method::compute_size_of_parameters(Thread *thread) { 443 ArgumentSizeComputer asc(signature()); 444 set_size_of_parameters(asc.size() + (is_static() ? 0 : 1)); 445 } 446 2115 if (WizardMode && code() != NULL) st->print(" ((nmethod*)%p)", code()); 2116 } 2117 2118 #if INCLUDE_SERVICES 2119 // Size Statistics 2120 void Method::collect_statistics(KlassSizeStats *sz) const { 2121 int mysize = sz->count(this); 2122 sz->_method_bytes += mysize; 2123 sz->_method_all_bytes += mysize; 2124 sz->_rw_bytes += mysize; 2125 2126 if (constMethod()) { 2127 constMethod()->collect_statistics(sz); 2128 } 2129 if (method_data()) { 2130 method_data()->collect_statistics(sz); 2131 } 2132 } 2133 #endif // INCLUDE_SERVICES 2134 2135 // TraceMethodUsage and PrintMethodUsageAtExit 2136 2137 // TraceMethodUsageRecord -- we can't use a HashtableEntry<> because 2138 // the Method may be garbage collected. Let's roll our own hash table. 2139 class TraceMethodUsageRecord : CHeapObj<mtTracing> { 2140 public: 2141 // It's OK to store Symbols here because they will NOT be GC'ed if 2142 // TraceMethodUsage is enabled. 2143 TraceMethodUsageRecord* _next; 2144 Symbol* _class_name; 2145 Symbol* _method_name; 2146 Symbol* _method_signature; 2147 }; 2148 2149 static const int TRACE_METHOD_USAGE_TABLE_SIZE = 20011; 2150 static TraceMethodUsageRecord** _method_usage_table = NULL; 2151 2152 void Method::trace_usage(TRAPS) const { 2153 MutexLocker ml(MethodUsage_lock, THREAD); 2154 2155 const int table_size = TRACE_METHOD_USAGE_TABLE_SIZE; 2156 if (_method_usage_table == NULL) { 2157 _method_usage_table = NEW_C_HEAP_ARRAY2(TraceMethodUsageRecord*, table_size, 2158 mtTracing, CURRENT_PC); 2159 memset(_method_usage_table, 0, sizeof(TraceMethodUsageRecord*)*table_size); 2160 } 2161 2162 Symbol* my_class = klass_name(); 2163 Symbol* my_name = name(); 2164 Symbol* my_sig = signature(); 2165 2166 unsigned int hash = my_class->identity_hash() + 2167 my_name->identity_hash() + 2168 my_sig->identity_hash(); 2169 juint index = juint(hash) % table_size; 2170 2171 for (TraceMethodUsageRecord* ptr = _method_usage_table[index]; 2172 ptr; 2173 ptr = ptr->_next) { 2174 if (ptr->_class_name == my_class && 2175 ptr->_method_name == my_name && 2176 ptr->_method_signature == my_sig) { 2177 return; 2178 } 2179 } 2180 TraceMethodUsageRecord* nptr = NEW_C_HEAP_OBJ(TraceMethodUsageRecord, mtTracing); 2181 nptr->_class_name = my_class; 2182 nptr->_method_name = my_name; 2183 nptr->_method_signature = my_sig; 2184 2185 nptr->_next = _method_usage_table[index]; 2186 _method_usage_table[index] = nptr; 2187 } 2188 2189 void Method::print_usage(outputStream* out) { 2190 MutexLockerEx ml(Thread::current()->is_VM_thread() ? NULL : MethodUsage_lock); 2191 out->print_cr("# Method::print_usage version 1"); 2192 if (_method_usage_table) { 2193 for (int i = 0; i < TRACE_METHOD_USAGE_TABLE_SIZE; i++) { 2194 // Print one item per line to make it easy to read the table during CDS dumping. 2195 for (TraceMethodUsageRecord* ptr = _method_usage_table[i]; 2196 ptr; 2197 ptr = ptr->_next) { 2198 ptr->_class_name->print_symbol_on(out); out->cr(); 2199 ptr->_method_name->print_symbol_on(out); out->cr(); 2200 ptr->_method_signature->print_symbol_on(out); out->cr(); 2201 } 2202 } 2203 } 2204 } 2205 2206 // Verification 2207 2208 void Method::verify_on(outputStream* st) { 2209 guarantee(is_method(), "object must be method"); 2210 guarantee(constants()->is_constantPool(), "should be constant pool"); 2211 guarantee(constMethod()->is_constMethod(), "should be ConstMethod*"); 2212 MethodData* md = method_data(); 2213 guarantee(md == NULL || 2214 md->is_methodData(), "should be method data"); 2215 } |