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

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

2008-09-22 Sam Weinig <[email protected]>

Reviewed by Maciej Stachowiak.

Patch for https://bugs.webkit.org/show_bug.cgi?id=21014
Speed up for..in by using StructureID to avoid call hasProperty

Speeds up fasta by 8%.

  • VM/JSPropertyNameIterator.cpp: (JSC::JSPropertyNameIterator::invalidate):
  • VM/JSPropertyNameIterator.h: (JSC::JSPropertyNameIterator::next):
  • kjs/PropertyNameArray.h: (JSC::PropertyNameArrayData::begin): (JSC::PropertyNameArrayData::end): (JSC::PropertyNameArrayData::setCachedStructureID): (JSC::PropertyNameArrayData::cachedStructureID):
  • kjs/StructureID.cpp: (JSC::StructureID::getEnumerablePropertyNames): (JSC::structureIDChainsAreEqual):
  • kjs/StructureID.h:
File size: 6.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
41namespace JSC {
42
43 class JSValue;
44 class PropertyNameArray;
45 class PropertyNameArrayData;
46 class StructureIDChain;
47
48 struct TransitionTableHash {
49 typedef std::pair<RefPtr<UString::Rep>, unsigned> TransitionTableKey;
50 static unsigned hash(const TransitionTableKey& p)
51 {
52 return p.first->computedHash();
53 }
54
55 static bool equal(const TransitionTableKey& a, const TransitionTableKey& b)
56 {
57 return a == b;
58 }
59
60 static const bool safeToCompareToEmptyOrDeleted = true;
61 };
62
63 struct TransitionTableHashTraits {
64 typedef WTF::HashTraits<RefPtr<UString::Rep> > FirstTraits;
65 typedef WTF::GenericHashTraits<unsigned> SecondTraits;
66 typedef std::pair<FirstTraits::TraitType, SecondTraits::TraitType> TraitType;
67
68 static const bool emptyValueIsZero = FirstTraits::emptyValueIsZero && SecondTraits::emptyValueIsZero;
69 static TraitType emptyValue() { return std::make_pair(FirstTraits::emptyValue(), SecondTraits::emptyValue()); }
70
71 static const bool needsDestruction = FirstTraits::needsDestruction || SecondTraits::needsDestruction;
72
73 static void constructDeletedValue(TraitType& slot) { FirstTraits::constructDeletedValue(slot.first); }
74 static bool isDeletedValue(const TraitType& value) { return FirstTraits::isDeletedValue(value.first); }
75 };
76
77 class StructureID : public RefCounted<StructureID> {
78 public:
79 friend class CTI;
80 static PassRefPtr<StructureID> create(JSValue* prototype, const TypeInfo& typeInfo)
81 {
82 return adoptRef(new StructureID(prototype, typeInfo));
83 }
84
85 static PassRefPtr<StructureID> changePrototypeTransition(StructureID*, JSValue* prototype);
86 static PassRefPtr<StructureID> addPropertyTransition(StructureID*, const Identifier& propertyName, JSValue*, unsigned attributes, JSObject* slotBase, PutPropertySlot&, PropertyStorage&);
87 static PassRefPtr<StructureID> getterSetterTransition(StructureID*);
88 static PassRefPtr<StructureID> toDictionaryTransition(StructureID*);
89 static PassRefPtr<StructureID> fromDictionaryTransition(StructureID*);
90
91 ~StructureID();
92
93 void mark()
94 {
95 if (!m_prototype->marked())
96 m_prototype->mark();
97 }
98
99 bool isDictionary() const { return m_isDictionary; }
100
101 const TypeInfo& typeInfo() const { return m_typeInfo; }
102
103 // For use when first creating a new structure.
104 TypeInfo& mutableTypeInfo() { return m_typeInfo; }
105
106 JSValue* storedPrototype() const { return m_prototype; }
107 JSValue* prototypeForLookup(ExecState*);
108
109 StructureID* previousID() const { return m_previous.get(); }
110
111 StructureIDChain* createCachedPrototypeChain();
112 void setCachedPrototypeChain(PassRefPtr<StructureIDChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
113 StructureIDChain* cachedPrototypeChain() const { return m_cachedPrototypeChain.get(); }
114
115 const PropertyMap& propertyMap() const { return m_propertyMap; }
116 PropertyMap& propertyMap() { return m_propertyMap; }
117
118 void getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*);
119 void clearEnumerationCache();
120
121 static void transitionTo(StructureID* oldStructureID, StructureID* newStructureID, JSObject* slotBase);
122
123 private:
124 typedef std::pair<RefPtr<UString::Rep>, unsigned> TransitionTableKey;
125 typedef HashMap<TransitionTableKey, StructureID*, TransitionTableHash, TransitionTableHashTraits> TransitionTable;
126
127 StructureID(JSValue* prototype, const TypeInfo&);
128
129 static const size_t s_maxTransitionLength = 64;
130
131 TypeInfo m_typeInfo;
132
133 bool m_isDictionary;
134
135 JSValue* m_prototype;
136 RefPtr<StructureIDChain> m_cachedPrototypeChain;
137
138 RefPtr<StructureID> m_previous;
139 UString::Rep* m_nameInPrevious;
140 unsigned m_attributesInPrevious;
141
142 size_t m_transitionCount;
143 TransitionTable m_transitionTable;
144
145 RefPtr<PropertyNameArrayData> m_cachedPropertyNameArrayData;
146
147 PropertyMap m_propertyMap;
148 };
149
150 class StructureIDChain : public RefCounted<StructureIDChain> {
151 public:
152 static PassRefPtr<StructureIDChain> create(StructureID* structureID) { return adoptRef(new StructureIDChain(structureID)); }
153
154 RefPtr<StructureID>* head() { return m_vector.get(); }
155
156 private:
157 StructureIDChain(StructureID* structureID);
158
159 OwnArrayPtr<RefPtr<StructureID> > m_vector;
160 };
161
162 bool structureIDChainsAreEqual(StructureIDChain*, StructureIDChain*);
163
164} // namespace JSC
165
166#endif // StructureID_h
Note: See TracBrowser for help on using the repository browser.