Chromium Code Reviews

Side by Side Diff: src/types.cc

Issue 251753005: Establish distributivity for type union & intersection (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Eps Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
« src/types.h ('K') | « src/types.h ('k') | src/types-inl.h » ('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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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 "types.h" 5 #include "types.h"
6 6
7 #include "string-stream.h" 7 #include "string-stream.h"
8 #include "types-inl.h" 8 #include "types-inl.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 121 matching lines...)
132 if (type->IsBitset()) { 132 if (type->IsBitset()) {
133 return type->AsBitset(); 133 return type->AsBitset();
134 } else if (type->IsUnion()) { 134 } else if (type->IsUnion()) {
135 UnionHandle unioned = handle(type->AsUnion()); 135 UnionHandle unioned = handle(type->AsUnion());
136 int bitset = kNone; 136 int bitset = kNone;
137 for (int i = 0; i < unioned->Length(); ++i) { 137 for (int i = 0; i < unioned->Length(); ++i) {
138 bitset |= unioned->Get(i)->BitsetLub(); 138 bitset |= unioned->Get(i)->BitsetLub();
139 } 139 }
140 return bitset; 140 return bitset;
141 } else if (type->IsClass()) { 141 } else if (type->IsClass()) {
142 int bitset = Config::lub_bitset(type); 142 // Little hack to avoid the need for a region for handlification here...
143 return bitset ? bitset : Lub(*type->AsClass()->Map()); 143 return Config::is_class(type) ? Lub(*Config::as_class(type)) :
144 type->AsClass()->Bound(NULL)->AsBitset();
144 } else if (type->IsConstant()) { 145 } else if (type->IsConstant()) {
145 int bitset = Config::lub_bitset(type); 146 return type->AsConstant()->Bound()->AsBitset();
146 return bitset ? bitset : Lub(*type->AsConstant()->Value()); 147 } else if (type->IsArray()) {
148 return type->AsArray()->Bound()->AsBitset();
149 } else if (type->IsFunction()) {
150 return type->AsFunction()->Bound()->AsBitset();
151 } else {
152 UNREACHABLE();
153 return kNone;
154 }
155 }
156
157
158 // Get the smallest bitset subsuming this type, ignoring current bounds.
159 template<class Config>
160 int TypeImpl<Config>::BitsetType::InherentLub(TypeImpl* type) {
161 DisallowHeapAllocation no_allocation;
162 if (type->IsBitset()) {
163 return type->AsBitset();
164 } else if (type->IsUnion()) {
165 UnionHandle unioned = handle(type->AsUnion());
166 int bitset = kNone;
167 for (int i = 0; i < unioned->Length(); ++i) {
168 bitset |= unioned->Get(i)->InherentBitsetLub();
169 }
170 return bitset;
171 } else if (type->IsClass()) {
172 return Lub(*type->AsClass()->Map());
173 } else if (type->IsConstant()) {
174 return Lub(*type->AsConstant()->Value());
147 } else if (type->IsArray()) { 175 } else if (type->IsArray()) {
148 return kArray; 176 return kArray;
149 } else if (type->IsFunction()) { 177 } else if (type->IsFunction()) {
150 return kFunction; 178 return kFunction;
151 } else { 179 } else {
152 UNREACHABLE(); 180 UNREACHABLE();
153 return kNone; 181 return kNone;
154 } 182 }
155 } 183 }
156 184
(...skipping 123 matching lines...)
280 DisallowHeapAllocation no_allocation; 308 DisallowHeapAllocation no_allocation;
281 309
282 // Fast path for bitsets. 310 // Fast path for bitsets.
283 if (this->IsNone()) return true; 311 if (this->IsNone()) return true;
284 if (that->IsBitset()) { 312 if (that->IsBitset()) {
285 return (BitsetType::Lub(this) | that->AsBitset()) == that->AsBitset(); 313 return (BitsetType::Lub(this) | that->AsBitset()) == that->AsBitset();
286 } 314 }
287 315
288 if (that->IsClass()) { 316 if (that->IsClass()) {
289 return this->IsClass() 317 return this->IsClass()
290 && *this->AsClass()->Map() == *that->AsClass()->Map(); 318 && *this->AsClass()->Map() == *that->AsClass()->Map()
319 && ((Config::is_class(that) && Config::is_class(this)) ||
320 BitsetType::New(this->BitsetLub())->Is(
321 BitsetType::New(that->BitsetLub())));
291 } 322 }
292 if (that->IsConstant()) { 323 if (that->IsConstant()) {
293 return this->IsConstant() 324 return this->IsConstant()
294 && *this->AsConstant()->Value() == *that->AsConstant()->Value(); 325 && *this->AsConstant()->Value() == *that->AsConstant()->Value()
326 && this->AsConstant()->Bound()->Is(that->AsConstant()->Bound());
295 } 327 }
296 if (that->IsArray()) { 328 if (that->IsArray()) {
297 return this->IsArray() 329 return this->IsArray()
298 && this->AsArray()->Element()->Equals(that->AsArray()->Element()); 330 && this->AsArray()->Element()->Equals(that->AsArray()->Element());
299 } 331 }
300 if (that->IsFunction()) { 332 if (that->IsFunction()) {
301 // We currently do not allow for any variance here, in order to keep 333 // We currently do not allow for any variance here, in order to keep
302 // Union and Intersect operations simple. 334 // Union and Intersect operations simple.
303 if (!this->IsFunction()) return false; 335 if (!this->IsFunction()) return false;
304 FunctionType* this_fun = this->AsFunction(); 336 FunctionType* this_fun = this->AsFunction();
(...skipping 112 matching lines...)
417 return this->Equals(that); 449 return this->Equals(that);
418 } 450 }
419 451
420 return false; 452 return false;
421 } 453 }
422 454
423 455
424 template<class Config> 456 template<class Config>
425 bool TypeImpl<Config>::Contains(i::Object* value) { 457 bool TypeImpl<Config>::Contains(i::Object* value) {
426 DisallowHeapAllocation no_allocation; 458 DisallowHeapAllocation no_allocation;
427
428 for (Iterator<i::Object> it = this->Constants(); !it.Done(); it.Advance()) { 459 for (Iterator<i::Object> it = this->Constants(); !it.Done(); it.Advance()) {
429 if (*it.Current() == value) return true; 460 if (*it.Current() == value) return true;
430 } 461 }
431 return BitsetType::New(BitsetType::Lub(value))->Is(this); 462 return BitsetType::New(BitsetType::Lub(value))->Is(this);
432 } 463 }
433 464
434 465
435 template<class Config> 466 template<class Config>
436 bool TypeImpl<Config>::InUnion(UnionHandle unioned, int current_size) { 467 bool TypeImpl<Config>::UnionType::Wellformed() {
437 ASSERT(!this->IsUnion()); 468 ASSERT(this->Length() >= 2);
Benedikt Meurer 2014/05/23 05:09:00 This function always returns true, so the return t
438 for (int i = 0; i < current_size; ++i) { 469 for (int i = 0; i < this->Length(); ++i) {
439 if (this->Is(unioned->Get(i))) return true; 470 ASSERT(!this->Get(i)->IsUnion());
471 if (i > 0) ASSERT(!this->Get(i)->IsBitset());
472 for (int j = 0; j < this->Length(); ++j) {
473 if (i != j) ASSERT(!this->Get(i)->Is(this->Get(j)));
474 }
440 } 475 }
441 return false; 476 return true;
442 } 477 }
443 478
444 479
445 // Get non-bitsets from this which are not subsumed by union, store at result, 480 template<class Config>
446 // starting at index. Returns updated index. 481 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Narrow(
482 int bitset, Region* region) {
483 TypeHandle bound = BitsetType::New(bitset, region);
484 if (this->IsClass()) {
485 return ClassType::New(this->AsClass()->Map(), bound, region);
486 } else if (this->IsConstant()) {
487 return ConstantType::New(this->AsConstant()->Value(), bound, region);
488 } else if (this->IsArray()) {
489 return ArrayType::New(this->AsArray()->Element(), bound, region);
490 } else if (this->IsFunction()) {
491 FunctionType* function = this->AsFunction();
492 int arity = function->Arity();
493 FunctionHandle type = FunctionType::New(
494 function->Result(), function->Receiver(), bound, arity, region);
495 for (int i = 0; i < arity; ++i) {
496 type->InitParameter(i, function->Parameter(i));
497 }
498 return type;
499 }
500 UNREACHABLE();
501 return TypeHandle();
502 }
503
504
505 template<class Config>
506 int TypeImpl<Config>::BoundBy(TypeImpl* that) {
507 ASSERT(!this->IsUnion());
508 if (that->IsBitset()) {
509 return that->AsBitset() & this->InherentBitsetLub();
510 } else if (that->IsUnion()) {
511 UnionType* unioned = that->AsUnion();
512 int length = unioned->Length();
513 int bitset = BitsetType::kNone;
514 for (int i = 0; i < length; ++i) {
515 bitset |= BoundBy(unioned->Get(i)->unhandle());
516 }
517 return bitset;
518 } else if (that->IsClass() && this->IsClass() &&
519 *this->AsClass()->Map() == *that->AsClass()->Map()) {
520 return that->BitsetLub();
521 } else if (that->IsConstant() && this->IsConstant() &&
522 *this->AsConstant()->Value() == *that->AsConstant()->Value()) {
523 return that->AsConstant()->Bound()->AsBitset();
524 } else if (that->IsArray() && this->IsArray() && this->Is(that)) {
525 return that->AsArray()->Bound()->AsBitset();
526 } else if (that->IsFunction() && this->IsFunction() && this->Is(that)) {
527 return that->AsFunction()->Bound()->AsBitset();
528 }
529 return BitsetType::kNone;
530 }
531
532
533 template<class Config>
534 int TypeImpl<Config>::IndexInUnion(
535 int bound, UnionHandle unioned, int current_size) {
536 ASSERT(!this->IsUnion());
537 for (int i = 0; i < current_size; ++i) {
538 TypeHandle that = unioned->Get(i);
539 if (that->IsBitset()) {
540 if ((bound | that->AsBitset()) == that->AsBitset()) return i;
541 } else if (that->IsClass() && this->IsClass()) {
542 if (*this->AsClass()->Map() == *that->AsClass()->Map()) return i;
543 } else if (that->IsConstant() && this->IsConstant()) {
544 if (*this->AsConstant()->Value() == *that->AsConstant()->Value())
545 return i;
546 } else if (that->IsArray() && this->IsArray()) {
547 if (this->Is(that)) return i;
548 } else if (that->IsFunction() && this->IsFunction()) {
549 if (this->Is(that)) return i;
550 }
551 }
552 return -1;
553 }
554
555
556 // Get non-bitsets from type, bounded by upper.
557 // Store at result starting at index. Returns updated index.
447 template<class Config> 558 template<class Config>
448 int TypeImpl<Config>::ExtendUnion( 559 int TypeImpl<Config>::ExtendUnion(
449 UnionHandle result, TypeHandle type, int current_size) { 560 UnionHandle result, int size, TypeHandle type,
450 int old_size = current_size; 561 TypeHandle other, bool is_intersect, Region* region) {
562 int old_size = size;
451 if (type->IsUnion()) { 563 if (type->IsUnion()) {
452 UnionHandle unioned = handle(type->AsUnion()); 564 UnionHandle unioned = handle(type->AsUnion());
453 for (int i = 0; i < unioned->Length(); ++i) { 565 for (int i = 0; i < unioned->Length(); ++i) {
454 TypeHandle type = unioned->Get(i); 566 TypeHandle type_i = unioned->Get(i);
455 ASSERT(i == 0 || !(type->IsBitset() || type->Is(unioned->Get(0)))); 567 ASSERT(i == 0 || !(type_i->IsBitset() || type_i->Is(unioned->Get(0))));
456 if (!type->IsBitset() && !type->InUnion(result, old_size)) { 568 if (!type_i->IsBitset()) {
457 result->Set(current_size++, type); 569 size = ExtendUnion(result, size, type_i, other, is_intersect, region);
458 } 570 }
459 } 571 }
460 } else if (!type->IsBitset()) { 572 } else if (!type->IsBitset()) {
461 // For all structural types, subtyping implies equivalence.
462 ASSERT(type->IsClass() || type->IsConstant() || 573 ASSERT(type->IsClass() || type->IsConstant() ||
463 type->IsArray() || type->IsFunction()); 574 type->IsArray() || type->IsFunction());
464 if (!type->InUnion(result, old_size)) { 575 int old_bound = type->BitsetLub();
465 result->Set(current_size++, type); 576 int other_bound = type->BoundBy(other->unhandle());
577 int new_bound =
578 is_intersect ? (old_bound & other_bound) : (old_bound | other_bound);
579 if (new_bound != BitsetType::kNone) {
580 int i = type->IndexInUnion(new_bound, result, old_size);
581 if (i == -1) {
582 i = size++;
583 } else if (result->Get(i)->IsBitset()) {
584 return size; // Already fully subsumed.
585 } else {
586 int type_i_bound = result->Get(i)->BitsetLub();
587 new_bound |= type_i_bound;
588 if (new_bound == type_i_bound) return size;
589 }
590 if (new_bound != old_bound) type = type->Narrow(new_bound, region);
591 result->Set(i, type);
466 } 592 }
467 } 593 }
468 return current_size; 594 return size;
469 } 595 }
470 596
471 597
472 // Union is O(1) on simple bit unions, but O(n*m) on structured unions. 598 // Union is O(1) on simple bitsets, but O(n*m) on structured unions.
473 template<class Config> 599 template<class Config>
474 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union( 600 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
475 TypeHandle type1, TypeHandle type2, Region* region) { 601 TypeHandle type1, TypeHandle type2, Region* region) {
476 // Fast case: bit sets. 602 // Fast case: bit sets.
477 if (type1->IsBitset() && type2->IsBitset()) { 603 if (type1->IsBitset() && type2->IsBitset()) {
478 return BitsetType::New(type1->AsBitset() | type2->AsBitset(), region); 604 return BitsetType::New(type1->AsBitset() | type2->AsBitset(), region);
479 } 605 }
480 606
481 // Fast case: top or bottom types. 607 // Fast case: top or bottom types.
482 if (type1->IsAny() || type2->IsNone()) return type1; 608 if (type1->IsAny() || type2->IsNone()) return type1;
(...skipping 15 matching lines...)
498 } 624 }
499 int bitset = type1->BitsetGlb() | type2->BitsetGlb(); 625 int bitset = type1->BitsetGlb() | type2->BitsetGlb();
500 if (bitset != BitsetType::kNone) ++size; 626 if (bitset != BitsetType::kNone) ++size;
501 ASSERT(size >= 1); 627 ASSERT(size >= 1);
502 628
503 UnionHandle unioned = UnionType::New(size, region); 629 UnionHandle unioned = UnionType::New(size, region);
504 size = 0; 630 size = 0;
505 if (bitset != BitsetType::kNone) { 631 if (bitset != BitsetType::kNone) {
506 unioned->Set(size++, BitsetType::New(bitset, region)); 632 unioned->Set(size++, BitsetType::New(bitset, region));
507 } 633 }
508 size = ExtendUnion(unioned, type1, size); 634
509 size = ExtendUnion(unioned, type2, size); 635 size = ExtendUnion(unioned, size, type1, type2, false, region);
636 size = ExtendUnion(unioned, size, type2, type1, false, region);
510 637
511 if (size == 1) { 638 if (size == 1) {
512 return unioned->Get(0); 639 return unioned->Get(0);
513 } else { 640 } else {
514 unioned->Shrink(size); 641 unioned->Shrink(size);
642 ASSERT(unioned->Wellformed());
515 return unioned; 643 return unioned;
516 } 644 }
517 } 645 }
518 646
519 647
520 // Get non-bitsets from type which are also in other, store at result, 648 // Intersection is O(1) on simple bitsets, but O(n*m) on structured unions.
521 // starting at index. Returns updated index.
522 template<class Config>
523 int TypeImpl<Config>::ExtendIntersection(
524 UnionHandle result, TypeHandle type, TypeHandle other, int current_size) {
525 int old_size = current_size;
526 if (type->IsUnion()) {
527 UnionHandle unioned = handle(type->AsUnion());
528 for (int i = 0; i < unioned->Length(); ++i) {
529 TypeHandle type = unioned->Get(i);
530 ASSERT(i == 0 || !(type->IsBitset() || type->Is(unioned->Get(0))));
531 if (!type->IsBitset() && type->Is(other) &&
532 !type->InUnion(result, old_size)) {
533 result->Set(current_size++, type);
534 }
535 }
536 } else if (!type->IsBitset()) {
537 // For all structural types, subtyping implies equivalence.
538 ASSERT(type->IsClass() || type->IsConstant() ||
539 type->IsArray() || type->IsFunction());
540 if (type->Is(other) && !type->InUnion(result, old_size)) {
541 result->Set(current_size++, type);
542 }
543 }
544 return current_size;
545 }
546
547
548 // Intersection is O(1) on simple bit unions, but O(n*m) on structured unions.
549 template<class Config> 649 template<class Config>
550 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect( 650 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
551 TypeHandle type1, TypeHandle type2, Region* region) { 651 TypeHandle type1, TypeHandle type2, Region* region) {
552 // Fast case: bit sets. 652 // Fast case: bit sets.
553 if (type1->IsBitset() && type2->IsBitset()) { 653 if (type1->IsBitset() && type2->IsBitset()) {
554 return BitsetType::New(type1->AsBitset() & type2->AsBitset(), region); 654 return BitsetType::New(type1->AsBitset() & type2->AsBitset(), region);
555 } 655 }
556 656
557 // Fast case: top or bottom types. 657 // Fast case: top or bottom types.
558 if (type1->IsNone() || type2->IsAny()) return type1; 658 if (type1->IsNone() || type2->IsAny()) return type1;
(...skipping 15 matching lines...)
574 } 674 }
575 int bitset = type1->BitsetGlb() & type2->BitsetGlb(); 675 int bitset = type1->BitsetGlb() & type2->BitsetGlb();
576 if (bitset != BitsetType::kNone) ++size; 676 if (bitset != BitsetType::kNone) ++size;
577 ASSERT(size >= 1); 677 ASSERT(size >= 1);
578 678
579 UnionHandle unioned = UnionType::New(size, region); 679 UnionHandle unioned = UnionType::New(size, region);
580 size = 0; 680 size = 0;
581 if (bitset != BitsetType::kNone) { 681 if (bitset != BitsetType::kNone) {
582 unioned->Set(size++, BitsetType::New(bitset, region)); 682 unioned->Set(size++, BitsetType::New(bitset, region));
583 } 683 }
584 size = ExtendIntersection(unioned, type1, type2, size); 684 size = ExtendUnion(unioned, size, type1, type2, true, region);
585 size = ExtendIntersection(unioned, type2, type1, size); 685 size = ExtendUnion(unioned, size, type2, type1, true, region);
586 686
587 if (size == 0) { 687 if (size == 0) {
588 return None(region); 688 return None(region);
589 } else if (size == 1) { 689 } else if (size == 1) {
590 return unioned->Get(0); 690 return unioned->Get(0);
591 } else { 691 } else {
592 unioned->Shrink(size); 692 unioned->Shrink(size);
693 ASSERT(unioned->Wellformed());
593 return unioned; 694 return unioned;
594 } 695 }
595 } 696 }
596 697
597 698
598 template<class Config> 699 template<class Config>
599 template<class OtherType> 700 template<class OtherType>
600 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Convert( 701 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Convert(
601 typename OtherType::TypeHandle type, Region* region) { 702 typename OtherType::TypeHandle type, Region* region) {
602 if (type->IsBitset()) { 703 if (type->IsBitset()) {
603 return BitsetType::New(type->AsBitset(), region); 704 return BitsetType::New(type->AsBitset(), region);
604 } else if (type->IsClass()) { 705 } else if (type->IsClass()) {
605 return ClassType::New(type->AsClass()->Map(), region); 706 return ClassType::New(
707 type->AsClass()->Map(),
708 BitsetType::New(type->BitsetLub(), region), region);
606 } else if (type->IsConstant()) { 709 } else if (type->IsConstant()) {
607 return ConstantType::New(type->AsConstant()->Value(), region); 710 return ConstantType::New(
711 type->AsConstant()->Value(),
712 Convert<OtherType>(type->AsConstant()->Bound(), region), region);
608 } else if (type->IsUnion()) { 713 } else if (type->IsUnion()) {
609 int length = type->AsUnion()->Length(); 714 int length = type->AsUnion()->Length();
610 UnionHandle unioned = UnionType::New(length, region); 715 UnionHandle unioned = UnionType::New(length, region);
611 for (int i = 0; i < length; ++i) { 716 for (int i = 0; i < length; ++i) {
612 unioned->Set(i, Convert<OtherType>(type->AsUnion()->Get(i), region)); 717 unioned->Set(i, Convert<OtherType>(type->AsUnion()->Get(i), region));
613 } 718 }
614 return unioned; 719 return unioned;
615 } else if (type->IsArray()) { 720 } else if (type->IsArray()) {
616 return ArrayType::New( 721 return ArrayType::New(
617 Convert<OtherType>(type->AsArray()->Element(), region), region); 722 Convert<OtherType>(type->AsArray()->Element(), region),
723 Convert<OtherType>(type->AsArray()->Bound(), region), region);
618 } else if (type->IsFunction()) { 724 } else if (type->IsFunction()) {
619 FunctionHandle function = FunctionType::New( 725 FunctionHandle function = FunctionType::New(
620 Convert<OtherType>(type->AsFunction()->Result(), region), 726 Convert<OtherType>(type->AsFunction()->Result(), region),
621 Convert<OtherType>(type->AsFunction()->Receiver(), region), 727 Convert<OtherType>(type->AsFunction()->Receiver(), region),
728 Convert<OtherType>(type->AsFunction()->Bound(), region),
622 type->AsFunction()->Arity(), region); 729 type->AsFunction()->Arity(), region);
623 for (int i = 0; i < function->Arity(); ++i) { 730 for (int i = 0; i < function->Arity(); ++i) {
624 function->InitParameter(i, 731 function->InitParameter(i,
625 Convert<OtherType>(type->AsFunction()->Parameter(i), region)); 732 Convert<OtherType>(type->AsFunction()->Parameter(i), region));
626 } 733 }
627 return function; 734 return function;
628 } else { 735 } else {
629 UNREACHABLE(); 736 UNREACHABLE();
630 return None(region); 737 return None(region);
631 } 738 }
(...skipping 140 matching lines...)
772 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; 879 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>;
773 880
774 template TypeImpl<ZoneTypeConfig>::TypeHandle 881 template TypeImpl<ZoneTypeConfig>::TypeHandle
775 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( 882 TypeImpl<ZoneTypeConfig>::Convert<HeapType>(
776 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); 883 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*);
777 template TypeImpl<HeapTypeConfig>::TypeHandle 884 template TypeImpl<HeapTypeConfig>::TypeHandle
778 TypeImpl<HeapTypeConfig>::Convert<Type>( 885 TypeImpl<HeapTypeConfig>::Convert<Type>(
779 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); 886 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*);
780 887
781 } } // namespace v8::internal 888 } } // namespace v8::internal
OLDNEW
« src/types.h ('K') | « src/types.h ('k') | src/types-inl.h » ('j') | no next file with comments »

Powered by Google App Engine