181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)/*
281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * Copyright (C) 2009 Apple Inc. All rights reserved.
381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * Copyright (C) 2013 Google Inc. All rights reserved.
481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) *
581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without
681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * modification, are permitted provided that the following conditions
781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * are met:
881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
1081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
1181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
1281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) *    documentation and/or other materials provided with the distribution.
1381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) *
1481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
1581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
1881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
1981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
2281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) */
2681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
2781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)#include "config.h"
2881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)#include "wtf/ArrayBufferContents.h"
2981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
30f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "wtf/Assertions.h"
3109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "wtf/PartitionAlloc.h"
323c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "wtf/WTF.h"
33fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch#include <string.h>
3481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
3581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)namespace WTF {
3681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
37e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)ArrayBufferContents::ArrayBufferContents()
3893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    : m_data(0)
3993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    , m_sizeInBytes(0)
4093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    , m_deallocationObserver(0) { }
4181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
42e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)ArrayBufferContents::ArrayBufferContents(unsigned numElements, unsigned elementByteSize, ArrayBufferContents::InitializationPolicy policy)
4393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    : m_data(0)
4493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    , m_sizeInBytes(0)
4593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    , m_deallocationObserver(0)
4693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
4793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // Do not allow 32-bit overflow of the total size.
4893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (numElements) {
4993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        unsigned totalSize = numElements * elementByteSize;
5093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        if (totalSize / numElements != elementByteSize) {
5193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            m_data = 0;
5293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            return;
5393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        }
5493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
55f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    allocateMemory(numElements * elementByteSize, policy, m_data);
56f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    m_sizeInBytes = numElements * elementByteSize;
5793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
5881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
5906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)ArrayBufferContents::ArrayBufferContents(
6006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    void* data, unsigned sizeInBytes, ArrayBufferDeallocationObserver* observer)
61e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    : m_data(data)
62e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    , m_sizeInBytes(sizeInBytes)
6306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    , m_deallocationObserver(observer)
64e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{
65e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    if (!m_data) {
66e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        ASSERT(!m_sizeInBytes);
67e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        m_sizeInBytes = 0;
68e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        // Allow null data if size is 0 bytes, make sure m_data is valid pointer.
693c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        // (partitionAllocGeneric guarantees valid pointer for size 0)
70f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        allocateMemory(0, ZeroInitialize, m_data);
71e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    }
72e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch}
73e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
7481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)ArrayBufferContents::~ArrayBufferContents()
7581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles){
763c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    freeMemory(m_data, m_sizeInBytes);
77e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    clear();
78e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)}
79e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
80e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)void ArrayBufferContents::clear()
81e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){
8293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (m_data && m_deallocationObserver)
8306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        m_deallocationObserver->arrayBufferDeallocated(m_sizeInBytes);
8493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    m_data = 0;
8593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    m_sizeInBytes = 0;
86e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    m_deallocationObserver = 0;
8781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)}
8881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
8993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void ArrayBufferContents::transfer(ArrayBufferContents& other)
9093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
9193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    ASSERT(!other.m_data);
9293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    other.m_data = m_data;
9393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    other.m_sizeInBytes = m_sizeInBytes;
9493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    clear();
9593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
9693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
97fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdochvoid ArrayBufferContents::copyTo(ArrayBufferContents& other)
98fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch{
99fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch    ASSERT(!other.m_sizeInBytes);
1003c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    other.freeMemory(other.m_data, other.m_sizeInBytes);
101fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch    allocateMemory(m_sizeInBytes, DontInitialize, other.m_data);
102fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch    if (!other.m_data)
103fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch        return;
104fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch    memcpy(other.m_data, m_data, m_sizeInBytes);
105fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch    other.m_sizeInBytes = m_sizeInBytes;
106fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch}
107fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
108f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)void ArrayBufferContents::allocateMemory(size_t size, InitializationPolicy policy, void*& data)
109e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{
11009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    data = partitionAllocGenericFlags(WTF::Partitions::getBufferPartition(), PartitionAllocReturnNull, size);
11109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (policy == ZeroInitialize && data)
112f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        memset(data, '\0', size);
113e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch}
114e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
1151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)void ArrayBufferContents::freeMemory(void* data, size_t)
116e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{
11709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    partitionFreeGeneric(WTF::Partitions::getBufferPartition(), data);
118e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch}
119e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
12081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)} // namespace WTF
121