| /* |
| * Copyright (c) 2003, 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_PRIMS_JVMTIENVTHREADSTATE_HPP |
| #define SHARE_VM_PRIMS_JVMTIENVTHREADSTATE_HPP |
| |
| #include "jvmtifiles/jvmti.h" |
| #include "memory/allocation.hpp" |
| #include "memory/allocation.inline.hpp" |
| #include "oops/instanceKlass.hpp" |
| #include "prims/jvmtiEventController.hpp" |
| #include "utilities/globalDefinitions.hpp" |
| #include "utilities/growableArray.hpp" |
| |
| class JvmtiEnv; |
| |
| /////////////////////////////////////////////////////////////// |
| // |
| // class JvmtiFramePop |
| // Used by : JvmtiFramePops |
| // Used by JVMTI methods: none directly. |
| // |
| // Wrapper class for FramePop, used in the JvmtiFramePops class. |
| // |
| // Two problems: 1) this isn't being used as a ValueObj class, in |
| // several places there are constructors for it. 2) It seems like |
| // overkill as a means to get an assert and name the geater than |
| // operator. I'm trying to to rewrite everything. |
| |
| class JvmtiFramePop VALUE_OBJ_CLASS_SPEC { |
| private: |
| // Frame number counting from BOTTOM (oldest) frame; |
| // bottom frame == #0 |
| int _frame_number; |
| public: |
| JvmtiFramePop() {} |
| JvmtiFramePop(int frame_number) { |
| assert(frame_number >= 0, "invalid frame number"); |
| _frame_number = frame_number; |
| } |
| |
| int frame_number() { return _frame_number; } |
| int above_on_stack(JvmtiFramePop& other) { return _frame_number > other._frame_number; } |
| void print() PRODUCT_RETURN; |
| }; |
| |
| |
| /////////////////////////////////////////////////////////////// |
| // |
| // class JvmtiFramePops |
| // Used by : JvmtiThreadState |
| // Used by JVMTI methods: none directly. |
| // |
| // A collection of JvmtiFramePop. |
| // It records what frames on a threads stack should post frame_pop events when they're exited. |
| // |
| |
| class JvmtiFramePops : public CHeapObj<mtInternal> { |
| private: |
| GrowableArray<int>* _pops; |
| |
| // should only be used by JvmtiEventControllerPrivate |
| // to insure they only occur at safepoints. |
| // Todo: add checks for safepoint |
| friend class JvmtiEventControllerPrivate; |
| void set(JvmtiFramePop& fp); |
| void clear(JvmtiFramePop& fp); |
| int clear_to(JvmtiFramePop& fp); |
| |
| public: |
| JvmtiFramePops(); |
| ~JvmtiFramePops(); |
| |
| bool contains(JvmtiFramePop& fp) { return _pops->contains(fp.frame_number()); } |
| int length() { return _pops->length(); } |
| void print() PRODUCT_RETURN; |
| }; |
| |
| |
| /////////////////////////////////////////////////////////////// |
| // |
| // class JvmtiEnvThreadState |
| // |
| // 2. Cache of pending frame_pop_events, created by NotifyFramePop |
| // and lazily initialized. |
| // 3: Location of last executed instruction, used to filter out duplicate |
| // events due to instruction rewriting. |
| |
| class JvmtiEnvThreadState : public CHeapObj<mtInternal> { |
| private: |
| friend class JvmtiEnv; |
| JavaThread *_thread; |
| JvmtiEnv *_env; |
| JvmtiEnvThreadState *_next; |
| jmethodID _current_method_id; |
| int _current_bci; |
| bool _breakpoint_posted; |
| bool _single_stepping_posted; |
| JvmtiEnvThreadEventEnable _event_enable; |
| void *_agent_thread_local_storage_data; // per env and per thread agent allocated data. |
| |
| // Class used to store pending framepops. |
| // lazily initialized by get_frame_pops(); |
| JvmtiFramePops *_frame_pops; |
| |
| inline void set_current_location(jmethodID method_id, int bci) { |
| _current_method_id = method_id; |
| _current_bci = bci; |
| } |
| |
| friend class JvmtiEnvThreadStateIterator; |
| JvmtiEnvThreadState* next() { return _next; } |
| |
| friend class JvmtiThreadState; |
| void set_next(JvmtiEnvThreadState* link) { _next = link; } |
| |
| public: |
| JvmtiEnvThreadState(JavaThread *thread, JvmtiEnvBase *env); |
| ~JvmtiEnvThreadState(); |
| |
| bool is_enabled(jvmtiEvent event_type) { return _event_enable.is_enabled(event_type); } |
| |
| JvmtiEnvThreadEventEnable *event_enable() { return &_event_enable; } |
| void *get_agent_thread_local_storage_data() { return _agent_thread_local_storage_data; } |
| void set_agent_thread_local_storage_data (void *data) { _agent_thread_local_storage_data = data; } |
| |
| |
| // If the thread is in the given method at the given |
| // location just return. Otherwise, reset the current location |
| // and reset _breakpoint_posted and _single_stepping_posted. |
| // _breakpoint_posted and _single_stepping_posted are only cleared |
| // here. |
| void compare_and_set_current_location(Method* method, address location, jvmtiEvent event); |
| |
| void clear_current_location() { set_current_location((jmethodID)NULL, 0); } |
| |
| void reset_current_location(jvmtiEvent event, bool enabled); |
| |
| inline void set_breakpoint_posted() { _breakpoint_posted = true; } |
| inline void set_single_stepping_posted() { |
| _single_stepping_posted = true; |
| } |
| inline bool breakpoint_posted() { return _breakpoint_posted; } |
| inline bool single_stepping_posted() { |
| return _single_stepping_posted; |
| } |
| |
| inline JavaThread *get_thread() { return _thread; } |
| inline JvmtiEnv *get_env() { return _env; } |
| |
| // lazily initialize _frame_pops |
| JvmtiFramePops* get_frame_pops(); |
| |
| bool has_frame_pops(); |
| |
| // quickly test whether we should deliver a frame pop event on return from sp |
| bool is_frame_pop(int cur_stack_depth); |
| |
| void set_frame_pop(int frame_number); |
| void clear_frame_pop(int frame_number); |
| void clear_to_frame_pop(int frame_number); |
| |
| }; |
| |
| #endif // SHARE_VM_PRIMS_JVMTIENVTHREADSTATE_HPP |