Mercurial > hg > openjdk > jdk7u > hotspot
changeset 3260:bca9e76ea254 jdk7u6-b03
Merge
author | asaha |
---|---|
date | Tue, 20 Mar 2012 10:17:41 -0700 |
parents | f1bccf74b888 (current diff) 376549fed156 (diff) |
children | b82c43fba5c0 |
files | .hgtags |
diffstat | 8 files changed, 495 insertions(+), 75 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Mon Mar 19 23:17:13 2012 -0700 +++ b/.hgtags Tue Mar 20 10:17:41 2012 -0700 @@ -251,5 +251,9 @@ f92a171cf0071ca6c3fa8231d7d570377f8b2f4d hs23-b16 931e5f39e365a0d550d79148ff87a7f9e864d2e1 hs23-b16 efb5f2662c96c472caa3327090268c75a86dd9c0 jdk7u4-b13 +82e719a2e6416838b4421637646cbfd7104c7716 jdk7u4-b14 +1c483d994a78e46c4656b6f3773c7014346d0f19 jdk7u4-b15 +34a4f7687460b1b2bfb1d87191919c5f101aa988 hs23-b17 +c6a96f7a781dd23d2b9fd6353fcd87493616c803 jdk7u4-b16 82e719a2e6416838b4421637646cbfd7104c7716 jdk7u6-b01 6b71938ee832043c337aa837fc0eb3bef088fd52 jdk7u6-b02
--- a/make/hotspot_version Mon Mar 19 23:17:13 2012 -0700 +++ b/make/hotspot_version Tue Mar 20 10:17:41 2012 -0700 @@ -35,7 +35,7 @@ HS_MAJOR_VER=23 HS_MINOR_VER=0 -HS_BUILD_NUMBER=16 +HS_BUILD_NUMBER=17 JDK_MAJOR_VER=1 JDK_MINOR_VER=8
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Mon Mar 19 23:17:13 2012 -0700 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Tue Mar 20 10:17:41 2012 -0700 @@ -1181,14 +1181,13 @@ BasicType* in_sig_bt) { // if map is non-NULL then the code should store the values, // otherwise it should load them. - int handle_index = 0; + int slot = arg_save_area; // Save down double word first for ( int i = 0; i < total_in_args; i++) { if (in_regs[i].first()->is_XMMRegister() && in_sig_bt[i] == T_DOUBLE) { - int slot = handle_index * VMRegImpl::slots_per_word + arg_save_area; int offset = slot * VMRegImpl::stack_slot_size; - handle_index += 2; - assert(handle_index <= stack_slots, "overflow"); + slot += VMRegImpl::slots_per_word; + assert(slot <= stack_slots, "overflow"); if (map != NULL) { __ movdbl(Address(rsp, offset), in_regs[i].first()->as_XMMRegister()); } else { @@ -1197,10 +1196,7 @@ } if (in_regs[i].first()->is_Register() && (in_sig_bt[i] == T_LONG || in_sig_bt[i] == T_ARRAY)) { - int slot = handle_index * VMRegImpl::slots_per_word + arg_save_area; int offset = slot * VMRegImpl::stack_slot_size; - handle_index += 2; - assert(handle_index <= stack_slots, "overflow"); if (map != NULL) { __ movq(Address(rsp, offset), in_regs[i].first()->as_Register()); if (in_sig_bt[i] == T_ARRAY) { @@ -1209,14 +1205,15 @@ } else { __ movq(in_regs[i].first()->as_Register(), Address(rsp, offset)); } + slot += VMRegImpl::slots_per_word; } } // Save or restore single word registers for ( int i = 0; i < total_in_args; i++) { if (in_regs[i].first()->is_Register()) { - int slot = handle_index++ * VMRegImpl::slots_per_word + arg_save_area; int offset = slot * VMRegImpl::stack_slot_size; - assert(handle_index <= stack_slots, "overflow"); + slot++; + assert(slot <= stack_slots, "overflow"); // Value is in an input register pass we must flush it to the stack const Register reg = in_regs[i].first()->as_Register(); @@ -1241,9 +1238,9 @@ } } else if (in_regs[i].first()->is_XMMRegister()) { if (in_sig_bt[i] == T_FLOAT) { - int slot = handle_index++ * VMRegImpl::slots_per_word + arg_save_area; int offset = slot * VMRegImpl::stack_slot_size; - assert(handle_index <= stack_slots, "overflow"); + slot++; + assert(slot <= stack_slots, "overflow"); if (map != NULL) { __ movflt(Address(rsp, offset), in_regs[i].first()->as_XMMRegister()); } else { @@ -1368,6 +1365,174 @@ __ bind(done); } + +class ComputeMoveOrder: public StackObj { + class MoveOperation: public ResourceObj { + friend class ComputeMoveOrder; + private: + VMRegPair _src; + VMRegPair _dst; + int _src_index; + int _dst_index; + bool _processed; + MoveOperation* _next; + MoveOperation* _prev; + + static int get_id(VMRegPair r) { + return r.first()->value(); + } + + public: + MoveOperation(int src_index, VMRegPair src, int dst_index, VMRegPair dst): + _src(src) + , _src_index(src_index) + , _dst(dst) + , _dst_index(dst_index) + , _next(NULL) + , _prev(NULL) + , _processed(false) { + } + + VMRegPair src() const { return _src; } + int src_id() const { return get_id(src()); } + int src_index() const { return _src_index; } + VMRegPair dst() const { return _dst; } + void set_dst(int i, VMRegPair dst) { _dst_index = i, _dst = dst; } + int dst_index() const { return _dst_index; } + int dst_id() const { return get_id(dst()); } + MoveOperation* next() const { return _next; } + MoveOperation* prev() const { return _prev; } + void set_processed() { _processed = true; } + bool is_processed() const { return _processed; } + + // insert + void break_cycle(VMRegPair temp_register) { + // create a new store following the last store + // to move from the temp_register to the original + MoveOperation* new_store = new MoveOperation(-1, temp_register, dst_index(), dst()); + + // break the cycle of links and insert new_store at the end + // break the reverse link. + MoveOperation* p = prev(); + assert(p->next() == this, "must be"); + _prev = NULL; + p->_next = new_store; + new_store->_prev = p; + + // change the original store to save it's value in the temp. + set_dst(-1, temp_register); + } + + void link(GrowableArray<MoveOperation*>& killer) { + // link this store in front the store that it depends on + MoveOperation* n = killer.at_grow(src_id(), NULL); + if (n != NULL) { + assert(_next == NULL && n->_prev == NULL, "shouldn't have been set yet"); + _next = n; + n->_prev = this; + } + } + }; + + private: + GrowableArray<MoveOperation*> edges; + + public: + ComputeMoveOrder(int total_in_args, VMRegPair* in_regs, int total_c_args, VMRegPair* out_regs, + BasicType* in_sig_bt, GrowableArray<int>& arg_order, VMRegPair tmp_vmreg) { + // Move operations where the dest is the stack can all be + // scheduled first since they can't interfere with the other moves. + for (int i = total_in_args - 1, c_arg = total_c_args - 1; i >= 0; i--, c_arg--) { + if (in_sig_bt[i] == T_ARRAY) { + c_arg--; + if (out_regs[c_arg].first()->is_stack() && + out_regs[c_arg + 1].first()->is_stack()) { + arg_order.push(i); + arg_order.push(c_arg); + } else { + if (out_regs[c_arg].first()->is_stack() || + in_regs[i].first() == out_regs[c_arg].first()) { + add_edge(i, in_regs[i].first(), c_arg, out_regs[c_arg + 1]); + } else { + add_edge(i, in_regs[i].first(), c_arg, out_regs[c_arg]); + } + } + } else if (in_sig_bt[i] == T_VOID) { + arg_order.push(i); + arg_order.push(c_arg); + } else { + if (out_regs[c_arg].first()->is_stack() || + in_regs[i].first() == out_regs[c_arg].first()) { + arg_order.push(i); + arg_order.push(c_arg); + } else { + add_edge(i, in_regs[i].first(), c_arg, out_regs[c_arg]); + } + } + } + // Break any cycles in the register moves and emit the in the + // proper order. + GrowableArray<MoveOperation*>* stores = get_store_order(tmp_vmreg); + for (int i = 0; i < stores->length(); i++) { + arg_order.push(stores->at(i)->src_index()); + arg_order.push(stores->at(i)->dst_index()); + } + } + + // Collected all the move operations + void add_edge(int src_index, VMRegPair src, int dst_index, VMRegPair dst) { + if (src.first() == dst.first()) return; + edges.append(new MoveOperation(src_index, src, dst_index, dst)); + } + + // Walk the edges breaking cycles between moves. The result list + // can be walked in order to produce the proper set of loads + GrowableArray<MoveOperation*>* get_store_order(VMRegPair temp_register) { + // Record which moves kill which values + GrowableArray<MoveOperation*> killer; + for (int i = 0; i < edges.length(); i++) { + MoveOperation* s = edges.at(i); + assert(killer.at_grow(s->dst_id(), NULL) == NULL, "only one killer"); + killer.at_put_grow(s->dst_id(), s, NULL); + } + assert(killer.at_grow(MoveOperation::get_id(temp_register), NULL) == NULL, + "make sure temp isn't in the registers that are killed"); + + // create links between loads and stores + for (int i = 0; i < edges.length(); i++) { + edges.at(i)->link(killer); + } + + // at this point, all the move operations are chained together + // in a doubly linked list. Processing it backwards finds + // the beginning of the chain, forwards finds the end. If there's + // a cycle it can be broken at any point, so pick an edge and walk + // backward until the list ends or we end where we started. + GrowableArray<MoveOperation*>* stores = new GrowableArray<MoveOperation*>(); + for (int e = 0; e < edges.length(); e++) { + MoveOperation* s = edges.at(e); + if (!s->is_processed()) { + MoveOperation* start = s; + // search for the beginning of the chain or cycle + while (start->prev() != NULL && start->prev() != s) { + start = start->prev(); + } + if (start->prev() == s) { + start->break_cycle(temp_register); + } + // walk the chain forward inserting to store list + while (start != NULL) { + stores->append(start); + start->set_processed(); + start = start->next(); + } + } + } + return stores; + } +}; + + // --------------------------------------------------------------------------- // Generate a native wrapper for a given method. The method takes arguments // in the Java compiled code convention, marshals them to the native @@ -1488,12 +1653,12 @@ if (in_regs[i].first()->is_Register()) { const Register reg = in_regs[i].first()->as_Register(); switch (in_sig_bt[i]) { - case T_ARRAY: case T_BOOLEAN: case T_BYTE: case T_SHORT: case T_CHAR: case T_INT: single_slots++; break; + case T_ARRAY: case T_LONG: double_slots++; break; default: ShouldNotReachHere(); } @@ -1690,36 +1855,43 @@ #endif /* ASSERT */ - if (is_critical_native) { - // The mapping of Java and C arguments passed in registers are - // rotated by one, which helps when passing arguments to regular - // Java method but for critical natives that creates a cycle which - // can cause arguments to be killed before they are used. Break - // the cycle by moving the first argument into a temporary - // register. - for (int i = 0; i < total_c_args; i++) { - if (in_regs[i].first()->is_Register() && - in_regs[i].first()->as_Register() == rdi) { - __ mov(rbx, rdi); - in_regs[i].set1(rbx->as_VMReg()); - } - } - } - // This may iterate in two different directions depending on the // kind of native it is. The reason is that for regular JNI natives // the incoming and outgoing registers are offset upwards and for // critical natives they are offset down. - int c_arg = total_c_args - 1; - int stride = -1; - int init = total_in_args - 1; - if (is_critical_native) { - // stride forwards - c_arg = 0; - stride = 1; - init = 0; + GrowableArray<int> arg_order(2 * total_in_args); + VMRegPair tmp_vmreg; + tmp_vmreg.set1(rbx->as_VMReg()); + + if (!is_critical_native) { + for (int i = total_in_args - 1, c_arg = total_c_args - 1; i >= 0; i--, c_arg--) { + arg_order.push(i); + arg_order.push(c_arg); + } + } else { + // Compute a valid move order, using tmp_vmreg to break any cycles + ComputeMoveOrder cmo(total_in_args, in_regs, total_c_args, out_regs, in_sig_bt, arg_order, tmp_vmreg); } - for (int i = init, count = 0; count < total_in_args; i += stride, c_arg += stride, count++ ) { + + int temploc = -1; + for (int ai = 0; ai < arg_order.length(); ai += 2) { + int i = arg_order.at(ai); + int c_arg = arg_order.at(ai + 1); + __ block_comment(err_msg("move %d -> %d", i, c_arg)); + if (c_arg == -1) { + assert(is_critical_native, "should only be required for critical natives"); + // This arg needs to be moved to a temporary + __ mov(tmp_vmreg.first()->as_Register(), in_regs[i].first()->as_Register()); + in_regs[i] = tmp_vmreg; + temploc = i; + continue; + } else if (i == -1) { + assert(is_critical_native, "should only be required for critical natives"); + // Read from the temporary location + assert(temploc != -1, "must be valid"); + i = temploc; + temploc = -1; + } #ifdef ASSERT if (in_regs[i].first()->is_Register()) { assert(!reg_destroyed[in_regs[i].first()->as_Register()->encoding()], "destroyed reg!"); @@ -1779,7 +1951,7 @@ // point c_arg at the first arg that is already loaded in case we // need to spill before we call out - c_arg++; + int c_arg = total_c_args - total_in_args; // Pre-load a static method's oop into r14. Used both by locking code and // the normal JNI call code.
--- a/src/share/vm/classfile/vmSymbols.hpp Mon Mar 19 23:17:13 2012 -0700 +++ b/src/share/vm/classfile/vmSymbols.hpp Tue Mar 20 10:17:41 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -509,6 +509,9 @@ template(clear_name, "clear") \ template(trigger_method_signature, "(ILjava/lang/management/MemoryUsage;)V") \ template(startAgent_name, "startAgent") \ + template(startRemoteAgent_name, "startRemoteManagementAgent") \ + template(startLocalAgent_name, "startLocalManagementAgent") \ + template(stopRemoteAgent_name, "stopRemoteManagementAgent") \ template(java_lang_management_ThreadInfo_constructor_signature, "(Ljava/lang/Thread;ILjava/lang/Object;Ljava/lang/Thread;JJJJ[Ljava/lang/StackTraceElement;)V") \ template(java_lang_management_ThreadInfo_with_locks_constructor_signature, "(Ljava/lang/Thread;ILjava/lang/Object;Ljava/lang/Thread;JJJJ[Ljava/lang/StackTraceElement;[Ljava/lang/Object;[I[Ljava/lang/Object;)V") \ template(long_long_long_long_void_signature, "(JJJJ)V") \
--- a/src/share/vm/opto/connode.cpp Mon Mar 19 23:17:13 2012 -0700 +++ b/src/share/vm/opto/connode.cpp Tue Mar 20 10:17:41 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1051,6 +1051,7 @@ //------------------------------Value------------------------------------------ const Type *CastX2PNode::Value( PhaseTransform *phase ) const { const Type* t = phase->type(in(1)); + if (t == Type::TOP) return Type::TOP; if (t->base() == Type_X && t->singleton()) { uintptr_t bits = (uintptr_t) t->is_intptr_t()->get_con(); if (bits == 0) return TypePtr::NULL_PTR; @@ -1121,6 +1122,7 @@ //------------------------------Value------------------------------------------ const Type *CastP2XNode::Value( PhaseTransform *phase ) const { const Type* t = phase->type(in(1)); + if (t == Type::TOP) return Type::TOP; if (t->base() == Type::RawPtr && t->singleton()) { uintptr_t bits = (uintptr_t) t->is_rawptr()->get_con(); return TypeX::make(bits);
--- a/src/share/vm/opto/escape.cpp Mon Mar 19 23:17:13 2012 -0700 +++ b/src/share/vm/opto/escape.cpp Tue Mar 20 10:17:41 2012 -0700 @@ -2035,40 +2035,14 @@ Node* store = ini->find_captured_store(offset, type2aelembytes(ft), phase); if (store != NULL && store->is_Store()) { value = store->in(MemNode::ValueIn); - } else if (ptn->edge_count() > 0) { // Are there oop stores? - // Check for a store which follows allocation without branches. + } else { + // There could be initializing stores which follow allocation. // For example, a volatile field store is not collected - // by Initialize node. TODO: it would be nice to use idom() here. - // - // Search all references to the same field which use different - // AddP nodes, for example, in the next case: - // - // Point p[] = new Point[1]; - // if ( x ) { p[0] = new Point(); p[0].x = x; } - // if ( p[0] != null ) { y = p[0].x; } // has CastPP + // by Initialize node. // - for (uint next = ei; (next < ae_cnt) && (value == NULL); next++) { - uint fpi = pta->edge_target(next); // Field (AddP) - PointsToNode *ptf = ptnode_adr(fpi); - if (ptf->offset() == offset) { - Node* nf = ptf->_node; - for (DUIterator_Fast imax, i = nf->fast_outs(imax); i < imax; i++) { - store = nf->fast_out(i); - if (store->is_Store() && store->in(0) != NULL) { - Node* ctrl = store->in(0); - while(!(ctrl == ini || ctrl == alloc || ctrl == NULL || - ctrl == C->root() || ctrl == C->top() || ctrl->is_Region() || - ctrl->is_IfTrue() || ctrl->is_IfFalse())) { - ctrl = ctrl->in(0); - } - if (ctrl == ini || ctrl == alloc) { - value = store->in(MemNode::ValueIn); - break; - } - } - } - } - } + // Need to check for dependent loads to separate such stores from + // stores which follow loads. For now, add initial value NULL so + // that compare pointers optimization works correctly. } } if (value == NULL || value != ptnode_adr(value->_idx)->_node) {
--- a/src/share/vm/services/diagnosticCommand.cpp Mon Mar 19 23:17:13 2012 -0700 +++ b/src/share/vm/services/diagnosticCommand.cpp Tue Mar 20 10:17:41 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,6 +49,11 @@ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(true, false)); + //Enhanced JMX Agent Support + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartRemoteDCmd>(true,false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartLocalDCmd>(true,false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStopRemoteDCmd>(true,false)); + } #ifndef HAVE_EXTRA_DCMD @@ -344,3 +349,185 @@ return 0; } } + +// Enhanced JMX Agent support + +JMXStartRemoteDCmd::JMXStartRemoteDCmd(outputStream *output, bool heap_allocated) : + + DCmdWithParser(output, heap_allocated), + + _config_file + ("config.file", + "set com.sun.management.config.file", "STRING", false), + + _jmxremote_port + ("jmxremote.port", + "set com.sun.management.jmxremote.port", "STRING", false), + + _jmxremote_rmi_port + ("jmxremote.rmi.port", + "set com.sun.management.jmxremote.rmi.port", "STRING", false), + + _jmxremote_ssl + ("jmxremote.ssl", + "set com.sun.management.jmxremote.ssl", "STRING", false), + + _jmxremote_registry_ssl + ("jmxremote.registry.ssl", + "set com.sun.management.jmxremote.registry.ssl", "STRING", false), + + _jmxremote_authenticate + ("jmxremote.authenticate", + "set com.sun.management.jmxremote.authenticate", "STRING", false), + + _jmxremote_password_file + ("jmxremote.password.file", + "set com.sun.management.jmxremote.password.file", "STRING", false), + + _jmxremote_access_file + ("jmxremote.access.file", + "set com.sun.management.jmxremote.access.file", "STRING", false), + + _jmxremote_login_config + ("jmxremote.login.config", + "set com.sun.management.jmxremote.login.config", "STRING", false), + + _jmxremote_ssl_enabled_cipher_suites + ("jmxremote.ssl.enabled.cipher.suites", + "set com.sun.management.jmxremote.ssl.enabled.cipher.suite", "STRING", false), + + _jmxremote_ssl_enabled_protocols + ("jmxremote.ssl.enabled.protocols", + "set com.sun.management.jmxremote.ssl.enabled.protocols", "STRING", false), + + _jmxremote_ssl_need_client_auth + ("jmxremote.ssl.need.client.auth", + "set com.sun.management.jmxremote.need.client.auth", "STRING", false), + + _jmxremote_ssl_config_file + ("jmxremote.ssl.config.file", + "set com.sun.management.jmxremote.ssl_config_file", "STRING", false) + + { + _dcmdparser.add_dcmd_option(&_config_file); + _dcmdparser.add_dcmd_option(&_jmxremote_port); + _dcmdparser.add_dcmd_option(&_jmxremote_rmi_port); + _dcmdparser.add_dcmd_option(&_jmxremote_ssl); + _dcmdparser.add_dcmd_option(&_jmxremote_registry_ssl); + _dcmdparser.add_dcmd_option(&_jmxremote_authenticate); + _dcmdparser.add_dcmd_option(&_jmxremote_password_file); + _dcmdparser.add_dcmd_option(&_jmxremote_access_file); + _dcmdparser.add_dcmd_option(&_jmxremote_login_config); + _dcmdparser.add_dcmd_option(&_jmxremote_ssl_enabled_cipher_suites); + _dcmdparser.add_dcmd_option(&_jmxremote_ssl_enabled_protocols); + _dcmdparser.add_dcmd_option(&_jmxremote_ssl_need_client_auth); + _dcmdparser.add_dcmd_option(&_jmxremote_ssl_config_file); +} + + +int JMXStartRemoteDCmd::num_arguments() { + ResourceMark rm; + JMXStartRemoteDCmd* dcmd = new JMXStartRemoteDCmd(NULL, false); + if (dcmd != NULL) { + DCmdMark mark(dcmd); + return dcmd->_dcmdparser.num_arguments(); + } else { + return 0; + } +} + + +void JMXStartRemoteDCmd::execute(TRAPS) { + ResourceMark rm(THREAD); + HandleMark hm(THREAD); + + // Load and initialize the sun.management.Agent class + // invoke startRemoteManagementAgent(string) method to start + // the remote management server. + // throw java.lang.NoSuchMethodError if the method doesn't exist + + Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); + klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::sun_management_Agent(), loader, Handle(), true, CHECK); + instanceKlassHandle ik (THREAD, k); + + JavaValue result(T_VOID); + + // Pass all command line arguments to java as key=value,... + // All checks are done on java side + + int len = 0; + stringStream options; + char comma[2] = {0,0}; + + // Leave default values on Agent.class side and pass only + // agruments explicitly set by user. All arguments passed + // to jcmd override properties with the same name set by + // command line with -D or by managmenent.properties + // file. +#define PUT_OPTION(a) \ + if ( (a).is_set() ){ \ + options.print("%scom.sun.management.%s=%s", comma, (a).name(), (a).value()); \ + comma[0] = ','; \ + } + + PUT_OPTION(_config_file); + PUT_OPTION(_jmxremote_port); + PUT_OPTION(_jmxremote_rmi_port); + PUT_OPTION(_jmxremote_ssl); + PUT_OPTION(_jmxremote_registry_ssl); + PUT_OPTION(_jmxremote_authenticate); + PUT_OPTION(_jmxremote_password_file); + PUT_OPTION(_jmxremote_access_file); + PUT_OPTION(_jmxremote_login_config); + PUT_OPTION(_jmxremote_ssl_enabled_cipher_suites); + PUT_OPTION(_jmxremote_ssl_enabled_protocols); + PUT_OPTION(_jmxremote_ssl_need_client_auth); + PUT_OPTION(_jmxremote_ssl_config_file); + +#undef PUT_OPTION + + Handle str = java_lang_String::create_from_str(options.as_string(), CHECK); + JavaCalls::call_static(&result, ik, vmSymbols::startRemoteAgent_name(), vmSymbols::string_void_signature(), str, CHECK); +} + +JMXStartLocalDCmd::JMXStartLocalDCmd(outputStream *output, bool heap_allocated) : + DCmd(output, heap_allocated) +{ + // do nothing +} + +void JMXStartLocalDCmd::execute(TRAPS) { + ResourceMark rm(THREAD); + HandleMark hm(THREAD); + + // Load and initialize the sun.management.Agent class + // invoke startLocalManagementAgent(void) method to start + // the local management server + // throw java.lang.NoSuchMethodError if method doesn't exist + + Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); + klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::sun_management_Agent(), loader, Handle(), true, CHECK); + instanceKlassHandle ik (THREAD, k); + + JavaValue result(T_VOID); + JavaCalls::call_static(&result, ik, vmSymbols::startLocalAgent_name(), vmSymbols::void_method_signature(), CHECK); +} + + +void JMXStopRemoteDCmd::execute(TRAPS) { + ResourceMark rm(THREAD); + HandleMark hm(THREAD); + + // Load and initialize the sun.management.Agent class + // invoke stopRemoteManagementAgent method to stop the + // management server + // throw java.lang.NoSuchMethodError if method doesn't exist + + Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); + klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::sun_management_Agent(), loader, Handle(), true, CHECK); + instanceKlassHandle ik (THREAD, k); + + JavaValue result(T_VOID); + JavaCalls::call_static(&result, ik, vmSymbols::stopRemoteAgent_name(), vmSymbols::void_method_signature(), CHECK); +} +
--- a/src/share/vm/services/diagnosticCommand.hpp Mon Mar 19 23:17:13 2012 -0700 +++ b/src/share/vm/services/diagnosticCommand.hpp Tue Mar 20 10:17:41 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -214,4 +214,82 @@ virtual void execute(TRAPS); }; +// Enhanced JMX Agent support + +class JMXStartRemoteDCmd : public DCmdWithParser { + + // Explicitly list all properties that could be + // passed to Agent.startRemoteManagementAgent() + // com.sun.management is omitted + + DCmdArgument<char *> _config_file; + DCmdArgument<char *> _jmxremote_port; + DCmdArgument<char *> _jmxremote_rmi_port; + DCmdArgument<char *> _jmxremote_ssl; + DCmdArgument<char *> _jmxremote_registry_ssl; + DCmdArgument<char *> _jmxremote_authenticate; + DCmdArgument<char *> _jmxremote_password_file; + DCmdArgument<char *> _jmxremote_access_file; + DCmdArgument<char *> _jmxremote_login_config; + DCmdArgument<char *> _jmxremote_ssl_enabled_cipher_suites; + DCmdArgument<char *> _jmxremote_ssl_enabled_protocols; + DCmdArgument<char *> _jmxremote_ssl_need_client_auth; + DCmdArgument<char *> _jmxremote_ssl_config_file; + +public: + JMXStartRemoteDCmd(outputStream *output, bool heap_allocated); + + static const char *name() { + return "ManagementAgent.start"; + } + + static const char *description() { + return "Start remote management agent."; + } + + static int num_arguments(); + + virtual void execute(TRAPS); + +}; + +class JMXStartLocalDCmd : public DCmd { + + // Explicitly request start of local agent, + // it will not be started by start dcmd + + +public: + JMXStartLocalDCmd(outputStream *output, bool heap_allocated); + + static const char *name() { + return "ManagementAgent.start_local"; + } + + static const char *description() { + return "Start local management agent."; + } + + virtual void execute(TRAPS); + +}; + +class JMXStopRemoteDCmd : public DCmd { +public: + JMXStopRemoteDCmd(outputStream *output, bool heap_allocated) : + DCmd(output, heap_allocated) { + // Do Nothing + } + + static const char *name() { + return "ManagementAgent.stop"; + } + + static const char *description() { + return "Stop remote management agent."; + } + + virtual void execute(TRAPS); +}; + #endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP