~ubuntu-branches/ubuntu/saucy/libv8/saucy

« back to all changes in this revision

Viewing changes to src/platform-win32.cc

  • Committer: Package Import Robot
  • Author(s): Jérémy Lal
  • Date: 2012-04-07 16:26:13 UTC
  • mfrom: (15.1.27 sid)
  • Revision ID: package-import@ubuntu.com-20120407162613-dqo1m6w9r3fh8tst
Tags: 3.8.9.16-3
* mipsel build fixes :
  + v8_use_mips_abi_hardfloat=false, this lowers EABI requirements.
  + v8_can_use_fpu_instructions=false, detect if FPU is present.
  + set -Wno-unused-but-set-variable only on mipsel.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2011 the V8 project authors. All rights reserved.
 
1
// Copyright 2012 the V8 project authors. All rights reserved.
2
2
// Redistribution and use in source and binary forms, with or without
3
3
// modification, are permitted provided that the following conditions are
4
4
// met:
198
198
 
199
199
// ----------------------------------------------------------------------------
200
200
// The Time class represents time on win32. A timestamp is represented as
201
 
// a 64-bit integer in 100 nano-seconds since January 1, 1601 (UTC). JavaScript
 
201
// a 64-bit integer in 100 nanoseconds since January 1, 1601 (UTC). JavaScript
202
202
// timestamps are represented as a doubles in milliseconds since 00:00:00 UTC,
203
203
// January 1, 1970.
204
204
 
528
528
}
529
529
 
530
530
 
531
 
void OS::Setup() {
 
531
void OS::SetUp() {
532
532
  // Seed the random number generator.
533
533
  // Convert the current time to a 64-bit integer first, before converting it
534
534
  // to an unsigned. Going directly can cause an overflow and the seed to be
776
776
 
777
777
// We keep the lowest and highest addresses mapped as a quick way of
778
778
// determining that pointers are outside the heap (used mostly in assertions
779
 
// and verification).  The estimate is conservative, ie, not all addresses in
 
779
// and verification).  The estimate is conservative, i.e., not all addresses in
780
780
// 'allocated' space are actually allocated to our heap.  The range is
781
781
// [lowest, highest), inclusive on the low and and exclusive on the high end.
782
782
static void* lowest_ever_allocated = reinterpret_cast<void*>(-1);
831
831
}
832
832
 
833
833
 
 
834
static void* GetRandomAddr() {
 
835
  Isolate* isolate = Isolate::UncheckedCurrent();
 
836
  // Note that the current isolate isn't set up in a call path via
 
837
  // CpuFeatures::Probe. We don't care about randomization in this case because
 
838
  // the code page is immediately freed.
 
839
  if (isolate != NULL) {
 
840
    // The address range used to randomize RWX allocations in OS::Allocate
 
841
    // Try not to map pages into the default range that windows loads DLLs
 
842
    // Use a multiple of 64k to prevent committing unused memory.
 
843
    // Note: This does not guarantee RWX regions will be within the
 
844
    // range kAllocationRandomAddressMin to kAllocationRandomAddressMax
 
845
#ifdef V8_HOST_ARCH_64_BIT
 
846
    static const intptr_t kAllocationRandomAddressMin = 0x0000000080000000;
 
847
    static const intptr_t kAllocationRandomAddressMax = 0x000003FFFFFF0000;
 
848
#else
 
849
    static const intptr_t kAllocationRandomAddressMin = 0x04000000;
 
850
    static const intptr_t kAllocationRandomAddressMax = 0x3FFF0000;
 
851
#endif
 
852
    uintptr_t address = (V8::RandomPrivate(isolate) << kPageSizeBits)
 
853
        | kAllocationRandomAddressMin;
 
854
    address &= kAllocationRandomAddressMax;
 
855
    return reinterpret_cast<void *>(address);
 
856
  }
 
857
  return NULL;
 
858
}
 
859
 
 
860
 
 
861
static void* RandomizedVirtualAlloc(size_t size, int action, int protection) {
 
862
  LPVOID base = NULL;
 
863
 
 
864
  if (protection == PAGE_EXECUTE_READWRITE || protection == PAGE_NOACCESS) {
 
865
    // For exectutable pages try and randomize the allocation address
 
866
    for (size_t attempts = 0; base == NULL && attempts < 3; ++attempts) {
 
867
      base = VirtualAlloc(GetRandomAddr(), size, action, protection);
 
868
    }
 
869
  }
 
870
 
 
871
  // After three attempts give up and let the OS find an address to use.
 
872
  if (base == NULL) base = VirtualAlloc(NULL, size, action, protection);
 
873
 
 
874
  return base;
 
875
}
 
876
 
 
877
 
834
878
void* OS::Allocate(const size_t requested,
835
879
                   size_t* allocated,
836
880
                   bool is_executable) {
837
 
  // The address range used to randomize RWX allocations in OS::Allocate
838
 
  // Try not to map pages into the default range that windows loads DLLs
839
 
  // Use a multiple of 64k to prevent committing unused memory.
840
 
  // Note: This does not guarantee RWX regions will be within the
841
 
  // range kAllocationRandomAddressMin to kAllocationRandomAddressMax
842
 
#ifdef V8_HOST_ARCH_64_BIT
843
 
  static const intptr_t kAllocationRandomAddressMin = 0x0000000080000000;
844
 
  static const intptr_t kAllocationRandomAddressMax = 0x000003FFFFFF0000;
845
 
#else
846
 
  static const intptr_t kAllocationRandomAddressMin = 0x04000000;
847
 
  static const intptr_t kAllocationRandomAddressMax = 0x3FFF0000;
848
 
#endif
849
 
 
850
881
  // VirtualAlloc rounds allocated size to page size automatically.
851
882
  size_t msize = RoundUp(requested, static_cast<int>(GetPageSize()));
852
 
  intptr_t address = 0;
853
883
 
854
884
  // Windows XP SP2 allows Data Excution Prevention (DEP).
855
885
  int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
856
886
 
857
 
  // For exectutable pages try and randomize the allocation address
858
 
  if (prot == PAGE_EXECUTE_READWRITE &&
859
 
      msize >= static_cast<size_t>(Page::kPageSize)) {
860
 
    address = (V8::RandomPrivate(Isolate::Current()) << kPageSizeBits)
861
 
      | kAllocationRandomAddressMin;
862
 
    address &= kAllocationRandomAddressMax;
863
 
  }
864
 
 
865
 
  LPVOID mbase = VirtualAlloc(reinterpret_cast<void *>(address),
866
 
                              msize,
867
 
                              MEM_COMMIT | MEM_RESERVE,
868
 
                              prot);
869
 
  if (mbase == NULL && address != 0)
870
 
    mbase = VirtualAlloc(NULL, msize, MEM_COMMIT | MEM_RESERVE, prot);
 
887
  LPVOID mbase = RandomizedVirtualAlloc(msize,
 
888
                                        MEM_COMMIT | MEM_RESERVE,
 
889
                                        prot);
871
890
 
872
891
  if (mbase == NULL) {
873
892
    LOG(ISOLATE, StringEvent("OS::Allocate", "VirtualAlloc failed"));
889
908
}
890
909
 
891
910
 
 
911
intptr_t OS::CommitPageSize() {
 
912
  return 4096;
 
913
}
 
914
 
 
915
 
892
916
void OS::ProtectCode(void* address, const size_t size) {
893
917
  DWORD old_protect;
894
918
  VirtualProtect(address, size, PAGE_EXECUTE_READ, &old_protect);
1466
1490
 
1467
1491
 
1468
1492
void* VirtualMemory::ReserveRegion(size_t size) {
1469
 
  return VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS);
 
1493
  return RandomizedVirtualAlloc(size, MEM_RESERVE, PAGE_NOACCESS);
1470
1494
}
1471
1495
 
1472
1496
 
1481
1505
}
1482
1506
 
1483
1507
 
 
1508
bool VirtualMemory::Guard(void* address) {
 
1509
  if (NULL == VirtualAlloc(address,
 
1510
                           OS::CommitPageSize(),
 
1511
                           MEM_COMMIT,
 
1512
                           PAGE_READONLY | PAGE_GUARD)) {
 
1513
    return false;
 
1514
  }
 
1515
  return true;
 
1516
}
 
1517
 
 
1518
 
1484
1519
bool VirtualMemory::UncommitRegion(void* base, size_t size) {
1485
1520
  return VirtualFree(base, size, MEM_DECOMMIT) != 0;
1486
1521
}
1491
1526
}
1492
1527
 
