Mercurial > hg > truffle
comparison src/share/vm/ci/ciInstanceKlass.cpp @ 6972:bd7a7ce2e264
6830717: replay of compilations would help with debugging
Summary: When java process crashed in compiler thread, repeat the compilation process will help finding root cause. This is done with using SA dump application class data and replay data from core dump, then use debug version of jvm to recompile the problematic java method.
Reviewed-by: kvn, twisti, sspitsyn
Contributed-by: yumin.qi@oracle.com
author | minqi |
---|---|
date | Mon, 12 Nov 2012 14:03:53 -0800 |
parents | da91efe96a93 |
children | 2cb439954abf fcc9e7681d63 |
comparison
equal
deleted
inserted
replaced
6965:3be318ecfae5 | 6972:bd7a7ce2e264 |
---|---|
559 _implementor = impl; | 559 _implementor = impl; |
560 } | 560 } |
561 } | 561 } |
562 return impl; | 562 return impl; |
563 } | 563 } |
564 | |
565 // Utility class for printing of the contents of the static fields for | |
566 // use by compilation replay. It only prints out the information that | |
567 // could be consumed by the compiler, so for primitive types it prints | |
568 // out the actual value. For Strings it's the actual string value. | |
569 // For array types it it's first level array size since that's the | |
570 // only value which statically unchangeable. For all other reference | |
571 // types it simply prints out the dynamic type. | |
572 | |
573 class StaticFinalFieldPrinter : public FieldClosure { | |
574 outputStream* _out; | |
575 const char* _holder; | |
576 public: | |
577 StaticFinalFieldPrinter(outputStream* out, const char* holder) : | |
578 _out(out), | |
579 _holder(holder) { | |
580 } | |
581 void do_field(fieldDescriptor* fd) { | |
582 if (fd->is_final() && !fd->has_initial_value()) { | |
583 oop mirror = fd->field_holder()->java_mirror(); | |
584 _out->print("staticfield %s %s %s ", _holder, fd->name()->as_quoted_ascii(), fd->signature()->as_quoted_ascii()); | |
585 switch (fd->field_type()) { | |
586 case T_BYTE: _out->print_cr("%d", mirror->byte_field(fd->offset())); break; | |
587 case T_BOOLEAN: _out->print_cr("%d", mirror->bool_field(fd->offset())); break; | |
588 case T_SHORT: _out->print_cr("%d", mirror->short_field(fd->offset())); break; | |
589 case T_CHAR: _out->print_cr("%d", mirror->char_field(fd->offset())); break; | |
590 case T_INT: _out->print_cr("%d", mirror->int_field(fd->offset())); break; | |
591 case T_LONG: _out->print_cr(INT64_FORMAT, mirror->long_field(fd->offset())); break; | |
592 case T_FLOAT: { | |
593 float f = mirror->float_field(fd->offset()); | |
594 _out->print_cr("%d", *(int*)&f); | |
595 break; | |
596 } | |
597 case T_DOUBLE: { | |
598 double d = mirror->double_field(fd->offset()); | |
599 _out->print_cr(INT64_FORMAT, *(jlong*)&d); | |
600 break; | |
601 } | |
602 case T_ARRAY: { | |
603 oop value = mirror->obj_field_acquire(fd->offset()); | |
604 if (value == NULL) { | |
605 _out->print_cr("null"); | |
606 } else { | |
607 typeArrayOop ta = (typeArrayOop)value; | |
608 _out->print("%d", ta->length()); | |
609 if (value->is_objArray()) { | |
610 objArrayOop oa = (objArrayOop)value; | |
611 const char* klass_name = value->klass()->name()->as_quoted_ascii(); | |
612 _out->print(" %s", klass_name); | |
613 } | |
614 _out->cr(); | |
615 } | |
616 break; | |
617 } | |
618 case T_OBJECT: { | |
619 oop value = mirror->obj_field_acquire(fd->offset()); | |
620 if (value == NULL) { | |
621 _out->print_cr("null"); | |
622 } else if (value->is_instance()) { | |
623 if (value->is_a(SystemDictionary::String_klass())) { | |
624 _out->print("\""); | |
625 _out->print_raw(java_lang_String::as_quoted_ascii(value)); | |
626 _out->print_cr("\""); | |
627 } else { | |
628 const char* klass_name = value->klass()->name()->as_quoted_ascii(); | |
629 _out->print_cr(klass_name); | |
630 } | |
631 } else { | |
632 ShouldNotReachHere(); | |
633 } | |
634 break; | |
635 } | |
636 default: | |
637 ShouldNotReachHere(); | |
638 } | |
639 } | |
640 } | |
641 }; | |
642 | |
643 | |
644 void ciInstanceKlass::dump_replay_data(outputStream* out) { | |
645 ASSERT_IN_VM; | |
646 InstanceKlass* ik = get_instanceKlass(); | |
647 ConstantPool* cp = ik->constants(); | |
648 | |
649 // Try to record related loaded classes | |
650 Klass* sub = ik->subklass(); | |
651 while (sub != NULL) { | |
652 if (sub->oop_is_instance()) { | |
653 out->print_cr("instanceKlass %s", sub->name()->as_quoted_ascii()); | |
654 } | |
655 sub = sub->next_sibling(); | |
656 } | |
657 | |
658 // Dump out the state of the constant pool tags. During replay the | |
659 // tags will be validated for things which shouldn't change and | |
660 // classes will be resolved if the tags indicate that they were | |
661 // resolved at compile time. | |
662 out->print("ciInstanceKlass %s %d %d %d", ik->name()->as_quoted_ascii(), | |
663 is_linked(), is_initialized(), cp->length()); | |
664 for (int index = 1; index < cp->length(); index++) { | |
665 out->print(" %d", cp->tags()->at(index)); | |
666 } | |
667 out->cr(); | |
668 if (is_initialized()) { | |
669 // Dump out the static final fields in case the compilation relies | |
670 // on their value for correct replay. | |
671 StaticFinalFieldPrinter sffp(out, ik->name()->as_quoted_ascii()); | |
672 ik->do_local_static_fields(&sffp); | |
673 } | |
674 } |