Bug 551276 - a more type-safe way to zero memory (r=Waldo)

--HG--
extra : rebase_source : fc5564c34cde6490a1d3b48a16a451f7e50c052a
This commit is contained in:
Luke Wagner 2010-03-10 15:34:12 -08:00
parent 2b44ad8323
commit a1a73dd94d
16 changed files with 71 additions and 37 deletions

View File

@ -2202,7 +2202,7 @@ array_sort(JSContext *cx, uintN argc, jsval *vp)
* initialization using memset.
*/
jsval *mergesort_tmp = vec + newlen;
memset(mergesort_tmp, 0, newlen * sizeof(jsval));
PodZero(mergesort_tmp, newlen);
tvr.changeLength(newlen * 2);
/* Here len == 2 * (newlen + undefs + number_of_holes). */
@ -2265,7 +2265,7 @@ array_sort(JSContext *cx, uintN argc, jsval *vp)
return false;
}
mergesort_tmp = vec + 2 * newlen;
memset(mergesort_tmp, 0, newlen * 2 * sizeof(jsval));
PodZero(mergesort_tmp, newlen * 2);
tvr.changeArray(vec, newlen * 4);
elemsize = 2 * sizeof(jsval);
}

View File

@ -1364,7 +1364,7 @@ js_ReportOutOfMemory(JSContext *cx)
const char *msg = efs ? efs->format : "Out of memory";
/* Fill out the report, but don't do anything that requires allocation. */
memset(&report, 0, sizeof (struct JSErrorReport));
PodZero(&report);
report.flags = JSREPORT_ERROR;
report.errorNumber = JSMSG_OUT_OF_MEMORY;
PopulateReportBlame(cx, &report);
@ -1455,7 +1455,7 @@ js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap)
return JS_FALSE;
messagelen = strlen(message);
memset(&report, 0, sizeof (struct JSErrorReport));
PodZero(&report);
report.flags = flags;
report.errorNumber = JSMSG_USER_DEFINED_ERROR;
report.ucmessage = ucmessage = js_InflateString(cx, message, &messagelen);
@ -1647,7 +1647,7 @@ js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,
return JS_TRUE;
warning = JSREPORT_IS_WARNING(flags);
memset(&report, 0, sizeof (struct JSErrorReport));
PodZero(&report);
report.flags = flags;
report.errorNumber = errorNumber;
PopulateReportBlame(cx, &report);

View File

@ -689,7 +689,7 @@ struct JSSetSlotRequest {
/* Caching Class.prototype lookups for the standard classes. */
struct JSClassProtoCache {
void purge() { memset(entries, 0, sizeof(entries)); }
void purge() { js::PodArrayZero(entries); }
#ifdef JS_PROTO_CACHE_METERING
struct Stats {

View File

@ -697,9 +697,9 @@ js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
argv[0] = OBJECT_TO_JSVAL(closure);
argv[1] = JSVAL_NULL;
memset(argv + 2, 0, (nslots - 2) * sizeof(jsval));
PodZero(argv + 2, nslots - 2);
memset(&frame, 0, sizeof(frame));
PodZero(&frame);
frame.script = script;
frame.regs = NULL;
frame.fun = fun;

View File

@ -988,7 +988,7 @@ js_InitExceptionClasses(JSContext *cx, JSObject *obj)
if (!js_GetClassPrototype(cx, obj, JSProto_Object, &obj_proto))
return NULL;
memset(roots, 0, sizeof(roots));
PodArrayZero(roots);
AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(roots), roots);
#ifdef __GNUC__
@ -1146,7 +1146,7 @@ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
cx->generatingError = JS_TRUE;
/* Protect the newly-created strings below from nesting GCs. */
memset(tv, 0, sizeof tv);
PodArrayZero(tv);
AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(tv), tv);
/*
@ -1211,7 +1211,7 @@ js_ReportUncaughtException(JSContext *cx)
if (!JS_GetPendingException(cx, &exn))
return false;
memset(roots, 0, sizeof roots);
PodArrayZero(roots);
AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(roots), roots);
/*
@ -1269,7 +1269,7 @@ js_ReportUncaughtException(JSContext *cx)
return false;
reportp = &report;
memset(&report, 0, sizeof report);
PodZero(&report);
report.filename = filename;
report.lineno = (uintN) lineno;
}

View File

@ -1678,7 +1678,7 @@ js_XDRFunctionObject(JSXDRState *xdr, JSObject **objp)
ok = false;
goto release_mark;
}
memset(bitmap, 0, bitmapLength * sizeof *bitmap);
PodZero(bitmap, bitmapLength);
for (i = 0; i != n; ++i) {
if (i < fun->nargs
? JS_LOCAL_NAME_TO_ATOM(names[i]) != NULL
@ -3035,7 +3035,7 @@ js_GetLocalNameArray(JSContext *cx, JSFunction *fun, JSArenaPool *pool)
#if JS_HAS_DESTRUCTURING
/* Some parameter names can be NULL due to destructuring patterns. */
memset(names, 0, fun->nargs * sizeof *names);
PodZero(names, fun->nargs);
#endif
map = fun->u.i.names.map;
args.fun = fun;

View File

@ -359,7 +359,7 @@ struct JSGCArena {
}
void clearMarkBitmap() {
memset(markBitmap, 0, sizeof(markBitmap));
PodArrayZero(markBitmap);
}
jsbitmap *getMarkBitmapEnd() {
@ -947,7 +947,7 @@ js_InitGC(JSRuntime *rt, uint32 maxbytes)
*/
rt->setGCLastBytes(8192);
METER(memset(&rt->gcStats, 0, sizeof rt->gcStats));
METER(PodZero(&rt->gcStats));
return true;
}
@ -1402,7 +1402,7 @@ JSGCFreeLists::moveTo(JSGCFreeLists *another)
{
*another = *this;
doubles = NULL;
memset(finalizables, 0, sizeof(finalizables));
PodArrayZero(finalizables);
JS_ASSERT(isEmpty());
}
@ -3088,7 +3088,7 @@ js_GC(JSContext *cx, JSGCInvocationKind gckind)
#ifdef JS_TRACER
if (gckind == GC_LAST_CONTEXT) {
/* Clear builtin functions, which are recreated on demand. */
memset(rt->builtinFunctions, 0, sizeof rt->builtinFunctions);
PodArrayZero(rt->builtinFunctions);
}
#endif

View File

@ -504,7 +504,7 @@ js_PurgePropertyCache(JSContext *cx, JSPropertyCache *cache)
return;
}
memset(cache->table, 0, sizeof cache->table);
PodArrayZero(cache->table);
cache->empty = JS_TRUE;
#ifdef JS_PROPERTY_CACHE_METERING

