Beispiel #1
0
SharedArrayRawBuffer*
SharedArrayRawBuffer::New(JSContext* cx, uint32_t length)
{
    // The value (uint32_t)-1 is used as a signal in various places,
    // so guard against it on principle.
    MOZ_ASSERT(length != (uint32_t)-1);

    // Add a page for the header and round to a page boundary.
    uint32_t allocSize = SharedArrayAllocSize(length);
    if (allocSize <= length)
        return nullptr;

    bool preparedForAsmJS = jit::JitOptions.asmJSAtomicsEnable && IsValidAsmJSHeapLength(length);

    void* p = nullptr;
    if (preparedForAsmJS) {
        // Test >= to guard against the case where multiple extant runtimes
        // race to allocate.
        if (++numLive >= maxLive) {
            JSRuntime* rt = cx->runtime();
            if (rt->largeAllocationFailureCallback)
                rt->largeAllocationFailureCallback(rt->largeAllocationFailureCallbackData);
            if (numLive >= maxLive) {
                numLive--;
                return nullptr;
            }
        }

        uint32_t mappedSize = SharedArrayMappedSize(allocSize);

        // Get the entire reserved region (with all pages inaccessible)
        p = MapMemory(mappedSize, false);
        if (!p) {
            numLive--;
            return nullptr;
        }

        if (!MarkValidRegion(p, allocSize)) {
            UnmapMemory(p, mappedSize);
            numLive--;
            return nullptr;
        }

# if defined(MOZ_VALGRIND) && defined(VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE)
        // Tell Valgrind/Memcheck to not report accesses in the inaccessible region.
        VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE((unsigned char*)p + allocSize,
                mappedSize - allocSize);
# endif
    } else {
        p = MapMemory(allocSize, true);
        if (!p)
            return nullptr;
    }

    uint8_t* buffer = reinterpret_cast<uint8_t*>(p) + gc::SystemPageSize();
    uint8_t* base = buffer - sizeof(SharedArrayRawBuffer);
    SharedArrayRawBuffer* rawbuf = new (base) SharedArrayRawBuffer(buffer, length, preparedForAsmJS);
    MOZ_ASSERT(rawbuf->length == length); // Deallocation needs this
    return rawbuf;
}
SharedArrayRawBuffer*
SharedArrayRawBuffer::New(JSContext* cx, uint32_t length)
{
    // The value (uint32_t)-1 is used as a signal in various places,
    // so guard against it on principle.
    MOZ_ASSERT(length != (uint32_t)-1);

    // Add a page for the header and round to a page boundary.
    uint32_t allocSize = (length + 2*AsmJSPageSize - 1) & ~(AsmJSPageSize - 1);
    if (allocSize <= length)
        return nullptr;
#if defined(ASMJS_MAY_USE_SIGNAL_HANDLERS_FOR_OOB)
    // Test >= to guard against the case where multiple extant runtimes
    // race to allocate.
    if (++numLive >= maxLive) {
        JSRuntime* rt = cx->runtime();
        if (rt->largeAllocationFailureCallback)
            rt->largeAllocationFailureCallback(rt->largeAllocationFailureCallbackData);
        if (numLive >= maxLive) {
            numLive--;
            return nullptr;
        }
    }
    // Get the entire reserved region (with all pages inaccessible)
    void* p = MapMemory(SharedArrayMappedSize, false);
    if (!p) {
        numLive--;
        return nullptr;
    }

    if (!MarkValidRegion(p, allocSize)) {
        UnmapMemory(p, SharedArrayMappedSize);
        numLive--;
        return nullptr;
    }
#   if defined(MOZ_VALGRIND) && defined(VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE)
    // Tell Valgrind/Memcheck to not report accesses in the inaccessible region.
    VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE((unsigned char*)p + allocSize,
                                                   SharedArrayMappedSize - allocSize);
#   endif
#else
    void* p = MapMemory(allocSize, true);
    if (!p)
        return nullptr;
#endif
    uint8_t* buffer = reinterpret_cast<uint8_t*>(p) + AsmJSPageSize;
    uint8_t* base = buffer - sizeof(SharedArrayRawBuffer);
    return new (base) SharedArrayRawBuffer(buffer, length);
}