From 9abfab09fa28c4d90277c34c4d3d045f620ff11f Mon Sep 17 00:00:00 2001 From: "rossberg@chromium.org" Date: Tue, 11 Mar 2014 10:28:38 +0000 Subject: [PATCH] Types: cache lub bitset to avoid heap access R=verwaest@chromium.org BUG= Review URL: https://codereview.chromium.org/186743002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19786 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/types.cc | 10 +++++---- src/types.h | 54 ++++++++++++++++++++++++++++++----------------- test/cctest/test-types.cc | 4 ++-- 3 files changed, 43 insertions(+), 25 deletions(-) diff --git a/src/types.cc b/src/types.cc index 3840e6f..cf41bb5 100644 --- a/src/types.cc +++ b/src/types.cc @@ -141,9 +141,11 @@ int TypeImpl::LubBitset() { } return bitset; } else if (this->IsClass()) { - return LubBitset(*this->AsClass()); + int bitset = Config::lub_bitset(this); + return bitset ? bitset : LubBitset(*this->AsClass()); } else { - return LubBitset(*this->AsConstant()); + int bitset = Config::lub_bitset(this); + return bitset ? bitset : LubBitset(*this->AsConstant()); } } @@ -548,9 +550,9 @@ typename TypeImpl::TypeHandle TypeImpl::Convert( if (type->IsBitset()) { return Config::from_bitset(type->AsBitset(), region); } else if (type->IsClass()) { - return Config::from_class(type->AsClass(), region); + return Config::from_class(type->AsClass(), type->LubBitset(), region); } else if (type->IsConstant()) { - return Config::from_constant(type->AsConstant(), region); + return Config::from_constant(type->AsConstant(), type->LubBitset(), region); } else { ASSERT(type->IsUnion()); typename OtherType::UnionedHandle unioned = type->AsUnion(); diff --git a/src/types.h b/src/types.h index 48b3933..5d3585a 100644 --- a/src/types.h +++ b/src/types.h @@ -87,12 +87,17 @@ namespace internal { // Consequently, do not use pointer equality for type tests, always use Is! // // Internally, all 'primitive' types, and their unions, are represented as -// bitsets via smis. Class is a heap pointer to the respective map. Only -// Constant's, or unions containing Class'es or Constant's, require allocation. +// bitsets. Class is a heap pointer to the respective map. Only Constant's, or +// unions containing Class'es or Constant's, currently require allocation. // Note that the bitset representation is closed under both Union and Intersect. // -// The type representation is heap-allocated, so cannot (currently) be used in -// a concurrent compilation context. +// There are two type representations, using different allocation: +// +// - class Type (zone-allocated, for compiler and concurrent compilation) +// - class HeapType (heap-allocated, for persistent types) +// +// Both provide the same API, and the Convert method can be used to interconvert +// them. For zone types, no query method touches the heap, only constructors do. #define BITSET_TYPE_LIST(V) \ @@ -147,14 +152,15 @@ namespace internal { // static Handle::type as_union(Type*); // static Type* from_bitset(int bitset); // static Handle::type from_bitset(int bitset, Region*); -// static Handle::type from_class(i::Handle, Region*) -// static Handle::type from_constant(i::Handle, Region*); +// static Handle::type from_class(i::Handle, int lub, Region*); +// static Handle::type from_constant(i::Handle, int, Region*); // static Handle::type from_union(Handle::type); // static Handle::type union_create(int size, Region*); // static void union_shrink(Handle::type, int size); // static Handle::type union_get(Handle::type, int); // static void union_set(Handle::type, int, Handle::type); // static int union_length(Handle::type); +// static int lub_bitset(Type*); // } template class TypeImpl : public Config::Base { @@ -171,10 +177,10 @@ class TypeImpl : public Config::Base { #undef DEFINE_TYPE_CONSTRUCTOR static TypeHandle Class(i::Handle map, Region* region) { - return Config::from_class(map, region); + return Config::from_class(map, LubBitset(*map), region); } static TypeHandle Constant(i::Handle value, Region* region) { - return Config::from_constant(value, region); + return Config::from_constant(value, LubBitset(*value), region); } static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg); @@ -335,7 +341,7 @@ struct ZoneTypeConfig { } template static void tagged_set(Tagged* tagged, int i, T value) { - tagged->at(i + 1) = reinterpret_cast(value); + tagged->at(i + 1) = reinterpret_cast(value); } static int tagged_length(Tagged* tagged) { return tagged->length() - 1; @@ -375,11 +381,11 @@ struct ZoneTypeConfig { } static i::Handle as_class(Type* type) { ASSERT(is_class(type)); - return i::Handle(tagged_get(as_tagged(type), 0)); + return i::Handle(tagged_get(as_tagged(type), 1)); } static i::Handle as_constant(Type* type) { ASSERT(is_constant(type)); - return i::Handle(tagged_get(as_tagged(type), 0)); + return i::Handle(tagged_get(as_tagged(type), 1)); } static Unioned* as_union(Type* type) { ASSERT(is_union(type)); @@ -399,14 +405,16 @@ struct ZoneTypeConfig { static Type* from_tagged(Tagged* tagged) { return reinterpret_cast(tagged); } - static Type* from_class(i::Handle map, Zone* zone) { - Tagged* tagged = tagged_create(kClassTag, 1, zone); - tagged_set(tagged, 0, map.location()); + static Type* from_class(i::Handle map, int lub, Zone* zone) { + Tagged* tagged = tagged_create(kClassTag, 2, zone); + tagged_set(tagged, 0, lub); + tagged_set(tagged, 1, map.location()); return from_tagged(tagged); } - static Type* from_constant(i::Handle value, Zone* zone) { - Tagged* tagged = tagged_create(kConstantTag, 1, zone); - tagged_set(tagged, 0, value.location()); + static Type* from_constant(i::Handle value, int lub, Zone* zone) { + Tagged* tagged = tagged_create(kConstantTag, 2, zone); + tagged_set(tagged, 0, lub); + tagged_set(tagged, 1, value.location()); return from_tagged(tagged); } static Type* from_union(Unioned* unioned) { @@ -434,6 +442,10 @@ struct ZoneTypeConfig { static int union_length(Unioned* unioned) { return tagged_length(tagged_from_union(unioned)); } + static int lub_bitset(Type* type) { + ASSERT(is_class(type) || is_constant(type)); + return tagged_get(as_tagged(type), 0); + } }; @@ -475,11 +487,12 @@ struct HeapTypeConfig { static i::Handle from_bitset(int bitset, Isolate* isolate) { return i::handle(from_bitset(bitset), isolate); } - static i::Handle from_class(i::Handle map, Isolate* isolate) { + static i::Handle from_class( + i::Handle map, int lub, Isolate* isolate) { return i::Handle::cast(i::Handle::cast(map)); } static i::Handle from_constant( - i::Handle value, Isolate* isolate) { + i::Handle value, int lub, Isolate* isolate) { i::Handle box = isolate->factory()->NewBox(value); return i::Handle::cast(i::Handle::cast(box)); } @@ -506,6 +519,9 @@ struct HeapTypeConfig { static int union_length(i::Handle unioned) { return unioned->length(); } + static int lub_bitset(Type* type) { + return 0; // kNone, which causes recomputation. + } }; typedef TypeImpl Type; diff --git a/test/cctest/test-types.cc b/test/cctest/test-types.cc index d29ee41..57f0b27 100644 --- a/test/cctest/test-types.cc +++ b/test/cctest/test-types.cc @@ -190,10 +190,10 @@ struct ZoneRep { return static_cast(reinterpret_cast(t) >> 1); } static Map* AsClass(Type* t) { - return *reinterpret_cast(AsTagged(t)->at(1)); + return *reinterpret_cast(AsTagged(t)->at(2)); } static Object* AsConstant(Type* t) { - return *reinterpret_cast(AsTagged(t)->at(1)); + return *reinterpret_cast(AsTagged(t)->at(2)); } static ZoneList* AsUnion(Type* t) { return reinterpret_cast*>(AsTagged(t)); -- 2.7.4