jdk/test/com/sun/jdi/ReferrersTest.java
author jjg
Thu, 22 May 2008 15:51:41 -0700
changeset 655 1ebc7ce89018
parent 2 90ce3da70b43
child 5506 202f599c92aa
permissions -rw-r--r--
6705945: com.sun.tools.javac.zip files do not have valid copyright Reviewed-by: mcimadamore
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
 *  @test
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
 *  @bug 5089849
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
 *  @summary Add support for backtracking reference graph.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
 *  @author jjh
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
 *  @run build TestScaffold VMConnection TargetListener TargetAdapter
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
 *  @run compile -g ReferrersTest.java
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 *  @run main ReferrersTest
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 *  To run this test do this:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 *     runregress -no ReferrersTest <cmd line options>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 *  where <cmd line options> are the options to be used to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 *  launch the debuggee, with the classname prefixed with @@.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 *  For example, this would run java2d demo as the debuggee:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 *     runregress -no ReferrersTest -classpath
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 *                                    $jdkDir/demo/jfc/Java2D/Java2Demo.jar \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 *                                    -client @@java2d.Java2Demo
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * In this mode, the specified debuggee is launched in debug mode,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * and the debugger waits for a keystroke before connecting to the debuggee.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * If <cmd line options> is not specified, then the ReferrersTarg class below
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * is run as the debuggee.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
import com.sun.jdi.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
import com.sun.jdi.event.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
import com.sun.jdi.request.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
import java.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
class ReferrersFiller {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
    // This many instances of this are created.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
    static int FILLER_COUNT = 20000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
    static ReferrersFiller[] lotsAndLots = new ReferrersFiller[
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
                                               ReferrersFiller.FILLER_COUNT];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    int xx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    ReferrersFiller(int p1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
        xx = p1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
class ReferrersTarg {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    // This many instances + 1 of this class are created.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    static int TARG_COUNT = 10;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    static ReferrersTarg theReferrersTarg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
    static ReferrersTarg[] allReferrersTargs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    // Each instance will point to the theReferrersTarg
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    ReferrersTarg oneReferrersTarg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    public static void bkpt() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    public static void main(String[] args) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
        System.out.println("Howdy!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
        for (int ii = 0; ii < ReferrersFiller.lotsAndLots.length; ii++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
            ReferrersFiller.lotsAndLots[ii] = new ReferrersFiller(ii);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        theReferrersTarg = new ReferrersTarg();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
        allReferrersTargs = new ReferrersTarg[ReferrersTarg.TARG_COUNT];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
        for (int ii = 0; ii < ReferrersTarg.TARG_COUNT; ii++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
            allReferrersTargs[ii] = new ReferrersTarg();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
            allReferrersTargs[ii].oneReferrersTarg = theReferrersTarg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
        bkpt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
        System.out.println("Goodbye from ReferrersTarg!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
/********** test program **********/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
public class ReferrersTest extends TestScaffold {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    static String targetName = "ReferrersTarg";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    ReferenceType targetClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
    ThreadReference mainThread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    ReferrersTest(String args[]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
        super(args);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    public static void main(String[] args) throws Exception {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
         * If args contains @@xxxx, then that is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
         * name of the class we are to run.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
        for (int ii = 0; ii < args.length; ii ++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
            if (args[ii].startsWith("@@")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
                targetName = args[ii] = args[ii].substring(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
        new ReferrersTest(args).startTests();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     * Used to sort a list of ReferenceTypes by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     * instance count.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    class ToSort implements Comparable<ToSort> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
        long count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        ReferenceType rt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
        public ToSort(long count, ReferenceType rt) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
            this.count = count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
            this.rt = rt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
        public int compareTo(ToSort obj) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
            if (count < obj.count) return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
            if (count == obj.count) return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
            return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    protected void runTests() throws Exception {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
         * Get to the top of main()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
         * to determine targetClass and mainThread
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
        int CUT_OFF = 1000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        BreakpointEvent bpe;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
        bpe = startToMain(targetName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        targetClass = bpe.location().declaringType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
        mainThread = bpe.thread();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
        if (targetName.equals("ReferrersTarg")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
            resumeTo("ReferrersTarg", "bkpt", "()V");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
            // Let debuggee run for awhile to get classes loaded
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
            vm().resume();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
                System.err.println("Press <enter> to continue");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
                System.in.read();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
                System.err.println("running...");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
            } catch(Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
            vm().suspend();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
        // Get all classes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        long start = System.currentTimeMillis();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        List<ReferenceType> allClasses = vm().allClasses();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        long end = System.currentTimeMillis();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        System.out.println( allClasses.size() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
                            " classes from vm.allClasses() took " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
                            (end - start) + " ms");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
        long[] counts;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        // Test for NPE
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
            boolean pass = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
                counts = vm().instanceCounts(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
            } catch (NullPointerException ee) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
                pass = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
            if (!pass) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
                failure("failure: NullPointerException not thrown on instanceCounts(null)");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
        // Test for 0 length array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
            List<ReferenceType>someClasses = new ArrayList(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
            counts = vm().instanceCounts(someClasses);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
            if (counts.length != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
                failure("failure: instanceCounts with a zero length array fails: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                        counts.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
        // Test various values of maxInstances
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        if (targetClass.name().equals("ReferrersTarg")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
            List<ObjectReference> noInstances = targetClass.instances(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
            if (noInstances.size() != ReferrersTarg.TARG_COUNT + 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
                failure("failure: instances(0): " + noInstances.size() + ", for " + targetClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
            noInstances = targetClass.instances(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            if (noInstances.size() != 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                failure("failure: instances(1): " + noInstances.size() + ", for " + targetClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
            boolean pass = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
                noInstances = targetClass.instances(-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
            } catch (IllegalArgumentException ee) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
                pass = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
            if (!pass) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
                failure("failure: instances(-1) did not get an exception");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        // Instance counts for all classes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
        start = System.currentTimeMillis();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        counts = vm().instanceCounts(allClasses);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        end = System.currentTimeMillis();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
        if (counts.length == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
            System.out.println("failure: No instances found");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
            throw new Exception("ReferrersTest: failed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        // Create a list of ReferenceTypes sorted by instance count
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
        int size = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        List<ToSort> sorted = new ArrayList(allClasses.size());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
        for (int ii = 0; ii < allClasses.size(); ii++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
            size += counts[ii];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
            ToSort tos = new ToSort(counts[ii], allClasses.get(ii));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
            sorted.add(tos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        System.out.println("instance counts for " + counts.length +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                           " classes got " + size + " instances and took " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
                            (end - start) + " ms");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        boolean gotReferrersFiller = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
        boolean gotReferrersTarg = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
        Collections.sort(sorted);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
        for (int ii = sorted.size() - 1; ii >= 0 ; ii--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
            ToSort xxx = sorted.get(ii);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
            if (xxx.rt.name().equals("ReferrersFiller") &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
                xxx.count == ReferrersFiller.FILLER_COUNT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
                gotReferrersFiller = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
            if (xxx.rt.name().equals("ReferrersTarg") &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
                xxx.count == ReferrersTarg.TARG_COUNT + 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
                gotReferrersTarg = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
        if (!gotReferrersFiller) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
            failure("failure: Expected " + ReferrersFiller.FILLER_COUNT +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
                        " instances of ReferrersFiller");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        if (!gotReferrersTarg) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
            failure("failure: Expected " + (ReferrersTarg.TARG_COUNT + 1) +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
                    " instances of ReferrersTarg");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
        List<List<ObjectReference>> allInstances = new ArrayList(10);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        // Instances, one class at a time, in sorted order, printing each line
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        if (true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
            System.out.println("\nGetting instances for one class " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
                               "at a time (limited) in sorted order");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
            List<ReferenceType> rtList = new ArrayList(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
            rtList.add(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
            long start1 = System.currentTimeMillis();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
            size = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
            long count = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
            for (int ii = sorted.size() - 1; ii >= 0 ; ii--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
                ToSort xxx = sorted.get(ii);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
                if (xxx.count <= CUT_OFF) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
                rtList.set(0, xxx.rt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
                start = System.currentTimeMillis();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
                List<ObjectReference> oneInstances = xxx.rt.instances(19999999);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
                end = System.currentTimeMillis();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
                size += oneInstances.size();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
                count++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
                System.out.println("Expected " + xxx.count + " instances, got " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                                   oneInstances.size() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
                                   " instances for " + sorted.get(ii).rt +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
                                   " in " + (end - start) + " ms");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
                if (xxx.rt.name().equals("ReferrersFiller") &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
                    oneInstances.size() != ReferrersFiller.FILLER_COUNT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
                    failure("failure: Expected " + ReferrersFiller.FILLER_COUNT +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                            " instances of ReferrersFiller");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
                if (xxx.rt.name().equals("ReferrersTarg") &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
                    oneInstances.size() != ReferrersTarg.TARG_COUNT + 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
                    failure("failure: Expected " + (ReferrersTarg.TARG_COUNT + 1) +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
                            " instances of ReferrersTarg");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
                allInstances.add(oneInstances);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            end = System.currentTimeMillis();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            System.out.println(size + " instances via making one vm.instances" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
                               " call for each of " + count +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
                               " classes took " + (end - start1) + " ms");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
            System.out.println("Per class = " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
                               (end - start) / allClasses.size() + " ms");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        // referrers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
        // Test various values of maxReferrers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
        if (targetClass.name().equals("ReferrersTarg")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
            Field field1 = targetClass.fieldByName("theReferrersTarg");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
            ObjectReference anInstance = (ObjectReference)targetClass.getValue(field1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
            List<ObjectReference> noReferrers = anInstance.referringObjects(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
            if (noReferrers.size() != ReferrersTarg.TARG_COUNT + 1 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                failure("failure: referringObjects(0) got " + noReferrers.size() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
                        ", for " + anInstance);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
            noReferrers = anInstance.referringObjects(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
            if (noReferrers.size() != 1 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
                failure("failure: referringObjects(1) got " + noReferrers.size() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
                        ", for " + anInstance);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            boolean pass = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
                noReferrers = anInstance.referringObjects(-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
            } catch (IllegalArgumentException ee) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
                pass = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
            if (!pass) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
                failure("failure: referringObjects(-1) did not get an exception");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
        List<ObjectReference> allReferrers = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
        List<ObjectReference> someInstances = new ArrayList();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
        if (targetName.equals("ReferrersTarg")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
            Field field1 = targetClass.fieldByName("theReferrersTarg");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
            ObjectReference val = (ObjectReference)targetClass.getValue(field1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
            someInstances.add(val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
            allReferrers = val.referringObjects(99999);  //LIMIT
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
            if (allReferrers.size() != ReferrersTarg.TARG_COUNT + 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
                failure("failure: expected " + (ReferrersTarg.TARG_COUNT + 1) +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
                        "referrers, but got " + allReferrers.size() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
                        " referrers for " + val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
            // referrers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
            // Create someInstances to find the referrers of.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
            for (int ii = 0; ii < allClasses.size(); ii++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
                List<ObjectReference> objRefList = allInstances.get(ii);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
                if (objRefList != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
                    int asize = objRefList.size();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
                    if (false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
                        System.out.println(asize + ", " + allClasses.get(ii));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
                    // Remember one instance per class to get referrers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
                    if (asize > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
                        someInstances.add(objRefList.get(0));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
        for (ObjectReference objRef: someInstances) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
            //System.out.println( "Getting referrers for " + objRef);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
            start = System.currentTimeMillis();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
            if ( true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
                showReferrers(objRef, 0, 0, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
                allReferrers = objRef.referringObjects(99999);  //LIMIT
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
                end = System.currentTimeMillis();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
                if (true || allReferrers.size() > 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
                    System.out.println( allReferrers.size() + " referrers for " + objRef + " took " + (end - start) + " ms");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
         * deal with results of test
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
         * if anything has called failure("foo") testFailed will be true
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
        if (!testFailed) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
            println("ReferrersTest: passed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
            throw new Exception("ReferrersTest: failed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
    void indent(int level) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
        for (int ii = 0; ii < level; ii++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
            System.out.print("    ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
    Map<ObjectReference, Object> visited = new HashMap(100);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
    void showReferrers(ObjectReference objRef, int level, int total, int which) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
        if (level == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
            visited.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
            if (visited.containsKey(objRef)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
                indent(level);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
                System.out.println("(" + which + ")" + ":<pruned> " + objRef);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
            visited.put(objRef, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
            indent(level);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
            //System.out.println(which + "/" + total + ": " + objRef + " took " + time + " ms");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        List<ObjectReference> allReferrers = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
        //System.out.println( "Getting referrers for " + objRef);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        long start, end;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
        start = System.currentTimeMillis();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        allReferrers = objRef.referringObjects(99999);  //LIMIT
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
        end = System.currentTimeMillis();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        if (which == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
            System.out.println(allReferrers.size() + " referrers for " + objRef + " took " + (end - start) + " ms");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
            System.out.println("(" + which + ") "  + objRef);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
            indent(level);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
            System.out.println("    " + allReferrers.size() + " referrers for " + objRef + " took " + (end - start) + " ms");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        // We have to stop going up a referrer chain in some cases
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
        Type rt = objRef.type();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        if (rt instanceof ClassType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
            ClassType ct = (ClassType)rt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
            String name = ct.name();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
            if (name.equals("sun.misc.SoftCache$ValueCell")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
            if (name.equals("java.lang.ref.Finalizer")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
            if (name.equals("java.lang.ref.SoftReference")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
            // oh oh, should really check for a subclass of ClassLoader :-)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
            if (name.indexOf("ClassLoader") >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
            // No doubt there are other reasons to stop ...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
        int itemNumber = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
        int allSize = allReferrers.size();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
        for (ObjectReference objx: allReferrers) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
            showReferrers(objx, level + 1, allSize, itemNumber++);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
}