src/share/vm/prims/jvmtiImpl.hpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File
*** old/src/share/vm/prims/jvmtiImpl.hpp	Tue Jan 25 11:42:51 2011
--- new/src/share/vm/prims/jvmtiImpl.hpp	Tue Jan 25 11:42:51 2011

*** 1,7 **** --- 1,7 ---- /* ! * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright (c) 1999, 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.
*** 431,439 **** --- 431,520 ---- static void print(); }; #endif // !JVMTI_KERNEL + /** + * When a thread (such as the compiler thread or VM thread) cannot post a + * JVMTI event itself because the event needs to be posted from a Java + * thread, then it can defer the event to the Service thread for posting. + * The information needed to post the event is encapsulated into this class + * and then enqueued onto the JvmtiDeferredEventQueue, where the Service + * thread will pick it up and post it. + * + * This is currently only used for posting compiled-method-load events, which + * we don't want posted from the compiler thread. + */ + class JvmtiDeferredEvent VALUE_OBJ_CLASS_SPEC { + private: + typedef enum { TYPE_NONE, TYPE_COMPILED_METHOD_LOAD } Type; + + Type _type; + union { + nmethod* _compiled_method_loaded; + } _event_data; + + JvmtiDeferredEvent() : _type(TYPE_NONE) {} + JvmtiDeferredEvent(Type t) : _type(t) {} + + void set_compiled_method_loaded(nmethod* nm) { + assert(_type == TYPE_COMPILED_METHOD_LOAD, "must be"); + _event_data._compiled_method_loaded = nm; + } + + nmethod* compiled_method_loaded() const { + assert(_type == TYPE_COMPILED_METHOD_LOAD, "must be"); + return _event_data._compiled_method_loaded; + } + + public: + + static JvmtiDeferredEvent null_event() { + return JvmtiDeferredEvent(); + } + + static JvmtiDeferredEvent compiled_method_load(nmethod* nm) { + JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_LOAD); + event.set_compiled_method_loaded(nm); + return event; + } + + // Actually posts the event. + void post(); + }; + + /** + * Events enqueued on this queue wake up the Service thread which dequeues + * and posts the events. The Service_lock is required to be held + * when enqueuing. + */ + class JvmtiDeferredEventQueue : AllStatic { + private: + class QueueNode : public CHeapObj { + private: + JvmtiDeferredEvent _event; + QueueNode* _next; + + public: + QueueNode() : _event(JvmtiDeferredEvent::null_event()), _next(NULL) {} + + const JvmtiDeferredEvent& event() const { return _event; } + QueueNode* next() const { return _next; } + + void set_event(const JvmtiDeferredEvent& ev) { _event = ev; } + void set_next(QueueNode* next) { _next = next; } + }; + + static QueueNode* _queue; + static QueueNode* _free_list; + + public: + // Must be holding Service_lock when calling these + static bool has_events() KERNEL_RETURN_(false); + static void enqueue(const JvmtiDeferredEvent& event) KERNEL_RETURN; + static JvmtiDeferredEvent dequeue() KERNEL_RETURN; + }; + // Utility macro that checks for NULL pointers: #define NULL_CHECK(X, Y) if ((X) == NULL) { return (Y); } #endif // SHARE_VM_PRIMS_JVMTIIMPL_HPP

src/share/vm/prims/jvmtiImpl.hpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File