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

Side by Side Diff: src/types.h

Issue 103743004: Implement zone-allocated types (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | src/types.cc » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 V(NonNumber, kAny - kNumber) \ 130 V(NonNumber, kAny - kNumber) \
131 V(Detectable, kAllocated - kUndetectable) 131 V(Detectable, kAllocated - kUndetectable)
132 132
133 133
134 // struct Config { 134 // struct Config {
135 // typedef Base; 135 // typedef Base;
136 // typedef Unioned; 136 // typedef Unioned;
137 // typedef Region; 137 // typedef Region;
138 // template<class> struct Handle { typedef type; } // No template typedefs... 138 // template<class> struct Handle { typedef type; } // No template typedefs...
139 // static Handle<Type>::type handle(Type* type); // !is_bitset(type) 139 // static Handle<Type>::type handle(Type* type); // !is_bitset(type)
140 // static bool is_bitset(Type* type); 140 // static bool is_bitset(Type*);
141 // static bool is_class(Type* type); 141 // static bool is_class(Type*);
142 // static bool is_constant(Type* type); 142 // static bool is_constant(Type*);
143 // static bool is_union(Type* type); 143 // static bool is_union(Type*);
144 // static int as_bitset(Type* type); 144 // static int as_bitset(Type*);
145 // static i::Handle<i::Map> as_class(Type* type); 145 // static i::Handle<i::Map> as_class(Type*);
146 // static i::Handle<i::Object> as_constant(Type* type); 146 // static i::Handle<i::Object> as_constant(Type*);
147 // static Handle<Unioned>::type as_union(Type* type); 147 // static Handle<Unioned>::type as_union(Type*);
148 // static Type* from_bitset(int bitset); 148 // static Type* from_bitset(int bitset);
149 // static Handle<Type>::type from_bitset(int bitset, Region* region); 149 // static Handle<Type>::type from_bitset(int bitset, Region*);
150 // static Handle<Type>::type from_class(i::Handle<i::Map> map, Region* region) 150 // static Handle<Type>::type from_class(i::Handle<i::Map>, Region*)
151 // static Handle<Type>::type from_constant( 151 // static Handle<Type>::type from_constant(i::Handle<i::Object>, Region*);
152 // i::Handle<i::Object> value, Region* region); 152 // static Handle<Type>::type from_union(Handle<Unioned>::type);
153 // static Handle<Type>::type from_union(Handle<Unioned>::T unioned); 153 // static Handle<Unioned>::type union_create(int size, Region*);
154 // static Handle<Unioned>::type union_create(int size, Region* region); 154 // static Handle<Unioned>::type union_shrink(
155 // static Handle<Type>::type union_get(Handle<Unioned>::T unioned, int i); 155 // Handle<Unioned>::type, int size, Region*);
156 // static Handle<Type>::type union_get(Handle<Unioned>::type, int);
157 // static void union_set(Handle<Unioned>::type, int, Handle<Type>::type);
158 // static int union_length(Handle<Unioned>::type);
156 // } 159 // }
157 template<class Config> 160 template<class Config>
158 class TypeImpl : public Config::Base { 161 class TypeImpl : public Config::Base {
159 public: 162 public:
160 typedef typename Config::template Handle<TypeImpl>::type TypeHandle; 163 typedef typename Config::template Handle<TypeImpl>::type TypeHandle;
161 typedef typename Config::Region Region; 164 typedef typename Config::Region Region;
162 165
163 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ 166 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \
164 static TypeImpl* type() { return Config::from_bitset(k##type); } \ 167 static TypeImpl* type() { return Config::from_bitset(k##type); } \
165 static TypeHandle type(Region* region) { \ 168 static TypeHandle type(Region* region) { \
(...skipping 10 matching lines...) Expand all
176 } 179 }
177 180
178 static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg); 181 static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg);
179 static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region* reg); 182 static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region* reg);
180 183
181 static TypeHandle Of(i::Handle<i::Object> value, Region* region) { 184 static TypeHandle Of(i::Handle<i::Object> value, Region* region) {
182 return Config::from_bitset(LubBitset(*value), region); 185 return Config::from_bitset(LubBitset(*value), region);
183 } 186 }
184 187
185 bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); } 188 bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); }
189 template<class TypeHandle>
186 bool Is(TypeHandle that) { return this->Is(*that); } 190 bool Is(TypeHandle that) { return this->Is(*that); }
187 bool Maybe(TypeImpl* that); 191 bool Maybe(TypeImpl* that);
192 template<class TypeHandle>
188 bool Maybe(TypeHandle that) { return this->Maybe(*that); } 193 bool Maybe(TypeHandle that) { return this->Maybe(*that); }
189 194
190 // State-dependent versions of Of and Is that consider subtyping between 195 // State-dependent versions of Of and Is that consider subtyping between
191 // a constant and its map class. 196 // a constant and its map class.
192 static TypeHandle OfCurrently(i::Handle<i::Object> value, Region* region); 197 static TypeHandle OfCurrently(i::Handle<i::Object> value, Region* region);
193 bool IsCurrently(TypeImpl* that); 198 bool IsCurrently(TypeImpl* that);
199 template<class TypeHandle>
194 bool IsCurrently(TypeHandle that) { return this->IsCurrently(*that); } 200 bool IsCurrently(TypeHandle that) { return this->IsCurrently(*that); }
195 201
196 bool IsClass() { return Config::is_class(this); } 202 bool IsClass() { return Config::is_class(this); }
197 bool IsConstant() { return Config::is_constant(this); } 203 bool IsConstant() { return Config::is_constant(this); }
198 i::Handle<i::Map> AsClass() { return Config::as_class(this); } 204 i::Handle<i::Map> AsClass() { return Config::as_class(this); }
199 i::Handle<i::Object> AsConstant() { return Config::as_constant(this); } 205 i::Handle<i::Object> AsConstant() { return Config::as_constant(this); }
200 206
201 int NumClasses(); 207 int NumClasses();
202 int NumConstants(); 208 int NumConstants();
203 209
(...skipping 21 matching lines...) Expand all
225 231
226 Iterator<i::Map> Classes() { 232 Iterator<i::Map> Classes() {
227 if (this->IsBitset()) return Iterator<i::Map>(); 233 if (this->IsBitset()) return Iterator<i::Map>();
228 return Iterator<i::Map>(Config::handle(this)); 234 return Iterator<i::Map>(Config::handle(this));
229 } 235 }
230 Iterator<i::Object> Constants() { 236 Iterator<i::Object> Constants() {
231 if (this->IsBitset()) return Iterator<i::Object>(); 237 if (this->IsBitset()) return Iterator<i::Object>();
232 return Iterator<i::Object>(Config::handle(this)); 238 return Iterator<i::Object>(Config::handle(this));
233 } 239 }
234 240
235 static TypeImpl* cast(i::Object* object) { 241 static TypeImpl* cast(typename Config::Base* object) {
236 TypeImpl* t = static_cast<Type*>(object); 242 TypeImpl* t = static_cast<TypeImpl*>(object);
237 ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsUnion()); 243 ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsUnion());
238 return t; 244 return t;
239 } 245 }
240 246
241 #ifdef OBJECT_PRINT 247 #ifdef OBJECT_PRINT
242 void TypePrint(); 248 void TypePrint();
243 void TypePrint(FILE* out); 249 void TypePrint(FILE* out);
244 #endif 250 #endif
245 251
246 private: 252 private:
(...skipping 22 matching lines...) Expand all
269 275
270 bool SlowIs(TypeImpl* that); 276 bool SlowIs(TypeImpl* that);
271 277
272 int LubBitset(); // least upper bound that's a bitset 278 int LubBitset(); // least upper bound that's a bitset
273 int GlbBitset(); // greatest lower bound that's a bitset 279 int GlbBitset(); // greatest lower bound that's a bitset
274 280
275 static int LubBitset(i::Object* value); 281 static int LubBitset(i::Object* value);
276 static int LubBitset(i::Map* map); 282 static int LubBitset(i::Map* map);
277 283
278 bool InUnion(UnionedHandle unioned, int current_size); 284 bool InUnion(UnionedHandle unioned, int current_size);
279 int ExtendUnion(UnionedHandle unioned, int current_size); 285 static int ExtendUnion(
280 int ExtendIntersection( 286 UnionedHandle unioned, TypeHandle t, int current_size);
281 UnionedHandle unioned, TypeHandle type, int current_size); 287 static int ExtendIntersection(
288 UnionedHandle unioned, TypeHandle t, TypeHandle other, int current_size);
282 289
283 static const char* bitset_name(int bitset); 290 static const char* bitset_name(int bitset);
284 }; 291 };
285 292
286 293
294 // Zone-allocated types are either (odd) integers to represent bitsets, or
295 // (even) pointers to zone lists for everything else. The first slot of every
296 // list is an explicit tag value to distinguish representation.
297 struct ZoneTypeConfig {
298 private:
299 typedef i::ZoneList<void*> Tagged;
300
301 enum Tag {
302 kClassTag,
303 kConstantTag,
304 kUnionTag
305 };
306
307 static Tagged* tagged_create(Tag tag, int size, Zone* zone) {
308 Tagged* tagged = new(zone) Tagged(size + 1, zone);
309 tagged->Add(reinterpret_cast<void*>(tag), zone);
310 tagged->AddBlock(NULL, size, zone);
311 return tagged;
312 }
313 static Tag tagged_tag(Tagged* tagged) {
314 return static_cast<Tag>(reinterpret_cast<int>(tagged->at(0)));
315 }
316 template<class T>
317 static T tagged_get(Tagged* tagged, int i) {
318 return reinterpret_cast<T>(tagged->at(i + 1));
319 }
320 template<class T>
321 static void tagged_set(Tagged* tagged, int i, T value) {
322 tagged->at(i + 1) = reinterpret_cast<T>(value);
323 }
324 static int tagged_length(Tagged* tagged) {
325 return tagged->length() - 1;
326 }
327
328 public:
329 typedef TypeImpl<ZoneTypeConfig> Type;
330 class Base {};
331 typedef i::ZoneList<Type*> Unioned;
332 typedef i::Zone Region;
333 template<class T> struct Handle { typedef T* type; };
334
335 static Type* handle(Type* type) { return type; }
336
337 static bool is(Type* type, Tag tag) {
338 return is_tagged(type) && tagged_tag(as_tagged(type)) == tag;
339 }
340
341 static bool is_bitset(Type* type) { return reinterpret_cast<int>(type) & 1; }
342 static bool is_tagged(Type* type) { return !is_bitset(type); }
343 static bool is_class(Type* type) { return is(type, kClassTag); }
344 static bool is_constant(Type* type) { return is(type, kConstantTag); }
345 static bool is_union(Type* type) { return is(type, kUnionTag); }
346 static bool tagged_is_union(Tagged* tagged) {
347 return is(from_tagged(tagged), kUnionTag);
348 }
349
350 static int as_bitset(Type* type) {
351 ASSERT(is_bitset(type));
352 return reinterpret_cast<int>(type) >> 1;
353 }
354 static Tagged* as_tagged(Type* type) {
355 ASSERT(is_tagged(type));
356 return reinterpret_cast<Tagged*>(type);
357 }
358 static i::Handle<i::Map> as_class(Type* type) {
359 ASSERT(is_class(type));
360 return i::Handle<i::Map>(tagged_get<i::Map**>(as_tagged(type), 0));
361 }
362 static i::Handle<i::Object> as_constant(Type* type) {
363 ASSERT(is_constant(type));
364 return i::Handle<i::Object>(tagged_get<i::Object**>(as_tagged(type), 0));
365 }
366 static Unioned* as_union(Type* type) {
367 ASSERT(is_union(type));
368 return tagged_as_union(as_tagged(type));
369 }
370 static Unioned* tagged_as_union(Tagged* tagged) {
371 ASSERT(tagged_is_union(tagged));
372 return reinterpret_cast<Unioned*>(tagged);
373 }
374
375 static Type* from_bitset(int bitset) {
376 return reinterpret_cast<Type*>((bitset << 1) | 1);
377 }
378 static Type* from_bitset(int bitset, Zone* Zone) {
379 return from_bitset(bitset);
380 }
381 static Type* from_tagged(Tagged* tagged) {
382 return reinterpret_cast<Type*>(tagged);
383 }
384 static Type* from_class(i::Handle<i::Map> map, Zone* zone) {
385 Tagged* tagged = tagged_create(kClassTag, 1, zone);
386 tagged_set(tagged, 0, map.location());
387 return from_tagged(tagged);
388 }
389 static Type* from_constant(i::Handle<i::Object> value, Zone* zone) {
390 Tagged* tagged = tagged_create(kConstantTag, 1, zone);
391 tagged_set(tagged, 0, value.location());
392 return from_tagged(tagged);
393 }
394 static Type* from_union(Unioned* unioned) {
395 return from_tagged(tagged_from_union(unioned));
396 }
397 static Tagged* tagged_from_union(Unioned* unioned) {
398 return reinterpret_cast<Tagged*>(unioned);
399 }
400
401 static Unioned* union_create(int size, Zone* zone) {
402 return tagged_as_union(tagged_create(kUnionTag, size, zone));
403 }
404 static Unioned* union_shrink(Unioned* unioned, int size, Zone* zone) {
titzer 2013/12/19 13:44:41 So this one mutates, but the heap one creates a ne
rossberg 2013/12/19 17:21:25 Was able to remove that with the Shrink method.
405 int length = tagged_length(tagged_from_union(unioned));
406 ASSERT(size <= length);
407 for (; size < length; --length) unioned->RemoveLast();
titzer 2013/12/19 13:44:41 I think you can use Rewind() here.
rossberg 2013/12/19 17:21:25 Done.
408 return unioned;
409 }
410 static Type* union_get(Unioned* unioned, int i) {
411 Type* type = tagged_get<Type*>(tagged_from_union(unioned), i);
412 ASSERT(!is_union(type));
titzer 2013/12/19 13:44:41 Asserting a union isn't a member of a union when g
rossberg 2013/12/19 17:21:25 It's a representational invariant, checked here ju
413 return type;
414 }
415 static void union_set(Unioned* unioned, int i, Type* type) {
416 ASSERT(!is_union(type));
417 tagged_set(tagged_from_union(unioned), i, type);
418 }
419 static int union_length(Unioned* unioned) {
420 return tagged_length(tagged_from_union(unioned));
421 }
422 };
423
424
425 // Heap-allocated types are either smis for bitsets, maps for classes, boxes for
426 // constants, or fixed arrays for unions.
287 struct HeapTypeConfig { 427 struct HeapTypeConfig {
288 typedef TypeImpl<HeapTypeConfig> Type; 428 typedef TypeImpl<HeapTypeConfig> Type;
289 typedef i::Object Base; 429 typedef i::Object Base;
290 typedef i::FixedArray Unioned; 430 typedef i::FixedArray Unioned;
291 typedef i::Isolate Region; 431 typedef i::Isolate Region;
292 template<class T> struct Handle { typedef i::Handle<T> type; }; 432 template<class T> struct Handle { typedef i::Handle<T> type; };
293 433
294 static i::Handle<Type> handle(Type* type) { 434 static i::Handle<Type> handle(Type* type) {
295 return i::handle(type, i::HeapObject::cast(type)->GetIsolate()); 435 return i::handle(type, i::HeapObject::cast(type)->GetIsolate());
296 } 436 }
(...skipping 21 matching lines...) Expand all
318 return Type::cast(i::Smi::FromInt(bitset)); 458 return Type::cast(i::Smi::FromInt(bitset));
319 } 459 }
320 static i::Handle<Type> from_bitset(int bitset, Isolate* isolate) { 460 static i::Handle<Type> from_bitset(int bitset, Isolate* isolate) {
321 return i::handle(from_bitset(bitset), isolate); 461 return i::handle(from_bitset(bitset), isolate);
322 } 462 }
323 static i::Handle<Type> from_class(i::Handle<i::Map> map, Isolate* isolate) { 463 static i::Handle<Type> from_class(i::Handle<i::Map> map, Isolate* isolate) {
324 return i::Handle<Type>::cast(i::Handle<Object>::cast(map)); 464 return i::Handle<Type>::cast(i::Handle<Object>::cast(map));
325 } 465 }
326 static i::Handle<Type> from_constant( 466 static i::Handle<Type> from_constant(
327 i::Handle<i::Object> value, Isolate* isolate) { 467 i::Handle<i::Object> value, Isolate* isolate) {
328 ASSERT(isolate || value->IsHeapObject());
329 if (!isolate) isolate = i::HeapObject::cast(*value)->GetIsolate();
330 i::Handle<Box> box = isolate->factory()->NewBox(value); 468 i::Handle<Box> box = isolate->factory()->NewBox(value);
331 return i::Handle<Type>::cast(i::Handle<Object>::cast(box)); 469 return i::Handle<Type>::cast(i::Handle<Object>::cast(box));
332 } 470 }
333 static i::Handle<Type> from_union(i::Handle<Unioned> unioned) { 471 static i::Handle<Type> from_union(i::Handle<Unioned> unioned) {
334 return i::Handle<Type>::cast(i::Handle<Object>::cast(unioned)); 472 return i::Handle<Type>::cast(i::Handle<Object>::cast(unioned));
335 } 473 }
336 474
337 static i::Handle<Unioned> union_create(int size, Isolate* isolate) { 475 static i::Handle<Unioned> union_create(int size, Isolate* isolate) {
338 return isolate->factory()->NewFixedArray(size); 476 return isolate->factory()->NewFixedArray(size);
339 } 477 }
478 static i::Handle<Unioned> union_shrink(
479 i::Handle<Unioned> unioned, int size, Isolate* isolate) {
480 if (size == unioned->length()) return unioned;
481 i::Handle<Unioned> result = union_create(size, isolate);
titzer 2013/12/19 13:44:41 You actually can chop a FixedArray with set_length
rossberg 2013/12/19 17:21:25 It's a bit more complicated than that. I introduce
482 for (int i = 0; i < size; ++i) result->set(i, unioned->get(i));
483 return result;
484 }
340 static i::Handle<Type> union_get(i::Handle<Unioned> unioned, int i) { 485 static i::Handle<Type> union_get(i::Handle<Unioned> unioned, int i) {
341 Type* type = static_cast<Type*>(unioned->get(i)); 486 Type* type = static_cast<Type*>(unioned->get(i));
342 ASSERT(!is_union(type)); 487 ASSERT(!is_union(type));
343 return i::handle(type, unioned->GetIsolate()); 488 return i::handle(type, unioned->GetIsolate());
344 } 489 }
490 static void union_set(
491 i::Handle<Unioned> unioned, int i, i::Handle<Type> type) {
492 ASSERT(!is_union(*type));
493 unioned->set(i, *type);
494 }
495 static int union_length(i::Handle<Unioned> unioned) {
496 return unioned->length();
497 }
345 }; 498 };
346 499
500 typedef TypeImpl<ZoneTypeConfig> ZoneType;
347 typedef TypeImpl<HeapTypeConfig> Type; 501 typedef TypeImpl<HeapTypeConfig> Type;
348 502
349 503
350 // A simple struct to represent a pair of lower/upper type bounds. 504 // A simple struct to represent a pair of lower/upper type bounds.
351 template<class Config> 505 template<class Config>
352 struct BoundsImpl { 506 struct BoundsImpl {
353 typedef TypeImpl<Config> Type; 507 typedef TypeImpl<Config> Type;
354 typedef typename Type::TypeHandle TypeHandle; 508 typedef typename Type::TypeHandle TypeHandle;
355 typedef typename Type::Region Region; 509 typedef typename Type::Region Region;
356 510
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 TypeHandle lower = Type::Union(b.lower, t, region); 544 TypeHandle lower = Type::Union(b.lower, t, region);
391 return BoundsImpl(lower, b.upper); 545 return BoundsImpl(lower, b.upper);
392 } 546 }
393 static BoundsImpl NarrowUpper(BoundsImpl b, TypeHandle t, Region* region) { 547 static BoundsImpl NarrowUpper(BoundsImpl b, TypeHandle t, Region* region) {
394 TypeHandle lower = Type::Intersect(b.lower, t, region); 548 TypeHandle lower = Type::Intersect(b.lower, t, region);
395 TypeHandle upper = Type::Intersect(b.upper, t, region); 549 TypeHandle upper = Type::Intersect(b.upper, t, region);
396 return BoundsImpl(lower, upper); 550 return BoundsImpl(lower, upper);
397 } 551 }
398 }; 552 };
399 553
554 typedef BoundsImpl<ZoneTypeConfig> ZoneBounds;
400 typedef BoundsImpl<HeapTypeConfig> Bounds; 555 typedef BoundsImpl<HeapTypeConfig> Bounds;
401 556
402 557
403 } } // namespace v8::internal 558 } } // namespace v8::internal
404 559
405 #endif // V8_TYPES_H_ 560 #endif // V8_TYPES_H_
OLDNEW
« no previous file with comments | « no previous file | src/types.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698