1 /*
2  * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /**
25  * @test
26  * @bug 4409582
27  * @summary Test all info returned by modification watchpoints
28  * @author Daniel Prusa (or someone in the FFJ group)
29  * @author Robert Field
30  *
31  * @run build TestScaffold VMConnection
32  * @run compile -g ModificationWatchpoints.java
33  * @run driver ModificationWatchpoints
34  */
35 import com.sun.jdi.*;
36 import com.sun.jdi.event.*;
37 import com.sun.jdi.request.*;
38 import java.util.*;
39 
40     /********** target program **********/
41 
42 class ModificationWatchpointsTarg {
43     public static final int RepeatCount = 3;
44 
45     public static final byte ByteVal = -17;
46     public static final char CharVal = 'Y';
47     public static final short ShortVal = -412;
48     public static final int IntVal = -711618;
49     public static final long LongVal = 0x1234567890123456L;
50     public static final float FloatVal = 7.986f;
51     public static final double DoubleVal = 3.14159265358979d;
52     public static final String StringVal = "OnceMore";
53     public static final Object ObjectVal = new Object();
54 
55     static byte sByte;
56     static char sChar;
57     static short sShort;
58     static int sInt;
59     static long sLong;
60     static float sFloat;
61     static double sDouble;
62     static String sString;
63     static Object sObject;
64 
65     byte iByte;
66     char iChar;
67     short iShort;
68     int iInt;
69     long iLong;
70     float iFloat;
71     double iDouble;
72     String iString;
73     Object iObject;
74 
iByteSet()75     void iByteSet() {
76         iByte = ByteVal;
77     }
78 
iCharSet()79     void iCharSet() {
80         iChar = CharVal;
81     }
82 
iShortSet()83     void iShortSet() {
84         iShort = ShortVal;
85     }
86 
iIntSet()87     void iIntSet() {
88         iInt = IntVal;
89     }
90 
iLongSet()91     void iLongSet() {
92         iLong = LongVal;
93     }
94 
iFloatSet()95     void iFloatSet() {
96         iFloat = FloatVal;
97     }
98 
iDoubleSet()99     void iDoubleSet() {
100         iDouble = DoubleVal;
101     }
102 
iStringSet()103     void iStringSet() {
104         iString = StringVal;
105     }
106 
iObjectSet()107     void iObjectSet() {
108         iObject = ObjectVal;
109     }
110 
sByteSet()111     static void sByteSet() {
112         sByte = ByteVal;
113     }
114 
sCharSet()115     static void sCharSet() {
116         sChar = CharVal;
117     }
118 
sShortSet()119     static void sShortSet() {
120         sShort = ShortVal;
121     }
122 
sIntSet()123     static void sIntSet() {
124         sInt = IntVal;
125     }
126 
sLongSet()127     static void sLongSet() {
128         sLong = LongVal;
129     }
130 
sFloatSet()131     static void sFloatSet() {
132         sFloat = FloatVal;
133     }
134 
sDoubleSet()135     static void sDoubleSet() {
136         sDouble = DoubleVal;
137     }
138 
sStringSet()139     static void sStringSet() {
140         sString = StringVal;
141     }
142 
sObjectSet()143     static void sObjectSet() {
144         sObject = ObjectVal;
145     }
146 
iUpdate()147     void iUpdate(){
148         iByteSet();
149         iCharSet();
150         iShortSet();
151         iIntSet();
152         iLongSet();
153         iFloatSet();
154         iDoubleSet();
155         iStringSet();
156         iObjectSet();
157     }
158 
sUpdate()159     static void sUpdate(){
160         sByteSet();
161         sCharSet();
162         sShortSet();
163         sIntSet();
164         sLongSet();
165         sFloatSet();
166         sDoubleSet();
167         sStringSet();
168         sObjectSet();
169     }
170 
main(String[] args)171     public static void main(String[] args){
172         ModificationWatchpointsTarg targ = new ModificationWatchpointsTarg();
173         for (int i = RepeatCount; i > 0; i--) {
174             sUpdate();
175             targ.iUpdate();
176         }
177     }
178 }
179 
180 public class ModificationWatchpoints extends TestScaffold {
181     ReferenceType targ;
182     List allMWP = new ArrayList();
183 
ModificationWatchpoints(String args[])184     ModificationWatchpoints (String args[]) {
185         super(args);
186     }
187 
main(String[] args)188     public static void main(String[] args)      throws Exception {
189         new ModificationWatchpoints(args).startTests();
190     }
191 
192     /********** event handlers **********/
193 
fieldModified(ModificationWatchpointEvent event)194     public void fieldModified(ModificationWatchpointEvent event) {
195         MWP mwp = (MWP)event.request().getProperty("executor");
196         mwp.fieldModified(event);
197     }
198 
199 
200     /********** test core **********/
201 
set(String fieldName, String valString)202     void set(String fieldName, String valString) {
203         Value val = targ.getValue(targ.fieldByName(valString));
204         MWP mwp = new MWP("ModificationWatchpointsTarg", fieldName, val);
205         allMWP.add(mwp);
206         mwp.set();
207     }
208 
runTests()209     protected void runTests() throws Exception {
210         /*
211          * Get to the top of main():
212          */
213         BreakpointEvent bpe = startToMain("ModificationWatchpointsTarg");
214         targ = bpe.location().declaringType();
215 
216         /*
217          * Set watchpoints
218          */
219         set("iByte", "ByteVal");
220         set("iChar", "CharVal");
221         set("iShort", "ShortVal");
222         set("iInt", "IntVal");
223         set("iLong", "LongVal");
224         set("iFloat", "FloatVal");
225         set("iDouble", "DoubleVal");
226         set("iString", "StringVal");
227         set("iObject", "ObjectVal");
228 
229         set("sByte", "ByteVal");
230         set("sChar", "CharVal");
231         set("sShort", "ShortVal");
232         set("sInt", "IntVal");
233         set("sLong", "LongVal");
234         set("sFloat", "FloatVal");
235         set("sDouble", "DoubleVal");
236         set("sString", "StringVal");
237         set("sObject", "ObjectVal");
238 
239         listenUntilVMDisconnect();
240 
241         if (!testFailed) {
242             for (Iterator it = allMWP.iterator(); it.hasNext();) {
243                 MWP mwp = (MWP)it.next();
244                 mwp.checkEventCounts(ModificationWatchpointsTarg.RepeatCount);
245             }
246         }
247 
248         if (!testFailed) {
249             println("ModificationWatchpoints: passed");
250         } else {
251             throw new Exception("ModificationWatchpoints: failed");
252         }
253     }
254 
255     /********** request wrapper **********/
256 
257     class MWP {
258         private final String className;
259         private final String fieldName;
260         private final Value expectedValue;
261         public int eventCount = 0;
262         public boolean failed = false;
263 
MWP(String className, String fieldName, Value value)264         public MWP(String className, String fieldName, Value value) {
265             this.className = className;
266             this.fieldName = fieldName;
267             this.expectedValue = value;
268         }
269 
270         /*
271          * Sets watchpoint with specified properties.
272          */
set()273         public void set() {
274             List classes = vm().classesByName(className);
275             if (classes.size() != 1) {
276                 failure("Expected one class named " + className + " got " + classes.size());
277             }
278 
279             set ((ReferenceType)classes.get(0));
280         }
281 
282         /**
283          * Sets watchpoint for given class.
284          */
set(ReferenceType clazz)285         public void set(ReferenceType clazz) {
286             Field f = clazz.fieldByName(fieldName);
287             ModificationWatchpointRequest mwr =
288                        eventRequestManager().createModificationWatchpointRequest(f);
289             mwr.putProperty("executor", this);
290             mwr.enable();
291             println("set watchpoint: " + className +"." + f);
292         }
293 
fieldModified(ModificationWatchpointEvent event)294         public void fieldModified(ModificationWatchpointEvent event) {
295             Value val = event.valueToBe();
296            println("Watchpoint reached: " + className + "." + fieldName +
297                    ", new value: " + val);
298             if (!val.equals(expectedValue)) {
299                 failure("FAILURE: value should be: " +
300                         expectedValue.getClass() + ":" + expectedValue +
301                         " has - " + val.getClass() + ":" + val);
302             }
303             if (!event.location().method().name().equals(fieldName + "Set")) {
304                 failure("FAILURE: occurred in wrong place: " + event.location());
305             }
306             eventCount++;
307         }
308 
checkEventCounts(int expectedCount)309         public void checkEventCounts(int expectedCount) {
310             if (eventCount != expectedCount) {
311                 failure(className + "." + fieldName +
312                         " - only got " + eventCount + " events");
313             }
314         }
315 
316     } // MWP inner class .................
317 }
318