jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MethodGenerator.java
author joehw
Sat, 18 Apr 2015 00:17:19 -0700
changeset 33349 975138b77cff
parent 25868 686eef1e7a79
child 46174 5611d2529b49
permissions -rw-r--r--
8068842: Better JAXP data handling Reviewed-by: dfuchs, lancea, hawtin
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6
7f561c08de6b Initial load
duke
parents:
diff changeset
     1
/*
33349
975138b77cff 8068842: Better JAXP data handling
joehw
parents: 25868
diff changeset
     2
 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
6
7f561c08de6b Initial load
duke
parents:
diff changeset
     3
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
     4
/*
33349
975138b77cff 8068842: Better JAXP data handling
joehw
parents: 25868
diff changeset
     5
 * Licensed to the Apache Software Foundation (ASF) under one or more
975138b77cff 8068842: Better JAXP data handling
joehw
parents: 25868
diff changeset
     6
 * contributor license agreements.  See the NOTICE file distributed with
975138b77cff 8068842: Better JAXP data handling
joehw
parents: 25868
diff changeset
     7
 * this work for additional information regarding copyright ownership.
975138b77cff 8068842: Better JAXP data handling
joehw
parents: 25868
diff changeset
     8
 * The ASF licenses this file to You under the Apache License, Version 2.0
975138b77cff 8068842: Better JAXP data handling
joehw
parents: 25868
diff changeset
     9
 * (the "License"); you may not use this file except in compliance with
975138b77cff 8068842: Better JAXP data handling
joehw
parents: 25868
diff changeset
    10
 * the License.  You may obtain a copy of the License at
6
7f561c08de6b Initial load
duke
parents:
diff changeset
    11
 *
33349
975138b77cff 8068842: Better JAXP data handling
joehw
parents: 25868
diff changeset
    12
 *      http://www.apache.org/licenses/LICENSE-2.0
6
7f561c08de6b Initial load
duke
parents:
diff changeset
    13
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    14
 * Unless required by applicable law or agreed to in writing, software
7f561c08de6b Initial load
duke
parents:
diff changeset
    15
 * distributed under the License is distributed on an "AS IS" BASIS,
7f561c08de6b Initial load
duke
parents:
diff changeset
    16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7f561c08de6b Initial load
duke
parents:
diff changeset
    17
 * See the License for the specific language governing permissions and
7f561c08de6b Initial load
duke
parents:
diff changeset
    18
 * limitations under the License.
7f561c08de6b Initial load
duke
parents:
diff changeset
    19
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    20
/*
7f561c08de6b Initial load
duke
parents:
diff changeset
    21
 * $Id: MethodGenerator.java,v 1.2.4.1 2005/09/05 11:16:47 pvedula Exp $
7f561c08de6b Initial load
duke
parents:
diff changeset
    22
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    23
7f561c08de6b Initial load
duke
parents:
diff changeset
    24
package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
7f561c08de6b Initial load
duke
parents:
diff changeset
    25
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    26
import java.util.ArrayList;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    27
import java.util.Collections;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    28
import java.util.HashMap;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    29
import java.util.Iterator;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    30
import java.util.Map;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    31
import java.util.Stack;
6
7f561c08de6b Initial load
duke
parents:
diff changeset
    32
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    33
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    34
import com.sun.org.apache.bcel.internal.Constants;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    35
import com.sun.org.apache.bcel.internal.classfile.Field;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    36
import com.sun.org.apache.bcel.internal.classfile.Method;
6
7f561c08de6b Initial load
duke
parents:
diff changeset
    37
import com.sun.org.apache.bcel.internal.generic.ALOAD;
7f561c08de6b Initial load
duke
parents:
diff changeset
    38
import com.sun.org.apache.bcel.internal.generic.ASTORE;
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    39
import com.sun.org.apache.bcel.internal.generic.BranchHandle;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    40
import com.sun.org.apache.bcel.internal.generic.BranchInstruction;
6
7f561c08de6b Initial load
duke
parents:
diff changeset
    41
import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    42
import com.sun.org.apache.bcel.internal.generic.DLOAD;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    43
import com.sun.org.apache.bcel.internal.generic.DSTORE;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    44
import com.sun.org.apache.bcel.internal.generic.FLOAD;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    45
import com.sun.org.apache.bcel.internal.generic.FSTORE;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    46
import com.sun.org.apache.bcel.internal.generic.GETFIELD;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    47
import com.sun.org.apache.bcel.internal.generic.GOTO;
6
7f561c08de6b Initial load
duke
parents:
diff changeset
    48
import com.sun.org.apache.bcel.internal.generic.ICONST;
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    49
import com.sun.org.apache.bcel.internal.generic.IfInstruction;
6
7f561c08de6b Initial load
duke
parents:
diff changeset
    50
import com.sun.org.apache.bcel.internal.generic.ILOAD;
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    51
import com.sun.org.apache.bcel.internal.generic.IndexedInstruction;
6
7f561c08de6b Initial load
duke
parents:
diff changeset
    52
import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    53
import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    54
import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    55
import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
6
7f561c08de6b Initial load
duke
parents:
diff changeset
    56
import com.sun.org.apache.bcel.internal.generic.ISTORE;
7f561c08de6b Initial load
duke
parents:
diff changeset
    57
import com.sun.org.apache.bcel.internal.generic.Instruction;
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    58
import com.sun.org.apache.bcel.internal.generic.InstructionConstants;
6
7f561c08de6b Initial load
duke
parents:
diff changeset
    59
import com.sun.org.apache.bcel.internal.generic.InstructionHandle;
7f561c08de6b Initial load
duke
parents:
diff changeset
    60
import com.sun.org.apache.bcel.internal.generic.InstructionList;
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    61
import com.sun.org.apache.bcel.internal.generic.InstructionTargeter;
6
7f561c08de6b Initial load
duke
parents:
diff changeset
    62
import com.sun.org.apache.bcel.internal.generic.LocalVariableGen;
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    63
import com.sun.org.apache.bcel.internal.generic.LocalVariableInstruction;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    64
import com.sun.org.apache.bcel.internal.generic.LLOAD;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    65
import com.sun.org.apache.bcel.internal.generic.LSTORE;
6
7f561c08de6b Initial load
duke
parents:
diff changeset
    66
import com.sun.org.apache.bcel.internal.generic.MethodGen;
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    67
import com.sun.org.apache.bcel.internal.generic.NEW;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    68
import com.sun.org.apache.bcel.internal.generic.PUTFIELD;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    69
import com.sun.org.apache.bcel.internal.generic.RET;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    70
import com.sun.org.apache.bcel.internal.generic.Select;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    71
import com.sun.org.apache.bcel.internal.generic.TargetLostException;
6
7f561c08de6b Initial load
duke
parents:
diff changeset
    72
import com.sun.org.apache.bcel.internal.generic.Type;
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    73
6
7f561c08de6b Initial load
duke
parents:
diff changeset
    74
import com.sun.org.apache.xalan.internal.xsltc.compiler.Pattern;
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    75
import com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC;
6
7f561c08de6b Initial load
duke
parents:
diff changeset
    76
7f561c08de6b Initial load
duke
parents:
diff changeset
    77
/**
7f561c08de6b Initial load
duke
parents:
diff changeset
    78
 * @author Jacek Ambroziak
7f561c08de6b Initial load
duke
parents:
diff changeset
    79
 * @author Santiago Pericas-Geertsen
7f561c08de6b Initial load
duke
parents:
diff changeset
    80
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    81
public class MethodGenerator extends MethodGen
7f561c08de6b Initial load
duke
parents:
diff changeset
    82
    implements com.sun.org.apache.xalan.internal.xsltc.compiler.Constants {
7f561c08de6b Initial load
duke
parents:
diff changeset
    83
    protected static final int INVALID_INDEX   = -1;
7f561c08de6b Initial load
duke
parents:
diff changeset
    84
7f561c08de6b Initial load
duke
parents:
diff changeset
    85
    private static final String START_ELEMENT_SIG
7f561c08de6b Initial load
duke
parents:
diff changeset
    86
        = "(" + STRING_SIG + ")V";
7f561c08de6b Initial load
duke
parents:
diff changeset
    87
    private static final String END_ELEMENT_SIG
7f561c08de6b Initial load
duke
parents:
diff changeset
    88
        = START_ELEMENT_SIG;
7f561c08de6b Initial load
duke
parents:
diff changeset
    89
7f561c08de6b Initial load
duke
parents:
diff changeset
    90
    private InstructionList _mapTypeSub;
7f561c08de6b Initial load
duke
parents:
diff changeset
    91
7f561c08de6b Initial load
duke
parents:
diff changeset
    92
    private static final int DOM_INDEX       = 1;
7f561c08de6b Initial load
duke
parents:
diff changeset
    93
    private static final int ITERATOR_INDEX  = 2;
7f561c08de6b Initial load
duke
parents:
diff changeset
    94
    private static final int HANDLER_INDEX   = 3;
7f561c08de6b Initial load
duke
parents:
diff changeset
    95
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    96
    private static final int MAX_METHOD_SIZE = 65535;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    97
    private static final int MAX_BRANCH_TARGET_OFFSET = 32767;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    98
    private static final int MIN_BRANCH_TARGET_OFFSET = -32768;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
    99
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   100
    private static final int TARGET_METHOD_SIZE = 60000;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   101
    private static final int MINIMUM_OUTLINEABLE_CHUNK_SIZE = 1000;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   102
6
7f561c08de6b Initial load
duke
parents:
diff changeset
   103
    private Instruction       _iloadCurrent;
7f561c08de6b Initial load
duke
parents:
diff changeset
   104
    private Instruction       _istoreCurrent;
7f561c08de6b Initial load
duke
parents:
diff changeset
   105
    private final Instruction _astoreHandler;
7f561c08de6b Initial load
duke
parents:
diff changeset
   106
    private final Instruction _aloadHandler;
7f561c08de6b Initial load
duke
parents:
diff changeset
   107
    private final Instruction _astoreIterator;
7f561c08de6b Initial load
duke
parents:
diff changeset
   108
    private final Instruction _aloadIterator;
7f561c08de6b Initial load
duke
parents:
diff changeset
   109
    private final Instruction _aloadDom;
7f561c08de6b Initial load
duke
parents:
diff changeset
   110
    private final Instruction _astoreDom;
7f561c08de6b Initial load
duke
parents:
diff changeset
   111
7f561c08de6b Initial load
duke
parents:
diff changeset
   112
    private final Instruction _startElement;
7f561c08de6b Initial load
duke
parents:
diff changeset
   113
    private final Instruction _endElement;
7f561c08de6b Initial load
duke
parents:
diff changeset
   114
    private final Instruction _startDocument;
7f561c08de6b Initial load
duke
parents:
diff changeset
   115
    private final Instruction _endDocument;
7f561c08de6b Initial load
duke
parents:
diff changeset
   116
    private final Instruction _attribute;
7f561c08de6b Initial load
duke
parents:
diff changeset
   117
    private final Instruction _uniqueAttribute;
7f561c08de6b Initial load
duke
parents:
diff changeset
   118
    private final Instruction _namespace;
7f561c08de6b Initial load
duke
parents:
diff changeset
   119
7f561c08de6b Initial load
duke
parents:
diff changeset
   120
    private final Instruction _setStartNode;
7f561c08de6b Initial load
duke
parents:
diff changeset
   121
    private final Instruction _reset;
7f561c08de6b Initial load
duke
parents:
diff changeset
   122
    private final Instruction _nextNode;
7f561c08de6b Initial load
duke
parents:
diff changeset
   123
7f561c08de6b Initial load
duke
parents:
diff changeset
   124
    private SlotAllocator _slotAllocator;
7f561c08de6b Initial load
duke
parents:
diff changeset
   125
    private boolean _allocatorInit = false;
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   126
    private LocalVariableRegistry _localVariableRegistry;
6
7f561c08de6b Initial load
duke
parents:
diff changeset
   127
        /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   128
                 * A mapping between patterns and instruction lists used by
7f561c08de6b Initial load
duke
parents:
diff changeset
   129
                 * test sequences to avoid compiling the same pattern multiple
7f561c08de6b Initial load
duke
parents:
diff changeset
   130
                 * times. Note that patterns whose kernels are "*", "node()"
7f561c08de6b Initial load
duke
parents:
diff changeset
   131
                 * and "@*" can between shared by test sequences.
7f561c08de6b Initial load
duke
parents:
diff changeset
   132
                 */
33349
975138b77cff 8068842: Better JAXP data handling
joehw
parents: 25868
diff changeset
   133
        private Map<Pattern, InstructionList> _preCompiled = new HashMap<>();
6
7f561c08de6b Initial load
duke
parents:
diff changeset
   134
7f561c08de6b Initial load
duke
parents:
diff changeset
   135
7f561c08de6b Initial load
duke
parents:
diff changeset
   136
    public MethodGenerator(int access_flags, Type return_type,
7f561c08de6b Initial load
duke
parents:
diff changeset
   137
                           Type[] arg_types, String[] arg_names,
7f561c08de6b Initial load
duke
parents:
diff changeset
   138
                           String method_name, String class_name,
7f561c08de6b Initial load
duke
parents:
diff changeset
   139
                           InstructionList il, ConstantPoolGen cpg) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   140
        super(access_flags, return_type, arg_types, arg_names, method_name,
7f561c08de6b Initial load
duke
parents:
diff changeset
   141
              class_name, il, cpg);
7f561c08de6b Initial load
duke
parents:
diff changeset
   142
7f561c08de6b Initial load
duke
parents:
diff changeset
   143
        _astoreHandler  = new ASTORE(HANDLER_INDEX);
7f561c08de6b Initial load
duke
parents:
diff changeset
   144
        _aloadHandler   = new ALOAD(HANDLER_INDEX);
7f561c08de6b Initial load
duke
parents:
diff changeset
   145
        _astoreIterator = new ASTORE(ITERATOR_INDEX);
