Bumping gaia.json for 1 gaia revision(s) a=gaia-bump
[gecko.git] / js / src / jsutil.cpp
blob5d1a074e0b6fc0c7fc575c4ef8640ac42e039691
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
36 JS_PUBLIC_API(void)
37 JS_Assert(const char* s, const char* file, int ln)
39 MOZ_ReportAssertionFailure(s, file, ln);
40 MOZ_CRASH();
43 #ifdef __linux__
45 #include <malloc.h>
46 #include <stdlib.h>
48 namespace js {
50 // This function calls all the vanilla heap allocation functions. It is never
51 // called, and exists purely to help config/check_vanilla_allocations.py. See
52 // that script for more details.
53 extern void
54 AllTheNonBasicVanillaNewAllocations()
56 // posix_memalign and aligned_alloc aren't available on all Linux
57 // configurations.
58 // valloc was deprecated in Android 5.0
59 //char* q;
60 //posix_memalign((void**)&q, 16, 16);
62 intptr_t p =
63 intptr_t(malloc(16)) +
64 intptr_t(calloc(1, 16)) +
65 intptr_t(realloc(nullptr, 16)) +
66 intptr_t(new char) +
67 intptr_t(new char) +
68 intptr_t(new char) +
69 intptr_t(new char[16]) +
70 intptr_t(memalign(16, 16)) +
71 //intptr_t(q) +
72 //intptr_t(aligned_alloc(16, 16)) +
73 //intptr_t(valloc(4096)) +
74 intptr_t(strdup("dummy"));
76 printf("%u\n", uint32_t(p)); // make sure |p| is not optimized away
78 free((int*)p); // this would crash if ever actually called
80 MOZ_CRASH();
83 } // namespace js
85 #endif // __linux__
87 #ifdef JS_BASIC_STATS
89 #include <math.h>
92 * Histogram bins count occurrences of values <= the bin label, as follows:
94 * linear: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 or more
95 * 2**x: 0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 or more
96 * 10**x: 0, 1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9 or more
98 * We wish to count occurrences of 0 and 1 values separately, always.
100 static uint32_t
101 BinToVal(unsigned logscale, unsigned bin)
103 MOZ_ASSERT(bin <= 10);
104 if (bin <= 1 || logscale == 0)
105 return bin;
106 --bin;
107 if (logscale == 2)
108 return JS_BIT(bin);
109 MOZ_ASSERT(logscale == 10);
110 return uint32_t(pow(10.0, (double) bin));
113 static unsigned
114 ValToBin(unsigned logscale, uint32_t val)
116 unsigned bin;
118 if (val <= 1)
119 return val;
120 bin = (logscale == 10)
121 ? (unsigned) ceil(log10((double) val))
122 : (logscale == 2)
123 ? (unsigned) CeilingLog2Size(val)
124 : val;
125 return Min(bin, 10U);
128 void
129 JS_BasicStatsAccum(JSBasicStats* bs, uint32_t val)
131 unsigned oldscale, newscale, bin;
132 double mean;
134 ++bs->num;
135 if (bs->max < val)
136 bs->max = val;
137 bs->sum += val;
138 bs->sqsum += (double)val * val;
140 oldscale = bs->logscale;
141 if (oldscale != 10) {
142 mean = bs->sum / bs->num;
143 if (bs->max > 16 && mean > 8) {
144 newscale = (bs->max > 1e6 && mean > 1000) ? 10 : 2;
145 if (newscale != oldscale) {
146 uint32_t newhist[11], newbin;
148 PodArrayZero(newhist);
149 for (bin = 0; bin <= 10; bin++) {
150 newbin = ValToBin(newscale, BinToVal(oldscale, bin));
151 newhist[newbin] += bs->hist[bin];
153 js_memcpy(bs->hist, newhist, sizeof bs->hist);
154 bs->logscale = newscale;
159 bin = ValToBin(bs->logscale, val);
160 ++bs->hist[bin];
163 double
164 JS_MeanAndStdDev(uint32_t num, double sum, double sqsum, double* sigma)
166 double var;
168 if (num == 0 || sum == 0) {
169 *sigma = 0;
170 return 0;
173 var = num * sqsum - sum * sum;
174 if (var < 0 || num == 1)
175 var = 0;
176 else
177 var /= (double)num * (num - 1);
179 /* Windows says sqrt(0.0) is "-1.#J" (?!) so we must test. */
180 *sigma = (var != 0) ? sqrt(var) : 0;
181 return sum / num;
184 void
185 JS_DumpBasicStats(JSBasicStats* bs, const char* title, FILE* fp)
187 double mean, sigma;
189 mean = JS_MeanAndStdDevBS(bs, &sigma);
190 fprintf(fp, "\nmean %s %g, std. deviation %g, max %lu\n",
191 title, mean, sigma, (unsigned long) bs->max);
192 JS_DumpHistogram(bs, fp);
195 void
196 JS_DumpHistogram(JSBasicStats* bs, FILE* fp)
198 unsigned bin;
199 uint32_t cnt, max;
200 double sum, mean;
202 for (bin = 0, max = 0, sum = 0; bin <= 10; bin++) {
203 cnt = bs->hist[bin];
204 if (max < cnt)
205 max = cnt;
206 sum += cnt;
208 mean = sum / cnt;
209 for (bin = 0; bin <= 10; bin++) {
210 unsigned val = BinToVal(bs->logscale, bin);
211 unsigned end = (bin == 10) ? 0 : BinToVal(bs->logscale, bin + 1);
212 cnt = bs->hist[bin];
213 if (val + 1 == end)
214 fprintf(fp, " [%6u]", val);
215 else if (end != 0)
216 fprintf(fp, "[%6u, %6u]", val, end - 1);
217 else
218 fprintf(fp, "[%6u, +inf]", val);
219 fprintf(fp, ": %8u ", cnt);
220 if (cnt != 0) {
221 if (max > 1e6 && mean > 1e3)
222 cnt = uint32_t(ceil(log10((double) cnt)));
223 else if (max > 16 && mean > 8)
224 cnt = CeilingLog2Size(cnt);
225 for (unsigned i = 0; i < cnt; i++)
226 putc('*', fp);
228 putc('\n', fp);
232 #endif /* JS_BASIC_STATS */