source: webkit/trunk/JavaScriptCore/runtime/PropertySlot.h@ 58990

Last change on this file since 58990 was 55564, checked in by [email protected], 15 years ago

2010-03-03 Oliver Hunt <[email protected]>

Reviewed by Gavin Barraclough.

Allow static property getters to interact with JSCs caching
https://bugs.webkit.org/show_bug.cgi?id=35716

Add new opcodes for handling cached lookup of static value getters.
More or less the same as with JS getters, all that changes is that
instead of calling through a JSFunction we always know that we have
a C function to call.

For the patching routines in the JIT we now need to pass a few
new parameters to allow us to pass enough information to the stub
function to allow us to call the C function correctly. Logically
this shouldn't actually be necessary as all of these functions ignore
the identifier, but removing the ident parameter would require
somewhat involved changes to the way we implement getOwnPropertySlot,
etc.

  • bytecode/CodeBlock.cpp: (JSC::CodeBlock::dump): (JSC::CodeBlock::derefStructures): (JSC::CodeBlock::refStructures):
  • bytecode/Instruction.h: (JSC::Instruction::Instruction): (JSC::Instruction::):
  • bytecode/Opcode.h:
  • interpreter/Interpreter.cpp: (JSC::Interpreter::tryCacheGetByID): (JSC::Interpreter::privateExecute):
  • jit/JIT.cpp: (JSC::JIT::privateCompileMainPass):
  • jit/JIT.h: (JSC::JIT::compileGetByIdProto): (JSC::JIT::compileGetByIdSelfList): (JSC::JIT::compileGetByIdProtoList): (JSC::JIT::compileGetByIdChainList): (JSC::JIT::compileGetByIdChain):
  • jit/JITPropertyAccess.cpp: (JSC::JIT::privateCompileGetByIdProto): (JSC::JIT::privateCompileGetByIdSelfList): (JSC::JIT::privateCompileGetByIdProtoList): (JSC::JIT::privateCompileGetByIdChainList): (JSC::JIT::privateCompileGetByIdChain):
  • jit/JITPropertyAccess32_64.cpp: (JSC::JIT::privateCompileGetByIdProto): (JSC::JIT::privateCompileGetByIdSelfList): (JSC::JIT::privateCompileGetByIdProtoList): (JSC::JIT::privateCompileGetByIdChainList): (JSC::JIT::privateCompileGetByIdChain):
  • jit/JITStubs.cpp: (JSC::JITThunks::tryCacheGetByID): (JSC::DEFINE_STUB_FUNCTION):
  • jit/JITStubs.h: (JSC::):
  • runtime/JSFunction.cpp: (JSC::JSFunction::getOwnPropertySlot):
  • runtime/Lookup.h: (JSC::getStaticPropertySlot): (JSC::getStaticValueSlot):
  • runtime/PropertySlot.h: (JSC::PropertySlot::): (JSC::PropertySlot::PropertySlot): (JSC::PropertySlot::cachedPropertyType): (JSC::PropertySlot::isCacheable): (JSC::PropertySlot::isCacheableValue): (JSC::PropertySlot::setValueSlot): (JSC::PropertySlot::setCacheableCustom): (JSC::PropertySlot::setGetterSlot): (JSC::PropertySlot::setCacheableGetterSlot): (JSC::PropertySlot::clearOffset): (JSC::PropertySlot::customGetter):

2010-03-03 Oliver Hunt <[email protected]>

Reviewed by Gavin Barraclough.

Allow static property getters to interact with JSCs caching
https://bugs.webkit.org/show_bug.cgi?id=35716

Add tests to ensure nothing horrifying happens to static property
getters if they're in a path where we end up caching lookups.

  • fast/js/pic/cached-named-property-getter-expected.txt: Added.
  • fast/js/pic/cached-named-property-getter.html: Added.

2010-03-03 Oliver Hunt <[email protected]>

Reviewed by Gavin Barraclough.

Allow static property getters to interact with JSCs caching
https://bugs.webkit.org/show_bug.cgi?id=35716

Update the obviously safe getters to allow caching

Test: fast/js/pic/cached-named-property-getter.html

  • bridge/runtime_array.cpp: (JSC::RuntimeArray::getOwnPropertySlot):
  • bridge/runtime_method.cpp: (JSC::RuntimeMethod::getOwnPropertySlot):
  • Property svn:eol-style set to native