7f561c08de6b Initial load
duke
parents:
diff changeset
   146
        _aloadIterator  = new ALOAD(ITERATOR_INDEX);
7f561c08de6b Initial load
duke
parents:
diff changeset
   147
        _aloadDom       = new ALOAD(DOM_INDEX);
7f561c08de6b Initial load
duke
parents:
diff changeset
   148
        _astoreDom      = new ASTORE(DOM_INDEX);
7f561c08de6b Initial load
duke
parents:
diff changeset
   149
7f561c08de6b Initial load
duke
parents:
diff changeset
   150
        final int startElement =
7f561c08de6b Initial load
duke
parents:
diff changeset
   151
            cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE,
7f561c08de6b Initial load
duke
parents:
diff changeset
   152
                                      "startElement",
7f561c08de6b Initial load
duke
parents:
diff changeset
   153
                                      START_ELEMENT_SIG);
7f561c08de6b Initial load
duke
parents:
diff changeset
   154
        _startElement = new INVOKEINTERFACE(startElement, 2);
7f561c08de6b Initial load
duke
parents:
diff changeset
   155
7f561c08de6b Initial load
duke
parents:
diff changeset
   156
        final int endElement =
7f561c08de6b Initial load
duke
parents:
diff changeset
   157
            cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE,
7f561c08de6b Initial load
duke
parents:
diff changeset
   158
                                      "endElement",
7f561c08de6b Initial load
duke
parents:
diff changeset
   159
                                      END_ELEMENT_SIG);
7f561c08de6b Initial load
duke
parents:
diff changeset
   160
        _endElement = new INVOKEINTERFACE(endElement, 2);
7f561c08de6b Initial load
duke
parents:
diff changeset
   161
7f561c08de6b Initial load
duke
parents:
diff changeset
   162
        final int attribute =
7f561c08de6b Initial load
duke
parents:
diff changeset
   163
            cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE,
7f561c08de6b Initial load
duke
parents:
diff changeset
   164
                                      "addAttribute",
7f561c08de6b Initial load
duke
parents:
diff changeset
   165
                                      "("
7f561c08de6b Initial load
duke
parents:
diff changeset
   166
                                      + STRING_SIG
7f561c08de6b Initial load
duke
parents:
diff changeset
   167
                                      + STRING_SIG
7f561c08de6b Initial load
duke
parents:
diff changeset
   168
                                      + ")V");
7f561c08de6b Initial load
duke
parents:
diff changeset
   169
        _attribute = new INVOKEINTERFACE(attribute, 3);
7f561c08de6b Initial load
duke
parents:
diff changeset
   170
7f561c08de6b Initial load
duke
parents:
diff changeset
   171
        final int uniqueAttribute =
7f561c08de6b Initial load
duke
parents:
diff changeset
   172
            cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE,
7f561c08de6b Initial load
duke
parents:
diff changeset
   173
                                      "addUniqueAttribute",
7f561c08de6b Initial load
duke
parents:
diff changeset
   174
                                      "("
7f561c08de6b Initial load
duke
parents:
diff changeset
   175
                                      + STRING_SIG
7f561c08de6b Initial load
duke
parents:
diff changeset
   176
                                      + STRING_SIG
7f561c08de6b Initial load
duke
parents:
diff changeset
   177
                                      + "I)V");
7f561c08de6b Initial load
duke
parents:
diff changeset
   178
        _uniqueAttribute = new INVOKEINTERFACE(uniqueAttribute, 4);
7f561c08de6b Initial load
duke
parents:
diff changeset
   179
7f561c08de6b Initial load
duke
parents:
diff changeset
   180
        final int namespace =
7f561c08de6b Initial load
duke
parents:
diff changeset
   181
            cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE,
7f561c08de6b Initial load
duke
parents:
diff changeset
   182
                                      "namespaceAfterStartElement",
7f561c08de6b Initial load
duke
parents:
diff changeset
   183
                                      "("
7f561c08de6b Initial load
duke
parents:
diff changeset
   184
                                      + STRING_SIG
7f561c08de6b Initial load
duke
parents:
diff changeset
   185
                                      + STRING_SIG
7f561c08de6b Initial load
duke
parents:
diff changeset
   186
                                      + ")V");
7f561c08de6b Initial load
duke
parents:
diff changeset
   187
        _namespace = new INVOKEINTERFACE(namespace, 3);
7f561c08de6b Initial load
duke
parents:
diff changeset
   188
7f561c08de6b Initial load
duke
parents:
diff changeset
   189
        int index = cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE,
7f561c08de6b Initial load
duke
parents:
diff changeset
   190
                                              "startDocument",
7f561c08de6b Initial load
duke
parents:
diff changeset
   191
                                              "()V");
7f561c08de6b Initial load
duke
parents:
diff changeset
   192
        _startDocument = new INVOKEINTERFACE(index, 1);
7f561c08de6b Initial load
duke
parents:
diff changeset
   193
7f561c08de6b Initial load
duke
parents:
diff changeset
   194
        index = cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE,
7f561c08de6b Initial load
duke
parents:
diff changeset
   195
                                          "endDocument",
7f561c08de6b Initial load
duke
parents:
diff changeset
   196
                                          "()V");
7f561c08de6b Initial load
duke
parents:
diff changeset
   197
        _endDocument = new INVOKEINTERFACE(index, 1);
7f561c08de6b Initial load
duke
parents:
diff changeset
   198
7f561c08de6b Initial load
duke
parents:
diff changeset
   199
7f561c08de6b Initial load
duke
parents:
diff changeset
   200
        index = cpg.addInterfaceMethodref(NODE_ITERATOR,
7f561c08de6b Initial load
duke
parents:
diff changeset
   201
                                          SET_START_NODE,
7f561c08de6b Initial load
duke
parents:
diff changeset
   202
                                          SET_START_NODE_SIG);
7f561c08de6b Initial load
duke
parents:
diff changeset
   203
        _setStartNode = new INVOKEINTERFACE(index, 2);
7f561c08de6b Initial load
duke
parents:
diff changeset
   204
7f561c08de6b Initial load
duke
parents:
diff changeset
   205
        index = cpg.addInterfaceMethodref(NODE_ITERATOR,
7f561c08de6b Initial load
duke
parents:
diff changeset
   206
                                          "reset", "()"+NODE_ITERATOR_SIG);
7f561c08de6b Initial load
duke
parents:
diff changeset
   207
        _reset = new INVOKEINTERFACE(index, 1);
7f561c08de6b Initial load
duke
parents:
diff changeset
   208
7f561c08de6b Initial load
duke
parents:
diff changeset
   209
        index = cpg.addInterfaceMethodref(NODE_ITERATOR, NEXT, NEXT_SIG);
7f561c08de6b Initial load
duke
parents:
diff changeset
   210
        _nextNode = new INVOKEINTERFACE(index, 1);
7f561c08de6b Initial load
duke
parents:
diff changeset
   211
7f561c08de6b Initial load
duke
parents:
diff changeset
   212
        _slotAllocator = new SlotAllocator();
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   213
        _slotAllocator.initialize(getLocalVariableRegistry().getLocals(false));
6
7f561c08de6b Initial load
duke
parents:
diff changeset
   214
        _allocatorInit = true;
7f561c08de6b Initial load
duke
parents:
diff changeset
   215
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   216
7f561c08de6b Initial load
duke
parents:
diff changeset
   217
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   218
     * Allocates a local variable. If the slot allocator has already been
7f561c08de6b Initial load
duke
parents:
diff changeset
   219
     * initialized, then call addLocalVariable2() so that the new variable
7f561c08de6b Initial load
duke
parents:
diff changeset
   220
     * is known to the allocator. Failing to do this may cause the allocator
7f561c08de6b Initial load
duke
parents:
diff changeset
   221
     * to return a slot that is already in use.
7f561c08de6b Initial load
duke
parents:
diff changeset
   222
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   223
    public LocalVariableGen addLocalVariable(String name, Type type,
7f561c08de6b Initial load
duke
parents:
diff changeset
   224
                                             InstructionHandle start,
7f561c08de6b Initial load
duke
parents:
diff changeset
   225
                                             InstructionHandle end)
7f561c08de6b Initial load
duke
parents:
diff changeset
   226
    {
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   227
        LocalVariableGen lvg;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   228
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   229
        if (_allocatorInit) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   230
            lvg = addLocalVariable2(name, type, start);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   231
        } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   232
            lvg = super.addLocalVariable(name, type, start, end);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   233
            getLocalVariableRegistry().registerLocalVariable(lvg);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   234
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   235
        return lvg;
6
7f561c08de6b Initial load
duke
parents:
diff changeset
   236
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   237
7f561c08de6b Initial load
duke
parents:
diff changeset
   238
    public LocalVariableGen addLocalVariable2(String name, Type type,
7f561c08de6b Initial load
duke
parents:
diff changeset
   239
                                              InstructionHandle start)
