~ubuntu-branches/ubuntu/precise/nodejs/precise

« back to all changes in this revision

Viewing changes to deps/v8/src/platform.h.orig

  • Committer: Bazaar Package Importer
  • Author(s): Jérémy Lal
  • Date: 2010-08-20 11:49:04 UTC
  • mfrom: (7.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20100820114904-lz22w6fkth7yh179
Tags: 0.2.0-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#define V8_INFINITY INFINITY
 
48
 
 
49
// Windows specific stuff.
 
50
#ifdef WIN32
 
51
 
 
52
// Microsoft Visual C++ specific stuff.
 
53
#ifdef _MSC_VER
 
54
 
 
55
enum {
 
56
  FP_NAN,
 
57
  FP_INFINITE,
 
58
  FP_ZERO,
 
59
  FP_SUBNORMAL,
 
60
  FP_NORMAL
 
61
};
 
62
 
 
63
#undef V8_INFINITY
 
64
#define V8_INFINITY HUGE_VAL
 
65
 
 
66
namespace v8 {
 
67
namespace internal {
 
68
int isfinite(double x);
 
69
} }
 
70
int isnan(double x);
 
71
int isinf(double x);
 
72
int isless(double x, double y);
 
73
int isgreater(double x, double y);
 
74
int fpclassify(double x);
 
75
int signbit(double x);
 
76
 
 
77
int strncasecmp(const char* s1, const char* s2, int n);
 
78
 
 
79
#endif  // _MSC_VER
 
80
 
 
81
// Random is missing on both Visual Studio and MinGW.
 
82
int random();
 
83
 
 
84
#endif  // WIN32
 
85
 
 
86
 
 
87
#ifdef __sun
 
88
# ifndef signbit
 
89
int signbit(double x);
 
90
# endif
 
91
#endif
 
92
 
 
93
 
 
94
// GCC specific stuff
 
95
#ifdef __GNUC__
 
96
 
 
97
// Needed for va_list on at least MinGW and Android.
 
98
#include <stdarg.h>
 
99
 
 
100
#define __GNUC_VERSION__ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100)
 
101
 
 
102
// Unfortunately, the INFINITY macro cannot be used with the '-pedantic'
 
103
// warning flag and certain versions of GCC due to a bug:
 
104
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11931
 
105
// For now, we use the more involved template-based version from <limits>, but
 
106
// only when compiling with GCC versions affected by the bug (2.96.x - 4.0.x)
 
107
// __GNUC_PREREQ is not defined in GCC for Mac OS X, so we define our own macro
 
108
#if __GNUC_VERSION__ >= 29600 && __GNUC_VERSION__ < 40100
 
109
#include <limits>
 
110
#undef V8_INFINITY
 
111
#define V8_INFINITY std::numeric_limits<double>::infinity()
 
112
#endif
 
113
 
 
114
#endif  // __GNUC__
 
115
 
 
116
namespace v8 {
 
117
namespace internal {
 
118
 
 
119
// Use AtomicWord for a machine-sized pointer. It is assumed that
 
120
// reads and writes of naturally aligned values of this type are atomic.
 
121
typedef intptr_t AtomicWord;
 
122
 
 
123
class Semaphore;
 
124
 
 
125
double ceiling(double x);
 
126
double modulo(double x, double y);
 
127
 
 
128
// Forward declarations.
 
129
class Socket;
 
130
 
 
131
// ----------------------------------------------------------------------------
 
132
// OS
 
133
//
 
134
// This class has static methods for the different platform specific
 
135
// functions. Add methods here to cope with differences between the
 
136
// supported platforms.
 
137
 
 
138
class OS {
 
139
 public:
 
140
  // Initializes the platform OS support. Called once at VM startup.
 
141
  static void Setup();
 
142
 
 
143
  // Returns the accumulated user time for thread. This routine
 
144
  // can be used for profiling. The implementation should
 
145
  // strive for high-precision timer resolution, preferable
 
146
  // micro-second resolution.
 
147
  static int GetUserTime(uint32_t* secs,  uint32_t* usecs);
 
148
 
 
149
  // Get a tick counter normalized to one tick per microsecond.
 
150
  // Used for calculating time intervals.
 
151
  static int64_t Ticks();
 
152
 
 
153
  // Returns current time as the number of milliseconds since
 
154
  // 00:00:00 UTC, January 1, 1970.
 
155
  static double TimeCurrentMillis();
 
156
 
 
157
  // Returns a string identifying the current time zone. The
 
158
  // timestamp is used for determining if DST is in effect.
 
159
  static const char* LocalTimezone(double time);
 
160
 
 
161
  // Returns the local time offset in milliseconds east of UTC without
 
162
  // taking daylight savings time into account.
 
163
  static double LocalTimeOffset();
 
164
 
 
165
  // Returns the daylight savings offset for the given time.
 
166
  static double DaylightSavingsOffset(double time);
 
167
 
 
168
  // Returns last OS error.
 
169
  static int GetLastError();
 
170
 
 
171
  static FILE* FOpen(const char* path, const char* mode);
 
172
 
 
173
  // Log file open mode is platform-dependent due to line ends issues.
 
174
  static const char* LogFileOpenMode;
 
175
 
 
176
  // Print output to console. This is mostly used for debugging output.
 
177
  // On platforms that has standard terminal output, the output
 
178
  // should go to stdout.
 
179
  static void Print(const char* format, ...);
 
180
  static void VPrint(const char* format, va_list args);
 
181
 
 
182
  // Print error output to console. This is mostly used for error message
 
183
  // output. On platforms that has standard terminal output, the output
 
184
  // should go to stderr.
 
185
  static void PrintError(const char* format, ...);
 
186
  static void VPrintError(const char* format, va_list args);
 
187
 
 
188
  // Allocate/Free memory used by JS heap. Pages are readable/writable, but
 
189
  // they are not guaranteed to be executable unless 'executable' is true.
 
190
  // Returns the address of allocated memory, or NULL if failed.
 
191
  static void* Allocate(const size_t requested,
 
192
                        size_t* allocated,
 
193
                        bool is_executable);
 
194
  static void Free(void* address, const size_t size);
 
195
  // Get the Alignment guaranteed by Allocate().
 
196
  static size_t AllocateAlignment();
 
197
 
 
198
#ifdef ENABLE_HEAP_PROTECTION
 
199
  // Protect/unprotect a block of memory by marking it read-only/writable.
 
200
  static void Protect(void* address, size_t size);
 
201
  static void Unprotect(void* address, size_t size, bool is_executable);
 
202
#endif
 
203
 
 
204
  // Returns an indication of whether a pointer is in a space that
 
205
  // has been allocated by Allocate().  This method may conservatively
 
206
  // always return false, but giving more accurate information may
 
207
  // improve the robustness of the stack dump code in the presence of
 
208
  // heap corruption.
 
209
  static bool IsOutsideAllocatedSpace(void* pointer);
 
210
 
 
211
  // Sleep for a number of milliseconds.
 
212
  static void Sleep(const int milliseconds);
 
213
 
 
214
  // Abort the current process.
 
215
  static void Abort();
 
216
 
 
217
  // Debug break.
 
218
  static void DebugBreak();
 
219
 
 
220
  // Walk the stack.
 
221
  static const int kStackWalkError = -1;
 
222
  static const int kStackWalkMaxNameLen = 256;
 
223
  static const int kStackWalkMaxTextLen = 256;
 
224
  struct StackFrame {
 
225
    void* address;
 
226
    char text[kStackWalkMaxTextLen];
 
227
  };
 
228
 
 
229
  static int StackWalk(Vector<StackFrame> frames);
 
230
 
 
231
  // Factory method for creating platform dependent Mutex.
 
232
  // Please use delete to reclaim the storage for the returned Mutex.
 
233
  static Mutex* CreateMutex();
 
234
 
 
235
  // Factory method for creating platform dependent Semaphore.
 
236
  // Please use delete to reclaim the storage for the returned Semaphore.
 
237
  static Semaphore* CreateSemaphore(int count);
 
238
 
 
239
  // Factory method for creating platform dependent Socket.
 
240
  // Please use delete to reclaim the storage for the returned Socket.
 
241
  static Socket* CreateSocket();
 
242
 
 
243
  class MemoryMappedFile {
 
244
   public:
 
245
    static MemoryMappedFile* create(const char* name, int size, void* initial);
 
246
    virtual ~MemoryMappedFile() { }
 
247
    virtual void* memory() = 0;
 
248
  };
 
249
 
 
250
  // Safe formatting print. Ensures that str is always null-terminated.
 
251
  // Returns the number of chars written, or -1 if output was truncated.
 
252
  static int SNPrintF(Vector<char> str, const char* format, ...);
 
253
  static int VSNPrintF(Vector<char> str,
 
254
                       const char* format,
 
255
                       va_list args);
 
256
 
 
257
  static char* StrChr(char* str, int c);
 
258
  static void StrNCpy(Vector<char> dest, const char* src, size_t n);
 
259
 
 
260
  // Support for profiler.  Can do nothing, in which case ticks
 
261
  // occuring in shared libraries will not be properly accounted
 
262
  // for.
 
263
  static void LogSharedLibraryAddresses();
 
264
 
 
265
  // The return value indicates the CPU features we are sure of because of the
 
266
  // OS.  For example MacOSX doesn't run on any x86 CPUs that don't have SSE2
 
267
  // instructions.
 
268
  // This is a little messy because the interpretation is subject to the cross
 
269
  // of the CPU and the OS.  The bits in the answer correspond to the bit
 
270
  // positions indicated by the members of the CpuFeature enum from globals.h
 
271
  static uint64_t CpuFeaturesImpliedByPlatform();
 
272
 
 
273
  // Returns the double constant NAN
 
274
  static double nan_value();
 
275
 
 
276
  // Support runtime detection of VFP3 on ARM CPUs.
 
277
  static bool ArmCpuHasFeature(CpuFeature feature);
 
278
 
 
279
  // Returns the activation frame alignment constraint or zero if
 
280
  // the platform doesn't care. Guaranteed to be a power of two.
 
281
  static int ActivationFrameAlignment();
 
282
 
 
283
  static void ReleaseStore(volatile AtomicWord* ptr, AtomicWord value);
 
284
 
 
285
 private:
 
286
  static const int msPerSecond = 1000;
 
287
 
 
288
  DISALLOW_IMPLICIT_CONSTRUCTORS(OS);
 
289
};
 
290
 
 
291
 
 
292
class VirtualMemory {
 
293
 public:
 
294
  // Reserves virtual memory with size.
 
295
  explicit VirtualMemory(size_t size);
 
296
  ~VirtualMemory();
 
297
 
 
298
  // Returns whether the memory has been reserved.
 
299
  bool IsReserved();
 
300
 
 
301
  // Returns the start address of the reserved memory.
 
302
  void* address() {
 
303
    ASSERT(IsReserved());
 
304
    return address_;
 
305
  };
 
306
 
 
307
  // Returns the size of the reserved memory.
 
308
  size_t size() { return size_; }
 
309
 
 
310
  // Commits real memory. Returns whether the operation succeeded.
 
311
  bool Commit(void* address, size_t size, bool is_executable);
 
312
 
 
313
  // Uncommit real memory.  Returns whether the operation succeeded.
 
314
  bool Uncommit(void* address, size_t size);
 
315
 
 
316
 private:
 
317
  void* address_;  // Start address of the virtual memory.
 
318
  size_t size_;  // Size of the virtual memory.
 
319
};
 
320
 
 
321
 
 
322
// ----------------------------------------------------------------------------
 
323
// ThreadHandle
 
324
//
 
325
// A ThreadHandle represents a thread identifier for a thread. The ThreadHandle
 
326
// does not own the underlying os handle. Thread handles can be used for
 
327
// refering to threads and testing equality.
 
328
 
 
329
class ThreadHandle {
 
330
 public:
 
331
  enum Kind { SELF, INVALID };
 
332
  explicit ThreadHandle(Kind kind);
 
333
 
 
334
  // Destructor.
 
335
  ~ThreadHandle();
 
336
 
 
337
  // Test for thread running.
 
338
  bool IsSelf() const;
 
339
 
 
340
  // Test for valid thread handle.
 
341
  bool IsValid() const;
 
342
 
 
343
  // Get platform-specific data.
 
344
  class PlatformData;
 
345
  PlatformData* thread_handle_data() { return data_; }
 
346
 
 
347
  // Initialize the handle to kind
 
348
  void Initialize(Kind kind);
 
349
 
 
350
 private:
 
351
  PlatformData* data_;  // Captures platform dependent data.
 
352
};
 
353
 
 
354
 
 
355
// ----------------------------------------------------------------------------
 
356
// Thread
 
357
//
 
358
// Thread objects are used for creating and running threads. When the start()
 
359
// method is called the new thread starts running the run() method in the new
 
360
// thread. The Thread object should not be deallocated before the thread has
 
361
// terminated.
 
362
 
 
363
class Thread: public ThreadHandle {
 
364
 public:
 
365
  // Opaque data type for thread-local storage keys.
 
366
  enum LocalStorageKey {};
 
367
 
 
368
  // Create new thread.
 
369
  Thread();
 
370
  virtual ~Thread();
 
371
 
 
372
  // Start new thread by calling the Run() method in the new thread.
 
373
  void Start();
 
374
 
 
375
  // Wait until thread terminates.
 
376
  void Join();
 
377
 
 
378
  // Abstract method for run handler.
 
379
  virtual void Run() = 0;
 
380
 
 
381
  // Thread-local storage.
 
382
  static LocalStorageKey CreateThreadLocalKey();
 
383
  static void DeleteThreadLocalKey(LocalStorageKey key);
 
384
  static void* GetThreadLocal(LocalStorageKey key);
 
385
  static int GetThreadLocalInt(LocalStorageKey key) {
 
386
    return static_cast<int>(reinterpret_cast<intptr_t>(GetThreadLocal(key)));
 
387
  }
 
388
  static void SetThreadLocal(LocalStorageKey key, void* value);
 
389
  static void SetThreadLocalInt(LocalStorageKey key, int value) {
 
390
    SetThreadLocal(key, reinterpret_cast<void*>(static_cast<intptr_t>(value)));
 
391
  }
 
392
  static bool HasThreadLocal(LocalStorageKey key) {
 
393
    return GetThreadLocal(key) != NULL;
 
394
  }
 
395
 
 
396
  // A hint to the scheduler to let another thread run.
 
397
  static void YieldCPU();
 
398
 
 
399
 private:
 
400
  class PlatformData;
 
401
  PlatformData* data_;
 
402
  DISALLOW_COPY_AND_ASSIGN(Thread);
 
403
};
 
404
 
 
405
 
 
406
// ----------------------------------------------------------------------------
 
407
// Mutex
 
408
//
 
409
// Mutexes are used for serializing access to non-reentrant sections of code.
 
410
// The implementations of mutex should allow for nested/recursive locking.
 
411
 
 
412
class Mutex {
 
413
 public:
 
414
  virtual ~Mutex() {}
 
415
 
 
416
  // Locks the given mutex. If the mutex is currently unlocked, it becomes
 
417
  // locked and owned by the calling thread, and immediately. If the mutex
 
418
  // is already locked by another thread, suspends the calling thread until
 
419
  // the mutex is unlocked.
 
420
  virtual int Lock() = 0;
 
421
 
 
422
  // Unlocks the given mutex. The mutex is assumed to be locked and owned by
 
423
  // the calling thread on entrance.
 
424
  virtual int Unlock() = 0;
 
425
};
 
426
 
 
427
 
 
428
// ----------------------------------------------------------------------------
 
429
// ScopedLock
 
430
//
 
431
// Stack-allocated ScopedLocks provide block-scoped locking and unlocking
 
432
// of a mutex.
 
433
class ScopedLock {
 
434
 public:
 
435
  explicit ScopedLock(Mutex* mutex): mutex_(mutex) {
 
436
    mutex_->Lock();
 
437
  }
 
438
  ~ScopedLock() {
 
439
    mutex_->Unlock();
 
440
  }
 
441
 
 
442
 private:
 
443
  Mutex* mutex_;
 
444
  DISALLOW_COPY_AND_ASSIGN(ScopedLock);
 
445
};
 
446
 
 
447
 
 
448
// ----------------------------------------------------------------------------
 
449
// Semaphore
 
450
//
 
451
// A semaphore object is a synchronization object that maintains a count. The
 
452
// count is decremented each time a thread completes a wait for the semaphore
 
453
// object and incremented each time a thread signals the semaphore. When the
 
454
// count reaches zero,  threads waiting for the semaphore blocks until the
 
455
// count becomes non-zero.
 
456
 
 
457
class Semaphore {
 
458
 public:
 
459
  virtual ~Semaphore() {}
 
460
 
 
461
  // Suspends the calling thread until the semaphore counter is non zero
 
462
  // and then decrements the semaphore counter.
 
463
  virtual void Wait() = 0;
 
464
 
 
465
  // Suspends the calling thread until the counter is non zero or the timeout
 
466
  // time has passsed. If timeout happens the return value is false and the
 
467
  // counter is unchanged. Otherwise the semaphore counter is decremented and
 
468
  // true is returned. The timeout value is specified in microseconds.
 
469
  virtual bool Wait(int timeout) = 0;
 
470
 
 
471
  // Increments the semaphore counter.
 
472
  virtual void Signal() = 0;
 
473
};
 
474
 
 
475
 
 
476
// ----------------------------------------------------------------------------
 
477
// Socket
 
478
//
 
479
 
 
480
class Socket {
 
481
 public:
 
482
  virtual ~Socket() {}
 
483
 
 
484
  // Server initialization.
 
485
  virtual bool Bind(const int port) = 0;
 
486
  virtual bool Listen(int backlog) const = 0;
 
487
  virtual Socket* Accept() const = 0;
 
488
 
 
489
  // Client initialization.
 
490
  virtual bool Connect(const char* host, const char* port) = 0;
 
491
 
 
492
  // Shutdown socket for both read and write. This causes blocking Send and
 
493
  // Receive calls to exit. After Shutdown the Socket object cannot be used for
 
494
  // any communication.
 
495
  virtual bool Shutdown() = 0;
 
496
 
 
497
  // Data Transimission
 
498
  virtual int Send(const char* data, int len) const = 0;
 
499
  virtual int Receive(char* data, int len) const = 0;
 
500
 
 
501
  // Set the value of the SO_REUSEADDR socket option.
 
502
  virtual bool SetReuseAddress(bool reuse_address) = 0;
 
503
 
 
504
  virtual bool IsValid() const = 0;
 
505
 
 
506
  static bool Setup();
 
507
  static int LastError();
 
508
  static uint16_t HToN(uint16_t value);
 
509
  static uint16_t NToH(uint16_t value);
 
510
  static uint32_t HToN(uint32_t value);
 
511
  static uint32_t NToH(uint32_t value);
 
512
};
 
513
 
 
514
 
 
515
// ----------------------------------------------------------------------------
 
516
// Sampler
 
517
//
 
518
// A sampler periodically samples the state of the VM and optionally
 
519
// (if used for profiling) the program counter and stack pointer for
 
520
// the thread that created it.
 
521
 
 
522
// TickSample captures the information collected for each sample.
 
523
class TickSample {
 
524
 public:
 
525
  TickSample()
 
526
      : state(OTHER),
 
527
        pc(NULL),
 
528
        sp(NULL),
 
529
        fp(NULL),
 
530
        function(NULL),
 
531
        frames_count(0) {}
 
532
  StateTag state;  // The state of the VM.
 
533
  Address pc;  // Instruction pointer.
 
534
  Address sp;  // Stack pointer.
 
535
  Address fp;  // Frame pointer.
 
536
  Address function;  // The last called JS function.
 
537
  static const int kMaxFramesCount = 64;
 
538
  Address stack[kMaxFramesCount];  // Call stack.
 
539
  int frames_count;  // Number of captured frames.
 
540
};
 
541
 
 
542
#ifdef ENABLE_LOGGING_AND_PROFILING
 
543
class Sampler {
 
544
 public:
 
545
  // Initialize sampler.
 
546
  explicit Sampler(int interval, bool profiling);
 
547
  virtual ~Sampler();
 
548
 
 
549
  // Performs stack sampling.
 
550
  virtual void SampleStack(TickSample* sample) = 0;
 
551
 
 
552
  // This method is called for each sampling period with the current
 
553
  // program counter.
 
554
  virtual void Tick(TickSample* sample) = 0;
 
555
 
 
556
  // Start and stop sampler.
 
557
  void Start();
 
558
  void Stop();
 
559
 
 
560
  // Is the sampler used for profiling.
 
561
  inline bool IsProfiling() { return profiling_; }
 
562
 
 
563
  // Whether the sampler is running (that is, consumes resources).
 
564
  inline bool IsActive() { return active_; }
 
565
 
 
566
  class PlatformData;
 
567
 
 
568
 private:
 
569
  const int interval_;
 
570
  const bool profiling_;
 
571
  bool active_;
 
572
  PlatformData* data_;  // Platform specific data.
 
573
  DISALLOW_IMPLICIT_CONSTRUCTORS(Sampler);
 
574
};
 
575
 
 
576
#endif  // ENABLE_LOGGING_AND_PROFILING
 
577
 
 
578
} }  // namespace v8::internal
 
579
 
 
580
#endif  // V8_PLATFORM_H_