6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining

Wed, 13 Jan 2010 09:39:46 -0700

author
dcubed
date
Wed, 13 Jan 2010 09:39:46 -0700
changeset 1619
7fbf850d87b7
parent 1556
98cd9901c161
child 1620
3908ad124838
child 1649
0fc941df6fb7

6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
Summary: Add support for additional implementation specific info to the JVM/TI CompiledMethodLoad event via the compile_info parameter.
Reviewed-by: never, ohair, tbell, tdeneau
Contributed-by: Vasanth Venkatachalam <vasanth.venkatachalam@amd.com>

make/Makefile file | annotate | diff | comparison | revisions
make/defs.make file | annotate | diff | comparison | revisions
src/share/vm/code/jvmticmlr.h file | annotate | diff | comparison | revisions
src/share/vm/includeDB_core file | annotate | diff | comparison | revisions
src/share/vm/prims/jvmtiExport.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/make/Makefile	Mon Dec 14 10:05:36 2009 -0700
     1.2 +++ b/make/Makefile	Wed Jan 13 09:39:46 2010 -0700
     1.3 @@ -1,5 +1,5 @@
     1.4  #
     1.5 -# Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
     1.6 +# Copyright 2005-2010 Sun Microsystems, Inc.  All Rights Reserved.
     1.7  # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8  #
     1.9  # This code is free software; you can redistribute it and/or modify it
    1.10 @@ -281,10 +281,13 @@
    1.11  $(EXPORT_LIB_DIR)/%.jar: $(GEN_DIR)/%.jar
    1.12  	$(install-file)
    1.13  
    1.14 -# Include files (jvmti.h, jni.h, $(JDK_INCLUDE_SUBDIR)/jni_md.h, jmm.h)
    1.15 +# Include files (jvmti.h, jvmticmlr.h, jni.h, $(JDK_INCLUDE_SUBDIR)/jni_md.h, jmm.h)
    1.16  $(EXPORT_INCLUDE_DIR)/%: $(GEN_DIR)/jvmtifiles/%
    1.17  	$(install-file)
    1.18  
    1.19 +$(EXPORT_INCLUDE_DIR)/%: $(HS_SRC_DIR)/share/vm/code/%
    1.20 +	$(install-file)
    1.21 +
    1.22  $(EXPORT_INCLUDE_DIR)/%: $(HS_SRC_DIR)/share/vm/prims/%
    1.23  	$(install-file)
    1.24  
     2.1 --- a/make/defs.make	Mon Dec 14 10:05:36 2009 -0700
     2.2 +++ b/make/defs.make	Wed Jan 13 09:39:46 2010 -0700
     2.3 @@ -1,5 +1,5 @@
     2.4  #
     2.5 -# Copyright 2006-2008 Sun Microsystems, Inc.  All Rights Reserved.
     2.6 +# Copyright 2006-2010 Sun Microsystems, Inc.  All Rights Reserved.
     2.7  # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.8  #
     2.9  # This code is free software; you can redistribute it and/or modify it
    2.10 @@ -259,6 +259,7 @@
    2.11  
    2.12  # Common export list of files
    2.13  EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jvmti.h
    2.14 +EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jvmticmlr.h
    2.15  EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jni.h
    2.16  EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/$(JDK_INCLUDE_SUBDIR)/jni_md.h
    2.17  EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jmm.h
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/share/vm/code/jvmticmlr.h	Wed Jan 13 09:39:46 2010 -0700
     3.3 @@ -0,0 +1,115 @@
     3.4 +/*
     3.5 + * Copyright 2010 Sun Microsystems, Inc.  All Rights Reserved.
     3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.7 + *
     3.8 + * This code is free software; you can redistribute it and/or modify it
     3.9 + * under the terms of the GNU General Public License version 2 only, as
    3.10 + * published by the Free Software Foundation.  Sun designates this
    3.11 + * particular file as subject to the "Classpath" exception as provided
    3.12 + * by Sun in the LICENSE file that accompanied this code.
    3.13 + *
    3.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    3.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    3.17 + * version 2 for more details (a copy is included in the LICENSE file that
    3.18 + * accompanied this code).
    3.19 + *
    3.20 + * You should have received a copy of the GNU General Public License version
    3.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    3.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    3.23 + *
    3.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    3.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
    3.26 + * have any questions.
    3.27 + */
    3.28 +
    3.29 +/*
    3.30 + * This header file defines the data structures sent by the VM
    3.31 + * through the JVMTI CompiledMethodLoad callback function via the
    3.32 + * "void * compile_info" parameter. The memory pointed to by the
    3.33 + * compile_info parameter may not be referenced after returning from
    3.34 + * the CompiledMethodLoad callback. These are VM implementation
    3.35 + * specific data structures that may evolve in future releases. A
    3.36 + * JVMTI agent should interpret a non-NULL compile_info as a pointer
    3.37 + * to a region of memory containing a list of records. In a typical
    3.38 + * usage scenario, a JVMTI agent would cast each record to a
    3.39 + * jvmtiCompiledMethodLoadRecordHeader, a struct that represents
    3.40 + * arbitrary information. This struct contains a kind field to indicate
    3.41 + * the kind of information being passed, and a pointer to the next
    3.42 + * record. If the kind field indicates inlining information, then the
    3.43 + * agent would cast the record to a jvmtiCompiledMethodLoadInlineRecord.
    3.44 + * This record contains an array of PCStackInfo structs, which indicate
    3.45 + * for every pc address what are the methods on the invocation stack.
    3.46 + * The "methods" and "bcis" fields in each PCStackInfo struct specify a
    3.47 + * 1-1 mapping between these inlined methods and their bytecode indices.
    3.48 + * This can be used to derive the proper source lines of the inlined
    3.49 + * methods.
    3.50 + */
    3.51 +
    3.52 +#ifndef _JVMTI_CMLR_H_
    3.53 +#define _JVMTI_CMLR_H_
    3.54 +
    3.55 +enum {
    3.56 +    JVMTI_CMLR_MAJOR_VERSION_1 = 0x00000001,
    3.57 +    JVMTI_CMLR_MINOR_VERSION_0 = 0x00000000,
    3.58 +
    3.59 +    JVMTI_CMLR_MAJOR_VERSION   = 0x00000001,
    3.60 +    JVMTI_CMLR_MINOR_VERSION   = 0x00000000
    3.61 +
    3.62 +    /*
    3.63 +     * This comment is for the "JDK import from HotSpot" sanity check:
    3.64 +     * version: 1.0.0
    3.65 +     */
    3.66 +};
    3.67 +
    3.68 +typedef enum {
    3.69 +    JVMTI_CMLR_DUMMY       = 1,
    3.70 +    JVMTI_CMLR_INLINE_INFO = 2
    3.71 +} jvmtiCMLRKind;
    3.72 +
    3.73 +/*
    3.74 + * Record that represents arbitrary information passed through JVMTI
    3.75 + * CompiledMethodLoadEvent void pointer.
    3.76 + */
    3.77 +typedef struct _jvmtiCompiledMethodLoadRecordHeader {
    3.78 +  jvmtiCMLRKind kind;     /* id for the kind of info passed in the record */
    3.79 +  jint majorinfoversion;  /* major and minor info version values. Init'ed */
    3.80 +  jint minorinfoversion;  /* to current version value in jvmtiExport.cpp. */
    3.81 +
    3.82 +  struct _jvmtiCompiledMethodLoadRecordHeader* next;
    3.83 +} jvmtiCompiledMethodLoadRecordHeader;
    3.84 +
    3.85 +/*
    3.86 + * Record that gives information about the methods on the compile-time
    3.87 + * stack at a specific pc address of a compiled method. Each element in
    3.88 + * the methods array maps to same element in the bcis array.
    3.89 + */
    3.90 +typedef struct _PCStackInfo {
    3.91 +  void* pc;             /* the pc address for this compiled method */
    3.92 +  jint numstackframes;  /* number of methods on the stack */
    3.93 +  jmethodID* methods;   /* array of numstackframes method ids */
    3.94 +  jint* bcis;           /* array of numstackframes bytecode indices */
    3.95 +} PCStackInfo;
    3.96 +
    3.97 +/*
    3.98 + * Record that contains inlining information for each pc address of
    3.99 + * an nmethod.
   3.100 + */
   3.101 +typedef struct _jvmtiCompiledMethodLoadInlineRecord {
   3.102 +  jvmtiCompiledMethodLoadRecordHeader header;  /* common header for casting */
   3.103 +  jint numpcs;          /* number of pc descriptors in this nmethod */
   3.104 +  PCStackInfo* pcinfo;  /* array of numpcs pc descriptors */
   3.105 +} jvmtiCompiledMethodLoadInlineRecord;
   3.106 +
   3.107 +/*
   3.108 + * Dummy record used to test that we can pass records with different
   3.109 + * information through the void pointer provided that they can be cast
   3.110 + * to a jvmtiCompiledMethodLoadRecordHeader.
   3.111 + */
   3.112 +
   3.113 +typedef struct _jvmtiCompiledMethodLoadDummyRecord {
   3.114 +  jvmtiCompiledMethodLoadRecordHeader header;  /* common header for casting */
   3.115 +  char message[50];
   3.116 +} jvmtiCompiledMethodLoadDummyRecord;
   3.117 +
   3.118 +#endif
     4.1 --- a/src/share/vm/includeDB_core	Mon Dec 14 10:05:36 2009 -0700
     4.2 +++ b/src/share/vm/includeDB_core	Wed Jan 13 09:39:46 2010 -0700
     4.3 @@ -1,5 +1,5 @@
     4.4  //
     4.5 -// Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
     4.6 +// Copyright 1997-2010 Sun Microsystems, Inc.  All Rights Reserved.
     4.7  // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.8  //
     4.9  // This code is free software; you can redistribute it and/or modify it
    4.10 @@ -2500,6 +2500,7 @@
    4.11  jvmtiExport.hpp                         handles.hpp
    4.12  jvmtiExport.hpp                         iterator.hpp
    4.13  jvmtiExport.hpp                         jvmti.h
    4.14 +jvmtiExport.hpp                         jvmticmlr.h
    4.15  jvmtiExport.hpp                         oop.hpp
    4.16  jvmtiExport.hpp                         oopsHierarchy.hpp
    4.17  
     5.1 --- a/src/share/vm/prims/jvmtiExport.cpp	Mon Dec 14 10:05:36 2009 -0700
     5.2 +++ b/src/share/vm/prims/jvmtiExport.cpp	Wed Jan 13 09:39:46 2010 -0700
     5.3 @@ -1,5 +1,5 @@
     5.4  /*
     5.5 - * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
     5.6 + * Copyright 2003-2010 Sun Microsystems, Inc.  All Rights Reserved.
     5.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.8   *
     5.9   * This code is free software; you can redistribute it and/or modify it
    5.10 @@ -686,11 +686,11 @@
    5.11    jvmtiAddrLocationMap *_map;
    5.12    const void *_compile_info;
    5.13   public:
    5.14 -  JvmtiCompiledMethodLoadEventMark(JavaThread *thread, nmethod *nm)
    5.15 +  JvmtiCompiledMethodLoadEventMark(JavaThread *thread, nmethod *nm, void* compile_info_ptr = NULL)
    5.16            : JvmtiMethodEventMark(thread,methodHandle(thread, nm->method())) {
    5.17      _code_data = nm->code_begin();
    5.18      _code_size = nm->code_size();
    5.19 -    _compile_info = NULL; /* no info for our VM. */
    5.20 +    _compile_info = compile_info_ptr; // Set void pointer of compiledMethodLoad Event. Default value is NULL.
    5.21      JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &_map, &_map_length);
    5.22    }
    5.23    ~JvmtiCompiledMethodLoadEventMark() {
    5.24 @@ -1752,6 +1752,46 @@
    5.25    }
    5.26  }
    5.27  
    5.28 +// Returns a record containing inlining information for the given nmethod
    5.29 +jvmtiCompiledMethodLoadInlineRecord* create_inline_record(nmethod* nm) {
    5.30 +  jint numstackframes = 0;
    5.31 +  jvmtiCompiledMethodLoadInlineRecord* record = (jvmtiCompiledMethodLoadInlineRecord*)NEW_RESOURCE_OBJ(jvmtiCompiledMethodLoadInlineRecord);
    5.32 +  record->header.kind = JVMTI_CMLR_INLINE_INFO;
    5.33 +  record->header.next = NULL;
    5.34 +  record->header.majorinfoversion = JVMTI_CMLR_MAJOR_VERSION_1;
    5.35 +  record->header.minorinfoversion = JVMTI_CMLR_MINOR_VERSION_0;
    5.36 +  record->numpcs = 0;
    5.37 +  for(PcDesc* p = nm->scopes_pcs_begin(); p < nm->scopes_pcs_end(); p++) {
    5.38 +   if(p->scope_decode_offset() == DebugInformationRecorder::serialized_null) continue;
    5.39 +   record->numpcs++;
    5.40 +  }
    5.41 +  record->pcinfo = (PCStackInfo*)(NEW_RESOURCE_ARRAY(PCStackInfo, record->numpcs));
    5.42 +  int scope = 0;
    5.43 +  for(PcDesc* p = nm->scopes_pcs_begin(); p < nm->scopes_pcs_end(); p++) {
    5.44 +    if(p->scope_decode_offset() == DebugInformationRecorder::serialized_null) continue;
    5.45 +    void* pc_address = (void*)p->real_pc(nm);
    5.46 +    assert(pc_address != NULL, "pc_address must be non-null");
    5.47 +    record->pcinfo[scope].pc = pc_address;
    5.48 +    numstackframes=0;
    5.49 +    for(ScopeDesc* sd = nm->scope_desc_at(p->real_pc(nm));sd != NULL;sd = sd->sender()) {
    5.50 +      numstackframes++;
    5.51 +    }
    5.52 +    assert(numstackframes != 0, "numstackframes must be nonzero.");
    5.53 +    record->pcinfo[scope].methods = (jmethodID *)NEW_RESOURCE_ARRAY(jmethodID, numstackframes);
    5.54 +    record->pcinfo[scope].bcis = (jint *)NEW_RESOURCE_ARRAY(jint, numstackframes);
    5.55 +    record->pcinfo[scope].numstackframes = numstackframes;
    5.56 +    int stackframe = 0;
    5.57 +    for(ScopeDesc* sd = nm->scope_desc_at(p->real_pc(nm));sd != NULL;sd = sd->sender()) {
    5.58 +      // sd->method() can be NULL for stubs but not for nmethods. To be completely robust, include an assert that we should never see a null sd->method()
    5.59 +      assert(!sd->method().is_null(), "sd->method() cannot be null.");
    5.60 +      record->pcinfo[scope].methods[stackframe] = sd->method()->jmethod_id();
    5.61 +      record->pcinfo[scope].bcis[stackframe] = sd->bci();
    5.62 +      stackframe++;
    5.63 +    }
    5.64 +    scope++;
    5.65 +  }
    5.66 +  return record;
    5.67 +}
    5.68  
    5.69  void JvmtiExport::post_compiled_method_load(nmethod *nm) {
    5.70    // If there are pending CompiledMethodUnload events then these are
    5.71 @@ -1780,7 +1820,11 @@
    5.72                  (nm->method() == NULL) ? "NULL" : nm->method()->name()->as_C_string()));
    5.73  
    5.74        ResourceMark rm(thread);
    5.75 -      JvmtiCompiledMethodLoadEventMark jem(thread, nm);
    5.76 +
    5.77 +      // Add inlining information
    5.78 +      jvmtiCompiledMethodLoadInlineRecord* inlinerecord = create_inline_record(nm);
    5.79 +      // Pass inlining information through the void pointer
    5.80 +      JvmtiCompiledMethodLoadEventMark jem(thread, nm, inlinerecord);
    5.81        JvmtiJavaThreadEventTransition jet(thread);
    5.82        jvmtiEventCompiledMethodLoad callback = env->callbacks()->CompiledMethodLoad;
    5.83        if (callback != NULL) {

mercurial