Changeset 19245 in webkit for trunk/JavaScriptCore/wtf


Ignore:
Timestamp:
Jan 29, 2007, 9:07:25 PM (18 years ago)
Author:
ggaren
Message:

JavaScriptCore:

Reviewed by Maciej Stachowiak.

Fixed <rdar://problem/4485644> REGRESSION: JavaScriptCore has init routines


The TCMalloc module now initializes, if needed, inside GetCache() and
fastMallocSetIsMultiThreaded(). We leverage the same synchronization
technique used for enabling / disabling the single-threaded optimization
to synchronize initialization of the library without requiring a lock
for every malloc.


1,251 runs of tcmalloc_unittest, 2 runs of a custom, massively multi-threaded
tcmalloc_unittest, and my custom version of the PLT show no regressions.
Super-accurate JS iBench reports a .24% regression, which is right at the
limit of its error range, so I'm declaring victory.

  • wtf/FastMalloc.cpp: (WTF::fastMallocSetIsMultiThreaded): Initialize, if needed. (InitModule() checks the "if needed" part.) (WTF::TCMalloc_ThreadCache::GetCache): Restored original TCMalloc code inside #ifdef, for posterity. Added new initialization logic. (WTF::TCMalloc_ThreadCache::InitModule): Call InitTSD(), since we don't have a static initializer to call it for us, now. This means that fastMalloc is not usable as a general libc allocator, but it never was, and if it were the general libc allocator, we wouldn't be here in the first place, so whatever. (WTF::TCMalloc_ThreadCache::InitTSD): Don't try to take the pageheap_lock, since InitModule already has it.

WebKitTools:

Reviewed by Maciej Stachowiak.

Fixed <rdar://problem/4485644> REGRESSION: JavaScriptCore has init routines


No more mollycoddling for you, FastMalloc.o!


  • Scripts/check-for-global-initializers:
Location:
trunk/JavaScriptCore/wtf
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/wtf/FastMalloc.cpp

    r19209 r19245  
    13921392}
    13931393
     1394#ifdef WTF_CHANGES
    13941395bool isMultiThreaded;
    13951396TCMalloc_ThreadCache *mainThreadCache;
    13961397
    1397 void fastMallocSetIsMultiThreaded() 
     1398void fastMallocSetIsMultiThreaded()
    13981399{
    13991400    // We lock when writing mainThreadCache but not when reading it. It's OK if
     
    14031404    // clients must call this function before allocating on other threads, so they'll
    14041405    // have synchronized before reading mainThreadCache.
    1405 
    1406     // mainThreadCache is only set when isMultiThreaded is false, to save a
    1407     // branch in some cases.
    1408 
    1409     SpinLockHolder lock(&pageheap_lock);
    1410     isMultiThreaded = true;
    1411     mainThreadCache = 0;
    1412 }
     1406   
     1407    // A similar principle applies to isMultiThreaded. It's OK for the main thread
     1408    // in GetCache() to read a stale, false value for isMultiThreaded because
     1409    // doing so will just cause it to make an unnecessary call to InitModule(),
     1410    // which will synchronize it.
     1411
     1412    // To save a branch in some cases, mainThreadCache is only set when
     1413    // isMultiThreaded is false.
     1414
     1415    {
     1416        SpinLockHolder lock(&pageheap_lock);
     1417        isMultiThreaded = true;
     1418        mainThreadCache = 0;
     1419    }
     1420
     1421    TCMalloc_ThreadCache::InitModule();
     1422}
     1423#endif
    14131424
    14141425ALWAYS_INLINE TCMalloc_ThreadCache* TCMalloc_ThreadCache::GetCache() {
    14151426  void* ptr = NULL;
     1427#ifndef WTF_CHANGES
    14161428  if (!tsd_inited) {
    14171429    InitModule();
    14181430  } else {
    1419       if (mainThreadCache)
    1420           ptr = mainThreadCache;
    1421       else
    1422           ptr = pthread_getspecific(heap_key);
    1423   }
     1431    ptr = pthread_getspecific(heap_key);
     1432  }
     1433#else
     1434  if (mainThreadCache) // fast path for single-threaded mode
     1435    return mainThreadCache;
     1436
     1437  if (isMultiThreaded) // fast path for multi-threaded mode -- heap_key already initialized
     1438    ptr = pthread_getspecific(heap_key);
     1439  else // slow path for possible first-time init
     1440    InitModule();
     1441#endif
    14241442  if (ptr == NULL) ptr = CreateCacheIfNecessary();
    14251443  return reinterpret_cast<TCMalloc_ThreadCache*>(ptr);
     
    14581476  SpinLockHolder h(&pageheap_lock);
    14591477  if (!phinited) {
     1478#ifdef WTF_CHANGES
     1479    InitTSD();
     1480#endif
    14601481    InitSizeClasses();
    14611482    threadheap_allocator.Init();
     
    14811502  pthread_t zero;
    14821503  memset(&zero, 0, sizeof(zero));
     1504#ifndef WTF_CHANGES
    14831505  SpinLockHolder h(&pageheap_lock);
     1506#else
     1507  ASSERT(pageheap_lock.IsLocked());
     1508#endif
    14841509  for (TCMalloc_ThreadCache* h = thread_heaps; h != NULL; h = h->next_) {
    14851510    if (h->tid_ == zero) {
     
    20532078};
    20542079
     2080#ifndef WTF_CHANGES
    20552081static TCMallocGuard module_enter_exit_hook;
    2056 
     2082#endif
    20572083
    20582084//-------------------------------------------------------------------
  • trunk/JavaScriptCore/wtf/TCSpinLock.h

    r13089 r19245  
    9595#endif
    9696  }
     97
     98#ifdef WTF_CHANGES 
     99  inline bool IsLocked() {
     100    return private_lockword_ != 0;
     101  }
     102#endif
    97103};
    98104
Note: See TracChangeset for help on using the changeset viewer.