Bug 620640 - Allow there to be more than 1 pending global slot to set (r=jorendorff)

--HG--
extra : rebase_source : 72562e0a3868f8cb65918c3c23f42d364e43ce41
This commit is contained in:
Luke Wagner 2011-01-11 15:19:57 -08:00
parent 5a102cb6a1
commit 9abddb6362
5 changed files with 45 additions and 13 deletions

View File

@ -0,0 +1,11 @@
var a, b;
function g(x) {
var y = x++;
return [x, y];
}
function f() {
for(var i=0; i<20; i++) {
[a,b] = g("10");
}
}
f();

View File

@ -435,6 +435,24 @@ Reverse(T *beg, T *end)
}
}
template <class T>
static inline T *
Find(T *beg, T *end, const T &v)
{
for (T *p = beg; p != end; ++p) {
if (*p == v)
return p;
}
return end;
}
template <class Container>
static inline typename Container::ElementType *
Find(Container &c, const typename Container::ElementType &v)
{
return Find(c.begin(), c.end(), v);
}
template <typename InputIterT, typename CallableT>
void
ForEach(InputIterT begin, InputIterT end, CallableT f)

View File

@ -2241,7 +2241,7 @@ TraceRecorder::TraceRecorder(JSContext* cx, VMSideExit* anchor, VMFragment* frag
pendingSpecializedNative(NULL),
pendingUnboxSlot(NULL),
pendingGuardCondition(NULL),
pendingGlobalSlotToSet(-1),
pendingGlobalSlotsToSet(cx),
pendingLoop(true),
generatedSpecializedNative(),
tempTypeMap(cx),
@ -3710,8 +3710,8 @@ TraceRecorder::writeBack(LIns* ins, LIns* base, ptrdiff_t offset, bool shouldDem
addr = StackAddress(base, offset);
} else {
addr = EosAddress(base, offset);
JS_ASSERT(pendingGlobalSlotToSet == -1);
pendingGlobalSlotToSet = offset / sizeof(double);
unsigned slot = unsigned(offset / sizeof(double));
(void)pendingGlobalSlotsToSet.append(slot); /* OOM is safe. */
}
return w.st(ins, addr);
}
@ -7214,7 +7214,7 @@ TraceRecorder::monitorRecording(JSOp op)
*/
pendingSpecializedNative = NULL;
newobj_ins = NULL;
pendingGlobalSlotToSet = -1;
pendingGlobalSlotsToSet.clear();
/* Handle one-shot request from finishGetProp or INSTANCEOF to snapshot post-op state and guard. */
if (pendingGuardCondition) {
@ -10173,7 +10173,7 @@ TraceRecorder::guardNativeConversion(Value& v)
}
JS_REQUIRES_STACK void
TraceRecorder::clearReturningFrameFromNativeveTracker()
TraceRecorder::clearReturningFrameFromNativeTracker()
{
/*
* Clear all tracker entries associated with the frame for the same reason
@ -10479,7 +10479,7 @@ TraceRecorder::record_JSOP_RETURN()
fp->fun()->atom ?
js_AtomToPrintableString(cx, fp->fun()->atom, &funBytes) :
"<anonymous>");
clearReturningFrameFromNativeveTracker();
clearReturningFrameFromNativeTracker();
return ARECORD_CONTINUE;
}
@ -15830,7 +15830,7 @@ TraceRecorder::record_JSOP_STOP()
} else {
rval_ins = w.immiUndefined();
}
clearReturningFrameFromNativeveTracker();
clearReturningFrameFromNativeTracker();
return ARECORD_CONTINUE;
}

View File

@ -1117,7 +1117,7 @@ class TraceRecorder
nanojit::LIns* pendingGuardCondition;
/* See AbortRecordingIfUnexpectedGlobalWrite. */
int pendingGlobalSlotToSet;
js::Vector<unsigned> pendingGlobalSlotsToSet;
/* Carry whether we have an always-exit from emitIf to checkTraceEnd. */
bool pendingLoop;
@ -1479,7 +1479,7 @@ class TraceRecorder
nanojit::LIns* obj_ins,
VMSideExit *exit);
JS_REQUIRES_STACK RecordingStatus guardNativeConversion(Value& v);
JS_REQUIRES_STACK void clearReturningFrameFromNativeveTracker();
JS_REQUIRES_STACK void clearReturningFrameFromNativeTracker();
JS_REQUIRES_STACK void putActivationObjects();
JS_REQUIRES_STACK RecordingStatus guardCallee(Value& callee);
JS_REQUIRES_STACK JSStackFrame *guardArguments(JSObject *obj, nanojit::LIns* obj_ins,
@ -1615,7 +1615,8 @@ class TraceRecorder
void forgetGuardedShapesForObject(JSObject* obj);
bool globalSetExpected(unsigned slot) {
if (pendingGlobalSlotToSet != (int)slot) {
unsigned *pi = Find(pendingGlobalSlotsToSet, slot);
if (pi == pendingGlobalSlotsToSet.end()) {
/*
* Do slot arithmetic manually to avoid getSlotRef assertions which
* do not need to be satisfied for this purpose.
@ -1635,7 +1636,7 @@ class TraceRecorder
*/
return tree->globalSlots->offsetOf((uint16)nativeGlobalSlot(vp)) == -1;
}
pendingGlobalSlotToSet = -1;
pendingGlobalSlotsToSet.erase(pi);
return true;
}
@ -1878,9 +1879,9 @@ namespace js {
* While recording, the slots of the global object may change payload or type.
* This is fine as long as the recorder expects this change (and therefore has
* generated the corresponding LIR, snapshots, etc). The recorder indicates
* that it expects a write to a global slot by setting pendingGlobalSlotToSet
* that it expects a write to a global slot by setting pendingGlobalSlotsToSet
* in the recorder, before the write is made by the interpreter, and clearing
* pendingGlobalSlotToSet before recording the next op. Any global slot write
* pendingGlobalSlotsToSet before recording the next op. Any global slot write
* that has not been whitelisted in this manner is therefore unexpected and, if
* the global slot is actually being tracked, recording must be aborted.
*/

View File

@ -260,6 +260,8 @@ class Vector : AllocPolicy
}
public:
typedef T ElementType;
Vector(AllocPolicy = AllocPolicy());
~Vector();