--- /dev/null 2016-10-25 08:46:44.038854975 +0200 +++ new/src/share/vm/evtrace/traceMetadata.inline.hpp 2016-10-25 10:40:15.274781561 +0200 @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2014, 2015, Dynatrace and/or its affiliates. All rights reserved. + * + * This file is part of the Lock Contention Tracing Subsystem for the HotSpot + * Virtual Machine, which is developed at Christian Doppler Laboratory on + * Monitoring and Evolution of Very-Large-Scale Software Systems. Please + * contact us at if you need additional information + * or have any questions. + * + * 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, see . + * + */ + +#ifndef SHARE_VM_EVTRACE_TRACEMETADATA_INLINE_HPP +#define SHARE_VM_EVTRACE_TRACEMETADATA_INLINE_HPP + +#include "runtime/thread.hpp" +#include "runtime/objectMonitor.hpp" +#include "runtime/objectMonitor.inline.hpp" +#include "jvmtifiles/jvmtiEnv.hpp" + +inline TraceTypes::timestamp TraceMetadata::time_now() { + return (TraceTypes::timestamp) os::javaTimeNanos(); +} + +inline TraceTypes::thread_id TraceMetadata::thread_id(Thread *t) { + assert(t != NULL, "thread is NULL"); + if (t->is_Java_thread()) { + JavaThread *jt = (JavaThread *) t; + return (TraceTypes::thread_id) java_lang_Thread::thread_id(jt->threadObj()); + } + return (TraceTypes::thread_id) -t->osthread()->thread_identifier(); +} + +inline TraceTypes::object_id TraceMetadata::object_id(oop obj) { + assert(obj != NULL, "object is NULL"); + return (TraceTypes::object_id) obj->identity_hash(); +} + +inline TraceTypes::objmonitor_id TraceMetadata::objmonitor_id(ObjectMonitor* m) { + assert(m != NULL, "object monitor is NULL"); + // NOTE: object monitors are native objects and are not moved by the garbage collector, so + // they can be identified by their address. However, monitors are allocated from pools and + // recycled after an object dies or on deflation. We must take this lifecycle into account + // when associating object monitors with objects. + return (TraceTypes::objmonitor_id) (intptr_t) m; +} + +inline TraceTypes::object_id TraceMetadata::objmonitor_object_id(ObjectMonitor* m) { + assert(m != NULL, "object monitor is NULL"); + if (m->header()->has_no_hash()) { + oop obj = (oop) m->object(); + return (TraceTypes::object_id) obj->identity_hash(); + } + return (TraceTypes::object_id) m->header()->hash(); +} + +inline TraceTypes::thread_state TraceMetadata::thread_state(Thread *t) { + assert(t != NULL, "thread is NULL"); + assert(t->is_Java_thread(), "only Java threads supported"); + + // just use JVMTI thread states + JavaThread *jt = (JavaThread *) t; + TraceTypes::thread_state state = 0; + if (jt->threadObj() != NULL) { // provides most state bits + state = (TraceTypes::thread_state) java_lang_Thread::get_thread_status(jt->threadObj()); + } + // additional state bits + if (jt->is_ext_suspended() || jt->is_external_suspend()) { // same as is_being_ext_suspended() but without locking + state |= JVMTI_THREAD_STATE_SUSPENDED; + } + JavaThreadState jts = jt->thread_state(); + if (jts == _thread_in_native) { + state |= JVMTI_THREAD_STATE_IN_NATIVE; + } + OSThread* osThread = jt->osthread(); + if (osThread != NULL && osThread->interrupted()) { + state |= JVMTI_THREAD_STATE_INTERRUPTED; + } + return state; +} + +inline TraceTypes::classloader_id TraceMetadata::classloader_id(ClassLoaderData* cld) { + return (TraceTypes::classloader_id) (intptr_t) cld; +} + +inline TraceTypes::class_id TraceMetadata::class_id(Klass *klass, bool &added) { + added = false; + if (!klass->is_tracing_known()) { + added = klass->atomic_mark_tracing_known(); + } + return (TraceTypes::class_id) (intptr_t) klass; +} + +inline TraceTypes::method_id TraceMetadata::method_id(Method* method, bool& added) { + assert(method->method_holder()->is_tracing_known(), "klass must be known"); + + added = false; + if (!method->is_tracing_known()) { + added = method->atomic_mark_tracing_known(); + } + return (TraceTypes::method_id) (intptr_t) method; +} + +inline TraceTypes::stack_id TraceMetadata::next_stack_id() { + assert(EnableEventTracingStackTraces, "stack traces not enabled"); + return (TraceTypes::stack_id) Atomic::add_ptr(1, &_last_stack_id); +} + +inline TraceTypes::seq_num TraceMetadata::next_global_seq() { + return (TraceTypes::seq_num) Atomic::add_ptr(1, &_last_global_seq); +} + +inline const CachedTraceStack * TraceMetadata::get_or_try_add_stack(CompositeTraceStack &ts, bool &known, TraceTypes::stack_id preallocated_id) { + return _stack_cache->get_or_try_add(ts, known, preallocated_id); +} + +inline void TraceMetadata::purge_unloading_classes(ClassLoaderData *loader) { + _stack_cache->purge_unloading_classes(loader); +} + +inline void TraceMetadata::purge_unloading_nmethod(const nmethod *nm) { + _stack_cache->purge_unloading_nmethod(nm); +} + +#endif /* SHARE_VM_EVTRACE_TRACEMETADATA_INLINE_HPP */