js/src/jsutil.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
michael@0 2 * vim: set ts=8 sts=4 et sw=4 tw=99:
michael@0 3 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 /* Various JS utility functions. */
michael@0 8
michael@0 9 #include "jsutil.h"
michael@0 10
michael@0 11 #include "mozilla/Assertions.h"
michael@0 12 #include "mozilla/MathAlgorithms.h"
michael@0 13 #include "mozilla/PodOperations.h"
michael@0 14
michael@0 15 #include <stdio.h>
michael@0 16
michael@0 17 #include "jstypes.h"
michael@0 18
michael@0 19 #ifdef WIN32
michael@0 20 # include "jswin.h"
michael@0 21 #endif
michael@0 22
michael@0 23 #include "js/Utility.h"
michael@0 24
michael@0 25 using namespace js;
michael@0 26
michael@0 27 using mozilla::CeilingLog2Size;
michael@0 28 using mozilla::PodArrayZero;
michael@0 29
michael@0 30 #if defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
michael@0 31 /* For JS_OOM_POSSIBLY_FAIL in jsutil.h. */
michael@0 32 JS_PUBLIC_DATA(uint32_t) OOM_maxAllocations = UINT32_MAX;
michael@0 33 JS_PUBLIC_DATA(uint32_t) OOM_counter = 0;
michael@0 34 #endif
michael@0 35
michael@0 36 /*
michael@0 37 * Checks the assumption that JS_FUNC_TO_DATA_PTR and JS_DATA_TO_FUNC_PTR
michael@0 38 * macros uses to implement casts between function and data pointers.
michael@0 39 */
michael@0 40 JS_STATIC_ASSERT(sizeof(void *) == sizeof(void (*)()));
michael@0 41
michael@0 42 JS_PUBLIC_API(void)
michael@0 43 JS_Assert(const char *s, const char *file, int ln)
michael@0 44 {
michael@0 45 MOZ_ReportAssertionFailure(s, file, ln);
michael@0 46 MOZ_CRASH();
michael@0 47 }
michael@0 48
michael@0 49 #ifdef __linux__
michael@0 50
michael@0 51 #include <malloc.h>
michael@0 52 #include <stdlib.h>
michael@0 53
michael@0 54 namespace js {
michael@0 55
michael@0 56 // This function calls all the vanilla heap allocation functions. It is never
michael@0 57 // called, and exists purely to help config/check_vanilla_allocations.py. See
michael@0 58 // that script for more details.
michael@0 59 extern void
michael@0 60 AllTheNonBasicVanillaNewAllocations()
michael@0 61 {
michael@0 62 // posix_memalign and aligned_alloc aren't available on all Linux
michael@0 63 // configurations.
michael@0 64 //char *q;
michael@0 65 //posix_memalign((void**)&q, 16, 16);
michael@0 66
michael@0 67 intptr_t p =
michael@0 68 intptr_t(malloc(16)) +
michael@0 69 intptr_t(calloc(1, 16)) +
michael@0 70 intptr_t(realloc(nullptr, 16)) +
michael@0 71 intptr_t(new char) +
michael@0 72 intptr_t(new char) +
michael@0 73 intptr_t(new char) +
michael@0 74 intptr_t(new char[16]) +
michael@0 75 intptr_t(memalign(16, 16)) +
michael@0 76 //intptr_t(q) +
michael@0 77 //intptr_t(aligned_alloc(16, 16)) +
michael@0 78 intptr_t(valloc(4096)) +
michael@0 79 intptr_t(strdup("dummy"));
michael@0 80
michael@0 81 printf("%u\n", uint32_t(p)); // make sure |p| is not optimized away
michael@0 82
michael@0 83 free((int*)p); // this would crash if ever actually called
michael@0 84
michael@0 85 MOZ_CRASH();
michael@0 86 }
michael@0 87
michael@0 88 } // namespace js
michael@0 89
michael@0 90 #endif // __linux__
michael@0 91
michael@0 92 #ifdef JS_BASIC_STATS
michael@0 93
michael@0 94 #include <math.h>
michael@0 95
michael@0 96 /*
michael@0 97 * Histogram bins count occurrences of values <= the bin label, as follows:
michael@0 98 *
michael@0 99 * linear: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 or more
michael@0 100 * 2**x: 0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 or more
michael@0 101 * 10**x: 0, 1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9 or more
michael@0 102 *
michael@0 103 * We wish to count occurrences of 0 and 1 values separately, always.
michael@0 104 */
michael@0 105 static uint32_t
michael@0 106 BinToVal(unsigned logscale, unsigned bin)
michael@0 107 {
michael@0 108 JS_ASSERT(bin <= 10);
michael@0 109 if (bin <= 1 || logscale == 0)
michael@0 110 return bin;
michael@0 111 --bin;
michael@0 112 if (logscale == 2)
michael@0 113 return JS_BIT(bin);
michael@0 114 JS_ASSERT(logscale == 10);
michael@0 115 return uint32_t(pow(10.0, (double) bin));
michael@0 116 }
michael@0 117
michael@0 118 static unsigned
michael@0 119 ValToBin(unsigned logscale, uint32_t val)
michael@0 120 {
michael@0 121 unsigned bin;
michael@0 122
michael@0 123 if (val <= 1)
michael@0 124 return val;
michael@0 125 bin = (logscale == 10)
michael@0 126 ? (unsigned) ceil(log10((double) val))
michael@0 127 : (logscale == 2)
michael@0 128 ? (unsigned) CeilingLog2Size(val)
michael@0 129 : val;
michael@0 130 return Min(bin, 10U);
michael@0 131 }
michael@0 132
michael@0 133 void
michael@0 134 JS_BasicStatsAccum(JSBasicStats *bs, uint32_t val)
michael@0 135 {
michael@0 136 unsigned oldscale, newscale, bin;
michael@0 137 double mean;
michael@0 138
michael@0 139 ++bs->num;
michael@0 140 if (bs->max < val)
michael@0 141 bs->max = val;
michael@0 142 bs->sum += val;
michael@0 143 bs->sqsum += (double)val * val;
michael@0 144
michael@0 145 oldscale = bs->logscale;
michael@0 146 if (oldscale != 10) {
michael@0 147 mean = bs->sum / bs->num;
michael@0 148 if (bs->max > 16 && mean > 8) {
michael@0 149 newscale = (bs->max > 1e6 && mean > 1000) ? 10 : 2;
michael@0 150 if (newscale != oldscale) {
michael@0 151 uint32_t newhist[11], newbin;
michael@0 152
michael@0 153 PodArrayZero(newhist);
michael@0 154 for (bin = 0; bin <= 10; bin++) {
michael@0 155 newbin = ValToBin(newscale, BinToVal(oldscale, bin));
michael@0 156 newhist[newbin] += bs->hist[bin];
michael@0 157 }
michael@0 158 js_memcpy(bs->hist, newhist, sizeof bs->hist);
michael@0 159 bs->logscale = newscale;
michael@0 160 }
michael@0 161 }
michael@0 162 }
michael@0 163
michael@0 164 bin = ValToBin(bs->logscale, val);
michael@0 165 ++bs->hist[bin];
michael@0 166 }
michael@0 167
michael@0 168 double
michael@0 169 JS_MeanAndStdDev(uint32_t num, double sum, double sqsum, double *sigma)
michael@0 170 {
michael@0 171 double var;
michael@0 172
michael@0 173 if (num == 0 || sum == 0) {
michael@0 174 *sigma = 0;
michael@0 175 return 0;
michael@0 176 }
michael@0 177
michael@0 178 var = num * sqsum - sum * sum;
michael@0 179 if (var < 0 || num == 1)
michael@0 180 var = 0;
michael@0 181 else
michael@0 182 var /= (double)num * (num - 1);
michael@0 183
michael@0 184 /* Windows says sqrt(0.0) is "-1.#J" (?!) so we must test. */
michael@0 185 *sigma = (var != 0) ? sqrt(var) : 0;
michael@0 186 return sum / num;
michael@0 187 }
michael@0 188
michael@0 189 void
michael@0 190 JS_DumpBasicStats(JSBasicStats *bs, const char *title, FILE *fp)
michael@0 191 {
michael@0 192 double mean, sigma;
michael@0 193
michael@0 194 mean = JS_MeanAndStdDevBS(bs, &sigma);
michael@0 195 fprintf(fp, "\nmean %s %g, std. deviation %g, max %lu\n",
michael@0 196 title, mean, sigma, (unsigned long) bs->max);
michael@0 197 JS_DumpHistogram(bs, fp);
michael@0 198 }
michael@0 199
michael@0 200 void
michael@0 201 JS_DumpHistogram(JSBasicStats *bs, FILE *fp)
michael@0 202 {
michael@0 203 unsigned bin;
michael@0 204 uint32_t cnt, max;
michael@0 205 double sum, mean;
michael@0 206
michael@0 207 for (bin = 0, max = 0, sum = 0; bin <= 10; bin++) {
michael@0 208 cnt = bs->hist[bin];
michael@0 209 if (max < cnt)
michael@0 210 max = cnt;
michael@0 211 sum += cnt;
michael@0 212 }
michael@0 213 mean = sum / cnt;
michael@0 214 for (bin = 0; bin <= 10; bin++) {
michael@0 215 unsigned val = BinToVal(bs->logscale, bin);
michael@0 216 unsigned end = (bin == 10) ? 0 : BinToVal(bs->logscale, bin + 1);
michael@0 217 cnt = bs->hist[bin];
michael@0 218 if (val + 1 == end)
michael@0 219 fprintf(fp, " [%6u]", val);
michael@0 220 else if (end != 0)
michael@0 221 fprintf(fp, "[%6u, %6u]", val, end - 1);
michael@0 222 else
michael@0 223 fprintf(fp, "[%6u, +inf]", val);
michael@0 224 fprintf(fp, ": %8u ", cnt);
michael@0 225 if (cnt != 0) {
michael@0 226 if (max > 1e6 && mean > 1e3)
michael@0 227 cnt = uint32_t(ceil(log10((double) cnt)));
michael@0 228 else if (max > 16 && mean > 8)
michael@0 229 cnt = CeilingLog2Size(cnt);
michael@0 230 for (unsigned i = 0; i < cnt; i++)
michael@0 231 putc('*', fp);
michael@0 232 }
michael@0 233 putc('\n', fp);
michael@0 234 }
michael@0 235 }
michael@0 236
michael@0 237 #endif /* JS_BASIC_STATS */

mercurial