@@ -494,14 +494,22 @@ void HelperMethodFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
494
494
495
495
TADDR FixupPrecode::GetMethodDesc ()
496
496
{
497
- _ASSERTE (!" ARM64:NYI" );
498
- return NULL ;
497
+ LIMITED_METHOD_DAC_CONTRACT;
498
+
499
+ // This lookup is also manually inlined in PrecodeFixupThunk assembly code
500
+ TADDR base = *PTR_TADDR (GetBase ());
501
+ if (base == NULL )
502
+ return NULL ;
503
+ return base + (m_MethodDescChunkIndex * MethodDesc::ALIGNMENT);
499
504
}
500
505
501
506
#ifdef DACCESS_COMPILE
502
507
void FixupPrecode::EnumMemoryRegions (CLRDataEnumMemoryFlags flags)
503
508
{
504
- _ASSERTE (!" ARM64:NYI" );
509
+ SUPPORTS_DAC;
510
+ DacEnumMemoryRegion (dac_cast<TADDR>(this ), sizeof (FixupPrecode));
511
+
512
+ DacEnumMemoryRegion (GetBase (), sizeof (TADDR));
505
513
}
506
514
#endif // DACCESS_COMPILE
507
515
@@ -574,19 +582,78 @@ void NDirectImportPrecode::Fixup(DataImage *image)
574
582
575
583
void FixupPrecode::Init (MethodDesc* pMD, LoaderAllocator *pLoaderAllocator, int iMethodDescChunkIndex /* =0*/ , int iPrecodeChunkIndex /* =0*/ )
576
584
{
577
- _ASSERTE (!" ARM64:NYI" );
585
+ WRAPPER_NO_CONTRACT;
586
+
587
+ InitCommon ();
588
+
589
+ // Initialize chunk indices only if they are not initialized yet. This is necessary to make MethodDesc::Reset work.
590
+ if (m_PrecodeChunkIndex == 0 )
591
+ {
592
+ _ASSERTE (FitsInU1 (iPrecodeChunkIndex));
593
+ m_PrecodeChunkIndex = static_cast <BYTE>(iPrecodeChunkIndex);
594
+ }
595
+
596
+ if (iMethodDescChunkIndex != -1 )
597
+ {
598
+ if (m_MethodDescChunkIndex == 0 )
599
+ {
600
+ _ASSERTE (FitsInU1 (iMethodDescChunkIndex));
601
+ m_MethodDescChunkIndex = static_cast <BYTE>(iMethodDescChunkIndex);
602
+ }
603
+
604
+ if (*(void **)GetBase () == NULL )
605
+ *(void **)GetBase () = (BYTE*)pMD - (iMethodDescChunkIndex * MethodDesc::ALIGNMENT);
606
+ }
607
+
608
+ _ASSERTE (GetMethodDesc () == (TADDR)pMD);
609
+
610
+ if (pLoaderAllocator != NULL )
611
+ {
612
+ m_pTarget = GetEEFuncEntryPoint (PrecodeFixupThunk);
613
+ }
578
614
}
579
615
580
616
#ifdef FEATURE_NATIVE_IMAGE_GENERATION
581
617
// Partial initialization. Used to save regrouped chunks.
582
618
void FixupPrecode::InitForSave (int iPrecodeChunkIndex)
583
619
{
584
- _ASSERTE (!" ARM64:NYI" );
620
+ STANDARD_VM_CONTRACT;
621
+
622
+ InitCommon ();
623
+
624
+ _ASSERTE (FitsInU1 (iPrecodeChunkIndex));
625
+ m_PrecodeChunkIndex = static_cast <BYTE>(iPrecodeChunkIndex);
626
+ // The rest is initialized in code:FixupPrecode::Fixup
585
627
}
586
628
587
629
void FixupPrecode::Fixup (DataImage *image, MethodDesc * pMD)
588
630
{
589
- _ASSERTE (!" ARM64:NYI" );
631
+ STANDARD_VM_CONTRACT;
632
+
633
+ // Note that GetMethodDesc() does not return the correct value because of
634
+ // regrouping of MethodDescs into hot and cold blocks. That's why the caller
635
+ // has to supply the actual MethodDesc
636
+
637
+ SSIZE_T mdChunkOffset;
638
+ ZapNode * pMDChunkNode = image->GetNodeForStructure (pMD, &mdChunkOffset);
639
+ ZapNode * pHelperThunk = image->GetHelperThunk (CORINFO_HELP_EE_PRECODE_FIXUP);
640
+
641
+ image->FixupFieldToNode (this , offsetof (FixupPrecode, m_pTarget), pHelperThunk);
642
+
643
+ // Set the actual chunk index
644
+ FixupPrecode * pNewPrecode = (FixupPrecode *)image->GetImagePointer (this );
645
+
646
+ size_t mdOffset = mdChunkOffset - sizeof (MethodDescChunk);
647
+ size_t chunkIndex = mdOffset / MethodDesc::ALIGNMENT;
648
+ _ASSERTE (FitsInU1 (chunkIndex));
649
+ pNewPrecode->m_MethodDescChunkIndex = (BYTE)chunkIndex;
650
+
651
+ // Fixup the base of MethodDescChunk
652
+ if (m_PrecodeChunkIndex == 0 )
653
+ {
654
+ image->FixupFieldToNode (this , (BYTE *)GetBase () - (BYTE *)this ,
655
+ pMDChunkNode, sizeof (MethodDescChunk));
656
+ }
590
657
}
591
658
#endif // FEATURE_NATIVE_IMAGE_GENERATION
592
659
@@ -618,7 +685,20 @@ BOOL DoesSlotCallPrestub(PCODE pCode)
618
685
{
619
686
PTR_DWORD pInstr = dac_cast<PTR_DWORD>(PCODEToPINSTR (pCode));
620
687
621
- // ARM64TODO: Check for FixupPrecode
688
+ // FixupPrecode
689
+ #if defined(HAS_FIXUP_PRECODE)
690
+ if (FixupPrecode::IsFixupPrecodeByASM (pCode))
691
+ {
692
+ PCODE pTarget = dac_cast<PTR_FixupPrecode>(pInstr)->m_pTarget ;
693
+
694
+ if (isJump (pTarget))
695
+ {
696
+ pTarget = decodeJump (pTarget);
697
+ }
698
+
699
+ return pTarget == (TADDR)PrecodeFixupThunk;
700
+ }
701
+ #endif
622
702
623
703
// StubPrecode
624
704
if (pInstr[0 ] == 0x10000089 && // adr x9, #16
@@ -627,7 +707,10 @@ BOOL DoesSlotCallPrestub(PCODE pCode)
627
707
{
628
708
PCODE pTarget = dac_cast<PTR_StubPrecode>(pInstr)->m_pTarget ;
629
709
630
- // ARM64TODO: implement for NGen case
710
+ if (isJump (pTarget))
711
+ {
712
+ pTarget = decodeJump (pTarget);
713
+ }
631
714
632
715
return pTarget == GetPreStubEntryPoint ();
633
716
}
0 commit comments