Ignore:
Timestamp:
Oct 31, 2007, 6:22:35 PM (18 years ago)
Author:
aroben
Message:

Fix a crash on launch due to a static initializer race

We now use fast inline assembler spinlocks which can be statically
initialized at compile time.

As a side benefit, this speeds up SunSpider by 0.4%.

Reviewed by Oliver.

  • wtf/FastMalloc.cpp:
  • wtf/TCSpinLock.h: (TCMalloc_SpinLock::Lock): (TCMalloc_SpinLock::Unlock): (TCMalloc_SlowLock):
  • wtf/TCSystemAlloc.cpp:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/wtf/TCSpinLock.h

    r27295 r27336  
    3434#define TCMALLOC_INTERNAL_SPINLOCK_H__
    3535
    36 #if (PLATFORM(X86) || PLATFORM(PPC)) && COMPILER(GCC)
     36#if (PLATFORM(X86) || PLATFORM(PPC)) && (COMPILER(GCC) || COMPILER(MSVC))
    3737
    3838#include <time.h>       /* For nanosleep() */
     
    4848#endif
    4949#include <stdlib.h>     /* for abort() */
     50
     51#if COMPILER(MSVC)
     52#define WIN32_LEAN_AND_MEAN
     53#include <windows.h>
     54#endif
    5055
    5156static void TCMalloc_SlowLock(volatile unsigned int* lockword);
     
    6065  inline void Lock() {
    6166    int r;
     67#if COMPILER(GCC)
    6268#if PLATFORM(X86)
    6369    __asm__ __volatile__
     
    7783         : "memory");
    7884#endif
     85#elif COMPILER(MSVC)
     86    __asm {
     87        mov eax, this    ; store &private_lockword_ (which is this+0) in eax
     88        mov ebx, 1       ; store 1 in ebx
     89        xchg [eax], ebx  ; exchange private_lockword_ and 1
     90        mov r, ebx       ; store old value of private_lockword_ in r
     91    }
     92#endif
    7993    if (r) TCMalloc_SlowLock(&private_lockword_);
    8094  }
    8195
    8296  inline void Unlock() {
     97#if COMPILER(GCC)
    8398#if PLATFORM(X86)
    8499    __asm__ __volatile__
     
    96111       : "memory");
    97112#endif
     113#elif COMPILER(MSVC)
     114      __asm {
     115          mov eax, this  ; store &private_lockword_ (which is this+0) in eax
     116          mov [eax], 0   ; set private_lockword_ to 0
     117      }
     118#endif
    98119  }
    99120
     
    111132  while (true) {
    112133    int r;
     134#if COMPILER(GCC)
    113135#if PLATFORM(X86)
    114136    __asm__ __volatile__
     
    128150         : "r" (tmp), "1" (lockword)
    129151         : "memory");
     152#endif
     153#elif COMPILER(MSVC)
     154    __asm {
     155        mov eax, lockword     ; assign lockword into eax
     156        mov ebx, 1            ; assign 1 into ebx
     157        xchg [eax], ebx       ; exchange *lockword and 1
     158        mov r, ebx            ; store old value of *lockword in r
     159    }
    130160#endif
    131161    if (!r) {
     
    143173
    144174    // Sleep for a few milliseconds
     175#if COMPILER(MSVC)
     176    Sleep(2);
     177#else
    145178    struct timespec tm;
    146179    tm.tv_sec = 0;
    147180    tm.tv_nsec = 2000001;
    148181    nanosleep(&tm, NULL);
     182#endif
    149183  }
    150184}
    151 
    152 #elif COMPILER(MSVC)
    153 
    154 #define WIN32_LEAN_AND_MEAN
    155 #include <windows.h>
    156 
    157 struct TCMalloc_SpinLock {
    158   CRITICAL_SECTION private_lock_;
    159 
    160   inline TCMalloc_SpinLock() {
    161     Init();
    162   }
    163 
    164   inline void Init() {
    165     InitializeCriticalSection(&private_lock_);
    166   }
    167   inline void Finalize() {
    168     DeleteCriticalSection(&private_lock_);
    169   }
    170   inline void Lock() {
    171     EnterCriticalSection(&private_lock_);
    172   }
    173   inline void Unlock() {
    174     LeaveCriticalSection(&private_lock_);
    175   }
    176 };
    177185
    178186#else
Note: See TracChangeset for help on using the changeset viewer.