comparison src/os/solaris/dtrace/libjvm_db.c @ 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 d68b1274b9ba
children fd94cbe7c5da
comparison
equal deleted inserted replaced
6724:36d1d483d5d6 6725:da91efe96a93
99 #define COMP_METHOD_SIGN '*' 99 #define COMP_METHOD_SIGN '*'
100 100
101 #define MAX_VFRAMES_CNT 256 101 #define MAX_VFRAMES_CNT 256
102 102
103 typedef struct vframe { 103 typedef struct vframe {
104 uint64_t methodOop; 104 uint64_t method;
105 int32_t sender_decode_offset; 105 int32_t sender_decode_offset;
106 int32_t methodIdx; 106 int32_t methodIdx;
107 int32_t bci; 107 int32_t bci;
108 int32_t line; 108 int32_t line;
109 } Vframe_t; 109 } Vframe_t;
127 int32_t instrs_beg; /* _code_offset */ 127 int32_t instrs_beg; /* _code_offset */
128 int32_t instrs_end; 128 int32_t instrs_end;
129 int32_t deopt_beg; /* _deoptimize_offset */ 129 int32_t deopt_beg; /* _deoptimize_offset */
130 int32_t scopes_data_beg; /* _scopes_data_offset */ 130 int32_t scopes_data_beg; /* _scopes_data_offset */
131 int32_t scopes_data_end; 131 int32_t scopes_data_end;
132 int32_t oops_beg; /* _oops_offset */ 132 int32_t metadata_beg; /* _metadata_offset */
133 int32_t oops_end; 133 int32_t metadata_end;
134 int32_t scopes_pcs_beg; /* _scopes_pcs_offset */ 134 int32_t scopes_pcs_beg; /* _scopes_pcs_offset */
135 int32_t scopes_pcs_end; 135 int32_t scopes_pcs_end;
136 136
137 int vf_cnt; 137 int vf_cnt;
138 Vframe_t vframes[MAX_VFRAMES_CNT]; 138 Vframe_t vframes[MAX_VFRAMES_CNT];
143 143
144 uint64_t nmethod_vtbl; 144 uint64_t nmethod_vtbl;
145 uint64_t CodeBlob_vtbl; 145 uint64_t CodeBlob_vtbl;
146 uint64_t BufferBlob_vtbl; 146 uint64_t BufferBlob_vtbl;
147 uint64_t RuntimeStub_vtbl; 147 uint64_t RuntimeStub_vtbl;
148 uint64_t Method_vtbl;
148 149
149 uint64_t Use_Compressed_Oops_address; 150 uint64_t Use_Compressed_Oops_address;
150 uint64_t Universe_methodKlassObj_address;
151 uint64_t Universe_narrow_oop_base_address; 151 uint64_t Universe_narrow_oop_base_address;
152 uint64_t Universe_narrow_oop_shift_address; 152 uint64_t Universe_narrow_oop_shift_address;
153 uint64_t CodeCache_heap_address; 153 uint64_t CodeCache_heap_address;
154 154
155 /* Volatiles */ 155 /* Volatiles */
156 uint8_t Use_Compressed_Oops; 156 uint8_t Use_Compressed_Oops;
157 uint64_t Universe_methodKlassObj;
158 uint64_t Universe_narrow_oop_base; 157 uint64_t Universe_narrow_oop_base;
159 uint32_t Universe_narrow_oop_shift; 158 uint32_t Universe_narrow_oop_shift;
160 uint64_t CodeCache_low; 159 uint64_t CodeCache_low;
161 uint64_t CodeCache_high; 160 uint64_t CodeCache_high;
162 uint64_t CodeCache_segmap_low; 161 uint64_t CodeCache_segmap_low;
163 uint64_t CodeCache_segmap_high; 162 uint64_t CodeCache_segmap_high;
164 163
165 int32_t SIZE_CodeCache_log2_segment; 164 int32_t SIZE_CodeCache_log2_segment;
166 165
167 uint64_t methodOopPtr; 166 uint64_t methodPtr;
168 uint64_t bcx; 167 uint64_t bcx;
169 168
170 Nmethod_t *N; /*Inlined methods support */ 169 Nmethod_t *N; /*Inlined methods support */
171 Frame_t prev_fr; 170 Frame_t prev_fr;
172 Frame_t curr_fr; 171 Frame_t curr_fr;
278 if (vmp->typeName[0] == 'C' && strcmp("CodeCache", vmp->typeName) == 0) { 277 if (vmp->typeName[0] == 'C' && strcmp("CodeCache", vmp->typeName) == 0) {
279 if (strcmp("_heap", vmp->fieldName) == 0) { 278 if (strcmp("_heap", vmp->fieldName) == 0) {
280 err = read_pointer(J, vmp->address, &J->CodeCache_heap_address); 279 err = read_pointer(J, vmp->address, &J->CodeCache_heap_address);
281 } 280 }
282 } else if (vmp->typeName[0] == 'U' && strcmp("Universe", vmp->typeName) == 0) { 281 } else if (vmp->typeName[0] == 'U' && strcmp("Universe", vmp->typeName) == 0) {
283 if (strcmp("_methodKlassObj", vmp->fieldName) == 0) {
284 J->Universe_methodKlassObj_address = vmp->address;
285 }
286 if (strcmp("_narrow_oop._base", vmp->fieldName) == 0) { 282 if (strcmp("_narrow_oop._base", vmp->fieldName) == 0) {
287 J->Universe_narrow_oop_base_address = vmp->address; 283 J->Universe_narrow_oop_base_address = vmp->address;
288 } 284 }
289 if (strcmp("_narrow_oop._shift", vmp->fieldName) == 0) { 285 if (strcmp("_narrow_oop._shift", vmp->fieldName) == 0) {
290 J->Universe_narrow_oop_shift_address = vmp->address; 286 J->Universe_narrow_oop_shift_address = vmp->address;
327 err = ps_pread(J->P, J->Use_Compressed_Oops_address, &J->Use_Compressed_Oops, sizeof(uint8_t)); 323 err = ps_pread(J->P, J->Use_Compressed_Oops_address, &J->Use_Compressed_Oops, sizeof(uint8_t));
328 CHECK_FAIL(err); 324 CHECK_FAIL(err);
329 } else { 325 } else {
330 J->Use_Compressed_Oops = 0; 326 J->Use_Compressed_Oops = 0;
331 } 327 }
332
333 err = read_pointer(J, J->Universe_methodKlassObj_address, &J->Universe_methodKlassObj);
334 CHECK_FAIL(err);
335 328
336 err = read_pointer(J, J->Universe_narrow_oop_base_address, &J->Universe_narrow_oop_base); 329 err = read_pointer(J, J->Universe_narrow_oop_base_address, &J->Universe_narrow_oop_base);
337 CHECK_FAIL(err); 330 CHECK_FAIL(err);
338 err = ps_pread(J->P, J->Universe_narrow_oop_shift_address, &J->Universe_narrow_oop_shift, sizeof(uint32_t)); 331 err = ps_pread(J->P, J->Universe_narrow_oop_shift_address, &J->Universe_narrow_oop_shift, sizeof(uint32_t));
339 CHECK_FAIL(err); 332 CHECK_FAIL(err);
453 if (err != PS_OK) J->BufferBlob_vtbl = 0; 446 if (err != PS_OK) J->BufferBlob_vtbl = 0;
454 err = find_symbol(J, "__1cICodeBlobG__vtbl_", &J->CodeBlob_vtbl); 447 err = find_symbol(J, "__1cICodeBlobG__vtbl_", &J->CodeBlob_vtbl);
455 CHECK_FAIL(err); 448 CHECK_FAIL(err);
456 err = find_symbol(J, "__1cLRuntimeStubG__vtbl_", &J->RuntimeStub_vtbl); 449 err = find_symbol(J, "__1cLRuntimeStubG__vtbl_", &J->RuntimeStub_vtbl);
457 CHECK_FAIL(err); 450 CHECK_FAIL(err);
451 err = find_symbol(J, "__1cGMethodG__vtbl_", &J->Method_vtbl);
452 CHECK_FAIL(err);
458 453
459 err = parse_vmstructs(J); 454 err = parse_vmstructs(J);
460 CHECK_FAIL(err); 455 CHECK_FAIL(err);
461 err = read_volatiles(J); 456 err = read_volatiles(J);
462 CHECK_FAIL(err); 457 CHECK_FAIL(err);
472 if (J != NULL) { 467 if (J != NULL) {
473 free(J); 468 free(J);
474 } 469 }
475 } 470 }
476 471
477 static int is_methodOop(jvm_agent_t* J, uint64_t methodOopPtr) { 472 static int is_method(jvm_agent_t* J, uint64_t methodPtr) {
478 uint64_t klass; 473 uint64_t klass;
479 int err; 474 int err = read_pointer(J, methodPtr, &klass);
480 // If UseCompressedOops, this was a compressed oop.
481 if (J->Use_Compressed_Oops != 0) {
482 uint32_t cklass;
483 err = read_compressed_pointer(J, methodOopPtr + OFFSET_oopDesc_metadata,
484 &cklass);
485 // decode heap oop, same as oop.inline.hpp
486 klass = (uint64_t)((uintptr_t)J->Universe_narrow_oop_base +
487 ((uintptr_t)cklass << J->Universe_narrow_oop_shift));
488 } else {
489 err = read_pointer(J, methodOopPtr + OFFSET_oopDesc_metadata, &klass);
490 }
491 if (err != PS_OK) goto fail; 475 if (err != PS_OK) goto fail;
492 return klass == J->Universe_methodKlassObj; 476 return klass == J->Method_vtbl;
493 477
494 fail: 478 fail:
495 return 0; 479 return 0;
496 } 480 }
497 481
498 static int 482 static int
499 name_for_methodOop(jvm_agent_t* J, uint64_t methodOopPtr, char * result, size_t size) 483 name_for_methodPtr(jvm_agent_t* J, uint64_t methodPtr, char * result, size_t size)
500 { 484 {
501 short nameIndex; 485 short nameIndex;
502 short signatureIndex; 486 short signatureIndex;
503 uint64_t constantPool; 487 uint64_t constantPool;
504 uint64_t constMethod; 488 uint64_t constMethod;
512 char * nameString = NULL; 496 char * nameString = NULL;
513 char * klassString = NULL; 497 char * klassString = NULL;
514 char * signatureString = NULL; 498 char * signatureString = NULL;
515 int err; 499 int err;
516 500
517 err = read_pointer(J, methodOopPtr + OFFSET_methodOopDesc_constMethod, &constMethod); 501 err = read_pointer(J, methodPtr + OFFSET_Method_constMethod, &constMethod);
518 CHECK_FAIL(err); 502 CHECK_FAIL(err);
519 err = read_pointer(J, constMethod + OFFSET_constMethodOopDesc_constants, &constantPool); 503 err = read_pointer(J, constMethod + OFFSET_ConstMethod_constants, &constantPool);
520 CHECK_FAIL(err); 504 CHECK_FAIL(err);
521 505
522 /* To get name string */ 506 /* To get name string */
523 err = ps_pread(J->P, constMethod + OFFSET_constMethodOopDesc_name_index, &nameIndex, 2); 507 err = ps_pread(J->P, constMethod + OFFSET_ConstMethod_name_index, &nameIndex, 2);
524 CHECK_FAIL(err); 508 CHECK_FAIL(err);
525 err = read_pointer(J, constantPool + nameIndex * POINTER_SIZE + SIZE_constantPoolOopDesc, &nameSymbol); 509 err = read_pointer(J, constantPool + nameIndex * POINTER_SIZE + SIZE_ConstantPool, &nameSymbol);
526 CHECK_FAIL(err); 510 CHECK_FAIL(err);
527 // The symbol is a CPSlot and has lower bit set to indicate metadata 511 // The symbol is a CPSlot and has lower bit set to indicate metadata
528 nameSymbol &= (~1); // remove metadata lsb 512 nameSymbol &= (~1); // remove metadata lsb
529 err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_length, &nameSymbolLength, 2); 513 err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_length, &nameSymbolLength, 2);
530 CHECK_FAIL(err); 514 CHECK_FAIL(err);
531 nameString = (char*)calloc(nameSymbolLength + 1, 1); 515 nameString = (char*)calloc(nameSymbolLength + 1, 1);
532 err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_body, nameString, nameSymbolLength); 516 err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_body, nameString, nameSymbolLength);
533 CHECK_FAIL(err); 517 CHECK_FAIL(err);
534 518
535 /* To get signature string */ 519 /* To get signature string */
536 err = ps_pread(J->P, constMethod + OFFSET_constMethodOopDesc_signature_index, &signatureIndex, 2); 520 err = ps_pread(J->P, constMethod + OFFSET_ConstMethod_signature_index, &signatureIndex, 2);
537 CHECK_FAIL(err); 521 CHECK_FAIL(err);
538 err = read_pointer(J, constantPool + signatureIndex * POINTER_SIZE + SIZE_constantPoolOopDesc, &signatureSymbol); 522 err = read_pointer(J, constantPool + signatureIndex * POINTER_SIZE + SIZE_ConstantPool, &signatureSymbol);
539 CHECK_FAIL(err); 523 CHECK_FAIL(err);
540 signatureSymbol &= (~1); // remove metadata lsb 524 signatureSymbol &= (~1); // remove metadata lsb
541 err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_length, &signatureSymbolLength, 2); 525 err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_length, &signatureSymbolLength, 2);
542 CHECK_FAIL(err); 526 CHECK_FAIL(err);
543 signatureString = (char*)calloc(signatureSymbolLength + 1, 1); 527 signatureString = (char*)calloc(signatureSymbolLength + 1, 1);
544 err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_body, signatureString, signatureSymbolLength); 528 err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_body, signatureString, signatureSymbolLength);
545 CHECK_FAIL(err); 529 CHECK_FAIL(err);
546 530
547 /* To get klass string */ 531 /* To get klass string */
548 err = read_pointer(J, constantPool + OFFSET_constantPoolOopDesc_pool_holder, &klassPtr); 532 err = read_pointer(J, constantPool + OFFSET_ConstantPool_pool_holder, &klassPtr);
549 CHECK_FAIL(err); 533 CHECK_FAIL(err);
550 err = read_pointer(J, klassPtr + OFFSET_Klass_name + SIZE_oopDesc, &klassSymbol); 534 err = read_pointer(J, klassPtr + OFFSET_Klass_name, &klassSymbol);
551 CHECK_FAIL(err); 535 CHECK_FAIL(err);
552 err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_length, &klassSymbolLength, 2); 536 err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_length, &klassSymbolLength, 2);
553 CHECK_FAIL(err); 537 CHECK_FAIL(err);
554 klassString = (char*)calloc(klassSymbolLength + 1, 1); 538 klassString = (char*)calloc(klassSymbolLength + 1, 1);
555 err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_body, klassString, klassSymbolLength); 539 err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_body, klassString, klassSymbolLength);
570 554
571 return PS_OK; 555 return PS_OK;
572 556
573 fail: 557 fail:
574 if (debug) { 558 if (debug) {
575 fprintf(stderr, "name_for_methodOop: FAIL \n\n"); 559 fprintf(stderr, "name_for_methodPtr: FAIL \n\n");
576 } 560 }
577 if (nameString != NULL) free(nameString); 561 if (nameString != NULL) free(nameString);
578 if (klassString != NULL) free(klassString); 562 if (klassString != NULL) free(klassString);
579 if (signatureString != NULL) free(signatureString); 563 if (signatureString != NULL) free(signatureString);
580 return -1; 564 return -1;
597 err = ps_pread(J->P, nm + OFFSET_nmethod_deoptimize_offset, &N->deopt_beg, SZ32); 581 err = ps_pread(J->P, nm + OFFSET_nmethod_deoptimize_offset, &N->deopt_beg, SZ32);
598 CHECK_FAIL(err); 582 CHECK_FAIL(err);
599 err = ps_pread(J->P, nm + OFFSET_nmethod_orig_pc_offset, &N->orig_pc_offset, SZ32); 583 err = ps_pread(J->P, nm + OFFSET_nmethod_orig_pc_offset, &N->orig_pc_offset, SZ32);
600 CHECK_FAIL(err); 584 CHECK_FAIL(err);
601 585
602 /* Oops */ 586 /* Metadata */
603 err = ps_pread(J->P, nm + OFFSET_nmethod_oops_offset, &N->oops_beg, SZ32); 587 err = ps_pread(J->P, nm + OFFSET_nmethod_metadata_offset, &N->metadata_beg, SZ32);
604 CHECK_FAIL(err); 588 CHECK_FAIL(err);
605 err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_offset, &N->oops_end, SZ32); 589 err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_offset, &N->metadata_end, SZ32);
606 CHECK_FAIL(err); 590 CHECK_FAIL(err);
607 591
608 /* scopes_pcs */ 592 /* scopes_pcs */
609 err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_pcs_offset, &N->scopes_pcs_beg, SZ32); 593 err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_pcs_offset, &N->scopes_pcs_beg, SZ32);
610 CHECK_FAIL(err); 594 CHECK_FAIL(err);
625 N->deopt_beg); 609 N->deopt_beg);
626 610
627 fprintf(stderr, "\t nmethod_info: orig_pc_offset: %#x \n", 611 fprintf(stderr, "\t nmethod_info: orig_pc_offset: %#x \n",
628 N->orig_pc_offset); 612 N->orig_pc_offset);
629 613
630 fprintf(stderr, "\t nmethod_info: oops_beg: %#x, oops_end: %#x\n", 614 fprintf(stderr, "\t nmethod_info: metadata_beg: %#x, metadata_end: %#x\n",
631 N->oops_beg, N->oops_end); 615 N->metadata_beg, N->metadata_end);
632 616
633 fprintf(stderr, "\t nmethod_info: scopes_data_beg: %#x, scopes_data_end: %#x\n", 617 fprintf(stderr, "\t nmethod_info: scopes_data_beg: %#x, scopes_data_end: %#x\n",
634 N->scopes_data_beg, N->scopes_data_end); 618 N->scopes_data_beg, N->scopes_data_end);
635 619
636 fprintf(stderr, "\t nmethod_info: scopes_pcs_beg: %#x, scopes_pcs_end: %#x\n", 620 fprintf(stderr, "\t nmethod_info: scopes_pcs_beg: %#x, scopes_pcs_end: %#x\n",
764 int32_t stream_line = 0; 748 int32_t stream_line = 0;
765 int32_t err; 749 int32_t err;
766 750
767 if (debug > 2) { 751 if (debug > 2) {
768 char name[256]; 752 char name[256];
769 err = name_for_methodOop(J, vf->methodOop, name, 256); 753 err = name_for_methodPtr(J, vf->method, name, 256);
770 CHECK_FAIL(err); 754 CHECK_FAIL(err);
771 fprintf(stderr, "\t line_number_from_bci: BEGIN, method name: %s, targ bci: %d\n", 755 fprintf(stderr, "\t line_number_from_bci: BEGIN, method name: %s, targ bci: %d\n",
772 name, vf->bci); 756 name, vf->bci);
773 } 757 }
774 758
775 err = read_pointer(J, vf->methodOop + OFFSET_methodOopDesc_constMethod, &constMethod); 759 err = read_pointer(J, vf->method + OFFSET_Method_constMethod, &constMethod);
776 CHECK_FAIL(err); 760 CHECK_FAIL(err);
777 761
778 vf->line = 0; 762 vf->line = 0;
779 err = ps_pread(J->P, constMethod + OFFSET_constMethodOopDesc_flags, &access_flags, sizeof(int8_t)); 763 err = ps_pread(J->P, constMethod + OFFSET_ConstMethod_flags, &access_flags, sizeof(int8_t));
780 CHECK_FAIL(err); 764 CHECK_FAIL(err);
781 765
782 if (!(access_flags & constMethodOopDesc_has_linenumber_table)) { 766 if (!(access_flags & ConstMethod_has_linenumber_table)) {
783 if (debug > 2) 767 if (debug > 2)
784 fprintf(stderr, "\t line_number_from_bci: END: !HAS_LINE_NUMBER_TABLE \n\n"); 768 fprintf(stderr, "\t line_number_from_bci: END: !HAS_LINE_NUMBER_TABLE \n\n");
785 return PS_OK; 769 return PS_OK;
786 } 770 }
787 771
788 /* The line numbers are a short array of 2-tuples [start_pc, line_number]. 772 /* The line numbers are a short array of 2-tuples [start_pc, line_number].
789 * Not necessarily sorted and not necessarily one-to-one. 773 * Not necessarily sorted and not necessarily one-to-one.
790 */ 774 */
791 775
792 err = ps_pread(J->P, constMethod + OFFSET_constMethodOopDesc_code_size, &code_size, SZ16); 776 err = ps_pread(J->P, constMethod + OFFSET_ConstMethod_code_size, &code_size, SZ16);
793 CHECK_FAIL(err); 777 CHECK_FAIL(err);
794 778
795 /* inlined_table_start() */ 779 /* inlined_table_start() */
796 code_end_delta = (uint64_t) (access_flags & AccessFlags_NATIVE) ? 2*POINTER_SIZE : 0; 780 code_end_delta = (uint64_t) (access_flags & AccessFlags_NATIVE) ? 2*POINTER_SIZE : 0;
797 buffer = constMethod + (uint64_t) SIZE_constMethodOopDesc + (uint64_t) code_size + code_end_delta; 781 buffer = constMethod + (uint64_t) SIZE_ConstMethod + (uint64_t) code_size + code_end_delta;
798 782
799 if (debug > 2) { 783 if (debug > 2) {
800 fprintf(stderr, "\t\t line_number_from_bci: methodOop: %#llx, native: %d\n", 784 fprintf(stderr, "\t\t line_number_from_bci: method: %#llx, native: %d\n",
801 vf->methodOop, (access_flags & AccessFlags_NATIVE)); 785 vf->method, (access_flags & AccessFlags_NATIVE));
802 fprintf(stderr, "\t\t line_number_from_bci: buffer: %#llx, code_size: %d\n", 786 fprintf(stderr, "\t\t line_number_from_bci: buffer: %#llx, code_size: %d\n",
803 buffer, (int) code_size); 787 buffer, (int) code_size);
804 } 788 }
805 789
806 while (read_pair(J, &buffer, &stream_bci, &stream_line) == 0) { 790 while (read_pair(J, &buffer, &stream_bci, &stream_line) == 0) {
960 } 944 }
961 945
962 err = scope_desc_at(N, decode_offset, vf); 946 err = scope_desc_at(N, decode_offset, vf);
963 CHECK_FAIL(err); 947 CHECK_FAIL(err);
964 948
965 if (vf->methodIdx > ((N->oops_end - N->oops_beg) / POINTER_SIZE)) { 949 if (vf->methodIdx > ((N->metadata_end - N->metadata_beg) / POINTER_SIZE)) {
966 fprintf(stderr, "\t scopeDesc_chain: (methodIdx > oops length) !\n"); 950 fprintf(stderr, "\t scopeDesc_chain: (methodIdx > metadata length) !\n");
967 return -1; 951 return -1;
968 } 952 }
969 err = read_pointer(N->J, N->nm + N->oops_beg + (vf->methodIdx-1)*POINTER_SIZE, 953 err = read_pointer(N->J, N->nm + N->metadata_beg + (vf->methodIdx-1)*POINTER_SIZE,
970 &vf->methodOop); 954 &vf->method);
971 CHECK_FAIL(err); 955 CHECK_FAIL(err);
972 956
973 if (vf->methodOop) { 957 if (vf->method) {
974 N->vf_cnt++; 958 N->vf_cnt++;
975 err = line_number_from_bci(N->J, vf); 959 err = line_number_from_bci(N->J, vf);
976 CHECK_FAIL(err); 960 CHECK_FAIL(err);
977 if (debug > 2) { 961 if (debug > 2) {
978 fprintf(stderr, "\t scopeDesc_chain: methodOop: %#8llx, line: %ld\n", 962 fprintf(stderr, "\t scopeDesc_chain: method: %#8llx, line: %ld\n",
979 vf->methodOop, vf->line); 963 vf->method, vf->line);
980 } 964 }
981 } 965 }
982 decode_offset = vf->sender_decode_offset; 966 decode_offset = vf->sender_decode_offset;
983 } 967 }
984 if (debug > 2) { 968 if (debug > 2) {
996 980
997 static int 981 static int
998 name_for_nmethod(jvm_agent_t* J, 982 name_for_nmethod(jvm_agent_t* J,
999 uint64_t nm, 983 uint64_t nm,
1000 uint64_t pc, 984 uint64_t pc,
1001 uint64_t methodOop, 985 uint64_t method,
1002 char *result, 986 char *result,
1003 size_t size, 987 size_t size,
1004 Jframe_t *jframe 988 Jframe_t *jframe
1005 ) { 989 ) {
1006 Nmethod_t *N; 990 Nmethod_t *N;
1060 vf = &N->vframes[0]; 1044 vf = &N->vframes[0];
1061 if (N->vf_cnt > 0) { 1045 if (N->vf_cnt > 0) {
1062 jframe->vf_cnt = N->vf_cnt; 1046 jframe->vf_cnt = N->vf_cnt;
1063 jframe->bci = vf->bci; 1047 jframe->bci = vf->bci;
1064 jframe->line = vf->line; 1048 jframe->line = vf->line;
1065 err = name_for_methodOop(J, N->vframes[0].methodOop, result+1, size-1); 1049 err = name_for_methodPtr(J, N->vframes[0].method, result+1, size-1);
1066 CHECK_FAIL(err); 1050 CHECK_FAIL(err);
1067 } else { 1051 } else {
1068 err = name_for_methodOop(J, methodOop, result+1, size-1); 1052 err = name_for_methodPtr(J, method, result+1, size-1);
1069 CHECK_FAIL(err); 1053 CHECK_FAIL(err);
1070 } 1054 }
1071 if (deoptimized) { 1055 if (deoptimized) {
1072 strncat(result + 1, " [deoptimized frame]; ", size-1); 1056 strncat(result + 1, " [deoptimized frame]; ", size-1);
1073 } else { 1057 } else {
1095 } 1079 }
1096 1080
1097 static int 1081 static int
1098 name_for_imethod(jvm_agent_t* J, 1082 name_for_imethod(jvm_agent_t* J,
1099 uint64_t bcx, 1083 uint64_t bcx,
1100 uint64_t methodOop, 1084 uint64_t method,
1101 char *result, 1085 char *result,
1102 size_t size, 1086 size_t size,
1103 Jframe_t *jframe 1087 Jframe_t *jframe
1104 ) { 1088 ) {
1105 uint64_t bci; 1089 uint64_t bci;
1106 uint64_t constMethod; 1090 uint64_t constMethod;
1107 Vframe_t vframe = {0}; 1091 Vframe_t vframe = {0};
1108 Vframe_t *vf = &vframe; 1092 Vframe_t *vf = &vframe;
1109 int32_t err; 1093 int32_t err;
1110 1094
1111 err = read_pointer(J, methodOop + OFFSET_methodOopDesc_constMethod, &constMethod); 1095 err = read_pointer(J, method + OFFSET_Method_constMethod, &constMethod);
1112 CHECK_FAIL(err); 1096 CHECK_FAIL(err);
1113 1097
1114 bci = is_bci(bcx) ? bcx : bcx - (constMethod + (uint64_t) SIZE_constMethodOopDesc); 1098 bci = is_bci(bcx) ? bcx : bcx - (constMethod + (uint64_t) SIZE_ConstMethod);
1115 1099
1116 if (debug) 1100 if (debug)
1117 fprintf(stderr, "\t name_for_imethod: BEGIN: methodOop: %#llx\n", methodOop); 1101 fprintf(stderr, "\t name_for_imethod: BEGIN: method: %#llx\n", method);
1118 1102
1119 err = name_for_methodOop(J, methodOop, result, size); 1103 err = name_for_methodPtr(J, method, result, size);
1120 CHECK_FAIL(err); 1104 CHECK_FAIL(err);
1121 if (debug) 1105 if (debug)
1122 fprintf(stderr, "\t name_for_imethod: method name: %s\n", result); 1106 fprintf(stderr, "\t name_for_imethod: method name: %s\n", result);
1123 1107
1124 if (bci > 0) { 1108 if (bci > 0) {
1125 vf->methodOop = methodOop; 1109 vf->method = method;
1126 vf->bci = bci; 1110 vf->bci = bci;
1127 err = line_number_from_bci(J, vf); 1111 err = line_number_from_bci(J, vf);
1128 CHECK_FAIL(err); 1112 CHECK_FAIL(err);
1129 } 1113 }
1130 jframe->bci = vf->bci; 1114 jframe->bci = vf->bci;
1159 1143
1160 err = read_pointer(J, start, &vtbl); 1144 err = read_pointer(J, start, &vtbl);
1161 CHECK_FAIL(err); 1145 CHECK_FAIL(err);
1162 1146
1163 if (vtbl == J->nmethod_vtbl) { 1147 if (vtbl == J->nmethod_vtbl) {
1164 uint64_t methodOop; 1148 uint64_t method;
1165 1149
1166 err = read_pointer(J, start + OFFSET_nmethod_method, &methodOop); 1150 err = read_pointer(J, start + OFFSET_nmethod_method, &method);
1167 CHECK_FAIL(err); 1151 CHECK_FAIL(err);
1168 1152
1169 if (debug) { 1153 if (debug) {
1170 fprintf(stderr, "name_for_codecache: start: %#8llx, pc: %#8llx, methodOop: %#8llx \n", 1154 fprintf(stderr, "name_for_codecache: start: %#8llx, pc: %#8llx, method: %#8llx \n",
1171 start, pc, methodOop); 1155 start, pc, method);
1172 } 1156 }
1173 err = name_for_nmethod(J, start, pc, methodOop, result, size, jframe); 1157 err = name_for_nmethod(J, start, pc, method, result, size, jframe);
1174 CHECK_FAIL(err); 1158 CHECK_FAIL(err);
1175 } else if (vtbl == J->BufferBlob_vtbl) { 1159 } else if (vtbl == J->BufferBlob_vtbl) {
1176 const char * name; 1160 const char * name;
1177 1161
1178 err = read_string_pointer(J, start + OFFSET_CodeBlob_name, &name); 1162 err = read_string_pointer(J, start + OFFSET_CodeBlob_name, &name);
1182 * We need some other way to distinguish "StubRoutines" 1166 * We need some other way to distinguish "StubRoutines"
1183 * and regular interpreted frames. 1167 * and regular interpreted frames.
1184 */ 1168 */
1185 if (err == PS_OK && strncmp(name, "Interpreter", 11) == 0) { 1169 if (err == PS_OK && strncmp(name, "Interpreter", 11) == 0) {
1186 *is_interpreted = 1; 1170 *is_interpreted = 1;
1187 if (is_methodOop(J, J->methodOopPtr)) { 1171 if (is_method(J, J->methodPtr)) {
1188 return name_for_imethod(J, J->bcx, J->methodOopPtr, result, size, jframe); 1172 return name_for_imethod(J, J->bcx, J->methodPtr, result, size, jframe);
1189 } 1173 }
1190 } 1174 }
1191 1175
1192 if (err == PS_OK) { 1176 if (err == PS_OK) {
1193 strncpy(result, name, size); 1177 strncpy(result, name, size);
1313 (void) sprintf(name, "Wrong inlinedMethod%1d()", vframe_no); 1297 (void) sprintf(name, "Wrong inlinedMethod%1d()", vframe_no);
1314 return -1; 1298 return -1;
1315 } 1299 }
1316 vf = N->vframes + vframe_no; 1300 vf = N->vframes + vframe_no;
1317 name[0] = COMP_METHOD_SIGN; 1301 name[0] = COMP_METHOD_SIGN;
1318 err = name_for_methodOop(J, vf->methodOop, name + 1, size); 1302 err = name_for_methodPtr(J, vf->method, name + 1, size);
1319 CHECK_FAIL(err); 1303 CHECK_FAIL(err);
1320 1304
1321 jframe->bci = vf->bci; 1305 jframe->bci = vf->bci;
1322 jframe->line = vf->line; 1306 jframe->line = vf->line;
1323 if (debug) { 1307 if (debug) {
1338 int Jlookup_by_regs(jvm_agent_t* J, const prgregset_t regs, char *name, 1322 int Jlookup_by_regs(jvm_agent_t* J, const prgregset_t regs, char *name,
1339 size_t size, Jframe_t *jframe) { 1323 size_t size, Jframe_t *jframe) {
1340 uintptr_t fp; 1324 uintptr_t fp;
1341 uintptr_t pc; 1325 uintptr_t pc;
1342 /* arguments given to read_pointer need to be worst case sized */ 1326 /* arguments given to read_pointer need to be worst case sized */
1343 uint64_t methodOopPtr = 0; 1327 uint64_t methodPtr = 0;
1344 uint64_t sender_sp; 1328 uint64_t sender_sp;
1345 uint64_t bcx = 0; 1329 uint64_t bcx = 0;
1346 int is_interpreted = 0; 1330 int is_interpreted = 0;
1347 int result = PS_OK; 1331 int result = PS_OK;
1348 int err = PS_OK; 1332 int err = PS_OK;
1372 * In the pcDesc structure return pc offset is recorded for CALL instructions. 1356 * In the pcDesc structure return pc offset is recorded for CALL instructions.
1373 * regs[R_PC] contains a CALL instruction pc offset. 1357 * regs[R_PC] contains a CALL instruction pc offset.
1374 */ 1358 */
1375 pc += 8; 1359 pc += 8;
1376 bcx = (uintptr_t) regs[R_L1]; 1360 bcx = (uintptr_t) regs[R_L1];
1377 methodOopPtr = (uintptr_t) regs[R_L2]; 1361 methodPtr = (uintptr_t) regs[R_L2];
1378 sender_sp = regs[R_I5]; 1362 sender_sp = regs[R_I5];
1379 if (debug > 2) { 1363 if (debug > 2) {
1380 fprintf(stderr, "\nregs[R_I1]=%lx, regs[R_I2]=%lx, regs[R_I5]=%lx, regs[R_L1]=%lx, regs[R_L2]=%lx\n", 1364 fprintf(stderr, "\nregs[R_I1]=%lx, regs[R_I2]=%lx, regs[R_I5]=%lx, regs[R_L1]=%lx, regs[R_L2]=%lx\n",
1381 regs[R_I1], regs[R_I2], regs[R_I5], regs[R_L1], regs[R_L2]); 1365 regs[R_I1], regs[R_I2], regs[R_I5], regs[R_L1], regs[R_L2]);
1382 } 1366 }
1393 } 1377 }
1394 if (debug > 2) { 1378 if (debug > 2) {
1395 printf("Jlookup_by_regs: J->prev_fr.fp = %#lx\n", J->prev_fr.fp); 1379 printf("Jlookup_by_regs: J->prev_fr.fp = %#lx\n", J->prev_fr.fp);
1396 } 1380 }
1397 1381
1398 if (read_pointer(J, fp + OFFSET_interpreter_frame_method, &methodOopPtr) != PS_OK) { 1382 if (read_pointer(J, fp + OFFSET_interpreter_frame_method, &methodPtr) != PS_OK) {
1399 methodOopPtr = 0; 1383 methodPtr = 0;
1400 } 1384 }
1401 if (read_pointer(J, fp + OFFSET_interpreter_frame_sender_sp, &sender_sp) != PS_OK) { 1385 if (read_pointer(J, fp + OFFSET_interpreter_frame_sender_sp, &sender_sp) != PS_OK) {
1402 sender_sp = 0; 1386 sender_sp = 0;
1403 } 1387 }
1404 if (read_pointer(J, fp + OFFSET_interpreter_frame_bcx_offset, &bcx) != PS_OK) { 1388 if (read_pointer(J, fp + OFFSET_interpreter_frame_bcx_offset, &bcx) != PS_OK) {
1405 bcx = 0; 1389 bcx = 0;
1406 } 1390 }
1407 #endif /* i386 */ 1391 #endif /* i386 */
1408 1392
1409 J->methodOopPtr = methodOopPtr; 1393 J->methodPtr = methodPtr;
1410 J->bcx = bcx; 1394 J->bcx = bcx;
1411 1395
1412 /* On x86 with C2 JVM: native frame may have wrong regs[R_FP] 1396 /* On x86 with C2 JVM: native frame may have wrong regs[R_FP]
1413 * For example: JVM_SuspendThread frame poins to the top interpreted frame. 1397 * For example: JVM_SuspendThread frame poins to the top interpreted frame.
1414 * If we call is_methodOop(J, methodOopPtr) before codecache_contains(J, pc) 1398 * If we call is_method(J, methodPtr) before codecache_contains(J, pc)
1415 * then we go over and omit both: nmethod and I2CAdapter frames. 1399 * then we go over and omit both: nmethod and I2CAdapter frames.
1416 * Note, that regs[R_PC] is always correct if frame defined correctly. 1400 * Note, that regs[R_PC] is always correct if frame defined correctly.
1417 * So it is better to call codecache_contains(J, pc) from the beginning. 1401 * So it is better to call codecache_contains(J, pc) from the beginning.
1418 */ 1402 */
1419 #ifndef X86_COMPILER2 1403 #ifndef X86_COMPILER2
1420 if (is_methodOop(J, J->methodOopPtr)) { 1404 if (is_method(J, J->methodPtr)) {
1421 result = name_for_imethod(J, bcx, J->methodOopPtr, name, size, jframe); 1405 result = name_for_imethod(J, bcx, J->methodPtr, name, size, jframe);
1422 /* If the methodOopPtr is a method then this is highly likely to be 1406 /* If the methodPtr is a method then this is highly likely to be
1423 an interpreter frame */ 1407 an interpreter frame */
1424 if (result >= 0) { 1408 if (result >= 0) {
1425 is_interpreted = 1; 1409 is_interpreted = 1;
1426 } 1410 }
1427 } else 1411 } else
1429 1413
1430 if (codecache_contains(J, pc)) { 1414 if (codecache_contains(J, pc)) {
1431 result = name_for_codecache(J, fp, pc, name, size, jframe, &is_interpreted); 1415 result = name_for_codecache(J, fp, pc, name, size, jframe, &is_interpreted);
1432 } 1416 }
1433 #ifdef X86_COMPILER2 1417 #ifdef X86_COMPILER2
1434 else if (is_methodOop(J, J->methodOopPtr)) { 1418 else if (is_method(J, J->methodPtr)) {
1435 result = name_for_imethod(J, bcx, J->methodOopPtr, name, size, jframe); 1419 result = name_for_imethod(J, bcx, J->methodPtr, name, size, jframe);
1436 /* If the methodOopPtr is a method then this is highly likely to be 1420 /* If the methodPtr is a method then this is highly likely to be
1437 an interpreter frame */ 1421 an interpreter frame */
1438 if (result >= 0) { 1422 if (result >= 0) {
1439 is_interpreted = 1; 1423 is_interpreted = 1;
1440 } 1424 }
1441 } 1425 }