globals.h 15.5 KB
Newer Older
1
// Copyright 2012 the V8 project authors. All rights reserved.
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
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

28 29 30
#ifndef V8_GLOBALS_H_
#define V8_GLOBALS_H_

31
#include "../include/v8stdint.h"
32

33 34 35 36 37
// Unfortunately, the INFINITY macro cannot be used with the '-pedantic'
// warning flag and certain versions of GCC due to a bug:
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11931
// For now, we use the more involved template-based version from <limits>, but
// only when compiling with GCC versions affected by the bug (2.96.x - 4.0.x)
38 39 40
#if V8_CC_GNU && V8_GNUC_PREREQ(2, 96, 0) && !V8_GNUC_PREREQ(4, 1, 0)
# include <limits>  // NOLINT
# define V8_INFINITY std::numeric_limits<double>::infinity()
41
#elif V8_LIBC_MSVCRT
42
# define V8_INFINITY HUGE_VAL
43 44
#else
# define V8_INFINITY INFINITY
45 46
#endif

47 48
namespace v8 {
namespace internal {
49

50
// Processor architecture detection.  For more info on what's defined, see:
51 52 53 54
//   http://msdn.microsoft.com/en-us/library/b0084kay.aspx
//   http://www.agner.org/optimize/calling_conventions.pdf
//   or with gcc, run: "echo | gcc -E -dM -"
#if defined(_M_X64) || defined(__x86_64__)
55
#if defined(__native_client__)
56 57 58 59 60 61
// For Native Client builds of V8, use V8_TARGET_ARCH_ARM, so that V8
// generates ARM machine code, together with a portable ARM simulator
// compiled for the host architecture in question.
//
// Since Native Client is ILP-32 on all architectures we use
// V8_HOST_ARCH_IA32 on both 32- and 64-bit x86.
62 63 64 65 66 67 68 69
#define V8_HOST_ARCH_IA32 1
#define V8_HOST_ARCH_32_BIT 1
#define V8_HOST_CAN_READ_UNALIGNED 1
#else
#define V8_HOST_ARCH_X64 1
#define V8_HOST_ARCH_64_BIT 1
#define V8_HOST_CAN_READ_UNALIGNED 1
#endif  // __native_client__
70
#elif defined(_M_IX86) || defined(__i386__)
71 72 73
#define V8_HOST_ARCH_IA32 1
#define V8_HOST_ARCH_32_BIT 1
#define V8_HOST_CAN_READ_UNALIGNED 1
74 75 76 77
#elif defined(__AARCH64EL__)
#define V8_HOST_ARCH_A64 1
#define V8_HOST_ARCH_64_BIT 1
#define V8_HOST_CAN_READ_UNALIGNED 1
78
#elif defined(__ARMEL__)
79 80
#define V8_HOST_ARCH_ARM 1
#define V8_HOST_ARCH_32_BIT 1
81
#elif defined(__MIPSEL__)
82 83
#define V8_HOST_ARCH_MIPS 1
#define V8_HOST_ARCH_32_BIT 1
84
#else
85
#error "Host architecture was not detected as supported by v8"
lrn@chromium.org's avatar
lrn@chromium.org committed
86 87
#endif

88 89 90 91 92
#if defined(__ARM_ARCH_7A__) || \
    defined(__ARM_ARCH_7R__) || \
    defined(__ARM_ARCH_7__)
# define CAN_USE_ARMV7_INSTRUCTIONS 1
# ifndef CAN_USE_VFP3_INSTRUCTIONS
93
#  define CAN_USE_VFP3_INSTRUCTIONS
94 95 96 97
# endif
#endif


98 99 100
// Target architecture detection. This may be set externally. If not, detect
// in the same way as the host architecture, that is, target the native
// environment as presented by the compiler.
101
#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_IA32 && \
102
    !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_A64 && !V8_TARGET_ARCH_MIPS
103 104 105 106
#if defined(_M_X64) || defined(__x86_64__)
#define V8_TARGET_ARCH_X64 1
#elif defined(_M_IX86) || defined(__i386__)
#define V8_TARGET_ARCH_IA32 1
107 108
#elif defined(__AARCH64EL__)
#define V8_TARGET_ARCH_A64 1
109 110 111 112 113 114 115
#elif defined(__ARMEL__)
#define V8_TARGET_ARCH_ARM 1
#elif defined(__MIPSEL__)
#define V8_TARGET_ARCH_MIPS 1
#else
#error Target architecture was not detected as supported by v8
#endif
116 117
#endif

118
// Check for supported combinations of host and target architectures.
119
#if V8_TARGET_ARCH_IA32 && !V8_HOST_ARCH_IA32
120 121 122 123 124 125 126 127
#error Target architecture ia32 is only supported on ia32 host
#endif
#if V8_TARGET_ARCH_X64 && !V8_HOST_ARCH_X64
#error Target architecture x64 is only supported on x64 host
#endif
#if (V8_TARGET_ARCH_ARM && !(V8_HOST_ARCH_IA32 || V8_HOST_ARCH_ARM))
#error Target architecture arm is only supported on arm and ia32 host
#endif
128 129 130
#if (V8_TARGET_ARCH_A64 && !(V8_HOST_ARCH_X64 || V8_HOST_ARCH_A64))
#error Target architecture a64 is only supported on a64 and x64 host
#endif
131 132
#if (V8_TARGET_ARCH_MIPS && !(V8_HOST_ARCH_IA32 || V8_HOST_ARCH_MIPS))
#error Target architecture mips is only supported on mips and ia32 host
133 134
#endif

135
// Determine whether we are running in a simulated environment.
136 137 138
// Setting USE_SIMULATOR explicitly from the build script will force
// the use of a simulated environment.
#if !defined(USE_SIMULATOR)
139 140 141
#if (V8_TARGET_ARCH_A64 && !V8_HOST_ARCH_A64)
#define USE_SIMULATOR 1
#endif
142 143 144 145 146
#if (V8_TARGET_ARCH_ARM && !V8_HOST_ARCH_ARM)
#define USE_SIMULATOR 1
#endif
#if (V8_TARGET_ARCH_MIPS && !V8_HOST_ARCH_MIPS)
#define USE_SIMULATOR 1
147
#endif
148 149
#endif

150 151 152 153 154 155 156
// Determine architecture endiannes (we only support little-endian).
#if V8_TARGET_ARCH_IA32
#define V8_TARGET_LITTLE_ENDIAN 1
#elif V8_TARGET_ARCH_X64
#define V8_TARGET_LITTLE_ENDIAN 1
#elif V8_TARGET_ARCH_ARM
#define V8_TARGET_LITTLE_ENDIAN 1
157 158
#elif V8_TARGET_ARCH_A64
#define V8_TARGET_LITTLE_ENDIAN 1
159 160
#elif V8_TARGET_ARCH_MIPS
#define V8_TARGET_LITTLE_ENDIAN 1
161
#else
162
#error Unknown target architecture endiannes
163 164
#endif

165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
// Support for alternative bool type. This is only enabled if the code is
// compiled with USE_MYBOOL defined. This catches some nasty type bugs.
// For instance, 'bool b = "false";' results in b == true! This is a hidden
// source of bugs.
// However, redefining the bool type does have some negative impact on some
// platforms. It gives rise to compiler warnings (i.e. with
// MSVC) in the API header files when mixing code that uses the standard
// bool with code that uses the redefined version.
// This does not actually belong in the platform code, but needs to be
// defined here because the platform code uses bool, and platform.h is
// include very early in the main include file.

#ifdef USE_MYBOOL
typedef unsigned int __my_bool__;
#define bool __my_bool__  // use 'indirection' to avoid name clashes
180 181
#endif

182 183 184
typedef uint8_t byte;
typedef byte* Address;

185 186 187
// Define our own macros for writing 64-bit constants.  This is less fragile
// than defining __STDC_CONSTANT_MACROS before including <stdint.h>, and it
// works on compilers that don't have it (like MSVC).
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
#if V8_CC_MSVC
# define V8_UINT64_C(x)   (x ## UI64)
# define V8_INT64_C(x)    (x ## I64)
# if V8_HOST_ARCH_64_BIT
#  define V8_INTPTR_C(x)  (x ## I64)
#  define V8_PTR_PREFIX   "ll"
# else
#  define V8_INTPTR_C(x)  (x)
#  define V8_PTR_PREFIX   ""
# endif  // V8_HOST_ARCH_64_BIT
#elif V8_CC_MINGW64
# define V8_UINT64_C(x)   (x ## ULL)
# define V8_INT64_C(x)    (x ## LL)
# define V8_INTPTR_C(x)   (x ## LL)
# define V8_PTR_PREFIX    "I64"
#elif V8_HOST_ARCH_64_BIT
204 205 206 207 208 209 210
# if V8_OS_MACOSX
#  define V8_UINT64_C(x)   (x ## ULL)
#  define V8_INT64_C(x)    (x ## LL)
# else
#  define V8_UINT64_C(x)   (x ## UL)
#  define V8_INT64_C(x)    (x ## L)
# endif
211 212
# define V8_INTPTR_C(x)   (x ## L)
# define V8_PTR_PREFIX    "l"
213
#else
214 215 216 217
# define V8_UINT64_C(x)   (x ## ULL)
# define V8_INT64_C(x)    (x ## LL)
# define V8_INTPTR_C(x)   (x)
# define V8_PTR_PREFIX    ""
218 219 220 221 222 223 224 225 226 227 228 229
#endif

// The following macro works on both 32 and 64-bit platforms.
// Usage: instead of writing 0x1234567890123456
//      write V8_2PART_UINT64_C(0x12345678,90123456);
#define V8_2PART_UINT64_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))

#define V8PRIxPTR V8_PTR_PREFIX "x"
#define V8PRIdPTR V8_PTR_PREFIX "d"
#define V8PRIuPTR V8_PTR_PREFIX "u"

// Fix for Mac OS X defining uintptr_t as "unsigned long":
230
#if V8_OS_MACOSX
231 232 233 234
#undef V8PRIxPTR
#define V8PRIxPTR "lx"
#endif

235
#if V8_OS_MACOSX || defined(__FreeBSD__) || defined(__OpenBSD__)
236 237 238
#define USING_BSD_ABI
#endif

239 240 241 242 243 244 245 246
// -----------------------------------------------------------------------------
// Constants

const int KB = 1024;
const int MB = KB * KB;
const int GB = KB * KB * KB;
const int kMaxInt = 0x7FFFFFFF;
const int kMinInt = -kMaxInt - 1;
247 248 249 250 251 252 253 254
const int kMaxInt8 = (1 << 7) - 1;
const int kMinInt8 = -(1 << 7);
const int kMaxUInt8 = (1 << 8) - 1;
const int kMinUInt8 = 0;
const int kMaxInt16 = (1 << 15) - 1;
const int kMinInt16 = -(1 << 15);
const int kMaxUInt16 = (1 << 16) - 1;
const int kMinUInt16 = 0;
255

256 257
const uint32_t kMaxUInt32 = 0xFFFFFFFFu;

258 259 260
const int kCharSize      = sizeof(char);      // NOLINT
const int kShortSize     = sizeof(short);     // NOLINT
const int kIntSize       = sizeof(int);       // NOLINT
261 262
const int kInt32Size     = sizeof(int32_t);   // NOLINT
const int kInt64Size     = sizeof(int64_t);   // NOLINT
263 264 265 266 267 268
const int kDoubleSize    = sizeof(double);    // NOLINT
const int kIntptrSize    = sizeof(intptr_t);  // NOLINT
const int kPointerSize   = sizeof(void*);     // NOLINT
const int kRegisterSize  = kPointerSize;
const int kPCOnStackSize = kRegisterSize;
const int kFPOnStackSize = kRegisterSize;
269

270 271
const int kDoubleSizeLog2 = 3;

272
#if V8_HOST_ARCH_64_BIT
273
const int kPointerSizeLog2 = 3;
274
const intptr_t kIntptrSignBit = V8_INT64_C(0x8000000000000000);
275
const uintptr_t kUintptrAllBitsSet = V8_UINT64_C(0xFFFFFFFFFFFFFFFF);
276
const bool kIs64BitArch = true;
277
#else
278
const int kPointerSizeLog2 = 2;
279
const intptr_t kIntptrSignBit = 0x80000000;
280
const uintptr_t kUintptrAllBitsSet = 0xFFFFFFFFu;
281
const bool kIs64BitArch = false;
282
#endif
283 284 285 286 287 288

const int kBitsPerByte = 8;
const int kBitsPerByteLog2 = 3;
const int kBitsPerPointer = kPointerSize * kBitsPerByte;
const int kBitsPerInt = kIntSize * kBitsPerByte;

289 290 291 292 293 294 295 296 297
// IEEE 754 single precision floating point number bit layout.
const uint32_t kBinary32SignMask = 0x80000000u;
const uint32_t kBinary32ExponentMask = 0x7f800000u;
const uint32_t kBinary32MantissaMask = 0x007fffffu;
const int kBinary32ExponentBias = 127;
const int kBinary32MaxExponent  = 0xFE;
const int kBinary32MinExponent  = 0x01;
const int kBinary32MantissaBits = 23;
const int kBinary32ExponentShift = 23;
298

299 300 301 302
// Quiet NaNs have bits 51 to 62 set, possibly the sign bit, and no
// other bits set.
const uint64_t kQuietNaNMask = static_cast<uint64_t>(0xfff) << 51;

303
// Latin1/UTF-16 constants
304
// Code-point values in Unicode 4.0 are 21 bits wide.
305
// Code units in UTF-16 are 16 bits wide.
306 307
typedef uint16_t uc16;
typedef int32_t uc32;
308
const int kOneByteSize    = kCharSize;
309 310
const int kUC16Size     = sizeof(uc16);      // NOLINT

311

312 313 314 315
// Round up n to be a multiple of sz, where sz is a power of 2.
#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))


316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
// The expression OFFSET_OF(type, field) computes the byte-offset
// of the specified field relative to the containing type. This
// corresponds to 'offsetof' (in stddef.h), except that it doesn't
// use 0 or NULL, which causes a problem with the compiler warnings
// we have enabled (which is also why 'offsetof' doesn't seem to work).
// Here we simply use the non-zero value 4, which seems to work.
#define OFFSET_OF(type, field)                                          \
  (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(4)->field)) - 4)


