Skip to content

Commit

Permalink
Use packed struct with bitfields to shrink all member modes down to 3…
Browse files Browse the repository at this point in the history
…2-bits (#236)

* Drop member extra_modes and reorder fields to improve alignment

* Use packed bitfield struct to collapse all modes down to 32-bits

* Use PACK macro

* Use enums directly to avoid needing to cast
  • Loading branch information
frmdstryr authored Jan 21, 2025
1 parent c365c61 commit 54adc3f
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 40 deletions.
18 changes: 9 additions & 9 deletions atom/src/behaviors.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace atom
namespace GetAttr
{

enum Mode
enum Mode: uint8_t
{
NoOp,
Slot,
Expand All @@ -37,7 +37,7 @@ enum Mode
namespace PostGetAttr
{

enum Mode
enum Mode: uint8_t
{
NoOp,
Delegate,
Expand All @@ -53,7 +53,7 @@ enum Mode
namespace SetAttr
{

enum Mode
enum Mode: uint8_t
{
NoOp,
Slot,
Expand All @@ -77,7 +77,7 @@ enum Mode
namespace PostSetAttr
{

enum Mode
enum Mode: uint8_t
{
NoOp,
Delegate,
Expand All @@ -94,7 +94,7 @@ enum Mode
namespace DefaultValue
{

enum Mode
enum Mode: uint8_t
{
NoOp,
Static,
Expand All @@ -119,7 +119,7 @@ enum Mode
namespace Validate
{

enum Mode
enum Mode: uint8_t
{
NoOp,
Bool,
Expand Down Expand Up @@ -162,7 +162,7 @@ enum Mode
namespace PostValidate
{

enum Mode
enum Mode: uint8_t
{
NoOp,
Delegate,
Expand All @@ -178,7 +178,7 @@ enum Mode
namespace DelAttr
{

enum Mode
enum Mode: uint8_t
{
NoOp,
Slot,
Expand All @@ -197,7 +197,7 @@ enum Mode
namespace GetState
{

enum Mode
enum Mode: uint8_t
{
Include, // We want include to be the default behavior
Exclude,
Expand Down
1 change: 0 additions & 1 deletion atom/src/member.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,6 @@ Member_clone( Member* self )
return 0;
Member* clone = member_cast( pyclone );
clone->modes = self->modes;
clone->extra_modes = self->extra_modes;
clone->index = self->index;
clone->name = cppy::incref( self->name );
if( self->metadata )
Expand Down
63 changes: 33 additions & 30 deletions atom/src/member.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,22 @@
namespace atom
{

PACK(struct MemberModes
{
GetAttr::Mode getattr: 4;
PostGetAttr::Mode post_getattr: 3;
SetAttr::Mode setattr: 4;
PostSetAttr::Mode post_setattr: 3;
DefaultValue::Mode default_value: 4;
Validate::Mode validate: 5;
PostValidate::Mode post_validate: 3;
DelAttr::Mode delattr: 3;
GetState::Mode getstate: 3;
});

struct Member
{
PyObject_HEAD
uint64_t modes;
uint64_t extra_modes;
uint32_t index;
PyObject* name;
PyObject* metadata;
PyObject* getattr_context;
Expand All @@ -44,6 +54,8 @@ struct Member
PyObject* getstate_context;
ModifyGuard<Member>* modify_guard;
std::vector<Observer>* static_observers;
MemberModes modes;
uint32_t index;

static PyType_Spec TypeObject_Spec;

Expand All @@ -57,101 +69,92 @@ struct Member

GetAttr::Mode get_getattr_mode()
{
return static_cast<GetAttr::Mode>( modes & 0xff );
return modes.getattr;
}

void set_getattr_mode( GetAttr::Mode mode )
{
uint64_t mask = UINT64_C( 0xffffffffffffff00 );
modes = ( modes & mask ) | ( static_cast<uint64_t>( mode & 0xff ) );
modes.getattr = mode;
}

SetAttr::Mode get_setattr_mode()
{
return static_cast<SetAttr::Mode>( ( modes >> 8 ) & 0xff );
return modes.setattr;
}

void set_setattr_mode( SetAttr::Mode mode )
{
uint64_t mask = UINT64_C( 0xffffffffffff00ff );
modes = ( modes & mask ) | ( static_cast<uint64_t>( mode & 0xff ) << 8 );
modes.setattr = mode;
}

PostGetAttr::Mode get_post_getattr_mode()
{
return static_cast<PostGetAttr::Mode>( ( modes >> 16 ) & 0xff );
return modes.post_getattr;
}

void set_post_getattr_mode( PostGetAttr::Mode mode )
{
uint64_t mask = UINT64_C( 0xffffffffff00ffff );
modes = ( modes & mask ) | ( static_cast<uint64_t>( mode & 0xff ) << 16 );
modes.post_getattr = mode;
}

PostSetAttr::Mode get_post_setattr_mode()
{
return static_cast<PostSetAttr::Mode>( ( modes >> 24 ) & 0xff );
return modes.post_setattr;
}

void set_post_setattr_mode( PostSetAttr::Mode mode )
{
uint64_t mask = UINT64_C( 0xffffffff00ffffff );
modes = ( modes & mask ) | ( static_cast<uint64_t>( mode & 0xff ) << 24 );
modes.post_setattr = mode;
}

DefaultValue::Mode get_default_value_mode()
{
return static_cast<DefaultValue::Mode>( ( modes >> 32 ) & 0xff );
return modes.default_value;
}

void set_default_value_mode( DefaultValue::Mode mode )
{
uint64_t mask = UINT64_C( 0xffffff00ffffffff );
modes = ( modes & mask ) | ( static_cast<uint64_t>( mode & 0xff ) << 32 );
modes.default_value = mode;
}

Validate::Mode get_validate_mode()
{
return static_cast<Validate::Mode>( ( modes >> 40 ) & 0xff );
return modes.validate;
}

void set_validate_mode( Validate::Mode mode )
{
uint64_t mask = UINT64_C( 0xffff00ffffffffff );
modes = ( modes & mask ) | ( static_cast<uint64_t>( mode & 0xff ) << 40 );
modes.validate = mode;
}

PostValidate::Mode get_post_validate_mode()
{
return static_cast<PostValidate::Mode>( ( modes >> 48 ) & 0xff );
return modes.post_validate;
}

void set_post_validate_mode( PostValidate::Mode mode )
{
uint64_t mask = UINT64_C( 0xff00ffffffffffff );
modes = ( modes & mask ) | ( static_cast<uint64_t>( mode & 0xff ) << 48 );
modes.post_validate = mode;
}

DelAttr::Mode get_delattr_mode()
{
return static_cast<DelAttr::Mode>( ( modes >> 56 ) & 0xff );
return modes.delattr;
}

void set_delattr_mode( DelAttr::Mode mode )
{
uint64_t mask = UINT64_C( 0x00ffffffffffffff );
modes = ( modes & mask ) | ( static_cast<uint64_t>( mode & 0xff ) << 56 );
modes.delattr = mode;
}

GetState::Mode get_getstate_mode()
{
return static_cast<GetState::Mode>( ( extra_modes ) & 0xff );
return modes.getstate;
}

void set_getstate_mode( GetState::Mode mode )
{
uint64_t mask = UINT64_C( 0xffffffffffffff00 );
extra_modes = ( extra_modes & mask ) | ( static_cast<uint64_t>( mode & 0xff ) );
modes.getstate = mode;
}

PyObject* getattr( CAtom* atom );
Expand Down
2 changes: 2 additions & 0 deletions atom/src/platstdint.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
#pragma once

#ifdef _MSC_VER
#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop))
#include "msstdint.h"
#else
#include <stdint.h>
#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__))
#endif

0 comments on commit 54adc3f

Please sign in to comment.