1
1
/*
2
- * Copyright (c) 2013, 2016 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2013, 2021 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
@@ -45,12 +45,21 @@ Java_com_sun_management_internal_DiagnosticCommandImpl_getDiagnosticCommands
45
45
return jmm_interface -> GetDiagnosticCommands (env );
46
46
}
47
47
48
- #define EXCEPTION_CHECK_AND_FREE (x ) do { \
49
- if ((*env)->ExceptionCheck(env)) { \
50
- free(x); \
51
- return NULL; \
52
- } \
53
- } while(0)
48
+ //
49
+ // Checks for an exception and if one occurred,
50
+ // pops 'pops' local frames and frees 'x' before
51
+ // returning NULL
52
+ //
53
+ #define POP_EXCEPTION_CHECK_AND_FREE (pops , x ) do { \
54
+ if ((*env)->ExceptionCheck(env)) { \
55
+ int i; \
56
+ for (i = 0; i < pops; i++) { \
57
+ (*env)->PopLocalFrame(env, NULL); \
58
+ } \
59
+ free(x); \
60
+ return NULL; \
61
+ } \
62
+ } while(0)
54
63
55
64
jobject getDiagnosticCommandArgumentInfoArray (JNIEnv * env , jstring command ,
56
65
int num_arg ) {
@@ -73,30 +82,29 @@ jobject getDiagnosticCommandArgumentInfoArray(JNIEnv *env, jstring command,
73
82
dcmd_arg_info_array );
74
83
dcmdArgInfoCls = (* env )-> FindClass (env ,
75
84
"com/sun/management/internal/DiagnosticCommandArgumentInfo" );
76
- if ((* env )-> ExceptionCheck (env )) {
77
- free (dcmd_arg_info_array );
78
- return NULL ;
79
- }
85
+ POP_EXCEPTION_CHECK_AND_FREE (0 , dcmd_arg_info_array );
80
86
81
87
result = (* env )-> NewObjectArray (env , num_arg , dcmdArgInfoCls , NULL );
82
88
if (result == NULL ) {
83
89
free (dcmd_arg_info_array );
84
90
return NULL ;
85
91
}
86
92
for (i = 0 ; i < num_arg ; i ++ ) {
87
- jstring jname , jdesc ,jtype ,jdefStr ;
93
+ // Capacity for 5 local refs: jname, jdesc, jtype, jdefStr and obj
94
+ (* env )-> PushLocalFrame (env , 5 );
95
+ jstring jname , jdesc , jtype , jdefStr ;
88
96
89
97
jname = (* env )-> NewStringUTF (env ,dcmd_arg_info_array [i ].name );
90
- EXCEPTION_CHECK_AND_FREE ( dcmd_arg_info_array );
98
+ POP_EXCEPTION_CHECK_AND_FREE ( 1 , dcmd_arg_info_array );
91
99
92
100
jdesc = (* env )-> NewStringUTF (env ,dcmd_arg_info_array [i ].description );
93
- EXCEPTION_CHECK_AND_FREE ( dcmd_arg_info_array );
101
+ POP_EXCEPTION_CHECK_AND_FREE ( 1 , dcmd_arg_info_array );
94
102
95
103
jtype = (* env )-> NewStringUTF (env ,dcmd_arg_info_array [i ].type );
96
- EXCEPTION_CHECK_AND_FREE ( dcmd_arg_info_array );
104
+ POP_EXCEPTION_CHECK_AND_FREE ( 1 , dcmd_arg_info_array );
97
105
98
106
jdefStr = (* env )-> NewStringUTF (env , dcmd_arg_info_array [i ].default_string );
99
- EXCEPTION_CHECK_AND_FREE ( dcmd_arg_info_array );
107
+ POP_EXCEPTION_CHECK_AND_FREE ( 1 , dcmd_arg_info_array );
100
108
obj = JNU_NewObjectByName (env ,
101
109
"com/sun/management/internal/DiagnosticCommandArgumentInfo" ,
102
110
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZI)V" ,
@@ -107,11 +115,13 @@ jobject getDiagnosticCommandArgumentInfoArray(JNIEnv *env, jstring command,
107
115
dcmd_arg_info_array [i ].multiple ,
108
116
dcmd_arg_info_array [i ].position );
109
117
if (obj == NULL ) {
118
+ (* env )-> PopLocalFrame (env , NULL );
110
119
free (dcmd_arg_info_array );
111
120
return NULL ;
112
121
}
122
+ obj = (* env )-> PopLocalFrame (env , obj );
113
123
(* env )-> SetObjectArrayElement (env , result , i , obj );
114
- EXCEPTION_CHECK_AND_FREE ( dcmd_arg_info_array );
124
+ POP_EXCEPTION_CHECK_AND_FREE ( 0 , dcmd_arg_info_array );
115
125
}
116
126
free (dcmd_arg_info_array );
117
127
arraysCls = (* env )-> FindClass (env , "java/util/Arrays" );
@@ -144,51 +154,67 @@ Java_com_sun_management_internal_DiagnosticCommandImpl_getDiagnosticCommandInfo
144
154
jint ret = jmm_interface -> GetOptionalSupport (env , & mos );
145
155
jsize num_commands ;
146
156
dcmdInfo * dcmd_info_array ;
147
- jstring jname , jdesc , jimpact ;
157
+ jstring jname , jdesc , jimpact , cmd ;
148
158
149
159
if (commands == NULL ) {
150
160
JNU_ThrowNullPointerException (env , "Invalid String Array" );
151
161
return NULL ;
152
162
}
153
163
num_commands = (* env )-> GetArrayLength (env , commands );
164
+ // Ensure capacity for 2 + num_commands local refs:
165
+ // 2 => dcmdInfoCls, result
166
+ // num_commmands => one obj per command
167
+ (* env )-> PushLocalFrame (env , 2 + num_commands );
154
168
dcmdInfoCls = (* env )-> FindClass (env ,
155
169
"com/sun/management/internal/DiagnosticCommandInfo" );
156
170
if ((* env )-> ExceptionCheck (env )) {
171
+ (* env )-> PopLocalFrame (env , NULL );
157
172
return NULL ;
158
173
}
159
174
160
175
result = (* env )-> NewObjectArray (env , num_commands , dcmdInfoCls , NULL );
161
176
if (result == NULL ) {
177
+ (* env )-> PopLocalFrame (env , NULL );
162
178
return NULL ;
163
179
}
164
180
if (num_commands == 0 ) {
181
+ result = (* env )-> PopLocalFrame (env , result );
165
182
/* Handle the 'zero commands' case specially to avoid calling 'malloc()' */
166
183
/* with a zero argument because that may legally return a NULL pointer. */
167
184
return result ;
168
185
}
169
186
dcmd_info_array = (dcmdInfo * ) malloc (num_commands * sizeof (dcmdInfo ));
170
187
if (dcmd_info_array == NULL ) {
188
+ (* env )-> PopLocalFrame (env , NULL );
171
189
JNU_ThrowOutOfMemoryError (env , NULL );
172
190
return NULL ;
173
191
}
174
192
jmm_interface -> GetDiagnosticCommandInfo (env , commands , dcmd_info_array );
175
193
for (i = 0 ; i < num_commands ; i ++ ) {
194
+ // Ensure capacity for 6 + 3 local refs:
195
+ // 6 => jname, jdesc, jimpact, cmd, args, obj
196
+ // 3 => permission class, name, action
197
+ (* env )-> PushLocalFrame (env , 6 + 3 );
198
+
199
+ cmd = (* env )-> GetObjectArrayElement (env , commands , i );
176
200
args = getDiagnosticCommandArgumentInfoArray (env ,
177
- ( * env ) -> GetObjectArrayElement ( env , commands , i ) ,
201
+ cmd ,
178
202
dcmd_info_array [i ].num_arguments );
179
203
if (args == NULL ) {
204
+ (* env )-> PopLocalFrame (env , NULL );
205
+ (* env )-> PopLocalFrame (env , NULL );
180
206
free (dcmd_info_array );
181
207
return NULL ;
182
208
}
183
209
184
210
jname = (* env )-> NewStringUTF (env ,dcmd_info_array [i ].name );
185
- EXCEPTION_CHECK_AND_FREE ( dcmd_info_array );
211
+ POP_EXCEPTION_CHECK_AND_FREE ( 2 , dcmd_info_array );
186
212
187
213
jdesc = (* env )-> NewStringUTF (env ,dcmd_info_array [i ].description );
188
- EXCEPTION_CHECK_AND_FREE ( dcmd_info_array );
214
+ POP_EXCEPTION_CHECK_AND_FREE ( 2 , dcmd_info_array );
189
215
190
216
jimpact = (* env )-> NewStringUTF (env ,dcmd_info_array [i ].impact );
191
- EXCEPTION_CHECK_AND_FREE ( dcmd_info_array );
217
+ POP_EXCEPTION_CHECK_AND_FREE ( 2 , dcmd_info_array );
192
218
193
219
obj = JNU_NewObjectByName (env ,
194
220
"com/sun/management/internal/DiagnosticCommandInfo" ,
@@ -200,13 +226,17 @@ Java_com_sun_management_internal_DiagnosticCommandImpl_getDiagnosticCommandInfo
200
226
dcmd_info_array [i ].enabled ,
201
227
args );
202
228
if (obj == NULL ) {
229
+ (* env )-> PopLocalFrame (env , NULL );
230
+ (* env )-> PopLocalFrame (env , NULL );
203
231
free (dcmd_info_array );
204
232
return NULL ;
205
233
}
234
+ obj = (* env )-> PopLocalFrame (env , obj );
206
235
207
236
(* env )-> SetObjectArrayElement (env , result , i , obj );
208
- EXCEPTION_CHECK_AND_FREE ( dcmd_info_array );
237
+ POP_EXCEPTION_CHECK_AND_FREE ( 1 , dcmd_info_array );
209
238
}
239
+ result = (* env )-> PopLocalFrame (env , result );
210
240
free (dcmd_info_array );
211
241
return result ;
212
242
}
0 commit comments