Bumping manifests a=b2g-bump
[gecko.git] / js / src / jsutil.cpp
blob94b6f6a0cc833a85ed2927e1695b8d4705aa4099
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. */
9 #include "jsutil.h"
11 #include "mozilla/Assertions.h"
12 #include "mozilla/MathAlgorithms.h"
13 #include "mozilla/PodOperations.h"
15 #include <stdio.h>
17 #include "jstypes.h"
19 #ifdef WIN32
20 # include "jswin.h"
21 #endif
23 #include "js/Utility.h"
25 using namespace js;
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;
34 #endif
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 (*)()));
42 JS_PUBLIC_API(void)
43 JS_Assert(const char *s, const char *file, int ln)
45 MOZ_ReportAssertionFailure(s, file, ln);
46 MOZ_CRASH();
49 #ifdef __linux__
51 #include <malloc.h>
52 #include <stdlib.h>
54 namespace js {
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.
59 extern void
60 AllTheNonBasicVanillaNewAllocations()
62 // posix_memalign and aligned_alloc aren't available on all Linux
63 // configurations.
64 //char *q;
65 //posix_memalign((void**)&q, 16, 16);
67 intptr_t p =
68 intptr_t(malloc(16)) +
69 intptr_t(calloc(1, 16)) +
70 intptr_t(realloc(nullptr, 16)) +
71 intptr_t(new char) +
72 intptr_t(new char) +
73 intptr_t(new char) +
74 intptr_t(new char[16]) +
75 intptr_t(memalign(16, 16)) +
76 //intptr_t(q) +
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
85 MOZ_CRASH();
88 } // namespace js
90 #endif // __linux__
92 #ifdef JS_BASIC_STATS
94 #include <math.h>
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.
105 static uint32_t
106 BinToVal(unsigned logscale, unsigned bin)
108 JS_ASSERT(bin <= 10);
109 if (bin <= 1 || logscale == 0)
110 return bin;
111 --bin;
112 if (logscale == 2)
113 return JS_BIT(bin);
114 JS_ASSERT(logscale == 10);
115 return uint32_t(pow(10.0, (double) bin));
118 static unsigned
119 ValToBin(unsigned logscale, uint32_t val)
121 unsigned bin;
123 if (val <= 1)
124 return val;
125 bin = (logscale == 10)
126 ? (unsigned) ceil(log10((double) val))
127 : (logscale == 2)
128 ? (unsigned) CeilingLog2Size(val)
129 : val;
130 return Min(bin, 10U);
133 void
134 JS_BasicStatsAccum(JSBasicStats *bs, uint32_t val)
136 unsigned oldscale, newscale, bin;
137 double mean;
139 ++bs->num;
140 if (bs->max < val)
141 bs->max = val;
142 bs->sum += val;
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);
165 ++bs->hist[bin];
168 double
169 JS_MeanAndStdDev(uint32_t num, double sum, double sqsum, double *sigma)
171 double var;
173 if (num == 0 || sum == 0) {
174 *sigma = 0;
175 return 0;
178 var = num * sqsum - sum * sum;
179 if (var < 0 || num == 1)
180 var = 0;
181 else
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;
186 return sum / num;
189 void
190 JS_DumpBasicStats(JSBasicStats *bs, const char *title, FILE *fp)
192 double mean, sigma;
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);
200 void
201 JS_DumpHistogram(JSBasicStats *bs, FILE *fp)
203 unsigned bin;
204 uint32_t cnt, max;
205 double sum, mean;
207 for (bin = 0, max = 0, sum = 0; bin <= 10; bin++) {
208 cnt = bs->hist[bin];
209 if (max < cnt)
210 max = cnt;
211 sum += cnt;
213 mean = sum / cnt;
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);
217 cnt = bs->hist[bin];
218 if (val + 1 == end)
219 fprintf(fp, " [%6u]", val);
220 else if (end != 0)
221 fprintf(fp, "[%6u, %6u]", val, end - 1);
222 else
223 fprintf(fp, "[%6u, +inf]", val);
224 fprintf(fp, ": %8u ", cnt);
225 if (cnt != 0) {
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++)
231 putc('*', fp);
233 putc('\n', fp);
237 #endif /* JS_BASIC_STATS */