diff --git a/make/Makefile b/make/Makefile index 5bef049093b742eaff093076aee32b94d061cf83..1d6af55a37cceff5fad1b0a7613a73afbc3ecec9 100644 --- a/make/Makefile +++ b/make/Makefile @@ -367,7 +367,7 @@ endif $(EXPORT_LIB_DIR)/%.jar: $(GEN_DIR)/%.jar $(install-file) -# Include files (jvmti.h, jvmticmlr.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, jfr.h) $(EXPORT_INCLUDE_DIR)/%: $(GEN_DIR)/jvmtifiles/% $(install-file) @@ -384,6 +384,16 @@ $(EXPORT_INCLUDE_DIR)/$(JDK_INCLUDE_SUBDIR)/jni_md.h: $(HS_JNI_ARCH_SRC) $(EXPORT_INCLUDE_DIR)/%: $(HS_SRC_DIR)/share/vm/services/% $(install-file) +JFR_EXISTS=$(shell if [ -d $(HS_ALT_SRC) ]; then echo 1; else echo 0; fi) +# export jfr.h +ifeq ($JFR_EXISTS,1) +$(EXPORT_INCLUDE_DIR)/%: $(HS_ALT_SRC)/share/vm/jfr/agent/% + $(install-file) +else +$(EXPORT_INCLUDE_DIR)/jfr.h: + +endif + # Doc files (jvmti.html) $(EXPORT_DOCS_DIR)/platform/jvmti/%: $(DOCS_DIR)/% $(install-file) diff --git a/make/bsd/makefiles/vm.make b/make/bsd/makefiles/vm.make index 35eca5dbeb3241a1b71702049d609ee14394b49b..0fad0639727ce2deba1766f15812909fcb791813 100644 --- a/make/bsd/makefiles/vm.make +++ b/make/bsd/makefiles/vm.make @@ -96,6 +96,10 @@ ifdef DEFAULT_LIBPATH CPPFLAGS += -DDEFAULT_LIBPATH="\"$(DEFAULT_LIBPATH)\"" endif +ifndef JAVASE_EMBEDDED +CFLAGS += -DINCLUDE_TRACE +endif + # CFLAGS_WARN holds compiler options to suppress/enable warnings. CFLAGS += $(CFLAGS_WARN/BYFILE) @@ -147,6 +151,12 @@ SOURCE_PATHS+=$(HS_COMMON_SRC)/os/posix/vm SOURCE_PATHS+=$(HS_COMMON_SRC)/cpu/$(Platform_arch)/vm SOURCE_PATHS+=$(HS_COMMON_SRC)/os_cpu/$(Platform_os_arch)/vm +ifndef JAVASE_EMBEDDED +SOURCE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \ + find $(HS_ALT_SRC)/share/vm/jfr -type d; \ + fi) +endif + CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path)) CORE_PATHS+=$(GENERATED)/jvmtifiles diff --git a/make/defs.make b/make/defs.make index 7434daebce6935d9b8490340675ae78f6a169df3..3a355c7699781b3122fdd0e30ec4d96b4b0fd77f 100644 --- a/make/defs.make +++ b/make/defs.make @@ -294,3 +294,7 @@ EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jvmticmlr.h EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jni.h EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/$(JDK_INCLUDE_SUBDIR)/jni_md.h EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jmm.h + +ifndef JAVASE_EMBEDDED +EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jfr.h +endif diff --git a/make/linux/makefiles/vm.make b/make/linux/makefiles/vm.make index d40678202e20e7bf27817060c76087c1b89ab0ea..fa2bcc3b05a1c9abdbd6a4f6f569b4ee373d3e2a 100644 --- a/make/linux/makefiles/vm.make +++ b/make/linux/makefiles/vm.make @@ -98,6 +98,10 @@ CPPFLAGS = \ ${JRE_VERSION} \ ${VM_DISTRO} +ifndef JAVASE_EMBEDDED +CFLAGS += -DINCLUDE_TRACE +endif + # CFLAGS_WARN holds compiler options to suppress/enable warnings. CFLAGS += $(CFLAGS_WARN/BYFILE) @@ -143,6 +147,12 @@ SOURCE_PATHS+=$(HS_COMMON_SRC)/os/posix/vm SOURCE_PATHS+=$(HS_COMMON_SRC)/cpu/$(Platform_arch)/vm SOURCE_PATHS+=$(HS_COMMON_SRC)/os_cpu/$(Platform_os_arch)/vm +ifndef JAVASE_EMBEDDED +SOURCE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \ + find $(HS_ALT_SRC)/share/vm/jfr -type d; \ + fi) +endif + CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path)) CORE_PATHS+=$(GENERATED)/jvmtifiles diff --git a/make/solaris/makefiles/vm.make b/make/solaris/makefiles/vm.make index 7b950af7f24cb3b21b6c00c16721efebdcae0df8..0895ea0ba7988f4a1d00365d21f71cf958a652de 100644 --- a/make/solaris/makefiles/vm.make +++ b/make/solaris/makefiles/vm.make @@ -93,7 +93,7 @@ CFLAGS += $(CFLAGS_WARN) CFLAGS += $(CFLAGS/NOEX) # Extra flags from gnumake's invocation or environment -CFLAGS += $(EXTRA_CFLAGS) +CFLAGS += $(EXTRA_CFLAGS) -DINCLUDE_TRACE # Math Library (libm.so), do not use -lm. # There might be two versions of libm.so on the build system: @@ -160,6 +160,10 @@ SOURCE_PATHS+=$(HS_COMMON_SRC)/os/posix/vm SOURCE_PATHS+=$(HS_COMMON_SRC)/cpu/$(Platform_arch)/vm SOURCE_PATHS+=$(HS_COMMON_SRC)/os_cpu/$(Platform_os_arch)/vm +SOURCE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \ + find $(HS_ALT_SRC)/share/vm/jfr -type d; \ + fi) + CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path)) CORE_PATHS+=$(GENERATED)/jvmtifiles diff --git a/make/windows/build.bat b/make/windows/build.bat index ee0a6b058d2e7d33ac81672d194e9f536bc6fa15..ac63bb2ad4ac6dd359e8e5b44a384bd5047fe91f 100644 --- a/make/windows/build.bat +++ b/make/windows/build.bat @@ -35,6 +35,8 @@ cl 2>&1 | grep "IA-64" >NUL if %errorlevel% == 0 goto isia64 cl 2>&1 | grep "AMD64" >NUL if %errorlevel% == 0 goto amd64 +cl 2>&1 | grep "x64" >NUL +if %errorlevel% == 0 goto amd64 set ARCH=x86 set BUILDARCH=i486 set Platform_arch=x86 diff --git a/make/windows/create_obj_files.sh b/make/windows/create_obj_files.sh index 59fe3a6932c1772a4140d3f61be73c6239835388..61903387dbebe24d16d2d49d37f494305e0b662c 100644 --- a/make/windows/create_obj_files.sh +++ b/make/windows/create_obj_files.sh @@ -73,6 +73,13 @@ done BASE_PATHS="${BASE_PATHS} ${GENERATED}/jvmtifiles" +if [ -d "${ALTSRC}/share/vm/jfr" ]; then + BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/agent" + BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/agent/isolated_deps/util" + BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/jvm" + BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr" +fi + CORE_PATHS="${BASE_PATHS}" # shared is already in BASE_PATHS. Should add vm/memory but that one is also in BASE_PATHS. if [ -d "${ALTSRC}/share/vm/gc_implementation" ]; then diff --git a/make/windows/makefiles/projectcreator.make b/make/windows/makefiles/projectcreator.make index 938ce82e9f1d2f9e57032960ded638a8384d71a1..3a6f9aa1b8d197e1d0443142578e561dc1be093b 100644 --- a/make/windows/makefiles/projectcreator.make +++ b/make/windows/makefiles/projectcreator.make @@ -58,7 +58,8 @@ ProjectCreatorIncludesPRIVATE=\ -absoluteInclude $(HOTSPOTBUILDSPACE)/%f/generated \ -ignorePath $(HOTSPOTBUILDSPACE)/%f/generated \ -ignorePath src\share\vm\adlc \ - -ignorePath src\share\vm\shark + -ignorePath src\share\vm\shark \ + -ignorePath posix # This is referenced externally by both the IDE and batch builds ProjectCreatorOptions= @@ -88,7 +89,7 @@ ProjectCreatorIDEOptions=\ -jdkTargetRoot $(HOTSPOTJDKDIST) \ -define ALIGN_STACK_FRAMES \ -define VM_LITTLE_ENDIAN \ - -prelink "" "Generating vm.def..." "cd $(HOTSPOTBUILDSPACE)\%f\%b set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME) $(HOTSPOTMKSHOME)\sh $(HOTSPOTWORKSPACE)\make\windows\build_vm_def.sh $(LINK_VER)" \ + -prelink "" "Generating vm.def..." "cd $(HOTSPOTBUILDSPACE)\%f\%b set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME) set JAVA_HOME=$(HOTSPOTJDKDIST) $(HOTSPOTMKSHOME)\sh $(HOTSPOTWORKSPACE)\make\windows\build_vm_def.sh $(LINK_VER)" \ -postbuild "" "Building hotspot.exe..." "cd $(HOTSPOTBUILDSPACE)\%f\%b set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME) nmake -f $(HOTSPOTWORKSPACE)\make\windows\projectfiles\common\Makefile LOCAL_MAKE=$(HOTSPOTBUILDSPACE)\%f\local.make JAVA_HOME=$(HOTSPOTJDKDIST) launcher" \ -ignoreFile jsig.c \ -ignoreFile jvmtiEnvRecommended.cpp \ diff --git a/make/windows/makefiles/vm.make b/make/windows/makefiles/vm.make index f0b1b9336305f0a02a10afbbb498da7516e9204a..d8c43a1f329a1f80f4aa0b85fba7714238fe5fb9 100644 --- a/make/windows/makefiles/vm.make +++ b/make/windows/makefiles/vm.make @@ -19,7 +19,7 @@ # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. -# +# # # Resource file containing VERSIONINFO @@ -30,7 +30,7 @@ Res_Files=.\version.res COMMONSRC=$(WorkSpace)\src ALTSRC=$(WorkSpace)\src\closed -!ifdef RELEASE +!ifdef RELEASE !ifdef DEVELOP CPP_FLAGS=$(CPP_FLAGS) /D "DEBUG" !else @@ -74,6 +74,10 @@ CPP_FLAGS=$(CPP_FLAGS) /D "HOTSPOT_BUILD_TARGET=\"$(BUILD_FLAVOR)\"" CPP_FLAGS=$(CPP_FLAGS) /D "HOTSPOT_BUILD_USER=\"$(BuildUser)\"" CPP_FLAGS=$(CPP_FLAGS) /D "HOTSPOT_VM_DISTRO=\"$(HOTSPOT_VM_DISTRO)\"" +!ifndef JAVASE_EMBEDDED +CPP_FLAGS=$(CPP_FLAGS) /D "INCLUDE_TRACE" +!endif + CPP_FLAGS=$(CPP_FLAGS) $(CPP_INCLUDE_DIRS) # Define that so jni.h is on correct side @@ -97,7 +101,7 @@ AGCT_EXPORT=/export:AsyncGetCallTrace !endif # If you modify exports below please do the corresponding changes in -# src/share/tools/ProjectCreator/WinGammaPlatformVC7.java +# src/share/tools/ProjectCreator/WinGammaPlatformVC7.java LINK_FLAGS=$(LINK_FLAGS) $(STACK_SIZE) /subsystem:windows /dll /base:0x8000000 \ /export:JNI_GetDefaultJavaVMInitArgs \ /export:JNI_CreateJavaVM \ @@ -170,6 +174,7 @@ VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/oops VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/prims VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/runtime VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/services +VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/trace VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/utilities VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/libadt VM_PATH=$(VM_PATH);$(WorkSpace)/src/os/windows/vm @@ -177,6 +182,13 @@ VM_PATH=$(VM_PATH);$(WorkSpace)/src/os_cpu/windows_$(Platform_arch)/vm VM_PATH=$(VM_PATH);$(WorkSpace)/src/cpu/$(Platform_arch)/vm VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/opto +!if exists($(ALTSRC)\share\vm\jfr) +VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr/agent +VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr/agent/isolated_deps/util +VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr/jvm +VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr +!endif + VM_PATH={$(VM_PATH)} # Special case files not using precompiled header files. @@ -263,6 +275,9 @@ bytecodeInterpreterWithChecks.obj: ..\generated\jvmtifiles\bytecodeInterpreterWi {$(COMMONSRC)\share\vm\services}.cpp.obj:: $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< +{$(COMMONSRC)\share\vm\trace}.cpp.obj:: + $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + {$(COMMONSRC)\share\vm\utilities}.cpp.obj:: $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< @@ -340,6 +355,9 @@ bytecodeInterpreterWithChecks.obj: ..\generated\jvmtifiles\bytecodeInterpreterWi {$(ALTSRC)\share\vm\services}.cpp.obj:: $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< +{$(ALTSRC)\share\vm\trace}.cpp.obj:: + $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + {$(ALTSRC)\share\vm\utilities}.cpp.obj:: $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< @@ -371,6 +389,18 @@ bytecodeInterpreterWithChecks.obj: ..\generated\jvmtifiles\bytecodeInterpreterWi {..\generated\jvmtifiles}.cpp.obj:: $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< +{$(ALTSRC)\share\vm\jfr}.cpp.obj:: + $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + +{$(ALTSRC)\share\vm\jfr\agent}.cpp.obj:: + $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + +{$(ALTSRC)\share\vm\jfr\agent\isolated_deps\util}.cpp.obj:: + $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + +{$(ALTSRC)\share\vm\jfr\jvm}.cpp.obj:: + $(CPP) $(CPP_FLAGS) $(CPP_USE_PCH) /c $< + default:: _build_pch_file.obj: diff --git a/src/share/vm/classfile/symbolTable.cpp b/src/share/vm/classfile/symbolTable.cpp index e3dd0862910f580427abe1a0777c7c4e1433cc3e..4dcdc533845c4745de64ece46de18fc179bb1b20 100644 --- a/src/share/vm/classfile/symbolTable.cpp +++ b/src/share/vm/classfile/symbolTable.cpp @@ -204,6 +204,24 @@ Symbol* SymbolTable::lookup_only(const char* name, int len, return s; } +// Look up the address of the literal in the SymbolTable for this Symbol* +// Do not create any new symbols +// Do not increment the reference count to keep this alive +Symbol** SymbolTable::lookup_symbol_addr(Symbol* sym){ + unsigned int hash = hash_symbol((char*)sym->bytes(), sym->utf8_length()); + int index = the_table()->hash_to_index(hash); + + for (HashtableEntry* e = the_table()->bucket(index); e != NULL; e = e->next()) { + if (e->hash() == hash) { + Symbol* literal_sym = e->literal(); + if (sym == literal_sym) { + return e->literal_addr(); + } + } + } + return NULL; +} + // Suggestion: Push unicode-based lookup all the way into the hashing // and probing logic, so there is no need for convert_to_utf8 until // an actual new Symbol* is created. diff --git a/src/share/vm/classfile/symbolTable.hpp b/src/share/vm/classfile/symbolTable.hpp index ca0b07d78883bb17e98698b89a0038f85bf3f47e..be74fab49d7544cc9ae6f9c37c19f479987f566a 100644 --- a/src/share/vm/classfile/symbolTable.hpp +++ b/src/share/vm/classfile/symbolTable.hpp @@ -144,6 +144,9 @@ public: static void release(Symbol* sym); + // Look up the address of the literal in the SymbolTable for this Symbol* + static Symbol** lookup_symbol_addr(Symbol* sym); + // jchar (utf16) version of lookups static Symbol* lookup_unicode(const jchar* name, int len, TRAPS); static Symbol* lookup_only_unicode(const jchar* name, int len, unsigned int& hash); diff --git a/src/share/vm/classfile/systemDictionary.cpp b/src/share/vm/classfile/systemDictionary.cpp index 1591b795fde1d1d25d66c604f052034681ff00a0..88ccc91b7907aeec18abb1b9da3f6aac922a5f6f 100644 --- a/src/share/vm/classfile/systemDictionary.cpp +++ b/src/share/vm/classfile/systemDictionary.cpp @@ -2131,6 +2131,12 @@ void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash, } } + // Assign a classid if one has not already been assigned. The + // counter does not need to be atomically incremented since this + // is only done while holding the SystemDictionary_lock. + // All loaded classes get a unique ID. + TRACE_INIT_ID(k); + // Check for a placeholder. If there, remove it and make a // new system dictionary entry. placeholders()->find_and_remove(p_index, p_hash, name, class_loader, THREAD); diff --git a/src/share/vm/oops/klass.cpp b/src/share/vm/oops/klass.cpp index 8541bd5d2b99ef47f074360b52f5a7e9f5aa48c8..77a2638f35e45e940d505c2c20233d52861f1ea2 100644 --- a/src/share/vm/oops/klass.cpp +++ b/src/share/vm/oops/klass.cpp @@ -158,6 +158,9 @@ klassOop Klass::base_create_klass_oop(KlassHandle& klass, int size, kl->set_next_sibling(NULL); kl->set_alloc_count(0); kl->set_alloc_size(0); +#ifdef TRACE_SET_KLASS_TRACE_ID + TRACE_SET_KLASS_TRACE_ID(kl, 0); +#endif kl->set_prototype_header(markOopDesc::prototype()); kl->set_biased_lock_revocation_count(0); diff --git a/src/share/vm/oops/klass.hpp b/src/share/vm/oops/klass.hpp index 407b1ef295af4869988c87897851ab0d4f625b91..131b14c6a0b111de7484fa5b88c81f99a4d23901 100644 --- a/src/share/vm/oops/klass.hpp +++ b/src/share/vm/oops/klass.hpp @@ -33,6 +33,7 @@ #include "oops/klassPS.hpp" #include "oops/oop.hpp" #include "runtime/orderAccess.hpp" +#include "trace/traceMacros.hpp" #include "utilities/accessFlags.hpp" #ifndef SERIALGC #include "gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp" @@ -80,6 +81,7 @@ // [last_biased_lock_bulk_revocation_time] (64 bits) // [prototype_header] // [biased_lock_revocation_count] +// [trace_id] // Forward declarations. @@ -263,6 +265,9 @@ class Klass : public Klass_vtbl { markOop _prototype_header; // Used when biased locking is both enabled and disabled for this type jint _biased_lock_revocation_count; +#ifdef TRACE_DEFINE_KLASS_TRACE_ID + TRACE_DEFINE_KLASS_TRACE_ID; +#endif public: // returns the enclosing klassOop @@ -683,6 +688,9 @@ class Klass : public Klass_vtbl { jlong last_biased_lock_bulk_revocation_time() { return _last_biased_lock_bulk_revocation_time; } void set_last_biased_lock_bulk_revocation_time(jlong cur_time) { _last_biased_lock_bulk_revocation_time = cur_time; } +#ifdef TRACE_DEFINE_KLASS_METHODS + TRACE_DEFINE_KLASS_METHODS; +#endif // garbage collection support virtual void follow_weak_klass_links( diff --git a/src/share/vm/oops/methodKlass.cpp b/src/share/vm/oops/methodKlass.cpp index f8d15108e7570ad01ea160bd07f3f2d5d69fee7a..b2d62358db84b0b0bc72f12db44eb7fe196a71e2 100644 --- a/src/share/vm/oops/methodKlass.cpp +++ b/src/share/vm/oops/methodKlass.cpp @@ -83,6 +83,7 @@ methodOop methodKlass::allocate(constMethodHandle xconst, m->set_max_stack(0); m->set_max_locals(0); m->set_intrinsic_id(vmIntrinsics::_none); + m->set_jfr_towrite(false); m->set_method_data(NULL); m->set_interpreter_throwout_count(0); m->set_vtable_index(methodOopDesc::garbage_vtable_index); diff --git a/src/share/vm/oops/methodOop.hpp b/src/share/vm/oops/methodOop.hpp index e8e73c63105aaa4d4cc424a0bc68348bee137f8d..cc9520a7f2ac8807e0283d71ba4c1694c7f3bf47 100644 --- a/src/share/vm/oops/methodOop.hpp +++ b/src/share/vm/oops/methodOop.hpp @@ -77,7 +77,7 @@ // | method_size | max_stack | // | max_locals | size_of_parameters | // |------------------------------------------------------| -// | intrinsic_id, (unused) | throwout_count | +// |intrinsic_id| flags | throwout_count | // |------------------------------------------------------| // | num_breakpoints | (unused) | // |------------------------------------------------------| @@ -124,6 +124,8 @@ class methodOopDesc : public oopDesc { u2 _max_locals; // Number of local variables used by this method u2 _size_of_parameters; // size of the parameter block (receiver + arguments) in words u1 _intrinsic_id; // vmSymbols::intrinsic_id (0 == _none) + u1 _jfr_towrite : 1, // Flags + : 7; u2 _interpreter_throwout_count; // Count of times method was exited via exception while interpreting u2 _number_of_breakpoints; // fullspeed debugging support InvocationCounter _invocation_counter; // Incremented before each activation of the method - used to trigger frequency-based optimizations @@ -225,6 +227,7 @@ class methodOopDesc : public oopDesc { void clear_number_of_breakpoints() { _number_of_breakpoints = 0; } // index into instanceKlass methods() array + // note: also used by jfr u2 method_idnum() const { return constMethod()->method_idnum(); } void set_method_idnum(u2 idnum) { constMethod()->set_method_idnum(idnum); } @@ -650,6 +653,9 @@ class methodOopDesc : public oopDesc { void init_intrinsic_id(); // updates from _none if a match static vmSymbols::SID klass_id_for_intrinsics(klassOop holder); + bool jfr_towrite() { return _jfr_towrite; } + void set_jfr_towrite(bool towrite) { _jfr_towrite = towrite; } + // On-stack replacement support bool has_osr_nmethod(int level, bool match_level) { return instanceKlass::cast(method_holder())->lookup_osr_nmethod(this, InvocationEntryBci, level, match_level) != NULL; diff --git a/src/share/vm/prims/jni.cpp b/src/share/vm/prims/jni.cpp index fc35714bbd5c05177f7bfee4f970cd9733d37598..833f6f1810c58295958556f7ec9bda096f96a9e9 100644 --- a/src/share/vm/prims/jni.cpp +++ b/src/share/vm/prims/jni.cpp @@ -48,6 +48,7 @@ #include "oops/typeArrayOop.hpp" #include "prims/jni.h" #include "prims/jniCheck.hpp" +#include "prims/jniExport.hpp" #include "prims/jniFastGetField.hpp" #include "prims/jvm.h" #include "prims/jvm_misc.hpp" @@ -66,6 +67,8 @@ #include "runtime/signature.hpp" #include "runtime/vm_operations.hpp" #include "services/runtimeService.hpp" +#include "trace/tracing.hpp" +#include "trace/traceEventTypes.hpp" #include "utilities/defaultStream.hpp" #include "utilities/dtrace.hpp" #include "utilities/events.hpp" @@ -5139,6 +5142,11 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, v if (JvmtiExport::should_post_thread_life()) { JvmtiExport::post_thread_start(thread); } + + EVENT_BEGIN(TraceEventThreadStart, event); + EVENT_COMMIT(event, + EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(thread->threadObj()))); + // Check if we should compile all classes on bootclasspath NOT_PRODUCT(if (CompileTheWorld) ClassLoader::compile_the_world();) // Since this is not a JVM_ENTRY we have to set the thread state manually before leaving. @@ -5337,6 +5345,10 @@ static jint attach_current_thread(JavaVM *vm, void **penv, void *_args, bool dae JvmtiExport::post_thread_start(thread); } + EVENT_BEGIN(TraceEventThreadStart, event); + EVENT_COMMIT(event, + EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(thread->threadObj()))); + *(JNIEnv**)penv = thread->jni_environment(); // Now leaving the VM, so change thread_state. This is normally automatically taken care @@ -5464,8 +5476,7 @@ jint JNICALL jni_GetEnv(JavaVM *vm, void **penv, jint version) { return ret; } - if (JvmtiExport::is_jvmti_version(version)) { - ret = JvmtiExport::get_jvmti_interface(vm, penv, version); + if (JniExportedInterface::GetExportedInterface(vm, penv, version, &ret)) { return ret; } diff --git a/src/share/vm/prims/jniExport.hpp b/src/share/vm/prims/jniExport.hpp new file mode 100644 index 0000000000000000000000000000000000000000..841b3dc5ccc876a532552d7a197a40e62375250a --- /dev/null +++ b/src/share/vm/prims/jniExport.hpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. 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. + * + * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_PRIMS_JNI_EXPORT_HPP +#define SHARE_VM_PRIMS_JNI_EXPORT_HPP + +#include "prims/jni.h" +#include "prims/jvmtiExport.hpp" + +class JniExportedInterface { + public: + static bool GetExportedInterface(JavaVM* vm, void** penv, jint version, jint* iface) { + if (JvmtiExport::is_jvmti_version(version)) { + *iface = JvmtiExport::get_jvmti_interface(vm, penv, version); + return true; + } + return false; + } +}; + +#endif // SHARE_VM_PRIMS_JNI_EXPORT_HPP diff --git a/src/share/vm/runtime/java.cpp b/src/share/vm/runtime/java.cpp index c04bd23caa2a39b610af01d5ce5f5a043ecbb92b..f256e515e9ca0729670d59f0deebd618e02511ef 100644 --- a/src/share/vm/runtime/java.cpp +++ b/src/share/vm/runtime/java.cpp @@ -57,6 +57,8 @@ #include "runtime/task.hpp" #include "runtime/timer.hpp" #include "runtime/vm_operations.hpp" +#include "trace/tracing.hpp" +#include "trace/traceEventTypes.hpp" #include "utilities/dtrace.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/histogram.hpp" @@ -502,6 +504,11 @@ void before_exit(JavaThread * thread) { if (JvmtiExport::should_post_thread_life()) { JvmtiExport::post_thread_end(thread); } + + EVENT_BEGIN(TraceEventThreadEnd, event); + EVENT_COMMIT(event, + EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(thread->threadObj()))); + // Always call even when there are not JVMTI environments yet, since environments // may be attached late and JVMTI must track phases of VM execution JvmtiExport::post_vm_death(); diff --git a/src/share/vm/runtime/mutexLocker.cpp b/src/share/vm/runtime/mutexLocker.cpp index 7653b5bef8477905cb1427afd1444f0f717d3004..0a2d8795bfd9a0e3f7aedf3405f212e9a4d35fe7 100644 --- a/src/share/vm/runtime/mutexLocker.cpp +++ b/src/share/vm/runtime/mutexLocker.cpp @@ -132,7 +132,13 @@ Mutex* HotCardCache_lock = NULL; Monitor* GCTaskManager_lock = NULL; Mutex* Management_lock = NULL; -Monitor* Service_lock = NULL; +Monitor* Service_lock = NULL; +Mutex* Stacktrace_lock = NULL; + +Monitor* JfrQuery_lock = NULL; +Monitor* JfrMsg_lock = NULL; +Mutex* JfrBuffer_lock = NULL; +Mutex* JfrStream_lock = NULL; #define MAX_NUM_MUTEX 128 static Monitor * _mutex_array[MAX_NUM_MUTEX]; @@ -207,6 +213,7 @@ void mutex_init() { def(Patching_lock , Mutex , special, true ); // used for safepointing and code patching. def(ObjAllocPost_lock , Monitor, special, false); def(Service_lock , Monitor, special, true ); // used for service thread operations + def(Stacktrace_lock , Mutex, special, true ); // used for JFR stacktrace database def(JmethodIdCreation_lock , Mutex , leaf, true ); // used for creating jmethodIDs. def(SystemDictionary_lock , Monitor, leaf, true ); // lookups done by VM thread @@ -271,6 +278,11 @@ void mutex_init() { def(Debug3_lock , Mutex , nonleaf+4, true ); def(ProfileVM_lock , Monitor, nonleaf+4, false); // used for profiling of the VMThread def(CompileThread_lock , Monitor, nonleaf+5, false ); + + def(JfrQuery_lock , Monitor, nonleaf, true); // JFR locks, keep these in consecutive order + def(JfrMsg_lock , Monitor, nonleaf+2, true); + def(JfrBuffer_lock , Mutex, nonleaf+3, true); + def(JfrStream_lock , Mutex, nonleaf+4, true); } GCMutexLocker::GCMutexLocker(Monitor * mutex) { diff --git a/src/share/vm/runtime/mutexLocker.hpp b/src/share/vm/runtime/mutexLocker.hpp index 37a3d3132b413665534a327cd9bac9d11a89c5c9..2a6bf369d79be039c861e6ce7fa93eee79a85bbf 100644 --- a/src/share/vm/runtime/mutexLocker.hpp +++ b/src/share/vm/runtime/mutexLocker.hpp @@ -135,6 +135,12 @@ extern Mutex* HotCardCache_lock; // protects the hot card cache extern Mutex* Management_lock; // a lock used to serialize JVM management extern Monitor* Service_lock; // a lock used for service thread operation +extern Mutex* Stacktrace_lock; // used to guard access to the stacktrace table + +extern Monitor* JfrQuery_lock; // protects JFR use +extern Monitor* JfrMsg_lock; // protects JFR messaging +extern Mutex* JfrBuffer_lock; // protects JFR buffer operations +extern Mutex* JfrStream_lock; // protects JFR stream access // A MutexLocker provides mutual exclusion with respect to a given mutex // for the scope which contains the locker. The lock is an OS lock, not diff --git a/src/share/vm/runtime/os.cpp b/src/share/vm/runtime/os.cpp index 773948971cd0746dd69c47643479c71f513aaec6..33495d66d43f9e2c5324bd39ec9e9d9a64072b6f 100644 --- a/src/share/vm/runtime/os.cpp +++ b/src/share/vm/runtime/os.cpp @@ -1101,6 +1101,7 @@ bool os::set_boot_path(char fileSep, char pathSep) { "%/lib/jsse.jar:" "%/lib/jce.jar:" "%/lib/charsets.jar:" + "%/lib/jfr.jar:" #ifdef __APPLE__ "%/lib/JObjC.jar:" #endif diff --git a/src/share/vm/runtime/thread.cpp b/src/share/vm/runtime/thread.cpp index da291036e8a637e54e6318f322221f087f4909a6..18c04a905d50576564f9a75515dfda551d2c08b8 100644 --- a/src/share/vm/runtime/thread.cpp +++ b/src/share/vm/runtime/thread.cpp @@ -73,6 +73,7 @@ #include "services/attachListener.hpp" #include "services/management.hpp" #include "services/threadService.hpp" +#include "trace/traceEventTypes.hpp" #include "utilities/defaultStream.hpp" #include "utilities/dtrace.hpp" #include "utilities/events.hpp" @@ -232,6 +233,7 @@ Thread::Thread() { CHECK_UNHANDLED_OOPS_ONLY(_gc_locked_out_count = 0;) _jvmti_env_iteration_count = 0; set_allocated_bytes(0); + set_trace_buffer(NULL); _vm_operation_started_count = 0; _vm_operation_completed_count = 0; _current_pending_monitor = NULL; @@ -1512,6 +1514,10 @@ void JavaThread::run() { JvmtiExport::post_thread_start(this); } + EVENT_BEGIN(TraceEventThreadStart, event); + EVENT_COMMIT(event, + EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(this->threadObj()))); + // We call another function to do the rest so we are sure that the stack addresses used // from there will be lower than the stack base just computed thread_main_inner(); @@ -1641,6 +1647,15 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) { } } + // Called before the java thread exit since we want to read info + // from java_lang_Thread object + EVENT_BEGIN(TraceEventThreadEnd, event); + EVENT_COMMIT(event, + EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(this->threadObj()))); + + // Call after last event on thread + EVENT_THREAD_EXIT(this); + // Call Thread.exit(). We try 3 times in case we got another Thread.stop during // the execution of the method. If that is not enough, then we don't really care. Thread.stop // is deprecated anyhow. @@ -3186,6 +3201,11 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { return status; } + // Must be run after init_ft which initializes ft_enabled + if (TRACE_INITIALIZE() != JNI_OK) { + vm_exit_during_initialization("Failed to initialize tracing backend"); + } + // Should be done after the heap is fully created main_thread->cache_global_variables(); @@ -3423,6 +3443,10 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { create_vm_init_libraries(); } + if (!TRACE_START()) { + vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION)); + } + // Notify JVMTI agents that VM initialization is complete - nop if no agents. JvmtiExport::post_vm_initialized(); diff --git a/src/share/vm/runtime/thread.hpp b/src/share/vm/runtime/thread.hpp index da13f12258b0b23a5edce5ceba21775da387f2b2..37bbf29372a9a6a376b0c017751df1c4eeb4857b 100644 --- a/src/share/vm/runtime/thread.hpp +++ b/src/share/vm/runtime/thread.hpp @@ -41,6 +41,7 @@ #include "runtime/stubRoutines.hpp" #include "runtime/threadLocalStorage.hpp" #include "runtime/unhandledOops.hpp" +#include "trace/tracing.hpp" #include "utilities/exceptions.hpp" #include "utilities/top.hpp" #ifndef SERIALGC @@ -246,6 +247,8 @@ class Thread: public ThreadShadow { jlong _allocated_bytes; // Cumulative number of bytes allocated on // the Java heap + TRACE_BUFFER _trace_buffer; // Thread-local buffer for tracing + int _vm_operation_started_count; // VM_Operation support int _vm_operation_completed_count; // VM_Operation support @@ -414,6 +417,9 @@ class Thread: public ThreadShadow { return allocated_bytes; } + TRACE_BUFFER trace_buffer() { return _trace_buffer; } + void set_trace_buffer(TRACE_BUFFER buf) { _trace_buffer = buf; } + // VM operation support int vm_operation_ticket() { return ++_vm_operation_started_count; } int vm_operation_completed_count() { return _vm_operation_completed_count; } diff --git a/src/share/vm/runtime/vm_operations.hpp b/src/share/vm/runtime/vm_operations.hpp index 77f262f6eda36efa2e33c0280ef57f4713e1f886..081c428a62bf534464f668f48bc8a787f239906f 100644 --- a/src/share/vm/runtime/vm_operations.hpp +++ b/src/share/vm/runtime/vm_operations.hpp @@ -93,6 +93,7 @@ template(HeapWalkOperation) \ template(HeapIterateOperation) \ template(ReportJavaOutOfMemory) \ + template(JFRCheckpoint) \ template(Exit) \ class VM_Operation: public CHeapObj { diff --git a/src/share/vm/trace/traceEventTypes.hpp b/src/share/vm/trace/traceEventTypes.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e7448aaebdffacd2dbdfaf04c2a3d14674daecb3 --- /dev/null +++ b/src/share/vm/trace/traceEventTypes.hpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. 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. + * + * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_TRACE_TRACE_EVENT_TYPES_HPP +#define SHARE_VM_TRACE_TRACE_EVENT_TYPES_HPP + +/* Empty, just a placeholder for tracing events */ + +#endif diff --git a/src/share/vm/trace/traceMacros.hpp b/src/share/vm/trace/traceMacros.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e9259352920aaa41a469efa69116839b1720fc6c --- /dev/null +++ b/src/share/vm/trace/traceMacros.hpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. 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. + * + * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_TRACE_TRACE_MACRO_HPP +#define SHARE_VM_TRACE_TRACE_MACRO_HPP + +#define EVENT_BEGIN(type, name) +#define EVENT_SET(name, field, value) +#define EVENT_COMMIT(name, ...) +#define EVENT_STARTED(name, time) +#define EVENT_ENDED(name, time) +#define EVENT_THREAD_EXIT(thread) + +#define TRACE_ENABLED 0 + +#define TRACE_INIT_ID(k) +#define TRACE_BUFFER void* + +#define TRACE_START() true +#define TRACE_INITIALIZE() 0 + +#endif diff --git a/src/share/vm/trace/tracing.hpp b/src/share/vm/trace/tracing.hpp new file mode 100644 index 0000000000000000000000000000000000000000..dcf0e5eb89389243da806020cff0c1a1796add8a --- /dev/null +++ b/src/share/vm/trace/tracing.hpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. 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. + * + * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_TRACE_TRACING_HPP +#define SHARE_VM_TRACE_TRACING_HPP + +#include "trace/traceMacros.hpp" + +#endif diff --git a/src/share/vm/utilities/globalDefinitions.hpp b/src/share/vm/utilities/globalDefinitions.hpp index 1425912ce37fdbca90f5fae65a9becf90973d766..89201f62f92e6085729ee24862a67091b6d1cf39 100644 --- a/src/share/vm/utilities/globalDefinitions.hpp +++ b/src/share/vm/utilities/globalDefinitions.hpp @@ -298,6 +298,11 @@ const jushort max_jushort = (jushort)-1; // 0xFFFF largest jushort const juint max_juint = (juint)-1; // 0xFFFFFFFF largest juint const julong max_julong = (julong)-1; // 0xFF....FF largest julong +typedef jbyte s1; +typedef jshort s2; +typedef jint s4; +typedef jlong s8; + //---------------------------------------------------------------------------------------------------- // JVM spec restrictions