Ejemplo n.º 1
0
    _Must_inspect_result_ bool WebAssemblySharedArrayBuffer::GrowMemory(uint32 newBufferLength)
    {
        uint32 bufferLength = sharedContents->bufferLength;
        BYTE* buffer = sharedContents->buffer;
        if (newBufferLength < bufferLength || newBufferLength > sharedContents->maxBufferLength)
        {
            AssertMsg(newBufferLength <= sharedContents->maxBufferLength, "This shouldn't happen");
            Assert(UNREACHED);
            JavascriptError::ThrowTypeError(GetScriptContext(), WASMERR_BufferGrowOnly);
        }

        uint32 growSize = newBufferLength - bufferLength;

        // We're not growing the buffer, do nothing
        if (growSize == 0)
        {
            return true;
        }

        AssertOrFailFast(buffer);
        if (IsValidVirtualBufferLength(newBufferLength))
        {
            auto virtualAllocFunc = [=]
            {
                return !!VirtualAlloc(buffer + bufferLength, growSize, MEM_COMMIT, PAGE_READWRITE);
            };
            if (!this->GetRecycler()->DoExternalAllocation(growSize, virtualAllocFunc))
            {
                return false;
            }

            this->GetRecycler()->AddExternalMemoryUsage(growSize);
        }
        else
        {
            // We have already allocated maxLength in the heap if we're not using virtual alloc
        }
        ZeroMemory(buffer + bufferLength, growSize);
        sharedContents->bufferLength = newBufferLength;
        ValidateBuffer();
        return true;
    }
Ejemplo n.º 2
0
    void WebAssemblySharedArrayBuffer::FreeBuffer(BYTE* buffer, uint32 length, uint32 maxLength)
    {
        if (IsValidVirtualBufferLength(length))
        {
            FreeMemAlloc(buffer);
        }
        else
        {
            HeapDeleteArray(maxLength, buffer);

            AssertOrFailFast(maxLength >= length);
            // JavascriptSharedArrayBuffer::Finalize will only report freeing `length`, we have to take care of the balance
            uint32 additionalSize = maxLength - length;
            if (additionalSize > 0)
            {
                Recycler* recycler = GetType()->GetLibrary()->GetRecycler();
                recycler->ReportExternalMemoryFree(additionalSize);
            }
        }
    }
Ejemplo n.º 3
0
    void JavascriptSharedArrayBuffer::Finalize(bool isShutdown)
    {
        if (sharedContents == nullptr)
        {
            return;
        }

        uint ref = InterlockedDecrement(&sharedContents->refCount);
        if (ref == 0)
        {
#if _WIN64
                //AsmJS Virtual Free
                //TOD - see if isBufferCleared need to be added for free too
                if (IsValidVirtualBufferLength(sharedContents->bufferLength) && !sharedContents->isBufferCleared)
                {
                    LPVOID startBuffer = (LPVOID)((uint64)sharedContents->buffer);
                    BOOL fSuccess = VirtualFree((LPVOID)startBuffer, 0, MEM_RELEASE);
                    Assert(fSuccess);
                    sharedContents->isBufferCleared = true;
                }
                else
                {
                    free(sharedContents->buffer);
                }
#else
                free(sharedContents->buffer);
#endif
            Recycler* recycler = GetType()->GetLibrary()->GetRecycler();
            recycler->ReportExternalMemoryFree(sharedContents->bufferLength);

            sharedContents->Cleanup();
            HeapDelete(sharedContents);
        }

        sharedContents = nullptr;
    }
Ejemplo n.º 4
0
 JavascriptSharedArrayBuffer::JavascriptSharedArrayBuffer(uint32 length, DynamicType * type) :
     SharedArrayBuffer(length, type, (IsValidVirtualBufferLength(length)) ? AllocWrapper : malloc)
 {
 }