Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -118,7 +118,7 @@ public CompilationBuilder UseDwarf5(bool value)
protected PreinitializationManager GetPreinitializationManager()
{
if (_preinitializationManager == null)
return new PreinitializationManager(_context, _compilationGroup, GetILProvider(), enableInterpreter: false);
return new PreinitializationManager(_context, _compilationGroup, GetILProvider(), new TypePreinit.DisabledPreinitializationPolicy());
return _preinitializationManager;
}

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -50,17 +50,10 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
Section nativeSection = nativeWriter.NewSection();
nativeSection.Place(hashtable);

foreach (TypeDesc type in factory.MetadataManager.GetTypesWithConstructedEETypes())
foreach (TypeDesc type in factory.MetadataManager.GetTypeTemplates())
{
if (!IsEligibleToHaveATemplate(type))
continue;

// Type's native layout info
NativeLayoutTemplateTypeLayoutVertexNode templateNode = factory.NativeLayout.TemplateTypeLayout(type);

// If this template isn't considered necessary, don't emit it.
if (!templateNode.Marked)
continue;
Vertex nativeLayout = templateNode.SavedVertex;

// Hashtable Entry
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -921,6 +921,8 @@ public sealed class NativeLayoutTemplateTypeLayoutVertexNode : NativeLayoutSaved
private TypeDesc _type;
private bool _isUniversalCanon;

public TypeDesc CanonType => _type.ConvertToCanonForm(CanonicalFormKind.Specific);

protected override string GetName(NodeFactory factory) => "NativeLayoutTemplateTypeLayoutVertexNode_" + factory.NameMangler.GetMangledTypeName(_type);

public NativeLayoutTemplateTypeLayoutVertexNode(NodeFactory factory, TypeDesc type)
Expand DownExpand Up@@ -989,7 +991,7 @@ public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFacto
}
}

if (context.PreinitializationManager.HasLazyStaticConstructor(_type))
if (context.PreinitializationManager.HasLazyStaticConstructor(_type.ConvertToCanonForm(CanonicalFormKind.Specific)))
{
yield return new DependencyListEntry(context.MethodEntrypoint(_type.GetStaticConstructor().GetCanonMethodTarget(CanonicalFormKind.Specific)), "cctor for template");
}
Expand DownExpand Up@@ -1188,7 +1190,7 @@ public override Vertex WriteVertex(NodeFactory factory)
layoutInfo.Append(BagElementKind.DictionaryLayout, dictionaryLayout.WriteVertex(factory));
}