View File

@ -317,7 +317,7 @@ js_InitLock(JSThinLock *tl)
tl->owner = 0;
tl->fat = (JSFatLock*)JS_NEW_LOCK();
#else
memset(tl, 0, sizeof(JSThinLock));
PodZero(tl);
#endif
}
@ -1352,7 +1352,7 @@ js_InitTitle(JSContext *cx, JSTitle *title)
{
#ifdef JS_THREADSAFE
title->ownercx = cx;
memset(&title->lock, 0, sizeof title->lock);
PodZero(&title->lock);
/*
* Set u.link = NULL, not u.count = 0, in case the target architecture's

View File

@ -851,7 +851,7 @@ struct JSCompiler : private js::AutoGCRooter {
aleFreeList(NULL), tokenStream(cx), principals(NULL),
callerFrame(cfp), nodeList(NULL), functionCount(0), traceListHead(NULL)
{
memset(tempFreeList, 0, sizeof tempFreeList);
js::PodArrayZero(tempFreeList);
setPrincipals(prin);
JS_ASSERT_IF(cfp, cfp->script);
}

View File

@ -175,7 +175,7 @@ TraceRecorder::downSnapshot(FrameInfo* downFrame)
VMSideExit* exit = (VMSideExit*)
traceMonitor->traceAlloc->alloc(sizeof(VMSideExit) + sizeof(TraceType) * exitTypeMapLen);
memset(exit, 0, sizeof(VMSideExit));
PodZero(exit);
exit->from = fragment;
exit->calldepth = 0;
JS_ASSERT(unsigned(exit->calldepth) == callDepth);
@ -450,7 +450,7 @@ TraceRecorder::slurpDownFrames(jsbytecode* return_pc)
jsbytecode* recursive_pc = return_pc + JSOP_CALL_LENGTH;
VMSideExit* exit = (VMSideExit*)
traceMonitor->traceAlloc->alloc(sizeof(VMSideExit) + sizeof(TraceType) * safeSlots);
memset(exit, 0, sizeof(VMSideExit));
PodZero(exit);
exit->pc = (jsbytecode*)recursive_pc;
exit->from = fragment;
exit->exitType = RECURSIVE_SLURP_FAIL_EXIT;

View File

@ -77,6 +77,8 @@
#include "jsxml.h"
#endif
using namespace js;
#define JS_KEYWORD(keyword, type, op, version) \
const char js_##keyword##_str[] = #keyword;
#include "jskeyword.tbl"
@ -511,7 +513,7 @@ ReportCompileErrorNumberVA(JSContext *cx, JSTokenStream *ts, JSParseNode *pn,
warning = false;
}
memset(&report, 0, sizeof report);
PodZero(&report);
report.flags = flags;
report.errorNumber = errorNumber;
message = NULL;

View File

@ -829,7 +829,7 @@ js_NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natoms,
script = (JSScript *) cx->malloc(size);
if (!script)
return NULL;
memset(script, 0, sizeof(JSScript));
PodZero(script);
script->length = length;
script->version = cx->version;

View File

@ -43,6 +43,7 @@
#include "jsbit.h"
#include <new>
#include <string.h>
namespace js {
@ -296,6 +297,37 @@ class LazilyConstructed
}
};
template <class T>
JS_ALWAYS_INLINE static void
PodZero(T *t)
{
memset(t, 0, sizeof(T));
}
template <class T>
JS_ALWAYS_INLINE static void
PodZero(T *t, size_t nelem)
{
memset(t, 0, nelem * sizeof(T));
}
/*
* Arrays implicitly convert to pointers to their first element, which is
* dangerous when combined with the above PodZero definitions. Adding an
* overload for arrays is ambiguous, so we need another identifier. The
* ambiguous overload is left to catch mistaken uses of PodZero; if you get a
* compile error involving PodZero and array types, use PodArrayZero instead.
*/
template <class T, size_t N> static void PodZero(T (&)[N]); /* undefined */
template <class T, size_t N> static void PodZero(T (&)[N], size_t); /* undefined */
template <class T, size_t N>
JS_ALWAYS_INLINE static void
PodArrayZero(T (&t)[N])
{
memset(t, 0, N * sizeof(T));
}
} /* namespace js */
#endif /* jstl_h_ */

