Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/prims/jvmtiImpl.hpp
41144 views
1
/*
2
* Copyright (c) 1999, 2021, 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
25
#ifndef SHARE_PRIMS_JVMTIIMPL_HPP
26
#define SHARE_PRIMS_JVMTIIMPL_HPP
27
28
#include "jvmtifiles/jvmti.h"
29
#include "oops/objArrayOop.hpp"
30
#include "prims/jvmtiEnvThreadState.hpp"
31
#include "prims/jvmtiEventController.hpp"
32
#include "prims/jvmtiTrace.hpp"
33
#include "prims/jvmtiUtil.hpp"
34
#include "runtime/escapeBarrier.hpp"
35
#include "runtime/stackValueCollection.hpp"
36
#include "runtime/vmOperations.hpp"
37
#include "utilities/ostream.hpp"
38
39
//
40
// Forward Declarations
41
//
42
43
class JvmtiBreakpoint;
44
class JvmtiBreakpoints;
45
46
47
///////////////////////////////////////////////////////////////
48
//
49
// class GrowableCache, GrowableElement
50
// Used by : JvmtiBreakpointCache
51
// Used by JVMTI methods: none directly.
52
//
53
// GrowableCache is a permanent CHeap growable array of <GrowableElement *>
54
//
55
// In addition, the GrowableCache maintains a NULL terminated cache array of type address
56
// that's created from the element array using the function:
57
// address GrowableElement::getCacheValue().
58
//
59
// Whenever the GrowableArray changes size, the cache array gets recomputed into a new C_HEAP allocated
60
// block of memory. Additionally, every time the cache changes its position in memory, the
61
// void (*_listener_fun)(void *this_obj, address* cache)
62
// gets called with the cache's new address. This gives the user of the GrowableCache a callback
63
// to update its pointer to the address cache.
64
//
65
66
class GrowableElement : public CHeapObj<mtInternal> {
67
public:
68
virtual ~GrowableElement() {}
69
virtual address getCacheValue() =0;
70
virtual bool equals(GrowableElement* e) =0;
71
virtual GrowableElement *clone() =0;
72
};
73
74
class GrowableCache {
75
76
private:
77
// Object pointer passed into cache & listener functions.
78
void *_this_obj;
79
80
// Array of elements in the collection
81
GrowableArray<GrowableElement *> *_elements;
82
83
// Parallel array of cached values
84
address *_cache;
85
86
// Listener for changes to the _cache field.
87
// Called whenever the _cache field has it's value changed
88
// (but NOT when cached elements are recomputed).
89
void (*_listener_fun)(void *, address*);
90
91
static bool equals(void *, GrowableElement *);
92
93
// recache all elements after size change, notify listener
94
void recache();
95
96
public:
97
GrowableCache();
98
~GrowableCache();
99
100
void initialize(void *this_obj, void listener_fun(void *, address*) );
101
102
// number of elements in the collection
103
int length();
104
// get the value of the index element in the collection
105
GrowableElement* at(int index);
106
// find the index of the element, -1 if it doesn't exist
107
int find(GrowableElement* e);
108
// append a copy of the element to the end of the collection, notify listener
109
void append(GrowableElement* e);
110
// remove the element at index, notify listener
111
void remove (int index);
112
// clear out all elements and release all heap space, notify listener
113
void clear();
114
};
115
116
117
///////////////////////////////////////////////////////////////
118
//
119
// class JvmtiBreakpointCache
120
// Used by : JvmtiBreakpoints
121
// Used by JVMTI methods: none directly.
122
// Note : typesafe wrapper for GrowableCache of JvmtiBreakpoint
123
//
124
125
class JvmtiBreakpointCache : public CHeapObj<mtInternal> {
126
127
private:
128
GrowableCache _cache;
129
130
public:
131
JvmtiBreakpointCache() {}
132
~JvmtiBreakpointCache() {}
133
134
void initialize(void *this_obj, void listener_fun(void *, address*) ) {
135
_cache.initialize(this_obj, listener_fun);
136
}
137
138
int length() { return _cache.length(); }
139
JvmtiBreakpoint& at(int index) { return (JvmtiBreakpoint&) *(_cache.at(index)); }
140
int find(JvmtiBreakpoint& e) { return _cache.find((GrowableElement *) &e); }
141
void append(JvmtiBreakpoint& e) { _cache.append((GrowableElement *) &e); }
142
void remove (int index) { _cache.remove(index); }
143
};
144
145
146
///////////////////////////////////////////////////////////////
147
//
148
// class JvmtiBreakpoint
149
// Used by : JvmtiBreakpoints
150
// Used by JVMTI methods: SetBreakpoint, ClearBreakpoint, ClearAllBreakpoints
151
// Note: Extends GrowableElement for use in a GrowableCache
152
//
153
// A JvmtiBreakpoint describes a location (class, method, bci) to break at.
154
//
155
156
typedef void (Method::*method_action)(int _bci);
157
158
class JvmtiBreakpoint : public GrowableElement {
159
private:
160
Method* _method;
161
int _bci;
162
OopHandle _class_holder; // keeps _method memory from being deallocated
163
164
public:
165
JvmtiBreakpoint() : _method(NULL), _bci(0) {}
166
JvmtiBreakpoint(Method* m_method, jlocation location);
167
virtual ~JvmtiBreakpoint();
168
bool equals(JvmtiBreakpoint& bp);
169
void copy(JvmtiBreakpoint& bp);
170
address getBcp() const;
171
void each_method_version_do(method_action meth_act);
172
void set();
173
void clear();
174
void print_on(outputStream* out) const;
175
176
Method* method() { return _method; }
177
178
// GrowableElement implementation
179
address getCacheValue() { return getBcp(); }
180
bool equals(GrowableElement* e) { return equals((JvmtiBreakpoint&) *e); }
181
182
GrowableElement *clone() {
183
JvmtiBreakpoint *bp = new JvmtiBreakpoint();
184
bp->copy(*this);
185
return bp;
186
}
187
};
188
189
190
///////////////////////////////////////////////////////////////
191
//
192
// class JvmtiBreakpoints
193
// Used by : JvmtiCurrentBreakpoints
194
// Used by JVMTI methods: none directly
195
// Note: A Helper class
196
//
197
// JvmtiBreakpoints is a GrowableCache of JvmtiBreakpoint.
198
// All changes to the GrowableCache occur at a safepoint using VM_ChangeBreakpoints.
199
//
200
// Because _bps is only modified at safepoints, its possible to always use the
201
// cached byte code pointers from _bps without doing any synchronization (see JvmtiCurrentBreakpoints).
202
//
203
// It would be possible to make JvmtiBreakpoints a static class, but I've made it
204
// CHeap allocated to emphasize its similarity to JvmtiFramePops.
205
//
206
207
class JvmtiBreakpoints : public CHeapObj<mtInternal> {
208
private:
209
210
JvmtiBreakpointCache _bps;
211
212
// These should only be used by VM_ChangeBreakpoints
213
// to insure they only occur at safepoints.
214
// Todo: add checks for safepoint
215
friend class VM_ChangeBreakpoints;
216
void set_at_safepoint(JvmtiBreakpoint& bp);
217
void clear_at_safepoint(JvmtiBreakpoint& bp);
218
219
public:
220
JvmtiBreakpoints(void listener_fun(void *, address *));
221
~JvmtiBreakpoints();
222
223
int length();
224
void print();
225
226
int set(JvmtiBreakpoint& bp);
227
int clear(JvmtiBreakpoint& bp);
228
void clearall_in_class_at_safepoint(Klass* klass);
229
};
230
231
232
///////////////////////////////////////////////////////////////
233
//
234
// class JvmtiCurrentBreakpoints
235
//
236
// A static wrapper class for the JvmtiBreakpoints that provides:
237
// 1. a fast inlined function to check if a byte code pointer is a breakpoint (is_breakpoint).
238
// 2. a function for lazily creating the JvmtiBreakpoints class (this is not strictly necessary,
239
// but I'm copying the code from JvmtiThreadState which needs to lazily initialize
240
// JvmtiFramePops).
241
// 3. An oops_do entry point for GC'ing the breakpoint array.
242
//
243
244
class JvmtiCurrentBreakpoints : public AllStatic {
245
246
private:
247
248
// Current breakpoints, lazily initialized by get_jvmti_breakpoints();
249
static JvmtiBreakpoints *_jvmti_breakpoints;
250
251
// NULL terminated cache of byte-code pointers corresponding to current breakpoints.
252
// Updated only at safepoints (with listener_fun) when the cache is moved.
253
// It exists only to make is_breakpoint fast.
254
static address *_breakpoint_list;
255
static inline void set_breakpoint_list(address *breakpoint_list) { _breakpoint_list = breakpoint_list; }
256
257
// Listener for the GrowableCache in _jvmti_breakpoints, updates _breakpoint_list.
258
static void listener_fun(void *this_obj, address *cache);
259
260
public:
261
static void initialize();
262
static void destroy();
263
264
// lazily create _jvmti_breakpoints and _breakpoint_list
265
static JvmtiBreakpoints& get_jvmti_breakpoints();
266
};
267
268
///////////////////////////////////////////////////////////////
269
//
270
// class VM_ChangeBreakpoints
271
// Used by : JvmtiBreakpoints
272
// Used by JVMTI methods: none directly.
273
// Note: A Helper class.
274
//
275
// VM_ChangeBreakpoints implements a VM_Operation for ALL modifications to the JvmtiBreakpoints class.
276
//
277
278
class VM_ChangeBreakpoints : public VM_Operation {
279
private:
280
JvmtiBreakpoints* _breakpoints;
281
int _operation;
282
JvmtiBreakpoint* _bp;
283
284
public:
285
enum { SET_BREAKPOINT=0, CLEAR_BREAKPOINT=1 };
286
287
VM_ChangeBreakpoints(int operation, JvmtiBreakpoint *bp) {
288
JvmtiBreakpoints& current_bps = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();
289
_breakpoints = &current_bps;
290
_bp = bp;
291
_operation = operation;
292
assert(bp != NULL, "bp != NULL");
293
}
294
295
VMOp_Type type() const { return VMOp_ChangeBreakpoints; }
296
void doit();
297
};
298
299
300
///////////////////////////////////////////////////////////////
301
// The get/set local operations must only be done by the VM thread
302
// because the interpreter version needs to access oop maps, which can
303
// only safely be done by the VM thread
304
//
305
// I'm told that in 1.5 oop maps are now protected by a lock and
306
// we could get rid of the VM op
307
// However if the VM op is removed then the target thread must
308
// be suspended AND a lock will be needed to prevent concurrent
309
// setting of locals to the same java thread. This lock is needed
310
// to prevent compiledVFrames from trying to add deferred updates
311
// to the thread simultaneously.
312
//
313
class VM_GetOrSetLocal : public VM_Operation {
314
protected:
315
JavaThread* _thread;
316
JavaThread* _calling_thread;
317
jint _depth;
318
jint _index;
319
BasicType _type;
320
jvalue _value;
321
javaVFrame* _jvf;
322
bool _set;
323
324
EscapeBarrier _eb;
325
326
// It is possible to get the receiver out of a non-static native wrapper
327
// frame. Use VM_GetReceiver to do this.
328
virtual bool getting_receiver() const { return false; }
329
330
jvmtiError _result;
331
332
vframe* get_vframe();
333
javaVFrame* get_java_vframe();
334
bool check_slot_type_lvt(javaVFrame* vf);
335
bool check_slot_type_no_lvt(javaVFrame* vf);
336
337
public:
338
// Constructor for non-object getter
339
VM_GetOrSetLocal(JavaThread* thread, jint depth, jint index, BasicType type);
340
341
// Constructor for object or non-object setter
342
VM_GetOrSetLocal(JavaThread* thread, jint depth, jint index, BasicType type, jvalue value);
343
344
// Constructor for object getter
345
VM_GetOrSetLocal(JavaThread* thread, JavaThread* calling_thread, jint depth,
346
int index);
347
348
VMOp_Type type() const { return VMOp_GetOrSetLocal; }
349
jvalue value() { return _value; }
350
jvmtiError result() { return _result; }
351
352
bool doit_prologue();
353
void doit();
354
bool allow_nested_vm_operations() const;
355
const char* name() const { return "get/set locals"; }
356
357
// Check that the klass is assignable to a type with the given signature.
358
static bool is_assignable(const char* ty_sign, Klass* klass, Thread* thread);
359
};
360
361
class VM_GetReceiver : public VM_GetOrSetLocal {
362
protected:
363
virtual bool getting_receiver() const { return true; }
364
365
public:
366
VM_GetReceiver(JavaThread* thread, JavaThread* calling_thread, jint depth);
367
const char* name() const { return "get receiver"; }
368
};
369
370
371
///////////////////////////////////////////////////////////////
372
//
373
// class JvmtiSuspendControl
374
//
375
// Convenience routines for suspending and resuming threads.
376
//
377
// All attempts by JVMTI to suspend and resume threads must go through the
378
// JvmtiSuspendControl interface.
379
//
380
// methods return true if successful
381
//
382
class JvmtiSuspendControl : public AllStatic {
383
public:
384
// suspend the thread, taking it to a safepoint
385
static bool suspend(JavaThread *java_thread);
386
// resume the thread
387
static bool resume(JavaThread *java_thread);
388
389
static void print();
390
};
391
392
393
/**
394
* When a thread (such as the compiler thread or VM thread) cannot post a
395
* JVMTI event itself because the event needs to be posted from a Java
396
* thread, then it can defer the event to the Service thread for posting.
397
* The information needed to post the event is encapsulated into this class
398
* and then enqueued onto the JvmtiDeferredEventQueue, where the Service
399
* thread will pick it up and post it.
400
*
401
* This is currently only used for posting compiled-method-load and unload
402
* events, which we don't want posted from the compiler thread.
403
*/
404
class JvmtiDeferredEvent {
405
friend class JvmtiDeferredEventQueue;
406
private:
407
typedef enum {
408
TYPE_NONE,
409
TYPE_COMPILED_METHOD_LOAD,
410
TYPE_COMPILED_METHOD_UNLOAD,
411
TYPE_DYNAMIC_CODE_GENERATED,
412
TYPE_CLASS_UNLOAD
413
} Type;
414
415
Type _type;
416
union {
417
nmethod* compiled_method_load;
418
struct {
419
jmethodID method_id;
420
const void* code_begin;
421
} compiled_method_unload;
422
struct {
423
const char* name;
424
const void* code_begin;
425
const void* code_end;
426
} dynamic_code_generated;
427
struct {
428
const char* name;
429
} class_unload;
430
} _event_data;
431
432
JvmtiDeferredEvent(Type t) : _type(t) {}
433
434
public:
435
436
JvmtiDeferredEvent() : _type(TYPE_NONE) {}
437
438
// Factory methods
439
static JvmtiDeferredEvent compiled_method_load_event(nmethod* nm)
440
NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
441
static JvmtiDeferredEvent compiled_method_unload_event(
442
jmethodID id, const void* code) NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
443
static JvmtiDeferredEvent dynamic_code_generated_event(
444
const char* name, const void* begin, const void* end)
445
NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
446
static JvmtiDeferredEvent class_unload_event(
447
const char* name) NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
448
449
// Actually posts the event.
450
void post() NOT_JVMTI_RETURN;
451
void post_compiled_method_load_event(JvmtiEnv* env) NOT_JVMTI_RETURN;
452
void run_nmethod_entry_barriers() NOT_JVMTI_RETURN;
453
// Sweeper support to keep nmethods from being zombied while in the queue.
454
void nmethods_do(CodeBlobClosure* cf) NOT_JVMTI_RETURN;
455
// GC support to keep nmethod from being unloaded while in the queue.
456
void oops_do(OopClosure* f, CodeBlobClosure* cf) NOT_JVMTI_RETURN;
457
};
458
459
/**
460
* Events enqueued on this queue wake up the Service thread which dequeues
461
* and posts the events. The Service_lock is required to be held
462
* when operating on the queue.
463
*/
464
class JvmtiDeferredEventQueue : public CHeapObj<mtInternal> {
465
friend class JvmtiDeferredEvent;
466
private:
467
class QueueNode : public CHeapObj<mtInternal> {
468
private:
469
JvmtiDeferredEvent _event;
470
QueueNode* _next;
471
472
public:
473
QueueNode(const JvmtiDeferredEvent& event)
474
: _event(event), _next(NULL) {}
475
476
JvmtiDeferredEvent& event() { return _event; }
477
QueueNode* next() const { return _next; }
478
479
void set_next(QueueNode* next) { _next = next; }
480
};
481
482
QueueNode* _queue_head;
483
QueueNode* _queue_tail;
484
485
public:
486
JvmtiDeferredEventQueue() : _queue_head(NULL), _queue_tail(NULL) {}
487
488
bool has_events() NOT_JVMTI_RETURN_(false);
489
JvmtiDeferredEvent dequeue() NOT_JVMTI_RETURN_(JvmtiDeferredEvent());
490
491
// Post all events in the queue for the current Jvmti environment
492
void post(JvmtiEnv* env) NOT_JVMTI_RETURN;
493
void enqueue(JvmtiDeferredEvent event) NOT_JVMTI_RETURN;
494
void run_nmethod_entry_barriers();
495
496
// Sweeper support to keep nmethods from being zombied while in the queue.
497
void nmethods_do(CodeBlobClosure* cf) NOT_JVMTI_RETURN;
498
// GC support to keep nmethod from being unloaded while in the queue.
499
void oops_do(OopClosure* f, CodeBlobClosure* cf) NOT_JVMTI_RETURN;
500
};
501
502
// Utility macro that checks for NULL pointers:
503
#define NULL_CHECK(X, Y) if ((X) == NULL) { return (Y); }
504
505
#endif // SHARE_PRIMS_JVMTIIMPL_HPP
506
507