Skip to content

Commit 84143bb

Browse files
author
Elia Trachsel
committed
[GR-64074] Inflater JavaLibJava Impl.
PullRequest: graal/20555
2 parents 075997e + be0bf8e commit 84143bb

File tree

7 files changed

+542
-1
lines changed

7 files changed

+542
-1
lines changed

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/descriptors/EspressoSymbols.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,10 @@ public static void ensureInitialized() {
154154
public static final Symbol<Type> jdk_internal_module_Modules = SYMBOLS.putType("Ljdk/internal/module/Modules;");
155155
public static final Symbol<Type> java_lang_module_ModuleDescriptor = SYMBOLS.putType("Ljava/lang/module/ModuleDescriptor;");
156156

157-
// CRC32
157+
// Espresso Libs
158158
public static final Symbol<Type> java_util_zip_CRC32 = SYMBOLS.putType("Ljava/util/zip/CRC32;");
159+
public static final Symbol<Type> java_util_zip_Inflater = SYMBOLS.putType("Ljava/util/zip/Inflater;");
160+
public static final Symbol<Type> java_util_zip_DataFormatException = SYMBOLS.putType("Ljava/util/zip/DataFormatException;");
159161

160162
// URL class loader
161163
public static final Symbol<Type> java_net_URLClassLoader = SYMBOLS.putType("Ljava/net/URLClassLoader;");
@@ -752,6 +754,13 @@ public static class Names {
752754
public static final Symbol<Name> instance = SYMBOLS.putName("instance");
753755
// java.util.zip
754756
public static final Symbol<Name> HIDDEN_CRC32 = SYMBOLS.putName("0HIDDEN_CRC32");
757+
public static final Symbol<Name> inputConsumed = SYMBOLS.putName("inputConsumed");
758+
public static final Symbol<Name> outputConsumed = SYMBOLS.putName("outputConsumed");
759+
public static final Symbol<Name> len = SYMBOLS.putName("len");
760+
public static final Symbol<Name> off = SYMBOLS.putName("off");
761+
public static final Symbol<Name> needDict = SYMBOLS.putName("needDict");
762+
public static final Symbol<Name> finished = SYMBOLS.putName("finished");
763+
public static final Symbol<Name> buf = SYMBOLS.putName("buf");
755764
// java.lang.invoke.*
756765
// CallSite
757766
public static final Symbol<Name> target = SYMBOLS.putName("target");
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright (c) 2023, 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+
package com.oracle.truffle.espresso.libs;
24+
25+
import java.util.zip.Inflater;
26+
27+
import com.oracle.truffle.api.CompilerDirectives;
28+
import com.oracle.truffle.espresso.meta.Meta;
29+
import com.oracle.truffle.espresso.runtime.EspressoContext;
30+
import com.oracle.truffle.espresso.runtime.EspressoException;
31+
32+
public class LibsState {
33+
private final StrongHandles<Inflater> handle2Inflater = new StrongHandles<>();
34+
35+
public int handlifyInflater(Inflater i) {
36+
return handle2Inflater.handlify(i);
37+
}
38+
39+
public void cleanInflater(long handle) {
40+
handle2Inflater.cleanIndex(handle);
41+
}
42+
43+
public Inflater getInflater(long handle) {
44+
Inflater inflater = handle2Inflater.getObject(handle);
45+
if (inflater == null) {
46+
throw throwInternalError();
47+
}
48+
return inflater;
49+
}
50+
51+
@CompilerDirectives.TruffleBoundary
52+
private static EspressoException throwInternalError() {
53+
Meta meta = EspressoContext.get(null).getMeta();
54+
return meta.throwExceptionWithMessage(meta.java_lang_InternalError, "the provided handle doesn't correspond to an Inflater");
55+
}
56+
57+
}
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*
2+
* Copyright (c) 2023, 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+
package com.oracle.truffle.espresso.libs;
24+
25+
import java.util.Arrays;
26+
import java.util.HashMap;
27+
import java.util.LinkedList;
28+
import java.util.Objects;
29+
30+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
31+
32+
// todo(trachsel) GR-65608 polish Strong and WeakHandles
33+
public class StrongHandles<T> {
34+
private static final int DEFAULT_INITIAL_CAPACITY = 16;
35+
36+
private final HashMap<T, Integer> map;
37+
private final LinkedList<Integer> freeList = new LinkedList<>();
38+
39+
// Non-empty.
40+
private T[] handles;
41+
42+
/**
43+
* Creates a handle collection pre-allocated capacity.
44+
*
45+
* @param initialCapacity must be > 0
46+
*/
47+
@SuppressWarnings({"unchecked", "rawtypes"})
48+
public StrongHandles(int initialCapacity) {
49+
if (initialCapacity <= 0) {
50+
throw new IllegalArgumentException("initialCapacity must be > 0");
51+
}
52+
map = new HashMap<>(initialCapacity);
53+
handles = (T[]) new Object[initialCapacity]; // Casting
54+
}
55+
56+
public StrongHandles() {
57+
this(DEFAULT_INITIAL_CAPACITY);
58+
}
59+
60+
/**
61+
* Creates a new handle for the given object or returns an existing handle if the object is
62+
* already in the collection.
63+
*
64+
* @return new or existing handle, provided handles are guanteed to be > 0
65+
*/
66+
@TruffleBoundary
67+
public synchronized int handlify(T object) {
68+
Objects.requireNonNull(object);
69+
Integer handle = map.get(object);
70+
return handle != null
71+
? handle
72+
: addHandle(object);
73+
}
74+
75+
/**
76+
* Returns the object associated with a handle. This operation is performance-critical,
77+
* shouldn't block.
78+
*
79+
* @param indexJ handle, must be > 0 and fit in an integer
80+
* @return the object associated with the handle or null if was collected
81+
*/
82+
@SuppressWarnings("unchecked")
83+
public T getObject(long indexJ) {
84+
int index = Math.toIntExact(indexJ);
85+
if (invalidIndex(index)) {
86+
return null;
87+
}
88+
return handles[index];
89+
90+
}
91+
92+
/**
93+
* Returns the handle associated with a given object.
94+
*
95+
* @return The handle associated with the given object or -1 if the object doesn't have a handle
96+
* or the object was collected. A valid handle is guaranteed to be != 0.
97+
*/
98+
@TruffleBoundary
99+
public synchronized long getIndex(T object) {
100+
Integer index = map.get(Objects.requireNonNull(object));
101+
return index != null
102+
? index
103+
: -1;
104+
}
105+
106+
@TruffleBoundary
107+
private int getFreeSlot() {
108+
if (!freeList.isEmpty()) {
109+
return freeList.removeFirst();
110+
}
111+
// 0 is a dummy entry, start at 1 to avoid NULL handles.
112+
for (int i = 1; i < handles.length; ++i) {
113+
if (handles[i] == null) {
114+
freeList.addLast(i);
115+
}
116+
}
117+
return freeList.isEmpty()
118+
? -1
119+
: freeList.removeFirst();
120+
}
121+
122+
@TruffleBoundary
123+
private synchronized int addHandle(T object) {
124+
Objects.requireNonNull(object);
125+
int index = getFreeSlot();
126+
if (index < 0) { // no slot available
127+
T[] newHandles = Arrays.copyOf(handles, 2 * handles.length);
128+
for (int i = handles.length; i < newHandles.length; ++i) {
129+
freeList.addLast(i);
130+
}
131+
handles = newHandles;
132+
index = freeList.removeFirst();
133+
}
134+
assert index >= 0;
135+
handles[index] = object;
136+
map.put(object, index);
137+
return index;
138+
}
139+
140+
@TruffleBoundary
141+
public synchronized boolean clean(T object) {
142+
Objects.requireNonNull(object);
143+
Integer index = map.get(object);
144+
if (index == null) {
145+
return false;
146+
}
147+
cleanIndex(index);
148+
return true;
149+
}
150+
151+
public synchronized boolean cleanIndex(long indexJ) {
152+
int index = Math.toIntExact(indexJ);
153+
if (invalidIndex(index)) {
154+
return false;
155+
}
156+
T object = handles[index];
157+
if (object != null) {
158+
handles[index] = null;
159+
map.remove(object);
160+
freeList.addLast(index);
161+
}
162+
return true;
163+
}
164+
165+
private boolean invalidIndex(int index) {
166+
return (index <= 0 || index >= handles.length);
167+
}
168+
}

0 commit comments

Comments
 (0)