1294 *dest++ = Bytes::get_Java_u2((u1*) (src++)); |
1294 *dest++ = Bytes::get_Java_u2((u1*) (src++)); |
1295 } |
1295 } |
1296 } |
1296 } |
1297 |
1297 |
1298 |
1298 |
1299 typeArrayHandle ClassFileParser::parse_exception_table(u4 code_length, |
1299 u2* ClassFileParser::parse_exception_table(u4 code_length, |
1300 u4 exception_table_length, |
1300 u4 exception_table_length, |
1301 constantPoolHandle cp, |
1301 constantPoolHandle cp, |
1302 TRAPS) { |
1302 TRAPS) { |
1303 ClassFileStream* cfs = stream(); |
1303 ClassFileStream* cfs = stream(); |
1304 typeArrayHandle nullHandle; |
1304 |
1305 |
1305 u2* exception_table_start = cfs->get_u2_buffer(); |
1306 // 4-tuples of ints [start_pc, end_pc, handler_pc, catch_type index] |
1306 assert(exception_table_start != NULL, "null exception table"); |
1307 typeArrayOop eh = oopFactory::new_permanent_intArray(exception_table_length*4, CHECK_(nullHandle)); |
1307 cfs->guarantee_more(8 * exception_table_length, CHECK_NULL); // start_pc, end_pc, handler_pc, catch_type_index |
1308 typeArrayHandle exception_handlers = typeArrayHandle(THREAD, eh); |
1308 // Will check legal target after parsing code array in verifier. |
1309 |
1309 if (_need_verify) { |
1310 int index = 0; |
1310 for (unsigned int i = 0; i < exception_table_length; i++) { |
1311 cfs->guarantee_more(8 * exception_table_length, CHECK_(nullHandle)); // start_pc, end_pc, handler_pc, catch_type_index |
1311 u2 start_pc = cfs->get_u2_fast(); |
1312 for (unsigned int i = 0; i < exception_table_length; i++) { |
1312 u2 end_pc = cfs->get_u2_fast(); |
1313 u2 start_pc = cfs->get_u2_fast(); |
1313 u2 handler_pc = cfs->get_u2_fast(); |
1314 u2 end_pc = cfs->get_u2_fast(); |
1314 u2 catch_type_index = cfs->get_u2_fast(); |
1315 u2 handler_pc = cfs->get_u2_fast(); |
|
1316 u2 catch_type_index = cfs->get_u2_fast(); |
|
1317 // Will check legal target after parsing code array in verifier. |
|
1318 if (_need_verify) { |
|
1319 guarantee_property((start_pc < end_pc) && (end_pc <= code_length), |
1315 guarantee_property((start_pc < end_pc) && (end_pc <= code_length), |
1320 "Illegal exception table range in class file %s", CHECK_(nullHandle)); |
1316 "Illegal exception table range in class file %s", |
|
1317 CHECK_NULL); |
1321 guarantee_property(handler_pc < code_length, |
1318 guarantee_property(handler_pc < code_length, |
1322 "Illegal exception table handler in class file %s", CHECK_(nullHandle)); |
1319 "Illegal exception table handler in class file %s", |
|
1320 CHECK_NULL); |
1323 if (catch_type_index != 0) { |
1321 if (catch_type_index != 0) { |
1324 guarantee_property(valid_cp_range(catch_type_index, cp->length()) && |
1322 guarantee_property(valid_cp_range(catch_type_index, cp->length()) && |
1325 is_klass_reference(cp, catch_type_index), |
1323 is_klass_reference(cp, catch_type_index), |
1326 "Catch type in exception table has bad constant type in class file %s", CHECK_(nullHandle)); |
1324 "Catch type in exception table has bad constant type in class file %s", CHECK_NULL); |
1327 } |
1325 } |
1328 } |
1326 } |
1329 exception_handlers->int_at_put(index++, start_pc); |
1327 } else { |
1330 exception_handlers->int_at_put(index++, end_pc); |
1328 cfs->skip_u2_fast(exception_table_length * 4); |
1331 exception_handlers->int_at_put(index++, handler_pc); |
1329 } |
1332 exception_handlers->int_at_put(index++, catch_type_index); |
1330 return exception_table_start; |
1333 } |
|
1334 return exception_handlers; |
|
1335 } |
1331 } |
1336 |
1332 |
1337 void ClassFileParser::parse_linenumber_table( |
1333 void ClassFileParser::parse_linenumber_table( |
1338 u4 code_attribute_length, u4 code_length, |
1334 u4 code_attribute_length, u4 code_length, |
1339 CompressedLineNumberWriteStream** write_stream, TRAPS) { |
1335 CompressedLineNumberWriteStream** write_stream, TRAPS) { |
1955 |
1952 |
1956 // Exception handler table |
1953 // Exception handler table |
1957 cfs->guarantee_more(2, CHECK_(nullHandle)); // exception_table_length |
1954 cfs->guarantee_more(2, CHECK_(nullHandle)); // exception_table_length |
1958 exception_table_length = cfs->get_u2_fast(); |
1955 exception_table_length = cfs->get_u2_fast(); |
1959 if (exception_table_length > 0) { |
1956 if (exception_table_length > 0) { |
1960 exception_handlers = |
1957 exception_table_start = |
1961 parse_exception_table(code_length, exception_table_length, cp, CHECK_(nullHandle)); |
1958 parse_exception_table(code_length, exception_table_length, cp, CHECK_(nullHandle)); |
1962 } |
1959 } |
1963 |
1960 |
1964 // Parse additional attributes in code attribute |
1961 // Parse additional attributes in code attribute |
1965 cfs->guarantee_more(2, CHECK_(nullHandle)); // code_attributes_count |
1962 cfs->guarantee_more(2, CHECK_(nullHandle)); // code_attributes_count |
2160 guarantee_property(access_flags.is_native() || access_flags.is_abstract() || parsed_code_attribute, |
2157 guarantee_property(access_flags.is_native() || access_flags.is_abstract() || parsed_code_attribute, |
2161 "Absent Code attribute in method that is not native or abstract in class file %s", CHECK_(nullHandle)); |
2158 "Absent Code attribute in method that is not native or abstract in class file %s", CHECK_(nullHandle)); |
2162 } |
2159 } |
2163 |
2160 |
2164 // All sizing information for a methodOop is finally available, now create it |
2161 // All sizing information for a methodOop is finally available, now create it |
2165 methodOop m_oop = oopFactory::new_method(code_length, access_flags, linenumber_table_length, |
2162 methodOop m_oop = oopFactory::new_method(code_length, access_flags, |
2166 total_lvt_length, checked_exceptions_length, |
2163 linenumber_table_length, |
2167 oopDesc::IsSafeConc, CHECK_(nullHandle)); |
2164 total_lvt_length, |
|
2165 exception_table_length, |
|
2166 checked_exceptions_length, |
|
2167 oopDesc::IsSafeConc, |
|
2168 CHECK_(nullHandle)); |
2168 methodHandle m (THREAD, m_oop); |
2169 methodHandle m (THREAD, m_oop); |
2169 |
2170 |
2170 ClassLoadingService::add_class_method_size(m_oop->size()*HeapWordSize); |
2171 ClassLoadingService::add_class_method_size(m_oop->size()*HeapWordSize); |
2171 |
2172 |
2172 // Fill in information from fixed part (access_flags already set) |
2173 // Fill in information from fixed part (access_flags already set) |
2193 #endif |
2194 #endif |
2194 |
2195 |
2195 // Fill in code attribute information |
2196 // Fill in code attribute information |
2196 m->set_max_stack(max_stack); |
2197 m->set_max_stack(max_stack); |
2197 m->set_max_locals(max_locals); |
2198 m->set_max_locals(max_locals); |
2198 m->constMethod()->set_stackmap_data(stackmap_data()); |
|
2199 |
2199 |
2200 /** |
2200 /** |
2201 * The exception_table field is the flag used to indicate |
2201 * The stackmap_data field is the flag used to indicate |
2202 * that the methodOop and it's associated constMethodOop are partially |
2202 * that the methodOop and it's associated constMethodOop are partially |
2203 * initialized and thus are exempt from pre/post GC verification. Once |
2203 * initialized and thus are exempt from pre/post GC verification. Once |
2204 * the field is set, the oops are considered fully initialized so make |
2204 * the field is set, the oops are considered fully initialized so make |
2205 * sure that the oops can pass verification when this field is set. |
2205 * sure that the oops can pass verification when this field is set. |
2206 */ |
2206 */ |
2207 m->set_exception_table(exception_handlers()); |
2207 m->constMethod()->set_stackmap_data(stackmap_data()); |
2208 |
2208 |
2209 // Copy byte codes |
2209 // Copy byte codes |
2210 m->set_code(code_start); |
2210 m->set_code(code_start); |
2211 |
2211 |
2212 // Copy line number table |
2212 // Copy line number table |
2213 if (linenumber_table != NULL) { |
2213 if (linenumber_table != NULL) { |
2214 memcpy(m->compressed_linenumber_table(), |
2214 memcpy(m->compressed_linenumber_table(), |
2215 linenumber_table->buffer(), linenumber_table_length); |
2215 linenumber_table->buffer(), linenumber_table_length); |
|
2216 } |
|
2217 |
|
2218 // Copy exception table |
|
2219 if (exception_table_length > 0) { |
|
2220 int size = |
|
2221 exception_table_length * sizeof(ExceptionTableElement) / sizeof(u2); |
|
2222 copy_u2_with_conversion((u2*) m->exception_table_start(), |
|
2223 exception_table_start, size); |
2216 } |
2224 } |
2217 |
2225 |
2218 // Copy checked exceptions |
2226 // Copy checked exceptions |
2219 if (checked_exceptions_length > 0) { |
2227 if (checked_exceptions_length > 0) { |
2220 int size = checked_exceptions_length * sizeof(CheckedExceptionElement) / sizeof(u2); |
2228 int size = checked_exceptions_length * sizeof(CheckedExceptionElement) / sizeof(u2); |