@@ -263,14 +263,14 @@ namespace Js
263263 this ->GetCurrentArgv ()[JavascriptFunctionArgIndex_ArgumentsObject] = args;
264264 }
265265
266- Js::Var * JavascriptStackWalker::GetJavascriptArgs () const
266+ Js::Var * JavascriptStackWalker::GetJavascriptArgs (bool boxArgsAndDeepCopy ) const
267267 {
268268 Assert (this ->IsJavascriptFrame ());
269269
270270#if ENABLE_NATIVE_CODEGEN
271271 if (inlinedFramesBeingWalked)
272272 {
273- return inlinedFrameWalker.GetArgv (/* includeThis = */ false );
273+ return inlinedFrameWalker.GetArgv (/* includeThis */ false , boxArgsAndDeepCopy );
274274 }
275275 else
276276#endif
@@ -450,7 +450,7 @@ namespace Js
450450 // are inlined frames on the stack the InlineeCallInfo of the first inlined frame
451451 // has the native offset of the current physical frame.
452452 Assert (!*inlinee);
453- InlinedFrameWalker::FromPhysicalFrame (tmpFrameWalker, currentFrame, ScriptFunction::FromVar (parentFunction), PreviousInterpreterFrameIsFromBailout (), loopNum, this , useInternalFrameInfo, false /* noAlloc*/ , false /* deepCopy */ );
453+ InlinedFrameWalker::FromPhysicalFrame (tmpFrameWalker, currentFrame, ScriptFunction::FromVar (parentFunction), PreviousInterpreterFrameIsFromBailout (), loopNum, this , useInternalFrameInfo, false /* noAlloc*/ );
454454 inlineeOffset = tmpFrameWalker.GetBottomMostInlineeOffset ();
455455 tmpFrameWalker.Close ();
456456 }
@@ -555,7 +555,7 @@ namespace Js
555555 }
556556
557557 bool hasInlinedFramesOnStack = InlinedFrameWalker::FromPhysicalFrame (inlinedFrameWalker, currentFrame,
558- ScriptFunction::FromVar (function), true /* fromBailout*/ , loopNum, this , false /* useInternalFrameInfo*/ , false /* noAlloc*/ , this -> deepCopyForArgs );
558+ ScriptFunction::FromVar (function), true /* fromBailout*/ , loopNum, this , false /* useInternalFrameInfo*/ , false /* noAlloc*/ );
559559
560560 if (hasInlinedFramesOnStack)
561561 {
@@ -611,8 +611,7 @@ namespace Js
611611 -1 , // loopNum
612612 nullptr ,// walker
613613 false , // useInternalFrameInfo
614- false , // noAlloc
615- this ->deepCopyForArgs
614+ false // noAlloc
616615 );
617616 if (inlinedFramesFound)
618617 {
@@ -658,8 +657,7 @@ namespace Js
658657 _NOINLINE
659658 JavascriptStackWalker::JavascriptStackWalker (ScriptContext * scriptContext, bool useEERContext, PVOID returnAddress, bool _forceFullWalk /* =false*/ ) :
660659 inlinedFrameCallInfo (CallFlags_None, 0 ), shouldDetectPartiallyInitializedInterpreterFrame(true ), forceFullWalk(_forceFullWalk),
661- previousInterpreterFrameIsFromBailout (false ), previousInterpreterFrameIsForLoopBody(false ), hasInlinedFramesOnStack(false ),
662- deepCopyForArgs (false )
660+ previousInterpreterFrameIsFromBailout (false ), previousInterpreterFrameIsForLoopBody(false ), hasInlinedFramesOnStack(false )
663661 {
664662 if (scriptContext == NULL )
665663 {
@@ -955,7 +953,7 @@ namespace Js
955953 Assert (this ->interpreterFrame ->TestFlags (Js::InterpreterStackFrameFlags_FromBailOut));
956954 InlinedFrameWalker tmpFrameWalker;
957955 Assert (InlinedFrameWalker::FromPhysicalFrame (tmpFrameWalker, currentFrame, Js::ScriptFunction::FromVar (argv[JavascriptFunctionArgIndex_Function]),
958- true /* fromBailout*/ , this ->tempInterpreterFrame ->GetCurrentLoopNum (), this , false /* useInternalFrameInfo*/ , true /* noAlloc*/ , false /* deepCopy */ ));
956+ true /* fromBailout*/ , this ->tempInterpreterFrame ->GetCurrentLoopNum (), this , false /* useInternalFrameInfo*/ , true /* noAlloc*/ ));
959957 tmpFrameWalker.Close ();
960958 }
961959#endif // DBG
@@ -1002,7 +1000,7 @@ namespace Js
10021000 {
10031001 if (includeInlineFrames &&
10041002 InlinedFrameWalker::FromPhysicalFrame (inlinedFrameWalker, currentFrame, Js::ScriptFunction::FromVar (argv[JavascriptFunctionArgIndex_Function]),
1005- false /* fromBailout*/ , this ->tempInterpreterFrame ->GetCurrentLoopNum (), this , false /* useInternalFrameInfo*/ , false /* noAlloc*/ , this -> deepCopyForArgs ))
1003+ false /* fromBailout*/ , this ->tempInterpreterFrame ->GetCurrentLoopNum (), this , false /* useInternalFrameInfo*/ , false /* noAlloc*/ ))
10061004 {
10071005 // Found inlined frames in a jitted loop body. We dont want to skip the inlined frames; walk all of them before setting codeAddress on lastInternalFrameInfo.
10081006 // DeepCopy here because, if there is an inlinee in a loop body, FromPhysicalFrame won't be called from UpdateFrame
@@ -1246,7 +1244,7 @@ namespace Js
12461244
12471245#if ENABLE_NATIVE_CODEGEN
12481246 bool InlinedFrameWalker::FromPhysicalFrame (InlinedFrameWalker& self, StackFrame& physicalFrame, Js::ScriptFunction *parent, bool fromBailout,
1249- int loopNum, const JavascriptStackWalker * const stackWalker, bool useInternalFrameInfo, bool noAlloc, bool deepCopy )
1247+ int loopNum, const JavascriptStackWalker * const stackWalker, bool useInternalFrameInfo, bool noAlloc)
12501248 {
12511249 bool inlinedFramesFound = false ;
12521250 FunctionBody* parentFunctionBody = parent->GetFunctionBody ();
@@ -1299,7 +1297,7 @@ namespace Js
12991297
13001298 if (record)
13011299 {
1302- record->RestoreFrames (parent->GetFunctionBody (), outerMostFrame, JavascriptCallStackLayout::FromFramePointer (framePointer), deepCopy );
1300+ record->RestoreFrames (parent->GetFunctionBody (), outerMostFrame, JavascriptCallStackLayout::FromFramePointer (framePointer), false /* boxValues */ );
13031301 }
13041302 }
13051303
@@ -1366,26 +1364,46 @@ namespace Js
13661364 return currentFrame->callInfo .Count ;
13671365 }
13681366
1369- Js::Var *InlinedFrameWalker::GetArgv (bool includeThis /* = true */ ) const
1367+ // Note: the boxArgsAndDeepCopy parameter should be true when a copy of the JS args must be ensured to
1368+ // be on the heap. This results in a new array of Vars with deep copied boxed values (where
1369+ // appropriate).
1370+ // Otherwise, this parameter should be false. For instance, if the args will only be used
1371+ // internally to gather type info, the values are not boxed (so, some Vars may still be on
1372+ // the stack) and the array of the current frame is returned.
1373+ Js::Var *InlinedFrameWalker::GetArgv (bool includeThis, bool boxArgsAndDeepCopy) const
13701374 {
13711375 InlinedFrameWalker::InlinedFrame *const currentFrame = GetCurrentFrame ();
13721376 Assert (currentFrame);
13731377
13741378 uint firstArg = includeThis ? InlinedFrameArgIndex_This : InlinedFrameArgIndex_SecondScriptArg;
1375- Js::Var *args = ¤tFrame->argv [firstArg];
1379+ size_t argCount = this ->GetArgc () - firstArg;
1380+ Js::Var *args;
1381+ if (!boxArgsAndDeepCopy)
1382+ {
1383+ args = ¤tFrame->argv [firstArg];
1384+
1385+ }
1386+ else
1387+ {
1388+ args = RecyclerNewArray (parentFunction->GetScriptContext ()->GetRecycler (), Js::Var, argCount);
1389+ for (size_t i = 0 ; i < argCount; i++)
1390+ {
1391+ args[i] = currentFrame->argv [firstArg + i];
1392+ }
13761393
1377- this ->FinalizeStackValues (args, this ->GetArgc () - firstArg);
1394+ this ->FinalizeStackValues (args, argCount, true /* deepCopy*/ );
1395+ }
13781396
13791397 return args;
13801398 }
13811399
1382- void InlinedFrameWalker::FinalizeStackValues (__in_ecount(argCount) Js::Var args[], size_t argCount) const
1400+ void InlinedFrameWalker::FinalizeStackValues (__in_ecount(argCount) Js::Var args[], size_t argCount, bool deepCopy ) const
13831401 {
13841402 ScriptContext *scriptContext = this ->GetFunctionObject ()->GetScriptContext ();
13851403
13861404 for (size_t i = 0 ; i < argCount; i++)
13871405 {
1388- args[i] = Js::JavascriptOperators::BoxStackInstance (args[i], scriptContext, false /* allowStackFunction*/ , false /* deepCopy*/ );
1406+ args[i] = Js::JavascriptOperators::BoxStackInstance (args[i], scriptContext, false /* allowStackFunction*/ , deepCopy);
13891407 }
13901408 }
13911409
0 commit comments