Files
sdk/pkg/vm/test/bytecode/object_table_test.dart
T
Alexander Markov 59e00e69be [vm,bytecode] Fix canonicalization of type arguments of recursive types
Previously, it was possible that type arguments of recursive types are
shared between unrelated recursive types if they have exactly the same shape
(e.g. Foo extends Base<Foo> and Bar extends Base<Bar> both have
type arguments <recursive-ref#0>).

Fixes ffi/structs_test in AOT+bytecode mode.

Change-Id: I516bc34c3b5797d76e1bf087ac3c8f075f1b6424
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/120380
Reviewed-by: Régis Crelier <regis@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
2019-10-06 16:50:42 +00:00

120 lines
4.5 KiB
Dart

// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart' show CoreTypes;
import 'package:kernel/testing/mock_sdk_component.dart';
import 'package:test/test.dart';
import 'package:expect/expect.dart';
import 'package:vm/bytecode/object_table.dart';
main() {
Library lib1;
Library lib2;
CoreTypes coreTypes;
Supertype objectSupertype;
ObjectTable objectTable;
Class addClass(Library lib, String name,
[List<TypeParameter> typeParameters = const []]) {
Class cls = new Class(
name: name, supertype: objectSupertype, typeParameters: typeParameters);
cls.parent = lib;
lib.addClass(cls);
return cls;
}
setUp(() {
// Start with mock SDK libraries.
Component component = createMockSdkComponent();
coreTypes = new CoreTypes(component);
objectSupertype = coreTypes.objectClass.asThisSupertype;
// Add test libraries.
lib1 = new Library(Uri.parse('org-dartlang:///test1.dart'), name: 'lib1');
lib1.parent = component;
component.libraries.add(lib1);
lib2 = new Library(Uri.parse('org-dartlang:///test2.dart'), name: 'lib2');
lib2.parent = component;
component.libraries.add(lib2);
objectTable = new ObjectTable();
});
tearDown(() {});
test('libraries', () {
final h1 = objectTable.getHandle(lib1);
final h2 = objectTable.getHandle(lib2);
Expect.notEquals(h1, h2);
Expect.identical(h1, objectTable.getHandle(lib1));
Expect.identical(h2, objectTable.getHandle(lib2));
Expect.equals(true, h1.isCacheable);
Expect.equals(true, h2.isCacheable);
Expect.equals(false, h1.shouldBeIncludedIntoIndexTable); // 2 uses
Expect.identical(h1, objectTable.getHandle(lib1));
Expect.equals(true, h1.shouldBeIncludedIntoIndexTable); // 3 uses
});
test('classes', () {
final Class c1 = addClass(lib1, 'A');
final Class c2 = addClass(lib1, 'B');
final Class c3 = addClass(lib2, 'A');
final h1 = objectTable.getHandle(c1);
final h2 = objectTable.getHandle(c2);
final h3 = objectTable.getHandle(c3);
Expect.notEquals(h1, h2);
Expect.notEquals(h1, h3);
Expect.notEquals(h2, h3);
Expect.identical(h1, objectTable.getHandle(c1));
Expect.identical(h2, objectTable.getHandle(c2));
Expect.identical(h3, objectTable.getHandle(c3));
Expect.equals(true, h1.isCacheable);
Expect.equals(true, h2.isCacheable);
Expect.equals(true, h3.isCacheable);
final lib1h = objectTable.getHandle(lib1);
final lib2h = objectTable.getHandle(lib2);
Expect.equals(true, lib1h.shouldBeIncludedIntoIndexTable); // 3 uses
Expect.equals(false, lib2h.shouldBeIncludedIntoIndexTable); // 2 uses
});
test('simple-types', () {
final h1a = objectTable.getHandle(new InterfaceType(coreTypes.intClass));
final h1b = objectTable.getHandle(new InterfaceType(coreTypes.intClass));
final h2a = objectTable.getHandle(const DynamicType());
final h2b = objectTable.getHandle(new DynamicType());
Expect.identical(h1a, h1b);
Expect.identical(h2a, h2b);
Expect.notEquals(h1a, h2a);
Expect.equals(true, h1a.isCacheable);
Expect.equals(true, h2a.isCacheable);
Expect.equals(false, h1a.shouldBeIncludedIntoIndexTable); // 2 uses
objectTable.getHandle(new InterfaceType(
coreTypes.listClass, [new InterfaceType(coreTypes.intClass)]));
Expect.equals(true, h1a.shouldBeIncludedIntoIndexTable); // 3 uses
});
test('recursive-types', () {
final base = addClass(lib1, "Base", [new TypeParameter("T")]);
final derived1 = addClass(lib1, "Derived");
derived1.supertype = new Supertype(base, [new InterfaceType(derived1)]);
final derived2 = addClass(lib2, "Derived");
derived2.supertype = new Supertype(base, [new InterfaceType(derived2)]);
final h1a = objectTable.getHandle(new InterfaceType(derived1));
final h1b = objectTable.getHandle(new InterfaceType(derived1));
final h2a = objectTable.getHandle(new InterfaceType(derived2));
final h2b = objectTable.getHandle(new InterfaceType(derived2));
Expect.identical(h1a, h1b);
Expect.identical(h2a, h2b);
Expect.notEquals(h1a, h2a);
Expect.equals(true, h1a.isCacheable);
Expect.equals(true, h2a.isCacheable);
final typeArgs1 = (h1a as dynamic).typeArgs;
final typeArgs2 = (h2a as dynamic).typeArgs;
Expect.equals(false, typeArgs1.isCacheable);
Expect.equals(false, typeArgs2.isCacheable);
});
}