1/*
2 * Copyright (C) 2013, 2014 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#include "config.h"
27#include "PropertyMapHashTable.h"
28
29#include "JSCInlines.h"
30
31namespace JSC {
32
33const ClassInfo PropertyTable::s_info = { "PropertyTable", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(PropertyTable) };
34
35PropertyTable* PropertyTable::create(VM& vm, unsigned initialCapacity)
36{
37 PropertyTable* table = new (NotNull, allocateCell<PropertyTable>(vm.heap)) PropertyTable(vm, initialCapacity);
38 table->finishCreation(vm);
39 return table;
40}
41
42PropertyTable* PropertyTable::clone(VM& vm, const PropertyTable& other)
43{
44 PropertyTable* table = new (NotNull, allocateCell<PropertyTable>(vm.heap)) PropertyTable(vm, other);
45 table->finishCreation(vm);
46 return table;
47}
48
49PropertyTable* PropertyTable::clone(VM& vm, unsigned initialCapacity, const PropertyTable& other)
50{
51 PropertyTable* table = new (NotNull, allocateCell<PropertyTable>(vm.heap)) PropertyTable(vm, initialCapacity, other);
52 table->finishCreation(vm);
53 return table;
54}
55
56PropertyTable::PropertyTable(VM& vm, unsigned initialCapacity)
57 : JSCell(vm, vm.propertyTableStructure.get())
58 , m_indexSize(sizeForCapacity(initialCapacity))
59 , m_indexMask(m_indexSize - 1)
60 , m_index(static_cast<unsigned*>(fastZeroedMalloc(dataSize())))
61 , m_keyCount(0)
62 , m_deletedCount(0)
63{
64 ASSERT(isPowerOf2(m_indexSize));
65}
66
67PropertyTable::PropertyTable(VM& vm, const PropertyTable& other)
68 : JSCell(vm, vm.propertyTableStructure.get())
69 , m_indexSize(other.m_indexSize)
70 , m_indexMask(other.m_indexMask)
71 , m_index(static_cast<unsigned*>(fastMalloc(dataSize())))
72 , m_keyCount(other.m_keyCount)
73 , m_deletedCount(other.m_deletedCount)
74{
75 ASSERT(isPowerOf2(m_indexSize));
76
77 memcpy(m_index, other.m_index, dataSize());
78
79 iterator end = this->end();
80 for (iterator iter = begin(); iter != end; ++iter)
81 iter->key->ref();
82
83 // Copy the m_deletedOffsets vector.
84 Vector<PropertyOffset>* otherDeletedOffsets = other.m_deletedOffsets.get();
85 if (otherDeletedOffsets)
86 m_deletedOffsets = std::make_unique<Vector<PropertyOffset>>(*otherDeletedOffsets);
87}
88
89PropertyTable::PropertyTable(VM& vm, unsigned initialCapacity, const PropertyTable& other)
90 : JSCell(vm, vm.propertyTableStructure.get())
91 , m_indexSize(sizeForCapacity(initialCapacity))
92 , m_indexMask(m_indexSize - 1)
93 , m_index(static_cast<unsigned*>(fastZeroedMalloc(dataSize())))
94 , m_keyCount(0)
95 , m_deletedCount(0)
96{
97 ASSERT(isPowerOf2(m_indexSize));
98 ASSERT(initialCapacity >= other.m_keyCount);
99
100 const_iterator end = other.end();
101 for (const_iterator iter = other.begin(); iter != end; ++iter) {
102 ASSERT(canInsert());
103 reinsert(*iter);
104 iter->key->ref();
105 }
106
107 // Copy the m_deletedOffsets vector.
108 Vector<PropertyOffset>* otherDeletedOffsets = other.m_deletedOffsets.get();
109 if (otherDeletedOffsets)
110 m_deletedOffsets = std::make_unique<Vector<PropertyOffset>>(*otherDeletedOffsets);
111}
112
113void PropertyTable::destroy(JSCell* cell)
114{
115 static_cast<PropertyTable*>(cell)->PropertyTable::~PropertyTable();
116}
117
118PropertyTable::~PropertyTable()
119{
120 iterator end = this->end();
121 for (iterator iter = begin(); iter != end; ++iter)
122 iter->key->deref();
123
124 fastFree(m_index);
125}
126
127} // namespace JSC
128
129