1463 } |
1526 } |
1464 |
1527 |
1465 // Walk the stack of the given thread. |
1528 // Walk the stack of the given thread. |
1466 // Dumps a HPROF_GC_ROOT_JAVA_FRAME record for each local |
1529 // Dumps a HPROF_GC_ROOT_JAVA_FRAME record for each local |
1467 // Dumps a HPROF_GC_ROOT_JNI_LOCAL record for each JNI local |
1530 // Dumps a HPROF_GC_ROOT_JNI_LOCAL record for each JNI local |
1468 void VM_HeapDumper::do_thread(JavaThread* java_thread, u4 thread_serial_num) { |
1531 // |
|
1532 // It returns the number of Java frames in this thread stack |
|
1533 int VM_HeapDumper::do_thread(JavaThread* java_thread, u4 thread_serial_num) { |
1469 JNILocalsDumper blk(writer(), thread_serial_num); |
1534 JNILocalsDumper blk(writer(), thread_serial_num); |
1470 |
1535 |
1471 oop threadObj = java_thread->threadObj(); |
1536 oop threadObj = java_thread->threadObj(); |
1472 assert(threadObj != NULL, "sanity check"); |
1537 assert(threadObj != NULL, "sanity check"); |
1473 |
1538 |
1474 // JNI locals for the top frame |
1539 int stack_depth = 0; |
1475 java_thread->active_handles()->oops_do(&blk); |
|
1476 |
|
1477 if (java_thread->has_last_Java_frame()) { |
1540 if (java_thread->has_last_Java_frame()) { |
1478 |
1541 |
1479 // vframes are resource allocated |
1542 // vframes are resource allocated |
1480 Thread* current_thread = Thread::current(); |
1543 Thread* current_thread = Thread::current(); |
1481 ResourceMark rm(current_thread); |
1544 ResourceMark rm(current_thread); |
1482 HandleMark hm(current_thread); |
1545 HandleMark hm(current_thread); |
1483 |
1546 |
1484 RegisterMap reg_map(java_thread); |
1547 RegisterMap reg_map(java_thread); |
1485 frame f = java_thread->last_frame(); |
1548 frame f = java_thread->last_frame(); |
1486 vframe* vf = vframe::new_vframe(&f, ®_map, java_thread); |
1549 vframe* vf = vframe::new_vframe(&f, ®_map, java_thread); |
|
1550 frame* last_entry_frame = NULL; |
1487 |
1551 |
1488 while (vf != NULL) { |
1552 while (vf != NULL) { |
|
1553 blk.set_frame_number(stack_depth); |
1489 if (vf->is_java_frame()) { |
1554 if (vf->is_java_frame()) { |
1490 |
1555 |
1491 // java frame (interpreted, compiled, ...) |
1556 // java frame (interpreted, compiled, ...) |
1492 javaVFrame *jvf = javaVFrame::cast(vf); |
1557 javaVFrame *jvf = javaVFrame::cast(vf); |
1493 |
|
1494 if (!(jvf->method()->is_native())) { |
1558 if (!(jvf->method()->is_native())) { |
1495 StackValueCollection* locals = jvf->locals(); |
1559 StackValueCollection* locals = jvf->locals(); |
1496 for (int slot=0; slot<locals->size(); slot++) { |
1560 for (int slot=0; slot<locals->size(); slot++) { |
1497 if (locals->at(slot)->type() == T_OBJECT) { |
1561 if (locals->at(slot)->type() == T_OBJECT) { |
1498 oop o = locals->obj_at(slot)(); |
1562 oop o = locals->obj_at(slot)(); |
1499 |
1563 |
1500 if (o != NULL) { |
1564 if (o != NULL) { |
1501 writer()->write_u1(HPROF_GC_ROOT_JAVA_FRAME); |
1565 writer()->write_u1(HPROF_GC_ROOT_JAVA_FRAME); |
1502 writer()->write_objectID(o); |
1566 writer()->write_objectID(o); |
1503 writer()->write_u4(thread_serial_num); |
1567 writer()->write_u4(thread_serial_num); |
1504 writer()->write_u4((u4)-1); // empty |
1568 writer()->write_u4((u4) stack_depth); |
1505 } |
1569 } |
1506 } |
1570 } |
1507 } |
1571 } |
|
1572 } else { |
|
1573 // native frame |
|
1574 if (stack_depth == 0) { |
|
1575 // JNI locals for the top frame. |
|
1576 java_thread->active_handles()->oops_do(&blk); |
|
1577 } else { |
|
1578 if (last_entry_frame != NULL) { |
|
1579 // JNI locals for the entry frame |
|
1580 assert(last_entry_frame->is_entry_frame(), "checking"); |
|
1581 last_entry_frame->entry_frame_call_wrapper()->handles()->oops_do(&blk); |
|
1582 } |
|
1583 } |
1508 } |
1584 } |
|
1585 // increment only for Java frames |
|
1586 stack_depth++; |
|
1587 last_entry_frame = NULL; |
|
1588 |
1509 } else { |
1589 } else { |
1510 |
|
1511 // externalVFrame - if it's an entry frame then report any JNI locals |
1590 // externalVFrame - if it's an entry frame then report any JNI locals |
1512 // as roots |
1591 // as roots when we find the corresponding native javaVFrame |
1513 frame* fr = vf->frame_pointer(); |
1592 frame* fr = vf->frame_pointer(); |
1514 assert(fr != NULL, "sanity check"); |
1593 assert(fr != NULL, "sanity check"); |
1515 if (fr->is_entry_frame()) { |
1594 if (fr->is_entry_frame()) { |
1516 fr->entry_frame_call_wrapper()->handles()->oops_do(&blk); |
1595 last_entry_frame = fr; |
1517 } |
1596 } |
1518 } |
1597 } |
1519 |
|
1520 vf = vf->sender(); |
1598 vf = vf->sender(); |
1521 } |
1599 } |
1522 } |
1600 } else { |
|
1601 // no last java frame but there may be JNI locals |
|
1602 java_thread->active_handles()->oops_do(&blk); |
|
1603 } |
|
1604 return stack_depth; |
1523 } |
1605 } |
1524 |
1606 |
1525 |
1607 |
1526 // write a HPROF_GC_ROOT_THREAD_OBJ record for each java thread. Then walk |
1608 // write a HPROF_GC_ROOT_THREAD_OBJ record for each java thread. Then walk |
1527 // the stack so that locals and JNI locals are dumped. |
1609 // the stack so that locals and JNI locals are dumped. |
1528 void VM_HeapDumper::do_threads() { |
1610 void VM_HeapDumper::do_threads() { |
1529 u4 thread_serial_num = 0; |
1611 for (int i=0; i < _num_threads; i++) { |
1530 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) { |
1612 JavaThread* thread = _stack_traces[i]->thread(); |
1531 oop threadObj = thread->threadObj(); |
1613 oop threadObj = thread->threadObj(); |
1532 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) { |
1614 u4 thread_serial_num = i+1; |
1533 ++thread_serial_num; |
1615 u4 stack_serial_num = thread_serial_num + STACK_TRACE_ID; |
1534 |
1616 writer()->write_u1(HPROF_GC_ROOT_THREAD_OBJ); |
1535 writer()->write_u1(HPROF_GC_ROOT_THREAD_OBJ); |
1617 writer()->write_objectID(threadObj); |
1536 writer()->write_objectID(threadObj); |
1618 writer()->write_u4(thread_serial_num); // thread number |
1537 writer()->write_u4(thread_serial_num); |
1619 writer()->write_u4(stack_serial_num); // stack trace serial number |
1538 writer()->write_u4(STACK_TRACE_ID); |
1620 int num_frames = do_thread(thread, thread_serial_num); |
1539 |
1621 assert(num_frames == _stack_traces[i]->get_stack_depth(), |
1540 do_thread(thread, thread_serial_num); |
1622 "total number of Java frames not matched"); |
1541 } |
|
1542 } |
1623 } |
1543 } |
1624 } |
1544 |
1625 |
1545 |
1626 |
1546 // The VM operation that dumps the heap. The dump consists of the following |
1627 // The VM operation that dumps the heap. The dump consists of the following |
1547 // records: |
1628 // records: |
1548 // |
1629 // |
1549 // HPROF_HEADER |
1630 // HPROF_HEADER |
1550 // HPROF_TRACE |
|
1551 // [HPROF_UTF8]* |
1631 // [HPROF_UTF8]* |
1552 // [HPROF_LOAD_CLASS]* |
1632 // [HPROF_LOAD_CLASS]* |
|
1633 // [[HPROF_FRAME]*|HPROF_TRACE]* |
1553 // [HPROF_GC_CLASS_DUMP]* |
1634 // [HPROF_GC_CLASS_DUMP]* |
1554 // HPROF_HEAP_DUMP |
1635 // HPROF_HEAP_DUMP |
1555 // |
1636 // |
1556 // The HPROF_TRACE record after the header is "dummy trace" record which does |
1637 // The HPROF_TRACE records represent the stack traces where the heap dump |
1557 // not include any frames. Other records which require a stack trace ID will |
1638 // is generated and a "dummy trace" record which does not include |
1558 // specify the trace ID of this record (1). It also means we can run HAT without |
1639 // any frames. The dummy trace record is used to be referenced as the |
1559 // needing the -stack false option. |
1640 // unknown object alloc site. |
1560 // |
1641 // |
1561 // The HPROF_HEAP_DUMP record has a length following by sub-records. To allow |
1642 // The HPROF_HEAP_DUMP record has a length following by sub-records. To allow |
1562 // the heap dump be generated in a single pass we remember the position of |
1643 // the heap dump be generated in a single pass we remember the position of |
1563 // the dump length and fix it up after all sub-records have been written. |
1644 // the dump length and fix it up after all sub-records have been written. |
1564 // To generate the sub-records we iterate over the heap, writing |
1645 // To generate the sub-records we iterate over the heap, writing |
1590 writer()->write_raw((void*)header, (int)strlen(header)); |
1671 writer()->write_raw((void*)header, (int)strlen(header)); |
1591 writer()->write_u1(0); // terminator |
1672 writer()->write_u1(0); // terminator |
1592 writer()->write_u4(oopSize); |
1673 writer()->write_u4(oopSize); |
1593 writer()->write_u8(os::javaTimeMillis()); |
1674 writer()->write_u8(os::javaTimeMillis()); |
1594 |
1675 |
1595 // HPROF_TRACE record without any frames |
|
1596 DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4)); |
|
1597 writer()->write_u4(STACK_TRACE_ID); |
|
1598 writer()->write_u4(0); // thread number |
|
1599 writer()->write_u4(0); // frame count |
|
1600 |
|
1601 // HPROF_UTF8 records |
1676 // HPROF_UTF8 records |
1602 SymbolTableDumper sym_dumper(writer()); |
1677 SymbolTableDumper sym_dumper(writer()); |
1603 SymbolTable::oops_do(&sym_dumper); |
1678 SymbolTable::oops_do(&sym_dumper); |
1604 |
1679 |
1605 // write HPROF_LOAD_CLASS records |
1680 // write HPROF_LOAD_CLASS records |
1606 SystemDictionary::classes_do(&do_load_class); |
1681 SystemDictionary::classes_do(&do_load_class); |
1607 Universe::basic_type_classes_do(&do_load_class); |
1682 Universe::basic_type_classes_do(&do_load_class); |
|
1683 |
|
1684 // write HPROF_FRAME and HPROF_TRACE records |
|
1685 // this must be called after _klass_map is built when iterating the classes above. |
|
1686 dump_stack_traces(); |
1608 |
1687 |
1609 // write HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT |
1688 // write HPROF_HEAP_DUMP or HPROF_HEAP_DUMP_SEGMENT |
1610 write_dump_header(); |
1689 write_dump_header(); |
1611 |
1690 |
1612 // Writes HPROF_GC_CLASS_DUMP records |
1691 // Writes HPROF_GC_CLASS_DUMP records |
1644 // fixes up the length of the dump record. In the case of a segmented |
1723 // fixes up the length of the dump record. In the case of a segmented |
1645 // heap then the HPROF_HEAP_DUMP_END record is also written. |
1724 // heap then the HPROF_HEAP_DUMP_END record is also written. |
1646 end_of_dump(); |
1725 end_of_dump(); |
1647 } |
1726 } |
1648 |
1727 |
|
1728 void VM_HeapDumper::dump_stack_traces() { |
|
1729 // write a HPROF_TRACE record without any frames to be referenced as object alloc sites |
|
1730 DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4)); |
|
1731 writer()->write_u4((u4) STACK_TRACE_ID); |
|
1732 writer()->write_u4(0); // thread number |
|
1733 writer()->write_u4(0); // frame count |
|
1734 |
|
1735 _stack_traces = NEW_C_HEAP_ARRAY(ThreadStackTrace*, Threads::number_of_threads()); |
|
1736 int frame_serial_num = 0; |
|
1737 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) { |
|
1738 oop threadObj = thread->threadObj(); |
|
1739 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) { |
|
1740 // dump thread stack trace |
|
1741 ThreadStackTrace* stack_trace = new ThreadStackTrace(thread, false); |
|
1742 stack_trace->dump_stack_at_safepoint(-1); |
|
1743 _stack_traces[_num_threads++] = stack_trace; |
|
1744 |
|
1745 // write HPROF_FRAME records for this thread's stack trace |
|
1746 int depth = stack_trace->get_stack_depth(); |
|
1747 int thread_frame_start = frame_serial_num; |
|
1748 for (int j=0; j < depth; j++) { |
|
1749 StackFrameInfo* frame = stack_trace->stack_frame_at(j); |
|
1750 methodOop m = frame->method(); |
|
1751 int class_serial_num = _klass_map->find(Klass::cast(m->method_holder())); |
|
1752 // the class serial number starts from 1 |
|
1753 assert(class_serial_num > 0, "class not found"); |
|
1754 DumperSupport::dump_stack_frame(writer(), ++frame_serial_num, class_serial_num, m, frame->bci()); |
|
1755 } |
|
1756 |
|
1757 // write HPROF_TRACE record for one thread |
|
1758 DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4) + depth*oopSize); |
|
1759 int stack_serial_num = _num_threads + STACK_TRACE_ID; |
|
1760 writer()->write_u4(stack_serial_num); // stack trace serial number |
|
1761 writer()->write_u4((u4) _num_threads); // thread serial number |
|
1762 writer()->write_u4(depth); // frame count |
|
1763 for (int j=1; j <= depth; j++) { |
|
1764 writer()->write_id(thread_frame_start + j); |
|
1765 } |
|
1766 } |
|
1767 } |
|
1768 } |
1649 |
1769 |
1650 // dump the heap to given path. |
1770 // dump the heap to given path. |
1651 int HeapDumper::dump(const char* path) { |
1771 int HeapDumper::dump(const char* path) { |
1652 assert(path != NULL && strlen(path) > 0, "path missing"); |
1772 assert(path != NULL && strlen(path) > 0, "path missing"); |
1653 |
1773 |