protected virtual void EmitDataInternal(ref ObjectDataBuilder builder, NodeFactory factory) { DictionaryLayoutNode layout = GetDictionaryLayout(factory); Instantiation typeInst = this.TypeInstantiation; Instantiation methodInst = this.MethodInstantiation; foreach (var entry in layout.Entries) { ISymbolNode targetNode = entry.GetTarget(factory, typeInst, methodInst); builder.EmitPointerReloc(targetNode); } }
protected override void OnMarked(NodeFactory factory) { // Commit all floating generic lookups associated with the method when the method // is proved not dead. if (_floatingGenericLookupResults != null) { Debug.Assert(_method.IsCanonicalMethod(CanonicalFormKind.Any)); TypeSystemEntity canonicalOwner = _method.HasInstantiation ? (TypeSystemEntity)_method : (TypeSystemEntity)_method.OwningType; DictionaryLayoutNode dictLayout = factory.GenericDictionaryLayout(canonicalOwner); foreach (var lookupResult in _floatingGenericLookupResults) { dictLayout.EnsureEntry(lookupResult); } } }
protected sealed override void OnMarked(NodeFactory factory) { DictionaryLayoutNode layout = factory.GenericDictionaryLayout(_dictionaryOwner); if (layout.HasUnfixedSlots) { // When the helper call gets marked, ensure the generic layout for the associated dictionaries // includes the signature. layout.EnsureEntry(_lookupSignature); if ((_id == ReadyToRunHelperId.GetGCStaticBase || _id == ReadyToRunHelperId.GetThreadStaticBase) && factory.TypeSystemContext.HasLazyStaticConstructor((TypeDesc)_target)) { // 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. layout.EnsureEntry(factory.GenericLookup.TypeNonGCStaticBase((TypeDesc)_target)); } } }
protected virtual void EmitDataInternal(ref ObjectDataBuilder builder, NodeFactory factory) { DictionaryLayoutNode layout = GetDictionaryLayout(factory); Instantiation typeInst = this.TypeInstantiation; Instantiation methodInst = this.MethodInstantiation; foreach (GenericLookupResult lookupResult in layout.Entries) { #if DEBUG int offsetBefore = builder.CountBytes; #endif lookupResult.EmitDictionaryEntry(ref builder, factory, typeInst, methodInst, this); #if DEBUG Debug.Assert(builder.CountBytes - offsetBefore == factory.Target.PointerSize); #endif } }
public sealed override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly); builder.AddSymbol(this); builder.RequireInitialPointerAlignment(); DictionaryLayoutNode layout = GetDictionaryLayout(factory); // Node representing the generic dictionary layout might be one of two kinds: // With fixed slots, or where slots are added as we're expanding the graph. // If it's the latter, we can't touch the collection of slots before the graph expansion // is complete (relocsOnly == false). It's someone else's responsibility // to make sure the dependencies are properly generated. // If this is a dictionary layout with fixed slots, it's the responsibility of // each dictionary to ensure the targets are marked. if (layout.HasFixedSlots || !relocsOnly) { // TODO: pass the layout we already have to EmitDataInternal EmitDataInternal(ref builder, factory, relocsOnly); } return(builder.ToObjectData()); }
protected virtual void EmitDataInternal(ref ObjectDataBuilder builder, NodeFactory factory, bool fixedLayoutOnly) { DictionaryLayoutNode layout = GetDictionaryLayout(factory); layout.EmitDictionaryData(ref builder, factory, this, fixedLayoutOnly: fixedLayoutOnly); }