source: webkit/trunk/JavaScriptCore/kjs/function.h@ 27199

Last change on this file since 27199 was 27199, checked in by ggaren, 18 years ago

Reviewed by Maciej Stachowiak, Darin Adler.


Much supporting work done by Maciej Stachowiak, Maks Orlovich, and
Cameron Zwarich.


AST transfom to replace slow resolve nodes with fast local variable
alternatives that do direct memory access. Currently, only ResolveNode
provides a fast local variable alternative. 6 others are soon to come.


16.7% speedup on SunSpider.


Most of this patch is just scaffolding to support iterating all the
resolve nodes in the AST through optimizeResolveNodes(). In
optimizeResolveNodes(), most classes just push their child nodes onto
the processing stack, while ResolveNodes actually replace themselves in
the tree with more optimized alternatives, if possible.

Here are the interesting bits:

  • kjs/nodes.h: Added PlacementNewAdoptTag, along with implementations in Node and ResolveNode. This tag allows you to use placement new to swap out a base class Node in favor of a subclass copy that holds the same data. (Without this tag, default initialization would NULL out RefPtrs, change line numbers, etc.)
  • kjs/nodes.cpp: (KJS::ResolveNode::evaluate): Since we're taking the slow path, ASSERT that the fast path is impossible, to make sure we didn't leave anything on the table.

(KJS::FunctionBodyNode::optimizeResolveNodes): Here's where the AST
transformation happens.


(KJS::ResolveNode::optimizeResolveNodes): Here's where the ResolveNode
optimization happens.

  • kjs/function.h: Added symbolTable() accessor for, for the sake of an ASSERT.
  • Property svn:eol-style set to native
