aoqi@0: /* aoqi@0: * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: * aoqi@0: */ aoqi@0: aoqi@0: #ifndef SHARE_VM_PRIMS_JVMTIENVTHREADSTATE_HPP aoqi@0: #define SHARE_VM_PRIMS_JVMTIENVTHREADSTATE_HPP aoqi@0: aoqi@0: #include "jvmtifiles/jvmti.h" aoqi@0: #include "memory/allocation.hpp" aoqi@0: #include "memory/allocation.inline.hpp" aoqi@0: #include "oops/instanceKlass.hpp" aoqi@0: #include "prims/jvmtiEventController.hpp" aoqi@0: #include "utilities/globalDefinitions.hpp" aoqi@0: #include "utilities/growableArray.hpp" aoqi@0: aoqi@0: class JvmtiEnv; aoqi@0: aoqi@0: /////////////////////////////////////////////////////////////// aoqi@0: // aoqi@0: // class JvmtiFramePop aoqi@0: // Used by : JvmtiFramePops aoqi@0: // Used by JVMTI methods: none directly. aoqi@0: // aoqi@0: // Wrapper class for FramePop, used in the JvmtiFramePops class. aoqi@0: // aoqi@0: // Two problems: 1) this isn't being used as a ValueObj class, in aoqi@0: // several places there are constructors for it. 2) It seems like aoqi@0: // overkill as a means to get an assert and name the geater than aoqi@0: // operator. I'm trying to to rewrite everything. aoqi@0: aoqi@0: class JvmtiFramePop VALUE_OBJ_CLASS_SPEC { aoqi@0: private: aoqi@0: // Frame number counting from BOTTOM (oldest) frame; aoqi@0: // bottom frame == #0 aoqi@0: int _frame_number; aoqi@0: public: aoqi@0: JvmtiFramePop() {} aoqi@0: JvmtiFramePop(int frame_number) { aoqi@0: assert(frame_number >= 0, "invalid frame number"); aoqi@0: _frame_number = frame_number; aoqi@0: } aoqi@0: aoqi@0: int frame_number() { return _frame_number; } aoqi@0: int above_on_stack(JvmtiFramePop& other) { return _frame_number > other._frame_number; } aoqi@0: void print() PRODUCT_RETURN; aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: /////////////////////////////////////////////////////////////// aoqi@0: // aoqi@0: // class JvmtiFramePops aoqi@0: // Used by : JvmtiThreadState aoqi@0: // Used by JVMTI methods: none directly. aoqi@0: // aoqi@0: // A collection of JvmtiFramePop. aoqi@0: // It records what frames on a threads stack should post frame_pop events when they're exited. aoqi@0: // aoqi@0: aoqi@0: class JvmtiFramePops : public CHeapObj { aoqi@0: private: aoqi@0: GrowableArray* _pops; aoqi@0: aoqi@0: // should only be used by JvmtiEventControllerPrivate aoqi@0: // to insure they only occur at safepoints. aoqi@0: // Todo: add checks for safepoint aoqi@0: friend class JvmtiEventControllerPrivate; aoqi@0: void set(JvmtiFramePop& fp); aoqi@0: void clear(JvmtiFramePop& fp); aoqi@0: int clear_to(JvmtiFramePop& fp); aoqi@0: aoqi@0: public: aoqi@0: JvmtiFramePops(); aoqi@0: ~JvmtiFramePops(); aoqi@0: aoqi@0: bool contains(JvmtiFramePop& fp) { return _pops->contains(fp.frame_number()); } aoqi@0: int length() { return _pops->length(); } aoqi@0: void print() PRODUCT_RETURN; aoqi@0: }; aoqi@0: aoqi@0: aoqi@0: /////////////////////////////////////////////////////////////// aoqi@0: // aoqi@0: // class JvmtiEnvThreadState aoqi@0: // aoqi@0: // 2. Cache of pending frame_pop_events, created by NotifyFramePop aoqi@0: // and lazily initialized. aoqi@0: // 3: Location of last executed instruction, used to filter out duplicate aoqi@0: // events due to instruction rewriting. aoqi@0: aoqi@0: class JvmtiEnvThreadState : public CHeapObj { aoqi@0: private: aoqi@0: friend class JvmtiEnv; aoqi@0: JavaThread *_thread; aoqi@0: JvmtiEnv *_env; aoqi@0: JvmtiEnvThreadState *_next; aoqi@0: jmethodID _current_method_id; aoqi@0: int _current_bci; aoqi@0: bool _breakpoint_posted; aoqi@0: bool _single_stepping_posted; aoqi@0: JvmtiEnvThreadEventEnable _event_enable; aoqi@0: void *_agent_thread_local_storage_data; // per env and per thread agent allocated data. aoqi@0: aoqi@0: // Class used to store pending framepops. aoqi@0: // lazily initialized by get_frame_pops(); aoqi@0: JvmtiFramePops *_frame_pops; aoqi@0: aoqi@0: inline void set_current_location(jmethodID method_id, int bci) { aoqi@0: _current_method_id = method_id; aoqi@0: _current_bci = bci; aoqi@0: } aoqi@0: aoqi@0: friend class JvmtiEnvThreadStateIterator; aoqi@0: JvmtiEnvThreadState* next() { return _next; } aoqi@0: aoqi@0: friend class JvmtiThreadState; aoqi@0: void set_next(JvmtiEnvThreadState* link) { _next = link; } aoqi@0: aoqi@0: public: aoqi@0: JvmtiEnvThreadState(JavaThread *thread, JvmtiEnvBase *env); aoqi@0: ~JvmtiEnvThreadState(); aoqi@0: aoqi@0: bool is_enabled(jvmtiEvent event_type) { return _event_enable.is_enabled(event_type); } aoqi@0: aoqi@0: JvmtiEnvThreadEventEnable *event_enable() { return &_event_enable; } aoqi@0: void *get_agent_thread_local_storage_data() { return _agent_thread_local_storage_data; } aoqi@0: void set_agent_thread_local_storage_data (void *data) { _agent_thread_local_storage_data = data; } aoqi@0: aoqi@0: aoqi@0: // If the thread is in the given method at the given aoqi@0: // location just return. Otherwise, reset the current location aoqi@0: // and reset _breakpoint_posted and _single_stepping_posted. aoqi@0: // _breakpoint_posted and _single_stepping_posted are only cleared aoqi@0: // here. aoqi@0: void compare_and_set_current_location(Method* method, address location, jvmtiEvent event); aoqi@0: aoqi@0: void clear_current_location() { set_current_location((jmethodID)NULL, 0); } aoqi@0: aoqi@0: void reset_current_location(jvmtiEvent event, bool enabled); aoqi@0: aoqi@0: inline void set_breakpoint_posted() { _breakpoint_posted = true; } aoqi@0: inline void set_single_stepping_posted() { aoqi@0: _single_stepping_posted = true; aoqi@0: } aoqi@0: inline bool breakpoint_posted() { return _breakpoint_posted; } aoqi@0: inline bool single_stepping_posted() { aoqi@0: return _single_stepping_posted; aoqi@0: } aoqi@0: aoqi@0: inline JavaThread *get_thread() { return _thread; } aoqi@0: inline JvmtiEnv *get_env() { return _env; } aoqi@0: aoqi@0: // lazily initialize _frame_pops aoqi@0: JvmtiFramePops* get_frame_pops(); aoqi@0: aoqi@0: bool has_frame_pops(); aoqi@0: aoqi@0: // quickly test whether we should deliver a frame pop event on return from sp aoqi@0: bool is_frame_pop(int cur_stack_depth); aoqi@0: aoqi@0: void set_frame_pop(int frame_number); aoqi@0: void clear_frame_pop(int frame_number); aoqi@0: void clear_to_frame_pop(int frame_number); aoqi@0: aoqi@0: }; aoqi@0: aoqi@0: #endif // SHARE_VM_PRIMS_JVMTIENVTHREADSTATE_HPP