if (factory.PreinitializationManager.HasLazyStaticConstructor(_type))
if (factory.PreinitializationManager.HasLazyStaticConstructor(_type.ConvertToCanonForm(CanonicalFormKind.Specific)))
{
MethodDesc cctorMethod = _type.GetStaticConstructor();
MethodDesc canonCctorMethod = cctorMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,7 +33,7 @@ public NonGCStaticsNode(MetadataType type, PreinitializationManager preinitializ

protected override ObjectNodeSection GetDehydratedSection(NodeFactory factory)
{
if (_preinitializationManager.HasLazyStaticConstructor(_type)
if (HasCCtorContext
|| _preinitializationManager.IsPreinitialized(_type))
{
// We have data to be emitted so this needs to be in an initialized data section
Expand DownExpand Up@@ -63,7 +63,7 @@ int ISymbolDefinitionNode.Offset
get
{
// Make sure the NonGCStatics symbol always points to the beginning of the data.
if (_preinitializationManager.HasLazyStaticConstructor(_type))
if (HasCCtorContext)
{
return GetClassConstructorContextStorageSize(_type.Context.Target, _type);
}
Expand All@@ -74,7 +74,25 @@ int ISymbolDefinitionNode.Offset
}
}

public bool HasCCtorContext => _preinitializationManager.HasLazyStaticConstructor(_type);
public static bool TypeHasCctorContext(PreinitializationManager preinitializationManager, MetadataType type)
{
// If the type has a lazy static constructor, we need the cctor context.
if (preinitializationManager.HasLazyStaticConstructor(type))
return true;

// If the type has a canonical form and accessing the base from a canonical
// context requires a cctor check, we need the cctor context.
TypeDesc canonType = type.ConvertToCanonForm(CanonicalFormKind.Specific);
if (canonType != type && preinitializationManager.HasLazyStaticConstructor(canonType))
return true;

// Otherwise no cctor context needed.
return false;
}

public bool HasCCtorContext => TypeHasCctorContext(_preinitializationManager, _type);

public bool HasLazyStaticConstructor => _preinitializationManager.HasLazyStaticConstructor(_type);

public override bool IsShareable => EETypeNode.IsTypeNodeShareable(_type);

Expand DownExpand Up@@ -124,7 +142,7 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo

// If the type has a class constructor, its non-GC statics section is prefixed
// by System.Runtime.CompilerServices.StaticClassConstructionContext struct.
if (factory.PreinitializationManager.HasLazyStaticConstructor(_type))
if (HasCCtorContext)
{
int alignmentRequired = Math.Max(_type.NonGCStaticFieldAlignment.AsInt, GetClassConstructorContextAlignment(_type.Context.Target));
int classConstructorContextStorageSize = GetClassConstructorContextStorageSize(factory.Target, _type);
Expand All@@ -138,7 +156,24 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo
// Emit the actual StaticClassConstructionContext
MethodDesc cctorMethod = _type.GetStaticConstructor();
builder.EmitPointerReloc(factory.ExactCallableAddress(cctorMethod));
builder.EmitZeroPointer();

// If we're emitting the cctor context, but the type is actually preinitialized, emit the
// cctor context as already executed.
if (!HasLazyStaticConstructor)
{
// Constructor executed
// TODO-NICE: introduce a named constant and also use it in the runner in CoreLib
builder.EmitInt(1);
}
else
{
// Constructor didn't execute
builder.EmitInt(0);
}

// Emit padding if needed
if (builder.TargetPointerSize == 8)
builder.EmitInt(0);
}
else
{
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -107,7 +107,7 @@ protected sealed override void OnMarked(NodeFactory factory)
layout.EnsureEntry(_lookupSignature);

if ((_id == ReadyToRunHelperId.GetGCStaticBase || _id == ReadyToRunHelperId.GetThreadStaticBase) &&
factory.PreinitializationManager.HasLazyStaticConstructor((TypeDesc)_target))
TriggersLazyStaticConstructor(factory))
{
// If the type has a lazy static constructor, we also need the non-GC static base
// because that's where the class constructor context is.
Expand All@@ -116,6 +116,12 @@ protected sealed override void OnMarked(NodeFactory factory)
}
}

private bool TriggersLazyStaticConstructor(NodeFactory factory)
{
TypeDesc type = (TypeDesc)_target;
return factory.PreinitializationManager.HasLazyStaticConstructor(type.ConvertToCanonForm(CanonicalFormKind.Specific));
}

public IEnumerable<DependencyListEntry> InstantiateDependencies(NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation)
{
DependencyList result = new DependencyList();
Expand All@@ -129,13 +135,11 @@ public IEnumerable<DependencyListEntry> InstantiateDependencies(NodeFactory fact
{
// If the type has a lazy static constructor, we also need the non-GC static base
// because that's where the class constructor context is.
TypeDesc type = (TypeDesc)_target;

if (factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (TriggersLazyStaticConstructor(factory))
{
result.Add(
new DependencyListEntry(
factory.GenericLookup.TypeNonGCStaticBase(type).GetTarget(factory, lookupContext),
factory.GenericLookup.TypeNonGCStaticBase((TypeDesc)_target).GetTarget(factory, lookupContext),
"Dictionary dependency"));
}
}
Expand DownExpand Up@@ -250,7 +254,7 @@ public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDep
// a template dictionary node.
TypeDesc type = (TypeDesc)_target;
Debug.Assert(templateLayout != null);
if (factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (TriggersLazyStaticConstructor(factory))
{
GenericLookupResult nonGcRegionLookup = factory.GenericLookup.TypeNonGCStaticBase(type);
conditionalDependencies.Add(new CombinedDependencyListEntry(nonGcRegionLookup.TemplateDictionaryNode(factory),
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ public static void AddStaticsInfoDependencies(ref DependencyList dependencies, N
dependencies.Add(factory.TypeGCStaticsSymbol(metadataType), "GC statics indirection for StaticsInfoHashtable");
}

if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || NonGCStaticsNode.TypeHasCctorContext(factory.PreinitializationManager, metadataType))
{
// The entry in the StaticsInfoHashtable points at the beginning of the static fields data, rather than the cctor
// context offset.
Expand DownExpand Up@@ -98,7 +98,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
{
bag.AppendUnsigned(BagElementKind.GcStaticData, _nativeStaticsReferences.GetIndex(factory.TypeGCStaticsSymbol(metadataType)));
}
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || NonGCStaticsNode.TypeHasCctorContext(factory.PreinitializationManager, metadataType))
{
bag.AppendUnsigned(BagElementKind.NonGcStaticData, _nativeStaticsReferences.GetIndex(factory.TypeNonGCStaticsSymbol(metadataType)));
}
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -70,8 +70,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -99,7 +98,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco
encoder.EmitLDR(encoder.TargetRegister.Result, encoder.TargetRegister.Result);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -132,7 +131,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -81,8 +81,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -111,7 +110,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en
encoder.EmitLDR(encoder.TargetRegister.Result, encoder.TargetRegister.Result);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -144,7 +143,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -70,8 +70,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -100,7 +99,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit
encoder.EmitLD(encoder.TargetRegister.Result, encoder.TargetRegister.Result, 0);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -133,7 +132,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -82,9 +82,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
{
Debug.Assert(contextRegister == encoder.TargetRegister.Arg0);

MetadataType target = (MetadataType)_target;

if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);
encoder.EmitRET();
Expand DownExpand Up@@ -119,7 +117,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
AddrMode loadFromResult = new AddrMode(encoder.TargetRegister.Result, null, 0, 0, AddrModeSize.Int64);
encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromResult);

if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -153,7 +151,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -118,7 +118,7 @@ public CompilationBuilder UseDwarf5(bool value)
protected PreinitializationManager GetPreinitializationManager()
{
if (_preinitializationManager == null)
return new PreinitializationManager(_context, _compilationGroup, GetILProvider(), enableInterpreter: false);
return new PreinitializationManager(_context, _compilationGroup, GetILProvider(), new TypePreinit.DisabledPreinitializationPolicy());
return _preinitializationManager;
}

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -50,17 +50,10 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
Section nativeSection = nativeWriter.NewSection();
nativeSection.Place(hashtable);

foreach (TypeDesc type in factory.MetadataManager.GetTypesWithConstructedEETypes())
foreach (TypeDesc type in factory.MetadataManager.GetTypeTemplates())
{
if (!IsEligibleToHaveATemplate(type))
continue;

// Type's native layout info
NativeLayoutTemplateTypeLayoutVertexNode templateNode = factory.NativeLayout.TemplateTypeLayout(type);

// If this template isn't considered necessary, don't emit it.
if (!templateNode.Marked)
continue;
Vertex nativeLayout = templateNode.SavedVertex;

// Hashtable Entry
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -921,6 +921,8 @@ public sealed class NativeLayoutTemplateTypeLayoutVertexNode : NativeLayoutSaved
private TypeDesc _type;
private bool _isUniversalCanon;

public TypeDesc CanonType => _type.ConvertToCanonForm(CanonicalFormKind.Specific);

protected override string GetName(NodeFactory factory) => "NativeLayoutTemplateTypeLayoutVertexNode_" + factory.NameMangler.GetMangledTypeName(_type);

public NativeLayoutTemplateTypeLayoutVertexNode(NodeFactory factory, TypeDesc type)
Expand DownExpand Up@@ -989,7 +991,7 @@ public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFacto
}
}

if (context.PreinitializationManager.HasLazyStaticConstructor(_type))
if (context.PreinitializationManager.HasLazyStaticConstructor(_type.ConvertToCanonForm(CanonicalFormKind.Specific)))
{
yield return new DependencyListEntry(context.MethodEntrypoint(_type.GetStaticConstructor().GetCanonMethodTarget(CanonicalFormKind.Specific)), "cctor for template");
}
Expand DownExpand Up@@ -1188,7 +1190,7 @@ public override Vertex WriteVertex(NodeFactory factory)
layoutInfo.Append(BagElementKind.DictionaryLayout, dictionaryLayout.WriteVertex(factory));
}

if (factory.PreinitializationManager.HasLazyStaticConstructor(_type))
if (factory.PreinitializationManager.HasLazyStaticConstructor(_type.ConvertToCanonForm(CanonicalFormKind.Specific)))
{
MethodDesc cctorMethod = _type.GetStaticConstructor();
MethodDesc canonCctorMethod = cctorMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,7 +33,7 @@ public NonGCStaticsNode(MetadataType type, PreinitializationManager preinitializ

protected override ObjectNodeSection GetDehydratedSection(NodeFactory factory)
{
if (_preinitializationManager.HasLazyStaticConstructor(_type)
if (HasCCtorContext
|| _preinitializationManager.IsPreinitialized(_type))
{
// We have data to be emitted so this needs to be in an initialized data section
Expand DownExpand Up@@ -63,7 +63,7 @@ int ISymbolDefinitionNode.Offset
get
{
// Make sure the NonGCStatics symbol always points to the beginning of the data.
if (_preinitializationManager.HasLazyStaticConstructor(_type))
if (HasCCtorContext)
{
return GetClassConstructorContextStorageSize(_type.Context.Target, _type);
}
Expand All@@ -74,7 +74,25 @@ int ISymbolDefinitionNode.Offset
}
}

public bool HasCCtorContext => _preinitializationManager.HasLazyStaticConstructor(_type);
public static bool TypeHasCctorContext(PreinitializationManager preinitializationManager, MetadataType type)
{
// If the type has a lazy static constructor, we need the cctor context.
if (preinitializationManager.HasLazyStaticConstructor(type))
return true;

// If the type has a canonical form and accessing the base from a canonical
// context requires a cctor check, we need the cctor context.
TypeDesc canonType = type.ConvertToCanonForm(CanonicalFormKind.Specific);
if (canonType != type && preinitializationManager.HasLazyStaticConstructor(canonType))
return true;

// Otherwise no cctor context needed.
return false;
}

public bool HasCCtorContext => TypeHasCctorContext(_preinitializationManager, _type);

public bool HasLazyStaticConstructor => _preinitializationManager.HasLazyStaticConstructor(_type);

public override bool IsShareable => EETypeNode.IsTypeNodeShareable(_type);

Expand DownExpand Up@@ -124,7 +142,7 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo

// If the type has a class constructor, its non-GC statics section is prefixed
// by System.Runtime.CompilerServices.StaticClassConstructionContext struct.
if (factory.PreinitializationManager.HasLazyStaticConstructor(_type))
if (HasCCtorContext)
{
int alignmentRequired = Math.Max(_type.NonGCStaticFieldAlignment.AsInt, GetClassConstructorContextAlignment(_type.Context.Target));
int classConstructorContextStorageSize = GetClassConstructorContextStorageSize(factory.Target, _type);
Expand All@@ -138,7 +156,24 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo
// Emit the actual StaticClassConstructionContext
MethodDesc cctorMethod = _type.GetStaticConstructor();
builder.EmitPointerReloc(factory.ExactCallableAddress(cctorMethod));
builder.EmitZeroPointer();

// If we're emitting the cctor context, but the type is actually preinitialized, emit the
// cctor context as already executed.
if (!HasLazyStaticConstructor)
{
// Constructor executed
// TODO-NICE: introduce a named constant and also use it in the runner in CoreLib
builder.EmitInt(1);
}
else
{
// Constructor didn't execute
builder.EmitInt(0);
}

// Emit padding if needed
if (builder.TargetPointerSize == 8)
builder.EmitInt(0);
}
else
{
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -107,7 +107,7 @@ protected sealed override void OnMarked(NodeFactory factory)
layout.EnsureEntry(_lookupSignature);

if ((_id == ReadyToRunHelperId.GetGCStaticBase || _id == ReadyToRunHelperId.GetThreadStaticBase) &&
factory.PreinitializationManager.HasLazyStaticConstructor((TypeDesc)_target))
TriggersLazyStaticConstructor(factory))
{
// If the type has a lazy static constructor, we also need the non-GC static base
// because that's where the class constructor context is.
Expand All@@ -116,6 +116,12 @@ protected sealed override void OnMarked(NodeFactory factory)
}
}

private bool TriggersLazyStaticConstructor(NodeFactory factory)
{
TypeDesc type = (TypeDesc)_target;
return factory.PreinitializationManager.HasLazyStaticConstructor(type.ConvertToCanonForm(CanonicalFormKind.Specific));
}

public IEnumerable<DependencyListEntry> InstantiateDependencies(NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation)
{
DependencyList result = new DependencyList();
Expand All@@ -129,13 +135,11 @@ public IEnumerable<DependencyListEntry> InstantiateDependencies(NodeFactory fact
{
// If the type has a lazy static constructor, we also need the non-GC static base
// because that's where the class constructor context is.
TypeDesc type = (TypeDesc)_target;

if (factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (TriggersLazyStaticConstructor(factory))
{
result.Add(
new DependencyListEntry(
factory.GenericLookup.TypeNonGCStaticBase(type).GetTarget(factory, lookupContext),
factory.GenericLookup.TypeNonGCStaticBase((TypeDesc)_target).GetTarget(factory, lookupContext),
"Dictionary dependency"));
}
}
Expand DownExpand Up@@ -250,7 +254,7 @@ public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDep
// a template dictionary node.
TypeDesc type = (TypeDesc)_target;
Debug.Assert(templateLayout != null);
if (factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (TriggersLazyStaticConstructor(factory))
{
GenericLookupResult nonGcRegionLookup = factory.GenericLookup.TypeNonGCStaticBase(type);
conditionalDependencies.Add(new CombinedDependencyListEntry(nonGcRegionLookup.TemplateDictionaryNode(factory),
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ public static void AddStaticsInfoDependencies(ref DependencyList dependencies, N
dependencies.Add(factory.TypeGCStaticsSymbol(metadataType), "GC statics indirection for StaticsInfoHashtable");
}

if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || NonGCStaticsNode.TypeHasCctorContext(factory.PreinitializationManager, metadataType))
{
// The entry in the StaticsInfoHashtable points at the beginning of the static fields data, rather than the cctor
// context offset.
Expand DownExpand Up@@ -98,7 +98,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
{
bag.AppendUnsigned(BagElementKind.GcStaticData, _nativeStaticsReferences.GetIndex(factory.TypeGCStaticsSymbol(metadataType)));
}
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || NonGCStaticsNode.TypeHasCctorContext(factory.PreinitializationManager, metadataType))
{
bag.AppendUnsigned(BagElementKind.NonGcStaticData, _nativeStaticsReferences.GetIndex(factory.TypeNonGCStaticsSymbol(metadataType)));
}
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -70,8 +70,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -99,7 +98,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco
encoder.EmitLDR(encoder.TargetRegister.Result, encoder.TargetRegister.Result);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -132,7 +131,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -81,8 +81,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -111,7 +110,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en
encoder.EmitLDR(encoder.TargetRegister.Result, encoder.TargetRegister.Result);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -144,7 +143,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -70,8 +70,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -100,7 +99,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit
encoder.EmitLD(encoder.TargetRegister.Result, encoder.TargetRegister.Result, 0);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -133,7 +132,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -82,9 +82,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
{
Debug.Assert(contextRegister == encoder.TargetRegister.Arg0);

MetadataType target = (MetadataType)_target;

if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);
encoder.EmitRET();
Expand DownExpand Up@@ -119,7 +117,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
AddrMode loadFromResult = new AddrMode(encoder.TargetRegister.Result, null, 0, 0, AddrModeSize.Int64);
encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromResult);

if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -153,7 +151,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -118,7 +118,7 @@ public CompilationBuilder UseDwarf5(bool value)
protected PreinitializationManager GetPreinitializationManager()
{
if (_preinitializationManager == null)
return new PreinitializationManager(_context, _compilationGroup, GetILProvider(), enableInterpreter: false);
return new PreinitializationManager(_context, _compilationGroup, GetILProvider(), new TypePreinit.DisabledPreinitializationPolicy());
return _preinitializationManager;
}

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -50,17 +50,10 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
Section nativeSection = nativeWriter.NewSection();
nativeSection.Place(hashtable);

foreach (TypeDesc type in factory.MetadataManager.GetTypesWithConstructedEETypes())
foreach (TypeDesc type in factory.MetadataManager.GetTypeTemplates())
{
if (!IsEligibleToHaveATemplate(type))
continue;

// Type's native layout info
NativeLayoutTemplateTypeLayoutVertexNode templateNode = factory.NativeLayout.TemplateTypeLayout(type);

// If this template isn't considered necessary, don't emit it.
if (!templateNode.Marked)
continue;
Vertex nativeLayout = templateNode.SavedVertex;

// Hashtable Entry
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -921,6 +921,8 @@ public sealed class NativeLayoutTemplateTypeLayoutVertexNode : NativeLayoutSaved
private TypeDesc _type;
private bool _isUniversalCanon;

public TypeDesc CanonType => _type.ConvertToCanonForm(CanonicalFormKind.Specific);

protected override string GetName(NodeFactory factory) => "NativeLayoutTemplateTypeLayoutVertexNode_" + factory.NameMangler.GetMangledTypeName(_type);

public NativeLayoutTemplateTypeLayoutVertexNode(NodeFactory factory, TypeDesc type)
Expand DownExpand Up@@ -989,7 +991,7 @@ public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFacto
}
}

if (context.PreinitializationManager.HasLazyStaticConstructor(_type))
if (context.PreinitializationManager.HasLazyStaticConstructor(_type.ConvertToCanonForm(CanonicalFormKind.Specific)))
{
yield return new DependencyListEntry(context.MethodEntrypoint(_type.GetStaticConstructor().GetCanonMethodTarget(CanonicalFormKind.Specific)), "cctor for template");
}
Expand DownExpand Up@@ -1188,7 +1190,7 @@ public override Vertex WriteVertex(NodeFactory factory)
layoutInfo.Append(BagElementKind.DictionaryLayout, dictionaryLayout.WriteVertex(factory));
}

if (factory.PreinitializationManager.HasLazyStaticConstructor(_type))
if (factory.PreinitializationManager.HasLazyStaticConstructor(_type.ConvertToCanonForm(CanonicalFormKind.Specific)))
{
MethodDesc cctorMethod = _type.GetStaticConstructor();
MethodDesc canonCctorMethod = cctorMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,7 +33,7 @@ public NonGCStaticsNode(MetadataType type, PreinitializationManager preinitializ

protected override ObjectNodeSection GetDehydratedSection(NodeFactory factory)
{
if (_preinitializationManager.HasLazyStaticConstructor(_type)
if (HasCCtorContext
|| _preinitializationManager.IsPreinitialized(_type))
{
// We have data to be emitted so this needs to be in an initialized data section
Expand DownExpand Up@@ -63,7 +63,7 @@ int ISymbolDefinitionNode.Offset
get
{
// Make sure the NonGCStatics symbol always points to the beginning of the data.
if (_preinitializationManager.HasLazyStaticConstructor(_type))
if (HasCCtorContext)
{
return GetClassConstructorContextStorageSize(_type.Context.Target, _type);
}
Expand All@@ -74,7 +74,25 @@ int ISymbolDefinitionNode.Offset
}
}

public bool HasCCtorContext => _preinitializationManager.HasLazyStaticConstructor(_type);
public static bool TypeHasCctorContext(PreinitializationManager preinitializationManager, MetadataType type)
{
// If the type has a lazy static constructor, we need the cctor context.
if (preinitializationManager.HasLazyStaticConstructor(type))
return true;

// If the type has a canonical form and accessing the base from a canonical
// context requires a cctor check, we need the cctor context.
TypeDesc canonType = type.ConvertToCanonForm(CanonicalFormKind.Specific);
if (canonType != type && preinitializationManager.HasLazyStaticConstructor(canonType))
return true;

// Otherwise no cctor context needed.
return false;
}

public bool HasCCtorContext => TypeHasCctorContext(_preinitializationManager, _type);

public bool HasLazyStaticConstructor => _preinitializationManager.HasLazyStaticConstructor(_type);

public override bool IsShareable => EETypeNode.IsTypeNodeShareable(_type);

Expand DownExpand Up@@ -124,7 +142,7 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo

// If the type has a class constructor, its non-GC statics section is prefixed
// by System.Runtime.CompilerServices.StaticClassConstructionContext struct.
if (factory.PreinitializationManager.HasLazyStaticConstructor(_type))
if (HasCCtorContext)
{
int alignmentRequired = Math.Max(_type.NonGCStaticFieldAlignment.AsInt, GetClassConstructorContextAlignment(_type.Context.Target));
int classConstructorContextStorageSize = GetClassConstructorContextStorageSize(factory.Target, _type);
Expand All@@ -138,7 +156,24 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo
// Emit the actual StaticClassConstructionContext
MethodDesc cctorMethod = _type.GetStaticConstructor();
builder.EmitPointerReloc(factory.ExactCallableAddress(cctorMethod));
builder.EmitZeroPointer();

// If we're emitting the cctor context, but the type is actually preinitialized, emit the
// cctor context as already executed.
if (!HasLazyStaticConstructor)
{
// Constructor executed
// TODO-NICE: introduce a named constant and also use it in the runner in CoreLib
builder.EmitInt(1);
}
else
{
// Constructor didn't execute
builder.EmitInt(0);
}

// Emit padding if needed
if (builder.TargetPointerSize == 8)
builder.EmitInt(0);
}
else
{
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -107,7 +107,7 @@ protected sealed override void OnMarked(NodeFactory factory)
layout.EnsureEntry(_lookupSignature);

if ((_id == ReadyToRunHelperId.GetGCStaticBase || _id == ReadyToRunHelperId.GetThreadStaticBase) &&
factory.PreinitializationManager.HasLazyStaticConstructor((TypeDesc)_target))
TriggersLazyStaticConstructor(factory))
{
// If the type has a lazy static constructor, we also need the non-GC static base
// because that's where the class constructor context is.
Expand All@@ -116,6 +116,12 @@ protected sealed override void OnMarked(NodeFactory factory)
}
}

private bool TriggersLazyStaticConstructor(NodeFactory factory)
{
TypeDesc type = (TypeDesc)_target;
return factory.PreinitializationManager.HasLazyStaticConstructor(type.ConvertToCanonForm(CanonicalFormKind.Specific));
}

public IEnumerable<DependencyListEntry> InstantiateDependencies(NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation)
{
DependencyList result = new DependencyList();
Expand All@@ -129,13 +135,11 @@ public IEnumerable<DependencyListEntry> InstantiateDependencies(NodeFactory fact
{
// If the type has a lazy static constructor, we also need the non-GC static base
// because that's where the class constructor context is.
TypeDesc type = (TypeDesc)_target;

if (factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (TriggersLazyStaticConstructor(factory))
{
result.Add(
new DependencyListEntry(
factory.GenericLookup.TypeNonGCStaticBase(type).GetTarget(factory, lookupContext),
factory.GenericLookup.TypeNonGCStaticBase((TypeDesc)_target).GetTarget(factory, lookupContext),
"Dictionary dependency"));
}
}
Expand DownExpand Up@@ -250,7 +254,7 @@ public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDep
// a template dictionary node.
TypeDesc type = (TypeDesc)_target;
Debug.Assert(templateLayout != null);
if (factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (TriggersLazyStaticConstructor(factory))
{
GenericLookupResult nonGcRegionLookup = factory.GenericLookup.TypeNonGCStaticBase(type);
conditionalDependencies.Add(new CombinedDependencyListEntry(nonGcRegionLookup.TemplateDictionaryNode(factory),
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ public static void AddStaticsInfoDependencies(ref DependencyList dependencies, N
dependencies.Add(factory.TypeGCStaticsSymbol(metadataType), "GC statics indirection for StaticsInfoHashtable");
}

if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || NonGCStaticsNode.TypeHasCctorContext(factory.PreinitializationManager, metadataType))
{
// The entry in the StaticsInfoHashtable points at the beginning of the static fields data, rather than the cctor
// context offset.
Expand DownExpand Up@@ -98,7 +98,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
{
bag.AppendUnsigned(BagElementKind.GcStaticData, _nativeStaticsReferences.GetIndex(factory.TypeGCStaticsSymbol(metadataType)));
}
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || NonGCStaticsNode.TypeHasCctorContext(factory.PreinitializationManager, metadataType))
{
bag.AppendUnsigned(BagElementKind.NonGcStaticData, _nativeStaticsReferences.GetIndex(factory.TypeNonGCStaticsSymbol(metadataType)));
}
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -70,8 +70,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -99,7 +98,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco
encoder.EmitLDR(encoder.TargetRegister.Result, encoder.TargetRegister.Result);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -132,7 +131,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -81,8 +81,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -111,7 +110,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en
encoder.EmitLDR(encoder.TargetRegister.Result, encoder.TargetRegister.Result);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -144,7 +143,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -70,8 +70,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -100,7 +99,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit
encoder.EmitLD(encoder.TargetRegister.Result, encoder.TargetRegister.Result, 0);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -133,7 +132,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -82,9 +82,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
{
Debug.Assert(contextRegister == encoder.TargetRegister.Arg0);

MetadataType target = (MetadataType)_target;

if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);
encoder.EmitRET();
Expand DownExpand Up@@ -119,7 +117,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
AddrMode loadFromResult = new AddrMode(encoder.TargetRegister.Result, null, 0, 0, AddrModeSize.Int64);
encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromResult);

if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -153,7 +151,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -118,7 +118,7 @@ public CompilationBuilder UseDwarf5(bool value)
protected PreinitializationManager GetPreinitializationManager()
{
if (_preinitializationManager == null)
return new PreinitializationManager(_context, _compilationGroup, GetILProvider(), enableInterpreter: false);
return new PreinitializationManager(_context, _compilationGroup, GetILProvider(), new TypePreinit.DisabledPreinitializationPolicy());
return _preinitializationManager;
}

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -50,17 +50,10 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
Section nativeSection = nativeWriter.NewSection();
nativeSection.Place(hashtable);

foreach (TypeDesc type in factory.MetadataManager.GetTypesWithConstructedEETypes())
foreach (TypeDesc type in factory.MetadataManager.GetTypeTemplates())
{
if (!IsEligibleToHaveATemplate(type))
continue;

// Type's native layout info
NativeLayoutTemplateTypeLayoutVertexNode templateNode = factory.NativeLayout.TemplateTypeLayout(type);

// If this template isn't considered necessary, don't emit it.
if (!templateNode.Marked)
continue;
Vertex nativeLayout = templateNode.SavedVertex;

// Hashtable Entry
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -921,6 +921,8 @@ public sealed class NativeLayoutTemplateTypeLayoutVertexNode : NativeLayoutSaved
private TypeDesc _type;
private bool _isUniversalCanon;

public TypeDesc CanonType => _type.ConvertToCanonForm(CanonicalFormKind.Specific);

protected override string GetName(NodeFactory factory) => "NativeLayoutTemplateTypeLayoutVertexNode_" + factory.NameMangler.GetMangledTypeName(_type);

public NativeLayoutTemplateTypeLayoutVertexNode(NodeFactory factory, TypeDesc type)
Expand DownExpand Up@@ -989,7 +991,7 @@ public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFacto
}
}

if (context.PreinitializationManager.HasLazyStaticConstructor(_type))
if (context.PreinitializationManager.HasLazyStaticConstructor(_type.ConvertToCanonForm(CanonicalFormKind.Specific)))
{
yield return new DependencyListEntry(context.MethodEntrypoint(_type.GetStaticConstructor().GetCanonMethodTarget(CanonicalFormKind.Specific)), "cctor for template");
}
Expand DownExpand Up@@ -1188,7 +1190,7 @@ public override Vertex WriteVertex(NodeFactory factory)
layoutInfo.Append(BagElementKind.DictionaryLayout, dictionaryLayout.WriteVertex(factory));
}

if (factory.PreinitializationManager.HasLazyStaticConstructor(_type))
if (factory.PreinitializationManager.HasLazyStaticConstructor(_type.ConvertToCanonForm(CanonicalFormKind.Specific)))
{
MethodDesc cctorMethod = _type.GetStaticConstructor();
MethodDesc canonCctorMethod = cctorMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,7 +33,7 @@ public NonGCStaticsNode(MetadataType type, PreinitializationManager preinitializ

protected override ObjectNodeSection GetDehydratedSection(NodeFactory factory)
{
if (_preinitializationManager.HasLazyStaticConstructor(_type)
if (HasCCtorContext
|| _preinitializationManager.IsPreinitialized(_type))
{
// We have data to be emitted so this needs to be in an initialized data section
Expand DownExpand Up@@ -63,7 +63,7 @@ int ISymbolDefinitionNode.Offset
get
{
// Make sure the NonGCStatics symbol always points to the beginning of the data.
if (_preinitializationManager.HasLazyStaticConstructor(_type))
if (HasCCtorContext)
{
return GetClassConstructorContextStorageSize(_type.Context.Target, _type);
}
Expand All@@ -74,7 +74,25 @@ int ISymbolDefinitionNode.Offset
}
}

public bool HasCCtorContext => _preinitializationManager.HasLazyStaticConstructor(_type);
public static bool TypeHasCctorContext(PreinitializationManager preinitializationManager, MetadataType type)
{
// If the type has a lazy static constructor, we need the cctor context.
if (preinitializationManager.HasLazyStaticConstructor(type))
return true;

// If the type has a canonical form and accessing the base from a canonical
// context requires a cctor check, we need the cctor context.
TypeDesc canonType = type.ConvertToCanonForm(CanonicalFormKind.Specific);
if (canonType != type && preinitializationManager.HasLazyStaticConstructor(canonType))
return true;

// Otherwise no cctor context needed.
return false;
}

public bool HasCCtorContext => TypeHasCctorContext(_preinitializationManager, _type);

public bool HasLazyStaticConstructor => _preinitializationManager.HasLazyStaticConstructor(_type);

public override bool IsShareable => EETypeNode.IsTypeNodeShareable(_type);

Expand DownExpand Up@@ -124,7 +142,7 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo

// If the type has a class constructor, its non-GC statics section is prefixed
// by System.Runtime.CompilerServices.StaticClassConstructionContext struct.
if (factory.PreinitializationManager.HasLazyStaticConstructor(_type))
if (HasCCtorContext)
{
int alignmentRequired = Math.Max(_type.NonGCStaticFieldAlignment.AsInt, GetClassConstructorContextAlignment(_type.Context.Target));
int classConstructorContextStorageSize = GetClassConstructorContextStorageSize(factory.Target, _type);
Expand All@@ -138,7 +156,24 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo
// Emit the actual StaticClassConstructionContext
MethodDesc cctorMethod = _type.GetStaticConstructor();
builder.EmitPointerReloc(factory.ExactCallableAddress(cctorMethod));
builder.EmitZeroPointer();

// If we're emitting the cctor context, but the type is actually preinitialized, emit the
// cctor context as already executed.
if (!HasLazyStaticConstructor)
{
// Constructor executed
// TODO-NICE: introduce a named constant and also use it in the runner in CoreLib
builder.EmitInt(1);
}
else
{
// Constructor didn't execute
builder.EmitInt(0);
}

// Emit padding if needed
if (builder.TargetPointerSize == 8)
builder.EmitInt(0);
}
else
{
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -107,7 +107,7 @@ protected sealed override void OnMarked(NodeFactory factory)
layout.EnsureEntry(_lookupSignature);

if ((_id == ReadyToRunHelperId.GetGCStaticBase || _id == ReadyToRunHelperId.GetThreadStaticBase) &&
factory.PreinitializationManager.HasLazyStaticConstructor((TypeDesc)_target))
TriggersLazyStaticConstructor(factory))
{
// If the type has a lazy static constructor, we also need the non-GC static base
// because that's where the class constructor context is.
Expand All@@ -116,6 +116,12 @@ protected sealed override void OnMarked(NodeFactory factory)
}
}

private bool TriggersLazyStaticConstructor(NodeFactory factory)
{
TypeDesc type = (TypeDesc)_target;
return factory.PreinitializationManager.HasLazyStaticConstructor(type.ConvertToCanonForm(CanonicalFormKind.Specific));
}

public IEnumerable<DependencyListEntry> InstantiateDependencies(NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation)
{
DependencyList result = new DependencyList();
Expand All@@ -129,13 +135,11 @@ public IEnumerable<DependencyListEntry> InstantiateDependencies(NodeFactory fact
{
// If the type has a lazy static constructor, we also need the non-GC static base
// because that's where the class constructor context is.
TypeDesc type = (TypeDesc)_target;

if (factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (TriggersLazyStaticConstructor(factory))
{
result.Add(
new DependencyListEntry(
factory.GenericLookup.TypeNonGCStaticBase(type).GetTarget(factory, lookupContext),
factory.GenericLookup.TypeNonGCStaticBase((TypeDesc)_target).GetTarget(factory, lookupContext),
"Dictionary dependency"));
}
}
Expand DownExpand Up@@ -250,7 +254,7 @@ public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDep
// a template dictionary node.
TypeDesc type = (TypeDesc)_target;
Debug.Assert(templateLayout != null);
if (factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (TriggersLazyStaticConstructor(factory))
{
GenericLookupResult nonGcRegionLookup = factory.GenericLookup.TypeNonGCStaticBase(type);
conditionalDependencies.Add(new CombinedDependencyListEntry(nonGcRegionLookup.TemplateDictionaryNode(factory),
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ public static void AddStaticsInfoDependencies(ref DependencyList dependencies, N
dependencies.Add(factory.TypeGCStaticsSymbol(metadataType), "GC statics indirection for StaticsInfoHashtable");
}

if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || NonGCStaticsNode.TypeHasCctorContext(factory.PreinitializationManager, metadataType))
{
// The entry in the StaticsInfoHashtable points at the beginning of the static fields data, rather than the cctor
// context offset.
Expand DownExpand Up@@ -98,7 +98,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
{
bag.AppendUnsigned(BagElementKind.GcStaticData, _nativeStaticsReferences.GetIndex(factory.TypeGCStaticsSymbol(metadataType)));
}
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || NonGCStaticsNode.TypeHasCctorContext(factory.PreinitializationManager, metadataType))
{
bag.AppendUnsigned(BagElementKind.NonGcStaticData, _nativeStaticsReferences.GetIndex(factory.TypeNonGCStaticsSymbol(metadataType)));
}
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -70,8 +70,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -99,7 +98,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco
encoder.EmitLDR(encoder.TargetRegister.Result, encoder.TargetRegister.Result);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -132,7 +131,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -81,8 +81,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -111,7 +110,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en
encoder.EmitLDR(encoder.TargetRegister.Result, encoder.TargetRegister.Result);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -144,7 +143,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -70,8 +70,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -100,7 +99,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit
encoder.EmitLD(encoder.TargetRegister.Result, encoder.TargetRegister.Result, 0);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -133,7 +132,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -82,9 +82,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
{
Debug.Assert(contextRegister == encoder.TargetRegister.Arg0);

MetadataType target = (MetadataType)_target;

if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);
encoder.EmitRET();
Expand DownExpand Up@@ -119,7 +117,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
AddrMode loadFromResult = new AddrMode(encoder.TargetRegister.Result, null, 0, 0, AddrModeSize.Int64);
encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromResult);

if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -153,7 +151,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -118,7 +118,7 @@ public CompilationBuilder UseDwarf5(bool value)
protected PreinitializationManager GetPreinitializationManager()
{
if (_preinitializationManager == null)
return new PreinitializationManager(_context, _compilationGroup, GetILProvider(), enableInterpreter: false);
return new PreinitializationManager(_context, _compilationGroup, GetILProvider(), new TypePreinit.DisabledPreinitializationPolicy());
return _preinitializationManager;
}

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -50,17 +50,10 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
Section nativeSection = nativeWriter.NewSection();
nativeSection.Place(hashtable);

foreach (TypeDesc type in factory.MetadataManager.GetTypesWithConstructedEETypes())
foreach (TypeDesc type in factory.MetadataManager.GetTypeTemplates())
{
if (!IsEligibleToHaveATemplate(type))
continue;

// Type's native layout info
NativeLayoutTemplateTypeLayoutVertexNode templateNode = factory.NativeLayout.TemplateTypeLayout(type);

// If this template isn't considered necessary, don't emit it.
if (!templateNode.Marked)
continue;
Vertex nativeLayout = templateNode.SavedVertex;

// Hashtable Entry
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -921,6 +921,8 @@ public sealed class NativeLayoutTemplateTypeLayoutVertexNode : NativeLayoutSaved
private TypeDesc _type;
private bool _isUniversalCanon;

public TypeDesc CanonType => _type.ConvertToCanonForm(CanonicalFormKind.Specific);

protected override string GetName(NodeFactory factory) => "NativeLayoutTemplateTypeLayoutVertexNode_" + factory.NameMangler.GetMangledTypeName(_type);

public NativeLayoutTemplateTypeLayoutVertexNode(NodeFactory factory, TypeDesc type)
Expand DownExpand Up@@ -989,7 +991,7 @@ public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFacto
}
}

if (context.PreinitializationManager.HasLazyStaticConstructor(_type))
if (context.PreinitializationManager.HasLazyStaticConstructor(_type.ConvertToCanonForm(CanonicalFormKind.Specific)))
{
yield return new DependencyListEntry(context.MethodEntrypoint(_type.GetStaticConstructor().GetCanonMethodTarget(CanonicalFormKind.Specific)), "cctor for template");
}
Expand DownExpand Up@@ -1188,7 +1190,7 @@ public override Vertex WriteVertex(NodeFactory factory)
layoutInfo.Append(BagElementKind.DictionaryLayout, dictionaryLayout.WriteVertex(factory));
}

if (factory.PreinitializationManager.HasLazyStaticConstructor(_type))
if (factory.PreinitializationManager.HasLazyStaticConstructor(_type.ConvertToCanonForm(CanonicalFormKind.Specific)))
{
MethodDesc cctorMethod = _type.GetStaticConstructor();
MethodDesc canonCctorMethod = cctorMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,7 +33,7 @@ public NonGCStaticsNode(MetadataType type, PreinitializationManager preinitializ

protected override ObjectNodeSection GetDehydratedSection(NodeFactory factory)
{
if (_preinitializationManager.HasLazyStaticConstructor(_type)
if (HasCCtorContext
|| _preinitializationManager.IsPreinitialized(_type))
{
// We have data to be emitted so this needs to be in an initialized data section
Expand DownExpand Up@@ -63,7 +63,7 @@ int ISymbolDefinitionNode.Offset
get
{
// Make sure the NonGCStatics symbol always points to the beginning of the data.
if (_preinitializationManager.HasLazyStaticConstructor(_type))
if (HasCCtorContext)
{
return GetClassConstructorContextStorageSize(_type.Context.Target, _type);
}
Expand All@@ -74,7 +74,25 @@ int ISymbolDefinitionNode.Offset
}
}

public bool HasCCtorContext => _preinitializationManager.HasLazyStaticConstructor(_type);
public static bool TypeHasCctorContext(PreinitializationManager preinitializationManager, MetadataType type)
{
// If the type has a lazy static constructor, we need the cctor context.
if (preinitializationManager.HasLazyStaticConstructor(type))
return true;

// If the type has a canonical form and accessing the base from a canonical
// context requires a cctor check, we need the cctor context.
TypeDesc canonType = type.ConvertToCanonForm(CanonicalFormKind.Specific);
if (canonType != type && preinitializationManager.HasLazyStaticConstructor(canonType))
return true;

// Otherwise no cctor context needed.
return false;
}

public bool HasCCtorContext => TypeHasCctorContext(_preinitializationManager, _type);

public bool HasLazyStaticConstructor => _preinitializationManager.HasLazyStaticConstructor(_type);

public override bool IsShareable => EETypeNode.IsTypeNodeShareable(_type);

Expand DownExpand Up@@ -124,7 +142,7 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo

// If the type has a class constructor, its non-GC statics section is prefixed
// by System.Runtime.CompilerServices.StaticClassConstructionContext struct.
if (factory.PreinitializationManager.HasLazyStaticConstructor(_type))
if (HasCCtorContext)
{
int alignmentRequired = Math.Max(_type.NonGCStaticFieldAlignment.AsInt, GetClassConstructorContextAlignment(_type.Context.Target));
int classConstructorContextStorageSize = GetClassConstructorContextStorageSize(factory.Target, _type);
Expand All@@ -138,7 +156,24 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo
// Emit the actual StaticClassConstructionContext
MethodDesc cctorMethod = _type.GetStaticConstructor();
builder.EmitPointerReloc(factory.ExactCallableAddress(cctorMethod));
builder.EmitZeroPointer();

// If we're emitting the cctor context, but the type is actually preinitialized, emit the
// cctor context as already executed.
if (!HasLazyStaticConstructor)
{
// Constructor executed
// TODO-NICE: introduce a named constant and also use it in the runner in CoreLib
builder.EmitInt(1);
}
else
{
// Constructor didn't execute
builder.EmitInt(0);
}

// Emit padding if needed
if (builder.TargetPointerSize == 8)
builder.EmitInt(0);
}
else
{
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -107,7 +107,7 @@ protected sealed override void OnMarked(NodeFactory factory)
layout.EnsureEntry(_lookupSignature);

if ((_id == ReadyToRunHelperId.GetGCStaticBase || _id == ReadyToRunHelperId.GetThreadStaticBase) &&
factory.PreinitializationManager.HasLazyStaticConstructor((TypeDesc)_target))
TriggersLazyStaticConstructor(factory))
{
// If the type has a lazy static constructor, we also need the non-GC static base
// because that's where the class constructor context is.
Expand All@@ -116,6 +116,12 @@ protected sealed override void OnMarked(NodeFactory factory)
}
}

private bool TriggersLazyStaticConstructor(NodeFactory factory)
{
TypeDesc type = (TypeDesc)_target;
return factory.PreinitializationManager.HasLazyStaticConstructor(type.ConvertToCanonForm(CanonicalFormKind.Specific));
}

public IEnumerable<DependencyListEntry> InstantiateDependencies(NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation)
{
DependencyList result = new DependencyList();
Expand All@@ -129,13 +135,11 @@ public IEnumerable<DependencyListEntry> InstantiateDependencies(NodeFactory fact
{
// If the type has a lazy static constructor, we also need the non-GC static base
// because that's where the class constructor context is.
TypeDesc type = (TypeDesc)_target;

if (factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (TriggersLazyStaticConstructor(factory))
{
result.Add(
new DependencyListEntry(
factory.GenericLookup.TypeNonGCStaticBase(type).GetTarget(factory, lookupContext),
factory.GenericLookup.TypeNonGCStaticBase((TypeDesc)_target).GetTarget(factory, lookupContext),
"Dictionary dependency"));
}
}
Expand DownExpand Up@@ -250,7 +254,7 @@ public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDep
// a template dictionary node.
TypeDesc type = (TypeDesc)_target;
Debug.Assert(templateLayout != null);
if (factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (TriggersLazyStaticConstructor(factory))
{
GenericLookupResult nonGcRegionLookup = factory.GenericLookup.TypeNonGCStaticBase(type);
conditionalDependencies.Add(new CombinedDependencyListEntry(nonGcRegionLookup.TemplateDictionaryNode(factory),
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ public static void AddStaticsInfoDependencies(ref DependencyList dependencies, N
dependencies.Add(factory.TypeGCStaticsSymbol(metadataType), "GC statics indirection for StaticsInfoHashtable");
}

if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || NonGCStaticsNode.TypeHasCctorContext(factory.PreinitializationManager, metadataType))
{
// The entry in the StaticsInfoHashtable points at the beginning of the static fields data, rather than the cctor
// context offset.
Expand DownExpand Up@@ -98,7 +98,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
{
bag.AppendUnsigned(BagElementKind.GcStaticData, _nativeStaticsReferences.GetIndex(factory.TypeGCStaticsSymbol(metadataType)));
}
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || NonGCStaticsNode.TypeHasCctorContext(factory.PreinitializationManager, metadataType))
{
bag.AppendUnsigned(BagElementKind.NonGcStaticData, _nativeStaticsReferences.GetIndex(factory.TypeNonGCStaticsSymbol(metadataType)));
}
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -70,8 +70,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -99,7 +98,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco
encoder.EmitLDR(encoder.TargetRegister.Result, encoder.TargetRegister.Result);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -132,7 +131,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -81,8 +81,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -111,7 +110,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en
encoder.EmitLDR(encoder.TargetRegister.Result, encoder.TargetRegister.Result);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -144,7 +143,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -70,8 +70,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -100,7 +99,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit
encoder.EmitLD(encoder.TargetRegister.Result, encoder.TargetRegister.Result, 0);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -133,7 +132,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -82,9 +82,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
{
Debug.Assert(contextRegister == encoder.TargetRegister.Arg0);

MetadataType target = (MetadataType)_target;

if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);
encoder.EmitRET();
Expand DownExpand Up@@ -119,7 +117,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
AddrMode loadFromResult = new AddrMode(encoder.TargetRegister.Result, null, 0, 0, AddrModeSize.Int64);
encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromResult);

if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -153,7 +151,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -118,7 +118,7 @@ public CompilationBuilder UseDwarf5(bool value)
protected PreinitializationManager GetPreinitializationManager()
{
if (_preinitializationManager == null)
return new PreinitializationManager(_context, _compilationGroup, GetILProvider(), enableInterpreter: false);
return new PreinitializationManager(_context, _compilationGroup, GetILProvider(), new TypePreinit.DisabledPreinitializationPolicy());
return _preinitializationManager;
}

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -50,17 +50,10 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
Section nativeSection = nativeWriter.NewSection();
nativeSection.Place(hashtable);

foreach (TypeDesc type in factory.MetadataManager.GetTypesWithConstructedEETypes())
foreach (TypeDesc type in factory.MetadataManager.GetTypeTemplates())
{
if (!IsEligibleToHaveATemplate(type))
continue;

// Type's native layout info
NativeLayoutTemplateTypeLayoutVertexNode templateNode = factory.NativeLayout.TemplateTypeLayout(type);

// If this template isn't considered necessary, don't emit it.
if (!templateNode.Marked)
continue;
Vertex nativeLayout = templateNode.SavedVertex;

// Hashtable Entry
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -921,6 +921,8 @@ public sealed class NativeLayoutTemplateTypeLayoutVertexNode : NativeLayoutSaved
private TypeDesc _type;
private bool _isUniversalCanon;

public TypeDesc CanonType => _type.ConvertToCanonForm(CanonicalFormKind.Specific);

protected override string GetName(NodeFactory factory) => "NativeLayoutTemplateTypeLayoutVertexNode_" + factory.NameMangler.GetMangledTypeName(_type);

public NativeLayoutTemplateTypeLayoutVertexNode(NodeFactory factory, TypeDesc type)
Expand DownExpand Up@@ -989,7 +991,7 @@ public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFacto
}
}

if (context.PreinitializationManager.HasLazyStaticConstructor(_type))
if (context.PreinitializationManager.HasLazyStaticConstructor(_type.ConvertToCanonForm(CanonicalFormKind.Specific)))
{
yield return new DependencyListEntry(context.MethodEntrypoint(_type.GetStaticConstructor().GetCanonMethodTarget(CanonicalFormKind.Specific)), "cctor for template");
}
Expand DownExpand Up@@ -1188,7 +1190,7 @@ public override Vertex WriteVertex(NodeFactory factory)
layoutInfo.Append(BagElementKind.DictionaryLayout, dictionaryLayout.WriteVertex(factory));
}

if (factory.PreinitializationManager.HasLazyStaticConstructor(_type))
if (factory.PreinitializationManager.HasLazyStaticConstructor(_type.ConvertToCanonForm(CanonicalFormKind.Specific)))
{
MethodDesc cctorMethod = _type.GetStaticConstructor();
MethodDesc canonCctorMethod = cctorMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,7 +33,7 @@ public NonGCStaticsNode(MetadataType type, PreinitializationManager preinitializ

protected override ObjectNodeSection GetDehydratedSection(NodeFactory factory)
{
if (_preinitializationManager.HasLazyStaticConstructor(_type)
if (HasCCtorContext
|| _preinitializationManager.IsPreinitialized(_type))
{
// We have data to be emitted so this needs to be in an initialized data section
Expand DownExpand Up@@ -63,7 +63,7 @@ int ISymbolDefinitionNode.Offset
get
{
// Make sure the NonGCStatics symbol always points to the beginning of the data.
if (_preinitializationManager.HasLazyStaticConstructor(_type))
if (HasCCtorContext)
{
return GetClassConstructorContextStorageSize(_type.Context.Target, _type);
}
Expand All@@ -74,7 +74,25 @@ int ISymbolDefinitionNode.Offset
}
}

public bool HasCCtorContext => _preinitializationManager.HasLazyStaticConstructor(_type);
public static bool TypeHasCctorContext(PreinitializationManager preinitializationManager, MetadataType type)
{
// If the type has a lazy static constructor, we need the cctor context.
if (preinitializationManager.HasLazyStaticConstructor(type))
return true;

// If the type has a canonical form and accessing the base from a canonical
// context requires a cctor check, we need the cctor context.
TypeDesc canonType = type.ConvertToCanonForm(CanonicalFormKind.Specific);
if (canonType != type && preinitializationManager.HasLazyStaticConstructor(canonType))
return true;

// Otherwise no cctor context needed.
return false;
}

public bool HasCCtorContext => TypeHasCctorContext(_preinitializationManager, _type);

public bool HasLazyStaticConstructor => _preinitializationManager.HasLazyStaticConstructor(_type);

public override bool IsShareable => EETypeNode.IsTypeNodeShareable(_type);

Expand DownExpand Up@@ -124,7 +142,7 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo

// If the type has a class constructor, its non-GC statics section is prefixed
// by System.Runtime.CompilerServices.StaticClassConstructionContext struct.
if (factory.PreinitializationManager.HasLazyStaticConstructor(_type))
if (HasCCtorContext)
{
int alignmentRequired = Math.Max(_type.NonGCStaticFieldAlignment.AsInt, GetClassConstructorContextAlignment(_type.Context.Target));
int classConstructorContextStorageSize = GetClassConstructorContextStorageSize(factory.Target, _type);
Expand All@@ -138,7 +156,24 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo
// Emit the actual StaticClassConstructionContext
MethodDesc cctorMethod = _type.GetStaticConstructor();
builder.EmitPointerReloc(factory.ExactCallableAddress(cctorMethod));
builder.EmitZeroPointer();

// If we're emitting the cctor context, but the type is actually preinitialized, emit the
// cctor context as already executed.
if (!HasLazyStaticConstructor)
{
// Constructor executed
// TODO-NICE: introduce a named constant and also use it in the runner in CoreLib
builder.EmitInt(1);
}
else
{
// Constructor didn't execute
builder.EmitInt(0);
}

// Emit padding if needed
if (builder.TargetPointerSize == 8)
builder.EmitInt(0);
}
else
{
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -107,7 +107,7 @@ protected sealed override void OnMarked(NodeFactory factory)
layout.EnsureEntry(_lookupSignature);

if ((_id == ReadyToRunHelperId.GetGCStaticBase || _id == ReadyToRunHelperId.GetThreadStaticBase) &&
factory.PreinitializationManager.HasLazyStaticConstructor((TypeDesc)_target))
TriggersLazyStaticConstructor(factory))
{
// If the type has a lazy static constructor, we also need the non-GC static base
// because that's where the class constructor context is.
Expand All@@ -116,6 +116,12 @@ protected sealed override void OnMarked(NodeFactory factory)
}
}

private bool TriggersLazyStaticConstructor(NodeFactory factory)
{
TypeDesc type = (TypeDesc)_target;
return factory.PreinitializationManager.HasLazyStaticConstructor(type.ConvertToCanonForm(CanonicalFormKind.Specific));
}

public IEnumerable<DependencyListEntry> InstantiateDependencies(NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation)
{
DependencyList result = new DependencyList();
Expand All@@ -129,13 +135,11 @@ public IEnumerable<DependencyListEntry> InstantiateDependencies(NodeFactory fact
{
// If the type has a lazy static constructor, we also need the non-GC static base
// because that's where the class constructor context is.
TypeDesc type = (TypeDesc)_target;

if (factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (TriggersLazyStaticConstructor(factory))
{
result.Add(
new DependencyListEntry(
factory.GenericLookup.TypeNonGCStaticBase(type).GetTarget(factory, lookupContext),
factory.GenericLookup.TypeNonGCStaticBase((TypeDesc)_target).GetTarget(factory, lookupContext),
"Dictionary dependency"));
}
}
Expand DownExpand Up@@ -250,7 +254,7 @@ public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDep
// a template dictionary node.
TypeDesc type = (TypeDesc)_target;
Debug.Assert(templateLayout != null);
if (factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (TriggersLazyStaticConstructor(factory))
{
GenericLookupResult nonGcRegionLookup = factory.GenericLookup.TypeNonGCStaticBase(type);
conditionalDependencies.Add(new CombinedDependencyListEntry(nonGcRegionLookup.TemplateDictionaryNode(factory),
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ public static void AddStaticsInfoDependencies(ref DependencyList dependencies, N
dependencies.Add(factory.TypeGCStaticsSymbol(metadataType), "GC statics indirection for StaticsInfoHashtable");
}

if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || NonGCStaticsNode.TypeHasCctorContext(factory.PreinitializationManager, metadataType))
{
// The entry in the StaticsInfoHashtable points at the beginning of the static fields data, rather than the cctor
// context offset.
Expand DownExpand Up@@ -98,7 +98,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
{
bag.AppendUnsigned(BagElementKind.GcStaticData, _nativeStaticsReferences.GetIndex(factory.TypeGCStaticsSymbol(metadataType)));
}
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || NonGCStaticsNode.TypeHasCctorContext(factory.PreinitializationManager, metadataType))
{
bag.AppendUnsigned(BagElementKind.NonGcStaticData, _nativeStaticsReferences.GetIndex(factory.TypeNonGCStaticsSymbol(metadataType)));
}
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -70,8 +70,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -99,7 +98,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco
encoder.EmitLDR(encoder.TargetRegister.Result, encoder.TargetRegister.Result);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -132,7 +131,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -81,8 +81,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -111,7 +110,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en
encoder.EmitLDR(encoder.TargetRegister.Result, encoder.TargetRegister.Result);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -144,7 +143,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -70,8 +70,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -100,7 +99,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit
encoder.EmitLD(encoder.TargetRegister.Result, encoder.TargetRegister.Result, 0);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -133,7 +132,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -82,9 +82,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
{
Debug.Assert(contextRegister == encoder.TargetRegister.Arg0);

MetadataType target = (MetadataType)_target;

if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);
encoder.EmitRET();
Expand DownExpand Up@@ -119,7 +117,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
AddrMode loadFromResult = new AddrMode(encoder.TargetRegister.Result, null, 0, 0, AddrModeSize.Int64);
encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromResult);

if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -153,7 +151,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -118,7 +118,7 @@ public CompilationBuilder UseDwarf5(bool value)
protected PreinitializationManager GetPreinitializationManager()
{
if (_preinitializationManager == null)
return new PreinitializationManager(_context, _compilationGroup, GetILProvider(), enableInterpreter: false);
return new PreinitializationManager(_context, _compilationGroup, GetILProvider(), new TypePreinit.DisabledPreinitializationPolicy());
return _preinitializationManager;
}

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -50,17 +50,10 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
Section nativeSection = nativeWriter.NewSection();
nativeSection.Place(hashtable);

foreach (TypeDesc type in factory.MetadataManager.GetTypesWithConstructedEETypes())
foreach (TypeDesc type in factory.MetadataManager.GetTypeTemplates())
{
if (!IsEligibleToHaveATemplate(type))
continue;

// Type's native layout info
NativeLayoutTemplateTypeLayoutVertexNode templateNode = factory.NativeLayout.TemplateTypeLayout(type);

// If this template isn't considered necessary, don't emit it.
if (!templateNode.Marked)
continue;
Vertex nativeLayout = templateNode.SavedVertex;

// Hashtable Entry
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -921,6 +921,8 @@ public sealed class NativeLayoutTemplateTypeLayoutVertexNode : NativeLayoutSaved
private TypeDesc _type;
private bool _isUniversalCanon;

public TypeDesc CanonType => _type.ConvertToCanonForm(CanonicalFormKind.Specific);

protected override string GetName(NodeFactory factory) => "NativeLayoutTemplateTypeLayoutVertexNode_" + factory.NameMangler.GetMangledTypeName(_type);

public NativeLayoutTemplateTypeLayoutVertexNode(NodeFactory factory, TypeDesc type)
Expand DownExpand Up@@ -989,7 +991,7 @@ public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFacto
}
}

if (context.PreinitializationManager.HasLazyStaticConstructor(_type))
if (context.PreinitializationManager.HasLazyStaticConstructor(_type.ConvertToCanonForm(CanonicalFormKind.Specific)))
{
yield return new DependencyListEntry(context.MethodEntrypoint(_type.GetStaticConstructor().GetCanonMethodTarget(CanonicalFormKind.Specific)), "cctor for template");
}
Expand DownExpand Up@@ -1188,7 +1190,7 @@ public override Vertex WriteVertex(NodeFactory factory)
layoutInfo.Append(BagElementKind.DictionaryLayout, dictionaryLayout.WriteVertex(factory));
}

if (factory.PreinitializationManager.HasLazyStaticConstructor(_type))
if (factory.PreinitializationManager.HasLazyStaticConstructor(_type.ConvertToCanonForm(CanonicalFormKind.Specific)))
{
MethodDesc cctorMethod = _type.GetStaticConstructor();
MethodDesc canonCctorMethod = cctorMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,7 +33,7 @@ public NonGCStaticsNode(MetadataType type, PreinitializationManager preinitializ

protected override ObjectNodeSection GetDehydratedSection(NodeFactory factory)
{
if (_preinitializationManager.HasLazyStaticConstructor(_type)
if (HasCCtorContext
|| _preinitializationManager.IsPreinitialized(_type))
{
// We have data to be emitted so this needs to be in an initialized data section
Expand DownExpand Up@@ -63,7 +63,7 @@ int ISymbolDefinitionNode.Offset
get
{
// Make sure the NonGCStatics symbol always points to the beginning of the data.
if (_preinitializationManager.HasLazyStaticConstructor(_type))
if (HasCCtorContext)
{
return GetClassConstructorContextStorageSize(_type.Context.Target, _type);
}
Expand All@@ -74,7 +74,25 @@ int ISymbolDefinitionNode.Offset
}
}

public bool HasCCtorContext => _preinitializationManager.HasLazyStaticConstructor(_type);
public static bool TypeHasCctorContext(PreinitializationManager preinitializationManager, MetadataType type)
{
// If the type has a lazy static constructor, we need the cctor context.
if (preinitializationManager.HasLazyStaticConstructor(type))
return true;

// If the type has a canonical form and accessing the base from a canonical
// context requires a cctor check, we need the cctor context.
TypeDesc canonType = type.ConvertToCanonForm(CanonicalFormKind.Specific);
if (canonType != type && preinitializationManager.HasLazyStaticConstructor(canonType))
return true;

// Otherwise no cctor context needed.
return false;
}

public bool HasCCtorContext => TypeHasCctorContext(_preinitializationManager, _type);

public bool HasLazyStaticConstructor => _preinitializationManager.HasLazyStaticConstructor(_type);

public override bool IsShareable => EETypeNode.IsTypeNodeShareable(_type);

Expand DownExpand Up@@ -124,7 +142,7 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo

// If the type has a class constructor, its non-GC statics section is prefixed
// by System.Runtime.CompilerServices.StaticClassConstructionContext struct.
if (factory.PreinitializationManager.HasLazyStaticConstructor(_type))
if (HasCCtorContext)
{
int alignmentRequired = Math.Max(_type.NonGCStaticFieldAlignment.AsInt, GetClassConstructorContextAlignment(_type.Context.Target));
int classConstructorContextStorageSize = GetClassConstructorContextStorageSize(factory.Target, _type);
Expand All@@ -138,7 +156,24 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo
// Emit the actual StaticClassConstructionContext
MethodDesc cctorMethod = _type.GetStaticConstructor();
builder.EmitPointerReloc(factory.ExactCallableAddress(cctorMethod));
builder.EmitZeroPointer();

// If we're emitting the cctor context, but the type is actually preinitialized, emit the
// cctor context as already executed.
if (!HasLazyStaticConstructor)
{
// Constructor executed
// TODO-NICE: introduce a named constant and also use it in the runner in CoreLib
builder.EmitInt(1);
}
else
{
// Constructor didn't execute
builder.EmitInt(0);
}

// Emit padding if needed
if (builder.TargetPointerSize == 8)
builder.EmitInt(0);
}
else
{
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -107,7 +107,7 @@ protected sealed override void OnMarked(NodeFactory factory)
layout.EnsureEntry(_lookupSignature);

if ((_id == ReadyToRunHelperId.GetGCStaticBase || _id == ReadyToRunHelperId.GetThreadStaticBase) &&
factory.PreinitializationManager.HasLazyStaticConstructor((TypeDesc)_target))
TriggersLazyStaticConstructor(factory))
{
// If the type has a lazy static constructor, we also need the non-GC static base
// because that's where the class constructor context is.
Expand All@@ -116,6 +116,12 @@ protected sealed override void OnMarked(NodeFactory factory)
}
}

private bool TriggersLazyStaticConstructor(NodeFactory factory)
{
TypeDesc type = (TypeDesc)_target;
return factory.PreinitializationManager.HasLazyStaticConstructor(type.ConvertToCanonForm(CanonicalFormKind.Specific));
}

public IEnumerable<DependencyListEntry> InstantiateDependencies(NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation)
{
DependencyList result = new DependencyList();
Expand All@@ -129,13 +135,11 @@ public IEnumerable<DependencyListEntry> InstantiateDependencies(NodeFactory fact
{
// If the type has a lazy static constructor, we also need the non-GC static base
// because that's where the class constructor context is.
TypeDesc type = (TypeDesc)_target;

if (factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (TriggersLazyStaticConstructor(factory))
{
result.Add(
new DependencyListEntry(
factory.GenericLookup.TypeNonGCStaticBase(type).GetTarget(factory, lookupContext),
factory.GenericLookup.TypeNonGCStaticBase((TypeDesc)_target).GetTarget(factory, lookupContext),
"Dictionary dependency"));
}
}
Expand DownExpand Up@@ -250,7 +254,7 @@ public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDep
// a template dictionary node.
TypeDesc type = (TypeDesc)_target;
Debug.Assert(templateLayout != null);
if (factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (TriggersLazyStaticConstructor(factory))
{
GenericLookupResult nonGcRegionLookup = factory.GenericLookup.TypeNonGCStaticBase(type);
conditionalDependencies.Add(new CombinedDependencyListEntry(nonGcRegionLookup.TemplateDictionaryNode(factory),
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ public static void AddStaticsInfoDependencies(ref DependencyList dependencies, N
dependencies.Add(factory.TypeGCStaticsSymbol(metadataType), "GC statics indirection for StaticsInfoHashtable");
}

if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || NonGCStaticsNode.TypeHasCctorContext(factory.PreinitializationManager, metadataType))
{
// The entry in the StaticsInfoHashtable points at the beginning of the static fields data, rather than the cctor
// context offset.
Expand DownExpand Up@@ -98,7 +98,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
{
bag.AppendUnsigned(BagElementKind.GcStaticData, _nativeStaticsReferences.GetIndex(factory.TypeGCStaticsSymbol(metadataType)));
}
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || NonGCStaticsNode.TypeHasCctorContext(factory.PreinitializationManager, metadataType))
{
bag.AppendUnsigned(BagElementKind.NonGcStaticData, _nativeStaticsReferences.GetIndex(factory.TypeNonGCStaticsSymbol(metadataType)));
}
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -70,8 +70,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -99,7 +98,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco
encoder.EmitLDR(encoder.TargetRegister.Result, encoder.TargetRegister.Result);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -132,7 +131,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -81,8 +81,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -111,7 +110,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en
encoder.EmitLDR(encoder.TargetRegister.Result, encoder.TargetRegister.Result);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -144,7 +143,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -70,8 +70,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -100,7 +99,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit
encoder.EmitLD(encoder.TargetRegister.Result, encoder.TargetRegister.Result, 0);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -133,7 +132,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -82,9 +82,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
{
Debug.Assert(contextRegister == encoder.TargetRegister.Arg0);

MetadataType target = (MetadataType)_target;

if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);
encoder.EmitRET();
Expand DownExpand Up@@ -119,7 +117,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
AddrMode loadFromResult = new AddrMode(encoder.TargetRegister.Result, null, 0, 0, AddrModeSize.Int64);
encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromResult);

if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -153,7 +151,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -118,7 +118,7 @@ public CompilationBuilder UseDwarf5(bool value)
protected PreinitializationManager GetPreinitializationManager()
{
if (_preinitializationManager == null)
return new PreinitializationManager(_context, _compilationGroup, GetILProvider(), enableInterpreter: false);
return new PreinitializationManager(_context, _compilationGroup, GetILProvider(), new TypePreinit.DisabledPreinitializationPolicy());
return _preinitializationManager;
}

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -50,17 +50,10 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
Section nativeSection = nativeWriter.NewSection();
nativeSection.Place(hashtable);

foreach (TypeDesc type in factory.MetadataManager.GetTypesWithConstructedEETypes())
foreach (TypeDesc type in factory.MetadataManager.GetTypeTemplates())
{
if (!IsEligibleToHaveATemplate(type))
continue;

// Type's native layout info
NativeLayoutTemplateTypeLayoutVertexNode templateNode = factory.NativeLayout.TemplateTypeLayout(type);

// If this template isn't considered necessary, don't emit it.
if (!templateNode.Marked)
continue;
Vertex nativeLayout = templateNode.SavedVertex;

// Hashtable Entry
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -921,6 +921,8 @@ public sealed class NativeLayoutTemplateTypeLayoutVertexNode : NativeLayoutSaved
private TypeDesc _type;
private bool _isUniversalCanon;

public TypeDesc CanonType => _type.ConvertToCanonForm(CanonicalFormKind.Specific);

protected override string GetName(NodeFactory factory) => "NativeLayoutTemplateTypeLayoutVertexNode_" + factory.NameMangler.GetMangledTypeName(_type);

public NativeLayoutTemplateTypeLayoutVertexNode(NodeFactory factory, TypeDesc type)
Expand DownExpand Up@@ -989,7 +991,7 @@ public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFacto
}
}

if (context.PreinitializationManager.HasLazyStaticConstructor(_type))
if (context.PreinitializationManager.HasLazyStaticConstructor(_type.ConvertToCanonForm(CanonicalFormKind.Specific)))
{
yield return new DependencyListEntry(context.MethodEntrypoint(_type.GetStaticConstructor().GetCanonMethodTarget(CanonicalFormKind.Specific)), "cctor for template");
}
Expand DownExpand Up@@ -1188,7 +1190,7 @@ public override Vertex WriteVertex(NodeFactory factory)
layoutInfo.Append(BagElementKind.DictionaryLayout, dictionaryLayout.WriteVertex(factory));
}

if (factory.PreinitializationManager.HasLazyStaticConstructor(_type))
if (factory.PreinitializationManager.HasLazyStaticConstructor(_type.ConvertToCanonForm(CanonicalFormKind.Specific)))
{
MethodDesc cctorMethod = _type.GetStaticConstructor();
MethodDesc canonCctorMethod = cctorMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,7 +33,7 @@ public NonGCStaticsNode(MetadataType type, PreinitializationManager preinitializ

protected override ObjectNodeSection GetDehydratedSection(NodeFactory factory)
{
if (_preinitializationManager.HasLazyStaticConstructor(_type)
if (HasCCtorContext
|| _preinitializationManager.IsPreinitialized(_type))
{
// We have data to be emitted so this needs to be in an initialized data section
Expand DownExpand Up@@ -63,7 +63,7 @@ int ISymbolDefinitionNode.Offset
get
{
// Make sure the NonGCStatics symbol always points to the beginning of the data.
if (_preinitializationManager.HasLazyStaticConstructor(_type))
if (HasCCtorContext)
{
return GetClassConstructorContextStorageSize(_type.Context.Target, _type);
}
Expand All@@ -74,7 +74,25 @@ int ISymbolDefinitionNode.Offset
}
}

public bool HasCCtorContext => _preinitializationManager.HasLazyStaticConstructor(_type);
public static bool TypeHasCctorContext(PreinitializationManager preinitializationManager, MetadataType type)
{
// If the type has a lazy static constructor, we need the cctor context.
if (preinitializationManager.HasLazyStaticConstructor(type))
return true;

// If the type has a canonical form and accessing the base from a canonical
// context requires a cctor check, we need the cctor context.
TypeDesc canonType = type.ConvertToCanonForm(CanonicalFormKind.Specific);
if (canonType != type && preinitializationManager.HasLazyStaticConstructor(canonType))
return true;

// Otherwise no cctor context needed.
return false;
}

public bool HasCCtorContext => TypeHasCctorContext(_preinitializationManager, _type);

public bool HasLazyStaticConstructor => _preinitializationManager.HasLazyStaticConstructor(_type);

public override bool IsShareable => EETypeNode.IsTypeNodeShareable(_type);

Expand DownExpand Up@@ -124,7 +142,7 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo

// If the type has a class constructor, its non-GC statics section is prefixed
// by System.Runtime.CompilerServices.StaticClassConstructionContext struct.
if (factory.PreinitializationManager.HasLazyStaticConstructor(_type))
if (HasCCtorContext)
{
int alignmentRequired = Math.Max(_type.NonGCStaticFieldAlignment.AsInt, GetClassConstructorContextAlignment(_type.Context.Target));
int classConstructorContextStorageSize = GetClassConstructorContextStorageSize(factory.Target, _type);
Expand All@@ -138,7 +156,24 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo
// Emit the actual StaticClassConstructionContext
MethodDesc cctorMethod = _type.GetStaticConstructor();
builder.EmitPointerReloc(factory.ExactCallableAddress(cctorMethod));
builder.EmitZeroPointer();

// If we're emitting the cctor context, but the type is actually preinitialized, emit the
// cctor context as already executed.
if (!HasLazyStaticConstructor)
{
// Constructor executed
// TODO-NICE: introduce a named constant and also use it in the runner in CoreLib
builder.EmitInt(1);
}
else
{
// Constructor didn't execute
builder.EmitInt(0);
}

// Emit padding if needed
if (builder.TargetPointerSize == 8)
builder.EmitInt(0);
}
else
{
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -107,7 +107,7 @@ protected sealed override void OnMarked(NodeFactory factory)
layout.EnsureEntry(_lookupSignature);

if ((_id == ReadyToRunHelperId.GetGCStaticBase || _id == ReadyToRunHelperId.GetThreadStaticBase) &&
factory.PreinitializationManager.HasLazyStaticConstructor((TypeDesc)_target))
TriggersLazyStaticConstructor(factory))
{
// If the type has a lazy static constructor, we also need the non-GC static base
// because that's where the class constructor context is.
Expand All@@ -116,6 +116,12 @@ protected sealed override void OnMarked(NodeFactory factory)
}
}

private bool TriggersLazyStaticConstructor(NodeFactory factory)
{
TypeDesc type = (TypeDesc)_target;
return factory.PreinitializationManager.HasLazyStaticConstructor(type.ConvertToCanonForm(CanonicalFormKind.Specific));
}

public IEnumerable<DependencyListEntry> InstantiateDependencies(NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation)
{
DependencyList result = new DependencyList();
Expand All@@ -129,13 +135,11 @@ public IEnumerable<DependencyListEntry> InstantiateDependencies(NodeFactory fact
{
// If the type has a lazy static constructor, we also need the non-GC static base
// because that's where the class constructor context is.
TypeDesc type = (TypeDesc)_target;

if (factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (TriggersLazyStaticConstructor(factory))
{
result.Add(
new DependencyListEntry(
factory.GenericLookup.TypeNonGCStaticBase(type).GetTarget(factory, lookupContext),
factory.GenericLookup.TypeNonGCStaticBase((TypeDesc)_target).GetTarget(factory, lookupContext),
"Dictionary dependency"));
}
}
Expand DownExpand Up@@ -250,7 +254,7 @@ public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDep
// a template dictionary node.
TypeDesc type = (TypeDesc)_target;
Debug.Assert(templateLayout != null);
if (factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (TriggersLazyStaticConstructor(factory))
{
GenericLookupResult nonGcRegionLookup = factory.GenericLookup.TypeNonGCStaticBase(type);
conditionalDependencies.Add(new CombinedDependencyListEntry(nonGcRegionLookup.TemplateDictionaryNode(factory),
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ public static void AddStaticsInfoDependencies(ref DependencyList dependencies, N
dependencies.Add(factory.TypeGCStaticsSymbol(metadataType), "GC statics indirection for StaticsInfoHashtable");
}

if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || NonGCStaticsNode.TypeHasCctorContext(factory.PreinitializationManager, metadataType))
{
// The entry in the StaticsInfoHashtable points at the beginning of the static fields data, rather than the cctor
// context offset.
Expand DownExpand Up@@ -98,7 +98,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
{
bag.AppendUnsigned(BagElementKind.GcStaticData, _nativeStaticsReferences.GetIndex(factory.TypeGCStaticsSymbol(metadataType)));
}
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.PreinitializationManager.HasLazyStaticConstructor(type))
if (metadataType.NonGCStaticFieldSize.AsInt > 0 || NonGCStaticsNode.TypeHasCctorContext(factory.PreinitializationManager, metadataType))
{
bag.AppendUnsigned(BagElementKind.NonGcStaticData, _nativeStaticsReferences.GetIndex(factory.TypeNonGCStaticsSymbol(metadataType)));
}
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -70,8 +70,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -99,7 +98,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco
encoder.EmitLDR(encoder.TargetRegister.Result, encoder.TargetRegister.Result);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -132,7 +131,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -81,8 +81,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -111,7 +110,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en
encoder.EmitLDR(encoder.TargetRegister.Result, encoder.TargetRegister.Result);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -144,7 +143,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -70,8 +70,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit

EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -100,7 +99,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit
encoder.EmitLD(encoder.TargetRegister.Result, encoder.TargetRegister.Result, 0);

MetadataType target = (MetadataType)_target;
if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -133,7 +132,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref LoongArch64Emit
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -82,9 +82,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
{
Debug.Assert(contextRegister == encoder.TargetRegister.Arg0);

MetadataType target = (MetadataType)_target;

if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Result, _lookupSignature, relocsOnly);
encoder.EmitRET();
Expand DownExpand Up@@ -119,7 +117,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
AddrMode loadFromResult = new AddrMode(encoder.TargetRegister.Result, null, 0, 0, AddrModeSize.Int64);
encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromResult);

if (!factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (!TriggersLazyStaticConstructor(factory))
{
encoder.EmitRET();
}
Expand DownExpand Up@@ -153,7 +151,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref X64Emitter enco
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg0, encoder.TargetRegister.Arg1, _lookupSignature, relocsOnly);

ISymbolNode helperEntrypoint;
if (factory.PreinitializationManager.HasLazyStaticConstructor(target))
if (TriggersLazyStaticConstructor(factory))
{
// There is a lazy class constructor. We need the non-GC static base because that's where the
// class constructor context lives.
Expand Down
Loading