jdk/test/java/lang/instrument/ilib/InjectBytecodes.java
author ohair
Wed, 06 Apr 2011 22:06:11 -0700
changeset 9035 1255eb81cc2f
parent 7803 56bc97d69d93
permissions -rw-r--r--
7033660: Update copyright year to 2011 on any files changed in 2011 Reviewed-by: dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
9035
1255eb81cc2f 7033660: Update copyright year to 2011 on any files changed in 2011
ohair
parents: 7803
diff changeset
     2
 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
2
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
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * questions.
2
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
 * An extension of BinaryCode that allows code to be printed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
 * Includes printing of disassembled byte codes, exception info,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
 * local variable and line number info.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
package ilib;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.io.ByteArrayInputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.io.CharArrayWriter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.io.DataInputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.io.PrintWriter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.io.PrintStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.util.Map;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import java.util.HashMap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
class InjectBytecodes implements RuntimeConstants {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
    private final ClassReaderWriter c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
    private final PrintStream output;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
    private final int length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
    private final int[] map;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
    private final byte[] widening;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
    private final Injector[] before = new Injector[256];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
    private final Injector[] after  = new Injector[256];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
    private final String className;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
    private final String methodName;
7803
56bc97d69d93 6880112: Project Coin: Port JDK core library code to use diamond operator
smarks
parents: 5506
diff changeset
    53
    private final Map<Integer,byte[]> snippets = new HashMap<>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
    private int pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
    private int newPos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
    private class Span {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
        final int delta;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
        final int target;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
        final int newDelta;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
        final int newTarget;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
        Span(int delta) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
            this.delta = delta;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
            this.target = pos + delta;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
            this.newTarget = map[target];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
            this.newDelta = newTarget - newPos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
     * Constructor
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    InjectBytecodes(ClassReaderWriter c, int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
                    String className, String methodName) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
        this.c = c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
        this.output = System.out;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
        this.length = length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
        this.map = new int[length + 1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
        this.widening = new byte[length + 1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
        this.className = className;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
        this.methodName = methodName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
        c.markLocalPositionStart();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
        for (int i = 0; i <= length; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
            map[i] = i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    public void inject(int at, byte[] newCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
        snippets.put(new Integer(at), newCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        trace("external ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
        inject(at, newCode.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    private void inject(int at, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
        if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
            traceln("Injecting " + len + " at " + at);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
        for (int i = at; i <= length; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
            map[i] += len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    private void widen(int at, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
        int delta = len - widening[at];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
        if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
            traceln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
            traceln("Widening to " + len + " at " + at);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
        inject(c.localPosition(), delta);  // inject at end of instruction
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
        widening[at] = (byte)len;          // mark at beginning of instruction
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    public void injectBefore(int code, Injector inj) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        before[code] = inj;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    public void injectAfter(int code, Injector inj) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
        after[code] = inj;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    private void trace(String str) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
        if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
            output.print(str);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    private void traceln(String str) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
            output.println(str);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    private void traceln() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
            output.println();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    private void trace(int i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
        if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
            output.print(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     * Print an integer so that it takes 'length' characters in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     * the output.  Temporary until formatting code is stable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    private void traceFixedWidthInt(int x, int length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
            CharArrayWriter baStream = new CharArrayWriter();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
            PrintWriter pStream = new PrintWriter(baStream);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
            pStream.print(x);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
            String str = baStream.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
            for (int cnt = length - str.length(); cnt > 0; --cnt)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
                trace(" ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
            trace(str);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    void adjustOffsets() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
            traceln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
            traceln("Method " + methodName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
            traceln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
        c.rewind();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
        while (c.localPosition() < length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
            insertAtInstruction();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        trace("Searching for adjustments...");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        c.rewind();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        while (c.localPosition() < length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
            if (!adjustInstruction()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
                c.rewind();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
                traceln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
                traceln("Restarting adjustments after change...");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        // write the new bytecodes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        traceln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        traceln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        trace("Writing new code...");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        c.rewind();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        while (c.localPosition() < length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
            writeInstruction();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
        if (!snippets.isEmpty()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
            throw new Error("not all snippets written");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
     * Walk one instruction inserting instrumentation at specified instructions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
    private void insertAtInstruction() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
        pos = c.localPosition();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        int opcode = c.readU1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        if (opcode == opc_wide) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            // no support for instrumenting wide instructions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
            int wopcode = c.readU1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
            int lvIndex = c.readU2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
            switch (wopcode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
            case opc_aload: case opc_astore:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            case opc_fload: case opc_fstore:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
            case opc_iload: case opc_istore:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
            case opc_lload: case opc_lstore:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            case opc_dload: case opc_dstore:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
            case opc_ret:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
            case opc_iinc:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
                c.readS2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
            default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
                throw new Error("Invalid wide opcode: " + wopcode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
            Injector inj;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
            inj = before[opcode];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
            if (inj != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
                inject(pos, inj.bytecodes(className, methodName, pos));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
            switch (opcode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
            case opc_tableswitch:{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
                int header = (pos+1+3) & (~3);        // 4byte boundry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
                c.skip(header - (pos+1));             // skip old padding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
                c.readU4();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                int low = c.readU4();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
                int high = c.readU4();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
                c.skip((high+1-low) * 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
            case opc_lookupswitch:{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
                int header = (pos+1+3) & (~3);        // 4byte boundry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
                c.skip(header - (pos+1));             // skip padding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                c.readU4();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
                int npairs = c.readU4();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
                c.skip(npairs * 8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
            default: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
                int instrLen = opcLengths[opcode];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
                c.skip(instrLen-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
            inj = after[opcode];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
            if (inj != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
                pos = c.localPosition();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
                inject(pos, inj.bytecodes(className, methodName, pos));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
     * Walk one instruction adjusting for insertions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    private boolean adjustInstruction() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
        pos = c.localPosition();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        newPos = map[pos];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
        int opcode = c.readU1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
        if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
            traceln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
            traceFixedWidthInt(pos, 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
            traceFixedWidthInt(newPos, 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
            trace(" ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        if (opcode == opc_wide) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
            int wopcode = c.readU1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
            int lvIndex = c.readU2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
            if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                trace(opcNames[wopcode] + "_w ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
            switch (wopcode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
            case opc_aload: case opc_astore:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
            case opc_fload: case opc_fstore:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
            case opc_iload: case opc_istore:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
            case opc_lload: case opc_lstore:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
            case opc_dload: case opc_dstore:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            case opc_ret:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
                trace(lvIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
            case opc_iinc:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
                int constVal = c.readS2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
                if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
                    trace(lvIndex + " " + constVal);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
            default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
                throw new Error("Invalid wide opcode: " + wopcode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
            if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                trace(opcNames[opcode]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
            switch (opcode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
            case opc_tableswitch:{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
                int widened = widening[pos];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
                int header = (pos+1+3) & (~3);        // 4byte boundry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
                int newHeader = (newPos+1+3) & (~3);  // 4byte boundry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
                c.skip(header - (pos+1));             // skip old padding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
                Span defaultSkip = new Span(c.readU4());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
                int low = c.readU4();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
                int high = c.readU4();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
                if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
                    trace(" " + low + " to " + high);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
                    trace(": default= [was] " + defaultSkip.target);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
                    trace(" [now] " + defaultSkip.newTarget);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
                    for (int i = low; i <= high; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
                        Span jump = new Span(c.readU4());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
                        traceln("");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
                        trace('\t');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
                        traceFixedWidthInt(i, 5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
                        trace(": " + jump.newTarget);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
                    c.skip((high+1-low) * 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                int newPadding = newHeader - newPos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
                int oldPadding = header - pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
                int deltaPadding = newPadding - oldPadding;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
                if (widened != deltaPadding) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
                    widen(pos, deltaPadding);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
                    return false;       // cause restart
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
            case opc_lookupswitch:{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
                int widened = widening[pos];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
                int header = (pos+1+3) & (~3);        // 4byte boundry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
                int newHeader = (newPos+1+3) & (~3);  // 4byte boundry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
                c.skip(header - (pos+1));             // skip old padding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
                Span defaultSkip = new Span(c.readU4());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
                int npairs = c.readU4();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
                if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
                    trace(" npairs: " + npairs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
                    trace(": default= [was] " + defaultSkip.target);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
                    trace(" [now] " + defaultSkip.newTarget);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
                    for (int i = 0; i< npairs; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
                        int match = c.readU4();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
                        Span jump = new Span(c.readU4());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
                        traceln("");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
                        trace('\t');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
                        traceFixedWidthInt(match, 5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
                        trace(": " + jump.newTarget);
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
                    c.skip(npairs * 8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
                int newPadding = newHeader - newPos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
                int oldPadding = header - pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
                int deltaPadding = newPadding - oldPadding;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
                if (widened != deltaPadding) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
                    widen(pos, deltaPadding);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
                    return false;       // cause restart
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
            case opc_jsr: case opc_goto:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
            case opc_ifeq: case opc_ifge: case opc_ifgt:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
            case opc_ifle: case opc_iflt: case opc_ifne:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
            case opc_if_icmpeq: case opc_if_icmpne: case opc_if_icmpge:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
            case opc_if_icmpgt: case opc_if_icmple: case opc_if_icmplt:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
            case opc_if_acmpeq: case opc_if_acmpne:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
            case opc_ifnull: case opc_ifnonnull: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
                int widened = widening[pos];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
                Span jump = new Span(c.readS2());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
                if (widened == 0) {  // not yet widened
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
                    int newDelta = jump.newDelta;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
                    if ((newDelta < -32768) || (newDelta > 32767)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
                        switch (opcode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
                        case opc_jsr: case opc_goto:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
                            widen(pos, 2); // will convert to wide
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
                        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
                            widen(pos, 5); // will inject goto_w
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
                        return false;       // cause restart
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
                if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
                    trace(" [was] " + jump.target + " ==> " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
                          " [now] " + jump.newTarget);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
            case opc_jsr_w:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
            case opc_goto_w: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
                Span jump = new Span(c.readU4());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
                if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
                    trace(" [was] " + jump.target +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
                          " [now] " + jump.newTarget);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
            default: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
                int instrLen = opcLengths[opcode];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
                c.skip(instrLen-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
        return true;     // successful return
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
     * Walk one instruction writing the transformed instruction.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    private void writeInstruction() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        pos = c.localPosition();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
        newPos = map[pos];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        byte[] newCode = snippets.remove(new Integer(pos));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
        if (newCode != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
            traceln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
            traceFixedWidthInt(pos, 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
            trace(" ... -- Inserting new code");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
            c.writeBytes(newCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
        int opcode = c.readU1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
        if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
            traceln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
            traceFixedWidthInt(pos, 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
            traceFixedWidthInt(newPos, 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
            trace(" ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
        if (opcode == opc_wide) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
            int wopcode = c.readU1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
            int lvIndex = c.readU2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
            if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
                trace(opcNames[wopcode] + "_w ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
            c.writeU1(opcode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
            c.writeU1(wopcode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
            c.writeU2(lvIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
            switch (wopcode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
            case opc_aload: case opc_astore:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
            case opc_fload: case opc_fstore:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
            case opc_iload: case opc_istore:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
            case opc_lload: case opc_lstore:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
            case opc_dload: case opc_dstore:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
            case opc_ret:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
                trace(lvIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
            case opc_iinc:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
                int constVal = c.readS2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
                c.writeU2(constVal);  // ??? U vs S
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
                if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
                    trace(lvIndex + " " + constVal);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
            default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
                throw new Error("Invalid wide opcode: " + wopcode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
            if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
                trace(opcNames[opcode]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
            switch (opcode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
            case opc_tableswitch:{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
                int header = (pos+1+3) & (~3);   // 4byte boundry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
                int newHeader = (newPos+1+3) & (~3); // 4byte boundry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
                c.skip(header - (pos+1));             // skip old padding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
                Span defaultSkip = new Span(c.readU4());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
                int low = c.readU4();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
                int high = c.readU4();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
                c.writeU1(opcode);                   // copy instruction
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
                for (int i = newPos+1; i < newHeader; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
                    c.writeU1(0);                    // write new padding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
                c.writeU4(defaultSkip.newDelta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
                c.writeU4(low);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
                c.writeU4(high);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
                if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
                    trace(" " + low + " to " + high);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
                    trace(": default= [was] " + defaultSkip.target);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
                    trace(" [now] " + defaultSkip.newTarget);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
                for (int i = low; i <= high; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
                    Span jump = new Span(c.readU4());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
                    c.writeU4(jump.newDelta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
                    if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
                        traceln("");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
                        trace('\t');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
                        traceFixedWidthInt(i, 5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
                        trace(": " + jump.newTarget);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
            case opc_lookupswitch:{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
                int header = (pos+1+3) & (~3);   // 4byte boundry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
                int newHeader = (newPos+1+3) & (~3); // 4byte boundry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
                c.skip(header - (pos+1));             // skip old padding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
                Span defaultSkip = new Span(c.readU4());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
                int npairs = c.readU4();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
                if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
                    trace(" npairs: " + npairs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
                    trace(": default= [was] " + defaultSkip.target);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
                    trace(" [now] " + defaultSkip.newTarget);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
                c.writeU1(opcode);                   // copy instruction
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
                for (int i = newPos+1; i < newHeader; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
                    c.writeU1(0);                    // write new padding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
                c.writeU4(defaultSkip.newDelta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
                c.writeU4(npairs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
                for (int i = 0; i< npairs; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
                    int match = c.readU4();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
                    Span jump = new Span(c.readU4());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
                    c.writeU4(match);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
                    c.writeU4(jump.newDelta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
                    if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
                        traceln("");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
                        trace('\t');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
                        traceFixedWidthInt(match, 5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
                        trace(": " + jump.newTarget);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
            case opc_jsr: case opc_goto:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
            case opc_ifeq: case opc_ifge: case opc_ifgt:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
            case opc_ifle: case opc_iflt: case opc_ifne:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            case opc_if_icmpeq: case opc_if_icmpne: case opc_if_icmpge:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
            case opc_if_icmpgt: case opc_if_icmple: case opc_if_icmplt:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
            case opc_if_acmpeq: case opc_if_acmpne:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
            case opc_ifnull: case opc_ifnonnull: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
                int widened = widening[pos];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
                Span jump = new Span(c.readS2());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
                int newOpcode = opcode;   // default to unchanged
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
                if (widened == 0) {        // not widened
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
                    c.writeU1(opcode);    // rewrite instruction
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
                    c.writeU2(jump.newDelta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
                } else if (widened == 2) { // wide form
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
                    switch (opcode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
                    case opc_jsr:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
                        newOpcode = opc_jsr_w;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
                    case opc_goto:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
                        newOpcode = opc_jsr_w;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
                    default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
                        throw new Error("unexpected opcode: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
                                   opcode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
                    c.writeU1(newOpcode);      // write wide instruction
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
                    c.writeU4(jump.newDelta);  // write new and wide delta
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
                } else if (widened == 5) {      // insert goto_w
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
                    switch (opcode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
                    case opc_ifeq:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
                        newOpcode = opc_ifne;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
                    case opc_ifge:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
                        newOpcode = opc_iflt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
                    case opc_ifgt:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
                        newOpcode = opc_ifle;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
                    case opc_ifle:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
                        newOpcode = opc_ifgt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
                    case opc_iflt:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
                        newOpcode = opc_ifge;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
                    case opc_ifne:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
                        newOpcode = opc_ifeq;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
                    case opc_if_icmpeq:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
                        newOpcode = opc_if_icmpne;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
                    case opc_if_icmpne:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
                        newOpcode = opc_if_icmpeq;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
                    case opc_if_icmpge:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
                        newOpcode = opc_if_icmplt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
                    case opc_if_icmpgt:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
                        newOpcode = opc_if_icmple;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
                    case opc_if_icmple:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
                        newOpcode = opc_if_icmpgt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
                    case opc_if_icmplt:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
                        newOpcode = opc_if_icmpge;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
                    case opc_if_acmpeq:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
                        newOpcode = opc_if_acmpne;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
                    case opc_if_acmpne:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
                        newOpcode = opc_if_acmpeq;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
                    case opc_ifnull:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
                        newOpcode = opc_ifnonnull;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
                    case opc_ifnonnull:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
                        newOpcode = opc_ifnull;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
                    default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
                        throw new Error("unexpected opcode: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
                                   opcode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
                    c.writeU1(newOpcode); // write inverse branch
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
                    c.writeU2(3 + 5);     // beyond if and goto_w
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
                    c.writeU1(opc_goto_w);// add a goto_w
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
                    c.writeU4(jump.newDelta);  // write new and wide delta
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
                    throw new Error("unexpected widening");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
                if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
                    trace(" [was] " + jump.target + " ==> " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
                          opcNames[newOpcode] +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
                          " [now] " + jump.newTarget);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
            case opc_jsr_w:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
            case opc_goto_w: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
                Span jump = new Span(c.readU4());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
                c.writeU1(opcode);        // instruction itself
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
                c.writeU4(jump.newDelta);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
                if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
                    trace(" [was] " + jump.target +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
                          " [now] " + jump.newTarget);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
            default: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
                int instrLen = opcLengths[opcode];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
                c.writeU1(opcode);        // instruction itself
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
                c.copy(instrLen-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
     * Copy the exception table for this method code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
    void copyExceptionTable() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
        int tableLength = c.copyU2();   // exception table len
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
        if (tableLength > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
            traceln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
            traceln("Exception table:");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
            traceln(" from:old/new  to:old/new target:old/new type");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
            for (int tcnt = tableLength; tcnt > 0; --tcnt) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
                int startPC = c.readU2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
                int newStartPC = map[startPC];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
                c.writeU2(newStartPC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
                int endPC = c.readU2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
                int newEndPC = map[endPC];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
                c.writeU2(newEndPC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
                int handlerPC = c.readU2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
                int newHandlerPC = map[handlerPC];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
                c.writeU2(newHandlerPC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
                int catchType = c.copyU2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
                if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
                    traceFixedWidthInt(startPC, 6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
                    traceFixedWidthInt(newStartPC, 6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
                    traceFixedWidthInt(endPC, 6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
                    traceFixedWidthInt(newEndPC, 6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
                    traceFixedWidthInt(handlerPC, 6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
                    traceFixedWidthInt(newHandlerPC, 6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
                    trace("    ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
                    if (catchType == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
                        traceln("any");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
                    else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
                        traceln("" + catchType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
     * Copy the line number table for this method code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
    void copyLineNumberAttr() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
        // name index already read
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
        c.copy(4);                      // attr len
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
        int tableLength = c.copyU2();   // line table len
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
        if (tableLength > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
            if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
                traceln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
                traceln("Line numbers for method " + methodName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
            for (int tcnt = tableLength; tcnt > 0; --tcnt) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
                int startPC = c.readU2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
                int newStartPC = map[startPC];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
                c.writeU2(newStartPC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
                int lineNumber = c.copyU2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
                if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
                    traceln("   line " + lineNumber +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
                            ": [was] " + startPC +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
                            " [now] " + newStartPC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
     * Copy the local variable table for this method code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
    void copyLocalVarAttr() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
        // name index already read
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
        c.copy(4);                      // attr len
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
        int tableLength = c.copyU2();   // local var table len
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
        if (tableLength > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
            if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
                traceln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
                traceln("Local variables for method " + methodName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
            for (int tcnt = tableLength; tcnt > 0; --tcnt) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
                int startPC = c.readU2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
                int newStartPC = map[startPC];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
                c.writeU2(newStartPC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
                int length = c.readU2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
                int endPC = startPC + length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
                int newEndPC = map[endPC];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
                int newLength = newEndPC - newStartPC;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
                c.writeU2(newLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
                int nameIndex = c.copyU2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
                int descriptorIndex = c.copyU2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
                int index = c.copyU2();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
                if (Inject.verbose) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
                    trace("   ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
                    trace(descriptorIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
                    trace(" ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
                    trace(nameIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
                    traceln("  pc= [was] " + startPC + " [now] " + newStartPC +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
                            ", length= [was] " + length + " [now] " + newLength +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
                            ", slot=" + index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
}