1493
1528
 
1494
 
 
1495
1529
// ----------------------------------------------------------------------------
1496
1530
// Win32 thread support.
1497
1531
 
1521
1555
// handle until it is started.
1522
1556
 
1523
1557
Thread::Thread(const Options& options)
1524
 
    : stack_size_(options.stack_size) {
1525
 
  data_ = new PlatformData(kNoThread);
1526
 
  set_name(options.name);
1527
 
}
1528
 
 
1529
 
 
1530
 
Thread::Thread(const char* name)
1531
 
    : stack_size_(0) {
1532
 
  data_ = new PlatformData(kNoThread);
1533
 
  set_name(name);
 
1558
    : stack_size_(options.stack_size()) {
 
1559
  data_ = new PlatformData(kNoThread);
 
1560
  set_name(options.name());
1534
1561
}
1535
1562
 
1536
1563
 
1820
1847
}
1821
1848
 
1822
1849
 
1823
 
bool Socket::Setup() {
 
1850
bool Socket::SetUp() {
1824
1851
  // Initialize Winsock32
1825
1852
  int err;
1826
1853
  WSADATA winsock_data;
1896
1923
 
1897
1924
class SamplerThread : public Thread {
1898
1925
 public:
 
1926
  static const int kSamplerThreadStackSize = 32 * KB;
 
1927
 
1899
1928
  explicit SamplerThread(int interval)
1900
 
      : Thread("SamplerThread"),
 
1929
      : Thread(Thread::Options("SamplerThread", kSamplerThreadStackSize)),
1901
1930
        interval_(interval) {}
1902
1931
 
1903
1932
  static void AddActiveSampler(Sampler* sampler) {
2001
2030
  static Mutex* mutex_;
2002
2031
  static SamplerThread* instance_;
2003
2032
 
 
2033
 private:
2004
2034
  DISALLOW_COPY_AND_ASSIGN(SamplerThread);
2005
2035
};
2006
2036