You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2014/09/17 12:34:51 UTC

svn commit: r1625504 - in /tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile: ClassParser.java FastDataInputStream.java

Author: markt
Date: Wed Sep 17 10:34:51 2014
New Revision: 1625504

URL: http://svn.apache.org/r1625504
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=56953
Further performance improvements to BCEL parser.
Based on a patch by hzhang9

Added:
    tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/FastDataInputStream.java   (with props)
Modified:
    tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/ClassParser.java

Modified: tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/ClassParser.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/ClassParser.java?rev=1625504&r1=1625503&r2=1625504&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/ClassParser.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/ClassParser.java Wed Sep 17 10:34:51 2014
@@ -17,9 +17,7 @@
  */
 package org.apache.tomcat.util.bcel.classfile;
 
-import java.io.BufferedInputStream;
 import java.io.DataInput;
-import java.io.DataInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 
@@ -59,7 +57,7 @@ public final class ClassParser {
      * @param file Input stream
      */
     public ClassParser(InputStream file) {
-        this.file = new DataInputStream(new BufferedInputStream(file, BUFSIZE));
+        this.file = new FastDataInputStream(file, BUFSIZE);
     }
 
 

Added: tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/FastDataInputStream.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/FastDataInputStream.java?rev=1625504&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/FastDataInputStream.java (added)
+++ tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/FastDataInputStream.java Wed Sep 17 10:34:51 2014
@@ -0,0 +1,236 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.util.bcel.classfile;
+
+import java.io.BufferedInputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A "FastDataInputStream" that get the numbers from buffer and from the target
+ * directly instead of "DataInputStream".
+ */
+class FastDataInputStream extends BufferedInputStream implements DataInput {
+
+    private final byte readBuffer[] = new byte[8];
+
+
+    public FastDataInputStream(InputStream in, int size) {
+        super(in, size);
+    }
+
+
+    @Override
+    public final int read(byte b[]) throws IOException {
+        return this.read(b, 0, b.length);
+    }
+
+
+    @Override
+    public final void readFully(byte b[]) throws IOException {
+        readFully(b, 0, b.length);
+    }
+
+
+    @Override
+    public final void readFully(byte b[], int off, int len) throws IOException {
+        if (len < 0)
+            throw new IndexOutOfBoundsException();
+        // Total read
+        int sum = 0;
+        // Current read
+        int cur = 0;
+        for(; sum < len; sum += cur){
+            cur = read(b, off + sum, len - sum);
+            if(cur < 0)
+                throw new EOFException();
+            sum += cur;
+        }
+    }
+
+
+    @Override
+    public boolean readBoolean() throws IOException {
+        if (pos >= count) {
+            fillNew();
+            if (pos >= count)
+                throw new EOFException();
+        }
+        int ch = this.buf[pos++] & 0xff;
+        return (ch != 0);
+    }
+
+
+    @Override
+    public final byte readByte() throws IOException {
+        if (pos >= count) {
+            fillNew();
+            if (pos >= count)
+                throw new EOFException();
+        }
+        return this.buf[pos++];
+    }
+
+
+    @Override
+    public int readUnsignedByte() throws IOException {
+        if (pos >= count) {
+            fillNew();
+            if (pos >= count)
+                throw new EOFException();
+        }
+        int ch = this.buf[pos++] & 0xff;
+        return ch;
+    }
+
+
+    @Override
+    public final short readShort() throws IOException {
+        if(pos + 1 >= count){
+            fillNew();
+            if(pos + 1 >= count) throw new EOFException();
+        }
+        int ch1 = this.buf[pos++] & 0xff;
+        int ch2 = this.buf[pos++] & 0xff;
+        return (short)((ch1 << 8) + (ch2 << 0));
+    }
+
+
+    @Override
+    public int readUnsignedShort() throws IOException{
+        if(pos + 1 >= count) {
+            fillNew();
+            if(pos + 1 >= count) throw new EOFException();
+        }
+
+        int ch1 = this.buf[pos++] & 0xff;
+        int ch2 = this.buf[pos++] & 0xff;
+        return (ch1 << 8) + (ch2 << 0);
+    }
+
+
+    @Override
+    public final char readChar() throws IOException {
+        if(pos + 1 >= count) {
+            fillNew();
+            if(pos + 1 >= count) throw new EOFException();
+        }
+        int ch1 = this.buf[pos++] & 0xff;
+        int ch2 = this.buf[pos++] & 0xff;
+        return (char)((ch1 << 8) + (ch2 << 0));
+    }
+
+
+    @Override
+    public final int readInt() throws IOException {
+        if(pos + 3 >= count){
+            fillNew();
+            if(pos + 3 >= count) throw new EOFException();
+        }
+        int ch1 = this.buf[pos++] & 0xff;
+        int ch2 = this.buf[pos++] & 0xff;
+        int ch3 = this.buf[pos++] & 0xff;
+        int ch4 = this.buf[pos++] & 0xff;
+        return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
+    }
+
+
+    @Override
+    public final long readLong() throws IOException {
+        readFully(readBuffer, 0, 8);
+        return (((long)readBuffer[0] << 56) +
+                ((long)(readBuffer[1] & 255) << 48) +
+                ((long)(readBuffer[2] & 255) << 40) +
+                ((long)(readBuffer[3] & 255) << 32) +
+                ((long)(readBuffer[4] & 255) << 24) +
+                ((readBuffer[5] & 255) << 16) +
+                ((readBuffer[6] & 255) <<  8) +
+                ((readBuffer[7] & 255) <<  0));
+    }
+
+
+    @Override
+    public final float readFloat() throws IOException {
+        return Float.intBitsToFloat(readInt());
+    }
+
+
+    @Override
+    public double readDouble() throws IOException {
+        return Double.longBitsToDouble(readLong());
+    }
+
+
+    @Override
+    public final String readUTF() throws IOException {
+        return DataInputStream.readUTF(this);
+    }
+
+
+    private void fillNew() throws IOException {
+        int remain = 0;
+        if(pos < count){
+            remain = count - pos;
+            System.arraycopy(buf, pos, buf, 0, remain);
+        }
+        pos = 0;
+        int n = this.in.read(buf, remain, buf.length - remain);
+        count = pos + n + remain;
+    }
+
+
+    @Override
+    public int skipBytes(int n) throws IOException {
+        int avail = count - pos;
+        // Total Skipped
+        int sum = 0;
+        // Current skipped
+        int cur = 0;
+        if (avail <= 0) {
+            // buffer is exhausted, read via stream directly
+            while (sum < n && (cur = (int) in.skip(n - sum)) > 0) {
+                sum += cur;
+            }
+            fillNew();
+            return sum;
+        }
+        // Data in the buffer is not enough
+        if(n > avail){
+            // Skip the data in buffer
+            pos += avail;
+            sum += avail;
+            // Read via stream
+            while (sum < n && (cur = (int) in.skip(n - sum)) > 0) {
+                sum += cur;
+            }
+            fillNew();
+            return sum;
+        }
+        pos += n;
+        return n;
+    }
+
+
+    @Override
+    public String readLine() throws IOException {
+        // Unimplemented
+        throw new IOException();
+    }
+}
\ No newline at end of file

Propchange: tomcat/trunk/java/org/apache/tomcat/util/bcel/classfile/FastDataInputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org