Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(750)

Side by Side Diff: src/interface.cc

Issue 918373002: Strip Interface class of most of its logic, make it all about Module exports (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Properly freeze interface at the end of ParseModule Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/interface.h ('k') | src/messages.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/interface.h" 7 #include "src/interface.h"
8 8
9 #include "src/base/lazy-instance.h" 9 #include "src/ast-value-factory.h"
10 10
11 namespace v8 { 11 namespace v8 {
12 namespace internal { 12 namespace internal {
13 13
14 // --------------------------------------------------------------------------- 14 // ---------------------------------------------------------------------------
15 // Initialization.
16
17 struct Interface::Cache {
18 template<int flags>
19 struct Create {
20 static void Construct(Interface* ptr) { ::new (ptr) Interface(flags); }
21 };
22 typedef Create<VALUE + FROZEN> ValueCreate;
23 typedef Create<VALUE + CONST + FROZEN> ConstCreate;
24
25 static base::LazyInstance<Interface, ValueCreate>::type value_interface;
26 static base::LazyInstance<Interface, ConstCreate>::type const_interface;
27 };
28
29
30 base::LazyInstance<Interface, Interface::Cache::ValueCreate>::type
31 Interface::Cache::value_interface = LAZY_INSTANCE_INITIALIZER;
32
33 base::LazyInstance<Interface, Interface::Cache::ConstCreate>::type
34 Interface::Cache::const_interface = LAZY_INSTANCE_INITIALIZER;
35
36
37 Interface* Interface::NewValue() {
38 return Cache::value_interface.Pointer(); // Cached.
39 }
40
41
42 Interface* Interface::NewConst() {
43 return Cache::const_interface.Pointer(); // Cached.
44 }
45
46
47 // ---------------------------------------------------------------------------
48 // Lookup.
49
50 Interface* Interface::Lookup(Handle<String> name, Zone* zone) {
51 DCHECK(IsModule());
52 ZoneHashMap* map = Chase()->exports_;
53 if (map == nullptr) return nullptr;
54 ZoneAllocationPolicy allocator(zone);
55 ZoneHashMap::Entry* p =
56 map->Lookup(name.location(), name->Hash(), false, allocator);
57 if (p == nullptr) return nullptr;
58 DCHECK(*static_cast<String**>(p->key) == *name);
59 DCHECK(p->value != nullptr);
60 return static_cast<Interface*>(p->value);
61 }
62
63
64 // ---------------------------------------------------------------------------
65 // Addition. 15 // Addition.
66 16
67 #ifdef DEBUG 17 #ifdef DEBUG
68 // Current nesting depth for debug output. 18 // Current nesting depth for debug output.
69 class Nesting { 19 class Nesting {
70 public: 20 public:
71 Nesting() { current_ += 2; } 21 Nesting() { current_ += 2; }
72 ~Nesting() { current_ -= 2; } 22 ~Nesting() { current_ -= 2; }
73 static int current() { return current_; } 23 static int current() { return current_; }
74 private: 24 private:
75 static int current_; 25 static int current_;
76 }; 26 };
77 27
78 int Nesting::current_ = 0; 28 int Nesting::current_ = 0;
79 #endif 29 #endif
80 30
81 31
82 void Interface::DoAdd(const void* name, uint32_t hash, Interface* interface, 32 void Interface::Add(const AstRawString* name, Zone* zone, bool* ok) {
83 Zone* zone, bool* ok) { 33 void* key = const_cast<AstRawString*>(name);
84 MakeModule(ok);
85 if (!*ok) return;
86 34
87 #ifdef DEBUG 35 #ifdef DEBUG
88 if (FLAG_print_interface_details) { 36 if (FLAG_print_interface_details) {
89 PrintF("%*s# Adding...\n", Nesting::current(), ""); 37 PrintF("%*s# Adding...\n", Nesting::current(), "");
90 PrintF("%*sthis = ", Nesting::current(), ""); 38 PrintF("%*sthis = ", Nesting::current(), "");
91 this->Print(Nesting::current()); 39 this->Print(Nesting::current());
92 const AstRawString* raw = static_cast<const AstRawString*>(name); 40 PrintF("%*s%.*s : ", Nesting::current(), "", name->length(),
93 PrintF("%*s%.*s : ", Nesting::current(), "", 41 name->raw_data());
94 raw->length(), raw->raw_data());
95 interface->Print(Nesting::current());
96 } 42 }
97 #endif 43 #endif
98 44
99 ZoneHashMap** map = &Chase()->exports_; 45 ZoneHashMap** map = &exports_;
100 ZoneAllocationPolicy allocator(zone); 46 ZoneAllocationPolicy allocator(zone);
101 47
102 if (*map == nullptr) { 48 if (*map == nullptr) {
103 *map = new(zone->New(sizeof(ZoneHashMap))) 49 *map = new(zone->New(sizeof(ZoneHashMap)))
104 ZoneHashMap(ZoneHashMap::PointersMatch, 50 ZoneHashMap(ZoneHashMap::PointersMatch,
105 ZoneHashMap::kDefaultHashMapCapacity, allocator); 51 ZoneHashMap::kDefaultHashMapCapacity, allocator);
106 } 52 }
107 53
108 ZoneHashMap::Entry* p = 54 ZoneHashMap::Entry* p =
109 (*map)->Lookup(const_cast<void*>(name), hash, !IsFrozen(), allocator); 55 (*map)->Lookup(key, name->hash(), !IsFrozen(), allocator);
110 if (p == nullptr) { 56 if (p == nullptr || p->value != nullptr) {
111 // This didn't have name but was frozen already, that's an error.
112 *ok = false; 57 *ok = false;
113 } else if (p->value == nullptr) {
114 p->value = interface;
115 } else {
116 #ifdef DEBUG
117 Nesting nested;
118 #endif
119 static_cast<Interface*>(p->value)->Unify(interface, zone, ok);
120 } 58 }
121 59
60 p->value = key;
61
122 #ifdef DEBUG 62 #ifdef DEBUG
123 if (FLAG_print_interface_details) { 63 if (FLAG_print_interface_details) {
124 PrintF("%*sthis' = ", Nesting::current(), ""); 64 PrintF("%*sthis' = ", Nesting::current(), "");
125 this->Print(Nesting::current()); 65 this->Print(Nesting::current());
126 PrintF("%*s# Added.\n", Nesting::current(), ""); 66 PrintF("%*s# Added.\n", Nesting::current(), "");
127 } 67 }
128 #endif 68 #endif
129 } 69 }
130 70
131 71
132 // --------------------------------------------------------------------------- 72 // ---------------------------------------------------------------------------
133 // Unification.
134
135 void Interface::Unify(Interface* that, Zone* zone, bool* ok) {
136 if (this->forward_) return this->Chase()->Unify(that, zone, ok);
137 if (that->forward_) return this->Unify(that->Chase(), zone, ok);
138 DCHECK(this->forward_ == nullptr);
139 DCHECK(that->forward_ == nullptr);
140
141 *ok = true;
142 if (this == that) return;
143 if (this->IsValue()) {
144 that->MakeValue(ok);
145 if (*ok && this->IsConst()) that->MakeConst(ok);
146 return;
147 }
148 if (that->IsValue()) {
149 this->MakeValue(ok);
150 if (*ok && that->IsConst()) this->MakeConst(ok);
151 return;
152 }
153
154 #ifdef DEBUG
155 if (FLAG_print_interface_details) {
156 PrintF("%*s# Unifying...\n", Nesting::current(), "");
157 PrintF("%*sthis = ", Nesting::current(), "");
158 this->Print(Nesting::current());
159 PrintF("%*sthat = ", Nesting::current(), "");
160 that->Print(Nesting::current());
161 }
162 #endif
163
164 // Merge the smaller interface into the larger, for performance.
165 if (this->exports_ != nullptr && (that->exports_ == nullptr ||
166 this->exports_->occupancy() >= that->exports_->occupancy())) {
167 this->DoUnify(that, ok, zone);
168 } else {
169 that->DoUnify(this, ok, zone);
170 }
171
172 #ifdef DEBUG
173 if (FLAG_print_interface_details) {
174 PrintF("%*sthis' = ", Nesting::current(), "");
175 this->Print(Nesting::current());
176 PrintF("%*sthat' = ", Nesting::current(), "");
177 that->Print(Nesting::current());
178 PrintF("%*s# Unified.\n", Nesting::current(), "");
179 }
180 #endif
181 }
182
183
184 void Interface::DoUnify(Interface* that, bool* ok, Zone* zone) {
185 DCHECK(this->forward_ == nullptr);
186 DCHECK(that->forward_ == nullptr);
187 DCHECK(!this->IsValue());
188 DCHECK(!that->IsValue());
189 DCHECK(this->index_ == -1);
190 DCHECK(that->index_ == -1);
191 DCHECK(*ok);
192
193 #ifdef DEBUG
194 Nesting nested;
195 #endif
196
197 // Try to merge all members from that into this.
198 ZoneHashMap* map = that->exports_;
199 if (map != nullptr) {
200 for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
201 this->DoAdd(p->key, p->hash, static_cast<Interface*>(p->value), zone, ok);
202 if (!*ok) return;
203 }
204 }
205
206 // If the new interface is larger than that's, then there were members in
207 // 'this' which 'that' didn't have. If 'that' was frozen that is an error.
208 int this_size = this->exports_ == nullptr ? 0 : this->exports_->occupancy();
209 int that_size = map == nullptr ? 0 : map->occupancy();
210 if (that->IsFrozen() && this_size > that_size) {
211 *ok = false;
212 return;
213 }
214
215 // Merge interfaces.
216 this->flags_ |= that->flags_;
217 that->forward_ = this;
218 }
219
220
221 // ---------------------------------------------------------------------------
222 // Printing. 73 // Printing.
223 74
224 #ifdef DEBUG 75 #ifdef DEBUG
225 void Interface::Print(int n) { 76 void Interface::Print(int n) {
226 int n0 = n > 0 ? n : 0; 77 int n0 = n > 0 ? n : 0;
227 78
228 if (FLAG_print_interface_details) { 79 if (FLAG_print_interface_details) {
229 PrintF("%p", static_cast<void*>(this)); 80 PrintF("%p ", static_cast<void*>(this));
230 for (Interface* link = this->forward_; link != nullptr;
231 link = link->forward_) {
232 PrintF("->%p", static_cast<void*>(link));
233 }
234 PrintF(" ");
235 } 81 }
236 82
237 if (IsUnknown()) { 83 PrintF("module %d %s{", Index(), IsFrozen() ? "" : "(unresolved) ");
238 PrintF("unknown\n"); 84 ZoneHashMap* map = exports_;
239 } else if (IsConst()) { 85 if (map == nullptr || map->occupancy() == 0) {
240 PrintF("const\n"); 86 PrintF("}\n");
241 } else if (IsValue()) { 87 } else if (n < 0 || n0 >= 2 * FLAG_print_interface_depth) {
242 PrintF("value\n"); 88 // Avoid infinite recursion on cyclic types.
243 } else if (IsModule()) { 89 PrintF("...}\n");
244 PrintF("module %d %s{", Index(), IsFrozen() ? "" : "(unresolved) "); 90 } else {
245 ZoneHashMap* map = Chase()->exports_; 91 PrintF("\n");
246 if (map == nullptr || map->occupancy() == 0) { 92 for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
247 PrintF("}\n"); 93 String* name = *static_cast<String**>(p->key);
248 } else if (n < 0 || n0 >= 2 * FLAG_print_interface_depth) { 94 PrintF("%*s%s : ", n0 + 2, "", name->ToAsciiArray());
249 // Avoid infinite recursion on cyclic types.
250 PrintF("...}\n");
251 } else {
252 PrintF("\n");
253 for (ZoneHashMap::Entry* p = map->Start();
254 p != nullptr; p = map->Next(p)) {
255 String* name = *static_cast<String**>(p->key);
256 Interface* interface = static_cast<Interface*>(p->value);
257 PrintF("%*s%s : ", n0 + 2, "", name->ToAsciiArray());
258 interface->Print(n0 + 2);
259 }
260 PrintF("%*s}\n", n0, "");
261 } 95 }
96 PrintF("%*s}\n", n0, "");
262 } 97 }
263 } 98 }
264 #endif 99 #endif
265 100
266 } } // namespace v8::internal 101 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/interface.h ('k') | src/messages.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698