comparison src/share/vm/runtime/fprofiler.cpp @ 6725:da91efe96a93

6964458: Reimplement class meta-data storage to use native memory Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author coleenp
date Sat, 01 Sep 2012 13:25:18 -0400
parents 1d7922586cf6
children aeaca88565e6
comparison
equal deleted inserted replaced
6724:36d1d483d5d6 6725:da91efe96a93
1 /* 1 /*
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. 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.
286 virtual bool is_compiled() const { return false; } 286 virtual bool is_compiled() const { return false; }
287 virtual bool is_stub() const { return false; } 287 virtual bool is_stub() const { return false; }
288 virtual bool is_runtime_stub() const{ return false; } 288 virtual bool is_runtime_stub() const{ return false; }
289 virtual void oops_do(OopClosure* f) = 0; 289 virtual void oops_do(OopClosure* f) = 0;
290 290
291 virtual bool interpreted_match(methodOop m) const { return false; } 291 virtual bool interpreted_match(Method* m) const { return false; }
292 virtual bool compiled_match(methodOop m ) const { return false; } 292 virtual bool compiled_match(Method* m ) const { return false; }
293 virtual bool stub_match(methodOop m, const char* name) const { return false; } 293 virtual bool stub_match(Method* m, const char* name) const { return false; }
294 virtual bool adapter_match() const { return false; } 294 virtual bool adapter_match() const { return false; }
295 virtual bool runtimeStub_match(const CodeBlob* stub, const char* name) const { return false; } 295 virtual bool runtimeStub_match(const CodeBlob* stub, const char* name) const { return false; }
296 virtual bool unknown_compiled_match(const CodeBlob* cb) const { return false; } 296 virtual bool unknown_compiled_match(const CodeBlob* cb) const { return false; }
297 297
298 static void print_title(outputStream* st) { 298 static void print_title(outputStream* st) {
310 st->fill_to(col3); 310 st->fill_to(col3);
311 st->print(msg); 311 st->print(msg);
312 st->cr(); 312 st->cr();
313 } 313 }
314 314
315 virtual methodOop method() = 0; 315 virtual Method* method() = 0;
316 316
317 virtual void print_method_on(outputStream* st) { 317 virtual void print_method_on(outputStream* st) {
318 int limit; 318 int limit;
319 int i; 319 int i;
320 methodOop m = method(); 320 Method* m = method();
321 Symbol* k = m->klass_name(); 321 Symbol* k = m->klass_name();
322 // Print the class name with dots instead of slashes 322 // Print the class name with dots instead of slashes
323 limit = k->utf8_length(); 323 limit = k->utf8_length();
324 for (i = 0 ; i < limit ; i += 1) { 324 for (i = 0 ; i < limit ; i += 1) {
325 char c = (char) k->byte_at(i); 325 char c = (char) k->byte_at(i);
340 if (Verbose || WizardMode) { 340 if (Verbose || WizardMode) {
341 // Disambiguate overloaded methods 341 // Disambiguate overloaded methods
342 Symbol* sig = m->signature(); 342 Symbol* sig = m->signature();
343 sig->print_symbol_on(st); 343 sig->print_symbol_on(st);
344 } else if (MethodHandles::is_signature_polymorphic(m->intrinsic_id())) 344 } else if (MethodHandles::is_signature_polymorphic(m->intrinsic_id()))
345 // compare with methodOopDesc::print_short_name 345 // compare with Method::print_short_name
346 MethodHandles::print_as_basic_type_signature_on(st, m->signature(), true); 346 MethodHandles::print_as_basic_type_signature_on(st, m->signature(), true);
347 } 347 }
348 348
349 virtual void print(outputStream* st, int total_ticks) { 349 virtual void print(outputStream* st, int total_ticks) {
350 ticks.print_code(st, total_ticks); 350 ticks.print_code(st, total_ticks);
354 print_method_on(st); 354 print_method_on(st);
355 st->cr(); 355 st->cr();
356 } 356 }
357 357
358 // for hashing into the table 358 // for hashing into the table
359 static int hash(methodOop method) { 359 static int hash(Method* method) {
360 // The point here is to try to make something fairly unique 360 // The point here is to try to make something fairly unique
361 // out of the fields we can read without grabbing any locks 361 // out of the fields we can read without grabbing any locks
362 // since the method may be locked when we need the hash. 362 // since the method may be locked when we need the hash.
363 return ( 363 return (
364 method->code_size() ^ 364 method->code_size() ^
386 void ProfilerNode::operator delete(void* p){ 386 void ProfilerNode::operator delete(void* p){
387 } 387 }
388 388
389 class interpretedNode : public ProfilerNode { 389 class interpretedNode : public ProfilerNode {
390 private: 390 private:
391 methodOop _method; 391 Method* _method;
392 oop _class_loader; // needed to keep metadata for the method alive
392 public: 393 public:
393 interpretedNode(methodOop method, TickPosition where) : ProfilerNode() { 394 interpretedNode(Method* method, TickPosition where) : ProfilerNode() {
394 _method = method; 395 _method = method;
396 _class_loader = method->method_holder()->class_loader();
395 update(where); 397 update(where);
396 } 398 }
397 399
398 bool is_interpreted() const { return true; } 400 bool is_interpreted() const { return true; }
399 401
400 bool interpreted_match(methodOop m) const { 402 bool interpreted_match(Method* m) const {
401 return _method == m; 403 return _method == m;
402 } 404 }
403 405
404 void oops_do(OopClosure* f) { 406 void oops_do(OopClosure* f) {
405 f->do_oop((oop*)&_method); 407 f->do_oop(&_class_loader);
406 } 408 }
407 409
408 methodOop method() { return _method; } 410 Method* method() { return _method; }
409 411
410 static void print_title(outputStream* st) { 412 static void print_title(outputStream* st) {
411 st->fill_to(col1); 413 st->fill_to(col1);
412 st->print("%11s", "Interpreted"); 414 st->print("%11s", "Interpreted");
413 ProfilerNode::print_title(st); 415 ProfilerNode::print_title(st);
423 } 425 }
424 }; 426 };
425 427
426 class compiledNode : public ProfilerNode { 428 class compiledNode : public ProfilerNode {
427 private: 429 private:
428 methodOop _method; 430 Method* _method;
431 oop _class_loader; // needed to keep metadata for the method alive
429 public: 432 public:
430 compiledNode(methodOop method, TickPosition where) : ProfilerNode() { 433 compiledNode(Method* method, TickPosition where) : ProfilerNode() {
431 _method = method; 434 _method = method;
435 _class_loader = method->method_holder()->class_loader();
432 update(where); 436 update(where);
433 } 437 }
434 bool is_compiled() const { return true; } 438 bool is_compiled() const { return true; }
435 439
436 bool compiled_match(methodOop m) const { 440 bool compiled_match(Method* m) const {
437 return _method == m; 441 return _method == m;
438 } 442 }
439 443
440 methodOop method() { return _method; } 444 Method* method() { return _method; }
441 445
442 void oops_do(OopClosure* f) { 446 void oops_do(OopClosure* f) {
443 f->do_oop((oop*)&_method); 447 f->do_oop(&_class_loader);
444 } 448 }
445 449
446 static void print_title(outputStream* st) { 450 static void print_title(outputStream* st) {
447 st->fill_to(col1); 451 st->fill_to(col1);
448 st->print("%11s", "Compiled"); 452 st->print("%11s", "Compiled");
458 } 462 }
459 }; 463 };
460 464
461 class stubNode : public ProfilerNode { 465 class stubNode : public ProfilerNode {
462 private: 466 private:
463 methodOop _method; 467 Method* _method;
468 oop _class_loader; // needed to keep metadata for the method alive
464 const char* _symbol; // The name of the nearest VM symbol (for +ProfileVM). Points to a unique string 469 const char* _symbol; // The name of the nearest VM symbol (for +ProfileVM). Points to a unique string
465 public: 470 public:
466 stubNode(methodOop method, const char* name, TickPosition where) : ProfilerNode() { 471 stubNode(Method* method, const char* name, TickPosition where) : ProfilerNode() {
467 _method = method; 472 _method = method;
473 _class_loader = method->method_holder()->class_loader();
468 _symbol = name; 474 _symbol = name;
469 update(where); 475 update(where);
470 } 476 }
471 477
472 bool is_stub() const { return true; } 478 bool is_stub() const { return true; }
473 479
474 bool stub_match(methodOop m, const char* name) const { 480 void oops_do(OopClosure* f) {
481 f->do_oop(&_class_loader);
482 }
483
484 bool stub_match(Method* m, const char* name) const {
475 return (_method == m) && (_symbol == name); 485 return (_method == m) && (_symbol == name);
476 } 486 }
477 487
478 void oops_do(OopClosure* f) { 488 Method* method() { return _method; }
479 f->do_oop((oop*)&_method);
480 }
481
482 methodOop method() { return _method; }
483 489
484 static void print_title(outputStream* st) { 490 static void print_title(outputStream* st) {
485 st->fill_to(col1); 491 st->fill_to(col1);
486 st->print("%11s", "Stub"); 492 st->print("%11s", "Stub");
487 ProfilerNode::print_title(st); 493 ProfilerNode::print_title(st);
510 } 516 }
511 bool is_compiled() const { return true; } 517 bool is_compiled() const { return true; }
512 518
513 bool adapter_match() const { return true; } 519 bool adapter_match() const { return true; }
514 520
515 methodOop method() { return NULL; } 521 Method* method() { return NULL; }
516 522
517 void oops_do(OopClosure* f) { 523 void oops_do(OopClosure* f) {
518 ; 524 ;
519 } 525 }
520 526
543 assert(stub->is_runtime_stub(), "wrong code blob"); 549 assert(stub->is_runtime_stub(), "wrong code blob");
544 return ((RuntimeStub*)_stub)->entry_point() == ((RuntimeStub*)stub)->entry_point() && 550 return ((RuntimeStub*)_stub)->entry_point() == ((RuntimeStub*)stub)->entry_point() &&
545 (_symbol == name); 551 (_symbol == name);
546 } 552 }
547 553
548 methodOop method() { return NULL; } 554 Method* method() { return NULL; }
549 555
550 static void print_title(outputStream* st) { 556 static void print_title(outputStream* st) {
551 st->fill_to(col1); 557 st->fill_to(col1);
552 st->print("%11s", "Runtime stub"); 558 st->print("%11s", "Runtime stub");
553 ProfilerNode::print_title(st); 559 ProfilerNode::print_title(st);
591 return !strcmp(((BufferBlob*)cb)->name(), _name); 597 return !strcmp(((BufferBlob*)cb)->name(), _name);
592 else 598 else
593 return !strcmp(((SingletonBlob*)cb)->name(), _name); 599 return !strcmp(((SingletonBlob*)cb)->name(), _name);
594 } 600 }
595 601
596 methodOop method() { return NULL; } 602 Method* method() { return NULL; }
597 603
598 void oops_do(OopClosure* f) { 604 void oops_do(OopClosure* f) {
599 ; 605 ;
600 } 606 }
601 607
625 const char *name() const { return _name; } 631 const char *name() const { return _name; }
626 bool is_compiled() const { return true; } 632 bool is_compiled() const { return true; }
627 633
628 bool vm_match(const char* name) const { return strcmp(name, _name) == 0; } 634 bool vm_match(const char* name) const { return strcmp(name, _name) == 0; }
629 635
630 methodOop method() { return NULL; } 636 Method* method() { return NULL; }
631 637
632 static int hash(const char* name){ 638 static int hash(const char* name){
633 // Compute a simple hash 639 // Compute a simple hash
634 const char* cp = name; 640 const char* cp = name;
635 int h = 0; 641 int h = 0;
659 st->print("%s", _name); 665 st->print("%s", _name);
660 } 666 }
661 } 667 }
662 }; 668 };
663 669
664 void ThreadProfiler::interpreted_update(methodOop method, TickPosition where) { 670 void ThreadProfiler::interpreted_update(Method* method, TickPosition where) {
665 int index = entry(ProfilerNode::hash(method)); 671 int index = entry(ProfilerNode::hash(method));
666 if (!table[index]) { 672 if (!table[index]) {
667 table[index] = new (this) interpretedNode(method, where); 673 table[index] = new (this) interpretedNode(method, where);
668 } else { 674 } else {
669 ProfilerNode* prev = table[index]; 675 ProfilerNode* prev = table[index];
676 } 682 }
677 prev->set_next(new (this) interpretedNode(method, where)); 683 prev->set_next(new (this) interpretedNode(method, where));
678 } 684 }
679 } 685 }
680 686
681 void ThreadProfiler::compiled_update(methodOop method, TickPosition where) { 687 void ThreadProfiler::compiled_update(Method* method, TickPosition where) {
682 int index = entry(ProfilerNode::hash(method)); 688 int index = entry(ProfilerNode::hash(method));
683 if (!table[index]) { 689 if (!table[index]) {
684 table[index] = new (this) compiledNode(method, where); 690 table[index] = new (this) compiledNode(method, where);
685 } else { 691 } else {
686 ProfilerNode* prev = table[index]; 692 ProfilerNode* prev = table[index];
693 } 699 }
694 prev->set_next(new (this) compiledNode(method, where)); 700 prev->set_next(new (this) compiledNode(method, where));
695 } 701 }
696 } 702 }
697 703
698 void ThreadProfiler::stub_update(methodOop method, const char* name, TickPosition where) { 704 void ThreadProfiler::stub_update(Method* method, const char* name, TickPosition where) {
699 int index = entry(ProfilerNode::hash(method)); 705 int index = entry(ProfilerNode::hash(method));
700 if (!table[index]) { 706 if (!table[index]) {
701 table[index] = new (this) stubNode(method, name, where); 707 table[index] = new (this) stubNode(method, name, where);
702 } else { 708 } else {
703 ProfilerNode* prev = table[index]; 709 ProfilerNode* prev = table[index];
955 return; 961 return;
956 } 962 }
957 963
958 // The frame has been fully validated so we can trust the method and bci 964 // The frame has been fully validated so we can trust the method and bci
959 965
960 methodOop method = *fr.interpreter_frame_method_addr(); 966 Method* method = *fr.interpreter_frame_method_addr();
961 967
962 interpreted_update(method, where); 968 interpreted_update(method, where);
963 969
964 // update byte code table 970 // update byte code table
965 InterpreterCodelet* desc = Interpreter::codelet_containing(fr.pc()); 971 InterpreterCodelet* desc = Interpreter::codelet_containing(fr.pc());
982 RegisterMap map(thread, false); 988 RegisterMap map(thread, false);
983 fr = fr.sender(&map); 989 fr = fr.sender(&map);
984 cb = fr.cb(); 990 cb = fr.cb();
985 localwhere = tp_native; 991 localwhere = tp_native;
986 } 992 }
987 methodOop method = (cb->is_nmethod()) ? ((nmethod *)cb)->method() : 993 Method* method = (cb->is_nmethod()) ? ((nmethod *)cb)->method() :
988 (methodOop)NULL; 994 (Method*)NULL;
989 995
990 if (method == NULL) { 996 if (method == NULL) {
991 if (cb->is_runtime_stub()) 997 if (cb->is_runtime_stub())
992 runtime_stub_update(cb, name, localwhere); 998 runtime_stub_update(cb, name, localwhere);
993 else 999 else