Bug 905300 - Remove dead code in SpiderMonkey. r=bhackett

This commit is contained in:
Jan de Mooij 2013-08-15 13:45:30 +02:00
parent b76cfc4979
commit 14be08cab8
29 changed files with 20 additions and 596 deletions

View File

@ -148,7 +148,6 @@ static bool sCCLockedOut;
static PRTime sCCLockedOutTime;
static JS::GCSliceCallback sPrevGCSliceCallback;
static js::AnalysisPurgeCallback sPrevAnalysisPurgeCallback;
static bool sHasRunGC;
@ -2568,32 +2567,6 @@ DOMGCSliceCallback(JSRuntime *aRt, JS::GCProgress aProgress, const JS::GCDescrip
(*sPrevGCSliceCallback)(aRt, aProgress, aDesc);
}
static void
DOMAnalysisPurgeCallback(JSRuntime *aRt, JS::Handle<JSFlatString*> aDesc)
{
NS_ASSERTION(NS_IsMainThread(), "GCs must run on the main thread");
PRTime delta = GetCollectionTimeDelta();
if (sPostGCEventsToConsole) {
NS_NAMED_LITERAL_STRING(kFmt, "Analysis Purge (T+%.1f) ");
nsString prefix;
prefix.Adopt(nsTextFormatter::smprintf(kFmt.get(),
double(delta) / PR_USEC_PER_SEC));
nsDependentJSString stats(aDesc);
nsString msg = prefix + stats;
nsCOMPtr<nsIConsoleService> cs = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
if (cs) {
cs->LogStringMessage(msg.get());
}
}
if (sPrevAnalysisPurgeCallback)
(*sPrevAnalysisPurgeCallback)(aRt, aDesc);
}
void
nsJSContext::ReportPendingException()
{
@ -2830,7 +2803,6 @@ nsJSRuntime::Init()
NS_ASSERTION(NS_IsMainThread(), "bad");
sPrevGCSliceCallback = JS::SetGCSliceCallback(sRuntime, DOMGCSliceCallback);
sPrevAnalysisPurgeCallback = js::SetAnalysisPurgeCallback(sRuntime, DOMAnalysisPurgeCallback);
// Set up the structured clone callbacks.
static JSStructuredCloneCallbacks cloneCallbacks = {
@ -2894,10 +2866,6 @@ nsJSRuntime::Init()
"javascript.options.mem.gc_high_frequency_high_limit_mb",
(void *)JSGC_HIGH_FREQUENCY_HIGH_LIMIT);
Preferences::RegisterCallbackAndCall(SetMemoryGCPrefChangedCallback,
"javascript.options.mem.analysis_purge_mb",
(void *)JSGC_ANALYSIS_PURGE_TRIGGER);
Preferences::RegisterCallbackAndCall(SetMemoryGCPrefChangedCallback,
"javascript.options.mem.gc_allocation_threshold_mb",
(void *)JSGC_ALLOCATION_THRESHOLD);

View File

@ -508,12 +508,6 @@ LoadJSGCMemoryOptions(const char* aPrefName, void* /* aClosure */)
continue;
}
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX "analysis_purge_mb");
if (memPrefName == matchName || (!rts && index == 8)) {
UpdateCommonJSGCMemoryOption(rts, matchName, JSGC_ANALYSIS_PURGE_TRIGGER);
continue;
}
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX
"gc_allocation_threshold_mb");
if (memPrefName == matchName || (!rts && index == 9)) {

View File

@ -55,7 +55,6 @@ struct JSSettings
JSSettings_JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX,
JSSettings_JSGC_HIGH_FREQUENCY_LOW_LIMIT,
JSSettings_JSGC_HIGH_FREQUENCY_HIGH_LIMIT,
JSSettings_JSGC_ANALYSIS_PURGE_TRIGGER,
JSSettings_JSGC_ALLOCATION_THRESHOLD,
JSSettings_JSGC_SLICE_TIME_BUDGET,
JSSettings_JSGC_DYNAMIC_HEAP_GROWTH,

View File

@ -4720,24 +4720,6 @@ IonBuilder::createThis(HandleFunction target, MDefinition *callee)
return createThisScripted(callee);
}
bool
IonBuilder::anyFunctionIsCloneAtCallsite(types::StackTypeSet *funTypes)
{
uint32_t count = funTypes->getObjectCount();
if (count < 1)
return false;
for (uint32_t i = 0; i < count; i++) {
JSObject *obj = funTypes->getSingleObject(i);
if (obj->is<JSFunction>() && obj->as<JSFunction>().isInterpreted() &&
obj->as<JSFunction>().nonLazyScript()->shouldCloneAtCallsite)
{
return true;
}
}
return false;
}
bool
IonBuilder::jsop_funcall(uint32_t argc)
{

View File

@ -577,7 +577,6 @@ class IonBuilder : public MIRGenerator
MTypeObjectDispatch *dispatch, MGetPropertyCache *cache,
MBasicBlock **fallbackTarget);
bool anyFunctionIsCloneAtCallsite(types::StackTypeSet *funTypes);
MDefinition *makeCallsiteClone(HandleFunction target, MDefinition *fun);
MCall *makeCallHelper(HandleFunction target, CallInfo &callInfo, bool cloneAtCallsite);
bool makeCall(HandleFunction target, CallInfo &callInfo, bool cloneAtCallsite);

