comparison src/share/vm/classfile/javaClasses.cpp @ 7627:c73c3f2c5b3b

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