@@ -92,119 +92,135 @@ GlobOpt::CaptureValuesIncremental(BasicBlock * block,
9292
9393 FOREACH_BITSET_IN_SPARSEBV (symId, block->globOptData .changedSyms )
9494 {
95- Sym * sym = hasConstValue ? iterConst.Data ().Key () : nullptr ;
9695 Value * val = nullptr ;
97- HashBucket<Sym *, Value *> * symIdBucket = nullptr ;
9896
99- // copy unchanged sym to new capturedValues
100- while (sym && sym->m_id < symId)
97+ // First process all unchanged syms with m_id < symId. Then, recapture the current changed sym.
98+
99+ // copy unchanged const sym to new capturedValues
100+ Sym * constSym = hasConstValue ? iterConst.Data ().Key () : nullptr ;
101+ while (constSym && constSym->m_id < symId)
101102 {
102- Assert (sym ->IsStackSym ());
103- if (!sym ->AsStackSym ()->HasArgSlotNum ())
103+ Assert (constSym ->IsStackSym ());
104+ if (!constSym ->AsStackSym ()->HasArgSlotNum ())
104105 {
105- bailOutConstValuesIter.InsertNodeBefore (this ->func ->m_alloc , sym ->AsStackSym (), iterConst.Data ().Value ());
106+ bailOutConstValuesIter.InsertNodeBefore (this ->func ->m_alloc , constSym ->AsStackSym (), iterConst.Data ().Value ());
106107 }
107108
108109 hasConstValue = iterConst.Next ();
109- sym = hasConstValue ? iterConst.Data ().Key () : nullptr ;
110+ constSym = hasConstValue ? iterConst.Data ().Key () : nullptr ;
110111 }
111- if (sym && sym ->m_id == symId)
112+ if (constSym && constSym ->m_id == symId)
112113 {
113114 hasConstValue = iterConst.Next ();
114115 }
115- if (symId != Js::Constants::InvalidSymID)
116- {
117- // recapture changed constant sym
118116
119- symIdBucket = block->globOptData .symToValueMap ->GetBucket (symId);
120- if (symIdBucket == nullptr )
121- {
122- continue ;
123- }
124-
125- Sym * symIdSym = symIdBucket->value ;
126- Assert (symIdSym->IsStackSym () && (symIdSym->AsStackSym ()->HasByteCodeRegSlot () || symIdSym->AsStackSym ()->HasArgSlotNum ()));
127-
128- val = symIdBucket->element ;
129- ValueInfo* valueInfo = val->GetValueInfo ();
130-
131- if (valueInfo->GetSymStore () != nullptr )
132- {
133- int32 intConstValue;
134- BailoutConstantValue constValue;
135-
136- if (valueInfo->TryGetIntConstantValue (&intConstValue))
137- {
138- constValue.InitIntConstValue (intConstValue);
139- bailOutConstValuesIter.InsertNodeBefore (this ->func ->m_alloc , symIdSym->AsStackSym (), constValue);
140-
141- continue ;
142- }
143- else if (valueInfo->IsVarConstant ())
144- {
145- constValue.InitVarConstValue (valueInfo->AsVarConstant ()->VarValue ());
146- bailOutConstValuesIter.InsertNodeBefore (this ->func ->m_alloc , symIdSym->AsStackSym (), constValue);
147-
148- continue ;
149- }
150- }
151- else if (!valueInfo->HasIntConstantValue ())
152- {
153- continue ;
154- }
155- }
156-
157- sym = hasCopyPropSym ? iterCopyPropSym.Data ().Key () : nullptr ;
158-
159- // process unchanged sym, but copy sym might have changed
160- while (sym && sym->m_id < symId)
117+ // process unchanged sym; copy-prop sym might have changed
118+ Sym * capturedSym = hasCopyPropSym ? iterCopyPropSym.Data ().Key () : nullptr ;
119+ while (capturedSym && capturedSym->m_id < symId)
161120 {
162- StackSym * copyPropSym = iterCopyPropSym.Data ().Value ();
121+ StackSym * capturedCopyPropSym = iterCopyPropSym.Data ().Value ();
163122
164- Assert (sym ->IsStackSym ());
123+ Assert (capturedSym ->IsStackSym ());
165124
166- if (!block->globOptData .changedSyms ->Test (copyPropSym ->m_id ))
125+ if (!block->globOptData .changedSyms ->Test (capturedCopyPropSym ->m_id ))
167126 {
168- if (!sym ->AsStackSym ()->HasArgSlotNum ())
127+ if (!capturedSym ->AsStackSym ()->HasArgSlotNum ())
169128 {
170- bailOutCopySymsIter.InsertNodeBefore (this ->func ->m_alloc , sym ->AsStackSym (), copyPropSym );
129+ bailOutCopySymsIter.InsertNodeBefore (this ->func ->m_alloc , capturedSym ->AsStackSym (), capturedCopyPropSym );
171130 }
172131 }
173132 else
174133 {
175- if (!sym ->AsStackSym ()->HasArgSlotNum ())
134+ if (!capturedSym ->AsStackSym ()->HasArgSlotNum ())
176135 {
177- val = this ->currentBlock ->globOptData .FindValue (sym );
136+ val = this ->currentBlock ->globOptData .FindValue (capturedSym );
178137 if (val != nullptr )
179138 {
180- CaptureCopyPropValue (block, sym , val, bailOutCopySymsIter);
139+ CaptureCopyPropValue (block, capturedSym , val, bailOutCopySymsIter);
181140 }
182141 }
183142 }
184143
185144 hasCopyPropSym = iterCopyPropSym.Next ();
186- sym = hasCopyPropSym ? iterCopyPropSym.Data ().Key () : nullptr ;
145+ capturedSym = hasCopyPropSym ? iterCopyPropSym.Data ().Key () : nullptr ;
187146 }
188- if (sym && sym ->m_id == symId)
147+ if (capturedSym && capturedSym ->m_id == symId)
189148 {
190149 hasCopyPropSym = iterCopyPropSym.Next ();
191150 }
151+
152+ // recapture changed sym
153+ HashBucket<Sym *, Value *> * symIdBucket = nullptr ;
192154 if (symId != Js::Constants::InvalidSymID)
193155 {
194- // recapture changed copy prop sym
195156 symIdBucket = block->globOptData .symToValueMap ->GetBucket (symId);
196157 if (symIdBucket != nullptr )
197158 {
198159 Sym * symIdSym = symIdBucket->value ;
199- val = this ->currentBlock ->globOptData .FindValue (symIdSym);
200- if (val != nullptr )
160+ Assert (symIdSym->IsStackSym () && (symIdSym->AsStackSym ()->HasByteCodeRegSlot () || symIdSym->AsStackSym ()->HasArgSlotNum ()));
161+
162+ val = symIdBucket->element ;
163+ Assert (val);
164+ ValueInfo* valueInfo = val->GetValueInfo ();
165+
166+ if (valueInfo->GetSymStore () != nullptr )
201167 {
202- CaptureCopyPropValue (block, symIdSym, val, bailOutCopySymsIter);
168+ int32 intConstValue;
169+ BailoutConstantValue constValue;
170+
171+ if (valueInfo->TryGetIntConstantValue (&intConstValue))
172+ {
173+ constValue.InitIntConstValue (intConstValue);
174+ bailOutConstValuesIter.InsertNodeBefore (this ->func ->m_alloc , symIdSym->AsStackSym (), constValue);
175+ }
176+ else if (valueInfo->IsVarConstant ())
177+ {
178+ constValue.InitVarConstValue (valueInfo->AsVarConstant ()->VarValue ());
179+ bailOutConstValuesIter.InsertNodeBefore (this ->func ->m_alloc , symIdSym->AsStackSym (), constValue);
180+ }
181+ else
182+ {
183+ CaptureCopyPropValue (block, symIdSym, val, bailOutCopySymsIter);
184+ }
203185 }
204186 }
205187 }
206188 }
207189 NEXT_BITSET_IN_SPARSEBV
190+
191+ // If, after going over the set of changed syms since the last time we captured values,
192+ // there are remaining unprocessed entries in the current captured values set,
193+ // they can simply be copied over to the new bailout info.
194+ while (hasConstValue)
195+ {
196+ Sym * constSym = iterConst.Data ().Key ();
197+ Assert (constSym->IsStackSym ());
198+ Assert (!block->globOptData .changedSyms ->Test (constSym->m_id ));
199+
200+ if (!constSym->AsStackSym ()->HasArgSlotNum ())
201+ {
202+ bailOutConstValuesIter.InsertNodeBefore (this ->func ->m_alloc , constSym->AsStackSym (), iterConst.Data ().Value ());
203+ }
204+
205+ hasConstValue = iterConst.Next ();
206+ }
207+
208+ while (hasCopyPropSym)
209+ {
210+ Sym * capturedSym = iterCopyPropSym.Data ().Key ();
211+ StackSym * capturedCopyPropSym = iterCopyPropSym.Data ().Value ();
212+
213+ Assert (capturedSym->IsStackSym ());
214+ Assert (!block->globOptData .changedSyms ->Test (capturedSym->m_id ) &&
215+ !block->globOptData .changedSyms ->Test (capturedCopyPropSym->m_id ));
216+
217+ if (!capturedSym->AsStackSym ()->HasArgSlotNum ())
218+ {
219+ bailOutCopySymsIter.InsertNodeBefore (this ->func ->m_alloc , capturedSym->AsStackSym (), capturedCopyPropSym);
220+ }
221+
222+ hasCopyPropSym = iterCopyPropSym.Next ();
223+ }
208224}
209225
210226
0 commit comments