Permalink
Browse files

Add objheader_common.h that contains SIZEOF_OBJHEADER and can be used…

… from eveywhere (as it was previously not accessible from JIT for example). Always use a 8 bytes ObjHeader and add extra bits for Class Allocated on stack. Update codegen to identity allocation on the stack.
  • Loading branch information...
xoofx committed Oct 2, 2015
1 parent 92252c1 commit 265453c4fd26e83ee957952fd442f58524bf76a2
Showing with 40 additions and 59 deletions.
  1. +1 −4 src/ToolBox/SOS/Strike/strike.h
  2. +19 −0 src/inc/objheader_common.h
  3. +4 −0 src/jit/codegencommon.cpp
  4. +4 −5 src/jit/lclvars.cpp
  5. +2 −2 src/vm/object.h
  6. +0 −15 src/vm/syncblk.cpp
  7. +10 −33 src/vm/syncblk.h
@@ -102,11 +102,8 @@
//The large object heap uses a different alignment
#define ALIGNCONSTLARGE 7

#ifdef _WIN64
// ClassAsValue: We use now 8 bytes for the object header by default
#define SIZEOF_OBJHEADER 8
#else // !_WIN64
#define SIZEOF_OBJHEADER 4
#endif // !_WIN64

#define plug_skew SIZEOF_OBJHEADER
#define min_obj_size (sizeof(BYTE*)+plug_skew+sizeof(size_t))
@@ -0,0 +1,19 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

#ifndef OBJHEADER_COMMON_H_
#define OBJHEADER_COMMON_H_

// The GC is highly dependent on SIZE_OF_OBJHEADER being exactly the sizeof(ObjHeader)
// We define this macro so that the preprocessor can calculate padding structures.
// ClassAsValue: We use now 8 bytes for the object header by default
#define SIZEOF_OBJHEADER 8

// ClassAsVaue: Extra bits to handle identity allocated object on the stack
#define BIT_OBJHEADER_STACK_ALLOCATED 0x00000001
#define BIT_OBJHEADER_EMBED_ALLOCATED 0x00000002
#define BIT_OBJHEADER_EMBED_OFFSET_MASK 0xFFFFFFFC

#endif
@@ -22,6 +22,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#endif
#include "codegen.h"

#include "objheader_common.h"
#include "gcinfo.h"
#include "emit.h"

@@ -6480,6 +6481,9 @@ void CodeGen::genZeroInitFrame(int untrLclHi,
/* lea eax, [MethodTable]*/
getEmitter()->emitIns_R_AI(INS_lea, EA_PTRSIZE, initReg, (ssize_t)(varDsc->lvReferenceTypeMethodTable));

/* mov DWORD [ebp - stackoffs - sizeof(ObjHeader)], 1 */
getEmitter()->emitIns_I_ARR(INS_mov, EA_4BYTE, BIT_OBJHEADER_STACK_ALLOCATED, genFramePointerReg(), REG_NA, varDsc->lvStkOffs - SIZEOF_OBJHEADER);

/* mov [ebp - stackoffs], eax */
getEmitter()->emitIns_AR_R(ins_Store(TYP_I_IMPL),
EA_PTRSIZE,
@@ -14,6 +14,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*/

#include "objheader_common.h"
#include "jitpch.h"
#ifdef _MSC_VER
#pragma hdrstop
@@ -4898,13 +4899,11 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
// Reserve the stack space for this variable
stkOffs = lvaAllocLocalAndSetVirtualOffset(lclNum, lvaLclSize(lclNum), stkOffs);

// ClassAsValue: If we have a reference type allocated on the stack, add a bit
// more space for the object header
// TODO: we should calculate the real space of the object header (OBJHEADER)
// ClassAsValue: If we have a reference type allocated on the stack, prefix by the ObjHeader
if (lvaTable[lclNum].lvType == TYP_STRUCT && lvaTable[lclNum].IsReferenceType())
{
lvaIncrementFrameSize(TARGET_POINTER_SIZE);
stkOffs -= TARGET_POINTER_SIZE;
lvaIncrementFrameSize(SIZEOF_OBJHEADER);
stkOffs -= SIZEOF_OBJHEADER;
}
}
}
@@ -280,10 +280,10 @@ class Object

// Access the ObjHeader which is at a negative offset on the object (because of
// cache lines)
PTR_ObjHeader GetHeader()
PTR_ObjHeader GetHeader() const
{
LIMITED_METHOD_DAC_CONTRACT;
return dac_cast<PTR_ObjHeader>(this) - 1;
return dac_cast<PTR_ObjHeader>((char*)this - sizeof(ObjHeader));
}