View File

@ -610,8 +610,8 @@ FragProfiling_showResults(TraceMonitor* tm)
uint64_t totCount = 0, cumulCount;
uint32_t totSE = 0;
size_t totCodeB = 0, totExitB = 0;
memset(topFragID, 0, sizeof(topFragID));
memset(topPI, 0, sizeof(topPI));
PodArrayZero(topFragID);
PodArrayZero(topPI);
FragStatsMap::Iter iter(*tm->profTab);
while (iter.next()) {
uint32_t fragID = iter.key();
@ -2699,7 +2699,7 @@ TraceMonitor::flush()
assembler = new (alloc) Assembler(*codeAlloc, alloc, alloc, core, &LogController, avmplus::AvmCore::config);
verbose_only( branches = NULL; )
memset(&vmfragments[0], 0, FRAGMENT_TABLE_SIZE * sizeof(TreeFragment*));
PodArrayZero(vmfragments);
reFragments = new (alloc) REHashMap(alloc);
needFlush = JS_FALSE;
@ -7382,7 +7382,7 @@ InitJIT(TraceMonitor *tm)
}
tm->lastFragID = 0;
#else
memset(&LogController, 0, sizeof(LogController));
PodZero(&LogController);
#endif
if (!did_we_check_processor_features) {
@ -7431,7 +7431,7 @@ InitJIT(TraceMonitor *tm)
verbose_only( tm->branches = NULL; )
#if !defined XP_WIN
debug_only(memset(&jitstats, 0, sizeof(jitstats)));
PodZero(&jitstats);
#endif
#ifdef JS_JIT_SPEW
@ -7526,7 +7526,7 @@ FinishJIT(TraceMonitor *tm)
}
#endif
memset(&tm->vmfragments[0], 0, FRAGMENT_TABLE_SIZE * sizeof(TreeFragment*));
PodArrayZero(tm->vmfragments);
if (tm->frameCache) {
delete tm->frameCache;
@ -9822,12 +9822,9 @@ TraceRecorder::record_EnterFrame(uintN& inlineCallCount)
RETURN_STOP_A("inner recursive tree is blacklisted");
JSContext* _cx = cx;
SlotList* globalSlots = tree->globalSlots;
TraceMonitor* tm = traceMonitor;
AbortRecording(cx, "trying to compile inner recursive tree");
JS_ASSERT(_cx->fp->argc == first->argc);
if (RecordTree(_cx, first, NULL, 0, globalSlots, Record_EnterFrame)) {
JS_ASSERT(tm->recorder);
}
RecordTree(_cx, first, NULL, 0, globalSlots, Record_EnterFrame);
break;
}
}

View File

@ -46,6 +46,7 @@
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jstl.h"
#ifdef WIN32
# include <windows.h>
@ -53,6 +54,8 @@
# include <signal.h>
#endif
using namespace js;
/*
* Checks the assumption that JS_FUNC_TO_DATA_PTR and JS_DATA_TO_FUNC_PTR
* macros uses to implement casts between function and data pointers.
@ -140,7 +143,7 @@ JS_BasicStatsAccum(JSBasicStats *bs, uint32 val)
if (newscale != oldscale) {
uint32 newhist[11], newbin;
memset(newhist, 0, sizeof newhist);
PodArrayZero(newhist);
for (bin = 0; bin <= 10; bin++) {
newbin = ValToBin(newscale, BinToVal(oldscale, bin));
newhist[newbin] += bs->hist[bin];