3
Fixing the bad JNI code in the font manager code. Two issues:
5
o The JNIEnv is unique to the thread. It cannot be saved by one thread and
6
reused by another. Use GetEnv instead.
8
o The 'font2D' jobject needs to be converted into a global reference because
9
its lifetime exceeds the lifetime of a native method call.
13
Appropriately register/free everything with the garbage collector.
19
# Date 1224202830 25200
20
# Node ID 3c9d6001d8a90698a3540a2a483717f26a98db78
21
# Parent 68730f05449cd4f39ce1cb82adc6c4e57f87554f
22
Crash in freetypeScaler.c due to insufficient GC protection
23
Summary: NewGlobalRef/DeleteGlobalRef as needed.
25
Contributed-by: yamauchi@google.com
27
diff --git a/make/sun/font/mapfile-vers.openjdk b/jdk/make/sun/font/mapfile-vers.openjdk
28
--- openjdk/jdk/make/sun/font/mapfile-vers.openjdk
29
+++ openjdk/jdk/make/sun/font/mapfile-vers.openjdk
38
diff --git a/src/share/native/sun/font/freetypeScaler.c b/src/share/native/sun/font/freetypeScaler.c
39
--- openjdk/jdk/src/share/native/sun/font/freetypeScaler.c
40
+++ openjdk/jdk/src/share/native/sun/font/freetypeScaler.c
42
#define ROUND(x) ((int) (x+0.5))
46
- JNI forbids sharing same env between different threads.
47
- We are safe, because pointer is overwritten every time we get into
48
- JNI call (see setupFTContext).
50
- Pointer is used by font data reading callbacks
51
- such as ReadTTFontFileFunc.
53
- NB: We may consider switching to JNI_GetEnv. */
59
void z_error(char *s) {}
62
+static JavaVM* jvm = NULL;
64
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
66
+ return JNI_VERSION_1_2;
69
/**************** Error handling utilities *****************/
71
static jmethodID invalidateScalerMID;
74
FT_Done_Face(scalerInfo->face);
75
FT_Done_FreeType(scalerInfo->library);
77
+ if (scalerInfo->font2D != NULL) {
78
+ (*env)->DeleteGlobalRef(env, scalerInfo->font2D);
81
if (scalerInfo->directBuffer != NULL) {
82
(*env)->DeleteGlobalRef(env, scalerInfo->directBuffer);
85
#define FILEDATACACHESIZE 1024
87
-/* NB: is it ever called? */
88
static void CloseTTFontFileFunc(FT_Stream stream) {
89
+ JNIEnv* env = (JNIEnv*) JNU_GetEnv(jvm, JNI_VERSION_1_2);
90
FTScalerInfo *scalerInfo = (FTScalerInfo *) stream->pathname.pointer;
91
- JNIEnv* env = scalerInfo->env;
92
jclass tmpClass = (*env)->FindClass(env, "sun/font/TrueTypeFont");
93
jfieldID platNameField =
94
(*env)->GetFieldID(env, tmpClass, "platName", "Ljava/lang/String;");
96
unsigned char* destBuffer,
97
unsigned long numBytes)
99
+ JNIEnv* env = (JNIEnv*) JNU_GetEnv(jvm, JNI_VERSION_1_2);
100
FTScalerInfo *scalerInfo = (FTScalerInfo *) stream->pathname.pointer;
101
- JNIEnv* env = scalerInfo->env;
106
if (scalerInfo == NULL)
109
- scalerInfo->env = env;
110
- scalerInfo->font2D = font2D;
111
+ scalerInfo->font2D = (*env)->NewGlobalRef(env, font2D);
112
scalerInfo->fontDataOffset = 0;
113
scalerInfo->fontDataLength = 0;
114
scalerInfo->fileSize = filesize;
117
error = FT_Init_FreeType(&scalerInfo->library);
119
+ (*env)->DeleteGlobalRef(env, scalerInfo->font2D);
125
if (scalerInfo->fontData != NULL)
126
free(scalerInfo->fontData);
127
+ (*env)->DeleteGlobalRef(env, scalerInfo->font2D);
132
FTScalerContext *context) {
135
- scalerInfo->env = env;
136
- scalerInfo->font2D = font2D;
137
+ if (scalerInfo->font2D != NULL) {
138
+ (*env)->DeleteGlobalRef(env, scalerInfo->font2D);
140
+ scalerInfo->font2D = (*env)->NewGlobalRef(env, font2D);
142
FT_Set_Transform(scalerInfo->face, &context->transform, NULL);