From 88cf1d87c60e963cbf4990d9fcefd9ea23880b62 Mon Sep 17 00:00:00 2001 From: Andreas Gal Date: Tue, 14 Jul 2009 17:03:20 -0700 Subject: [PATCH] Avoid integer math for GC trigger factor calculation in allocation path, take 2 (503463, r=dmandelin). --- js/src/jsapi.cpp | 2 +- js/src/jscntxt.h | 12 ++++++++---- js/src/jsgc.cpp | 27 +++++++++++++++++++++++---- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 312b416c7ef..13085424304 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -2585,7 +2585,7 @@ JS_SetGCParameter(JSRuntime *rt, JSGCParamKey key, uint32 value) default: JS_ASSERT(key == JSGC_TRIGGER_FACTOR); JS_ASSERT(value >= 100); - rt->gcTriggerFactor = value; + rt->setGCTriggerFactor(value); return; } } diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index 9f7c9183bff..0f8b5d8ce50 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -369,15 +369,16 @@ struct JSRuntime { JSDHashTable gcRootsHash; JSDHashTable *gcLocksHash; jsrefcount gcKeepAtoms; - uint32 gcBytes; - uint32 gcLastBytes; - uint32 gcMaxBytes; - uint32 gcMaxMallocBytes; + size_t gcBytes; + size_t gcLastBytes; + size_t gcMaxBytes; + size_t gcMaxMallocBytes; uint32 gcEmptyArenaPoolLifespan; uint32 gcLevel; uint32 gcNumber; JSTracer *gcMarkingTracer; uint32 gcTriggerFactor; + size_t gcTriggerBytes; volatile JSBool gcIsNeeded; /* @@ -682,6 +683,9 @@ struct JSRuntime { JSFunctionMeter functionMeter; char lastScriptFilename[1024]; #endif + + void setGCTriggerFactor(uint32 factor); + void setGCLastBytes(size_t lastBytes); }; /* Common macros to access thread-local caches in JSThread or JSRuntime. */ diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index c262021f540..d33259635eb 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -1308,13 +1308,13 @@ js_InitGC(JSRuntime *rt, uint32 maxbytes) * By default the trigger factor gets maximum possible value. This * means that GC will not be triggered by growth of GC memory (gcBytes). */ - rt->gcTriggerFactor = (uint32) -1; + rt->setGCTriggerFactor((uint32) -1); /* * The assigned value prevents GC from running when GC memory is too low * (during JS engine start). */ - rt->gcLastBytes = 8192; + rt->setGCLastBytes(8192); METER(memset(&rt->gcStats, 0, sizeof rt->gcStats)); return JS_TRUE; @@ -1800,6 +1800,25 @@ EnsureLocalFreeList(JSContext *cx) #endif +void +JSRuntime::setGCTriggerFactor(uint32 factor) +{ + JS_ASSERT(factor >= 100); + + gcTriggerFactor = factor; + setGCLastBytes(gcLastBytes); +} + +void +JSRuntime::setGCLastBytes(size_t lastBytes) +{ + gcLastBytes = lastBytes; + uint64 triggerBytes = uint64(lastBytes) * uint64(gcTriggerFactor / 100); + if (triggerBytes != size_t(triggerBytes)) + triggerBytes = size_t(-1); + gcTriggerBytes = size_t(triggerBytes); +} + static JS_INLINE bool IsGCThresholdReached(JSRuntime *rt) { @@ -1814,7 +1833,7 @@ IsGCThresholdReached(JSRuntime *rt) * the gcBytes value is close to zero at the JS engine start. */ return rt->gcMallocBytes >= rt->gcMaxMallocBytes || - rt->gcBytes / rt->gcTriggerFactor >= rt->gcLastBytes / 100; + rt->gcBytes >= rt->gcTriggerBytes; } void * @@ -3846,7 +3865,7 @@ out: goto restart; } - rt->gcLastBytes = rt->gcBytes; + rt->setGCLastBytes(rt->gcBytes); done_running: rt->gcLevel = 0; rt->gcRunning = JS_FALSE;