Version 2.15.0-193.0.dev

Merge commit 'b9b1ea6b5dc94ab5275624c1db6b61d01b9408a3' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 187181e..38a93cf 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -1644,7 +1644,7 @@
   Token? abstractKeyword;
 
   /// The name of the superclass of the class being declared.
-  TypeNameImpl _superclass;
+  NamedTypeImpl _superclass;
 
   /// The with clause for this class.
   WithClauseImpl _withClause;
@@ -1711,14 +1711,14 @@
 
   @Deprecated('Use superclass2 instead')
   @override
-  TypeNameImpl get superclass => _superclass;
+  NamedTypeImpl get superclass => _superclass;
 
   set superclass(NamedType superclass) {
-    _superclass = _becomeParentOf(superclass as TypeNameImpl);
+    _superclass = _becomeParentOf(superclass as NamedTypeImpl);
   }
 
   @override
-  TypeNameImpl get superclass2 => _superclass;
+  NamedTypeImpl get superclass2 => _superclass;
 
   @override
   TypeParameterListImpl? get typeParameters => _typeParameters;
@@ -2594,7 +2594,7 @@
 ///        type ('.' identifier)?
 class ConstructorNameImpl extends AstNodeImpl implements ConstructorName {
   /// The name of the type defining the constructor.
-  TypeNameImpl _type;
+  NamedTypeImpl _type;
 
   /// The token for the period before the constructor name, or `null` if the
   /// specified constructor is the unnamed constructor.
@@ -2644,14 +2644,14 @@
 
   @Deprecated('Use type2 instead')
   @override
-  TypeNameImpl get type => _type;
+  NamedTypeImpl get type => _type;
 
   set type(NamedType type) {
-    _type = _becomeParentOf(type as TypeNameImpl);
+    _type = _becomeParentOf(type as NamedTypeImpl);
   }
 
   @override
-  TypeNameImpl get type2 => _type;
+  NamedTypeImpl get type2 => _type;
 
   @override
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitConstructorName(this);
@@ -3638,7 +3638,7 @@
   Token extendsKeyword;
 
   /// The name of the class that is being extended.
-  TypeNameImpl _superclass;
+  NamedTypeImpl _superclass;
 
   /// Initialize a newly created extends clause.
   ExtendsClauseImpl(this.extendsKeyword, this._superclass) {
@@ -3658,14 +3658,14 @@
 
   @Deprecated('Use superclass2 instead')
   @override
-  TypeNameImpl get superclass => _superclass;
+  NamedTypeImpl get superclass => _superclass;
 
   set superclass(NamedType name) {
-    _superclass = _becomeParentOf(name as TypeNameImpl);
+    _superclass = _becomeParentOf(name as NamedTypeImpl);
   }
 
   @override
-  TypeNameImpl get superclass2 => _superclass;
+  NamedTypeImpl get superclass2 => _superclass;
 
   @override
   E? accept<E>(AstVisitor<E> visitor) => visitor.visitExtendsClause(this);
@@ -7378,6 +7378,82 @@
   }
 }
 