File size: 7.0 KB
Line 
1// -*- c-basic-offset: 2 -*-
2/*
3 * Copyright (C) 1999-2000 Harri Porten ([email protected])
4 * Copyright (C) 2003, 2006, 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_FUNCTION_H
24#define KJS_FUNCTION_H
25
26#include "SymbolTable.h"
27#include "object.h"
28#include <wtf/OwnPtr.h>
29#include <wtf/Vector.h>
30
31namespace KJS {
32
33 class ActivationImp;
34 class FunctionBodyNode;
35 class FunctionPrototype;
36
37 class InternalFunctionImp : public JSObject {
38 public:
39 InternalFunctionImp();
40 InternalFunctionImp(FunctionPrototype*);
41 InternalFunctionImp(FunctionPrototype*, const Identifier&);
42
43 virtual bool implementsCall() const;
44 virtual JSValue* callAsFunction(ExecState*, JSObject* thisObjec, const List& args) = 0;
45 virtual bool implementsHasInstance() const;
46
47 virtual const ClassInfo* classInfo() const { return &info; }
48 static const ClassInfo info;
49 const Identifier& functionName() const { return m_name; }
50
51 private:
52 Identifier m_name;
53 };
54
55 /**
56 * @internal
57 *
58 * The initial value of Function.prototype (and thus all objects created
59 * with the Function constructor)
60 */
61 class FunctionPrototype : public InternalFunctionImp {
62 public:
63 FunctionPrototype(ExecState *exec);
64 virtual ~FunctionPrototype();
65
66 virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args);
67 };
68
69 class FunctionImp : public InternalFunctionImp {
70 friend class ActivationImp;
71 public:
72 FunctionImp(ExecState*, const Identifier& name, FunctionBodyNode*, const ScopeChain&);
73
74 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
75 virtual void put(ExecState*, const Identifier& propertyName, JSValue* value, int attr = None);
76 virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
77
78 virtual bool implementsConstruct() const { return true; }
79 virtual JSObject* construct(ExecState*, const List& args);
80
81 virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const List& args);
82 Completion execute(ExecState*);
83
84 // Note: unlike body->paramName, this returns Identifier::null for parameters
85 // that will never get set, due to later param having the same name
86 Identifier getParameterName(int index);
87
88 virtual const ClassInfo* classInfo() const { return &info; }
89 static const ClassInfo info;
90
91 RefPtr<FunctionBodyNode> body;
92
93 void setScope(const ScopeChain& s) { _scope = s; }
94 const ScopeChain& scope() const { return _scope; }
95
96 virtual void mark();
97
98 private:
99 ScopeChain _scope;
100
101 static JSValue* argumentsGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
102 static JSValue* callerGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
103 static JSValue* lengthGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
104 };
105
106 class IndexToNameMap {
107 public:
108 IndexToNameMap(FunctionImp* func, const List& args);
109 ~IndexToNameMap();
110
111 Identifier& operator[](int index);
112 Identifier& operator[](const Identifier &indexIdentifier);
113 bool isMapped(const Identifier& index) const;
114 void unMap(const Identifier& index);
115
116 private:
117 IndexToNameMap(); // prevent construction w/o parameters
118 int size;
119 Identifier* _map;
120 };
121
122 class Arguments : public JSObject {
123 public:
124 Arguments(ExecState*, FunctionImp* func, const List& args, ActivationImp* act);
125 virtual void mark();
126 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
127 virtual void put(ExecState*, const Identifier& propertyName, JSValue* value, int attr = None);
128 virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
129 virtual const ClassInfo* classInfo() const { return &info; }
130 static const ClassInfo info;
131 private:
132 static JSValue* mappedIndexGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot);
133
134 ActivationImp* _activationObject;
135 mutable IndexToNameMap indexToNameMap;
136 };
137
138 class ActivationImp : public JSObject {
139 public:
140 struct LocalStorageEntry {
141 LocalStorageEntry()
142 {
143 }
144
145 LocalStorageEntry(JSValue* v, int a)
146 : value(v)
147 , attributes(a)
148 {
149 }
150
151 JSValue* value;
152 int attributes;
153 };
154
155 typedef Vector<LocalStorageEntry, 32> LocalStorage;
156
157 private:
158 struct ActivationImpPrivate {
159 ActivationImpPrivate(FunctionImp* f, const List& a)
160 : function(f)
161 , arguments(a)
162 , argumentsObject(0)
163 {
164 ASSERT(f);
165 }
166
167 FunctionImp* function;
168 LocalStorage localStorage;
169
170 List arguments;
171 Arguments* argumentsObject;
172 };
173
174 public:
175 ActivationImp(FunctionImp* function, const List& arguments);
176
177 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
178 virtual void put(ExecState*, const Identifier& propertyName, JSValue* value, int attr = None);
179 virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
180
181 virtual const ClassInfo* classInfo() const { return &info; }
182 static const ClassInfo info;
183
184 virtual void mark();
185
186 bool isActivation() { return true; }
187
188 void releaseArguments() { d->arguments.reset(); }
189
190 LocalStorage& localStorage() { return d->localStorage; }
191 SymbolTable& symbolTable() { return *m_symbolTable; }
192
193 private:
194 static PropertySlot::GetValueFunc getArgumentsGetter();
195 static JSValue* argumentsGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot);
196 void createArgumentsObject(ExecState*);
197
198 OwnPtr<ActivationImpPrivate> d;
199 SymbolTable* m_symbolTable;
200 };
201
202 class GlobalFuncImp : public InternalFunctionImp {
203 public:
204 GlobalFuncImp(ExecState*, FunctionPrototype*, int i, int len, const Identifier&);
205 virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const List& args);
206 enum { Eval, ParseInt, ParseFloat, IsNaN, IsFinite, Escape, UnEscape,
207 DecodeURI, DecodeURIComponent, EncodeURI, EncodeURIComponent
208#ifndef NDEBUG
209 , KJSPrint
210#endif
211};
212 private:
213 int id;
214 };
215
216 static const double mantissaOverflowLowerBound = 9007199254740992.0;
217 double parseIntOverflow(const char* s, int length, int radix);
218
219} // namespace
220
221#endif
Note: See TracBrowser for help on using the repository browser.