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 '\000',
        _jfr_towrite = 0 '\000',
        _caller_sensitive = 0 '\000',
        _force_inline = 0 '\000',
        _hidden = 0 '\000',
        _dont_inline = 0 '\000',
        _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 '\000',
        _jfr_towrite = 0 '\000',
        _caller_sensitive = 0 '\000',
        _force_inline = 0 '\000',
        _hidden = 0 '\000',
        _dont_inline = 0 '\000',
        _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
}

方法解析结束

posted @ 2021-04-01 11:28  张艳涛&java  阅读(134)  评论(0编辑  收藏  举报