Skip to content

Commit 4244c3f

Browse files
VMDouble: Fix memory leaks in toString() and parseDouble()
Function _dtoa() from fdlibm/dtoa.c was failing to release memory allocated during double->string conversion. A similar problem was also present in parseDoubleFromChars() from java_lang_VMDouble.c. This caused leaks in VMDouble.toString() and .parseDouble(). Fixed by adding a new function _reclaim_reent, ported from current newlib. Fixes #34 (BZ#29263)
1 parent 4fc47fb commit 4244c3f

4 files changed

Lines changed: 42 additions & 13 deletions

File tree

native/fdlibm/dtoa.c

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -898,23 +898,11 @@ _DEFUN (_dtoa,
898898
{
899899
struct _Jv_reent reent;
900900
char *p;
901-
int i;
902901

903902
memset (&reent, 0, sizeof reent);
904903

905904
p = _dtoa_r (&reent, _d, mode, ndigits, decpt, sign, rve, float_type);
906905
strcpy (buf, p);
907906

908-
for (i = 0; i < reent._result_k; ++i)
909-
{
910-
struct _Jv_Bigint *l = reent._freelist[i];
911-
while (l)
912-
{
913-
struct _Jv_Bigint *next = l->_next;
914-
free (l);
915-
l = next;
916-
}
917-
}
918-
if (reent._freelist)
919-
free (reent._freelist);
907+
_reclaim_reent (&reent);
920908
}

native/fdlibm/mprec.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595

9696
#define _REENT_CHECK_MP(x)
9797
#define _REENT_MP_FREELIST(x) ((x)->_freelist)
98+
#define _REENT_MP_RESULT(x) ((x)->_result)
9899
#define _REENT_MP_P5S(x) ((x)->_p5s)
99100

100101
typedef unsigned long __ULong;
@@ -108,6 +109,42 @@ mprec_calloc (void *ignore, size_t x1, size_t x2)
108109
return result;
109110
}
110111

112+
void
113+
_reclaim_reent (struct _reent *ptr)
114+
{
115+
if (_REENT_MP_FREELIST(ptr))
116+
{
117+
int i;
118+
for (i = 0; i < ptr->_max_k; i++)
119+
{
120+
struct _Bigint *thisone, *nextone;
121+
122+
nextone = _REENT_MP_FREELIST(ptr)[i];
123+
while (nextone)
124+
{
125+
thisone = nextone;
126+
nextone = nextone->_next;
127+
free (thisone);
128+
}
129+
}
130+
131+
free (_REENT_MP_FREELIST(ptr));
132+
}
133+
if (_REENT_MP_RESULT(ptr))
134+
free (_REENT_MP_RESULT(ptr));
135+
if (_REENT_MP_P5S(ptr))
136+
{
137+
struct _Bigint *thisone, *nextone;
138+
nextone = _REENT_MP_P5S(ptr);
139+
while (nextone)
140+
{
141+
thisone = nextone;
142+
nextone = nextone->_next;
143+
free (thisone);
144+
}
145+
}
146+
}
147+
111148
_Bigint *
112149
_DEFUN (Balloc, (ptr, k), struct _reent *ptr _AND int k)
113150
{

native/fdlibm/mprec.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,13 +343,15 @@ typedef struct _Jv_Bigint _Jv_Bigint;
343343
#define _dtoa _Jv_dtoa
344344
#define _dtoa_r _Jv_dtoa_r
345345
#define _strtod_r _Jv_strtod_r
346+
#define _reclaim_reent _Jv_reclaim_reent
346347

347348
extern double _EXFUN(_strtod_r, (struct _Jv_reent *ptr, const char *s00, char **se));
348349
extern char* _EXFUN(_dtoa_r, (struct _Jv_reent *ptr, double d,
349350
int mode, int ndigits, int *decpt, int *sign,
350351
char **rve, int float_type));
351352
void _EXFUN(_dtoa, (double d, int mode, int ndigits, int *decpt, int *sign,
352353
char **rve, char *buf, int float_type));
354+
void _EXFUN(_reclaim_reent, (struct _Jv_reent *ptr));
353355

354356
double _EXFUN(ulp,(double x));
355357
double _EXFUN(b2d,(_Jv_Bigint *a , int *e));

native/jni/java-lang/java_lang_VMDouble.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,8 @@ parseDoubleFromChars(JNIEnv * env, const char * buf)
224224

225225
val = _strtod_r (&reent, p, &endptr);
226226

227+
_reclaim_reent (&reent);
228+
227229
#ifdef DEBUG
228230
fprintf (stderr, "java.lang.VMDouble.parseDouble val = %g\n", val);
229231
fprintf (stderr, "java.lang.VMDouble.parseDouble %p != %p ???\n",

0 commit comments

Comments
 (0)