summaryrefslogtreecommitdiff
path: root/src/3rdparty/v8/src/platform.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/v8/src/platform.h')
-rw-r--r--src/3rdparty/v8/src/platform.h693
1 files changed, 693 insertions, 0 deletions
diff --git a/src/3rdparty/v8/src/platform.h b/src/3rdparty/v8/src/platform.h
new file mode 100644
index 0000000..fea16c8
--- /dev/null
+++ b/src/3rdparty/v8/src/platform.h
@@ -0,0 +1,693 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// 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.
+
+// This module contains the platform-specific code. This make the rest of the
+// code less dependent on operating system, compilers and runtime libraries.
+// This module does specifically not deal with differences between different
+// processor architecture.
+// The platform classes have the same definition for all platforms. The
+// implementation for a particular platform is put in platform_<os>.cc.
+// The build system then uses the implementation for the target platform.
+//
+// This design has been chosen because it is simple and fast. Alternatively,
+// the platform dependent classes could have been implemented using abstract
+// superclasses with virtual methods and having specializations for each
+// platform. This design was rejected because it was more complicated and
+// slower. It would require factory methods for selecting the right
+// implementation and the overhead of virtual methods for performance
+// sensitive like mutex locking/unlocking.
+
+#ifndef V8_PLATFORM_H_
+#define V8_PLATFORM_H_
+
+#define V8_INFINITY INFINITY
+
+// Windows specific stuff.
+#ifdef WIN32
+
+// Microsoft Visual C++ specific stuff.
+#ifdef _MSC_VER
+
+enum {
+ FP_NAN,
+ FP_INFINITE,
+ FP_ZERO,
+ FP_SUBNORMAL,
+ FP_NORMAL
+};
+
+#undef V8_INFINITY
+#define V8_INFINITY HUGE_VAL
+
+namespace v8 {
+namespace internal {
+int isfinite(double x);
+} }
+int isnan(double x);
+int isinf(double x);
+int isless(double x, double y);
+int isgreater(double x, double y);
+int fpclassify(double x);
+int signbit(double x);
+
+int strncasecmp(const char* s1, const char* s2, int n);
+
+#endif // _MSC_VER
+
+// Random is missing on both Visual Studio and MinGW.
+int random();
+
+#endif // WIN32
+
+
+#ifdef __sun
+# ifndef signbit
+int signbit(double x);
+# endif
+#endif
+
+
+// GCC specific stuff
+#ifdef __GNUC__
+
+// Needed for va_list on at least MinGW and Android.
+#include <stdarg.h>
+
+#define __GNUC_VERSION__ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100)
+
+// 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)
+// __GNUC_PREREQ is not defined in GCC for Mac OS X, so we define our own macro
+#if __GNUC_VERSION__ >= 29600 && __GNUC_VERSION__ < 40100
+#include <limits>
+#undef V8_INFINITY
+#define V8_INFINITY std::numeric_limits<double>::infinity()
+#endif
+
+#endif // __GNUC__
+
+#include "atomicops.h"
+#include "platform-tls.h"
+#include "utils.h"
+#include "v8globals.h"
+
+namespace v8 {
+namespace internal {
+
+// Use AtomicWord for a machine-sized pointer. It is assumed that
+// reads and writes of naturally aligned values of this type are atomic.
+typedef intptr_t AtomicWord;
+
+class Semaphore;
+class Mutex;
+
+double ceiling(double x);
+double modulo(double x, double y);
+
+// Forward declarations.
+class Socket;
+
+// ----------------------------------------------------------------------------
+// OS
+//
+// This class has static methods for the different platform specific
+// functions. Add methods here to cope with differences between the
+// supported platforms.
+
+class OS {
+ public:
+ // Initializes the platform OS support. Called once at VM startup.
+ static void Setup();
+
+ // Returns the accumulated user time for thread. This routine
+ // can be used for profiling. The implementation should
+ // strive for high-precision timer resolution, preferable
+ // micro-second resolution.
+ static int GetUserTime(uint32_t* secs, uint32_t* usecs);
+
+ // Get a tick counter normalized to one tick per microsecond.
+ // Used for calculating time intervals.
+ static int64_t Ticks();
+
+ // Returns current time as the number of milliseconds since
+ // 00:00:00 UTC, January 1, 1970.
+ static double TimeCurrentMillis();
+
+ // Returns a string identifying the current time zone. The
+ // timestamp is used for determining if DST is in effect.
+ static const char* LocalTimezone(double time);
+
+ // Returns the local time offset in milliseconds east of UTC without
+ // taking daylight savings time into account.
+ static double LocalTimeOffset();
+
+ // Returns the daylight savings offset for the given time.
+ static double DaylightSavingsOffset(double time);
+
+ // Returns last OS error.
+ static int GetLastError();
+
+ static FILE* FOpen(const char* path, const char* mode);
+ static bool Remove(const char* path);
+
+ // Log file open mode is platform-dependent due to line ends issues.
+ static const char* const LogFileOpenMode;
+
+ // Print output to console. This is mostly used for debugging output.
+ // On platforms that has standard terminal output, the output
+ // should go to stdout.
+ static void Print(const char* format, ...);
+ static void VPrint(const char* format, va_list args);
+
+ // Print output to a file. This is mostly used for debugging output.
+ static void FPrint(FILE* out, const char* format, ...);
+ static void VFPrint(FILE* out, const char* format, va_list args);
+
+ // Print error output to console. This is mostly used for error message
+ // output. On platforms that has standard terminal output, the output
+ // should go to stderr.
+ static void PrintError(const char* format, ...);
+ static void VPrintError(const char* format, va_list args);
+
+ // Allocate/Free memory used by JS heap. Pages are readable/writable, but
+ // they are not guaranteed to be executable unless 'executable' is true.
+ // Returns the address of allocated memory, or NULL if failed.
+ static void* Allocate(const size_t requested,
+ size_t* allocated,
+ bool is_executable);
+ static void Free(void* address, const size_t size);
+ // Get the Alignment guaranteed by Allocate().
+ static size_t AllocateAlignment();
+
+#ifdef ENABLE_HEAP_PROTECTION
+ // Protect/unprotect a block of memory by marking it read-only/writable.
+ static void Protect(void* address, size_t size);
+ static void Unprotect(void* address, size_t size, bool is_executable);
+#endif
+
+ // Returns an indication of whether a pointer is in a space that
+ // has been allocated by Allocate(). This method may conservatively
+ // always return false, but giving more accurate information may
+ // improve the robustness of the stack dump code in the presence of
+ // heap corruption.
+ static bool IsOutsideAllocatedSpace(void* pointer);
+
+ // Sleep for a number of milliseconds.
+ static void Sleep(const int milliseconds);
+
+ // Abort the current process.
+ static void Abort();
+
+ // Debug break.
+ static void DebugBreak();
+
+ // Walk the stack.
+ static const int kStackWalkError = -1;
+ static const int kStackWalkMaxNameLen = 256;
+ static const int kStackWalkMaxTextLen = 256;
+ struct StackFrame {
+ void* address;
+ char text[kStackWalkMaxTextLen];
+ };
+
+ static int StackWalk(Vector<StackFrame> frames);
+
+ // Factory method for creating platform dependent Mutex.
+ // Please use delete to reclaim the storage for the returned Mutex.
+ static Mutex* CreateMutex();
+
+ // Factory method for creating platform dependent Semaphore.
+ // Please use delete to reclaim the storage for the returned Semaphore.
+ static Semaphore* CreateSemaphore(int count);
+
+ // Factory method for creating platform dependent Socket.
+ // Please use delete to reclaim the storage for the returned Socket.
+ static Socket* CreateSocket();
+
+ class MemoryMappedFile {
+ public:
+ static MemoryMappedFile* open(const char* name);
+ static MemoryMappedFile* create(const char* name, int size, void* initial);
+ virtual ~MemoryMappedFile() { }
+ virtual void* memory() = 0;
+ virtual int size() = 0;
+ };
+
+ // Safe formatting print. Ensures that str is always null-terminated.
+ // Returns the number of chars written, or -1 if output was truncated.
+ static int SNPrintF(Vector<char> str, const char* format, ...);
+ static int VSNPrintF(Vector<char> str,
+ const char* format,
+ va_list args);
+
+ static char* StrChr(char* str, int c);
+ static void StrNCpy(Vector<char> dest, const char* src, size_t n);
+
+ // Support for the profiler. Can do nothing, in which case ticks
+ // occuring in shared libraries will not be properly accounted for.
+ static void LogSharedLibraryAddresses();
+
+ // Support for the profiler. Notifies the external profiling
+ // process that a code moving garbage collection starts. Can do
+ // nothing, in which case the code objects must not move (e.g., by
+ // using --never-compact) if accurate profiling is desired.
+ static void SignalCodeMovingGC();
+
+ // The return value indicates the CPU features we are sure of because of the
+ // OS. For example MacOSX doesn't run on any x86 CPUs that don't have SSE2
+ // instructions.
+ // This is a little messy because the interpretation is subject to the cross
+ // of the CPU and the OS. The bits in the answer correspond to the bit
+ // positions indicated by the members of the CpuFeature enum from globals.h
+ static uint64_t CpuFeaturesImpliedByPlatform();
+
+ // Returns the double constant NAN
+ static double nan_value();
+
+ // Support runtime detection of VFP3 on ARM CPUs.
+ static bool ArmCpuHasFeature(CpuFeature feature);
+
+ // Support runtime detection of FPU on MIPS CPUs.
+ static bool MipsCpuHasFeature(CpuFeature feature);
+
+ // Returns the activation frame alignment constraint or zero if
+ // the platform doesn't care. Guaranteed to be a power of two.
+ static int ActivationFrameAlignment();
+
+ static void ReleaseStore(volatile AtomicWord* ptr, AtomicWord value);
+
+#if defined(V8_TARGET_ARCH_IA32)
+ // Copy memory area to disjoint memory area.
+ static void MemCopy(void* dest, const void* src, size_t size);
+ // Limit below which the extra overhead of the MemCopy function is likely
+ // to outweigh the benefits of faster copying.
+ static const int kMinComplexMemCopy = 64;
+ typedef void (*MemCopyFunction)(void* dest, const void* src, size_t size);
+
+#else // V8_TARGET_ARCH_IA32
+ static void MemCopy(void* dest, const void* src, size_t size) {
+ memcpy(dest, src, size);
+ }
+ static const int kMinComplexMemCopy = 256;
+#endif // V8_TARGET_ARCH_IA32
+
+ private:
+ static const int msPerSecond = 1000;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(OS);
+};
+
+
+class VirtualMemory {
+ public:
+ // Reserves virtual memory with size.
+ explicit VirtualMemory(size_t size);
+ ~VirtualMemory();
+
+ // Returns whether the memory has been reserved.
+ bool IsReserved();
+
+ // Returns the start address of the reserved memory.
+ void* address() {
+ ASSERT(IsReserved());
+ return address_;
+ }
+
+ // Returns the size of the reserved memory.
+ size_t size() { return size_; }
+
+ // Commits real memory. Returns whether the operation succeeded.
+ bool Commit(void* address, size_t size, bool is_executable);
+
+ // Uncommit real memory. Returns whether the operation succeeded.
+ bool Uncommit(void* address, size_t size);
+
+ private:
+ void* address_; // Start address of the virtual memory.
+ size_t size_; // Size of the virtual memory.
+};
+
+
+// ----------------------------------------------------------------------------
+// ThreadHandle
+//
+// A ThreadHandle represents a thread identifier for a thread. The ThreadHandle
+// does not own the underlying os handle. Thread handles can be used for
+// refering to threads and testing equality.
+
+class ThreadHandle {
+ public:
+ enum Kind { SELF, INVALID };
+ explicit ThreadHandle(Kind kind);
+
+ // Destructor.
+ ~ThreadHandle();
+
+ // Test for thread running.
+ bool IsSelf() const;
+
+ // Test for valid thread handle.
+ bool IsValid() const;
+
+ // Get platform-specific data.
+ class PlatformData;
+ PlatformData* thread_handle_data() { return data_; }
+
+ // Initialize the handle to kind
+ void Initialize(Kind kind);
+
+ private:
+ PlatformData* data_; // Captures platform dependent data.
+};
+
+
+// ----------------------------------------------------------------------------
+// Thread
+//
+// Thread objects are used for creating and running threads. When the start()
+// method is called the new thread starts running the run() method in the new
+// thread. The Thread object should not be deallocated before the thread has
+// terminated.
+
+class Thread: public ThreadHandle {
+ public:
+ // Opaque data type for thread-local storage keys.
+ // LOCAL_STORAGE_KEY_MIN_VALUE and LOCAL_STORAGE_KEY_MAX_VALUE are specified
+ // to ensure that enumeration type has correct value range (see Issue 830 for
+ // more details).
+ enum LocalStorageKey {
+ LOCAL_STORAGE_KEY_MIN_VALUE = kMinInt,
+ LOCAL_STORAGE_KEY_MAX_VALUE = kMaxInt
+ };
+
+ struct Options {
+ Options() : name("v8:<unknown>"), stack_size(0) {}
+
+ const char* name;
+ int stack_size;
+ };
+
+ // Create new thread (with a value for storing in the TLS isolate field).
+ Thread(Isolate* isolate, const Options& options);
+ Thread(Isolate* isolate, const char* name);
+ virtual ~Thread();
+
+ // Start new thread by calling the Run() method in the new thread.
+ void Start();
+
+ // Wait until thread terminates.
+ void Join();
+
+ inline const char* name() const {
+ return name_;
+ }
+
+ // Abstract method for run handler.
+ virtual void Run() = 0;
+
+ // Thread-local storage.
+ static LocalStorageKey CreateThreadLocalKey();
+ static void DeleteThreadLocalKey(LocalStorageKey key);
+ static void* GetThreadLocal(LocalStorageKey key);
+ static int GetThreadLocalInt(LocalStorageKey key) {
+ return static_cast<int>(reinterpret_cast<intptr_t>(GetThreadLocal(key)));
+ }
+ static void SetThreadLocal(LocalStorageKey key, void* value);
+ static void SetThreadLocalInt(LocalStorageKey key, int value) {
+ SetThreadLocal(key, reinterpret_cast<void*>(static_cast<intptr_t>(value)));
+ }
+ static bool HasThreadLocal(LocalStorageKey key) {
+ return GetThreadLocal(key) != NULL;
+ }
+
+#ifdef V8_FAST_TLS_SUPPORTED
+ static inline void* GetExistingThreadLocal(LocalStorageKey key) {
+ void* result = reinterpret_cast<void*>(
+ InternalGetExistingThreadLocal(static_cast<intptr_t>(key)));
+ ASSERT(result == GetThreadLocal(key));
+ return result;
+ }
+#else
+ static inline void* GetExistingThreadLocal(LocalStorageKey key) {
+ return GetThreadLocal(key);
+ }
+#endif
+
+ // A hint to the scheduler to let another thread run.
+ static void YieldCPU();
+
+ Isolate* isolate() const { return isolate_; }
+
+ // The thread name length is limited to 16 based on Linux's implementation of
+ // prctl().
+ static const int kMaxThreadNameLength = 16;
+ private:
+ void set_name(const char *name);
+
+ class PlatformData;
+ PlatformData* data_;
+ Isolate* isolate_;
+ char name_[kMaxThreadNameLength];
+ int stack_size_;
+
+ DISALLOW_COPY_AND_ASSIGN(Thread);
+};
+
+
+// ----------------------------------------------------------------------------
+// Mutex
+//
+// Mutexes are used for serializing access to non-reentrant sections of code.
+// The implementations of mutex should allow for nested/recursive locking.
+
+class Mutex {
+ public:
+ virtual ~Mutex() {}
+
+ // Locks the given mutex. If the mutex is currently unlocked, it becomes
+ // locked and owned by the calling thread, and immediately. If the mutex
+ // is already locked by another thread, suspends the calling thread until
+ // the mutex is unlocked.
+ virtual int Lock() = 0;
+
+ // Unlocks the given mutex. The mutex is assumed to be locked and owned by
+ // the calling thread on entrance.
+ virtual int Unlock() = 0;
+
+ // Tries to lock the given mutex. Returns whether the mutex was
+ // successfully locked.
+ virtual bool TryLock() = 0;
+};
+
+
+// ----------------------------------------------------------------------------
+// ScopedLock
+//
+// Stack-allocated ScopedLocks provide block-scoped locking and
+// unlocking of a mutex.
+class ScopedLock {
+ public:
+ explicit ScopedLock(Mutex* mutex): mutex_(mutex) {
+ ASSERT(mutex_ != NULL);
+ mutex_->Lock();
+ }
+ ~ScopedLock() {
+ mutex_->Unlock();
+ }
+
+ private:
+ Mutex* mutex_;
+ DISALLOW_COPY_AND_ASSIGN(ScopedLock);
+};
+
+
+// ----------------------------------------------------------------------------
+// Semaphore
+//
+// A semaphore object is a synchronization object that maintains a count. The
+// count is decremented each time a thread completes a wait for the semaphore
+// object and incremented each time a thread signals the semaphore. When the
+// count reaches zero, threads waiting for the semaphore blocks until the
+// count becomes non-zero.
+
+class Semaphore {
+ public:
+ virtual ~Semaphore() {}
+
+ // Suspends the calling thread until the semaphore counter is non zero
+ // and then decrements the semaphore counter.
+ virtual void Wait() = 0;
+
+ // Suspends the calling thread until the counter is non zero or the timeout
+ // time has passsed. If timeout happens the return value is false and the
+ // counter is unchanged. Otherwise the semaphore counter is decremented and
+ // true is returned. The timeout value is specified in microseconds.
+ virtual bool Wait(int timeout) = 0;
+
+ // Increments the semaphore counter.
+ virtual void Signal() = 0;
+};
+
+
+// ----------------------------------------------------------------------------
+// Socket
+//
+
+class Socket {
+ public:
+ virtual ~Socket() {}
+
+ // Server initialization.
+ virtual bool Bind(const int port) = 0;
+ virtual bool Listen(int backlog) const = 0;
+ virtual Socket* Accept() const = 0;
+
+ // Client initialization.
+ virtual bool Connect(const char* host, const char* port) = 0;
+
+ // Shutdown socket for both read and write. This causes blocking Send and
+ // Receive calls to exit. After Shutdown the Socket object cannot be used for
+ // any communication.
+ virtual bool Shutdown() = 0;
+
+ // Data Transimission
+ virtual int Send(const char* data, int len) const = 0;
+ virtual int Receive(char* data, int len) const = 0;
+
+ // Set the value of the SO_REUSEADDR socket option.
+ virtual bool SetReuseAddress(bool reuse_address) = 0;
+
+ virtual bool IsValid() const = 0;
+
+ static bool Setup();
+ static int LastError();
+ static uint16_t HToN(uint16_t value);
+ static uint16_t NToH(uint16_t value);
+ static uint32_t HToN(uint32_t value);
+ static uint32_t NToH(uint32_t value);
+};
+
+
+// ----------------------------------------------------------------------------
+// Sampler
+//
+// A sampler periodically samples the state of the VM and optionally
+// (if used for profiling) the program counter and stack pointer for
+// the thread that created it.
+
+// TickSample captures the information collected for each sample.
+class TickSample {
+ public:
+ TickSample()
+ : state(OTHER),
+ pc(NULL),
+ sp(NULL),
+ fp(NULL),
+ tos(NULL),
+ frames_count(0),
+ has_external_callback(false) {}
+ StateTag state; // The state of the VM.
+ Address pc; // Instruction pointer.
+ Address sp; // Stack pointer.
+ Address fp; // Frame pointer.
+ union {
+ Address tos; // Top stack value (*sp).
+ Address external_callback;
+ };
+ static const int kMaxFramesCount = 64;
+ Address stack[kMaxFramesCount]; // Call stack.
+ int frames_count : 8; // Number of captured frames.
+ bool has_external_callback : 1;
+};
+
+#ifdef ENABLE_LOGGING_AND_PROFILING
+class Sampler {
+ public:
+ // Initialize sampler.
+ Sampler(Isolate* isolate, int interval);
+ virtual ~Sampler();
+
+ int interval() const { return interval_; }
+
+ // Performs stack sampling.
+ void SampleStack(TickSample* sample) {
+ DoSampleStack(sample);
+ IncSamplesTaken();
+ }
+
+ // This method is called for each sampling period with the current
+ // program counter.
+ virtual void Tick(TickSample* sample) = 0;
+
+ // Start and stop sampler.
+ void Start();
+ void Stop();
+
+ // Is the sampler used for profiling?
+ bool IsProfiling() const { return NoBarrier_Load(&profiling_) > 0; }
+ void IncreaseProfilingDepth() { NoBarrier_AtomicIncrement(&profiling_, 1); }
+ void DecreaseProfilingDepth() { NoBarrier_AtomicIncrement(&profiling_, -1); }
+
+ // Whether the sampler is running (that is, consumes resources).
+ bool IsActive() const { return NoBarrier_Load(&active_); }
+
+ Isolate* isolate() { return isolate_; }
+
+ // Used in tests to make sure that stack sampling is performed.
+ int samples_taken() const { return samples_taken_; }
+ void ResetSamplesTaken() { samples_taken_ = 0; }
+
+ class PlatformData;
+ PlatformData* data() { return data_; }
+
+ PlatformData* platform_data() { return data_; }
+
+ protected:
+ virtual void DoSampleStack(TickSample* sample) = 0;
+
+ private:
+ void SetActive(bool value) { NoBarrier_Store(&active_, value); }
+ void IncSamplesTaken() { if (++samples_taken_ < 0) samples_taken_ = 0; }
+
+ Isolate* isolate_;
+ const int interval_;
+ Atomic32 profiling_;
+ Atomic32 active_;
+ PlatformData* data_; // Platform specific data.
+ int samples_taken_; // Counts stack samples taken.
+ DISALLOW_IMPLICIT_CONSTRUCTORS(Sampler);
+};
+
+
+#endif // ENABLE_LOGGING_AND_PROFILING
+
+} } // namespace v8::internal
+
+#endif // V8_PLATFORM_H_