Skip to content

Commit 3a170fb

Browse files
author
Jianchun Xu
committed
swb: simplify write barrier macros
Apply template traits to field types to simplify write barrier field annotations. Now most annotations are Field or FieldNoBarrier (for pointers known not needing write barrier). Replaced `WB_ITEM_TYPE` with `Field`.
1 parent 747216b commit 3a170fb

File tree

7 files changed

+56
-81
lines changed

7 files changed

+56
-81
lines changed

lib/Common/DataStructures/BaseDictionary.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ namespace JsUtil
8181
typedef typename AllocatorInfo<TAllocator, TValue>::AllocatorType AllocatorType;
8282
typedef SizePolicy CurrentSizePolicy;
8383
typedef Entry<
84-
WB_ITEM_TYPE(TKey, TAllocator),
85-
WB_ITEM_TYPE(TValue, TAllocator)> EntryType;
84+
Field(TKey, TAllocator),
85+
Field(TValue, TAllocator)> EntryType;
8686

8787
template<class TDictionary> class EntryIterator;
8888
template<class TDictionary> class BucketEntryIterator;
@@ -92,17 +92,17 @@ namespace JsUtil
9292
friend class Js::RemoteDictionary<BaseDictionary>;
9393
template <typename ValueOrKey> struct ComparerType { typedef Comparer<ValueOrKey> Type; }; // Used by diagnostics to access Comparer type
9494

95-
Pointer(int, TAllocator) buckets;
96-
Pointer(EntryType, TAllocator) entries;
97-
PointerNoBarrier(AllocatorType) alloc;
95+
Field(int*, TAllocator) buckets;
96+
Field(EntryType*, TAllocator) entries;
97+
FieldNoBarrier(AllocatorType*) alloc;
9898
Field(int) size;
9999
Field(uint) bucketCount;
100100
Field(int) count;
101101
Field(int) freeList;
102102
Field(int) freeCount;
103103

