Merge

Mon, 09 Apr 2012 08:38:16 -0700

author
dcubed
date
Mon, 09 Apr 2012 08:38:16 -0700
changeset 3699
a4b63a58d295
parent 3697
4a32c51458b9
parent 3698
19e197e2a1af
child 3700
10c12fb36ed2

Merge

     1.1 --- a/src/cpu/x86/vm/templateTable_x86_32.cpp	Sat Apr 07 09:06:55 2012 -0700
     1.2 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp	Mon Apr 09 08:38:16 2012 -0700
     1.3 @@ -2651,56 +2651,49 @@
     1.4      // Check to see if a field modification watch has been set before we take
     1.5      // the time to call into the VM.
     1.6      Label L2;
     1.7 -    __ mov32(rcx, ExternalAddress((address)JvmtiExport::get_field_modification_count_addr()));
     1.8 -    __ testl(rcx,rcx);
     1.9 -    __ jcc(Assembler::zero, L2);
    1.10 -    __ pop_ptr(rbx);               // copy the object pointer from tos
    1.11 -    __ verify_oop(rbx);
    1.12 -    __ push_ptr(rbx);              // put the object pointer back on tos
    1.13 -    __ subptr(rsp, sizeof(jvalue));  // add space for a jvalue object
    1.14 -    __ mov(rcx, rsp);
    1.15 -    __ push_ptr(rbx);                 // save object pointer so we can steal rbx,
    1.16 -    __ xorptr(rbx, rbx);
    1.17 -    const Address lo_value(rcx, rbx, Address::times_1, 0*wordSize);
    1.18 -    const Address hi_value(rcx, rbx, Address::times_1, 1*wordSize);
    1.19 -    switch (bytecode()) {          // load values into the jvalue object
    1.20 -    case Bytecodes::_fast_bputfield: __ movb(lo_value, rax); break;
    1.21 -    case Bytecodes::_fast_sputfield: __ movw(lo_value, rax); break;
    1.22 -    case Bytecodes::_fast_cputfield: __ movw(lo_value, rax); break;
    1.23 -    case Bytecodes::_fast_iputfield: __ movl(lo_value, rax);                         break;
    1.24 -    case Bytecodes::_fast_lputfield:
    1.25 -      NOT_LP64(__ movptr(hi_value, rdx));
    1.26 -      __ movptr(lo_value, rax);
    1.27 -      break;
    1.28 -
    1.29 -    // need to call fld_s() after fstp_s() to restore the value for below
    1.30 -    case Bytecodes::_fast_fputfield: __ fstp_s(lo_value); __ fld_s(lo_value);        break;
    1.31 -
    1.32 -    // need to call fld_d() after fstp_d() to restore the value for below
    1.33 -    case Bytecodes::_fast_dputfield: __ fstp_d(lo_value); __ fld_d(lo_value);        break;
    1.34 -
    1.35 -    // since rcx is not an object we don't call store_check() here
    1.36 -    case Bytecodes::_fast_aputfield: __ movptr(lo_value, rax);                       break;
    1.37 -
    1.38 -    default:  ShouldNotReachHere();
    1.39 -    }
    1.40 -    __ pop_ptr(rbx);  // restore copy of object pointer
    1.41 -
    1.42 -    // Save rax, and sometimes rdx because call_VM() will clobber them,
    1.43 -    // then use them for JVM/DI purposes
    1.44 -    __ push(rax);
    1.45 -    if (bytecode() == Bytecodes::_fast_lputfield) __ push(rdx);
    1.46 -    // access constant pool cache entry
    1.47 -    __ get_cache_entry_pointer_at_bcp(rax, rdx, 1);
    1.48 -    __ verify_oop(rbx);
    1.49 -    // rbx,: object pointer copied above
    1.50 -    // rax,: cache entry pointer
    1.51 -    // rcx: jvalue object on the stack
    1.52 -    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_modification), rbx, rax, rcx);
    1.53 -    if (bytecode() == Bytecodes::_fast_lputfield) __ pop(rdx);  // restore high value
    1.54 -    __ pop(rax);     // restore lower value
    1.55 -    __ addptr(rsp, sizeof(jvalue));  // release jvalue object space
    1.56 -    __ bind(L2);
    1.57 +     __ mov32(rcx, ExternalAddress((address)JvmtiExport::get_field_modification_count_addr()));
    1.58 +     __ testl(rcx,rcx);
    1.59 +     __ jcc(Assembler::zero, L2);
    1.60 +     __ pop_ptr(rbx);               // copy the object pointer from tos
    1.61 +     __ verify_oop(rbx);
    1.62 +     __ push_ptr(rbx);              // put the object pointer back on tos
    1.63 +
    1.64 +     // Save tos values before call_VM() clobbers them. Since we have
    1.65 +     // to do it for every data type, we use the saved values as the
    1.66 +     // jvalue object.
    1.67 +     switch (bytecode()) {          // load values into the jvalue object
    1.68 +     case Bytecodes::_fast_aputfield: __ push_ptr(rax); break;
    1.69 +     case Bytecodes::_fast_bputfield: // fall through
    1.70 +     case Bytecodes::_fast_sputfield: // fall through
    1.71 +     case Bytecodes::_fast_cputfield: // fall through
    1.72 +     case Bytecodes::_fast_iputfield: __ push_i(rax); break;
    1.73 +     case Bytecodes::_fast_dputfield: __ push_d(); break;
    1.74 +     case Bytecodes::_fast_fputfield: __ push_f(); break;
    1.75 +     case Bytecodes::_fast_lputfield: __ push_l(rax); break;
    1.76 +
    1.77 +     default:
    1.78 +       ShouldNotReachHere();
    1.79 +     }
    1.80 +     __ mov(rcx, rsp);              // points to jvalue on the stack
    1.81 +     // access constant pool cache entry
    1.82 +     __ get_cache_entry_pointer_at_bcp(rax, rdx, 1);
    1.83 +     __ verify_oop(rbx);
    1.84 +     // rbx,: object pointer copied above
    1.85 +     // rax,: cache entry pointer
    1.86 +     // rcx: jvalue object on the stack
    1.87 +     __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_modification), rbx, rax, rcx);
    1.88 +
    1.89 +     switch (bytecode()) {             // restore tos values
    1.90 +     case Bytecodes::_fast_aputfield: __ pop_ptr(rax); break;
    1.91 +     case Bytecodes::_fast_bputfield: // fall through
    1.92 +     case Bytecodes::_fast_sputfield: // fall through
    1.93 +     case Bytecodes::_fast_cputfield: // fall through
    1.94 +     case Bytecodes::_fast_iputfield: __ pop_i(rax); break;
    1.95 +     case Bytecodes::_fast_dputfield: __ pop_d(); break;
    1.96 +     case Bytecodes::_fast_fputfield: __ pop_f(); break;
    1.97 +     case Bytecodes::_fast_lputfield: __ pop_l(rax); break;
    1.98 +     }
    1.99 +     __ bind(L2);
   1.100    }
   1.101  }
   1.102  
     2.1 --- a/src/cpu/x86/vm/templateTable_x86_64.cpp	Sat Apr 07 09:06:55 2012 -0700
     2.2 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp	Mon Apr 09 08:38:16 2012 -0700
     2.3 @@ -2685,26 +2685,23 @@
     2.4      __ pop_ptr(rbx);                  // copy the object pointer from tos
     2.5      __ verify_oop(rbx);
     2.6      __ push_ptr(rbx);                 // put the object pointer back on tos
     2.7 -    __ subptr(rsp, sizeof(jvalue));  // add space for a jvalue object
     2.8 -    __ mov(c_rarg3, rsp);
     2.9 -    const Address field(c_rarg3, 0);
    2.10 -
    2.11 +    // Save tos values before call_VM() clobbers them. Since we have
    2.12 +    // to do it for every data type, we use the saved values as the
    2.13 +    // jvalue object.
    2.14      switch (bytecode()) {          // load values into the jvalue object
    2.15 -    case Bytecodes::_fast_aputfield: __ movq(field, rax); break;
    2.16 -    case Bytecodes::_fast_lputfield: __ movq(field, rax); break;
    2.17 -    case Bytecodes::_fast_iputfield: __ movl(field, rax); break;
    2.18 -    case Bytecodes::_fast_bputfield: __ movb(field, rax); break;
    2.19 +    case Bytecodes::_fast_aputfield: __ push_ptr(rax); break;
    2.20 +    case Bytecodes::_fast_bputfield: // fall through
    2.21      case Bytecodes::_fast_sputfield: // fall through
    2.22 -    case Bytecodes::_fast_cputfield: __ movw(field, rax); break;
    2.23 -    case Bytecodes::_fast_fputfield: __ movflt(field, xmm0); break;
    2.24 -    case Bytecodes::_fast_dputfield: __ movdbl(field, xmm0); break;
    2.25 +    case Bytecodes::_fast_cputfield: // fall through
    2.26 +    case Bytecodes::_fast_iputfield: __ push_i(rax); break;
    2.27 +    case Bytecodes::_fast_dputfield: __ push_d(); break;
    2.28 +    case Bytecodes::_fast_fputfield: __ push_f(); break;
    2.29 +    case Bytecodes::_fast_lputfield: __ push_l(rax); break;
    2.30 +
    2.31      default:
    2.32        ShouldNotReachHere();
    2.33      }
    2.34 -
    2.35 -    // Save rax because call_VM() will clobber it, then use it for
    2.36 -    // JVMTI purposes
    2.37 -    __ push(rax);
    2.38 +    __ mov(c_rarg3, rsp);             // points to jvalue on the stack
    2.39      // access constant pool cache entry
    2.40      __ get_cache_entry_pointer_at_bcp(c_rarg2, rax, 1);
    2.41      __ verify_oop(rbx);
    2.42 @@ -2715,8 +2712,17 @@
    2.43                 CAST_FROM_FN_PTR(address,
    2.44                                  InterpreterRuntime::post_field_modification),
    2.45                 rbx, c_rarg2, c_rarg3);
    2.46 -    __ pop(rax);     // restore lower value
    2.47 -    __ addptr(rsp, sizeof(jvalue));  // release jvalue object space
    2.48 +
    2.49 +    switch (bytecode()) {             // restore tos values
    2.50 +    case Bytecodes::_fast_aputfield: __ pop_ptr(rax); break;
    2.51 +    case Bytecodes::_fast_bputfield: // fall through
    2.52 +    case Bytecodes::_fast_sputfield: // fall through
    2.53 +    case Bytecodes::_fast_cputfield: // fall through
    2.54 +    case Bytecodes::_fast_iputfield: __ pop_i(rax); break;
    2.55 +    case Bytecodes::_fast_dputfield: __ pop_d(); break;
    2.56 +    case Bytecodes::_fast_fputfield: __ pop_f(); break;
    2.57 +    case Bytecodes::_fast_lputfield: __ pop_l(rax); break;
    2.58 +    }
    2.59      __ bind(L2);
    2.60    }
    2.61  }
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/test/runtime/7158988/FieldMonitor.java	Mon Apr 09 08:38:16 2012 -0700
     3.3 @@ -0,0 +1,249 @@
     3.4 +/*
     3.5 + * Copyright 2012 SAP AG.  All Rights Reserved.
     3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.7 + *
     3.8 + * This code is free software; you can redistribute it and/or modify it
     3.9 + * under the terms of the GNU General Public License version 2 only, as
    3.10 + * published by the Free Software Foundation.
    3.11 + *
    3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    3.15 + * version 2 for more details (a copy is included in the LICENSE file that
    3.16 + * accompanied this code).
    3.17 + *
    3.18 + * You should have received a copy of the GNU General Public License version
    3.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    3.21 + *
    3.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    3.23 + * or visit www.oracle.com if you need additional information or have any
    3.24 + * questions.
    3.25 + */
    3.26 +
    3.27 +/*
    3.28 + * @test FieldMonitor.java
    3.29 + * @bug 7158988
    3.30 + * @summary verify jvm does not crash while debugging
    3.31 + * @run shell TestFieldMonitor.sh
    3.32 + * @author axel.siebenborn@sap.com
    3.33 + */
    3.34 +import java.io.BufferedReader;
    3.35 +import java.io.IOException;
    3.36 +import java.io.InputStream;
    3.37 +import java.io.InputStreamReader;
    3.38 +import java.io.OutputStream;
    3.39 +import java.io.OutputStreamWriter;
    3.40 +import java.io.Reader;
    3.41 +import java.io.Writer;
    3.42 +import java.util.Iterator;
    3.43 +import java.util.List;
    3.44 +import java.util.Map;
    3.45 +
    3.46 +import com.sun.jdi.Bootstrap;
    3.47 +import com.sun.jdi.Field;
    3.48 +import com.sun.jdi.ReferenceType;
    3.49 +import com.sun.jdi.VirtualMachine;
    3.50 +import com.sun.jdi.connect.Connector;
    3.51 +import com.sun.jdi.connect.IllegalConnectorArgumentsException;
    3.52 +import com.sun.jdi.connect.LaunchingConnector;
    3.53 +import com.sun.jdi.connect.VMStartException;
    3.54 +import com.sun.jdi.event.ClassPrepareEvent;
    3.55 +import com.sun.jdi.event.Event;
    3.56 +import com.sun.jdi.event.EventQueue;
    3.57 +import com.sun.jdi.event.EventSet;
    3.58 +import com.sun.jdi.event.ModificationWatchpointEvent;
    3.59 +import com.sun.jdi.event.VMDeathEvent;
    3.60 +import com.sun.jdi.event.VMDisconnectEvent;
    3.61 +import com.sun.jdi.request.ClassPrepareRequest;
    3.62 +import com.sun.jdi.request.EventRequest;
    3.63 +import com.sun.jdi.request.EventRequestManager;
    3.64 +import com.sun.jdi.request.ModificationWatchpointRequest;
    3.65 +
    3.66 +public class FieldMonitor {
    3.67 +
    3.68 +  public static final String CLASS_NAME = "TestPostFieldModification";
    3.69 +  public static final String FIELD_NAME = "value";
    3.70 +  public static final String ARGUMENTS = "-Xshare:off -XX:+PrintGC";
    3.71 +
    3.72 +  public static void main(String[] args)
    3.73 +      throws IOException, InterruptedException {
    3.74 +
    3.75 +    StringBuffer sb = new StringBuffer();
    3.76 +
    3.77 +    for (int i=0; i < args.length; i++) {
    3.78 +        sb.append(' ');
    3.79 +        sb.append(args[i]);
    3.80 +    }
    3.81 +    //VirtualMachine vm = launchTarget(sb.toString());
    3.82 +    VirtualMachine vm = launchTarget(CLASS_NAME);
    3.83 +
    3.84 +    System.out.println("Vm launched");
    3.85 +    // set watch field on already loaded classes
    3.86 +    List<ReferenceType> referenceTypes = vm
    3.87 +        .classesByName(CLASS_NAME);
    3.88 +    for (ReferenceType refType : referenceTypes) {
    3.89 +      addFieldWatch(vm, refType);
    3.90 +    }
    3.91 +    // watch for loaded classes
    3.92 +    addClassWatch(vm);
    3.93 +
    3.94 +    // process events
    3.95 +    EventQueue eventQueue = vm.eventQueue();
    3.96 +    // resume the vm
    3.97 +
    3.98 +    Process process = vm.process();
    3.99 +
   3.100 +
   3.101 +    // Copy target's output and error to our output and error.
   3.102 +    Thread outThread = new StreamRedirectThread("out reader", process.getInputStream());
   3.103 +    Thread errThread = new StreamRedirectThread("error reader", process.getErrorStream());
   3.104 +
   3.105 +    errThread.start();
   3.106 +    outThread.start();
   3.107 +
   3.108 +
   3.109 +    vm.resume();
   3.110 +    boolean connected = true;
   3.111 +    while (connected) {
   3.112 +      EventSet eventSet = eventQueue.remove();
   3.113 +      for (Event event : eventSet) {
   3.114 +        if (event instanceof VMDeathEvent
   3.115 +            || event instanceof VMDisconnectEvent) {
   3.116 +          // exit
   3.117 +          connected = false;
   3.118 +        } else if (event instanceof ClassPrepareEvent) {
   3.119 +          // watch field on loaded class
   3.120 +          System.out.println("ClassPrepareEvent");
   3.121 +          ClassPrepareEvent classPrepEvent = (ClassPrepareEvent) event;
   3.122 +          ReferenceType refType = classPrepEvent
   3.123 +              .referenceType();
   3.124 +          addFieldWatch(vm, refType);
   3.125 +        } else if (event instanceof ModificationWatchpointEvent) {
   3.126 +          System.out.println("sleep for 500 ms");
   3.127 +          Thread.sleep(500);
   3.128 +          System.out.println("resume...");
   3.129 +
   3.130 +          ModificationWatchpointEvent modEvent = (ModificationWatchpointEvent) event;
   3.131 +          System.out.println("old="
   3.132 +              + modEvent.valueCurrent());
   3.133 +          System.out.println("new=" + modEvent.valueToBe());
   3.134 +          System.out.println();
   3.135 +        }
   3.136 +      }
   3.137 +      eventSet.resume();
   3.138 +    }
   3.139 +    // Shutdown begins when event thread terminates
   3.140 +    try {
   3.141 +        errThread.join(); // Make sure output is forwarded
   3.142 +        outThread.join();
   3.143 +    } catch (InterruptedException exc) {
   3.144 +        // we don't interrupt
   3.145 +    }
   3.146 +  }
   3.147 +
   3.148 +  /**
   3.149 +   * Find a com.sun.jdi.CommandLineLaunch connector
   3.150 +   */
   3.151 +  static LaunchingConnector findLaunchingConnector() {
   3.152 +    List <Connector> connectors = Bootstrap.virtualMachineManager().allConnectors();
   3.153 +    Iterator <Connector> iter = connectors.iterator();
   3.154 +    while (iter.hasNext()) {
   3.155 +      Connector connector = iter.next();
   3.156 +      if (connector.name().equals("com.sun.jdi.CommandLineLaunch")) {
   3.157 +        return (LaunchingConnector)connector;
   3.158 +      }
   3.159 +    }
   3.160 +    throw new Error("No launching connector");
   3.161 +  }
   3.162 +  /**
   3.163 +   * Return the launching connector's arguments.
   3.164 +   */
   3.165 + static Map <String,Connector.Argument> connectorArguments(LaunchingConnector connector, String mainArgs) {
   3.166 +      Map<String,Connector.Argument> arguments = connector.defaultArguments();
   3.167 +      for (String key : arguments.keySet()) {
   3.168 +        System.out.println(key);
   3.169 +      }
   3.170 +
   3.171 +      Connector.Argument mainArg = (Connector.Argument)arguments.get("main");
   3.172 +      if (mainArg == null) {
   3.173 +          throw new Error("Bad launching connector");
   3.174 +      }
   3.175 +      mainArg.setValue(mainArgs);
   3.176 +
   3.177 +      Connector.Argument optionsArg = (Connector.Argument)arguments.get("options");
   3.178 +      if (optionsArg == null) {
   3.179 +        throw new Error("Bad launching connector");
   3.180 +      }
   3.181 +      optionsArg.setValue(ARGUMENTS);
   3.182 +      return arguments;
   3.183 +  }
   3.184 +
   3.185 + static VirtualMachine launchTarget(String mainArgs) {
   3.186 +    LaunchingConnector connector = findLaunchingConnector();
   3.187 +    Map  arguments = connectorArguments(connector, mainArgs);
   3.188 +    try {
   3.189 +        return (VirtualMachine) connector.launch(arguments);
   3.190 +    } catch (IOException exc) {
   3.191 +        throw new Error("Unable to launch target VM: " + exc);
   3.192 +    } catch (IllegalConnectorArgumentsException exc) {
   3.193 +        throw new Error("Internal error: " + exc);
   3.194 +    } catch (VMStartException exc) {
   3.195 +        throw new Error("Target VM failed to initialize: " +
   3.196 +                        exc.getMessage());
   3.197 +    }
   3.198 +}
   3.199 +
   3.200 +
   3.201 +  private static void addClassWatch(VirtualMachine vm) {
   3.202 +    EventRequestManager erm = vm.eventRequestManager();
   3.203 +    ClassPrepareRequest classPrepareRequest = erm
   3.204 +        .createClassPrepareRequest();
   3.205 +    classPrepareRequest.addClassFilter(CLASS_NAME);
   3.206 +    classPrepareRequest.setEnabled(true);
   3.207 +  }
   3.208 +
   3.209 +
   3.210 +  private static void addFieldWatch(VirtualMachine vm,
   3.211 +      ReferenceType refType) {
   3.212 +    EventRequestManager erm = vm.eventRequestManager();
   3.213 +    Field field = refType.fieldByName(FIELD_NAME);
   3.214 +    ModificationWatchpointRequest modificationWatchpointRequest = erm
   3.215 +        .createModificationWatchpointRequest(field);
   3.216 +    modificationWatchpointRequest.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
   3.217 +    modificationWatchpointRequest.setEnabled(true);
   3.218 +  }
   3.219 +}
   3.220 +
   3.221 +class StreamRedirectThread extends Thread {
   3.222 +
   3.223 +  private final BufferedReader in;
   3.224 +
   3.225 +  private static final int BUFFER_SIZE = 2048;
   3.226 +
   3.227 +  /**
   3.228 +   * Set up for copy.
   3.229 +   * @param name  Name of the thread
   3.230 +   * @param in    Stream to copy from
   3.231 +   * @param out   Stream to copy to
   3.232 +   */
   3.233 +  StreamRedirectThread(String name, InputStream in) {
   3.234 +    super(name);
   3.235 +    this.in = new BufferedReader(new InputStreamReader(in));
   3.236 +  }
   3.237 +
   3.238 +  /**
   3.239 +   * Copy.
   3.240 +   */
   3.241 +  public void run() {
   3.242 +    try {
   3.243 +      String line;
   3.244 +        while ((line = in.readLine ()) != null) {
   3.245 +          System.out.println ("testvm: " + line);
   3.246 +      }
   3.247 +     System.out.flush();
   3.248 +    } catch(IOException exc) {
   3.249 +      System.err.println("Child I/O Transfer - " + exc);
   3.250 +    }
   3.251 +  }
   3.252 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/test/runtime/7158988/TestFieldMonitor.sh	Mon Apr 09 08:38:16 2012 -0700
     4.3 @@ -0,0 +1,94 @@
     4.4 +#!/bin/sh
     4.5 +
     4.6 +if [ "${TESTSRC}" = "" ]
     4.7 +then TESTSRC=.
     4.8 +fi
     4.9 +
    4.10 +if [ "${TESTJAVA}" = "" ]
    4.11 +then
    4.12 +  PARENT=`dirname \`which java\``
    4.13 +  TESTJAVA=`dirname ${PARENT}`
    4.14 +  echo "TESTJAVA not set, selecting " ${TESTJAVA}
    4.15 +  echo "If this is incorrect, try setting the variable manually."
    4.16 +fi
    4.17 +
    4.18 +if [ "${TESTCLASSES}" = "" ]
    4.19 +then
    4.20 +  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
    4.21 +  exit 1
    4.22 +fi
    4.23 +
    4.24 +BIT_FLAG=""
    4.25 +
    4.26 +# set platform-dependent variables
    4.27 +OS=`uname -s`
    4.28 +case "$OS" in
    4.29 +  SunOS | Linux )
    4.30 +    NULL=/dev/null
    4.31 +    PS=":"
    4.32 +    FS="/"
    4.33 +    ## for solaris, linux it's HOME
    4.34 +    FILE_LOCATION=$HOME
    4.35 +    if [ -f ${FILE_LOCATION}${FS}JDK64BIT -a ${OS} = "SunOS" -a `uname -p`='sparc' ]
    4.36 +    then
    4.37 +        BIT_FLAG="-d64"
    4.38 +    fi
    4.39 +    ;;
    4.40 +  Windows_95 | Windows_98 | Windows_ME )
    4.41 +    NULL=NUL
    4.42 +    PS=";"
    4.43 +    FS="\\"
    4.44 +    echo "Test skipped, only for WinNT"
    4.45 +    exit 0
    4.46 +    ;;
    4.47 +  Windows_NT )
    4.48 +    NULL=NUL
    4.49 +    PS=";"
    4.50 +    FS="\\"
    4.51 +    ;;
    4.52 +  * )
    4.53 +    echo "Unrecognized system!"
    4.54 +    exit 1;
    4.55 +    ;;
    4.56 +esac
    4.57 +
    4.58 +#CLASSPATH=.${PS}${TESTCLASSES} ; export CLASSPATH
    4.59 +
    4.60 +cp ${TESTSRC}${FS}*.java .
    4.61 +
    4.62 +${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -fullversion
    4.63 +
    4.64 +${TESTJAVA}${FS}bin${FS}javac -classpath .${PS}$TESTJAVA${FS}lib${FS}tools.jar *.java
    4.65 +
    4.66 +${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -classpath .${PS}$TESTJAVA${FS}lib${FS}tools.jar FieldMonitor > test.out 2>&1 &
    4.67 +
    4.68 +P_PID=$!
    4.69 +
    4.70 +sleep 60
    4.71 +STATUS=0
    4.72 +
    4.73 +case "$OS" in
    4.74 +    SunOS | Linux )
    4.75 +        ps -ef | grep $P_PID | grep -v grep > ${NULL}
    4.76 +        if [ $? = 0 ]; then
    4.77 +            kill -9 $P_PID
    4.78 +            STATUS=1
    4.79 +        fi
    4.80 +        ;;
    4.81 +      * )
    4.82 +        ps | grep -i "FieldMonitor" | grep -v grep > ${NULL}
    4.83 +        if [ $? = 0 ]; then
    4.84 +            C_PID=`ps | grep -i "FieldMonitor" | awk '{print $1}'`
    4.85 +            kill -s 9 $C_PID
    4.86 +            STATUS=1
    4.87 +        fi
    4.88 +        ;;
    4.89 +esac
    4.90 +
    4.91 +grep "A fatal error has been detected" test.out > ${NULL}
    4.92 +if [ $? = 0 ]; then
    4.93 +    cat test.out
    4.94 +    STATUS=1
    4.95 +fi
    4.96 +
    4.97 +exit $STATUS
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/test/runtime/7158988/TestPostFieldModification.java	Mon Apr 09 08:38:16 2012 -0700
     5.3 @@ -0,0 +1,249 @@
     5.4 +/*
     5.5 + * Copyright 2012 SAP AG.  All Rights Reserved.
     5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.7 + *
     5.8 + * This code is free software; you can redistribute it and/or modify it
     5.9 + * under the terms of the GNU General Public License version 2 only, as
    5.10 + * published by the Free Software Foundation.
    5.11 + *
    5.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    5.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    5.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    5.15 + * version 2 for more details (a copy is included in the LICENSE file that
    5.16 + * accompanied this code).
    5.17 + *
    5.18 + * You should have received a copy of the GNU General Public License version
    5.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    5.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    5.21 + *
    5.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    5.23 + * or visit www.oracle.com if you need additional information or have any
    5.24 + * questions.
    5.25 + */
    5.26 +
    5.27 +/*
    5.28 + * @test FieldMonitor.java
    5.29 + * @bug 7158988
    5.30 + * @summary verify jvm does not crash while debugging
    5.31 + * @run shell TestFieldMonitor.sh
    5.32 + * @author axel.siebenborn@sap.com
    5.33 + */
    5.34 +import java.io.BufferedReader;
    5.35 +import java.io.IOException;
    5.36 +import java.io.InputStream;
    5.37 +import java.io.InputStreamReader;
    5.38 +import java.io.OutputStream;
    5.39 +import java.io.OutputStreamWriter;
    5.40 +import java.io.Reader;
    5.41 +import java.io.Writer;
    5.42 +import java.util.Iterator;
    5.43 +import java.util.List;
    5.44 +import java.util.Map;
    5.45 +
    5.46 +import com.sun.jdi.Bootstrap;
    5.47 +import com.sun.jdi.Field;
    5.48 +import com.sun.jdi.ReferenceType;
    5.49 +import com.sun.jdi.VirtualMachine;
    5.50 +import com.sun.jdi.connect.Connector;
    5.51 +import com.sun.jdi.connect.IllegalConnectorArgumentsException;
    5.52 +import com.sun.jdi.connect.LaunchingConnector;
    5.53 +import com.sun.jdi.connect.VMStartException;
    5.54 +import com.sun.jdi.event.ClassPrepareEvent;
    5.55 +import com.sun.jdi.event.Event;
    5.56 +import com.sun.jdi.event.EventQueue;
    5.57 +import com.sun.jdi.event.EventSet;
    5.58 +import com.sun.jdi.event.ModificationWatchpointEvent;
    5.59 +import com.sun.jdi.event.VMDeathEvent;
    5.60 +import com.sun.jdi.event.VMDisconnectEvent;
    5.61 +import com.sun.jdi.request.ClassPrepareRequest;
    5.62 +import com.sun.jdi.request.EventRequest;
    5.63 +import com.sun.jdi.request.EventRequestManager;
    5.64 +import com.sun.jdi.request.ModificationWatchpointRequest;
    5.65 +
    5.66 +public class FieldMonitor {
    5.67 +
    5.68 +  public static final String CLASS_NAME = "TestPostFieldModification";
    5.69 +  public static final String FIELD_NAME = "value";
    5.70 +  public static final String ARGUMENTS = "-Xshare:off -XX:+PrintGC";
    5.71 +
    5.72 +  public static void main(String[] args)
    5.73 +      throws IOException, InterruptedException {
    5.74 +
    5.75 +    StringBuffer sb = new StringBuffer();
    5.76 +
    5.77 +    for (int i=0; i < args.length; i++) {
    5.78 +        sb.append(' ');
    5.79 +        sb.append(args[i]);
    5.80 +    }
    5.81 +    //VirtualMachine vm = launchTarget(sb.toString());
    5.82 +    VirtualMachine vm = launchTarget(CLASS_NAME);
    5.83 +
    5.84 +    System.out.println("Vm launched");
    5.85 +    // set watch field on already loaded classes
    5.86 +    List<ReferenceType> referenceTypes = vm
    5.87 +        .classesByName(CLASS_NAME);
    5.88 +    for (ReferenceType refType : referenceTypes) {
    5.89 +      addFieldWatch(vm, refType);
    5.90 +    }
    5.91 +    // watch for loaded classes
    5.92 +    addClassWatch(vm);
    5.93 +
    5.94 +    // process events
    5.95 +    EventQueue eventQueue = vm.eventQueue();
    5.96 +    // resume the vm
    5.97 +
    5.98 +    Process process = vm.process();
    5.99 +
   5.100 +
   5.101 +    // Copy target's output and error to our output and error.
   5.102 +    Thread outThread = new StreamRedirectThread("out reader", process.getInputStream());
   5.103 +    Thread errThread = new StreamRedirectThread("error reader", process.getErrorStream());
   5.104 +
   5.105 +    errThread.start();
   5.106 +    outThread.start();
   5.107 +
   5.108 +
   5.109 +    vm.resume();
   5.110 +    boolean connected = true;
   5.111 +    while (connected) {
   5.112 +      EventSet eventSet = eventQueue.remove();
   5.113 +      for (Event event : eventSet) {
   5.114 +        if (event instanceof VMDeathEvent
   5.115 +            || event instanceof VMDisconnectEvent) {
   5.116 +          // exit
   5.117 +          connected = false;
   5.118 +        } else if (event instanceof ClassPrepareEvent) {
   5.119 +          // watch field on loaded class
   5.120 +          System.out.println("ClassPrepareEvent");
   5.121 +          ClassPrepareEvent classPrepEvent = (ClassPrepareEvent) event;
   5.122 +          ReferenceType refType = classPrepEvent
   5.123 +              .referenceType();
   5.124 +          addFieldWatch(vm, refType);
   5.125 +        } else if (event instanceof ModificationWatchpointEvent) {
   5.126 +          System.out.println("sleep for 500 ms");
   5.127 +          Thread.sleep(500);
   5.128 +          System.out.println("resume...");
   5.129 +
   5.130 +          ModificationWatchpointEvent modEvent = (ModificationWatchpointEvent) event;
   5.131 +          System.out.println("old="
   5.132 +              + modEvent.valueCurrent());
   5.133 +          System.out.println("new=" + modEvent.valueToBe());
   5.134 +          System.out.println();
   5.135 +        }
   5.136 +      }
   5.137 +      eventSet.resume();
   5.138 +    }
   5.139 +    // Shutdown begins when event thread terminates
   5.140 +    try {
   5.141 +        errThread.join(); // Make sure output is forwarded
   5.142 +        outThread.join();
   5.143 +    } catch (InterruptedException exc) {
   5.144 +        // we don't interrupt
   5.145 +    }
   5.146 +  }
   5.147 +
   5.148 +  /**
   5.149 +   * Find a com.sun.jdi.CommandLineLaunch connector
   5.150 +   */
   5.151 +  static LaunchingConnector findLaunchingConnector() {
   5.152 +    List <Connector> connectors = Bootstrap.virtualMachineManager().allConnectors();
   5.153 +    Iterator <Connector> iter = connectors.iterator();
   5.154 +    while (iter.hasNext()) {
   5.155 +      Connector connector = iter.next();
   5.156 +      if (connector.name().equals("com.sun.jdi.CommandLineLaunch")) {
   5.157 +        return (LaunchingConnector)connector;
   5.158 +      }
   5.159 +    }
   5.160 +    throw new Error("No launching connector");
   5.161 +  }
   5.162 +  /**
   5.163 +   * Return the launching connector's arguments.
   5.164 +   */
   5.165 + static Map <String,Connector.Argument> connectorArguments(LaunchingConnector connector, String mainArgs) {
   5.166 +      Map<String,Connector.Argument> arguments = connector.defaultArguments();
   5.167 +      for (String key : arguments.keySet()) {
   5.168 +        System.out.println(key);
   5.169 +      }
   5.170 +
   5.171 +      Connector.Argument mainArg = (Connector.Argument)arguments.get("main");
   5.172 +      if (mainArg == null) {
   5.173 +          throw new Error("Bad launching connector");
   5.174 +      }
   5.175 +      mainArg.setValue(mainArgs);
   5.176 +
   5.177 +      Connector.Argument optionsArg = (Connector.Argument)arguments.get("options");
   5.178 +      if (optionsArg == null) {
   5.179 +        throw new Error("Bad launching connector");
   5.180 +      }
   5.181 +      optionsArg.setValue(ARGUMENTS);
   5.182 +      return arguments;
   5.183 +  }
   5.184 +
   5.185 + static VirtualMachine launchTarget(String mainArgs) {
   5.186 +    LaunchingConnector connector = findLaunchingConnector();
   5.187 +    Map  arguments = connectorArguments(connector, mainArgs);
   5.188 +    try {
   5.189 +        return (VirtualMachine) connector.launch(arguments);
   5.190 +    } catch (IOException exc) {
   5.191 +        throw new Error("Unable to launch target VM: " + exc);
   5.192 +    } catch (IllegalConnectorArgumentsException exc) {
   5.193 +        throw new Error("Internal error: " + exc);
   5.194 +    } catch (VMStartException exc) {
   5.195 +        throw new Error("Target VM failed to initialize: " +
   5.196 +                        exc.getMessage());
   5.197 +    }
   5.198 +}
   5.199 +
   5.200 +
   5.201 +  private static void addClassWatch(VirtualMachine vm) {
   5.202 +    EventRequestManager erm = vm.eventRequestManager();
   5.203 +    ClassPrepareRequest classPrepareRequest = erm
   5.204 +        .createClassPrepareRequest();
   5.205 +    classPrepareRequest.addClassFilter(CLASS_NAME);
   5.206 +    classPrepareRequest.setEnabled(true);
   5.207 +  }
   5.208 +
   5.209 +
   5.210 +  private static void addFieldWatch(VirtualMachine vm,
   5.211 +      ReferenceType refType) {
   5.212 +    EventRequestManager erm = vm.eventRequestManager();
   5.213 +    Field field = refType.fieldByName(FIELD_NAME);
   5.214 +    ModificationWatchpointRequest modificationWatchpointRequest = erm
   5.215 +        .createModificationWatchpointRequest(field);
   5.216 +    modificationWatchpointRequest.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
   5.217 +    modificationWatchpointRequest.setEnabled(true);
   5.218 +  }
   5.219 +}
   5.220 +
   5.221 +class StreamRedirectThread extends Thread {
   5.222 +
   5.223 +  private final BufferedReader in;
   5.224 +
   5.225 +  private static final int BUFFER_SIZE = 2048;
   5.226 +
   5.227 +  /**
   5.228 +   * Set up for copy.
   5.229 +   * @param name  Name of the thread
   5.230 +   * @param in    Stream to copy from
   5.231 +   * @param out   Stream to copy to
   5.232 +   */
   5.233 +  StreamRedirectThread(String name, InputStream in) {
   5.234 +    super(name);
   5.235 +    this.in = new BufferedReader(new InputStreamReader(in));
   5.236 +  }
   5.237 +
   5.238 +  /**
   5.239 +   * Copy.
   5.240 +   */
   5.241 +  public void run() {
   5.242 +    try {
   5.243 +      String line;
   5.244 +        while ((line = in.readLine ()) != null) {
   5.245 +          System.out.println ("testvm: " + line);
   5.246 +      }
   5.247 +     System.out.flush();
   5.248 +    } catch(IOException exc) {
   5.249 +      System.err.println("Child I/O Transfer - " + exc);
   5.250 +    }
   5.251 +  }
   5.252 +}

mercurial