@@ -206,7 +206,7 @@ Maybe<InlinableCallData> FindInlinableCallData(ICCacheIRStub* stub) {
206206
207207 ObjOperandId calleeGuardOperand;
208208 CallFlags flags;
209- JSFunction* target = nullptr ;
209+ JSScript* targetScript = nullptr ;
210210
211211 CacheIRReader reader (stubInfo);
212212 while (reader.more ()) {
@@ -219,21 +219,26 @@ Maybe<InlinableCallData> FindInlinableCallData(ICCacheIRStub* stub) {
219219
220220 switch (op) {
221221 case CacheOp::GuardSpecificFunction: {
222- // If we see a guard, remember which operand we are guarding.
222+ // If we see a guard for a scripted function, remember which
223+ // operand we are guarding.
223224 MOZ_ASSERT (data.isNothing ());
224- calleeGuardOperand = reader.objOperandId ();
225+ ObjOperandId maybeCalleeGuardOperand = reader.objOperandId ();
225226 uint32_t targetOffset = reader.stubOffset ();
226227 (void )reader.stubOffset (); // nargsAndFlags
227- uintptr_t rawTarget = stubInfo->getStubRawWord (stubData, targetOffset);
228- target = reinterpret_cast <JSFunction*>(rawTarget);
228+ uintptr_t rawFunction = stubInfo->getStubRawWord (stubData, targetOffset);
229+ JSFunction* function = reinterpret_cast <JSFunction*>(rawFunction);
230+ if (function->hasBytecode ()) {
231+ calleeGuardOperand = maybeCalleeGuardOperand;
232+ targetScript = function->nonLazyScript ();
233+ }
229234 break ;
230235 }
231236 case CacheOp::GuardFunctionScript: {
232237 MOZ_ASSERT (data.isNothing ());
233238 calleeGuardOperand = reader.objOperandId ();
234239 uint32_t targetOffset = reader.stubOffset ();
235- uintptr_t rawTarget = stubInfo->getStubRawWord (stubData, targetOffset);
236- target = reinterpret_cast <BaseScript *>(rawTarget)-> function ( );
240+ uintptr_t rawScript = stubInfo->getStubRawWord (stubData, targetOffset);
241+ targetScript = reinterpret_cast <JSScript *>(rawScript );
237242 (void )reader.stubOffset (); // nargsAndFlags
238243 break ;
239244 }
@@ -294,7 +299,7 @@ Maybe<InlinableCallData> FindInlinableCallData(ICCacheIRStub* stub) {
294299 }
295300 data->calleeOperand = calleeGuardOperand;
296301 data->callFlags = flags;
297- data->target = target ;
302+ data->target = targetScript ;
298303 }
299304 return data;
300305}
@@ -306,7 +311,7 @@ Maybe<InlinableGetterData> FindInlinableGetterData(ICCacheIRStub* stub) {
306311 const uint8_t * stubData = stub->stubDataStart ();
307312
308313 ObjOperandId maybeCalleeOperand;
309- uintptr_t maybeRawCallee = 0 ;
314+ JSScript* targetScript = nullptr ;
310315
311316 CacheIRReader reader (stubInfo);
312317 while (reader.more ()) {
@@ -320,9 +325,14 @@ Maybe<InlinableGetterData> FindInlinableGetterData(ICCacheIRStub* stub) {
320325 switch (op) {
321326 case CacheOp::LoadObject: {
322327 // If we load a constant object, remember it in case it's the callee.
323- maybeCalleeOperand = reader.objOperandId ();
324- uint32_t maybeCalleeOffset = reader.stubOffset ();
325- maybeRawCallee = stubInfo->getStubRawWord (stubData, maybeCalleeOffset);
328+ ObjOperandId resultOperand = reader.objOperandId ();
329+ uint32_t objOffset = reader.stubOffset ();
330+ uintptr_t rawObject = stubInfo->getStubRawWord (stubData, objOffset);
331+ JSObject* object = reinterpret_cast <JSObject*>(rawObject);
332+ if (object->is <JSFunction>() && object->as <JSFunction>().hasBytecode ()) {
333+ maybeCalleeOperand = resultOperand;
334+ targetScript = object->as <JSFunction>().nonLazyScript ();
335+ }
326336 break ;
327337 }
328338 case CacheOp::CallScriptedGetterResult: {
@@ -333,7 +343,7 @@ Maybe<InlinableGetterData> FindInlinableGetterData(ICCacheIRStub* stub) {
333343
334344 if (maybeCalleeOperand == calleeOperand) {
335345 data.emplace ();
336- data->target = reinterpret_cast <JSFunction*>(maybeRawCallee) ;
346+ data->target = targetScript ;
337347 data->receiverOperand = receiverOperand;
338348 data->calleeOperand = calleeOperand;
339349 data->sameRealm = sameRealm;
@@ -352,7 +362,7 @@ Maybe<InlinableGetterData> FindInlinableGetterData(ICCacheIRStub* stub) {
352362
353363 if (maybeCalleeOperand == calleeOperand) {
354364 data.emplace ();
355- data->target = reinterpret_cast <JSFunction*>(maybeRawCallee) ;
365+ data->target = targetScript ;
356366 data->receiverOperand = receiverOperand;
357367 data->calleeOperand = calleeOperand;
358368 data->icScript = reinterpret_cast <ICScript*>(rawICScript);
@@ -384,7 +394,7 @@ Maybe<InlinableSetterData> FindInlinableSetterData(ICCacheIRStub* stub) {
384394 const uint8_t * stubData = stub->stubDataStart ();
385395
386396 ObjOperandId maybeCalleeOperand;
387- uintptr_t maybeRawCallee = 0 ;
397+ JSScript* targetScript = nullptr ;
388398
389399 CacheIRReader reader (stubInfo);
390400 while (reader.more ()) {
@@ -398,9 +408,14 @@ Maybe<InlinableSetterData> FindInlinableSetterData(ICCacheIRStub* stub) {
398408 switch (op) {
399409 case CacheOp::LoadObject: {
400410 // If we load a constant object, remember it in case it's the callee.
401- maybeCalleeOperand = reader.objOperandId ();
402- uint32_t maybeCalleeOffset = reader.stubOffset ();
403- maybeRawCallee = stubInfo->getStubRawWord (stubData, maybeCalleeOffset);
411+ ObjOperandId resultOperand = reader.objOperandId ();
412+ uint32_t objOffset = reader.stubOffset ();
413+ uintptr_t rawObject = stubInfo->getStubRawWord (stubData, objOffset);
414+ JSObject* object = reinterpret_cast <JSObject*>(rawObject);
415+ if (object->is <JSFunction>() && object->as <JSFunction>().hasBytecode ()) {
416+ maybeCalleeOperand = resultOperand;
417+ targetScript = object->as <JSFunction>().nonLazyScript ();
418+ }
404419 break ;
405420 }
406421 case CacheOp::CallScriptedSetter: {
@@ -412,7 +427,7 @@ Maybe<InlinableSetterData> FindInlinableSetterData(ICCacheIRStub* stub) {
412427
413428 if (maybeCalleeOperand == calleeOperand) {
414429 data.emplace ();
415- data->target = reinterpret_cast <JSFunction*>(maybeRawCallee) ;
430+ data->target = targetScript ;
416431 data->receiverOperand = receiverOperand;
417432 data->calleeOperand = calleeOperand;
418433 data->rhsOperand = rhsOperand;
@@ -433,7 +448,7 @@ Maybe<InlinableSetterData> FindInlinableSetterData(ICCacheIRStub* stub) {
433448
434449 if (maybeCalleeOperand == calleeOperand) {
435450 data.emplace ();
436- data->target = reinterpret_cast <JSFunction*>(maybeRawCallee) ;
451+ data->target = targetScript ;
437452 data->receiverOperand = receiverOperand;
438453 data->calleeOperand = calleeOperand;
439454 data->rhsOperand = rhsOperand;
@@ -512,13 +527,12 @@ bool TrialInliner::IsValidInliningOp(JSOp op) {
512527}
513528
514529/* static*/
515- bool TrialInliner::canInline (JSFunction* target , HandleScript caller,
530+ bool TrialInliner::canInline (JSScript* script , HandleScript caller,
516531 BytecodeLocation loc) {
517- if (!target ->hasJitScript ()) {
532+ if (!script ->hasJitScript ()) {
518533 JitSpew (JitSpew_WarpTrialInlining, " SKIP: no JIT script" );
519534 return false ;
520535 }
521- JSScript* script = target->nonLazyScript ();
522536 if (!script->jitScript ()->hasBaselineScript ()) {
523537 JitSpew (JitSpew_WarpTrialInlining, " SKIP: no BaselineScript" );
524538 return false ;
@@ -536,7 +550,7 @@ bool TrialInliner::canInline(JSFunction* target, HandleScript caller,
536550 return false ;
537551 }
538552 // Don't inline cross-realm calls.
539- if (target ->realm () != caller->realm ()) {
553+ if (script ->realm () != caller->realm ()) {
540554 JitSpew (JitSpew_WarpTrialInlining, " SKIP: cross-realm call" );
541555 return false ;
542556 }
@@ -567,9 +581,10 @@ bool TrialInliner::canInline(JSFunction* target, HandleScript caller,
567581 }
568582 }
569583
570- if (TooManyFormalArguments (target->nargs ())) {
584+ if (script->function () &&
585+ TooManyFormalArguments (script->function ()->nargs ())) {
571586 JitSpew (JitSpew_WarpTrialInlining, " SKIP: Too many formal arguments: %u" ,
572- unsigned (target ->nargs ()));
587+ unsigned (script-> function () ->nargs ()));
573588 return false ;
574589 }
575590
@@ -623,38 +638,36 @@ static bool ShouldUseMonomorphicInlining(JSScript* targetScript) {
623638 return true ;
624639}
625640
626- TrialInliningDecision TrialInliner::getInliningDecision (JSFunction* target ,
641+ TrialInliningDecision TrialInliner::getInliningDecision (JSScript* targetScript ,
627642 ICCacheIRStub* stub,
628643 BytecodeLocation loc) {
629644#ifdef JS_JITSPEW
630645 if (JitSpewEnabled (JitSpew_WarpTrialInlining)) {
631- BaseScript* baseScript =
632- target->hasBaseScript () ? target->baseScript () : nullptr ;
633-
634646 UniqueChars funName;
635- if (target->maybePartialDisplayAtom ()) {
636- funName = AtomToPrintableString (cx (), target->maybePartialDisplayAtom ());
647+ if (targetScript->function ()) {
648+ if (JSAtom* atom = targetScript->function ()->maybePartialDisplayAtom ()) {
649+ funName = AtomToPrintableString (cx (), atom);
650+ }
637651 }
638652
639653 JitSpew (JitSpew_WarpTrialInlining,
640654 " Inlining candidate JSOp::%s (offset=%u): callee script '%s' "
641655 " (%s:%u:%u)" ,
642656 CodeName (loc.getOp ()), loc.bytecodeToOffset (script_),
643657 funName ? funName.get () : " <unnamed>" ,
644- baseScript ? baseScript ->filename () : " <not-scripted> " ,
645- baseScript ? baseScript ->lineno () : 0 ,
646- baseScript ? baseScript ->column ().oneOriginValue () : 0 );
658+ targetScript ->filename (),
659+ targetScript ->lineno (),
660+ targetScript ->column ().oneOriginValue ());
647661 JitSpewIndent spewIndent (JitSpew_WarpTrialInlining);
648662 }
649663#endif
650664
651- if (!canInline (target , script_, loc)) {
665+ if (!canInline (targetScript , script_, loc)) {
652666 return TrialInliningDecision::NoInline;
653667 }
654668
655669 // Don't inline (direct) recursive calls. This still allows recursion if
656670 // called through another function (f => g => f).
657- JSScript* targetScript = target->nonLazyScript ();
658671 if (script_ == targetScript) {
659672 JitSpew (JitSpew_WarpTrialInlining, " SKIP: recursion" );
660673 return TrialInliningDecision::NoInline;
@@ -705,18 +718,15 @@ TrialInliningDecision TrialInliner::getInliningDecision(JSFunction* target,
705718 return TrialInliningDecision::MonomorphicInline;
706719}
707720
708- ICScript* TrialInliner::createInlinedICScript (JSFunction* target ,
721+ ICScript* TrialInliner::createInlinedICScript (JSScript* targetScript ,
709722 BytecodeLocation loc) {
710- MOZ_ASSERT (target->hasJitEntry ());
711- MOZ_ASSERT (target->hasJitScript ());
723+ MOZ_ASSERT (targetScript->hasJitScript ());
712724
713725 InliningRoot* root = getOrCreateInliningRoot ();
714726 if (!root) {
715727 return nullptr ;
716728 }
717729
718- JSScript* targetScript = target->baseScript ()->asJSScript ();
719-
720730 // We don't have to check for overflow here because we have already
721731 // successfully allocated an ICScript with this number of entries
722732 // when creating the JitScript for the target function, and we
@@ -857,7 +867,8 @@ bool TrialInliner::maybeInlineGetter(ICEntry& entry, ICFallbackStub* fallback,
857867 cloneSharedPrefix (stub, data->endOfSharedPrefix , writer);
858868
859869 writer.callInlinedGetterResult (data->receiverOperand , data->calleeOperand ,
860- data->target , newICScript, data->sameRealm );
870+ data->target ->function (), newICScript,
871+ data->sameRealm );
861872 writer.returnFromIC ();
862873
863874 return replaceICStub (entry, fallback, writer, kind);
@@ -901,8 +912,8 @@ bool TrialInliner::maybeInlineSetter(ICEntry& entry, ICFallbackStub* fallback,
901912 cloneSharedPrefix (stub, data->endOfSharedPrefix , writer);
902913
903914 writer.callInlinedSetter (data->receiverOperand , data->calleeOperand ,
904- data->target , data->rhsOperand , newICScript ,
905- data->sameRealm );
915+ data->target -> function () , data->rhsOperand ,
916+ newICScript, data->sameRealm );
906917 writer.returnFromIC ();
907918
908919 return replaceICStub (entry, fallback, writer, kind);
0 commit comments