Changeset 75709 in webkit


Ignore:
Timestamp:
Jan 13, 2011 3:58:25 AM (13 years ago)
Author:
xan@webkit.org
Message:

2011-01-13 Xan Lopez <xlopez@igalia.com>

Reviewed by Gavin Barraclough.

JIT requires VM overcommit (particularly on x86-64), Linux does not by default support this without swap?
https://bugs.webkit.org/show_bug.cgi?id=42756

The FixedVMPool Allocator does not work well on systems where
allocating very large amounts of memory upfront is not reasonable,
like Linux without overcommit enabled. As a workaround, on Linux,
default to the values used in embedded environments (in the MB
range), and only jump to the GB range if we detect at runtime that
overcommit is enabled. Should fix crashes on Linux/x86_64 with
less than 3 or 4GB of RAM.

  • jit/ExecutableAllocatorFixedVMPool.cpp: (JSC::FixedVMPoolAllocator::free): use new variables for VM pool size and coalesce limit. (JSC::ExecutableAllocator::isValid): swap the variables from embedded to generic values at runtime, on linux, if overcommit is enabled. (JSC::ExecutableAllocator::underMemoryPressure): use new variables for VM pool size and coalesce limit.
Location:
trunk/Source/JavaScriptCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r75625 r75709  
     12011-01-13  Xan Lopez  <xlopez@igalia.com>
     2
     3        Reviewed by Gavin Barraclough.
     4
     5        JIT requires VM overcommit (particularly on x86-64), Linux does not by default support this without swap?
     6        https://bugs.webkit.org/show_bug.cgi?id=42756
     7
     8        The FixedVMPool Allocator does not work well on systems where
     9        allocating very large amounts of memory upfront is not reasonable,
     10        like Linux without overcommit enabled. As a workaround, on Linux,
     11        default to the values used in embedded environments (in the MB
     12        range), and only jump to the GB range if we detect at runtime that
     13        overcommit is enabled. Should fix crashes on Linux/x86_64 with
     14        less than 3 or 4GB of RAM.
     15
     16        * jit/ExecutableAllocatorFixedVMPool.cpp:
     17        (JSC::FixedVMPoolAllocator::free): use new variables for VM pool
     18        size and coalesce limit.
     19        (JSC::ExecutableAllocator::isValid): swap the variables from
     20        embedded to generic values at runtime, on linux, if overcommit is
     21        enabled.
     22        (JSC::ExecutableAllocator::underMemoryPressure): use new variables
     23        for VM pool size and coalesce limit.
     24
    1252011-01-12  Xan Lopez  <xlopez@igalia.com>
    226
  • trunk/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp

    r74454 r75709  
    3939#include <wtf/VMTags.h>
    4040
    41 #if CPU(X86_64)
    42     // These limits suitable on 64-bit platforms (particularly x86-64, where we require all jumps to have a 2Gb max range).
    43     #define VM_POOL_SIZE (2u * 1024u * 1024u * 1024u) // 2Gb
    44     #define COALESCE_LIMIT (16u * 1024u * 1024u) // 16Mb
     41#if OS(LINUX)
     42#include <stdio.h>
     43#endif
     44
     45static const unsigned vmPoolSizeGeneric = 2u * 1024u * 1024u * 1024u; // 2Gb
     46static const unsigned coalesceLimitGeneric = 16u * 1024u * 1024u; // 16Mb
     47
     48static const unsigned vmPoolSizeEmbedded = 32u * 1024u * 1024u; // 32Mb
     49static const unsigned coalesceLimitEmbedded = 4u * 1024u * 1024u; // 4Mb
     50
     51#if CPU(X86_64) && !OS(LINUX)
     52// These limits suitable on 64-bit platforms (particularly x86-64,
     53// where we require all jumps to have a 2Gb max range). We don't
     54// enable this by default on Linux, since it needs overcommit and
     55// distros commonly disable that feature. We'll check the value
     56// for the overcommit feature at runtime and re-assign the Generic
     57// values if it's enabled.
     58static unsigned vmPoolSize = vmPoolSizeGeneric; // 2Gb
     59static unsigned coalesceLimit = coalesceLimitGeneric; // 16Mb
    4560#else
    4661    // These limits are hopefully sensible on embedded platforms.
    47     #define VM_POOL_SIZE (32u * 1024u * 1024u) // 32Mb
    48     #define COALESCE_LIMIT (4u * 1024u * 1024u) // 4Mb
     62static unsigned vmPoolSize = vmPoolSizeEmbedded; // 32Mb
     63static unsigned coalesceLimit = coalesceLimitEmbedded; // 4Mb
    4964#endif
    5065
     
    316331        // coalescing any neighboring fragments.
    317332        m_countFreedSinceLastCoalesce += size;
    318         if (m_countFreedSinceLastCoalesce >= COALESCE_LIMIT) {
     333        if (m_countFreedSinceLastCoalesce >= coalesceLimit) {
    319334            m_countFreedSinceLastCoalesce = 0;
    320335            coalesceFreeSpace();
     
    434449static size_t allocatedCount = 0;
    435450
     451#if OS(LINUX)
     452static void maybeModifyVMPoolSize()
     453{
     454    FILE* fp = fopen("/proc/sys/vm/overcommit_memory", "r");
     455    if (!fp)
     456        return;
     457
     458    unsigned overcommit = 0;
     459    fscanf(fp, "%u", &overcommit);
     460    if (overcommit == 1) {
     461        vmPoolSize = vmPoolSizeGeneric; // 2Gb
     462        coalesceLimit = coalesceLimitGeneric; // 16Mb
     463    }
     464
     465    fclose(fp);
     466}
     467#endif
     468
    436469bool ExecutableAllocator::isValid() const
    437470{
    438471    SpinLockHolder lock_holder(&spinlock);
    439     if (!allocator)
    440         allocator = new FixedVMPoolAllocator(JIT_ALLOCATOR_LARGE_ALLOC_SIZE, VM_POOL_SIZE);
     472    if (!allocator) {
     473#if OS(LINUX)
     474        maybeModifyVMPoolSize();
     475#endif
     476        allocator = new FixedVMPoolAllocator(JIT_ALLOCATOR_LARGE_ALLOC_SIZE, vmPoolSize);
     477    }
    441478    return allocator->isValid();
    442479}
     
    446483    // Technically we should take the spin lock here, but we don't care if we get stale data.
    447484    // This is only really a heuristic anyway.
    448     return allocatedCount > (VM_POOL_SIZE / 2);
     485    return allocatedCount > (vmPoolSize / 2);
    449486}
    450487
Note: See TracChangeset for help on using the changeset viewer.