src: deduplicate CHECK_EQ/CHECK_NE macros
[platform/upstream/nodejs.git] / src / node_win32_etw_provider-inl.h
1 // Copyright Joyent, Inc. and other Node contributors.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to permit
8 // persons to whom the Software is furnished to do so, subject to the
9 // following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 #ifndef SRC_NODE_WIN32_ETW_PROVIDER_INL_H_
23 #define SRC_NODE_WIN32_ETW_PROVIDER_INL_H_
24
25 #include "node_win32_etw_provider.h"
26 #include "node_etw_provider.h"
27
28 namespace node {
29
30 // From node_win32_etw_provider.cc
31 extern REGHANDLE node_provider;
32 extern EventWriteFunc event_write;
33 extern int events_enabled;
34
35 #define ETW_WRITE_STRING_DATA(data_descriptor, data)                          \
36   EventDataDescCreate(data_descriptor,                                        \
37                       data,                                                   \
38                       (strlen(data) + 1) * sizeof(*data));
39
40 #define ETW_WRITE_INT32_DATA(data_descriptor, data)  \
41   EventDataDescCreate(data_descriptor, data, sizeof(int32_t));
42
43 #define ETW_WRITE_INT64_DATA(data_descriptor, data)  \
44   EventDataDescCreate(data_descriptor, data, sizeof(int64_t));
45
46 #define ETW_WRITE_ADDRESS_DATA(data_descriptor, data)  \
47   EventDataDescCreate(data_descriptor, data, sizeof(intptr_t));
48
49 #define ETW_WRITE_INT16_DATA(data_descriptor, data)  \
50   EventDataDescCreate(data_descriptor, data, sizeof(int16_t));
51
52 #define ETW_WRITE_WSTRING_DATA_LENGTH(data_descriptor, data, data_len_bytes)  \
53   EventDataDescCreate(data_descriptor,                                        \
54                       data,                                                   \
55                       data_len_bytes);
56
57 #define ETW_WRITE_NET_CONNECTION(descriptors, conn)                           \
58   ETW_WRITE_INT32_DATA(descriptors, &conn->fd);                               \
59   ETW_WRITE_INT32_DATA(descriptors + 1, &conn->port);                         \
60   ETW_WRITE_STRING_DATA(descriptors + 2, conn->remote);                       \
61   ETW_WRITE_INT32_DATA(descriptors + 3, &conn->buffered);
62
63 #define ETW_WRITE_HTTP_SERVER_REQUEST(descriptors, req)                       \
64   ETW_WRITE_STRING_DATA(descriptors, req->url);                               \
65   ETW_WRITE_STRING_DATA(descriptors + 1, req->method);                        \
66   ETW_WRITE_STRING_DATA(descriptors + 2, req->forwardedFor);
67
68 #define ETW_WRITE_HTTP_CLIENT_REQUEST(descriptors, req)                       \
69   ETW_WRITE_STRING_DATA(descriptors, req->url);                               \
70   ETW_WRITE_STRING_DATA(descriptors + 1, req->method);
71
72 #define ETW_WRITE_GC(descriptors, type, flags)                                \
73   ETW_WRITE_INT32_DATA(descriptors, &type);                                   \
74   ETW_WRITE_INT32_DATA(descriptors + 1, &flags);
75
76 #define ETW_WRITE_V8ADDRESSCHANGE(descriptors, addr1, addr2)                  \
77     ETW_WRITE_ADDRESS_DATA(descriptors, &addr1);                              \
78     ETW_WRITE_ADDRESS_DATA(descriptors + 1, &addr2);
79
80 #define ETW_WRITE_JSMETHOD_LOADUNLOAD(descriptors,                            \
81                                       context,                                \
82                                       startAddr,                              \
83                                       size,                                   \
84                                       id,                                     \
85                                       flags,                                  \
86                                       rangeId,                                \
87                                       sourceId,                               \
88                                       line,                                   \
89                                       col,                                    \
90                                       name,                                   \
91                                       name_len_bytes)                         \
92     ETW_WRITE_ADDRESS_DATA(descriptors, &context);                            \
93     ETW_WRITE_ADDRESS_DATA(descriptors + 1, &startAddr);                      \
94     ETW_WRITE_INT64_DATA(descriptors + 2, &size);                             \
95     ETW_WRITE_INT32_DATA(descriptors + 3, &id);                               \
96     ETW_WRITE_INT16_DATA(descriptors + 4, &flags);                            \
97     ETW_WRITE_INT16_DATA(descriptors + 5, &rangeId);                          \
98     ETW_WRITE_INT64_DATA(descriptors + 6, &sourceId);                         \
99     ETW_WRITE_INT32_DATA(descriptors + 7, &line);                             \
100     ETW_WRITE_INT32_DATA(descriptors + 8, &col);                              \
101     ETW_WRITE_WSTRING_DATA_LENGTH(descriptors + 9, name, name_len_bytes);
102
103
104 #define ETW_WRITE_EVENT(eventDescriptor, dataDescriptors)                     \
105   DWORD status = event_write(node_provider,                                   \
106                              &eventDescriptor,                                \
107                              sizeof(dataDescriptors) /                        \
108                                  sizeof(*dataDescriptors),                    \
109                              dataDescriptors);                                \
110   assert(status == ERROR_SUCCESS);
111
112
113 void NODE_HTTP_SERVER_REQUEST(node_dtrace_http_server_request_t* req,
114     node_dtrace_connection_t* conn, const char *remote, int port,
115     const char *method, const char *url, int fd) {
116   EVENT_DATA_DESCRIPTOR descriptors[7];
117   ETW_WRITE_HTTP_SERVER_REQUEST(descriptors, req);
118   ETW_WRITE_NET_CONNECTION(descriptors + 3, conn);
119   ETW_WRITE_EVENT(NODE_HTTP_SERVER_REQUEST_EVENT, descriptors);
120 }
121
122
123 void NODE_HTTP_SERVER_RESPONSE(node_dtrace_connection_t* conn,
124     const char *remote, int port, int fd) {
125   EVENT_DATA_DESCRIPTOR descriptors[4];
126   ETW_WRITE_NET_CONNECTION(descriptors, conn);
127   ETW_WRITE_EVENT(NODE_HTTP_SERVER_RESPONSE_EVENT, descriptors);
128 }
129
130
131 void NODE_HTTP_CLIENT_REQUEST(node_dtrace_http_client_request_t* req,
132     node_dtrace_connection_t* conn, const char *remote, int port,
133     const char *method, const char *url, int fd) {
134   EVENT_DATA_DESCRIPTOR descriptors[6];
135   ETW_WRITE_HTTP_CLIENT_REQUEST(descriptors, req);
136   ETW_WRITE_NET_CONNECTION(descriptors + 2, conn);
137   ETW_WRITE_EVENT(NODE_HTTP_CLIENT_REQUEST_EVENT, descriptors);
138 }
139
140
141 void NODE_HTTP_CLIENT_RESPONSE(node_dtrace_connection_t* conn,
142     const char *remote, int port, int fd) {
143   EVENT_DATA_DESCRIPTOR descriptors[4];
144   ETW_WRITE_NET_CONNECTION(descriptors, conn);
145   ETW_WRITE_EVENT(NODE_HTTP_CLIENT_RESPONSE_EVENT, descriptors);
146 }
147
148
149 void NODE_NET_SERVER_CONNECTION(node_dtrace_connection_t* conn,
150     const char *remote, int port, int fd) {
151   EVENT_DATA_DESCRIPTOR descriptors[4];
152   ETW_WRITE_NET_CONNECTION(descriptors, conn);
153   ETW_WRITE_EVENT(NODE_NET_SERVER_CONNECTION_EVENT, descriptors);
154 }
155
156
157 void NODE_NET_STREAM_END(node_dtrace_connection_t* conn,
158     const char *remote, int port, int fd) {
159   EVENT_DATA_DESCRIPTOR descriptors[4];
160   ETW_WRITE_NET_CONNECTION(descriptors, conn);
161   ETW_WRITE_EVENT(NODE_NET_STREAM_END_EVENT, descriptors);
162 }
163
164
165 void NODE_GC_START(v8::GCType type, v8::GCCallbackFlags flags) {
166   if (events_enabled > 0) {
167     EVENT_DATA_DESCRIPTOR descriptors[2];
168     ETW_WRITE_GC(descriptors, type, flags);
169     ETW_WRITE_EVENT(NODE_GC_START_EVENT, descriptors);
170   }
171 }
172
173
174 void NODE_GC_DONE(v8::GCType type, v8::GCCallbackFlags flags) {
175   if (events_enabled > 0) {
176     EVENT_DATA_DESCRIPTOR descriptors[2];
177     ETW_WRITE_GC(descriptors, type, flags);
178     ETW_WRITE_EVENT(NODE_GC_DONE_EVENT, descriptors);
179   }
180 }
181
182
183 void NODE_V8SYMBOL_REMOVE(const void* addr1, const void* addr2) {
184   if (events_enabled > 0) {
185     EVENT_DATA_DESCRIPTOR descriptors[2];
186     ETW_WRITE_V8ADDRESSCHANGE(descriptors, addr1, addr2);
187     ETW_WRITE_EVENT(NODE_V8SYMBOL_REMOVE_EVENT, descriptors);
188   }
189 }
190
191
192 void NODE_V8SYMBOL_MOVE(const void* addr1, const void* addr2) {
193   if (events_enabled > 0) {
194     EVENT_DATA_DESCRIPTOR descriptors[2];
195     ETW_WRITE_V8ADDRESSCHANGE(descriptors, addr1, addr2);
196     ETW_WRITE_EVENT(NODE_V8SYMBOL_MOVE_EVENT, descriptors);
197   }
198 }
199
200
201 void NODE_V8SYMBOL_RESET() {
202   if (events_enabled > 0) {
203     int val = 0;
204     EVENT_DATA_DESCRIPTOR descriptors[1];
205     ETW_WRITE_INT32_DATA(descriptors, &val);
206     ETW_WRITE_EVENT(NODE_V8SYMBOL_RESET_EVENT, descriptors);
207   }
208 }
209
210 #define SETSYMBUF(s)  \
211   wcscpy(symbuf, s);  \
212   symbol_len = ARRAY_SIZE(s) - 1;
213
214 void NODE_V8SYMBOL_ADD(LPCSTR symbol,
215                        int symbol_len,
216                        const void* addr1,
217                        int len) {
218   if (events_enabled > 0) {
219     wchar_t symbuf[128];
220     if (symbol == NULL) {
221       SETSYMBUF(L"NULL");
222     } else {
223       symbol_len = MultiByteToWideChar(CP_ACP,
224                                        0,
225                                        symbol,
226                                        symbol_len,
227                                        symbuf,
228                                        128);
229       if (symbol_len == 0) {
230         SETSYMBUF(L"Invalid");
231       } else {
232         if (symbol_len > 127) {
233           symbol_len = 127;
234         }
235         symbuf[symbol_len] = L'\0';
236       }
237     }
238     void* context = NULL;
239     INT64 size = (INT64)len;
240     INT32 id = (INT32)addr1;
241     INT16 flags = 0;
242     INT16 rangeid = 1;
243     INT32 col = 1;
244     INT32 line = 1;
245     INT64 sourceid = 0;
246     EVENT_DATA_DESCRIPTOR descriptors[10];
247     ETW_WRITE_JSMETHOD_LOADUNLOAD(descriptors,
248                                   context,
249                                   addr1,
250                                   size,
251                                   id,
252                                   flags,
253                                   rangeid,
254                                   sourceid,
255                                   line,
256                                   col,
257                                   symbuf,
258                                   symbol_len * sizeof(symbuf[0]));
259     ETW_WRITE_EVENT(MethodLoad, descriptors);
260   }
261 }
262 #undef SETSYMBUF
263
264
265 bool NODE_HTTP_SERVER_REQUEST_ENABLED() { return events_enabled > 0; }
266 bool NODE_HTTP_SERVER_RESPONSE_ENABLED() { return events_enabled > 0; }
267 bool NODE_HTTP_CLIENT_REQUEST_ENABLED() { return events_enabled > 0; }
268 bool NODE_HTTP_CLIENT_RESPONSE_ENABLED() { return events_enabled > 0; }
269 bool NODE_NET_SERVER_CONNECTION_ENABLED() { return events_enabled > 0; }
270 bool NODE_NET_STREAM_END_ENABLED() { return events_enabled > 0; }
271 bool NODE_NET_SOCKET_READ_ENABLED() { return events_enabled > 0; }
272 bool NODE_NET_SOCKET_WRITE_ENABLED() { return events_enabled > 0; }
273 bool NODE_V8SYMBOL_ENABLED() { return events_enabled > 0; }
274
275 }  // namespace node
276
277 #endif  // SRC_NODE_WIN32_ETW_PROVIDER_INL_H_