7f561c08de6b Initial load
duke
parents:
diff changeset
   240
    {
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   241
        LocalVariableGen lvg = super.addLocalVariable(name, type,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   242
                                              _slotAllocator.allocateSlot(type),
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   243
                                              start, null);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   244
        getLocalVariableRegistry().registerLocalVariable(lvg);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   245
        return lvg;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   246
    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   247
    private LocalVariableRegistry getLocalVariableRegistry() {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   248
        if (_localVariableRegistry == null) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   249
            _localVariableRegistry = new LocalVariableRegistry();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   250
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   251
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   252
        return _localVariableRegistry;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   253
    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   254
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   255
    /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   256
     * Keeps track of all local variables used in the method.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   257
     * <p>The
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   258
     * {@link MethodGen#addLocalVariable(String,Type,InstructionHandle,InstructionHandle)}</code>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   259
     * and
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   260
     * {@link MethodGen#addLocalVariable(String,Type,int,InstructionHandle,InstructionHandle)}</code>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   261
     * methods of {@link MethodGen} will only keep track of
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   262
     * {@link LocalVariableGen} object until it'ss removed by a call to
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   263
     * {@link MethodGen#removeLocalVariable(LocalVariableGen)}.</p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   264
     * <p>In order to support efficient copying of local variables to outlined
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   265
     * methods by
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   266
     * {@link #outline(InstructionHandle,InstructionHandle,String,ClassGenerator)},
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   267
     * this class keeps track of all local variables defined by the method.</p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   268
     */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   269
    protected class LocalVariableRegistry {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   270
        /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   271
         * <p>A <code>java.lang.ArrayList</code> of all
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   272
         * {@link LocalVariableGen}s created for this method, indexed by the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   273
         * slot number of the local variable.  The JVM stack frame of local
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   274
         * variables is divided into "slots".  A single slot can be used to
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   275
         * store more than one variable in a method, without regard to type, so
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   276
         * long as the byte code keeps the ranges of the two disjoint.</p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   277
         * <p>If only one registration of use of a particular slot occurs, the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   278
         * corresponding entry of <code>_variables</code> contains the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   279
         * <code>LocalVariableGen</code>; if more than one occurs, the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   280
         * corresponding entry contains all such <code>LocalVariableGen</code>s
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   281
         * registered for the same slot; and if none occurs, the entry will be
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   282
         * <code>null</code>.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   283
         */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   284
        protected ArrayList _variables = new ArrayList();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   285
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   286
        /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   287
         * Maps a name to a {@link LocalVariableGen}
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   288
         */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   289
        protected HashMap _nameToLVGMap = new HashMap();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   290
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   291
        /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   292
         * Registers a {@link org.apache.bcel.generic.LocalVariableGen}
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   293
         * for this method.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   294
         * <p><b>Preconditions:</b>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   295
         * <ul>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   296
         * <li>The range of instructions for <code>lvg</code> does not
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   297
         * overlap with the range of instructions for any
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   298
         * <code>LocalVariableGen</code> with the same slot index previously
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   299
         * registered for this method.  <b><em>(Unchecked.)</em></b></li>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   300
         * </ul></p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   301
         * @param lvg The variable to be registered
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   302
         */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   303
        protected void registerLocalVariable(LocalVariableGen lvg) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   304
            int slot = lvg.getIndex();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   305
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   306
            int registrySize = _variables.size();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   307
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   308
            // If the LocalVariableGen uses a slot index beyond any previously
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   309
            // encountered, expand the _variables, padding with intervening null
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   310
            // entries as required.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   311
            if (slot >= registrySize) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   312
                for (int i = registrySize; i < slot; i++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   313
                    _variables.add(null);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   314
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   315
                _variables.add(lvg);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   316
            } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   317
                // If the LocalVariableGen reuses a slot, make sure the entry
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   318
                // in _variables contains an ArrayList and add the newly
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   319
                // registered LocalVariableGen to the list.  If the entry in
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   320
                // _variables just contains null padding, store the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   321
                // LocalVariableGen directly.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   322
                Object localsInSlot = _variables.get(slot);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   323
                if (localsInSlot != null) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   324
                    if (localsInSlot instanceof LocalVariableGen) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   325
                        ArrayList listOfLocalsInSlot = new ArrayList();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   326
                        listOfLocalsInSlot.add(localsInSlot);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   327
                        listOfLocalsInSlot.add(lvg);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   328
                        _variables.set(slot, listOfLocalsInSlot);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   329
                    } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   330
                        ((ArrayList) localsInSlot).add(lvg);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   331
                    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   332
                } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   333
                    _variables.set(slot, lvg);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   334
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   335
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   336
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   337
            registerByName(lvg);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   338
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   339
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   340
        /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   341
         * <p>Find which {@link LocalVariableGen}, if any, is registered for a
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   342
         * particular JVM local stack frame slot at a particular position in the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   343
         * byte code for the method.</p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   344
         * <p><b>Preconditions:</b>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   345
         * <ul>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   346
         * <li>The {@link InstructionList#setPositions()} has been called for
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   347
         * the {@link InstructionList} associated with this
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   348
         * {@link MethodGenerator}.</li>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   349
         * </ul></p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   350
         * @param slot the JVM local stack frame slot number
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   351
         * @param offset the position in the byte code
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   352
         * @return the <code>LocalVariableGen</code> for the local variable
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   353
         * stored in the relevant slot at the relevant offset; <code>null</code>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   354
         * if there is none.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   355
         */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   356
        protected LocalVariableGen lookupRegisteredLocalVariable(int slot,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   357
                                                                 int offset) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   358
            Object localsInSlot = (_variables != null) ? _variables.get(slot)
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   359
                                                       : null;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   360
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   361
            // If this slot index was never used, _variables.get will return
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   362
            // null; if it was used once, it will return the LocalVariableGen;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   363
            // more than once it will return an ArrayList of all the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   364
            // LocalVariableGens for variables stored in that slot.  For each
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   365
            // LocalVariableGen, check whether its range includes the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   366
            // specified offset, and return the first such encountered.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   367
            if (localsInSlot != null) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   368
                if (localsInSlot instanceof LocalVariableGen) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   369
                    LocalVariableGen lvg = (LocalVariableGen)localsInSlot;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   370
                    if (offsetInLocalVariableGenRange(lvg, offset)) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   371
                        return lvg;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   372
                    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   373
                } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   374
                    ArrayList listOfLocalsInSlot = (ArrayList) localsInSlot;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   375
                    int size = listOfLocalsInSlot.size();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   376
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   377
                    for (int i = 0; i < size; i++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   378
                        LocalVariableGen lvg =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   379
                            (LocalVariableGen)listOfLocalsInSlot.get(i);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   380
                        if (offsetInLocalVariableGenRange(lvg, offset)) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   381
                            return lvg;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   382
                        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   383
                    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   384
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   385
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   386
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   387
            // No local variable stored in the specified slot at the specified
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   388
            return null;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   389
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   390
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   391
        /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   392
         * <p>Set up a mapping of the name of the specified
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   393
         * {@link LocalVariableGen} object to the <code>LocalVariableGen</code>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   394
         * itself.</p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   395
         * <p>This is a bit of a hack.  XSLTC is relying on the fact that the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   396
         * name that is being looked up won't be duplicated, which isn't
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   397
         * guaranteed.  It replaces code which used to call
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   398
         * {@link MethodGen#getLocalVariables()} and looped through the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   399
         * <code>LocalVariableGen</code> objects it contained to find the one
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   400
         * with the specified name.  However, <code>getLocalVariables()</code>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   401
         * has the side effect of setting the start and end for any
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   402
         * <code>LocalVariableGen</code> which did not already have them
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   403
         * set, which causes problems for outlining..</p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   404
         * <p>See also {@link #lookUpByName(String)} and
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   405
         * {@link #removeByNameTracking(LocalVariableGen)}</P
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   406
         * @param lvg a <code>LocalVariableGen</code>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   407
         */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   408
        protected void registerByName(LocalVariableGen lvg) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   409
            Object duplicateNameEntry = _nameToLVGMap.get(lvg.getName());
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   410
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   411
            if (duplicateNameEntry == null) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   412
                _nameToLVGMap.put(lvg.getName(), lvg);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   413
            } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   414
                ArrayList sameNameList;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   415
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   416
                if (duplicateNameEntry instanceof ArrayList) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   417
                    sameNameList = (ArrayList) duplicateNameEntry;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   418
                    sameNameList.add(lvg);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   419
                } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   420
                    sameNameList = new ArrayList();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   421
                    sameNameList.add(duplicateNameEntry);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   422
                    sameNameList.add(lvg);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   423
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   424
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   425
                _nameToLVGMap.put(lvg.getName(), sameNameList);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   426
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   427
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   428
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   429
        /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   430
         * Remove the mapping from the name of the specified
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   431
         * {@link LocalVariableGen} to itself.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   432
         * See also {@link #registerByName(LocalVariableGen)} and
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   433
         * {@link #lookUpByName(String)}
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   434
         * @param lvg a <code>LocalVariableGen</code>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   435
         */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   436
        protected void removeByNameTracking(LocalVariableGen lvg) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   437
            Object duplicateNameEntry = _nameToLVGMap.get(lvg.getName());
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   438
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   439
            if (duplicateNameEntry instanceof ArrayList) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   440
                ArrayList sameNameList = (ArrayList) duplicateNameEntry;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   441
                for (int i = 0; i < sameNameList.size(); i++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   442
                    if (sameNameList.get(i) == lvg) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   443
                        sameNameList.remove(i);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   444
                        break;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   445
                    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   446
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   447
            } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   448
                _nameToLVGMap.remove(lvg);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   449
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   450
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   451
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   452
        /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   453
         * <p>Given the name of a variable, finds a {@link LocalVariableGen}
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   454
         * corresponding to it.</p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   455
         * <p>See also {@link #registerByName(LocalVariableGen)} and
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   456
         * {@link #removeByNameTracking(LocalVariableGen)}</p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   457
         * @param name
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   458
         * @return
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   459
         */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   460
        protected LocalVariableGen lookUpByName(String name) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   461
            LocalVariableGen lvg = null;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   462
            Object duplicateNameEntry = _nameToLVGMap.get(name);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   463
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   464
            if (duplicateNameEntry instanceof ArrayList) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   465
                ArrayList sameNameList = (ArrayList) duplicateNameEntry;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   466
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   467
                for (int i = 0; i < sameNameList.size(); i++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   468
                    lvg = (LocalVariableGen)sameNameList.get(i);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   469
                    if (lvg.getName() == name) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   470
                        break;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   471
                    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   472
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   473
            } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   474
                lvg = (LocalVariableGen) duplicateNameEntry;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   475
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   476
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   477
            return lvg;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   478
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   479
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   480
        /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   481
         * <p>Gets all {@link LocalVariableGen} objects for this method.</p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   482
         * <p>When the <code>includeRemoved</code> argument has the value
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   483
         * <code>false</code>, this method replaces uses of
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   484
         * {@link MethodGen#getLocalVariables()} which has
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   485
         * a side-effect of setting the start and end range for any
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   486
         * <code>LocalVariableGen</code> if either was <code>null</code>.  That
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   487
         * side-effect causes problems for outlining of code in XSLTC.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   488
         * @param includeRemoved Specifies whether all local variables ever
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   489
         * declared should be returned (<code>true</code>) or only those not
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   490
         * removed (<code>false</code>)
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   491
         * @return an array of <code>LocalVariableGen</code> containing all the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   492
         * local variables
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   493
         */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   494
        protected LocalVariableGen[] getLocals(boolean includeRemoved) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   495
            LocalVariableGen[] locals = null;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   496
            ArrayList allVarsEverDeclared = new ArrayList();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   497
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   498
            if (includeRemoved) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   499
                int slotCount = allVarsEverDeclared.size();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   500
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   501
                for (int i = 0; i < slotCount; i++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   502
                    Object slotEntries = _variables.get(i);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   503
                    if (slotEntries != null) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   504
                        if (slotEntries instanceof ArrayList) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   505
                            ArrayList slotList = (ArrayList) slotEntries;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   506
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   507
                            for (int j = 0; j < slotList.size(); j++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   508
                                allVarsEverDeclared.add(slotList.get(i));
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   509
                            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   510
                        } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   511
                            allVarsEverDeclared.add(slotEntries);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   512
                        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   513
                    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   514
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   515
            } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   516
                Iterator nameVarsPairsIter = _nameToLVGMap.entrySet().iterator();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   517
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   518
                while (nameVarsPairsIter.hasNext()) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   519
                    Map.Entry nameVarsPair =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   520
                                  (Map.Entry) nameVarsPairsIter.next();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   521
                    Object vars = nameVarsPair.getValue();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   522
                    if (vars != null) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   523
                        if (vars instanceof ArrayList) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   524
                            ArrayList varsList = (ArrayList) vars;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   525
                            for (int i = 0; i < varsList.size(); i++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   526
                                allVarsEverDeclared.add(varsList.get(i));
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   527
                            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   528
                        } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   529
                            allVarsEverDeclared.add(vars);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   530
                        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   531
                    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   532
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   533
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   534
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   535
            locals = new LocalVariableGen[allVarsEverDeclared.size()];
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   536
            allVarsEverDeclared.toArray(locals);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   537
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   538
            return locals;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   539
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   540
    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   541
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   542
    /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   543
     * Determines whether a particular variable is in use at a particular offset
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   544
     * in the byte code for this method.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   545
     * <p><b>Preconditions:</b>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   546
     * <ul>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   547
     * <li>The {@link InstructionList#setPositions()} has been called for the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   548
     * {@link InstructionList} associated with this {@link MethodGenerator}.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   549
     * </li></ul></p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   550
     * @param lvg the {@link LocalVariableGen} for the variable
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   551
     * @param offset the position in the byte code
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   552
     * @return <code>true</code> if and only if the specified variable is in
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   553
     * use at the particular byte code offset.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   554
     */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   555
    boolean offsetInLocalVariableGenRange(LocalVariableGen lvg, int offset) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   556
        InstructionHandle lvgStart = lvg.getStart();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   557
        InstructionHandle lvgEnd = lvg.getEnd();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   558
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   559
        // If no start handle is recorded for the LocalVariableGen, it is
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   560
        // assumed to be in use from the beginning of the method.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   561
        if (lvgStart == null) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   562
            lvgStart = getInstructionList().getStart();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   563
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   564
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   565
        // If no end handle is recorded for the LocalVariableGen, it is assumed
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   566
        // to be in use to the end of the method.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   567
        if (lvgEnd == null) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   568
            lvgEnd = getInstructionList().getEnd();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   569
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   570
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   571
        // Does the range of the instruction include the specified offset?
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   572
        // Note that the InstructionHandle.getPosition method returns the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   573
        // offset of the beginning of an instruction.  A LocalVariableGen's
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   574
        // range includes the end instruction itself, so that instruction's
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   575
        // length must be taken into consideration in computing whether the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   576
        // varible is in range at a particular offset.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   577
        return ((lvgStart.getPosition() <= offset)
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   578
                    && (lvgEnd.getPosition()
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   579
                            + lvgEnd.getInstruction().getLength() >= offset));
6
7f561c08de6b Initial load
duke
parents:
diff changeset
   580
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   581
7f561c08de6b Initial load
duke
parents:
diff changeset
   582
    public void removeLocalVariable(LocalVariableGen lvg) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   583
        _slotAllocator.releaseSlot(lvg);
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   584
        getLocalVariableRegistry().removeByNameTracking(lvg);
6
7f561c08de6b Initial load
duke
parents:
diff changeset
   585
        super.removeLocalVariable(lvg);
7f561c08de6b Initial load
duke
parents:
diff changeset
   586
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   587
7f561c08de6b Initial load
duke
parents:
diff changeset
   588
    public Instruction loadDOM() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   589
        return _aloadDom;
7f561c08de6b Initial load
duke
parents:
diff changeset
   590
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   591
7f561c08de6b Initial load
duke
parents:
diff changeset
   592
    public Instruction storeDOM() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   593
        return _astoreDom;
7f561c08de6b Initial load
duke
parents:
diff changeset
   594
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   595
7f561c08de6b Initial load
duke
parents:
diff changeset
   596
    public Instruction storeHandler() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   597
        return _astoreHandler;
7f561c08de6b Initial load
duke
parents:
diff changeset
   598
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   599
7f561c08de6b Initial load
duke
parents:
diff changeset
   600
    public Instruction loadHandler() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   601
        return _aloadHandler;
7f561c08de6b Initial load
duke
parents:
diff changeset
   602
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   603
7f561c08de6b Initial load
duke
parents:
diff changeset
   604
    public Instruction storeIterator() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   605
        return _astoreIterator;
7f561c08de6b Initial load
duke
parents:
diff changeset
   606
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   607
7f561c08de6b Initial load
duke
parents:
diff changeset
   608
    public Instruction loadIterator() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   609
        return _aloadIterator;
7f561c08de6b Initial load
duke
parents:
diff changeset
   610
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   611
7f561c08de6b Initial load
duke
parents:
diff changeset
   612
    public final Instruction setStartNode() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   613
        return _setStartNode;
7f561c08de6b Initial load
duke
parents:
diff changeset
   614
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   615
7f561c08de6b Initial load
duke
parents:
diff changeset
   616
    public final Instruction reset() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   617
        return _reset;
7f561c08de6b Initial load
duke
parents:
diff changeset
   618
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   619
7f561c08de6b Initial load
duke
parents:
diff changeset
   620
    public final Instruction nextNode() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   621
        return _nextNode;
7f561c08de6b Initial load
duke
parents:
diff changeset
   622
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   623
7f561c08de6b Initial load
duke
parents:
diff changeset
   624
    public final Instruction startElement() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   625
        return _startElement;
7f561c08de6b Initial load
duke
parents:
diff changeset
   626
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   627
7f561c08de6b Initial load
duke
parents:
diff changeset
   628
    public final Instruction endElement() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   629
        return _endElement;
7f561c08de6b Initial load
duke
parents:
diff changeset
   630
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   631
7f561c08de6b Initial load
duke
parents:
diff changeset
   632
    public final Instruction startDocument() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   633
        return _startDocument;
7f561c08de6b Initial load
duke
parents:
diff changeset
   634
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   635
7f561c08de6b Initial load
duke
parents:
diff changeset
   636
    public final Instruction endDocument() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   637
        return _endDocument;
7f561c08de6b Initial load
duke
parents:
diff changeset
   638
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   639
7f561c08de6b Initial load
duke
parents:
diff changeset
   640
    public final Instruction attribute() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   641
        return _attribute;
7f561c08de6b Initial load
duke
parents:
diff changeset
   642
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   643
7f561c08de6b Initial load
duke
parents:
diff changeset
   644
    public final Instruction uniqueAttribute() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   645
        return _uniqueAttribute;
7f561c08de6b Initial load
duke
parents:
diff changeset
   646
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   647
7f561c08de6b Initial load
duke
parents:
diff changeset
   648
    public final Instruction namespace() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   649
        return _namespace;
7f561c08de6b Initial load
duke
parents:
diff changeset
   650
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   651
7f561c08de6b Initial load
duke
parents:
diff changeset
   652
    public Instruction loadCurrentNode() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   653
        if (_iloadCurrent == null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   654
            int idx = getLocalIndex("current");
7f561c08de6b Initial load
duke
parents:
diff changeset
   655
            if (idx > 0)
7f561c08de6b Initial load
duke
parents:
diff changeset
   656
                _iloadCurrent = new ILOAD(idx);
7f561c08de6b Initial load
duke
parents:
diff changeset
   657
            else
7f561c08de6b Initial load
duke
parents:
diff changeset
   658
                _iloadCurrent = new ICONST(0);
7f561c08de6b Initial load
duke
parents:
diff changeset
   659
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   660
        return _iloadCurrent;
7f561c08de6b Initial load
duke
parents:
diff changeset
   661
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   662
7f561c08de6b Initial load
duke
parents:
diff changeset
   663
    public Instruction storeCurrentNode() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   664
        return _istoreCurrent != null
7f561c08de6b Initial load
duke
parents:
diff changeset
   665
            ? _istoreCurrent
7f561c08de6b Initial load
duke
parents:
diff changeset
   666
            : (_istoreCurrent = new ISTORE(getLocalIndex("current")));
7f561c08de6b Initial load
duke
parents:
diff changeset
   667
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   668
7f561c08de6b Initial load
duke
parents:
diff changeset
   669
    /** by default context node is the same as current node. MK437 */
7f561c08de6b Initial load
duke
parents:
diff changeset
   670
    public Instruction loadContextNode() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   671
        return loadCurrentNode();
7f561c08de6b Initial load
duke
parents:
diff changeset
   672
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   673
7f561c08de6b Initial load
duke
parents:
diff changeset
   674
    public Instruction storeContextNode() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   675
        return storeCurrentNode();
7f561c08de6b Initial load
duke
parents:
diff changeset
   676
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   677
7f561c08de6b Initial load
duke
parents:
diff changeset
   678
    public int getLocalIndex(String name) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   679
        return getLocalVariable(name).getIndex();
7f561c08de6b Initial load
duke
parents:
diff changeset
   680
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   681
7f561c08de6b Initial load
duke
parents:
diff changeset
   682
    public LocalVariableGen getLocalVariable(String name) {
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   683
        return getLocalVariableRegistry().lookUpByName(name);
6
7f561c08de6b Initial load
duke
parents:
diff changeset
   684
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   685
7f561c08de6b Initial load
duke
parents:
diff changeset
   686
    public void setMaxLocals() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   687
7f561c08de6b Initial load
duke
parents:
diff changeset
   688
        // Get the current number of local variable slots
7f561c08de6b Initial load
duke
parents:
diff changeset
   689
        int maxLocals = super.getMaxLocals();
7f561c08de6b Initial load
duke
parents:
diff changeset
   690
        int prevLocals = maxLocals;
7f561c08de6b Initial load
duke
parents:
diff changeset
   691
7f561c08de6b Initial load
duke
parents:
diff changeset
   692
        // Get numer of actual variables
7f561c08de6b Initial load
duke
parents:
diff changeset
   693
        final LocalVariableGen[] localVars = super.getLocalVariables();
7f561c08de6b Initial load
duke
parents:
diff changeset
   694
        if (localVars != null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   695
            if (localVars.length > maxLocals)
7f561c08de6b Initial load
duke
parents:
diff changeset
   696
                maxLocals = localVars.length;
7f561c08de6b Initial load
duke
parents:
diff changeset
   697
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   698
7f561c08de6b Initial load
duke
parents:
diff changeset
   699
        // We want at least 5 local variable slots (for parameters)
7f561c08de6b Initial load
duke
parents:
diff changeset
   700
        if (maxLocals < 5) maxLocals = 5;
7f561c08de6b Initial load
duke
parents:
diff changeset
   701
7f561c08de6b Initial load
duke
parents:
diff changeset
   702
        super.setMaxLocals(maxLocals);
7f561c08de6b Initial load
duke
parents:
diff changeset
   703
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   704
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   705
    /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   706
     * Add a pre-compiled pattern to this mode.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   707
     */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   708
    public void addInstructionList(Pattern pattern, InstructionList ilist) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   709
        _preCompiled.put(pattern, ilist);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   710
    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   711
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   712
    /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   713
     * Get the instruction list for a pre-compiled pattern. Used by
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   714
     * test sequences to avoid compiling patterns more than once.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   715
     */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   716
    public InstructionList getInstructionList(Pattern pattern) {
33349
975138b77cff 8068842: Better JAXP data handling
joehw
parents: 25868
diff changeset
   717
        return _preCompiled.get(pattern);
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   718
    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   719
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   720
    /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   721
     * Used to keep track of an outlineable chunk of instructions in the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   722
     * current method.  See {@link OutlineableChunkStart} and
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   723
     * {@link OutlineableChunkEnd} for more information.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   724
     */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   725
    private class Chunk implements Comparable {
6
7f561c08de6b Initial load
duke
parents:
diff changeset
   726
        /**
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   727
         * {@link InstructionHandle} of the first instruction in the outlineable
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   728
         * chunk.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   729
         */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   730
        private InstructionHandle m_start;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   731
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   732
        /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   733
         * {@link org.apache.bcel.generic.InstructionHandle} of the first
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   734
         * instruction in the outlineable chunk.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   735
         */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   736
        private InstructionHandle m_end;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   737
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   738
        /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   739
         * Number of bytes in the instructions contained in this outlineable
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   740
         * chunk.
6
7f561c08de6b Initial load
duke
parents:
diff changeset
   741
         */
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   742
        private int m_size;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   743
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   744
        /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   745
         * <p>Constructor for an outlineable {@link MethodGenerator.Chunk}.</p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   746
         * <p><b>Preconditions:</b>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   747
         * <ul>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   748
         * <li>The {@link InstructionList#setPositions()} has been called for
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   749
         * the {@link InstructionList} associated with this
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   750
         * {@link MethodGenerator}.</li>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   751
         * </ul></p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   752
         * @param start The {@link InstructionHandle} of the first
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   753
         *              instruction in the outlineable chunk.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   754
         * @param end The {@link InstructionHandle} of the last
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   755
         *            instruction in the outlineable chunk.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   756
         */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   757
        Chunk(InstructionHandle start, InstructionHandle end) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   758
            m_start = start;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   759
            m_end = end;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   760
            m_size = end.getPosition() - start.getPosition();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   761
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   762
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   763
        /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   764
         * Determines whether this outlineable {@link MethodGenerator.Chunk} is
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   765
         * followed immediately by the argument
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   766
         * <code>MethodGenerator.Chunk</code>, with no other intervening
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   767
         * instructions, including {@link OutlineableChunkStart} or
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   768
         * {@link OutlineableChunkEnd} instructions.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   769
         * @param neighbour an outlineable {@link MethodGenerator.Chunk}
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   770
         * @return <code>true</code> if and only if the argument chunk
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   771
         * immediately follows <code>this</code> chunk
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   772
         */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   773
        boolean isAdjacentTo(Chunk neighbour) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   774
            return getChunkEnd().getNext() == neighbour.getChunkStart();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   775
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   776
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   777
        /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   778
         * Getter method for the start of this {@linke MethodGenerator.Chunk}
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   779
         * @return the {@link org.apache.bcel.generic.InstructionHandle} of the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   780
         * start of this chunk
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   781
         */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   782
        InstructionHandle getChunkStart() {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   783
            return m_start;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   784
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   785
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   786
        /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   787
         * Getter method for the end of this {@link MethodGenerator.Chunk}
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   788
         * @return the {@link InstructionHandle} of the start of this chunk
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   789
         */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   790
        InstructionHandle getChunkEnd() {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   791
            return m_end;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   792
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   793
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   794
        /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   795
         * The size of this {@link MethodGenerator.Chunk}
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   796
         * @return the number of bytes in the byte code represented by this
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   797
         *         chunk.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   798
         */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   799
        int getChunkSize() {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   800
            return m_size;
6
7f561c08de6b Initial load
duke
parents:
diff changeset
   801
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   802
7f561c08de6b Initial load
duke
parents:
diff changeset
   803
        /**
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   804
         * Implements the <code>java.util.Comparable.compareTo(Object)</code>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   805
         * method.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   806
         * @return
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   807
         * <ul>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   808
         * <li>A positive <code>int</code> if the length of <code>this</code>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   809
         * chunk in bytes is greater than that of <code>comparand</code></li>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   810
         * <li>A negative <code>int</code> if the length of <code>this</code>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   811
         * chunk in bytes is less than that of <code>comparand</code></li>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   812
         * <li>Zero, otherwise.</li>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   813
         * </ul>
6
7f561c08de6b Initial load
duke
parents:
diff changeset
   814
         */
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   815
        public int compareTo(Object comparand) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   816
            return getChunkSize() - ((Chunk)comparand).getChunkSize();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   817
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   818
    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   819
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   820
    /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   821
     * Find the outlineable chunks in this method that would be the best choices
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   822
     * to outline, based on size and position in the method.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   823
     * @param classGen The {@link ClassGen} with which the generated methods
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   824
     *                 will be associated
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   825
     * @param totalMethodSize the size of the bytecode in the original method
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   826
     * @return a <code>java.util.ArrayList</code> containing the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   827
     *  {@link MethodGenerator.Chunk}s that may be outlined from this method
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   828
     */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   829
    private ArrayList getCandidateChunks(ClassGenerator classGen,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   830
                                         int totalMethodSize) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   831
        Iterator instructions = getInstructionList().iterator();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   832
        ArrayList candidateChunks = new ArrayList();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   833
        ArrayList currLevelChunks = new ArrayList();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   834
        Stack subChunkStack = new Stack();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   835
        boolean openChunkAtCurrLevel = false;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   836
        boolean firstInstruction = true;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   837
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   838
        InstructionHandle currentHandle;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   839
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   840
        if (m_openChunks != 0) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   841
            String msg =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   842
                (new ErrorMsg(ErrorMsg.OUTLINE_ERR_UNBALANCED_MARKERS))
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   843
                    .toString();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   844
            throw new InternalError(msg);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   845
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   846
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   847
        // Scan instructions in the method, keeping track of the nesting level
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   848
        // of outlineable chunks.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   849
        //
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   850
        // currLevelChunks
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   851
        //     keeps track of the child chunks of a chunk.  For each chunk,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   852
        //     there will be a pair of entries:  the InstructionHandles for the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   853
        //     start and for the end of the chunk
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   854
        // subChunkStack
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   855
        //     a stack containing the partially accumulated currLevelChunks for
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   856
        //     each chunk that's still open at the current position in the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   857
        //     InstructionList.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   858
        // candidateChunks
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   859
        //     the list of chunks which have been accepted as candidates chunks
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   860
        //     for outlining
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   861
        do {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   862
            // Get the next instruction.  The loop will perform one extra
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   863
            // iteration after it reaches the end of the InstructionList, with
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   864
            // currentHandle set to null.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   865
            currentHandle = instructions.hasNext()
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   866
                                    ? (InstructionHandle) instructions.next()
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   867
                                    : null;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   868
            Instruction inst =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   869
                    (currentHandle != null) ? currentHandle.getInstruction()
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   870
                                            : null;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   871
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   872
            // At the first iteration, create a chunk representing all the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   873
            // code in the method.  This is done just to simplify the logic -
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   874
            // this chunk can never be outlined because it will be too big.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   875
            if (firstInstruction) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   876
                openChunkAtCurrLevel = true;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   877
                currLevelChunks.add(currentHandle);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   878
                firstInstruction = false;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   879
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   880
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   881
            // Found a new chunk
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   882
            if (inst instanceof OutlineableChunkStart) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   883
                // If last MarkerInstruction encountered was an
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   884
                // OutlineableChunkStart, this represents the first chunk
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   885
                // nested within that previous chunk - push the list of chunks
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   886
                // from the outer level onto the stack
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   887
                if (openChunkAtCurrLevel) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   888
                    subChunkStack.push(currLevelChunks);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   889
                    currLevelChunks = new ArrayList();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   890
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   891
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   892
                openChunkAtCurrLevel = true;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   893
                currLevelChunks.add(currentHandle);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   894
            // Close off an open chunk
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   895
            } else if (currentHandle == null
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   896
                           || inst instanceof OutlineableChunkEnd) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   897
                ArrayList nestedSubChunks = null;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   898
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   899
                // If the last MarkerInstruction encountered was an
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   900
                // OutlineableChunkEnd, it means that the current instruction
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   901
                // marks the end of a chunk that contained child chunks.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   902
                // Those children might need to be examined below in case they
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   903
                // are better candidates for outlining than the current chunk.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   904
                if (!openChunkAtCurrLevel) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   905
                    nestedSubChunks = currLevelChunks;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   906
                    currLevelChunks = (ArrayList)subChunkStack.pop();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   907
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   908
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   909
                // Get the handle for the start of this chunk (the last entry
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   910
                // in currLevelChunks)
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   911
                InstructionHandle chunkStart =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   912
                        (InstructionHandle) currLevelChunks.get(
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   913
                                                      currLevelChunks.size()-1);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   914
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   915
                int chunkEndPosition =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   916
                        (currentHandle != null) ? currentHandle.getPosition()
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   917
                                                : totalMethodSize;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   918
                int chunkSize = chunkEndPosition - chunkStart.getPosition();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   919
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   920
                // Two ranges of chunk size to consider:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   921
                //
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   922
                // 1. [0,TARGET_METHOD_SIZE]
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   923
                //      Keep this chunk in consideration as a candidate,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   924
                //      and ignore its subchunks, if any - there's nothing to be
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   925
                //      gained by outlining both the current chunk and its
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   926
                //      children!
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   927
                //
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   928
                // 2. (TARGET_METHOD_SIZE,+infinity)
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   929
                //      Ignore this chunk - it's too big.  Add its subchunks
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   930
                //      as candidates, after merging adjacent chunks to produce
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   931
                //      chunks that are as large as possible
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   932
                if (chunkSize <= TARGET_METHOD_SIZE) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   933
                    currLevelChunks.add(currentHandle);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   934
                } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   935
                    if (!openChunkAtCurrLevel) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   936
                        int childChunkCount = nestedSubChunks.size() / 2;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   937
                        if (childChunkCount > 0) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   938
                            Chunk[] childChunks = new Chunk[childChunkCount];
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   939
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   940
                            // Gather all the child chunks of the current chunk
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   941
                            for (int i = 0; i < childChunkCount; i++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   942
                                InstructionHandle start =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   943
                                    (InstructionHandle) nestedSubChunks
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   944
                                                            .get(i*2);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   945
                                InstructionHandle end =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   946
                                    (InstructionHandle) nestedSubChunks
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   947
                                                            .get(i*2+1);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   948
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   949
                                childChunks[i] = new Chunk(start, end);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   950
                            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   951
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   952
                            // Merge adjacent siblings
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   953
                            ArrayList mergedChildChunks =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   954
                                        mergeAdjacentChunks(childChunks);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   955
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   956
                            // Add chunks that mean minimum size requirements
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   957
                            // to the list of candidate chunks for outlining
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   958
                            for (int i = 0; i < mergedChildChunks.size(); i++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   959
                                Chunk mergedChunk =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   960
                                    (Chunk)mergedChildChunks.get(i);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   961
                                int mergedSize = mergedChunk.getChunkSize();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   962
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   963
                                if (mergedSize >= MINIMUM_OUTLINEABLE_CHUNK_SIZE
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   964
                                        && mergedSize <= TARGET_METHOD_SIZE) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   965
                                    candidateChunks.add(mergedChunk);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   966
                                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   967
                            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   968
                        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   969
                    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   970
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   971
                    // Drop the chunk which was too big
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   972
                    currLevelChunks.remove(currLevelChunks.size() - 1);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   973
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   974
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   975
                // currLevelChunks contains pairs of InstructionHandles.  If
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   976
                // its size is an odd number, the loop has encountered the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   977
                // start of a chunk at this level, but not its end.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   978
                openChunkAtCurrLevel = ((currLevelChunks.size() & 0x1) == 1);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   979
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   980
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   981
        } while (currentHandle != null);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   982
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   983
        return candidateChunks;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   984
    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   985
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   986
    /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   987
     * Merge adjacent sibling chunks to produce larger candidate chunks for
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   988
     * outlining
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   989
     * @param chunks array of sibling {@link MethodGenerator.Chunk}s that are
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   990
     *               under consideration for outlining.  Chunks must be in
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   991
     *               the order encountered in the {@link InstructionList}
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   992
     * @return a <code>java.util.ArrayList</code> of
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   993
     *         <code>MethodGenerator.Chunk</code>s maximally merged
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   994
     */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   995
    private ArrayList mergeAdjacentChunks(Chunk[] chunks) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   996
        int[] adjacencyRunStart = new int[chunks.length];
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   997
        int[] adjacencyRunLength = new int[chunks.length];
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   998
        boolean[] chunkWasMerged = new boolean[chunks.length];
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
   999
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1000
        int maximumRunOfChunks = 0;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1001
        int startOfCurrentRun;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1002
        int numAdjacentRuns = 0;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1003
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1004
        ArrayList mergedChunks = new ArrayList();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1005
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1006
        startOfCurrentRun = 0;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1007
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1008
        // Loop through chunks, and record in adjacencyRunStart where each
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1009
        // run of adjacent chunks begins and how many are in that run.  For
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1010
        // example, given chunks A B C D E F, if A is adjacent to B, but not
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1011
        // to C, and C, D, E and F are all adjacent,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1012
        //   adjacencyRunStart[0] == 0; adjacencyRunLength[0] == 2
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1013
        //   adjacencyRunStart[1] == 2; adjacencyRunLength[1] == 4
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1014
        for (int i = 1; i < chunks.length; i++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1015
            if (!chunks[i-1].isAdjacentTo(chunks[i])) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1016
                int lengthOfRun = i - startOfCurrentRun;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1017
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1018
                // Track the longest run of chunks found
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1019
                if (maximumRunOfChunks < lengthOfRun) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1020
                    maximumRunOfChunks = lengthOfRun;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1021
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1022
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1023
                if (lengthOfRun > 1 ) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1024
                    adjacencyRunLength[numAdjacentRuns] = lengthOfRun;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1025
                    adjacencyRunStart[numAdjacentRuns] = startOfCurrentRun;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1026
                    numAdjacentRuns++;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1027
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1028
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1029
                startOfCurrentRun = i;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1030
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1031
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1032
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1033
        if (chunks.length - startOfCurrentRun > 1) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1034
            int lengthOfRun = chunks.length - startOfCurrentRun;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1035
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1036
            // Track the longest run of chunks found
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1037
            if (maximumRunOfChunks < lengthOfRun) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1038
                maximumRunOfChunks = lengthOfRun;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1039
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1040
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1041
            adjacencyRunLength[numAdjacentRuns] =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1042
                        chunks.length - startOfCurrentRun;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1043
            adjacencyRunStart[numAdjacentRuns] = startOfCurrentRun;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1044
            numAdjacentRuns++;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1045
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1046
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1047
        // Try merging adjacent chunks to come up with better sized chunks for
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1048
        // outlining.  This algorithm is not optimal, but it should be
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1049
        // reasonably fast.  Consider an example like this, where four chunks
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1050
        // of the sizes specified in brackets are adjacent.  The best way of
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1051
        // combining these chunks would be to merge the first pair and merge
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1052
        // the last three to form two chunks, but the algorithm will merge the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1053
        // three in the middle instead, leaving three chunks in all.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1054
        //    [25000] [25000] [20000] [1000] [20000]
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1055
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1056
        // Start by trying to merge the maximum number of adjacent chunks, and
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1057
        // work down from there.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1058
        for (int numToMerge = maximumRunOfChunks; numToMerge>1; numToMerge--) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1059
            // Look at each run of adjacent chunks
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1060
            for (int run = 0; run < numAdjacentRuns; run++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1061
                int runStart = adjacencyRunStart[run];
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1062
                int runEnd = runStart + adjacencyRunLength[run] - 1;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1063
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1064
                boolean foundChunksToMerge = false;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1065
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1066
                // Within the current run of adjacent chunks, look at all
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1067
                // "subruns" of length numToMerge, until we run out or find
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1068
                // a subrun that can be merged.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1069
                for (int mergeStart = runStart;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1070
                     mergeStart+numToMerge-1 <= runEnd && !foundChunksToMerge;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1071
                     mergeStart++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1072
                    int mergeEnd = mergeStart + numToMerge - 1;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1073
                    int mergeSize = 0;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1074
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1075
                    // Find out how big the subrun is
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1076
                    for (int j = mergeStart; j <= mergeEnd; j++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1077
                        mergeSize = mergeSize + chunks[j].getChunkSize();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1078
                    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1079
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1080
                    // If the current subrun is small enough to outline,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1081
                    // merge it, and split the remaining chunks in the run
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1082
                    if (mergeSize <= TARGET_METHOD_SIZE) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1083
                        foundChunksToMerge = true;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1084
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1085
                        for (int j = mergeStart; j <= mergeEnd; j++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1086
                            chunkWasMerged[j] = true;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1087
                        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1088
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1089
                        mergedChunks.add(
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1090
                                new Chunk(chunks[mergeStart].getChunkStart(),
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1091
                                          chunks[mergeEnd].getChunkEnd()));
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1092
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1093
                        // Adjust the length of the current run of adjacent
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1094
                        // chunks to end at the newly merged chunk...
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1095
                        adjacencyRunLength[run] =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1096
                                adjacencyRunStart[run] - mergeStart;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1097
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1098
                        int trailingRunLength = runEnd - mergeEnd;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1099
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1100
                        // and any chunks that follow the newly merged chunk
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1101
                        // in the current run of adjacent chunks form another
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1102
                        // new run of adjacent chunks
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1103
                        if (trailingRunLength >= 2) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1104
                            adjacencyRunStart[numAdjacentRuns] = mergeEnd + 1;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1105
                            adjacencyRunLength[numAdjacentRuns] =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1106
                                                            trailingRunLength;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1107
                            numAdjacentRuns++;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1108
                        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1109
                    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1110
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1111
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1112
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1113
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1114
        // Make a final pass for any chunk that wasn't merged with a sibling
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1115
        // and include it in the list of chunks after merging.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1116
        for (int i = 0; i < chunks.length; i++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1117
            if (!chunkWasMerged[i]) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1118
                mergedChunks.add(chunks[i]);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1119
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1120
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1121
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1122
        return mergedChunks;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1123
    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1124
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1125
    /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1126
     * Breaks up the IL for this {@link MethodGenerator} into separate
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1127
     * outlined methods so that no method exceeds the 64KB limit on the length
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1128
     * of the byte code associated with a method.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1129
     * @param classGen The {@link ClassGen} with which the generated methods
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1130
     *                 will be associated
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1131
     * @param originalMethodSize The number of bytes of bytecode represented by
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1132
     *                 the {@link InstructionList} of this method
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1133
     * @return an array of the outlined <code>Method</code>s and the original
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1134
     *         method itself
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1135
     */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1136
    public Method[] outlineChunks(ClassGenerator classGen,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1137
                                  int originalMethodSize) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1138
        ArrayList methodsOutlined = new ArrayList();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1139
        int currentMethodSize = originalMethodSize;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1140
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1141
        int outlinedCount = 0;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1142
        boolean moreMethodsOutlined;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1143
        String originalMethodName = getName();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1144
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1145
        // Special handling for initialization methods.  No other methods can
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1146
        // include the less than and greater than characters in their names,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1147
        // so we munge the names here.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1148
        if (originalMethodName.equals("<init>")) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1149
            originalMethodName = "$lt$init$gt$";
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1150
        } else if (originalMethodName.equals("<clinit>")) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1151
            originalMethodName = "$lt$clinit$gt$";
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1152
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1153
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1154
        // Loop until the original method comes in under the JVM limit or
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1155
        // the loop was unable to outline any more methods
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1156
        do {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1157
            // Get all the best candidates for outlining, and sort them in
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1158
            // ascending order of size
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1159
            ArrayList candidateChunks = getCandidateChunks(classGen,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1160
                                                           currentMethodSize);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1161
            Collections.sort(candidateChunks);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1162
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1163
            moreMethodsOutlined = false;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1164
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1165
            // Loop over the candidates for outlining, from the largest to the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1166
            // smallest and outline them one at a time, until the loop has
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1167
            // outlined all or the original method comes in under the JVM
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1168
            // limit on the size of a method.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1169
            for (int i = candidateChunks.size()-1;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1170
                 i >= 0 && currentMethodSize > TARGET_METHOD_SIZE;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1171
                 i--) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1172
                Chunk chunkToOutline = (Chunk)candidateChunks.get(i);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1173
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1174
                methodsOutlined.add(outline(chunkToOutline.getChunkStart(),
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1175
                                            chunkToOutline.getChunkEnd(),
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1176
                                            originalMethodName + "$outline$"
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1177
                                                               + outlinedCount,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1178
                                            classGen));
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1179
                outlinedCount++;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1180
                moreMethodsOutlined = true;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1181
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1182
                InstructionList il = getInstructionList();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1183
                InstructionHandle lastInst = il.getEnd();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1184
                il.setPositions();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1185
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1186
                // Check the size of the method now
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1187
                currentMethodSize =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1188
                        lastInst.getPosition()
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1189
                                + lastInst.getInstruction().getLength();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1190
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1191
        } while (moreMethodsOutlined && currentMethodSize > TARGET_METHOD_SIZE);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1192
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1193
        // Outlining failed to reduce the size of the current method
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1194
        // sufficiently.  Throw an internal error.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1195
        if (currentMethodSize > MAX_METHOD_SIZE) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1196
            String msg = (new ErrorMsg(ErrorMsg.OUTLINE_ERR_METHOD_TOO_BIG))
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1197
                                  .toString();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1198
            throw new InternalError(msg);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1199
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1200
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1201
        Method[] methodsArr = new Method[methodsOutlined.size() + 1];
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1202
        methodsOutlined.toArray(methodsArr);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1203
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1204
        methodsArr[methodsOutlined.size()] = getThisMethod();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1205
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1206
        return methodsArr;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1207
    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1208
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1209
    /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1210
     * Given an outlineable chunk of code in the current {@link MethodGenerator}
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1211
     * move ("outline") the chunk to a new method, and replace the chunk in the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1212
     * old method with a reference to that new method.  No
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1213
     * {@link OutlineableChunkStart} or {@link OutlineableChunkEnd} instructions
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1214
     * are copied.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1215
     * @param first The {@link InstructionHandle} of the first instruction in
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1216
     *              the chunk to outline
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1217
     * @param last The <code>InstructionHandle</code> of the last instruction in
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1218
     *             the chunk to outline
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1219
     * @param outlinedMethodName The name of the new method
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1220
     * @param classGen The {@link ClassGenerator} of which the original
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1221
     *              and new methods will be members
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1222
     * @return The new {@link Method} containing the outlined code.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1223
     */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1224
    private Method outline(InstructionHandle first, InstructionHandle last,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1225
                           String outlinedMethodName, ClassGenerator classGen) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1226
        // We're not equipped to deal with exception handlers yet.  Bail out!
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1227
        if (getExceptionHandlers().length != 0) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1228
            String msg = (new ErrorMsg(ErrorMsg.OUTLINE_ERR_TRY_CATCH))
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1229
                                  .toString();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1230
            throw new InternalError(msg);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1231
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1232
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1233
        int outlineChunkStartOffset = first.getPosition();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1234
        int outlineChunkEndOffset = last.getPosition()
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1235
                                        + last.getInstruction().getLength();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1236
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1237
        ConstantPoolGen cpg = getConstantPool();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1238
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1239
        // Create new outlined method with signature:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1240
        //
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1241
        //   private final outlinedMethodName(CopyLocals copyLocals);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1242
        //
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1243
        // CopyLocals is an object that is used to copy-in/copy-out local
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1244
        // variables that are used by the outlined method.   Only locals whose
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1245
        // value is potentially set or referenced outside the range of the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1246
        // chunk that is being outlined will be represented in CopyLocals.  The
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1247
        // type of the variable for copying local variables is actually
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1248
        // generated to be unique - it is not named CopyLocals.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1249
        //
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1250
        // The outlined method never needs to be referenced outside of this
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1251
        // class, and will never be overridden, so we mark it private final.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1252
        final InstructionList newIL = new InstructionList();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1253
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1254
        final XSLTC  xsltc = classGen.getParser().getXSLTC();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1255
        final String argTypeName = xsltc.getHelperClassName();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1256
        final Type[] argTypes =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1257
            new Type[] {(new ObjectType(argTypeName)).toJCType()};
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1258
        final String argName = "copyLocals";
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1259
        final String[] argNames = new String[] {argName};
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1260
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1261
        int methodAttributes = ACC_PRIVATE | ACC_FINAL;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1262
        final boolean isStaticMethod = (getAccessFlags() & ACC_STATIC) != 0;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1263
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1264
        if (isStaticMethod) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1265
            methodAttributes = methodAttributes | ACC_STATIC;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1266
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1267
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1268
        final MethodGenerator outlinedMethodGen =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1269
            new MethodGenerator(methodAttributes,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1270
                                com.sun.org.apache.bcel.internal.generic.Type.VOID,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1271
                                argTypes, argNames, outlinedMethodName,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1272
                                getClassName(), newIL, cpg);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1273
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1274
        // Create class for copying local variables to the outlined method.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1275
        // The fields the class will need to contain will be determined as the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1276
        // code in the outlineable chunk is examined.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1277
        ClassGenerator copyAreaCG
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1278
            = new ClassGenerator(argTypeName, OBJECT_CLASS, argTypeName+".java",
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1279
                                 ACC_FINAL | ACC_PUBLIC | ACC_SUPER, null,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1280
                                 classGen.getStylesheet()) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1281
                      public boolean isExternal() {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1282
                          return true;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1283
                      }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1284
                  };
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1285
        ConstantPoolGen copyAreaCPG = copyAreaCG.getConstantPool();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1286
        copyAreaCG.addEmptyConstructor(ACC_PUBLIC);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1287
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1288
        // Number of fields in the copy class
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1289
        int copyAreaFieldCount = 0;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1290
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1291
        // The handle for the instruction after the last one to be outlined.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1292
        // Note that this should never end up being null.  An outlineable chunk
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1293
        // won't contain a RETURN instruction or other branch out of the chunk,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1294
        // and the JVM specification prohibits code in a method from just
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1295
        // "falling off the end" so this should always point to a valid handle.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1296
        InstructionHandle limit = last.getNext();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1297
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1298
        // InstructionLists for copying values into and out of an instance of
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1299
        // CopyLocals:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1300
        //      oldMethCoypInIL  - from locals in old method into an instance
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1301
        //                         of the CopyLocals class (oldMethCopyInIL)
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1302
        //      oldMethCopyOutIL - from CopyLocals back into locals in the old
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1303
        //                         method
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1304
        //      newMethCopyInIL  - from CopyLocals into locals in the new
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1305
        //                         method
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1306
        //      newMethCopyOutIL - from locals in new method into the instance
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1307
        //                         of the CopyLocals class
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1308
        InstructionList oldMethCopyInIL  = new InstructionList();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1309
        InstructionList oldMethCopyOutIL = new InstructionList();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1310
        InstructionList newMethCopyInIL  = new InstructionList();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1311
        InstructionList newMethCopyOutIL = new InstructionList();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1312
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1313
        // Allocate instance of class in which we'll copy in or copy out locals
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1314
        // and make two copies:  last copy is used to invoke constructor;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1315
        // other two are used for references to fields in the CopyLocals object
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1316
        InstructionHandle outlinedMethodCallSetup =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1317
            oldMethCopyInIL.append(new NEW(cpg.addClass(argTypeName)));
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1318
        oldMethCopyInIL.append(InstructionConstants.DUP);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1319
        oldMethCopyInIL.append(InstructionConstants.DUP);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1320
        oldMethCopyInIL.append(
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1321
            new INVOKESPECIAL(cpg.addMethodref(argTypeName, "<init>", "()V")));
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1322
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1323
        // Generate code to invoke the new outlined method, and place the code
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1324
        // on oldMethCopyOutIL
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1325
        InstructionHandle outlinedMethodRef;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1326
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1327
        if (isStaticMethod) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1328
            outlinedMethodRef =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1329
                oldMethCopyOutIL.append(
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1330
                    new INVOKESTATIC(cpg.addMethodref(
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1331
                                          classGen.getClassName(),
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1332
                                          outlinedMethodName,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1333
                                          outlinedMethodGen.getSignature())));
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1334
        } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1335
            oldMethCopyOutIL.append(InstructionConstants.THIS);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1336
            oldMethCopyOutIL.append(InstructionConstants.SWAP);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1337
            outlinedMethodRef =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1338
                oldMethCopyOutIL.append(
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1339
                    new INVOKEVIRTUAL(cpg.addMethodref(
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1340
                                          classGen.getClassName(),
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1341
                                          outlinedMethodName,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1342
                                          outlinedMethodGen.getSignature())));
6
7f561c08de6b Initial load
duke
parents:
diff changeset
  1343
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
  1344
12458
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1345
        // Used to keep track of the first in a sequence of
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1346
        // OutlineableChunkStart instructions
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1347
        boolean chunkStartTargetMappingsPending = false;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1348
        InstructionHandle pendingTargetMappingHandle = null;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1349
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1350
        // Used to keep track of the last instruction that was copied
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1351
        InstructionHandle lastCopyHandle = null;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1352
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1353
        // Keeps track of the mapping from instruction handles in the old
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1354
        // method to instruction handles in the outlined method.  Only need
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1355
        // to track instructions that are targeted by something else in the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1356
        // generated BCEL
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1357
        HashMap targetMap   = new HashMap();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1358
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1359
        // Keeps track of the mapping from local variables in the old method
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1360
        // to local variables in the outlined method.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1361
        HashMap localVarMap = new HashMap();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1362
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1363
        HashMap revisedLocalVarStart = new HashMap();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1364
        HashMap revisedLocalVarEnd = new HashMap();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1365
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1366
        // Pass 1: Make copies of all instructions, append them to the new list
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1367
        // and associate old instruction references with the new ones, i.e.,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1368
        // a 1:1 mapping.  The special marker instructions are not copied.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1369
        // Also, identify local variables whose values need to be copied into or
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1370
        // out of the new outlined method, and builds up targetMap and
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1371
        // localVarMap as described above.  The code identifies those local
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1372
        // variables first so that they can have fixed slots in the stack
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1373
        // frame for the outlined method assigned them ahead of all those
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1374
        // variables that don't need to exist for the entirety of the outlined
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1375
        // method invocation.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1376
        for (InstructionHandle ih = first; ih != limit; ih = ih.getNext()) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1377
            Instruction inst = ih.getInstruction();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1378
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1379
            // MarkerInstructions are not copied, so if something else targets
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1380
            // one, the targetMap will point to the nearest copied sibling
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1381
            // InstructionHandle:  for an OutlineableChunkEnd, the nearest
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1382
            // preceding sibling; for an OutlineableChunkStart, the nearest
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1383
            // following sibling.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1384
            if (inst instanceof MarkerInstruction) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1385
                if (ih.hasTargeters()) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1386
                    if (inst instanceof OutlineableChunkEnd) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1387
                        targetMap.put(ih, lastCopyHandle);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1388
                    } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1389
                        if (!chunkStartTargetMappingsPending)  {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1390
                            chunkStartTargetMappingsPending = true;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1391
                            pendingTargetMappingHandle = ih;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1392
                        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1393
                    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1394
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1395
            } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1396
                // Copy the instruction and append it to the outlined method's
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1397
                // InstructionList.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1398
                Instruction c = inst.copy(); // Use clone for shallow copy
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1399
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1400
                if (c instanceof BranchInstruction) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1401
                    lastCopyHandle = newIL.append((BranchInstruction)c);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1402
                } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1403
                    lastCopyHandle = newIL.append(c);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1404
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1405
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1406
                if (c instanceof LocalVariableInstruction
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1407
                        || c instanceof RET) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1408
                    // For any instruction that touches a local variable,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1409
                    // check whether the local variable's value needs to be
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1410
                    // copied into or out of the outlined method.  If so,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1411
                    // generate the code to perform the necessary copying, and
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1412
                    // use localVarMap to map the variable in the original
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1413
                    // method to the variable in the new method.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1414
                    IndexedInstruction lvi = (IndexedInstruction)c;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1415
                    int oldLocalVarIndex = lvi.getIndex();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1416
                    LocalVariableGen oldLVG =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1417
                            getLocalVariableRegistry()
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1418
                                .lookupRegisteredLocalVariable(oldLocalVarIndex,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1419
                                                              ih.getPosition());
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1420
                    LocalVariableGen newLVG =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1421
                            (LocalVariableGen)localVarMap.get(oldLVG);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1422
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1423
                    // Has the code already mapped this local variable to a
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1424
                    // local in the new method?
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1425
                    if (localVarMap.get(oldLVG) == null) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1426
                        // Determine whether the local variable needs to be
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1427
                        // copied into or out of the outlined by checking
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1428
                        // whether the range of instructions in which the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1429
                        // variable is accessible is outside the range of
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1430
                        // instructions in the outlineable chunk.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1431
                        // Special case a chunk start offset of zero:  a local
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1432
                        // variable live at that position must be a method
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1433
                        // parameter, so the code doesn't need to check whether
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1434
                        // the variable is live before that point; being live
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1435
                        // at offset zero is sufficient to know that the value
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1436
                        // must be copied in to the outlined method.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1437
                        boolean copyInLocalValue =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1438
                            offsetInLocalVariableGenRange(oldLVG,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1439
                                                (outlineChunkStartOffset != 0)
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1440
                                                    ? outlineChunkStartOffset-1
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1441
                                                    : 0);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1442
                        boolean copyOutLocalValue =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1443
                            offsetInLocalVariableGenRange(oldLVG,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1444
                                                outlineChunkEndOffset+1);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1445
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1446
                        // For any variable that needs to be copied into or out
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1447
                        // of the outlined method, create a field in the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1448
                        // CopyLocals class, and generate the necessary code for
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1449
                        // copying the value.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1450
                        if (copyInLocalValue || copyOutLocalValue) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1451
                            String varName = oldLVG.getName();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1452
                            Type varType = oldLVG.getType();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1453
                            newLVG = outlinedMethodGen.addLocalVariable(varName,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1454
                                                                        varType,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1455
                                                                        null,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1456
                                                                        null);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1457
                            int newLocalVarIndex = newLVG.getIndex();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1458
                            String varSignature = varType.getSignature();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1459
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1460
                            // Record the mapping from the old local to the new
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1461
                            localVarMap.put(oldLVG, newLVG);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1462
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1463
                            copyAreaFieldCount++;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1464
                            String copyAreaFieldName =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1465
                                           "field" + copyAreaFieldCount;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1466
                            copyAreaCG.addField(
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1467
                                new Field(ACC_PUBLIC,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1468
                                        copyAreaCPG.addUtf8(copyAreaFieldName),
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1469
                                        copyAreaCPG.addUtf8(varSignature),
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1470
                                        null, copyAreaCPG.getConstantPool()));
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1471
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1472
                            int fieldRef = cpg.addFieldref(argTypeName,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1473
                                                           copyAreaFieldName,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1474
                                                           varSignature);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1475
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1476
                            if (copyInLocalValue) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1477
                                // Generate code for the old method to store the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1478
                                // value of the local into the correct field in
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1479
                                // CopyLocals prior to invocation of the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1480
                                // outlined method.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1481
                                oldMethCopyInIL.append(
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1482
                                        InstructionConstants.DUP);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1483
                                InstructionHandle copyInLoad =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1484
                                    oldMethCopyInIL.append(
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1485
                                        loadLocal(oldLocalVarIndex, varType));
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1486
                                oldMethCopyInIL.append(new PUTFIELD(fieldRef));
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1487
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1488
                                // If the end of the live range of the old
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1489
                                // variable was in the middle of the outlined
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1490
                                // chunk.  Make the load of its value the new
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1491
                                // end of its range.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1492
                                if (!copyOutLocalValue) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1493
                                    revisedLocalVarEnd.put(oldLVG, copyInLoad);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1494
                                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1495
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1496
                                // Generate code for start of the outlined
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1497
                                // method to copy the value from a field in
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1498
                                // CopyLocals to the new local in the outlined
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1499
                                // method
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1500
                                newMethCopyInIL.append(
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1501
                                        InstructionConstants.ALOAD_1);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1502
                                newMethCopyInIL.append(new GETFIELD(fieldRef));
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1503
                                newMethCopyInIL.append(
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1504
                                        storeLocal(newLocalVarIndex, varType));
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1505
                            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1506
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1507
                            if (copyOutLocalValue) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1508
                                // Generate code for the end of the outlined
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1509
                                // method to copy the value from the new local
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1510
                                // variable into a field in CopyLocals
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1511
                                // method
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1512
                                newMethCopyOutIL.append(
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1513
                                        InstructionConstants.ALOAD_1);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1514
                                newMethCopyOutIL.append(
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1515
                                        loadLocal(newLocalVarIndex, varType));
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1516
                                newMethCopyOutIL.append(new PUTFIELD(fieldRef));
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1517
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1518
                                // Generate code to copy the value from a field
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1519
                                // in CopyLocals into a local in the original
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1520
                                // method following invocation of the outlined
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1521
                                // method.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1522
                                oldMethCopyOutIL.append(
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1523
                                        InstructionConstants.DUP);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1524
                                oldMethCopyOutIL.append(new GETFIELD(fieldRef));
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1525
                                InstructionHandle copyOutStore =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1526
                                    oldMethCopyOutIL.append(
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1527
                                        storeLocal(oldLocalVarIndex, varType));
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1528
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1529
                                // If the start of the live range of the old
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1530
                                // variable was in the middle of the outlined
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1531
                                // chunk.  Make this store into it the new start
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1532
                                // of its range.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1533
                                if (!copyInLocalValue) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1534
                                    revisedLocalVarStart.put(oldLVG,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1535
                                                             copyOutStore);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1536
                                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1537
                            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1538
                        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1539
                    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1540
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1541
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1542
                if (ih.hasTargeters()) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1543
                    targetMap.put(ih, lastCopyHandle);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1544
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1545
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1546
                // If this is the first instruction copied following a sequence
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1547
                // of OutlineableChunkStart instructions, indicate that the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1548
                // sequence of old instruction all map to this newly created
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1549
                // instruction
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1550
                if (chunkStartTargetMappingsPending) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1551
                    do {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1552
                         targetMap.put(pendingTargetMappingHandle,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1553
                                       lastCopyHandle);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1554
                         pendingTargetMappingHandle =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1555
                                 pendingTargetMappingHandle.getNext();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1556
                    } while(pendingTargetMappingHandle != ih);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1557
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1558
                    chunkStartTargetMappingsPending = false;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1559
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1560
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1561
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1562
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1563
        // Pass 2: Walk old and new instruction lists, updating branch targets
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1564
        // and local variable references in the new list
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1565
        InstructionHandle ih = first;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1566
        InstructionHandle ch = newIL.getStart();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1567
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1568
        while (ch != null) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1569
            // i == old instruction; c == copied instruction
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1570
            Instruction i = ih.getInstruction();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1571
            Instruction c = ch.getInstruction();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1572
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1573
            if (i instanceof BranchInstruction) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1574
                BranchInstruction bc      = (BranchInstruction)c;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1575
                BranchInstruction bi      = (BranchInstruction)i;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1576
                InstructionHandle itarget = bi.getTarget(); // old target
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1577
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1578
                // New target must be in targetMap
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1579
                InstructionHandle newTarget =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1580
                    (InstructionHandle)targetMap.get(itarget);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1581
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1582
                bc.setTarget(newTarget);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1583
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1584
                // Handle LOOKUPSWITCH or TABLESWITCH which may have many
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1585
                // target instructions
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1586
                if (bi instanceof Select) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1587
                    InstructionHandle[] itargets = ((Select)bi).getTargets();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1588
                    InstructionHandle[] ctargets = ((Select)bc).getTargets();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1589
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1590
                    // Update all targets
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1591
                    for (int j=0; j < itargets.length; j++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1592
                        ctargets[j] =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1593
                            (InstructionHandle)targetMap.get(itargets[j]);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1594
                    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1595
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1596
            }  else if (i instanceof LocalVariableInstruction
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1597
                            || i instanceof RET) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1598
                // For any instruction that touches a local variable,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1599
                // map the location of the variable in the original
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1600
                // method to its location in the new method.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1601
                IndexedInstruction lvi = (IndexedInstruction)c;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1602
                int oldLocalVarIndex = lvi.getIndex();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1603
                LocalVariableGen oldLVG =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1604
                        getLocalVariableRegistry()
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1605
                                .lookupRegisteredLocalVariable(oldLocalVarIndex,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1606
                                                              ih.getPosition());
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1607
                LocalVariableGen newLVG =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1608
                        (LocalVariableGen)localVarMap.get(oldLVG);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1609
                int newLocalVarIndex;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1610
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1611
                if (newLVG == null) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1612
                    // Create new variable based on old variable - use same
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1613
                    // name and type, but we will let the variable be active
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1614
                    // for the entire outlined method.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1615
                    // LocalVariableGen oldLocal = oldLocals[oldLocalVarIndex];
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1616
                    String varName = oldLVG.getName();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1617
                    Type varType = oldLVG.getType();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1618
                    newLVG = outlinedMethodGen.addLocalVariable(varName,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1619
                                                                varType,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1620
                                                                null,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1621
                                                                null);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1622
                    newLocalVarIndex = newLVG.getIndex();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1623
                    localVarMap.put(oldLVG, newLVG);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1624
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1625
                    // The old variable's live range was wholly contained in
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1626
                    // the outlined chunk.  There should no longer be stores
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1627
                    // of values into it or loads of its value, so we can just
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1628
                    // mark its live range as the reference to the outlined
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1629
                    // method.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1630
                    revisedLocalVarStart.put(oldLVG, outlinedMethodRef);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1631
                    revisedLocalVarEnd.put(oldLVG, outlinedMethodRef);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1632
                } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1633
                    newLocalVarIndex = newLVG.getIndex();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1634
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1635
                lvi.setIndex(newLocalVarIndex);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1636
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1637
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1638
            // If the old instruction marks the end of the range of a local
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1639
            // variable, make sure that any slots on the stack reserved for
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1640
            // local variables are made available for reuse by calling
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1641
            // MethodGenerator.removeLocalVariable
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1642
            if (ih.hasTargeters()) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1643
                InstructionTargeter[] targeters = ih.getTargeters();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1644
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1645
                for (int idx = 0; idx < targeters.length; idx++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1646
                    InstructionTargeter targeter = targeters[idx];
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1647
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1648
                    if (targeter instanceof LocalVariableGen
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1649
                            && ((LocalVariableGen)targeter).getEnd()==ih) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1650
                        Object newLVG = localVarMap.get(targeter);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1651
                        if (newLVG != null) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1652
                            outlinedMethodGen.removeLocalVariable(
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1653
                                                  (LocalVariableGen)newLVG);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1654
                        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1655
                    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1656
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1657
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1658
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1659
            // If the current instruction in the original list was a marker,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1660
            // it wasn't copied, so don't advance through the list of copied
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1661
            // instructions yet.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1662
            if (!(i instanceof MarkerInstruction)) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1663
                ch = ch.getNext();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1664
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1665
            ih = ih.getNext();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1666
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1667
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1668
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1669
        // POP the reference to the CopyLocals object from the stack
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1670
        oldMethCopyOutIL.append(InstructionConstants.POP);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1671
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1672
        // Now that the generation of the outlined code is complete, update
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1673
        // the old local variables with new start and end ranges, as required.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1674
        Iterator revisedLocalVarStartPairIter = revisedLocalVarStart.entrySet()
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1675
                                                                    .iterator();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1676
        while (revisedLocalVarStartPairIter.hasNext()) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1677
            Map.Entry lvgRangeStartPair =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1678
                    (Map.Entry)revisedLocalVarStartPairIter.next();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1679
            LocalVariableGen lvg = (LocalVariableGen)lvgRangeStartPair.getKey();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1680
            InstructionHandle startInst =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1681
                    (InstructionHandle)lvgRangeStartPair.getValue();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1682
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1683
            lvg.setStart(startInst);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1684
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1685
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1686
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1687
        Iterator revisedLocalVarEndPairIter = revisedLocalVarEnd.entrySet()
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1688
                                                                .iterator();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1689
        while (revisedLocalVarEndPairIter.hasNext()) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1690
            Map.Entry lvgRangeEndPair =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1691
                    (Map.Entry)revisedLocalVarEndPairIter.next();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1692
            LocalVariableGen lvg = (LocalVariableGen)lvgRangeEndPair.getKey();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1693
            InstructionHandle endInst =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1694
                    (InstructionHandle)lvgRangeEndPair.getValue();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1695
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1696
            lvg.setEnd(endInst);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1697
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1698
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1699
        xsltc.dumpClass(copyAreaCG.getJavaClass());
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1700
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1701
        // Assemble the instruction lists so that the old method invokes the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1702
        // new outlined method
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1703
        InstructionList oldMethodIL = getInstructionList();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1704
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1705
        oldMethodIL.insert(first, oldMethCopyInIL);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1706
        oldMethodIL.insert(first, oldMethCopyOutIL);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1707
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1708
        // Insert the copying code into the outlined method
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1709
        newIL.insert(newMethCopyInIL);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1710
        newIL.append(newMethCopyOutIL);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1711
        newIL.append(InstructionConstants.RETURN);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1712
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1713
        // Discard instructions in outlineable chunk from old method
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1714
        try {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1715
            oldMethodIL.delete(first, last);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1716
        } catch (TargetLostException e) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1717
            InstructionHandle[] targets = e.getTargets();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1718
            // If there were still references to old instructions lingering,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1719
            // clean those up.  The only instructions targetting the deleted
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1720
            // instructions should have been part of the chunk that was just
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1721
            // deleted, except that instructions might branch to the start of
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1722
            // the outlined chunk; similarly, all the live ranges of local
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1723
            // variables should have been adjusted, except for unreferenced
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1724
            // variables.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1725
            for (int i = 0; i < targets.length; i++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1726
                InstructionHandle lostTarget = targets[i];
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1727
                InstructionTargeter[] targeters = lostTarget.getTargeters();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1728
                for (int j = 0; j < targeters.length; j++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1729
                    if (targeters[j] instanceof LocalVariableGen) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1730
                        LocalVariableGen lvgTargeter =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1731
                                             (LocalVariableGen) targeters[j];
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1732
                        // In the case of any lingering variable references,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1733
                        // just make the live range point to the outlined
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1734
                        // function reference.  Such variables should be unused
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1735
                        // anyway.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1736
                        if (lvgTargeter.getStart() == lostTarget) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1737
                            lvgTargeter.setStart(outlinedMethodRef);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1738
                        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1739
                        if (lvgTargeter.getEnd() == lostTarget) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1740
                            lvgTargeter.setEnd(outlinedMethodRef);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1741
                        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1742
                    } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1743
                        targeters[j].updateTarget(lostTarget,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1744
                                                  outlinedMethodCallSetup);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1745
                    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1746
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1747
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1748
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1749
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1750
        // Make a copy for the new method of all exceptions that might be thrown
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1751
        String[] exceptions = getExceptions();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1752
        for (int i = 0; i < exceptions.length; i++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1753
            outlinedMethodGen.addException(exceptions[i]);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1754
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1755
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1756
        return outlinedMethodGen.getThisMethod();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1757
    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1758
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1759
    /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1760
     * Helper method to generate an instance of a subclass of
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1761
     * {@link LoadInstruction} based on the specified {@link Type} that will
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1762
     * load the specified local variable
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1763
     * @param index the JVM stack frame index of the variable that is to be
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1764
     * loaded
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1765
     * @param type the {@link Type} of the variable
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1766
     * @return the generated {@link LoadInstruction}
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1767
     */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1768
    private static Instruction loadLocal(int index, Type type) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1769
        if (type == Type.BOOLEAN) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1770
           return new ILOAD(index);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1771
        } else if (type == Type.INT) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1772
           return new ILOAD(index);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1773
        } else if (type == Type.SHORT) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1774
           return new ILOAD(index);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1775
        } else if (type == Type.LONG) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1776
           return new LLOAD(index);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1777
        } else if (type == Type.BYTE) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1778
           return new ILOAD(index);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1779
        } else if (type == Type.CHAR) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1780
           return new ILOAD(index);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1781
        } else if (type == Type.FLOAT) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1782
           return new FLOAD(index);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1783
        } else if (type == Type.DOUBLE) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1784
           return new DLOAD(index);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1785
        } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1786
           return new ALOAD(index);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1787
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1788
    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1789
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1790
    /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1791
     * Helper method to generate an instance of a subclass of
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1792
     * {@link StoreInstruction} based on the specified {@link Type} that will
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1793
     * store a value in the specified local variable
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1794
     * @param index the JVM stack frame index of the variable that is to be
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1795
     * stored
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1796
     * @param type the {@link Type} of the variable
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1797
     * @return the generated {@link StoredInstruction}
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1798
     */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1799
    private static Instruction storeLocal(int index, Type type) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1800
        if (type == Type.BOOLEAN) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1801
           return new ISTORE(index);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1802
        } else if (type == Type.INT) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1803
           return new ISTORE(index);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1804
        } else if (type == Type.SHORT) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1805
           return new ISTORE(index);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1806
        } else if (type == Type.LONG) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1807
           return new LSTORE(index);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1808
        } else if (type == Type.BYTE) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1809
           return new ISTORE(index);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1810
        } else if (type == Type.CHAR) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1811
           return new ISTORE(index);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1812
        } else if (type == Type.FLOAT) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1813
           return new FSTORE(index);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1814
        } else if (type == Type.DOUBLE) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1815
           return new DSTORE(index);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1816
        } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1817
           return new ASTORE(index);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1818
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1819
    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1820
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1821
    /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1822
     * Track the number of outlineable chunks seen.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1823
     */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1824
    private int m_totalChunks = 0;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1825
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1826
    /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1827
     * Track the number of outlineable chunks started but not yet ended.  Used
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1828
     * to detect imbalances in byte code generation.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1829
     */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1830
    private int m_openChunks = 0;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1831
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1832
    /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1833
     * Mark the end of the method's
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1834
     * {@link InstructionList} as the start of an outlineable chunk of code.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1835
     * The outlineable chunk begins after the {@link InstructionHandle} that is
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1836
     * at the end of the method's {@link InstructionList}, or at the start of
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1837
     * the method if the <code>InstructionList</code> is empty.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1838
     * See {@link OutlineableChunkStart} for more information.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1839
     */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1840
    public void markChunkStart() {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1841
        // m_chunkTree.markChunkStart();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1842
        getInstructionList()
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1843
                .append(OutlineableChunkStart.OUTLINEABLECHUNKSTART);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1844
        m_totalChunks++;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1845
        m_openChunks++;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1846
    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1847
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1848
    /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1849
     * Mark the end of an outlineable chunk of code.  See
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1850
     * {@link OutlineableChunkStart} for more information.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1851
     */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1852
    public void markChunkEnd() {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1853
        // m_chunkTree.markChunkEnd();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1854
        getInstructionList()
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1855
                .append(OutlineableChunkEnd.OUTLINEABLECHUNKEND);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1856
        m_openChunks--;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1857
        if (m_openChunks < 0) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1858
            String msg = (new ErrorMsg(ErrorMsg.OUTLINE_ERR_UNBALANCED_MARKERS))
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1859
                                 .toString();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1860
            throw new InternalError(msg);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1861
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1862
    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1863
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1864
    /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1865
     * <p>Get all {@link Method}s generated by this {@link MethodGenerator}.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1866
     * The {@link MethodGen#getMethod()} only returns a single
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1867
     * <code>Method</code> object.  This method takes into account the Java
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1868
     * Virtual Machine Specification limit of 64KB on the size of a method, and
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1869
     * may return more than one <code>Method</code>.</p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1870
     * <p>If the code associated with the <code>MethodGenerator</code> would
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1871
     * exceed the 64KB limit, this method will attempt to split the code in
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1872
     * the {@link InstructionList} associated with this
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1873
     * <code>MethodGenerator</code> into several methods.</p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1874
     * @param classGen the {@link ClassGenerator} of which these methods are
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1875
     *                 members
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1876
     * @return an array of all the <code>Method</code>s generated
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1877
     */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1878
    Method[] getGeneratedMethods(ClassGenerator classGen) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1879
        Method[] generatedMethods;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1880
        InstructionList il = getInstructionList();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1881
        InstructionHandle last = il.getEnd();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1882
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1883
        il.setPositions();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1884
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1885
        int instructionListSize =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1886
                    last.getPosition() + last.getInstruction().getLength();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1887
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1888
        // Need to look for any branch target offsets that exceed the range
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1889
        // [-32768,32767]
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1890
        if (instructionListSize > MAX_BRANCH_TARGET_OFFSET) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1891
            boolean ilChanged = widenConditionalBranchTargetOffsets();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1892
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1893
            // If any branch instructions needed widening, recompute the size
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1894
            // of the byte code for the method
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1895
            if (ilChanged) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1896
                il.setPositions();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1897
                last = il.getEnd();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1898
                instructionListSize =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1899
                        last.getPosition() + last.getInstruction().getLength();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1900
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1901
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1902
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1903
        if (instructionListSize > MAX_METHOD_SIZE) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1904
            generatedMethods = outlineChunks(classGen, instructionListSize);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1905
        } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1906
            generatedMethods = new Method[] {getThisMethod()};
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1907
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1908
        return generatedMethods;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1909
    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1910
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1911
    protected Method getThisMethod() {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1912
        stripAttributes(true);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1913
        setMaxLocals();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1914
        setMaxStack();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1915
        removeNOPs();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1916
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1917
        return getMethod();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1918
    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1919
    /**
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1920
     * <p>Rewrites branches to avoid the JVM limits of relative branch
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1921
     * offsets.  There is no need to invoke this method if the bytecode for the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1922
     * {@link MethodGenerator} does not exceed 32KB.</p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1923
     * <p>The Java Virtual Machine Specification permits the code portion of a
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1924
     * method to be up to 64KB in length.  However, some control transfer
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1925
     * instructions specify relative offsets as a signed 16-bit quantity,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1926
     * limiting the range to a subset of the instructions that might be in a
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1927
     * method.</p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1928
     * <p>The <code>TABLESWITCH</code> and <code>LOOKUPSWITCH</code>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1929
     * instructions always use 32-bit signed relative offsets, so they are
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1930
     * immune to this problem.</p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1931
     * <p>The <code>GOTO</code> and <code>JSR</code>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1932
     * instructions come in two forms, one of which uses 16-bit relative
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1933
     * offsets, and the other of which uses 32-bit relative offsets.  The BCEL
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1934
     * library decides whether to use the wide form of <code>GOTO</code> or
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1935
     * <code>JSR</code>instructions based on the relative offset of the target
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1936
     * of the instruction without any intervention by the user of the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1937
     * library.</p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1938
     * <p>This leaves the various conditional branch instructions,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1939
     * <code>IFEQ</code>, <code>IFNULL</code>, <code>IF_ICMPEQ</code>,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1940
     * <em>et al.</em>, all of which use 16-bit signed relative offsets, with no
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1941
     * 32-bit wide form available.</p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1942
     * <p>This method scans the {@link InstructionList} associated with this
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1943
     * {@link MethodGenerator} and finds all conditional branch instructions
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1944
     * that might exceed the 16-bit limitation for relative branch offsets.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1945
     * The logic of each such instruction is inverted, and made to target the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1946
     * instruction which follows it.  An unconditional branch to the original
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1947
     * target of the instruction is then inserted between the conditional
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1948
     * branch and the instruction which previously followed it.  The
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1949
     * unconditional branch is permitted to have a 16-bit or a 32-bit relative
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1950
     * offset, as described above.  For example,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1951
     * <code>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1952
     * 1234:   NOP
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1953
     *          ...
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1954
     * 55278:  IFEQ -54044
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1955
     * 55280:  NOP
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1956
     * </code>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1957
     * is rewritten as
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1958
     * <code>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1959
     * 1234:   NOP
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1960
     *          ...
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1961
     * 55278:  IFNE 7
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1962
     * 55280:  GOTO_W -54046
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1963
     * 55285:  NOP
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1964
     * </code></p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1965
     * <p><b>Preconditions:</b>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1966
     * <ul><li>The {@link InstructionList#setPositions()} has been called for
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1967
     * the <code>InstructionList</code> associated with this
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1968
     * <code>MethodGenerator</code>.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1969
     * </li></ul></p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1970
     * <p><b>Postconditions:</b>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1971
     * <ul><li>Any further changes to the <code>InstructionList</code> for this
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1972
     * <code>MethodGenerator</code> will invalidate the changes made by this
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1973
     * method.</li></ul>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1974
     * </p>
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1975
     * @return <code>true</code> if the <code>InstructionList</code> was
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1976
     * modified; <code>false</code> otherwise
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1977
     * @see The Java Virtual Machine Specification, Second Edition
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1978
     */
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1979
    boolean widenConditionalBranchTargetOffsets() {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1980
        boolean ilChanged = false;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1981
        int maxOffsetChange = 0;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1982
        InstructionList il = getInstructionList();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1983
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1984
        // Loop through all the instructions, finding those that would be
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1985
        // affected by inserting new instructions in the InstructionList, and
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1986
        // calculating the maximum amount by which the relative offset between
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1987
        // two instructions could possibly change.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1988
        // In part this loop duplicates code in
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1989
        // org.apache.bcel.generic.InstructionList.setPosition(), which does
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1990
        // this to determine whether to use 16-bit or 32-bit offsets for GOTO
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1991
        // and JSR instructions.  Ideally, that method would do the same for
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1992
        // conditional branch instructions, but it doesn't, so we duplicate the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1993
        // processing here.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1994
        for (InstructionHandle ih = il.getStart();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1995
             ih != null;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1996
             ih = ih.getNext()) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1997
            Instruction inst = ih.getInstruction();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1998
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  1999
            switch (inst.getOpcode()) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2000
                // Instructions that may have 16-bit or 32-bit branch targets.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2001
                // The size of the branch offset might increase by two bytes.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2002
                case Constants.GOTO:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2003
                case Constants.JSR:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2004
                    maxOffsetChange = maxOffsetChange + 2;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2005
                    break;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2006
                // Instructions that contain padding for alignment purposes
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2007
                // Up to three bytes of padding might be needed.  For greater
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2008
                // accuracy, we should be able to discount any padding already
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2009
                // added to these instructions by InstructionList.setPosition(),
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2010
                // their APIs do not expose that information.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2011
                case Constants.TABLESWITCH:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2012
                case Constants.LOOKUPSWITCH:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2013
                    maxOffsetChange = maxOffsetChange + 3;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2014
                    break;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2015
                // Instructions that might be rewritten by this method as a
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2016
                // conditional branch followed by an unconditional branch.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2017
                // The unconditional branch would require five bytes.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2018
                case Constants.IF_ACMPEQ:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2019
                case Constants.IF_ACMPNE:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2020
                case Constants.IF_ICMPEQ:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2021
                case Constants.IF_ICMPGE:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2022
                case Constants.IF_ICMPGT:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2023
                case Constants.IF_ICMPLE:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2024
                case Constants.IF_ICMPLT:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2025
                case Constants.IF_ICMPNE:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2026
                case Constants.IFEQ:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2027
                case Constants.IFGE:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2028
                case Constants.IFGT:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2029
                case Constants.IFLE:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2030
                case Constants.IFLT:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2031
                case Constants.IFNE:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2032
                case Constants.IFNONNULL:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2033
                case Constants.IFNULL:
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2034
                    maxOffsetChange = maxOffsetChange + 5;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2035
                    break;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2036
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2037
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2038
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2039
        // Now that the maximum number of bytes by which the method might grow
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2040
        // has been determined, look for conditional branches to see which
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2041
        // might possibly exceed the 16-bit relative offset.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2042
        for (InstructionHandle ih = il.getStart();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2043
             ih != null;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2044
             ih = ih.getNext()) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2045
            Instruction inst = ih.getInstruction();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2046
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2047
            if (inst instanceof IfInstruction) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2048
                IfInstruction oldIfInst = (IfInstruction)inst;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2049
                BranchHandle oldIfHandle = (BranchHandle)ih;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2050
                InstructionHandle target = oldIfInst.getTarget();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2051
                int relativeTargetOffset = target.getPosition()
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2052
                                               - oldIfHandle.getPosition();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2053
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2054
                // Consider the worst case scenario in which the conditional
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2055
                // branch and its target are separated by all the instructions
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2056
                // in the method that might increase in size.  If that results
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2057
                // in a relative offset that cannot be represented as a 32-bit
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2058
                // signed quantity, rewrite the instruction as described above.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2059
                if ((relativeTargetOffset - maxOffsetChange
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2060
                             < MIN_BRANCH_TARGET_OFFSET)
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2061
                        || (relativeTargetOffset + maxOffsetChange
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2062
                                    > MAX_BRANCH_TARGET_OFFSET)) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2063
                    // Invert the logic of the IF instruction, and append
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2064
                    // that to the InstructionList following the original IF
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2065
                    // instruction
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2066
                    InstructionHandle nextHandle = oldIfHandle.getNext();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2067
                    IfInstruction invertedIfInst = oldIfInst.negate();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2068
                    BranchHandle invertedIfHandle = il.append(oldIfHandle,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2069
                                                              invertedIfInst);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2070
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2071
                    // Append an unconditional branch to the target of the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2072
                    // original IF instruction after the new IF instruction
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2073
                    BranchHandle gotoHandle = il.append(invertedIfHandle,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2074
                                                        new GOTO(target));
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2075
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2076
                    // If the original IF was the last instruction in
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2077
                    // InstructionList, add a new no-op to act as the target
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2078
                    // of the new IF
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2079
                    if (nextHandle == null) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2080
                        nextHandle = il.append(gotoHandle, NOP);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2081
                    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2082
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2083
                    // Make the new IF instruction branch around the GOTO
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2084
                    invertedIfHandle.updateTarget(target, nextHandle);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2085
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2086
                    // If anything still "points" to the old IF instruction,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2087
                    // make adjustments to refer to either the new IF or GOTO
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2088
                    // instruction
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2089
                    if (oldIfHandle.hasTargeters()) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2090
                        InstructionTargeter[] targeters =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2091
                                                  oldIfHandle.getTargeters();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2092
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2093
                        for (int i = 0; i < targeters.length; i++) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2094
                            InstructionTargeter targeter = targeters[i];
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2095
                            // Ideally, one should simply be able to use
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2096
                            // InstructionTargeter.updateTarget to change
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2097
                            // references to the old IF instruction to the new
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2098
                            // IF instruction.  However, if a LocalVariableGen
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2099
                            // indicated the old IF marked the end of the range
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2100
                            // in which the IF variable is in use, the live
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2101
                            // range of the variable must extend to include the
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2102
                            // newly created GOTO instruction.  The need for
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2103
                            // this sort of specific knowledge of an
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2104
                            // implementor of the InstructionTargeter interface
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2105
                            // makes the code more fragile.  Future implementors
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2106
                            // of the interface might have similar requirements
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2107
                            // which wouldn't be accommodated seemlessly.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2108
                            if (targeter instanceof LocalVariableGen) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2109
                                LocalVariableGen lvg =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2110
                                        (LocalVariableGen) targeter;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2111
                                if (lvg.getStart() == oldIfHandle) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2112
                                    lvg.setStart(invertedIfHandle);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2113
                                } else if (lvg.getEnd() == oldIfHandle) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2114
                                    lvg.setEnd(gotoHandle);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2115
                                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2116
                            } else {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2117
                                targeter.updateTarget(oldIfHandle,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2118
                                                      invertedIfHandle);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2119
                            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2120
                        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2121
                    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2122
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2123
                    try {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2124
                        il.delete(oldIfHandle);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2125
                    } catch (TargetLostException tle) {
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2126
                        // This can never happen - we updated the list of
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2127
                        // instructions that target the deleted instruction
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2128
                        // prior to deleting it.
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2129
                        String msg =
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2130
                            new ErrorMsg(ErrorMsg.OUTLINE_ERR_DELETED_TARGET,
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2131
                                         tle.getMessage()).toString();
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2132
                        throw new InternalError(msg);
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2133
                    }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2134
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2135
                    // Adjust the pointer in the InstructionList to point after
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2136
                    // the newly inserted IF instruction
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2137
                    ih = gotoHandle;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2138
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2139
                    // Indicate that this method rewrote at least one IF
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2140
                    ilChanged = true;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2141
                }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2142
            }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2143
        }
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2144
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2145
        // Did this method rewrite any IF instructions?
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2146
        return ilChanged;
d601e4bba306 7160380: Sync JDK8 with JAXP 1.4.5
joehw
parents: 12457
diff changeset
  2147
    }
6
7f561c08de6b Initial load
duke
parents:
diff changeset
  2148
}