Bug 516396: Merge rev. 4.8 from the trunk. NSPR_4_7_BRANCH
authorwtc%google.com
Sat, 03 Oct 2009 01:17:42 +0000
branchNSPR_4_7_BRANCH
changeset 4159 b05865b74b3c4ef2bcf1052f6909ab8fd682979f
parent 4132 80826c25888774ccadc45545199a15d8ca784521
child 4160 a46e66b3c10f116e1777169a584b4d371019fde8
push idunknown
push userunknown
push dateunknown
bugs516396
Bug 516396: Merge rev. 4.8 from the trunk. Backported two changes from dtoa.c upstream made on 2009-03-01 and 2009-04-19. Here is an excerpt from the 'changes' file describing these changes: dtoa.c and gdtoa/gdtoaimp.h and gdtoa/misc.c: reduce Kmax, and use MALLOC and FREE or free for huge blocks, which are possible only in pathological cases, such as dtoa calls in mode 3 with thousands of digits requested, or strtod() calls with thousand of digits. For the latter case, I have an alternate approach that runs much faster and uses less memory, but finding time to get it ready for distribution may take a while. dtoa.c, gdtoa/misc.c: do not attempt to allocate large memory blocks from the private memory pool (which was an unlikely event, but a bug). Tag: NSPR_4_7_BRANCH
pr/src/misc/prdtoa.c
--- a/pr/src/misc/prdtoa.c
+++ b/pr/src/misc/prdtoa.c
@@ -170,17 +170,22 @@ void _PR_CleanupDtoa(void)
  *	Llong, #define #ULLong to be the corresponding unsigned type.
  * #define KR_headers for old-style C function headers.
  * #define Bad_float_h if your system lacks a float.h or if it does not
  *	define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
  *	FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
  * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
  *	if memory is available and otherwise does something you deem
  *	appropriate.  If MALLOC is undefined, malloc will be invoked
- *	directly -- and assumed always to succeed.
+ *	directly -- and assumed always to succeed.  Similarly, if you
+ *	want something other than the system's free() to be called to
+ *	recycle memory acquired from MALLOC, #define FREE to be the
+ *	name of the alternate routine.  (FREE or free is only called in
+ *	pathological cases, e.g., in a dtoa call after a dtoa return in
+ *	mode 3 with thousands of digits requested.)
  * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making
  *	memory allocations from a private pool of memory when possible.
  *	When used, the private pool is PRIVATE_MEM bytes long:  2304 bytes,
  *	unless #defined to be a different length.  This default length
  *	suffices to get rid of MALLOC calls except for unusual cases,
  *	such as decimal-to-binary conversion of a very long string of
  *	digits.  The longest string dtoa can return is about 751 bytes
  *	long.  For conversions by strtod of strings of 800 digits and
@@ -538,17 +543,17 @@ extern double rnd_prod(double, double), 
 #endif
 #endif /* NO_LONG_LONG */
 
 #ifndef MULTIPLE_THREADS
 #define ACQUIRE_DTOA_LOCK(n)	/*nothing*/
 #define FREE_DTOA_LOCK(n)	/*nothing*/
 #endif
 
-#define Kmax 15
+#define Kmax 7
 
  struct
 Bigint {
 	struct Bigint *next;
 	int k, maxwds, sign, wds;
 	ULong x[1];
 	};
 
@@ -566,27 +571,28 @@ Balloc
 {
 	int x;
 	Bigint *rv;
 #ifndef Omit_Private_Memory
 	unsigned int len;
 #endif
 
 	ACQUIRE_DTOA_LOCK(0);
-	if (rv = freelist[k]) {
+	/* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */
+	/* but this case seems very unlikely. */
+	if (k <= Kmax && (rv = freelist[k]))
 		freelist[k] = rv->next;
-		}
 	else {
 		x = 1 << k;
 #ifdef Omit_Private_Memory
 		rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
 #else
 		len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
 			/sizeof(double);
-		if (pmem_next - private_mem + len <= PRIVATE_mem) {
+		if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) {
 			rv = (Bigint*)pmem_next;
 			pmem_next += len;
 			}
 		else
 			rv = (Bigint*)MALLOC(len*sizeof(double));
 #endif
 		rv->k = k;
 		rv->maxwds = x;
@@ -600,20 +606,28 @@ Balloc
 Bfree
 #ifdef KR_headers
 	(v) Bigint *v;
 #else
 	(Bigint *v)
 #endif
 {
 	if (v) {
-		ACQUIRE_DTOA_LOCK(0);
-		v->next = freelist[v->k];
-		freelist[v->k] = v;
-		FREE_DTOA_LOCK(0);
+		if (v->k > Kmax)
+#ifdef FREE
+			FREE((void*)v);
+#else
+			free((void*)v);
+#endif
+		else {
+			ACQUIRE_DTOA_LOCK(0);
+			v->next = freelist[v->k];
+			freelist[v->k] = v;
+			FREE_DTOA_LOCK(0);
+			}
 		}
 	}
 
 #define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
 y->wds*sizeof(Long) + 2*sizeof(int))
 
  static Bigint *
 multadd