1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* Various JS utility functions. */
11 #include "mozilla/Assertions.h"
12 #include "mozilla/MathAlgorithms.h"
13 #include "mozilla/PodOperations.h"
23 #include "js/Utility.h"
27 using mozilla::CeilingLog2Size
;
28 using mozilla::PodArrayZero
;
30 #if defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
31 /* For JS_OOM_POSSIBLY_FAIL in jsutil.h. */
32 JS_PUBLIC_DATA(uint32_t) OOM_maxAllocations
= UINT32_MAX
;
33 JS_PUBLIC_DATA(uint32_t) OOM_counter
= 0;
37 * Checks the assumption that JS_FUNC_TO_DATA_PTR and JS_DATA_TO_FUNC_PTR
38 * macros uses to implement casts between function and data pointers.
40 JS_STATIC_ASSERT(sizeof(void *) == sizeof(void (*)()));
43 JS_Assert(const char *s
, const char *file
, int ln
)
45 MOZ_ReportAssertionFailure(s
, file
, ln
);
56 // This function calls all the vanilla heap allocation functions. It is never
57 // called, and exists purely to help config/check_vanilla_allocations.py. See
58 // that script for more details.
60 AllTheNonBasicVanillaNewAllocations()
62 // posix_memalign and aligned_alloc aren't available on all Linux
65 //posix_memalign((void**)&q, 16, 16);
68 intptr_t(malloc(16)) +
69 intptr_t(calloc(1, 16)) +
70 intptr_t(realloc(nullptr, 16)) +
74 intptr_t(new char[16]) +
75 intptr_t(memalign(16, 16)) +
77 //intptr_t(aligned_alloc(16, 16)) +
78 intptr_t(valloc(4096)) +
79 intptr_t(strdup("dummy"));
81 printf("%u\n", uint32_t(p
)); // make sure |p| is not optimized away
83 free((int*)p
); // this would crash if ever actually called
97 * Histogram bins count occurrences of values <= the bin label, as follows:
99 * linear: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 or more
100 * 2**x: 0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 or more
101 * 10**x: 0, 1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9 or more
103 * We wish to count occurrences of 0 and 1 values separately, always.
106 BinToVal(unsigned logscale
, unsigned bin
)
108 JS_ASSERT(bin
<= 10);
109 if (bin
<= 1 || logscale
== 0)
114 JS_ASSERT(logscale
== 10);
115 return uint32_t(pow(10.0, (double) bin
));
119 ValToBin(unsigned logscale
, uint32_t val
)
125 bin
= (logscale
== 10)
126 ? (unsigned) ceil(log10((double) val
))
128 ? (unsigned) CeilingLog2Size(val
)
130 return Min(bin
, 10U);
134 JS_BasicStatsAccum(JSBasicStats
*bs
, uint32_t val
)
136 unsigned oldscale
, newscale
, bin
;
143 bs
->sqsum
+= (double)val
* val
;
145 oldscale
= bs
->logscale
;
146 if (oldscale
!= 10) {
147 mean
= bs
->sum
/ bs
->num
;
148 if (bs
->max
> 16 && mean
> 8) {
149 newscale
= (bs
->max
> 1e6
&& mean
> 1000) ? 10 : 2;
150 if (newscale
!= oldscale
) {
151 uint32_t newhist
[11], newbin
;
153 PodArrayZero(newhist
);
154 for (bin
= 0; bin
<= 10; bin
++) {
155 newbin
= ValToBin(newscale
, BinToVal(oldscale
, bin
));
156 newhist
[newbin
] += bs
->hist
[bin
];
158 js_memcpy(bs
->hist
, newhist
, sizeof bs
->hist
);
159 bs
->logscale
= newscale
;
164 bin
= ValToBin(bs
->logscale
, val
);
169 JS_MeanAndStdDev(uint32_t num
, double sum
, double sqsum
, double *sigma
)
173 if (num
== 0 || sum
== 0) {
178 var
= num
* sqsum
- sum
* sum
;
179 if (var
< 0 || num
== 1)
182 var
/= (double)num
* (num
- 1);
184 /* Windows says sqrt(0.0) is "-1.#J" (?!) so we must test. */
185 *sigma
= (var
!= 0) ? sqrt(var
) : 0;
190 JS_DumpBasicStats(JSBasicStats
*bs
, const char *title
, FILE *fp
)
194 mean
= JS_MeanAndStdDevBS(bs
, &sigma
);
195 fprintf(fp
, "\nmean %s %g, std. deviation %g, max %lu\n",
196 title
, mean
, sigma
, (unsigned long) bs
->max
);
197 JS_DumpHistogram(bs
, fp
);
201 JS_DumpHistogram(JSBasicStats
*bs
, FILE *fp
)
207 for (bin
= 0, max
= 0, sum
= 0; bin
<= 10; bin
++) {
214 for (bin
= 0; bin
<= 10; bin
++) {
215 unsigned val
= BinToVal(bs
->logscale
, bin
);
216 unsigned end
= (bin
== 10) ? 0 : BinToVal(bs
->logscale
, bin
+ 1);
219 fprintf(fp
, " [%6u]", val
);
221 fprintf(fp
, "[%6u, %6u]", val
, end
- 1);
223 fprintf(fp
, "[%6u, +inf]", val
);
224 fprintf(fp
, ": %8u ", cnt
);
226 if (max
> 1e6
&& mean
> 1e3
)
227 cnt
= uint32_t(ceil(log10((double) cnt
)));
228 else if (max
> 16 && mean
> 8)
229 cnt
= CeilingLog2Size(cnt
);
230 for (unsigned i
= 0; i
< cnt
; i
++)
237 #endif /* JS_BASIC_STATS */