zoukankan      html  css  js  c++  java
  • jvm源码解读--06 Method 方法解析

    进入

        // Methods
        bool has_final_method = false;
        AccessFlags promoted_flags;
        promoted_flags.set_flags(0);
        Array<Method*>* methods = parse_methods(access_flags.is_interface(),
                                                &promoted_flags,
                                                &has_final_method,
                                                &has_default_methods,
                                                CHECK_(nullHandle));

    接着进入

    Array<Method*>* ClassFileParser::parse_methods(bool is_interface,
                                                   AccessFlags* promoted_flags,
                                                   bool* has_final_method,
                                                   bool* has_default_methods,
                                                   TRAPS) {
      ClassFileStream* cfs = stream();
      cfs->guarantee_more(2, CHECK_NULL);  // length
      u2 length = cfs->get_u2_fast();  //value=14 共14个方法
      if (length == 0) {
        _methods = Universe::the_empty_method_array();
      } else {
        _methods = MetadataFactory::new_array<Method*>(_loader_data, length, NULL, CHECK_NULL);//分配内存
    
        HandleMark hm(THREAD);
        for (int index = 0; index < length; index++) {   //进入循环,为每个一个方法进行解析
          methodHandle method = parse_method(is_interface,
                                             promoted_flags,
                                             CHECK_NULL);
    
          if (method->is_final()) {
            *has_final_method = true;
          }
          if (is_interface && !(*has_default_methods)
            && !method->is_abstract() && !method->is_static()
            && !method->is_private()) {
            // default method
            *has_default_methods = true;
          }
          _methods->at_put(index, method());
        }

    在进入

    methodHandle ClassFileParser::parse_method(bool is_interface,
                                               AccessFlags *promoted_flags,
                                               TRAPS) {
      ClassFileStream* cfs = stream();
      methodHandle nullHandle;
      ResourceMark rm(THREAD);
      // Parse fixed parts
      cfs->guarantee_more(8, CHECK_(nullHandle)); // access_flags, name_index, descriptor_index, attributes_count
    
      int flags = cfs->get_u2_fast();
      u2 name_index = cfs->get_u2_fast();
      int cp_size = _cp->length();
      check_property(
        valid_symbol_at(name_index),
        "Illegal constant pool index %u for method name in class file %s",
        name_index, CHECK_(nullHandle));
      Symbol*  name = _cp->symbol_at(name_index);
      verify_legal_method_name(name, CHECK_(nullHandle));
    
      u2 signature_index = cfs->get_u2_fast();
      guarantee_property(
        valid_symbol_at(signature_index),
        "Illegal constant pool index %u for method signature in class file %s",
        signature_index, CHECK_(nullHandle));
      Symbol*  signature = _cp->symbol_at(signature_index);
    
      AccessFlags access_flags;
      if (name == vmSymbols::class_initializer_name()) {
        // We ignore the other access flags for a valid class initializer.
        // (JVM Spec 2nd ed., chapter 4.6)
        if (_major_version < 51) { // backward compatibility
          flags = JVM_ACC_STATIC;
        } else if ((flags & JVM_ACC_STATIC) == JVM_ACC_STATIC) {
          flags &= JVM_ACC_STATIC | JVM_ACC_STRICT;
        }
      } else {
        verify_legal_method_modifiers(flags, is_interface, name, CHECK_(nullHandle));
      }
    
      int args_size = -1;  // only used when _need_verify is true
      if (_need_verify) {
        args_size = ((flags & JVM_ACC_STATIC) ? 0 : 1) +
                     verify_legal_method_signature(name, signature, CHECK_(nullHandle));
        if (args_size > MAX_ARGS_SIZE) {
          classfile_parse_error("Too many arguments in method signature in class file %s", CHECK_(nullHandle));
        }
      }
    
      access_flags.set_flags(flags & JVM_RECOGNIZED_METHOD_MODIFIERS);
    
      // Default values for code and exceptions attribute elements
      u2 max_stack = 0;
      u2 max_locals = 0;
      u4 code_length = 0;
      u1* code_start = 0;
      u2 exception_table_length = 0;
      u2* exception_table_start = NULL;
      Array<int>* exception_handlers = Universe::the_empty_int_array();
      u2 checked_exceptions_length = 0;
      u2* checked_exceptions_start = NULL;
      CompressedLineNumberWriteStream* linenumber_table = NULL;
      int linenumber_table_length = 0;
      int total_lvt_length = 0;
      u2 lvt_cnt = 0;
      u2 lvtt_cnt = 0;
      bool lvt_allocated = false;
      u2 max_lvt_cnt = INITIAL_MAX_LVT_NUMBER;
      u2 max_lvtt_cnt = INITIAL_MAX_LVT_NUMBER;
      u2* localvariable_table_length;
      u2** localvariable_table_start;
      u2* localvariable_type_table_length;
      u2** localvariable_type_table_start;
      u2 method_parameters_length = 0;
      u1* method_parameters_data = NULL;
      bool method_parameters_seen = false;
      bool parsed_code_attribute = false;
      bool parsed_checked_exceptions_attribute = false;
      bool parsed_stackmap_attribute = false;
      // stackmap attribute - JDK1.5
      u1* stackmap_data = NULL;
      int stackmap_data_length = 0;
      u2 generic_signature_index = 0;
      MethodAnnotationCollector parsed_annotations;
      u1* runtime_visible_annotations = NULL;
      int runtime_visible_annotations_length = 0;
      u1* runtime_invisible_annotations = NULL;
      int runtime_invisible_annotations_length = 0;
      u1* runtime_visible_parameter_annotations = NULL;
      int runtime_visible_parameter_annotations_length = 0;
      u1* runtime_invisible_parameter_annotations = NULL;
      int runtime_invisible_parameter_annotations_length = 0;
      u1* runtime_visible_type_annotations = NULL;
      int runtime_visible_type_annotations_length = 0;
      u1* runtime_invisible_type_annotations = NULL;
      int runtime_invisible_type_annotations_length = 0;
      bool runtime_invisible_type_annotations_exists = false;
      u1* annotation_default = NULL;
      int annotation_default_length = 0;
    
      // Parse code and exceptions attribute
      u2 method_attributes_count = cfs->get_u2_fast();
      while (method_attributes_count--) {
        cfs->guarantee_more(6, CHECK_(nullHandle));  // method_attribute_name_index, method_attribute_length
        u2 method_attribute_name_index = cfs->get_u2_fast();
        u4 method_attribute_length = cfs->get_u4_fast();
        check_property(
          valid_symbol_at(method_attribute_name_index),
          "Invalid method attribute name index %u in class file %s",
          method_attribute_name_index, CHECK_(nullHandle));
    
        Symbol* method_attribute_name = _cp->symbol_at(method_attribute_name_index);
        if (method_attribute_name == vmSymbols::tag_code()) {
          // Parse Code attribute
          if (_need_verify) {
            guarantee_property(
                !access_flags.is_native() && !access_flags.is_abstract(),
                            "Code attribute in native or abstract methods in class file %s",
                             CHECK_(nullHandle));
          }
          if (parsed_code_attribute) {
            classfile_parse_error("Multiple Code attributes in class file %s", CHECK_(nullHandle));
          }
          parsed_code_attribute = true;
    
          // Stack size, locals size, and code size
          if (_major_version == 45 && _minor_version <= 2) {
            cfs->guarantee_more(4, CHECK_(nullHandle));
            max_stack = cfs->get_u1_fast();
            max_locals = cfs->get_u1_fast();
            code_length = cfs->get_u2_fast();
          } else {
            cfs->guarantee_more(8, CHECK_(nullHandle));
            max_stack = cfs->get_u2_fast();
            max_locals = cfs->get_u2_fast();
            code_length = cfs->get_u4_fast();
          }
          if (_need_verify) {
            guarantee_property(args_size <= max_locals,
                               "Arguments can't fit into locals in class file %s", CHECK_(nullHandle));
            guarantee_property(code_length > 0 && code_length <= MAX_CODE_SIZE,
                               "Invalid method Code length %u in class file %s",
                               code_length, CHECK_(nullHandle));
          }
          // Code pointer
          code_start = cfs->get_u1_buffer();
          assert(code_start != NULL, "null code start");
          cfs->guarantee_more(code_length, CHECK_(nullHandle));
          cfs->skip_u1_fast(code_length);
    
          // Exception handler table
          cfs->guarantee_more(2, CHECK_(nullHandle));  // exception_table_length
          exception_table_length = cfs->get_u2_fast();
          if (exception_table_length > 0) {
            exception_table_start =
                  parse_exception_table(code_length, exception_table_length, CHECK_(nullHandle));
          }
    
          // Parse additional attributes in code attribute
          cfs->guarantee_more(2, CHECK_(nullHandle));  // code_attributes_count
          u2 code_attributes_count = cfs->get_u2_fast();
    
          unsigned int calculated_attribute_length = 0;
    
          if (_major_version > 45 || (_major_version == 45 && _minor_version > 2)) {
            calculated_attribute_length =
                sizeof(max_stack) + sizeof(max_locals) + sizeof(code_length);
          } else {
            // max_stack, locals and length are smaller in pre-version 45.2 classes
            calculated_attribute_length = sizeof(u1) + sizeof(u1) + sizeof(u2);
          }
          calculated_attribute_length +=
            code_length +
            sizeof(exception_table_length) +
            sizeof(code_attributes_count) +
            exception_table_length *
                ( sizeof(u2) +   // start_pc
                  sizeof(u2) +   // end_pc
                  sizeof(u2) +   // handler_pc
                  sizeof(u2) );  // catch_type_index
    
          while (code_attributes_count--) {
            cfs->guarantee_more(6, CHECK_(nullHandle));  // code_attribute_name_index, code_attribute_length
            u2 code_attribute_name_index = cfs->get_u2_fast();
            u4 code_attribute_length = cfs->get_u4_fast();
            calculated_attribute_length += code_attribute_length +
                                           sizeof(code_attribute_name_index) +
                                           sizeof(code_attribute_length);
            check_property(valid_symbol_at(code_attribute_name_index),
                           "Invalid code attribute name index %u in class file %s",
                           code_attribute_name_index,
                           CHECK_(nullHandle));
            if (LoadLineNumberTables &&
                _cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_line_number_table()) {
              // Parse and compress line number table
              parse_linenumber_table(code_attribute_length, code_length,
                &linenumber_table, CHECK_(nullHandle));
    
            } else if (LoadLocalVariableTables &&
                       _cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_local_variable_table()) {
              // Parse local variable table
              if (!lvt_allocated) {
                localvariable_table_length = NEW_RESOURCE_ARRAY_IN_THREAD(
                  THREAD, u2,  INITIAL_MAX_LVT_NUMBER);
                localvariable_table_start = NEW_RESOURCE_ARRAY_IN_THREAD(
                  THREAD, u2*, INITIAL_MAX_LVT_NUMBER);
                localvariable_type_table_length = NEW_RESOURCE_ARRAY_IN_THREAD(
                  THREAD, u2,  INITIAL_MAX_LVT_NUMBER);
                localvariable_type_table_start = NEW_RESOURCE_ARRAY_IN_THREAD(
                  THREAD, u2*, INITIAL_MAX_LVT_NUMBER);
                lvt_allocated = true;
              }
              if (lvt_cnt == max_lvt_cnt) {
                max_lvt_cnt <<= 1;
                localvariable_table_length = REALLOC_RESOURCE_ARRAY(u2, localvariable_table_length, lvt_cnt, max_lvt_cnt);
                localvariable_table_start  = REALLOC_RESOURCE_ARRAY(u2*, localvariable_table_start, lvt_cnt, max_lvt_cnt);
              }
              localvariable_table_start[lvt_cnt] =
                parse_localvariable_table(code_length,
                                          max_locals,
                                          code_attribute_length,
                                          &localvariable_table_length[lvt_cnt],
                                          false,    // is not LVTT
                                          CHECK_(nullHandle));
              total_lvt_length += localvariable_table_length[lvt_cnt];
              lvt_cnt++;
            } else if (LoadLocalVariableTypeTables &&
                       _major_version >= JAVA_1_5_VERSION &&
                       _cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_local_variable_type_table()) {
              if (!lvt_allocated) {
                localvariable_table_length = NEW_RESOURCE_ARRAY_IN_THREAD(
                  THREAD, u2,  INITIAL_MAX_LVT_NUMBER);
                localvariable_table_start = NEW_RESOURCE_ARRAY_IN_THREAD(
                  THREAD, u2*, INITIAL_MAX_LVT_NUMBER);
                localvariable_type_table_length = NEW_RESOURCE_ARRAY_IN_THREAD(
                  THREAD, u2,  INITIAL_MAX_LVT_NUMBER);
                localvariable_type_table_start = NEW_RESOURCE_ARRAY_IN_THREAD(
                  THREAD, u2*, INITIAL_MAX_LVT_NUMBER);
                lvt_allocated = true;
              }
              // Parse local variable type table
              if (lvtt_cnt == max_lvtt_cnt) {
                max_lvtt_cnt <<= 1;
                localvariable_type_table_length = REALLOC_RESOURCE_ARRAY(u2, localvariable_type_table_length, lvtt_cnt, max_lvtt_cnt);
                localvariable_type_table_start  = REALLOC_RESOURCE_ARRAY(u2*, localvariable_type_table_start, lvtt_cnt, max_lvtt_cnt);
              }
              localvariable_type_table_start[lvtt_cnt] =
                parse_localvariable_table(code_length,
                                          max_locals,
                                          code_attribute_length,
                                          &localvariable_type_table_length[lvtt_cnt],
                                          true,     // is LVTT
                                          CHECK_(nullHandle));
              lvtt_cnt++;
            } else if (_major_version >= Verifier::STACKMAP_ATTRIBUTE_MAJOR_VERSION &&
                       _cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_stack_map_table()) {
              // Stack map is only needed by the new verifier in JDK1.5.
              if (parsed_stackmap_attribute) {
                classfile_parse_error("Multiple StackMapTable attributes in class file %s", CHECK_(nullHandle));
              }
              stackmap_data = parse_stackmap_table(code_attribute_length, CHECK_(nullHandle));
              stackmap_data_length = code_attribute_length;
              parsed_stackmap_attribute = true;
            } else {
              // Skip unknown attributes
              cfs->skip_u1(code_attribute_length, CHECK_(nullHandle));
            }
          }
          // check method attribute length
          if (_need_verify) {
            guarantee_property(method_attribute_length == calculated_attribute_length,
                               "Code segment has wrong length in class file %s", CHECK_(nullHandle));
          }
        } else if (method_attribute_name == vmSymbols::tag_exceptions()) {
          // Parse Exceptions attribute
          if (parsed_checked_exceptions_attribute) {
            classfile_parse_error("Multiple Exceptions attributes in class file %s", CHECK_(nullHandle));
          }
          parsed_checked_exceptions_attribute = true;
          checked_exceptions_start =
                parse_checked_exceptions(&checked_exceptions_length,
                                         method_attribute_length,
                                         CHECK_(nullHandle));
        } else if (method_attribute_name == vmSymbols::tag_method_parameters()) {
          // reject multiple method parameters
          if (method_parameters_seen) {
            classfile_parse_error("Multiple MethodParameters attributes in class file %s", CHECK_(nullHandle));
          }
          method_parameters_seen = true;
          method_parameters_length = cfs->get_u1_fast();
          if (method_attribute_length != (method_parameters_length * 4u) + 1u) {
            classfile_parse_error(
              "Invalid MethodParameters method attribute length %u in class file",
              method_attribute_length, CHECK_(nullHandle));
          }
          method_parameters_data = cfs->get_u1_buffer();
          cfs->skip_u2_fast(method_parameters_length);
          cfs->skip_u2_fast(method_parameters_length);
          // ignore this attribute if it cannot be reflected
          if (!SystemDictionary::Parameter_klass_loaded())
            method_parameters_length = 0;
        } else if (method_attribute_name == vmSymbols::tag_synthetic()) {
          if (method_attribute_length != 0) {
            classfile_parse_error(
              "Invalid Synthetic method attribute length %u in class file %s",
              method_attribute_length, CHECK_(nullHandle));
          }
          // Should we check that there hasn't already been a synthetic attribute?
          access_flags.set_is_synthetic();
        } else if (method_attribute_name == vmSymbols::tag_deprecated()) { // 4276120
          if (method_attribute_length != 0) {
            classfile_parse_error(
              "Invalid Deprecated method attribute length %u in class file %s",
              method_attribute_length, CHECK_(nullHandle));
          }
        } else if (_major_version >= JAVA_1_5_VERSION) {
          if (method_attribute_name == vmSymbols::tag_signature()) {
            if (method_attribute_length != 2) {
              classfile_parse_error(
                "Invalid Signature attribute length %u in class file %s",
                method_attribute_length, CHECK_(nullHandle));
            }
            cfs->guarantee_more(2, CHECK_(nullHandle));  // generic_signature_index
            generic_signature_index = cfs->get_u2_fast();
          } else if (method_attribute_name == vmSymbols::tag_runtime_visible_annotations()) {
            runtime_visible_annotations_length = method_attribute_length;
            runtime_visible_annotations = cfs->get_u1_buffer();
            assert(runtime_visible_annotations != NULL, "null visible annotations");
            parse_annotations(runtime_visible_annotations,
                runtime_visible_annotations_length, &parsed_annotations,
                CHECK_(nullHandle));
            cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle));
          } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
            runtime_invisible_annotations_length = method_attribute_length;
            runtime_invisible_annotations = cfs->get_u1_buffer();
            assert(runtime_invisible_annotations != NULL, "null invisible annotations");
            cfs->skip_u1(runtime_invisible_annotations_length, CHECK_(nullHandle));
          } else if (method_attribute_name == vmSymbols::tag_runtime_visible_parameter_annotations()) {
            runtime_visible_parameter_annotations_length = method_attribute_length;
            runtime_visible_parameter_annotations = cfs->get_u1_buffer();
            assert(runtime_visible_parameter_annotations != NULL, "null visible parameter annotations");
            cfs->skip_u1(runtime_visible_parameter_annotations_length, CHECK_(nullHandle));
          } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_parameter_annotations()) {
            runtime_invisible_parameter_annotations_length = method_attribute_length;
            runtime_invisible_parameter_annotations = cfs->get_u1_buffer();
            assert(runtime_invisible_parameter_annotations != NULL, "null invisible parameter annotations");
            cfs->skip_u1(runtime_invisible_parameter_annotations_length, CHECK_(nullHandle));
          } else if (method_attribute_name == vmSymbols::tag_annotation_default()) {
            annotation_default_length = method_attribute_length;
            annotation_default = cfs->get_u1_buffer();
            assert(annotation_default != NULL, "null annotation default");
            cfs->skip_u1(annotation_default_length, CHECK_(nullHandle));
          } else if (method_attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) {
            if (runtime_visible_type_annotations != NULL) {
              classfile_parse_error(
                "Multiple RuntimeVisibleTypeAnnotations attributes for method in class file %s",
                CHECK_(nullHandle));
            }
            runtime_visible_type_annotations_length = method_attribute_length;
            runtime_visible_type_annotations = cfs->get_u1_buffer();
            assert(runtime_visible_type_annotations != NULL, "null visible type annotations");
            // No need for the VM to parse Type annotations
            cfs->skip_u1(runtime_visible_type_annotations_length, CHECK_(nullHandle));
          } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) {
            if (runtime_invisible_type_annotations_exists) {
              classfile_parse_error(
                "Multiple RuntimeInvisibleTypeAnnotations attributes for method in class file %s",
                CHECK_(nullHandle));
            } else {
              runtime_invisible_type_annotations_exists = true;
            }
            if (PreserveAllAnnotations) {
              runtime_invisible_type_annotations_length = method_attribute_length;
              runtime_invisible_type_annotations = cfs->get_u1_buffer();
              assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations");
            }
            cfs->skip_u1(method_attribute_length, CHECK_(nullHandle));
          } else {
            // Skip unknown attributes
            cfs->skip_u1(method_attribute_length, CHECK_(nullHandle));
          }
        } else {
          // Skip unknown attributes
          cfs->skip_u1(method_attribute_length, CHECK_(nullHandle));
        }
      }
    
      if (linenumber_table != NULL) {
        linenumber_table->write_terminator();
        linenumber_table_length = linenumber_table->position();
      }
    
      // Make sure there's at least one Code attribute in non-native/non-abstract method
      if (_need_verify) {
        guarantee_property(access_flags.is_native() || access_flags.is_abstract() || parsed_code_attribute,
                          "Absent Code attribute in method that is not native or abstract in class file %s", CHECK_(nullHandle));
      }
    
      // All sizing information for a Method* is finally available, now create it
      InlineTableSizes sizes(
          total_lvt_length,
          linenumber_table_length,
          exception_table_length,
          checked_exceptions_length,
          method_parameters_length,
          generic_signature_index,
          runtime_visible_annotations_length +
               runtime_invisible_annotations_length,
          runtime_visible_parameter_annotations_length +
               runtime_invisible_parameter_annotations_length,
          runtime_visible_type_annotations_length +
               runtime_invisible_type_annotations_length,
          annotation_default_length,
          0);
    
      Method* m = Method::allocate(
          _loader_data, code_length, access_flags, &sizes,
          ConstMethod::NORMAL, CHECK_(nullHandle));
    
      ClassLoadingService::add_class_method_size(m->size()*HeapWordSize);
    
      // Fill in information from fixed part (access_flags already set)
      m->set_constants(_cp);
      m->set_name_index(name_index);
      m->set_signature_index(signature_index);
    #ifdef CC_INTERP
      // hmm is there a gc issue here??
      ResultTypeFinder rtf(_cp->symbol_at(signature_index));
      m->set_result_index(rtf.type());
    #endif
    
      if (args_size >= 0) {
        m->set_size_of_parameters(args_size);
      } else {
        m->compute_size_of_parameters(THREAD);
      }
    #ifdef ASSERT
      if (args_size >= 0) {
        m->compute_size_of_parameters(THREAD);
        assert(args_size == m->size_of_parameters(), "");
      }
    #endif
    
      // Fill in code attribute information
      m->set_max_stack(max_stack);
      m->set_max_locals(max_locals);
      if (stackmap_data != NULL) {
        m->constMethod()->copy_stackmap_data(_loader_data, stackmap_data,
                                             stackmap_data_length, CHECK_NULL);
      }
    
      // Copy byte codes
      m->set_code(code_start);
    
      // Copy line number table
      if (linenumber_table != NULL) {
        memcpy(m->compressed_linenumber_table(),
               linenumber_table->buffer(), linenumber_table_length);
      }
    
      // Copy exception table
      if (exception_table_length > 0) {
        int size =
          exception_table_length * sizeof(ExceptionTableElement) / sizeof(u2);
        copy_u2_with_conversion((u2*) m->exception_table_start(),
                                 exception_table_start, size);
      }
    
      // Copy method parameters
      if (method_parameters_length > 0) {
        MethodParametersElement* elem = m->constMethod()->method_parameters_start();
        for (int i = 0; i < method_parameters_length; i++) {
          elem[i].name_cp_index = Bytes::get_Java_u2(method_parameters_data);
          method_parameters_data += 2;
          elem[i].flags = Bytes::get_Java_u2(method_parameters_data);
          method_parameters_data += 2;
        }
      }
    
      // Copy checked exceptions
      if (checked_exceptions_length > 0) {
        int size = checked_exceptions_length * sizeof(CheckedExceptionElement) / sizeof(u2);
        copy_u2_with_conversion((u2*) m->checked_exceptions_start(), checked_exceptions_start, size);
      }
    
      // Copy class file LVT's/LVTT's into the HotSpot internal LVT.
      if (total_lvt_length > 0) {
        promoted_flags->set_has_localvariable_table();
        copy_localvariable_table(m->constMethod(), lvt_cnt,
                                 localvariable_table_length,
                                 localvariable_table_start,
                                 lvtt_cnt,
                                 localvariable_type_table_length,
                                 localvariable_type_table_start, CHECK_NULL);
      }
    
      if (parsed_annotations.has_any_annotations())
        parsed_annotations.apply_to(m);
    
      // Copy annotations
      copy_method_annotations(m->constMethod(),
                              runtime_visible_annotations,
                              runtime_visible_annotations_length,
                              runtime_invisible_annotations,
                              runtime_invisible_annotations_length,
                              runtime_visible_parameter_annotations,
                              runtime_visible_parameter_annotations_length,
                              runtime_invisible_parameter_annotations,
                              runtime_invisible_parameter_annotations_length,
                              runtime_visible_type_annotations,
                              runtime_visible_type_annotations_length,
                              runtime_invisible_type_annotations,
                              runtime_invisible_type_annotations_length,
                              annotation_default,
                              annotation_default_length,
                              CHECK_NULL);
    
      if (name == vmSymbols::finalize_method_name() &&
          signature == vmSymbols::void_method_signature()) {
        if (m->is_empty_method()) {
          _has_empty_finalizer = true;
        } else {
          _has_finalizer = true;
        }
      }
      if (name == vmSymbols::object_initializer_name() &&
          signature == vmSymbols::void_method_signature() &&
          m->is_vanilla_constructor()) {
        _has_vanilla_constructor = true;
      }
    
      NOT_PRODUCT(m->verify());
      return m;
    }
    //方法解析之前先看下,结构
    ClassFile {
        ...
        u2 methods_count;
        method_info methods[methods_count];
    };
    
    method_info {
        u2 access_flags;
        u2 name_index;
        u2 descriptor_index;
        u2 attributes_count;
        attribute_info attributes[attributes_count];
    };
    attribute_info {
        u2 attribute_name_index;
        u4 attribute_length;
        u1 info[attribute_length];
    }
    //查询出来的Symbol是Code,则看Code的定义
    4.7.3 The Code Attribute
            The Code attribute has the following format:
    Code_attribute {
        u2 attribute_name_index;
        u4 attribute_length;
        u2 max_stack;
        u2 max_locals;
        u4 code_length;
        u1 code[code_length];
        u2 exception_table_length;
        {   u2 start_pc;
            u2 end_pc;
            u2 handler_pc;
            u2 catch_type;
        } exception_table[exception_table_length];
        u2 attributes_count;
        attribute_info attributes[attributes_count];
    }

    进入这个长长的方法之后,我们逐条解析

    int flags = cfs->get_u2_fast();  //flag=1
    u2 name_index = cfs->get_u2_fast(); //name_index 19
    int cp_size = _cp->length();  //cp_size=87
    
    Symbol*  name = _cp->symbol_at(name_index);  //(gdb) p name->as_C_string() $1 = 0x7fb9b000f138 "<init>"
    
    u2 signature_index = cfs->get_u2_fast(); //value=20
    
    Symbol*  signature = _cp->symbol_at(signature_index); //$2 = 0x7fb9b000f148 "()V"

    接着

      AccessFlags access_flags;
      if (name == vmSymbols::class_initializer_name()) {
        // We ignore the other access flags for a valid class initializer.
        // (JVM Spec 2nd ed., chapter 4.6)
        if (_major_version < 51) { // backward compatibility
          flags = JVM_ACC_STATIC;
        } else if ((flags & JVM_ACC_STATIC) == JVM_ACC_STATIC) {
          flags &= JVM_ACC_STATIC | JVM_ACC_STRICT;
        }
      } else {
        verify_legal_method_modifiers(flags, is_interface, name, CHECK_(nullHandle));
      }

    对标记的进行解析,由于这个是一个宏

    VM_SYMBOLS_DO(VM_SYMBOL_DECLARE, VM_SYMBOL_DECLARE)
    
    VM_SYMBOL_DECLARE(object_initializer_name,                   "<init>")
    
    #define VM_SYMBOL_DECLARE(name, ignore)                 
        static Symbol* name() {                               
          return _symbols[VM_SYMBOL_ENUM_NAME(name)];         
        }
    #define VM_SYMBOL_ENUM_NAME(name)    name##_enum     //注意##为链接符号
    
        static Symbol* object_initializer_name() {
        return _symbols[object_initializer_name_enum];
        }
    
    解析后
    enum SID {
        NO_SID = 0,
    
    /* commonly used class names */
        java_lang_System_enum,
        java_lang_Object_enum,
        java_lang_Class_enum,
        java_lang_String_enum,
        java_lang_StringValue_enum,
        java_lang_StringCache_enum,
        java_lang_Thread_enum,
        java_lang_ThreadGroup_enum,
        java_lang_Cloneable_enum,
        java_lang_Throwable_enum,
        java_lang_ClassLoader_enum,
        java_lang_ClassLoader_NativeLibrary_enum,
        java_lang_ThreadDeath_enum,
        java_lang_Boolean_enum,
        java_lang_Character_enum,
        java_lang_Character_CharacterCache_enum,
        java_lang_Float_enum,
        java_lang_Double_enum,
        java_lang_Byte_enum,
        java_lang_Byte_Cache_enum,
        java_lang_Short_enum,
        java_lang_Short_ShortCache_enum,
        java_lang_Integer_enum,
        java_lang_Integer_IntegerCache_enum,
        java_lang_Long_enum,
        java_lang_Long_LongCache_enum,
        java_lang_Shutdown_enum,
        java_lang_ref_Reference_enum,
        java_lang_ref_SoftReference_enum,
        java_lang_ref_WeakReference_enum,
        java_lang_ref_FinalReference_enum,
        java_lang_ref_PhantomReference_enum,
        sun_misc_Cleaner_enum,
        java_lang_ref_Finalizer_enum,
        java_lang_reflect_AccessibleObject_enum,
        java_lang_reflect_Method_enum,
        java_lang_reflect_Constructor_enum,
        java_lang_reflect_Field_enum,
        java_lang_reflect_Array_enum,
        java_lang_StringBuffer_enum,
        java_lang_StringBuilder_enum,
        java_lang_CharSequence_enum,
        java_security_AccessControlContext_enum,
        java_security_ProtectionDomain_enum,
        impliesCreateAccessControlContext_name_enum,
        java_io_OutputStream_enum,
        java_io_Reader_enum,
        java_io_BufferedReader_enum,
        java_io_FileInputStream_enum,
        java_io_ByteArrayInputStream_enum,
        java_io_Serializable_enum,
        java_util_Arrays_enum,
        java_util_Properties_enum,
        java_util_Vector_enum,
        java_util_AbstractList_enum,
        java_util_Hashtable_enum,
        java_util_HashMap_enum,
        java_lang_Compiler_enum,
        sun_misc_Signal_enum,
        java_lang_AssertionStatusDirectives_enum,
        sun_jkernel_DownloadManager_enum,
        getBootClassPathEntryForClass_name_enum,
        sun_misc_PostVMInitHook_enum,
    
    /* class file format tags */
        tag_source_file_enum,
        tag_inner_classes_enum,
        tag_constant_value_enum,
        tag_code_enum,
        tag_exceptions_enum,
        tag_line_number_table_enum,
        tag_local_variable_table_enum,
        tag_local_variable_type_table_enum,
        tag_stack_map_table_enum,
        tag_synthetic_enum,
        tag_deprecated_enum,
        tag_source_debug_extension_enum,
        tag_signature_enum,
        tag_runtime_visible_annotations_enum,
        tag_runtime_invisible_annotations_enum,
        tag_runtime_visible_parameter_annotations_enum,
        tag_runtime_invisible_parameter_annotations_enum,
        tag_annotation_default_enum,
        tag_enclosing_method_enum,
        tag_bootstrap_methods_enum,
    
    /* exception klasses: at least all exceptions thrown by the VM have entries here */
        java_lang_ArithmeticException_enum,
        java_lang_ArrayIndexOutOfBoundsException_enum,
        java_lang_ArrayStoreException_enum,
        java_lang_ClassCastException_enum,
        java_lang_ClassNotFoundException_enum,
        java_lang_CloneNotSupportedException_enum,
        java_lang_IllegalAccessException_enum,
        java_lang_IllegalArgumentException_enum,
        java_lang_IllegalStateException_enum,
        java_lang_IllegalMonitorStateException_enum,
        java_lang_IllegalThreadStateException_enum,
        java_lang_IndexOutOfBoundsException_enum,
        java_lang_InstantiationException_enum,
        java_lang_InstantiationError_enum,
        java_lang_InterruptedException_enum,
        java_lang_BootstrapMethodError_enum,
        java_lang_LinkageError_enum,
        java_lang_NegativeArraySizeException_enum,
        java_lang_NoSuchFieldException_enum,
        java_lang_NoSuchMethodException_enum,
        java_lang_NullPointerException_enum,
        java_lang_StringIndexOutOfBoundsException_enum,
        java_lang_InvalidClassException_enum,
        java_lang_reflect_InvocationTargetException_enum,
        java_lang_Exception_enum,
        java_lang_RuntimeException_enum,
        java_io_IOException_enum,
        java_security_PrivilegedActionException_enum,
    
    /* error klasses: at least all errors thrown by the VM have entries here */
        java_lang_AbstractMethodError_enum,
        java_lang_ClassCircularityError_enum,
        java_lang_ClassFormatError_enum,
        java_lang_UnsupportedClassVersionError_enum,
        java_lang_Error_enum,
        java_lang_ExceptionInInitializerError_enum,
        java_lang_IllegalAccessError_enum,
        java_lang_IncompatibleClassChangeError_enum,
        java_lang_InternalError_enum,
        java_lang_NoClassDefFoundError_enum,
        java_lang_NoSuchFieldError_enum,
        java_lang_NoSuchMethodError_enum,
        java_lang_OutOfMemoryError_enum,
        java_lang_UnsatisfiedLinkError_enum,
        java_lang_VerifyError_enum,
        java_lang_SecurityException_enum,
        java_lang_VirtualMachineError_enum,
        java_lang_StackOverflowError_enum,
        java_lang_StackTraceElement_enum,
        java_util_concurrent_locks_AbstractOwnableSynchronizer_enum,
    
    
        sun_reflect_FieldInfo_enum,
        sun_reflect_MethodInfo_enum,
        sun_reflect_MagicAccessorImpl_enum,
        sun_reflect_MethodAccessorImpl_enum,
        sun_reflect_ConstructorAccessorImpl_enum,
        sun_reflect_SerializationConstructorAccessorImpl_enum,
        sun_reflect_DelegatingClassLoader_enum,
        sun_reflect_Reflection_enum,
        checkedExceptions_name_enum,
        clazz_name_enum,
        exceptionTypes_name_enum,
        modifiers_name_enum,
        newConstructor_name_enum,
        newConstructor_signature_enum,
        newField_name_enum,
        newField_signature_enum,
        newMethod_name_enum,
        newMethod_signature_enum,
    /* the following two names must be in order: */
        invokeExact_name_enum,
        invokeGeneric_name_enum,
        invokeVarargs_name_enum,
        star_name_enum, /*not really a name*/
        invoke_name_enum,
        override_name_enum,
        parameterTypes_name_enum,
        returnType_name_enum,
        signature_name_enum,
        slot_name_enum,
        selectAlternative_name_enum,
    
    /* Support for annotations (JDK 1.5 and above) */
    
        annotations_name_enum,
        parameter_annotations_name_enum,
        annotation_default_name_enum,
        sun_reflect_ConstantPool_enum,
        constantPoolOop_name_enum,
        sun_reflect_UnsafeStaticFieldAccessorImpl_enum,
        base_name_enum,
    
    /* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */
        java_lang_invoke_InvokeDynamic_enum,
        java_lang_invoke_Linkage_enum,
        java_lang_invoke_CallSite_enum,
        java_lang_invoke_ConstantCallSite_enum,
        java_lang_invoke_MutableCallSite_enum,
        java_lang_invoke_VolatileCallSite_enum,
        java_lang_invoke_MethodHandle_enum,
        java_lang_invoke_MethodType_enum,
        java_lang_invoke_WrongMethodTypeException_enum,
        java_lang_invoke_MethodType_signature_enum,
        java_lang_invoke_MethodHandle_signature_enum,
    /* internal classes known only to the JVM: */
        java_lang_invoke_MethodTypeForm_enum,
        java_lang_invoke_MethodTypeForm_signature_enum,
        java_lang_invoke_MemberName_enum,
        java_lang_invoke_MethodHandleNatives_enum,
        java_lang_invoke_MethodHandleImpl_enum,
        java_lang_invoke_AdapterMethodHandle_enum,
        java_lang_invoke_BoundMethodHandle_enum,
        java_lang_invoke_DirectMethodHandle_enum,
        java_lang_invoke_CountingMethodHandle_enum,
    /* internal up-calls made only by the JVM, via class sun.invoke.MethodHandleNatives: */
        findMethodHandleType_name_enum,
        findMethodHandleType_signature_enum,
        notifyGenericMethodType_name_enum,
        notifyGenericMethodType_signature_enum,
        linkMethodHandleConstant_name_enum,
        linkMethodHandleConstant_signature_enum,
        makeDynamicCallSite_name_enum,
        makeDynamicCallSite_signature_enum,
        setTargetNormal_name_enum,
        setTargetVolatile_name_enum,
        setTarget_signature_enum,
    
        selectAlternative_signature_enum,
    
    /* common method and field names */
        object_initializer_name_enum,
        class_initializer_name_enum,
        println_name_enum,
        printStackTrace_name_enum,
        main_name_enum,
        name_name_enum,
        priority_name_enum,
        stillborn_name_enum,
        group_name_enum,
        daemon_name_enum,
        eetop_name_enum,
        thread_status_name_enum,
        run_method_name_enum,
        exit_method_name_enum,
        add_method_name_enum,
        remove_method_name_enum,
        parent_name_enum,
        threads_name_enum,
        groups_name_enum,
        maxPriority_name_enum,
        destroyed_name_enum,
        vmAllowSuspension_name_enum,
        nthreads_name_enum,
        ngroups_name_enum,
        shutdown_method_name_enum,
        finalize_method_name_enum,
        reference_lock_name_enum,
        reference_discovered_name_enum,
        run_finalization_name_enum,
        run_finalizers_on_exit_name_enum,
        uncaughtException_name_enum,
        dispatchUncaughtException_name_enum,
        initializeSystemClass_name_enum,
        loadClass_name_enum,
        loadClassInternal_name_enum,
        get_name_enum,
        put_name_enum,
        type_name_enum,
        findNative_name_enum,
        deadChild_name_enum,
        addClass_name_enum,
        getFromClass_name_enum,
        dispatch_name_enum,
        getSystemClassLoader_name_enum,
        fillInStackTrace_name_enum,
        fillInStackTrace0_name_enum,
        getCause_name_enum,
        initCause_name_enum,
        setProperty_name_enum,
        getProperty_name_enum,
        context_name_enum,
        privilegedContext_name_enum,
        contextClassLoader_name_enum,
        inheritedAccessControlContext_name_enum,
        isPrivileged_name_enum,
        isAuthorized_name_enum,
        wait_name_enum,
        checkPackageAccess_name_enum,
        stackSize_name_enum,
        thread_id_name_enum,
        newInstance0_name_enum,
        limit_name_enum,
        forName_name_enum,
        forName0_name_enum,
        isJavaIdentifierStart_name_enum,
        isJavaIdentifierPart_name_enum,
        exclusive_owner_thread_name_enum,
        park_blocker_name_enum,
        park_event_name_enum,
        cache_field_name_enum,
        value_name_enum,
        offset_name_enum,
        count_name_enum,
        hash_name_enum,
        frontCacheEnabled_name_enum,
        stringCacheEnabled_name_enum,
        numberOfLeadingZeros_name_enum,
        numberOfTrailingZeros_name_enum,
        bitCount_name_enum,
        profile_name_enum,
        equals_name_enum,
        target_name_enum,
        toString_name_enum,
        values_name_enum,
        receiver_name_enum,
        vmmethod_name_enum,
        vmtarget_name_enum,
        vmentry_name_enum,
        vmcount_name_enum,
        vmslots_name_enum,
        vmlayout_name_enum,
        vmindex_name_enum,
        vmargslot_name_enum,
        flags_name_enum,
        argument_name_enum,
        conversion_name_enum,
        rtype_name_enum,
        ptypes_name_enum,
        form_name_enum,
        erasedType_name_enum,
        genericInvoker_name_enum,
        append_name_enum,
        klass_name_enum,
        resolved_constructor_name_enum,
        array_klass_name_enum,
        oop_size_name_enum,
        static_oop_field_count_name_enum,
    ...省略 若干
        FIRST_SID = NO_SID + 1
    };

    接着

    /接着
    // Parse code and exceptions attribute
    u2 method_attributes_count = cfs->get_u2_fast();
    while (method_attributes_count--) {
    cfs->guarantee_more(6, CHECK_(nullHandle));  // method_attribute_name_index, method_attribute_length
    u2 method_attribute_name_index = cfs->get_u2_fast();  //value=21
    u4 method_attribute_length = cfs->get_u4_fast();  //value =43
    check_property(
            valid_symbol_at(method_attribute_name_index),
    "Invalid method attribute name index %u in class file %s",
    method_attribute_name_index, CHECK_(nullHandle));
    //调用了_cp对象的方法
    Symbol* method_attribute_name = _cp->symbol_at(method_attribute_name_index);//arg=21,
    //(gdb) p method_attribute_name->as_C_string()
    //$6 = 0x7f7a7c00f148 "Code"
    Symbol* symbol_at(int which) {
        assert(tag_at(which).is_utf8(), "Corrupted constant pool");
        return *symbol_at_addr(which);
    }
    Symbol** symbol_at_addr(int which) const {
        assert(is_within_bounds(which), "index out of bounds");
        return (Symbol**) &base()[which];
    }
    intptr_t* base() const { return (intptr_t*) (((char*) this) + sizeof(ConstantPool)); }
    
    (gdb) p this
    $5 = (const ConstantPool * const) 0x7f7a6ab8c108

    很多内容都是解析,省略

    接着进入创建Method与ConstMethod对象

    // All sizing information for a Method* is finally available, now create it
    InlineTableSizes sizes(
            total_lvt_length,
            linenumber_table_length,
            exception_table_length,
            checked_exceptions_length,
            method_parameters_length,
            generic_signature_index,
            runtime_visible_annotations_length +
    runtime_invisible_annotations_length,
    runtime_visible_parameter_annotations_length +
    runtime_invisible_parameter_annotations_length,
    runtime_visible_type_annotations_length +
    runtime_invisible_type_annotations_length,
    annotation_default_length,
    0);
    
    Method* m = Method::allocate(
            _loader_data, code_length, access_flags, &sizes,
            ConstMethod::NORMAL, CHECK_(nullHandle));
    其中的InlineTableSizes sizes(xx,xx,xx,xx)是构造方法,有点没看出来,因为这里类是宏定义的解析完之后的为
    解析完之后的为
            (gdb) ptype InlineTableSizes
    type = class InlineTableSizes : private StackObj {
    private:
        int _localvariable_table_length;
        int _compressed_linenumber_size;
        int _exception_table_length;
        int _checked_exceptions_length;
        int _method_parameters_length;
        int _generic_signature_index;
        int _method_annotations_length;
        int _parameter_annotations_length;
        int _type_annotations_length;
        int _default_annotations_length;
        int _end;
    
    public:
        InlineTableSizes(int, int, int, int, int, int, int, int, int, int, int):{}
        InlineTableSizes(void);
        int localvariable_table_length(void) const;
        int compressed_linenumber_size(void) const;
        int exception_table_length(void) const;
        int checked_exceptions_length(void) const;
        int method_parameters_length(void) const;
        int generic_signature_index(void) const;
        int method_annotations_length(void) const;
        int parameter_annotations_length(void) const;
        int type_annotations_length(void) const;
        int default_annotations_length(void) const;
    }

    解析构造方法:解析过程如下

    InlineTableSizes(
    INLINE_TABLES_DO(INLINE_TABLE_PARAM)
    int end) :
    INLINE_TABLES_DO(INLINE_TABLE_INIT)
    _end(end) {}
    
    
    #define INLINE_TABLES_DO(do_element)            
      do_element(localvariable_table_length)        
      do_element(compressed_linenumber_size)        
      do_element(exception_table_length)            
      do_element(checked_exceptions_length)         
      do_element(method_parameters_length)          
      do_element(generic_signature_index)           
      do_element(method_annotations_length)         
      do_element(parameter_annotations_length)      
      do_element(type_annotations_length)           
      do_element(default_annotations_length)
    
    #define INLINE_TABLE_INIT(sym)       _##sym(sym),
    
    代换
    InlineTableSizes() :
    INLINE_TABLE_INIT(localvariable_table_length)
    INLINE_TABLE_INIT(compressed_linenumber_size)
    INLINE_TABLE_INIT(compressed_linenumber_size)
    INLINE_TABLE_INIT(exception_table_length)
    INLINE_TABLE_INIT(checked_exceptions_length)
    INLINE_TABLE_INIT(method_parameters_length)
    INLINE_TABLE_INIT(generic_signature_index)
    INLINE_TABLE_INIT(method_annotations_length)
    INLINE_TABLE_INIT(parameter_annotations_length)
    INLINE_TABLE_INIT(type_annotations_length)
    INLINE_TABLE_INIT(default_annotations_length)
    _end(end) {}
    
    代换第二层
    InlineTableSizes(int localvariable_table_length,
                     int compressed_linenumber_size,
                     int exception_table_length,
                     int checked_exceptions_length,
                     int method_parameters_length,
                     int generic_signature_index,
                     int method_annotations_length,
                     int parameter_annotations_length,
                     int type_annotations_length,
                     int default_annotations_length
            ) :
    _localvariable_table_length(localvariable_table_length),
    _compressed_linenumber_size(compressed_linenumber_size),
    _compressed_linenumber_size(compressed_linenumber_size),
    _exception_table_length(exception_table_length),
    _checked_exceptions_length(checked_exceptions_length),
    _method_parameters_length(method_parameters_length),
    _generic_signature_index(generic_signature_index),
    _method_annotations_length(method_annotations_length),
    _parameter_annotations_length(parameter_annotations_length),
    _type_annotations_length(type_annotations_length),
    _default_annotations_length(default_annotations_length),
    _end(end) {}
    //接着进入流程

    //接着进入流程

    Method* Method::allocate(ClassLoaderData* loader_data,
                             int byte_code_size,
                             AccessFlags access_flags,
                             InlineTableSizes* sizes,
                             ConstMethod::MethodType method_type,
                             TRAPS) {
        assert(!access_flags.is_native() || byte_code_size == 0,
               "native methods should not contain byte codes");
        ConstMethod* cm = ConstMethod::allocate(loader_data,
                                                byte_code_size,
                                                sizes,
                                                method_type,
                                                CHECK_NULL);
    
        int size = Method::size(access_flags.is_native());
    
        return new (loader_data, size, false, MetaspaceObj::MethodType, THREAD) Method(cm, access_flags, size);
    }

    标记的有点意思

    int ConstMethod::size(int code_size,InlineTableSizes* sizes) {
        int extra_bytes = code_size;
        if (sizes->compressed_linenumber_size() > 0) {
            extra_bytes += sizes->compressed_linenumber_size();
        }
        if (sizes->checked_exceptions_length() > 0) {
            extra_bytes += sizeof(u2);
            extra_bytes += sizes->checked_exceptions_length() * sizeof(CheckedExceptionElement);
        }
        if (sizes->localvariable_table_length() > 0) {
            extra_bytes += sizeof(u2);
            extra_bytes += sizes->localvariable_table_length() * sizeof(LocalVariableTableElement);
        }
        if (sizes->exception_table_length() > 0) {
            extra_bytes += sizeof(u2);
            extra_bytes += sizes->exception_table_length() * sizeof(ExceptionTableElement);
        }
        if (sizes->generic_signature_index() != 0) {
            extra_bytes += sizeof(u2);
        }
        if (sizes->method_parameters_length() > 0) {
            extra_bytes += sizeof(u2);
            extra_bytes += sizes->method_parameters_length() * sizeof(MethodParametersElement);
        }
    
        // Align sizes up to a word.
        extra_bytes = align_size_up(extra_bytes, BytesPerWord);
    
        // One pointer per annotation array
        if (sizes->method_annotations_length() > 0) {
            extra_bytes += sizeof(AnnotationArray*);
        }
        if (sizes->parameter_annotations_length() > 0) {
            extra_bytes += sizeof(AnnotationArray*);
        }
        if (sizes->type_annotations_length() > 0) {
            extra_bytes += sizeof(AnnotationArray*);
        }
        if (sizes->default_annotations_length() > 0) {
            extra_bytes += sizeof(AnnotationArray*);
        }
    
        int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord;
        return align_object_size(header_size() + extra_words); // 内存大小的单位为字
    }
    
    static int header_size() {
        return sizeof(ConstMethod)/HeapWordSize;
    }

    所以有俩部分,一部分是ConstMethod 的sizeof 另外一部分就是Code字节码和InlineTableSizes的内容

    分布图如

    /////////////////////////////////////
    /        ConstantMethod            /
    / --------------------------------/
     Code
     ---------------------------------
    localvariable_table_length      / 这个属性 Object 没有
    ---------------------------------
    compressed_linenumber_size
    --------------------------------

    打印内存内容

    参数
    set print pretty on 格式化c结构体输出
    
    (gdb) set print pretty on
            (gdb) p *sizes
    $13 = (InlineTableSizes) {
            <StackObj> = {
                <AllocatedObj> = {
                    _vptr.AllocatedObj = 0x7f7a81c5c8f0 <vtable for InlineTableSizes+16>
                }, <No data fields>},
            members of InlineTableSizes:
            _localvariable_table_length = 1,
            _compressed_linenumber_size = 4,
            _exception_table_length = 0,
            _checked_exceptions_length = 0,
            _method_parameters_length = 0,
            _generic_signature_index = 0,
            _method_annotations_length = 0,
            _parameter_annotations_length = 0,
            _type_annotations_length = 0,
            _default_annotations_length = 0,
            _end = 0
    }

    //当创建cm对象之后,打印

    (gdb) p cm
    $14 = (ConstMethod *) 0x7f7a6ab8c4a8
            (gdb) p * cm
    $15 = {
            <MetaspaceObj> = {<No data fields>},
            members of ConstMethod:
            _fingerprint = 9223372036854775808,
            _constants = 0x0,
            _stackmap_data = 0x0,
            _constMethod_size = 9,
            _flags = 5,
            _code_size = 1,
            _name_index = 0,
            _signature_index = 0,
            _method_idnum = 0,
            _max_stack = 0,
            _max_locals = 0,
            _size_of_parameters = 0,
            static MAX_IDNUM = 65534,
            static UNSET_IDNUM = 65535
    }

    给Method 创建对象

    int size = Method::size(access_flags.is_native());  //size=12
    //进入方法
    int Method::size(bool is_native) { //false
        // If native, then include pointers for native_function and signature_handler
        int extra_bytes = (is_native) ? 2*sizeof(address*) : 0;
        int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord;
        return align_object_size(header_size() + extra_words);
    }
    
    static int header_size(){ return sizeof(Method)/HeapWordSize; }

    打印对象

    (gdb) p m
    $26 = (Method *) 0x7f7a6ab8c4f0
            (gdb) p * m
    $27 = (Method) {
            <Metadata> = {
                <MetaspaceObj> = {<No data fields>},
                members of Metadata:
                _vptr.Metadata = 0x7f7a81c84b90 <vtable for Method+16>,
                        _valid = 0
            },
            members of Method:
            _constMethod = 0x7f7a6ab8c4a8,
            _method_data = 0x0,
            _method_counters = 0x0,
            _access_flags = {
                _flags = 1
            },
            _vtable_index = -3,
            _method_size = 12,
            _intrinsic_id = 0 '00',
            _jfr_towrite = 0 '00',
            _caller_sensitive = 0 '00',
            _force_inline = 0 '00',
            _hidden = 0 '00',
            _dont_inline = 0 '00',
            _compiled_invocation_count = 0,
            _i2i_entry = 0x0,
            _adapter = 0x0,
            _from_compiled_entry = 0x0,
            _code = 0x0,
            _from_interpreted_entry = 0x0,
            static extra_stack_entries_for_jsr292 = 1
    }

    接着进入对象的属性设置

    ClassLoadingService::add_class_method_size(m->size()*HeapWordSize);
    
    // Copy byte codes
    m->set_code(code_start);
    // byte codes
    void    set_code(address code)      { return constMethod()->set_code(code); }
    void    set_code(address code) {
        if (code_size() > 0) {
            memcpy(code_base(), code, code_size());
        }
    }
    address code_base() const            { return (address) (this+1); }

    这里有点意思

    (gdb) p this
    $3 = (const ConstMethod * const) 0x7f950f4304a8
            (gdb) p this +1                             //注意,这里取的是COde字节码
    $4 = (const ConstMethod * const) 0x7f950f4304d8
            (gdb) p sizeof(*this)
    $5 = 320
    注意的是this +1 ,因为this 类型ConstMethod那么+1 就加上320个字节,那么就是在对象后面的第一个字节

    最后打印对象

    (gdb) p * m
    $11 = (Method) {
            <Metadata> = {
                <MetaspaceObj> = {<No data fields>},
                members of Metadata:
                _vptr.Metadata = 0x7f9532845b90 <vtable for Method+16>,
                        _valid = 0
            },
            members of Method:
            _constMethod = 0x7f950f4304a8,
            _method_data = 0x0,
            _method_counters = 0x0,
            _access_flags = {
                _flags = 1
            },
            _vtable_index = -3,
            _method_size = 12,
            _intrinsic_id = 0 '00',
            _jfr_towrite = 0 '00',
            _caller_sensitive = 0 '00',
            _force_inline = 0 '00',
            _hidden = 0 '00',
            _dont_inline = 0 '00',
            _compiled_invocation_count = 0,
            _i2i_entry = 0x0,
            _adapter = 0x0,
            _from_compiled_entry = 0x0,
            _code = 0x0,
            _from_interpreted_entry = 0x0,
            static extra_stack_entries_for_jsr292 = 1
    }
    
    (gdb) p * m->constMethod()
    $12 = {
            <MetaspaceObj> = {<No data fields>},
            members of ConstMethod:
            _fingerprint = 9223372036854775808,
            _constants = 0x7f950f430108,
            _stackmap_data = 0x0,
            _constMethod_size = 9,
            _flags = 5,
            _code_size = 1,
            _name_index = 19,
            _signature_index = 20,
            _method_idnum = 0,
            _max_stack = 0,
            _max_locals = 1,
            _size_of_parameters = 1,
            static MAX_IDNUM = 65534,
            static UNSET_IDNUM = 65535
    }

    方法解析结束

  • 相关阅读:
    es从aws迁移阿里云问题总结
    MySQL & Canal流程&架构梳理
    这么优雅的Java ORM没见过吧!
    Five86-1靶机渗透实战
    从信息泄露到域控
    禁用浏览器在触摸屏上双指缩放的功能
    使用java动态字节码技术简单实现arthas的trace功能。
    apisix网关-构建docker镜像构建及插件化开发
    query扩展方法汇总
    为什么.NET Standard 仍然有意义?
  • 原文地址:https://www.cnblogs.com/zytcomeon/p/14605544.html
Copyright © 2011-2022 走看看