< prev index next >

src/hotspot/share/classfile/verifier.cpp

Print this page

        

*** 28,48 **** #include "classfile/classLoader.hpp" #include "classfile/javaClasses.hpp" #include "classfile/stackMapTable.hpp" #include "classfile/stackMapFrame.hpp" #include "classfile/stackMapTableFormat.hpp" - #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/verifier.hpp" #include "classfile/vmSymbols.hpp" #include "interpreter/bytecodes.hpp" #include "interpreter/bytecodeStream.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" - #include "memory/universe.hpp" #include "oops/constantPool.inline.hpp" #include "oops/instanceKlass.hpp" #include "oops/oop.inline.hpp" #include "oops/typeArrayOop.hpp" #include "runtime/fieldDescriptor.hpp" --- 28,46 ----
*** 593,605 **** VerificationType ClassVerifier::object_type() const { return VerificationType::reference_type(vmSymbols::java_lang_Object()); } ! TypeOrigin ClassVerifier::ref_ctx(const char* sig) { VerificationType vt = VerificationType::reference_type( ! create_temporary_symbol(sig, (int)strlen(sig))); return TypeOrigin::implicit(vt); } void ClassVerifier::verify_class(TRAPS) { log_info(verification)("Verifying class %s with new format", _klass->external_name()); --- 591,603 ---- VerificationType ClassVerifier::object_type() const { return VerificationType::reference_type(vmSymbols::java_lang_Object()); } ! TypeOrigin ClassVerifier::ref_ctx(const char* sig, TRAPS) { VerificationType vt = VerificationType::reference_type( ! create_temporary_symbol(sig, (int)strlen(sig), THREAD)); return TypeOrigin::implicit(vt); } void ClassVerifier::verify_class(TRAPS) { log_info(verification)("Verifying class %s with new format", _klass->external_name());
*** 645,655 **** int sig_i = 0; GrowableArray<VerificationType>* verif_types = sig_verif_types->sig_verif_types(); // Translate the signature arguments into verification types. while (!sig_stream.at_return_type()) { ! int n = change_sig_to_verificationType(&sig_stream, sig_type); assert(n <= 2, "Unexpected signature type"); // Store verification type(s). Longs and Doubles each have two verificationTypes. for (int x = 0; x < n; x++) { verif_types->push(sig_type[x]); --- 643,653 ---- int sig_i = 0; GrowableArray<VerificationType>* verif_types = sig_verif_types->sig_verif_types(); // Translate the signature arguments into verification types. while (!sig_stream.at_return_type()) { ! int n = change_sig_to_verificationType(&sig_stream, sig_type, CHECK_VERIFY(this)); assert(n <= 2, "Unexpected signature type"); // Store verification type(s). Longs and Doubles each have two verificationTypes. for (int x = 0; x < n; x++) { verif_types->push(sig_type[x]);
*** 662,672 **** // be compared with sig_verify_types' length to see if there is a return type. sig_verif_types->set_num_args(sig_i); // Store verification type(s) for the return type, if there is one. if (sig_stream.type() != T_VOID) { ! int n = change_sig_to_verificationType(&sig_stream, sig_type); assert(n <= 2, "Unexpected signature return type"); for (int y = 0; y < n; y++) { verif_types->push(sig_type[y]); } } --- 660,670 ---- // be compared with sig_verify_types' length to see if there is a return type. sig_verif_types->set_num_args(sig_i); // Store verification type(s) for the return type, if there is one. if (sig_stream.type() != T_VOID) { ! int n = change_sig_to_verificationType(&sig_stream, sig_type, CHECK_VERIFY(this)); assert(n <= 2, "Unexpected signature return type"); for (int y = 0; y < n; y++) { verif_types->push(sig_type[y]); } }
*** 923,933 **** VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_int_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[I")), bad_type_msg, "iaload"); return; } current_frame.push_stack( VerificationType::integer_type(), CHECK_VERIFY(this)); --- 921,931 ---- VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_int_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[I", THREAD)), bad_type_msg, "iaload"); return; } current_frame.push_stack( VerificationType::integer_type(), CHECK_VERIFY(this));
*** 951,961 **** VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_char_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[C")), bad_type_msg, "caload"); return; } current_frame.push_stack( VerificationType::integer_type(), CHECK_VERIFY(this)); --- 949,959 ---- VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_char_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[C", THREAD)), bad_type_msg, "caload"); return; } current_frame.push_stack( VerificationType::integer_type(), CHECK_VERIFY(this));
*** 965,975 **** VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_short_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[S")), bad_type_msg, "saload"); return; } current_frame.push_stack( VerificationType::integer_type(), CHECK_VERIFY(this)); --- 963,973 ---- VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_short_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[S", THREAD)), bad_type_msg, "saload"); return; } current_frame.push_stack( VerificationType::integer_type(), CHECK_VERIFY(this));
*** 979,989 **** VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_long_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[J")), bad_type_msg, "laload"); return; } current_frame.push_stack_2( VerificationType::long_type(), --- 977,987 ---- VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_long_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[J", THREAD)), bad_type_msg, "laload"); return; } current_frame.push_stack_2( VerificationType::long_type(),
*** 994,1004 **** VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_float_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[F")), bad_type_msg, "faload"); return; } current_frame.push_stack( VerificationType::float_type(), CHECK_VERIFY(this)); --- 992,1002 ---- VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_float_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[F", THREAD)), bad_type_msg, "faload"); return; } current_frame.push_stack( VerificationType::float_type(), CHECK_VERIFY(this));
*** 1008,1018 **** VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_double_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[D")), bad_type_msg, "daload"); return; } current_frame.push_stack_2( VerificationType::double_type(), --- 1006,1016 ---- VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_double_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[D", THREAD)), bad_type_msg, "daload"); return; } current_frame.push_stack_2( VerificationType::double_type(),
*** 1097,1107 **** VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_int_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[I")), bad_type_msg, "iastore"); return; } no_control_flow = false; break; case Bytecodes::_bastore : --- 1095,1105 ---- VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_int_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[I", THREAD)), bad_type_msg, "iastore"); return; } no_control_flow = false; break; case Bytecodes::_bastore :
*** 1125,1135 **** VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_char_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[C")), bad_type_msg, "castore"); return; } no_control_flow = false; break; case Bytecodes::_sastore : --- 1123,1133 ---- VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_char_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[C", THREAD)), bad_type_msg, "castore"); return; } no_control_flow = false; break; case Bytecodes::_sastore :
*** 1139,1149 **** VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_short_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[S")), bad_type_msg, "sastore"); return; } no_control_flow = false; break; case Bytecodes::_lastore : --- 1137,1147 ---- VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_short_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[S", THREAD)), bad_type_msg, "sastore"); return; } no_control_flow = false; break; case Bytecodes::_lastore :
*** 1154,1164 **** VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_long_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[J")), bad_type_msg, "lastore"); return; } no_control_flow = false; break; case Bytecodes::_fastore : --- 1152,1162 ---- VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_long_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[J", THREAD)), bad_type_msg, "lastore"); return; } no_control_flow = false; break; case Bytecodes::_fastore :
*** 1168,1178 **** (VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_float_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[F")), bad_type_msg, "fastore"); return; } no_control_flow = false; break; case Bytecodes::_dastore : --- 1166,1176 ---- (VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_float_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[F", THREAD)), bad_type_msg, "fastore"); return; } no_control_flow = false; break; case Bytecodes::_dastore :
*** 1183,1193 **** VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_double_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[D")), bad_type_msg, "dastore"); return; } no_control_flow = false; break; case Bytecodes::_aastore : --- 1181,1191 ---- VerificationType::integer_type(), CHECK_VERIFY(this)); atype = current_frame.pop_stack( VerificationType::reference_check(), CHECK_VERIFY(this)); if (!atype.is_double_array()) { verify_error(ErrorContext::bad_type(bci, ! current_frame.stack_top_ctx(), ref_ctx("[D", THREAD)), bad_type_msg, "dastore"); return; } no_control_flow = false; break; case Bytecodes::_aastore :
*** 2060,2072 **** va_list va; va_start(va, msg); ss.vprint(msg, va); va_end(va); if (!_method.is_null()) { ! ss.print(" in method '"); ! _method->print_external_name(&ss); ! ss.print("'"); } _message = ss.as_string(); } Klass* ClassVerifier::load_class(Symbol* name, TRAPS) { --- 2058,2068 ---- va_list va; va_start(va, msg); ss.vprint(msg, va); va_end(va); if (!_method.is_null()) { ! ss.print(" in method %s", _method->name_and_sig_as_C_string()); } _message = ss.as_string(); } Klass* ClassVerifier::load_class(Symbol* name, TRAPS) {
*** 2181,2191 **** assert(sizeof(VerificationType) == sizeof(uintptr_t), "buffer type must match VerificationType size"); uintptr_t constant_type_buffer[2]; VerificationType* v_constant_type = (VerificationType*)constant_type_buffer; SignatureStream sig_stream(constant_type, false); ! int n = change_sig_to_verificationType(&sig_stream, v_constant_type); int opcode_n = (opcode == Bytecodes::_ldc2_w ? 2 : 1); if (n != opcode_n) { // wrong kind of ldc; reverify against updated type mask types &= ~(1 << JVM_CONSTANT_Dynamic); verify_cp_type(bci, index, cp, types, CHECK_VERIFY(this)); --- 2177,2188 ---- assert(sizeof(VerificationType) == sizeof(uintptr_t), "buffer type must match VerificationType size"); uintptr_t constant_type_buffer[2]; VerificationType* v_constant_type = (VerificationType*)constant_type_buffer; SignatureStream sig_stream(constant_type, false); ! int n = change_sig_to_verificationType( ! &sig_stream, v_constant_type, CHECK_VERIFY(this)); int opcode_n = (opcode == Bytecodes::_ldc2_w ? 2 : 1); if (n != opcode_n) { // wrong kind of ldc; reverify against updated type mask types &= ~(1 << JVM_CONSTANT_Dynamic); verify_cp_type(bci, index, cp, types, CHECK_VERIFY(this));
*** 2322,2332 **** // stack allocating it. Plus it would run constructors. This shows up // in performance profiles. SignatureStream sig_stream(field_sig, false); VerificationType stack_object_type; ! int n = change_sig_to_verificationType(&sig_stream, field_type); u2 bci = bcs->bci(); bool is_assignable; switch (bcs->raw_code()) { case Bytecodes::_getstatic: { for (int i = 0; i < n; i++) { --- 2319,2330 ---- // stack allocating it. Plus it would run constructors. This shows up // in performance profiles. SignatureStream sig_stream(field_sig, false); VerificationType stack_object_type; ! int n = change_sig_to_verificationType( ! &sig_stream, field_type, CHECK_VERIFY(this)); u2 bci = bcs->bci(); bool is_assignable; switch (bcs->raw_code()) { case Bytecodes::_getstatic: { for (int i = 0; i < n; i++) {
*** 2998,3008 **** verify_error(ErrorContext::bad_code(bci), "Illegal newarray instruction"); return VerificationType::bogus_type(); } // from_bt[index] contains the array signature which has a length of 2 ! Symbol* sig = create_temporary_symbol(from_bt[index], 2); return VerificationType::reference_type(sig); } void ClassVerifier::verify_anewarray( u2 bci, u2 index, const constantPoolHandle& cp, --- 2996,3007 ---- verify_error(ErrorContext::bad_code(bci), "Illegal newarray instruction"); return VerificationType::bogus_type(); } // from_bt[index] contains the array signature which has a length of 2 ! Symbol* sig = create_temporary_symbol( ! from_bt[index], 2, CHECK_(VerificationType::bogus_type())); return VerificationType::reference_type(sig); } void ClassVerifier::verify_anewarray( u2 bci, u2 index, const constantPoolHandle& cp,
*** 3036,3046 **** length = (int)strlen(component_name) + 3; arr_sig_str = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, length + 1); int n = os::snprintf(arr_sig_str, length + 1, "[L%s;", component_name); assert(n == length, "Unexpected number of characters in string"); } ! Symbol* arr_sig = create_temporary_symbol(arr_sig_str, length); VerificationType new_array_type = VerificationType::reference_type(arr_sig); current_frame->push_stack(new_array_type, CHECK_VERIFY(this)); } void ClassVerifier::verify_iload(u2 index, StackMapFrame* current_frame, TRAPS) { --- 3035,3046 ---- length = (int)strlen(component_name) + 3; arr_sig_str = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, length + 1); int n = os::snprintf(arr_sig_str, length + 1, "[L%s;", component_name); assert(n == length, "Unexpected number of characters in string"); } ! Symbol* arr_sig = create_temporary_symbol( ! arr_sig_str, length, CHECK_VERIFY(this)); VerificationType new_array_type = VerificationType::reference_type(arr_sig); current_frame->push_stack(new_array_type, CHECK_VERIFY(this)); } void ClassVerifier::verify_iload(u2 index, StackMapFrame* current_frame, TRAPS) {
*** 3144,3165 **** // The verifier creates symbols which are substrings of Symbols. // These are stored in the verifier until the end of verification so that // they can be reference counted. Symbol* ClassVerifier::create_temporary_symbol(const Symbol *s, int begin, ! int end) { const char* name = (const char*)s->base() + begin; int length = end - begin; ! return create_temporary_symbol(name, length); } ! Symbol* ClassVerifier::create_temporary_symbol(const char *name, int length) { // Quick deduplication check if (_previous_symbol != NULL && _previous_symbol->equals(name, length)) { return _previous_symbol; } ! Symbol* sym = SymbolTable::new_symbol(name, length); if (!sym->is_permanent()) { if (_symbols == NULL) { _symbols = new GrowableArray<Symbol*>(50, 0, NULL); } _symbols->push(sym); --- 3144,3165 ---- // The verifier creates symbols which are substrings of Symbols. // These are stored in the verifier until the end of verification so that // they can be reference counted. Symbol* ClassVerifier::create_temporary_symbol(const Symbol *s, int begin, ! int end, TRAPS) { const char* name = (const char*)s->base() + begin; int length = end - begin; ! return create_temporary_symbol(name, length, CHECK_NULL); } ! Symbol* ClassVerifier::create_temporary_symbol(const char *name, int length, TRAPS) { // Quick deduplication check if (_previous_symbol != NULL && _previous_symbol->equals(name, length)) { return _previous_symbol; } ! Symbol* sym = SymbolTable::new_symbol(name, length, CHECK_NULL); if (!sym->is_permanent()) { if (_symbols == NULL) { _symbols = new GrowableArray<Symbol*>(50, 0, NULL); } _symbols->push(sym);
< prev index next >