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 JS_Assert(const char* s
, const char* file
, int ln
)
39 MOZ_ReportAssertionFailure(s
, file
, ln
);
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.
54 AllTheNonBasicVanillaNewAllocations()
56 // posix_memalign and aligned_alloc aren't available on all Linux
58 // valloc was deprecated in Android 5.0
60 //posix_memalign((void**)&q, 16, 16);
63 intptr_t(malloc(16)) +
64 intptr_t(calloc(1, 16)) +
65 intptr_t(realloc(nullptr, 16)) +
69 intptr_t(new char[16]) +
70 intptr_t(memalign(16, 16)) +
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
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.
101 BinToVal(unsigned logscale
, unsigned bin
)
103 MOZ_ASSERT(bin
<= 10);
104 if (bin
<= 1 || logscale
== 0)
109 MOZ_ASSERT(logscale
== 10);
110 return uint32_t(pow(10.0, (double) bin
));
114 ValToBin(unsigned logscale
, uint32_t val
)
120 bin
= (logscale
== 10)
121 ? (unsigned) ceil(log10((double) val
))
123 ? (unsigned) CeilingLog2Size(val
)
125 return Min(bin
, 10U);
129 JS_BasicStatsAccum(JSBasicStats
* bs
, uint32_t val
)
131 unsigned oldscale
, newscale
, bin
;
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
);
164 JS_MeanAndStdDev(uint32_t num
, double sum
, double sqsum
, double* sigma
)
168 if (num
== 0 || sum
== 0) {
173 var
= num
* sqsum
- sum
* sum
;
174 if (var
< 0 || num
== 1)
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;
185 JS_DumpBasicStats(JSBasicStats
* bs
, const char* title
, FILE* fp
)
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
);
196 JS_DumpHistogram(JSBasicStats
* bs
, FILE* fp
)
202 for (bin
= 0, max
= 0, sum
= 0; bin
<= 10; bin
++) {
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);
214 fprintf(fp
, " [%6u]", val
);
216 fprintf(fp
, "[%6u, %6u]", val
, end
- 1);
218 fprintf(fp
, "[%6u, +inf]", val
);
219 fprintf(fp
, ": %8u ", cnt
);
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
++)
232 #endif /* JS_BASIC_STATS */