Skip to content

Allocate static boxes on FOH #2 - #79188

Merged
EgorBo merged 14 commits into
dotnet:mainfrom
EgorBo:static-boxes
Dec 6, 2022
Merged

Allocate static boxes on FOH #2#79188
EgorBo merged 14 commits into
dotnet:mainfrom
EgorBo:static-boxes

Conversation

@EgorBo

@EgorBoEgorBo commented Dec 3, 2022

Copy link
Copy Markdown
Member

Reverts 2nd part of #78296 revert.

NOTE: this doesn't fix the flaky NRE as I'm able to reproduce it locally

@ghostghost assigned EgorBoDec 3, 2022
@ghostghost added the area-VM-coreclr label Dec 3, 2022
@EgorBo

EgorBo commented Dec 3, 2022

Copy link
Copy Markdown
MemberAuthor

@jkotas maybe it rings a bell to you - so when I set StaticBoxInitLock crst scope I might still hit a

Consistency check failed: Crst Level violation: Can't take level 12 lock CrstAssemblyLoader because you already holding level 4 lock CrstStaticBoxInit

My understanding that it happens because of pFieldMT->EnsureInstanceActive(); inside AllocateStaticBox - but if I move this call to a place before I open the CrstStaticBoxInit it won't help, because it doesn't block the thread and wait till the assembly is loaded, right? So the question is - should I somehow wait field's type to be fully loaded before I open the scope or in this particular case it's fine to modify Crst to account for CrstAssemblyLoader ?

@jkotas

Copy link
Copy Markdown
Member

AssemblyLoader can run arbitrary code (e.g. due to user overridable ResolveAssembly event). You do not want to be holding any runtime locks when the assembly loader runs.

@EgorBo

Copy link
Copy Markdown
MemberAuthor

@jkotas it looks like the issue is fixed via GCPROTECT_BEGININTERIOR(boxedStaticHandle); - can't repro it anymore

@EgorBo
EgorBo marked this pull request as ready for review December 4, 2022 20:59
@EgorBoEgorBo closed this Dec 4, 2022
@EgorBoEgorBo reopened this Dec 4, 2022
@EgorBo

Copy link
Copy Markdown
MemberAuthor

/azp run runtime-coreclr outerloop, runtime-coreclr gcstress0x3-gcstress0xc

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 2 pipeline(s).

@jkotas

Copy link
Copy Markdown
Member

it looks like the issue is fixed via GCPROTECT_BEGININTERIOR(boxedStaticHandle); - can't repro it anymore

If it is the case, it means that fieldAddress can be moved by the GC and the problems is spread over more places. For example, pResult->fieldLookup.addr at https://github.com/dotnet/runtime/pull/79188/files#diff-98b4e379205d747e922689cb993f985be190fedb509fd486e99280c842703472R1574 can be moved by the GC as well.

Comment threadsrc/coreclr/vm/jitinterface.cpp Outdated

pResult->fieldLookup.addr = pField->GetStaticAddressHandle((void*)pField->GetBase());
pResult->fieldLookup.accessType = IAT_VALUE;
GCPROTECT_BEGININTERIOR(pResult->fieldLookup.addr);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What guarantees that pResult->fieldLookup.addr is not going to move once it is return to the JIT?

@EgorBoEgorBoDec 5, 2022

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jkotas I don't have a good explanation yet, what I understand so far:

  1. GetGCStaticsBasePointer is assumed to be moveable already: https://github.com/dotnet/runtime/blob/main/src/coreclr/vm/methodtable.cpp#L3485
  2. I thought that it supposed to return an address to a pinned area so that's how we can give it to JIT
    but apparently it works differently for collectible contexts? And in case of collectible context is not supposed to be consumed by JIT (should go through the CORINFO_HELP_GETSHARED_GCSTATIC_BASE_DYNAMICCLASS helper)
  3. the places where it's used already seem to be safe? because of COOP and nothing triggers GC (and e.g. BulkStaticsLogger::LogAllStatics() has GC_NOTRIGGER)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the statics for collectible types do not seem to be pinned:

voidDomainLocalModule::AllocateDynamicClass(MethodTable *pMT)
. I assume that it is to prevent GC heap fragmentation that the long-term pinning would cause.

I think that this means that we need to avoid giving the JIT address of the collectible type statics?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this means that we need to avoid giving the JIT address of the collectible type statics?

Looks like we already don't do it, at least we don't hit that path where we set the address.

Comment threadsrc/coreclr/vm/methodtable.cpp Outdated
Comment threadsrc/coreclr/vm/methodtable.cpp Outdated

@jkotasjkotas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM otherwise. Thank you!

EgorBoand others added 2 commits December 5, 2022 21:40
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
@EgorBo

Copy link
Copy Markdown
MemberAuthor

Failures are #79255

@ghostghost locked as resolved and limited conversation to collaborators Jan 5, 2023
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@EgorBo@jkotas