// The expression ARRAY_SIZE(a) is a compile-time constant of type
// size_t which represents the number of elements of the given
// array. You should only use ARRAY_SIZE on statically allocated
// arrays.
#define ARRAY_SIZE(a)                                   \
  ((sizeof(a) / sizeof(*(a))) /                         \
  static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))


// The USE(x) template is used to silence C++ compiler warnings
// issued for (yet) unused variables (typically parameters).
template <typename T>
338
inline void USE(T) { }
339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355


// FUNCTION_ADDR(f) gets the address of a C function f.
#define FUNCTION_ADDR(f)                                        \
  (reinterpret_cast<v8::internal::Address>(reinterpret_cast<intptr_t>(f)))


// FUNCTION_CAST<F>(addr) casts an address into a function
// of type F. Used to invoke generated code from within C.
template <typename F>
F FUNCTION_CAST(Address addr) {
  return reinterpret_cast<F>(reinterpret_cast<intptr_t>(addr));
}


// A macro to disallow the evil copy constructor and operator= functions
// This should be used in the private: declarations for a class
356 357 358
#define DISALLOW_COPY_AND_ASSIGN(TypeName)  \
  TypeName(const TypeName&) V8_DELETE;      \
  void operator=(const TypeName&) V8_DELETE
359 360 361 362 363 364 365 366


