source: webkit/trunk/JavaScriptCore/kjs/StructureID.h@ 37747

Last change on this file since 37747 was 37747, checked in by [email protected], 17 years ago

2008-10-16 Sam Weinig <[email protected]>

Reviewed by Cameron Zwarich.

Fix for https://bugs.webkit.org/show_bug.cgi?id=21683
Don't create intermediate StructureIDs for builtin objects

Second stage in reduce number of StructureIDs created when initializing the
JSGlobalObject.

  • Use putDirectWithoutTransition for the remaining singleton objects to reduce the number of StructureIDs create for about:blank from 132 to 73.
  • kjs/ArrayConstructor.cpp: (JSC::ArrayConstructor::ArrayConstructor):
  • kjs/BooleanConstructor.cpp: (JSC::BooleanConstructor::BooleanConstructor):
  • kjs/BooleanPrototype.cpp: (JSC::BooleanPrototype::BooleanPrototype):
  • kjs/DateConstructor.cpp: (JSC::DateConstructor::DateConstructor):
  • kjs/ErrorConstructor.cpp: (JSC::ErrorConstructor::ErrorConstructor):
  • kjs/ErrorPrototype.cpp: (JSC::ErrorPrototype::ErrorPrototype):
  • kjs/FunctionConstructor.cpp: (JSC::FunctionConstructor::FunctionConstructor):
  • kjs/FunctionPrototype.cpp: (JSC::FunctionPrototype::FunctionPrototype): (JSC::FunctionPrototype::addFunctionProperties):
  • kjs/FunctionPrototype.h: (JSC::FunctionPrototype::createStructureID):
  • kjs/InternalFunction.cpp:
  • kjs/InternalFunction.h: (JSC::InternalFunction::InternalFunction):
  • kjs/JSGlobalObject.cpp: (JSC::JSGlobalObject::reset):
  • kjs/JSObject.h:
  • kjs/MathObject.cpp: (JSC::MathObject::MathObject):
  • kjs/NumberConstructor.cpp: (JSC::NumberConstructor::NumberConstructor):
  • kjs/NumberPrototype.cpp: (JSC::NumberPrototype::NumberPrototype):
  • kjs/ObjectConstructor.cpp: (JSC::ObjectConstructor::ObjectConstructor):
  • kjs/RegExpConstructor.cpp: (JSC::RegExpConstructor::RegExpConstructor):
  • kjs/RegExpPrototype.cpp: (JSC::RegExpPrototype::RegExpPrototype):
  • kjs/StringConstructor.cpp: (JSC::StringConstructor::StringConstructor):
  • kjs/StringPrototype.cpp: (JSC::StringPrototype::StringPrototype):
  • kjs/StructureID.cpp: (JSC::StructureID::dumpStatistics):
  • kjs/StructureID.h: (JSC::StructureID::setPrototypeWithoutTransition):
