Foo::s_info should be Foo::info(), so that you can change how the s_info is actually...
[WebKit-https.git] / Source / JavaScriptCore / runtime / PropertyTable.cpp
1 /*
2  * Copyright (C) 2013 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 COMPUTER, 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 COMPUTER, 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 "JSCJSValueInlines.h"
30 #include "JSCellInlines.h"
31 #include "SlotVisitorInlines.h"
32 #include "StructureInlines.h"
33
34 namespace JSC {
35
36 const ClassInfo PropertyTable::s_info = { "PropertyTable", 0, 0, 0, CREATE_METHOD_TABLE(PropertyTable) };
37
38 PropertyTable* PropertyTable::create(VM& vm, unsigned initialCapacity)
39 {
40     PropertyTable* table = new (NotNull, allocateCell<PropertyTable>(vm.heap)) PropertyTable(vm, initialCapacity);
41     table->finishCreation(vm);
42     return table;
43 }
44
45 PropertyTable* PropertyTable::clone(VM& vm, JSCell* owner, const PropertyTable& other)
46 {
47     PropertyTable* table = new (NotNull, allocateCell<PropertyTable>(vm.heap)) PropertyTable(vm, owner, other);
48     table->finishCreation(vm);
49     return table;
50 }
51
52 PropertyTable* PropertyTable::clone(VM& vm, JSCell* owner, unsigned initialCapacity, const PropertyTable& other)
53 {
54     PropertyTable* table = new (NotNull, allocateCell<PropertyTable>(vm.heap)) PropertyTable(vm, owner, initialCapacity, other);
55     table->finishCreation(vm);
56     return table;
57 }
58
59 PropertyTable::PropertyTable(VM& vm, unsigned initialCapacity)
60     : JSCell(vm, vm.propertyTableStructure.get())
61     , m_indexSize(sizeForCapacity(initialCapacity))
62     , m_indexMask(m_indexSize - 1)
63     , m_index(static_cast<unsigned*>(fastZeroedMalloc(dataSize())))
64     , m_keyCount(0)
65     , m_deletedCount(0)
66 {
67     ASSERT(isPowerOf2(m_indexSize));
68 }
69
70 PropertyTable::PropertyTable(VM& vm, JSCell* owner, const PropertyTable& other)
71     : JSCell(vm, vm.propertyTableStructure.get())
72     , m_indexSize(other.m_indexSize)
73     , m_indexMask(other.m_indexMask)
74     , m_index(static_cast<unsigned*>(fastMalloc(dataSize())))
75     , m_keyCount(other.m_keyCount)
76     , m_deletedCount(other.m_deletedCount)
77 {
78     ASSERT(isPowerOf2(m_indexSize));
79
80     memcpy(m_index, other.m_index, dataSize());
81
82     iterator end = this->end();
83     for (iterator iter = begin(); iter != end; ++iter) {
84         iter->key->ref();
85         Heap::writeBarrier(owner, iter->specificValue.get());
86     }
87
88     // Copy the m_deletedOffsets vector.
89     Vector<PropertyOffset>* otherDeletedOffsets = other.m_deletedOffsets.get();
90     if (otherDeletedOffsets)
91         m_deletedOffsets = adoptPtr(new Vector<PropertyOffset>(*otherDeletedOffsets));
92 }
93
94 PropertyTable::PropertyTable(VM& vm, JSCell* owner, unsigned initialCapacity, const PropertyTable& other)
95     : JSCell(vm, vm.propertyTableStructure.get())
96     , m_indexSize(sizeForCapacity(initialCapacity))
97     , m_indexMask(m_indexSize - 1)
98     , m_index(static_cast<unsigned*>(fastZeroedMalloc(dataSize())))
99     , m_keyCount(0)
100     , m_deletedCount(0)
101 {
102     ASSERT(isPowerOf2(m_indexSize));
103     ASSERT(initialCapacity >= other.m_keyCount);
104
105     const_iterator end = other.end();
106     for (const_iterator iter = other.begin(); iter != end; ++iter) {
107         ASSERT(canInsert());
108         reinsert(*iter);
109         iter->key->ref();
110         Heap::writeBarrier(owner, iter->specificValue.get());
111     }
112
113     // Copy the m_deletedOffsets vector.
114     Vector<PropertyOffset>* otherDeletedOffsets = other.m_deletedOffsets.get();
115     if (otherDeletedOffsets)
116         m_deletedOffsets = adoptPtr(new Vector<PropertyOffset>(*otherDeletedOffsets));
117 }
118
119 void PropertyTable::destroy(JSCell* cell)
120 {
121     static_cast<PropertyTable*>(cell)->PropertyTable::~PropertyTable();
122 }
123
124 PropertyTable::~PropertyTable()
125 {
126     iterator end = this->end();
127     for (iterator iter = begin(); iter != end; ++iter)
128         iter->key->deref();
129
130     fastFree(m_index);
131 }
132
133 void PropertyTable::visitChildren(JSCell* cell, SlotVisitor& visitor)
134 {
135     PropertyTable* thisObject = jsCast<PropertyTable*>(cell);
136     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
137     ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
138
139     JSCell::visitChildren(thisObject, visitor);
140
141     PropertyTable::iterator end = thisObject->end();
142     for (PropertyTable::iterator ptr = thisObject->begin(); ptr != end; ++ptr)
143         visitor.append(&ptr->specificValue);
144 }
145
146 }