+/// The name of a type, which can optionally include type arguments.
+///
+///    typeName ::=
+///        [Identifier] typeArguments? '?'?
+/// ignore: deprecated_member_use_from_same_package
+class NamedTypeImpl extends TypeAnnotationImpl implements TypeName {
+  /// The name of the type.
+  IdentifierImpl _name;
+
+  /// The type arguments associated with the type, or `null` if there are no
+  /// type arguments.
+  TypeArgumentListImpl? _typeArguments;
+
+  @override
+  Token? question;
+
+  /// The type being named, or `null` if the AST structure has not been
+  /// resolved, or if this is part of a [ConstructorReference].
+  @override
+  DartType? type;
+
+  /// Initialize a newly created type name. The [typeArguments] can be `null` if
+  /// there are no type arguments.
+  NamedTypeImpl(this._name, this._typeArguments, {this.question}) {
+    _becomeParentOf(_name);
+    _becomeParentOf(_typeArguments);
+  }
+
+  @override
+  Token get beginToken => _name.beginToken;
+
+  @override
+  Iterable<SyntacticEntity> get childEntities => ChildEntities()
+    ..add(_name)
+    ..add(_typeArguments)
+    ..add(question);
+
+  @override
+  Token get endToken => question ?? _typeArguments?.endToken ?? _name.endToken;
+
+  @override
+  bool get isDeferred {
+    Identifier identifier = name;
+    if (identifier is! PrefixedIdentifier) {
+      return false;
+    }
+    return identifier.isDeferred;
+  }
+
+  @override
+  bool get isSynthetic => _name.isSynthetic && _typeArguments == null;
+
+  @override
+  IdentifierImpl get name => _name;
+
+  set name(Identifier identifier) {
+    _name = _becomeParentOf(identifier as IdentifierImpl);
+  }
+
+  @override
+  TypeArgumentListImpl? get typeArguments => _typeArguments;
+
+  set typeArguments(TypeArgumentList? typeArguments) {
+    _typeArguments = _becomeParentOf(typeArguments as TypeArgumentListImpl?);
+  }
+
+  @override
+  E? accept<E>(AstVisitor<E> visitor) => visitor.visitNamedType(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _name.accept(visitor);
+    _typeArguments?.accept(visitor);
+  }
+}
+
 /// A node that represents a directive that impacts the namespace of a library.
 ///
 ///    directive ::=
@@ -10215,7 +10291,7 @@
 /// always be the type `Type`).  To see the type represented by the type literal
 /// use `.typeName.type`.
 class TypeLiteralImpl extends ExpressionImpl implements TypeLiteral {
-  TypeNameImpl _typeName;
+  NamedTypeImpl _typeName;
 
   TypeLiteralImpl(this._typeName) {
     _becomeParentOf(_typeName);
@@ -10237,13 +10313,13 @@
       : Precedence.postfix;
 
   @override
-  TypeNameImpl get type => _typeName;
+  NamedTypeImpl get type => _typeName;
 
   @Deprecated('Use namedType instead')
   @override
-  TypeNameImpl get typeName => _typeName;
+  NamedTypeImpl get typeName => _typeName;
 
-  set typeName(TypeNameImpl value) {
+  set typeName(NamedTypeImpl value) {
     _typeName = _becomeParentOf(value);
   }
 
@@ -10256,82 +10332,6 @@
   }
 }
 
-/// The name of a type, which can optionally include type arguments.
-///
-///    typeName ::=
-///        [Identifier] typeArguments? '?'?
-/// ignore: deprecated_member_use_from_same_package
-class TypeNameImpl extends TypeAnnotationImpl implements TypeName {
-  /// The name of the type.
-  IdentifierImpl _name;
-
-  /// The type arguments associated with the type, or `null` if there are no
-  /// type arguments.
-  TypeArgumentListImpl? _typeArguments;
-
-  @override
-  Token? question;
-
-  /// The type being named, or `null` if the AST structure has not been
-  /// resolved, or if this is part of a [ConstructorReference].
-  @override
-  DartType? type;
-
-  /// Initialize a newly created type name. The [typeArguments] can be `null` if
-  /// there are no type arguments.
-  TypeNameImpl(this._name, this._typeArguments, {this.question}) {
-    _becomeParentOf(_name);
-    _becomeParentOf(_typeArguments);
-  }
-
-  @override
-  Token get beginToken => _name.beginToken;
-
-  @override
-  Iterable<SyntacticEntity> get childEntities => ChildEntities()
-    ..add(_name)
-    ..add(_typeArguments)
-    ..add(question);
-
-  @override
-  Token get endToken => question ?? _typeArguments?.endToken ?? _name.endToken;
-
-  @override
-  bool get isDeferred {
-    Identifier identifier = name;
-    if (identifier is! PrefixedIdentifier) {
-      return false;
-    }
-    return identifier.isDeferred;
-  }
-
-  @override
-  bool get isSynthetic => _name.isSynthetic && _typeArguments == null;
-
-  @override
-  IdentifierImpl get name => _name;
-
-  set name(Identifier identifier) {
-    _name = _becomeParentOf(identifier as IdentifierImpl);
-  }
-
-  @override
-  TypeArgumentListImpl? get typeArguments => _typeArguments;
-
-  set typeArguments(TypeArgumentList? typeArguments) {
-    _typeArguments = _becomeParentOf(typeArguments as TypeArgumentListImpl?);
-  }
-
-  @override
-  E? accept<E>(AstVisitor<E> visitor) => visitor.visitNamedType(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _name.accept(visitor);
-    _typeArguments?.accept(visitor);
-  }
-}
-
 /// A type parameter.
 ///
 ///    typeParameter ::=
diff --git a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
index e12111d..0fcad99 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
@@ -197,7 +197,7 @@
           typeParameters as TypeParameterListImpl?,
           equals,
           abstractKeyword,
-          superclass as TypeNameImpl,
+          superclass as NamedTypeImpl,
           withClause as WithClauseImpl,
           implementsClause as ImplementsClauseImpl?,
           semicolon);
