jvmtiEnvThreadState.hpp revision 1879:f95d63e2154a
1193323Sed/*
2193323Sed * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3193323Sed * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4193323Sed *
5193323Sed * This code is free software; you can redistribute it and/or modify it
6193323Sed * under the terms of the GNU General Public License version 2 only, as
7193323Sed * published by the Free Software Foundation.
8193323Sed *
9193323Sed * This code is distributed in the hope that it will be useful, but WITHOUT
10193323Sed * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11193323Sed * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12193323Sed * version 2 for more details (a copy is included in the LICENSE file that
13193323Sed * accompanied this code).
14243830Sdim *
15243830Sdim * You should have received a copy of the GNU General Public License version
16193323Sed * 2 along with this work; if not, write to the Free Software Foundation,
17239462Sdim * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18249423Sdim *
19193323Sed * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20239462Sdim * or visit www.oracle.com if you need additional information or have any
21249423Sdim * questions.
22249423Sdim *
23243830Sdim */
24239462Sdim
25239462Sdim#ifndef SHARE_VM_PRIMS_JVMTIENVTHREADSTATE_HPP
26193323Sed#define SHARE_VM_PRIMS_JVMTIENVTHREADSTATE_HPP
27239462Sdim
28239462Sdim#include "jvmtifiles/jvmti.h"
29239462Sdim#include "memory/allocation.hpp"
30193323Sed#include "memory/allocation.inline.hpp"
31193323Sed#include "oops/instanceKlass.hpp"
32239462Sdim#include "prims/jvmtiEventController.hpp"
33239462Sdim#include "utilities/globalDefinitions.hpp"
34243830Sdim#include "utilities/growableArray.hpp"
35243830Sdim
36243830Sdimclass JvmtiEnv;
37243830Sdim
38243830Sdim///////////////////////////////////////////////////////////////
39243830Sdim//
40243830Sdim// class JvmtiFramePop
41243830Sdim// Used by              : JvmtiFramePops
42243830Sdim// Used by JVMTI methods: none directly.
43239462Sdim//
44243830Sdim// Wrapper class for FramePop, used in the JvmtiFramePops class.
45243830Sdim//
46243830Sdim// Two problems: 1) this isn't being used as a ValueObj class, in
47243830Sdim// several places there are constructors for it. 2) It seems like
48243830Sdim// overkill as a means to get an assert and name the geater than
49243830Sdim// operator.  I'm trying to to rewrite everything.
50243830Sdim
51243830Sdimclass JvmtiFramePop VALUE_OBJ_CLASS_SPEC {
52243830Sdim private:
53243830Sdim  // Frame number counting from BOTTOM (oldest) frame;
54243830Sdim  // bottom frame == #0
55243830Sdim  int _frame_number;
56243830Sdim public:
57243830Sdim  JvmtiFramePop() {}
58243830Sdim  JvmtiFramePop(int frame_number) {
59243830Sdim    assert(frame_number >= 0, "invalid frame number");
60243830Sdim    _frame_number = frame_number;
61239462Sdim  }
62239462Sdim
63239462Sdim  int frame_number() { return _frame_number; }
64239462Sdim  int above_on_stack(JvmtiFramePop& other) { return _frame_number > other._frame_number; }
65239462Sdim  void print() PRODUCT_RETURN;
66239462Sdim};
67239462Sdim
68239462Sdim
69239462Sdim///////////////////////////////////////////////////////////////
70239462Sdim//
71239462Sdim// class JvmtiFramePops
72239462Sdim// Used by              : JvmtiThreadState
73239462Sdim// Used by JVMTI methods: none directly.
74239462Sdim//
75239462Sdim// A collection of JvmtiFramePop.
76239462Sdim// It records what frames on a threads stack should post frame_pop events when they're exited.
77239462Sdim//
78239462Sdim
79239462Sdimclass JvmtiFramePops : public CHeapObj {
80239462Sdim private:
81239462Sdim  GrowableArray<int>* _pops;
82239462Sdim
83239462Sdim  // should only be used by JvmtiEventControllerPrivate
84243830Sdim  // to insure they only occur at safepoints.
85243830Sdim  // Todo: add checks for safepoint
86243830Sdim  friend class JvmtiEventControllerPrivate;
87243830Sdim  void set(JvmtiFramePop& fp);
88243830Sdim  void clear(JvmtiFramePop& fp);
89243830Sdim  int clear_to(JvmtiFramePop& fp);
90249423Sdim
91249423Sdim public:
92243830Sdim  JvmtiFramePops();
93243830Sdim  ~JvmtiFramePops();
94243830Sdim
95239462Sdim  bool contains(JvmtiFramePop& fp) { return _pops->contains(fp.frame_number()); }
96239462Sdim  int length() { return _pops->length(); }
97243830Sdim  void print() PRODUCT_RETURN;
98239462Sdim};
99239462Sdim
100239462Sdim
101239462Sdim///////////////////////////////////////////////////////////////
102239462Sdim//
103239462Sdim// class JvmtiEnvThreadState
104239462Sdim//
105239462Sdim// 2. Cache of pending frame_pop_events, created by NotifyFramePop
106239462Sdim//    and lazily initialized.
107239462Sdim// 3: Location of last executed instruction, used to filter out duplicate
108239462Sdim//    events due to instruction rewriting.
109239462Sdim
110239462Sdimclass JvmtiEnvThreadState : public CHeapObj {
111193323Sedprivate:
112193323Sed  friend class JvmtiEnv;
113193323Sed  JavaThread        *_thread;
114195340Sed  JvmtiEnv          *_env;
115193323Sed  JvmtiEnvThreadState *_next;
116193323Sed  jmethodID         _current_method_id;
117193323Sed  int               _current_bci;
118193323Sed  bool              _breakpoint_posted;
119193323Sed  bool              _single_stepping_posted;
120193323Sed  JvmtiEnvThreadEventEnable _event_enable;
121221345Sdim  void              *_agent_thread_local_storage_data; // per env and per thread agent allocated data.
122224145Sdim
123224145Sdim  // Class used to store pending framepops.
124221345Sdim  // lazily initialized by get_frame_pops();
125221345Sdim  JvmtiFramePops *_frame_pops;
126221345Sdim
127221345Sdim  inline void set_current_location(jmethodID method_id, int bci) {
128221345Sdim    _current_method_id = method_id;
129224145Sdim    _current_bci  = bci;
130224145Sdim  }
131234353Sdim
132234353Sdim  friend class JvmtiEnvThreadStateIterator;
133234353Sdim  JvmtiEnvThreadState* next() { return _next; }
134234353Sdim
135234353Sdim  friend class JvmtiThreadState;
136234353Sdim  void set_next(JvmtiEnvThreadState* link) { _next = link; }
137234353Sdim
138224145Sdimpublic:
139234353Sdim  JvmtiEnvThreadState(JavaThread *thread, JvmtiEnvBase *env);
140234353Sdim  ~JvmtiEnvThreadState();
141234353Sdim
142234353Sdim  bool is_enabled(jvmtiEvent event_type) { return _event_enable.is_enabled(event_type); }
143234353Sdim
144234353Sdim  JvmtiEnvThreadEventEnable *event_enable() { return &_event_enable; }
145221345Sdim  void *get_agent_thread_local_storage_data() { return _agent_thread_local_storage_data; }
146234353Sdim  void set_agent_thread_local_storage_data (void *data) { _agent_thread_local_storage_data = data; }
147234353Sdim
148234353Sdim
149234353Sdim  // If the thread is in the given method at the given
150221345Sdim  // location just return.  Otherwise, reset the current location
151234353Sdim  // and reset _breakpoint_posted and _single_stepping_posted.
152234353Sdim  // _breakpoint_posted and _single_stepping_posted are only cleared
153193323Sed  // here.
154234353Sdim  void compare_and_set_current_location(methodOop method, address location, jvmtiEvent event);
155234353Sdim
156221345Sdim  void clear_current_location() { set_current_location((jmethodID)NULL, 0); }
157234353Sdim
158234353Sdim  void reset_current_location(jvmtiEvent event, bool enabled);
159234353Sdim
160234353Sdim  inline void set_breakpoint_posted()  { _breakpoint_posted = true; }
161234353Sdim  inline void set_single_stepping_posted() {
162234353Sdim    _single_stepping_posted = true;
163234353Sdim  }
164234353Sdim  inline bool breakpoint_posted() { return _breakpoint_posted; }
165193323Sed  inline bool single_stepping_posted() {
166221345Sdim    return _single_stepping_posted;
167224145Sdim  }
168193323Sed
169193323Sed  inline JavaThread *get_thread() { return _thread; }
170193323Sed  inline JvmtiEnv *get_env() { return _env; }
171193323Sed
172193323Sed  // lazily initialize _frame_pops
173193323Sed  JvmtiFramePops* get_frame_pops();
174224145Sdim
175193323Sed  bool has_frame_pops();
176193323Sed
177193323Sed  // quickly test whether we should deliver a frame pop event on return from sp
178224145Sdim  bool is_frame_pop(int cur_stack_depth);
179224145Sdim
180224145Sdim  void set_frame_pop(int frame_number);
181224145Sdim  void clear_frame_pop(int frame_number);
182193323Sed  void clear_to_frame_pop(int frame_number);
183193323Sed
184193323Sed};
185193323Sed
186234353Sdim#endif // SHARE_VM_PRIMS_JVMTIENVTHREADSTATE_HPP
187234353Sdim