comparison src/share/vm/classfile/javaClasses.cpp @ 7624:b14da2e6f2dc

7174978: NPG: Fix bactrace builder for class redefinition Summary: Remove Method* from backtrace but save version so redefine classes doesn't give inaccurate line numbers. Removed old Merlin API with duplicate code. Reviewed-by: dholmes, sspitsyn
author coleenp
date Thu, 17 Jan 2013 13:40:31 -0500
parents ade95d680b42
children c73c3f2c5b3b
comparison
equal deleted inserted replaced
7623:203f64878aab 7624:b14da2e6f2dc
1 /* 1 /*
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
1156 if (msg != NULL) { 1156 if (msg != NULL) {
1157 st->print(": %s", java_lang_String::as_utf8_string(msg)); 1157 st->print(": %s", java_lang_String::as_utf8_string(msg));
1158 } 1158 }
1159 } 1159 }
1160 1160
1161 // Print stack trace element to resource allocated buffer 1161 // After this many redefines, the stack trace is unreliable.
1162 char* java_lang_Throwable::print_stack_element_to_buffer(Method* method, int bci) { 1162 const int MAX_VERSION = USHRT_MAX;
1163 // Get strings and string lengths 1163
1164 InstanceKlass* klass = method->method_holder(); 1164 // Helper backtrace functions to store bci|version together.
1165 const char* klass_name = klass->external_name(); 1165 static inline int merge_bci_and_version(int bci, int version) {
1166 int buf_len = (int)strlen(klass_name); 1166 // only store u2 for version, checking for overflow.
1167 char* source_file_name; 1167 if (version > USHRT_MAX || version < 0) version = MAX_VERSION;
1168 if (klass->source_file_name() == NULL) { 1168 assert((jushort)bci == bci, "bci should be short");
1169 source_file_name = NULL; 1169 return build_int_from_shorts(version, bci);
1170 }
1171
1172 static inline int bci_at(unsigned int merged) {
1173 return extract_high_short_from_int(merged);
1174 }
1175 static inline int version_at(unsigned int merged) {
1176 return extract_low_short_from_int(merged);
1177 }
1178
1179 static inline bool version_matches(Method* method, int version) {
1180 return (method->constants()->version() == version && version < MAX_VERSION);
1181 }
1182
1183 static inline int get_line_number(Method* method, int bci) {
1184 int line_number = 0;
1185 if (method->is_native()) {
1186 // Negative value different from -1 below, enabling Java code in
1187 // class java.lang.StackTraceElement to distinguish "native" from
1188 // "no LineNumberTable". JDK tests for -2.
1189 line_number = -2;
1170 } else { 1190 } else {
1171 source_file_name = klass->source_file_name()->as_C_string(); 1191 // Returns -1 if no LineNumberTable, and otherwise actual line number
1172 buf_len += (int)strlen(source_file_name); 1192 line_number = method->line_number_from_bci(bci);
1173 } 1193 if (line_number == -1 && ShowHiddenFrames) {
1174 char* method_name = method->name()->as_C_string(); 1194 line_number = bci + 1000000;
1175 buf_len += (int)strlen(method_name); 1195 }
1176 1196 }
1177 // Allocate temporary buffer with extra space for formatting and line number 1197 return line_number;
1178 char* buf = NEW_RESOURCE_ARRAY(char, buf_len + 64);
1179
1180 // Print stack trace line in buffer
1181 sprintf(buf, "\tat %s.%s", klass_name, method_name);
1182 if (method->is_native()) {
1183 strcat(buf, "(Native Method)");
1184 } else {
1185 int line_number = method->line_number_from_bci(bci);
1186 if (source_file_name != NULL && (line_number != -1)) {
1187 // Sourcename and linenumber
1188 sprintf(buf + (int)strlen(buf), "(%s:%d)", source_file_name, line_number);
1189 } else if (source_file_name != NULL) {
1190 // Just sourcename
1191 sprintf(buf + (int)strlen(buf), "(%s)", source_file_name);
1192 } else {
1193 // Neither soucename and linenumber
1194 sprintf(buf + (int)strlen(buf), "(Unknown Source)");
1195 }
1196 nmethod* nm = method->code();
1197 if (WizardMode && nm != NULL) {
1198 sprintf(buf + (int)strlen(buf), "(nmethod " INTPTR_FORMAT ")", (intptr_t)nm);
1199 }
1200 }
1201
1202 return buf;
1203 }
1204
1205
1206 void java_lang_Throwable::print_stack_element(Handle stream, Method* method, int bci) {
1207 ResourceMark rm;
1208 char* buf = print_stack_element_to_buffer(method, bci);
1209 print_to_stream(stream, buf);
1210 }
1211
1212 void java_lang_Throwable::print_stack_element(outputStream *st, Method* method, int bci) {
1213 ResourceMark rm;
1214 char* buf = print_stack_element_to_buffer(method, bci);
1215 st->print_cr("%s", buf);
1216 }
1217
1218 void java_lang_Throwable::print_to_stream(Handle stream, const char* str) {
1219 if (stream.is_null()) {
1220 tty->print_cr("%s", str);
1221 } else {
1222 EXCEPTION_MARK;
1223 JavaValue result(T_VOID);
1224 Handle arg (THREAD, oopFactory::new_charArray(str, THREAD));
1225 if (!HAS_PENDING_EXCEPTION) {
1226 JavaCalls::call_virtual(&result,
1227 stream,
1228 KlassHandle(THREAD, stream->klass()),
1229 vmSymbols::println_name(),
1230 vmSymbols::char_array_void_signature(),
1231 arg,
1232 THREAD);
1233 }
1234 // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM.
1235 if (HAS_PENDING_EXCEPTION) CLEAR_PENDING_EXCEPTION;
1236 }
1237
1238 }
1239
1240
1241 const char* java_lang_Throwable::no_stack_trace_message() {
1242 return "\t<<no stack trace available>>";
1243 }
1244
1245
1246 // Currently used only for exceptions occurring during startup
1247 void java_lang_Throwable::print_stack_trace(oop throwable, outputStream* st) {
1248 Thread *THREAD = Thread::current();
1249 Handle h_throwable(THREAD, throwable);
1250 while (h_throwable.not_null()) {
1251 objArrayHandle result (THREAD, objArrayOop(backtrace(h_throwable())));
1252 if (result.is_null()) {
1253 st->print_cr(no_stack_trace_message());
1254 return;
1255 }
1256
1257 while (result.not_null()) {
1258 typeArrayHandle methods (THREAD,
1259 typeArrayOop(result->obj_at(trace_methods_offset)));
1260 typeArrayHandle bcis (THREAD,
1261 typeArrayOop(result->obj_at(trace_bcis_offset)));
1262
1263 if (methods.is_null() || bcis.is_null()) {
1264 st->print_cr(no_stack_trace_message());
1265 return;
1266 }
1267
1268 int length = methods()->length();
1269 for (int index = 0; index < length; index++) {
1270 Method* method = ((Method*)methods()->metadata_at(index));
1271 if (method == NULL) goto handle_cause;
1272 int bci = bcis->ushort_at(index);
1273 print_stack_element(st, method, bci);
1274 }
1275 result = objArrayHandle(THREAD, objArrayOop(result->obj_at(trace_next_offset)));
1276 }
1277 handle_cause:
1278 {
1279 EXCEPTION_MARK;
1280 JavaValue result(T_OBJECT);
1281 JavaCalls::call_virtual(&result,
1282 h_throwable,
1283 KlassHandle(THREAD, h_throwable->klass()),
1284 vmSymbols::getCause_name(),
1285 vmSymbols::void_throwable_signature(),
1286 THREAD);
1287 // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM.
1288 if (HAS_PENDING_EXCEPTION) {
1289 CLEAR_PENDING_EXCEPTION;
1290 h_throwable = Handle();
1291 } else {
1292 h_throwable = Handle(THREAD, (oop) result.get_jobject());
1293 if (h_throwable.not_null()) {
1294 st->print("Caused by: ");
1295 print(h_throwable, st);
1296 st->cr();
1297 }
1298 }
1299 }
1300 }
1301 }
1302
1303
1304 void java_lang_Throwable::print_stack_trace(oop throwable, oop print_stream) {
1305 // Note: this is no longer used in Merlin, but we support it for compatibility.
1306 Thread *thread = Thread::current();
1307 Handle stream(thread, print_stream);
1308 objArrayHandle result (thread, objArrayOop(backtrace(throwable)));
1309 if (result.is_null()) {
1310 print_to_stream(stream, no_stack_trace_message());
1311 return;
1312 }
1313
1314 while (result.not_null()) {
1315 typeArrayHandle methods(thread,
1316 typeArrayOop(result->obj_at(trace_methods_offset)));
1317 typeArrayHandle bcis (thread,
1318 typeArrayOop(result->obj_at(trace_bcis_offset)));
1319
1320 if (methods.is_null() || bcis.is_null()) {
1321 print_to_stream(stream, no_stack_trace_message());
1322 return;
1323 }
1324
1325 int length = methods()->length();
1326 for (int index = 0; index < length; index++) {
1327 Method* method = ((Method*)methods()->metadata_at(index));
1328 if (method == NULL) return;
1329 int bci = bcis->ushort_at(index);
1330 print_stack_element(stream, method, bci);
1331 }
1332 result = objArrayHandle(thread, objArrayOop(result->obj_at(trace_next_offset)));
1333 }
1334 } 1198 }
1335 1199
1336 // This class provides a simple wrapper over the internal structure of 1200 // This class provides a simple wrapper over the internal structure of
1337 // exception backtrace to insulate users of the backtrace from needing 1201 // exception backtrace to insulate users of the backtrace from needing
1338 // to know what it looks like. 1202 // to know what it looks like.
1348 1212
1349 public: 1213 public:
1350 1214
1351 enum { 1215 enum {
1352 trace_methods_offset = java_lang_Throwable::trace_methods_offset, 1216 trace_methods_offset = java_lang_Throwable::trace_methods_offset,
1353 trace_bcis_offset = java_lang_Throwable::trace_bcis_offset, 1217 trace_bcis_offset = java_lang_Throwable::trace_bcis_offset,
1354 trace_mirrors_offset = java_lang_Throwable::trace_mirrors_offset, 1218 trace_mirrors_offset = java_lang_Throwable::trace_mirrors_offset,
1355 trace_next_offset = java_lang_Throwable::trace_next_offset, 1219 trace_next_offset = java_lang_Throwable::trace_next_offset,
1356 trace_size = java_lang_Throwable::trace_size, 1220 trace_size = java_lang_Throwable::trace_size,
1357 trace_chunk_size = java_lang_Throwable::trace_chunk_size 1221 trace_chunk_size = java_lang_Throwable::trace_chunk_size
1358 }; 1222 };
1359 1223
1224 // get info out of chunks
1225 static typeArrayOop get_methods(objArrayHandle chunk) {
1226 typeArrayOop methods = typeArrayOop(chunk->obj_at(trace_methods_offset));
1227 assert(methods != NULL, "method array should be initialized in backtrace");
1228 return methods;
1229 }
1230 static typeArrayOop get_bcis(objArrayHandle chunk) {
1231 typeArrayOop bcis = typeArrayOop(chunk->obj_at(trace_bcis_offset));
1232 assert(bcis != NULL, "bci array should be initialized in backtrace");
1233 return bcis;
1234 }
1235 static objArrayOop get_mirrors(objArrayHandle chunk) {
1236 objArrayOop mirrors = objArrayOop(chunk->obj_at(trace_mirrors_offset));
1237 assert(mirrors != NULL, "mirror array should be initialized in backtrace");
1238 return mirrors;
1239 }
1240
1360 // constructor for new backtrace 1241 // constructor for new backtrace
1361 BacktraceBuilder(TRAPS): _methods(NULL), _bcis(NULL), _head(NULL), _mirrors(NULL) { 1242 BacktraceBuilder(TRAPS): _methods(NULL), _bcis(NULL), _head(NULL), _mirrors(NULL) {
1362 expand(CHECK); 1243 expand(CHECK);
1363 _backtrace = _head; 1244 _backtrace = _head;
1364 _index = 0; 1245 _index = 0;
1365 } 1246 }
1366 1247
1248 BacktraceBuilder(objArrayHandle backtrace) {
1249 _methods = get_methods(backtrace);
1250 _bcis = get_bcis(backtrace);
1251 _mirrors = get_mirrors(backtrace);
1252 assert(_methods->length() == _bcis->length() &&
1253 _methods->length() == _mirrors->length(),
1254 "method and source information arrays should match");
1255
1256 // head is the preallocated backtrace
1257 _backtrace = _head = backtrace();
1258 _index = 0;
1259 }
1260
1367 void expand(TRAPS) { 1261 void expand(TRAPS) {
1368 objArrayHandle old_head(THREAD, _head); 1262 objArrayHandle old_head(THREAD, _head);
1369 Pause_No_Safepoint_Verifier pnsv(&_nsv); 1263 Pause_No_Safepoint_Verifier pnsv(&_nsv);
1370 1264
1371 objArrayOop head = oopFactory::new_objectArray(trace_size, CHECK); 1265 objArrayOop head = oopFactory::new_objectArray(trace_size, CHECK);
1372 objArrayHandle new_head(THREAD, head); 1266 objArrayHandle new_head(THREAD, head);
1373 1267
1374 typeArrayOop methods = oopFactory::new_metaDataArray(trace_chunk_size, CHECK); 1268 typeArrayOop methods = oopFactory::new_shortArray(trace_chunk_size, CHECK);
1375 typeArrayHandle new_methods(THREAD, methods); 1269 typeArrayHandle new_methods(THREAD, methods);
1376 1270
1377 typeArrayOop bcis = oopFactory::new_shortArray(trace_chunk_size, CHECK); 1271 typeArrayOop bcis = oopFactory::new_intArray(trace_chunk_size, CHECK);
1378 typeArrayHandle new_bcis(THREAD, bcis); 1272 typeArrayHandle new_bcis(THREAD, bcis);
1379 1273
1380 objArrayOop mirrors = oopFactory::new_objectArray(trace_chunk_size, CHECK); 1274 objArrayOop mirrors = oopFactory::new_objectArray(trace_chunk_size, CHECK);
1381 objArrayHandle new_mirrors(THREAD, mirrors); 1275 objArrayHandle new_mirrors(THREAD, mirrors);
1382 1276
1387 new_head->obj_at_put(trace_bcis_offset, new_bcis()); 1281 new_head->obj_at_put(trace_bcis_offset, new_bcis());
1388 new_head->obj_at_put(trace_mirrors_offset, new_mirrors()); 1282 new_head->obj_at_put(trace_mirrors_offset, new_mirrors());
1389 1283
1390 _head = new_head(); 1284 _head = new_head();
1391 _methods = new_methods(); 1285 _methods = new_methods();
1392 _bcis = new_bcis(); 1286 _bcis = new_bcis();
1393 _mirrors = new_mirrors(); 1287 _mirrors = new_mirrors();
1394 _index = 0; 1288 _index = 0;
1395 } 1289 }
1396 1290
1397 oop backtrace() { 1291 oop backtrace() {
1401 inline void push(Method* method, int bci, TRAPS) { 1295 inline void push(Method* method, int bci, TRAPS) {
1402 // Smear the -1 bci to 0 since the array only holds unsigned 1296 // Smear the -1 bci to 0 since the array only holds unsigned
1403 // shorts. The later line number lookup would just smear the -1 1297 // shorts. The later line number lookup would just smear the -1
1404 // to a 0 even if it could be recorded. 1298 // to a 0 even if it could be recorded.
1405 if (bci == SynchronizationEntryBCI) bci = 0; 1299 if (bci == SynchronizationEntryBCI) bci = 0;
1406 assert(bci == (jushort)bci, "doesn't fit");
1407 1300
1408 if (_index >= trace_chunk_size) { 1301 if (_index >= trace_chunk_size) {
1409 methodHandle mhandle(THREAD, method); 1302 methodHandle mhandle(THREAD, method);
1410 expand(CHECK); 1303 expand(CHECK);
1411 method = mhandle(); 1304 method = mhandle();
1412 } 1305 }
1413 1306
1414 _methods->metadata_at_put(_index, method); 1307 _methods->short_at_put(_index, method->method_idnum());
1415 _bcis->ushort_at_put(_index, bci); 1308 _bcis->int_at_put(_index, merge_bci_and_version(bci, method->constants()->version()));
1416 // we need to save the mirrors in the backtrace to keep the methods from 1309
1417 // being unloaded if their class loader is unloaded while we still have 1310 // We need to save the mirrors in the backtrace to keep the class
1418 // this stack trace. 1311 // from being unloaded while we still have this stack trace.
1312 assert(method->method_holder()->java_mirror() != NULL, "never push null for mirror");
1419 _mirrors->obj_at_put(_index, method->method_holder()->java_mirror()); 1313 _mirrors->obj_at_put(_index, method->method_holder()->java_mirror());
1420 _index++; 1314 _index++;
1421 } 1315 }
1422 1316
1423 Method* current_method() {
1424 assert(_index >= 0 && _index < trace_chunk_size, "out of range");
1425 return ((Method*)_methods->metadata_at(_index));
1426 }
1427
1428 jushort current_bci() {
1429 assert(_index >= 0 && _index < trace_chunk_size, "out of range");
1430 return _bcis->ushort_at(_index);
1431 }
1432 }; 1317 };
1433 1318
1319 // Print stack trace element to resource allocated buffer
1320 char* java_lang_Throwable::print_stack_element_to_buffer(Handle mirror,
1321 int method_id, int version, int bci) {
1322
1323 // Get strings and string lengths
1324 InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror()));
1325 const char* klass_name = holder->external_name();
1326 int buf_len = (int)strlen(klass_name);
1327
1328 // pushing to the stack trace added one.
1329 Method* method = holder->method_with_idnum(method_id);
1330 char* method_name = method->name()->as_C_string();
1331 buf_len += (int)strlen(method_name);
1332
1333 char* source_file_name = NULL;
1334 if (version_matches(method, version)) {
1335 Symbol* source = holder->source_file_name();
1336 if (source != NULL) {
1337 source_file_name = source->as_C_string();
1338 buf_len += (int)strlen(source_file_name);
1339 }
1340 }
1341
1342 // Allocate temporary buffer with extra space for formatting and line number
1343 char* buf = NEW_RESOURCE_ARRAY(char, buf_len + 64);
1344
1345 // Print stack trace line in buffer
1346 sprintf(buf, "\tat %s.%s", klass_name, method_name);
1347
1348 if (!version_matches(method, version)) {
1349 strcat(buf, "(Redefined)");
1350 } else {
1351 int line_number = get_line_number(method, bci);
1352 if (line_number == -2) {
1353 strcat(buf, "(Native Method)");
1354 } else {
1355 if (source_file_name != NULL && (line_number != -1)) {
1356 // Sourcename and linenumber
1357 sprintf(buf + (int)strlen(buf), "(%s:%d)", source_file_name, line_number);
1358 } else if (source_file_name != NULL) {
1359 // Just sourcename
1360 sprintf(buf + (int)strlen(buf), "(%s)", source_file_name);
1361 } else {
1362 // Neither sourcename nor linenumber
1363 sprintf(buf + (int)strlen(buf), "(Unknown Source)");
1364 }
1365 nmethod* nm = method->code();
1366 if (WizardMode && nm != NULL) {
1367 sprintf(buf + (int)strlen(buf), "(nmethod " INTPTR_FORMAT ")", (intptr_t)nm);
1368 }
1369 }
1370 }
1371
1372 return buf;
1373 }
1374
1375 void java_lang_Throwable::print_stack_element(outputStream *st, Handle mirror,
1376 int method_id, int version, int bci) {
1377 ResourceMark rm;
1378 char* buf = print_stack_element_to_buffer(mirror, method_id, version, bci);
1379 st->print_cr("%s", buf);
1380 }
1381
1382 void java_lang_Throwable::print_stack_element(outputStream *st, methodHandle method, int bci) {
1383 Handle mirror = method->method_holder()->java_mirror();
1384 int method_id = method->method_idnum();
1385 int version = method->constants()->version();
1386 print_stack_element(st, mirror, method_id, version, bci);
1387 }
1388
1389 const char* java_lang_Throwable::no_stack_trace_message() {
1390 return "\t<<no stack trace available>>";
1391 }
1392
1393
1394 // Currently used only for exceptions occurring during startup
1395 void java_lang_Throwable::print_stack_trace(oop throwable, outputStream* st) {
1396 Thread *THREAD = Thread::current();
1397 Handle h_throwable(THREAD, throwable);
1398 while (h_throwable.not_null()) {
1399 objArrayHandle result (THREAD, objArrayOop(backtrace(h_throwable())));
1400 if (result.is_null()) {
1401 st->print_cr(no_stack_trace_message());
1402 return;
1403 }
1404
1405 while (result.not_null()) {
1406
1407 // Get method id, bci, version and mirror from chunk
1408 typeArrayHandle methods (THREAD, BacktraceBuilder::get_methods(result));
1409 typeArrayHandle bcis (THREAD, BacktraceBuilder::get_bcis(result));
1410 objArrayHandle mirrors (THREAD, BacktraceBuilder::get_mirrors(result));
1411
1412 int length = methods()->length();
1413 for (int index = 0; index < length; index++) {
1414 Handle mirror(THREAD, mirrors->obj_at(index));
1415 // NULL mirror means end of stack trace
1416 if (mirror.is_null()) goto handle_cause;
1417 int method = methods->short_at(index);
1418 int version = version_at(bcis->int_at(index));
1419 int bci = bci_at(bcis->int_at(index));
1420 print_stack_element(st, mirror, method, version, bci);
1421 }
1422 result = objArrayHandle(THREAD, objArrayOop(result->obj_at(trace_next_offset)));
1423 }
1424 handle_cause:
1425 {
1426 EXCEPTION_MARK;
1427 JavaValue cause(T_OBJECT);
1428 JavaCalls::call_virtual(&cause,
1429 h_throwable,
1430 KlassHandle(THREAD, h_throwable->klass()),
1431 vmSymbols::getCause_name(),
1432 vmSymbols::void_throwable_signature(),
1433 THREAD);
1434 // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM.
1435 if (HAS_PENDING_EXCEPTION) {
1436 CLEAR_PENDING_EXCEPTION;
1437 h_throwable = Handle();
1438 } else {
1439 h_throwable = Handle(THREAD, (oop) cause.get_jobject());
1440 if (h_throwable.not_null()) {
1441 st->print("Caused by: ");
1442 print(h_throwable, st);
1443 st->cr();
1444 }
1445 }
1446 }
1447 }
1448 }
1434 1449
1435 void java_lang_Throwable::fill_in_stack_trace(Handle throwable, methodHandle method, TRAPS) { 1450 void java_lang_Throwable::fill_in_stack_trace(Handle throwable, methodHandle method, TRAPS) {
1436 if (!StackTraceInThrowable) return; 1451 if (!StackTraceInThrowable) return;
1437 ResourceMark rm(THREAD); 1452 ResourceMark rm(THREAD);
1438 1453
1589 void java_lang_Throwable::allocate_backtrace(Handle throwable, TRAPS) { 1604 void java_lang_Throwable::allocate_backtrace(Handle throwable, TRAPS) {
1590 // Allocate stack trace - backtrace is created but not filled in 1605 // Allocate stack trace - backtrace is created but not filled in
1591 1606
1592 // No-op if stack trace is disabled 1607 // No-op if stack trace is disabled
1593 if (!StackTraceInThrowable) return; 1608 if (!StackTraceInThrowable) return;
1594 1609 BacktraceBuilder bt(CHECK); // creates a backtrace
1595 objArrayOop h_oop = oopFactory::new_objectArray(trace_size, CHECK); 1610 set_backtrace(throwable(), bt.backtrace());
1596 objArrayHandle backtrace (THREAD, h_oop);
1597 typeArrayOop m_oop = oopFactory::new_metaDataArray(trace_chunk_size, CHECK);
1598 typeArrayHandle methods (THREAD, m_oop);
1599 typeArrayOop b = oopFactory::new_shortArray(trace_chunk_size, CHECK);
1600 typeArrayHandle bcis(THREAD, b);
1601 objArrayOop mirror_oop = oopFactory::new_objectArray(trace_chunk_size, CHECK);
1602 objArrayHandle mirrors (THREAD, mirror_oop);
1603
1604 // backtrace has space for one chunk (next is NULL)
1605 backtrace->obj_at_put(trace_methods_offset, methods());
1606 backtrace->obj_at_put(trace_bcis_offset, bcis());
1607 backtrace->obj_at_put(trace_mirrors_offset, mirrors());
1608 set_backtrace(throwable(), backtrace());
1609 } 1611 }
1610 1612
1611 1613
1612 void java_lang_Throwable::fill_in_stack_trace_of_preallocated_backtrace(Handle throwable) { 1614 void java_lang_Throwable::fill_in_stack_trace_of_preallocated_backtrace(Handle throwable) {
1613 // Fill in stack trace into preallocated backtrace (no GC) 1615 // Fill in stack trace into preallocated backtrace (no GC)
1615 // No-op if stack trace is disabled 1617 // No-op if stack trace is disabled
1616 if (!StackTraceInThrowable) return; 1618 if (!StackTraceInThrowable) return;
1617 1619
1618 assert(throwable->is_a(SystemDictionary::Throwable_klass()), "sanity check"); 1620 assert(throwable->is_a(SystemDictionary::Throwable_klass()), "sanity check");
1619 1621
1620 objArrayOop backtrace = (objArrayOop)java_lang_Throwable::backtrace(throwable()); 1622 JavaThread* THREAD = JavaThread::current();
1621 assert(backtrace != NULL, "backtrace not preallocated"); 1623
1622 1624 objArrayHandle backtrace (THREAD, (objArrayOop)java_lang_Throwable::backtrace(throwable()));
1623 oop m = backtrace->obj_at(trace_methods_offset); 1625 assert(backtrace.not_null(), "backtrace should have been preallocated");
1624 typeArrayOop methods = typeArrayOop(m); 1626
1625 assert(methods != NULL && methods->length() > 0, "method array not preallocated"); 1627 ResourceMark rm(THREAD);
1626 1628 vframeStream st(THREAD);
1627 oop b = backtrace->obj_at(trace_bcis_offset); 1629
1628 typeArrayOop bcis = typeArrayOop(b); 1630 BacktraceBuilder bt(backtrace);
1629 assert(bcis != NULL, "bci array not preallocated");
1630
1631 oop mr = backtrace->obj_at(trace_mirrors_offset);
1632 objArrayOop mirrors = objArrayOop(mr);
1633 assert(mirrors != NULL, "bci array not preallocated");
1634
1635 assert(methods->length() == bcis->length() &&
1636 methods->length() == mirrors->length(),
1637 "method and bci arrays should match");
1638
1639 JavaThread* thread = JavaThread::current();
1640 ResourceMark rm(thread);
1641 vframeStream st(thread);
1642 1631
1643 // Unlike fill_in_stack_trace we do not skip fillInStackTrace or throwable init 1632 // Unlike fill_in_stack_trace we do not skip fillInStackTrace or throwable init
1644 // methods as preallocated errors aren't created by "java" code. 1633 // methods as preallocated errors aren't created by "java" code.
1645 1634
1646 // fill in as much stack trace as possible 1635 // fill in as much stack trace as possible
1636 typeArrayOop methods = BacktraceBuilder::get_methods(backtrace);
1647 int max_chunks = MIN2(methods->length(), (int)MaxJavaStackTraceDepth); 1637 int max_chunks = MIN2(methods->length(), (int)MaxJavaStackTraceDepth);
1648 int chunk_count = 0; 1638 int chunk_count = 0;
1649 1639
1650 for (;!st.at_end(); st.next()) { 1640 for (;!st.at_end(); st.next()) {
1651 // Add entry and smear the -1 bci to 0 since the array only holds 1641 bt.push(st.method(), st.bci(), CHECK);
1652 // unsigned shorts. The later line number lookup would just smear
1653 // the -1 to a 0 even if it could be recorded.
1654 int bci = st.bci();
1655 if (bci == SynchronizationEntryBCI) bci = 0;
1656 assert(bci == (jushort)bci, "doesn't fit");
1657 bcis->ushort_at_put(chunk_count, bci);
1658 methods->metadata_at_put(chunk_count, st.method());
1659 mirrors->obj_at_put(chunk_count,
1660 st.method()->method_holder()->java_mirror());
1661
1662 chunk_count++; 1642 chunk_count++;
1663 1643
1664 // Bail-out for deep stacks 1644 // Bail-out for deep stacks
1665 if (chunk_count >= max_chunks) break; 1645 if (chunk_count >= max_chunks) break;
1666 } 1646 }
1670 // can be removed in a JDK using this JVM version 1650 // can be removed in a JDK using this JVM version
1671 if (JDK_Version::is_gte_jdk17x_version()) { 1651 if (JDK_Version::is_gte_jdk17x_version()) {
1672 java_lang_Throwable::set_stacktrace(throwable(), java_lang_Throwable::unassigned_stacktrace()); 1652 java_lang_Throwable::set_stacktrace(throwable(), java_lang_Throwable::unassigned_stacktrace());
1673 assert(java_lang_Throwable::unassigned_stacktrace() != NULL, "not initialized"); 1653 assert(java_lang_Throwable::unassigned_stacktrace() != NULL, "not initialized");
1674 } 1654 }
1675
1676 } 1655 }
1677 1656
1678 1657
1679 int java_lang_Throwable::get_stack_trace_depth(oop throwable, TRAPS) { 1658 int java_lang_Throwable::get_stack_trace_depth(oop throwable, TRAPS) {
1680 if (throwable == NULL) { 1659 if (throwable == NULL) {
1689 if (next == NULL) break; 1668 if (next == NULL) break;
1690 depth += trace_chunk_size; 1669 depth += trace_chunk_size;
1691 chunk = next; 1670 chunk = next;
1692 } 1671 }
1693 assert(chunk != NULL && chunk->obj_at(trace_next_offset) == NULL, "sanity check"); 1672 assert(chunk != NULL && chunk->obj_at(trace_next_offset) == NULL, "sanity check");
1694 // Count element in remaining partial chunk 1673 // Count element in remaining partial chunk. NULL value for mirror
1695 typeArrayOop methods = typeArrayOop(chunk->obj_at(trace_methods_offset)); 1674 // marks the end of the stack trace elements that are saved.
1696 typeArrayOop bcis = typeArrayOop(chunk->obj_at(trace_bcis_offset)); 1675 objArrayOop mirrors = BacktraceBuilder::get_mirrors(chunk);
1697 assert(methods != NULL && bcis != NULL, "sanity check"); 1676 assert(mirrors != NULL, "sanity check");
1698 for (int i = 0; i < methods->length(); i++) { 1677 for (int i = 0; i < mirrors->length(); i++) {
1699 if (methods->metadata_at(i) == NULL) break; 1678 if (mirrors->obj_at(i) == NULL) break;
1700 depth++; 1679 depth++;
1701 } 1680 }
1702 } 1681 }
1703 return depth; 1682 return depth;
1704 } 1683 }
1720 skip_chunks--; 1699 skip_chunks--;
1721 } 1700 }
1722 if (chunk == NULL) { 1701 if (chunk == NULL) {
1723 THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL); 1702 THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL);
1724 } 1703 }
1725 // Get method,bci from chunk 1704 // Get method id, bci, version and mirror from chunk
1726 typeArrayOop methods = typeArrayOop(chunk->obj_at(trace_methods_offset)); 1705 typeArrayOop methods = BacktraceBuilder::get_methods(chunk);
1727 typeArrayOop bcis = typeArrayOop(chunk->obj_at(trace_bcis_offset)); 1706 typeArrayOop bcis = BacktraceBuilder::get_bcis(chunk);
1728 assert(methods != NULL && bcis != NULL, "sanity check"); 1707 objArrayOop mirrors = BacktraceBuilder::get_mirrors(chunk);
1729 methodHandle method(THREAD, ((Method*)methods->metadata_at(chunk_index))); 1708
1730 int bci = bcis->ushort_at(chunk_index); 1709 assert(methods != NULL && bcis != NULL && mirrors != NULL, "sanity check");
1710
1711 int method = methods->short_at(chunk_index);
1712 int version = version_at(bcis->int_at(chunk_index));
1713 int bci = bci_at(bcis->int_at(chunk_index));
1714 Handle mirror(THREAD, mirrors->obj_at(chunk_index));
1715
1731 // Chunk can be partial full 1716 // Chunk can be partial full
1732 if (method.is_null()) { 1717 if (mirror.is_null()) {
1733 THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL); 1718 THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL);
1734 } 1719 }
1735 1720
1736 oop element = java_lang_StackTraceElement::create(method, bci, CHECK_0); 1721 oop element = java_lang_StackTraceElement::create(mirror, method, version, bci, CHECK_0);
1737 return element; 1722 return element;
1738 } 1723 }
1739 1724
1740 oop java_lang_StackTraceElement::create(methodHandle method, int bci, TRAPS) { 1725 oop java_lang_StackTraceElement::create(Handle mirror, int method_id, int version, int bci, TRAPS) {
1741 // SystemDictionary::stackTraceElement_klass() will be null for pre-1.4 JDKs
1742 assert(JDK_Version::is_gte_jdk14x_version(), "should only be called in >= 1.4");
1743
1744 // Allocate java.lang.StackTraceElement instance 1726 // Allocate java.lang.StackTraceElement instance
1745 Klass* k = SystemDictionary::StackTraceElement_klass(); 1727 Klass* k = SystemDictionary::StackTraceElement_klass();
1746 assert(k != NULL, "must be loaded in 1.4+"); 1728 assert(k != NULL, "must be loaded in 1.4+");
1747 instanceKlassHandle ik (THREAD, k); 1729 instanceKlassHandle ik (THREAD, k);
1748 if (ik->should_be_initialized()) { 1730 if (ik->should_be_initialized()) {
1750 } 1732 }
1751 1733
1752 Handle element = ik->allocate_instance_handle(CHECK_0); 1734 Handle element = ik->allocate_instance_handle(CHECK_0);
1753 // Fill in class name 1735 // Fill in class name
1754 ResourceMark rm(THREAD); 1736 ResourceMark rm(THREAD);
1755 const char* str = method->method_holder()->external_name(); 1737 InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror()));
1738 const char* str = holder->external_name();
1756 oop classname = StringTable::intern((char*) str, CHECK_0); 1739 oop classname = StringTable::intern((char*) str, CHECK_0);
1757 java_lang_StackTraceElement::set_declaringClass(element(), classname); 1740 java_lang_StackTraceElement::set_declaringClass(element(), classname);
1741
1758 // Fill in method name 1742 // Fill in method name
1743 Method* method = holder->method_with_idnum(method_id);
1759 oop methodname = StringTable::intern(method->name(), CHECK_0); 1744 oop methodname = StringTable::intern(method->name(), CHECK_0);
1760 java_lang_StackTraceElement::set_methodName(element(), methodname); 1745 java_lang_StackTraceElement::set_methodName(element(), methodname);
1761 // Fill in source file name 1746
1762 Symbol* source = method->method_holder()->source_file_name(); 1747 if (!version_matches(method, version)) {
1763 if (ShowHiddenFrames && source == NULL) 1748 // The method was redefined, accurate line number information isn't available
1764 source = vmSymbols::unknown_class_name(); 1749 java_lang_StackTraceElement::set_fileName(element(), NULL);
1765 oop filename = StringTable::intern(source, CHECK_0); 1750 java_lang_StackTraceElement::set_lineNumber(element(), -1);
1766 java_lang_StackTraceElement::set_fileName(element(), filename);
1767 // File in source line number
1768 int line_number;
1769 if (method->is_native()) {
1770 // Negative value different from -1 below, enabling Java code in
1771 // class java.lang.StackTraceElement to distinguish "native" from
1772 // "no LineNumberTable".
1773 line_number = -2;
1774 } else { 1751 } else {
1775 // Returns -1 if no LineNumberTable, and otherwise actual line number 1752 // Fill in source file name and line number.
1776 line_number = method->line_number_from_bci(bci); 1753 Symbol* source = holder->source_file_name();
1777 if (line_number == -1 && ShowHiddenFrames) { 1754 if (ShowHiddenFrames && source == NULL)
1778 line_number = bci + 1000000; 1755 source = vmSymbols::unknown_class_name();
1779 } 1756 oop filename = StringTable::intern(source, CHECK_0);
1780 } 1757 java_lang_StackTraceElement::set_fileName(element(), filename);
1781 java_lang_StackTraceElement::set_lineNumber(element(), line_number); 1758
1782 1759 int line_number = get_line_number(method, bci);
1760 java_lang_StackTraceElement::set_lineNumber(element(), line_number);
1761 }
1783 return element(); 1762 return element();
1784 } 1763 }
1785 1764
1765 oop java_lang_StackTraceElement::create(methodHandle method, int bci, TRAPS) {
1766 Handle mirror (THREAD, method->method_holder()->java_mirror());
1767 int method_id = method->method_idnum();
1768 return create(mirror, method_id, method->constants()->version(), bci, THREAD);
1769 }
1786 1770
1787 void java_lang_reflect_AccessibleObject::compute_offsets() { 1771 void java_lang_reflect_AccessibleObject::compute_offsets() {
1788 Klass* k = SystemDictionary::reflect_AccessibleObject_klass(); 1772 Klass* k = SystemDictionary::reflect_AccessibleObject_klass();
1789 compute_offset(override_offset, k, vmSymbols::override_name(), vmSymbols::bool_signature()); 1773 compute_offset(override_offset, k, vmSymbols::override_name(), vmSymbols::bool_signature());
1790 } 1774 }