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