src/share/vm/classfile/javaClasses.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 8140685.02 Sdiff src/share/vm/classfile

src/share/vm/classfile/javaClasses.cpp

Print this page




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());


src/share/vm/classfile/javaClasses.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File