@@ -4165,7 +4165,16 @@ size_t gcard_of ( uint8_t*);
4165
4165
// We only do this when we decide to compact.
4166
4166
#define BGC_MARKED_BY_FGC (size_t)0x2
4167
4167
#define MAKE_FREE_OBJ_IN_COMPACT (size_t)0x4
4168
- #endif //DOUBLY_LINKED_FL
4168
+ #define ALLOWED_SPECIAL_HEADER_BITS (GC_MARKED|BGC_MARKED_BY_FGC|MAKE_FREE_OBJ_IN_COMPACT)
4169
+ #else //DOUBLY_LINKED_FL
4170
+ #define ALLOWED_SPECIAL_HEADER_BITS (GC_MARKED)
4171
+ #endif //!DOUBLY_LINKED_FL
4172
+
4173
+ #ifdef HOST_64BIT
4174
+ #define SPECIAL_HEADER_BITS (0x7)
4175
+ #else
4176
+ #define SPECIAL_HEADER_BITS (0x3)
4177
+ #endif
4169
4178
4170
4179
#define slot(i, j) ((uint8_t**)(i))[(j)+1]
4171
4180
@@ -4267,11 +4276,7 @@ class CObjectHeader : public Object
4267
4276
4268
4277
MethodTable *GetMethodTable() const
4269
4278
{
4270
- return( (MethodTable *) (((size_t) RawGetMethodTable()) & (~(GC_MARKED
4271
- #ifdef DOUBLY_LINKED_FL
4272
- | BGC_MARKED_BY_FGC | MAKE_FREE_OBJ_IN_COMPACT
4273
- #endif //DOUBLY_LINKED_FL
4274
- ))));
4279
+ return( (MethodTable *) (((size_t) RawGetMethodTable()) & (~SPECIAL_HEADER_BITS)));
4275
4280
}
4276
4281
4277
4282
void SetMarked()
@@ -4339,6 +4344,26 @@ class CObjectHeader : public Object
4339
4344
}
4340
4345
#endif //DOUBLY_LINKED_FL
4341
4346
4347
+ size_t ClearSpecialBits()
4348
+ {
4349
+ size_t special_bits = ((size_t)RawGetMethodTable()) & SPECIAL_HEADER_BITS;
4350
+ if (special_bits != 0)
4351
+ {
4352
+ assert ((special_bits & (~ALLOWED_SPECIAL_HEADER_BITS)) == 0);
4353
+ RawSetMethodTable ((MethodTable*)(((size_t)RawGetMethodTable()) & ~(SPECIAL_HEADER_BITS)));
4354
+ }
4355
+ return special_bits;
4356
+ }
4357
+
4358
+ void SetSpecialBits (size_t special_bits)
4359
+ {
4360
+ assert ((special_bits & (~ALLOWED_SPECIAL_HEADER_BITS)) == 0);
4361
+ if (special_bits != 0)
4362
+ {
4363
+ RawSetMethodTable ((MethodTable*)(((size_t)RawGetMethodTable()) | special_bits));
4364
+ }
4365
+ }
4366
+
4342
4367
CGCDesc *GetSlotMap ()
4343
4368
{
4344
4369
assert (GetMethodTable()->ContainsPointers());
@@ -4506,6 +4531,17 @@ inline
4506
4531
BOOL is_plug_padded (uint8_t* node){return FALSE;}
4507
4532
#endif //SHORT_PLUGS
4508
4533
4534
+ inline
4535
+ size_t clear_special_bits (uint8_t* node)
4536
+ {
4537
+ return header(node)->ClearSpecialBits();
4538
+ }
4539
+
4540
+ inline
4541
+ void set_special_bits (uint8_t* node, size_t special_bits)
4542
+ {
4543
+ header(node)->SetSpecialBits (special_bits);
4544
+ }
4509
4545
4510
4546
inline size_t unused_array_size(uint8_t * p)
4511
4547
{
@@ -20978,16 +21014,16 @@ void gc_heap::enque_pinned_plug (uint8_t* plug,
20978
21014
20979
21015
if (save_pre_plug_info_p)
20980
21016
{
20981
- #ifdef SHORT_PLUGS
20982
- BOOL is_padded = is_plug_padded (last_object_in_last_plug);
20983
- if (is_padded)
20984
- clear_plug_padded (last_object_in_last_plug);
20985
- #endif //SHORT_PLUGS
21017
+ // In the case of short plugs or doubly linked free lists, there may be extra bits
21018
+ // set in the method table pointer.
21019
+ // Clear these bits for the copy saved in saved_pre_plug, but not for the copy
21020
+ // saved in saved_pre_plug_reloc.
21021
+ // This is because we need these bits for compaction, but not for mark & sweep.
21022
+ size_t special_bits = clear_special_bits (last_object_in_last_plug);
21023
+ // now copy the bits over
20986
21024
memcpy (&(m.saved_pre_plug), &(((plug_and_gap*)plug)[-1]), sizeof (gap_reloc_pair));
20987
- #ifdef SHORT_PLUGS
20988
- if (is_padded)
20989
- set_plug_padded (last_object_in_last_plug);
20990
- #endif //SHORT_PLUGS
21025
+ // restore the bits in the original
21026
+ set_special_bits (last_object_in_last_plug, special_bits);
20991
21027
20992
21028
memcpy (&(m.saved_pre_plug_reloc), &(((plug_and_gap*)plug)[-1]), sizeof (gap_reloc_pair));
20993
21029
@@ -20997,7 +21033,7 @@ void gc_heap::enque_pinned_plug (uint8_t* plug,
20997
21033
{
20998
21034
record_interesting_data_point (idp_pre_short);
20999
21035
#ifdef SHORT_PLUGS
21000
- if (is_padded )
21036
+ if (is_plug_padded (last_object_in_last_plug) )
21001
21037
record_interesting_data_point (idp_pre_short_padded);
21002
21038
#endif //SHORT_PLUGS
21003
21039
dprintf (3, ("encountered a short object %Ix right before pinned plug %Ix!",
@@ -21041,16 +21077,17 @@ void gc_heap::save_post_plug_info (uint8_t* last_pinned_plug, uint8_t* last_obje
21041
21077
assert (last_pinned_plug == m.first);
21042
21078
m.saved_post_plug_info_start = (uint8_t*)&(((plug_and_gap*)post_plug)[-1]);
21043
21079
21044
- #ifdef SHORT_PLUGS
21045
- BOOL is_padded = is_plug_padded (last_object_in_last_plug);
21046
- if (is_padded)
21047
- clear_plug_padded (last_object_in_last_plug);
21048
- #endif //SHORT_PLUGS
21080
+ // In the case of short plugs or doubly linked free lists, there may be extra bits
21081
+ // set in the method table pointer.
21082
+ // Clear these bits for the copy saved in saved_post_plug, but not for the copy
21083
+ // saved in saved_post_plug_reloc.
21084
+ // This is because we need these bits for compaction, but not for mark & sweep.
21085
+ // Note that currently none of these bits will ever be set in the object saved *after*
21086
+ // a pinned plug - this object is currently pinned along with the pinned object before it
21087
+ size_t special_bits = clear_special_bits (last_object_in_last_plug);
21049
21088
memcpy (&(m.saved_post_plug), m.saved_post_plug_info_start, sizeof (gap_reloc_pair));
21050
- #ifdef SHORT_PLUGS
21051
- if (is_padded)
21052
- set_plug_padded (last_object_in_last_plug);
21053
- #endif //SHORT_PLUGS
21089
+ // restore the bits in the original
21090
+ set_special_bits (last_object_in_last_plug, special_bits);
21054
21091
21055
21092
memcpy (&(m.saved_post_plug_reloc), m.saved_post_plug_info_start, sizeof (gap_reloc_pair));
21056
21093
@@ -21069,7 +21106,7 @@ void gc_heap::save_post_plug_info (uint8_t* last_pinned_plug, uint8_t* last_obje
21069
21106
dprintf (3, ("PP %Ix last obj %Ix is too short", last_pinned_plug, last_object_in_last_plug));
21070
21107
record_interesting_data_point (idp_post_short);
21071
21108
#ifdef SHORT_PLUGS
21072
- if (is_padded )
21109
+ if (is_plug_padded (last_object_in_last_plug) )
21073
21110
record_interesting_data_point (idp_post_short_padded);
21074
21111
#endif //SHORT_PLUGS
21075
21112
m.set_post_short();
0 commit comments