-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
Copy pathFunctionCodeGenJitTimeData.h
195 lines (157 loc) · 8.73 KB
/
FunctionCodeGenJitTimeData.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#pragma once
#if ENABLE_NATIVE_CODEGEN
// forward ref
struct FunctionBodyDataIDL;
namespace Js
{
// - Data generated for jitting purposes
// - Recycler-allocated, lifetime is from when a code gen work item is added to the jit queue, to when jitting is complete
// - Also keeps the function body and inlinee function bodies alive while jitting.
class FunctionCodeGenJitTimeData
{
private:
Field(FunctionInfo *) const functionInfo;
// Point's to an entry point if the work item needs the entry point alive- null for cases where the entry point isn't used
Field(EntryPointInfo *) const entryPointInfo;
// These cloned inline caches are guaranteed to have stable data while jitting, but will be collectible after jitting
Field(ObjTypeSpecFldInfoArray) objTypeSpecFldInfoArray;
// Globally ordered list of all object type specialized property access information (monomorphic and polymorphic caches combined).
Field(uint) globalObjTypeSpecFldInfoCount;
Field(Field(ObjTypeSpecFldInfo*)*) globalObjTypeSpecFldInfoArray;
// There will be a non-null entry for each profiled call site where a function is to be inlined
Field(Field(FunctionCodeGenJitTimeData*)*) inlinees;
Field(Field(FunctionCodeGenJitTimeData*)*) ldFldInlinees;
Field(Field(FunctionCodeGenJitTimeData*)*) callbackInlinees;
Field(Field(FunctionCodeGenJitTimeData*)*) callApplyTargetInlinees;
Field(RecyclerWeakReference<FunctionBody>*) weakFuncRef;
Field(PolymorphicInlineCacheInfoIDL*) inlineeInfo;
Field(PolymorphicInlineCacheInfoIDL*) selfInfo;
Field(PolymorphicInlineCacheIDL*) polymorphicInlineCaches;
// current value of global this object, may be changed in case of script engine invalidation
Field(Var) globalThisObject;
// Number of functions that are to be inlined (this is not the length of the 'inlinees' array above, includes getter setter inlinee count)
Field(uint) inlineeCount;
// Number of counts of getter setter to be inlined. This is not an exact count as inline caches are shared and we have no way of knowing
// accurate count.
Field(uint) ldFldInlineeCount;
// For polymorphic call site we will have linked list of FunctionCodeGenJitTimeData
// Each is differentiated by id starting from 0, 1
Field(FunctionCodeGenJitTimeData *) next;
Field(bool) isInlined;
// This indicates the function is aggressively Inlined(see NativeCodeGenerator::TryAggressiveInlining) .
Field(bool) isAggressiveInliningEnabled;
// The profiled iterations need to be determined at the time of gathering code gen data on the main thread
Field(const uint16) profiledIterations;
FunctionCodeGenJitTimeData(FunctionInfo *const functionInfo, EntryPointInfo *const entryPoint, Var globalThis, uint16 profiledIterations, bool isInlined = true);
#ifdef FIELD_ACCESS_STATS
public:
Field(FieldAccessStatsPtr) inlineCacheStats;
void EnsureInlineCacheStats(Recycler* recycler);
void AddInlineeInlineCacheStats(FunctionCodeGenJitTimeData* inlineeJitTimeData);
#endif
public:
static FunctionCodeGenJitTimeData* New(Recycler* recycler, FunctionInfo *const functionInfo, EntryPointInfo *const entryPoint, bool isInlined = true);
public:
Field(BVFixed *) inlineesBv;
Field(Js::PropertyId*) sharedPropertyGuards;
Field(uint) sharedPropertyGuardCount;
FunctionInfo *GetFunctionInfo() const;
FunctionBody *GetFunctionBody() const;
Var GetGlobalThisObject() const;
FunctionBodyDataIDL *GetJITBody() const;
FunctionCodeGenJitTimeData *GetNext() const { return next; }
const ObjTypeSpecFldInfoArray* GetObjTypeSpecFldInfoArray() const { return &this->objTypeSpecFldInfoArray; }
ObjTypeSpecFldInfoArray* GetObjTypeSpecFldInfoArray() { return &this->objTypeSpecFldInfoArray; }
EntryPointInfo* GetEntryPointInfo() const { return this->entryPointInfo; }
public:
const FunctionCodeGenJitTimeData *GetInlinee(const ProfileId profiledCallSiteId) const;
const FunctionCodeGenJitTimeData *GetLdFldInlinee(const InlineCacheIndex inlineCacheIndex) const;
const FunctionCodeGenJitTimeData * GetCallbackInlinee(const ProfileId profiledCallSiteId) const;
const FunctionCodeGenJitTimeData * GetCallApplyTargetInlinee(const ProfileId callApplyCallSiteId) const;
FunctionCodeGenJitTimeData *AddInlinee(
Recycler *const recycler,
const ProfileId profiledCallSiteId,
FunctionInfo *const inlinee,
bool isInlined = true);
uint InlineeCount() const;
uint LdFldInlineeCount() const;
bool IsLdFldInlineePresent() const { return ldFldInlineeCount != 0; }
RecyclerWeakReference<FunctionBody> *GetWeakFuncRef() const { return this->weakFuncRef; }
void SetWeakFuncRef(RecyclerWeakReference<FunctionBody> *weakFuncRef)
{
Assert(this->weakFuncRef == nullptr || weakFuncRef == nullptr || this->weakFuncRef == weakFuncRef);
this->weakFuncRef = weakFuncRef;
}
void SetPolymorphicInlineInfo(PolymorphicInlineCacheInfoIDL* inlineeInfo, PolymorphicInlineCacheInfoIDL* selfInfo, PolymorphicInlineCacheIDL* polymorphicInlineCaches)
{
this->inlineeInfo = inlineeInfo;
this->selfInfo = selfInfo;
this->polymorphicInlineCaches = polymorphicInlineCaches;
}
FunctionCodeGenJitTimeData *AddLdFldInlinee(
Recycler *const recycler,
const InlineCacheIndex inlineCacheIndex,
FunctionInfo *const inlinee);
FunctionCodeGenJitTimeData * AddCallbackInlinee(
Recycler *const recycler,
const ProfileId profiledCallSiteId,
FunctionInfo *const inlinee);
FunctionCodeGenJitTimeData * AddCallApplyTargetInlinee(
Recycler *const recycler,
const ProfileId profiledCallSiteId,
const ProfileId callApplyCallSiteId,
FunctionInfo *const inlinee);
bool IsPolymorphicCallSite(const ProfileId profiledCallSiteId) const;
// This function walks all the chained jittimedata and returns the one which match the functionInfo.
// This can return null, if the functionInfo doesn't match.
const FunctionCodeGenJitTimeData *GetJitTimeDataFromFunctionInfo(FunctionInfo *polyFunctioInfoy) const;
uint GetGlobalObjTypeSpecFldInfoCount() const { return this->globalObjTypeSpecFldInfoCount; }
Field(ObjTypeSpecFldInfo*)* GetGlobalObjTypeSpecFldInfoArray() const {return this->globalObjTypeSpecFldInfoArray; }
ObjTypeSpecFldInfo* GetGlobalObjTypeSpecFldInfo(uint propertyInfoId) const
{
Assert(this->globalObjTypeSpecFldInfoArray != nullptr && propertyInfoId < this->globalObjTypeSpecFldInfoCount);
return this->globalObjTypeSpecFldInfoArray[propertyInfoId];
}
void SetGlobalObjTypeSpecFldInfo(uint propertyInfoId, ObjTypeSpecFldInfo* info) const
{
Assert(this->globalObjTypeSpecFldInfoArray != nullptr && propertyInfoId < this->globalObjTypeSpecFldInfoCount);
this->globalObjTypeSpecFldInfoArray[propertyInfoId] = info;
}
void SetGlobalObjTypeSpecFldInfoArray(Field(ObjTypeSpecFldInfo*)* array, uint count)
{
Assert(array != nullptr);
this->globalObjTypeSpecFldInfoArray = array;
this->globalObjTypeSpecFldInfoCount = count;
}
bool GetIsInlined() const
{
return isInlined;
}
bool GetIsAggressiveInliningEnabled() const
{
return isAggressiveInliningEnabled;
}
void SetIsAggressiveInliningEnabled()
{
isAggressiveInliningEnabled = true;
}
void SetupRecursiveInlineeChain(
Recycler *const recycler,
const ProfileId profiledCallSiteId)
{
if (!inlinees)
{
inlinees = RecyclerNewArrayZ(recycler, Field(FunctionCodeGenJitTimeData *), GetFunctionBody()->GetProfiledCallSiteCount());
}
inlinees[profiledCallSiteId] = this;
inlineeCount++;
}
uint16 GetProfiledIterations() const;
PREVENT_COPY(FunctionCodeGenJitTimeData)
};
}
#endif