1/* 2 * Copyright (C) 2012 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef ArrayStorage_h 27#define ArrayStorage_h 28 29#include "ArrayConventions.h" 30#include "Butterfly.h" 31#include "IndexingHeader.h" 32#include "SparseArrayValueMap.h" 33#include "WriteBarrier.h" 34#include <wtf/Noncopyable.h> 35 36namespace JSC { 37 38// This struct holds the actual data values of an array. A JSArray object points to its contained ArrayStorage 39// struct by pointing to m_vector. To access the contained ArrayStorage struct, use the getStorage() and 40// setStorage() methods. It is important to note that there may be space before the ArrayStorage that 41// is used to quick unshift / shift operation. The actual allocated pointer is available by using: 42// getStorage() - m_indexBias * sizeof(JSValue) 43// All slots in ArrayStorage (slots from 0 to vectorLength) are expected to be initialized to a JSValue or, 44// for hole slots, JSValue(). 45struct ArrayStorage { 46 WTF_MAKE_NONCOPYABLE(ArrayStorage); 47private: 48 ArrayStorage() { } // Not directly instantiable. Can only be created as part of a Butterfly. 49public: 50 51 static ArrayStorage* from(Butterfly* butterfly) { return reinterpret_cast_ptr<ArrayStorage*>(butterfly); } 52 static ArrayStorage* from(IndexingHeader* indexingHeader) { return indexingHeader->arrayStorage(); } 53 54 Butterfly* butterfly() { return reinterpret_cast<Butterfly*>(this); } 55 IndexingHeader* indexingHeader() { return IndexingHeader::from(this); } 56 const IndexingHeader* indexingHeader() const { return IndexingHeader::from(this); } 57 58 // We steal two fields from the indexing header: vectorLength and length. 59 unsigned length() const { return indexingHeader()->publicLength(); } 60 void setLength(unsigned length) { indexingHeader()->setPublicLength(length); } 61 unsigned vectorLength() { return indexingHeader()->vectorLength(); } 62 void setVectorLength(unsigned length) { indexingHeader()->setVectorLength(length); } 63 64 ALWAYS_INLINE void copyHeaderFromDuringGC(const ArrayStorage& other) 65 { 66 m_sparseMap.copyFrom(other.m_sparseMap); 67 m_indexBias = other.m_indexBias; 68 m_numValuesInVector = other.m_numValuesInVector; 69 } 70 71 bool hasHoles() const 72 { 73 return m_numValuesInVector != length(); 74 } 75 76 bool inSparseMode() 77 { 78 return m_sparseMap && m_sparseMap->sparseMode(); 79 } 80 81 ContiguousJSValues vector() { return ContiguousJSValues(m_vector, vectorLength()); } 82 83 WriteBarrier<SparseArrayValueMap> m_sparseMap; 84 unsigned m_indexBias; 85 unsigned m_numValuesInVector; 86#if USE(JSVALUE32_64) 87 uintptr_t m_padding; 88#endif 89 WriteBarrier<Unknown> m_vector[1]; 90 91 static ptrdiff_t lengthOffset() { return Butterfly::offsetOfPublicLength(); } 92 static ptrdiff_t vectorLengthOffset() { return Butterfly::offsetOfVectorLength(); } 93 static ptrdiff_t numValuesInVectorOffset() { return OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector); } 94 static ptrdiff_t vectorOffset() { return OBJECT_OFFSETOF(ArrayStorage, m_vector); } 95 static ptrdiff_t indexBiasOffset() { return OBJECT_OFFSETOF(ArrayStorage, m_indexBias); } 96 static ptrdiff_t sparseMapOffset() { return OBJECT_OFFSETOF(ArrayStorage, m_sparseMap); } 97 98 static size_t sizeFor(unsigned vectorLength) 99 { 100 return ArrayStorage::vectorOffset() + vectorLength * sizeof(WriteBarrier<Unknown>); 101 } 102}; 103 104} // namespace JSC 105 106#endif // ArrayStorage_h 107 108