// Get the current address of the object (works for debug refs, too.)
@@ -3647,18 +3647,3 @@ void SyncBlock::SetEnCInfo(EnCSyncBlockInfo *pEnCInfo)
}
#endif // EnC_SUPPORTED
#endif // !DACCESS_COMPILE

#if defined(_WIN64) && defined(_DEBUG)
void ObjHeader::IllegalAlignPad()
{
WRAPPER_NO_CONTRACT;
#ifdef LOGGING
void** object = ((void**) this) + 1;
LogSpewAlways("\n\n******** Illegal ObjHeader m_alignpad not 0, object" FMT_ADDR "\n\n",
DBG_ADDR(object));
#endif
_ASSERTE(m_alignpad == 0);
}
#endif // _WIN64 && _DEBUG


@@ -79,14 +79,14 @@ class EnCSyncBlockInfo;
typedef DPTR(EnCSyncBlockInfo) PTR_EnCSyncBlockInfo;

#endif // EnC_SUPPORTED
#include "objheader_common.h"

#include "eventstore.hpp"

#include "eventstore.hpp"

#include "synch.h"


// At a negative offset from each Object is an ObjHeader. The 'size' of the
// object includes these bytes. However, we rely on the previous object allocation
// to zero out the ObjHeader for the current allocation. And the limits of the
@@ -149,15 +149,6 @@ typedef DPTR(EnCSyncBlockInfo) PTR_EnCSyncBlockInfo;
// Spin for about 1000 cycles before waiting longer.
#define BIT_SBLK_SPIN_COUNT 1000

// The GC is highly dependent on SIZE_OF_OBJHEADER being exactly the sizeof(ObjHeader)
// We define this macro so that the preprocessor can calculate padding structures.
#ifdef _WIN64
#define SIZEOF_OBJHEADER 8
#else // !_WIN64
#define SIZEOF_OBJHEADER 4
#endif // !_WIN64


inline void InitializeSpinConstants()
{
WRAPPER_NO_CONTRACT;
@@ -1069,16 +1060,10 @@ class ObjHeader
friend class CheckAsmOffsets;

private:
// !!! Notice: m_SyncBlockValue *MUST* be the last field in ObjHeader.
#ifdef _WIN64
DWORD m_alignpad;
#endif // _WIN64

Volatile<DWORD> m_SyncBlockValue; // the Index and the Bits

#if defined(_WIN64) && defined(_DEBUG)
void IllegalAlignPad();
#endif // _WIN64 && _DEBUG
// ClassAsValue: bits to store ClassAsValue information (allocated on the stack or embed object, reference to parent...)
DWORD m_extraGCBits;
// !!! Notice: m_SyncBlockValue *MUST* be the last field in ObjHeader.
Volatile<DWORD> m_SyncBlockValue; // the Index and the Bits

INCONTRACT(void * GetPtrForLockContract());

@@ -1088,12 +1073,6 @@ class ObjHeader
FORCEINLINE DWORD GetHeaderSyncBlockIndex()
{
LIMITED_METHOD_DAC_CONTRACT;
#if defined(_WIN64) && defined(_DEBUG) && !defined(DACCESS_COMPILE)
// On WIN64 this field is never modified, but was initialized to 0
if (m_alignpad != 0)
IllegalAlignPad();
#endif // _WIN64 && _DEBUG && !DACCESS_COMPILE

// pull the value out before checking it to avoid race condition
DWORD value = m_SyncBlockValue.LoadWithoutBarrier();
if ((value & (BIT_SBLK_IS_HASH_OR_SYNCBLKINDEX | BIT_SBLK_IS_HASHCODE)) != BIT_SBLK_IS_HASH_OR_SYNCBLKINDEX)
@@ -1212,16 +1191,14 @@ class ObjHeader
{
LIMITED_METHOD_CONTRACT;
SUPPORTS_DAC;

#if defined(_WIN64) && defined(_DEBUG) && !defined(DACCESS_COMPILE)
// On WIN64 this field is never modified, but was initialized to 0
if (m_alignpad != 0)
IllegalAlignPad();
#endif // _WIN64 && _DEBUG && !DACCESS_COMPILE

return m_SyncBlockValue.LoadWithoutBarrier();
}

// returns extra bits
DWORD GetExtraBits()
{
return m_extraGCBits;
}

DWORD SetBits(DWORD newBits, DWORD oldBits)
{

0 comments on commit 265453c

Please sign in to comment.