718 lines
28 KiB
Diff
718 lines
28 KiB
Diff
Subject: [PATCH] [Huawei]support KAE-zip
|
|
|
|
---
|
|
jdk/make/CompileLaunchers.gmk | 34 ++++---
|
|
jdk/make/lib/CoreLibraries.gmk | 71 ++++++++++++++
|
|
jdk/make/mapfiles/libzip/mapfile-vers | 3 +
|
|
.../share/classes/java/util/zip/Deflater.java | 10 +-
|
|
.../java/util/zip/GZIPInputStream.java | 14 +++
|
|
.../java/util/zip/GZIPOutputStream.java | 20 ++++
|
|
.../share/classes/java/util/zip/Inflater.java | 14 ++-
|
|
.../java/util/zip/InflaterOutputStream.java | 24 ++---
|
|
jdk/src/share/lib/security/java.policy | 2 +
|
|
jdk/src/share/native/java/util/zip/Deflater.c | 37 +++++++
|
|
jdk/src/share/native/java/util/zip/Inflater.c | 98 +++++++++++++++++++
|
|
.../java/util/zip/DeflateIn_InflateOut.java | 74 +++++++++++++-
|
|
12 files changed, 367 insertions(+), 34 deletions(-)
|
|
|
|
diff --git a/jdk/make/CompileLaunchers.gmk b/jdk/make/CompileLaunchers.gmk
|
|
index de1ea9f4b..513e2ee1b 100644
|
|
--- a/jdk/make/CompileLaunchers.gmk
|
|
+++ b/jdk/make/CompileLaunchers.gmk
|
|
@@ -474,17 +474,29 @@ ifeq ($(USE_EXTERNAL_LIBZ), true)
|
|
UNPACKEXE_ZIPOBJS := -lz
|
|
else
|
|
UNPACKEXE_CFLAGS := -I$(JDK_TOPDIR)/src/share/native/java/util/zip/zlib
|
|
- UNPACKEXE_ZIPOBJS := $(JDK_OUTPUTDIR)/objs/libzip/zcrc32$(OBJ_SUFFIX) \
|
|
- $(JDK_OUTPUTDIR)/objs/libzip/deflate$(OBJ_SUFFIX) \
|
|
- $(JDK_OUTPUTDIR)/objs/libzip/trees$(OBJ_SUFFIX) \
|
|
- $(JDK_OUTPUTDIR)/objs/libzip/zadler32$(OBJ_SUFFIX) \
|
|
- $(JDK_OUTPUTDIR)/objs/libzip/compress$(OBJ_SUFFIX) \
|
|
- $(JDK_OUTPUTDIR)/objs/libzip/zutil$(OBJ_SUFFIX) \
|
|
- $(JDK_OUTPUTDIR)/objs/libzip/inflate$(OBJ_SUFFIX) \
|
|
- $(JDK_OUTPUTDIR)/objs/libzip/infback$(OBJ_SUFFIX) \
|
|
- $(JDK_OUTPUTDIR)/objs/libzip/inftrees$(OBJ_SUFFIX) \
|
|
- $(JDK_OUTPUTDIR)/objs/libzip/inffast$(OBJ_SUFFIX)
|
|
-
|
|
+ ifeq ($(OPENJDK_TARGET_OS), windows)
|
|
+ UNPACKEXE_ZIPOBJS := $(JDK_OUTPUTDIR)/objs/libzip/zcrc32$(OBJ_SUFFIX) \
|
|
+ $(JDK_OUTPUTDIR)/objs/libzip/deflate$(OBJ_SUFFIX) \
|
|
+ $(JDK_OUTPUTDIR)/objs/libzip/trees$(OBJ_SUFFIX) \
|
|
+ $(JDK_OUTPUTDIR)/objs/libzip/zadler32$(OBJ_SUFFIX) \
|
|
+ $(JDK_OUTPUTDIR)/objs/libzip/compress$(OBJ_SUFFIX) \
|
|
+ $(JDK_OUTPUTDIR)/objs/libzip/zutil$(OBJ_SUFFIX) \
|
|
+ $(JDK_OUTPUTDIR)/objs/libzip/inflate$(OBJ_SUFFIX) \
|
|
+ $(JDK_OUTPUTDIR)/objs/libzip/infback$(OBJ_SUFFIX) \
|
|
+ $(JDK_OUTPUTDIR)/objs/libzip/inftrees$(OBJ_SUFFIX) \
|
|
+ $(JDK_OUTPUTDIR)/objs/libzip/inffast$(OBJ_SUFFIX)
|
|
+ else
|
|
+ UNPACKEXE_ZIPOBJS := $(JDK_OUTPUTDIR)/objs/libz/zcrc32$(OBJ_SUFFIX) \
|
|
+ $(JDK_OUTPUTDIR)/objs/libz/deflate$(OBJ_SUFFIX) \
|
|
+ $(JDK_OUTPUTDIR)/objs/libz/trees$(OBJ_SUFFIX) \
|
|
+ $(JDK_OUTPUTDIR)/objs/libz/zadler32$(OBJ_SUFFIX) \
|
|
+ $(JDK_OUTPUTDIR)/objs/libz/compress$(OBJ_SUFFIX) \
|
|
+ $(JDK_OUTPUTDIR)/objs/libz/zutil$(OBJ_SUFFIX) \
|
|
+ $(JDK_OUTPUTDIR)/objs/libz/inflate$(OBJ_SUFFIX) \
|
|
+ $(JDK_OUTPUTDIR)/objs/libz/infback$(OBJ_SUFFIX) \
|
|
+ $(JDK_OUTPUTDIR)/objs/libz/inftrees$(OBJ_SUFFIX) \
|
|
+ $(JDK_OUTPUTDIR)/objs/libz/inffast$(OBJ_SUFFIX)
|
|
+ endif
|
|
endif
|
|
|
|
UNPACKEXE_LANG := C
|
|
diff --git a/jdk/make/lib/CoreLibraries.gmk b/jdk/make/lib/CoreLibraries.gmk
|
|
index d1cd1d3de..1af991693 100644
|
|
--- a/jdk/make/lib/CoreLibraries.gmk
|
|
+++ b/jdk/make/lib/CoreLibraries.gmk
|
|
@@ -261,11 +261,76 @@ $(BUILD_LIBJAVA): $(BUILD_LIBFDLIBM)
|
|
|
|
##########################################################################################
|
|
|
|
+ifneq ($(USE_EXTERNAL_LIBZ), true)
|
|
+ ifneq ($(OPENJDK_TARGET_OS), windows)
|
|
+ BUILD_LIBZ_EXCLUDES :=
|
|
+
|
|
+ ZLIB_CPPFLAGS := -I$(JDK_TOPDIR)/src/share/native/java/util/zip/zlib
|
|
+ ifeq ($(OPENJDK_TARGET_OS), macosx)
|
|
+ ZLIB_CPPFLAGS += -DHAVE_UNISTD_H
|
|
+ endif
|
|
+
|
|
+ BUILD_LIBZ_REORDER :=
|
|
+ ifeq ($(OPENJDK_TARGET_OS), solaris)
|
|
+ ifneq ($(OPENJDK_TARGET_CPU), x86_64)
|
|
+ BUILD_LIBZ_REORDER := $(JDK_TOPDIR)/make/mapfiles/libzip/reorder-$(OPENJDK_TARGET_CPU)
|
|
+ endif
|
|
+ endif
|
|
+
|
|
+ ifeq ($(LIBZ_CAN_USE_MMAP), true)
|
|
+ BUILD_LIBZ_MMAP := -DUSE_MMAP
|
|
+ endif
|
|
+
|
|
+ $(eval $(call SetupNativeCompilation,BUILD_LIBZ, \
|
|
+ LIBRARY := z, \
|
|
+ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
|
|
+ LANG := C, \
|
|
+ OPTIMIZATION := LOW, \
|
|
+ SRC := $(JDK_TOPDIR)/src/share/native/java/util/zip/zlib, \
|
|
+ EXCLUDES := $(LIBZ_EXCLUDES), \
|
|
+ CFLAGS := $(CFLAGS_JDKLIB) \
|
|
+ $(ZLIB_CPPFLAGS) \
|
|
+ -I$(JDK_TOPDIR)/src/share/native/java/io \
|
|
+ -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/io, \
|
|
+ CFLAGS_posix := $(BUILD_LIBZ_MMAP) -UDEBUG, \
|
|
+ MAPFILE := , \
|
|
+ REORDER := $(BUILD_LIBZ_REORDER), \
|
|
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
|
|
+ $(call SET_SHARED_LIBRARY_ORIGIN) \
|
|
+ $(EXPORT_Z_FUNCS), \
|
|
+ LDFLAGS_windows := jvm.lib \
|
|
+ $(WIN_JAVA_LIB), \
|
|
+ LDFLAGS_SUFFIX_linux := , \
|
|
+ LDFLAGS_SUFFIX_solaris := , \
|
|
+ LDFLAGS_SUFFIX_aix := ,\
|
|
+ LDFLAGS_SUFFIX_macosx := , \
|
|
+ VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/windows/resource/version.rc, \
|
|
+ RC_FLAGS := $(RC_FLAGS) \
|
|
+ -D "JDK_FNAME=z.dll" \
|
|
+ -D "JDK_INTERNAL_NAME=z" \
|
|
+ -D "JDK_FTYPE=0x2L", \
|
|
+ OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libz, \
|
|
+ DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
|
|
+
|
|
+
|
|
+ $(BUILD_LIBZ): $(BUILD_LIBJAVA)
|
|
+
|
|
+ BUILD_LIBRARIES += $(BUILD_LIBZ)
|
|
+ endif
|
|
+endif
|
|
+
|
|
+##########################################################################################
|
|
+
|
|
BUILD_LIBZIP_EXCLUDES :=
|
|
ifeq ($(USE_EXTERNAL_LIBZ), true)
|
|
+ BUILD_LIBZIP_SRC :=
|
|
LIBZ := -lz
|
|
LIBZIP_EXCLUDES += zlib
|
|
else
|
|
+ ifneq ($(OPENJDK_TARGET_OS), windows)
|
|
+ BUILD_LIBZIP_SRC := Adler32.c CRC32.c Deflater.c Inflater.c zip_util.c ZipFile.c
|
|
+ LIBZ := -lz
|
|
+ endif
|
|
ZLIB_CPPFLAGS := -I$(JDK_TOPDIR)/src/share/native/java/util/zip/zlib
|
|
ifeq ($(OPENJDK_TARGET_OS), macosx)
|
|
ZLIB_CPPFLAGS += -DHAVE_UNISTD_H
|
|
@@ -289,6 +354,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBZIP, \
|
|
LANG := C, \
|
|
OPTIMIZATION := LOW, \
|
|
SRC := $(JDK_TOPDIR)/src/share/native/java/util/zip, \
|
|
+ INCLUDE_FILES := $(BUILD_LIBZIP_SRC), \
|
|
EXCLUDES := $(LIBZIP_EXCLUDES), \
|
|
CFLAGS := $(CFLAGS_JDKLIB) \
|
|
$(ZLIB_CPPFLAGS) \
|
|
@@ -315,9 +381,14 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBZIP, \
|
|
OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libzip, \
|
|
DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
|
|
|
|
+ifneq ($(USE_EXTERNAL_LIBZ), true)
|
|
+ LIBZ :=
|
|
+endif
|
|
|
|
$(BUILD_LIBZIP): $(BUILD_LIBJAVA)
|
|
|
|
+$(BUILD_LIBZIP): $(BUILD_LIBZ)
|
|
+
|
|
BUILD_LIBRARIES += $(BUILD_LIBZIP)
|
|
|
|
##########################################################################################
|
|
diff --git a/jdk/make/mapfiles/libzip/mapfile-vers b/jdk/make/mapfiles/libzip/mapfile-vers
|
|
index 5d33990c3..5c6d27d0d 100644
|
|
--- a/jdk/make/mapfiles/libzip/mapfile-vers
|
|
+++ b/jdk/make/mapfiles/libzip/mapfile-vers
|
|
@@ -38,13 +38,16 @@ SUNWprivate_1.1 {
|
|
Java_java_util_zip_Deflater_end;
|
|
Java_java_util_zip_Deflater_getAdler;
|
|
Java_java_util_zip_Deflater_init;
|
|
+ Java_java_util_zip_Deflater_initKae;
|
|
Java_java_util_zip_Deflater_initIDs;
|
|
Java_java_util_zip_Deflater_reset;
|
|
Java_java_util_zip_Deflater_setDictionary;
|
|
Java_java_util_zip_Inflater_end;
|
|
Java_java_util_zip_Inflater_getAdler;
|
|
Java_java_util_zip_Inflater_inflateBytes;
|
|
+ Java_java_util_zip_Inflater_inflateBytesKAE;
|
|
Java_java_util_zip_Inflater_init;
|
|
+ Java_java_util_zip_Inflater_initKae;
|
|
Java_java_util_zip_Inflater_initIDs;
|
|
Java_java_util_zip_Inflater_reset;
|
|
Java_java_util_zip_Inflater_setDictionary;
|
|
diff --git a/jdk/src/share/classes/java/util/zip/Deflater.java b/jdk/src/share/classes/java/util/zip/Deflater.java
|
|
index bffa397d9..a4ea40cf8 100644
|
|
--- a/jdk/src/share/classes/java/util/zip/Deflater.java
|
|
+++ b/jdk/src/share/classes/java/util/zip/Deflater.java
|
|
@@ -81,6 +81,7 @@ class Deflater {
|
|
private boolean finish, finished;
|
|
private long bytesRead;
|
|
private long bytesWritten;
|
|
+ private boolean defalterUseKae;
|
|
|
|
/**
|
|
* Compression method for the deflate algorithm (the only one currently
|
|
@@ -168,7 +169,13 @@ class Deflater {
|
|
public Deflater(int level, boolean nowrap) {
|
|
this.level = level;
|
|
this.strategy = DEFAULT_STRATEGY;
|
|
- this.zsRef = new ZStreamRef(init(level, DEFAULT_STRATEGY, nowrap));
|
|
+ if (("true".equals(System.getProperty("GZIP_USE_KAE", "false"))) &&
|
|
+ ("aarch64".equals(System.getProperty("os.arch")))) {
|
|
+ this.defalterUseKae = true;
|
|
+ }
|
|
+ this.zsRef = defalterUseKae ?
|
|
+ new ZStreamRef(initKae(level, DEFAULT_STRATEGY)) :
|
|
+ new ZStreamRef(init(level, DEFAULT_STRATEGY, nowrap));
|
|
}
|
|
|
|
/**
|
|
@@ -571,6 +578,7 @@ class Deflater {
|
|
|
|
private static native void initIDs();
|
|
private native static long init(int level, int strategy, boolean nowrap);
|
|
+ private native static long initKae(int level, int strategy);
|
|
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);
|
|
diff --git a/jdk/src/share/classes/java/util/zip/GZIPInputStream.java b/jdk/src/share/classes/java/util/zip/GZIPInputStream.java
|
|
index 0d57e8ab3..7fb753729 100644
|
|
--- a/jdk/src/share/classes/java/util/zip/GZIPInputStream.java
|
|
+++ b/jdk/src/share/classes/java/util/zip/GZIPInputStream.java
|
|
@@ -54,6 +54,11 @@ class GZIPInputStream extends InflaterInputStream {
|
|
|
|
private boolean closed = false;
|
|
|
|
+ /*
|
|
+ * GZIP use KAE.
|
|
+ */
|
|
+ private boolean gzipUseKae = false;
|
|
+
|
|
/**
|
|
* Check to make sure that this stream has not been closed
|
|
*/
|
|
@@ -76,6 +81,12 @@ class GZIPInputStream extends InflaterInputStream {
|
|
public GZIPInputStream(InputStream in, int size) throws IOException {
|
|
super(in, new Inflater(true), size);
|
|
usesDefaultInflater = true;
|
|
+ if (("true".equals(System.getProperty("GZIP_USE_KAE", "false"))) &&
|
|
+ ("aarch64".equals(System.getProperty("os.arch")))) {
|
|
+ gzipUseKae = true;
|
|
+ }
|
|
+ // file header will be readed by kae zlib when use kae
|
|
+ if (gzipUseKae) return;
|
|
readHeader(in);
|
|
}
|
|
|
|
@@ -209,6 +220,9 @@ class GZIPInputStream extends InflaterInputStream {
|
|
* data set)
|
|
*/
|
|
private boolean readTrailer() throws IOException {
|
|
+ // file trailer will be readed by kae zlib when use kae
|
|
+ if (gzipUseKae) return true;
|
|
+
|
|
InputStream in = this.in;
|
|
int n = inf.getRemaining();
|
|
if (n > 0) {
|
|
diff --git a/jdk/src/share/classes/java/util/zip/GZIPOutputStream.java b/jdk/src/share/classes/java/util/zip/GZIPOutputStream.java
|
|
index 1c3f8592e..0f0be98bb 100644
|
|
--- a/jdk/src/share/classes/java/util/zip/GZIPOutputStream.java
|
|
+++ b/jdk/src/share/classes/java/util/zip/GZIPOutputStream.java
|
|
@@ -52,6 +52,11 @@ class GZIPOutputStream extends DeflaterOutputStream {
|
|
*/
|
|
private final static int TRAILER_SIZE = 8;
|
|
|
|
+ /*
|
|
+ * GZIP use KAE.
|
|
+ */
|
|
+ private boolean gzipUseKae = false;
|
|
+
|
|
/**
|
|
* Creates a new output stream with the specified buffer size.
|
|
*
|
|
@@ -91,6 +96,12 @@ class GZIPOutputStream extends DeflaterOutputStream {
|
|
size,
|
|
syncFlush);
|
|
usesDefaultDeflater = true;
|
|
+ if (("true".equals(System.getProperty("GZIP_USE_KAE", "false"))) &&
|
|
+ ("aarch64".equals(System.getProperty("os.arch")))) {
|
|
+ gzipUseKae = true;
|
|
+ }
|
|
+ // file header will be writed by kae zlib when use kae
|
|
+ if (gzipUseKae) return;
|
|
writeHeader();
|
|
crc.reset();
|
|
}
|
|
@@ -160,6 +171,11 @@ class GZIPOutputStream extends DeflaterOutputStream {
|
|
int len = def.deflate(buf, 0, buf.length);
|
|
if (def.finished() && len <= buf.length - TRAILER_SIZE) {
|
|
// last deflater buffer. Fit trailer at the end
|
|
+ // file trailer will be writed by kae zlib when use kae
|
|
+ if (gzipUseKae) {
|
|
+ out.write(buf, 0, len);
|
|
+ return;
|
|
+ }
|
|
writeTrailer(buf, len);
|
|
len = len + TRAILER_SIZE;
|
|
out.write(buf, 0, len);
|
|
@@ -168,6 +184,10 @@ class GZIPOutputStream extends DeflaterOutputStream {
|
|
if (len > 0)
|
|
out.write(buf, 0, len);
|
|
}
|
|
+ // file trailer will be writed by kae zlib when use kae
|
|
+ if (gzipUseKae) {
|
|
+ return;
|
|
+ }
|
|
// if we can't fit the trailer at the end of the last
|
|
// deflater buffer, we write it separately
|
|
byte[] trailer = new byte[TRAILER_SIZE];
|
|
diff --git a/jdk/src/share/classes/java/util/zip/Inflater.java b/jdk/src/share/classes/java/util/zip/Inflater.java
|
|
index c1eefe122..42e90f525 100644
|
|
--- a/jdk/src/share/classes/java/util/zip/Inflater.java
|
|
+++ b/jdk/src/share/classes/java/util/zip/Inflater.java
|
|
@@ -80,6 +80,7 @@ class Inflater {
|
|
private boolean needDict;
|
|
private long bytesRead;
|
|
private long bytesWritten;
|
|
+ private boolean inflaterUseKae;
|
|
|
|
private static final byte[] defaultBuf = new byte[0];
|
|
|
|
@@ -100,7 +101,11 @@ class Inflater {
|
|
* @param nowrap if true then support GZIP compatible compression
|
|
*/
|
|
public Inflater(boolean nowrap) {
|
|
- zsRef = new ZStreamRef(init(nowrap));
|
|
+ if (("true".equals(System.getProperty("GZIP_USE_KAE", "false"))) &&
|
|
+ ("aarch64".equals(System.getProperty("os.arch")))) {
|
|
+ inflaterUseKae = true;
|
|
+ }
|
|
+ zsRef = inflaterUseKae ? new ZStreamRef(initKae()): new ZStreamRef(init(nowrap));
|
|
}
|
|
|
|
/**
|
|
@@ -256,7 +261,9 @@ class Inflater {
|
|
synchronized (zsRef) {
|
|
ensureOpen();
|
|
int thisLen = this.len;
|
|
- int n = inflateBytes(zsRef.address(), b, off, len);
|
|
+ int n = this.inflaterUseKae ?
|
|
+ inflateBytesKAE(zsRef.address(), b, off, len) :
|
|
+ inflateBytes(zsRef.address(), b, off, len);
|
|
bytesWritten += n;
|
|
bytesRead += (thisLen - this.len);
|
|
return n;
|
|
@@ -397,10 +404,13 @@ class Inflater {
|
|
|
|
private native static void initIDs();
|
|
private native static long init(boolean nowrap);
|
|
+ private native static long initKae();
|
|
private native static void setDictionary(long addr, byte[] b, int off,
|
|
int len);
|
|
private native int inflateBytes(long addr, byte[] b, int off, int len)
|
|
throws DataFormatException;
|
|
+ private native int inflateBytesKAE(long addr, byte[] b, int off, int len)
|
|
+ throws DataFormatException;
|
|
private native static int getAdler(long addr);
|
|
private native static void reset(long addr);
|
|
private native static void end(long addr);
|
|
diff --git a/jdk/src/share/classes/java/util/zip/InflaterOutputStream.java b/jdk/src/share/classes/java/util/zip/InflaterOutputStream.java
|
|
index 02900c741..62c6bb153 100644
|
|
--- a/jdk/src/share/classes/java/util/zip/InflaterOutputStream.java
|
|
+++ b/jdk/src/share/classes/java/util/zip/InflaterOutputStream.java
|
|
@@ -1,5 +1,5 @@
|
|
/*
|
|
- * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
|
|
+ * Copyright (c) 2006, 2020, Oracle and/or its affiliates. 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
|
|
@@ -236,16 +236,9 @@ public class InflaterOutputStream extends FilterOutputStream {
|
|
|
|
// Fill the decompressor buffer with output data
|
|
if (inf.needsInput()) {
|
|
- int part;
|
|
-
|
|
- if (len < 1) {
|
|
- break;
|
|
- }
|
|
-
|
|
- part = (len < 512 ? len : 512);
|
|
- inf.setInput(b, off, part);
|
|
- off += part;
|
|
- len -= part;
|
|
+ inf.setInput(b, off, len);
|
|
+ // Only use input buffer once.
|
|
+ len = 0;
|
|
}
|
|
|
|
// Decompress and write blocks of output data
|
|
@@ -256,13 +249,14 @@ public class InflaterOutputStream extends FilterOutputStream {
|
|
}
|
|
} while (n > 0);
|
|
|
|
- // Check the decompressor
|
|
- if (inf.finished()) {
|
|
- break;
|
|
- }
|
|
+ // Check for missing dictionary first
|
|
if (inf.needsDictionary()) {
|
|
throw new ZipException("ZLIB dictionary missing");
|
|
}
|
|
+ // Check the decompressor
|
|
+ if (inf.finished() || (len == 0) /* no more input */ ) {
|
|
+ break;
|
|
+ }
|
|
}
|
|
} catch (DataFormatException ex) {
|
|
// Improperly formatted compressed (ZIP) data
|
|
diff --git a/jdk/src/share/lib/security/java.policy b/jdk/src/share/lib/security/java.policy
|
|
index 8b6289720..baec2ea15 100644
|
|
--- a/jdk/src/share/lib/security/java.policy
|
|
+++ b/jdk/src/share/lib/security/java.policy
|
|
@@ -48,5 +48,7 @@ grant {
|
|
permission java.util.PropertyPermission "java.vm.name", "read";
|
|
|
|
permission java.util.PropertyPermission "sun.security.pkcs11.disableKeyExtraction", "read";
|
|
+
|
|
+ permission java.util.PropertyPermission "GZIP_USE_KAE", "read";
|
|
};
|
|
|
|
diff --git a/jdk/src/share/native/java/util/zip/Deflater.c b/jdk/src/share/native/java/util/zip/Deflater.c
|
|
index c1bd34667..1b048e4f5 100644
|
|
--- a/jdk/src/share/native/java/util/zip/Deflater.c
|
|
+++ b/jdk/src/share/native/java/util/zip/Deflater.c
|
|
@@ -37,6 +37,7 @@
|
|
#include "java_util_zip_Deflater.h"
|
|
|
|
#define DEF_MEM_LEVEL 8
|
|
+#define KAE_DEFLATER_WindowBit 31
|
|
|
|
static jfieldID levelID;
|
|
static jfieldID strategyID;
|
|
@@ -104,6 +105,42 @@ Java_java_util_zip_Deflater_init(JNIEnv *env, jclass cls, jint level,
|
|
}
|
|
}
|
|
|
|
+JNIEXPORT jlong JNICALL
|
|
+Java_java_util_zip_Deflater_initKae(JNIEnv *env, jclass cls, jint level,
|
|
+ jint strategy)
|
|
+{
|
|
+ z_stream *strm = calloc(1, sizeof(z_stream));
|
|
+
|
|
+ if (strm == 0) {
|
|
+ JNU_ThrowOutOfMemoryError(env, 0);
|
|
+ return jlong_zero;
|
|
+ } else {
|
|
+ const char *msg;
|
|
+ int ret = deflateInit2(strm, level, Z_DEFLATED, KAE_DEFLATER_WindowBit, DEF_MEM_LEVEL, strategy);
|
|
+ switch (ret) {
|
|
+ case Z_OK:
|
|
+ return ptr_to_jlong(strm);
|
|
+ case Z_MEM_ERROR:
|
|
+ free(strm);
|
|
+ JNU_ThrowOutOfMemoryError(env, 0);
|
|
+ return jlong_zero;
|
|
+ case Z_STREAM_ERROR:
|
|
+ free(strm);
|
|
+ JNU_ThrowIllegalArgumentException(env, 0);
|
|
+ return jlong_zero;
|
|
+ default:
|
|
+ msg = ((strm->msg != NULL) ? strm->msg :
|
|
+ (ret == Z_VERSION_ERROR) ?
|
|
+ "zlib returned Z_VERSION_ERROR: "
|
|
+ "compile time and runtime zlib implementations differ" :
|
|
+ "unknown error initializing zlib library");
|
|
+ free(strm);
|
|
+ JNU_ThrowInternalError(env, msg);
|
|
+ return jlong_zero;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
JNIEXPORT void JNICALL
|
|
Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr,
|
|
jarray b, jint off, jint len)
|
|
diff --git a/jdk/src/share/native/java/util/zip/Inflater.c b/jdk/src/share/native/java/util/zip/Inflater.c
|
|
index 79bcdd5b6..fca207215 100644
|
|
--- a/jdk/src/share/native/java/util/zip/Inflater.c
|
|
+++ b/jdk/src/share/native/java/util/zip/Inflater.c
|
|
@@ -41,6 +41,7 @@
|
|
|
|
#define ThrowDataFormatException(env, msg) \
|
|
JNU_ThrowByName(env, "java/util/zip/DataFormatException", msg)
|
|
+#define KAE_INFLATER_WindowBit 31
|
|
|
|
static jfieldID needDictID;
|
|
static jfieldID finishedID;
|
|
@@ -94,6 +95,39 @@ Java_java_util_zip_Inflater_init(JNIEnv *env, jclass cls, jboolean nowrap)
|
|
}
|
|
}
|
|
|
|
+JNIEXPORT jlong JNICALL
|
|
+Java_java_util_zip_Inflater_initKae(JNIEnv *env, jclass cls)
|
|
+{
|
|
+ z_stream *strm = calloc(1, sizeof(z_stream));
|
|
+
|
|
+ if (strm == NULL) {
|
|
+ JNU_ThrowOutOfMemoryError(env, 0);
|
|
+ return jlong_zero;
|
|
+ } else {
|
|
+ const char *msg;
|
|
+ int ret = inflateInit2(strm, KAE_INFLATER_WindowBit);
|
|
+ switch (ret) {
|
|
+ case Z_OK:
|
|
+ return ptr_to_jlong(strm);
|
|
+ case Z_MEM_ERROR:
|
|
+ free(strm);
|
|
+ JNU_ThrowOutOfMemoryError(env, 0);
|
|
+ return jlong_zero;
|
|
+ default:
|
|
+ msg = ((strm->msg != NULL) ? strm->msg :
|
|
+ (ret == Z_VERSION_ERROR) ?
|
|
+ "zlib returned Z_VERSION_ERROR: "
|
|
+ "compile time and runtime zlib implementations differ" :
|
|
+ (ret == Z_STREAM_ERROR) ?
|
|
+ "inflateInit2 returned Z_STREAM_ERROR" :
|
|
+ "unknown error initializing zlib library");
|
|
+ free(strm);
|
|
+ JNU_ThrowInternalError(env, msg);
|
|
+ return jlong_zero;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
JNIEXPORT void JNICALL
|
|
Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr,
|
|
jarray b, jint off, jint len)
|
|
@@ -181,6 +215,70 @@ Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr,
|
|
}
|
|
}
|
|
|
|
+JNIEXPORT jint JNICALL
|
|
+Java_java_util_zip_Inflater_inflateBytesKAE(JNIEnv *env, jobject this, jlong addr,
|
|
+ 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;
|
|
+
|
|
+ in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0);
|
|
+ if (in_buf == NULL) {
|
|
+ if (this_len != 0 && (*env)->ExceptionOccurred(env) == NULL)
|
|
+ JNU_ThrowOutOfMemoryError(env, 0);
|
|
+ return 0;
|
|
+ }
|
|
+ out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
|
|
+ if (out_buf == NULL) {
|
|
+ (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
|
|
+ if (len != 0 && (*env)->ExceptionOccurred(env) == NULL)
|
|
+ JNU_ThrowOutOfMemoryError(env, 0);
|
|
+ return 0;
|
|
+ }
|
|
+ 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_SYNC_FLUSH);
|
|
+ (*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:
|
|
+ this_off += this_len - strm->avail_in;
|
|
+ (*env)->SetIntField(env, this, offID, this_off);
|
|
+ (*env)->SetIntField(env, this, lenID, strm->avail_in);
|
|
+ return (jint) (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 addr)
|
|
{
|
|
diff --git a/jdk/test/java/util/zip/DeflateIn_InflateOut.java b/jdk/test/java/util/zip/DeflateIn_InflateOut.java
|
|
index dd69a7773..048d8e34c 100644
|
|
--- a/jdk/test/java/util/zip/DeflateIn_InflateOut.java
|
|
+++ b/jdk/test/java/util/zip/DeflateIn_InflateOut.java
|
|
@@ -41,14 +41,31 @@ public class DeflateIn_InflateOut {
|
|
private static ByteArrayOutputStream baos;
|
|
private static InflaterOutputStream ios;
|
|
|
|
- private static void reset() {
|
|
+ private static Inflater reset(byte[] dict) {
|
|
new Random(new Date().getTime()).nextBytes(data);
|
|
|
|
bais = new ByteArrayInputStream(data);
|
|
- dis = new DeflaterInputStream(bais);
|
|
+ if (dict == null) {
|
|
+ dis = new DeflaterInputStream(bais);
|
|
+ } else {
|
|
+ Deflater def = new Deflater();
|
|
+ def.setDictionary(dict);
|
|
+ dis = new DeflaterInputStream(bais, def);
|
|
+ }
|
|
|
|
baos = new ByteArrayOutputStream();
|
|
- ios = new InflaterOutputStream(baos);
|
|
+ if (dict == null) {
|
|
+ ios = new InflaterOutputStream(baos);
|
|
+ return null;
|
|
+ } else {
|
|
+ Inflater inf = new Inflater();
|
|
+ ios = new InflaterOutputStream(baos, inf);
|
|
+ return inf;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static void reset() {
|
|
+ reset(null);
|
|
}
|
|
|
|
/** Check byte arrays read/write. */
|
|
@@ -216,6 +233,44 @@ public class DeflateIn_InflateOut {
|
|
check(numNotSkipped + numSkipBytes == numReadable);
|
|
}
|
|
|
|
+ /** Check "needsDictionary()". */
|
|
+ private static void NeedsDictionary() throws Throwable {
|
|
+ byte[] dict = {1, 2, 3, 4};
|
|
+ Adler32 adler32 = new Adler32();
|
|
+ adler32.update(dict);
|
|
+ long checksum = adler32.getValue();
|
|
+ byte[] buf = new byte[512];
|
|
+
|
|
+ Inflater inf = reset(dict);
|
|
+ check(dis.available() == 1);
|
|
+ boolean dictSet = false;
|
|
+ for (;;) {
|
|
+ int len = dis.read(buf, 0, buf.length);
|
|
+ if (len < 0) {
|
|
+ break;
|
|
+ } else {
|
|
+ try {
|
|
+ ios.write(buf, 0, len);
|
|
+ if (dictSet == false) {
|
|
+ check(false, "Must throw ZipException without dictionary");
|
|
+ return;
|
|
+ }
|
|
+ } catch (ZipException ze) {
|
|
+ check(dictSet == false, "Dictonary must be set only once");
|
|
+ check(checksum == inf.getAdler(), "Incorrect dictionary");
|
|
+ inf.setDictionary(dict);
|
|
+ // After setting the dictionary, we have to flush the
|
|
+ // InflaterOutputStream now in order to consume all the
|
|
+ // pending input data from the last, failed call to "write()".
|
|
+ ios.flush();
|
|
+ dictSet = true;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ check(dis.available() == 0);
|
|
+ ios.close();
|
|
+ check(Arrays.equals(data, baos.toByteArray()));
|
|
+ }
|
|
|
|
public static void realMain(String[] args) throws Throwable {
|
|
ArrayReadWrite();
|
|
@@ -227,15 +282,24 @@ public class DeflateIn_InflateOut {
|
|
ByteReadByteWrite();
|
|
|
|
SkipBytes();
|
|
+
|
|
+ NeedsDictionary();
|
|
}
|
|
|
|
//--------------------- Infrastructure ---------------------------
|
|
static volatile int passed = 0, failed = 0;
|
|
static void pass() {passed++;}
|
|
- static void fail() {failed++; Thread.dumpStack();}
|
|
- static void fail(String msg) {System.out.println(msg); fail();}
|
|
+ static void fail() { fail(null); }
|
|
+ static void fail(String msg) {
|
|
+ failed++;
|
|
+ if (msg != null) {
|
|
+ System.err.println(msg);
|
|
+ }
|
|
+ Thread.dumpStack();
|
|
+ }
|
|
static void unexpected(Throwable t) {failed++; t.printStackTrace();}
|
|
static void check(boolean cond) {if (cond) pass(); else fail();}
|
|
+ static void check(boolean cond, String msg) {if (cond) pass(); else fail(msg);}
|
|
static void equal(Object x, Object y) {
|
|
if (x == null ? y == null : x.equals(y)) pass();
|
|
else fail(x + " not equal to " + y);}
|
|
--
|
|
2.23.0
|
|
|