Skip to content

Commit 54adc3f

Browse files
authored
Use packed struct with bitfields to shrink all member modes down to 32-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
1 parent c365c61 commit 54adc3f

File tree

4 files changed

+44
-40
lines changed

4 files changed

+44
-40
lines changed

atom/src/behaviors.h

+9-9
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace atom
1414
namespace GetAttr
1515
{
1616

17-
enum Mode
17+
enum Mode: uint8_t
1818
{
1919
NoOp,
2020
Slot,
@@ -37,7 +37,7 @@ enum Mode
3737
namespace PostGetAttr
3838
{
3939

40-
enum Mode
40+
enum Mode: uint8_t
4141
{
4242
NoOp,
4343
Delegate,
@@ -53,7 +53,7 @@ enum Mode
5353
namespace SetAttr
5454
{
5555

56-
enum Mode
56+
enum Mode: uint8_t
5757
{
5858
NoOp,
5959
Slot,
@@ -77,7 +77,7 @@ enum Mode
7777
namespace PostSetAttr
7878
{
7979

80-
enum Mode
80+
enum Mode: uint8_t
8181
{
8282
NoOp,
8383
Delegate,
@@ -94,7 +94,7 @@ enum Mode
9494
namespace DefaultValue
9595
{
9696

97-
enum Mode
97+
enum Mode: uint8_t
9898
{
9999
NoOp,
100100
Static,
@@ -119,7 +119,7 @@ enum Mode
119119
namespace Validate
120120
{
121121

122-
enum Mode
122+
enum Mode: uint8_t
123123
{
124124
NoOp,
125125
Bool,
@@ -162,7 +162,7 @@ enum Mode
162162
namespace PostValidate
163163
{
164164

165-
enum Mode
165+
enum Mode: uint8_t
166166
{
167167
NoOp,
168168
Delegate,
@@ -178,7 +178,7 @@ enum Mode
178178
namespace DelAttr
179179
{
180180

181-
enum Mode
181+
enum Mode: uint8_t
182182
{
183183
NoOp,
184184
Slot,
@@ -197,7 +197,7 @@ enum Mode
197197
namespace GetState
198198
{
199199

200-
enum Mode
200+
enum Mode: uint8_t
201201
{
202202
Include, // We want include to be the default behavior
203203
Exclude,

atom/src/member.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,6 @@ Member_clone( Member* self )
390390
return 0;
391391
Member* clone = member_cast( pyclone );
392392
clone->modes = self->modes;
393-
clone->extra_modes = self->extra_modes;
394393
clone->index = self->index;
395394
clone->name = cppy::incref( self->name );
396395
if( self->metadata )

atom/src/member.h

+33-30
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,22 @@
2525
namespace atom
2626
{
2727

28+
PACK(struct MemberModes
29+
{
30+
GetAttr::Mode getattr: 4;
31+
PostGetAttr::Mode post_getattr: 3;
32+
SetAttr::Mode setattr: 4;
33+
PostSetAttr::Mode post_setattr: 3;
34+
DefaultValue::Mode default_value: 4;
35+
Validate::Mode validate: 5;
36+
PostValidate::Mode post_validate: 3;
37+
DelAttr::Mode delattr: 3;
38+
GetState::Mode getstate: 3;
39+
});
40+
2841
struct Member
2942
{
3043
PyObject_HEAD
31-
uint64_t modes;
32-
uint64_t extra_modes;
33-
uint32_t index;
3444
PyObject* name;
3545
PyObject* metadata;
3646
PyObject* getattr_context;
@@ -44,6 +54,8 @@ struct Member
4454
PyObject* getstate_context;
4555
ModifyGuard<Member>* modify_guard;
4656
std::vector<Observer>* static_observers;
57+
MemberModes modes;
58+
uint32_t index;
4759

4860
static PyType_Spec TypeObject_Spec;
4961

@@ -57,101 +69,92 @@ struct Member
5769

5870
GetAttr::Mode get_getattr_mode()
5971
{
60-
return static_cast<GetAttr::Mode>( modes & 0xff );
72+
return modes.getattr;
6173
}
6274

6375
void set_getattr_mode( GetAttr::Mode mode )
6476
{
65-
uint64_t mask = UINT64_C( 0xffffffffffffff00 );
66-
modes = ( modes & mask ) | ( static_cast<uint64_t>( mode & 0xff ) );
77+
modes.getattr = mode;
6778
}
6879

6980
SetAttr::Mode get_setattr_mode()
7081
{
71-
return static_cast<SetAttr::Mode>( ( modes >> 8 ) & 0xff );
82+
return modes.setattr;
7283
}
7384

7485
void set_setattr_mode( SetAttr::Mode mode )
7586
{
76-
uint64_t mask = UINT64_C( 0xffffffffffff00ff );
77-
modes = ( modes & mask ) | ( static_cast<uint64_t>( mode & 0xff ) << 8 );
87+
modes.setattr = mode;
7888
}
7989

8090
PostGetAttr::Mode get_post_getattr_mode()
8191
{
82-
return static_cast<PostGetAttr::Mode>( ( modes >> 16 ) & 0xff );
92+
return modes.post_getattr;
8393
}
8494

8595
void set_post_getattr_mode( PostGetAttr::Mode mode )
8696
{
87-
uint64_t mask = UINT64_C( 0xffffffffff00ffff );
88-
modes = ( modes & mask ) | ( static_cast<uint64_t>( mode & 0xff ) << 16 );
97+
modes.post_getattr = mode;
8998
}
9099

91100
PostSetAttr::Mode get_post_setattr_mode()
92101
{
93-
return static_cast<PostSetAttr::Mode>( ( modes >> 24 ) & 0xff );
102+
return modes.post_setattr;
94103
}
95104

96105
void set_post_setattr_mode( PostSetAttr::Mode mode )
97106
{
98-
uint64_t mask = UINT64_C( 0xffffffff00ffffff );
99-
modes = ( modes & mask ) | ( static_cast<uint64_t>( mode & 0xff ) << 24 );
107+
modes.post_setattr = mode;
100108
}
101109

102110
DefaultValue::Mode get_default_value_mode()
103111
{
104-
return static_cast<DefaultValue::Mode>( ( modes >> 32 ) & 0xff );
112+
return modes.default_value;
105113
}
106114

107115
void set_default_value_mode( DefaultValue::Mode mode )
108116
{
109-
uint64_t mask = UINT64_C( 0xffffff00ffffffff );
110-
modes = ( modes & mask ) | ( static_cast<uint64_t>( mode & 0xff ) << 32 );
117+
modes.default_value = mode;
111118
}
112119

113120
Validate::Mode get_validate_mode()
114121
{
115-
return static_cast<Validate::Mode>( ( modes >> 40 ) & 0xff );
122+
return modes.validate;
116123
}
117124

118125
void set_validate_mode( Validate::Mode mode )
119126
{
120-
uint64_t mask = UINT64_C( 0xffff00ffffffffff );
121-
modes = ( modes & mask ) | ( static_cast<uint64_t>( mode & 0xff ) << 40 );
127+
modes.validate = mode;
122128
}
123129

124130
PostValidate::Mode get_post_validate_mode()
125131
{
126-
return static_cast<PostValidate::Mode>( ( modes >> 48 ) & 0xff );
132+
return modes.post_validate;
127133
}
128134

129135
void set_post_validate_mode( PostValidate::Mode mode )
130136
{
131-
uint64_t mask = UINT64_C( 0xff00ffffffffffff );
132-
modes = ( modes & mask ) | ( static_cast<uint64_t>( mode & 0xff ) << 48 );
137+
modes.post_validate = mode;
133138
}
134139

135140
DelAttr::Mode get_delattr_mode()
136141
{
137-
return static_cast<DelAttr::Mode>( ( modes >> 56 ) & 0xff );
142+
return modes.delattr;
138143
}
139144

140145
void set_delattr_mode( DelAttr::Mode mode )
141146
{
142-
uint64_t mask = UINT64_C( 0x00ffffffffffffff );
143-
modes = ( modes & mask ) | ( static_cast<uint64_t>( mode & 0xff ) << 56 );
147+
modes.delattr = mode;
144148
}
145149

146150
GetState::Mode get_getstate_mode()
147151
{
148-
return static_cast<GetState::Mode>( ( extra_modes ) & 0xff );
152+
return modes.getstate;
149153
}
150154

151155
void set_getstate_mode( GetState::Mode mode )
152156
{
153-
uint64_t mask = UINT64_C( 0xffffffffffffff00 );
154-
extra_modes = ( extra_modes & mask ) | ( static_cast<uint64_t>( mode & 0xff ) );
157+
modes.getstate = mode;
155158
}
156159

157160
PyObject* getattr( CAtom* atom );

atom/src/platstdint.h

+2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
#pragma once
99

1010
#ifdef _MSC_VER
11+
#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop))
1112
#include "msstdint.h"
1213
#else
1314
#include <stdint.h>
15+
#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__))
1416
#endif

0 commit comments

Comments
 (0)