Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Replace some sizeof-s with target specific constants #18245

Merged
merged 5 commits into from Jun 4, 2018
Merged

Replace some sizeof-s with target specific constants #18245

merged 5 commits into from Jun 4, 2018

Conversation

echesakov
Copy link

@echesakov echesakov commented Jun 1, 2018

The goal of this PR is to identify all places in VM using sizeof operator that should be made target-specific in order to support cross-bitness scenario #16513. The proposal is to introduce CrossBitness_SizeOf operator to make such places explicit.

CrossBitness_SizeOf operator satisfies the following conditions:

  1. CrossBitness_SizeOf(X) == sizeof(X) in non-crossbitness scenarios;
  2. CrossBitness_SizeOf(X) == sizeof(Y) where Y is a "fake" structure created to describe layout of X on the target platform in crossbitness scenarios (i.e. x64_arm). Note that usually sizeof(X) != sizeof(Y).

It's been proven experimentally that this subset of changes is needed in order to get outputs of x64_arm and arm_arm crossgens to be binary identical for S.P.C.dll and CoreFx assemblies.

This PR also includes other related changes:

  1. LOG2_PTRSIZE should depend on _TARGET_64BIT_;
  2. more careful pointer arithmetic in FakePromote and ReportPointersFromValueType.

This PR is to initiate design discussion (at alternatives discussion) and not a final work.

Update: the final solution is to replace identified sizeof expressions with target-specifics constants

@jkotas PTAL

@echesakov echesakov added area-VM Design Discussion Ongoing discussion about design without consensus labels Jun 1, 2018
@@ -2139,7 +2139,7 @@ void Module::BuildStaticsOffsets(AllocMemTracker *pamTracker)
(S_SIZE_T(2 * sizeof(DWORD))*(S_SIZE_T(dwNumTypes)+S_SIZE_T(1)))));

for (DWORD i = 0; i < dwIndex; i++) {
pRegularStaticOffsets[i * 2 ] = dwGCHandles[0]*sizeof(OBJECTREF);
Copy link
Member

Choose a reason for hiding this comment

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

sizeof(OBJECTREF) can be just TARGET_POINTER_SIZE. We use TARGET_POINTER_SIZE for object reference sizes in many places already, so a few more are not a concern.

Copy link
Author

Choose a reason for hiding this comment

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

Sure, I will replace with TARGET_POINTER_SIZE instead

#endif // _TARGET_64BIT_
};

struct StringObject : public Object
Copy link
Member

Choose a reason for hiding this comment

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

I do not see this used.

Copy link
Member

Choose a reason for hiding this comment

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

I guess it was needed before #17876

Copy link
Author

@echesakov echesakov Jun 2, 2018

Choose a reason for hiding this comment

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

Yes, you're right. It was needed before for ObjSizeOf(StringObject) in StringObject::GetSize.

#ifndef CROSSBITNESS_H
#define CROSSBITNESS_H

struct CrossBitness
Copy link
Member

Choose a reason for hiding this comment

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

I would rather use explicitly manually defined sizes than trust the C++ compiler that it is going to layout the structures the way we expect.

Building upon approach I took in https://github.com/dotnet/coreclr/pull/17876/files .

Copy link
Author

@echesakov echesakov Jun 2, 2018

Choose a reason for hiding this comment

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

@jkotas I also though about this alternative. But then I would also need to replace all ObjSizeOf(Object) and ObjSizeOf(ArrayBase) expressions with some constants as well.

Is any standard name for sizeof(Object) + sizeof(ObjHeader)?

@jkotas
Copy link
Member

jkotas commented Jun 2, 2018

sizeof(Object) + sizeof(ObjHeader)

I would call it OBJECT_BASE_SIZE.

@jkotas
Copy link
Member

jkotas commented Jun 2, 2018

Or Object::GetBaseSize()

@jkotas
Copy link
Member

jkotas commented Jun 2, 2018

BTW: How far do you think you are right now - are there things that you have working locally?

@echesakov
Copy link
Author

@jkotas The x64_arm crossgen version in https://github.com/echesakovMSFT/coreclr/tree/CrossCrossGen compiles and runs (at least on Windows) and I can crossgen S.P.C.dll and all CoreFx assemblies

@echesakov
Copy link
Author

@jkotas Regarding placements such constants - would asmconstants.h be appropriate file? Or I can keep them in crossbitness.h (for 32 and 64 bit targets) ?

