Mercurial > hg > truffle
annotate src/share/vm/services/attachListener.cpp @ 5763:a3d71693e0ce
removed bytecode disassembly from CodeCacheRuntime into separate BytecodeDisassembler class
removed VM call for doing bytecode disassembly
added support for explicitly excluding classes from JaCoCo (put '// JaCoCo Exclude' somewhere in the source file)
added node intrinsics to MaterializeNode
added snippets for the UnsignedMath classes
each file opened by CFGPrinter now includes a unique id in its name to avoid a race of multiple threads writing to the same file
the IdealGraphPrinter uses the new BytecodeDisassembler mechanism
teh UnsignedMath class is exclude from JaCoCo processing as it is used in snippets
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 04 Jul 2012 21:57:49 +0200 |
parents | 4f25538b54c9 |
children | d2a62e0f25eb |
rev | line source |
---|---|
0 | 1 /* |
2426
1d1603768966
7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents:
2177
diff
changeset
|
2 * Copyright (c) 2005, 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:
1142
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1142
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:
1142
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/javaClasses.hpp" | |
27 #include "classfile/systemDictionary.hpp" | |
28 #include "gc_implementation/shared/vmGCOperations.hpp" | |
29 #include "memory/resourceArea.hpp" | |
30 #include "prims/jvmtiExport.hpp" | |
31 #include "runtime/arguments.hpp" | |
32 #include "runtime/globals.hpp" | |
33 #include "runtime/java.hpp" | |
34 #include "runtime/javaCalls.hpp" | |
35 #include "runtime/os.hpp" | |
36 #include "services/attachListener.hpp" | |
4133 | 37 #include "services/diagnosticCommand.hpp" |
1972 | 38 #include "services/heapDumper.hpp" |
0 | 39 |
40 volatile bool AttachListener::_initialized; | |
41 | |
42 // Implementation of "properties" command. | |
43 // | |
44 // Invokes sun.misc.VMSupport.serializePropertiesToByteArray to serialize | |
45 // the system properties into a byte array. | |
46 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
47 static klassOop load_and_initialize_klass(Symbol* sh, TRAPS) { |
0 | 48 klassOop k = SystemDictionary::resolve_or_fail(sh, true, CHECK_NULL); |
49 instanceKlassHandle ik (THREAD, k); | |
50 if (ik->should_be_initialized()) { | |
51 ik->initialize(CHECK_NULL); | |
52 } | |
53 return ik(); | |
54 } | |
55 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
56 static jint get_properties(AttachOperation* op, outputStream* out, Symbol* serializePropertiesMethod) { |
0 | 57 Thread* THREAD = Thread::current(); |
58 HandleMark hm; | |
59 | |
60 // load sun.misc.VMSupport | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
61 Symbol* klass = vmSymbols::sun_misc_VMSupport(); |
0 | 62 klassOop k = load_and_initialize_klass(klass, THREAD); |
63 if (HAS_PENDING_EXCEPTION) { | |
64 java_lang_Throwable::print(PENDING_EXCEPTION, out); | |
65 CLEAR_PENDING_EXCEPTION; | |
66 return JNI_ERR; | |
67 } | |
68 instanceKlassHandle ik(THREAD, k); | |
69 | |
70 // invoke the serializePropertiesToByteArray method | |
71 JavaValue result(T_OBJECT); | |
72 JavaCallArguments args; | |
73 | |
74 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
75 Symbol* signature = vmSymbols::serializePropertiesToByteArray_signature(); |
0 | 76 JavaCalls::call_static(&result, |
77 ik, | |
78 serializePropertiesMethod, | |
79 signature, | |
80 &args, | |
81 THREAD); | |
82 if (HAS_PENDING_EXCEPTION) { | |
83 java_lang_Throwable::print(PENDING_EXCEPTION, out); | |
84 CLEAR_PENDING_EXCEPTION; | |
85 return JNI_ERR; | |
86 } | |
87 | |
88 // The result should be a [B | |
89 oop res = (oop)result.get_jobject(); | |
90 assert(res->is_typeArray(), "just checking"); | |
91 assert(typeArrayKlass::cast(res->klass())->element_type() == T_BYTE, "just checking"); | |
92 | |
93 // copy the bytes to the output stream | |
94 typeArrayOop ba = typeArrayOop(res); | |
95 jbyte* addr = typeArrayOop(res)->byte_at_addr(0); | |
96 out->print_raw((const char*)addr, ba->length()); | |
97 | |
98 return JNI_OK; | |
99 } | |
100 | |
101 // Implementation of "properties" command. | |
4773 | 102 // See also: PrintSystemPropertiesDCmd class |
0 | 103 static jint get_system_properties(AttachOperation* op, outputStream* out) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
104 return get_properties(op, out, vmSymbols::serializePropertiesToByteArray_name()); |
0 | 105 } |
106 | |
107 // Implementation of "agent_properties" command. | |
108 static jint get_agent_properties(AttachOperation* op, outputStream* out) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
109 return get_properties(op, out, vmSymbols::serializeAgentPropertiesToByteArray_name()); |
0 | 110 } |
111 | |
112 // Implementation of "datadump" command. | |
113 // | |
114 // Raises a SIGBREAK signal so that VM dump threads, does deadlock detection, | |
115 // etc. In theory this command should only post a DataDumpRequest to any | |
116 // JVMTI environment that has enabled this event. However it's useful to | |
117 // trigger the SIGBREAK handler. | |
118 | |
119 static jint data_dump(AttachOperation* op, outputStream* out) { | |
120 if (!ReduceSignalUsage) { | |
121 AttachListener::pd_data_dump(); | |
122 } else { | |
123 if (JvmtiExport::should_post_data_dump()) { | |
124 JvmtiExport::post_data_dump(); | |
125 } | |
126 } | |
127 return JNI_OK; | |
128 } | |
129 | |
130 // Implementation of "threaddump" command - essentially a remote ctrl-break | |
4773 | 131 // See also: ThreadDumpDCmd class |
0 | 132 // |
133 static jint thread_dump(AttachOperation* op, outputStream* out) { | |
134 bool print_concurrent_locks = false; | |
135 if (op->arg(0) != NULL && strcmp(op->arg(0), "-l") == 0) { | |
136 print_concurrent_locks = true; | |
137 } | |
138 | |
139 // thread stacks | |
140 VM_PrintThreads op1(out, print_concurrent_locks); | |
141 VMThread::execute(&op1); | |
142 | |
143 // JNI global handles | |
144 VM_PrintJNI op2(out); | |
145 VMThread::execute(&op2); | |
146 | |
147 // Deadlock detection | |
148 VM_FindDeadlocks op3(out); | |
149 VMThread::execute(&op3); | |
150 | |
151 return JNI_OK; | |
152 } | |
153 | |
4133 | 154 // A jcmd attach operation request was received, which will now |
155 // dispatch to the diagnostic commands used for serviceability functions. | |
156 static jint jcmd(AttachOperation* op, outputStream* out) { | |
157 Thread* THREAD = Thread::current(); | |
158 // All the supplied jcmd arguments are stored as a single | |
159 // string (op->arg(0)). This is parsed by the Dcmd framework. | |
160 DCmd::parse_and_execute(out, op->arg(0), ' ', THREAD); | |
161 if (HAS_PENDING_EXCEPTION) { | |
162 java_lang_Throwable::print(PENDING_EXCEPTION, out); | |
4773 | 163 out->cr(); |
4133 | 164 CLEAR_PENDING_EXCEPTION; |
165 // The exception has been printed on the output stream | |
166 // If the JVM returns JNI_ERR, the attachAPI throws a generic I/O | |
167 // exception and the content of the output stream is not processed. | |
168 // By returning JNI_OK, the exception will be displayed on the client side | |
169 } | |
170 return JNI_OK; | |
171 } | |
172 | |
0 | 173 #ifndef SERVICES_KERNEL // Heap dumping not supported |
174 // Implementation of "dumpheap" command. | |
4773 | 175 // See also: HeapDumpDCmd class |
0 | 176 // |
177 // Input arguments :- | |
178 // arg0: Name of the dump file | |
179 // arg1: "-live" or "-all" | |
180 jint dump_heap(AttachOperation* op, outputStream* out) { | |
181 const char* path = op->arg(0); | |
182 if (path == NULL || path[0] == '\0') { | |
183 out->print_cr("No dump file specified"); | |
184 } else { | |
185 bool live_objects_only = true; // default is true to retain the behavior before this change is made | |
186 const char* arg1 = op->arg(1); | |
187 if (arg1 != NULL && (strlen(arg1) > 0)) { | |
188 if (strcmp(arg1, "-all") != 0 && strcmp(arg1, "-live") != 0) { | |
189 out->print_cr("Invalid argument to dumpheap operation: %s", arg1); | |
190 return JNI_ERR; | |
191 } | |
192 live_objects_only = strcmp(arg1, "-live") == 0; | |
193 } | |
194 | |
195 // Request a full GC before heap dump if live_objects_only = true | |
196 // This helps reduces the amount of unreachable objects in the dump | |
197 // and makes it easier to browse. | |
198 HeapDumper dumper(live_objects_only /* request GC */); | |
199 int res = dumper.dump(op->arg(0)); | |
200 if (res == 0) { | |
201 out->print_cr("Heap dump file created"); | |
202 } else { | |
203 // heap dump failed | |
204 ResourceMark rm; | |
205 char* error = dumper.error_as_C_string(); | |
206 if (error == NULL) { | |
207 out->print_cr("Dump failed - reason unknown"); | |
208 } else { | |
209 out->print_cr("%s", error); | |
210 } | |
211 } | |
212 } | |
213 return JNI_OK; | |
214 } | |
215 #endif // SERVICES_KERNEL | |
216 | |
217 // Implementation of "inspectheap" command | |
4773 | 218 // See also: ClassHistogramDCmd class |
0 | 219 // |
220 // Input arguments :- | |
221 // arg0: "-live" or "-all" | |
222 static jint heap_inspection(AttachOperation* op, outputStream* out) { | |
223 bool live_objects_only = true; // default is true to retain the behavior before this change is made | |
224 const char* arg0 = op->arg(0); | |
225 if (arg0 != NULL && (strlen(arg0) > 0)) { | |
226 if (strcmp(arg0, "-all") != 0 && strcmp(arg0, "-live") != 0) { | |
227 out->print_cr("Invalid argument to inspectheap operation: %s", arg0); | |
228 return JNI_ERR; | |
229 } | |
230 live_objects_only = strcmp(arg0, "-live") == 0; | |
231 } | |
615
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
0
diff
changeset
|
232 VM_GC_HeapInspection heapop(out, live_objects_only /* request full gc */, true /* need_prologue */); |
0 | 233 VMThread::execute(&heapop); |
234 return JNI_OK; | |
235 } | |
236 | |
237 // set a boolean global flag using value from AttachOperation | |
238 static jint set_bool_flag(const char* name, AttachOperation* op, outputStream* out) { | |
239 bool value = true; | |
240 const char* arg1; | |
241 if ((arg1 = op->arg(1)) != NULL) { | |
242 int tmp; | |
243 int n = sscanf(arg1, "%d", &tmp); | |
244 if (n != 1) { | |
1067
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
245 out->print_cr("flag value must be a boolean (1 or 0)"); |
0 | 246 return JNI_ERR; |
247 } | |
248 value = (tmp != 0); | |
249 } | |
250 bool res = CommandLineFlags::boolAtPut((char*)name, &value, ATTACH_ON_DEMAND); | |
251 if (! res) { | |
252 out->print_cr("setting flag %s failed", name); | |
253 } | |
254 return res? JNI_OK : JNI_ERR; | |
255 } | |
256 | |
257 // set a intx global flag using value from AttachOperation | |
258 static jint set_intx_flag(const char* name, AttachOperation* op, outputStream* out) { | |
259 intx value; | |
260 const char* arg1; | |
261 if ((arg1 = op->arg(1)) != NULL) { | |
262 int n = sscanf(arg1, INTX_FORMAT, &value); | |
263 if (n != 1) { | |
1067
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
264 out->print_cr("flag value must be an integer"); |
0 | 265 return JNI_ERR; |
266 } | |
267 } | |
1067
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
268 bool res = CommandLineFlags::intxAtPut((char*)name, &value, ATTACH_ON_DEMAND); |
0 | 269 if (! res) { |
270 out->print_cr("setting flag %s failed", name); | |
271 } | |
272 | |
273 return res? JNI_OK : JNI_ERR; | |
274 } | |
275 | |
276 // set a uintx global flag using value from AttachOperation | |
277 static jint set_uintx_flag(const char* name, AttachOperation* op, outputStream* out) { | |
278 uintx value; | |
279 const char* arg1; | |
280 if ((arg1 = op->arg(1)) != NULL) { | |
281 int n = sscanf(arg1, UINTX_FORMAT, &value); | |
282 if (n != 1) { | |
1067
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
283 out->print_cr("flag value must be an unsigned integer"); |
0 | 284 return JNI_ERR; |
285 } | |
286 } | |
1067
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
287 bool res = CommandLineFlags::uintxAtPut((char*)name, &value, ATTACH_ON_DEMAND); |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
288 if (! res) { |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
289 out->print_cr("setting flag %s failed", name); |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
290 } |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
291 |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
292 return res? JNI_OK : JNI_ERR; |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
293 } |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
294 |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
295 // set a uint64_t global flag using value from AttachOperation |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
296 static jint set_uint64_t_flag(const char* name, AttachOperation* op, outputStream* out) { |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
297 uint64_t value; |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
298 const char* arg1; |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
299 if ((arg1 = op->arg(1)) != NULL) { |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
300 int n = sscanf(arg1, UINT64_FORMAT, &value); |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
301 if (n != 1) { |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
302 out->print_cr("flag value must be an unsigned 64-bit integer"); |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
303 return JNI_ERR; |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
304 } |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
305 } |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
306 bool res = CommandLineFlags::uint64_tAtPut((char*)name, &value, ATTACH_ON_DEMAND); |
0 | 307 if (! res) { |
308 out->print_cr("setting flag %s failed", name); | |
309 } | |
310 | |
311 return res? JNI_OK : JNI_ERR; | |
312 } | |
313 | |
314 // set a string global flag using value from AttachOperation | |
315 static jint set_ccstr_flag(const char* name, AttachOperation* op, outputStream* out) { | |
316 const char* value; | |
317 if ((value = op->arg(1)) == NULL) { | |
1067
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
318 out->print_cr("flag value must be a string"); |
0 | 319 return JNI_ERR; |
320 } | |
1067
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
321 bool res = CommandLineFlags::ccstrAtPut((char*)name, &value, ATTACH_ON_DEMAND); |
0 | 322 if (res) { |
323 FREE_C_HEAP_ARRAY(char, value); | |
324 } else { | |
325 out->print_cr("setting flag %s failed", name); | |
326 } | |
327 | |
328 return res? JNI_OK : JNI_ERR; | |
329 } | |
330 | |
331 // Implementation of "setflag" command | |
332 static jint set_flag(AttachOperation* op, outputStream* out) { | |
333 | |
334 const char* name = NULL; | |
335 if ((name = op->arg(0)) == NULL) { | |
336 out->print_cr("flag name is missing"); | |
337 return JNI_ERR; | |
338 } | |
339 | |
340 Flag* f = Flag::find_flag((char*)name, strlen(name)); | |
341 if (f && f->is_external() && f->is_writeable()) { | |
342 if (f->is_bool()) { | |
343 return set_bool_flag(name, op, out); | |
344 } else if (f->is_intx()) { | |
345 return set_intx_flag(name, op, out); | |
346 } else if (f->is_uintx()) { | |
347 return set_uintx_flag(name, op, out); | |
1067
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
348 } else if (f->is_uint64_t()) { |
ba7ea42fc66e
6898160: Need serviceability support for new vm argument type 'uint64_t'
phh
parents:
615
diff
changeset
|
349 return set_uint64_t_flag(name, op, out); |
0 | 350 } else if (f->is_ccstr()) { |
351 return set_ccstr_flag(name, op, out); | |
352 } else { | |
353 ShouldNotReachHere(); | |
354 return JNI_ERR; | |
355 } | |
356 } else { | |
357 return AttachListener::pd_set_flag(op, out); | |
358 } | |
359 } | |
360 | |
361 // Implementation of "printflag" command | |
4773 | 362 // See also: PrintVMFlagsDCmd class |
0 | 363 static jint print_flag(AttachOperation* op, outputStream* out) { |
364 const char* name = NULL; | |
365 if ((name = op->arg(0)) == NULL) { | |
366 out->print_cr("flag name is missing"); | |
367 return JNI_ERR; | |
368 } | |
369 Flag* f = Flag::find_flag((char*)name, strlen(name)); | |
370 if (f) { | |
371 f->print_as_flag(out); | |
372 out->print_cr(""); | |
373 } else { | |
374 out->print_cr("no such flag '%s'", name); | |
375 } | |
376 return JNI_OK; | |
377 } | |
378 | |
379 // Table to map operation names to functions. | |
380 | |
381 // names must be of length <= AttachOperation::name_length_max | |
382 static AttachOperationFunctionInfo funcs[] = { | |
383 { "agentProperties", get_agent_properties }, | |
384 { "datadump", data_dump }, | |
385 #ifndef SERVICES_KERNEL | |
386 { "dumpheap", dump_heap }, | |
387 #endif // SERVICES_KERNEL | |
388 { "load", JvmtiExport::load_agent_library }, | |
389 { "properties", get_system_properties }, | |
390 { "threaddump", thread_dump }, | |
391 { "inspectheap", heap_inspection }, | |
392 { "setflag", set_flag }, | |
393 { "printflag", print_flag }, | |
4133 | 394 { "jcmd", jcmd }, |
0 | 395 { NULL, NULL } |
396 }; | |
397 | |
398 | |
399 | |
400 // The Attach Listener threads services a queue. It dequeues an operation | |
401 // from the queue, examines the operation name (command), and dispatches | |
402 // to the corresponding function to perform the operation. | |
403 | |
404 static void attach_listener_thread_entry(JavaThread* thread, TRAPS) { | |
405 os::set_priority(thread, NearMaxPriority); | |
406 | |
407 if (AttachListener::pd_init() != 0) { | |
408 return; | |
409 } | |
410 AttachListener::set_initialized(); | |
411 | |
412 for (;;) { | |
413 AttachOperation* op = AttachListener::dequeue(); | |
414 if (op == NULL) { | |
415 return; // dequeue failed or shutdown | |
416 } | |
417 | |
418 ResourceMark rm; | |
419 bufferedStream st; | |
420 jint res = JNI_OK; | |
421 | |
422 // handle special detachall operation | |
423 if (strcmp(op->name(), AttachOperation::detachall_operation_name()) == 0) { | |
424 AttachListener::detachall(); | |
425 } else { | |
426 // find the function to dispatch too | |
427 AttachOperationFunctionInfo* info = NULL; | |
428 for (int i=0; funcs[i].name != NULL; i++) { | |
429 const char* name = funcs[i].name; | |
430 assert(strlen(name) <= AttachOperation::name_length_max, "operation <= name_length_max"); | |
431 if (strcmp(op->name(), name) == 0) { | |
432 info = &(funcs[i]); | |
433 break; | |
434 } | |
435 } | |
436 | |
437 // check for platform dependent attach operation | |
438 if (info == NULL) { | |
439 info = AttachListener::pd_find_operation(op->name()); | |
440 } | |
441 | |
442 if (info != NULL) { | |
443 // dispatch to the function that implements this operation | |
444 res = (info->func)(op, &st); | |
445 } else { | |
446 st.print("Operation %s not recognized!", op->name()); | |
447 res = JNI_ERR; | |
448 } | |
449 } | |
450 | |
451 // operation complete - send result and output to client | |
452 op->complete(res, &st); | |
453 } | |
454 } | |
455 | |
456 // Starts the Attach Listener thread | |
457 void AttachListener::init() { | |
458 EXCEPTION_MARK; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
459 klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK); |
0 | 460 instanceKlassHandle klass (THREAD, k); |
461 instanceHandle thread_oop = klass->allocate_instance_handle(CHECK); | |
462 | |
463 const char thread_name[] = "Attach Listener"; | |
464 Handle string = java_lang_String::create_from_str(thread_name, CHECK); | |
465 | |
466 // Initialize thread_oop to put it into the system threadGroup | |
467 Handle thread_group (THREAD, Universe::system_thread_group()); | |
468 JavaValue result(T_VOID); | |
469 JavaCalls::call_special(&result, thread_oop, | |
470 klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
471 vmSymbols::object_initializer_name(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
472 vmSymbols::threadgroup_string_void_signature(), |
0 | 473 thread_group, |
474 string, | |
475 CHECK); | |
476 | |
1142 | 477 KlassHandle group(THREAD, SystemDictionary::ThreadGroup_klass()); |
0 | 478 JavaCalls::call_special(&result, |
479 thread_group, | |
480 group, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
481 vmSymbols::add_method_name(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
482 vmSymbols::thread_void_signature(), |
0 | 483 thread_oop, // ARG 1 |
484 CHECK); | |
485 | |
486 { MutexLocker mu(Threads_lock); | |
487 JavaThread* listener_thread = new JavaThread(&attach_listener_thread_entry); | |
488 | |
489 // Check that thread and osthread were created | |
490 if (listener_thread == NULL || listener_thread->osthread() == NULL) { | |
491 vm_exit_during_initialization("java.lang.OutOfMemoryError", | |
492 "unable to create new native thread"); | |
493 } | |
494 | |
495 java_lang_Thread::set_thread(thread_oop(), listener_thread); | |
496 java_lang_Thread::set_daemon(thread_oop()); | |
497 | |
498 listener_thread->set_threadObj(thread_oop()); | |
499 Threads::add(listener_thread); | |
500 Thread::start(listener_thread); | |
501 } | |
502 } | |
503 | |
504 // Performs clean-up tasks on platforms where we can detect that the last | |
505 // client has detached | |
506 void AttachListener::detachall() { | |
507 // call the platform dependent clean-up | |
508 pd_detachall(); | |
509 } |