View File

@ -155,15 +155,12 @@ class IonFrameIterator
bool isConstructing() const;
bool isEntryJSFrame() const;
void *calleeToken() const;
JSFunction *callee() const;
JSFunction *maybeCallee() const;
unsigned numActualArgs() const;
JSScript *script() const;
void baselineScriptAndPc(JSScript **scriptRes, jsbytecode **pcRes) const;
Value *nativeVp() const;
Value *actualArgs() const;
// Returns the return address of the frame above this one (that is, the

View File

@ -160,27 +160,6 @@ IonFrameIterator::isParallelFunctionFrame() const
return GetCalleeTokenTag(calleeToken()) == CalleeToken_ParallelFunction;
}
bool
IonFrameIterator::isEntryJSFrame() const
{
if (prevType() == IonFrame_OptimizedJS || prevType() == IonFrame_Unwound_OptimizedJS)
return false;
if (prevType() == IonFrame_BaselineStub || prevType() == IonFrame_Unwound_BaselineStub)
return false;
if (prevType() == IonFrame_Entry)
return true;
IonFrameIterator iter(*this);
++iter;
for (; !iter.done(); ++iter) {
if (iter.isScripted())
return false;
}
return true;
}
JSScript *
IonFrameIterator::script() const
{
@ -221,13 +200,6 @@ IonFrameIterator::baselineScriptAndPc(JSScript **scriptRes, jsbytecode **pcRes)
}
}
Value *
IonFrameIterator::nativeVp() const
{
JS_ASSERT(isNative());
return exitFrame()->nativeExit()->vp();
}
Value *
IonFrameIterator::actualArgs() const
{

View File

@ -64,7 +64,6 @@ class Loop
bool isInLoop(MDefinition *ins);
bool isBeforeLoop(MDefinition *ins);
bool isLoopInvariant(MInstruction *ins);
bool isLoopInvariant(MDefinition *ins);
// This method determines if this block hot within a loop. That is, if it's
// always or usually run when the loop executes
@ -353,15 +352,6 @@ Loop::isLoopInvariant(MInstruction *ins)
return true;
}
bool
Loop::isLoopInvariant(MDefinition *ins)
{
if (!isInLoop(ins))
return true;
return ins->isInstruction() && isLoopInvariant(ins->toInstruction());
}
bool
Loop::checkHotness(MBasicBlock *block)
{

View File

@ -1351,26 +1351,6 @@ LinearScanAllocator::UnhandledQueue::enqueueForward(LiveInterval *after, LiveInt
insertBefore(*i, interval);
}
/*
* Append to the queue head in O(1).
*/
void
LinearScanAllocator::UnhandledQueue::enqueueAtHead(LiveInterval *interval)
{
#ifdef DEBUG
// Assuming that the queue is in sorted order, assert that order is
// maintained by inserting at the back.
if (!empty()) {
LiveInterval *back = peekBack();
JS_ASSERT(back->start() >= interval->start());
JS_ASSERT_IF(back->start() == interval->start(),
back->requirement()->priority() >= interval->requirement()->priority());
}
#endif
pushBack(interval);
}
void
LinearScanAllocator::UnhandledQueue::assertSorted()
{

View File

@ -69,7 +69,6 @@ class LinearScanAllocator : public LiveRangeAllocator<LinearScanVirtualRegister>
public:
void enqueueForward(LiveInterval *after, LiveInterval *interval);
void enqueueBackward(LiveInterval *interval);
void enqueueAtHead(LiveInterval *interval);
void assertSorted();

View File

@ -67,17 +67,7 @@ ScriptAnalysis::addJump(JSContext *cx, unsigned offset,
if (offset < *currentOffset) {
hasLoops_ = true;
if (code->analyzed) {
/*
* Backedge in a do-while loop, the body has been analyzed. Rewalk
* the body to set inLoop bits.
*/
for (unsigned i = offset; i <= *currentOffset; i++) {
Bytecode *code = maybeCode(i);
if (code)
code->inLoop = true;
}
} else {
if (!code->analyzed) {
/*
* Backedge in a while/for loop, whose body has not been analyzed
* due to a lack of fallthrough at the loop head. Roll back the
@ -141,23 +131,12 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
escapedSlots[LocalSlot(script_, bi.frameIndex())] = allVarsAliased || bi->aliased();
}
/*
* If the script is in debug mode, JS_SetFrameReturnValue can be called at
* any safe point.
*/
if (cx->compartment()->debugMode())
usesReturnValue_ = true;
bool heavyweight = script_->function() && script_->function()->isHeavyweight();
isIonInlineable = true;
if (heavyweight || cx->compartment()->debugMode())
isIonInlineable = false;
modifiesArguments_ = false;
if (heavyweight)
modifiesArguments_ = true;
canTrackVars = true;
/*
@ -223,7 +202,6 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
* analyzed before the backedge was seen.
*/
if (forwardLoop) {
code->inLoop = true;
if (forwardLoop <= offset)
forwardLoop = 0;
}
@ -235,11 +213,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
code->analyzed = true;
if (forwardCatch)
code->inTryBlock = true;
if (script_->hasBreakpointsAt(pc)) {
code->safePoint = true;
canTrackVars = false;
isIonInlineable = false;
}
@ -265,7 +239,6 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
case JSOP_SETRVAL:
case JSOP_POPV:
usesReturnValue_ = true;
isIonInlineable = false;
break;
@ -307,16 +280,6 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
isIonInlineable = false;
break;
case JSOP_THIS:
usesThisValue_ = true;
break;
case JSOP_CALL:
case JSOP_NEW:
/* Only consider potentially inlineable calls here. */
hasFunctionCalls_ = true;
break;
case JSOP_TABLESWITCH: {
isIonInlineable = false;
unsigned defaultOffset = offset + GET_JUMP_OFFSET(pc);
@ -328,7 +291,6 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
if (!addJump(cx, defaultOffset, &nextOffset, &forwardJump, &forwardLoop, stackDepth))
return;
getCode(defaultOffset).safePoint = true;
for (int32_t i = low; i <= high; i++) {
unsigned targetOffset = offset + GET_JUMP_OFFSET(pc2);
@ -336,7 +298,6 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
if (!addJump(cx, targetOffset, &nextOffset, &forwardJump, &forwardLoop, stackDepth))
return;
}
getCode(targetOffset).safePoint = true;
pc2 += JUMP_OFFSET_LEN;
}
break;
@ -365,7 +326,6 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
if (!addJump(cx, catchOffset, &nextOffset, &forwardJump, &forwardLoop, stackDepth))
return;
getCode(catchOffset).exceptionEntry = true;
getCode(catchOffset).safePoint = true;
}
}
}
@ -399,10 +359,6 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
break;
}
case JSOP_SETARG:
modifiesArguments_ = true;
break;
case JSOP_GETPROP:
case JSOP_CALLPROP:
case JSOP_LENGTH:
@ -423,6 +379,8 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
/* Additional opcodes which can be both compiled both normally and inline. */
case JSOP_ARGUMENTS:
case JSOP_CALL:
case JSOP_NEW:
case JSOP_FUNCALL:
case JSOP_FUNAPPLY:
case JSOP_CALLEE:
@ -483,6 +441,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
case JSOP_ENDITER:
case JSOP_POP:
case JSOP_GETARG:
case JSOP_SETARG:
case JSOP_CALLARG:
case JSOP_BINDGNAME:
case JSOP_UINT16:
@ -519,6 +478,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
case JSOP_LOOPENTRY:
case JSOP_NOTEARG:
case JSOP_REST:
case JSOP_THIS:
break;
default:
@ -538,9 +498,6 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
unsigned targetOffset = offset + GET_JUMP_OFFSET(pc);
if (!addJump(cx, targetOffset, &nextOffset, &forwardJump, &forwardLoop, newStackDepth))
return;
if (op == JSOP_CASE || op == JSOP_DEFAULT)
getCode(targetOffset).safePoint = true;
}
/* Handle any fallthrough from this opcode. */
@ -629,9 +586,6 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
continue;
}
if (loop && code->safePoint)
loop->hasSafePoints = true;
jsbytecode *pc = script_->code + offset;
JSOp op = (JSOp) *pc;
@ -654,10 +608,6 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
JS_ASSERT_IF(loop, loop->head < offset);
}
/* Find the last jump target in the loop, other than the initial entry point. */
if (loop && code->jumpTarget && offset != loop->entry && offset > loop->lastBlock)
loop->lastBlock = offset;
if (code->exceptionEntry) {
DebugOnly<bool> found = false;
JSTryNote *tn = script_->trynotes()->vector;
@ -728,15 +678,6 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
}
break;
case JSOP_NEW:
case JSOP_CALL:
case JSOP_EVAL:
case JSOP_FUNAPPLY:
case JSOP_FUNCALL:
if (loop)
loop->hasCallsLoops = true;
break;
case JSOP_LOOPENTRY:
getCode(offset).loop = loop;
break;
@ -752,13 +693,6 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
*/
uint32_t targetOffset = FollowBranch(cx, script_, offset);
/*
* Watch for 'continue' statements in the loop body, which are
* jumps to the entry offset separate from the initial jump.
*/
if (loop && loop->entry == targetOffset && loop->entry > loop->lastBlock)
loop->lastBlock = loop->entry;
if (targetOffset < offset) {
/* This is a loop back edge, no lifetime to pull in yet. */
@ -767,14 +701,6 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
JS_ASSERT(nop == JSOP_LOOPHEAD);
#endif
/*
* If we already have a loop, it is an outer loop and we
* need to prune the last block in the loop --- we do not
* track 'continue' statements for outer loops.
*/
if (loop && loop->entry > loop->lastBlock)
loop->lastBlock = loop->entry;
LoopAnalysis *nloop = alloc.new_<LoopAnalysis>();
if (!nloop) {
js_free(saved);
@ -783,18 +709,12 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
}
PodZero(nloop);
if (loop) {
loop->hasCallsLoops = true;
nloop->depth = loop->depth + 1;
}
nloop->parent = loop;
loop = nloop;
getCode(targetOffset).loop = loop;
loop->head = targetOffset;
loop->backedge = offset;
loop->lastBlock = loop->head;
/*
* Find the entry jump, which will be a GOTO for 'for' or
@ -809,15 +729,15 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
jsbytecode *entrypc = script_->code + entry;
if (JSOp(*entrypc) == JSOP_GOTO)
loop->entry = entry + GET_JUMP_OFFSET(entrypc);
entry += GET_JUMP_OFFSET(entrypc);
else
loop->entry = targetOffset;
entry = targetOffset;
} else {
/* Do-while loop at the start of the script. */
loop->entry = targetOffset;
entry = targetOffset;
}
JS_ASSERT(script_->code[loop->entry] == JSOP_LOOPHEAD ||
script_->code[loop->entry] == JSOP_LOOPENTRY);
JS_ASSERT(script_->code[entry] == JSOP_LOOPHEAD ||
script_->code[entry] == JSOP_LOOPENTRY);
} else {
for (unsigned i = 0; i < savedCount; i++) {
LifetimeVariable &var = *saved[i];
@ -863,7 +783,7 @@ LifetimeVariable::print() const
{
Lifetime *segment = lifetime ? lifetime : saved;
while (segment) {
printf(" (%u,%u%s)", segment->start, segment->end, segment->loopTail ? ",tail" : "");
printf(" (%u,%u)", segment->start, segment->end);
segment = segment->next;
}
printf("\n");
@ -1032,7 +952,6 @@ ScriptAnalysis::extendVariable(JSContext *cx, LifetimeVariable &var,
return;
}
tail->start = segment->end;
tail->loopTail = true;
/*
* Clear the segment's saved end, but preserve in the tail if this
@ -1325,7 +1244,7 @@ ScriptAnalysis::analyzeSSA(JSContext *cx)
stackDepth += ndefs;
if (BytecodeUpdatesSlot(op)) {
if (op == JSOP_SETARG || op == JSOP_SETLOCAL) {
uint32_t slot = GetBytecodeSlot(script_, pc);
if (trackSlot(slot)) {
mergeBranchTarget(cx, values[slot], slot, branchTargets, offset);

View File

@ -80,15 +80,6 @@ class Bytecode
/* Whether this is a catch/finally entry point. */
bool exceptionEntry : 1;
/* Whether this is in a try block. */
bool inTryBlock : 1;
/* Whether this is in a loop. */
bool inLoop : 1;
/* Method JIT safe point. */
bool safePoint : 1;
/*
* Side effects of this bytecode were not determined by type inference.
* Either a property set with unknown lvalue, or call with unknown callee.
@ -295,13 +286,6 @@ static inline uint32_t GetBytecodeSlot(JSScript *script, jsbytecode *pc)
}
}
/* Slot opcodes which update SSA information. */
static inline bool
BytecodeUpdatesSlot(JSOp op)
{
return (op == JSOP_SETARG || op == JSOP_SETLOCAL);
}
/*
* Information about the lifetime of a local or argument. These form a linked
* list describing successive intervals in the program where the variable's
@ -324,13 +308,6 @@ struct Lifetime
*/
uint32_t savedEnd;
/*
* This is an artificial segment extending the lifetime of this variable
* when it is live at the head of the loop. It will not be used until the
* next iteration.
*/
bool loopTail;
/*
* The start of this lifetime is a bytecode writing the variable. Each
* write to a variable is associated with a lifetime.
@ -342,7 +319,7 @@ struct Lifetime
Lifetime(uint32_t offset, uint32_t savedEnd, Lifetime *next)
: start(offset), end(offset), savedEnd(savedEnd),
loopTail(false), write(false), next(next)
write(false), next(next)
{}
};
@ -361,29 +338,6 @@ class LoopAnalysis
* between the head and the backedge forms the loop body.
*/
uint32_t backedge;
/* Target offset of the initial jump or fallthrough into the loop. */
uint32_t entry;
/*
* Start of the last basic block in the loop, excluding the initial jump to
* entry. All code between lastBlock and the backedge runs in every
* iteration, and if entry >= lastBlock all code between entry and the
* backedge runs when the loop is initially entered.
*/
uint32_t lastBlock;
/* Loop nesting depth, 0 for the outermost loop. */
uint16_t depth;
/*
* This loop contains safe points in its body which the interpreter might
* join at directly.
*/
bool hasSafePoints;
/* This loop has calls or inner loops. */
bool hasCallsLoops;
};
/* Current lifetime information for a variable. */
@ -711,11 +665,7 @@ class ScriptAnalysis
/* --------- Bytecode analysis --------- */
bool usesReturnValue_:1;
bool usesScopeChain_:1;
bool usesThisValue_:1;
bool hasFunctionCalls_:1;
bool modifiesArguments_:1;
bool localsAliasStack_:1;
bool isIonInlineable:1;
bool canTrackVars:1;
@ -763,24 +713,13 @@ class ScriptAnalysis
/* Number of property read opcodes in the script. */
uint32_t numPropertyReads() const { return numPropertyReads_; }
/* Whether there are POPV/SETRVAL bytecodes which can write to the frame's rval. */
bool usesReturnValue() const { return usesReturnValue_; }
/* Whether there are NAME bytecodes which can access the frame's scope chain. */
bool usesScopeChain() const { return usesScopeChain_; }
bool usesThisValue() const { return usesThisValue_; }
bool hasFunctionCalls() const { return hasFunctionCalls_; }
uint32_t numReturnSites() const { return numReturnSites_; }
bool hasLoops() const { return hasLoops_; }
/*
* True if all named formal arguments are not modified. If the arguments
* object cannot escape, the arguments are never modified within the script.
*/
bool modifiesArguments() { return modifiesArguments_; }
/*
* True if there are any LOCAL opcodes aliasing values on the stack (above
* script_->nfixed).
@ -862,9 +801,6 @@ class ScriptAnalysis
inline types::StackTypeSet *poppedTypes(uint32_t offset, uint32_t which);
inline types::StackTypeSet *poppedTypes(const jsbytecode *pc, uint32_t which);
/* Whether an arithmetic operation is operating on integers, with an integer result. */
bool integerOperation(jsbytecode *pc);
bool trackUseChain(const SSAValue &v) {
JS_ASSERT_IF(v.kind() == SSAValue::VAR, trackSlot(v.varSlot()));
return v.kind() != SSAValue::EMPTY &&
@ -877,12 +813,6 @@ class ScriptAnalysis
*/
inline SSAUseChain *& useChain(const SSAValue &v);
LoopAnalysis *getLoop(uint32_t offset) {
JS_ASSERT(offset < script_->length);
return getCode(offset).loop;
}
LoopAnalysis *getLoop(const jsbytecode *pc) { return getLoop(pc - script_->code); }
/* For a JSOP_CALL* op, get the pc of the corresponding JSOP_CALL/NEW/etc. */
inline jsbytecode *getCallPC(jsbytecode *pc);

View File

@ -2495,9 +2495,6 @@ JS_SetGCParameter(JSRuntime *rt, JSGCParamKey key, uint32_t value)
case JSGC_DYNAMIC_MARK_SLICE:
rt->gcDynamicMarkSlice = value;
break;
case JSGC_ANALYSIS_PURGE_TRIGGER:
rt->analysisPurgeTriggerBytes = value * 1024 * 1024;
break;
case JSGC_ALLOCATION_THRESHOLD:
rt->gcAllocationThreshold = value * 1024 * 1024;
break;
@ -2550,8 +2547,6 @@ JS_GetGCParameter(JSRuntime *rt, JSGCParamKey key)
return rt->gcDynamicHeapGrowth;
case JSGC_DYNAMIC_MARK_SLICE:
return rt->gcDynamicMarkSlice;
case JSGC_ANALYSIS_PURGE_TRIGGER:
return rt->analysisPurgeTriggerBytes / 1024 / 1024;
case JSGC_ALLOCATION_THRESHOLD:
return rt->gcAllocationThreshold / 1024 / 1024;
default:

View File

@ -2783,18 +2783,15 @@ typedef enum JSGCParamKey {
/* If true, high-frequency GCs will use a longer mark slice. */
JSGC_DYNAMIC_MARK_SLICE = 18,
/* Number of megabytes of analysis data to allocate before purging. */
JSGC_ANALYSIS_PURGE_TRIGGER = 19,
/* Lower limit after which we limit the heap growth. */
JSGC_ALLOCATION_THRESHOLD = 20,
JSGC_ALLOCATION_THRESHOLD = 19,
/*
* We decommit memory lazily. If more than this number of megabytes is
* available to be decommitted, then JS_MaybeGC will trigger a shrinking GC
* to decommit it.
*/
JSGC_DECOMMIT_THRESHOLD = 21
JSGC_DECOMMIT_THRESHOLD = 20
} JSGCParamKey;
typedef enum JSGCMode {

View File

@ -813,14 +813,6 @@ GCDescription::formatJSON(JSRuntime *rt, uint64_t timestamp) const
return rt->gcStats.formatJSON(timestamp);
}
JS_FRIEND_API(AnalysisPurgeCallback)
js::SetAnalysisPurgeCallback(JSRuntime *rt, AnalysisPurgeCallback callback)
{
AnalysisPurgeCallback old = rt->analysisPurgeCallback;
rt->analysisPurgeCallback = callback;
return old;
}
JS_FRIEND_API(void)
JS::NotifyDidPaint(JSRuntime *rt)
{

View File

@ -772,12 +772,6 @@ GetContextStructuredCloneCallbacks(JSContext *cx);
extern JS_FRIEND_API(bool)
IsContextRunningJS(JSContext *cx);
typedef void
(* AnalysisPurgeCallback)(JSRuntime *rt, JS::Handle<JSFlatString*> desc);
extern JS_FRIEND_API(AnalysisPurgeCallback)
SetAnalysisPurgeCallback(JSRuntime *rt, AnalysisPurgeCallback callback);
typedef bool
(* DOMInstanceClassMatchesProto)(JS::HandleObject protoObject, uint32_t protoID,
uint32_t depth);

View File

@ -4808,8 +4808,6 @@ gc::RunDebugGC(JSContext *cx)
{
rt->gcIncrementalLimit = rt->gcZealFrequency / 2;
}
} else if (type == ZealPurgeAnalysisValue) {
cx->compartment()->types.maybePurgeAnalysis(cx, /* force = */ true);
} else {
Collect(rt, false, SliceBudget::Unlimited, GC_NORMAL, JS::gcreason::DEBUG_GC);
}

View File

@ -1349,8 +1349,7 @@ const int ZealIncrementalMarkAllThenFinish = 9;
const int ZealIncrementalMultipleSlices = 10;
const int ZealVerifierPostValue = 11;
const int ZealFrameVerifierPostValue = 12;
const int ZealPurgeAnalysisValue = 13;
const int ZealLimit = 13;
const int ZealLimit = 12;
enum VerifierType {
PreBarrierVerifier,

View File

@ -353,64 +353,6 @@ TypeSet::isSubset(TypeSet *other)
return true;
}
bool
TypeSet::isSubsetIgnorePrimitives(TypeSet *other)
{
TypeFlags otherFlags = other->baseFlags() | TYPE_FLAG_PRIMITIVE;
if ((baseFlags() & otherFlags) != baseFlags())
return false;
if (unknownObject()) {
JS_ASSERT(other->unknownObject());
} else {
for (unsigned i = 0; i < getObjectCount(); i++) {
TypeObjectKey *obj = getObject(i);
if (!obj)
continue;
if (!other->hasType(Type::ObjectType(obj)))
return false;
}
}
return true;
}
bool
TypeSet::intersectionEmpty(TypeSet *other)
{
// For unknown/unknownObject there is no reason they couldn't intersect.
// I.e. we eagerly return their intersection isn't empty.
// That's ok, since we can't make predictions that can be checked to not hold.
if (unknown() || other->unknown())
return false;
if (unknownObject() && other->unknownObject())
return false;
if (unknownObject() && other->getObjectCount() > 0)
return false;
if (other->unknownObject() && getObjectCount() > 0)
return false;
// Test if there is an intersection in the baseFlags
if ((baseFlags() & other->baseFlags()) != 0)
return false;
// Test if there are object that are in both TypeSets
if (!unknownObject()) {
for (unsigned i = 0; i < getObjectCount(); i++) {
TypeObjectKey *obj = getObject(i);
if (!obj)
continue;
if (other->hasType(Type::ObjectType(obj)))
return false;
}
}
return true;
}
inline void
TypeSet::addTypesToConstraint(JSContext *cx, TypeConstraint *constraint)
{
@ -2003,22 +1945,6 @@ HeapTypeSet::knownNonEmpty(JSContext *cx)
return false;
}
bool
StackTypeSet::knownNonStringPrimitive()
{
TypeFlags flags = baseFlags();
if (baseObjectCount() > 0)
return false;
if (flags >= TYPE_FLAG_STRING)
return false;
if (baseFlags() == 0)
return false;
return true;
}
bool
StackTypeSet::filtersType(const StackTypeSet *other, Type filteredType) const
{
@ -4788,29 +4714,6 @@ ScriptAnalysis::analyzeTypes(JSContext *cx)
TypeScript::AddFreezeConstraints(cx, script_);
}
bool
ScriptAnalysis::integerOperation(jsbytecode *pc)
{
JS_ASSERT(uint32_t(pc - script_->code) < script_->length);
switch (JSOp(*pc)) {
case JSOP_ADD:
case JSOP_SUB:
case JSOP_MUL:
case JSOP_DIV:
if (pushedTypes(pc, 0)->getKnownTypeTag() != JSVAL_TYPE_INT32)
return false;
if (poppedTypes(pc, 0)->getKnownTypeTag() != JSVAL_TYPE_INT32)
return false;
if (poppedTypes(pc, 1)->getKnownTypeTag() != JSVAL_TYPE_INT32)
return false;
return true;
default:
return true;
}
}
/*
* Persistent constraint clearing out newScript and definite properties from
* an object should a property on another object get a getter or setter.
@ -6660,102 +6563,6 @@ TypeScript::AddFreezeConstraints(JSContext *cx, JSScript *script)
}
}
/* static */ void
TypeScript::Purge(JSContext *cx, HandleScript script)
{
if (!script->types)
return;
unsigned num = NumTypeSets(script);
TypeSet *typeArray = script->types->typeArray();
TypeSet *returnTypes = ReturnTypes(script);
bool ranInference = script->hasAnalysis() && script->analysis()->ranInference();
script->clearAnalysis();
if (!ranInference && !script->hasFreezeConstraints) {
/*
* Even if the script hasn't been analyzed by TI, TypeConstraintCall
* can still add constraints on 'this' for 'new' calls.
*/
ThisTypes(script)->constraintList = NULL;
#ifdef DEBUG
for (size_t i = 0; i < num; i++) {
TypeSet *types = &typeArray[i];
JS_ASSERT_IF(types != returnTypes, !types->constraintList);
}
#endif
return;
}
for (size_t i = 0; i < num; i++) {
TypeSet *types = &typeArray[i];
if (types != returnTypes)
types->constraintList = NULL;
}
if (script->hasFreezeConstraints)
TypeScript::AddFreezeConstraints(cx, script);
}
void
TypeCompartment::maybePurgeAnalysis(JSContext *cx, bool force)
{
// FIXME bug 781657
return;
JS_ASSERT(this == &cx->compartment()->types);
JS_ASSERT(!cx->compartment()->activeAnalysis);
if (!cx->typeInferenceEnabled())
return;
size_t triggerBytes = cx->runtime()->analysisPurgeTriggerBytes;
size_t beforeUsed = cx->compartment()->analysisLifoAlloc.used();
if (!force) {
if (!triggerBytes || triggerBytes >= beforeUsed)
return;
}
AutoEnterAnalysis enter(cx);
/* Reset the analysis pool, making its memory available for reuse. */
cx->compartment()->analysisLifoAlloc.releaseAll();
uint64_t start = PRMJ_Now();
for (gc::CellIter i(cx->zone(), gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
RootedScript script(cx, i.get<JSScript>());
if (script->compartment() == cx->compartment())
TypeScript::Purge(cx, script);
}
uint64_t done = PRMJ_Now();
if (cx->runtime()->analysisPurgeCallback) {
size_t afterUsed = cx->compartment()->analysisLifoAlloc.used();
size_t typeUsed = cx->typeLifoAlloc().used();
char buf[1000];
JS_snprintf(buf, sizeof(buf),
"Total Time %.2f ms, %d bytes before, %d bytes after\n",
(done - start) / double(PRMJ_USEC_PER_MSEC),
(int) (beforeUsed + typeUsed),
(int) (afterUsed + typeUsed));
JSString *desc = JS_NewStringCopyZ(cx, buf);
if (!desc) {
cx->clearPendingException();
return;
}
JS::Rooted<JSFlatString*> flat(cx, &desc->asFlat());
cx->runtime()->analysisPurgeCallback(cx->runtime(), flat);
}
}
static void
SizeOfScriptTypeInferenceData(JSScript *script, JS::TypeInferenceSizes *sizes,
mozilla::MallocSizeOf mallocSizeOf)

View File

@ -535,8 +535,6 @@ class TypeSet
* This variant doesn't freeze constraints. That variant is called knownSubset
*/
bool isSubset(TypeSet *other);
bool isSubsetIgnorePrimitives(TypeSet *other);
bool intersectionEmpty(TypeSet *other);
inline StackTypeSet *toStackTypeSet();
inline HeapTypeSet *toHeapTypeSet();
@ -650,12 +648,6 @@ class StackTypeSet : public TypeSet
*/
bool filtersType(const StackTypeSet *other, Type type) const;
/*
* Get whether this type only contains non-string primitives:
* null/undefined/int/double, or some combination of those.
*/
bool knownNonStringPrimitive();
enum DoubleConversion {
/* All types in the set should use eager double conversion. */
AlwaysConvertToDoubles,
@ -1439,8 +1431,6 @@ struct TypeCompartment
void sweepShapes(FreeOp *fop);
void sweepCompilerOutputs(FreeOp *fop, bool discardConstraints);
void maybePurgeAnalysis(JSContext *cx, bool force = false);
void finalizeObjects();
};

View File

@ -797,12 +797,6 @@ Sprinter::operator[](size_t off)
return *(base + off);
}
bool
Sprinter::empty() const
{
return *base == 0;
}
char *
Sprinter::reserve(size_t len)
{
@ -818,15 +812,6 @@ Sprinter::reserve(size_t len)
return sb;
}
char *
Sprinter::reserveAndClear(size_t len)
{
char *sb = reserve(len);
if (sb)
memset(sb, 0, len);
return sb;
}
ptrdiff_t
Sprinter::put(const char *s, size_t len)
{
@ -904,35 +889,15 @@ Sprinter::printf(const char *fmt, ...)
return -1;
}
void
Sprinter::setOffset(const char *end)
{
JS_ASSERT(end >= base && end < base + size);
offset = end - base;
}
void
Sprinter::setOffset(ptrdiff_t off)
{
JS_ASSERT(off >= 0 && (size_t) off < size);
offset = off;
}
ptrdiff_t
Sprinter::getOffset() const
{
return offset;
}
ptrdiff_t
Sprinter::getOffsetOf(const char *string) const
{
JS_ASSERT(string >= base && string < base + size);
return string - base;
}
void
Sprinter::reportOutOfMemory() {
Sprinter::reportOutOfMemory()
{
if (reportedOOM)
return;
js_ReportOutOfMemory(context);
@ -940,7 +905,8 @@ Sprinter::reportOutOfMemory() {
}
bool
Sprinter::hadOutOfMemory() const {
Sprinter::hadOutOfMemory() const
{
return reportedOOM;
}

View File

@ -451,8 +451,6 @@ class Sprinter
char *stringAt(ptrdiff_t off) const;
/* Returns the char at offset |off| */
char &operator[](size_t off);
/* Test if this Sprinter is empty */
bool empty() const;
/*
* Attempt to reserve len + 1 space (for a trailing NULL byte). If the
@ -460,8 +458,6 @@ class Sprinter
* internal content. The caller *must* completely fill this space on success.
*/
char *reserve(size_t len);
/* Like reserve, but memory is initialized to 0 */
char *reserveAndClear(size_t len);
/*
* Puts |len| characters from |s| at the current position and return an offset to
@ -474,13 +470,7 @@ class Sprinter
/* Prints a formatted string into the buffer */
int printf(const char *fmt, ...);
/* Change the offset */
void setOffset(const char *end);
void setOffset(ptrdiff_t off);
/* Get the offset */
ptrdiff_t getOffset() const;
ptrdiff_t getOffsetOf(const char *string) const;
/*
* Report that a string operation failed to get the memory it requested. The

View File

@ -2004,14 +2004,6 @@ JSScript::numNotes()
return sn - notes_ + 1; /* +1 for the terminator */
}
bool
JSScript::isShortRunning()
{
return length < 100 &&
hasAnalysis() &&
!analysis()->hasFunctionCalls();
}
js::GlobalObject&
JSScript::uninlinedGlobal() const
{

View File

@ -803,9 +803,6 @@ class JSScript : public js::gc::Cell
inline void clearAnalysis();
inline js::analyze::ScriptAnalysis *analysis();
/* Heuristic to check if the function is expected to be "short running". */
bool isShortRunning();
inline void clearPropertyReadTypes();
inline js::GlobalObject &global() const;

View File

@ -4021,17 +4021,6 @@ js_strlen(const jschar *s)
return (size_t)(t - s);
}
jschar *
js_strchr(const jschar *s, jschar c)
{
while (*s != 0) {
if (*s == c)
return (jschar *)s;
s++;
}
return NULL;
}
jschar *
js_strdup(JSContext *cx, const jschar *s)
{

View File

@ -224,9 +224,6 @@ StringHasPattern(const jschar *text, uint32_t textlen,
extern size_t
js_strlen(const jschar *s);
extern jschar *
js_strchr(const jschar *s, jschar c);
extern jschar *
js_strchr_limit(const jschar *s, jschar c, const jschar *limit);

View File

@ -215,8 +215,6 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
gcCallback(NULL),
gcSliceCallback(NULL),
gcFinalizeCallback(NULL),
analysisPurgeCallback(NULL),
analysisPurgeTriggerBytes(0),
gcMallocBytes(0),
scriptAndCountsVector(NULL),
NaNValue(UndefinedValue()),

View File

@ -1171,7 +1171,6 @@ struct JSRuntime : public JS::shadow::Runtime,
bool needZealousGC() {
if (gcNextScheduled > 0 && --gcNextScheduled == 0) {
if (gcZeal() == js::gc::ZealAllocValue ||
gcZeal() == js::gc::ZealPurgeAnalysisValue ||
(gcZeal() >= js::gc::ZealIncrementalRootsThenFinish &&
gcZeal() <= js::gc::ZealIncrementalMultipleSlices))
{
@ -1195,9 +1194,6 @@ struct JSRuntime : public JS::shadow::Runtime,
void *gcCallbackData;
js::AnalysisPurgeCallback analysisPurgeCallback;
uint64_t analysisPurgeTriggerBytes;
private:
/*
* Malloc counter to measure memory pressure for GC scheduling. It runs

View File

@ -851,8 +851,6 @@ pref("javascript.options.mem.gc_dynamic_mark_slice", true);
pref("javascript.options.mem.gc_allocation_threshold_mb", 30);
pref("javascript.options.mem.gc_decommit_threshold_mb", 32);
pref("javascript.options.mem.analysis_purge_mb", 100);
pref("javascript.options.showInConsole", false);
// advanced prefs