1519 // After this many redefines, the stack trace is unreliable.
1520 const int MAX_VERSION = USHRT_MAX;
1521
1522 static inline bool version_matches(Method* method, int version) {
1523 assert(version < MAX_VERSION, "version is too big");
1524 return method != NULL && (method->constants()->version() == version);
1525 }
1526
1527 // This class provides a simple wrapper over the internal structure of
1528 // exception backtrace to insulate users of the backtrace from needing
1529 // to know what it looks like.
1530 class BacktraceBuilder: public StackObj {
1531 private:
1532 Handle _backtrace;
1533 objArrayOop _head;
1534 typeArrayOop _methods;
1535 typeArrayOop _bcis;
1536 objArrayOop _mirrors;
1537 typeArrayOop _cprefs; // needed to insulate method name against redefinition
1538 int _index;
1539 No_Safepoint_Verifier _nsv;
1540
1541 public:
1542
1543 enum {
1544 trace_methods_offset = java_lang_Throwable::trace_methods_offset,
1545 trace_bcis_offset = java_lang_Throwable::trace_bcis_offset,
1546 trace_mirrors_offset = java_lang_Throwable::trace_mirrors_offset,
1547 trace_cprefs_offset = java_lang_Throwable::trace_cprefs_offset,
1548 trace_next_offset = java_lang_Throwable::trace_next_offset,
1549 trace_size = java_lang_Throwable::trace_size,
1550 trace_chunk_size = java_lang_Throwable::trace_chunk_size
1551 };
1552
1553 // get info out of chunks
1554 static typeArrayOop get_methods(objArrayHandle chunk) {
1555 typeArrayOop methods = typeArrayOop(chunk->obj_at(trace_methods_offset));
1556 assert(methods != NULL, "method array should be initialized in backtrace");
1557 return methods;
1558 }
1559 static typeArrayOop get_bcis(objArrayHandle chunk) {
1578 _backtrace = _head;
1579 _index = 0;
1580 }
1581
1582 BacktraceBuilder(objArrayHandle backtrace) {
1583 _methods = get_methods(backtrace);
1584 _bcis = get_bcis(backtrace);
1585 _mirrors = get_mirrors(backtrace);
1586 _cprefs = get_cprefs(backtrace);
1587 assert(_methods->length() == _bcis->length() &&
1588 _methods->length() == _mirrors->length(),
1589 "method and source information arrays should match");
1590
1591 // head is the preallocated backtrace
1592 _backtrace = _head = backtrace();
1593 _index = 0;
1594 }
1595
1596 void expand(TRAPS) {
1597 objArrayHandle old_head(THREAD, _head);
1598 Pause_No_Safepoint_Verifier pnsv(&_nsv);
1599
1600 objArrayOop head = oopFactory::new_objectArray(trace_size, CHECK);
1601 objArrayHandle new_head(THREAD, head);
1602
1603 typeArrayOop methods = oopFactory::new_shortArray(trace_chunk_size, CHECK);
1604 typeArrayHandle new_methods(THREAD, methods);
1605
1606 typeArrayOop bcis = oopFactory::new_intArray(trace_chunk_size, CHECK);
1607 typeArrayHandle new_bcis(THREAD, bcis);
1608
1609 objArrayOop mirrors = oopFactory::new_objectArray(trace_chunk_size, CHECK);
1610 objArrayHandle new_mirrors(THREAD, mirrors);
1611
1612 typeArrayOop cprefs = oopFactory::new_shortArray(trace_chunk_size, CHECK);
1613 typeArrayHandle new_cprefs(THREAD, cprefs);
1614
1615 if (!old_head.is_null()) {
1616 old_head->obj_at_put(trace_next_offset, new_head());
1617 }
1618 new_head->obj_at_put(trace_methods_offset, new_methods());
|
1519 // After this many redefines, the stack trace is unreliable.
1520 const int MAX_VERSION = USHRT_MAX;
1521
1522 static inline bool version_matches(Method* method, int version) {
1523 assert(version < MAX_VERSION, "version is too big");
1524 return method != NULL && (method->constants()->version() == version);
1525 }
1526
1527 // This class provides a simple wrapper over the internal structure of
1528 // exception backtrace to insulate users of the backtrace from needing
1529 // to know what it looks like.
1530 class BacktraceBuilder: public StackObj {
1531 private:
1532 Handle _backtrace;
1533 objArrayOop _head;
1534 typeArrayOop _methods;
1535 typeArrayOop _bcis;
1536 objArrayOop _mirrors;
1537 typeArrayOop _cprefs; // needed to insulate method name against redefinition
1538 int _index;
1539 NoSafepointVerifier _nsv;
1540
1541 public:
1542
1543 enum {
1544 trace_methods_offset = java_lang_Throwable::trace_methods_offset,
1545 trace_bcis_offset = java_lang_Throwable::trace_bcis_offset,
1546 trace_mirrors_offset = java_lang_Throwable::trace_mirrors_offset,
1547 trace_cprefs_offset = java_lang_Throwable::trace_cprefs_offset,
1548 trace_next_offset = java_lang_Throwable::trace_next_offset,
1549 trace_size = java_lang_Throwable::trace_size,
1550 trace_chunk_size = java_lang_Throwable::trace_chunk_size
1551 };
1552
1553 // get info out of chunks
1554 static typeArrayOop get_methods(objArrayHandle chunk) {
1555 typeArrayOop methods = typeArrayOop(chunk->obj_at(trace_methods_offset));
1556 assert(methods != NULL, "method array should be initialized in backtrace");
1557 return methods;
1558 }
1559 static typeArrayOop get_bcis(objArrayHandle chunk) {
1578 _backtrace = _head;
1579 _index = 0;
1580 }
1581
1582 BacktraceBuilder(objArrayHandle backtrace) {
1583 _methods = get_methods(backtrace);
1584 _bcis = get_bcis(backtrace);
1585 _mirrors = get_mirrors(backtrace);
1586 _cprefs = get_cprefs(backtrace);
1587 assert(_methods->length() == _bcis->length() &&
1588 _methods->length() == _mirrors->length(),
1589 "method and source information arrays should match");
1590
1591 // head is the preallocated backtrace
1592 _backtrace = _head = backtrace();
1593 _index = 0;
1594 }
1595
1596 void expand(TRAPS) {
1597 objArrayHandle old_head(THREAD, _head);
1598 PauseNoSafepointVerifier pnsv(&_nsv);
1599
1600 objArrayOop head = oopFactory::new_objectArray(trace_size, CHECK);
1601 objArrayHandle new_head(THREAD, head);
1602
1603 typeArrayOop methods = oopFactory::new_shortArray(trace_chunk_size, CHECK);
1604 typeArrayHandle new_methods(THREAD, methods);
1605
1606 typeArrayOop bcis = oopFactory::new_intArray(trace_chunk_size, CHECK);
1607 typeArrayHandle new_bcis(THREAD, bcis);
1608
1609 objArrayOop mirrors = oopFactory::new_objectArray(trace_chunk_size, CHECK);
1610 objArrayHandle new_mirrors(THREAD, mirrors);
1611
1612 typeArrayOop cprefs = oopFactory::new_shortArray(trace_chunk_size, CHECK);
1613 typeArrayHandle new_cprefs(THREAD, cprefs);
1614
1615 if (!old_head.is_null()) {
1616 old_head->obj_at_put(trace_next_offset, new_head());
1617 }
1618 new_head->obj_at_put(trace_methods_offset, new_methods());
|