The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / platform.h @ 40c0f755

History | View | Annotate | Download (16.6 KB)

1
// Copyright 2006-2008 the V8 project authors. All rights reserved.
2
// Redistribution and use in source and binary forms, with or without
3
// modification, are permitted provided that the following conditions are
4
// met:
5
//
6
//     * Redistributions of source code must retain the above copyright
7
//       notice, this list of conditions and the following disclaimer.
8
//     * Redistributions in binary form must reproduce the above
9
//       copyright notice, this list of conditions and the following
10
//       disclaimer in the documentation and/or other materials provided
11
//       with the distribution.
12
//     * Neither the name of Google Inc. nor the names of its
13
//       contributors may be used to endorse or promote products derived
14
//       from this software without specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27

    
28
// This module contains the platform-specific code. This make the rest of the
29
// code less dependent on operating system, compilers and runtime libraries.
30
// This module does specifically not deal with differences between different
31
// processor architecture.
32
// The platform classes have the same definition for all platforms. The
33
// implementation for a particular platform is put in platform_<os>.cc.
34
// The build system then uses the implementation for the target platform.
35
//
36
// This design has been chosen because it is simple and fast. Alternatively,
37
// the platform dependent classes could have been implemented using abstract
38
// superclasses with virtual methods and having specializations for each
39
// platform. This design was rejected because it was more complicated and
40
// slower. It would require factory methods for selecting the right
41
// implementation and the overhead of virtual methods for performance
42
// sensitive like mutex locking/unlocking.
43

    
44
#ifndef V8_PLATFORM_H_
45
#define V8_PLATFORM_H_
46

    
47
// Windows specific stuff.
48
#ifdef WIN32
49

    
50
// Microsoft Visual C++ specific stuff.
51
#ifdef _MSC_VER
52

    
53
enum {
54
  FP_NAN,
55
  FP_INFINITE,
56
  FP_ZERO,
57
  FP_SUBNORMAL,
58
  FP_NORMAL
59
};
60

    
61
#define INFINITY HUGE_VAL
62

    
63
namespace v8 { namespace internal {
64
int isfinite(double x);
65
} }
66
int isnan(double x);
67
int isinf(double x);
68
int isless(double x, double y);
69
int isgreater(double x, double y);
70
int fpclassify(double x);
71
int signbit(double x);
72

    
73
int strncasecmp(const char* s1, const char* s2, int n);
74

    
75
#endif  // _MSC_VER
76

    
77
// MinGW specific stuff.
78
#ifdef __MINGW32__
79

    
80
// Needed for va_list.
81
#include <stdarg.h>
82

    
83
#endif  // __MINGW32__
84

    
85
// Random is missing on both Visual Studio and MinGW.
86
int random();
87

    
88
#endif  // WIN32
89

    
90
// GCC specific stuff
91
#ifdef __GNUC__
92
#define __GNUC_VERSION__ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100)
93

    
94
// Unfortunately, the INFINITY macro cannot be used with the '-pedantic'
95
// warning flag and certain versions of GCC due to a bug:
96
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11931
97
// For now, we use the more involved template-based version from <limits>, but
98
// only when compiling with GCC versions affected by the bug (2.96.x - 4.0.x)
99
// __GNUC_PREREQ is not defined in GCC for Mac OS X, so we define our own macro
100
#if __GNUC_VERSION__ >= 29600 && __GNUC_VERSION__ < 40100
101
#include <limits>
102
#undef INFINITY
103
#define INFINITY std::numeric_limits<double>::infinity()
104
#endif
105

    
106
#endif  // __GNUC__
107

    
108
namespace v8 { namespace internal {
109

    
110
double ceiling(double x);
111

    
112
// Forward declarations.
113
class Socket;
114

    
115
// ----------------------------------------------------------------------------
116
// OS
117
//
118
// This class has static methods for the different platform specific
119
// functions. Add methods here to cope with differences between the
120
// supported platforms.
121

    
122
class OS {
123
 public:
124
  // Initializes the platform OS support. Called once at VM startup.
125
  static void Setup();
126

    
127
  // Returns the accumulated user time for thread. This routine
128
  // can be used for profiling. The implementation should
129
  // strive for high-precision timer resolution, preferable
130
  // micro-second resolution.
131
  static int GetUserTime(uint32_t* secs,  uint32_t* usecs);
132

    
133
  // Get a tick counter normalized to one tick per microsecond.
134
  // Used for calculating time intervals.
135
  static int64_t Ticks();
136

    
137
  // Returns current time as the number of milliseconds since
138
  // 00:00:00 UTC, January 1, 1970.
139
  static double TimeCurrentMillis();
140

    
141
  // Returns a string identifying the current time zone. The
142
  // timestamp is used for determining if DST is in effect.
143
  static char* LocalTimezone(double time);
144

    
145
  // Returns the local time offset in milliseconds east of UTC without
146
  // taking daylight savings time into account.
147
  static double LocalTimeOffset();
148

    
149
  // Returns the daylight savings offset for the given time.
150
  static double DaylightSavingsOffset(double time);
151

    
152
  static FILE* FOpen(const char* path, const char* mode);
153

    
154
  // Log file open mode is platform-dependent due to line ends issues.
155
  static const char* LogFileOpenMode;
156

    
157
  // Print output to console. This is mostly used for debugging output.
158
  // On platforms that has standard terminal output, the output
159
  // should go to stdout.
160
  static void Print(const char* format, ...);
161
  static void VPrint(const char* format, va_list args);
162

    
163
  // Print error output to console. This is mostly used for error message
164
  // output. On platforms that has standard terminal output, the output
165
  // should go to stderr.
166
  static void PrintError(const char* format, ...);
167
  static void VPrintError(const char* format, va_list args);
168

    
169
  // Allocate/Free memory used by JS heap. Pages are readable/writable, but
170
  // they are not guaranteed to be executable unless 'executable' is true.
171
  // Returns the address of allocated memory, or NULL if failed.
172
  static void* Allocate(const size_t requested,
173
                        size_t* allocated,
174
                        bool is_executable);
175
  static void Free(void* address, const size_t size);
176
  // Get the Alignment guaranteed by Allocate().
177
  static size_t AllocateAlignment();
178

    
179
#ifdef ENABLE_HEAP_PROTECTION
180
  // Protect/unprotect a block of memory by marking it read-only/writable.
181
  static void Protect(void* address, size_t size);
182
  static void Unprotect(void* address, size_t size, bool is_executable);
183
#endif
184

    
185
  // Returns an indication of whether a pointer is in a space that
186
  // has been allocated by Allocate().  This method may conservatively
187
  // always return false, but giving more accurate information may
188
  // improve the robustness of the stack dump code in the presence of
189
  // heap corruption.
190
  static bool IsOutsideAllocatedSpace(void* pointer);
191

    
192
  // Sleep for a number of milliseconds.
193
  static void Sleep(const int milliseconds);
194

    
195
  // Abort the current process.
196
  static void Abort();
197

    
198
  // Debug break.
199
  static void DebugBreak();
200

    
201
  // Walk the stack.
202
  static const int kStackWalkError = -1;
203
  static const int kStackWalkMaxNameLen = 256;
204
  static const int kStackWalkMaxTextLen = 256;
205
  struct StackFrame {
206
    void* address;
207
    char text[kStackWalkMaxTextLen];
208
  };
209

    
210
  static int StackWalk(StackFrame* frames, int frames_size);
211

    
212
  // Factory method for creating platform dependent Mutex.
213
  // Please use delete to reclaim the storage for the returned Mutex.
214
  static Mutex* CreateMutex();
215

    
216
  // Factory method for creating platform dependent Semaphore.
217
  // Please use delete to reclaim the storage for the returned Semaphore.
218
  static Semaphore* CreateSemaphore(int count);
219

    
220
  // Factory method for creating platform dependent Socket.
221
  // Please use delete to reclaim the storage for the returned Socket.
222
  static Socket* CreateSocket();
223

    
224
  class MemoryMappedFile {
225
   public:
226
    static MemoryMappedFile* create(const char* name, int size, void* initial);
227
    virtual ~MemoryMappedFile() { }
228
    virtual void* memory() = 0;
229
  };
230

    
231
  // Safe formatting print. Ensures that str is always null-terminated.
232
  // Returns the number of chars written, or -1 if output was truncated.
233
  static int SNPrintF(Vector<char> str, const char* format, ...);
234
  static int VSNPrintF(Vector<char> str,
235
                       const char* format,
236
                       va_list args);
237

    
238
  static char* StrChr(char* str, int c);
239
  static void StrNCpy(Vector<char> dest, const char* src, size_t n);
240

    
241
  // Support for profiler.  Can do nothing, in which case ticks
242
  // occuring in shared libraries will not be properly accounted
243
  // for.
244
  static void LogSharedLibraryAddresses();
245

    
246
  // Returns the double constant NAN
247
  static double nan_value();
248

    
249
  // Returns the activation frame alignment constraint or zero if
250
  // the platform doesn't care. Guaranteed to be a power of two.
251
  static int ActivationFrameAlignment();
252

    
253
 private:
254
  static const int msPerSecond = 1000;
255

    
256
  DISALLOW_IMPLICIT_CONSTRUCTORS(OS);
257
};
258

    
259

    
260
class VirtualMemory {
261
 public:
262
  // Reserves virtual memory with size.
263
  explicit VirtualMemory(size_t size);
264
  ~VirtualMemory();
265

    
266
  // Returns whether the memory has been reserved.
267
  bool IsReserved();
268

    
269
  // Returns the start address of the reserved memory.
270
  void* address() {
271
    ASSERT(IsReserved());
272
    return address_;
273
  };
274

    
275
  // Returns the size of the reserved memory.
276
  size_t size() { return size_; }
277

    
278
  // Commits real memory. Returns whether the operation succeeded.
279
  bool Commit(void* address, size_t size, bool is_executable);
280

    
281
  // Uncommit real memory.  Returns whether the operation succeeded.
282
  bool Uncommit(void* address, size_t size);
283

    
284
 private:
285
  void* address_;  // Start address of the virtual memory.
286
  size_t size_;  // Size of the virtual memory.
287
};
288

    
289

    
290
// ----------------------------------------------------------------------------
291
// ThreadHandle
292
//
293
// A ThreadHandle represents a thread identifier for a thread. The ThreadHandle
294
// does not own the underlying os handle. Thread handles can be used for
295
// refering to threads and testing equality.
296

    
297
class ThreadHandle {
298
 public:
299
  enum Kind { SELF, INVALID };
300
  explicit ThreadHandle(Kind kind);
301

    
302
  // Destructor.
303
  ~ThreadHandle();
304

    
305
  // Test for thread running.
306
  bool IsSelf() const;
307

    
308
  // Test for valid thread handle.
309
  bool IsValid() const;
310

    
311
  // Get platform-specific data.
312
  class PlatformData;
313
  PlatformData* thread_handle_data() { return data_; }
314

    
315
  // Initialize the handle to kind
316
  void Initialize(Kind kind);
317

    
318
 private:
319
  PlatformData* data_;  // Captures platform dependent data.
320
};
321

    
322

    
323
// ----------------------------------------------------------------------------
324
// Thread
325
//
326
// Thread objects are used for creating and running threads. When the start()
327
// method is called the new thread starts running the run() method in the new
328
// thread. The Thread object should not be deallocated before the thread has
329
// terminated.
330

    
331
class Thread: public ThreadHandle {
332
 public:
333
  // Opaque data type for thread-local storage keys.
334
  enum LocalStorageKey {};
335

    
336
  // Create new thread.
337
  Thread();
338
  virtual ~Thread();
339

    
340
  // Start new thread by calling the Run() method in the new thread.
341
  void Start();
342

    
343
  // Wait until thread terminates.
344
  void Join();
345

    
346
  // Abstract method for run handler.
347
  virtual void Run() = 0;
348

    
349
  // Thread-local storage.
350
  static LocalStorageKey CreateThreadLocalKey();
351
  static void DeleteThreadLocalKey(LocalStorageKey key);
352
  static void* GetThreadLocal(LocalStorageKey key);
353
  static void SetThreadLocal(LocalStorageKey key, void* value);
354

    
355
  // A hint to the scheduler to let another thread run.
356
  static void YieldCPU();
357

    
358
 private:
359
  class PlatformData;
360
  PlatformData* data_;
361
  DISALLOW_COPY_AND_ASSIGN(Thread);
362
};
363

    
364

    
365
// ----------------------------------------------------------------------------
366
// Mutex
367
//
368
// Mutexes are used for serializing access to non-reentrant sections of code.
369
// The implementations of mutex should allow for nested/recursive locking.
370

    
371
class Mutex {
372
 public:
373
  virtual ~Mutex() {}
374

    
375
  // Locks the given mutex. If the mutex is currently unlocked, it becomes
376
  // locked and owned by the calling thread, and immediately. If the mutex
377
  // is already locked by another thread, suspends the calling thread until
378
  // the mutex is unlocked.
379
  virtual int Lock() = 0;
380

    
381
  // Unlocks the given mutex. The mutex is assumed to be locked and owned by
382
  // the calling thread on entrance.
383
  virtual int Unlock() = 0;
384
};
385

    
386

    
387
// ----------------------------------------------------------------------------
388
// ScopedLock
389
//
390
// Stack-allocated ScopedLocks provide block-scoped locking and unlocking
391
// of a mutex.
392
class ScopedLock {
393
 public:
394
  explicit ScopedLock(Mutex* mutex): mutex_(mutex) {
395
    mutex_->Lock();
396
  }
397
  ~ScopedLock() {
398
    mutex_->Unlock();
399
  }
400

    
401
 private:
402
  Mutex* mutex_;
403
  DISALLOW_COPY_AND_ASSIGN(ScopedLock);
404
};
405

    
406

    
407
// ----------------------------------------------------------------------------
408
// Semaphore
409
//
410
// A semaphore object is a synchronization object that maintains a count. The
411
// count is decremented each time a thread completes a wait for the semaphore
412
// object and incremented each time a thread signals the semaphore. When the
413
// count reaches zero,  threads waiting for the semaphore blocks until the
414
// count becomes non-zero.
415

    
416
class Semaphore {
417
 public:
418
  virtual ~Semaphore() {}
419

    
420
  // Suspends the calling thread until the semaphore counter is non zero
421
  // and then decrements the semaphore counter.
422
  virtual void Wait() = 0;
423

    
424
  // Suspends the calling thread until the counter is non zero or the timeout
425
  // time has passsed. If timeout happens the return value is false and the
426
  // counter is unchanged. Otherwise the semaphore counter is decremented and
427
  // true is returned. The timeout value is specified in microseconds.
428
  virtual bool Wait(int timeout) = 0;
429

    
430
  // Increments the semaphore counter.
431
  virtual void Signal() = 0;
432
};
433

    
434

    
435
// ----------------------------------------------------------------------------
436
// Socket
437
//
438

    
439
class Socket {
440
 public:
441
  virtual ~Socket() {}
442

    
443
  // Server initialization.
444
  virtual bool Bind(const int port) = 0;
445
  virtual bool Listen(int backlog) const = 0;
446
  virtual Socket* Accept() const = 0;
447

    
448
  // Client initialization.
449
  virtual bool Connect(const char* host, const char* port) = 0;
450

    
451
  // Shutdown socket for both read and write. This causes blocking Send and
452
  // Receive calls to exit. After Shutdown the Socket object cannot be used for
453
  // any communication.
454
  virtual bool Shutdown() = 0;
455

    
456
  // Data Transimission
457
  virtual int Send(const char* data, int len) const = 0;
458
  virtual int Receive(char* data, int len) const = 0;
459

    
460
  // Set the value of the SO_REUSEADDR socket option.
461
  virtual bool SetReuseAddress(bool reuse_address) = 0;
462

    
463
  virtual bool IsValid() const = 0;
464

    
465
  static bool Setup();
466
  static int LastError();
467
  static uint16_t HToN(uint16_t value);
468
  static uint16_t NToH(uint16_t value);
469
  static uint32_t HToN(uint32_t value);
470
  static uint32_t NToH(uint32_t value);
471
};
472

    
473

    
474
#ifdef ENABLE_LOGGING_AND_PROFILING
475
// ----------------------------------------------------------------------------
476
// Sampler
477
//
478
// A sampler periodically samples the state of the VM and optionally
479
// (if used for profiling) the program counter and stack pointer for
480
// the thread that created it.
481

    
482
// TickSample captures the information collected for each sample.
483
class TickSample {
484
 public:
485
  TickSample() : pc(0), sp(0), fp(0), state(OTHER) {}
486
  unsigned int pc;  // Instruction pointer.
487
  unsigned int sp;  // Stack pointer.
488
  unsigned int fp;  // Frame pointer.
489
  StateTag state;   // The state of the VM.
490
  static const int kMaxFramesCount = 100;
491
  EmbeddedVector<Address, kMaxFramesCount> stack;  // Call stack.
492
  int frames_count;  // Number of captured frames.
493
};
494

    
495
class Sampler {
496
 public:
497
  // Initialize sampler.
498
  explicit Sampler(int interval, bool profiling);
499
  virtual ~Sampler();
500

    
501
  // This method is called for each sampling period with the current
502
  // program counter.
503
  virtual void Tick(TickSample* sample) = 0;
504

    
505
  // Start and stop sampler.
506
  void Start();
507
  void Stop();
508

    
509
  // Is the sampler used for profiling.
510
  inline bool IsProfiling() { return profiling_; }
511

    
512
  class PlatformData;
513
 protected:
514
  inline bool IsActive() { return active_; }
515

    
516
 private:
517
  int interval_;
518
  bool profiling_;
519
  bool active_;
520
  PlatformData* data_;  // Platform specific data.
521
  DISALLOW_IMPLICIT_CONSTRUCTORS(Sampler);
522
};
523

    
524
#endif  // ENABLE_LOGGING_AND_PROFILING
525

    
526
} }  // namespace v8::internal
527

    
528
#endif  // V8_PLATFORM_H_