Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Side by Side Diff: runtime/vm/globals.h

Issue 9209001: Move utils.h and utils.cc from runtime/vm to runtime/platform (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed review comments from iposva@ and ager@ Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #ifndef VM_GLOBALS_H_ 5 #ifndef VM_GLOBALS_H_
6 #define VM_GLOBALS_H_ 6 #define VM_GLOBALS_H_
7 7
8 // This file contains global definitions for the VM library only. Anything that 8 // This file contains global definitions for the VM library only. Anything that
9 // is more globally useful should be added to 'vm/globals.h'. 9 // is more globally useful should be added to 'vm/globals.h'.
10 10
11 #include "platform/globals.h" 11 #include "platform/globals.h"
12 12
13 #if defined(_WIN32) 13 #if defined(_WIN32)
14 // Undef conflicting defines. 14 // Undef conflicting defines.
15 #undef PARITY_EVEN 15 #undef PARITY_EVEN
16 #undef PARITY_ODD 16 #undef PARITY_ODD
17 #undef near 17 #undef near
18 #endif 18 #endif
19 19
20 // The following #defines are invalidated. 20 // The following #defines are invalidated.
21 #undef OVERFLOW // From math.h conflicts in constants_ia32.h 21 #undef OVERFLOW // From math.h conflicts in constants_ia32.h
22 22
23 namespace dart { 23 namespace dart {
24 24
25 // Processor architecture detection. For more info on what's defined, see:
26 // http://msdn.microsoft.com/en-us/library/b0084kay.aspx
27 // http://www.agner.org/optimize/calling_conventions.pdf
28 // or with gcc, run: "echo | gcc -E -dM -"
29 #if defined(_M_X64) || defined(__x86_64__)
30 #define HOST_ARCH_X64 1
31 #define ARCH_IS_64_BIT 1
32 #elif defined(_M_IX86) || defined(__i386__)
33 #define HOST_ARCH_IA32 1
34 #define ARCH_IS_32_BIT 1
35 #elif defined(__ARMEL__)
36 #define HOST_ARCH_ARM 1
37 #define ARCH_IS_32_BIT 1
38 #else
39 #error Architecture was not detected as supported by Dart.
40 #endif
41
42 #if !defined(TARGET_ARCH_ARM)
43 #if !defined(TARGET_ARCH_X64)
44 #if !defined(TARGET_ARCH_IA32)
45 // No target architecture specified pick the one matching the host architecture.
46 #if defined(HOST_ARCH_ARM)
47 #define TARGET_ARCH_ARM 1
48 #elif defined(HOST_ARCH_X64)
49 #define TARGET_ARCH_X64 1
50 #elif defined(HOST_ARCH_IA32)
51 #define TARGET_ARCH_IA32 1
52 #else
53 #error Automatic target architecture detection failed.
54 #endif
55 #endif
56 #endif
57 #endif
58
59 // Verify that host and target architectures match, we cannot
60 // have a 64 bit Dart VM generating 32 bit code or vice-versa.
61 #if defined(TARGET_ARCH_X64)
62 #if !defined(ARCH_IS_64_BIT)
63 #error Mismatched Host/Target architectures.
64 #endif
65 #elif defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM)
66 #if !defined(ARCH_IS_32_BIT)
67 #error Mismatched Host/Target architectures.
68 #endif
69 #endif
70
71
72 // Printf format for intptr_t on Windows.
73 #if !defined(PRIxPTR) && defined(TARGET_OS_WINDOWS)
74 #if defined(ARCH_IS_32_BIT)
75 #define PRIxPTR "x"
76 #else
77 #define PRIxPTR "llx"
78 #endif // defined(ARCH_IS_32_BIT)
79 #endif // !defined(PRIxPTR) && defined(TARGET_OS_WINDOWS)
80
81
82 // Suffixes for 64-bit integer literals.
83 #ifdef _MSC_VER
84 #define DART_INT64_C(x) x##I64
85 #define DART_UINT64_C(x) x##UI64
86 #else
87 #define DART_INT64_C(x) x##LL
88 #define DART_UINT64_C(x) x##ULL
89 #endif
90
91
92 // The following macro works on both 32 and 64-bit platforms.
93 // Usage: instead of writing 0x1234567890123456
94 // write DART_2PART_UINT64_C(0x12345678,90123456);
95 #define DART_2PART_UINT64_C(a, b) \
96 (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
97
98
99 // Types for native machine words. Guaranteed to be able to hold pointers and
100 // integers.
101 typedef intptr_t word;
102 typedef uintptr_t uword;
103
104 // A type large enough to contain the value of the C++ vtable. This is needed
105 // to support the handle operations.
106 typedef uword cpp_vtable;
107
108 // Byte sizes.
109 const int kWordSize = sizeof(word);
110 #ifdef ARCH_IS_32_BIT
111 const int kWordSizeLog2 = 2;
112 #else
113 const int kWordSizeLog2 = 3;
114 #endif
115
116 // Bit sizes.
117 const int kBitsPerByte = 8;
118 const int kBitsPerByteLog2 = 3;
119 const int kBitsPerWord = kWordSize * kBitsPerByte;
120
121 // System-wide named constants.
122 const int KB = 1024;
123 const int MB = KB * KB;
124 const int GB = KB * KB * KB;
125 const intptr_t kIntptrOne = 1;
126 const intptr_t kIntptrMin = (kIntptrOne << (kBitsPerWord - 1));
127 const intptr_t kIntptrMax = ~kIntptrMin;
128
129 // Time constants.
130 const int kMillisecondsPerSecond = 1000;
131 const int kMicrosecondsPerMillisecond = 1000;
132 const int kMicrosecondsPerSecond = (kMicrosecondsPerMillisecond *
133 kMillisecondsPerSecond);
134 const int kNanosecondsPerMicrosecond = 1000;
135 const int kNanosecondsPerMillisecond = (kNanosecondsPerMicrosecond *
136 kMicrosecondsPerMillisecond);
137 const int kNanosecondsPerSecond = (kNanosecondsPerMicrosecond *
138 kMicrosecondsPerSecond);
139
140 // The expression ARRAY_SIZE(array) is a compile-time constant of type 25 // The expression ARRAY_SIZE(array) is a compile-time constant of type
141 // size_t which represents the number of elements of the given 26 // size_t which represents the number of elements of the given
142 // array. You should only use ARRAY_SIZE on statically allocated 27 // array. You should only use ARRAY_SIZE on statically allocated
143 // arrays. 28 // arrays.
144 #define ARRAY_SIZE(array) \ 29 #define ARRAY_SIZE(array) \
145 ((sizeof(array) / sizeof(*(array))) / \ 30 ((sizeof(array) / sizeof(*(array))) / \
146 static_cast<intptr_t>(!(sizeof(array) % sizeof(*(array))))) 31 static_cast<intptr_t>(!(sizeof(array) % sizeof(*(array)))))
147 32
148 33
149 // The expression OFFSET_OF(type, field) computes the byte-offset of 34 // The expression OFFSET_OF(type, field) computes the byte-offset of
150 // the specified field relative to the containing type. 35 // the specified field relative to the containing type.
151 // 36 //
152 // The expression OFFSET_OF_RETURNED_VALUE(type, accessor) computes the 37 // The expression OFFSET_OF_RETURNED_VALUE(type, accessor) computes the
153 // byte-offset of the return value of the accessor to the containing type. 38 // byte-offset of the return value of the accessor to the containing type.
154 // 39 //
155 // None of these use 0 or NULL, which causes a problem with the compiler 40 // None of these use 0 or NULL, which causes a problem with the compiler
156 // warnings we have enabled (which is also why 'offsetof' doesn't seem to work). 41 // warnings we have enabled (which is also why 'offsetof' doesn't seem to work).
157 // The workaround is to use the non-zero value kOffsetOfPtr. 42 // The workaround is to use the non-zero value kOffsetOfPtr.
158 const intptr_t kOffsetOfPtr = 32; 43 const intptr_t kOffsetOfPtr = 32;
159 44
160 #define OFFSET_OF(type, field) \ 45 #define OFFSET_OF(type, field) \
161 (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(kOffsetOfPtr)->field)) \ 46 (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(kOffsetOfPtr)->field)) \
162 - kOffsetOfPtr) 47 - kOffsetOfPtr)
163 48
164 #define OFFSET_OF_RETURNED_VALUE(type, accessor) \ 49 #define OFFSET_OF_RETURNED_VALUE(type, accessor) \
165 (reinterpret_cast<intptr_t>( \ 50 (reinterpret_cast<intptr_t>( \
166 (reinterpret_cast<type*>(kOffsetOfPtr)->accessor())) - kOffsetOfPtr) 51 (reinterpret_cast<type*>(kOffsetOfPtr)->accessor())) - kOffsetOfPtr)
167 52
168 53
169 // Use implicit_cast as a safe version of static_cast or const_cast 54 // A type large enough to contain the value of the C++ vtable. This is needed
170 // for upcasting in the type hierarchy (i.e. casting a pointer to Foo 55 // to support the handle operations.
171 // to a pointer to SuperclassOfFoo or casting a pointer to Foo to 56 typedef uword cpp_vtable;
172 // a const pointer to Foo).
173 // When you use implicit_cast, the compiler checks that the cast is safe.
174 // Such explicit implicit_casts are necessary in surprisingly many
175 // situations where C++ demands an exact type match instead of an
176 // argument type convertable to a target type.
177 //
178 // The From type can be inferred, so the preferred syntax for using
179 // implicit_cast is the same as for static_cast etc.:
180 //
181 // implicit_cast<ToType>(expr)
182 //
183 // implicit_cast would have been part of the C++ standard library,
184 // but the proposal was submitted too late. It will probably make
185 // its way into the language in the future.
186 template<typename To, typename From>
187 inline To implicit_cast(From const &f) {
188 return f;
189 }
190
191
192 // Use like this: down_cast<T*>(foo);
193 template<typename To, typename From> // use like this: down_cast<T*>(foo);
194 inline To down_cast(From* f) { // so we only accept pointers
195 // Ensures that To is a sub-type of From *. This test is here only
196 // for compile-time type checking, and has no overhead in an
197 // optimized build at run-time, as it will be optimized away completely.
198 if (false) {
199 implicit_cast<From*, To>(0);
200 }
201 return static_cast<To>(f);
202 }
203
204
205 // The type-based aliasing rule allows the compiler to assume that
206 // pointers of different types (for some definition of different)
207 // never alias each other. Thus the following code does not work:
208 //
209 // float f = foo();
210 // int fbits = *(int*)(&f);
211 //
212 // The compiler 'knows' that the int pointer can't refer to f since
213 // the types don't match, so the compiler may cache f in a register,
214 // leaving random data in fbits. Using C++ style casts makes no
215 // difference, however a pointer to char data is assumed to alias any
216 // other pointer. This is the 'memcpy exception'.
217 //
218 // The bit_cast function uses the memcpy exception to move the bits
219 // from a variable of one type to a variable of another type. Of
220 // course the end result is likely to be implementation dependent.
221 // Most compilers (gcc-4.2 and MSVC 2005) will completely optimize
222 // bit_cast away.
223 //
224 // There is an additional use for bit_cast. Recent gccs will warn when
225 // they see casts that may result in breakage due to the type-based
226 // aliasing rule. If you have checked that there is no breakage you
227 // can use bit_cast to cast one pointer type to another. This confuses
228 // gcc enough that it can no longer see that you have cast one pointer
229 // type to another thus avoiding the warning.
230 template <class D, class S>
231 inline D bit_cast(const S& source) {
232 // Compile time assertion: sizeof(D) == sizeof(S). A compile error
233 // here means your D and S have different sizes.
234 typedef char VerifySizesAreEqual[sizeof(D) == sizeof(S) ? 1 : -1];
235
236 D destination;
237 // This use of memcpy is safe: source and destination cannot overlap.
238 memcpy(&destination, &source, sizeof(destination));
239 return destination;
240 }
241
242
243 // Similar to bit_cast, but allows copying from types of unrelated
244 // sizes. This method was introduced to enable the strict aliasing
245 // optimizations of GCC 4.4. Basically, GCC mindlessly relies on
246 // obscure details in the C++ standard that make reinterpret_cast
247 // virtually useless.
248 template<class D, class S>
249 inline D bit_copy(const S& source) {
250 D destination;
251 // This use of memcpy is safe: source and destination cannot overlap.
252 memcpy(&destination,
253 reinterpret_cast<const void*>(&source),
254 sizeof(destination));
255 return destination;
256 }
257
258 // A macro to ensure that memcpy cannot be called. memcpy does not handle
259 // overlapping memory regions. Even though this is well documented it seems
260 // to be used in error quite often. To avoid problems we disallow the direct
261 // use of memcpy here.
262 //
263 // On Windows the basic libraries use memcpy and therefore compilation will
264 // fail if memcpy is overwritten even if user code does not use memcpy.
265 #if defined(memcpy)
266 #undef memcpy
267 #endif
268 #if !defined(TARGET_OS_WINDOWS)
269 #define memcpy "Please use memmove instead of memcpy."
270 #endif
271 57
272 58
273 // When using GCC we can use GCC attributes to ensure that certain 59 // When using GCC we can use GCC attributes to ensure that certain
274 // contants are 16 byte aligned. 60 // contants are 16 byte aligned.
275 #if defined(TARGET_OS_WINDOWS) 61 #if defined(TARGET_OS_WINDOWS)
276 #define ALIGN16 __declspec(align(16)) 62 #define ALIGN16 __declspec(align(16))
277 #else 63 #else
278 #define ALIGN16 __attribute__((aligned(16))) 64 #define ALIGN16 __attribute__((aligned(16)))
279 #endif 65 #endif
280 66
281 } // namespace dart 67 } // namespace dart
282 68
283 #endif // VM_GLOBALS_H_ 69 #endif // VM_GLOBALS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698