changeset 2379:ff9c2f53594e

6745393: Inflater/Deflater clone issue Summary: To use explicit lobk object. Reviewed-by: alanb
author sherman
date Wed, 25 Nov 2009 11:29:23 -0800
parents e943f6b0b0e9
children d893f890b4dd
files src/share/classes/java/util/zip/Deflater.java src/share/classes/java/util/zip/Inflater.java src/share/native/java/util/zip/Deflater.c src/share/native/java/util/zip/Inflater.c
diffstat 4 files changed, 338 insertions(+), 296 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/zip/Deflater.java	Wed Nov 25 10:02:50 2009 +0000
+++ b/src/share/classes/java/util/zip/Deflater.java	Wed Nov 25 11:29:23 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -72,7 +72,8 @@
  */
 public
 class Deflater {
-    private long strm;
+
+    private final ZStreamRef zsRef;
     private byte[] buf = new byte[0];
     private int off, len;
     private int level, strategy;
@@ -165,7 +166,7 @@
     public Deflater(int level, boolean nowrap) {
         this.level = level;
         this.strategy = DEFAULT_STRATEGY;
-        strm = init(level, DEFAULT_STRATEGY, nowrap);
+        this.zsRef = new ZStreamRef(init(level, DEFAULT_STRATEGY, nowrap));
     }
 
     /**
@@ -193,16 +194,18 @@
      * @param len the length of the data
      * @see Deflater#needsInput
      */
-    public synchronized void setInput(byte[] b, int off, int len) {
+    public void setInput(byte[] b, int off, int len) {
         if (b== null) {
             throw new NullPointerException();
         }
         if (off < 0 || len < 0 || off > b.length - len) {
             throw new ArrayIndexOutOfBoundsException();
         }
-        this.buf = b;
-        this.off = off;
-        this.len = len;
+        synchronized (zsRef) {
+            this.buf = b;
+            this.off = off;
+            this.len = len;
+        }
     }
 
     /**
@@ -227,14 +230,17 @@
      * @see Inflater#inflate
      * @see Inflater#getAdler
      */
-    public synchronized void setDictionary(byte[] b, int off, int len) {
-        if (strm == 0 || b == null) {
+    public void setDictionary(byte[] b, int off, int len) {
+        if (b == null) {
             throw new NullPointerException();
         }
         if (off < 0 || len < 0 || off > b.length - len) {
             throw new ArrayIndexOutOfBoundsException();
         }
-        setDictionary(strm, b, off, len);
+        synchronized (zsRef) {
+            ensureOpen();
+            setDictionary(zsRef.address(), b, off, len);
+        }
     }
 
     /**
@@ -257,7 +263,7 @@
      * @exception IllegalArgumentException if the compression strategy is
      *                                     invalid
      */
-    public synchronized void setStrategy(int strategy) {
+    public void setStrategy(int strategy) {
         switch (strategy) {
           case DEFAULT_STRATEGY:
           case FILTERED:
@@ -266,9 +272,11 @@
           default:
             throw new IllegalArgumentException();
         }
-        if (this.strategy != strategy) {
-            this.strategy = strategy;
-            setParams = true;
+        synchronized (zsRef) {
+            if (this.strategy != strategy) {
+                this.strategy = strategy;
+                setParams = true;
+            }
         }
     }
 
@@ -277,13 +285,15 @@
      * @param level the new compression level (0-9)
      * @exception IllegalArgumentException if the compression level is invalid
      */
-    public synchronized void setLevel(int level) {
+    public void setLevel(int level) {
         if ((level < 0 || level > 9) && level != DEFAULT_COMPRESSION) {
             throw new IllegalArgumentException("invalid compression level");
         }
-        if (this.level != level) {
-            this.level = level;
-            setParams = true;
+        synchronized (zsRef) {
+            if (this.level != level) {
+                this.level = level;
+                setParams = true;
+            }
         }
     }
 
@@ -301,8 +311,10 @@
      * When called, indicates that compression should end with the current
      * contents of the input buffer.
      */
-    public synchronized void finish() {
-        finish = true;
+    public void finish() {
+        synchronized (zsRef) {
+            finish = true;
+        }
     }
 
     /**
@@ -311,8 +323,10 @@
      * @return true if the end of the compressed data output stream has
      * been reached
      */
-    public synchronized boolean finished() {
-        return finished;
+    public boolean finished() {
+        synchronized (zsRef) {
+            return finished;
+        }
     }
 
     /**
@@ -399,26 +413,31 @@
      * @throws IllegalArgumentException if the flush mode is invalid
      * @since 1.7
      */
-    public synchronized int deflate(byte[] b, int off, int len, int flush) {
+    public int deflate(byte[] b, int off, int len, int flush) {
         if (b == null) {
             throw new NullPointerException();
         }
         if (off < 0 || len < 0 || off > b.length - len) {
             throw new ArrayIndexOutOfBoundsException();
         }
-        if (flush == NO_FLUSH || flush == SYNC_FLUSH ||
-            flush == FULL_FLUSH)
-            return deflateBytes(b, off, len, flush);
-        throw new IllegalArgumentException();
+        synchronized (zsRef) {
+            ensureOpen();
+            if (flush == NO_FLUSH || flush == SYNC_FLUSH ||
+                flush == FULL_FLUSH)
+                return deflateBytes(zsRef.address(), b, off, len, flush);
+            throw new IllegalArgumentException();
+        }
     }
 
     /**
      * Returns the ADLER-32 value of the uncompressed data.
      * @return the ADLER-32 value of the uncompressed data
      */
-    public synchronized int getAdler() {
-        ensureOpen();
-        return getAdler(strm);
+    public int getAdler() {
+        synchronized (zsRef) {
+            ensureOpen();
+            return getAdler(zsRef.address());
+        }
     }
 
     /**
@@ -440,9 +459,11 @@
      * @return the total (non-negative) number of uncompressed bytes input so far
      * @since 1.5
      */
-    public synchronized long getBytesRead() {
-        ensureOpen();
-        return getBytesRead(strm);
+    public long getBytesRead() {
+        synchronized (zsRef) {
+            ensureOpen();
+            return getBytesRead(zsRef.address());
+        }
     }
 
     /**
@@ -464,21 +485,25 @@
      * @return the total (non-negative) number of compressed bytes output so far
      * @since 1.5
      */
-    public synchronized long getBytesWritten() {
-        ensureOpen();
-        return getBytesWritten(strm);
+    public long getBytesWritten() {
+        synchronized (zsRef) {
+            ensureOpen();
+            return getBytesWritten(zsRef.address());
+        }
     }
 
     /**
      * Resets deflater so that a new set of input data can be processed.
      * Keeps current compression level and strategy settings.
      */
-    public synchronized void reset() {
-        ensureOpen();
-        reset(strm);
-        finish = false;
-        finished = false;
-        off = len = 0;
+    public void reset() {
+        synchronized (zsRef) {
+            ensureOpen();
+            reset(zsRef.address());
+            finish = false;
+            finished = false;
+            off = len = 0;
+        }
     }
 
     /**
@@ -488,11 +513,14 @@
      * finalize() method. Once this method is called, the behavior
      * of the Deflater object is undefined.
      */
-    public synchronized void end() {
-        if (strm != 0) {
-            end(strm);
-            strm = 0;
-            buf = null;
+    public void end() {
+        synchronized (zsRef) {
+            long addr = zsRef.address();
+            zsRef.clear();
+            if (addr != 0) {
+                end(addr);
+                buf = null;
+            }
         }
     }
 
@@ -504,18 +532,19 @@
     }
 
     private void ensureOpen() {
-        if (strm == 0)
-            throw new NullPointerException();
+        assert Thread.holdsLock(zsRef);
+        if (zsRef.address() == 0)
+            throw new NullPointerException("Deflater has been closed");
     }
 
     private static native void initIDs();
     private native static long init(int level, int strategy, boolean nowrap);
-    private native static void setDictionary(long strm, byte[] b, int off,
-                                             int len);
-    private native int deflateBytes(byte[] b, int off, int len, int flush);
-    private native static int getAdler(long strm);
-    private native static long getBytesRead(long strm);
-    private native static long getBytesWritten(long strm);
-    private native static void reset(long strm);
-    private native static void end(long strm);
+    private native static void setDictionary(long addr, byte[] b, int off, int len);
+    private native int deflateBytes(long addr, byte[] b, int off, int len,
+                                    int flush);
+    private native static int getAdler(long addr);
+    private native static long getBytesRead(long addr);
+    private native static long getBytesWritten(long addr);
+    private native static void reset(long addr);
+    private native static void end(long addr);
 }
--- a/src/share/classes/java/util/zip/Inflater.java	Wed Nov 25 10:02:50 2009 +0000
+++ b/src/share/classes/java/util/zip/Inflater.java	Wed Nov 25 11:29:23 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -72,7 +72,8 @@
  */
 public
 class Inflater {
-    private long strm;
+
+    private final ZStreamRef zsRef;
     private byte[] buf = defaultBuf;
     private int off, len;
     private boolean finished;
@@ -97,7 +98,7 @@
      * @param nowrap if true then support GZIP compatible compression
      */
     public Inflater(boolean nowrap) {
-        strm = init(nowrap);
+        zsRef = new ZStreamRef(init(nowrap));
     }
 
     /**
@@ -116,16 +117,18 @@
      * @param len the length of the input data
      * @see Inflater#needsInput
      */
-    public synchronized void setInput(byte[] b, int off, int len) {
+    public void setInput(byte[] b, int off, int len) {
         if (b == null) {
             throw new NullPointerException();
         }
         if (off < 0 || len < 0 || off > b.length - len) {
             throw new ArrayIndexOutOfBoundsException();
         }
-        this.buf = b;
-        this.off = off;
-        this.len = len;
+        synchronized (zsRef) {
+            this.buf = b;
+            this.off = off;
+            this.len = len;
+        }
     }
 
     /**
@@ -150,15 +153,18 @@
      * @see Inflater#needsDictionary
      * @see Inflater#getAdler
      */
-    public synchronized void setDictionary(byte[] b, int off, int len) {
-        if (strm == 0 || b == null) {
+    public void setDictionary(byte[] b, int off, int len) {
+        if (b == null) {
             throw new NullPointerException();
         }
         if (off < 0 || len < 0 || off > b.length - len) {
             throw new ArrayIndexOutOfBoundsException();
         }
-        setDictionary(strm, b, off, len);
-        needDict = false;
+        synchronized (zsRef) {
+            ensureOpen();
+            setDictionary(zsRef.address(), b, off, len);
+            needDict = false;
+        }
     }
 
     /**
@@ -180,8 +186,10 @@
      * buffer after decompression has finished.
      * @return the total number of bytes remaining in the input buffer
      */
-    public synchronized int getRemaining() {
-        return len;
+    public int getRemaining() {
+        synchronized (zsRef) {
+            return len;
+        }
     }
 
     /**
@@ -190,8 +198,10 @@
      * to provide more input.
      * @return true if no data remains in the input buffer
      */
-    public synchronized boolean needsInput() {
-        return len <= 0;
+    public boolean needsInput() {
+        synchronized (zsRef) {
+            return len <= 0;
+        }
     }
 
     /**
@@ -199,8 +209,10 @@
      * @return true if a preset dictionary is needed for decompression
      * @see Inflater#setDictionary
      */
-    public synchronized boolean needsDictionary() {
-        return needDict;
+    public boolean needsDictionary() {
+        synchronized (zsRef) {
+            return needDict;
+        }
     }
 
     /**
@@ -209,8 +221,10 @@
      * @return true if the end of the compressed data stream has been
      * reached
      */
-    public synchronized boolean finished() {
-        return finished;
+    public boolean finished() {
+        synchronized (zsRef) {
+            return finished;
+        }
     }
 
     /**
@@ -228,7 +242,7 @@
      * @see Inflater#needsInput
      * @see Inflater#needsDictionary
      */
-    public synchronized int inflate(byte[] b, int off, int len)
+    public int inflate(byte[] b, int off, int len)
         throws DataFormatException
     {
         if (b == null) {
@@ -237,7 +251,10 @@
         if (off < 0 || len < 0 || off > b.length - len) {
             throw new ArrayIndexOutOfBoundsException();
         }
-        return inflateBytes(b, off, len);
+        synchronized (zsRef) {
+            ensureOpen();
+            return inflateBytes(zsRef.address(), b, off, len);
+        }
     }
 
     /**
@@ -261,9 +278,11 @@
      * Returns the ADLER-32 value of the uncompressed data.
      * @return the ADLER-32 value of the uncompressed data
      */
-    public synchronized int getAdler() {
-        ensureOpen();
-        return getAdler(strm);
+    public int getAdler() {
+        synchronized (zsRef) {
+            ensureOpen();
+            return getAdler(zsRef.address());
+        }
     }
 
     /**
@@ -285,9 +304,11 @@
      * @return the total (non-negative) number of compressed bytes input so far
      * @since 1.5
      */
-    public synchronized long getBytesRead() {
-        ensureOpen();
-        return getBytesRead(strm);
+    public long getBytesRead() {
+        synchronized (zsRef) {
+            ensureOpen();
+            return getBytesRead(zsRef.address());
+        }
     }
 
     /**
@@ -309,21 +330,25 @@
      * @return the total (non-negative) number of uncompressed bytes output so far
      * @since 1.5
      */
-    public synchronized long getBytesWritten() {
-        ensureOpen();
-        return getBytesWritten(strm);
+    public long getBytesWritten() {
+        synchronized (zsRef) {
+            ensureOpen();
+            return getBytesWritten(zsRef.address());
+        }
     }
 
     /**
      * Resets inflater so that a new set of input data can be processed.
      */
-    public synchronized void reset() {
-        ensureOpen();
-        reset(strm);
-        buf = defaultBuf;
-        finished = false;
-        needDict = false;
-        off = len = 0;
+    public void reset() {
+        synchronized (zsRef) {
+            ensureOpen();
+            reset(zsRef.address());
+            buf = defaultBuf;
+            finished = false;
+            needDict = false;
+            off = len = 0;
+        }
     }
 
     /**
@@ -333,11 +358,14 @@
      * method. Once this method is called, the behavior of the Inflater
      * object is undefined.
      */
-    public synchronized void end() {
-        if (strm != 0) {
-            end(strm);
-            strm = 0;
-            buf = null;
+    public void end() {
+        synchronized (zsRef) {
+            long addr = zsRef.address();
+            zsRef.clear();
+            if (addr != 0) {
+                end(addr);
+                buf = null;
+            }
         }
     }
 
@@ -349,19 +377,20 @@
     }
 
     private void ensureOpen () {
-        if (strm == 0)
-            throw new NullPointerException();
+        assert Thread.holdsLock(zsRef);
+        if (zsRef.address() == 0)
+            throw new NullPointerException("Inflater has been closed");
     }
 
     private native static void initIDs();
     private native static long init(boolean nowrap);
-    private native static void setDictionary(long strm, byte[] b, int off,
+    private native static void setDictionary(long addr, byte[] b, int off,
                                              int len);
-    private native int inflateBytes(byte[] b, int off, int len)
+    private native int inflateBytes(long addr, byte[] b, int off, int len)
             throws DataFormatException;
-    private native static int getAdler(long strm);
-    private native static long getBytesRead(long strm);
-    private native static long getBytesWritten(long strm);
-    private native static void reset(long strm);
-    private native static void end(long strm);
+    private native static int getAdler(long addr);
+    private native static long getBytesRead(long addr);
+    private native static long getBytesWritten(long addr);
+    private native static void reset(long addr);
+    private native static void end(long addr);
 }
--- a/src/share/native/java/util/zip/Deflater.c	Wed Nov 25 10:02:50 2009 +0000
+++ b/src/share/native/java/util/zip/Deflater.c	Wed Nov 25 11:29:23 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,7 +38,6 @@
 
 #define DEF_MEM_LEVEL 8
 
-static jfieldID strmID;
 static jfieldID levelID;
 static jfieldID strategyID;
 static jfieldID setParamsID;
@@ -49,7 +48,6 @@
 JNIEXPORT void JNICALL
 Java_java_util_zip_Deflater_initIDs(JNIEnv *env, jclass cls)
 {
-    strmID = (*env)->GetFieldID(env, cls, "strm", "J");
     levelID = (*env)->GetFieldID(env, cls, "level", "I");
     strategyID = (*env)->GetFieldID(env, cls, "strategy", "I");
     setParamsID = (*env)->GetFieldID(env, cls, "setParams", "Z");
@@ -94,7 +92,7 @@
 }
 
 JNIEXPORT void JNICALL
-Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong strm,
+Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr,
                                           jarray b, jint off, jint len)
 {
     Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
@@ -102,7 +100,7 @@
     if (buf == 0) {/* out of memory */
         return;
     }
-    res = deflateSetDictionary((z_stream *)jlong_to_ptr(strm), buf + off, len);
+    res = deflateSetDictionary((z_stream *)jlong_to_ptr(addr), buf + off, len);
     (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0);
     switch (res) {
     case Z_OK:
@@ -111,151 +109,144 @@
         JNU_ThrowIllegalArgumentException(env, 0);
         break;
     default:
-        JNU_ThrowInternalError(env, ((z_stream *)jlong_to_ptr(strm))->msg);
+        JNU_ThrowInternalError(env, ((z_stream *)jlong_to_ptr(addr))->msg);
         break;
     }
 }
 
 JNIEXPORT jint JNICALL
-Java_java_util_zip_Deflater_deflateBytes(JNIEnv *env, jobject this,
+Java_java_util_zip_Deflater_deflateBytes(JNIEnv *env, jobject this, jlong addr,
                                          jarray b, jint off, jint len, jint flush)
 {
-    z_stream *strm = jlong_to_ptr((*env)->GetLongField(env, this, strmID));
+    z_stream *strm = jlong_to_ptr(addr);
 
-    if (strm == 0) {
-        JNU_ThrowNullPointerException(env, 0);
-        return 0;
-    } else {
-        jarray this_buf = (*env)->GetObjectField(env, this, bufID);
-        jint this_off = (*env)->GetIntField(env, this, offID);
-        jint this_len = (*env)->GetIntField(env, this, lenID);
-        jbyte *in_buf;
-        jbyte *out_buf;
-        int res;
-        if ((*env)->GetBooleanField(env, this, setParamsID)) {
-            int level = (*env)->GetIntField(env, this, levelID);
-            int strategy = (*env)->GetIntField(env, this, strategyID);
+    jarray this_buf = (*env)->GetObjectField(env, this, bufID);
+    jint this_off = (*env)->GetIntField(env, this, offID);
+    jint this_len = (*env)->GetIntField(env, this, lenID);
+    jbyte *in_buf;
+    jbyte *out_buf;
+    int res;
+    if ((*env)->GetBooleanField(env, this, setParamsID)) {
+        int level = (*env)->GetIntField(env, this, levelID);
+        int strategy = (*env)->GetIntField(env, this, strategyID);
 
-            in_buf = (jbyte *) malloc(this_len);
-            if (in_buf == 0) {
-                JNU_ThrowOutOfMemoryError(env, 0);
-                return 0;
-            }
-            (*env)->GetByteArrayRegion(env, this_buf, this_off, this_len, in_buf);
+        in_buf = (jbyte *) malloc(this_len);
+        if (in_buf == 0) {
+            JNU_ThrowOutOfMemoryError(env, 0);
+            return 0;
+        }
+        (*env)->GetByteArrayRegion(env, this_buf, this_off, this_len, in_buf);
+        out_buf = (jbyte *) malloc(len);
+        if (out_buf == 0) {
+            free(in_buf);
+            JNU_ThrowOutOfMemoryError(env, 0);
+            return 0;
+        }
 
-            out_buf = (jbyte *) malloc(len);
-            if (out_buf == 0) {
-                free(in_buf);
-                JNU_ThrowOutOfMemoryError(env, 0);
-                return 0;
-            }
+        strm->next_in = (Bytef *) in_buf;
+        strm->next_out = (Bytef *) out_buf;
+        strm->avail_in = this_len;
+        strm->avail_out = len;
+        res = deflateParams(strm, level, strategy);
 
-            strm->next_in = (Bytef *) in_buf;
-            strm->next_out = (Bytef *) out_buf;
-            strm->avail_in = this_len;
-            strm->avail_out = len;
-            res = deflateParams(strm, level, strategy);
-
-            if (res == Z_OK) {
-                (*env)->SetByteArrayRegion(env, b, off, len - strm->avail_out, out_buf);
-            }
-            free(out_buf);
-            free(in_buf);
+        if (res == Z_OK) {
+            (*env)->SetByteArrayRegion(env, b, off, len - strm->avail_out, out_buf);
+        }
+        free(out_buf);
+        free(in_buf);
 
-            switch (res) {
-            case Z_OK:
-                (*env)->SetBooleanField(env, this, setParamsID, JNI_FALSE);
-                this_off += this_len - strm->avail_in;
-                (*env)->SetIntField(env, this, offID, this_off);
-                (*env)->SetIntField(env, this, lenID, strm->avail_in);
-                return len - strm->avail_out;
-            case Z_BUF_ERROR:
-                (*env)->SetBooleanField(env, this, setParamsID, JNI_FALSE);
-                return 0;
-            default:
-                JNU_ThrowInternalError(env, strm->msg);
-                return 0;
-            }
-        } else {
-            jboolean finish = (*env)->GetBooleanField(env, this, finishID);
-
-            in_buf = (jbyte *) malloc(this_len);
-            if (in_buf == 0) {
-                JNU_ThrowOutOfMemoryError(env, 0);
-                return 0;
-            }
-            (*env)->GetByteArrayRegion(env, this_buf, this_off, this_len, in_buf);
+        switch (res) {
+        case Z_OK:
+            (*env)->SetBooleanField(env, this, setParamsID, JNI_FALSE);
+            this_off += this_len - strm->avail_in;
+            (*env)->SetIntField(env, this, offID, this_off);
+            (*env)->SetIntField(env, this, lenID, strm->avail_in);
+            return len - strm->avail_out;
+        case Z_BUF_ERROR:
+            (*env)->SetBooleanField(env, this, setParamsID, JNI_FALSE);
+            return 0;
+        default:
+            JNU_ThrowInternalError(env, strm->msg);
+            return 0;
+        }
+    } else {
+        jboolean finish = (*env)->GetBooleanField(env, this, finishID);
+        in_buf = (jbyte *) malloc(this_len);
+        if (in_buf == 0) {
+            JNU_ThrowOutOfMemoryError(env, 0);
+            return 0;
+        }
+        (*env)->GetByteArrayRegion(env, this_buf, this_off, this_len, in_buf);
 
-            out_buf = (jbyte *) malloc(len);
-            if (out_buf == 0) {
-                free(in_buf);
-                JNU_ThrowOutOfMemoryError(env, 0);
-                return 0;
-            }
+        out_buf = (jbyte *) malloc(len);
+        if (out_buf == 0) {
+            free(in_buf);
+            JNU_ThrowOutOfMemoryError(env, 0);
+            return 0;
+        }
 
-            strm->next_in = (Bytef *) in_buf;
-            strm->next_out = (Bytef *) out_buf;
-            strm->avail_in = this_len;
-            strm->avail_out = len;
-            res = deflate(strm, finish ? Z_FINISH : flush);
+        strm->next_in = (Bytef *) in_buf;
+        strm->next_out = (Bytef *) out_buf;
+        strm->avail_in = this_len;
+        strm->avail_out = len;
+        res = deflate(strm, finish ? Z_FINISH : flush);
 
-            if (res == Z_STREAM_END || res == Z_OK) {
-                (*env)->SetByteArrayRegion(env, b, off, len - strm->avail_out, out_buf);
-            }
-            free(out_buf);
-            free(in_buf);
+        if (res == Z_STREAM_END || res == Z_OK) {
+            (*env)->SetByteArrayRegion(env, b, off, len - strm->avail_out, out_buf);
+        }
+        free(out_buf);
+        free(in_buf);
 
-            switch (res) {
-            case Z_STREAM_END:
-                (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE);
-                /* fall through */
-            case Z_OK:
-                this_off += this_len - strm->avail_in;
-                (*env)->SetIntField(env, this, offID, this_off);
-                (*env)->SetIntField(env, this, lenID, strm->avail_in);
-                return len - strm->avail_out;
-            case Z_BUF_ERROR:
-                return 0;
+        switch (res) {
+        case Z_STREAM_END:
+            (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE);
+            /* fall through */
+        case Z_OK:
+            this_off += this_len - strm->avail_in;
+            (*env)->SetIntField(env, this, offID, this_off);
+            (*env)->SetIntField(env, this, lenID, strm->avail_in);
+            return len - strm->avail_out;
+        case Z_BUF_ERROR:
+            return 0;
             default:
-                JNU_ThrowInternalError(env, strm->msg);
-                return 0;
-            }
+            JNU_ThrowInternalError(env, strm->msg);
+            return 0;
         }
     }
 }
 
 JNIEXPORT jint JNICALL
-Java_java_util_zip_Deflater_getAdler(JNIEnv *env, jclass cls, jlong strm)
+Java_java_util_zip_Deflater_getAdler(JNIEnv *env, jclass cls, jlong addr)
 {
-    return ((z_stream *)jlong_to_ptr(strm))->adler;
+    return ((z_stream *)jlong_to_ptr(addr))->adler;
 }
 
 JNIEXPORT jlong JNICALL
-Java_java_util_zip_Deflater_getBytesRead(JNIEnv *env, jclass cls, jlong strm)
+Java_java_util_zip_Deflater_getBytesRead(JNIEnv *env, jclass cls, jlong addr)
 {
-    return ((z_stream *)jlong_to_ptr(strm))->total_in;
+    return ((z_stream *)jlong_to_ptr(addr))->total_in;
 }
 
 JNIEXPORT jlong JNICALL
-Java_java_util_zip_Deflater_getBytesWritten(JNIEnv *env, jclass cls, jlong strm)
+Java_java_util_zip_Deflater_getBytesWritten(JNIEnv *env, jclass cls, jlong addr)
 {
-    return ((z_stream *)jlong_to_ptr(strm))->total_out;
+    return ((z_stream *)jlong_to_ptr(addr))->total_out;
 }
 
 JNIEXPORT void JNICALL
-Java_java_util_zip_Deflater_reset(JNIEnv *env, jclass cls, jlong strm)
+Java_java_util_zip_Deflater_reset(JNIEnv *env, jclass cls, jlong addr)
 {
-    if (deflateReset((z_stream *)jlong_to_ptr(strm)) != Z_OK) {
+    if (deflateReset((z_stream *)jlong_to_ptr(addr)) != Z_OK) {
         JNU_ThrowInternalError(env, 0);
     }
 }
 
 JNIEXPORT void JNICALL
-Java_java_util_zip_Deflater_end(JNIEnv *env, jclass cls, jlong strm)
+Java_java_util_zip_Deflater_end(JNIEnv *env, jclass cls, jlong addr)
 {
-    if (deflateEnd((z_stream *)jlong_to_ptr(strm)) == Z_STREAM_ERROR) {
+    if (deflateEnd((z_stream *)jlong_to_ptr(addr)) == Z_STREAM_ERROR) {
         JNU_ThrowInternalError(env, 0);
     } else {
-        free((z_stream *)jlong_to_ptr(strm));
+        free((z_stream *)jlong_to_ptr(addr));
     }
 }
--- a/src/share/native/java/util/zip/Inflater.c	Wed Nov 25 10:02:50 2009 +0000
+++ b/src/share/native/java/util/zip/Inflater.c	Wed Nov 25 11:29:23 2009 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,6 @@
 #define ThrowDataFormatException(env, msg) \
         JNU_ThrowByName(env, "java/util/zip/DataFormatException", msg)
 
-static jfieldID strmID;
 static jfieldID needDictID;
 static jfieldID finishedID;
 static jfieldID bufID, offID, lenID;
@@ -49,7 +48,6 @@
 JNIEXPORT void JNICALL
 Java_java_util_zip_Inflater_initIDs(JNIEnv *env, jclass cls)
 {
-    strmID = (*env)->GetFieldID(env, cls, "strm", "J");
     needDictID = (*env)->GetFieldID(env, cls, "needDict", "Z");
     finishedID = (*env)->GetFieldID(env, cls, "finished", "Z");
     bufID = (*env)->GetFieldID(env, cls, "buf", "[B");
@@ -84,134 +82,129 @@
 }
 
 JNIEXPORT void JNICALL
-Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong strm,
+Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr,
                                           jarray b, jint off, jint len)
 {
     Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
     int res;
     if (buf == 0) /* out of memory */
         return;
-    res = inflateSetDictionary(jlong_to_ptr(strm), buf + off, len);
+    res = inflateSetDictionary(jlong_to_ptr(addr), buf + off, len);
     (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0);
     switch (res) {
     case Z_OK:
         break;
     case Z_STREAM_ERROR:
     case Z_DATA_ERROR:
-        JNU_ThrowIllegalArgumentException(env, ((z_stream *)jlong_to_ptr(strm))->msg);
+        JNU_ThrowIllegalArgumentException(env, ((z_stream *)jlong_to_ptr(addr))->msg);
         break;
     default:
-        JNU_ThrowInternalError(env, ((z_stream *)jlong_to_ptr(strm))->msg);
+        JNU_ThrowInternalError(env, ((z_stream *)jlong_to_ptr(addr))->msg);
         break;
     }
 }
 
 JNIEXPORT jint JNICALL
-Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this,
+Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr,
                                          jarray b, jint off, jint len)
 {
-    z_stream *strm = jlong_to_ptr((*env)->GetLongField(env, this, strmID));
+    z_stream *strm = jlong_to_ptr(addr);
 
-    if (strm == 0) {
-        JNU_ThrowNullPointerException(env, 0);
-        return 0;
-    } else {
-        jarray this_buf = (jarray)(*env)->GetObjectField(env, this, bufID);
-        jint this_off = (*env)->GetIntField(env, this, offID);
-        jint this_len = (*env)->GetIntField(env, this, lenID);
-        jbyte *in_buf;
-        jbyte *out_buf;
-        int ret;
+    jarray this_buf = (jarray)(*env)->GetObjectField(env, this, bufID);
+    jint this_off = (*env)->GetIntField(env, this, offID);
+    jint this_len = (*env)->GetIntField(env, this, lenID);
+    jbyte *in_buf;
+    jbyte *out_buf;
+    int ret;
 
-        in_buf = (jbyte *) malloc(this_len);
-        if (in_buf == 0) {
-            JNU_ThrowOutOfMemoryError(env, 0);
-            return 0;
-        }
-        (*env)->GetByteArrayRegion(env, this_buf, this_off, this_len, in_buf);
+    in_buf = (jbyte *) malloc(this_len);
+    if (in_buf == 0) {
+        JNU_ThrowOutOfMemoryError(env, 0);
+        return 0;
+    }
+    (*env)->GetByteArrayRegion(env, this_buf, this_off, this_len, in_buf);
 
-        out_buf = (jbyte *) malloc(len);
-        if (out_buf == 0) {
-            free(in_buf);
-            JNU_ThrowOutOfMemoryError(env, 0);
-            return 0;
-        }
+    out_buf = (jbyte *) malloc(len);
+    if (out_buf == 0) {
+        free(in_buf);
+        JNU_ThrowOutOfMemoryError(env, 0);
+        return 0;
+    }
 
-        strm->next_in  = (Bytef *) in_buf;
-        strm->next_out = (Bytef *) out_buf;
-        strm->avail_in  = this_len;
-        strm->avail_out = len;
-        ret = inflate(strm, Z_PARTIAL_FLUSH);
+    strm->next_in  = (Bytef *) in_buf;
+    strm->next_out = (Bytef *) out_buf;
+    strm->avail_in  = this_len;
+    strm->avail_out = len;
+    ret = inflate(strm, Z_PARTIAL_FLUSH);
 
-        if (ret == Z_STREAM_END || ret == Z_OK) {
-            (*env)->SetByteArrayRegion(env, b, off, len - strm->avail_out, out_buf);
-        }
-        free(out_buf);
-        free(in_buf);
+    if (ret == Z_STREAM_END || ret == Z_OK) {
+        (*env)->SetByteArrayRegion(env, b, off, len - strm->avail_out, out_buf);
+    }
+    free(out_buf);
+    free(in_buf);
 
-        switch (ret) {
-        case Z_STREAM_END:
-            (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE);
-            /* fall through */
-        case Z_OK:
-            this_off += this_len - strm->avail_in;
-            (*env)->SetIntField(env, this, offID, this_off);
-            (*env)->SetIntField(env, this, lenID, strm->avail_in);
-            return len - strm->avail_out;
-        case Z_NEED_DICT:
-            (*env)->SetBooleanField(env, this, needDictID, JNI_TRUE);
-            /* Might have consumed some input here! */
-            this_off += this_len - strm->avail_in;
-            (*env)->SetIntField(env, this, offID, this_off);
-            (*env)->SetIntField(env, this, lenID, strm->avail_in);
-            return 0;
-        case Z_BUF_ERROR:
-            return 0;
-        case Z_DATA_ERROR:
-            ThrowDataFormatException(env, strm->msg);
-            return 0;
-        case Z_MEM_ERROR:
-            JNU_ThrowOutOfMemoryError(env, 0);
-            return 0;
-        default:
-            JNU_ThrowInternalError(env, strm->msg);
-            return 0;
-        }
+    switch (ret) {
+    case Z_STREAM_END:
+        (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE);
+        /* fall through */
+    case Z_OK:
+        this_off += this_len - strm->avail_in;
+        (*env)->SetIntField(env, this, offID, this_off);
+        (*env)->SetIntField(env, this, lenID, strm->avail_in);
+        return len - strm->avail_out;
+    case Z_NEED_DICT:
+        (*env)->SetBooleanField(env, this, needDictID, JNI_TRUE);
+        /* Might have consumed some input here! */
+        this_off += this_len - strm->avail_in;
+        (*env)->SetIntField(env, this, offID, this_off);
+        (*env)->SetIntField(env, this, lenID, strm->avail_in);
+        return 0;
+    case Z_BUF_ERROR:
+        return 0;
+    case Z_DATA_ERROR:
+        ThrowDataFormatException(env, strm->msg);
+        return 0;
+    case Z_MEM_ERROR:
+        JNU_ThrowOutOfMemoryError(env, 0);
+        return 0;
+    default:
+        JNU_ThrowInternalError(env, strm->msg);
+        return 0;
     }
 }
 
 JNIEXPORT jint JNICALL
-Java_java_util_zip_Inflater_getAdler(JNIEnv *env, jclass cls, jlong strm)
+Java_java_util_zip_Inflater_getAdler(JNIEnv *env, jclass cls, jlong addr)
 {
-    return ((z_stream *)jlong_to_ptr(strm))->adler;
+    return ((z_stream *)jlong_to_ptr(addr))->adler;
 }
 
 JNIEXPORT jlong JNICALL
-Java_java_util_zip_Inflater_getBytesRead(JNIEnv *env, jclass cls, jlong strm)
+Java_java_util_zip_Inflater_getBytesRead(JNIEnv *env, jclass cls, jlong addr)
 {
-    return ((z_stream *)jlong_to_ptr(strm))->total_in;
+    return ((z_stream *)jlong_to_ptr(addr))->total_in;
 }
 
 JNIEXPORT jlong JNICALL
-Java_java_util_zip_Inflater_getBytesWritten(JNIEnv *env, jclass cls, jlong strm)
+Java_java_util_zip_Inflater_getBytesWritten(JNIEnv *env, jclass cls, jlong addr)
 {
-    return ((z_stream *)jlong_to_ptr(strm))->total_out;
+    return ((z_stream *)jlong_to_ptr(addr))->total_out;
 }
 
 JNIEXPORT void JNICALL
-Java_java_util_zip_Inflater_reset(JNIEnv *env, jclass cls, jlong strm)
+Java_java_util_zip_Inflater_reset(JNIEnv *env, jclass cls, jlong addr)
 {
-    if (inflateReset(jlong_to_ptr(strm)) != Z_OK) {
+    if (inflateReset(jlong_to_ptr(addr)) != Z_OK) {
         JNU_ThrowInternalError(env, 0);
     }
 }
 
 JNIEXPORT void JNICALL
-Java_java_util_zip_Inflater_end(JNIEnv *env, jclass cls, jlong strm)
+Java_java_util_zip_Inflater_end(JNIEnv *env, jclass cls, jlong addr)
 {
-    if (inflateEnd(jlong_to_ptr(strm)) == Z_STREAM_ERROR) {
+    if (inflateEnd(jlong_to_ptr(addr)) == Z_STREAM_ERROR) {
         JNU_ThrowInternalError(env, 0);
     } else {
-        free(jlong_to_ptr(strm));
+        free(jlong_to_ptr(addr));
     }
 }