source: webkit/trunk/JavaScriptCore/kjs/StructureID.cpp@ 36693

Last change on this file since 36693 was 36445, checked in by Adam Roben, 17 years ago

Build fix

  • kjs/StructureID.cpp: Removed a stray semicolon.
File size: 6.8 KB
Line 
1/*
2 * Copyright (C) 2008 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 "StructureID.h"
28
29#include "identifier.h"
30#include "JSObject.h"
31#include "PropertyNameArray.h"
32#include <wtf/RefPtr.h>
33
34using namespace std;
35
36namespace JSC {
37
38StructureID::StructureID(JSValue* prototype, JSType type)
39 : m_isDictionary(false)
40 , m_type(type)
41 , m_prototype(prototype)
42 , m_cachedPrototypeChain(0)
43 , m_previous(0)
44 , m_nameInPrevious(0)
45 , m_transitionCount(0)
46{
47 ASSERT(m_prototype);
48 ASSERT(m_prototype->isObject() || m_prototype->isNull());
49}
50
51void StructureID::getEnumerablePropertyNames(PropertyNameArray& propertyNames) const
52{
53 if (m_cachedPropertyNameArray.isEmpty())
54 m_propertyMap.getEnumerablePropertyNames(m_cachedPropertyNameArray);
55
56 if (!propertyNames.size()) {
57 for (size_t i = 0; i < m_cachedPropertyNameArray.size(); ++i)
58 propertyNames.addKnownUnique(m_cachedPropertyNameArray[i]);
59 } else {
60 for (size_t i = 0; i < m_cachedPropertyNameArray.size(); ++i)
61 propertyNames.add(m_cachedPropertyNameArray[i]);
62 }
63}
64
65void StructureID::transitionTo(StructureID* oldStructureID, StructureID* newStructureID, JSObject* slotBase)
66{
67 if (!slotBase->usingInlineStorage() && oldStructureID->m_propertyMap.size() != newStructureID->m_propertyMap.size())
68 slotBase->allocatePropertyStorage(oldStructureID->m_propertyMap.size(), newStructureID->m_propertyMap.size());
69}
70
71PassRefPtr<StructureID> StructureID::addPropertyTransition(StructureID* structureID, const Identifier& propertyName, JSValue* value, unsigned attributes, JSObject* slotBase, PutPropertySlot& slot, PropertyStorage& propertyStorage)
72{
73 ASSERT(!structureID->m_isDictionary);
74 ASSERT(structureID->m_type == ObjectType);
75
76 if (StructureID* existingTransition = structureID->m_transitionTable.get(make_pair(propertyName.ustring().rep(), attributes))) {
77 if (!slotBase->usingInlineStorage() && structureID->m_propertyMap.size() != existingTransition->m_propertyMap.size())
78 slotBase->allocatePropertyStorage(structureID->m_propertyMap.size(), existingTransition->m_propertyMap.size());
79
80 size_t offset = existingTransition->propertyMap().getOffset(propertyName);
81 ASSERT(offset != WTF::notFound);
82 propertyStorage[offset] = value;
83 slot.setNewProperty(slotBase, offset);
84
85 return existingTransition;
86 }
87
88 if (structureID->m_transitionCount > s_maxTransitionLength) {
89 RefPtr<StructureID> transition = toDictionaryTransition(structureID);
90 transition->m_propertyMap.put(propertyName, value, attributes, false, slotBase, slot, propertyStorage);
91 return transition.release();
92 }
93
94 RefPtr<StructureID> transition = create(structureID->m_prototype);
95 transition->m_cachedPrototypeChain = structureID->m_cachedPrototypeChain;
96 transition->m_previous = structureID;
97 transition->m_nameInPrevious = propertyName.ustring().rep();
98 transition->m_attributesInPrevious = attributes;
99 transition->m_transitionCount = structureID->m_transitionCount + 1;
100 transition->m_propertyMap = structureID->m_propertyMap;
101
102 transition->m_propertyMap.put(propertyName, value, attributes, false, slotBase, slot, propertyStorage);
103
104 structureID->m_transitionTable.add(make_pair(propertyName.ustring().rep(), attributes), transition.get());
105 return transition.release();
106}
107
108PassRefPtr<StructureID> StructureID::toDictionaryTransition(StructureID* structureID)
109{
110 ASSERT(!structureID->m_isDictionary);
111
112 RefPtr<StructureID> transition = create(structureID->m_prototype);
113 transition->m_isDictionary = true;
114 transition->m_propertyMap = structureID->m_propertyMap;
115 return transition.release();
116}
117
118PassRefPtr<StructureID> StructureID::fromDictionaryTransition(StructureID* structureID)
119{
120 ASSERT(structureID->m_isDictionary);
121
122 // Since dictionary StructureIDs are not shared, and no opcodes specialize
123 // for them, we don't need to allocate a new StructureID when transitioning
124 // to non-dictionary status.
125 structureID->m_isDictionary = false;
126 return structureID;
127}
128
129PassRefPtr<StructureID> StructureID::changePrototypeTransition(StructureID* structureID, JSValue* prototype)
130{
131 RefPtr<StructureID> transition = create(prototype);
132 transition->m_transitionCount = structureID->m_transitionCount + 1;
133 transition->m_propertyMap = structureID->m_propertyMap;
134 return transition.release();
135}
136
137PassRefPtr<StructureID> StructureID::getterSetterTransition(StructureID* structureID)
138{
139 RefPtr<StructureID> transition = create(structureID->storedPrototype());
140 transition->m_transitionCount = structureID->m_transitionCount + 1;
141 transition->m_propertyMap = structureID->m_propertyMap;
142 return transition.release();
143}
144
145StructureID::~StructureID()
146{
147 if (m_previous) {
148 ASSERT(m_previous->m_transitionTable.contains(make_pair(m_nameInPrevious, m_attributesInPrevious)));
149 m_previous->m_transitionTable.remove(make_pair(m_nameInPrevious, m_attributesInPrevious));
150 }
151}
152
153StructureIDChain::StructureIDChain(StructureID* structureID)
154{
155 size_t size = 1;
156
157 StructureID* tmp = structureID;
158 while (!tmp->storedPrototype()->isNull()) {
159 ++size;
160 tmp = static_cast<JSCell*>(tmp->storedPrototype())->structureID();
161 }
162
163 m_vector.set(new RefPtr<StructureID>[size + 1]);
164
165 size_t i;
166 for (i = 0; i < size - 1; ++i) {
167 m_vector[i] = structureID;
168 structureID = static_cast<JSObject*>(structureID->storedPrototype())->structureID();
169 }
170 m_vector[i] = structureID;
171 m_vector[i + 1] = 0;
172}
173
174} // namespace JSC
Note: See TracBrowser for help on using the repository browser.