jaxp/src/com/sun/org/apache/bcel/internal/generic/SWITCH.java
author dfuchs
Fri, 17 May 2013 10:40:21 +0200
changeset 17538 d8d911c4e5d4
parent 12457 c348e06f0e82
permissions -rw-r--r--
8013900: More warnings compiling jaxp. Summary: Some internal implementation classes in Jaxp were redefining equals() without redefining hashCode(). This patch adds hashCode() methods that are consistent with equals(). Reviewed-by: chegar, joehw
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6
7f561c08de6b Initial load
duke
parents:
diff changeset
     1
/*
7f561c08de6b Initial load
duke
parents:
diff changeset
     2
 * reserved comment block
7f561c08de6b Initial load
duke
parents:
diff changeset
     3
 * DO NOT REMOVE OR ALTER!
7f561c08de6b Initial load
duke
parents:
diff changeset
     4
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
     5
package com.sun.org.apache.bcel.internal.generic;
7f561c08de6b Initial load
duke
parents:
diff changeset
     6
7f561c08de6b Initial load
duke
parents:
diff changeset
     7
/* ====================================================================
7f561c08de6b Initial load
duke
parents:
diff changeset
     8
 * The Apache Software License, Version 1.1
7f561c08de6b Initial load
duke
parents:
diff changeset
     9
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    10
 * Copyright (c) 2001 The Apache Software Foundation.  All rights
7f561c08de6b Initial load
duke
parents:
diff changeset
    11
 * reserved.
7f561c08de6b Initial load
duke
parents:
diff changeset
    12
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    13
 * Redistribution and use in source and binary forms, with or without
7f561c08de6b Initial load
duke
parents:
diff changeset
    14
 * modification, are permitted provided that the following conditions
7f561c08de6b Initial load
duke
parents:
diff changeset
    15
 * are met:
7f561c08de6b Initial load
duke
parents:
diff changeset
    16
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    17
 * 1. Redistributions of source code must retain the above copyright
7f561c08de6b Initial load
duke
parents:
diff changeset
    18
 *    notice, this list of conditions and the following disclaimer.
7f561c08de6b Initial load
duke
parents:
diff changeset
    19
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    20
 * 2. Redistributions in binary form must reproduce the above copyright
7f561c08de6b Initial load
duke
parents:
diff changeset
    21
 *    notice, this list of conditions and the following disclaimer in
7f561c08de6b Initial load
duke
parents:
diff changeset
    22
 *    the documentation and/or other materials provided with the
7f561c08de6b Initial load
duke
parents:
diff changeset
    23
 *    distribution.
7f561c08de6b Initial load
duke
parents:
diff changeset
    24
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    25
 * 3. The end-user documentation included with the redistribution,
7f561c08de6b Initial load
duke
parents:
diff changeset
    26
 *    if any, must include the following acknowledgment:
7f561c08de6b Initial load
duke
parents:
diff changeset
    27
 *       "This product includes software developed by the
7f561c08de6b Initial load
duke
parents:
diff changeset
    28
 *        Apache Software Foundation (http://www.apache.org/)."
7f561c08de6b Initial load
duke
parents:
diff changeset
    29
 *    Alternately, this acknowledgment may appear in the software itself,
7f561c08de6b Initial load
duke
parents:
diff changeset
    30
 *    if and wherever such third-party acknowledgments normally appear.
7f561c08de6b Initial load
duke
parents:
diff changeset
    31
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    32
 * 4. The names "Apache" and "Apache Software Foundation" and
7f561c08de6b Initial load
duke
parents:
diff changeset
    33
 *    "Apache BCEL" must not be used to endorse or promote products
7f561c08de6b Initial load
duke
parents:
diff changeset
    34
 *    derived from this software without prior written permission. For
7f561c08de6b Initial load
duke
parents:
diff changeset
    35
 *    written permission, please contact apache@apache.org.
7f561c08de6b Initial load
duke
parents:
diff changeset
    36
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    37
 * 5. Products derived from this software may not be called "Apache",
7f561c08de6b Initial load
duke
parents:
diff changeset
    38
 *    "Apache BCEL", nor may "Apache" appear in their name, without
7f561c08de6b Initial load
duke
parents:
diff changeset
    39
 *    prior written permission of the Apache Software Foundation.
7f561c08de6b Initial load
duke
parents:
diff changeset
    40
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    41
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
7f561c08de6b Initial load
duke
parents:
diff changeset
    42
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
7f561c08de6b Initial load
duke
parents:
diff changeset
    43
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
7f561c08de6b Initial load
duke
parents:
diff changeset
    44
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
7f561c08de6b Initial load
duke
parents:
diff changeset
    45
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
7f561c08de6b Initial load
duke
parents:
diff changeset
    46
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
7f561c08de6b Initial load
duke
parents:
diff changeset
    47
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
7f561c08de6b Initial load
duke
parents:
diff changeset
    48
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
7f561c08de6b Initial load
duke
parents:
diff changeset
    49
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
7f561c08de6b Initial load
duke
parents:
diff changeset
    50
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
7f561c08de6b Initial load
duke
parents:
diff changeset
    51
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
7f561c08de6b Initial load
duke
parents:
diff changeset
    52
 * SUCH DAMAGE.
7f561c08de6b Initial load
duke
parents:
diff changeset
    53
 * ====================================================================
7f561c08de6b Initial load
duke
parents:
diff changeset
    54
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    55
 * This software consists of voluntary contributions made by many
7f561c08de6b Initial load
duke
parents:
diff changeset
    56
 * individuals on behalf of the Apache Software Foundation.  For more
7f561c08de6b Initial load
duke
parents:
diff changeset
    57
 * information on the Apache Software Foundation, please see
7f561c08de6b Initial load
duke
parents:
diff changeset
    58
 * <http://www.apache.org/>.
7f561c08de6b Initial load
duke
parents:
diff changeset
    59
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    60
7f561c08de6b Initial load
duke
parents:
diff changeset
    61
/**
7f561c08de6b Initial load
duke
parents:
diff changeset
    62
 * SWITCH - Branch depending on int value, generates either LOOKUPSWITCH or
7f561c08de6b Initial load
duke
parents:
diff changeset
    63
 * TABLESWITCH instruction, depending on whether the match values (int[]) can be
7f561c08de6b Initial load
duke
parents:
diff changeset
    64
 * sorted with no gaps between the numbers.
7f561c08de6b Initial load
duke
parents:
diff changeset
    65
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    66
 * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
7f561c08de6b Initial load
duke
parents:
diff changeset
    67
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    68
public final class SWITCH implements CompoundInstruction {
7f561c08de6b Initial load
duke
parents:
diff changeset
    69
  private int[]               match;
7f561c08de6b Initial load
duke
parents:
diff changeset
    70
  private InstructionHandle[] targets;
7f561c08de6b Initial load
duke
parents:
diff changeset
    71
  private Select              instruction;
7f561c08de6b Initial load
duke
parents:
diff changeset
    72
  private int                 match_length;
7f561c08de6b Initial load
duke
parents:
diff changeset
    73
7f561c08de6b Initial load
duke
parents:
diff changeset
    74
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    75
   * Template for switch() constructs. If the match array can be
7f561c08de6b Initial load
duke
parents:
diff changeset
    76
   * sorted in ascending order with gaps no larger than max_gap
7f561c08de6b Initial load
duke
parents:
diff changeset
    77
   * between the numbers, a TABLESWITCH instruction is generated, and
7f561c08de6b Initial load
duke
parents:
diff changeset
    78
   * a LOOKUPSWITCH otherwise. The former may be more efficient, but
7f561c08de6b Initial load
duke
parents:
diff changeset
    79
   * needs more space.
7f561c08de6b Initial load
duke
parents:
diff changeset
    80
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
    81
   * Note, that the key array always will be sorted, though we leave
7f561c08de6b Initial load
duke
parents:
diff changeset
    82
   * the original arrays unaltered.
7f561c08de6b Initial load
duke
parents:
diff changeset
    83
   *
7f561c08de6b Initial load
duke
parents:
diff changeset
    84
   * @param match array of match values (case 2: ... case 7: ..., etc.)
7f561c08de6b Initial load
duke
parents:
diff changeset
    85
   * @param targets the instructions to be branched to for each case
7f561c08de6b Initial load
duke
parents:
diff changeset
    86
   * @param target the default target
7f561c08de6b Initial load
duke
parents:
diff changeset
    87
   * @param max_gap maximum gap that may between case branches
7f561c08de6b Initial load
duke
parents:
diff changeset
    88
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
    89
  public SWITCH(int[] match, InstructionHandle[] targets,
7f561c08de6b Initial load
duke
parents:
diff changeset
    90
                InstructionHandle target, int max_gap) {
7f561c08de6b Initial load
duke
parents:
diff changeset
    91
    this.match   = (int[])match.clone();
7f561c08de6b Initial load
duke
parents:
diff changeset
    92
    this.targets = (InstructionHandle[])targets.clone();
7f561c08de6b Initial load
duke
parents:
diff changeset
    93
7f561c08de6b Initial load
duke
parents:
diff changeset
    94
    if((match_length = match.length) < 2) // (almost) empty switch, or just default
7f561c08de6b Initial load
duke
parents:
diff changeset
    95
      instruction = new TABLESWITCH(match, targets, target);
7f561c08de6b Initial load
duke
parents:
diff changeset
    96
    else {
7f561c08de6b Initial load
duke
parents:
diff changeset
    97
      sort(0, match_length - 1);
7f561c08de6b Initial load
duke
parents:
diff changeset
    98
7f561c08de6b Initial load
duke
parents:
diff changeset
    99
      if(matchIsOrdered(max_gap)) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   100
        fillup(max_gap, target);
7f561c08de6b Initial load
duke
parents:
diff changeset
   101
7f561c08de6b Initial load
duke
parents:
diff changeset
   102
        instruction = new TABLESWITCH(this.match, this.targets, target);
7f561c08de6b Initial load
duke
parents:
diff changeset
   103
      }
7f561c08de6b Initial load
duke
parents:
diff changeset
   104
      else
7f561c08de6b Initial load
duke
parents:
diff changeset
   105
        instruction = new LOOKUPSWITCH(this.match, this.targets, target);
7f561c08de6b Initial load
duke
parents:
diff changeset
   106
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   107
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   108
7f561c08de6b Initial load
duke
parents:
diff changeset
   109
  public SWITCH(int[] match, InstructionHandle[] targets,
7f561c08de6b Initial load
duke
parents:
diff changeset
   110
                InstructionHandle target) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   111
    this(match, targets, target, 1);
7f561c08de6b Initial load
duke
parents:
diff changeset
   112
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   113
7f561c08de6b Initial load
duke
parents:
diff changeset
   114
  private final void fillup(int max_gap, InstructionHandle target) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   115
    int                 max_size = match_length + match_length * max_gap;
7f561c08de6b Initial load
duke
parents:
diff changeset
   116
    int[]               m_vec    = new int[max_size];
7f561c08de6b Initial load
duke
parents:
diff changeset
   117
    InstructionHandle[] t_vec    = new InstructionHandle[max_size];
7f561c08de6b Initial load
duke
parents:
diff changeset
   118
    int                 count    = 1;
7f561c08de6b Initial load
duke
parents:
diff changeset
   119
7f561c08de6b Initial load
duke
parents:
diff changeset
   120
    m_vec[0] = match[0];
7f561c08de6b Initial load
duke
parents:
diff changeset
   121
    t_vec[0] = targets[0];
7f561c08de6b Initial load
duke
parents:
diff changeset
   122
7f561c08de6b Initial load
duke
parents:
diff changeset
   123
    for(int i=1; i < match_length; i++) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   124
      int prev = match[i-1];
7f561c08de6b Initial load
duke
parents:
diff changeset
   125
      int gap  = match[i] - prev;
7f561c08de6b Initial load
duke
parents:
diff changeset
   126
7f561c08de6b Initial load
duke
parents:
diff changeset
   127
      for(int j=1; j < gap; j++) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   128
        m_vec[count] = prev + j;
7f561c08de6b Initial load
duke
parents:
diff changeset
   129
        t_vec[count] = target;
7f561c08de6b Initial load
duke
parents:
diff changeset
   130
        count++;
7f561c08de6b Initial load
duke
parents:
diff changeset
   131
      }
7f561c08de6b Initial load
duke
parents:
diff changeset
   132
7f561c08de6b Initial load
duke
parents:
diff changeset
   133
      m_vec[count] = match[i];
7f561c08de6b Initial load
duke
parents:
diff changeset
   134
      t_vec[count] = targets[i];
7f561c08de6b Initial load
duke
parents:
diff changeset
   135
      count++;
7f561c08de6b Initial load
duke
parents:
diff changeset
   136
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   137
7f561c08de6b Initial load
duke
parents:
diff changeset
   138
    match   = new int[count];
7f561c08de6b Initial load
duke
parents:
diff changeset
   139
    targets = new InstructionHandle[count];
7f561c08de6b Initial load
duke
parents:
diff changeset
   140
7f561c08de6b Initial load
duke
parents:
diff changeset
   141
    System.arraycopy(m_vec, 0, match, 0, count);
7f561c08de6b Initial load
duke
parents:
diff changeset
   142
    System.arraycopy(t_vec, 0, targets, 0, count);
7f561c08de6b Initial load
duke
parents:
diff changeset
   143
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   144
7f561c08de6b Initial load
duke
parents:
diff changeset
   145
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   146
   * Sort match and targets array with QuickSort.
7f561c08de6b Initial load
duke
parents:
diff changeset
   147
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   148
  private final void sort(int l, int r) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   149
    int i = l, j = r;
7f561c08de6b Initial load
duke
parents:
diff changeset
   150
    int h, m = match[(l + r) / 2];
7f561c08de6b Initial load
duke
parents:
diff changeset
   151
    InstructionHandle h2;
7f561c08de6b Initial load
duke
parents:
diff changeset
   152
7f561c08de6b Initial load
duke
parents:
diff changeset
   153
    do {
7f561c08de6b Initial load
duke
parents:
diff changeset
   154
      while(match[i] < m) i++;
7f561c08de6b Initial load
duke
parents:
diff changeset
   155
      while(m < match[j]) j--;
7f561c08de6b Initial load
duke
parents:
diff changeset
   156
7f561c08de6b Initial load
duke
parents:
diff changeset
   157
      if(i <= j) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   158
        h=match[i]; match[i]=match[j]; match[j]=h; // Swap elements
7f561c08de6b Initial load
duke
parents:
diff changeset
   159
        h2=targets[i]; targets[i]=targets[j]; targets[j]=h2; // Swap instructions, too
7f561c08de6b Initial load
duke
parents:
diff changeset
   160
        i++; j--;
7f561c08de6b Initial load
duke
parents:
diff changeset
   161
      }
7f561c08de6b Initial load
duke
parents:
diff changeset
   162
    } while(i <= j);
7f561c08de6b Initial load
duke
parents:
diff changeset
   163
7f561c08de6b Initial load
duke
parents:
diff changeset
   164
    if(l < j) sort(l, j);
7f561c08de6b Initial load
duke
parents:
diff changeset
   165
    if(i < r) sort(i, r);
7f561c08de6b Initial load
duke
parents:
diff changeset
   166
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   167
7f561c08de6b Initial load
duke
parents:
diff changeset
   168
  /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   169
   * @return match is sorted in ascending order with no gap bigger than max_gap?
7f561c08de6b Initial load
duke
parents:
diff changeset
   170
   */
7f561c08de6b Initial load
duke
parents:
diff changeset
   171
  private final boolean matchIsOrdered(int max_gap) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   172
    for(int i=1; i < match_length; i++)
7f561c08de6b Initial load
duke
parents:
diff changeset
   173
      if(match[i] - match[i-1] > max_gap)
7f561c08de6b Initial load
duke
parents:
diff changeset
   174
        return false;
7f561c08de6b Initial load
duke
parents:
diff changeset
   175
7f561c08de6b Initial load
duke
parents:
diff changeset
   176
    return true;
7f561c08de6b Initial load
duke
parents:
diff changeset
   177
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   178
7f561c08de6b Initial load
duke
parents:
diff changeset
   179
  public final InstructionList getInstructionList() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   180
    return new InstructionList(instruction);
7f561c08de6b Initial load
duke
parents:
diff changeset
   181
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   182
7f561c08de6b Initial load
duke
parents:
diff changeset
   183
  public final Instruction getInstruction() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   184
    return instruction;
7f561c08de6b Initial load
duke
parents:
diff changeset
   185
  }
7f561c08de6b Initial load
duke
parents:
diff changeset
   186
}