@@ -298,7 +298,7 @@
   ConstructorNameImpl constructorName(
           NamedType type, Token? period, SimpleIdentifier? name) =>
       ConstructorNameImpl(
-          type as TypeNameImpl, period, name as SimpleIdentifierImpl?);
+          type as NamedTypeImpl, period, name as SimpleIdentifierImpl?);
 
   @override
   ConstructorReferenceImpl constructorReference(
@@ -434,7 +434,7 @@
 
   @override
   ExtendsClauseImpl extendsClause(Token extendsKeyword, NamedType superclass) =>
-      ExtendsClauseImpl(extendsKeyword, superclass as TypeNameImpl);
+      ExtendsClauseImpl(extendsKeyword, superclass as NamedTypeImpl);
 
   @override
   ExtensionDeclarationImpl extensionDeclaration(
@@ -980,12 +980,12 @@
       NamedExpressionImpl(name as LabelImpl, expression as ExpressionImpl);
 
   @override
-  TypeNameImpl namedType({
+  NamedTypeImpl namedType({
     required Identifier name,
     TypeArgumentList? typeArguments,
     Token? question,
   }) =>
-      TypeNameImpl(
+      NamedTypeImpl(
           name as IdentifierImpl, typeArguments as TypeArgumentListImpl?,
           question: question);
 
@@ -1242,13 +1242,13 @@
 
   @override
   TypeLiteralImpl typeLiteral({required NamedType typeName}) =>
-      TypeLiteralImpl(typeName as TypeNameImpl);
+      TypeLiteralImpl(typeName as NamedTypeImpl);
 
   @Deprecated('Use namedType() instead')
   @override
-  TypeNameImpl typeName(Identifier name, TypeArgumentList? typeArguments,
+  NamedTypeImpl typeName(Identifier name, TypeArgumentList? typeArguments,
           {Token? question}) =>
-      TypeNameImpl(
+      NamedTypeImpl(
           name as IdentifierImpl, typeArguments as TypeArgumentListImpl?,
           question: question);
 
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 0a2871d..11c386e 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -2534,7 +2534,7 @@
   }
 
   @override
-  bool? visitNamedType(covariant TypeNameImpl node) {
+  bool? visitNamedType(covariant NamedTypeImpl node) {
     if (identical(node.name, _oldNode)) {
       node.name = _newNode as Identifier;
       return true;
@@ -2864,14 +2864,14 @@
   @override
   bool visitTypeLiteral(covariant TypeLiteralImpl node) {
     if (identical(node.type, _oldNode)) {
-      node.typeName = _newNode as TypeNameImpl;
+      node.typeName = _newNode as NamedTypeImpl;
       return true;
     }
     return visitNode(node);
   }
 
   @override
-  bool visitTypeName(covariant TypeNameImpl node) {
+  bool visitTypeName(covariant NamedTypeImpl node) {
     throw StateError('Should not be invoked');
   }
 
diff --git a/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart
index 9cf8cfd..969d189 100644
--- a/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart
@@ -74,7 +74,7 @@
   /// given [node] is resolved, all its children must be already resolved.
   ///
   /// The client must set [nameScope] before calling [resolve].
-  void resolve(TypeNameImpl node) {
+  void resolve(NamedTypeImpl node) {
     rewriteResult = null;
     hasErrorReported = false;
 
@@ -283,7 +283,7 @@
     }
   }
 
-  void _resolveToElement(TypeNameImpl node, Element? element) {
+  void _resolveToElement(NamedTypeImpl node, Element? element) {
     if (element == null) {
       node.type = dynamicType;
       if (!_libraryElement.shouldIgnoreUndefinedIdentifier(node.name)) {
@@ -306,7 +306,7 @@
   /// will be a [PrefixElement]. But when we resolved the `prefix` it turned
   /// out to be a [ClassElement], so it is probably a `Class.constructor`.
   void _rewriteToConstructorName(
-    TypeNameImpl node,
+    NamedTypeImpl node,
     PrefixedIdentifier typeIdentifier,
   ) {
     var constructorName = node.parent;
diff --git a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
index 1793675..0fb4f74 100644
--- a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
@@ -882,7 +882,7 @@
   }
 
   @override
-  void visitNamedType(covariant TypeNameImpl node) {
+  void visitNamedType(covariant NamedTypeImpl node) {
     node.typeArguments?.accept(this);
 
     _typeNameResolver.nameScope = _nameScope;
@@ -1256,7 +1256,7 @@
   /// The flag [asClass] specifies if the type will be used as a class, so mixin
   /// declarations are not valid (they declare interfaces and mixins, but not
   /// classes).
-  void _resolveType(TypeNameImpl namedType, ErrorCode errorCode,
+  void _resolveType(NamedTypeImpl namedType, ErrorCode errorCode,
       {bool asClass = false}) {
     _typeNameResolver.classHierarchy_namedType = namedType;
     visitNamedType(namedType);
@@ -1295,7 +1295,7 @@
   /// @return an array containing all of the types that were resolved.
   void _resolveTypes(NodeList<NamedType> namedTypes, ErrorCode errorCode) {
     for (var namedType in namedTypes) {
-      _resolveType(namedType as TypeNameImpl, errorCode);
+      _resolveType(namedType as NamedTypeImpl, errorCode);
     }
   }
 
@@ -1305,7 +1305,7 @@
     for (var namedType in clause.mixinTypes2) {
       _typeNameResolver.withClause_namedType = namedType;
       _resolveType(
-        namedType as TypeNameImpl,
+        namedType as NamedTypeImpl,
         CompileTimeErrorCode.MIXIN_OF_NON_CLASS,
       );
       _typeNameResolver.withClause_namedType = null;
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
index 6077d91..d722db43 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
@@ -1427,7 +1427,7 @@
   ///
   /// <b>Note:</b> This method does not correctly handle class elements that
   /// have type parameters.
-  static TypeNameImpl typeName(ClassElement element,
+  static NamedTypeImpl typeName(ClassElement element,
       [List<TypeAnnotation>? arguments]) {
     var name = identifier3(element.name);
     name.staticElement = element;
@@ -1442,14 +1442,14 @@
     return typeName;
   }
 
-  static TypeNameImpl typeName3(Identifier name,
+  static NamedTypeImpl typeName3(Identifier name,
           [List<TypeAnnotation>? arguments]) =>
       astFactory.namedType(
         name: name,
         typeArguments: typeArgumentList(arguments),
       );
 
-  static TypeNameImpl typeName4(String name,
+  static NamedTypeImpl typeName4(String name,
           [List<TypeAnnotation>? arguments, bool question = false]) =>
       astFactory.namedType(
         name: identifier3(name),
diff --git a/pkg/analyzer/lib/src/summary2/default_types_builder.dart b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
index 356de04..d565a18 100644
--- a/pkg/analyzer/lib/src/summary2/default_types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
@@ -91,7 +91,7 @@
         var boundNode = element.parameter.bound;
         if (boundNode is GenericFunctionTypeImpl) {
           boundNode.type = DynamicTypeImpl.instance;
-        } else if (boundNode is TypeNameImpl) {
+        } else if (boundNode is NamedTypeImpl) {
           boundNode.type = DynamicTypeImpl.instance;
         } else {
           throw UnimplementedError('(${boundNode.runtimeType}) $boundNode');
@@ -108,7 +108,7 @@
     for (var parameter in typeParameters) {
       parameter as TypeParameterImpl;
       var boundNode = parameter.bound;
-      if (boundNode is TypeNameImpl) {
+      if (boundNode is NamedTypeImpl) {
         if (typeParametersByName == null) {
           typeParametersByName = {};
           for (var parameterNode in typeParameters) {
diff --git a/pkg/analyzer/lib/src/summary2/named_type_builder.dart b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
index 5c3473b..e6cd97a 100644
--- a/pkg/analyzer/lib/src/summary2/named_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
@@ -40,7 +40,7 @@
   /// The node for which this builder is created, or `null` if the builder
   /// was detached from its node, e.g. during computing default types for
   /// type parameters.
-  final TypeNameImpl? node;
+  final NamedTypeImpl? node;
 
   /// The actual built type, not a [TypeBuilder] anymore.
   ///
@@ -55,7 +55,7 @@
   factory NamedTypeBuilder.of(
     Linker linker,
     TypeSystemImpl typeSystem,
-    TypeNameImpl node,
+    NamedTypeImpl node,
     Element element,
     NullabilitySuffix nullabilitySuffix,
   ) {
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index ef6c180..6e6cbe2 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -311,7 +311,7 @@
   }
 
   @override
-  void visitNamedType(covariant TypeNameImpl node) {
+  void visitNamedType(covariant NamedTypeImpl node) {
     var typeIdentifier = node.name;
 
     Element? element;
diff --git a/pkg/analyzer/lib/src/summary2/types_builder.dart b/pkg/analyzer/lib/src/summary2/types_builder.dart
index 48731a7..9887d9c 100644
--- a/pkg/analyzer/lib/src/summary2/types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/types_builder.dart
@@ -364,7 +364,7 @@
     if (withClause == null) return;
 
     for (var mixinNode in withClause.mixinTypes2) {
-      var mixinType = _inferSingle(mixinNode as TypeNameImpl);
+      var mixinType = _inferSingle(mixinNode as NamedTypeImpl);
       interfacesMerger.addWithSupertypes(mixinType);
     }
   }
@@ -400,7 +400,7 @@
     return result;
   }
 
-  InterfaceType _inferSingle(TypeNameImpl mixinNode) {
+  InterfaceType _inferSingle(NamedTypeImpl mixinNode) {
     var mixinType = _interfaceType(mixinNode.typeOrThrow);
 
     if (mixinNode.typeArguments != null) {
diff --git a/pkg/nnbd_migration/lib/src/fix_builder.dart b/pkg/nnbd_migration/lib/src/fix_builder.dart
index 7524133..5e57c8b 100644
--- a/pkg/nnbd_migration/lib/src/fix_builder.dart
+++ b/pkg/nnbd_migration/lib/src/fix_builder.dart
@@ -1231,7 +1231,7 @@
         _makeTypeNameNullable(node, decoratedType);
       }
     }
-    (node as TypeNameImpl).type =
+    (node as NamedTypeImpl).type =
         _fixBuilder._variables!.toFinalType(decoratedType);
     super.visitNamedType(node);
   }
diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc
index 7d35302..74a7257 100644
--- a/runtime/vm/compiler/backend/range_analysis.cc
+++ b/runtime/vm/compiler/backend/range_analysis.cc
@@ -642,8 +642,6 @@
   }
 
  private:
-  typedef DirectChainedHashMap<PointerKeyValueTrait<Instruction> > Map;
-
   Instruction* EmitRecursively(Instruction* instruction, Instruction* sink) {
     // Schedule all unscheduled inputs and unwrap all constrained inputs.
     for (intptr_t i = 0; i < instruction->InputCount(); i++) {
@@ -723,7 +721,7 @@
   }
 
   FlowGraph* flow_graph_;
-  Map map_;
+  PointerSet<Instruction> map_;
   const ZoneGrowableArray<BlockEntryInstr*>& loop_headers_;
   GrowableArray<BlockEntryInstr*> pre_headers_;
   GrowableArray<Instruction*> emitted_;
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index a704ac9..6f13e1f 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -46,9 +46,7 @@
   }
 
  private:
-  typedef DirectChainedHashMap<PointerKeyValueTrait<Instruction> > Map;
-
-  Map map_;
+  PointerSet<Instruction> map_;
 };
 
 // Place describes an abstract location (e.g. field) that IR can load
@@ -683,7 +681,7 @@
 class AliasedSet : public ZoneAllocated {
  public:
   AliasedSet(Zone* zone,
-             DirectChainedHashMap<PointerKeyValueTrait<Place> >* places_map,
+             PointerSet<Place>* places_map,
              ZoneGrowableArray<Place*>* places,
              PhiPlaceMoves* phi_moves)
       : zone_(zone),
@@ -1179,7 +1177,7 @@
 
   Zone* zone_;
 
-  DirectChainedHashMap<PointerKeyValueTrait<Place> >* places_map_;
+  PointerSet<Place>* places_map_;
 
   const ZoneGrowableArray<Place*>& places_;
 
@@ -1188,7 +1186,7 @@
   // A list of all seen aliases and a map that allows looking up canonical
   // alias object.
   GrowableArray<const Place*> aliases_;
-  DirectChainedHashMap<PointerKeyValueTrait<const Place> > aliases_map_;
+  PointerSet<const Place> aliases_map_;
 
   SmallSet<Place::ElementSize> typed_data_access_sizes_;
 
@@ -1244,9 +1242,8 @@
 // corresponding to phi input are numbered and record outgoing phi moves
 // for each block which establish correspondence between phi dependent place
 // and phi input's place that is flowing in.
-static PhiPlaceMoves* ComputePhiMoves(
-    DirectChainedHashMap<PointerKeyValueTrait<Place> >* map,
-    ZoneGrowableArray<Place*>* places) {
+static PhiPlaceMoves* ComputePhiMoves(PointerSet<Place>* map,
+                                      ZoneGrowableArray<Place*>* places) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   PhiPlaceMoves* phi_moves = new (zone) PhiPlaceMoves();
@@ -1300,10 +1297,9 @@
 
 enum CSEMode { kOptimizeLoads, kOptimizeStores };
 
-static AliasedSet* NumberPlaces(
-    FlowGraph* graph,
-    DirectChainedHashMap<PointerKeyValueTrait<Place> >* map,
-    CSEMode mode) {
+static AliasedSet* NumberPlaces(FlowGraph* graph,
+                                PointerSet<Place>* map,
+                                CSEMode mode) {
   // Loads representing different expression ids will be collected and
   // used to build per offset kill sets.
   Zone* zone = graph->zone();
@@ -1735,7 +1731,7 @@
       return false;
     }
 
-    DirectChainedHashMap<PointerKeyValueTrait<Place> > map;
+    PointerSet<Place> map;
     AliasedSet* aliased_set = NumberPlaces(graph, &map, kOptimizeLoads);
     if ((aliased_set != NULL) && !aliased_set->IsEmpty()) {
       // If any loads were forwarded return true from Optimize to run load
@@ -2774,7 +2770,7 @@
   }
 
   FlowGraph* graph_;
-  DirectChainedHashMap<PointerKeyValueTrait<Place> >* map_;
+  PointerSet<Place>* map_;
 
   // Mapping between field offsets in words and expression ids of loads from
   // that offset.
@@ -2866,7 +2862,7 @@
  public:
   StoreOptimizer(FlowGraph* graph,
                  AliasedSet* aliased_set,
-                 DirectChainedHashMap<PointerKeyValueTrait<Place> >* map)
+                 PointerSet<Place>* map)
       : LivenessAnalysis(aliased_set->max_place_id(), graph->postorder()),
         graph_(graph),
         map_(map),
@@ -2887,7 +2883,7 @@
       return;
     }
 
-    DirectChainedHashMap<PointerKeyValueTrait<Place> > map;
+    PointerSet<Place> map;
     AliasedSet* aliased_set = NumberPlaces(graph, &map, kOptimizeStores);
     if ((aliased_set != NULL) && !aliased_set->IsEmpty()) {
       StoreOptimizer store_optimizer(graph, aliased_set, &map);
@@ -3048,7 +3044,7 @@
   }
 
   FlowGraph* graph_;
-  DirectChainedHashMap<PointerKeyValueTrait<Place> >* map_;
+  PointerSet<Place>* map_;
 
   // Mapping between field offsets in words and expression ids of loads from
   // that offset.
diff --git a/runtime/vm/compiler/backend/slot.cc b/runtime/vm/compiler/backend/slot.cc
index 15f0080..b4b9920 100644
--- a/runtime/vm/compiler/backend/slot.cc
+++ b/runtime/vm/compiler/backend/slot.cc
@@ -43,7 +43,7 @@
       : zone_(thread->zone()), fields_(thread->zone()) {}
 
   Zone* const zone_;
-  DirectChainedHashMap<PointerKeyValueTrait<const Slot> > fields_;
+  PointerSet<const Slot> fields_;
 };
 
 #define NATIVE_SLOT_NAME(C, F) Kind::k##C##_##F
diff --git a/runtime/vm/hash_map.h b/runtime/vm/hash_map.h
index e1f1be9..2c816a6 100644
--- a/runtime/vm/hash_map.h
+++ b/runtime/vm/hash_map.h
@@ -359,22 +359,22 @@
 };
 
 template <typename T>
-class PointerKeyValueTrait {
+class PointerSetKeyValueTrait {
  public:
   typedef T* Value;
   typedef T* Key;
   typedef T* Pair;
 
   static Key KeyOf(Pair kv) { return kv; }
-
   static Value ValueOf(Pair kv) { return kv; }
-
   static inline uword Hash(Key key) { return key->Hash(); }
-
   static inline bool IsKeyEqual(Pair kv, Key key) { return kv->Equals(*key); }
 };
 
 template <typename T>
+using PointerSet = DirectChainedHashMap<PointerSetKeyValueTrait<T>>;
+
+template <typename T>
 class NumbersKeyValueTrait {
  public:
   typedef T Value;
@@ -408,12 +408,14 @@
   static bool IsKeyEqual(Pair kv, Key key) { return kv.key == key; }
 };
 
-class CStringSetKeyValueTrait : public PointerKeyValueTrait<const char> {
+class CStringSetKeyValueTrait {
  public:
-  using Key = PointerKeyValueTrait<const char>::Key;
-  using Value = PointerKeyValueTrait<const char>::Value;
-  using Pair = PointerKeyValueTrait<const char>::Pair;
+  using Key = const char*;
+  using Value = const char*;
+  using Pair = const char*;
 
+  static Key KeyOf(Pair kv) { return kv; }
+  static Value ValueOf(Pair kv) { return kv; }
   static uword Hash(Key key) {
     ASSERT(key != nullptr);
     return Utils::StringHash(key, strlen(key));
diff --git a/runtime/vm/hash_map_test.cc b/runtime/vm/hash_map_test.cc
index 52fc97a..014de42 100644
--- a/runtime/vm/hash_map_test.cc
+++ b/runtime/vm/hash_map_test.cc
@@ -19,7 +19,7 @@
 };
 
 TEST_CASE(DirectChainedHashMap) {
-  DirectChainedHashMap<PointerKeyValueTrait<TestValue> > map;
+  DirectChainedHashMap<PointerSetKeyValueTrait<TestValue>> map;
   EXPECT(map.IsEmpty());
   TestValue v1(0);
   TestValue v2(1);
@@ -33,14 +33,14 @@
   EXPECT(map.Remove(&v1));
   EXPECT(map.Lookup(&v1) == NULL);
   map.Insert(&v1);
-  DirectChainedHashMap<PointerKeyValueTrait<TestValue> > map2(map);
+  DirectChainedHashMap<PointerSetKeyValueTrait<TestValue>> map2(map);
   EXPECT(map2.LookupValue(&v1) == &v1);
   EXPECT(map2.LookupValue(&v2) == &v2);
   EXPECT(map2.LookupValue(&v3) == &v1);
 }
 
 TEST_CASE(DirectChainedHashMapInsertRemove) {
-  DirectChainedHashMap<PointerKeyValueTrait<TestValue> > map;
+  DirectChainedHashMap<PointerSetKeyValueTrait<TestValue>> map;
   EXPECT(map.IsEmpty());
   TestValue v1(1);
   TestValue v2(3);  // Note: v1, v2, v3 should have the same hash.
@@ -97,7 +97,7 @@
 }
 
 TEST_CASE(MallocDirectChainedHashMap) {
-  MallocDirectChainedHashMap<PointerKeyValueTrait<TestValue> > map;
+  MallocDirectChainedHashMap<PointerSetKeyValueTrait<TestValue>> map;
   EXPECT(map.IsEmpty());
   TestValue v1(0);
   TestValue v2(1);
@@ -108,7 +108,7 @@
   EXPECT(map.LookupValue(&v1) == &v1);
   EXPECT(map.LookupValue(&v2) == &v2);
   EXPECT(map.LookupValue(&v3) == &v1);
-  MallocDirectChainedHashMap<PointerKeyValueTrait<TestValue> > map2(map);
+  MallocDirectChainedHashMap<PointerSetKeyValueTrait<TestValue>> map2(map);
   EXPECT(map2.LookupValue(&v1) == &v1);
   EXPECT(map2.LookupValue(&v2) == &v2);
   EXPECT(map2.LookupValue(&v3) == &v1);
@@ -117,7 +117,7 @@
 TEST_CASE(ZoneDirectChainedHashMap) {
   auto zone = thread->zone();
   auto const map = new (zone)
-      ZoneDirectChainedHashMap<PointerKeyValueTrait<TestValue>>(zone);
+      ZoneDirectChainedHashMap<PointerSetKeyValueTrait<TestValue>>(zone);
   EXPECT(map->IsEmpty());
   TestValue v1(0);
   TestValue v2(1);
diff --git a/runtime/vm/program_visitor.cc b/runtime/vm/program_visitor.cc
index 0a07b1e..977592d 100644
--- a/runtime/vm/program_visitor.cc
+++ b/runtime/vm/program_visitor.cc
@@ -646,7 +646,7 @@
   class NormalizeAndDedupCompressedStackMapsVisitor
       : public CodeVisitor,
         public Dedupper<CompressedStackMaps,
-                        PointerKeyValueTrait<const CompressedStackMaps>> {
+                        PointerSetKeyValueTrait<const CompressedStackMaps>> {
    public:
     NormalizeAndDedupCompressedStackMapsVisitor(Zone* zone,
                                                 IsolateGroup* isolate_group)
diff --git a/tools/VERSION b/tools/VERSION
index 47e078c..b02aebf 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 15
 PATCH 0
-PRERELEASE 192
+PRERELEASE 193
 PRERELEASE_PATCH 0
\ No newline at end of file