// A macro to disallow all the implicit constructors, namely the
// default constructor, copy constructor and operator= functions.
//
// This should be used in the private: declarations for a class
// that wants to prevent anyone from instantiating it. This is
// especially useful for classes containing only static methods.
367 368
#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName)  \
  TypeName() V8_DELETE;                           \
369
  DISALLOW_COPY_AND_ASSIGN(TypeName)
370 371


372 373 374
// Newly written code should use V8_INLINE and V8_NOINLINE directly.
#define INLINE(declarator)    V8_INLINE declarator
#define NO_INLINE(declarator) V8_NOINLINE declarator
375

376

377 378
// Newly written code should use V8_WARN_UNUSED_RESULT.
#define MUST_USE_RESULT V8_WARN_UNUSED_RESULT
379

380 381 382 383

// Define DISABLE_ASAN macros.
#if defined(__has_feature)
#if __has_feature(address_sanitizer)
384
#define DISABLE_ASAN __attribute__((no_sanitize_address))
385 386 387 388 389 390 391 392
#endif
#endif


#ifndef DISABLE_ASAN
#define DISABLE_ASAN
#endif

393 394 395 396 397 398
#if V8_CC_GNU
#define V8_IMMEDIATE_CRASH() __builtin_trap()
#else
#define V8_IMMEDIATE_CRASH() ((void(*)())0)()
#endif

