source: webkit/trunk/JavaScriptCore/kjs/JSGlobalObject.h@ 29059

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

JavaScriptCore:

Reviewed by Oliver Hunt.


Optimized global access to global variables, using a symbol table.


SunSpider reports a 1.5% overall speedup, a 6.2% speedup on 3d-morph,
and a whopping 33.1% speedup on bitops-bitwise-and.

  • API/JSCallbackObjectFunctions.h: Replaced calls to JSObject:: with calls to Base::, since JSObject is not always our base class. This was always a bug, but the bug is even more apparent after some of my changes.

(KJS::::staticFunctionGetter): Replaced use of getDirect with call to
getOwnPropertySlot. Global declarations are no longer stored in the
property map, so a call to getDirect is insufficient for finding
override properties.

  • API/testapi.c:
  • API/testapi.js: Added test for the getDirect change mentioned above.
  • kjs/ExecState.cpp:
  • kjs/ExecState.h: Dialed back the optimization to store a direct pointer to the localStorage buffer. One ExecState can grow the global object's localStorage without another ExecState's knowledge, so ExecState can't store a direct pointer to the localStorage buffer unless/until we invent a way to update all the relevant ExecStates.
  • kjs/JSGlobalObject.cpp: Inserted the symbol table into get and put operations. (KJS::JSGlobalObject::reset): Reset the symbol table and local storage, too. Also, clear the property map here, removing the need for a separate call.
  • kjs/JSVariableObject.cpp:
  • kjs/JSVariableObject.h: Added support for saving localStorage and the symbol table to the back/forward cache, and restoring them.
  • kjs/function.cpp: (KJS::GlobalFuncImp::callAsFunction): Renamed progNode to evalNode because it's an EvalNode, not a ProgramNode.
  • kjs/lookup.h: (KJS::cacheGlobalObject): Replaced put with faster putDirect, since that's how the rest of lookup.h works. putDirect is safe here because cacheGlobalObject is only used for objects whose names are not valid identifiers.
  • kjs/nodes.cpp: The good stuff!

(KJS::EvalNode::processDeclarations): Replaced hasProperty with
the new hasOwnProperty, which is slightly faster.

  • kjs/object.h: Nixed clearProperties because clear() does this job now.
  • kjs/property_map.cpp:
  • kjs/property_map.h: More back/forward cache support.


  • wtf/Vector.h: (WTF::::grow): Added fast non-branching grow function. I used it in an earlier version of this patch, even though it's not used anymore.

JavaScriptGlue:

Build fix.

  • ForwardingHeaders/wtf/VectorTraits.h: Added.

WebCore:

Reviewed by Oliver Hunt.

Build support:

  • ForwardingHeaders/kjs/SymbolTable.h: Added.
  • ForwardingHeaders/wtf/VectorTraits.h: Added.
  • bindings/js/JSDOMWindowCustom.cpp: (WebCore::JSDOMWindow::customGetOwnPropertySlot): Replaced use of getDirectLocation with getOwnPropertySlot. getDirectLocation is no longer valid, since global declarations are not stored in the property map.

(WebCore::JSDOMWindow::customPut): Replaced use of JSObject::put with
JSGlobalObject::put. JSObject::put is no longer valid, since global
declarations are not stored in the property map.

  • bindings/js/kjs_window.cpp: Replaced JSObject:: calls with Base:: calls, since JSObject is not our base class. This was always a bug, but the bug is even more apparent after some of my changes.

(KJS::Window::clear): Removed call to clearProperties because
JSGlobalObject::reset takes care of that now.

  • history/CachedPage.cpp:
  • history/CachedPage.h: Added support for saving a symbol table and localStorage to the page cache, and restoring it.

WebKit/mac:

Reviewed by Oliver Hunt.

Build fix.

  • ForwardingHeaders/kjs/SymbolTable.h: Added.
  • ForwardingHeaders/wtf/VectorTraits.h: Added.

LayoutTests:

Reviewed by Oliver Hunt.


Added some tests to verify some of the changes I made while optimizing
global access to global variables.

  • fast/dom/Window/resources/window-property-clearing-iframe0.html: Added.
  • fast/dom/Window/resources/window-property-clearing-iframe1.html: Added.
  • fast/dom/Window/window-property-clearing-expected.txt: Added.
  • fast/dom/Window/window-property-clearing.html: Added.
  • fast/dom/getter-on-window-object2-expected.txt: Added.
  • fast/dom/getter-on-window-object2.html: Added.

Checked in failing results for these const tests. The symbol table
optimization broke const. (We didn't know this before because our only
tests used global variables.)

  • fast/js/const-expected.txt:
  • fast/js/kde/const-expected.txt:
  • fast/js/resources/for-in-avoid-duplicates.js: Fixed a typo I noticed. Not related to this patch.
  • fast/dom/Window/window-property-shadowing.html: Changed this test to use "this" instead of "window". The fact that "window" worked before, despite an overriding / shadowing var declaration, was a bug.