File size: 7.9 KB
Line 
1/*
2 * Copyright (C) 2005, 2007, 2008 Apple Inc. All rights reserved.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 *
19 */
20
21#ifndef PropertySlot_h
22#define PropertySlot_h
23
24#include "Identifier.h"
25#include "JSValue.h"
26#include "Register.h"
27#include <wtf/Assertions.h>
28#include <wtf/NotFound.h>
29
30namespace JSC {
31
32 class ExecState;
33 class JSObject;
34
35#define JSC_VALUE_SLOT_MARKER 0
36#define JSC_REGISTER_SLOT_MARKER reinterpret_cast<GetValueFunc>(1)
37#define INDEX_GETTER_MARKER reinterpret_cast<GetValueFunc>(2)
38#define GETTER_FUNCTION_MARKER reinterpret_cast<GetValueFunc>(3)
39
40 class PropertySlot {
41 public:
42 enum CachedPropertyType {
43 Uncacheable,
44 Getter,
45 Custom,
46 Value
47 };
48
49 PropertySlot()
50 : m_cachedPropertyType(Uncacheable)
51 {
52 clearBase();
53 clearOffset();
54 clearValue();
55 }
56
57 explicit PropertySlot(const JSValue base)
58 : m_slotBase(base)
59 , m_cachedPropertyType(Uncacheable)
60 {
61 clearOffset();
62 clearValue();
63 }
64
65 typedef JSValue (*GetValueFunc)(ExecState*, JSValue slotBase, const Identifier&);
66 typedef JSValue (*GetIndexValueFunc)(ExecState*, JSValue slotBase, unsigned);
67
68 JSValue getValue(ExecState* exec, const Identifier& propertyName) const
69 {
70 if (m_getValue == JSC_VALUE_SLOT_MARKER)
71 return *m_data.valueSlot;
72 if (m_getValue == JSC_REGISTER_SLOT_MARKER)
73 return (*m_data.registerSlot).jsValue();
74 if (m_getValue == INDEX_GETTER_MARKER)
75 return m_getIndexValue(exec, slotBase(), index());
76 if (m_getValue == GETTER_FUNCTION_MARKER)
77 return functionGetter(exec);
78 return m_getValue(exec, slotBase(), propertyName);
79 }
80
81 JSValue getValue(ExecState* exec, unsigned propertyName) const
82 {
83 if (m_getValue == JSC_VALUE_SLOT_MARKER)
84 return *m_data.valueSlot;
85 if (m_getValue == JSC_REGISTER_SLOT_MARKER)
86 return (*m_data.registerSlot).jsValue();
87 if (m_getValue == INDEX_GETTER_MARKER)
88 return m_getIndexValue(exec, m_slotBase, m_data.index);
89 if (m_getValue == GETTER_FUNCTION_MARKER)
90 return functionGetter(exec);
91 return m_getValue(exec, slotBase(), Identifier::from(exec, propertyName));
92 }
93
94 CachedPropertyType cachedPropertyType() const { return m_cachedPropertyType; }
95 bool isCacheable() const { return m_cachedPropertyType != Uncacheable; }
96 bool isCacheableValue() const { return m_cachedPropertyType == Value; }
97 size_t cachedOffset() const
98 {
99 ASSERT(isCacheable());
100 return m_offset;
101 }
102
103 void setValueSlot(JSValue* valueSlot)
104 {
105 ASSERT(valueSlot);
106 clearBase();
107 clearOffset();
108 m_getValue = JSC_VALUE_SLOT_MARKER;
109 m_data.valueSlot = valueSlot;
110 }
111
112 void setValueSlot(JSValue slotBase, JSValue* valueSlot)
113 {
114 ASSERT(valueSlot);
115 m_getValue = JSC_VALUE_SLOT_MARKER;
116 m_slotBase = slotBase;
117 m_data.valueSlot = valueSlot;
118 }
119
120 void setValueSlot(JSValue slotBase, JSValue* valueSlot, size_t offset)
121 {
122 ASSERT(valueSlot);
123 m_getValue = JSC_VALUE_SLOT_MARKER;
124 m_slotBase = slotBase;
125 m_data.valueSlot = valueSlot;
126 m_offset = offset;
127 m_cachedPropertyType = Value;
128 }
129
130 void setValue(JSValue value)
131 {
132 ASSERT(value);
133 clearBase();
134 clearOffset();
135 m_getValue = JSC_VALUE_SLOT_MARKER;
136 m_value = value;
137 m_data.valueSlot = &m_value;
138 }
139
140 void setRegisterSlot(Register* registerSlot)
141 {
142 ASSERT(registerSlot);
143 clearBase();
144 clearOffset();
145 m_getValue = JSC_REGISTER_SLOT_MARKER;
146 m_data.registerSlot = registerSlot;
147 }
148
149 void setCustom(JSValue slotBase, GetValueFunc getValue)
150 {
151 ASSERT(slotBase);
152 ASSERT(getValue);
153 m_getValue = getValue;
154 m_getIndexValue = 0;
155 m_slotBase = slotBase;
156 }
157
158 void setCacheableCustom(JSValue slotBase, GetValueFunc getValue)
159 {
160 ASSERT(slotBase);
161 ASSERT(getValue);
162 m_getValue = getValue;
163 m_getIndexValue = 0;
164 m_slotBase = slotBase;
165 m_cachedPropertyType = Custom;
166 }
167
168 void setCustomIndex(JSValue slotBase, unsigned index, GetIndexValueFunc getIndexValue)
169 {
170 ASSERT(slotBase);
171 ASSERT(getIndexValue);
172 m_getValue = INDEX_GETTER_MARKER;
173 m_getIndexValue = getIndexValue;
174 m_slotBase = slotBase;
175 m_data.index = index;
176 }
177
178 void setGetterSlot(JSObject* getterFunc)
179 {
180 ASSERT(getterFunc);
181 m_thisValue = m_slotBase;
182 m_getValue = GETTER_FUNCTION_MARKER;
183 m_data.getterFunc = getterFunc;
184 }
185
186 void setCacheableGetterSlot(JSValue slotBase, JSObject* getterFunc, unsigned offset)
187 {
188 ASSERT(getterFunc);
189 m_getValue = GETTER_FUNCTION_MARKER;
190 m_thisValue = m_slotBase;
191 m_slotBase = slotBase;
192 m_data.getterFunc = getterFunc;
193 m_offset = offset;
194 m_cachedPropertyType = Getter;
195 }
196
197 void setUndefined()
198 {
199 setValue(jsUndefined());
200 }
201
202 JSValue slotBase() const
203 {
204 return m_slotBase;
205 }
206
207 void setBase(JSValue base)
208 {
209 ASSERT(m_slotBase);
210 ASSERT(base);
211 m_slotBase = base;
212 }
213
214 void clearBase()
215 {
216#ifndef NDEBUG
217 m_slotBase = JSValue();
218#endif
219 }
220
221 void clearValue()
222 {
223#ifndef NDEBUG
224 m_value = JSValue();
225#endif
226 }
227
228 void clearOffset()
229 {
230 // Clear offset even in release builds, in case this PropertySlot has been used before.
231 // (For other data members, we don't need to clear anything because reuse would meaningfully overwrite them.)
232 m_offset = 0;
233 m_cachedPropertyType = Uncacheable;
234 }
235
236 unsigned index() const { return m_data.index; }
237
238 JSValue thisValue() const { return m_thisValue; }
239
240 GetValueFunc customGetter() const
241 {
242 ASSERT(m_cachedPropertyType == Custom);
243 return m_getValue;
244 }
245 private:
246 JSValue functionGetter(ExecState*) const;
247
248 GetValueFunc m_getValue;
249 GetIndexValueFunc m_getIndexValue;
250
251 JSValue m_slotBase;
252 union {
253 JSObject* getterFunc;
254 JSValue* valueSlot;
255 Register* registerSlot;
256 unsigned index;
257 } m_data;
258
259 JSValue m_value;
260 JSValue m_thisValue;
261
262 size_t m_offset;
263 CachedPropertyType m_cachedPropertyType;
264 };
265
266} // namespace JSC
267
268#endif // PropertySlot_h
Note: See TracBrowser for help on using the repository browser.