File size: 7.3 KB
Line 
1// -*- mode: c++; c-basic-offset: 4 -*-
2/*
3 * Copyright (C) 2008 Apple Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#ifndef StructureID_h
28#define StructureID_h
29
30#include "JSType.h"
31#include "JSValue.h"
32#include "PropertyMap.h"
33#include "TypeInfo.h"
34#include "ustring.h"
35#include <wtf/HashFunctions.h>
36#include <wtf/HashTraits.h>
37#include <wtf/OwnArrayPtr.h>
38#include <wtf/PassRefPtr.h>
39#include <wtf/RefCounted.h>
40
41#define DUMP_STRUCTURE_ID_STATISTICS 0
42
43namespace JSC {
44
45 class PropertyNameArray;
46 class PropertyNameArrayData;
47 class StructureIDChain;
48
49 struct TransitionTableHash {
50 typedef std::pair<RefPtr<UString::Rep>, unsigned> TransitionTableKey;
51 static unsigned hash(const TransitionTableKey& p)
52 {
53 return p.first->computedHash();
54 }
55
56 static bool equal(const TransitionTableKey& a, const TransitionTableKey& b)
57 {
58 return a == b;
59 }
60
61 static const bool safeToCompareToEmptyOrDeleted = true;
62 };
63
64 struct TransitionTableHashTraits {
65 typedef WTF::HashTraits<RefPtr<UString::Rep> > FirstTraits;
66 typedef WTF::GenericHashTraits<unsigned> SecondTraits;
67 typedef std::pair<FirstTraits::TraitType, SecondTraits::TraitType> TraitType;
68
69 static const bool emptyValueIsZero = FirstTraits::emptyValueIsZero && SecondTraits::emptyValueIsZero;
70 static TraitType emptyValue() { return std::make_pair(FirstTraits::emptyValue(), SecondTraits::emptyValue()); }
71
72 static const bool needsDestruction = FirstTraits::needsDestruction || SecondTraits::needsDestruction;
73
74 static void constructDeletedValue(TraitType& slot) { FirstTraits::constructDeletedValue(slot.first); }
75 static bool isDeletedValue(const TraitType& value) { return FirstTraits::isDeletedValue(value.first); }
76 };
77
78 class StructureID : public RefCounted<StructureID> {
79 public:
80 friend class CTI;
81 static PassRefPtr<StructureID> create(JSValuePtr prototype, const TypeInfo& typeInfo)
82 {
83 return adoptRef(new StructureID(prototype, typeInfo));
84 }
85
86 static void startIgnoringLeaks();
87 static void stopIgnoringLeaks();
88
89#if DUMP_STRUCTURE_ID_STATISTICS
90 static void dumpStatistics();
91#endif
92
93 static PassRefPtr<StructureID> changePrototypeTransition(StructureID*, JSValuePtr prototype);
94 static PassRefPtr<StructureID> addPropertyTransition(StructureID*, const Identifier& propertyName, unsigned attributes, size_t& offset);
95 static PassRefPtr<StructureID> getterSetterTransition(StructureID*);
96 static PassRefPtr<StructureID> toDictionaryTransition(StructureID*);
97 static PassRefPtr<StructureID> fromDictionaryTransition(StructureID*);
98
99 ~StructureID();
100
101 void mark()
102 {
103 if (!m_prototype->marked())
104 m_prototype->mark();
105 }
106
107 // These should be used with caution.
108 size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes);
109 void setPrototypeWithoutTransition(JSValuePtr prototype) { m_prototype = prototype; }
110
111 bool isDictionary() const { return m_isDictionary; }
112
113 const TypeInfo& typeInfo() const { return m_typeInfo; }
114
115 // For use when first creating a new structure.
116 TypeInfo& mutableTypeInfo() { return m_typeInfo; }
117
118 JSValuePtr storedPrototype() const { return m_prototype; }
119 JSValuePtr prototypeForLookup(ExecState*);
120
121 StructureID* previousID() const { return m_previous.get(); }
122
123 StructureIDChain* createCachedPrototypeChain();
124 void setCachedPrototypeChain(PassRefPtr<StructureIDChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
125 StructureIDChain* cachedPrototypeChain() const { return m_cachedPrototypeChain.get(); }
126
127 const PropertyMap& propertyMap() const { return m_propertyMap; }
128 PropertyMap& propertyMap() { return m_propertyMap; }
129
130 void setCachedTransistionOffset(size_t offset) { m_cachedTransistionOffset = offset; }
131 size_t cachedTransistionOffset() const { return m_cachedTransistionOffset; }
132
133 void growPropertyStorageCapacity();
134 size_t propertyStorageCapacity() const { return m_propertyStorageCapacity; }
135
136 void getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*);
137 void clearEnumerationCache();
138
139 bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
140 void setHasGetterSetterProperties(bool hasGetterSetterProperties) { m_hasGetterSetterProperties = hasGetterSetterProperties; }
141
142 private:
143 typedef std::pair<RefPtr<UString::Rep>, unsigned> TransitionTableKey;
144 typedef HashMap<TransitionTableKey, StructureID*, TransitionTableHash, TransitionTableHashTraits> TransitionTable;
145
146 StructureID(JSValuePtr prototype, const TypeInfo&);
147
148 static const size_t s_maxTransitionLength = 64;
149
150 TypeInfo m_typeInfo;
151
152 bool m_isDictionary;
153
154 bool m_hasGetterSetterProperties;
155
156 JSValuePtr m_prototype;
157 RefPtr<StructureIDChain> m_cachedPrototypeChain;
158
159 RefPtr<StructureID> m_previous;
160 UString::Rep* m_nameInPrevious;
161 unsigned m_attributesInPrevious;
162
163 size_t m_transitionCount;
164 bool m_usingSingleTransitionSlot;
165 union {
166 StructureID* singleTransition;
167 TransitionTable* table;
168 } m_transitions;
169
170 RefPtr<PropertyNameArrayData> m_cachedPropertyNameArrayData;
171
172 PropertyMap m_propertyMap;
173 size_t m_propertyStorageCapacity;
174
175 size_t m_cachedTransistionOffset;
176 };
177
178 class StructureIDChain : public RefCounted<StructureIDChain> {
179 public:
180 static PassRefPtr<StructureIDChain> create(StructureID* structureID) { return adoptRef(new StructureIDChain(structureID)); }
181
182 RefPtr<StructureID>* head() { return m_vector.get(); }
183
184 private:
185 StructureIDChain(StructureID* structureID);
186
187 OwnArrayPtr<RefPtr<StructureID> > m_vector;
188 };
189
190 bool structureIDChainsAreEqual(StructureIDChain*, StructureIDChain*);
191
192} // namespace JSC
193
194#endif // StructureID_h
Note: See TracBrowser for help on using the repository browser.