--- old/src/share/native/java/util/zip/Inflater.c 2011-04-01 14:30:56.616729291 -0700 +++ new/src/share/native/java/util/zip/Inflater.c 2011-04-01 14:30:56.387960326 -0700 @@ -38,8 +38,6 @@ #include "zlib.h" #include "java_util_zip_Inflater.h" -#define MIN2(x, y) ((x) < (y) ? (x) : (y)) - #define ThrowDataFormatException(env, msg) \ JNU_ThrowByName(env, "java/util/zip/DataFormatException", msg) @@ -111,71 +109,50 @@ jarray b, jint off, jint len) { z_stream *strm = jlong_to_ptr(addr); - 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; - /* - * Avoid excess copying. - * zlib stream usually has a few bytes of overhead for header info - * (depends on the underlying data) - * - * (a) 5 bytes per 16KB - * (b) 6 bytes for entire stream - * (c) 4 bytes for gzip header - * (d) 2 bytes for crc - * - * Use 20 bytes as the "safe cutoff" number. - */ - jint in_len = MIN2(this_len, len + 20); - jint consumed; - - in_buf = (jbyte *) malloc(in_len); - if (in_buf == 0) { - if (in_len != 0) + + in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0); + if (in_buf == NULL) { + if (this_len != 0) JNU_ThrowOutOfMemoryError(env, 0); return 0; } - (*env)->GetByteArrayRegion(env, this_buf, this_off, in_len, in_buf); - - out_buf = (jbyte *) malloc(len); - if (out_buf == 0) { - free(in_buf); + out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); + if (out_buf == NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); if (len != 0) JNU_ThrowOutOfMemoryError(env, 0); return 0; } - - strm->next_in = (Bytef *) in_buf; - strm->next_out = (Bytef *) out_buf; - strm->avail_in = in_len; + strm->next_in = (Bytef *) (in_buf + this_off); + strm->next_out = (Bytef *) (out_buf + off); + 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); + (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0); + (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); switch (ret) { case Z_STREAM_END: (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE); /* fall through */ case Z_OK: - consumed = in_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off + consumed); - (*env)->SetIntField(env, this, lenID, this_len - consumed); + 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! */ - consumed = in_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off + consumed); - (*env)->SetIntField(env, this, lenID, this_len - consumed); + 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;