Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
463 changes: 0 additions & 463 deletions src/coreclr/inc/bitvector.h

This file was deleted.

1 change: 0 additions & 1 deletion src/coreclr/inc/eetwain.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
#include "regdisp.h"
#include "corjit.h" // For NativeVarInfo
#include "stackwalktypes.h"
#include "bitvector.h"
#include "gcinfotypes.h"

#if !defined(TARGET_X86)
Expand Down
291 changes: 287 additions & 4 deletions src/coreclr/inc/gc_unwind_x86.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ enum regNum
REGI_NA = REGI_COUNT
};

/*****************************************************************************
Register masks
*/

enum RegMask
{
RM_EAX = 0x01,
Expand All @@ -47,6 +43,293 @@ enum RegMask
RM_CALLEE_TRASHED = (RM_ALL & ~RM_CALLEE_SAVED),
};

#define CONSTRUCT_ptrArgTP(arg,shift) ptrArgTP((arg), (shift))

// Bit vector structure that can hold MAX_PTRARG_OFS bits and efficiently
// handle small vectors.
class ptrArgTP
{
typedef UINT_PTR ChunkType; // The size of integer type that the machine can operate on directly

enum
{
IS_BIG = 1, // The low bit is used to discrimate m_val and m_vals
CHUNK_BITS = sizeof(ChunkType)*8, // The number of bits that we can manipuate as a chunk
SMALL_BITS = CHUNK_BITS - 1, // The number of bits we can fit in the small representation
VALS_COUNT = MAX_PTRARG_OFS / CHUNK_BITS, // The number of ChunkType elements in the Vals array
};

static const ChunkType MaxVal = ((ChunkType)1 << SMALL_BITS) - 1; // Maximum value that can be stored in m_val

struct Vals
{
unsigned m_encodedLength; // An encoding of the current length of the 'm_chunks' array
ChunkType m_chunks[VALS_COUNT];

BOOL isBig() const
{
return ((m_encodedLength & IS_BIG) != 0);
}

unsigned GetLength() const
{
if (isBig())
{
unsigned length = (m_encodedLength >> 1);
_ASSERTE(length > 0);
return length;
}
else
{
return 0;
}
}

void SetLength(unsigned length)
{
_ASSERTE(length > 0);
_ASSERTE(length <= VALS_COUNT);

m_encodedLength = (ChunkType) (length << 1);
m_encodedLength |= (ChunkType) IS_BIG;
}
};

union
{
ChunkType m_val; // if m_val bit 0 is false, then bits 1-N are the bit vector
Vals m_vals; // if m_val bit 1 is true, then use Vals
};

BOOL isBig() const
Comment thread
filipnavara marked this conversation as resolved.
Outdated
{
LIMITED_METHOD_CONTRACT;
SUPPORTS_DAC;

return ((m_val & IS_BIG) != 0);
}

void toBig()
{
LIMITED_METHOD_CONTRACT;
SUPPORTS_DAC;

if (!isBig())
{
doBigInit(smallBits());
}
}

ChunkType smallBits() const
{
LIMITED_METHOD_CONTRACT;
SUPPORTS_DAC;

_ASSERTE(!isBig());
return (m_val >> 1);
}

void doBigInit(ChunkType arg);
void doBigInit(const ptrArgTP& arg);
void doBigLeftShiftAssign(unsigned arg);
void doBigRightShiftAssign(unsigned arg);
void doBigDiffAssign(const ptrArgTP&);
void doBigAndAssign(const ptrArgTP&);
void doBigOrAssign(const ptrArgTP& arg);
BOOL doBigEquals(const ptrArgTP&) const;
BOOL doBigIntersect(const ptrArgTP&) const;

public:
ptrArgTP()
{
LIMITED_METHOD_CONTRACT;
SUPPORTS_DAC;

m_val = 0;
}

explicit ptrArgTP(ChunkType arg)
{
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;

if (arg > MaxVal)
{
doBigInit(arg);
}
else
{
m_val = ChunkType(arg << 1);
}
}

ptrArgTP(ChunkType arg, UINT shift)
{
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;

if ((arg > MaxVal) || (shift >= SMALL_BITS) || (arg > (MaxVal >> shift)))
{
doBigInit(arg);
doBigLeftShiftAssign(shift);
}
else
{
m_val = ChunkType(arg << (shift+1));
}
}

ptrArgTP operator &(const ptrArgTP& arg) const
{
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;

ptrArgTP ret = *this;
ret &= arg;
return ret;
}

BOOL operator ==(const ptrArgTP& arg) const
{
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;

if ((m_val | arg.m_val) & IS_BIG)
{
return doBigEquals(arg);
}
else
{
return m_val == arg.m_val;
}
}

BOOL operator !=(const ptrArgTP& arg) const
{
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;

return !(*this == arg);
}

void operator <<=(unsigned shift)
{
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;

if ((m_val == 0) || (shift == 0)) // Zero is a special case, don't need to do anything
return;

if (isBig() || (shift >= SMALL_BITS) || (m_val > (MaxVal >> (shift-1))))
{
doBigLeftShiftAssign(shift);
}
else
{
m_val <<= shift;
}
}

void operator >>=(unsigned shift)
{
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;

if (isBig())
{
doBigRightShiftAssign(shift);
}
else
{
m_val >>= shift;
m_val &= ~IS_BIG; // clear the isBig bit if it got set
}
}

void operator |=(const ptrArgTP& arg)
{
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;

if (((m_val | arg.m_val) & IS_BIG) != 0)
{
doBigOrAssign(arg);
}
else
{
m_val |= arg.m_val;
}
}

void operator &=(const ptrArgTP& arg)
{
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;

if (((m_val | arg.m_val) & IS_BIG) != 0)
{
doBigAndAssign(arg);
}
else
{
m_val &= arg.m_val;
}
}

friend BOOL isZero(const ptrArgTP& arg)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What are these friends for?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I took it from the original bitvector. These methods are not used as member methods. I can change it but I wanted to limit the number of changes.

@jkotas jkotas Feb 7, 2025

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I meant what does friend modifier on a method implementation do in C++? I am surprised that it compiles, but I cannot think of what it can do.

I would not mind deleting unnecessary cruft. I agree that it is best to avoid any logic changes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think it is basically equivalent to declaring friend BOOL isZero(const ptrArgTP& arg); here and then placing the method itself outside of the struct/class.

{
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;

return arg.m_val == 0;
}

friend BOOL intersect(const ptrArgTP& arg1, const ptrArgTP& arg2)
{
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;

if (((arg1.m_val | arg2.m_val) & IS_BIG) != 0)
{
return arg1.doBigIntersect(arg2);
}
else
{
return ((arg1.m_val & arg2.m_val) != 0);
}
}

friend void setDiff(ptrArgTP& target, const ptrArgTP& arg)
{
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;

if (((target.m_val | arg.m_val) & IS_BIG) != 0)
{
target.doBigDiffAssign(arg);
}
else
{
target.m_val &= ~arg.m_val;
}
}

friend ChunkType toUnsigned(const ptrArgTP& arg)
{
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;

if (arg.isBig())
{
return arg.m_vals.m_chunks[0]; // Note truncation
}
else
{
return arg.smallBits();
}
}
};

/*****************************************************************************
*
* Helper to extract basic info from a method info block.
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/inc/gcinfotypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,8 @@ inline const char *ReturnKindToString(ReturnKind returnKind)
#ifdef TARGET_X86

#include <stdlib.h> // For memcmp()
#include "bitvector.h" // for ptrArgTP

#define MAX_PTRARG_OFS 1024

#ifndef FASTCALL
#define FASTCALL __fastcall
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
#define CONTRACTL_END
#define NOTHROW
#define GC_NOTRIGGER
#define WRAPPER_NO_CONTRACT
#define CONTRACT(x)
#define CONTRACT_END
#define RETURN return

#include "../../inc/gcdecoder.cpp"
#include "../../inc/gc_unwind_x86.h"
Expand Down
1 change: 0 additions & 1 deletion src/coreclr/utilcode/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ set(UTILCODE_COMMON_SOURCES
check.cpp
log.cpp
arraylist.cpp
bitvector.cpp
comex.cpp
guidfromname.cpp
memorypool.cpp
Expand Down
Loading