1 /* 2 * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 #ifndef _JAVA_JVMTIENVTHREADSTATE_H_ 25 #define _JAVA_JVMTIENVTHREADSTATE_H_ 26 27 class JvmtiEnv; 28 29 /////////////////////////////////////////////////////////////// 30 // 31 // class JvmtiFramePop 32 // Used by : JvmtiFramePops 33 // Used by JVMTI methods: none directly. 34 // 35 // Wrapper class for FramePop, used in the JvmtiFramePops class. 36 // 37 // Two problems: 1) this isn't being used as a ValueObj class, in 38 // several places there are constructors for it. 2) It seems like 39 // overkill as a means to get an assert and name the geater than 40 // operator. I'm trying to to rewrite everything. 41 42 class JvmtiFramePop VALUE_OBJ_CLASS_SPEC { 43 private: 44 // Frame number counting from BOTTOM (oldest) frame; 45 // bottom frame == #0 46 int _frame_number; 47 public: 48 JvmtiFramePop() {} 49 JvmtiFramePop(int frame_number) { 50 assert(frame_number >= 0, "invalid frame number"); 51 _frame_number = frame_number; 52 } 53 54 int frame_number() { return _frame_number; } 55 int above_on_stack(JvmtiFramePop& other) { return _frame_number > other._frame_number; } 56 void print() PRODUCT_RETURN; 57 }; 58 59 60 /////////////////////////////////////////////////////////////// 61 // 62 // class JvmtiFramePops 63 // Used by : JvmtiThreadState 64 // Used by JVMTI methods: none directly. 65 // 66 // A collection of JvmtiFramePop. 67 // It records what frames on a threads stack should post frame_pop events when they're exited. 68 // 69 70 class JvmtiFramePops : public CHeapObj { 71 private: 72 GrowableArray<int>* _pops; 73 74 // should only be used by JvmtiEventControllerPrivate 75 // to insure they only occur at safepoints. 76 // Todo: add checks for safepoint 77 friend class JvmtiEventControllerPrivate; 78 void set(JvmtiFramePop& fp); 79 void clear(JvmtiFramePop& fp); 80 int clear_to(JvmtiFramePop& fp); 81 82 public: 83 JvmtiFramePops(); 84 ~JvmtiFramePops(); 85 86 bool contains(JvmtiFramePop& fp) { return _pops->contains(fp.frame_number()); } 87 int length() { return _pops->length(); } 88 void print() PRODUCT_RETURN; 89 }; 90 91 92 /////////////////////////////////////////////////////////////// 93 // 94 // class JvmtiEnvThreadState 95 // 96 // 2. Cache of pending frame_pop_events, created by NotifyFramePop 97 // and lazily initialized. 98 // 3: Location of last executed instruction, used to filter out duplicate 99 // events due to instruction rewriting. 100 101 class JvmtiEnvThreadState : public CHeapObj { 102 private: 103 friend class JvmtiEnv; 104 JavaThread *_thread; 105 JvmtiEnv *_env; 106 JvmtiEnvThreadState *_next; 107 jmethodID _current_method_id; 108 int _current_bci; 109 bool _breakpoint_posted; 110 bool _single_stepping_posted; 111 JvmtiEnvThreadEventEnable _event_enable; 112 void *_agent_thread_local_storage_data; // per env and per thread agent allocated data. 113 114 // Class used to store pending framepops. 115 // lazily initialized by get_frame_pops(); 116 JvmtiFramePops *_frame_pops; 117 118 inline void set_current_location(jmethodID method_id, int bci) { 119 _current_method_id = method_id; 120 _current_bci = bci; 121 } 122 123 friend class JvmtiEnvThreadStateIterator; 124 JvmtiEnvThreadState* next() { return _next; } 125 126 friend class JvmtiThreadState; 127 void set_next(JvmtiEnvThreadState* link) { _next = link; } 128 129 public: 130 JvmtiEnvThreadState(JavaThread *thread, JvmtiEnvBase *env); 131 ~JvmtiEnvThreadState(); 132 133 bool is_enabled(jvmtiEvent event_type) { return _event_enable.is_enabled(event_type); } 134 135 JvmtiEnvThreadEventEnable *event_enable() { return &_event_enable; } 136 void *get_agent_thread_local_storage_data() { return _agent_thread_local_storage_data; } 137 void set_agent_thread_local_storage_data (void *data) { _agent_thread_local_storage_data = data; } 138 139 140 // If the thread is in the given method at the given 141 // location just return. Otherwise, reset the current location 142 // and reset _breakpoint_posted and _single_stepping_posted. 143 // _breakpoint_posted and _single_stepping_posted are only cleared 144 // here. 145 void compare_and_set_current_location(methodOop method, address location, jvmtiEvent event); 146 147 void clear_current_location() { set_current_location((jmethodID)NULL, 0); } 148 149 void reset_current_location(jvmtiEvent event, bool enabled); 150 151 inline void set_breakpoint_posted() { _breakpoint_posted = true; } 152 inline void set_single_stepping_posted() { 153 _single_stepping_posted = true; 154 } 155 inline bool breakpoint_posted() { return _breakpoint_posted; } 156 inline bool single_stepping_posted() { 157 return _single_stepping_posted; 158 } 159 160 inline JavaThread *get_thread() { return _thread; } 161 inline JvmtiEnv *get_env() { return _env; } 162 163 // lazily initialize _frame_pops 164 JvmtiFramePops* get_frame_pops(); 165 166 bool has_frame_pops(); 167 168 // quickly test whether we should deliver a frame pop event on return from sp 169 bool is_frame_pop(int cur_stack_depth); 170 171 void set_frame_pop(int frame_number); 172 void clear_frame_pop(int frame_number); 173 void clear_to_frame_pop(int frame_number); 174 175 }; 176 177 #endif /* _JAVA_JVMTIENVTHREADSTATE_H_ */