Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove the concept of packable fields from EEClass #96699

Merged
Show file tree
Hide file tree
Changes from 5 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
4 changes: 2 additions & 2 deletions src/coreclr/vm/array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,9 +307,9 @@ MethodTable* Module::CreateArrayMethodTable(TypeHandle elemTypeHnd, CorElementTy

if (pCanonMT == NULL)
{
// Allocate ArrayClass (including space for packed fields), MethodTable, and class name in one alloc.
// Allocate ArrayClass, MethodTable, and class name in one alloc.
// Remember to pad allocation size for ArrayClass portion to ensure MethodTable is pointer aligned.
cbArrayClass = ALIGN_UP(sizeof(ArrayClass) + sizeof(EEClassPackedFields), sizeof(void*));
cbArrayClass = ALIGN_UP(sizeof(ArrayClass), sizeof(void*));
}

// ArrayClass already includes one void*
Expand Down
70 changes: 2 additions & 68 deletions src/coreclr/vm/class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,6 @@
#ifndef DACCESS_COMPILE


//*******************************************************************************
EEClass::EEClass(DWORD cbFixedEEClassFields)
{
LIMITED_METHOD_CONTRACT;

// Cache size of fixed fields (this instance also contains a set of packed fields whose final size isn't
// determined until the end of class loading). We store the size into a spare byte made available by
// compiler field alignment, so we need to ensure we never allocate a flavor of EEClass more than 255
// bytes long.
_ASSERTE(cbFixedEEClassFields <= 0xff);
m_cbFixedEEClassFields = (BYTE)cbFixedEEClassFields;

// All other members are initialized to zero
}

//*******************************************************************************
void *EEClass::operator new(
Expand All @@ -59,12 +45,7 @@ void *EEClass::operator new(
}
CONTRACTL_END;

// EEClass (or sub-type) is always followed immediately by an EEClassPackedFields structure. This is
// maximally sized at runtime but in the ngen scenario will be optimized into a smaller structure (which
// is why it must go after all the fixed sized fields).
S_SIZE_T safeSize = S_SIZE_T(size) + S_SIZE_T(sizeof(EEClassPackedFields));

void *p = pamTracker->Track(pHeap->AllocMem(safeSize));
void *p = pamTracker->Track(pHeap->AllocMem(S_SIZE_T(size)));

// No need to memset since this memory came from VirtualAlloc'ed memory
// memset (p, 0, size);
Expand Down Expand Up @@ -209,7 +190,7 @@ EEClass::CreateMinimalClass(LoaderHeap *pHeap, AllocMemTracker *pamTracker)
}
CONTRACTL_END;

return new (pHeap, pamTracker) EEClass(sizeof(EEClass));
return new (pHeap, pamTracker) EEClass();
Copy link
Member

Choose a reason for hiding this comment

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

Does CreateMinimalClass still make sense as a separate helper now that 'minimal' is just normal?

Copy link
Member Author

Choose a reason for hiding this comment

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

We still want to allocate using the LoaderHeap as that is what controls object lifetime. We have no mechanism in place to run delete and free memory for these piecemeal.

}


Expand Down Expand Up @@ -3282,11 +3263,6 @@ EEClass::EnumMemoryRegions(CLRDataEnumMemoryFlags flags, MethodTable * pMT)
DAC_ENUM_DTHIS();
EMEM_OUT(("MEM: %p EEClass\n", dac_cast<TADDR>(this)));

// The DAC_ENUM_DTHIS above won't have reported the packed fields tacked on the end of this instance (they
// aren't part of the static class definition because the fields are variably sized and thus have to come
// right at the end of the structure, even for sub-types such as LayoutEEClass or DelegateEEClass).
DacEnumMemoryRegion(dac_cast<TADDR>(GetPackedFields()), sizeof(EEClassPackedFields));

if (HasOptionalFields())
DacEnumMemoryRegion(dac_cast<TADDR>(GetOptionalFields()), sizeof(EEClassOptionalFields));

Expand Down Expand Up @@ -3319,45 +3295,3 @@ EEClass::EnumMemoryRegions(CLRDataEnumMemoryFlags flags, MethodTable * pMT)

#endif // DACCESS_COMPILE

// Get pointer to the packed fields structure attached to this instance.
PTR_EEClassPackedFields EEClass::GetPackedFields()
{
LIMITED_METHOD_DAC_CONTRACT;

return dac_cast<PTR_EEClassPackedFields>(PTR_HOST_TO_TADDR(this) + m_cbFixedEEClassFields);
}

// Get the value of the given field. Works regardless of whether the field is currently in its packed or
// unpacked state.
DWORD EEClass::GetPackableField(EEClassFieldId eField)
{
CONTRACTL
{
NOTHROW;
GC_NOTRIGGER;
MODE_ANY;
SUPPORTS_DAC;
}
CONTRACTL_END;

return m_fFieldsArePacked ?
GetPackedFields()->GetPackedField(eField) :
GetPackedFields()->GetUnpackedField(eField);
}

// Set the value of the given field. The field *must* be in the unpacked state for this to be legal (in
// practice all packable fields must be initialized during class construction and from then on remain
// immutable).
void EEClass::SetPackableField(EEClassFieldId eField, DWORD dwValue)
{
CONTRACTL
{
NOTHROW;
GC_NOTRIGGER;
MODE_ANY;
}
CONTRACTL_END;

_ASSERTE(!m_fFieldsArePacked);
GetPackedFields()->SetUnpackedField(eField, dwValue);
}
Loading
Loading