Mercurial > hg > truffle
comparison src/share/vm/classfile/verifier.cpp @ 6213:8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
Summary: Change constMethodOop::_exception_table to optionally inlined u2 table.
Reviewed-by: bdelsart, coleenp, kamg
author | jiangli |
---|---|
date | Tue, 26 Jun 2012 19:08:44 -0400 |
parents | e17b61ba7bb3 |
children | f0b82641fb7e |
comparison
equal
deleted
inserted
replaced
6177:06320b1578cb | 6213:8150fa46d2ed |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1998, 2012, 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. |
1366 | 1366 |
1367 return code_data; | 1367 return code_data; |
1368 } | 1368 } |
1369 | 1369 |
1370 void ClassVerifier::verify_exception_handler_table(u4 code_length, char* code_data, int& min, int& max, TRAPS) { | 1370 void ClassVerifier::verify_exception_handler_table(u4 code_length, char* code_data, int& min, int& max, TRAPS) { |
1371 typeArrayHandle exhandlers (THREAD, _method->exception_table()); | 1371 ExceptionTable exhandlers(_method()); |
1372 int exlength = exhandlers.length(); | |
1372 constantPoolHandle cp (THREAD, _method->constants()); | 1373 constantPoolHandle cp (THREAD, _method->constants()); |
1373 | 1374 |
1374 if (exhandlers() != NULL) { | 1375 for(int i = 0; i < exlength; i++) { |
1375 for(int i = 0; i < exhandlers->length();) { | 1376 //reacquire the table in case a GC happened |
1376 u2 start_pc = exhandlers->int_at(i++); | 1377 ExceptionTable exhandlers(_method()); |
1377 u2 end_pc = exhandlers->int_at(i++); | 1378 u2 start_pc = exhandlers.start_pc(i); |
1378 u2 handler_pc = exhandlers->int_at(i++); | 1379 u2 end_pc = exhandlers.end_pc(i); |
1379 if (start_pc >= code_length || code_data[start_pc] == 0) { | 1380 u2 handler_pc = exhandlers.handler_pc(i); |
1380 class_format_error("Illegal exception table start_pc %d", start_pc); | 1381 if (start_pc >= code_length || code_data[start_pc] == 0) { |
1382 class_format_error("Illegal exception table start_pc %d", start_pc); | |
1383 return; | |
1384 } | |
1385 if (end_pc != code_length) { // special case: end_pc == code_length | |
1386 if (end_pc > code_length || code_data[end_pc] == 0) { | |
1387 class_format_error("Illegal exception table end_pc %d", end_pc); | |
1381 return; | 1388 return; |
1382 } | 1389 } |
1383 if (end_pc != code_length) { // special case: end_pc == code_length | 1390 } |
1384 if (end_pc > code_length || code_data[end_pc] == 0) { | 1391 if (handler_pc >= code_length || code_data[handler_pc] == 0) { |
1385 class_format_error("Illegal exception table end_pc %d", end_pc); | 1392 class_format_error("Illegal exception table handler_pc %d", handler_pc); |
1386 return; | 1393 return; |
1387 } | 1394 } |
1388 } | 1395 int catch_type_index = exhandlers.catch_type_index(i); |
1389 if (handler_pc >= code_length || code_data[handler_pc] == 0) { | 1396 if (catch_type_index != 0) { |
1390 class_format_error("Illegal exception table handler_pc %d", handler_pc); | 1397 VerificationType catch_type = cp_index_to_type( |
1398 catch_type_index, cp, CHECK_VERIFY(this)); | |
1399 VerificationType throwable = | |
1400 VerificationType::reference_type(vmSymbols::java_lang_Throwable()); | |
1401 bool is_subclass = throwable.is_assignable_from( | |
1402 catch_type, this, CHECK_VERIFY(this)); | |
1403 if (!is_subclass) { | |
1404 // 4286534: should throw VerifyError according to recent spec change | |
1405 verify_error( | |
1406 "Catch type is not a subclass of Throwable in handler %d", | |
1407 handler_pc); | |
1391 return; | 1408 return; |
1392 } | 1409 } |
1393 int catch_type_index = exhandlers->int_at(i++); | 1410 } |
1394 if (catch_type_index != 0) { | 1411 if (start_pc < min) min = start_pc; |
1395 VerificationType catch_type = cp_index_to_type( | 1412 if (end_pc > max) max = end_pc; |
1396 catch_type_index, cp, CHECK_VERIFY(this)); | |
1397 VerificationType throwable = | |
1398 VerificationType::reference_type(vmSymbols::java_lang_Throwable()); | |
1399 bool is_subclass = throwable.is_assignable_from( | |
1400 catch_type, this, CHECK_VERIFY(this)); | |
1401 if (!is_subclass) { | |
1402 // 4286534: should throw VerifyError according to recent spec change | |
1403 verify_error( | |
1404 "Catch type is not a subclass of Throwable in handler %d", | |
1405 handler_pc); | |
1406 return; | |
1407 } | |
1408 } | |
1409 if (start_pc < min) min = start_pc; | |
1410 if (end_pc > max) max = end_pc; | |
1411 } | |
1412 } | 1413 } |
1413 } | 1414 } |
1414 | 1415 |
1415 void ClassVerifier::verify_local_variable_table(u4 code_length, char* code_data, TRAPS) { | 1416 void ClassVerifier::verify_local_variable_table(u4 code_length, char* code_data, TRAPS) { |
1416 int localvariable_table_length = _method()->localvariable_table_length(); | 1417 int localvariable_table_length = _method()->localvariable_table_length(); |
1472 } | 1473 } |
1473 | 1474 |
1474 void ClassVerifier::verify_exception_handler_targets(u2 bci, bool this_uninit, StackMapFrame* current_frame, | 1475 void ClassVerifier::verify_exception_handler_targets(u2 bci, bool this_uninit, StackMapFrame* current_frame, |
1475 StackMapTable* stackmap_table, TRAPS) { | 1476 StackMapTable* stackmap_table, TRAPS) { |
1476 constantPoolHandle cp (THREAD, _method->constants()); | 1477 constantPoolHandle cp (THREAD, _method->constants()); |
1477 typeArrayHandle exhandlers (THREAD, _method->exception_table()); | 1478 ExceptionTable exhandlers(_method()); |
1478 if (exhandlers() != NULL) { | 1479 int exlength = exhandlers.length(); |
1479 for(int i = 0; i < exhandlers->length();) { | 1480 for(int i = 0; i < exlength; i++) { |
1480 u2 start_pc = exhandlers->int_at(i++); | 1481 //reacquire the table in case a GC happened |
1481 u2 end_pc = exhandlers->int_at(i++); | 1482 ExceptionTable exhandlers(_method()); |
1482 u2 handler_pc = exhandlers->int_at(i++); | 1483 u2 start_pc = exhandlers.start_pc(i); |
1483 int catch_type_index = exhandlers->int_at(i++); | 1484 u2 end_pc = exhandlers.end_pc(i); |
1484 if(bci >= start_pc && bci < end_pc) { | 1485 u2 handler_pc = exhandlers.handler_pc(i); |
1485 u1 flags = current_frame->flags(); | 1486 int catch_type_index = exhandlers.catch_type_index(i); |
1486 if (this_uninit) { flags |= FLAG_THIS_UNINIT; } | 1487 if(bci >= start_pc && bci < end_pc) { |
1487 StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags); | 1488 u1 flags = current_frame->flags(); |
1488 if (catch_type_index != 0) { | 1489 if (this_uninit) { flags |= FLAG_THIS_UNINIT; } |
1489 // We know that this index refers to a subclass of Throwable | 1490 StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags); |
1490 VerificationType catch_type = cp_index_to_type( | 1491 if (catch_type_index != 0) { |
1491 catch_type_index, cp, CHECK_VERIFY(this)); | 1492 // We know that this index refers to a subclass of Throwable |
1492 new_frame->push_stack(catch_type, CHECK_VERIFY(this)); | 1493 VerificationType catch_type = cp_index_to_type( |
1493 } else { | 1494 catch_type_index, cp, CHECK_VERIFY(this)); |
1494 VerificationType throwable = | 1495 new_frame->push_stack(catch_type, CHECK_VERIFY(this)); |
1495 VerificationType::reference_type(vmSymbols::java_lang_Throwable()); | 1496 } else { |
1496 new_frame->push_stack(throwable, CHECK_VERIFY(this)); | 1497 VerificationType throwable = |
1497 } | 1498 VerificationType::reference_type(vmSymbols::java_lang_Throwable()); |
1498 bool match = stackmap_table->match_stackmap( | 1499 new_frame->push_stack(throwable, CHECK_VERIFY(this)); |
1499 new_frame, handler_pc, true, false, CHECK_VERIFY(this)); | 1500 } |
1500 if (!match) { | 1501 bool match = stackmap_table->match_stackmap( |
1501 verify_error(bci, | 1502 new_frame, handler_pc, true, false, CHECK_VERIFY(this)); |
1502 "Stack map does not match the one at exception handler %d", | 1503 if (!match) { |
1503 handler_pc); | 1504 verify_error(bci, |
1504 return; | 1505 "Stack map does not match the one at exception handler %d", |
1505 } | 1506 handler_pc); |
1507 return; | |
1506 } | 1508 } |
1507 } | 1509 } |
1508 } | 1510 } |
1509 } | 1511 } |
1510 | 1512 |