src/share/vm/oops/method.cpp

Print this page




 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 }