source: webkit/trunk/JavaScriptCore/kjs/JSVariableObject.h@ 31114

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

Add fast multi-level scope lookup

Reviewed by Geoff, Darin and Weinig

Add logic and AST nodes to provide rapid variable resolution across
static scope boundaries. This also adds logic that allows us to skip
any static scopes that do not contain the variable to be resolved.

This results in a ~2.5% speedup in SunSpider, and gives a 25-30% speedup
in some simple and ad hoc closure and global variable access tests.

  • Property svn:eol-style set to native
File size: 5.3 KB
Line 
1/*
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
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 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef JSVariableObject_h
30#define JSVariableObject_h
31
32#include "LocalStorage.h"
33#include "SymbolTable.h"
34#include "object.h"
35
36namespace KJS {
37
38 class JSVariableObject : public JSObject {
39 public:
40 SymbolTable& symbolTable() { return *d->symbolTable; }
41 LocalStorage& localStorage() { return d->localStorage; }
42
43 void saveLocalStorage(SavedProperties&) const;
44 void restoreLocalStorage(const SavedProperties&);
45
46 virtual void initializeVariable(ExecState*, const Identifier&, JSValue*, unsigned attributes) = 0;
47
48 virtual bool deleteProperty(ExecState*, const Identifier&);
49 virtual void getPropertyNames(ExecState*, PropertyNameArray&);
50
51 virtual void mark();
52
53 virtual bool isVariableObject() const;
54 virtual bool isDynamicScope() const = 0;
55
56 protected:
57 // Subclasses of JSVariableObject can subclass this struct to add data
58 // without increasing their own size (since there's a hard limit on the
59 // size of a JSCell).
60 struct JSVariableObjectData {
61 JSVariableObjectData() { }
62 JSVariableObjectData(SymbolTable* s)
63 : symbolTable(s) // Subclass owns this pointer.
64 {
65 }
66
67 LocalStorage localStorage; // Storage for variables in the symbol table.
68 SymbolTable* symbolTable; // Maps name -> index in localStorage.
69 };
70
71 JSVariableObject() { }
72
73 JSVariableObject(JSVariableObjectData* data)
74 : d(data) // Subclass owns this pointer.
75 {
76 }
77
78 JSVariableObject(JSValue* proto, JSVariableObjectData* data)
79 : JSObject(proto)
80 , d(data) // Subclass owns this pointer.
81 {
82 }
83
84 bool symbolTableGet(const Identifier&, PropertySlot&);
85 bool symbolTablePut(const Identifier&, JSValue*);
86 bool symbolTableInitializeVariable(const Identifier&, JSValue*, unsigned attributes);
87
88 JSVariableObjectData* d;
89 };
90
91 inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot)
92 {
93 size_t index = symbolTable().get(propertyName.ustring().rep());
94 if (index != missingSymbolMarker()) {
95#ifndef NDEBUG
96 // During initialization, the variable object needs to advertise that it has certain
97 // properties, even if they're not ready for access yet. This check verifies that
98 // no one tries to access such a property.
99
100 // In a release build, we optimize this check away and just return an invalid pointer.
101 // There's no harm in an invalid pointer, since no one dereferences it.
102 if (index >= d->localStorage.size()) {
103 slot.setUngettable(this);
104 return true;
105 }
106#endif
107 slot.setValueSlot(this, &d->localStorage[index].value);
108 return true;
109 }
110 return false;
111 }
112
113 inline bool JSVariableObject::symbolTablePut(const Identifier& propertyName, JSValue* value)
114 {
115 size_t index = symbolTable().get(propertyName.ustring().rep());
116 if (index == missingSymbolMarker())
117 return false;
118 LocalStorageEntry& entry = d->localStorage[index];
119 if (entry.attributes & ReadOnly)
120 return true;
121 entry.value = value;
122 return true;
123 }
124
125 inline bool JSVariableObject::symbolTableInitializeVariable(const Identifier& propertyName, JSValue* value, unsigned attributes)
126 {
127 size_t index = symbolTable().get(propertyName.ustring().rep());
128 if (index == missingSymbolMarker())
129 return false;
130 LocalStorageEntry& entry = d->localStorage[index];
131 entry.value = value;
132 entry.attributes = attributes;
133 return true;
134 }
135
136} // namespace KJS
137
138#endif // JSVariableObject_h
Note: See TracBrowser for help on using the repository browser.