Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/prims/jvmtiEnv.cpp
41144 views
1
/*
2
* Copyright (c) 2003, 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
#include "precompiled.hpp"
26
#include "classfile/classLoaderExt.hpp"
27
#include "classfile/javaClasses.inline.hpp"
28
#include "classfile/stringTable.hpp"
29
#include "classfile/modules.hpp"
30
#include "classfile/systemDictionary.hpp"
31
#include "classfile/vmClasses.hpp"
32
#include "classfile/vmSymbols.hpp"
33
#include "gc/shared/collectedHeap.hpp"
34
#include "interpreter/bytecodeStream.hpp"
35
#include "interpreter/interpreter.hpp"
36
#include "jfr/jfrEvents.hpp"
37
#include "jvmtifiles/jvmtiEnv.hpp"
38
#include "logging/log.hpp"
39
#include "logging/logConfiguration.hpp"
40
#include "memory/resourceArea.hpp"
41
#include "memory/universe.hpp"
42
#include "oops/instanceKlass.hpp"
43
#include "oops/klass.inline.hpp"
44
#include "oops/objArrayOop.inline.hpp"
45
#include "oops/oop.inline.hpp"
46
#include "prims/jniCheck.hpp"
47
#include "prims/jvm_misc.hpp"
48
#include "prims/jvmtiAgentThread.hpp"
49
#include "prims/jvmtiClassFileReconstituter.hpp"
50
#include "prims/jvmtiCodeBlobEvents.hpp"
51
#include "prims/jvmtiExtensions.hpp"
52
#include "prims/jvmtiGetLoadedClasses.hpp"
53
#include "prims/jvmtiImpl.hpp"
54
#include "prims/jvmtiManageCapabilities.hpp"
55
#include "prims/jvmtiRawMonitor.hpp"
56
#include "prims/jvmtiRedefineClasses.hpp"
57
#include "prims/jvmtiTagMap.hpp"
58
#include "prims/jvmtiThreadState.inline.hpp"
59
#include "prims/jvmtiUtil.hpp"
60
#include "runtime/arguments.hpp"
61
#include "runtime/deoptimization.hpp"
62
#include "runtime/fieldDescriptor.inline.hpp"
63
#include "runtime/handles.inline.hpp"
64
#include "runtime/interfaceSupport.inline.hpp"
65
#include "runtime/javaCalls.hpp"
66
#include "runtime/jfieldIDWorkaround.hpp"
67
#include "runtime/jniHandles.inline.hpp"
68
#include "runtime/objectMonitor.inline.hpp"
69
#include "runtime/osThread.hpp"
70
#include "runtime/reflectionUtils.hpp"
71
#include "runtime/signature.hpp"
72
#include "runtime/thread.inline.hpp"
73
#include "runtime/threadHeapSampler.hpp"
74
#include "runtime/threadSMR.hpp"
75
#include "runtime/timerTrace.hpp"
76
#include "runtime/vframe.inline.hpp"
77
#include "runtime/vmThread.hpp"
78
#include "services/threadService.hpp"
79
#include "utilities/exceptions.hpp"
80
#include "utilities/preserveException.hpp"
81
#include "utilities/utf8.hpp"
82
83
84
#define FIXLATER 0 // REMOVE this when completed.
85
86
// FIXLATER: hook into JvmtiTrace
87
#define TraceJVMTICalls false
88
89
JvmtiEnv::JvmtiEnv(jint version) : JvmtiEnvBase(version) {
90
}
91
92
JvmtiEnv::~JvmtiEnv() {
93
}
94
95
JvmtiEnv*
96
JvmtiEnv::create_a_jvmti(jint version) {
97
return new JvmtiEnv(version);
98
}
99
100
// VM operation class to copy jni function table at safepoint.
101
// More than one java threads or jvmti agents may be reading/
102
// modifying jni function tables. To reduce the risk of bad
103
// interaction b/w these threads it is copied at safepoint.
104
class VM_JNIFunctionTableCopier : public VM_Operation {
105
private:
106
const struct JNINativeInterface_ *_function_table;
107
public:
108
VM_JNIFunctionTableCopier(const struct JNINativeInterface_ *func_tbl) {
109
_function_table = func_tbl;
110
};
111
112
VMOp_Type type() const { return VMOp_JNIFunctionTableCopier; }
113
void doit() {
114
copy_jni_function_table(_function_table);
115
};
116
};
117
118
//
119
// Do not change the "prefix" marker below, everything above it is copied
120
// unchanged into the filled stub, everything below is controlled by the
121
// stub filler (only method bodies are carried forward, and then only for
122
// functionality still in the spec).
123
//
124
// end file prefix
125
126
//
127
// Memory Management functions
128
//
129
130
// mem_ptr - pre-checked for NULL
131
jvmtiError
132
JvmtiEnv::Allocate(jlong size, unsigned char** mem_ptr) {
133
return allocate(size, mem_ptr);
134
} /* end Allocate */
135
136
137
// mem - NULL is a valid value, must be checked
138
jvmtiError
139
JvmtiEnv::Deallocate(unsigned char* mem) {
140
return deallocate(mem);
141
} /* end Deallocate */
142
143
// java_thread - protected by ThreadsListHandle and pre-checked
144
// data - NULL is a valid value, must be checked
145
jvmtiError
146
JvmtiEnv::SetThreadLocalStorage(JavaThread* java_thread, const void* data) {
147
JvmtiThreadState* state = java_thread->jvmti_thread_state();
148
if (state == NULL) {
149
if (data == NULL) {
150
// leaving state unset same as data set to NULL
151
return JVMTI_ERROR_NONE;
152
}
153
// otherwise, create the state
154
state = JvmtiThreadState::state_for(java_thread);
155
if (state == NULL) {
156
return JVMTI_ERROR_THREAD_NOT_ALIVE;
157
}
158
}
159
state->env_thread_state(this)->set_agent_thread_local_storage_data((void*)data);
160
return JVMTI_ERROR_NONE;
161
} /* end SetThreadLocalStorage */
162
163
164
// thread - NOT protected by ThreadsListHandle and NOT pre-checked
165
// data_ptr - pre-checked for NULL
166
jvmtiError
167
JvmtiEnv::GetThreadLocalStorage(jthread thread, void** data_ptr) {
168
JavaThread* current_thread = JavaThread::current();
169
if (thread == NULL) {
170
JvmtiThreadState* state = current_thread->jvmti_thread_state();
171
*data_ptr = (state == NULL) ? NULL :
172
state->env_thread_state(this)->get_agent_thread_local_storage_data();
173
} else {
174
// jvmti_GetThreadLocalStorage is "in native" and doesn't transition
175
// the thread to _thread_in_vm. However, when the TLS for a thread
176
// other than the current thread is required we need to transition
177
// from native so as to resolve the jthread.
178
179
MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, current_thread));
180
ThreadInVMfromNative __tiv(current_thread);
181
VM_ENTRY_BASE(jvmtiError, JvmtiEnv::GetThreadLocalStorage , current_thread)
182
debug_only(VMNativeEntryWrapper __vew;)
183
184
JavaThread* java_thread = NULL;
185
ThreadsListHandle tlh(current_thread);
186
jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, NULL);
187
if (err != JVMTI_ERROR_NONE) {
188
return err;
189
}
190
191
JvmtiThreadState* state = java_thread->jvmti_thread_state();
192
*data_ptr = (state == NULL) ? NULL :
193
state->env_thread_state(this)->get_agent_thread_local_storage_data();
194
}
195
return JVMTI_ERROR_NONE;
196
} /* end GetThreadLocalStorage */
197
198
//
199
// Module functions
200
//
201
202
// module_count_ptr - pre-checked for NULL
203
// modules_ptr - pre-checked for NULL
204
jvmtiError
205
JvmtiEnv::GetAllModules(jint* module_count_ptr, jobject** modules_ptr) {
206
JvmtiModuleClosure jmc;
207
208
return jmc.get_all_modules(this, module_count_ptr, modules_ptr);
209
} /* end GetAllModules */
210
211
212
// class_loader - NULL is a valid value, must be pre-checked
213
// package_name - pre-checked for NULL
214
// module_ptr - pre-checked for NULL
215
jvmtiError
216
JvmtiEnv::GetNamedModule(jobject class_loader, const char* package_name, jobject* module_ptr) {
217
JavaThread* THREAD = JavaThread::current(); // For exception macros.
218
ResourceMark rm(THREAD);
219
Handle h_loader (THREAD, JNIHandles::resolve(class_loader));
220
// Check that loader is a subclass of java.lang.ClassLoader.
221
if (h_loader.not_null() && !java_lang_ClassLoader::is_subclass(h_loader->klass())) {
222
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
223
}
224
oop module = Modules::get_named_module(h_loader, package_name);
225
*module_ptr = module != NULL ? JNIHandles::make_local(THREAD, module) : NULL;
226
return JVMTI_ERROR_NONE;
227
} /* end GetNamedModule */
228
229
230
// module - pre-checked for NULL
231
// to_module - pre-checked for NULL
232
jvmtiError
233
JvmtiEnv::AddModuleReads(jobject module, jobject to_module) {
234
JavaThread* THREAD = JavaThread::current(); // For exception macros.
235
236
// check module
237
Handle h_module(THREAD, JNIHandles::resolve(module));
238
if (!java_lang_Module::is_instance(h_module())) {
239
return JVMTI_ERROR_INVALID_MODULE;
240
}
241
// check to_module
242
Handle h_to_module(THREAD, JNIHandles::resolve(to_module));
243
if (!java_lang_Module::is_instance(h_to_module())) {
244
return JVMTI_ERROR_INVALID_MODULE;
245
}
246
return JvmtiExport::add_module_reads(h_module, h_to_module, THREAD);
247
} /* end AddModuleReads */
248
249
250
// module - pre-checked for NULL
251
// pkg_name - pre-checked for NULL
252
// to_module - pre-checked for NULL
253
jvmtiError
254
JvmtiEnv::AddModuleExports(jobject module, const char* pkg_name, jobject to_module) {
255
JavaThread* THREAD = JavaThread::current(); // For exception macros.
256
Handle h_pkg = java_lang_String::create_from_str(pkg_name, THREAD);
257
258
// check module
259
Handle h_module(THREAD, JNIHandles::resolve(module));
260
if (!java_lang_Module::is_instance(h_module())) {
261
return JVMTI_ERROR_INVALID_MODULE;
262
}
263
// check to_module
264
Handle h_to_module(THREAD, JNIHandles::resolve(to_module));
265
if (!java_lang_Module::is_instance(h_to_module())) {
266
return JVMTI_ERROR_INVALID_MODULE;
267
}
268
return JvmtiExport::add_module_exports(h_module, h_pkg, h_to_module, THREAD);
269
} /* end AddModuleExports */
270
271
272
// module - pre-checked for NULL
273
// pkg_name - pre-checked for NULL
274
// to_module - pre-checked for NULL
275
jvmtiError
276
JvmtiEnv::AddModuleOpens(jobject module, const char* pkg_name, jobject to_module) {
277
JavaThread* THREAD = JavaThread::current(); // For exception macros.
278
Handle h_pkg = java_lang_String::create_from_str(pkg_name, THREAD);
279
280
// check module
281
Handle h_module(THREAD, JNIHandles::resolve(module));
282
if (!java_lang_Module::is_instance(h_module())) {
283
return JVMTI_ERROR_INVALID_MODULE;
284
}
285
// check to_module
286
Handle h_to_module(THREAD, JNIHandles::resolve(to_module));
287
if (!java_lang_Module::is_instance(h_to_module())) {
288
return JVMTI_ERROR_INVALID_MODULE;
289
}
290
return JvmtiExport::add_module_opens(h_module, h_pkg, h_to_module, THREAD);
291
} /* end AddModuleOpens */
292
293
294
// module - pre-checked for NULL
295
// service - pre-checked for NULL
296
jvmtiError
297
JvmtiEnv::AddModuleUses(jobject module, jclass service) {
298
JavaThread* THREAD = JavaThread::current(); // For exception macros.
299
300
// check module
301
Handle h_module(THREAD, JNIHandles::resolve(module));
302
if (!java_lang_Module::is_instance(h_module())) {
303
return JVMTI_ERROR_INVALID_MODULE;
304
}
305
// check service
306
Handle h_service(THREAD, JNIHandles::resolve_external_guard(service));
307
if (!java_lang_Class::is_instance(h_service()) ||
308
java_lang_Class::is_primitive(h_service())) {
309
return JVMTI_ERROR_INVALID_CLASS;
310
}
311
return JvmtiExport::add_module_uses(h_module, h_service, THREAD);
312
} /* end AddModuleUses */
313
314
315
// module - pre-checked for NULL
316
// service - pre-checked for NULL
317
// impl_class - pre-checked for NULL
318
jvmtiError
319
JvmtiEnv::AddModuleProvides(jobject module, jclass service, jclass impl_class) {
320
JavaThread* THREAD = JavaThread::current(); // For exception macros.
321
322
// check module
323
Handle h_module(THREAD, JNIHandles::resolve(module));
324
if (!java_lang_Module::is_instance(h_module())) {
325
return JVMTI_ERROR_INVALID_MODULE;
326
}
327
// check service
328
Handle h_service(THREAD, JNIHandles::resolve_external_guard(service));
329
if (!java_lang_Class::is_instance(h_service()) ||
330
java_lang_Class::is_primitive(h_service())) {
331
return JVMTI_ERROR_INVALID_CLASS;
332
}
333
// check impl_class
334
Handle h_impl_class(THREAD, JNIHandles::resolve_external_guard(impl_class));
335
if (!java_lang_Class::is_instance(h_impl_class()) ||
336
java_lang_Class::is_primitive(h_impl_class())) {
337
return JVMTI_ERROR_INVALID_CLASS;
338
}
339
return JvmtiExport::add_module_provides(h_module, h_service, h_impl_class, THREAD);
340
} /* end AddModuleProvides */
341
342
// module - pre-checked for NULL
343
// is_modifiable_class_ptr - pre-checked for NULL
344
jvmtiError
345
JvmtiEnv::IsModifiableModule(jobject module, jboolean* is_modifiable_module_ptr) {
346
JavaThread* current = JavaThread::current();
347
348
// check module
349
Handle h_module(current, JNIHandles::resolve(module));
350
if (!java_lang_Module::is_instance(h_module())) {
351
return JVMTI_ERROR_INVALID_MODULE;
352
}
353
354
*is_modifiable_module_ptr = JNI_TRUE;
355
return JVMTI_ERROR_NONE;
356
} /* end IsModifiableModule */
357
358
359
//
360
// Class functions
361
//
362
363
// class_count_ptr - pre-checked for NULL
364
// classes_ptr - pre-checked for NULL
365
jvmtiError
366
JvmtiEnv::GetLoadedClasses(jint* class_count_ptr, jclass** classes_ptr) {
367
return JvmtiGetLoadedClasses::getLoadedClasses(this, class_count_ptr, classes_ptr);
368
} /* end GetLoadedClasses */
369
370
371
// initiating_loader - NULL is a valid value, must be checked
372
// class_count_ptr - pre-checked for NULL
373
// classes_ptr - pre-checked for NULL
374
jvmtiError
375
JvmtiEnv::GetClassLoaderClasses(jobject initiating_loader, jint* class_count_ptr, jclass** classes_ptr) {
376
return JvmtiGetLoadedClasses::getClassLoaderClasses(this, initiating_loader,
377
class_count_ptr, classes_ptr);
378
} /* end GetClassLoaderClasses */
379
380
// k_mirror - may be primitive, this must be checked
381
// is_modifiable_class_ptr - pre-checked for NULL
382
jvmtiError
383
JvmtiEnv::IsModifiableClass(oop k_mirror, jboolean* is_modifiable_class_ptr) {
384
*is_modifiable_class_ptr = VM_RedefineClasses::is_modifiable_class(k_mirror)?
385
JNI_TRUE : JNI_FALSE;
386
return JVMTI_ERROR_NONE;
387
} /* end IsModifiableClass */
388
389
// class_count - pre-checked to be greater than or equal to 0
390
// classes - pre-checked for NULL
391
jvmtiError
392
JvmtiEnv::RetransformClasses(jint class_count, const jclass* classes) {
393
//TODO: add locking
394
395
int index;
396
JavaThread* current_thread = JavaThread::current();
397
ResourceMark rm(current_thread);
398
399
jvmtiClassDefinition* class_definitions =
400
NEW_RESOURCE_ARRAY(jvmtiClassDefinition, class_count);
401
NULL_CHECK(class_definitions, JVMTI_ERROR_OUT_OF_MEMORY);
402
403
for (index = 0; index < class_count; index++) {
404
HandleMark hm(current_thread);
405
406
jclass jcls = classes[index];
407
oop k_mirror = JNIHandles::resolve_external_guard(jcls);
408
if (k_mirror == NULL) {
409
return JVMTI_ERROR_INVALID_CLASS;
410
}
411
if (!k_mirror->is_a(vmClasses::Class_klass())) {
412
return JVMTI_ERROR_INVALID_CLASS;
413
}
414
415
if (!VM_RedefineClasses::is_modifiable_class(k_mirror)) {
416
return JVMTI_ERROR_UNMODIFIABLE_CLASS;
417
}
418
419
Klass* klass = java_lang_Class::as_Klass(k_mirror);
420
421
jint status = klass->jvmti_class_status();
422
if (status & (JVMTI_CLASS_STATUS_ERROR)) {
423
return JVMTI_ERROR_INVALID_CLASS;
424
}
425
426
InstanceKlass* ik = InstanceKlass::cast(klass);
427
if (ik->get_cached_class_file_bytes() == NULL) {
428
// Not cached, we need to reconstitute the class file from the
429
// VM representation. We don't attach the reconstituted class
430
// bytes to the InstanceKlass here because they have not been
431
// validated and we're not at a safepoint.
432
JvmtiClassFileReconstituter reconstituter(ik);
433
if (reconstituter.get_error() != JVMTI_ERROR_NONE) {
434
return reconstituter.get_error();
435
}
436
437
class_definitions[index].class_byte_count = (jint)reconstituter.class_file_size();
438
class_definitions[index].class_bytes = (unsigned char*)
439
reconstituter.class_file_bytes();
440
} else {
441
// it is cached, get it from the cache
442
class_definitions[index].class_byte_count = ik->get_cached_class_file_len();
443
class_definitions[index].class_bytes = ik->get_cached_class_file_bytes();
444
}
445
class_definitions[index].klass = jcls;
446
}
447
EventRetransformClasses event;
448
VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_retransform);
449
VMThread::execute(&op);
450
jvmtiError error = op.check_error();
451
if (error == JVMTI_ERROR_NONE) {
452
event.set_classCount(class_count);
453
event.set_redefinitionId(op.id());
454
event.commit();
455
}
456
return error;
457
} /* end RetransformClasses */
458
459
460
// class_count - pre-checked to be greater than or equal to 0
461
// class_definitions - pre-checked for NULL
462
jvmtiError
463
JvmtiEnv::RedefineClasses(jint class_count, const jvmtiClassDefinition* class_definitions) {
464
//TODO: add locking
465
EventRedefineClasses event;
466
VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine);
467
VMThread::execute(&op);
468
jvmtiError error = op.check_error();
469
if (error == JVMTI_ERROR_NONE) {
470
event.set_classCount(class_count);
471
event.set_redefinitionId(op.id());
472
event.commit();
473
}
474
return error;
475
} /* end RedefineClasses */
476
477
478
//
479
// Object functions
480
//
481
482
// size_ptr - pre-checked for NULL
483
jvmtiError
484
JvmtiEnv::GetObjectSize(jobject object, jlong* size_ptr) {
485
oop mirror = JNIHandles::resolve_external_guard(object);
486
NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT);
487
*size_ptr = (jlong)mirror->size() * wordSize;
488
return JVMTI_ERROR_NONE;
489
} /* end GetObjectSize */
490
491
//
492
// Method functions
493
//
494
495
// prefix - NULL is a valid value, must be checked
496
jvmtiError
497
JvmtiEnv::SetNativeMethodPrefix(const char* prefix) {
498
return prefix == NULL?
499
SetNativeMethodPrefixes(0, NULL) :
500
SetNativeMethodPrefixes(1, (char**)&prefix);
501
} /* end SetNativeMethodPrefix */
502
503
504
// prefix_count - pre-checked to be greater than or equal to 0
505
// prefixes - pre-checked for NULL
506
jvmtiError
507
JvmtiEnv::SetNativeMethodPrefixes(jint prefix_count, char** prefixes) {
508
// Have to grab JVMTI thread state lock to be sure that some thread
509
// isn't accessing the prefixes at the same time we are setting them.
510
// No locks during VM bring-up.
511
if (Threads::number_of_threads() == 0) {
512
return set_native_method_prefixes(prefix_count, prefixes);
513
} else {
514
MutexLocker mu(JvmtiThreadState_lock);
515
return set_native_method_prefixes(prefix_count, prefixes);
516
}
517
} /* end SetNativeMethodPrefixes */
518
519
//
520
// Event Management functions
521
//
522
523
// callbacks - NULL is a valid value, must be checked
524
// size_of_callbacks - pre-checked to be greater than or equal to 0
525
jvmtiError
526
JvmtiEnv::SetEventCallbacks(const jvmtiEventCallbacks* callbacks, jint size_of_callbacks) {
527
JvmtiEventController::set_event_callbacks(this, callbacks, size_of_callbacks);
528
return JVMTI_ERROR_NONE;
529
} /* end SetEventCallbacks */
530
531
532
// event_thread - NULL is a valid value, must be checked
533
jvmtiError
534
JvmtiEnv::SetEventNotificationMode(jvmtiEventMode mode, jvmtiEvent event_type, jthread event_thread, ...) {
535
if (event_thread == NULL) {
536
// Can be called at Agent_OnLoad() time with event_thread == NULL
537
// when Thread::current() does not work yet so we cannot create a
538
// ThreadsListHandle that is common to both thread-specific and
539
// global code paths.
540
541
// event_type must be valid
542
if (!JvmtiEventController::is_valid_event_type(event_type)) {
543
return JVMTI_ERROR_INVALID_EVENT_TYPE;
544
}
545
546
bool enabled = (mode == JVMTI_ENABLE);
547
548
// assure that needed capabilities are present
549
if (enabled && !JvmtiUtil::has_event_capability(event_type, get_capabilities())) {
550
return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
551
}
552
553
if (event_type == JVMTI_EVENT_CLASS_FILE_LOAD_HOOK && enabled) {
554
record_class_file_load_hook_enabled();
555
}
556
557
JvmtiEventController::set_user_enabled(this, (JavaThread*) NULL, event_type, enabled);
558
} else {
559
// We have a specified event_thread.
560
JavaThread* java_thread = NULL;
561
ThreadsListHandle tlh;
562
jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), event_thread, &java_thread, NULL);
563
if (err != JVMTI_ERROR_NONE) {
564
return err;
565
}
566
567
// event_type must be valid
568
if (!JvmtiEventController::is_valid_event_type(event_type)) {
569
return JVMTI_ERROR_INVALID_EVENT_TYPE;
570
}
571
572
// global events cannot be controlled at thread level.
573
if (JvmtiEventController::is_global_event(event_type)) {
574
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
575
}
576
577
bool enabled = (mode == JVMTI_ENABLE);
578
579
// assure that needed capabilities are present
580
if (enabled && !JvmtiUtil::has_event_capability(event_type, get_capabilities())) {
581
return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
582
}
583
584
if (event_type == JVMTI_EVENT_CLASS_FILE_LOAD_HOOK && enabled) {
585
record_class_file_load_hook_enabled();
586
}
587
JvmtiEventController::set_user_enabled(this, java_thread, event_type, enabled);
588
}
589
590
return JVMTI_ERROR_NONE;
591
} /* end SetEventNotificationMode */
592
593
//
594
// Capability functions
595
//
596
597
// capabilities_ptr - pre-checked for NULL
598
jvmtiError
599
JvmtiEnv::GetPotentialCapabilities(jvmtiCapabilities* capabilities_ptr) {
600
JvmtiManageCapabilities::get_potential_capabilities(get_capabilities(),
601
get_prohibited_capabilities(),
602
capabilities_ptr);
603
return JVMTI_ERROR_NONE;
604
} /* end GetPotentialCapabilities */
605
606
607
// capabilities_ptr - pre-checked for NULL
608
jvmtiError
609
JvmtiEnv::AddCapabilities(const jvmtiCapabilities* capabilities_ptr) {
610
return JvmtiManageCapabilities::add_capabilities(get_capabilities(),
611
get_prohibited_capabilities(),
612
capabilities_ptr,
613
get_capabilities());
614
} /* end AddCapabilities */
615
616
617
// capabilities_ptr - pre-checked for NULL
618
jvmtiError
619
JvmtiEnv::RelinquishCapabilities(const jvmtiCapabilities* capabilities_ptr) {
620
JvmtiManageCapabilities::relinquish_capabilities(get_capabilities(), capabilities_ptr, get_capabilities());
621
return JVMTI_ERROR_NONE;
622
} /* end RelinquishCapabilities */
623
624
625
// capabilities_ptr - pre-checked for NULL
626
jvmtiError
627
JvmtiEnv::GetCapabilities(jvmtiCapabilities* capabilities_ptr) {
628
JvmtiManageCapabilities::copy_capabilities(get_capabilities(), capabilities_ptr);
629
return JVMTI_ERROR_NONE;
630
} /* end GetCapabilities */
631
632
//
633
// Class Loader Search functions
634
//
635
636
// segment - pre-checked for NULL
637
jvmtiError
638
JvmtiEnv::AddToBootstrapClassLoaderSearch(const char* segment) {
639
jvmtiPhase phase = get_phase();
640
if (phase == JVMTI_PHASE_ONLOAD) {
641
Arguments::append_sysclasspath(segment);
642
return JVMTI_ERROR_NONE;
643
} else if (use_version_1_0_semantics()) {
644
// This JvmtiEnv requested version 1.0 semantics and this function
645
// is only allowed in the ONLOAD phase in version 1.0 so we need to
646
// return an error here.
647
return JVMTI_ERROR_WRONG_PHASE;
648
} else if (phase == JVMTI_PHASE_LIVE) {
649
// The phase is checked by the wrapper that called this function,
650
// but this thread could be racing with the thread that is
651
// terminating the VM so we check one more time.
652
653
// create the zip entry
654
ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment, true);
655
if (zip_entry == NULL) {
656
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
657
}
658
659
// add the jar file to the bootclasspath
660
log_info(class, load)("opened: %s", zip_entry->name());
661
#if INCLUDE_CDS
662
ClassLoaderExt::append_boot_classpath(zip_entry);
663
#else
664
ClassLoader::add_to_boot_append_entries(zip_entry);
665
#endif
666
return JVMTI_ERROR_NONE;
667
} else {
668
return JVMTI_ERROR_WRONG_PHASE;
669
}
670
671
} /* end AddToBootstrapClassLoaderSearch */
672
673
674
// segment - pre-checked for NULL
675
jvmtiError
676
JvmtiEnv::AddToSystemClassLoaderSearch(const char* segment) {
677
jvmtiPhase phase = get_phase();
678
679
if (phase == JVMTI_PHASE_ONLOAD) {
680
for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) {
681
if (strcmp("java.class.path", p->key()) == 0) {
682
p->append_value(segment);
683
break;
684
}
685
}
686
return JVMTI_ERROR_NONE;
687
} else if (phase == JVMTI_PHASE_LIVE) {
688
// The phase is checked by the wrapper that called this function,
689
// but this thread could be racing with the thread that is
690
// terminating the VM so we check one more time.
691
JavaThread* THREAD = JavaThread::current(); // For exception macros.
692
HandleMark hm(THREAD);
693
694
// create the zip entry (which will open the zip file and hence
695
// check that the segment is indeed a zip file).
696
ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment, false);
697
if (zip_entry == NULL) {
698
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
699
}
700
delete zip_entry; // no longer needed
701
702
// lock the loader
703
Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
704
ObjectLocker ol(loader, THREAD);
705
706
// need the path as java.lang.String
707
Handle path = java_lang_String::create_from_platform_dependent_str(segment, THREAD);
708
if (HAS_PENDING_EXCEPTION) {
709
CLEAR_PENDING_EXCEPTION;
710
return JVMTI_ERROR_INTERNAL;
711
}
712
713
// Invoke the appendToClassPathForInstrumentation method - if the method
714
// is not found it means the loader doesn't support adding to the class path
715
// in the live phase.
716
{
717
JavaValue res(T_VOID);
718
JavaCalls::call_special(&res,
719
loader,
720
loader->klass(),
721
vmSymbols::appendToClassPathForInstrumentation_name(),
722
vmSymbols::appendToClassPathForInstrumentation_signature(),
723
path,
724
THREAD);
725
if (HAS_PENDING_EXCEPTION) {
726
Symbol* ex_name = PENDING_EXCEPTION->klass()->name();
727
CLEAR_PENDING_EXCEPTION;
728
729
if (ex_name == vmSymbols::java_lang_NoSuchMethodError()) {
730
return JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED;
731
} else {
732
return JVMTI_ERROR_INTERNAL;
733
}
734
}
735
}
736
737
return JVMTI_ERROR_NONE;
738
} else {
739
return JVMTI_ERROR_WRONG_PHASE;
740
}
741
} /* end AddToSystemClassLoaderSearch */
742
743
//
744
// General functions
745
//
746
747
// phase_ptr - pre-checked for NULL
748
jvmtiError
749
JvmtiEnv::GetPhase(jvmtiPhase* phase_ptr) {
750
*phase_ptr = phase();
751
return JVMTI_ERROR_NONE;
752
} /* end GetPhase */
753
754
755
jvmtiError
756
JvmtiEnv::DisposeEnvironment() {
757
dispose();
758
return JVMTI_ERROR_NONE;
759
} /* end DisposeEnvironment */
760
761
762
// data - NULL is a valid value, must be checked
763
jvmtiError
764
JvmtiEnv::SetEnvironmentLocalStorage(const void* data) {
765
set_env_local_storage(data);
766
return JVMTI_ERROR_NONE;
767
} /* end SetEnvironmentLocalStorage */
768
769
770
// data_ptr - pre-checked for NULL
771
jvmtiError
772
JvmtiEnv::GetEnvironmentLocalStorage(void** data_ptr) {
773
*data_ptr = (void*)get_env_local_storage();
774
return JVMTI_ERROR_NONE;
775
} /* end GetEnvironmentLocalStorage */
776
777
// version_ptr - pre-checked for NULL
778
jvmtiError
779
JvmtiEnv::GetVersionNumber(jint* version_ptr) {
780
*version_ptr = JVMTI_VERSION;
781
return JVMTI_ERROR_NONE;
782
} /* end GetVersionNumber */
783
784
785
// name_ptr - pre-checked for NULL
786
jvmtiError
787
JvmtiEnv::GetErrorName(jvmtiError error, char** name_ptr) {
788
if (error < JVMTI_ERROR_NONE || error > JVMTI_ERROR_MAX) {
789
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
790
}
791
const char *name = JvmtiUtil::error_name(error);
792
if (name == NULL) {
793
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
794
}
795
size_t len = strlen(name) + 1;
796
jvmtiError err = allocate(len, (unsigned char**)name_ptr);
797
if (err == JVMTI_ERROR_NONE) {
798
memcpy(*name_ptr, name, len);
799
}
800
return err;
801
} /* end GetErrorName */
802
803
804
jvmtiError
805
JvmtiEnv::SetVerboseFlag(jvmtiVerboseFlag flag, jboolean value) {
806
LogLevelType level = value == 0 ? LogLevel::Off : LogLevel::Info;
807
switch (flag) {
808
case JVMTI_VERBOSE_OTHER:
809
// ignore
810
break;
811
case JVMTI_VERBOSE_CLASS:
812
LogConfiguration::configure_stdout(level, false, LOG_TAGS(class, unload));
813
LogConfiguration::configure_stdout(level, false, LOG_TAGS(class, load));
814
break;
815
case JVMTI_VERBOSE_GC:
816
LogConfiguration::configure_stdout(level, true, LOG_TAGS(gc));
817
break;
818
case JVMTI_VERBOSE_JNI:
819
level = value == 0 ? LogLevel::Off : LogLevel::Debug;
820
LogConfiguration::configure_stdout(level, true, LOG_TAGS(jni, resolve));
821
break;
822
default:
823
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
824
};
825
return JVMTI_ERROR_NONE;
826
} /* end SetVerboseFlag */
827
828
829
// format_ptr - pre-checked for NULL
830
jvmtiError
831
JvmtiEnv::GetJLocationFormat(jvmtiJlocationFormat* format_ptr) {
832
*format_ptr = JVMTI_JLOCATION_JVMBCI;
833
return JVMTI_ERROR_NONE;
834
} /* end GetJLocationFormat */
835
836
//
837
// Thread functions
838
//
839
840
// thread - NOT protected by ThreadsListHandle and NOT pre-checked
841
// thread_state_ptr - pre-checked for NULL
842
jvmtiError
843
JvmtiEnv::GetThreadState(jthread thread, jint* thread_state_ptr) {
844
JavaThread* current_thread = JavaThread::current();
845
JavaThread* java_thread = NULL;
846
oop thread_oop = NULL;
847
ThreadsListHandle tlh(current_thread);
848
849
if (thread == NULL) {
850
java_thread = current_thread;
851
thread_oop = java_thread->threadObj();
852
853
if (thread_oop == NULL || !thread_oop->is_a(vmClasses::Thread_klass())) {
854
return JVMTI_ERROR_INVALID_THREAD;
855
}
856
} else {
857
jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, &thread_oop);
858
if (err != JVMTI_ERROR_NONE) {
859
// We got an error code so we don't have a JavaThread *, but
860
// only return an error from here if we didn't get a valid
861
// thread_oop.
862
if (thread_oop == NULL) {
863
return err;
864
}
865
// We have a valid thread_oop so we can return some thread state.
866
}
867
}
868
869
// get most state bits
870
jint state = (jint)java_lang_Thread::get_thread_status(thread_oop);
871
872
if (java_thread != NULL) {
873
// We have a JavaThread* so add more state bits.
874
JavaThreadState jts = java_thread->thread_state();
875
876
if (java_thread->is_suspended()) {
877
state |= JVMTI_THREAD_STATE_SUSPENDED;
878
}
879
if (jts == _thread_in_native) {
880
state |= JVMTI_THREAD_STATE_IN_NATIVE;
881
}
882
if (java_thread->is_interrupted(false)) {
883
state |= JVMTI_THREAD_STATE_INTERRUPTED;
884
}
885
}
886
887
*thread_state_ptr = state;
888
return JVMTI_ERROR_NONE;
889
} /* end GetThreadState */
890
891
892
// thread_ptr - pre-checked for NULL
893
jvmtiError
894
JvmtiEnv::GetCurrentThread(jthread* thread_ptr) {
895
JavaThread* current_thread = JavaThread::current();
896
*thread_ptr = (jthread)JNIHandles::make_local(current_thread, current_thread->threadObj());
897
return JVMTI_ERROR_NONE;
898
} /* end GetCurrentThread */
899
900
901
// threads_count_ptr - pre-checked for NULL
902
// threads_ptr - pre-checked for NULL
903
jvmtiError
904
JvmtiEnv::GetAllThreads(jint* threads_count_ptr, jthread** threads_ptr) {
905
int nthreads = 0;
906
Handle *thread_objs = NULL;
907
Thread* current_thread = Thread::current();
908
ResourceMark rm(current_thread);
909
HandleMark hm(current_thread);
910
911
// enumerate threads (including agent threads)
912
ThreadsListEnumerator tle(current_thread, true);
913
nthreads = tle.num_threads();
914
*threads_count_ptr = nthreads;
915
916
if (nthreads == 0) {
917
*threads_ptr = NULL;
918
return JVMTI_ERROR_NONE;
919
}
920
921
thread_objs = NEW_RESOURCE_ARRAY(Handle, nthreads);
922
NULL_CHECK(thread_objs, JVMTI_ERROR_OUT_OF_MEMORY);
923
924
for (int i = 0; i < nthreads; i++) {
925
thread_objs[i] = Handle(tle.get_threadObj(i));
926
}
927
928
jthread *jthreads = new_jthreadArray(nthreads, thread_objs);
929
NULL_CHECK(jthreads, JVMTI_ERROR_OUT_OF_MEMORY);
930
931
*threads_ptr = jthreads;
932
return JVMTI_ERROR_NONE;
933
} /* end GetAllThreads */
934
935
936
// java_thread - protected by ThreadsListHandle and pre-checked
937
jvmtiError
938
JvmtiEnv::SuspendThread(JavaThread* java_thread) {
939
// don't allow hidden thread suspend request.
940
if (java_thread->is_hidden_from_external_view()) {
941
return JVMTI_ERROR_NONE;
942
}
943
if (java_thread->is_suspended()) {
944
return JVMTI_ERROR_THREAD_SUSPENDED;
945
}
946
if (!JvmtiSuspendControl::suspend(java_thread)) {
947
// Either the thread is already suspended or
948
// it was in the process of exiting.
949
if (java_thread->is_exiting()) {
950
return JVMTI_ERROR_THREAD_NOT_ALIVE;
951
}
952
return JVMTI_ERROR_THREAD_SUSPENDED;
953
}
954
return JVMTI_ERROR_NONE;
955
} /* end SuspendThread */
956
957
958
// request_count - pre-checked to be greater than or equal to 0
959
// request_list - pre-checked for NULL
960
// results - pre-checked for NULL
961
jvmtiError
962
JvmtiEnv::SuspendThreadList(jint request_count, const jthread* request_list, jvmtiError* results) {
963
int self_index = -1;
964
int needSafepoint = 0; // > 0 if we need a safepoint
965
JavaThread* current = JavaThread::current();
966
ThreadsListHandle tlh(current);
967
for (int i = 0; i < request_count; i++) {
968
JavaThread *java_thread = NULL;
969
jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), request_list[i], &java_thread, NULL);
970
if (err != JVMTI_ERROR_NONE) {
971
results[i] = err;
972
continue;
973
}
974
// don't allow hidden thread suspend request.
975
if (java_thread->is_hidden_from_external_view()) {
976
results[i] = JVMTI_ERROR_NONE; // indicate successful suspend
977
continue;
978
}
979
if (java_thread->is_suspended()) {
980
results[i] = JVMTI_ERROR_THREAD_SUSPENDED;
981
continue;
982
}
983
if (java_thread == current) {
984
self_index = i;
985
continue;
986
}
987
if (!JvmtiSuspendControl::suspend(java_thread)) {
988
// Either the thread is already suspended or
989
// it was in the process of exiting.
990
if (java_thread->is_exiting()) {
991
results[i] = JVMTI_ERROR_THREAD_NOT_ALIVE;
992
continue;
993
}
994
results[i] = JVMTI_ERROR_THREAD_SUSPENDED;
995
continue;
996
}
997
results[i] = JVMTI_ERROR_NONE; // indicate successful suspend
998
}
999
if (self_index >= 0) {
1000
if (!JvmtiSuspendControl::suspend(current)) {
1001
// Either the thread is already suspended or
1002
// it was in the process of exiting.
1003
if (current->is_exiting()) {
1004
results[self_index] = JVMTI_ERROR_THREAD_NOT_ALIVE;
1005
} else {
1006
results[self_index] = JVMTI_ERROR_THREAD_SUSPENDED;
1007
}
1008
} else {
1009
results[self_index] = JVMTI_ERROR_NONE; // indicate successful suspend
1010
}
1011
}
1012
// per-thread suspend results returned via results parameter
1013
return JVMTI_ERROR_NONE;
1014
} /* end SuspendThreadList */
1015
1016
1017
// java_thread - protected by ThreadsListHandle and pre-checked
1018
jvmtiError
1019
JvmtiEnv::ResumeThread(JavaThread* java_thread) {
1020
// don't allow hidden thread resume request.
1021
if (java_thread->is_hidden_from_external_view()) {
1022
return JVMTI_ERROR_NONE;
1023
}
1024
if (!java_thread->is_suspended()) {
1025
return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
1026
}
1027
if (!JvmtiSuspendControl::resume(java_thread)) {
1028
return JVMTI_ERROR_INTERNAL;
1029
}
1030
return JVMTI_ERROR_NONE;
1031
} /* end ResumeThread */
1032
1033
1034
// request_count - pre-checked to be greater than or equal to 0
1035
// request_list - pre-checked for NULL
1036
// results - pre-checked for NULL
1037
jvmtiError
1038
JvmtiEnv::ResumeThreadList(jint request_count, const jthread* request_list, jvmtiError* results) {
1039
ThreadsListHandle tlh;
1040
for (int i = 0; i < request_count; i++) {
1041
JavaThread* java_thread = NULL;
1042
jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), request_list[i], &java_thread, NULL);
1043
if (err != JVMTI_ERROR_NONE) {
1044
results[i] = err;
1045
continue;
1046
}
1047
// don't allow hidden thread resume request.
1048
if (java_thread->is_hidden_from_external_view()) {
1049
results[i] = JVMTI_ERROR_NONE; // indicate successful resume
1050
continue;
1051
}
1052
if (!java_thread->is_suspended()) {
1053
results[i] = JVMTI_ERROR_THREAD_NOT_SUSPENDED;
1054
continue;
1055
}
1056
1057
if (!JvmtiSuspendControl::resume(java_thread)) {
1058
results[i] = JVMTI_ERROR_INTERNAL;
1059
continue;
1060
}
1061
1062
results[i] = JVMTI_ERROR_NONE; // indicate successful resume
1063
}
1064
// per-thread resume results returned via results parameter
1065
return JVMTI_ERROR_NONE;
1066
} /* end ResumeThreadList */
1067
1068
1069
// java_thread - protected by ThreadsListHandle and pre-checked
1070
jvmtiError
1071
JvmtiEnv::StopThread(JavaThread* java_thread, jobject exception) {
1072
oop e = JNIHandles::resolve_external_guard(exception);
1073
NULL_CHECK(e, JVMTI_ERROR_NULL_POINTER);
1074
1075
JavaThread::send_async_exception(java_thread->threadObj(), e);
1076
1077
return JVMTI_ERROR_NONE;
1078
1079
} /* end StopThread */
1080
1081
1082
// thread - NOT protected by ThreadsListHandle and NOT pre-checked
1083
jvmtiError
1084
JvmtiEnv::InterruptThread(jthread thread) {
1085
JavaThread* current_thread = JavaThread::current();
1086
JavaThread* java_thread = NULL;
1087
ThreadsListHandle tlh(current_thread);
1088
jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, NULL);
1089
if (err != JVMTI_ERROR_NONE) {
1090
return err;
1091
}
1092
// Really this should be a Java call to Thread.interrupt to ensure the same
1093
// semantics, however historically this has not been done for some reason.
1094
// So we continue with that (which means we don't interact with any Java-level
1095
// Interruptible object) but we must set the Java-level interrupted state.
1096
java_lang_Thread::set_interrupted(JNIHandles::resolve(thread), true);
1097
java_thread->interrupt();
1098
1099
return JVMTI_ERROR_NONE;
1100
} /* end InterruptThread */
1101
1102
1103
// thread - NOT protected by ThreadsListHandle and NOT pre-checked
1104
// info_ptr - pre-checked for NULL
1105
jvmtiError
1106
JvmtiEnv::GetThreadInfo(jthread thread, jvmtiThreadInfo* info_ptr) {
1107
JavaThread* current_thread = JavaThread::current();
1108
ResourceMark rm(current_thread);
1109
HandleMark hm(current_thread);
1110
1111
ThreadsListHandle tlh(current_thread);
1112
1113
// if thread is NULL the current thread is used
1114
oop thread_oop = NULL;
1115
if (thread == NULL) {
1116
thread_oop = current_thread->threadObj();
1117
if (thread_oop == NULL || !thread_oop->is_a(vmClasses::Thread_klass())) {
1118
return JVMTI_ERROR_INVALID_THREAD;
1119
}
1120
} else {
1121
JavaThread* java_thread = NULL;
1122
jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, &thread_oop);
1123
if (err != JVMTI_ERROR_NONE) {
1124
// We got an error code so we don't have a JavaThread *, but
1125
// only return an error from here if we didn't get a valid
1126
// thread_oop.
1127
if (thread_oop == NULL) {
1128
return err;
1129
}
1130
// We have a valid thread_oop so we can return some thread info.
1131
}
1132
}
1133
1134
Handle thread_obj(current_thread, thread_oop);
1135
Handle name;
1136
ThreadPriority priority;
1137
Handle thread_group;
1138
Handle context_class_loader;
1139
bool is_daemon;
1140
1141
name = Handle(current_thread, java_lang_Thread::name(thread_obj()));
1142
priority = java_lang_Thread::priority(thread_obj());
1143
thread_group = Handle(current_thread, java_lang_Thread::threadGroup(thread_obj()));
1144
is_daemon = java_lang_Thread::is_daemon(thread_obj());
1145
1146
oop loader = java_lang_Thread::context_class_loader(thread_obj());
1147
context_class_loader = Handle(current_thread, loader);
1148
1149
{ const char *n;
1150
1151
if (name() != NULL) {
1152
n = java_lang_String::as_utf8_string(name());
1153
} else {
1154
int utf8_length = 0;
1155
n = UNICODE::as_utf8((jchar*) NULL, utf8_length);
1156
}
1157
1158
info_ptr->name = (char *) jvmtiMalloc(strlen(n)+1);
1159
if (info_ptr->name == NULL)
1160
return JVMTI_ERROR_OUT_OF_MEMORY;
1161
1162
strcpy(info_ptr->name, n);
1163
}
1164
info_ptr->is_daemon = is_daemon;
1165
info_ptr->priority = priority;
1166
1167
info_ptr->context_class_loader = (context_class_loader.is_null()) ? NULL :
1168
jni_reference(context_class_loader);
1169
info_ptr->thread_group = jni_reference(thread_group);
1170
1171
return JVMTI_ERROR_NONE;
1172
} /* end GetThreadInfo */
1173
1174
1175
// java_thread - protected by ThreadsListHandle and pre-checked
1176
// owned_monitor_count_ptr - pre-checked for NULL
1177
// owned_monitors_ptr - pre-checked for NULL
1178
jvmtiError
1179
JvmtiEnv::GetOwnedMonitorInfo(JavaThread* java_thread, jint* owned_monitor_count_ptr, jobject** owned_monitors_ptr) {
1180
jvmtiError err = JVMTI_ERROR_NONE;
1181
JavaThread* calling_thread = JavaThread::current();
1182
1183
EscapeBarrier eb(true, calling_thread, java_thread);
1184
if (!eb.deoptimize_objects(MaxJavaStackTraceDepth)) {
1185
return JVMTI_ERROR_OUT_OF_MEMORY;
1186
}
1187
1188
// growable array of jvmti monitors info on the C-heap
1189
GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list =
1190
new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, mtServiceability);
1191
1192
// It is only safe to perform the direct operation on the current
1193
// thread. All other usage needs to use a direct handshake for safety.
1194
if (java_thread == calling_thread) {
1195
err = get_owned_monitors(calling_thread, java_thread, owned_monitors_list);
1196
} else {
1197
// get owned monitors info with handshake
1198
GetOwnedMonitorInfoClosure op(calling_thread, this, owned_monitors_list);
1199
Handshake::execute(&op, java_thread);
1200
err = op.result();
1201
}
1202
jint owned_monitor_count = owned_monitors_list->length();
1203
if (err == JVMTI_ERROR_NONE) {
1204
if ((err = allocate(owned_monitor_count * sizeof(jobject *),
1205
(unsigned char**)owned_monitors_ptr)) == JVMTI_ERROR_NONE) {
1206
// copy into the returned array
1207
for (int i = 0; i < owned_monitor_count; i++) {
1208
(*owned_monitors_ptr)[i] =
1209
((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(i))->monitor;
1210
}
1211
*owned_monitor_count_ptr = owned_monitor_count;
1212
}
1213
}
1214
// clean up.
1215
for (int i = 0; i < owned_monitor_count; i++) {
1216
deallocate((unsigned char*)owned_monitors_list->at(i));
1217
}
1218
delete owned_monitors_list;
1219
1220
return err;
1221
} /* end GetOwnedMonitorInfo */
1222
1223
1224
// java_thread - protected by ThreadsListHandle and pre-checked
1225
// monitor_info_count_ptr - pre-checked for NULL
1226
// monitor_info_ptr - pre-checked for NULL
1227
jvmtiError
1228
JvmtiEnv::GetOwnedMonitorStackDepthInfo(JavaThread* java_thread, jint* monitor_info_count_ptr, jvmtiMonitorStackDepthInfo** monitor_info_ptr) {
1229
jvmtiError err = JVMTI_ERROR_NONE;
1230
JavaThread* calling_thread = JavaThread::current();
1231
1232
EscapeBarrier eb(true, calling_thread, java_thread);
1233
if (!eb.deoptimize_objects(MaxJavaStackTraceDepth)) {
1234
return JVMTI_ERROR_OUT_OF_MEMORY;
1235
}
1236
1237
// growable array of jvmti monitors info on the C-heap
1238
GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list =
1239
new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, mtServiceability);
1240
1241
// It is only safe to perform the direct operation on the current
1242
// thread. All other usage needs to use a direct handshake for safety.
1243
if (java_thread == calling_thread) {
1244
err = get_owned_monitors(calling_thread, java_thread, owned_monitors_list);
1245
} else {
1246
// get owned monitors info with handshake
1247
GetOwnedMonitorInfoClosure op(calling_thread, this, owned_monitors_list);
1248
Handshake::execute(&op, java_thread);
1249
err = op.result();
1250
}
1251
1252
jint owned_monitor_count = owned_monitors_list->length();
1253
if (err == JVMTI_ERROR_NONE) {
1254
if ((err = allocate(owned_monitor_count * sizeof(jvmtiMonitorStackDepthInfo),
1255
(unsigned char**)monitor_info_ptr)) == JVMTI_ERROR_NONE) {
1256
// copy to output array.
1257
for (int i = 0; i < owned_monitor_count; i++) {
1258
(*monitor_info_ptr)[i].monitor =
1259
((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(i))->monitor;
1260
(*monitor_info_ptr)[i].stack_depth =
1261
((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(i))->stack_depth;
1262
}
1263
}
1264
*monitor_info_count_ptr = owned_monitor_count;
1265
}
1266
1267
// clean up.
1268
for (int i = 0; i < owned_monitor_count; i++) {
1269
deallocate((unsigned char*)owned_monitors_list->at(i));
1270
}
1271
delete owned_monitors_list;
1272
1273
return err;
1274
} /* end GetOwnedMonitorStackDepthInfo */
1275
1276
1277
// java_thread - protected by ThreadsListHandle and pre-checked
1278
// monitor_ptr - pre-checked for NULL
1279
jvmtiError
1280
JvmtiEnv::GetCurrentContendedMonitor(JavaThread* java_thread, jobject* monitor_ptr) {
1281
jvmtiError err = JVMTI_ERROR_NONE;
1282
JavaThread* calling_thread = JavaThread::current();
1283
1284
// It is only safe to perform the direct operation on the current
1285
// thread. All other usage needs to use a direct handshake for safety.
1286
if (java_thread == calling_thread) {
1287
err = get_current_contended_monitor(calling_thread, java_thread, monitor_ptr);
1288
} else {
1289
// get contended monitor information with handshake
1290
GetCurrentContendedMonitorClosure op(calling_thread, this, monitor_ptr);
1291
Handshake::execute(&op, java_thread);
1292
err = op.result();
1293
}
1294
return err;
1295
} /* end GetCurrentContendedMonitor */
1296
1297
1298
// thread - NOT protected by ThreadsListHandle and NOT pre-checked
1299
// proc - pre-checked for NULL
1300
// arg - NULL is a valid value, must be checked
1301
jvmtiError
1302
JvmtiEnv::RunAgentThread(jthread thread, jvmtiStartFunction proc, const void* arg, jint priority) {
1303
JavaThread* current_thread = JavaThread::current();
1304
1305
JavaThread* java_thread = NULL;
1306
oop thread_oop = NULL;
1307
ThreadsListHandle tlh(current_thread);
1308
jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &java_thread, &thread_oop);
1309
if (err != JVMTI_ERROR_NONE) {
1310
// We got an error code so we don't have a JavaThread *, but
1311
// only return an error from here if we didn't get a valid
1312
// thread_oop.
1313
if (thread_oop == NULL) {
1314
return err;
1315
}
1316
// We have a valid thread_oop.
1317
}
1318
1319
if (java_thread != NULL) {
1320
// 'thread' refers to an existing JavaThread.
1321
return JVMTI_ERROR_INVALID_THREAD;
1322
}
1323
1324
if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) {
1325
return JVMTI_ERROR_INVALID_PRIORITY;
1326
}
1327
1328
Handle thread_hndl(current_thread, thread_oop);
1329
{
1330
MutexLocker mu(current_thread, Threads_lock); // grab Threads_lock
1331
1332
JvmtiAgentThread *new_thread = new JvmtiAgentThread(this, proc, arg);
1333
1334
// At this point it may be possible that no osthread was created for the
1335
// JavaThread due to lack of memory.
1336
if (new_thread == NULL || new_thread->osthread() == NULL) {
1337
if (new_thread != NULL) {
1338
new_thread->smr_delete();
1339
}
1340
return JVMTI_ERROR_OUT_OF_MEMORY;
1341
}
1342
1343
java_lang_Thread::set_thread(thread_hndl(), new_thread);
1344
java_lang_Thread::set_priority(thread_hndl(), (ThreadPriority)priority);
1345
java_lang_Thread::set_daemon(thread_hndl());
1346
1347
new_thread->set_threadObj(thread_hndl());
1348
Threads::add(new_thread);
1349
Thread::start(new_thread);
1350
} // unlock Threads_lock
1351
1352
return JVMTI_ERROR_NONE;
1353
} /* end RunAgentThread */
1354
1355
//
1356
// Thread Group functions
1357
//
1358
1359
// group_count_ptr - pre-checked for NULL
1360
// groups_ptr - pre-checked for NULL
1361
jvmtiError
1362
JvmtiEnv::GetTopThreadGroups(jint* group_count_ptr, jthreadGroup** groups_ptr) {
1363
JavaThread* current_thread = JavaThread::current();
1364
1365
// Only one top level thread group now.
1366
*group_count_ptr = 1;
1367
1368
// Allocate memory to store global-refs to the thread groups.
1369
// Assume this area is freed by caller.
1370
*groups_ptr = (jthreadGroup *) jvmtiMalloc((sizeof(jthreadGroup)) * (*group_count_ptr));
1371
1372
NULL_CHECK(*groups_ptr, JVMTI_ERROR_OUT_OF_MEMORY);
1373
1374
// Convert oop to Handle, then convert Handle to global-ref.
1375
{
1376
HandleMark hm(current_thread);
1377
Handle system_thread_group(current_thread, Universe::system_thread_group());
1378
*groups_ptr[0] = jni_reference(system_thread_group);
1379
}
1380
1381
return JVMTI_ERROR_NONE;
1382
} /* end GetTopThreadGroups */
1383
1384
1385
// info_ptr - pre-checked for NULL
1386
jvmtiError
1387
JvmtiEnv::GetThreadGroupInfo(jthreadGroup group, jvmtiThreadGroupInfo* info_ptr) {
1388
Thread* current_thread = Thread::current();
1389
ResourceMark rm(current_thread);
1390
HandleMark hm(current_thread);
1391
1392
Handle group_obj (current_thread, JNIHandles::resolve_external_guard(group));
1393
NULL_CHECK(group_obj(), JVMTI_ERROR_INVALID_THREAD_GROUP);
1394
1395
const char* name;
1396
Handle parent_group;
1397
bool is_daemon;
1398
ThreadPriority max_priority;
1399
1400
name = java_lang_ThreadGroup::name(group_obj());
1401
parent_group = Handle(current_thread, java_lang_ThreadGroup::parent(group_obj()));
1402
is_daemon = java_lang_ThreadGroup::is_daemon(group_obj());
1403
max_priority = java_lang_ThreadGroup::maxPriority(group_obj());
1404
1405
info_ptr->is_daemon = is_daemon;
1406
info_ptr->max_priority = max_priority;
1407
info_ptr->parent = jni_reference(parent_group);
1408
1409
if (name != NULL) {
1410
info_ptr->name = (char*)jvmtiMalloc(strlen(name)+1);
1411
NULL_CHECK(info_ptr->name, JVMTI_ERROR_OUT_OF_MEMORY);
1412
strcpy(info_ptr->name, name);
1413
} else {
1414
info_ptr->name = NULL;
1415
}
1416
1417
return JVMTI_ERROR_NONE;
1418
} /* end GetThreadGroupInfo */
1419
1420
1421
// thread_count_ptr - pre-checked for NULL
1422
// threads_ptr - pre-checked for NULL
1423
// group_count_ptr - pre-checked for NULL
1424
// groups_ptr - pre-checked for NULL
1425
jvmtiError
1426
JvmtiEnv::GetThreadGroupChildren(jthreadGroup group, jint* thread_count_ptr, jthread** threads_ptr, jint* group_count_ptr, jthreadGroup** groups_ptr) {
1427
JavaThread* current_thread = JavaThread::current();
1428
oop group_obj = JNIHandles::resolve_external_guard(group);
1429
NULL_CHECK(group_obj, JVMTI_ERROR_INVALID_THREAD_GROUP);
1430
1431
Handle *thread_objs = NULL;
1432
Handle *group_objs = NULL;
1433
int nthreads = 0;
1434
int ngroups = 0;
1435
int hidden_threads = 0;
1436
1437
ResourceMark rm(current_thread);
1438
HandleMark hm(current_thread);
1439
1440
Handle group_hdl(current_thread, group_obj);
1441
1442
{ // Cannot allow thread or group counts to change.
1443
ObjectLocker ol(group_hdl, current_thread);
1444
1445
nthreads = java_lang_ThreadGroup::nthreads(group_hdl());
1446
ngroups = java_lang_ThreadGroup::ngroups(group_hdl());
1447
1448
if (nthreads > 0) {
1449
ThreadsListHandle tlh(current_thread);
1450
objArrayOop threads = java_lang_ThreadGroup::threads(group_hdl());
1451
assert(nthreads <= threads->length(), "too many threads");
1452
thread_objs = NEW_RESOURCE_ARRAY(Handle,nthreads);
1453
for (int i = 0, j = 0; i < nthreads; i++) {
1454
oop thread_obj = threads->obj_at(i);
1455
assert(thread_obj != NULL, "thread_obj is NULL");
1456
JavaThread *java_thread = NULL;
1457
jvmtiError err = JvmtiExport::cv_oop_to_JavaThread(tlh.list(), thread_obj, &java_thread);
1458
if (err == JVMTI_ERROR_NONE) {
1459
// Have a valid JavaThread*.
1460
if (java_thread->is_hidden_from_external_view()) {
1461
// Filter out hidden java threads.
1462
hidden_threads++;
1463
continue;
1464
}
1465
} else {
1466
// We couldn't convert thread_obj into a JavaThread*.
1467
if (err == JVMTI_ERROR_INVALID_THREAD) {
1468
// The thread_obj does not refer to a java.lang.Thread object
1469
// so skip it.
1470
hidden_threads++;
1471
continue;
1472
}
1473
// We have a valid thread_obj, but no JavaThread*; the caller
1474
// can still have limited use for the thread_obj.
1475
}
1476
thread_objs[j++] = Handle(current_thread, thread_obj);
1477
}
1478
nthreads -= hidden_threads;
1479
} // ThreadsListHandle is destroyed here.
1480
1481
if (ngroups > 0) {
1482
objArrayOop groups = java_lang_ThreadGroup::groups(group_hdl());
1483
assert(ngroups <= groups->length(), "too many groups");
1484
group_objs = NEW_RESOURCE_ARRAY(Handle,ngroups);
1485
for (int i = 0; i < ngroups; i++) {
1486
oop group_obj = groups->obj_at(i);
1487
assert(group_obj != NULL, "group_obj != NULL");
1488
group_objs[i] = Handle(current_thread, group_obj);
1489
}
1490
}
1491
} // ThreadGroup unlocked here
1492
1493
*group_count_ptr = ngroups;
1494
*thread_count_ptr = nthreads;
1495
*threads_ptr = new_jthreadArray(nthreads, thread_objs);
1496
*groups_ptr = new_jthreadGroupArray(ngroups, group_objs);
1497
if ((nthreads > 0) && (*threads_ptr == NULL)) {
1498
return JVMTI_ERROR_OUT_OF_MEMORY;
1499
}
1500
if ((ngroups > 0) && (*groups_ptr == NULL)) {
1501
return JVMTI_ERROR_OUT_OF_MEMORY;
1502
}
1503
1504
return JVMTI_ERROR_NONE;
1505
} /* end GetThreadGroupChildren */
1506
1507
1508
//
1509
// Stack Frame functions
1510
//
1511
1512
// java_thread - protected by ThreadsListHandle and pre-checked
1513
// max_frame_count - pre-checked to be greater than or equal to 0
1514
// frame_buffer - pre-checked for NULL
1515
// count_ptr - pre-checked for NULL
1516
jvmtiError
1517
JvmtiEnv::GetStackTrace(JavaThread* java_thread, jint start_depth, jint max_frame_count, jvmtiFrameInfo* frame_buffer, jint* count_ptr) {
1518
jvmtiError err = JVMTI_ERROR_NONE;
1519
1520
// It is only safe to perform the direct operation on the current
1521
// thread. All other usage needs to use a direct handshake for safety.
1522
if (java_thread == JavaThread::current()) {
1523
err = get_stack_trace(java_thread, start_depth, max_frame_count, frame_buffer, count_ptr);
1524
} else {
1525
// Get stack trace with handshake.
1526
GetStackTraceClosure op(this, start_depth, max_frame_count, frame_buffer, count_ptr);
1527
Handshake::execute(&op, java_thread);
1528
err = op.result();
1529
}
1530
1531
return err;
1532
} /* end GetStackTrace */
1533
1534
1535
// max_frame_count - pre-checked to be greater than or equal to 0
1536
// stack_info_ptr - pre-checked for NULL
1537
// thread_count_ptr - pre-checked for NULL
1538
jvmtiError
1539
JvmtiEnv::GetAllStackTraces(jint max_frame_count, jvmtiStackInfo** stack_info_ptr, jint* thread_count_ptr) {
1540
jvmtiError err = JVMTI_ERROR_NONE;
1541
JavaThread* calling_thread = JavaThread::current();
1542
1543
// JVMTI get stack traces at safepoint.
1544
VM_GetAllStackTraces op(this, calling_thread, max_frame_count);
1545
VMThread::execute(&op);
1546
*thread_count_ptr = op.final_thread_count();
1547
*stack_info_ptr = op.stack_info();
1548
err = op.result();
1549
return err;
1550
} /* end GetAllStackTraces */
1551
1552
1553
// thread_count - pre-checked to be greater than or equal to 0
1554
// thread_list - pre-checked for NULL
1555
// max_frame_count - pre-checked to be greater than or equal to 0
1556
// stack_info_ptr - pre-checked for NULL
1557
jvmtiError
1558
JvmtiEnv::GetThreadListStackTraces(jint thread_count, const jthread* thread_list, jint max_frame_count, jvmtiStackInfo** stack_info_ptr) {
1559
jvmtiError err = JVMTI_ERROR_NONE;
1560
1561
if (thread_count == 1) {
1562
// Use direct handshake if we need to get only one stack trace.
1563
JavaThread *current_thread = JavaThread::current();
1564
ThreadsListHandle tlh(current_thread);
1565
JavaThread *java_thread;
1566
err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), *thread_list, &java_thread, NULL);
1567
if (err != JVMTI_ERROR_NONE) {
1568
return err;
1569
}
1570
1571
GetSingleStackTraceClosure op(this, current_thread, *thread_list, max_frame_count);
1572
Handshake::execute(&op, java_thread);
1573
err = op.result();
1574
if (err == JVMTI_ERROR_NONE) {
1575
*stack_info_ptr = op.stack_info();
1576
}
1577
} else {
1578
// JVMTI get stack traces at safepoint.
1579
VM_GetThreadListStackTraces op(this, thread_count, thread_list, max_frame_count);
1580
VMThread::execute(&op);
1581
err = op.result();
1582
if (err == JVMTI_ERROR_NONE) {
1583
*stack_info_ptr = op.stack_info();
1584
}
1585
}
1586
return err;
1587
} /* end GetThreadListStackTraces */
1588
1589
1590
// java_thread - protected by ThreadsListHandle and pre-checked
1591
// count_ptr - pre-checked for NULL
1592
jvmtiError
1593
JvmtiEnv::GetFrameCount(JavaThread* java_thread, jint* count_ptr) {
1594
jvmtiError err = JVMTI_ERROR_NONE;
1595
1596
// retrieve or create JvmtiThreadState.
1597
JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread);
1598
if (state == NULL) {
1599
return JVMTI_ERROR_THREAD_NOT_ALIVE;
1600
}
1601
1602
// It is only safe to perform the direct operation on the current
1603
// thread. All other usage needs to use a direct handshake for safety.
1604
if (java_thread == JavaThread::current()) {
1605
err = get_frame_count(state, count_ptr);
1606
} else {
1607
// get java stack frame count with handshake.
1608
GetFrameCountClosure op(this, state, count_ptr);
1609
Handshake::execute(&op, java_thread);
1610
err = op.result();
1611
}
1612
return err;
1613
} /* end GetFrameCount */
1614
1615
1616
// java_thread - protected by ThreadsListHandle and pre-checked
1617
jvmtiError
1618
JvmtiEnv::PopFrame(JavaThread* java_thread) {
1619
// retrieve or create the state
1620
JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread);
1621
if (state == NULL) {
1622
return JVMTI_ERROR_THREAD_NOT_ALIVE;
1623
}
1624
1625
// Eagerly reallocate scalar replaced objects.
1626
JavaThread* current_thread = JavaThread::current();
1627
EscapeBarrier eb(true, current_thread, java_thread);
1628
if (!eb.deoptimize_objects(1)) {
1629
// Reallocation of scalar replaced objects failed -> return with error
1630
return JVMTI_ERROR_OUT_OF_MEMORY;
1631
}
1632
1633
MutexLocker mu(JvmtiThreadState_lock);
1634
UpdateForPopTopFrameClosure op(state);
1635
if (java_thread == current_thread) {
1636
op.doit(java_thread, true /* self */);
1637
} else {
1638
Handshake::execute(&op, java_thread);
1639
}
1640
return op.result();
1641
} /* end PopFrame */
1642
1643
1644
// java_thread - protected by ThreadsListHandle and pre-checked
1645
// depth - pre-checked as non-negative
1646
// method_ptr - pre-checked for NULL
1647
// location_ptr - pre-checked for NULL
1648
jvmtiError
1649
JvmtiEnv::GetFrameLocation(JavaThread* java_thread, jint depth, jmethodID* method_ptr, jlocation* location_ptr) {
1650
jvmtiError err = JVMTI_ERROR_NONE;
1651
1652
// It is only safe to perform the direct operation on the current
1653
// thread. All other usage needs to use a direct handshake for safety.
1654
if (java_thread == JavaThread::current()) {
1655
err = get_frame_location(java_thread, depth, method_ptr, location_ptr);
1656
} else {
1657
// JVMTI get java stack frame location via direct handshake.
1658
GetFrameLocationClosure op(this, depth, method_ptr, location_ptr);
1659
Handshake::execute(&op, java_thread);
1660
err = op.result();
1661
}
1662
return err;
1663
} /* end GetFrameLocation */
1664
1665
1666
// java_thread - protected by ThreadsListHandle and pre-checked
1667
// depth - pre-checked as non-negative
1668
jvmtiError
1669
JvmtiEnv::NotifyFramePop(JavaThread* java_thread, jint depth) {
1670
JvmtiThreadState *state = JvmtiThreadState::state_for(java_thread);
1671
if (state == NULL) {
1672
return JVMTI_ERROR_THREAD_NOT_ALIVE;
1673
}
1674
1675
SetFramePopClosure op(this, state, depth);
1676
MutexLocker mu(JvmtiThreadState_lock);
1677
if (java_thread == JavaThread::current()) {
1678
op.doit(java_thread, true /* self */);
1679
} else {
1680
Handshake::execute(&op, java_thread);
1681
}
1682
return op.result();
1683
} /* end NotifyFramePop */
1684
1685
1686
//
1687
// Force Early Return functions
1688
//
1689
1690
// java_thread - protected by ThreadsListHandle and pre-checked
1691
jvmtiError
1692
JvmtiEnv::ForceEarlyReturnObject(JavaThread* java_thread, jobject value) {
1693
jvalue val;
1694
val.l = value;
1695
return force_early_return(java_thread, val, atos);
1696
} /* end ForceEarlyReturnObject */
1697
1698
1699
// java_thread - protected by ThreadsListHandle and pre-checked
1700
jvmtiError
1701
JvmtiEnv::ForceEarlyReturnInt(JavaThread* java_thread, jint value) {
1702
jvalue val;
1703
val.i = value;
1704
return force_early_return(java_thread, val, itos);
1705
} /* end ForceEarlyReturnInt */
1706
1707
1708
// java_thread - protected by ThreadsListHandle and pre-checked
1709
jvmtiError
1710
JvmtiEnv::ForceEarlyReturnLong(JavaThread* java_thread, jlong value) {
1711
jvalue val;
1712
val.j = value;
1713
return force_early_return(java_thread, val, ltos);
1714
} /* end ForceEarlyReturnLong */
1715
1716
1717
// java_thread - protected by ThreadsListHandle and pre-checked
1718
jvmtiError
1719
JvmtiEnv::ForceEarlyReturnFloat(JavaThread* java_thread, jfloat value) {
1720
jvalue val;
1721
val.f = value;
1722
return force_early_return(java_thread, val, ftos);
1723
} /* end ForceEarlyReturnFloat */
1724
1725
1726
// java_thread - protected by ThreadsListHandle and pre-checked
1727
jvmtiError
1728
JvmtiEnv::ForceEarlyReturnDouble(JavaThread* java_thread, jdouble value) {
1729
jvalue val;
1730
val.d = value;
1731
return force_early_return(java_thread, val, dtos);
1732
} /* end ForceEarlyReturnDouble */
1733
1734
1735
// java_thread - protected by ThreadsListHandle and pre-checked
1736
jvmtiError
1737
JvmtiEnv::ForceEarlyReturnVoid(JavaThread* java_thread) {
1738
jvalue val;
1739
val.j = 0L;
1740
return force_early_return(java_thread, val, vtos);
1741
} /* end ForceEarlyReturnVoid */
1742
1743
1744
//
1745
// Heap functions
1746
//
1747
1748
// klass - NULL is a valid value, must be checked
1749
// initial_object - NULL is a valid value, must be checked
1750
// callbacks - pre-checked for NULL
1751
// user_data - NULL is a valid value, must be checked
1752
jvmtiError
1753
JvmtiEnv::FollowReferences(jint heap_filter, jclass klass, jobject initial_object, const jvmtiHeapCallbacks* callbacks, const void* user_data) {
1754
// check klass if provided
1755
Klass* k = NULL;
1756
if (klass != NULL) {
1757
oop k_mirror = JNIHandles::resolve_external_guard(klass);
1758
if (k_mirror == NULL) {
1759
return JVMTI_ERROR_INVALID_CLASS;
1760
}
1761
if (java_lang_Class::is_primitive(k_mirror)) {
1762
return JVMTI_ERROR_NONE;
1763
}
1764
k = java_lang_Class::as_Klass(k_mirror);
1765
if (klass == NULL) {
1766
return JVMTI_ERROR_INVALID_CLASS;
1767
}
1768
}
1769
1770
if (initial_object != NULL) {
1771
oop init_obj = JNIHandles::resolve_external_guard(initial_object);
1772
if (init_obj == NULL) {
1773
return JVMTI_ERROR_INVALID_OBJECT;
1774
}
1775
}
1776
1777
Thread *thread = Thread::current();
1778
HandleMark hm(thread);
1779
1780
TraceTime t("FollowReferences", TRACETIME_LOG(Debug, jvmti, objecttagging));
1781
JvmtiTagMap::tag_map_for(this)->follow_references(heap_filter, k, initial_object, callbacks, user_data);
1782
return JVMTI_ERROR_NONE;
1783
} /* end FollowReferences */
1784
1785
1786
// klass - NULL is a valid value, must be checked
1787
// callbacks - pre-checked for NULL
1788
// user_data - NULL is a valid value, must be checked
1789
jvmtiError
1790
JvmtiEnv::IterateThroughHeap(jint heap_filter, jclass klass, const jvmtiHeapCallbacks* callbacks, const void* user_data) {
1791
// check klass if provided
1792
Klass* k = NULL;
1793
if (klass != NULL) {
1794
oop k_mirror = JNIHandles::resolve_external_guard(klass);
1795
if (k_mirror == NULL) {
1796
return JVMTI_ERROR_INVALID_CLASS;
1797
}
1798
if (java_lang_Class::is_primitive(k_mirror)) {
1799
return JVMTI_ERROR_NONE;
1800
}
1801
k = java_lang_Class::as_Klass(k_mirror);
1802
if (k == NULL) {
1803
return JVMTI_ERROR_INVALID_CLASS;
1804
}
1805
}
1806
1807
TraceTime t("IterateThroughHeap", TRACETIME_LOG(Debug, jvmti, objecttagging));
1808
JvmtiTagMap::tag_map_for(this)->iterate_through_heap(heap_filter, k, callbacks, user_data);
1809
return JVMTI_ERROR_NONE;
1810
} /* end IterateThroughHeap */
1811
1812
1813
// tag_ptr - pre-checked for NULL
1814
jvmtiError
1815
JvmtiEnv::GetTag(jobject object, jlong* tag_ptr) {
1816
oop o = JNIHandles::resolve_external_guard(object);
1817
NULL_CHECK(o, JVMTI_ERROR_INVALID_OBJECT);
1818
*tag_ptr = JvmtiTagMap::tag_map_for(this)->get_tag(object);
1819
return JVMTI_ERROR_NONE;
1820
} /* end GetTag */
1821
1822
1823
jvmtiError
1824
JvmtiEnv::SetTag(jobject object, jlong tag) {
1825
oop o = JNIHandles::resolve_external_guard(object);
1826
NULL_CHECK(o, JVMTI_ERROR_INVALID_OBJECT);
1827
JvmtiTagMap::tag_map_for(this)->set_tag(object, tag);
1828
return JVMTI_ERROR_NONE;
1829
} /* end SetTag */
1830
1831
1832
// tag_count - pre-checked to be greater than or equal to 0
1833
// tags - pre-checked for NULL
1834
// count_ptr - pre-checked for NULL
1835
// object_result_ptr - NULL is a valid value, must be checked
1836
// tag_result_ptr - NULL is a valid value, must be checked
1837
jvmtiError
1838
JvmtiEnv::GetObjectsWithTags(jint tag_count, const jlong* tags, jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) {
1839
TraceTime t("GetObjectsWithTags", TRACETIME_LOG(Debug, jvmti, objecttagging));
1840
return JvmtiTagMap::tag_map_for(this)->get_objects_with_tags((jlong*)tags, tag_count, count_ptr, object_result_ptr, tag_result_ptr);
1841
} /* end GetObjectsWithTags */
1842
1843
1844
jvmtiError
1845
JvmtiEnv::ForceGarbageCollection() {
1846
Universe::heap()->collect(GCCause::_jvmti_force_gc);
1847
return JVMTI_ERROR_NONE;
1848
} /* end ForceGarbageCollection */
1849
1850
1851
//
1852
// Heap (1.0) functions
1853
//
1854
1855
// object_reference_callback - pre-checked for NULL
1856
// user_data - NULL is a valid value, must be checked
1857
jvmtiError
1858
JvmtiEnv::IterateOverObjectsReachableFromObject(jobject object, jvmtiObjectReferenceCallback object_reference_callback, const void* user_data) {
1859
oop o = JNIHandles::resolve_external_guard(object);
1860
NULL_CHECK(o, JVMTI_ERROR_INVALID_OBJECT);
1861
JvmtiTagMap::tag_map_for(this)->iterate_over_objects_reachable_from_object(object, object_reference_callback, user_data);
1862
return JVMTI_ERROR_NONE;
1863
} /* end IterateOverObjectsReachableFromObject */
1864
1865
1866
// heap_root_callback - NULL is a valid value, must be checked
1867
// stack_ref_callback - NULL is a valid value, must be checked
1868
// object_ref_callback - NULL is a valid value, must be checked
1869
// user_data - NULL is a valid value, must be checked
1870
jvmtiError
1871
JvmtiEnv::IterateOverReachableObjects(jvmtiHeapRootCallback heap_root_callback, jvmtiStackReferenceCallback stack_ref_callback, jvmtiObjectReferenceCallback object_ref_callback, const void* user_data) {
1872
TraceTime t("IterateOverReachableObjects", TRACETIME_LOG(Debug, jvmti, objecttagging));
1873
JvmtiTagMap::tag_map_for(this)->iterate_over_reachable_objects(heap_root_callback, stack_ref_callback, object_ref_callback, user_data);
1874
return JVMTI_ERROR_NONE;
1875
} /* end IterateOverReachableObjects */
1876
1877
1878
// heap_object_callback - pre-checked for NULL
1879
// user_data - NULL is a valid value, must be checked
1880
jvmtiError
1881
JvmtiEnv::IterateOverHeap(jvmtiHeapObjectFilter object_filter, jvmtiHeapObjectCallback heap_object_callback, const void* user_data) {
1882
TraceTime t("IterateOverHeap", TRACETIME_LOG(Debug, jvmti, objecttagging));
1883
Thread *thread = Thread::current();
1884
HandleMark hm(thread);
1885
JvmtiTagMap::tag_map_for(this)->iterate_over_heap(object_filter, NULL, heap_object_callback, user_data);
1886
return JVMTI_ERROR_NONE;
1887
} /* end IterateOverHeap */
1888
1889
1890
// k_mirror - may be primitive, this must be checked
1891
// heap_object_callback - pre-checked for NULL
1892
// user_data - NULL is a valid value, must be checked
1893
jvmtiError
1894
JvmtiEnv::IterateOverInstancesOfClass(oop k_mirror, jvmtiHeapObjectFilter object_filter, jvmtiHeapObjectCallback heap_object_callback, const void* user_data) {
1895
if (java_lang_Class::is_primitive(k_mirror)) {
1896
// DO PRIMITIVE CLASS PROCESSING
1897
return JVMTI_ERROR_NONE;
1898
}
1899
Klass* klass = java_lang_Class::as_Klass(k_mirror);
1900
if (klass == NULL) {
1901
return JVMTI_ERROR_INVALID_CLASS;
1902
}
1903
TraceTime t("IterateOverInstancesOfClass", TRACETIME_LOG(Debug, jvmti, objecttagging));
1904
JvmtiTagMap::tag_map_for(this)->iterate_over_heap(object_filter, klass, heap_object_callback, user_data);
1905
return JVMTI_ERROR_NONE;
1906
} /* end IterateOverInstancesOfClass */
1907
1908
1909
//
1910
// Local Variable functions
1911
//
1912
1913
// java_thread - protected by ThreadsListHandle and pre-checked
1914
// depth - pre-checked as non-negative
1915
// value_ptr - pre-checked for NULL
1916
jvmtiError
1917
JvmtiEnv::GetLocalObject(JavaThread* java_thread, jint depth, jint slot, jobject* value_ptr) {
1918
JavaThread* current_thread = JavaThread::current();
1919
// rm object is created to clean up the javaVFrame created in
1920
// doit_prologue(), but after doit() is finished with it.
1921
ResourceMark rm(current_thread);
1922
1923
VM_GetOrSetLocal op(java_thread, current_thread, depth, slot);
1924
VMThread::execute(&op);
1925
jvmtiError err = op.result();
1926
if (err != JVMTI_ERROR_NONE) {
1927
return err;
1928
} else {
1929
*value_ptr = op.value().l;
1930
return JVMTI_ERROR_NONE;
1931
}
1932
} /* end GetLocalObject */
1933
1934
// java_thread - protected by ThreadsListHandle and pre-checked
1935
// depth - pre-checked as non-negative
1936
// value - pre-checked for NULL
1937
jvmtiError
1938
JvmtiEnv::GetLocalInstance(JavaThread* java_thread, jint depth, jobject* value_ptr){
1939
JavaThread* current_thread = JavaThread::current();
1940
// rm object is created to clean up the javaVFrame created in
1941
// doit_prologue(), but after doit() is finished with it.
1942
ResourceMark rm(current_thread);
1943
1944
VM_GetReceiver op(java_thread, current_thread, depth);
1945
VMThread::execute(&op);
1946
jvmtiError err = op.result();
1947
if (err != JVMTI_ERROR_NONE) {
1948
return err;
1949
} else {
1950
*value_ptr = op.value().l;
1951
return JVMTI_ERROR_NONE;
1952
}
1953
} /* end GetLocalInstance */
1954
1955
1956
// java_thread - protected by ThreadsListHandle and pre-checked
1957
// depth - pre-checked as non-negative
1958
// value_ptr - pre-checked for NULL
1959
jvmtiError
1960
JvmtiEnv::GetLocalInt(JavaThread* java_thread, jint depth, jint slot, jint* value_ptr) {
1961
// rm object is created to clean up the javaVFrame created in
1962
// doit_prologue(), but after doit() is finished with it.
1963
ResourceMark rm;
1964
1965
VM_GetOrSetLocal op(java_thread, depth, slot, T_INT);
1966
VMThread::execute(&op);
1967
*value_ptr = op.value().i;
1968
return op.result();
1969
} /* end GetLocalInt */
1970
1971
1972
// java_thread - protected by ThreadsListHandle and pre-checked
1973
// depth - pre-checked as non-negative
1974
// value_ptr - pre-checked for NULL
1975
jvmtiError
1976
JvmtiEnv::GetLocalLong(JavaThread* java_thread, jint depth, jint slot, jlong* value_ptr) {
1977
// rm object is created to clean up the javaVFrame created in
1978
// doit_prologue(), but after doit() is finished with it.
1979
ResourceMark rm;
1980
1981
VM_GetOrSetLocal op(java_thread, depth, slot, T_LONG);
1982
VMThread::execute(&op);
1983
*value_ptr = op.value().j;
1984
return op.result();
1985
} /* end GetLocalLong */
1986
1987
1988
// java_thread - protected by ThreadsListHandle and pre-checked
1989
// depth - pre-checked as non-negative
1990
// value_ptr - pre-checked for NULL
1991
jvmtiError
1992
JvmtiEnv::GetLocalFloat(JavaThread* java_thread, jint depth, jint slot, jfloat* value_ptr) {
1993
// rm object is created to clean up the javaVFrame created in
1994
// doit_prologue(), but after doit() is finished with it.
1995
ResourceMark rm;
1996
1997
VM_GetOrSetLocal op(java_thread, depth, slot, T_FLOAT);
1998
VMThread::execute(&op);
1999
*value_ptr = op.value().f;
2000
return op.result();
2001
} /* end GetLocalFloat */
2002
2003
2004
// java_thread - protected by ThreadsListHandle and pre-checked
2005
// depth - pre-checked as non-negative
2006
// value_ptr - pre-checked for NULL
2007
jvmtiError
2008
JvmtiEnv::GetLocalDouble(JavaThread* java_thread, jint depth, jint slot, jdouble* value_ptr) {
2009
// rm object is created to clean up the javaVFrame created in
2010
// doit_prologue(), but after doit() is finished with it.
2011
ResourceMark rm;
2012
2013
VM_GetOrSetLocal op(java_thread, depth, slot, T_DOUBLE);
2014
VMThread::execute(&op);
2015
*value_ptr = op.value().d;
2016
return op.result();
2017
} /* end GetLocalDouble */
2018
2019
2020
// java_thread - protected by ThreadsListHandle and pre-checked
2021
// depth - pre-checked as non-negative
2022
jvmtiError
2023
JvmtiEnv::SetLocalObject(JavaThread* java_thread, jint depth, jint slot, jobject value) {
2024
// rm object is created to clean up the javaVFrame created in
2025
// doit_prologue(), but after doit() is finished with it.
2026
ResourceMark rm;
2027
jvalue val;
2028
val.l = value;
2029
VM_GetOrSetLocal op(java_thread, depth, slot, T_OBJECT, val);
2030
VMThread::execute(&op);
2031
return op.result();
2032
} /* end SetLocalObject */
2033
2034
2035
// java_thread - protected by ThreadsListHandle and pre-checked
2036
// depth - pre-checked as non-negative
2037
jvmtiError
2038
JvmtiEnv::SetLocalInt(JavaThread* java_thread, jint depth, jint slot, jint value) {
2039
// rm object is created to clean up the javaVFrame created in
2040
// doit_prologue(), but after doit() is finished with it.
2041
ResourceMark rm;
2042
jvalue val;
2043
val.i = value;
2044
VM_GetOrSetLocal op(java_thread, depth, slot, T_INT, val);
2045
VMThread::execute(&op);
2046
return op.result();
2047
} /* end SetLocalInt */
2048
2049
2050
// java_thread - protected by ThreadsListHandle and pre-checked
2051
// depth - pre-checked as non-negative
2052
jvmtiError
2053
JvmtiEnv::SetLocalLong(JavaThread* java_thread, jint depth, jint slot, jlong value) {
2054
// rm object is created to clean up the javaVFrame created in
2055
// doit_prologue(), but after doit() is finished with it.
2056
ResourceMark rm;
2057
jvalue val;
2058
val.j = value;
2059
VM_GetOrSetLocal op(java_thread, depth, slot, T_LONG, val);
2060
VMThread::execute(&op);
2061
return op.result();
2062
} /* end SetLocalLong */
2063
2064
2065
// java_thread - protected by ThreadsListHandle and pre-checked
2066
// depth - pre-checked as non-negative
2067
jvmtiError
2068
JvmtiEnv::SetLocalFloat(JavaThread* java_thread, jint depth, jint slot, jfloat value) {
2069
// rm object is created to clean up the javaVFrame created in
2070
// doit_prologue(), but after doit() is finished with it.
2071
ResourceMark rm;
2072
jvalue val;
2073
val.f = value;
2074
VM_GetOrSetLocal op(java_thread, depth, slot, T_FLOAT, val);
2075
VMThread::execute(&op);
2076
return op.result();
2077
} /* end SetLocalFloat */
2078
2079
2080
// java_thread - protected by ThreadsListHandle and pre-checked
2081
// depth - pre-checked as non-negative
2082
jvmtiError
2083
JvmtiEnv::SetLocalDouble(JavaThread* java_thread, jint depth, jint slot, jdouble value) {
2084
// rm object is created to clean up the javaVFrame created in
2085
// doit_prologue(), but after doit() is finished with it.
2086
ResourceMark rm;
2087
jvalue val;
2088
val.d = value;
2089
VM_GetOrSetLocal op(java_thread, depth, slot, T_DOUBLE, val);
2090
VMThread::execute(&op);
2091
return op.result();
2092
} /* end SetLocalDouble */
2093
2094
2095
//
2096
// Breakpoint functions
2097
//
2098
2099
// method - pre-checked for validity, but may be NULL meaning obsolete method
2100
jvmtiError
2101
JvmtiEnv::SetBreakpoint(Method* method, jlocation location) {
2102
NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
2103
if (location < 0) { // simple invalid location check first
2104
return JVMTI_ERROR_INVALID_LOCATION;
2105
}
2106
// verify that the breakpoint is not past the end of the method
2107
if (location >= (jlocation) method->code_size()) {
2108
return JVMTI_ERROR_INVALID_LOCATION;
2109
}
2110
2111
ResourceMark rm;
2112
JvmtiBreakpoint bp(method, location);
2113
JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();
2114
if (jvmti_breakpoints.set(bp) == JVMTI_ERROR_DUPLICATE)
2115
return JVMTI_ERROR_DUPLICATE;
2116
2117
if (TraceJVMTICalls) {
2118
jvmti_breakpoints.print();
2119
}
2120
2121
return JVMTI_ERROR_NONE;
2122
} /* end SetBreakpoint */
2123
2124
2125
// method - pre-checked for validity, but may be NULL meaning obsolete method
2126
jvmtiError
2127
JvmtiEnv::ClearBreakpoint(Method* method, jlocation location) {
2128
NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
2129
2130
if (location < 0) { // simple invalid location check first
2131
return JVMTI_ERROR_INVALID_LOCATION;
2132
}
2133
2134
// verify that the breakpoint is not past the end of the method
2135
if (location >= (jlocation) method->code_size()) {
2136
return JVMTI_ERROR_INVALID_LOCATION;
2137
}
2138
2139
JvmtiBreakpoint bp(method, location);
2140
2141
JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();
2142
if (jvmti_breakpoints.clear(bp) == JVMTI_ERROR_NOT_FOUND)
2143
return JVMTI_ERROR_NOT_FOUND;
2144
2145
if (TraceJVMTICalls) {
2146
jvmti_breakpoints.print();
2147
}
2148
2149
return JVMTI_ERROR_NONE;
2150
} /* end ClearBreakpoint */
2151
2152
2153
//
2154
// Watched Field functions
2155
//
2156
2157
jvmtiError
2158
JvmtiEnv::SetFieldAccessWatch(fieldDescriptor* fdesc_ptr) {
2159
// make sure we haven't set this watch before
2160
if (fdesc_ptr->is_field_access_watched()) return JVMTI_ERROR_DUPLICATE;
2161
fdesc_ptr->set_is_field_access_watched(true);
2162
2163
JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_ACCESS, true);
2164
2165
return JVMTI_ERROR_NONE;
2166
} /* end SetFieldAccessWatch */
2167
2168
2169
jvmtiError
2170
JvmtiEnv::ClearFieldAccessWatch(fieldDescriptor* fdesc_ptr) {
2171
// make sure we have a watch to clear
2172
if (!fdesc_ptr->is_field_access_watched()) return JVMTI_ERROR_NOT_FOUND;
2173
fdesc_ptr->set_is_field_access_watched(false);
2174
2175
JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_ACCESS, false);
2176
2177
return JVMTI_ERROR_NONE;
2178
} /* end ClearFieldAccessWatch */
2179
2180
2181
jvmtiError
2182
JvmtiEnv::SetFieldModificationWatch(fieldDescriptor* fdesc_ptr) {
2183
// make sure we haven't set this watch before
2184
if (fdesc_ptr->is_field_modification_watched()) return JVMTI_ERROR_DUPLICATE;
2185
fdesc_ptr->set_is_field_modification_watched(true);
2186
2187
JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_MODIFICATION, true);
2188
2189
return JVMTI_ERROR_NONE;
2190
} /* end SetFieldModificationWatch */
2191
2192
2193
jvmtiError
2194
JvmtiEnv::ClearFieldModificationWatch(fieldDescriptor* fdesc_ptr) {
2195
// make sure we have a watch to clear
2196
if (!fdesc_ptr->is_field_modification_watched()) return JVMTI_ERROR_NOT_FOUND;
2197
fdesc_ptr->set_is_field_modification_watched(false);
2198
2199
JvmtiEventController::change_field_watch(JVMTI_EVENT_FIELD_MODIFICATION, false);
2200
2201
return JVMTI_ERROR_NONE;
2202
} /* end ClearFieldModificationWatch */
2203
2204
//
2205
// Class functions
2206
//
2207
2208
2209
// k_mirror - may be primitive, this must be checked
2210
// signature_ptr - NULL is a valid value, must be checked
2211
// generic_ptr - NULL is a valid value, must be checked
2212
jvmtiError
2213
JvmtiEnv::GetClassSignature(oop k_mirror, char** signature_ptr, char** generic_ptr) {
2214
ResourceMark rm;
2215
bool isPrimitive = java_lang_Class::is_primitive(k_mirror);
2216
Klass* k = NULL;
2217
if (!isPrimitive) {
2218
k = java_lang_Class::as_Klass(k_mirror);
2219
NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
2220
}
2221
if (signature_ptr != NULL) {
2222
char* result = NULL;
2223
if (isPrimitive) {
2224
char tchar = type2char(java_lang_Class::primitive_type(k_mirror));
2225
result = (char*) jvmtiMalloc(2);
2226
result[0] = tchar;
2227
result[1] = '\0';
2228
} else {
2229
const char* class_sig = k->signature_name();
2230
result = (char *) jvmtiMalloc(strlen(class_sig)+1);
2231
strcpy(result, class_sig);
2232
}
2233
*signature_ptr = result;
2234
}
2235
if (generic_ptr != NULL) {
2236
*generic_ptr = NULL;
2237
if (!isPrimitive && k->is_instance_klass()) {
2238
Symbol* soo = InstanceKlass::cast(k)->generic_signature();
2239
if (soo != NULL) {
2240
const char *gen_sig = soo->as_C_string();
2241
if (gen_sig != NULL) {
2242
char* gen_result;
2243
jvmtiError err = allocate(strlen(gen_sig) + 1,
2244
(unsigned char **)&gen_result);
2245
if (err != JVMTI_ERROR_NONE) {
2246
return err;
2247
}
2248
strcpy(gen_result, gen_sig);
2249
*generic_ptr = gen_result;
2250
}
2251
}
2252
}
2253
}
2254
return JVMTI_ERROR_NONE;
2255
} /* end GetClassSignature */
2256
2257
2258
// k_mirror - may be primitive, this must be checked
2259
// status_ptr - pre-checked for NULL
2260
jvmtiError
2261
JvmtiEnv::GetClassStatus(oop k_mirror, jint* status_ptr) {
2262
jint result = 0;
2263
if (java_lang_Class::is_primitive(k_mirror)) {
2264
result |= JVMTI_CLASS_STATUS_PRIMITIVE;
2265
} else {
2266
Klass* k = java_lang_Class::as_Klass(k_mirror);
2267
NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
2268
result = k->jvmti_class_status();
2269
}
2270
*status_ptr = result;
2271
2272
return JVMTI_ERROR_NONE;
2273
} /* end GetClassStatus */
2274
2275
2276
// k_mirror - may be primitive, this must be checked
2277
// source_name_ptr - pre-checked for NULL
2278
jvmtiError
2279
JvmtiEnv::GetSourceFileName(oop k_mirror, char** source_name_ptr) {
2280
if (java_lang_Class::is_primitive(k_mirror)) {
2281
return JVMTI_ERROR_ABSENT_INFORMATION;
2282
}
2283
Klass* k_klass = java_lang_Class::as_Klass(k_mirror);
2284
NULL_CHECK(k_klass, JVMTI_ERROR_INVALID_CLASS);
2285
2286
if (!k_klass->is_instance_klass()) {
2287
return JVMTI_ERROR_ABSENT_INFORMATION;
2288
}
2289
2290
Symbol* sfnOop = InstanceKlass::cast(k_klass)->source_file_name();
2291
NULL_CHECK(sfnOop, JVMTI_ERROR_ABSENT_INFORMATION);
2292
{
2293
JavaThread* current_thread = JavaThread::current();
2294
ResourceMark rm(current_thread);
2295
const char* sfncp = (const char*) sfnOop->as_C_string();
2296
*source_name_ptr = (char *) jvmtiMalloc(strlen(sfncp)+1);
2297
strcpy(*source_name_ptr, sfncp);
2298
}
2299
2300
return JVMTI_ERROR_NONE;
2301
} /* end GetSourceFileName */
2302
2303
2304
// k_mirror - may be primitive, this must be checked
2305
// modifiers_ptr - pre-checked for NULL
2306
jvmtiError
2307
JvmtiEnv::GetClassModifiers(oop k_mirror, jint* modifiers_ptr) {
2308
JavaThread* current_thread = JavaThread::current();
2309
jint result = 0;
2310
if (!java_lang_Class::is_primitive(k_mirror)) {
2311
Klass* k = java_lang_Class::as_Klass(k_mirror);
2312
NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
2313
result = k->compute_modifier_flags();
2314
2315
// Reset the deleted ACC_SUPER bit (deleted in compute_modifier_flags()).
2316
if (k->is_super()) {
2317
result |= JVM_ACC_SUPER;
2318
}
2319
} else {
2320
result = (JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC);
2321
}
2322
*modifiers_ptr = result;
2323
2324
return JVMTI_ERROR_NONE;
2325
} /* end GetClassModifiers */
2326
2327
2328
// k_mirror - may be primitive, this must be checked
2329
// method_count_ptr - pre-checked for NULL
2330
// methods_ptr - pre-checked for NULL
2331
jvmtiError
2332
JvmtiEnv::GetClassMethods(oop k_mirror, jint* method_count_ptr, jmethodID** methods_ptr) {
2333
JavaThread* current_thread = JavaThread::current();
2334
HandleMark hm(current_thread);
2335
2336
if (java_lang_Class::is_primitive(k_mirror)) {
2337
*method_count_ptr = 0;
2338
*methods_ptr = (jmethodID*) jvmtiMalloc(0 * sizeof(jmethodID));
2339
return JVMTI_ERROR_NONE;
2340
}
2341
Klass* k = java_lang_Class::as_Klass(k_mirror);
2342
NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
2343
2344
// Return CLASS_NOT_PREPARED error as per JVMTI spec.
2345
if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) )) {
2346
return JVMTI_ERROR_CLASS_NOT_PREPARED;
2347
}
2348
2349
if (!k->is_instance_klass()) {
2350
*method_count_ptr = 0;
2351
*methods_ptr = (jmethodID*) jvmtiMalloc(0 * sizeof(jmethodID));
2352
return JVMTI_ERROR_NONE;
2353
}
2354
InstanceKlass* ik = InstanceKlass::cast(k);
2355
// Allocate the result and fill it in
2356
int result_length = ik->methods()->length();
2357
jmethodID* result_list = (jmethodID*)jvmtiMalloc(result_length * sizeof(jmethodID));
2358
int index;
2359
bool jmethodids_found = true;
2360
int skipped = 0; // skip overpass methods
2361
2362
for (index = 0; index < result_length; index++) {
2363
Method* m = ik->methods()->at(index);
2364
// Depending on can_maintain_original_method_order capability use the original
2365
// method ordering indices stored in the class, so we can emit jmethodIDs in
2366
// the order they appeared in the class file or just copy in current order.
2367
int result_index = JvmtiExport::can_maintain_original_method_order() ? ik->method_ordering()->at(index) : index;
2368
assert(result_index >= 0 && result_index < result_length, "invalid original method index");
2369
if (m->is_overpass()) {
2370
result_list[result_index] = NULL;
2371
skipped++;
2372
continue;
2373
}
2374
jmethodID id;
2375
if (jmethodids_found) {
2376
id = m->find_jmethod_id_or_null();
2377
if (id == NULL) {
2378
// If we find an uninitialized value, make sure there is
2379
// enough space for all the uninitialized values we might
2380
// find.
2381
ik->ensure_space_for_methodids(index);
2382
jmethodids_found = false;
2383
id = m->jmethod_id();
2384
}
2385
} else {
2386
id = m->jmethod_id();
2387
}
2388
result_list[result_index] = id;
2389
}
2390
2391
// Fill in return value.
2392
if (skipped > 0) {
2393
// copy results skipping NULL methodIDs
2394
*methods_ptr = (jmethodID*)jvmtiMalloc((result_length - skipped) * sizeof(jmethodID));
2395
*method_count_ptr = result_length - skipped;
2396
for (index = 0, skipped = 0; index < result_length; index++) {
2397
if (result_list[index] == NULL) {
2398
skipped++;
2399
} else {
2400
(*methods_ptr)[index - skipped] = result_list[index];
2401
}
2402
}
2403
deallocate((unsigned char *)result_list);
2404
} else {
2405
*method_count_ptr = result_length;
2406
*methods_ptr = result_list;
2407
}
2408
2409
return JVMTI_ERROR_NONE;
2410
} /* end GetClassMethods */
2411
2412
2413
// k_mirror - may be primitive, this must be checked
2414
// field_count_ptr - pre-checked for NULL
2415
// fields_ptr - pre-checked for NULL
2416
jvmtiError
2417
JvmtiEnv::GetClassFields(oop k_mirror, jint* field_count_ptr, jfieldID** fields_ptr) {
2418
if (java_lang_Class::is_primitive(k_mirror)) {
2419
*field_count_ptr = 0;
2420
*fields_ptr = (jfieldID*) jvmtiMalloc(0 * sizeof(jfieldID));
2421
return JVMTI_ERROR_NONE;
2422
}
2423
JavaThread* current_thread = JavaThread::current();
2424
HandleMark hm(current_thread);
2425
Klass* k = java_lang_Class::as_Klass(k_mirror);
2426
NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
2427
2428
// Return CLASS_NOT_PREPARED error as per JVMTI spec.
2429
if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) )) {
2430
return JVMTI_ERROR_CLASS_NOT_PREPARED;
2431
}
2432
2433
if (!k->is_instance_klass()) {
2434
*field_count_ptr = 0;
2435
*fields_ptr = (jfieldID*) jvmtiMalloc(0 * sizeof(jfieldID));
2436
return JVMTI_ERROR_NONE;
2437
}
2438
2439
2440
InstanceKlass* ik = InstanceKlass::cast(k);
2441
2442
int result_count = 0;
2443
// First, count the fields.
2444
FilteredFieldStream flds(ik, true, true);
2445
result_count = flds.field_count();
2446
2447
// Allocate the result and fill it in
2448
jfieldID* result_list = (jfieldID*) jvmtiMalloc(result_count * sizeof(jfieldID));
2449
// The JVMTI spec requires fields in the order they occur in the class file,
2450
// this is the reverse order of what FieldStream hands out.
2451
int id_index = (result_count - 1);
2452
2453
for (FilteredFieldStream src_st(ik, true, true); !src_st.eos(); src_st.next()) {
2454
result_list[id_index--] = jfieldIDWorkaround::to_jfieldID(
2455
ik, src_st.offset(),
2456
src_st.access_flags().is_static());
2457
}
2458
assert(id_index == -1, "just checking");
2459
// Fill in the results
2460
*field_count_ptr = result_count;
2461
*fields_ptr = result_list;
2462
2463
return JVMTI_ERROR_NONE;
2464
} /* end GetClassFields */
2465
2466
2467
// k_mirror - may be primitive, this must be checked
2468
// interface_count_ptr - pre-checked for NULL
2469
// interfaces_ptr - pre-checked for NULL
2470
jvmtiError
2471
JvmtiEnv::GetImplementedInterfaces(oop k_mirror, jint* interface_count_ptr, jclass** interfaces_ptr) {
2472
{
2473
if (java_lang_Class::is_primitive(k_mirror)) {
2474
*interface_count_ptr = 0;
2475
*interfaces_ptr = (jclass*) jvmtiMalloc(0 * sizeof(jclass));
2476
return JVMTI_ERROR_NONE;
2477
}
2478
JavaThread* current_thread = JavaThread::current();
2479
HandleMark hm(current_thread);
2480
Klass* k = java_lang_Class::as_Klass(k_mirror);
2481
NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
2482
2483
// Return CLASS_NOT_PREPARED error as per JVMTI spec.
2484
if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) ))
2485
return JVMTI_ERROR_CLASS_NOT_PREPARED;
2486
2487
if (!k->is_instance_klass()) {
2488
*interface_count_ptr = 0;
2489
*interfaces_ptr = (jclass*) jvmtiMalloc(0 * sizeof(jclass));
2490
return JVMTI_ERROR_NONE;
2491
}
2492
2493
Array<InstanceKlass*>* interface_list = InstanceKlass::cast(k)->local_interfaces();
2494
const int result_length = (interface_list == NULL ? 0 : interface_list->length());
2495
jclass* result_list = (jclass*) jvmtiMalloc(result_length * sizeof(jclass));
2496
for (int i_index = 0; i_index < result_length; i_index += 1) {
2497
InstanceKlass* klass_at = interface_list->at(i_index);
2498
assert(klass_at->is_klass(), "interfaces must be Klass*s");
2499
assert(klass_at->is_interface(), "interfaces must be interfaces");
2500
oop mirror_at = klass_at->java_mirror();
2501
Handle handle_at = Handle(current_thread, mirror_at);
2502
result_list[i_index] = (jclass) jni_reference(handle_at);
2503
}
2504
*interface_count_ptr = result_length;
2505
*interfaces_ptr = result_list;
2506
}
2507
2508
return JVMTI_ERROR_NONE;
2509
} /* end GetImplementedInterfaces */
2510
2511
2512
// k_mirror - may be primitive, this must be checked
2513
// minor_version_ptr - pre-checked for NULL
2514
// major_version_ptr - pre-checked for NULL
2515
jvmtiError
2516
JvmtiEnv::GetClassVersionNumbers(oop k_mirror, jint* minor_version_ptr, jint* major_version_ptr) {
2517
if (java_lang_Class::is_primitive(k_mirror)) {
2518
return JVMTI_ERROR_ABSENT_INFORMATION;
2519
}
2520
Klass* klass = java_lang_Class::as_Klass(k_mirror);
2521
2522
jint status = klass->jvmti_class_status();
2523
if (status & (JVMTI_CLASS_STATUS_ERROR)) {
2524
return JVMTI_ERROR_INVALID_CLASS;
2525
}
2526
if (status & (JVMTI_CLASS_STATUS_ARRAY)) {
2527
return JVMTI_ERROR_ABSENT_INFORMATION;
2528
}
2529
2530
InstanceKlass* ik = InstanceKlass::cast(klass);
2531
*minor_version_ptr = ik->minor_version();
2532
*major_version_ptr = ik->major_version();
2533
2534
return JVMTI_ERROR_NONE;
2535
} /* end GetClassVersionNumbers */
2536
2537
2538
// k_mirror - may be primitive, this must be checked
2539
// constant_pool_count_ptr - pre-checked for NULL
2540
// constant_pool_byte_count_ptr - pre-checked for NULL
2541
// constant_pool_bytes_ptr - pre-checked for NULL
2542
jvmtiError
2543
JvmtiEnv::GetConstantPool(oop k_mirror, jint* constant_pool_count_ptr, jint* constant_pool_byte_count_ptr, unsigned char** constant_pool_bytes_ptr) {
2544
if (java_lang_Class::is_primitive(k_mirror)) {
2545
return JVMTI_ERROR_ABSENT_INFORMATION;
2546
}
2547
2548
Klass* klass = java_lang_Class::as_Klass(k_mirror);
2549
Thread *thread = Thread::current();
2550
ResourceMark rm(thread);
2551
2552
jint status = klass->jvmti_class_status();
2553
if (status & (JVMTI_CLASS_STATUS_ERROR)) {
2554
return JVMTI_ERROR_INVALID_CLASS;
2555
}
2556
if (status & (JVMTI_CLASS_STATUS_ARRAY)) {
2557
return JVMTI_ERROR_ABSENT_INFORMATION;
2558
}
2559
2560
InstanceKlass* ik = InstanceKlass::cast(klass);
2561
JvmtiConstantPoolReconstituter reconstituter(ik);
2562
if (reconstituter.get_error() != JVMTI_ERROR_NONE) {
2563
return reconstituter.get_error();
2564
}
2565
2566
unsigned char *cpool_bytes;
2567
int cpool_size = reconstituter.cpool_size();
2568
if (reconstituter.get_error() != JVMTI_ERROR_NONE) {
2569
return reconstituter.get_error();
2570
}
2571
jvmtiError res = allocate(cpool_size, &cpool_bytes);
2572
if (res != JVMTI_ERROR_NONE) {
2573
return res;
2574
}
2575
reconstituter.copy_cpool_bytes(cpool_bytes);
2576
if (reconstituter.get_error() != JVMTI_ERROR_NONE) {
2577
return reconstituter.get_error();
2578
}
2579
2580
constantPoolHandle constants(thread, ik->constants());
2581
*constant_pool_count_ptr = constants->length();
2582
*constant_pool_byte_count_ptr = cpool_size;
2583
*constant_pool_bytes_ptr = cpool_bytes;
2584
2585
return JVMTI_ERROR_NONE;
2586
} /* end GetConstantPool */
2587
2588
2589
// k_mirror - may be primitive, this must be checked
2590
// is_interface_ptr - pre-checked for NULL
2591
jvmtiError
2592
JvmtiEnv::IsInterface(oop k_mirror, jboolean* is_interface_ptr) {
2593
{
2594
bool result = false;
2595
if (!java_lang_Class::is_primitive(k_mirror)) {
2596
Klass* k = java_lang_Class::as_Klass(k_mirror);
2597
if (k != NULL && k->is_interface()) {
2598
result = true;
2599
}
2600
}
2601
*is_interface_ptr = result;
2602
}
2603
2604
return JVMTI_ERROR_NONE;
2605
} /* end IsInterface */
2606
2607
2608
// k_mirror - may be primitive, this must be checked
2609
// is_array_class_ptr - pre-checked for NULL
2610
jvmtiError
2611
JvmtiEnv::IsArrayClass(oop k_mirror, jboolean* is_array_class_ptr) {
2612
{
2613
bool result = false;
2614
if (!java_lang_Class::is_primitive(k_mirror)) {
2615
Klass* k = java_lang_Class::as_Klass(k_mirror);
2616
if (k != NULL && k->is_array_klass()) {
2617
result = true;
2618
}
2619
}
2620
*is_array_class_ptr = result;
2621
}
2622
2623
return JVMTI_ERROR_NONE;
2624
} /* end IsArrayClass */
2625
2626
2627
// k_mirror - may be primitive, this must be checked
2628
// classloader_ptr - pre-checked for NULL
2629
jvmtiError
2630
JvmtiEnv::GetClassLoader(oop k_mirror, jobject* classloader_ptr) {
2631
{
2632
if (java_lang_Class::is_primitive(k_mirror)) {
2633
*classloader_ptr = (jclass) jni_reference(Handle());
2634
return JVMTI_ERROR_NONE;
2635
}
2636
JavaThread* current_thread = JavaThread::current();
2637
HandleMark hm(current_thread);
2638
Klass* k = java_lang_Class::as_Klass(k_mirror);
2639
NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
2640
2641
oop result_oop = k->class_loader();
2642
if (result_oop == NULL) {
2643
*classloader_ptr = (jclass) jni_reference(Handle());
2644
return JVMTI_ERROR_NONE;
2645
}
2646
Handle result_handle = Handle(current_thread, result_oop);
2647
jclass result_jnihandle = (jclass) jni_reference(result_handle);
2648
*classloader_ptr = result_jnihandle;
2649
}
2650
return JVMTI_ERROR_NONE;
2651
} /* end GetClassLoader */
2652
2653
2654
// k_mirror - may be primitive, this must be checked
2655
// source_debug_extension_ptr - pre-checked for NULL
2656
jvmtiError
2657
JvmtiEnv::GetSourceDebugExtension(oop k_mirror, char** source_debug_extension_ptr) {
2658
{
2659
if (java_lang_Class::is_primitive(k_mirror)) {
2660
return JVMTI_ERROR_ABSENT_INFORMATION;
2661
}
2662
Klass* k = java_lang_Class::as_Klass(k_mirror);
2663
NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
2664
if (!k->is_instance_klass()) {
2665
return JVMTI_ERROR_ABSENT_INFORMATION;
2666
}
2667
const char* sde = InstanceKlass::cast(k)->source_debug_extension();
2668
NULL_CHECK(sde, JVMTI_ERROR_ABSENT_INFORMATION);
2669
2670
{
2671
*source_debug_extension_ptr = (char *) jvmtiMalloc(strlen(sde)+1);
2672
strcpy(*source_debug_extension_ptr, sde);
2673
}
2674
}
2675
2676
return JVMTI_ERROR_NONE;
2677
} /* end GetSourceDebugExtension */
2678
2679
//
2680
// Object functions
2681
//
2682
2683
// hash_code_ptr - pre-checked for NULL
2684
jvmtiError
2685
JvmtiEnv::GetObjectHashCode(jobject object, jint* hash_code_ptr) {
2686
oop mirror = JNIHandles::resolve_external_guard(object);
2687
NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT);
2688
NULL_CHECK(hash_code_ptr, JVMTI_ERROR_NULL_POINTER);
2689
2690
{
2691
jint result = (jint) mirror->identity_hash();
2692
*hash_code_ptr = result;
2693
}
2694
return JVMTI_ERROR_NONE;
2695
} /* end GetObjectHashCode */
2696
2697
2698
// info_ptr - pre-checked for NULL
2699
jvmtiError
2700
JvmtiEnv::GetObjectMonitorUsage(jobject object, jvmtiMonitorUsage* info_ptr) {
2701
// This needs to be performed at a safepoint to gather stable data
2702
// because monitor owner / waiters might not be suspended.
2703
VM_GetObjectMonitorUsage op(this, JavaThread::current(), object, info_ptr);
2704
VMThread::execute(&op);
2705
return op.result();
2706
} /* end GetObjectMonitorUsage */
2707
2708
2709
//
2710
// Field functions
2711
//
2712
2713
// name_ptr - NULL is a valid value, must be checked
2714
// signature_ptr - NULL is a valid value, must be checked
2715
// generic_ptr - NULL is a valid value, must be checked
2716
jvmtiError
2717
JvmtiEnv::GetFieldName(fieldDescriptor* fdesc_ptr, char** name_ptr, char** signature_ptr, char** generic_ptr) {
2718
JavaThread* current_thread = JavaThread::current();
2719
ResourceMark rm(current_thread);
2720
if (name_ptr == NULL) {
2721
// just don't return the name
2722
} else {
2723
const char* fieldName = fdesc_ptr->name()->as_C_string();
2724
*name_ptr = (char*) jvmtiMalloc(strlen(fieldName) + 1);
2725
if (*name_ptr == NULL)
2726
return JVMTI_ERROR_OUT_OF_MEMORY;
2727
strcpy(*name_ptr, fieldName);
2728
}
2729
if (signature_ptr== NULL) {
2730
// just don't return the signature
2731
} else {
2732
const char* fieldSignature = fdesc_ptr->signature()->as_C_string();
2733
*signature_ptr = (char*) jvmtiMalloc(strlen(fieldSignature) + 1);
2734
if (*signature_ptr == NULL)
2735
return JVMTI_ERROR_OUT_OF_MEMORY;
2736
strcpy(*signature_ptr, fieldSignature);
2737
}
2738
if (generic_ptr != NULL) {
2739
*generic_ptr = NULL;
2740
Symbol* soop = fdesc_ptr->generic_signature();
2741
if (soop != NULL) {
2742
const char* gen_sig = soop->as_C_string();
2743
if (gen_sig != NULL) {
2744
jvmtiError err = allocate(strlen(gen_sig) + 1, (unsigned char **)generic_ptr);
2745
if (err != JVMTI_ERROR_NONE) {
2746
return err;
2747
}
2748
strcpy(*generic_ptr, gen_sig);
2749
}
2750
}
2751
}
2752
return JVMTI_ERROR_NONE;
2753
} /* end GetFieldName */
2754
2755
2756
// declaring_class_ptr - pre-checked for NULL
2757
jvmtiError
2758
JvmtiEnv::GetFieldDeclaringClass(fieldDescriptor* fdesc_ptr, jclass* declaring_class_ptr) {
2759
2760
*declaring_class_ptr = get_jni_class_non_null(fdesc_ptr->field_holder());
2761
return JVMTI_ERROR_NONE;
2762
} /* end GetFieldDeclaringClass */
2763
2764
2765
// modifiers_ptr - pre-checked for NULL
2766
jvmtiError
2767
JvmtiEnv::GetFieldModifiers(fieldDescriptor* fdesc_ptr, jint* modifiers_ptr) {
2768
2769
AccessFlags resultFlags = fdesc_ptr->access_flags();
2770
jint result = resultFlags.as_int();
2771
*modifiers_ptr = result;
2772
2773
return JVMTI_ERROR_NONE;
2774
} /* end GetFieldModifiers */
2775
2776
2777
// is_synthetic_ptr - pre-checked for NULL
2778
jvmtiError
2779
JvmtiEnv::IsFieldSynthetic(fieldDescriptor* fdesc_ptr, jboolean* is_synthetic_ptr) {
2780
*is_synthetic_ptr = fdesc_ptr->is_synthetic();
2781
return JVMTI_ERROR_NONE;
2782
} /* end IsFieldSynthetic */
2783
2784
2785
//
2786
// Method functions
2787
//
2788
2789
// method - pre-checked for validity, but may be NULL meaning obsolete method
2790
// name_ptr - NULL is a valid value, must be checked
2791
// signature_ptr - NULL is a valid value, must be checked
2792
// generic_ptr - NULL is a valid value, must be checked
2793
jvmtiError
2794
JvmtiEnv::GetMethodName(Method* method, char** name_ptr, char** signature_ptr, char** generic_ptr) {
2795
NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
2796
JavaThread* current_thread = JavaThread::current();
2797
2798
ResourceMark rm(current_thread); // get the utf8 name and signature
2799
if (name_ptr == NULL) {
2800
// just don't return the name
2801
} else {
2802
const char* utf8_name = (const char *) method->name()->as_utf8();
2803
*name_ptr = (char *) jvmtiMalloc(strlen(utf8_name)+1);
2804
strcpy(*name_ptr, utf8_name);
2805
}
2806
if (signature_ptr == NULL) {
2807
// just don't return the signature
2808
} else {
2809
const char* utf8_signature = (const char *) method->signature()->as_utf8();
2810
*signature_ptr = (char *) jvmtiMalloc(strlen(utf8_signature) + 1);
2811
strcpy(*signature_ptr, utf8_signature);
2812
}
2813
2814
if (generic_ptr != NULL) {
2815
*generic_ptr = NULL;
2816
Symbol* soop = method->generic_signature();
2817
if (soop != NULL) {
2818
const char* gen_sig = soop->as_C_string();
2819
if (gen_sig != NULL) {
2820
jvmtiError err = allocate(strlen(gen_sig) + 1, (unsigned char **)generic_ptr);
2821
if (err != JVMTI_ERROR_NONE) {
2822
return err;
2823
}
2824
strcpy(*generic_ptr, gen_sig);
2825
}
2826
}
2827
}
2828
return JVMTI_ERROR_NONE;
2829
} /* end GetMethodName */
2830
2831
2832
// method - pre-checked for validity, but may be NULL meaning obsolete method
2833
// declaring_class_ptr - pre-checked for NULL
2834
jvmtiError
2835
JvmtiEnv::GetMethodDeclaringClass(Method* method, jclass* declaring_class_ptr) {
2836
NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
2837
(*declaring_class_ptr) = get_jni_class_non_null(method->method_holder());
2838
return JVMTI_ERROR_NONE;
2839
} /* end GetMethodDeclaringClass */
2840
2841
2842
// method - pre-checked for validity, but may be NULL meaning obsolete method
2843
// modifiers_ptr - pre-checked for NULL
2844
jvmtiError
2845
JvmtiEnv::GetMethodModifiers(Method* method, jint* modifiers_ptr) {
2846
NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
2847
(*modifiers_ptr) = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS;
2848
return JVMTI_ERROR_NONE;
2849
} /* end GetMethodModifiers */
2850
2851
2852
// method - pre-checked for validity, but may be NULL meaning obsolete method
2853
// max_ptr - pre-checked for NULL
2854
jvmtiError
2855
JvmtiEnv::GetMaxLocals(Method* method, jint* max_ptr) {
2856
NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
2857
// get max stack
2858
(*max_ptr) = method->max_locals();
2859
return JVMTI_ERROR_NONE;
2860
} /* end GetMaxLocals */
2861
2862
2863
// method - pre-checked for validity, but may be NULL meaning obsolete method
2864
// size_ptr - pre-checked for NULL
2865
jvmtiError
2866
JvmtiEnv::GetArgumentsSize(Method* method, jint* size_ptr) {
2867
NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
2868
// get size of arguments
2869
2870
(*size_ptr) = method->size_of_parameters();
2871
return JVMTI_ERROR_NONE;
2872
} /* end GetArgumentsSize */
2873
2874
2875
// method - pre-checked for validity, but may be NULL meaning obsolete method
2876
// entry_count_ptr - pre-checked for NULL
2877
// table_ptr - pre-checked for NULL
2878
jvmtiError
2879
JvmtiEnv::GetLineNumberTable(Method* method, jint* entry_count_ptr, jvmtiLineNumberEntry** table_ptr) {
2880
NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
2881
if (!method->has_linenumber_table()) {
2882
return (JVMTI_ERROR_ABSENT_INFORMATION);
2883
}
2884
2885
// The line number table is compressed so we don't know how big it is until decompressed.
2886
// Decompression is really fast so we just do it twice.
2887
2888
// Compute size of table
2889
jint num_entries = 0;
2890
CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
2891
while (stream.read_pair()) {
2892
num_entries++;
2893
}
2894
jvmtiLineNumberEntry *jvmti_table =
2895
(jvmtiLineNumberEntry *)jvmtiMalloc(num_entries * (sizeof(jvmtiLineNumberEntry)));
2896
2897
// Fill jvmti table
2898
if (num_entries > 0) {
2899
int index = 0;
2900
CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
2901
while (stream.read_pair()) {
2902
jvmti_table[index].start_location = (jlocation) stream.bci();
2903
jvmti_table[index].line_number = (jint) stream.line();
2904
index++;
2905
}
2906
assert(index == num_entries, "sanity check");
2907
}
2908
2909
// Set up results
2910
(*entry_count_ptr) = num_entries;
2911
(*table_ptr) = jvmti_table;
2912
2913
return JVMTI_ERROR_NONE;
2914
} /* end GetLineNumberTable */
2915
2916
2917
// method - pre-checked for validity, but may be NULL meaning obsolete method
2918
// start_location_ptr - pre-checked for NULL
2919
// end_location_ptr - pre-checked for NULL
2920
jvmtiError
2921
JvmtiEnv::GetMethodLocation(Method* method, jlocation* start_location_ptr, jlocation* end_location_ptr) {
2922
2923
NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
2924
// get start and end location
2925
(*end_location_ptr) = (jlocation) (method->code_size() - 1);
2926
if (method->code_size() == 0) {
2927
// there is no code so there is no start location
2928
(*start_location_ptr) = (jlocation)(-1);
2929
} else {
2930
(*start_location_ptr) = (jlocation)(0);
2931
}
2932
2933
return JVMTI_ERROR_NONE;
2934
} /* end GetMethodLocation */
2935
2936
2937
// method - pre-checked for validity, but may be NULL meaning obsolete method
2938
// entry_count_ptr - pre-checked for NULL
2939
// table_ptr - pre-checked for NULL
2940
jvmtiError
2941
JvmtiEnv::GetLocalVariableTable(Method* method, jint* entry_count_ptr, jvmtiLocalVariableEntry** table_ptr) {
2942
2943
NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
2944
JavaThread* current_thread = JavaThread::current();
2945
2946
// does the klass have any local variable information?
2947
InstanceKlass* ik = method->method_holder();
2948
if (!ik->access_flags().has_localvariable_table()) {
2949
return (JVMTI_ERROR_ABSENT_INFORMATION);
2950
}
2951
2952
ConstantPool* constants = method->constants();
2953
NULL_CHECK(constants, JVMTI_ERROR_ABSENT_INFORMATION);
2954
2955
// in the vm localvariable table representation, 6 consecutive elements in the table
2956
// represent a 6-tuple of shorts
2957
// [start_pc, length, name_index, descriptor_index, signature_index, index]
2958
jint num_entries = method->localvariable_table_length();
2959
jvmtiLocalVariableEntry *jvmti_table = (jvmtiLocalVariableEntry *)
2960
jvmtiMalloc(num_entries * (sizeof(jvmtiLocalVariableEntry)));
2961
2962
if (num_entries > 0) {
2963
LocalVariableTableElement* table = method->localvariable_table_start();
2964
for (int i = 0; i < num_entries; i++) {
2965
// get the 5 tuple information from the vm table
2966
jlocation start_location = (jlocation) table[i].start_bci;
2967
jint length = (jint) table[i].length;
2968
int name_index = (int) table[i].name_cp_index;
2969
int signature_index = (int) table[i].descriptor_cp_index;
2970
int generic_signature_index = (int) table[i].signature_cp_index;
2971
jint slot = (jint) table[i].slot;
2972
2973
// get utf8 name and signature
2974
char *name_buf = NULL;
2975
char *sig_buf = NULL;
2976
char *gen_sig_buf = NULL;
2977
{
2978
ResourceMark rm(current_thread);
2979
2980
const char *utf8_name = (const char *) constants->symbol_at(name_index)->as_utf8();
2981
name_buf = (char *) jvmtiMalloc(strlen(utf8_name)+1);
2982
strcpy(name_buf, utf8_name);
2983
2984
const char *utf8_signature = (const char *) constants->symbol_at(signature_index)->as_utf8();
2985
sig_buf = (char *) jvmtiMalloc(strlen(utf8_signature)+1);
2986
strcpy(sig_buf, utf8_signature);
2987
2988
if (generic_signature_index > 0) {
2989
const char *utf8_gen_sign = (const char *)
2990
constants->symbol_at(generic_signature_index)->as_utf8();
2991
gen_sig_buf = (char *) jvmtiMalloc(strlen(utf8_gen_sign)+1);
2992
strcpy(gen_sig_buf, utf8_gen_sign);
2993
}
2994
}
2995
2996
// fill in the jvmti local variable table
2997
jvmti_table[i].start_location = start_location;
2998
jvmti_table[i].length = length;
2999
jvmti_table[i].name = name_buf;
3000
jvmti_table[i].signature = sig_buf;
3001
jvmti_table[i].generic_signature = gen_sig_buf;
3002
jvmti_table[i].slot = slot;
3003
}
3004
}
3005
3006
// set results
3007
(*entry_count_ptr) = num_entries;
3008
(*table_ptr) = jvmti_table;
3009
3010
return JVMTI_ERROR_NONE;
3011
} /* end GetLocalVariableTable */
3012
3013
3014
// method - pre-checked for validity, but may be NULL meaning obsolete method
3015
// bytecode_count_ptr - pre-checked for NULL
3016
// bytecodes_ptr - pre-checked for NULL
3017
jvmtiError
3018
JvmtiEnv::GetBytecodes(Method* method, jint* bytecode_count_ptr, unsigned char** bytecodes_ptr) {
3019
NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3020
3021
methodHandle mh(Thread::current(), method);
3022
jint size = (jint)mh->code_size();
3023
jvmtiError err = allocate(size, bytecodes_ptr);
3024
if (err != JVMTI_ERROR_NONE) {
3025
return err;
3026
}
3027
3028
(*bytecode_count_ptr) = size;
3029
// get byte codes
3030
JvmtiClassFileReconstituter::copy_bytecodes(mh, *bytecodes_ptr);
3031
3032
return JVMTI_ERROR_NONE;
3033
} /* end GetBytecodes */
3034
3035
3036
// method - pre-checked for validity, but may be NULL meaning obsolete method
3037
// is_native_ptr - pre-checked for NULL
3038
jvmtiError
3039
JvmtiEnv::IsMethodNative(Method* method, jboolean* is_native_ptr) {
3040
NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3041
(*is_native_ptr) = method->is_native();
3042
return JVMTI_ERROR_NONE;
3043
} /* end IsMethodNative */
3044
3045
3046
// method - pre-checked for validity, but may be NULL meaning obsolete method
3047
// is_synthetic_ptr - pre-checked for NULL
3048
jvmtiError
3049
JvmtiEnv::IsMethodSynthetic(Method* method, jboolean* is_synthetic_ptr) {
3050
NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
3051
(*is_synthetic_ptr) = method->is_synthetic();
3052
return JVMTI_ERROR_NONE;
3053
} /* end IsMethodSynthetic */
3054
3055
3056
// method - pre-checked for validity, but may be NULL meaning obsolete method
3057
// is_obsolete_ptr - pre-checked for NULL
3058
jvmtiError
3059
JvmtiEnv::IsMethodObsolete(Method* method, jboolean* is_obsolete_ptr) {
3060
if (use_version_1_0_semantics() &&
3061
get_capabilities()->can_redefine_classes == 0) {
3062
// This JvmtiEnv requested version 1.0 semantics and this function
3063
// requires the can_redefine_classes capability in version 1.0 so
3064
// we need to return an error here.
3065
return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
3066
}
3067
3068
if (method == NULL || method->is_obsolete()) {
3069
*is_obsolete_ptr = true;
3070
} else {
3071
*is_obsolete_ptr = false;
3072
}
3073
return JVMTI_ERROR_NONE;
3074
} /* end IsMethodObsolete */
3075
3076
//
3077
// Raw Monitor functions
3078
//
3079
3080
// name - pre-checked for NULL
3081
// monitor_ptr - pre-checked for NULL
3082
jvmtiError
3083
JvmtiEnv::CreateRawMonitor(const char* name, jrawMonitorID* monitor_ptr) {
3084
JvmtiRawMonitor* rmonitor = new JvmtiRawMonitor(name);
3085
NULL_CHECK(rmonitor, JVMTI_ERROR_OUT_OF_MEMORY);
3086
3087
*monitor_ptr = (jrawMonitorID)rmonitor;
3088
3089
return JVMTI_ERROR_NONE;
3090
} /* end CreateRawMonitor */
3091
3092
3093
// rmonitor - pre-checked for validity
3094
jvmtiError
3095
JvmtiEnv::DestroyRawMonitor(JvmtiRawMonitor * rmonitor) {
3096
if (Threads::number_of_threads() == 0) {
3097
// Remove this monitor from pending raw monitors list
3098
// if it has entered in onload or start phase.
3099
JvmtiPendingMonitors::destroy(rmonitor);
3100
} else {
3101
Thread* thread = Thread::current();
3102
if (rmonitor->owner() == thread) {
3103
// The caller owns this monitor which we are about to destroy.
3104
// We exit the underlying synchronization object so that the
3105
// "delete monitor" call below can work without an assertion
3106
// failure on systems that don't like destroying synchronization
3107
// objects that are locked.
3108
int r;
3109
int recursion = rmonitor->recursions();
3110
for (int i = 0; i <= recursion; i++) {
3111
r = rmonitor->raw_exit(thread);
3112
assert(r == JvmtiRawMonitor::M_OK, "raw_exit should have worked");
3113
if (r != JvmtiRawMonitor::M_OK) { // robustness
3114
return JVMTI_ERROR_INTERNAL;
3115
}
3116
}
3117
}
3118
if (rmonitor->owner() != NULL) {
3119
// The caller is trying to destroy a monitor that is locked by
3120
// someone else. While this is not forbidden by the JVMTI
3121
// spec, it will cause an assertion failure on systems that don't
3122
// like destroying synchronization objects that are locked.
3123
// We indicate a problem with the error return (and leak the
3124
// monitor's memory).
3125
return JVMTI_ERROR_NOT_MONITOR_OWNER;
3126
}
3127
}
3128
3129
delete rmonitor;
3130
3131
return JVMTI_ERROR_NONE;
3132
} /* end DestroyRawMonitor */
3133
3134
3135
// rmonitor - pre-checked for validity
3136
jvmtiError
3137
JvmtiEnv::RawMonitorEnter(JvmtiRawMonitor * rmonitor) {
3138
if (Threads::number_of_threads() == 0) {
3139
// No JavaThreads exist so JvmtiRawMonitor enter cannot be
3140
// used, add this raw monitor to the pending list.
3141
// The pending monitors will be actually entered when
3142
// the VM is setup.
3143
// See transition_pending_raw_monitors in create_vm()
3144
// in thread.cpp.
3145
JvmtiPendingMonitors::enter(rmonitor);
3146
} else {
3147
rmonitor->raw_enter(Thread::current());
3148
}
3149
return JVMTI_ERROR_NONE;
3150
} /* end RawMonitorEnter */
3151
3152
3153
// rmonitor - pre-checked for validity
3154
jvmtiError
3155
JvmtiEnv::RawMonitorExit(JvmtiRawMonitor * rmonitor) {
3156
jvmtiError err = JVMTI_ERROR_NONE;
3157
3158
if (Threads::number_of_threads() == 0) {
3159
// No JavaThreads exist so just remove this monitor from the pending list.
3160
// Bool value from exit is false if rmonitor is not in the list.
3161
if (!JvmtiPendingMonitors::exit(rmonitor)) {
3162
err = JVMTI_ERROR_NOT_MONITOR_OWNER;
3163
}
3164
} else {
3165
Thread* thread = Thread::current();
3166
int r = rmonitor->raw_exit(thread);
3167
if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
3168
err = JVMTI_ERROR_NOT_MONITOR_OWNER;
3169
}
3170
}
3171
return err;
3172
} /* end RawMonitorExit */
3173
3174
3175
// rmonitor - pre-checked for validity
3176
jvmtiError
3177
JvmtiEnv::RawMonitorWait(JvmtiRawMonitor * rmonitor, jlong millis) {
3178
Thread* thread = Thread::current();
3179
int r = rmonitor->raw_wait(millis, thread);
3180
3181
switch (r) {
3182
case JvmtiRawMonitor::M_INTERRUPTED:
3183
return JVMTI_ERROR_INTERRUPT;
3184
case JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE:
3185
return JVMTI_ERROR_NOT_MONITOR_OWNER;
3186
default:
3187
return JVMTI_ERROR_NONE;
3188
}
3189
} /* end RawMonitorWait */
3190
3191
3192
// rmonitor - pre-checked for validity
3193
jvmtiError
3194
JvmtiEnv::RawMonitorNotify(JvmtiRawMonitor * rmonitor) {
3195
Thread* thread = Thread::current();
3196
int r = rmonitor->raw_notify(thread);
3197
3198
if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
3199
return JVMTI_ERROR_NOT_MONITOR_OWNER;
3200
}
3201
return JVMTI_ERROR_NONE;
3202
} /* end RawMonitorNotify */
3203
3204
3205
// rmonitor - pre-checked for validity
3206
jvmtiError
3207
JvmtiEnv::RawMonitorNotifyAll(JvmtiRawMonitor * rmonitor) {
3208
Thread* thread = Thread::current();
3209
int r = rmonitor->raw_notifyAll(thread);
3210
3211
if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
3212
return JVMTI_ERROR_NOT_MONITOR_OWNER;
3213
}
3214
return JVMTI_ERROR_NONE;
3215
} /* end RawMonitorNotifyAll */
3216
3217
3218
//
3219
// JNI Function Interception functions
3220
//
3221
3222
3223
// function_table - pre-checked for NULL
3224
jvmtiError
3225
JvmtiEnv::SetJNIFunctionTable(const jniNativeInterface* function_table) {
3226
// Copy jni function table at safepoint.
3227
VM_JNIFunctionTableCopier copier(function_table);
3228
VMThread::execute(&copier);
3229
3230
return JVMTI_ERROR_NONE;
3231
} /* end SetJNIFunctionTable */
3232
3233
3234
// function_table - pre-checked for NULL
3235
jvmtiError
3236
JvmtiEnv::GetJNIFunctionTable(jniNativeInterface** function_table) {
3237
*function_table=(jniNativeInterface*)jvmtiMalloc(sizeof(jniNativeInterface));
3238
if (*function_table == NULL)
3239
return JVMTI_ERROR_OUT_OF_MEMORY;
3240
memcpy(*function_table,(JavaThread::current())->get_jni_functions(),sizeof(jniNativeInterface));
3241
return JVMTI_ERROR_NONE;
3242
} /* end GetJNIFunctionTable */
3243
3244
3245
//
3246
// Event Management functions
3247
//
3248
3249
jvmtiError
3250
JvmtiEnv::GenerateEvents(jvmtiEvent event_type) {
3251
// can only generate two event types
3252
if (event_type != JVMTI_EVENT_COMPILED_METHOD_LOAD &&
3253
event_type != JVMTI_EVENT_DYNAMIC_CODE_GENERATED) {
3254
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3255
}
3256
3257
// for compiled_method_load events we must check that the environment
3258
// has the can_generate_compiled_method_load_events capability.
3259
if (event_type == JVMTI_EVENT_COMPILED_METHOD_LOAD) {
3260
if (get_capabilities()->can_generate_compiled_method_load_events == 0) {
3261
return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
3262
}
3263
return JvmtiCodeBlobEvents::generate_compiled_method_load_events(this);
3264
} else {
3265
return JvmtiCodeBlobEvents::generate_dynamic_code_events(this);
3266
}
3267
3268
} /* end GenerateEvents */
3269
3270
3271
//
3272
// Extension Mechanism functions
3273
//
3274
3275
// extension_count_ptr - pre-checked for NULL
3276
// extensions - pre-checked for NULL
3277
jvmtiError
3278
JvmtiEnv::GetExtensionFunctions(jint* extension_count_ptr, jvmtiExtensionFunctionInfo** extensions) {
3279
return JvmtiExtensions::get_functions(this, extension_count_ptr, extensions);
3280
} /* end GetExtensionFunctions */
3281
3282
3283
// extension_count_ptr - pre-checked for NULL
3284
// extensions - pre-checked for NULL
3285
jvmtiError
3286
JvmtiEnv::GetExtensionEvents(jint* extension_count_ptr, jvmtiExtensionEventInfo** extensions) {
3287
return JvmtiExtensions::get_events(this, extension_count_ptr, extensions);
3288
} /* end GetExtensionEvents */
3289
3290
3291
// callback - NULL is a valid value, must be checked
3292
jvmtiError
3293
JvmtiEnv::SetExtensionEventCallback(jint extension_event_index, jvmtiExtensionEvent callback) {
3294
return JvmtiExtensions::set_event_callback(this, extension_event_index, callback);
3295
} /* end SetExtensionEventCallback */
3296
3297
//
3298
// Timers functions
3299
//
3300
3301
// info_ptr - pre-checked for NULL
3302
jvmtiError
3303
JvmtiEnv::GetCurrentThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) {
3304
os::current_thread_cpu_time_info(info_ptr);
3305
return JVMTI_ERROR_NONE;
3306
} /* end GetCurrentThreadCpuTimerInfo */
3307
3308
3309
// nanos_ptr - pre-checked for NULL
3310
jvmtiError
3311
JvmtiEnv::GetCurrentThreadCpuTime(jlong* nanos_ptr) {
3312
*nanos_ptr = os::current_thread_cpu_time();
3313
return JVMTI_ERROR_NONE;
3314
} /* end GetCurrentThreadCpuTime */
3315
3316
3317
// info_ptr - pre-checked for NULL
3318
jvmtiError
3319
JvmtiEnv::GetThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) {
3320
os::thread_cpu_time_info(info_ptr);
3321
return JVMTI_ERROR_NONE;
3322
} /* end GetThreadCpuTimerInfo */
3323
3324
3325
// java_thread - protected by ThreadsListHandle and pre-checked
3326
// nanos_ptr - pre-checked for NULL
3327
jvmtiError
3328
JvmtiEnv::GetThreadCpuTime(JavaThread* java_thread, jlong* nanos_ptr) {
3329
*nanos_ptr = os::thread_cpu_time(java_thread);
3330
return JVMTI_ERROR_NONE;
3331
} /* end GetThreadCpuTime */
3332
3333
3334
// info_ptr - pre-checked for NULL
3335
jvmtiError
3336
JvmtiEnv::GetTimerInfo(jvmtiTimerInfo* info_ptr) {
3337
os::javaTimeNanos_info(info_ptr);
3338
return JVMTI_ERROR_NONE;
3339
} /* end GetTimerInfo */
3340
3341
3342
// nanos_ptr - pre-checked for NULL
3343
jvmtiError
3344
JvmtiEnv::GetTime(jlong* nanos_ptr) {
3345
*nanos_ptr = os::javaTimeNanos();
3346
return JVMTI_ERROR_NONE;
3347
} /* end GetTime */
3348
3349
3350
// processor_count_ptr - pre-checked for NULL
3351
jvmtiError
3352
JvmtiEnv::GetAvailableProcessors(jint* processor_count_ptr) {
3353
*processor_count_ptr = os::active_processor_count();
3354
return JVMTI_ERROR_NONE;
3355
} /* end GetAvailableProcessors */
3356
3357
jvmtiError
3358
JvmtiEnv::SetHeapSamplingInterval(jint sampling_interval) {
3359
if (sampling_interval < 0) {
3360
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3361
}
3362
ThreadHeapSampler::set_sampling_interval(sampling_interval);
3363
return JVMTI_ERROR_NONE;
3364
} /* end SetHeapSamplingInterval */
3365
3366
//
3367
// System Properties functions
3368
//
3369
3370
// count_ptr - pre-checked for NULL
3371
// property_ptr - pre-checked for NULL
3372
jvmtiError
3373
JvmtiEnv::GetSystemProperties(jint* count_ptr, char*** property_ptr) {
3374
jvmtiError err = JVMTI_ERROR_NONE;
3375
3376
// Get the number of readable properties.
3377
*count_ptr = Arguments::PropertyList_readable_count(Arguments::system_properties());
3378
3379
// Allocate memory to hold the exact number of readable properties.
3380
err = allocate(*count_ptr * sizeof(char *), (unsigned char **)property_ptr);
3381
if (err != JVMTI_ERROR_NONE) {
3382
return err;
3383
}
3384
int readable_count = 0;
3385
// Loop through the system properties until all the readable properties are found.
3386
for (SystemProperty* p = Arguments::system_properties(); p != NULL && readable_count < *count_ptr; p = p->next()) {
3387
if (p->is_readable()) {
3388
const char *key = p->key();
3389
char **tmp_value = *property_ptr+readable_count;
3390
readable_count++;
3391
err = allocate((strlen(key)+1) * sizeof(char), (unsigned char**)tmp_value);
3392
if (err == JVMTI_ERROR_NONE) {
3393
strcpy(*tmp_value, key);
3394
} else {
3395
// clean up previously allocated memory.
3396
for (int j = 0; j < readable_count; j++) {
3397
Deallocate((unsigned char*)*property_ptr+j);
3398
}
3399
Deallocate((unsigned char*)property_ptr);
3400
break;
3401
}
3402
}
3403
}
3404
assert(err != JVMTI_ERROR_NONE || readable_count == *count_ptr, "Bad readable property count");
3405
return err;
3406
} /* end GetSystemProperties */
3407
3408
3409
// property - pre-checked for NULL
3410
// value_ptr - pre-checked for NULL
3411
jvmtiError
3412
JvmtiEnv::GetSystemProperty(const char* property, char** value_ptr) {
3413
jvmtiError err = JVMTI_ERROR_NONE;
3414
const char *value;
3415
3416
// Return JVMTI_ERROR_NOT_AVAILABLE if property is not readable or doesn't exist.
3417
value = Arguments::PropertyList_get_readable_value(Arguments::system_properties(), property);
3418
if (value == NULL) {
3419
err = JVMTI_ERROR_NOT_AVAILABLE;
3420
} else {
3421
err = allocate((strlen(value)+1) * sizeof(char), (unsigned char **)value_ptr);
3422
if (err == JVMTI_ERROR_NONE) {
3423
strcpy(*value_ptr, value);
3424
}
3425
}
3426
return err;
3427
} /* end GetSystemProperty */
3428
3429
3430
// property - pre-checked for NULL
3431
// value - NULL is a valid value, must be checked
3432
jvmtiError
3433
JvmtiEnv::SetSystemProperty(const char* property, const char* value_ptr) {
3434
jvmtiError err =JVMTI_ERROR_NOT_AVAILABLE;
3435
3436
for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) {
3437
if (strcmp(property, p->key()) == 0) {
3438
if (p->set_writeable_value(value_ptr)) {
3439
err = JVMTI_ERROR_NONE;
3440
}
3441
}
3442
}
3443
return err;
3444
} /* end SetSystemProperty */
3445
3446