mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
6580131: 3/4 CompiledMethodLoad events don't produce the expected extra notifications to describe inlining
Add support for additional implementation specific info to the JVM/TI CompiledMethodLoad event via the compile_info parameter. Reviewed-by: never, ohair, tbell, tdeneau
This commit is contained in:
parent
ce78944539
commit
a5e58e8d53
5 changed files with 172 additions and 8 deletions
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
|
# Copyright 2005-2010 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -281,10 +281,13 @@ endif
|
||||||
$(EXPORT_LIB_DIR)/%.jar: $(GEN_DIR)/%.jar
|
$(EXPORT_LIB_DIR)/%.jar: $(GEN_DIR)/%.jar
|
||||||
$(install-file)
|
$(install-file)
|
||||||
|
|
||||||
# Include files (jvmti.h, jni.h, $(JDK_INCLUDE_SUBDIR)/jni_md.h, jmm.h)
|
# Include files (jvmti.h, jvmticmlr.h, jni.h, $(JDK_INCLUDE_SUBDIR)/jni_md.h, jmm.h)
|
||||||
$(EXPORT_INCLUDE_DIR)/%: $(GEN_DIR)/jvmtifiles/%
|
$(EXPORT_INCLUDE_DIR)/%: $(GEN_DIR)/jvmtifiles/%
|
||||||
$(install-file)
|
$(install-file)
|
||||||
|
|
||||||
|
$(EXPORT_INCLUDE_DIR)/%: $(HS_SRC_DIR)/share/vm/code/%
|
||||||
|
$(install-file)
|
||||||
|
|
||||||
$(EXPORT_INCLUDE_DIR)/%: $(HS_SRC_DIR)/share/vm/prims/%
|
$(EXPORT_INCLUDE_DIR)/%: $(HS_SRC_DIR)/share/vm/prims/%
|
||||||
$(install-file)
|
$(install-file)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved.
|
# Copyright 2006-2010 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -259,6 +259,7 @@ EXPORT_JRE_LIB_ARCH_DIR = $(EXPORT_JRE_LIB_DIR)/$(LIBARCH)
|
||||||
|
|
||||||
# Common export list of files
|
# Common export list of files
|
||||||
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jvmti.h
|
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jvmti.h
|
||||||
|
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jvmticmlr.h
|
||||||
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jni.h
|
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jni.h
|
||||||
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/$(JDK_INCLUDE_SUBDIR)/jni_md.h
|
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/$(JDK_INCLUDE_SUBDIR)/jni_md.h
|
||||||
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jmm.h
|
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jmm.h
|
||||||
|
|
115
hotspot/src/share/vm/code/jvmticmlr.h
Normal file
115
hotspot/src/share/vm/code/jvmticmlr.h
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Sun designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Sun in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This header file defines the data structures sent by the VM
|
||||||
|
* through the JVMTI CompiledMethodLoad callback function via the
|
||||||
|
* "void * compile_info" parameter. The memory pointed to by the
|
||||||
|
* compile_info parameter may not be referenced after returning from
|
||||||
|
* the CompiledMethodLoad callback. These are VM implementation
|
||||||
|
* specific data structures that may evolve in future releases. A
|
||||||
|
* JVMTI agent should interpret a non-NULL compile_info as a pointer
|
||||||
|
* to a region of memory containing a list of records. In a typical
|
||||||
|
* usage scenario, a JVMTI agent would cast each record to a
|
||||||
|
* jvmtiCompiledMethodLoadRecordHeader, a struct that represents
|
||||||
|
* arbitrary information. This struct contains a kind field to indicate
|
||||||
|
* the kind of information being passed, and a pointer to the next
|
||||||
|
* record. If the kind field indicates inlining information, then the
|
||||||
|
* agent would cast the record to a jvmtiCompiledMethodLoadInlineRecord.
|
||||||
|
* This record contains an array of PCStackInfo structs, which indicate
|
||||||
|
* for every pc address what are the methods on the invocation stack.
|
||||||
|
* The "methods" and "bcis" fields in each PCStackInfo struct specify a
|
||||||
|
* 1-1 mapping between these inlined methods and their bytecode indices.
|
||||||
|
* This can be used to derive the proper source lines of the inlined
|
||||||
|
* methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _JVMTI_CMLR_H_
|
||||||
|
#define _JVMTI_CMLR_H_
|
||||||
|
|
||||||
|
enum {
|
||||||
|
JVMTI_CMLR_MAJOR_VERSION_1 = 0x00000001,
|
||||||
|
JVMTI_CMLR_MINOR_VERSION_0 = 0x00000000,
|
||||||
|
|
||||||
|
JVMTI_CMLR_MAJOR_VERSION = 0x00000001,
|
||||||
|
JVMTI_CMLR_MINOR_VERSION = 0x00000000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This comment is for the "JDK import from HotSpot" sanity check:
|
||||||
|
* version: 1.0.0
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
JVMTI_CMLR_DUMMY = 1,
|
||||||
|
JVMTI_CMLR_INLINE_INFO = 2
|
||||||
|
} jvmtiCMLRKind;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record that represents arbitrary information passed through JVMTI
|
||||||
|
* CompiledMethodLoadEvent void pointer.
|
||||||
|
*/
|
||||||
|
typedef struct _jvmtiCompiledMethodLoadRecordHeader {
|
||||||
|
jvmtiCMLRKind kind; /* id for the kind of info passed in the record */
|
||||||
|
jint majorinfoversion; /* major and minor info version values. Init'ed */
|
||||||
|
jint minorinfoversion; /* to current version value in jvmtiExport.cpp. */
|
||||||
|
|
||||||
|
struct _jvmtiCompiledMethodLoadRecordHeader* next;
|
||||||
|
} jvmtiCompiledMethodLoadRecordHeader;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record that gives information about the methods on the compile-time
|
||||||
|
* stack at a specific pc address of a compiled method. Each element in
|
||||||
|
* the methods array maps to same element in the bcis array.
|
||||||
|
*/
|
||||||
|
typedef struct _PCStackInfo {
|
||||||
|
void* pc; /* the pc address for this compiled method */
|
||||||
|
jint numstackframes; /* number of methods on the stack */
|
||||||
|
jmethodID* methods; /* array of numstackframes method ids */
|
||||||
|
jint* bcis; /* array of numstackframes bytecode indices */
|
||||||
|
} PCStackInfo;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record that contains inlining information for each pc address of
|
||||||
|
* an nmethod.
|
||||||
|
*/
|
||||||
|
typedef struct _jvmtiCompiledMethodLoadInlineRecord {
|
||||||
|
jvmtiCompiledMethodLoadRecordHeader header; /* common header for casting */
|
||||||
|
jint numpcs; /* number of pc descriptors in this nmethod */
|
||||||
|
PCStackInfo* pcinfo; /* array of numpcs pc descriptors */
|
||||||
|
} jvmtiCompiledMethodLoadInlineRecord;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dummy record used to test that we can pass records with different
|
||||||
|
* information through the void pointer provided that they can be cast
|
||||||
|
* to a jvmtiCompiledMethodLoadRecordHeader.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct _jvmtiCompiledMethodLoadDummyRecord {
|
||||||
|
jvmtiCompiledMethodLoadRecordHeader header; /* common header for casting */
|
||||||
|
char message[50];
|
||||||
|
} jvmtiCompiledMethodLoadDummyRecord;
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
// Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -2500,6 +2500,7 @@ jvmtiExport.hpp growableArray.hpp
|
||||||
jvmtiExport.hpp handles.hpp
|
jvmtiExport.hpp handles.hpp
|
||||||
jvmtiExport.hpp iterator.hpp
|
jvmtiExport.hpp iterator.hpp
|
||||||
jvmtiExport.hpp jvmti.h
|
jvmtiExport.hpp jvmti.h
|
||||||
|
jvmtiExport.hpp jvmticmlr.h
|
||||||
jvmtiExport.hpp oop.hpp
|
jvmtiExport.hpp oop.hpp
|
||||||
jvmtiExport.hpp oopsHierarchy.hpp
|
jvmtiExport.hpp oopsHierarchy.hpp
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2003-2010 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -686,11 +686,11 @@ class JvmtiCompiledMethodLoadEventMark : public JvmtiMethodEventMark {
|
||||||
jvmtiAddrLocationMap *_map;
|
jvmtiAddrLocationMap *_map;
|
||||||
const void *_compile_info;
|
const void *_compile_info;
|
||||||
public:
|
public:
|
||||||
JvmtiCompiledMethodLoadEventMark(JavaThread *thread, nmethod *nm)
|
JvmtiCompiledMethodLoadEventMark(JavaThread *thread, nmethod *nm, void* compile_info_ptr = NULL)
|
||||||
: JvmtiMethodEventMark(thread,methodHandle(thread, nm->method())) {
|
: JvmtiMethodEventMark(thread,methodHandle(thread, nm->method())) {
|
||||||
_code_data = nm->code_begin();
|
_code_data = nm->code_begin();
|
||||||
_code_size = nm->code_size();
|
_code_size = nm->code_size();
|
||||||
_compile_info = NULL; /* no info for our VM. */
|
_compile_info = compile_info_ptr; // Set void pointer of compiledMethodLoad Event. Default value is NULL.
|
||||||
JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &_map, &_map_length);
|
JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &_map, &_map_length);
|
||||||
}
|
}
|
||||||
~JvmtiCompiledMethodLoadEventMark() {
|
~JvmtiCompiledMethodLoadEventMark() {
|
||||||
|
@ -1752,6 +1752,46 @@ void JvmtiExport::post_native_method_bind(methodOop method, address* function_pt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns a record containing inlining information for the given nmethod
|
||||||
|
jvmtiCompiledMethodLoadInlineRecord* create_inline_record(nmethod* nm) {
|
||||||
|
jint numstackframes = 0;
|
||||||
|
jvmtiCompiledMethodLoadInlineRecord* record = (jvmtiCompiledMethodLoadInlineRecord*)NEW_RESOURCE_OBJ(jvmtiCompiledMethodLoadInlineRecord);
|
||||||
|
record->header.kind = JVMTI_CMLR_INLINE_INFO;
|
||||||
|
record->header.next = NULL;
|
||||||
|
record->header.majorinfoversion = JVMTI_CMLR_MAJOR_VERSION_1;
|
||||||
|
record->header.minorinfoversion = JVMTI_CMLR_MINOR_VERSION_0;
|
||||||
|
record->numpcs = 0;
|
||||||
|
for(PcDesc* p = nm->scopes_pcs_begin(); p < nm->scopes_pcs_end(); p++) {
|
||||||
|
if(p->scope_decode_offset() == DebugInformationRecorder::serialized_null) continue;
|
||||||
|
record->numpcs++;
|
||||||
|
}
|
||||||
|
record->pcinfo = (PCStackInfo*)(NEW_RESOURCE_ARRAY(PCStackInfo, record->numpcs));
|
||||||
|
int scope = 0;
|
||||||
|
for(PcDesc* p = nm->scopes_pcs_begin(); p < nm->scopes_pcs_end(); p++) {
|
||||||
|
if(p->scope_decode_offset() == DebugInformationRecorder::serialized_null) continue;
|
||||||
|
void* pc_address = (void*)p->real_pc(nm);
|
||||||
|
assert(pc_address != NULL, "pc_address must be non-null");
|
||||||
|
record->pcinfo[scope].pc = pc_address;
|
||||||
|
numstackframes=0;
|
||||||
|
for(ScopeDesc* sd = nm->scope_desc_at(p->real_pc(nm));sd != NULL;sd = sd->sender()) {
|
||||||
|
numstackframes++;
|
||||||
|
}
|
||||||
|
assert(numstackframes != 0, "numstackframes must be nonzero.");
|
||||||
|
record->pcinfo[scope].methods = (jmethodID *)NEW_RESOURCE_ARRAY(jmethodID, numstackframes);
|
||||||
|
record->pcinfo[scope].bcis = (jint *)NEW_RESOURCE_ARRAY(jint, numstackframes);
|
||||||
|
record->pcinfo[scope].numstackframes = numstackframes;
|
||||||
|
int stackframe = 0;
|
||||||
|
for(ScopeDesc* sd = nm->scope_desc_at(p->real_pc(nm));sd != NULL;sd = sd->sender()) {
|
||||||
|
// 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()
|
||||||
|
assert(!sd->method().is_null(), "sd->method() cannot be null.");
|
||||||
|
record->pcinfo[scope].methods[stackframe] = sd->method()->jmethod_id();
|
||||||
|
record->pcinfo[scope].bcis[stackframe] = sd->bci();
|
||||||
|
stackframe++;
|
||||||
|
}
|
||||||
|
scope++;
|
||||||
|
}
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
void JvmtiExport::post_compiled_method_load(nmethod *nm) {
|
void JvmtiExport::post_compiled_method_load(nmethod *nm) {
|
||||||
// If there are pending CompiledMethodUnload events then these are
|
// If there are pending CompiledMethodUnload events then these are
|
||||||
|
@ -1780,7 +1820,11 @@ void JvmtiExport::post_compiled_method_load(nmethod *nm) {
|
||||||
(nm->method() == NULL) ? "NULL" : nm->method()->name()->as_C_string()));
|
(nm->method() == NULL) ? "NULL" : nm->method()->name()->as_C_string()));
|
||||||
|
|
||||||
ResourceMark rm(thread);
|
ResourceMark rm(thread);
|
||||||
JvmtiCompiledMethodLoadEventMark jem(thread, nm);
|
|
||||||
|
// Add inlining information
|
||||||
|
jvmtiCompiledMethodLoadInlineRecord* inlinerecord = create_inline_record(nm);
|
||||||
|
// Pass inlining information through the void pointer
|
||||||
|
JvmtiCompiledMethodLoadEventMark jem(thread, nm, inlinerecord);
|
||||||
JvmtiJavaThreadEventTransition jet(thread);
|
JvmtiJavaThreadEventTransition jet(thread);
|
||||||
jvmtiEventCompiledMethodLoad callback = env->callbacks()->CompiledMethodLoad;
|
jvmtiEventCompiledMethodLoad callback = env->callbacks()->CompiledMethodLoad;
|
||||||
if (callback != NULL) {
|
if (callback != NULL) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue