source: webkit/trunk/JavaScriptCore/kjs/JSCell.h@ 37285

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

JavaScriptCore:

2008-10-03 Maciej Stachowiak <[email protected]>

Reviewed by Cameron Zwarich.


I changed things so that functions which use "this" do a fast
version of toThisObject conversion if needed. Currently we miss
the conversion entirely, at least for primitive types. Using
TypeInfo and the primitive check, I made the fast case bail out
pretty fast.


This is inexplicably an 1.007x SunSpider speedup (and a wash on V8 benchmarks).


Also renamed some opcodes for clarity:


init ==> enter
init_activation ==> enter_with_activation


  • VM/CTI.cpp: (JSC::CTI::privateCompileMainPass): (JSC::CTI::privateCompileSlowCases):
  • VM/CodeBlock.cpp: (JSC::CodeBlock::dump):
  • VM/CodeGenerator.cpp: (JSC::CodeGenerator::generate): (JSC::CodeGenerator::CodeGenerator):
  • VM/Machine.cpp: (JSC::Machine::privateExecute): (JSC::Machine::cti_op_convert_this):
  • VM/Machine.h:
  • VM/Opcode.h:
  • kjs/JSActivation.cpp: (JSC::JSActivation::JSActivation):
  • kjs/JSActivation.h: (JSC::JSActivation::createStructureID):
  • kjs/JSCell.h: (JSC::JSValue::needsThisConversion):
  • kjs/JSGlobalData.cpp: (JSC::JSGlobalData::JSGlobalData):
  • kjs/JSGlobalData.h:
  • kjs/JSNumberCell.h: (JSC::JSNumberCell::createStructureID):
  • kjs/JSStaticScopeObject.h: (JSC::JSStaticScopeObject::JSStaticScopeObject): (JSC::JSStaticScopeObject::createStructureID):
  • kjs/JSString.h: (JSC::JSString::createStructureID):
  • kjs/JSValue.h:
  • kjs/TypeInfo.h: (JSC::TypeInfo::needsThisConversion):
  • kjs/nodes.h: (JSC::ScopeNode::usesThis):

WebCore:

2008-10-03 Maciej Stachowiak <[email protected]>

Reviewed by Cameron Zwarich.

Updated so toThis conversion for the split window is handled properly.

  • bindings/scripts/CodeGeneratorJS.pm:

LayoutTests:

2008-10-03 Maciej Stachowiak <[email protected]>

Reviewed by Cameron Zwarich.


  • test case for: "this" object in methods called on primitives should be wrapper object
  • fast/js/primitive-method-this-expected.txt: Added.
  • fast/js/primitive-method-this.html: Added.
  • fast/js/resources/primitive-method-this.js: Added.
  • Property svn:eol-style set to native
File size: 10.3 KB
Line 
1/*
2 * Copyright (C) 1999-2001 Harri Porten ([email protected])
3 * Copyright (C) 2001 Peter Kelly ([email protected])
4 * Copyright (C) 2003, 2004, 2005, 2007, 2008 Apple Inc. All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#ifndef JSCell_h
24#define JSCell_h
25
26#include "StructureID.h"
27#include "JSValue.h"
28#include "collector.h"
29
30namespace JSC {
31
32 class JSCell : public JSValue {
33 friend class Heap;
34 friend class GetterSetter;
35 friend class JSObject;
36 friend class JSPropertyNameIterator;
37 friend class JSValue;
38 friend class JSNumberCell;
39 friend class JSString;
40 friend class Machine;
41 friend class CTI;
42 private:
43 explicit JSCell(StructureID*);
44 virtual ~JSCell();
45
46 public:
47 // Querying the type.
48 bool isNumber() const;
49 bool isString() const;
50 bool isObject() const;
51 virtual bool isGetterSetter() const;
52 virtual bool isObject(const ClassInfo*) const;
53
54 StructureID* structureID() const;
55
56 // Extracting the value.
57 bool getNumber(double&) const;
58 double getNumber() const; // NaN if not a number
59 bool getString(UString&) const;
60 UString getString() const; // null string if not a string
61 JSObject* getObject(); // NULL if not an object
62 const JSObject* getObject() const; // NULL if not an object
63
64 virtual CallType getCallData(CallData&);
65 virtual ConstructType getConstructData(ConstructData&);
66
67 // Extracting integer values.
68 virtual bool getUInt32(uint32_t&) const;
69 virtual bool getTruncatedInt32(int32_t&) const;
70 virtual bool getTruncatedUInt32(uint32_t&) const;
71
72 // Basic conversions.
73 virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const = 0;
74 virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*&) = 0;
75 virtual bool toBoolean(ExecState*) const = 0;
76 virtual double toNumber(ExecState*) const = 0;
77 virtual UString toString(ExecState*) const = 0;
78 virtual JSObject* toObject(ExecState*) const = 0;
79
80 // Garbage collection.
81 void* operator new(size_t, ExecState*);
82 void* operator new(size_t, JSGlobalData*);
83 void* operator new(size_t, void* placementNewDestination) { return placementNewDestination; }
84 virtual void mark();
85 bool marked() const;
86
87 // Object operations, with the toObject operation included.
88 virtual const ClassInfo* classInfo() const;
89 virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
90 virtual void put(ExecState*, unsigned propertyName, JSValue*);
91 virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
92 virtual bool deleteProperty(ExecState*, unsigned propertyName);
93
94 virtual JSObject* toThisObject(ExecState*) const;
95 virtual UString toThisString(ExecState*) const;
96 virtual JSString* toThisJSString(ExecState*);
97 virtual JSValue* getJSNumber();
98 void* vptr() { return *reinterpret_cast<void**>(this); }
99
100 private:
101 // Base implementation, but for non-object classes implements getPropertySlot.
102 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
103 virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
104
105 StructureID* m_structureID;
106 };
107
108 inline JSCell::JSCell(StructureID* structureID)
109 : m_structureID(structureID)
110 {
111 }
112
113 inline JSCell::~JSCell()
114 {
115 }
116
117 inline bool JSCell::isNumber() const
118 {
119 return Heap::isNumber(const_cast<JSCell*>(this));
120 }
121
122 inline bool JSCell::isObject() const
123 {
124 return m_structureID->typeInfo().type() == ObjectType;
125 }
126
127 inline bool JSCell::isString() const
128 {
129 return m_structureID->typeInfo().type() == StringType;
130 }
131
132 inline StructureID* JSCell::structureID() const
133 {
134 return m_structureID;
135 }
136
137 inline bool JSCell::marked() const
138 {
139 return Heap::isCellMarked(this);
140 }
141
142 inline void JSCell::mark()
143 {
144 return Heap::markCell(this);
145 }
146
147 ALWAYS_INLINE JSCell* JSValue::asCell()
148 {
149 ASSERT(!JSImmediate::isImmediate(this));
150 return static_cast<JSCell*>(this);
151 }
152
153 ALWAYS_INLINE const JSCell* JSValue::asCell() const
154 {
155 ASSERT(!JSImmediate::isImmediate(this));
156 return static_cast<const JSCell*>(this);
157 }
158
159 inline void* JSCell::operator new(size_t size, JSGlobalData* globalData)
160 {
161#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
162 return globalData->heap.inlineAllocate(size);
163#else
164 return globalData->heap.allocate(size);
165#endif
166 }
167
168 // --- JSValue inlines ----------------------------
169
170 inline bool JSValue::isNumber() const
171 {
172 return JSImmediate::isNumber(this) || (!JSImmediate::isImmediate(this) && asCell()->isNumber());
173 }
174
175 inline bool JSValue::isString() const
176 {
177 return !JSImmediate::isImmediate(this) && asCell()->isString();
178 }
179
180 inline bool JSValue::isGetterSetter() const
181 {
182 return !JSImmediate::isImmediate(this) && asCell()->isGetterSetter();
183 }
184
185 inline bool JSValue::isObject() const
186 {
187 return !JSImmediate::isImmediate(this) && asCell()->isObject();
188 }
189
190 inline bool JSValue::getNumber(double& v) const
191 {
192 if (JSImmediate::isImmediate(this)) {
193 v = JSImmediate::toDouble(this);
194 return true;
195 }
196 return asCell()->getNumber(v);
197 }
198
199 inline double JSValue::getNumber() const
200 {
201 return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : asCell()->getNumber();
202 }
203
204 inline bool JSValue::getString(UString& s) const
205 {
206 return !JSImmediate::isImmediate(this) && asCell()->getString(s);
207 }
208
209 inline UString JSValue::getString() const
210 {
211 return JSImmediate::isImmediate(this) ? UString() : asCell()->getString();
212 }
213
214 inline JSObject* JSValue::getObject()
215 {
216 return JSImmediate::isImmediate(this) ? 0 : asCell()->getObject();
217 }
218
219 inline const JSObject* JSValue::getObject() const
220 {
221 return JSImmediate::isImmediate(this) ? 0 : asCell()->getObject();
222 }
223
224 inline CallType JSValue::getCallData(CallData& callData)
225 {
226 return JSImmediate::isImmediate(this) ? CallTypeNone : asCell()->getCallData(callData);
227 }
228
229 inline ConstructType JSValue::getConstructData(ConstructData& constructData)
230 {
231 return JSImmediate::isImmediate(this) ? ConstructTypeNone : asCell()->getConstructData(constructData);
232 }
233
234 ALWAYS_INLINE bool JSValue::getUInt32(uint32_t& v) const
235 {
236 return JSImmediate::isImmediate(this) ? JSImmediate::getUInt32(this, v) : asCell()->getUInt32(v);
237 }
238
239 ALWAYS_INLINE bool JSValue::getTruncatedInt32(int32_t& v) const
240 {
241 return JSImmediate::isImmediate(this) ? JSImmediate::getTruncatedInt32(this, v) : asCell()->getTruncatedInt32(v);
242 }
243
244 inline bool JSValue::getTruncatedUInt32(uint32_t& v) const
245 {
246 return JSImmediate::isImmediate(this) ? JSImmediate::getTruncatedUInt32(this, v) : asCell()->getTruncatedUInt32(v);
247 }
248
249 inline void JSValue::mark()
250 {
251 ASSERT(!JSImmediate::isImmediate(this)); // callers should check !marked() before calling mark()
252 asCell()->mark();
253 }
254
255 inline bool JSValue::marked() const
256 {
257 return JSImmediate::isImmediate(this) || asCell()->marked();
258 }
259
260 inline JSValue* JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
261 {
262 return JSImmediate::isImmediate(this) ? const_cast<JSValue*>(this) : asCell()->toPrimitive(exec, preferredType);
263 }
264
265 inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue*& value)
266 {
267 if (JSImmediate::isImmediate(this)) {
268 number = JSImmediate::toDouble(this);
269 value = this;
270 return true;
271 }
272 return asCell()->getPrimitiveNumber(exec, number, value);
273 }
274
275 inline bool JSValue::toBoolean(ExecState* exec) const
276 {
277 return JSImmediate::isImmediate(this) ? JSImmediate::toBoolean(this) : asCell()->toBoolean(exec);
278 }
279
280 ALWAYS_INLINE double JSValue::toNumber(ExecState* exec) const
281 {
282 return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : asCell()->toNumber(exec);
283 }
284
285 inline UString JSValue::toString(ExecState* exec) const
286 {
287 return JSImmediate::isImmediate(this) ? JSImmediate::toString(this) : asCell()->toString(exec);
288 }
289
290 inline JSObject* JSValue::toObject(ExecState* exec) const
291 {
292 return JSImmediate::isImmediate(this) ? JSImmediate::toObject(this, exec) : asCell()->toObject(exec);
293 }
294
295 inline JSObject* JSValue::toThisObject(ExecState* exec) const
296 {
297 if (UNLIKELY(JSImmediate::isImmediate(this)))
298 return JSImmediate::toObject(this, exec);
299 return asCell()->toThisObject(exec);
300 }
301
302 inline bool JSValue::needsThisConversion() const
303 {
304 if (UNLIKELY(JSImmediate::isImmediate(this)))
305 return true;
306
307 return asCell()->structureID()->typeInfo().needsThisConversion();
308 }
309
310 inline UString JSValue::toThisString(ExecState* exec) const
311 {
312 return JSImmediate::isImmediate(this) ? JSImmediate::toString(this) : asCell()->toThisString(exec);
313 }
314
315 inline JSValue* JSValue::getJSNumber()
316 {
317
318 return JSImmediate::isNumber(this) ? this : (JSImmediate::isImmediate(this) ? 0 : asCell()->getJSNumber());
319 }
320
321} // namespace JSC
322
323#endif // JSCell_h
Note: See TracBrowser for help on using the repository browser.