1 | // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
---|---|
2 | // for details. All rights reserved. Use of this source code is governed by a |
3 | // BSD-style license that can be found in the LICENSE file. |
4 | |
5 | #ifndef RUNTIME_PLATFORM_GLOBALS_H_ |
6 | #define RUNTIME_PLATFORM_GLOBALS_H_ |
7 | |
8 | #if __cplusplus >= 201703L // C++17 |
9 | #define FALL_THROUGH [[fallthrough]] // NOLINT |
10 | #elif defined(__GNUC__) && __GNUC__ >= 7 |
11 | #define FALL_THROUGH __attribute__((fallthrough)); |
12 | #elif defined(__clang__) |
13 | #define FALL_THROUGH [[clang::fallthrough]] // NOLINT |
14 | #else |
15 | #define FALL_THROUGH ((void)0) |
16 | #endif |
17 | |
18 | #if !defined(NDEBUG) && !defined(DEBUG) |
19 | #if defined(GOOGLE3) |
20 | // google3 builds use NDEBUG to indicate non-debug builds which is different |
21 | // from the way the Dart project expects it: DEBUG indicating a debug build. |
22 | #define DEBUG |
23 | #else |
24 | // Since <cassert> uses NDEBUG to signify that assert() macros should be turned |
25 | // off, we'll define it when DEBUG is _not_ set. |
26 | #define NDEBUG |
27 | #endif // GOOGLE3 |
28 | #endif // !NDEBUG && !DEBUG |
29 | |
30 | // __STDC_FORMAT_MACROS has to be defined before including <inttypes.h> to |
31 | // enable platform independent printf format specifiers. |
32 | #ifndef __STDC_FORMAT_MACROS |
33 | #define __STDC_FORMAT_MACROS |
34 | #endif |
35 | |
36 | #if defined(_WIN32) |
37 | // Cut down on the amount of stuff that gets included via windows.h. |
38 | #if !defined(WIN32_LEAN_AND_MEAN) |
39 | #define WIN32_LEAN_AND_MEAN |
40 | #endif |
41 | |
42 | #if !defined(NOMINMAX) |
43 | #define NOMINMAX |
44 | #endif |
45 | |
46 | #if !defined(NOKERNEL) |
47 | #define NOKERNEL |
48 | #endif |
49 | |
50 | #if !defined(NOSERVICE) |
51 | #define NOSERVICE |
52 | #endif |
53 | |
54 | #if !defined(NOSOUND) |
55 | #define NOSOUND |
56 | #endif |
57 | |
58 | #if !defined(NOMCX) |
59 | #define NOMCX |
60 | #endif |
61 | |
62 | #if !defined(UNICODE) |
63 | #define _UNICODE |
64 | #define UNICODE |
65 | #endif |
66 | |
67 | #include <Rpc.h> |
68 | #include <VersionHelpers.h> |
69 | #include <intrin.h> |
70 | #include <shellapi.h> |
71 | #include <windows.h> |
72 | #include <winsock2.h> |
73 | #endif // defined(_WIN32) |
74 | |
75 | #if !defined(_WIN32) |
76 | #include <arpa/inet.h> |
77 | #include <unistd.h> |
78 | #endif // !defined(_WIN32) |
79 | |
80 | #include <float.h> |
81 | #include <inttypes.h> |
82 | #include <limits.h> |
83 | #include <math.h> |
84 | #include <stdarg.h> |
85 | #include <stddef.h> |
86 | #include <stdint.h> |
87 | #include <stdio.h> |
88 | #include <stdlib.h> |
89 | #include <string.h> |
90 | #include <sys/types.h> |
91 | |
92 | #include <cassert> // For assert() in constant expressions. |
93 | |
94 | #if defined(_WIN32) |
95 | #include "platform/floating_point_win.h" |
96 | #endif // defined(_WIN32) |
97 | |
98 | #if !defined(_WIN32) |
99 | #include "platform/floating_point.h" |
100 | #endif // !defined(_WIN32) |
101 | |
102 | // Target OS detection. |
103 | // for more information on predefined macros: |
104 | // - http://msdn.microsoft.com/en-us/library/b0084kay.aspx |
105 | // - with gcc, run: "echo | gcc -E -dM -" |
106 | #if defined(__ANDROID__) |
107 | |
108 | // Check for Android first, to determine its difference from Linux. |
109 | #define DART_HOST_OS_ANDROID 1 |
110 | |
111 | #elif defined(__linux__) || defined(__FreeBSD__) |
112 | |
113 | // Generic Linux. |
114 | #define DART_HOST_OS_LINUX 1 |
115 | |
116 | #elif defined(__APPLE__) |
117 | |
118 | // Define the flavor of Mac OS we are running on. |
119 | #include <TargetConditionals.h> |
120 | #define DART_HOST_OS_MACOS 1 |
121 | #if TARGET_OS_IPHONE |
122 | #define DART_HOST_OS_IOS 1 |
123 | #endif |
124 | |
125 | #elif defined(_WIN32) |
126 | |
127 | // Windows, both 32- and 64-bit, regardless of the check for _WIN32. |
128 | #define DART_HOST_OS_WINDOWS 1 |
129 | |
130 | #elif defined(__Fuchsia__) |
131 | #define DART_HOST_OS_FUCHSIA |
132 | |
133 | #elif !defined(DART_HOST_OS_FUCHSIA) |
134 | #error Automatic target os detection failed. |
135 | #endif |
136 | |
137 | #if defined(DEBUG) |
138 | #define DEBUG_ONLY(code) code |
139 | #else // defined(DEBUG) |
140 | #define DEBUG_ONLY(code) |
141 | #endif // defined(DEBUG) |
142 | |
143 | namespace dart { |
144 | |
145 | struct simd128_value_t { |
146 | union { |
147 | int32_t int_storage[4]; |
148 | int64_t int64_storage[2]; |
149 | float float_storage[4]; |
150 | double double_storage[2]; |
151 | }; |
152 | simd128_value_t& readFrom(const float* v) { |
153 | float_storage[0] = v[0]; |
154 | float_storage[1] = v[1]; |
155 | float_storage[2] = v[2]; |
156 | float_storage[3] = v[3]; |
157 | return *this; |
158 | } |
159 | simd128_value_t& readFrom(const int32_t* v) { |
160 | int_storage[0] = v[0]; |
161 | int_storage[1] = v[1]; |
162 | int_storage[2] = v[2]; |
163 | int_storage[3] = v[3]; |
164 | return *this; |
165 | } |
166 | simd128_value_t& readFrom(const double* v) { |
167 | double_storage[0] = v[0]; |
168 | double_storage[1] = v[1]; |
169 | return *this; |
170 | } |
171 | simd128_value_t& readFrom(const simd128_value_t* v) { |
172 | *this = *v; |
173 | return *this; |
174 | } |
175 | void writeTo(float* v) { |
176 | v[0] = float_storage[0]; |
177 | v[1] = float_storage[1]; |
178 | v[2] = float_storage[2]; |
179 | v[3] = float_storage[3]; |
180 | } |
181 | void writeTo(int32_t* v) { |
182 | v[0] = int_storage[0]; |
183 | v[1] = int_storage[1]; |
184 | v[2] = int_storage[2]; |
185 | v[3] = int_storage[3]; |
186 | } |
187 | void writeTo(double* v) { |
188 | v[0] = double_storage[0]; |
189 | v[1] = double_storage[1]; |
190 | } |
191 | void writeTo(simd128_value_t* v) { *v = *this; } |
192 | }; |
193 | |
194 | // Processor architecture detection. For more info on what's defined, see: |
195 | // http://msdn.microsoft.com/en-us/library/b0084kay.aspx |
196 | // http://www.agner.org/optimize/calling_conventions.pdf |
197 | // or with gcc, run: "echo | gcc -E -dM -" |
198 | #if defined(_M_X64) || defined(__x86_64__) |
199 | #define HOST_ARCH_X64 1 |
200 | #define ARCH_IS_64_BIT 1 |
201 | #elif defined(_M_IX86) || defined(__i386__) |
202 | #define HOST_ARCH_IA32 1 |
203 | #define ARCH_IS_32_BIT 1 |
204 | #elif defined(_M_ARM) || defined(__ARMEL__) |
205 | #define HOST_ARCH_ARM 1 |
206 | #define ARCH_IS_32_BIT 1 |
207 | #elif defined(_M_ARM64) || defined(__aarch64__) |
208 | #define HOST_ARCH_ARM64 1 |
209 | #define ARCH_IS_64_BIT 1 |
210 | #elif defined(__riscv) |
211 | #if __SIZEOF_POINTER__ == 4 |
212 | #define HOST_ARCH_RISCV32 1 |
213 | #define ARCH_IS_32_BIT 1 |
214 | #elif __SIZEOF_POINTER__ == 8 |
215 | #define HOST_ARCH_RISCV64 1 |
216 | #define ARCH_IS_64_BIT 1 |
217 | #else |
218 | #error Unknown XLEN |
219 | #endif |
220 | #else |
221 | #error Architecture was not detected as supported by Dart. |
222 | #endif |
223 | |
224 | // DART_FORCE_INLINE strongly hints to the compiler that a function should |
225 | // be inlined. Your function is not guaranteed to be inlined but this is |
226 | // stronger than just using "inline". |
227 | // See: http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx for an |
228 | // explanation of some the cases when a function can never be inlined. |
229 | #ifdef _MSC_VER |
230 | #define DART_FORCE_INLINE __forceinline |
231 | #elif __GNUC__ |
232 | #define DART_FORCE_INLINE inline __attribute__((always_inline)) |
233 | #else |
234 | #error Automatic compiler detection failed. |
235 | #endif |
236 | |
237 | // DART_NOINLINE tells compiler to never inline a particular function. |
238 | #ifdef _MSC_VER |
239 | #define DART_NOINLINE __declspec(noinline) |
240 | #elif __GNUC__ |
241 | #define DART_NOINLINE __attribute__((noinline)) |
242 | #else |
243 | #error Automatic compiler detection failed. |
244 | #endif |
245 | |
246 | #ifdef _MSC_VER |
247 | #elif __GNUC__ |
248 | #define DART_HAS_COMPUTED_GOTO 1 |
249 | #else |
250 | #error Automatic compiler detection failed. |
251 | #endif |
252 | |
253 | // LIKELY/UNLIKELY give the compiler branch predictions that may affect block |
254 | // scheduling. |
255 | #ifdef __GNUC__ |
256 | #define LIKELY(cond) __builtin_expect((cond), 1) |
257 | #define UNLIKELY(cond) __builtin_expect((cond), 0) |
258 | #else |
259 | #define LIKELY(cond) cond |
260 | #define UNLIKELY(cond) cond |
261 | #endif |
262 | |
263 | // DART_UNUSED indicates to the compiler that a variable or typedef is expected |
264 | // to be unused and disables the related warning. |
265 | #ifdef __GNUC__ |
266 | #define DART_UNUSED __attribute__((unused)) |
267 | #else |
268 | #define DART_UNUSED |
269 | #endif |
270 | |
271 | // DART_USED indicates to the compiler that a global variable or typedef is used |
272 | // disables e.g. the gcc warning "unused-variable" |
273 | #ifdef __GNUC__ |
274 | #define DART_USED __attribute__((used)) |
275 | #else |
276 | #define DART_USED |
277 | #endif |
278 | |
279 | // DART_NORETURN indicates to the compiler that a function does not return. |
280 | // It should be used on functions that unconditionally call functions like |
281 | // exit(), which end the program. We use it to avoid compiler warnings in |
282 | // callers of DART_NORETURN functions. |
283 | #ifdef _MSC_VER |
284 | #define DART_NORETURN __declspec(noreturn) |
285 | #elif __GNUC__ |
286 | #define DART_NORETURN __attribute__((noreturn)) |
287 | #else |
288 | #error Automatic compiler detection failed. |
289 | #endif |
290 | |
291 | #ifdef _MSC_VER |
292 | #define DART_PRETTY_FUNCTION __FUNCSIG__ |
293 | #elif __GNUC__ |
294 | #define DART_PRETTY_FUNCTION __PRETTY_FUNCTION__ |
295 | #else |
296 | #error Automatic compiler detection failed. |
297 | #endif |
298 | |
299 | #if !defined(TARGET_ARCH_ARM) && !defined(TARGET_ARCH_X64) && \ |
300 | !defined(TARGET_ARCH_IA32) && !defined(TARGET_ARCH_ARM64) && \ |
301 | !defined(TARGET_ARCH_RISCV32) && !defined(TARGET_ARCH_RISCV64) |
302 | // No target architecture specified pick the one matching the host architecture. |
303 | #if defined(HOST_ARCH_ARM) |
304 | #define TARGET_ARCH_ARM 1 |
305 | #elif defined(HOST_ARCH_X64) |
306 | #define TARGET_ARCH_X64 1 |
307 | #elif defined(HOST_ARCH_IA32) |
308 | #define TARGET_ARCH_IA32 1 |
309 | #elif defined(HOST_ARCH_ARM64) |
310 | #define TARGET_ARCH_ARM64 1 |
311 | #elif defined(HOST_ARCH_RISCV32) |
312 | #define TARGET_ARCH_RISCV32 1 |
313 | #elif defined(HOST_ARCH_RISCV64) |
314 | #define TARGET_ARCH_RISCV64 1 |
315 | #else |
316 | #error Automatic target architecture detection failed. |
317 | #endif |
318 | #endif |
319 | |
320 | #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) || \ |
321 | defined(TARGET_ARCH_RISCV32) |
322 | #define TARGET_ARCH_IS_32_BIT 1 |
323 | #elif defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_ARM64) || \ |
324 | defined(TARGET_ARCH_RISCV64) |
325 | #define TARGET_ARCH_IS_64_BIT 1 |
326 | #else |
327 | #error Automatic target architecture detection failed. |
328 | #endif |
329 | |
330 | #if defined(TARGET_ARCH_IS_64_BIT) && !defined(DART_COMPRESSED_POINTERS) |
331 | #define HAS_SMI_63_BITS 1 |
332 | #endif |
333 | |
334 | // Verify that host and target architectures match, we cannot |
335 | // have a 64 bit Dart VM generating 32 bit code or vice-versa. |
336 | #if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_ARM64) || \ |
337 | defined(TARGET_ARCH_RISCV64) |
338 | #if !defined(ARCH_IS_64_BIT) && !defined(FFI_UNIT_TESTS) |
339 | #error Mismatched Host/Target architectures. |
340 | #endif // !defined(ARCH_IS_64_BIT) && !defined(FFI_UNIT_TESTS) |
341 | #elif defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) || \ |
342 | defined(TARGET_ARCH_RISCV32) |
343 | #if defined(ARCH_IS_64_BIT) && defined(TARGET_ARCH_ARM) |
344 | // This is simarm_x64 or simarm_arm64, which is the only case where host/target |
345 | // architecture mismatch is allowed. Unless, we're running FFI unit tests. |
346 | #define IS_SIMARM_HOST64 1 |
347 | #elif !defined(ARCH_IS_32_BIT) && !defined(FFI_UNIT_TESTS) |
348 | #error Mismatched Host/Target architectures. |
349 | #endif // !defined(ARCH_IS_32_BIT) && !defined(FFI_UNIT_TESTS) |
350 | #endif // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) |
351 | |
352 | // Determine whether we will be using the simulator. |
353 | #if defined(TARGET_ARCH_IA32) |
354 | #if !defined(HOST_ARCH_IA32) |
355 | #define USING_SIMULATOR 1 |
356 | #endif |
357 | #elif defined(TARGET_ARCH_X64) |
358 | #if !defined(HOST_ARCH_X64) |
359 | #define USING_SIMULATOR 1 |
360 | #endif |
361 | #elif defined(TARGET_ARCH_ARM) |
362 | #if !defined(HOST_ARCH_ARM) |
363 | #define TARGET_HOST_MISMATCH 1 |
364 | #if !defined(IS_SIMARM_HOST64) |
365 | #define USING_SIMULATOR 1 |
366 | #endif |
367 | #endif |
368 | #elif defined(TARGET_ARCH_ARM64) |
369 | #if !defined(HOST_ARCH_ARM64) |
370 | #define USING_SIMULATOR 1 |
371 | #endif |
372 | #elif defined(TARGET_ARCH_RISCV32) |
373 | #if !defined(HOST_ARCH_RISCV32) |
374 | #define USING_SIMULATOR 1 |
375 | #endif |
376 | #elif defined(TARGET_ARCH_RISCV64) |
377 | #if !defined(HOST_ARCH_RISCV64) |
378 | #define USING_SIMULATOR 1 |
379 | #endif |
380 | #else |
381 | #error Unknown architecture. |
382 | #endif |
383 | |
384 | #if !defined(DART_TARGET_OS_ANDROID) && !defined(DART_TARGET_OS_FUCHSIA) && \ |
385 | !defined(DART_TARGET_OS_MACOS_IOS) && !defined(DART_TARGET_OS_LINUX) && \ |
386 | !defined(DART_TARGET_OS_MACOS) && !defined(DART_TARGET_OS_WINDOWS) |
387 | // No target OS specified; pick the one matching the host OS. |
388 | #if defined(DART_HOST_OS_ANDROID) |
389 | #define DART_TARGET_OS_ANDROID 1 |
390 | #elif defined(DART_HOST_OS_FUCHSIA) |
391 | #define DART_TARGET_OS_FUCHSIA 1 |
392 | #elif defined(DART_HOST_OS_IOS) |
393 | #define DART_TARGET_OS_MACOS 1 |
394 | #define DART_TARGET_OS_MACOS_IOS 1 |
395 | #elif defined(DART_HOST_OS_LINUX) |
396 | #define DART_TARGET_OS_LINUX 1 |
397 | #elif defined(DART_HOST_OS_MACOS) |
398 | #define DART_TARGET_OS_MACOS 1 |
399 | #elif defined(DART_HOST_OS_WINDOWS) |
400 | #define DART_TARGET_OS_WINDOWS 1 |
401 | #else |
402 | #error Automatic target OS detection failed. |
403 | #endif |
404 | #endif |
405 | |
406 | // Determine whether dual mapping of code pages is supported. |
407 | // We test dual mapping on linux x64 and deploy it on fuchsia. |
408 | #if !defined(DART_PRECOMPILED_RUNTIME) && \ |
409 | (defined(DART_TARGET_OS_LINUX) && defined(TARGET_ARCH_X64) || \ |
410 | defined(DART_TARGET_OS_FUCHSIA)) |
411 | #define DUAL_MAPPING_SUPPORTED 1 |
412 | #endif |
413 | |
414 | // Short form printf format specifiers |
415 | #define Pd PRIdPTR |
416 | #define Pu PRIuPTR |
417 | #define Px PRIxPTR |
418 | #define PX PRIXPTR |
419 | #define Pd32 PRId32 |
420 | #define Pu32 PRIu32 |
421 | #define Px32 PRIx32 |
422 | #define PX32 PRIX32 |
423 | #define Pd64 PRId64 |
424 | #define Pu64 PRIu64 |
425 | #define Px64 PRIx64 |
426 | #define PX64 PRIX64 |
427 | |
428 | // Zero-padded pointer |
429 | #if defined(ARCH_IS_32_BIT) |
430 | #define Pp "08" PRIxPTR |
431 | #else |
432 | #define Pp "016" PRIxPTR |
433 | #endif |
434 | |
435 | // Suffixes for 64-bit integer literals. |
436 | #ifdef _MSC_VER |
437 | #define DART_INT64_C(x) x##I64 |
438 | #define DART_UINT64_C(x) x##UI64 |
439 | #else |
440 | #define DART_INT64_C(x) x##LL |
441 | #define DART_UINT64_C(x) x##ULL |
442 | #endif |
443 | |
444 | // Replace calls to strtoll with _strtoi64 on Windows. |
445 | #ifdef _MSC_VER |
446 | #define strtoll _strtoi64 |
447 | #endif |
448 | |
449 | // Byte sizes. |
450 | constexpr int kInt8SizeLog2 = 0; |
451 | constexpr int kInt8Size = 1 << kInt8SizeLog2; |
452 | static_assert(kInt8Size == sizeof(int8_t), "Mismatched int8 size constant"); |
453 | constexpr int kInt16SizeLog2 = 1; |
454 | constexpr int kInt16Size = 1 << kInt16SizeLog2; |
455 | static_assert(kInt16Size == sizeof(int16_t), "Mismatched int16 size constant"); |
456 | constexpr int kInt32SizeLog2 = 2; |
457 | constexpr int kInt32Size = 1 << kInt32SizeLog2; |
458 | static_assert(kInt32Size == sizeof(int32_t), "Mismatched int32 size constant"); |
459 | constexpr int kInt64SizeLog2 = 3; |
460 | constexpr int kInt64Size = 1 << kInt64SizeLog2; |
461 | static_assert(kInt64Size == sizeof(int64_t), "Mismatched int64 size constant"); |
462 | |
463 | constexpr int kDoubleSize = sizeof(double); |
464 | constexpr int kFloatSize = sizeof(float); |
465 | constexpr int kQuadSize = 4 * kFloatSize; |
466 | constexpr int kSimd128Size = sizeof(simd128_value_t); |
467 | |
468 | // Bit sizes. |
469 | constexpr int kBitsPerByteLog2 = 3; |
470 | constexpr int kBitsPerByte = 1 << kBitsPerByteLog2; |
471 | constexpr int kBitsPerInt8 = kInt8Size * kBitsPerByte; |
472 | constexpr int kBitsPerInt16 = kInt16Size * kBitsPerByte; |
473 | constexpr int kBitsPerInt32 = kInt32Size * kBitsPerByte; |
474 | constexpr int kBitsPerInt64 = kInt64Size * kBitsPerByte; |
475 | |
476 | // The following macro works on both 32 and 64-bit platforms. |
477 | // Usage: instead of writing 0x1234567890123456ULL |
478 | // write DART_2PART_UINT64_C(0x12345678,90123456); |
479 | #define DART_2PART_UINT64_C(a, b) \ |
480 | (((static_cast<uint64_t>(a) << kBitsPerInt32) + 0x##b##u)) |
481 | |
482 | // Integer constants. |
483 | constexpr int8_t kMinInt8 = 0x80; |
484 | constexpr int8_t kMaxInt8 = 0x7F; |
485 | constexpr uint8_t kMaxUint8 = 0xFF; |
486 | constexpr int16_t kMinInt16 = 0x8000; |
487 | constexpr int16_t kMaxInt16 = 0x7FFF; |
488 | constexpr uint16_t kMaxUint16 = 0xFFFF; |
489 | constexpr int32_t kMinInt32 = 0x80000000; |
490 | constexpr int32_t kMaxInt32 = 0x7FFFFFFF; |
491 | constexpr uint32_t kMaxUint32 = 0xFFFFFFFF; |
492 | constexpr int64_t kMinInt64 = DART_INT64_C(0x8000000000000000); |
493 | constexpr int64_t kMaxInt64 = DART_INT64_C(0x7FFFFFFFFFFFFFFF); |
494 | constexpr uint64_t kMaxUint64 = DART_2PART_UINT64_C(0xFFFFFFFF, FFFFFFFF); |
495 | |
496 | constexpr int kMinInt = INT_MIN; |
497 | constexpr int kMaxInt = INT_MAX; |
498 | constexpr int kMaxUint = UINT_MAX; |
499 | |
500 | constexpr int64_t kMinInt64RepresentableAsDouble = kMinInt64; |
501 | constexpr int64_t kMaxInt64RepresentableAsDouble = |
502 | DART_INT64_C(0x7FFFFFFFFFFFFC00); |
503 | constexpr int64_t kSignBitDouble = DART_INT64_C(0x8000000000000000); |
504 | |
505 | // Types for native machine words. Guaranteed to be able to hold pointers and |
506 | // integers. |
507 | typedef intptr_t word; |
508 | typedef uintptr_t uword; |
509 | |
510 | // Byte sizes for native machine words. |
511 | #ifdef ARCH_IS_32_BIT |
512 | constexpr int kWordSizeLog2 = kInt32SizeLog2; |
513 | #else |
514 | constexpr int kWordSizeLog2 = kInt64SizeLog2; |
515 | #endif |
516 | constexpr int kWordSize = 1 << kWordSizeLog2; |
517 | static_assert(kWordSize == sizeof(word), "Mismatched word size constant"); |
518 | |
519 | // Bit sizes for native machine words. |
520 | constexpr int kBitsPerWordLog2 = kWordSizeLog2 + kBitsPerByteLog2; |
521 | constexpr int kBitsPerWord = 1 << kBitsPerWordLog2; |
522 | |
523 | // Integer constants for native machine words. |
524 | constexpr word kWordMin = static_cast<uword>(1) << (kBitsPerWord - 1); |
525 | constexpr word kWordMax = (static_cast<uword>(1) << (kBitsPerWord - 1)) - 1; |
526 | constexpr uword kUwordMax = static_cast<uword>(-1); |
527 | |
528 | // Size of a class id assigned to concrete, abstract and top-level classes. |
529 | // |
530 | // We use a signed integer type here to make it comparable with intptr_t. |
531 | typedef int32_t classid_t; |
532 | |
533 | // System-wide named constants. |
534 | constexpr intptr_t KBLog2 = 10; |
535 | constexpr intptr_t KB = 1 << KBLog2; |
536 | constexpr intptr_t MBLog2 = KBLog2 + KBLog2; |
537 | constexpr intptr_t MB = 1 << MBLog2; |
538 | constexpr intptr_t GBLog2 = MBLog2 + KBLog2; |
539 | constexpr intptr_t GB = 1 << GBLog2; |
540 | |
541 | constexpr intptr_t KBInWordsLog2 = KBLog2 - kWordSizeLog2; |
542 | constexpr intptr_t KBInWords = 1 << KBInWordsLog2; |
543 | constexpr intptr_t MBInWordsLog2 = KBLog2 + KBInWordsLog2; |
544 | constexpr intptr_t MBInWords = 1 << MBInWordsLog2; |
545 | constexpr intptr_t GBInWordsLog2 = MBLog2 + KBInWordsLog2; |
546 | constexpr intptr_t GBInWords = 1 << GBInWordsLog2; |
547 | |
548 | // Helpers to round memory sizes to human readable values. |
549 | constexpr intptr_t RoundWordsToKB(intptr_t size_in_words) { |
550 | return (size_in_words + (KBInWords >> 1)) >> KBInWordsLog2; |
551 | } |
552 | constexpr intptr_t RoundWordsToMB(intptr_t size_in_words) { |
553 | return (size_in_words + (MBInWords >> 1)) >> MBInWordsLog2; |
554 | } |
555 | constexpr intptr_t RoundWordsToGB(intptr_t size_in_words) { |
556 | return (size_in_words + (GBInWords >> 1)) >> GBInWordsLog2; |
557 | } |
558 | constexpr double WordsToMB(intptr_t size_in_words) { |
559 | return static_cast<double>(size_in_words) / MBInWords; |
560 | } |
561 | |
562 | constexpr intptr_t kIntptrOne = 1; |
563 | constexpr intptr_t kIntptrMin = (kIntptrOne << (kBitsPerWord - 1)); |
564 | constexpr intptr_t kIntptrMax = ~kIntptrMin; |
565 | |
566 | // Time constants. |
567 | constexpr int kMillisecondsPerSecond = 1000; |
568 | constexpr int kMicrosecondsPerMillisecond = 1000; |
569 | constexpr int kMicrosecondsPerSecond = |
570 | (kMicrosecondsPerMillisecond * kMillisecondsPerSecond); |
571 | constexpr int kNanosecondsPerMicrosecond = 1000; |
572 | constexpr int kNanosecondsPerMillisecond = |
573 | (kNanosecondsPerMicrosecond * kMicrosecondsPerMillisecond); |
574 | constexpr int kNanosecondsPerSecond = |
575 | (kNanosecondsPerMicrosecond * kMicrosecondsPerSecond); |
576 | |
577 | // Helpers to scale micro second times to human understandable values. |
578 | constexpr double MicrosecondsToSeconds(int64_t micros) { |
579 | return static_cast<double>(micros) / kMicrosecondsPerSecond; |
580 | } |
581 | constexpr double MicrosecondsToMilliseconds(int64_t micros) { |
582 | return static_cast<double>(micros) / kMicrosecondsPerMillisecond; |
583 | } |
584 | |
585 | // A macro to disallow the copy constructor and operator= functions. |
586 | // This should be used in the private: declarations for a class. |
587 | #if !defined(DISALLOW_COPY_AND_ASSIGN) |
588 | #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ |
589 | private: \ |
590 | TypeName(const TypeName&) = delete; \ |
591 | void operator=(const TypeName&) = delete |
592 | #endif // !defined(DISALLOW_COPY_AND_ASSIGN) |
593 | |
594 | // A macro to disallow all the implicit constructors, namely the default |
595 | // constructor, copy constructor and operator= functions. This should be |
596 | // used in the private: declarations for a class that wants to prevent |
597 | // anyone from instantiating it. This is especially useful for classes |
598 | // containing only static methods. |
599 | #if !defined(DISALLOW_IMPLICIT_CONSTRUCTORS) |
600 | #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ |
601 | private: \ |
602 | TypeName() = delete; \ |
603 | DISALLOW_COPY_AND_ASSIGN(TypeName) |
604 | #endif // !defined(DISALLOW_IMPLICIT_CONSTRUCTORS) |
605 | |
606 | // Macro to disallow allocation in the C++ heap. This should be used |
607 | // in the private section for a class. Don't use UNREACHABLE here to |
608 | // avoid circular dependencies between platform/globals.h and |
609 | // platform/assert.h. |
610 | #if !defined(DISALLOW_ALLOCATION) |
611 | #define DISALLOW_ALLOCATION() \ |
612 | public: \ |
613 | void operator delete(void* pointer) { \ |
614 | fprintf(stderr, "unreachable code\n"); \ |
615 | abort(); \ |
616 | } \ |
617 | \ |
618 | private: \ |
619 | void* operator new(size_t size); |
620 | #endif // !defined(DISALLOW_ALLOCATION) |
621 | |
622 | // The USE(x) template is used to silence C++ compiler warnings issued |
623 | // for unused variables. |
624 | template <typename T> |
625 | static inline void USE(T&&) {} |
626 | |
627 | // The type-based aliasing rule allows the compiler to assume that |
628 | // pointers of different types (for some definition of different) |
629 | // never alias each other. Thus the following code does not work: |
630 | // |
631 | // float f = foo(); |
632 | // int fbits = *(int*)(&f); |
633 | // |
634 | // The compiler 'knows' that the int pointer can't refer to f since |
635 | // the types don't match, so the compiler may cache f in a register, |
636 | // leaving random data in fbits. Using C++ style casts makes no |
637 | // difference, however a pointer to char data is assumed to alias any |
638 | // other pointer. This is the 'memcpy exception'. |
639 | // |
640 | // The bit_cast function uses the memcpy exception to move the bits |
641 | // from a variable of one type to a variable of another type. Of |
642 | // course the end result is likely to be implementation dependent. |
643 | // Most compilers (gcc-4.2 and MSVC 2005) will completely optimize |
644 | // bit_cast away. |
645 | // |
646 | // There is an additional use for bit_cast. Recent gccs will warn when |
647 | // they see casts that may result in breakage due to the type-based |
648 | // aliasing rule. If you have checked that there is no breakage you |
649 | // can use bit_cast to cast one pointer type to another. This confuses |
650 | // gcc enough that it can no longer see that you have cast one pointer |
651 | // type to another thus avoiding the warning. |
652 | template <class D, class S> |
653 | DART_FORCE_INLINE D bit_cast(const S& source) { |
654 | static_assert(sizeof(D) == sizeof(S), |
655 | "Source and destination must have the same size"); |
656 | |
657 | D destination; |
658 | // This use of memcpy is safe: source and destination cannot overlap. |
659 | memcpy(&destination, &source, sizeof(destination)); |
660 | return destination; |
661 | } |
662 | |
663 | // Similar to bit_cast, but allows copying from types of unrelated |
664 | // sizes. This method was introduced to enable the strict aliasing |
665 | // optimizations of GCC 4.4. Basically, GCC mindlessly relies on |
666 | // obscure details in the C++ standard that make reinterpret_cast |
667 | // virtually useless. |
668 | template <class D, class S> |
669 | DART_FORCE_INLINE D bit_copy(const S& source) { |
670 | D destination; |
671 | // This use of memcpy is safe: source and destination cannot overlap. |
672 | memcpy(&destination, reinterpret_cast<const void*>(&source), |
673 | sizeof(destination)); |
674 | return destination; |
675 | } |
676 | |
677 | // On Windows the reentrant version of strtok is called |
678 | // strtok_s. Unify on the posix name strtok_r. |
679 | #if defined(DART_HOST_OS_WINDOWS) |
680 | #define snprintf _sprintf_p |
681 | #define strtok_r strtok_s |
682 | #endif |
683 | |
684 | #if !defined(DART_HOST_OS_WINDOWS) |
685 | #if defined(TEMP_FAILURE_RETRY) |
686 | // TEMP_FAILURE_RETRY is defined in unistd.h on some platforms. We should |
687 | // not use that version, but instead the one in signal_blocker.h, to ensure |
688 | // we disable signal interrupts. |
689 | #undef TEMP_FAILURE_RETRY |
690 | #endif // defined(TEMP_FAILURE_RETRY) |
691 | #endif // !defined(DART_HOST_OS_WINDOWS) |
692 | |
693 | #if __GNUC__ |
694 | // Tell the compiler to do printf format string checking if the |
695 | // compiler supports it; see the 'format' attribute in |
696 | // <http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Function-Attributes.html>. |
697 | // |
698 | // N.B.: As the GCC manual states, "[s]ince non-static C++ methods |
699 | // have an implicit 'this' argument, the arguments of such methods |
700 | // should be counted from two, not one." |
701 | #define PRINTF_ATTRIBUTE(string_index, first_to_check) \ |
702 | __attribute__((__format__(__printf__, string_index, first_to_check))) |
703 | #else |
704 | #define PRINTF_ATTRIBUTE(string_index, first_to_check) |
705 | #endif |
706 | |
707 | #if defined(_WIN32) |
708 | #define STDIN_FILENO 0 |
709 | #define STDOUT_FILENO 1 |
710 | #define STDERR_FILENO 2 |
711 | #endif |
712 | |
713 | #ifndef PATH_MAX |
714 | // Most platforms use PATH_MAX, but in Windows it's called MAX_PATH. |
715 | #define PATH_MAX MAX_PATH |
716 | #endif |
717 | |
718 | // Undefine math.h definition which clashes with our condition names. |
719 | #undef OVERFLOW |
720 | |
721 | // Include IL printer and disassembler functionality into non-PRODUCT builds, |
722 | // in all AOT compiler builds or when forced. |
723 | #if !defined(PRODUCT) || defined(DART_PRECOMPILER) || \ |
724 | defined(FORCE_INCLUDE_DISASSEMBLER) |
725 | #if defined(DART_PRECOMPILED_RUNTIME) && defined(PRODUCT) |
726 | #error Requested to include IL printer into PRODUCT AOT runtime |
727 | #endif |
728 | #define INCLUDE_IL_PRINTER 1 |
729 | #if !defined(FORCE_INCLUDE_DISASSEMBLER) |
730 | #define FORCE_INCLUDE_DISASSEMBLER 1 |
731 | #endif |
732 | #endif |
733 | |
734 | // Include HeapSnapshotWriter functionality if not in PRODUCT. |
735 | #if !defined(DART_ENABLE_HEAP_SNAPSHOT_WRITER) && !defined(PRODUCT) |
736 | #define DART_ENABLE_HEAP_SNAPSHOT_WRITER 1 |
737 | #endif |
738 | |
739 | #if defined(DART_HOST_OS_ANDROID) |
740 | #define kHostOperatingSystemName "android" |
741 | #elif defined(DART_HOST_OS_FUCHSIA) |
742 | #define kHostOperatingSystemName "fuchsia" |
743 | #elif defined(DART_HOST_OS_IOS) |
744 | #define kHostOperatingSystemName "ios" |
745 | #elif defined(DART_HOST_OS_LINUX) |
746 | #define kHostOperatingSystemName "linux" |
747 | #elif defined(DART_HOST_OS_MACOS) |
748 | #define kHostOperatingSystemName "macos" |
749 | #elif defined(DART_HOST_OS_WINDOWS) |
750 | #define kHostOperatingSystemName "windows" |
751 | #else |
752 | #error Host operating system detection failed. |
753 | #endif |
754 | |
755 | #if defined(HOST_ARCH_ARM) |
756 | #define kHostArchitectureName "arm" |
757 | #elif defined(HOST_ARCH_ARM64) |
758 | #define kHostArchitectureName "arm64" |
759 | #elif defined(HOST_ARCH_IA32) |
760 | #define kHostArchitectureName "ia32" |
761 | #elif defined(HOST_ARCH_RISCV32) |
762 | #define kHostArchitectureName "riscv32" |
763 | #elif defined(HOST_ARCH_RISCV64) |
764 | #define kHostArchitectureName "riscv64" |
765 | #elif defined(HOST_ARCH_X64) |
766 | #define kHostArchitectureName "x64" |
767 | #else |
768 | #error Host architecture detection failed. |
769 | #endif |
770 | |
771 | #if defined(TARGET_ARCH_ARM) |
772 | #define kTargetArchitectureName "arm" |
773 | #elif defined(TARGET_ARCH_ARM64) |
774 | #define kTargetArchitectureName "arm64" |
775 | #elif defined(TARGET_ARCH_IA32) |
776 | #define kTargetArchitectureName "ia32" |
777 | #elif defined(TARGET_ARCH_RISCV32) |
778 | #define kTargetArchitectureName "riscv32" |
779 | #elif defined(TARGET_ARCH_RISCV64) |
780 | #define kTargetArchitectureName "riscv64" |
781 | #elif defined(TARGET_ARCH_X64) |
782 | #define kTargetArchitectureName "x64" |
783 | #else |
784 | #error Target architecture detection failed. |
785 | #endif |
786 | |
787 | // The ordering between DART_TARGET_OS_MACOS_IOS and DART_TARGET_OS_MACOS |
788 | // below is important, since the latter is sometimes defined when the former |
789 | // is, and sometimes not (e.g., ffi tests), so we need to test the former |
790 | // before the latter. |
791 | #if defined(DART_TARGET_OS_ANDROID) |
792 | #define kTargetOperatingSystemName "android" |
793 | #elif defined(DART_TARGET_OS_FUCHSIA) |
794 | #define kTargetOperatingSystemName "fuchsia" |
795 | #elif defined(DART_TARGET_OS_LINUX) |
796 | #define kTargetOperatingSystemName "linux" |
797 | #elif defined(DART_TARGET_OS_MACOS_IOS) |
798 | #define kTargetOperatingSystemName "ios" |
799 | #elif defined(DART_TARGET_OS_MACOS) |
800 | #define kTargetOperatingSystemName "macos" |
801 | #elif defined(DART_TARGET_OS_WINDOWS) |
802 | #define kTargetOperatingSystemName "windows" |
803 | #else |
804 | #error Target operating system detection failed. |
805 | #endif |
806 | |
807 | } // namespace dart |
808 | |
809 | #endif // RUNTIME_PLATFORM_GLOBALS_H_ |
810 |
Definitions
- simd128_value_t
- readFrom
- readFrom
- readFrom
- readFrom
- writeTo
- writeTo
- writeTo
- writeTo
- kInt8SizeLog2
- kInt8Size
- kInt16SizeLog2
- kInt16Size
- kInt32SizeLog2
- kInt32Size
- kInt64SizeLog2
- kInt64Size
- kDoubleSize
- kFloatSize
- kQuadSize
- kSimd128Size
- kBitsPerByteLog2
- kBitsPerByte
- kBitsPerInt8
- kBitsPerInt16
- kBitsPerInt32
- kBitsPerInt64
- kMinInt8
- kMaxInt8
- kMaxUint8
- kMinInt16
- kMaxInt16
- kMaxUint16
- kMinInt32
- kMaxInt32
- kMaxUint32
- kMinInt64
- kMaxInt64
- kMaxUint64
- kMinInt
- kMaxInt
- kMaxUint
- kMinInt64RepresentableAsDouble
- kMaxInt64RepresentableAsDouble
- kSignBitDouble
- kWordSizeLog2
- kWordSize
- kBitsPerWordLog2
- kBitsPerWord
- kWordMin
- kWordMax
- kUwordMax
- KBLog2
- KB
- MBLog2
- MB
- GBLog2
- GB
- KBInWordsLog2
- KBInWords
- MBInWordsLog2
- MBInWords
- GBInWordsLog2
- GBInWords
- RoundWordsToKB
- RoundWordsToMB
- RoundWordsToGB
- WordsToMB
- kIntptrOne
- kIntptrMin
- kIntptrMax
- kMillisecondsPerSecond
- kMicrosecondsPerMillisecond
- kMicrosecondsPerSecond
- kNanosecondsPerMicrosecond
- kNanosecondsPerMillisecond
- kNanosecondsPerSecond
- MicrosecondsToSeconds
- MicrosecondsToMilliseconds
- USE
- bit_cast
Learn more about Flutter for embedded and desktop on industrialflutter.com