399

400 401 402
// -----------------------------------------------------------------------------
// Forward declarations for frequently used classes
// (sorted alphabetically)
403

404 405
class FreeStoreAllocationPolicy;
template <typename T, class P = FreeStoreAllocationPolicy> class List;
406

407 408 409
// -----------------------------------------------------------------------------
// Declarations for use in both the preparser and the rest of V8.

410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428
// The different language modes that V8 implements. ES5 defines two language
// modes: an unrestricted mode respectively a strict mode which are indicated by
// CLASSIC_MODE respectively STRICT_MODE in the enum. The harmony spec drafts
// for the next ES standard specify a new third mode which is called 'extended
// mode'. The extended mode is only available if the harmony flag is set. It is
// based on the 'strict mode' and adds new functionality to it. This means that
// most of the semantics of these two modes coincide.
//
// In the current draft the term 'base code' is used to refer to code that is
// neither in strict nor extended mode. However, the more distinguishing term
// 'classic mode' is used in V8 instead to avoid mix-ups.

enum LanguageMode {
  CLASSIC_MODE,
  STRICT_MODE,
  EXTENDED_MODE
};


429
// The Strict Mode (ECMA-262 5th edition, 4.2.2).
430 431 432 433
//
// This flag is used in the backend to represent the language mode. So far
// there is no semantic difference between the strict and the extended mode in
// the backend, so both modes are represented by the kStrictMode value.
434 435
enum StrictModeFlag {
  kNonStrictMode,
436
  kStrictMode
437 438 439
};


440 441 442
} }  // namespace v8::internal

#endif  // V8_GLOBALS_H_