1 /* 2 * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 package com.sun.hotspot.tools.compiler; 26 27 import java.io.*; 28 import java.util.regex.*; 29 30 /** 31 * This class is a filter class to deal with malformed XML that used 32 * to be produced by the JVM when generating LogCompilation. In 1.6 33 * and later releases it shouldn't be required. 34 */ 35 class LogCleanupReader extends Reader { 36 37 private Reader reader; 38 39 private char[] buffer = new char[4096]; 40 41 private int bufferCount; 42 43 private int bufferOffset; 44 45 private char[] line = new char[1024]; 46 47 private int index; 48 49 private int length; 50 51 private char[] one = new char[1]; 52 53 LogCleanupReader(Reader r) { 54 reader = r; 55 } 56 57 static final private Matcher duplicateCompileID = Pattern.compile(".+ compile_id='[0-9]+'.*( compile_id='[0-9]+)").matcher(""); 58 static final private Matcher compilerName = Pattern.compile("' (C[12]) compile_id=").matcher(""); 59 static final private Matcher destroyVM = Pattern.compile("'(destroy_vm)/").matcher(""); 60 61 /** 62 * The log cleanup takes place in this method. If any of the three patterns 63 * ({@link #duplicateCompileID}, {@link #compilerName}, {@link #destroyVM}) 64 * match, that indicates a problem in the log. The cleanup is performed by 65 * correcting the input line and writing it back into the {@link #line} 66 * buffer. 67 */ 68 private void fill() throws IOException { 69 rawFill(); 70 if (length != -1) { 71 boolean changed = false; 72 String s = new String(line, 0, length); 73 74 compilerName.reset(s); 75 if (compilerName.find()) { 76 s = s.substring(0, compilerName.start(1)) + s.substring(compilerName.end(1) + 1); 77 changed = true; 78 } 79 80 duplicateCompileID.reset(s); 81 if (duplicateCompileID.lookingAt()) { 82 s = s.substring(0, duplicateCompileID.start(1)) + s.substring(duplicateCompileID.end(1) + 1); 83 changed = true; 84 } 85 86 destroyVM.reset(s); 87 if (destroyVM.find()) { 88 s = s.substring(0, destroyVM.start(1)) + s.substring(destroyVM.end(1)); 89 changed = true; 90 } 91 92 if (changed) { 93 s.getChars(0, s.length(), line, 0); 94 length = s.length(); 95 } 96 } 97 } 98 99 private void rawFill() throws IOException { 100 if (bufferCount == -1) { 101 length = -1; 102 return; 103 } 104 105 int i = 0; 106 boolean fillNonEOL = true; 107 outer: 108 while (true) { 109 if (fillNonEOL) { 110 int p; 111 for (p = bufferOffset; p < bufferCount; p++) { 112 char c = buffer[p]; 113 if (c == '\r' || c == '\n') { 114 bufferOffset = p; 115 fillNonEOL = false; 116 continue outer; 117 } 118 if (i >= line.length) { 119 // copy and enlarge the line array 120 char[] newLine = new char[line.length * 2]; 121 System.arraycopy(line, 0, newLine, 0, line.length); 122 line = newLine; 123 } 124 line[i++] = c; 125 } 126 bufferOffset = p; 127 } else { 128 int p; 129 for (p = bufferOffset; p < bufferCount; p++) { 130 char c = buffer[p]; 131 if (c != '\r' && c != '\n') { 132 bufferOffset = p; 133 length = i; 134 index = 0; 135 return; 136 } 137 line[i++] = c; 138 } 139 bufferOffset = p; 140 } 141 if (bufferCount == -1) { 142 if (i == 0) { 143 length = -1; 144 } else { 145 length = i; 146 } 147 index = 0; 148 return; 149 } 150 if (bufferOffset != bufferCount) { 151 System.out.println(bufferOffset); 152 System.out.println(bufferCount); 153 throw new InternalError("how did we get here"); 154 } 155 // load more data and try again. 156 bufferCount = reader.read(buffer, 0, buffer.length); 157 bufferOffset = 0; 158 } 159 } 160 161 public int read() throws java.io.IOException { 162 read(one, 0, 1); 163 return one[0]; 164 } 165 166 public int read(char[] buffer) throws java.io.IOException { 167 return read(buffer, 0, buffer.length); 168 } 169 170 public int read(char[] b, int off, int len) throws java.io.IOException { 171 if (length == -1) { 172 return -1; 173 } 174 175 if (index == length) { 176 fill(); 177 if (length == -1) { 178 return -1; 179 } 180 } 181 int n = Math.min(length - index, Math.min(b.length - off, len)); 182 // System.out.printf("%d %d %d %d %d\n", index, length, off, len, n); 183 System.arraycopy(line, index, b, off, n); 184 index += n; 185 return n; 186 } 187 188 public long skip(long n) throws java.io.IOException { 189 long result = n; 190 while (n-- > 0) read(); 191 return result; 192 } 193 194 public boolean ready() throws java.io.IOException { 195 return reader.ready() || (line != null && length > 0); 196 } 197 198 public boolean markSupported() { 199 return false; 200 } 201 202 public void mark(int unused) throws java.io.IOException { 203 throw new UnsupportedOperationException("mark not supported"); 204 } 205 206 public void reset() throws java.io.IOException { 207 reader.reset(); 208 line = null; 209 index = 0; 210 } 211 212 public void close() throws java.io.IOException { 213 reader.close(); 214 line = null; 215 index = 0; 216 } 217 }