104104
#if PROFILE_DICTIONARY
105-
PointerNoBarrier(DictionaryStats) stats;
105+
FieldNoBarrier(DictionaryStats*) stats;
106106
#endif
107107
enum InsertOperations
108108
{
@@ -1569,7 +1569,7 @@ namespace JsUtil
15691569
class SynchronizedDictionary: protected BaseDictionary<TKey, TValue, TAllocator, SizePolicy, Comparer, Entry>
15701570
{
15711571
private:
1572-
PointerNoBarrier(SyncObject) syncObj;
1572+
FieldNoBarrier(SyncObject*) syncObj;
15731573

15741574
typedef BaseDictionary<TKey, TValue, TAllocator, SizePolicy, Comparer, Entry> Base;
15751575
public:

lib/Common/Memory/RecyclerPointers.h

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -63,40 +63,17 @@ struct AllocatorWriteBarrierPolicy<RecyclerNonLeafAllocator, T> { typedef _write
6363
template <>
6464
struct AllocatorWriteBarrierPolicy<RecyclerNonLeafAllocator, int> { typedef _no_write_barrier_policy Policy; };
6565

66-
// Choose WriteBarrierPtr or NoWriteBarrierPtr based on Policy
66+
// Choose write barrier Field type: T unchanged, or WriteBarrierPtr based on Policy.
6767
//
6868
template <class T, class Policy>
69-
struct _WriteBarrierPtrPolicy { typedef NoWriteBarrierPtr<T> Ptr; };
69+
struct _WriteBarrierFieldType { typedef T Type; };
7070
template <class T>
71-
struct _WriteBarrierPtrPolicy<T, _write_barrier_policy> { typedef WriteBarrierPtr<T> Ptr; };
71+
struct _WriteBarrierFieldType<T*, _write_barrier_policy> { typedef WriteBarrierPtr<T> Type; };
7272

73-
// Choose WriteBarrierPtr or NoWriteBarrierPtr based on Allocator and T* type
74-
//
7573
template <class T,
7674
class Allocator = Recycler,
77-
class Policy = typename AllocatorWriteBarrierPolicy<Allocator, T*>::Policy>
78-
struct WriteBarrierPtrTraits { typedef typename _WriteBarrierPtrPolicy<T, Policy>::Ptr Ptr; };
79-
80-
// Choose WriteBarrierPtr type if Allocator is recycler type and element type T
81-
// is a pointer type, otherwise use type T unchanged.
82-
//
83-
// Used to wrap array item type when write barrier is needed (wraps pointer
84-
// item type with WriteBarrierPtr).
85-
//
86-
template <class T, class Policy>
87-
struct _ArrayItemTypeTraits
88-
{
89-
typedef T Type;
90-
};
91-
template <class T>
92-
struct _ArrayItemTypeTraits<T*, _write_barrier_policy>
93-
{
94-
typedef WriteBarrierPtr<T> Type;
95-
};
96-
template <class T,
97-
class Allocator,
9875
class Policy = typename AllocatorWriteBarrierPolicy<Allocator, T>::Policy>
99-
struct WriteBarrierArrayItemTraits { typedef typename _ArrayItemTypeTraits<T, Policy>::Type Type; };
76+
struct WriteBarrierFieldTypeTraits { typedef typename _WriteBarrierFieldType<T, Policy>::Type Type; };
10077

10178
// ArrayWriteBarrier behavior
10279
//

lib/Common/Memory/WriteBarrierMacros.h

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,38 +28,30 @@
2828

2929
#define SAVE_WRITE_BARRIER_MACROS() \
3030
PushMacro("Field") \
31-
PushMacro("PointerNoBarrier") \
32-
PushMacro("Pointer") \
33-
PushMacro("WB_ITEM_TYPE")
31+
PushMacro("FieldNoBarrier")
3432

3533
#define RESTORE_WRITE_BARRIER_MACROS() \
3634
PopMacro("Field") \
37-
PopMacro("PointerNoBarrier") \
38-
PopMacro("Pointer") \
39-
PopMacro("WB_ITEM_TYPE")
35+
PopMacro("FieldNoBarrier")
4036

4137
#endif
4238

4339
#ifdef FORCE_USE_WRITE_BARRIER
4440
SAVE_WRITE_BARRIER_MACROS()
4541
#undef Field
46-
#undef PointerNoBarrier
47-
#undef Pointer
48-
#undef WB_ITEM_TYPE
42+
#undef FieldNoBarrier
4943
#endif
5044

5145
// TODO: Turn off these annotations on Win32
5246
#if defined(__clang__) || defined(FORCE_USE_WRITE_BARRIER)
5347
// Various macros for defining field attributes
54-
#define Field(type) NoWriteBarrierField<type>
55-
#define PointerNoBarrier(type) NoWriteBarrierPtr<type>
56-
#define Pointer(type, ...) typename WriteBarrierPtrTraits<type, ##__VA_ARGS__>::Ptr
57-
#define WB_ITEM_TYPE(type, ...) typename WriteBarrierArrayItemTraits<type, ##__VA_ARGS__>::Type
48+
#define Field(type, ...) \
49+
typename WriteBarrierFieldTypeTraits<type, ##__VA_ARGS__>::Type
50+
#define FieldNoBarrier(type) \
51+
typename WriteBarrierFieldTypeTraits<type, _no_write_barrier_policy, _no_write_barrier_policy>::Type
5852
#else
59-
#define Field(type) type
60-
#define PointerNoBarrier(type) type*
61-
#define Pointer(type, ...) type*
62-
#define WB_ITEM_TYPE(type, ...) type
53+
#define Field(type, ...) type
54+
#define FieldNoBarrier(type) type
6355
#endif
6456

6557
#undef FORCE_USE_WRITE_BARRIER

lib/Runtime/Base/AuxPtrs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace Js
2828
static const uint8 MaxCount;
2929
Field(uint8) count; // always saving maxCount
3030
Field(FieldsEnum) type[_MaxCount]; // save instantiated pointer enum
31-
Pointer(void) ptr[_MaxCount]; // save instantiated pointer address
31+
Field(void*) ptr[_MaxCount]; // save instantiated pointer address
3232
AuxPtrsFix();
3333
AuxPtrsFix(AuxPtrsFix<FieldsEnum, 16>* ptr16); // called when promoting from AuxPtrs16 to AuxPtrs32
3434
void* Get(FieldsEnum e);
@@ -53,7 +53,7 @@ namespace Js
5353
Field(uint8) count; // save instantiated pointers count
5454
Field(uint8) capacity; // save number of pointers can be hold in current instance of AuxPtrs
5555
Field(uint8) offsets[static_cast<int>(FieldsEnum::Max)]; // save position of each instantiated pointers, if not instantiate, it's invalid
56-
Pointer(void) ptrs[1]; // instantiated pointer addresses
56+
Field(void*) ptrs[1]; // instantiated pointer addresses
5757
AuxPtrs(uint8 capacity, AuxPtrs32* ptr32); // called when promoting from AuxPtrs32 to AuxPtrs
5858
AuxPtrs(uint8 capacity, AuxPtrs* ptr); // called when expanding (i.e. promoting from AuxPtrs to bigger AuxPtrs)
5959
void* Get(FieldsEnum e);

lib/Runtime/Base/CompactCounters.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ namespace Js
3737
mutable Field(bool) bgThreadCallStarted;
3838
Field(bool) isCleaningUp;
3939
#endif
40-
Pointer(Fields) fields;
40+
Field(Fields*) fields;
4141

4242
CompactCounters() { }
4343
CompactCounters(T* host)

lib/Runtime/Base/FunctionBody.h

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,7 +1351,7 @@ namespace Js
13511351

13521352
typedef AuxPtrs<FunctionProxy, AuxPointerType> AuxPtrsT;
13531353
friend AuxPtrsT;
1354-
Pointer(AuxPtrsT) auxPtrs;
1354+
Field(AuxPtrsT*) auxPtrs;
13551355
void* GetAuxPtr(AuxPointerType e) const;
13561356
void* GetAuxPtrWithLock(AuxPointerType e) const;
13571357
void SetAuxPtr(AuxPointerType e, void* ptr);
@@ -1451,17 +1451,17 @@ namespace Js
14511451

14521452
protected:
14531453
// Static method(s)
1454-
static void SetDisplayName(const char16* srcName, Pointer(const char16)* destName, uint displayNameLength, ScriptContext * scriptContext, SetDisplayNameFlags flags = SetDisplayNameFlagsNone);
1454+
static void SetDisplayName(const char16* srcName, Field(const char16*)* destName, uint displayNameLength, ScriptContext * scriptContext, SetDisplayNameFlags flags = SetDisplayNameFlagsNone);
14551455
static bool SetDisplayName(const char16* srcName, const char16** destName, uint displayNameLength, ScriptContext * scriptContext, SetDisplayNameFlags flags = SetDisplayNameFlagsNone);
14561456
static bool IsConstantFunctionName(const char16* srcName);
14571457

14581458
protected:
1459-
PointerNoBarrier(ScriptContext) m_scriptContext; // Memory context for this function body
1460-
Pointer(Utf8SourceInfo) m_utf8SourceInfo;
1459+
FieldNoBarrier(ScriptContext*) m_scriptContext; // Memory context for this function body
1460+
Field(Utf8SourceInfo*) m_utf8SourceInfo;
14611461
// WriteBarrier-TODO: Consider changing this to NoWriteBarrierPtr, and skip tagging- also, tagging is likely unnecessary since that pointer in question is likely not resolvable
1462-
PointerNoBarrier(FunctionProxyPtr) m_referenceInParentFunction; // Reference to nested function reference to this function in the parent function body (tagged to not be actual reference)
1463-
Pointer(ScriptFunctionType) deferredPrototypeType;
1464-
Pointer(ProxyEntryPointInfo) m_defaultEntryPointInfo; // The default entry point info for the function proxy
1462+
FieldNoBarrier(FunctionProxyPtr*) m_referenceInParentFunction; // Reference to nested function reference to this function in the parent function body (tagged to not be actual reference)
1463+
Field(ScriptFunctionType*) deferredPrototypeType;
1464+
Field(ProxyEntryPointInfo*) m_defaultEntryPointInfo; // The default entry point info for the function proxy
14651465

14661466
Field(uint) m_functionNumber; // Per thread global function number
14671467

@@ -1771,7 +1771,7 @@ namespace Js
17711771
Field(bool) m_utf8SourceHasBeenSet; // start of UTF8-encoded source
17721772
Field(uint) m_sourceIndex; // index into the scriptContext's list of saved sources
17731773
#if DYNAMIC_INTERPRETER_THUNK
1774-
PointerNoBarrier(void) m_dynamicInterpreterThunk; // Unique 'thunk' for every interpreted function - used for ETW symbol decoding.
1774+
FieldNoBarrier(void*) m_dynamicInterpreterThunk; // Unique 'thunk' for every interpreted function - used for ETW symbol decoding.
17751775
#endif
17761776
Field(uint) m_cbStartOffset; // pUtf8Source is this many bytes from the start of the scriptContext's source buffer.
17771777

@@ -1783,10 +1783,10 @@ namespace Js
17831783

17841784
ULONG m_lineNumber;
17851785
ULONG m_columnNumber;
1786-
Pointer(const char16) m_displayName; // Optional name
1786+
Field(const char16*) m_displayName; // Optional name
17871787
uint m_displayNameLength;
1788-
Pointer(PropertyRecordList) m_boundPropertyRecords;
1789-
Pointer(NestedArray) nestedArray;
1788+
Field(PropertyRecordList*) m_boundPropertyRecords;
1789+
Field(NestedArray*) nestedArray;
17901790

17911791
public:
17921792
#if DBG
@@ -1988,16 +1988,16 @@ namespace Js
19881988
friend class ByteCodeBufferBuilder;
19891989

19901990
public:
1991-
PointerNoBarrier(SmallSpanSequence) pSpanSequence;
1991+
FieldNoBarrier(SmallSpanSequence*) pSpanSequence;
19921992

19931993
RegSlot frameDisplayRegister; // this register slot cannot be 0 so we use that sentinel value to indicate invalid
19941994
RegSlot objectRegister; // this register slot cannot be 0 so we use that sentinel value to indicate invalid
1995-
Pointer(ScopeObjectChain) pScopeObjectChain;
1996-
Pointer(ByteBlock) m_probeBackingBlock; // NULL if no Probes, otherwise a copy of the unmodified the byte-codeblock //Delay
1995+
Field(ScopeObjectChain*) pScopeObjectChain;
1996+
Field(ByteBlock*) m_probeBackingBlock; // NULL if no Probes, otherwise a copy of the unmodified the byte-codeblock //Delay
19971997
int32 m_probeCount; // The number of installed probes (such as breakpoints).
19981998

19991999
// List of bytecode offset for the Branch bytecode.
2000-
Pointer(AuxStatementData) m_auxStatementData;
2000+
Field(AuxStatementData*) m_auxStatementData;
20012001

20022002
SourceInfo():
20032003
frameDisplayRegister(0),
@@ -2012,18 +2012,18 @@ namespace Js
20122012
};
20132013

20142014
private:
2015-
Pointer(ByteBlock) byteCodeBlock; // Function byte-code for script functions
2016-
Pointer(FunctionEntryPointList) entryPoints;
2017-
Pointer(Var) m_constTable;
2018-
Pointer(void*) inlineCaches;
2015+
Field(ByteBlock*) byteCodeBlock; // Function byte-code for script functions
2016+
Field(FunctionEntryPointList*) entryPoints;
2017+
Field(Var*) m_constTable;
2018+
Field(void**) inlineCaches;
20192019
InlineCachePointerArray<PolymorphicInlineCache> polymorphicInlineCaches; // Contains the latest polymorphic inline caches
2020-
Pointer(PropertyId) cacheIdToPropertyIdMap;
2020+
Field(PropertyId*) cacheIdToPropertyIdMap;
20212021

20222022
#if DBG
20232023
#define InlineCacheTypeNone 0x00
20242024
#define InlineCacheTypeInlineCache 0x01
20252025
#define InlineCacheTypeIsInst 0x02
2026-
Pointer(byte) m_inlineCacheTypes;
2026+
Field(byte*) m_inlineCacheTypes;
20272027
#endif
20282028
public:
20292029
PropertyId * GetCacheIdToPropertyIdMap()
@@ -2149,7 +2149,7 @@ namespace Js
21492149
#ifdef IR_VIEWER
21502150
// whether IR Dump is enabled for this function (used by parseIR)
21512151
bool m_isIRDumpEnabled : 1;
2152-
Pointer(Js::DynamicObject) m_irDumpBaseObject;
2152+
Field(Js::DynamicObject*) m_irDumpBaseObject;
21532153
#endif /* IR_VIEWER */
21542154

21552155
Field(uint8) bailOnMisingProfileCount;
@@ -2181,14 +2181,14 @@ namespace Js
21812181
// copied in FunctionBody::Clone
21822182
//
21832183

2184-
PointerNoBarrier(Js::ByteCodeCache) byteCodeCache; // Not GC allocated so naked pointer
2184+
FieldNoBarrier(Js::ByteCodeCache*) byteCodeCache; // Not GC allocated so naked pointer
21852185
#ifdef ENABLE_DEBUG_CONFIG_OPTIONS
21862186
static bool shareInlineCaches;
21872187
#endif
2188-
Pointer(FunctionEntryPointInfo) defaultFunctionEntryPointInfo;
2188+
Field(FunctionEntryPointInfo*) defaultFunctionEntryPointInfo;
21892189

21902190
#if ENABLE_PROFILE_INFO
2191-
Pointer(DynamicProfileInfo) dynamicProfileInfo;
2191+
Field(DynamicProfileInfo*) dynamicProfileInfo;
21922192
#endif
21932193

21942194

tools/RecyclerChecker/RecyclerChecker.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,16 @@
1414
using namespace clang;
1515
using namespace std;
1616

17+
template <size_t N>
18+
bool StartsWith(const string& s, const char (&prefix)[N])
19+
{
20+
return s.compare(0, string::npos, prefix, N - 1) == 0;
21+
}
1722

1823
namespace
1924
{
20-
2125
class MainVisitor;
26+
2227
class CheckAllocationsInFunctionVisitor :
2328
public RecursiveASTVisitor<CheckAllocationsInFunctionVisitor>
2429
{
@@ -80,8 +85,9 @@ class MainVisitor:
8085
else
8186
{
8287
auto fieldTypeName = qualType.getAsString();
83-
if (fieldTypeName.find("WriteBarrierPtr") == 0) // starts with
88+
if (StartsWith(fieldTypeName, "typename WriteBarrierFieldTypeTraits"))
8489
{
90+
// Note this only indicates the class is write-barrier annotated
8591
hasBarrieredField = true;
8692
}
8793
else if (type->isCompoundType())

0 commit comments

Comments
 (0)