hotspot/src/share/vm/classfile/classFileParser.cpp
changeset 46513 c61eea516a0a
parent 46504 38048d4d20e7
child 46619 a3919f5e8d2b
equal deleted inserted replaced
46512:1ba5728eda0d 46513:c61eea516a0a
  1697     }
  1697     }
  1698   }
  1698   }
  1699 }
  1699 }
  1700 
  1700 
  1701 
  1701 
  1702 const void* ClassFileParser::parse_exception_table(const ClassFileStream* const cfs,
  1702 const ClassFileParser::unsafe_u2* ClassFileParser::parse_exception_table(const ClassFileStream* const cfs,
  1703                                                    u4 code_length,
  1703                                                                          u4 code_length,
  1704                                                    u4 exception_table_length,
  1704                                                                          u4 exception_table_length,
  1705                                                    TRAPS) {
  1705                                                                          TRAPS) {
  1706   assert(cfs != NULL, "invariant");
  1706   assert(cfs != NULL, "invariant");
  1707 
  1707 
  1708   const void* const exception_table_start = cfs->current();
  1708   const unsafe_u2* const exception_table_start = cfs->current();
  1709   assert(exception_table_start != NULL, "null exception table");
  1709   assert(exception_table_start != NULL, "null exception table");
  1710 
  1710 
  1711   cfs->guarantee_more(8 * exception_table_length, CHECK_NULL); // start_pc,
  1711   cfs->guarantee_more(8 * exception_table_length, CHECK_NULL); // start_pc,
  1712                                                                // end_pc,
  1712                                                                // end_pc,
  1713                                                                // handler_pc,
  1713                                                                // handler_pc,
  1821   lvt->slot                = Bytes::get_Java_u2((u1*) &src->slot);
  1821   lvt->slot                = Bytes::get_Java_u2((u1*) &src->slot);
  1822 }
  1822 }
  1823 
  1823 
  1824 // Function is used to parse both attributes:
  1824 // Function is used to parse both attributes:
  1825 // LocalVariableTable (LVT) and LocalVariableTypeTable (LVTT)
  1825 // LocalVariableTable (LVT) and LocalVariableTypeTable (LVTT)
  1826 const void* ClassFileParser::parse_localvariable_table(const ClassFileStream* cfs,
  1826 const ClassFileParser::unsafe_u2* ClassFileParser::parse_localvariable_table(const ClassFileStream* cfs,
  1827                                                        u4 code_length,
  1827                                                                              u4 code_length,
  1828                                                        u2 max_locals,
  1828                                                                              u2 max_locals,
  1829                                                        u4 code_attribute_length,
  1829                                                                              u4 code_attribute_length,
  1830                                                        u2* const localvariable_table_length,
  1830                                                                              u2* const localvariable_table_length,
  1831                                                        bool isLVTT,
  1831                                                                              bool isLVTT,
  1832                                                        TRAPS) {
  1832                                                                              TRAPS) {
  1833   const char* const tbl_name = (isLVTT) ? "LocalVariableTypeTable" : "LocalVariableTable";
  1833   const char* const tbl_name = (isLVTT) ? "LocalVariableTypeTable" : "LocalVariableTable";
  1834   *localvariable_table_length = cfs->get_u2(CHECK_NULL);
  1834   *localvariable_table_length = cfs->get_u2(CHECK_NULL);
  1835   const unsigned int size =
  1835   const unsigned int size =
  1836     (*localvariable_table_length) * sizeof(Classfile_LVT_Element) / sizeof(u2);
  1836     (*localvariable_table_length) * sizeof(Classfile_LVT_Element) / sizeof(u2);
  1837 
  1837 
  1841   if (_need_verify) {
  1841   if (_need_verify) {
  1842     guarantee_property(code_attribute_length == (sizeof(*localvariable_table_length) + size * sizeof(u2)),
  1842     guarantee_property(code_attribute_length == (sizeof(*localvariable_table_length) + size * sizeof(u2)),
  1843                        "%s has wrong length in class file %s", tbl_name, CHECK_NULL);
  1843                        "%s has wrong length in class file %s", tbl_name, CHECK_NULL);
  1844   }
  1844   }
  1845 
  1845 
  1846   const void* const localvariable_table_start = cfs->current();
  1846   const unsafe_u2* const localvariable_table_start = cfs->current();
  1847   assert(localvariable_table_start != NULL, "null local variable table");
  1847   assert(localvariable_table_start != NULL, "null local variable table");
  1848   if (!_need_verify) {
  1848   if (!_need_verify) {
  1849     cfs->skip_u2_fast(size);
  1849     cfs->skip_u2_fast(size);
  1850   } else {
  1850   } else {
  1851     cfs->guarantee_more(size * 2, CHECK_NULL);
  1851     cfs->guarantee_more(size * 2, CHECK_NULL);
  1957     return NULL;
  1957     return NULL;
  1958   }
  1958   }
  1959   return stackmap_table_start;
  1959   return stackmap_table_start;
  1960 }
  1960 }
  1961 
  1961 
  1962 const void* ClassFileParser::parse_checked_exceptions(const ClassFileStream* const cfs,
  1962 const ClassFileParser::unsafe_u2* ClassFileParser::parse_checked_exceptions(const ClassFileStream* const cfs,
  1963                                                       u2* const checked_exceptions_length,
  1963                                                                             u2* const checked_exceptions_length,
  1964                                                       u4 method_attribute_length,
  1964                                                                             u4 method_attribute_length,
  1965                                                       TRAPS) {
  1965                                                                             TRAPS) {
  1966   assert(cfs != NULL, "invariant");
  1966   assert(cfs != NULL, "invariant");
  1967   assert(checked_exceptions_length != NULL, "invariant");
  1967   assert(checked_exceptions_length != NULL, "invariant");
  1968 
  1968 
  1969   cfs->guarantee_more(2, CHECK_NULL);  // checked_exceptions_length
  1969   cfs->guarantee_more(2, CHECK_NULL);  // checked_exceptions_length
  1970   *checked_exceptions_length = cfs->get_u2_fast();
  1970   *checked_exceptions_length = cfs->get_u2_fast();
  1971   const unsigned int size =
  1971   const unsigned int size =
  1972     (*checked_exceptions_length) * sizeof(CheckedExceptionElement) / sizeof(u2);
  1972     (*checked_exceptions_length) * sizeof(CheckedExceptionElement) / sizeof(u2);
  1973   const void* const checked_exceptions_start = cfs->current();
  1973   const unsafe_u2* const checked_exceptions_start = cfs->current();
  1974   assert(checked_exceptions_start != NULL, "null checked exceptions");
  1974   assert(checked_exceptions_start != NULL, "null checked exceptions");
  1975   if (!_need_verify) {
  1975   if (!_need_verify) {
  1976     cfs->skip_u2_fast(size);
  1976     cfs->skip_u2_fast(size);
  1977   } else {
  1977   } else {
  1978     // Verify each value in the checked exception table
  1978     // Verify each value in the checked exception table
  2135  *   - HotSpot internal LVT keeps natural ordering of class file LVT entries.
  2135  *   - HotSpot internal LVT keeps natural ordering of class file LVT entries.
  2136  */
  2136  */
  2137 void ClassFileParser::copy_localvariable_table(const ConstMethod* cm,
  2137 void ClassFileParser::copy_localvariable_table(const ConstMethod* cm,
  2138                                                int lvt_cnt,
  2138                                                int lvt_cnt,
  2139                                                u2* const localvariable_table_length,
  2139                                                u2* const localvariable_table_length,
  2140                                                const void** const localvariable_table_start,
  2140                                                const unsafe_u2** const localvariable_table_start,
  2141                                                int lvtt_cnt,
  2141                                                int lvtt_cnt,
  2142                                                u2* const localvariable_type_table_length,
  2142                                                u2* const localvariable_type_table_length,
  2143                                                const void** const localvariable_type_table_start,
  2143                                                const unsafe_u2** const localvariable_type_table_start,
  2144                                                TRAPS) {
  2144                                                TRAPS) {
  2145 
  2145 
  2146   ResourceMark rm(THREAD);
  2146   ResourceMark rm(THREAD);
  2147 
  2147 
  2148   typedef ResourceHashtable<LocalVariableTableElement, LocalVariableTableElement*,
  2148   typedef ResourceHashtable<LocalVariableTableElement, LocalVariableTableElement*,
  2333   u2 max_stack = 0;
  2333   u2 max_stack = 0;
  2334   u2 max_locals = 0;
  2334   u2 max_locals = 0;
  2335   u4 code_length = 0;
  2335   u4 code_length = 0;
  2336   const u1* code_start = 0;
  2336   const u1* code_start = 0;
  2337   u2 exception_table_length = 0;
  2337   u2 exception_table_length = 0;
  2338   const void* exception_table_start = NULL; // (potentially unaligned) pointer to array of u2 elements
  2338   const unsafe_u2* exception_table_start = NULL; // (potentially unaligned) pointer to array of u2 elements
  2339   Array<int>* exception_handlers = Universe::the_empty_int_array();
  2339   Array<int>* exception_handlers = Universe::the_empty_int_array();
  2340   u2 checked_exceptions_length = 0;
  2340   u2 checked_exceptions_length = 0;
  2341   const void* checked_exceptions_start = NULL; // (potentially unaligned) pointer to array of u2 elements
  2341   const unsafe_u2* checked_exceptions_start = NULL; // (potentially unaligned) pointer to array of u2 elements
  2342   CompressedLineNumberWriteStream* linenumber_table = NULL;
  2342   CompressedLineNumberWriteStream* linenumber_table = NULL;
  2343   int linenumber_table_length = 0;
  2343   int linenumber_table_length = 0;
  2344   int total_lvt_length = 0;
  2344   int total_lvt_length = 0;
  2345   u2 lvt_cnt = 0;
  2345   u2 lvt_cnt = 0;
  2346   u2 lvtt_cnt = 0;
  2346   u2 lvtt_cnt = 0;
  2347   bool lvt_allocated = false;
  2347   bool lvt_allocated = false;
  2348   u2 max_lvt_cnt = INITIAL_MAX_LVT_NUMBER;
  2348   u2 max_lvt_cnt = INITIAL_MAX_LVT_NUMBER;
  2349   u2 max_lvtt_cnt = INITIAL_MAX_LVT_NUMBER;
  2349   u2 max_lvtt_cnt = INITIAL_MAX_LVT_NUMBER;
  2350   u2* localvariable_table_length = NULL;
  2350   u2* localvariable_table_length = NULL;
  2351   const void** localvariable_table_start = NULL; // (potentially unaligned) pointer to array of LVT attributes
  2351   const unsafe_u2** localvariable_table_start = NULL; // (potentially unaligned) pointer to array of LVT attributes
  2352   u2* localvariable_type_table_length = NULL;
  2352   u2* localvariable_type_table_length = NULL;
  2353   const void** localvariable_type_table_start = NULL; // (potentially unaligned) pointer to LVTT attributes
  2353   const unsafe_u2** localvariable_type_table_start = NULL; // (potentially unaligned) pointer to LVTT attributes
  2354   int method_parameters_length = -1;
  2354   int method_parameters_length = -1;
  2355   const u1* method_parameters_data = NULL;
  2355   const u1* method_parameters_data = NULL;
  2356   bool method_parameters_seen = false;
  2356   bool method_parameters_seen = false;
  2357   bool parsed_code_attribute = false;
  2357   bool parsed_code_attribute = false;
  2358   bool parsed_checked_exceptions_attribute = false;
  2358   bool parsed_checked_exceptions_attribute = false;
  2489           // Parse local variable table
  2489           // Parse local variable table
  2490           if (!lvt_allocated) {
  2490           if (!lvt_allocated) {
  2491             localvariable_table_length = NEW_RESOURCE_ARRAY_IN_THREAD(
  2491             localvariable_table_length = NEW_RESOURCE_ARRAY_IN_THREAD(
  2492               THREAD, u2,  INITIAL_MAX_LVT_NUMBER);
  2492               THREAD, u2,  INITIAL_MAX_LVT_NUMBER);
  2493             localvariable_table_start = NEW_RESOURCE_ARRAY_IN_THREAD(
  2493             localvariable_table_start = NEW_RESOURCE_ARRAY_IN_THREAD(
  2494               THREAD, const void*, INITIAL_MAX_LVT_NUMBER);
  2494               THREAD, const unsafe_u2*, INITIAL_MAX_LVT_NUMBER);
  2495             localvariable_type_table_length = NEW_RESOURCE_ARRAY_IN_THREAD(
  2495             localvariable_type_table_length = NEW_RESOURCE_ARRAY_IN_THREAD(
  2496               THREAD, u2,  INITIAL_MAX_LVT_NUMBER);
  2496               THREAD, u2,  INITIAL_MAX_LVT_NUMBER);
  2497             localvariable_type_table_start = NEW_RESOURCE_ARRAY_IN_THREAD(
  2497             localvariable_type_table_start = NEW_RESOURCE_ARRAY_IN_THREAD(
  2498               THREAD, const void*, INITIAL_MAX_LVT_NUMBER);
  2498               THREAD, const unsafe_u2*, INITIAL_MAX_LVT_NUMBER);
  2499             lvt_allocated = true;
  2499             lvt_allocated = true;
  2500           }
  2500           }
  2501           if (lvt_cnt == max_lvt_cnt) {
  2501           if (lvt_cnt == max_lvt_cnt) {
  2502             max_lvt_cnt <<= 1;
  2502             max_lvt_cnt <<= 1;
  2503             localvariable_table_length = REALLOC_RESOURCE_ARRAY(u2, localvariable_table_length, lvt_cnt, max_lvt_cnt);
  2503             localvariable_table_length = REALLOC_RESOURCE_ARRAY(u2, localvariable_table_length, lvt_cnt, max_lvt_cnt);
  2504             localvariable_table_start  = REALLOC_RESOURCE_ARRAY(const void*, localvariable_table_start, lvt_cnt, max_lvt_cnt);
  2504             localvariable_table_start  = REALLOC_RESOURCE_ARRAY(const unsafe_u2*, localvariable_table_start, lvt_cnt, max_lvt_cnt);
  2505           }
  2505           }
  2506           localvariable_table_start[lvt_cnt] =
  2506           localvariable_table_start[lvt_cnt] =
  2507             parse_localvariable_table(cfs,
  2507             parse_localvariable_table(cfs,
  2508                                       code_length,
  2508                                       code_length,
  2509                                       max_locals,
  2509                                       max_locals,
  2518                    cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_local_variable_type_table()) {
  2518                    cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_local_variable_type_table()) {
  2519           if (!lvt_allocated) {
  2519           if (!lvt_allocated) {
  2520             localvariable_table_length = NEW_RESOURCE_ARRAY_IN_THREAD(
  2520             localvariable_table_length = NEW_RESOURCE_ARRAY_IN_THREAD(
  2521               THREAD, u2,  INITIAL_MAX_LVT_NUMBER);
  2521               THREAD, u2,  INITIAL_MAX_LVT_NUMBER);
  2522             localvariable_table_start = NEW_RESOURCE_ARRAY_IN_THREAD(
  2522             localvariable_table_start = NEW_RESOURCE_ARRAY_IN_THREAD(
  2523               THREAD, const void*, INITIAL_MAX_LVT_NUMBER);
  2523               THREAD, const unsafe_u2*, INITIAL_MAX_LVT_NUMBER);
  2524             localvariable_type_table_length = NEW_RESOURCE_ARRAY_IN_THREAD(
  2524             localvariable_type_table_length = NEW_RESOURCE_ARRAY_IN_THREAD(
  2525               THREAD, u2,  INITIAL_MAX_LVT_NUMBER);
  2525               THREAD, u2,  INITIAL_MAX_LVT_NUMBER);
  2526             localvariable_type_table_start = NEW_RESOURCE_ARRAY_IN_THREAD(
  2526             localvariable_type_table_start = NEW_RESOURCE_ARRAY_IN_THREAD(
  2527               THREAD, const void*, INITIAL_MAX_LVT_NUMBER);
  2527               THREAD, const unsafe_u2*, INITIAL_MAX_LVT_NUMBER);
  2528             lvt_allocated = true;
  2528             lvt_allocated = true;
  2529           }
  2529           }
  2530           // Parse local variable type table
  2530           // Parse local variable type table
  2531           if (lvtt_cnt == max_lvtt_cnt) {
  2531           if (lvtt_cnt == max_lvtt_cnt) {
  2532             max_lvtt_cnt <<= 1;
  2532             max_lvtt_cnt <<= 1;
  2533             localvariable_type_table_length = REALLOC_RESOURCE_ARRAY(u2, localvariable_type_table_length, lvtt_cnt, max_lvtt_cnt);
  2533             localvariable_type_table_length = REALLOC_RESOURCE_ARRAY(u2, localvariable_type_table_length, lvtt_cnt, max_lvtt_cnt);
  2534             localvariable_type_table_start  = REALLOC_RESOURCE_ARRAY(const void*, localvariable_type_table_start, lvtt_cnt, max_lvtt_cnt);
  2534             localvariable_type_table_start  = REALLOC_RESOURCE_ARRAY(const unsafe_u2*, localvariable_type_table_start, lvtt_cnt, max_lvtt_cnt);
  2535           }
  2535           }
  2536           localvariable_type_table_start[lvtt_cnt] =
  2536           localvariable_type_table_start[lvtt_cnt] =
  2537             parse_localvariable_table(cfs,
  2537             parse_localvariable_table(cfs,
  2538                                       code_length,
  2538                                       code_length,
  2539                                       max_locals,
  2539                                       max_locals,