File size: 9.8 KB
Line 
1// -*- c-basic-offset: 4 -*-
2/*
3 * Copyright (C) 2007 Eric Seidel <[email protected]>
4 * Copyright (C) 2007 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 KJS_GlobalObject_h
24#define KJS_GlobalObject_h
25
26#include "JSVariableObject.h"
27
28namespace KJS {
29
30 class ArrayObjectImp;
31 class ArrayPrototype;
32 class BooleanObjectImp;
33 class BooleanPrototype;
34 class DateObjectImp;
35 class DatePrototype;
36 class Debugger;
37 class ErrorObjectImp;
38 class ErrorPrototype;
39 class EvalError;
40 class EvalErrorPrototype;
41 class FunctionObjectImp;
42 class FunctionPrototype;
43 class JSGlobalObject;
44 class NativeErrorImp;
45 class NativeErrorPrototype;
46 class NumberObjectImp;
47 class NumberPrototype;
48 class ObjectObjectImp;
49 class ObjectPrototype;
50 class RangeError;
51 class RangeErrorPrototype;
52 class ReferenceError;
53 class ReferenceError;
54 class ReferenceErrorPrototype;
55 class RegExpObjectImp;
56 class RegExpPrototype;
57 class RuntimeMethod;
58 class SavedBuiltins;
59 class ScopeChain;
60 class StringObjectImp;
61 class StringPrototype;
62 class SyntaxErrorPrototype;
63 class TypeError;
64 class TypeErrorPrototype;
65 class UriError;
66 class UriErrorPrototype;
67
68 enum CompatMode { NativeMode, IECompat, NetscapeCompat };
69
70 class JSGlobalObject : public JSVariableObject {
71 protected:
72 using JSVariableObject::JSVariableObjectData;
73
74 struct JSGlobalObjectData : public JSVariableObjectData {
75 JSGlobalObjectData(JSGlobalObject* globalObject)
76 : JSVariableObjectData(&inlineSymbolTable)
77 , globalExec(globalObject, globalObject, 0)
78 {
79 }
80
81 JSGlobalObject* next;
82 JSGlobalObject* prev;
83
84 Debugger* debugger;
85 CompatMode compatMode;
86
87 ExecState globalExec;
88 ExecState* currentExec;
89 int recursion;
90
91 unsigned timeoutTime;
92 unsigned timeAtLastCheckTimeout;
93 unsigned timeExecuting;
94 unsigned timeoutCheckCount;
95 unsigned tickCount;
96 unsigned ticksUntilNextTimeoutCheck;
97
98 ObjectObjectImp* objectConstructor;
99 FunctionObjectImp* functionConstructor;
100 ArrayObjectImp* arrayConstructor;
101 BooleanObjectImp* booleanConstructor;
102 StringObjectImp* stringConstructor;
103 NumberObjectImp* numberConstructor;
104 DateObjectImp* dateConstructor;
105 RegExpObjectImp* regExpConstructor;
106 ErrorObjectImp* errorConstructor;
107 NativeErrorImp* evalErrorConstructor;
108 NativeErrorImp* rangeErrorConstructor;
109 NativeErrorImp* referenceErrorConstructor;
110 NativeErrorImp* syntaxErrorConstructor;
111 NativeErrorImp* typeErrorConstructor;
112 NativeErrorImp* URIErrorConstructor;
113
114 ObjectPrototype* objectPrototype;
115 FunctionPrototype* functionPrototype;
116 ArrayPrototype* arrayPrototype;
117 BooleanPrototype* booleanPrototype;
118 StringPrototype* stringPrototype;
119 NumberPrototype* numberPrototype;
120 DatePrototype* datePrototype;
121 RegExpPrototype* regExpPrototype;
122 ErrorPrototype* errorPrototype;
123 NativeErrorPrototype* evalErrorPrototype;
124 NativeErrorPrototype* rangeErrorPrototype;
125 NativeErrorPrototype* referenceErrorPrototype;
126 NativeErrorPrototype* syntaxErrorPrototype;
127 NativeErrorPrototype* typeErrorPrototype;
128 NativeErrorPrototype* URIErrorPrototype;
129
130 SymbolTable inlineSymbolTable;
131 };
132
133 public:
134 JSGlobalObject()
135 : JSVariableObject(new JSGlobalObjectData(this))
136 {
137 init();
138 }
139
140 protected:
141 JSGlobalObject(JSValue* proto)
142 : JSVariableObject(proto, new JSGlobalObjectData(this))
143 {
144 init();
145 }
146
147 public:
148 virtual ~JSGlobalObject();
149
150 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
151 virtual void put(ExecState*, const Identifier&, JSValue*, int attr = None);
152
153 // Linked list of all global objects.
154 static JSGlobalObject* head() { return s_head; }
155 JSGlobalObject* next() { return d()->next; }
156
157 // Resets the global object to contain only built-in properties, sets
158 // the global object's prototype to "prototype," then adds the
159 // default object prototype to the tail of the global object's
160 // prototype chain.
161 void reset(JSValue* prototype);
162
163 // The following accessors return pristine values, even if a script
164 // replaces the global object's associated property.
165
166 ObjectObjectImp* objectConstructor() const { return d()->objectConstructor; }
167 FunctionObjectImp* functionConstructor() const { return d()->functionConstructor; }
168 ArrayObjectImp* arrayConstructor() const { return d()->arrayConstructor; }
169 BooleanObjectImp* booleanConstructor() const { return d()->booleanConstructor; }
170 StringObjectImp* stringConstructor() const{ return d()->stringConstructor; }
171 NumberObjectImp* numberConstructor() const{ return d()->numberConstructor; }
172 DateObjectImp* dateConstructor() const{ return d()->dateConstructor; }
173 RegExpObjectImp* regExpConstructor() const { return d()->regExpConstructor; }
174 ErrorObjectImp* errorConstructor() const { return d()->errorConstructor; }
175 NativeErrorImp* evalErrorConstructor() const { return d()->evalErrorConstructor; }
176 NativeErrorImp* rangeErrorConstructor() const { return d()->rangeErrorConstructor; }
177 NativeErrorImp* referenceErrorConstructor() const { return d()->referenceErrorConstructor; }
178 NativeErrorImp* syntaxErrorConstructor() const { return d()->syntaxErrorConstructor; }
179 NativeErrorImp* typeErrorConstructor() const { return d()->typeErrorConstructor; }
180 NativeErrorImp* URIErrorConstructor() const { return d()->URIErrorConstructor; }
181
182 ObjectPrototype* objectPrototype() const { return d()->objectPrototype; }
183 FunctionPrototype* functionPrototype() const { return d()->functionPrototype; }
184 ArrayPrototype* arrayPrototype() const { return d()->arrayPrototype; }
185 BooleanPrototype* booleanPrototype() const { return d()->booleanPrototype; }
186 StringPrototype* stringPrototype() const { return d()->stringPrototype; }
187 NumberPrototype* numberPrototype() const { return d()->numberPrototype; }
188 DatePrototype* datePrototype() const { return d()->datePrototype; }
189 RegExpPrototype* regExpPrototype() const { return d()->regExpPrototype; }
190 ErrorPrototype* errorPrototype() const { return d()->errorPrototype; }
191 NativeErrorPrototype* evalErrorPrototype() const { return d()->evalErrorPrototype; }
192 NativeErrorPrototype* rangeErrorPrototype() const { return d()->rangeErrorPrototype; }
193 NativeErrorPrototype* referenceErrorPrototype() const { return d()->referenceErrorPrototype; }
194 NativeErrorPrototype* syntaxErrorPrototype() const { return d()->syntaxErrorPrototype; }
195 NativeErrorPrototype* typeErrorPrototype() const { return d()->typeErrorPrototype; }
196 NativeErrorPrototype* URIErrorPrototype() const { return d()->URIErrorPrototype; }
197
198 void saveBuiltins(SavedBuiltins&) const;
199 void restoreBuiltins(const SavedBuiltins&);
200
201 void setTimeoutTime(unsigned timeoutTime) { d()->timeoutTime = timeoutTime; }
202 void startTimeoutCheck();
203 void stopTimeoutCheck();
204 bool timedOut();
205
206 Debugger* debugger() const { return d()->debugger; }
207 void setDebugger(Debugger* debugger) { d()->debugger = debugger; }
208
209 void setCurrentExec(ExecState* exec) { d()->currentExec = exec; }
210 ExecState* currentExec() const { return d()->currentExec; }
211
212 // FIXME: Let's just pick one compatible behavior and go with it.
213 void setCompatMode(CompatMode mode) { d()->compatMode = mode; }
214 CompatMode compatMode() const { return d()->compatMode; }
215
216 int recursion() { return d()->recursion; }
217 void incRecursion() { ++d()->recursion; }
218 void decRecursion() { --d()->recursion; }
219
220 virtual void mark();
221
222 virtual bool isGlobalObject() const { return true; }
223
224 virtual ExecState* globalExec();
225
226 virtual bool shouldInterruptScript() const { return true; }
227
228 virtual bool allowsAccessFrom(const JSGlobalObject*) const { return true; }
229
230 private:
231 void init();
232
233 JSGlobalObjectData* d() const { return static_cast<JSGlobalObjectData*>(JSVariableObject::d); }
234
235 bool checkTimeout();
236 void resetTimeoutCheck();
237
238 static JSGlobalObject* s_head;
239 };
240
241 inline bool JSGlobalObject::timedOut()
242 {
243 d()->tickCount++;
244
245 if (d()->tickCount != d()->ticksUntilNextTimeoutCheck)
246 return false;
247
248 return checkTimeout();
249 }
250
251} // namespace KJS
252
253#endif // KJS_GlobalObject_h
Note: See TracBrowser for help on using the repository browser.