1345 } else { 1346 // Returns -1 if no LineNumberTable, and otherwise actual line number 1347 line_number = method->line_number_from_bci(bci); 1348 if (line_number == -1 && ShowHiddenFrames) { 1349 line_number = bci + 1000000; 1350 } 1351 } 1352 return line_number; 1353 } 1354 1355 // This class provides a simple wrapper over the internal structure of 1356 // exception backtrace to insulate users of the backtrace from needing 1357 // to know what it looks like. 1358 class BacktraceBuilder: public StackObj { 1359 private: 1360 Handle _backtrace; 1361 objArrayOop _head; 1362 typeArrayOop _methods; 1363 typeArrayOop _bcis; 1364 objArrayOop _mirrors; 1365 typeArrayOop _cprefs; // needed to insulate method name against redefinition 1366 int _index; 1367 No_Safepoint_Verifier _nsv; 1368 1369 public: 1370 1371 enum { 1372 trace_methods_offset = java_lang_Throwable::trace_methods_offset, 1373 trace_bcis_offset = java_lang_Throwable::trace_bcis_offset, 1374 trace_mirrors_offset = java_lang_Throwable::trace_mirrors_offset, 1375 trace_cprefs_offset = java_lang_Throwable::trace_cprefs_offset, 1376 trace_next_offset = java_lang_Throwable::trace_next_offset, 1377 trace_size = java_lang_Throwable::trace_size, 1378 trace_chunk_size = java_lang_Throwable::trace_chunk_size 1379 }; 1380 1381 // get info out of chunks 1382 static typeArrayOop get_methods(objArrayHandle chunk) { 1383 typeArrayOop methods = typeArrayOop(chunk->obj_at(trace_methods_offset)); 1384 assert(methods != NULL, "method array should be initialized in backtrace"); 1385 return methods; 1386 } 1387 static typeArrayOop get_bcis(objArrayHandle chunk) { 1388 typeArrayOop bcis = typeArrayOop(chunk->obj_at(trace_bcis_offset)); 1389 assert(bcis != NULL, "bci array should be initialized in backtrace"); 1390 return bcis; 1391 } 1392 static objArrayOop get_mirrors(objArrayHandle chunk) { 1393 objArrayOop mirrors = objArrayOop(chunk->obj_at(trace_mirrors_offset)); 1394 assert(mirrors != NULL, "mirror array should be initialized in backtrace"); 1395 return mirrors; 1396 } 1397 static typeArrayOop get_cprefs(objArrayHandle chunk) { 1398 typeArrayOop cprefs = typeArrayOop(chunk->obj_at(trace_cprefs_offset)); 1399 assert(cprefs != NULL, "cprefs array should be initialized in backtrace"); 1400 return cprefs; 1401 } 1402 1403 // constructor for new backtrace 1404 BacktraceBuilder(TRAPS): _methods(NULL), _bcis(NULL), _head(NULL), _mirrors(NULL), _cprefs(NULL) { 1405 expand(CHECK); 1406 _backtrace = _head; 1407 _index = 0; 1408 } 1409 1410 BacktraceBuilder(objArrayHandle backtrace) { 1411 _methods = get_methods(backtrace); 1412 _bcis = get_bcis(backtrace); 1413 _mirrors = get_mirrors(backtrace); 1414 _cprefs = get_cprefs(backtrace); 1415 assert(_methods->length() == _bcis->length() && 1416 _methods->length() == _mirrors->length(), 1417 "method and source information arrays should match"); 1418 1419 // head is the preallocated backtrace 1420 _backtrace = _head = backtrace(); 1421 _index = 0; 1422 } 1423 1424 void expand(TRAPS) { 1425 objArrayHandle old_head(THREAD, _head); 1426 Pause_No_Safepoint_Verifier pnsv(&_nsv); 1427 1428 objArrayOop head = oopFactory::new_objectArray(trace_size, CHECK); 1429 objArrayHandle new_head(THREAD, head); 1430 1431 typeArrayOop methods = oopFactory::new_shortArray(trace_chunk_size, CHECK); 1432 typeArrayHandle new_methods(THREAD, methods); 1433 1434 typeArrayOop bcis = oopFactory::new_intArray(trace_chunk_size, CHECK); 1435 typeArrayHandle new_bcis(THREAD, bcis); 1436 1437 objArrayOop mirrors = oopFactory::new_objectArray(trace_chunk_size, CHECK); 1438 objArrayHandle new_mirrors(THREAD, mirrors); 1439 1440 typeArrayOop cprefs = oopFactory::new_shortArray(trace_chunk_size, CHECK); 1441 typeArrayHandle new_cprefs(THREAD, cprefs); 1442 1443 if (!old_head.is_null()) { 1444 old_head->obj_at_put(trace_next_offset, new_head()); 1445 } 1446 new_head->obj_at_put(trace_methods_offset, new_methods()); 1447 new_head->obj_at_put(trace_bcis_offset, new_bcis()); 1448 new_head->obj_at_put(trace_mirrors_offset, new_mirrors()); 1449 new_head->obj_at_put(trace_cprefs_offset, new_cprefs()); 1450 1451 _head = new_head(); 1452 _methods = new_methods(); 1453 _bcis = new_bcis(); 1454 _mirrors = new_mirrors(); 1455 _cprefs = new_cprefs(); 1456 _index = 0; 1457 } 1458 1459 oop backtrace() { 1460 return _backtrace(); 1461 } 1462 1463 inline void push(Method* method, int bci, TRAPS) { 1464 // Smear the -1 bci to 0 since the array only holds unsigned 1465 // shorts. The later line number lookup would just smear the -1 1466 // to a 0 even if it could be recorded. 1467 if (bci == SynchronizationEntryBCI) bci = 0; 1468 1469 if (_index >= trace_chunk_size) { 1470 methodHandle mhandle(THREAD, method); 1471 expand(CHECK); 1472 method = mhandle(); 1473 } 1474 1475 _methods->short_at_put(_index, method->orig_method_idnum()); 1476 _bcis->int_at_put(_index, merge_bci_and_version(bci, method->constants()->version())); 1477 _cprefs->short_at_put(_index, method->name_index()); 1478 1479 // We need to save the mirrors in the backtrace to keep the class 1480 // from being unloaded while we still have this stack trace. 1481 assert(method->method_holder()->java_mirror() != NULL, "never push null for mirror"); 1482 _mirrors->obj_at_put(_index, method->method_holder()->java_mirror()); 1483 _index++; 1484 } 1485 1486 }; 1487 1488 Symbol* get_source_file_name(InstanceKlass* holder, int version) { 1489 // Find the specific ik version that contains this source_file_name_index 1490 // via the previous versions list, but use the current version's 1491 // constant pool to look it up. The previous version's index has been 1492 // merged for the current constant pool. 1493 InstanceKlass* ik = holder->get_klass_version(version); 1494 // This version has been cleaned up. 1495 if (ik == NULL) return NULL; 1496 int source_file_name_index = ik->source_file_name_index(); 1497 return (source_file_name_index == 0) ? 1498 (Symbol*)NULL : holder->constants()->symbol_at(source_file_name_index); 1499 } 1500 1501 // Print stack trace element to resource allocated buffer 1502 char* java_lang_Throwable::print_stack_element_to_buffer(Handle mirror, 1503 int method_id, int version, int bci, int cpref) { 1504 1505 // Get strings and string lengths 1506 InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror())); 1507 const char* klass_name = holder->external_name(); 1508 int buf_len = (int)strlen(klass_name); 1509 1510 Method* method = holder->method_with_orig_idnum(method_id, version); 1511 1512 // The method can be NULL if the requested class version is gone 1513 Symbol* sym = (method != NULL) ? method->name() : holder->constants()->symbol_at(cpref); 1514 char* method_name = sym->as_C_string(); 1515 buf_len += (int)strlen(method_name); 1516 1517 char* source_file_name = NULL; 1518 Symbol* source = get_source_file_name(holder, version); 1519 if (source != NULL) { 1520 source_file_name = source->as_C_string(); 1521 buf_len += (int)strlen(source_file_name); 1522 } 1523 1524 // Allocate temporary buffer with extra space for formatting and line number 1525 char* buf = NEW_RESOURCE_ARRAY(char, buf_len + 64); 1526 1527 // Print stack trace line in buffer 1528 sprintf(buf, "\tat %s.%s", klass_name, method_name); 1529 1530 if (!version_matches(method, version)) { 1531 strcat(buf, "(Redefined)"); 1532 } else { 1533 int line_number = get_line_number(method, bci); 1534 if (line_number == -2) { 1537 if (source_file_name != NULL && (line_number != -1)) { 1538 // Sourcename and linenumber 1539 sprintf(buf + (int)strlen(buf), "(%s:%d)", source_file_name, line_number); 1540 } else if (source_file_name != NULL) { 1541 // Just sourcename 1542 sprintf(buf + (int)strlen(buf), "(%s)", source_file_name); 1543 } else { 1544 // Neither sourcename nor linenumber 1545 sprintf(buf + (int)strlen(buf), "(Unknown Source)"); 1546 } 1547 nmethod* nm = method->code(); 1548 if (WizardMode && nm != NULL) { 1549 sprintf(buf + (int)strlen(buf), "(nmethod " INTPTR_FORMAT ")", (intptr_t)nm); 1550 } 1551 } 1552 } 1553 1554 return buf; 1555 } 1556 1557 void java_lang_Throwable::print_stack_element(outputStream *st, Handle mirror, 1558 int method_id, int version, int bci, int cpref) { 1559 ResourceMark rm; 1560 char* buf = print_stack_element_to_buffer(mirror, method_id, version, bci, cpref); 1561 st->print_cr("%s", buf); 1562 } 1563 1564 void java_lang_Throwable::print_stack_element(outputStream *st, const methodHandle& method, int bci) { 1565 Handle mirror = method->method_holder()->java_mirror(); 1566 int method_id = method->orig_method_idnum(); 1567 int version = method->constants()->version(); 1568 int cpref = method->name_index(); 1569 print_stack_element(st, mirror, method_id, version, bci, cpref); 1570 } 1571 1572 const char* java_lang_Throwable::no_stack_trace_message() { 1573 return "\t<<no stack trace available>>"; 1574 } 1575 1576 1577 // Currently used only for exceptions occurring during startup 1578 void java_lang_Throwable::print_stack_trace(oop throwable, outputStream* st) { 1579 Thread *THREAD = Thread::current(); 1580 Handle h_throwable(THREAD, throwable); 1581 while (h_throwable.not_null()) { 1582 objArrayHandle result (THREAD, objArrayOop(backtrace(h_throwable()))); 1583 if (result.is_null()) { 1584 st->print_raw_cr(no_stack_trace_message()); 1585 return; 1586 } 1587 1588 while (result.not_null()) { 1589 1590 // Get method id, bci, version and mirror from chunk 1591 typeArrayHandle methods (THREAD, BacktraceBuilder::get_methods(result)); 1592 typeArrayHandle bcis (THREAD, BacktraceBuilder::get_bcis(result)); 1593 objArrayHandle mirrors (THREAD, BacktraceBuilder::get_mirrors(result)); 1594 typeArrayHandle cprefs (THREAD, BacktraceBuilder::get_cprefs(result)); 1595 1596 int length = methods()->length(); 1597 for (int index = 0; index < length; index++) { 1598 Handle mirror(THREAD, mirrors->obj_at(index)); 1599 // NULL mirror means end of stack trace 1600 if (mirror.is_null()) goto handle_cause; 1601 int method = methods->short_at(index); 1602 int version = version_at(bcis->int_at(index)); 1603 int bci = bci_at(bcis->int_at(index)); 1604 int cpref = cprefs->short_at(index); 1605 print_stack_element(st, mirror, method, version, bci, cpref); 1606 } 1607 result = objArrayHandle(THREAD, objArrayOop(result->obj_at(trace_next_offset))); 1608 } 1609 handle_cause: 1610 { 1611 EXCEPTION_MARK; 1612 JavaValue cause(T_OBJECT); 1613 JavaCalls::call_virtual(&cause, 1614 h_throwable, 1615 KlassHandle(THREAD, h_throwable->klass()), 1616 vmSymbols::getCause_name(), 1617 vmSymbols::void_throwable_signature(), 1618 THREAD); 1619 // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM. 1620 if (HAS_PENDING_EXCEPTION) { 1621 CLEAR_PENDING_EXCEPTION; 1622 h_throwable = Handle(); 1623 } else { 1624 h_throwable = Handle(THREAD, (oop) cause.get_jobject()); 1625 if (h_throwable.not_null()) { 1861 1862 1863 oop java_lang_Throwable::get_stack_trace_element(oop throwable, int index, TRAPS) { 1864 if (throwable == NULL) { 1865 THROW_0(vmSymbols::java_lang_NullPointerException()); 1866 } 1867 if (index < 0) { 1868 THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL); 1869 } 1870 // Compute how many chunks to skip and index into actual chunk 1871 objArrayOop chunk = objArrayOop(backtrace(throwable)); 1872 int skip_chunks = index / trace_chunk_size; 1873 int chunk_index = index % trace_chunk_size; 1874 while (chunk != NULL && skip_chunks > 0) { 1875 chunk = objArrayOop(chunk->obj_at(trace_next_offset)); 1876 skip_chunks--; 1877 } 1878 if (chunk == NULL) { 1879 THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL); 1880 } 1881 // Get method id, bci, version, mirror and cpref from chunk 1882 typeArrayOop methods = BacktraceBuilder::get_methods(chunk); 1883 typeArrayOop bcis = BacktraceBuilder::get_bcis(chunk); 1884 objArrayOop mirrors = BacktraceBuilder::get_mirrors(chunk); 1885 typeArrayOop cprefs = BacktraceBuilder::get_cprefs(chunk); 1886 1887 assert(methods != NULL && bcis != NULL && mirrors != NULL, "sanity check"); 1888 1889 int method = methods->short_at(chunk_index); 1890 int version = version_at(bcis->int_at(chunk_index)); 1891 int bci = bci_at(bcis->int_at(chunk_index)); 1892 int cpref = cprefs->short_at(chunk_index); 1893 Handle mirror(THREAD, mirrors->obj_at(chunk_index)); 1894 1895 // Chunk can be partial full 1896 if (mirror.is_null()) { 1897 THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL); 1898 } 1899 oop element = java_lang_StackTraceElement::create(mirror, method, version, bci, cpref, CHECK_0); 1900 return element; 1901 } 1902 1903 oop java_lang_StackTraceElement::create(Handle mirror, int method_id, 1904 int version, int bci, int cpref, TRAPS) { 1905 // Allocate java.lang.StackTraceElement instance 1906 Klass* k = SystemDictionary::StackTraceElement_klass(); 1907 assert(k != NULL, "must be loaded in 1.4+"); 1908 instanceKlassHandle ik (THREAD, k); 1909 if (ik->should_be_initialized()) { 1910 ik->initialize(CHECK_0); 1911 } 1912 1913 Handle element = ik->allocate_instance_handle(CHECK_0); 1914 // Fill in class name 1915 ResourceMark rm(THREAD); 1916 InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror())); 1917 const char* str = holder->external_name(); 1918 oop classname = StringTable::intern((char*) str, CHECK_0); 1919 java_lang_StackTraceElement::set_declaringClass(element(), classname); 1920 1921 Method* method = holder->method_with_orig_idnum(method_id, version); 1922 1923 // The method can be NULL if the requested class version is gone 1924 Symbol* sym = (method != NULL) ? method->name() : holder->constants()->symbol_at(cpref); 1925 1926 // Fill in method name 1927 oop methodname = StringTable::intern(sym, CHECK_0); 1928 java_lang_StackTraceElement::set_methodName(element(), methodname); 1929 1930 if (!version_matches(method, version)) { 1931 // The method was redefined, accurate line number information isn't available 1932 java_lang_StackTraceElement::set_fileName(element(), NULL); 1933 java_lang_StackTraceElement::set_lineNumber(element(), -1); 1934 } else { 1935 // Fill in source file name and line number. 1936 Symbol* source = get_source_file_name(holder, version); 1937 if (ShowHiddenFrames && source == NULL) 1938 source = vmSymbols::unknown_class_name(); 1939 oop filename = StringTable::intern(source, CHECK_0); 1940 java_lang_StackTraceElement::set_fileName(element(), filename); 1941 1942 int line_number = get_line_number(method, bci); 1943 java_lang_StackTraceElement::set_lineNumber(element(), line_number); 1944 } 1945 return element(); 1946 } 1947 1948 oop java_lang_StackTraceElement::create(const methodHandle& method, int bci, TRAPS) { 1949 Handle mirror (THREAD, method->method_holder()->java_mirror()); 1950 int method_id = method->orig_method_idnum(); 1951 int cpref = method->name_index(); 1952 return create(mirror, method_id, method->constants()->version(), bci, cpref, THREAD); 1953 } 1954 1955 void java_lang_reflect_AccessibleObject::compute_offsets() { 1956 Klass* k = SystemDictionary::reflect_AccessibleObject_klass(); 1957 compute_offset(override_offset, k, vmSymbols::override_name(), vmSymbols::bool_signature()); 1958 } 1959 1960 jboolean java_lang_reflect_AccessibleObject::override(oop reflect) { 1961 assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 1962 return (jboolean) reflect->bool_field(override_offset); 1963 } 1964 1965 void java_lang_reflect_AccessibleObject::set_override(oop reflect, jboolean value) { 1966 assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 1967 reflect->bool_field_put(override_offset, (int) value); 1968 } 1969 1970 void java_lang_reflect_Method::compute_offsets() { 1971 Klass* k = SystemDictionary::reflect_Method_klass(); 1972 compute_offset(clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature()); | 1345 } else { 1346 // Returns -1 if no LineNumberTable, and otherwise actual line number 1347 line_number = method->line_number_from_bci(bci); 1348 if (line_number == -1 && ShowHiddenFrames) { 1349 line_number = bci + 1000000; 1350 } 1351 } 1352 return line_number; 1353 } 1354 1355 // This class provides a simple wrapper over the internal structure of 1356 // exception backtrace to insulate users of the backtrace from needing 1357 // to know what it looks like. 1358 class BacktraceBuilder: public StackObj { 1359 private: 1360 Handle _backtrace; 1361 objArrayOop _head; 1362 typeArrayOop _methods; 1363 typeArrayOop _bcis; 1364 objArrayOop _mirrors; 1365 typeArrayOop _names; // needed to insulate method name against redefinition 1366 int _index; 1367 No_Safepoint_Verifier _nsv; 1368 1369 public: 1370 1371 enum { 1372 trace_methods_offset = java_lang_Throwable::trace_methods_offset, 1373 trace_bcis_offset = java_lang_Throwable::trace_bcis_offset, 1374 trace_mirrors_offset = java_lang_Throwable::trace_mirrors_offset, 1375 trace_names_offset = java_lang_Throwable::trace_names_offset, 1376 trace_next_offset = java_lang_Throwable::trace_next_offset, 1377 trace_size = java_lang_Throwable::trace_size, 1378 trace_chunk_size = java_lang_Throwable::trace_chunk_size 1379 }; 1380 1381 // get info out of chunks 1382 static typeArrayOop get_methods(objArrayHandle chunk) { 1383 typeArrayOop methods = typeArrayOop(chunk->obj_at(trace_methods_offset)); 1384 assert(methods != NULL, "method array should be initialized in backtrace"); 1385 return methods; 1386 } 1387 static typeArrayOop get_bcis(objArrayHandle chunk) { 1388 typeArrayOop bcis = typeArrayOop(chunk->obj_at(trace_bcis_offset)); 1389 assert(bcis != NULL, "bci array should be initialized in backtrace"); 1390 return bcis; 1391 } 1392 static objArrayOop get_mirrors(objArrayHandle chunk) { 1393 objArrayOop mirrors = objArrayOop(chunk->obj_at(trace_mirrors_offset)); 1394 assert(mirrors != NULL, "mirror array should be initialized in backtrace"); 1395 return mirrors; 1396 } 1397 static typeArrayOop get_names(objArrayHandle chunk) { 1398 typeArrayOop names = typeArrayOop(chunk->obj_at(trace_names_offset)); 1399 assert(names != NULL, "names array should be initialized in backtrace"); 1400 return names; 1401 } 1402 1403 // constructor for new backtrace 1404 BacktraceBuilder(TRAPS): _methods(NULL), _bcis(NULL), _head(NULL), _mirrors(NULL), _names(NULL) { 1405 expand(CHECK); 1406 _backtrace = _head; 1407 _index = 0; 1408 } 1409 1410 BacktraceBuilder(objArrayHandle backtrace) { 1411 _methods = get_methods(backtrace); 1412 _bcis = get_bcis(backtrace); 1413 _mirrors = get_mirrors(backtrace); 1414 _names = get_names(backtrace); 1415 assert(_methods->length() == _bcis->length() && 1416 _methods->length() == _mirrors->length(), 1417 "method and source information arrays should match"); 1418 1419 // head is the preallocated backtrace 1420 _backtrace = _head = backtrace(); 1421 _index = 0; 1422 } 1423 1424 void expand(TRAPS) { 1425 objArrayHandle old_head(THREAD, _head); 1426 Pause_No_Safepoint_Verifier pnsv(&_nsv); 1427 1428 objArrayOop head = oopFactory::new_objectArray(trace_size, CHECK); 1429 objArrayHandle new_head(THREAD, head); 1430 1431 typeArrayOop methods = oopFactory::new_shortArray(trace_chunk_size, CHECK); 1432 typeArrayHandle new_methods(THREAD, methods); 1433 1434 typeArrayOop bcis = oopFactory::new_intArray(trace_chunk_size, CHECK); 1435 typeArrayHandle new_bcis(THREAD, bcis); 1436 1437 objArrayOop mirrors = oopFactory::new_objectArray(trace_chunk_size, CHECK); 1438 objArrayHandle new_mirrors(THREAD, mirrors); 1439 1440 typeArrayOop names = oopFactory::new_symbolArray(trace_chunk_size, CHECK); 1441 typeArrayHandle new_names(THREAD, names); 1442 1443 if (!old_head.is_null()) { 1444 old_head->obj_at_put(trace_next_offset, new_head()); 1445 } 1446 new_head->obj_at_put(trace_methods_offset, new_methods()); 1447 new_head->obj_at_put(trace_bcis_offset, new_bcis()); 1448 new_head->obj_at_put(trace_mirrors_offset, new_mirrors()); 1449 new_head->obj_at_put(trace_names_offset, new_names()); 1450 1451 _head = new_head(); 1452 _methods = new_methods(); 1453 _bcis = new_bcis(); 1454 _mirrors = new_mirrors(); 1455 _names = new_names(); 1456 _index = 0; 1457 } 1458 1459 oop backtrace() { 1460 return _backtrace(); 1461 } 1462 1463 inline void push(Method* method, int bci, TRAPS) { 1464 // Smear the -1 bci to 0 since the array only holds unsigned 1465 // shorts. The later line number lookup would just smear the -1 1466 // to a 0 even if it could be recorded. 1467 if (bci == SynchronizationEntryBCI) bci = 0; 1468 1469 if (_index >= trace_chunk_size) { 1470 methodHandle mhandle(THREAD, method); 1471 expand(CHECK); 1472 method = mhandle(); 1473 } 1474 1475 _methods->short_at_put(_index, method->orig_method_idnum()); 1476 _bcis->int_at_put(_index, merge_bci_and_version(bci, method->constants()->version())); 1477 // We can store Symbol* in the backtrace without additional refcounting because the 1478 // Symbol* for the name is kept alive because the class containing the method is kept 1479 // alive via. the mirror. Since redefinition does not allow deleting methods, the new 1480 // class will also have this name, somewhere, maybe not at the same constant pool index. 1481 _names->symbol_at_put(_index, method->name()); 1482 1483 // We need to save the mirrors in the backtrace to keep the class 1484 // from being unloaded while we still have this stack trace. 1485 assert(method->method_holder()->java_mirror() != NULL, "never push null for mirror"); 1486 _mirrors->obj_at_put(_index, method->method_holder()->java_mirror()); 1487 _index++; 1488 } 1489 1490 }; 1491 1492 Symbol* get_source_file_name(InstanceKlass* holder, int version) { 1493 // Find the specific ik version that contains this source_file_name_index 1494 // via the previous versions list, but use the current version's 1495 // constant pool to look it up. The previous version's index has been 1496 // merged for the current constant pool. 1497 InstanceKlass* ik = holder->get_klass_version(version); 1498 // This version has been cleaned up. 1499 if (ik == NULL) return NULL; 1500 int source_file_name_index = ik->source_file_name_index(); 1501 return (source_file_name_index == 0) ? 1502 (Symbol*)NULL : holder->constants()->symbol_at(source_file_name_index); 1503 } 1504 1505 // Print stack trace element to resource allocated buffer 1506 char* print_stack_element_to_buffer(Handle mirror, int method_id, int version, int bci, Symbol* name) { 1507 1508 // Get strings and string lengths 1509 InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror())); 1510 const char* klass_name = holder->external_name(); 1511 int buf_len = (int)strlen(klass_name); 1512 1513 Method* method = holder->method_with_orig_idnum(method_id, version); 1514 1515 char* method_name = name->as_C_string(); 1516 buf_len += (int)strlen(method_name); 1517 1518 char* source_file_name = NULL; 1519 Symbol* source = get_source_file_name(holder, version); 1520 if (source != NULL) { 1521 source_file_name = source->as_C_string(); 1522 buf_len += (int)strlen(source_file_name); 1523 } 1524 1525 // Allocate temporary buffer with extra space for formatting and line number 1526 char* buf = NEW_RESOURCE_ARRAY(char, buf_len + 64); 1527 1528 // Print stack trace line in buffer 1529 sprintf(buf, "\tat %s.%s", klass_name, method_name); 1530 1531 if (!version_matches(method, version)) { 1532 strcat(buf, "(Redefined)"); 1533 } else { 1534 int line_number = get_line_number(method, bci); 1535 if (line_number == -2) { 1538 if (source_file_name != NULL && (line_number != -1)) { 1539 // Sourcename and linenumber 1540 sprintf(buf + (int)strlen(buf), "(%s:%d)", source_file_name, line_number); 1541 } else if (source_file_name != NULL) { 1542 // Just sourcename 1543 sprintf(buf + (int)strlen(buf), "(%s)", source_file_name); 1544 } else { 1545 // Neither sourcename nor linenumber 1546 sprintf(buf + (int)strlen(buf), "(Unknown Source)"); 1547 } 1548 nmethod* nm = method->code(); 1549 if (WizardMode && nm != NULL) { 1550 sprintf(buf + (int)strlen(buf), "(nmethod " INTPTR_FORMAT ")", (intptr_t)nm); 1551 } 1552 } 1553 } 1554 1555 return buf; 1556 } 1557 1558 void print_stack_element_internal(outputStream *st, Handle mirror, 1559 int method_id, int version, int bci, Symbol* name) { 1560 ResourceMark rm; 1561 char* buf = print_stack_element_to_buffer(mirror, method_id, version, bci, name); 1562 st->print_cr("%s", buf); 1563 } 1564 1565 void java_lang_Throwable::print_stack_element(outputStream *st, const methodHandle& method, int bci) { 1566 Handle mirror = method->method_holder()->java_mirror(); 1567 int method_id = method->orig_method_idnum(); 1568 int version = method->constants()->version(); 1569 Symbol *name = method->name(); 1570 print_stack_element_internal(st, mirror, method_id, version, bci, name); 1571 } 1572 1573 1574 // Currently used only for exceptions occurring during startup 1575 void java_lang_Throwable::print_stack_trace(oop throwable, outputStream* st) { 1576 Thread *THREAD = Thread::current(); 1577 Handle h_throwable(THREAD, throwable); 1578 while (h_throwable.not_null()) { 1579 objArrayHandle result (THREAD, objArrayOop(backtrace(h_throwable()))); 1580 if (result.is_null()) { 1581 st->print_raw_cr("\t<<no stack trace available>>"); 1582 return; 1583 } 1584 1585 while (result.not_null()) { 1586 1587 // Get method id, bci, version and mirror from chunk 1588 typeArrayHandle methods (THREAD, BacktraceBuilder::get_methods(result)); 1589 typeArrayHandle bcis (THREAD, BacktraceBuilder::get_bcis(result)); 1590 objArrayHandle mirrors (THREAD, BacktraceBuilder::get_mirrors(result)); 1591 typeArrayHandle names (THREAD, BacktraceBuilder::get_names(result)); 1592 1593 int length = methods()->length(); 1594 for (int index = 0; index < length; index++) { 1595 Handle mirror(THREAD, mirrors->obj_at(index)); 1596 // NULL mirror means end of stack trace 1597 if (mirror.is_null()) goto handle_cause; 1598 int method = methods->short_at(index); 1599 int version = version_at(bcis->int_at(index)); 1600 int bci = bci_at(bcis->int_at(index)); 1601 Symbol* name = names->symbol_at(index); 1602 print_stack_element_internal(st, mirror, method, version, bci, name); 1603 } 1604 result = objArrayHandle(THREAD, objArrayOop(result->obj_at(trace_next_offset))); 1605 } 1606 handle_cause: 1607 { 1608 EXCEPTION_MARK; 1609 JavaValue cause(T_OBJECT); 1610 JavaCalls::call_virtual(&cause, 1611 h_throwable, 1612 KlassHandle(THREAD, h_throwable->klass()), 1613 vmSymbols::getCause_name(), 1614 vmSymbols::void_throwable_signature(), 1615 THREAD); 1616 // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM. 1617 if (HAS_PENDING_EXCEPTION) { 1618 CLEAR_PENDING_EXCEPTION; 1619 h_throwable = Handle(); 1620 } else { 1621 h_throwable = Handle(THREAD, (oop) cause.get_jobject()); 1622 if (h_throwable.not_null()) { 1858 1859 1860 oop java_lang_Throwable::get_stack_trace_element(oop throwable, int index, TRAPS) { 1861 if (throwable == NULL) { 1862 THROW_0(vmSymbols::java_lang_NullPointerException()); 1863 } 1864 if (index < 0) { 1865 THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL); 1866 } 1867 // Compute how many chunks to skip and index into actual chunk 1868 objArrayOop chunk = objArrayOop(backtrace(throwable)); 1869 int skip_chunks = index / trace_chunk_size; 1870 int chunk_index = index % trace_chunk_size; 1871 while (chunk != NULL && skip_chunks > 0) { 1872 chunk = objArrayOop(chunk->obj_at(trace_next_offset)); 1873 skip_chunks--; 1874 } 1875 if (chunk == NULL) { 1876 THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL); 1877 } 1878 // Get method id, bci, version, mirror and name from chunk 1879 typeArrayOop methods = BacktraceBuilder::get_methods(chunk); 1880 typeArrayOop bcis = BacktraceBuilder::get_bcis(chunk); 1881 objArrayOop mirrors = BacktraceBuilder::get_mirrors(chunk); 1882 typeArrayOop names = BacktraceBuilder::get_names(chunk); 1883 1884 assert(methods != NULL && bcis != NULL && mirrors != NULL, "sanity check"); 1885 1886 int method = methods->short_at(chunk_index); 1887 int version = version_at(bcis->int_at(chunk_index)); 1888 int bci = bci_at(bcis->int_at(chunk_index)); 1889 Symbol* name = names->symbol_at(chunk_index); 1890 Handle mirror(THREAD, mirrors->obj_at(chunk_index)); 1891 1892 // Chunk can be partial full 1893 if (mirror.is_null()) { 1894 THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL); 1895 } 1896 oop element = java_lang_StackTraceElement::create(mirror, method, version, bci, name, CHECK_0); 1897 return element; 1898 } 1899 1900 oop java_lang_StackTraceElement::create(Handle mirror, int method_id, 1901 int version, int bci, Symbol* name, TRAPS) { 1902 // Allocate java.lang.StackTraceElement instance 1903 Klass* k = SystemDictionary::StackTraceElement_klass(); 1904 assert(k != NULL, "must be loaded in 1.4+"); 1905 instanceKlassHandle ik (THREAD, k); 1906 if (ik->should_be_initialized()) { 1907 ik->initialize(CHECK_0); 1908 } 1909 1910 Handle element = ik->allocate_instance_handle(CHECK_0); 1911 // Fill in class name 1912 ResourceMark rm(THREAD); 1913 InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror())); 1914 const char* str = holder->external_name(); 1915 oop classname = StringTable::intern((char*) str, CHECK_0); 1916 java_lang_StackTraceElement::set_declaringClass(element(), classname); 1917 1918 1919 // Fill in method name 1920 oop methodname = StringTable::intern(name, CHECK_0); 1921 java_lang_StackTraceElement::set_methodName(element(), methodname); 1922 1923 // The method can be NULL if the requested class version is gone 1924 Method* method = holder->method_with_orig_idnum(method_id, version); 1925 if (!version_matches(method, version)) { 1926 // The method was redefined, accurate line number information isn't available 1927 java_lang_StackTraceElement::set_fileName(element(), NULL); 1928 java_lang_StackTraceElement::set_lineNumber(element(), -1); 1929 } else { 1930 // Fill in source file name and line number. 1931 Symbol* source = get_source_file_name(holder, version); 1932 if (ShowHiddenFrames && source == NULL) 1933 source = vmSymbols::unknown_class_name(); 1934 oop filename = StringTable::intern(source, CHECK_0); 1935 java_lang_StackTraceElement::set_fileName(element(), filename); 1936 1937 int line_number = get_line_number(method, bci); 1938 java_lang_StackTraceElement::set_lineNumber(element(), line_number); 1939 } 1940 return element(); 1941 } 1942 1943 oop java_lang_StackTraceElement::create(const methodHandle& method, int bci, TRAPS) { 1944 Handle mirror (THREAD, method->method_holder()->java_mirror()); 1945 int method_id = method->orig_method_idnum(); 1946 Symbol* name = method->name(); 1947 return create(mirror, method_id, method->constants()->version(), bci, name, THREAD); 1948 } 1949 1950 void java_lang_reflect_AccessibleObject::compute_offsets() { 1951 Klass* k = SystemDictionary::reflect_AccessibleObject_klass(); 1952 compute_offset(override_offset, k, vmSymbols::override_name(), vmSymbols::bool_signature()); 1953 } 1954 1955 jboolean java_lang_reflect_AccessibleObject::override(oop reflect) { 1956 assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 1957 return (jboolean) reflect->bool_field(override_offset); 1958 } 1959 1960 void java_lang_reflect_AccessibleObject::set_override(oop reflect, jboolean value) { 1961 assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 1962 reflect->bool_field_put(override_offset, (int) value); 1963 } 1964 1965 void java_lang_reflect_Method::compute_offsets() { 1966 Klass* k = SystemDictionary::reflect_Method_klass(); 1967 compute_offset(clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature()); |