@jkotas
Copy link
Member

jkotas commented Jun 2, 2018

asmconstants.h is per architecture, so it would need to be duplicated.

I would probably just add them at the top of object.h before MIN_OBJECT_SIZE, something like:

#define OBJHEADER_SIZE      TARGET_POINTER_SIZE /* ObjHeader */

#define OBJECT_SIZE         TARGET_POINTER_SIZE /* MethodTable* */
#define OBJECT_BASESIZE     (OBJHEADER_SIZE + OBJECT_SIZE)

#define ARRAYBASE_SIZE      (OBJECT_SIZE /* PTR_MethodTable */ + TARGET_POINTER_SIZE /* _numComponents + pad */)
#define ARRAYBASE_BASESIZE  (OBJHEADER_SIZE + ARRAYBASE_SIZE)

#define MIN_OBJECT_SIZE     (2*TARGET_POINTER_SIZE + OBJHEADER_SIZE)

@@ -257,7 +257,7 @@ inline /* static */ unsigned ArrayBase::GetBoundsOffset(MethodTable* pMT)
if (!pMT->IsMultiDimArray())
return(offsetof(ArrayBase, m_NumComponents));
_ASSERTE(pMT->GetInternalCorElementType() == ELEMENT_TYPE_ARRAY);
Copy link
Member

Choose a reason for hiding this comment

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

You can also fix offsetof(ArrayBase, m_NumComponents) a few lines above while you are on it. Replace it with OBJECT_SIZE /* offset(ArrayBase, m_NumComponents */ ?

Copy link
Author

Choose a reason for hiding this comment

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

Done. Thanks for catching this

@echesakov
Copy link
Author

After I replaced ObjSizeOf and CrossBitness_SizeOf with predefined constants I think next logical step should be adding some kind of checking (either at compile time or running time) that the values of these constants stay valid. For example,

C_ASSERT(sizeof(ObjHeader) == OBJHEADER_SIZE);
C_ASSERT(sizeof(Object) == OBJECT_SIZE);

However, such assertions would be valid only for non-crossbitness scenarios (so I can limit them to such scenarois only with ifdefs).

@jkotas What do you think?

@jkotas
Copy link
Member

jkotas commented Jun 2, 2018

You can add these static asserts somewhere if you would like.

I am not really concerned about these particular constants. This is unlikely to change; and if it does change and the constants get out of sync by accident, it will be easy to notice because of nothing will work.

* OBJHEADER_SIZE
* OBJECT_SIZE
* OBJECT_BASESIZE
* ARRAYBASE_SIZE
* ARRAYBASE_BASESIZE

and use them instead of corresponding expressions

* sizeof(ObjHeader)
* sizeof(Object)
* ObjSizeOf(Object)
* sizeof(ArrayBase)
* ObjSizeOf(ArrayBase)
@echesakov
Copy link
Author

echesakov commented Jun 3, 2018

@jkotas Agree, this assertions would not be that helpful. I rebased and squashed some commits and wait for green ci. Thanks for the help!

@echesakov echesakov changed the title [WIP] Introduce CrossBitness_SizeOf operator to support CrossBitness CrossGen Replace some sizeof-s with target specific constants Jun 3, 2018
@echesakov echesakov removed the Design Discussion Ongoing discussion about design without consensus label Jun 3, 2018
@echesakov echesakov merged commit de58676 into dotnet:master Jun 4, 2018
@echesakov echesakov deleted the CrossBitnessSizeOf branch June 4, 2018 17:08
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
* Replace sizeof expressions with target-specific constants:

* sizeof(ObjHeader) -> OBJHEADER_SIZE
* sizeof(Object) -> OBJECT_SIZE
* ObjSizeOf(Object) -> OBJECT_BASESIZE
* sizeof(ArrayBase) -> ARRAYBASE_SIZE
* ObjSizeOf(ArrayBase) -> ARRAYBASE_BASESIZE

* Remove ObjSizeOf macro

* Use OBJECT_SIZE in ArrayBase::GetBoundsOffset

* Cast ppObj to CORCOMPILE_GCREFMAP_TOKENS* before dereferencing in FakePromote

* LOG2_PTRSIZE should depend on _TARGET_64BIT_

Commit migrated from dotnet/coreclr@de58676
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
2 participants