Skip to content

Commit

Permalink
[dart2js] Add redirections for unneeded native classes in ruleset.
Browse files Browse the repository at this point in the history
Change-Id: Ic29686447c87b7707480a161e76ab500c1455617
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/130011
Commit-Queue: Mayank Patke <fishythefish@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
  • Loading branch information
fishythefish authored and commit-bot@chromium.org committed Jan 3, 2020
1 parent a62e63f commit b5bf014
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 4 deletions.
4 changes: 2 additions & 2 deletions pkg/compiler/lib/src/js_backend/runtime_types_new.dart
Original file line number Diff line number Diff line change
Expand Up @@ -501,8 +501,8 @@ class Ruleset {
bool get isEmpty => _redirections.isEmpty && _entries.isEmpty;
bool get isNotEmpty => _redirections.isNotEmpty || _entries.isNotEmpty;

void addRedirection(ClassEntity targetClass, ClassEntity redirection) {
_redirections[targetClass] = redirection;
void addRedirection(ClassEntity redirectee, ClassEntity target) {
_redirections[redirectee] = target;
}

void addEntry(InterfaceType targetType, Iterable<InterfaceType> supertypes,
Expand Down
1 change: 1 addition & 0 deletions pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ class CodeEmitterTask extends CompilerTask {
closedWorld,
codegen.rtiEncoder,
codegen.rtiRecipeEncoder,
_nativeEmitter,
_backendStrategy.sourceInformationStrategy,
this,
_generateSourceMap);
Expand Down
5 changes: 5 additions & 0 deletions pkg/compiler/lib/src/js_emitter/model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

library dart2js.new_js_emitter.model;

import '../common_elements.dart';
import '../constants/values.dart' show ConstantValue;
import '../deferred_load.dart' show OutputUnit;
import '../elements/entities.dart';
Expand Down Expand Up @@ -315,6 +316,10 @@ class Class implements FieldContainer {

bool get isSimpleMixinApplication => false;

bool isTriviallyChecked(CommonElements commonElements) =>
classChecksNewRti.checks.every((TypeCheck check) =>
check.cls == commonElements.objectClass || check.cls == element);

Class get superclass => _superclass;

void setSuperclass(Class superclass) {
Expand Down
18 changes: 18 additions & 0 deletions pkg/compiler/lib/src/js_emitter/native_emitter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ class NativeEmitter {
// Caches the methods that have a native body.
Set<FunctionEntity> nativeMethods = new Set<FunctionEntity>();

// Type metadata redirections, where the key is the class being redirected to
// and the value is the list of classes being redirected.
final Map<Class, List<Class>> typeRedirections = {};

NativeEmitter(
this._emitterTask, this._closedWorld, this._nativeCodegenEnqueuer);

Expand Down Expand Up @@ -112,6 +116,7 @@ class NativeEmitter {
// Find which classes are needed and which are non-leaf classes. Any class
// that is not needed can be treated as a leaf class equivalent to some
// needed class.
// We may still need to include type metadata for some unneeded classes.

Set<Class> neededClasses = new Set<Class>();
Set<Class> nonLeafClasses = new Set<Class>();
Expand Down Expand Up @@ -152,6 +157,19 @@ class NativeEmitter {
neededClasses.add(cls);
neededClasses.add(cls.superclass);
nonLeafClasses.add(cls.superclass);
} else if (!cls.isTriviallyChecked(_commonElements) ||
cls.namedTypeVariablesNewRti.isNotEmpty) {
// The class is not marked 'needed', but we still need it in the type
// metadata.

// Redirect this class (and all classes which would have redirected to
// this class) to its superclass. Because we have a post-order visit,
// this eventually causes all such native classes to redirect to their
// leaf interceptors.
List<Class> redirectedClasses = typeRedirections[cls] ?? [];
redirectedClasses.add(cls);
typeRedirections[cls.superclass] = redirectedClasses;
typeRedirections.remove(cls);
}
}

Expand Down
4 changes: 4 additions & 0 deletions pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import '../../universe/codegen_world_builder.dart' show CodegenWorld;
import '../../world.dart' show JClosedWorld;
import '../js_emitter.dart' show Emitter, ModularEmitter;
import '../model.dart';
import '../native_emitter.dart';
import '../program_builder/program_builder.dart' show ProgramBuilder;
import 'model_emitter.dart';

Expand Down Expand Up @@ -152,6 +153,7 @@ class EmitterImpl extends ModularEmitterBase implements Emitter {
final RecipeEncoder _rtiRecipeEncoder;
final CompilerTask _task;
ModelEmitter _emitter;
final NativeEmitter _nativeEmitter;

@override
Program programForTesting;
Expand All @@ -165,6 +167,7 @@ class EmitterImpl extends ModularEmitterBase implements Emitter {
this._closedWorld,
this._rtiEncoder,
this._rtiRecipeEncoder,
this._nativeEmitter,
SourceInformationStrategy sourceInformationStrategy,
this._task,
bool shouldGenerateSourceMap)
Expand All @@ -178,6 +181,7 @@ class EmitterImpl extends ModularEmitterBase implements Emitter {
_closedWorld,
_task,
this,
_nativeEmitter,
sourceInformationStrategy,
_rtiEncoder,
_rtiRecipeEncoder,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,7 @@ class FragmentEmitter {
final Emitter _emitter;
final ConstantEmitter _constantEmitter;
final ModelEmitter _modelEmitter;
final NativeEmitter _nativeEmitter;
final JClosedWorld _closedWorld;
final CodegenWorld _codegenWorld;
RecipeEncoder _recipeEncoder;
Expand Down Expand Up @@ -622,6 +623,7 @@ class FragmentEmitter {
this._emitter,
this._constantEmitter,
this._modelEmitter,
this._nativeEmitter,
this._closedWorld,
this._codegenWorld) {
if (_options.experimentNewRti) {
Expand Down Expand Up @@ -1977,6 +1979,9 @@ class FragmentEmitter {
ClassEntity jsObjectClass = _commonElements.jsJavaScriptObjectClass;
InterfaceType jsObjectType = _elementEnvironment.getThisType(jsObjectClass);

Map<Class, List<Class>> nativeRedirections =
_nativeEmitter.typeRedirections;

Ruleset ruleset = Ruleset.empty();
Map<ClassEntity, int> erasedTypes = {};
Iterable<Class> classes =
Expand All @@ -1990,17 +1995,20 @@ class FragmentEmitter {
erasedTypes[element] = targetType.typeArguments.length;
}

if (cls.classChecksNewRti == null) return;
bool isInterop = _nativeData.isJsInteropClass(element);

Iterable<TypeCheck> checks = cls.classChecksNewRti.checks;
Iterable<TypeCheck> checks = cls.classChecksNewRti?.checks ?? [];
Iterable<InterfaceType> supertypes = isInterop
? checks
.map((check) => _elementEnvironment.getJsInteropType(check.cls))
: checks
.map((check) => _dartTypes.asInstanceOf(targetType, check.cls));

Map<TypeVariableType, DartType> typeVariables = {};
Set<TypeVariableType> namedTypeVariables = cls.namedTypeVariablesNewRti;
nativeRedirections[cls]?.forEach((Class redirectee) {
namedTypeVariables.addAll(redirectee.namedTypeVariablesNewRti);
});
for (TypeVariableType typeVariable in cls.namedTypeVariablesNewRti) {
TypeVariableEntity element = typeVariable.element;
InterfaceType supertype = isInterop
Expand All @@ -2026,6 +2034,12 @@ class FragmentEmitter {
});
}

nativeRedirections.forEach((Class target, List<Class> redirectees) {
for (Class redirectee in redirectees) {
ruleset.addRedirection(redirectee.element, target.element);
}
});

if (ruleset.isNotEmpty) {
FunctionEntity addRules = _closedWorld.commonElements.rtiAddRulesMethod;
statements.add(js.js.statement('#(init.#,JSON.parse(#));', [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import '../constant_ordering.dart' show ConstantOrdering;
import '../headers.dart';
import '../js_emitter.dart' show buildTearOffCode, NativeGenerator;
import '../model.dart';
import '../native_emitter.dart';

part 'fragment_emitter.dart';

Expand All @@ -81,6 +82,7 @@ class ModelEmitter {
final CompilerTask _task;
final Emitter _emitter;
ConstantEmitter _constantEmitter;
final NativeEmitter _nativeEmitter;
final bool _shouldGenerateSourceMap;
final JClosedWorld _closedWorld;
final ConstantOrdering _constantOrdering;
Expand Down Expand Up @@ -109,6 +111,7 @@ class ModelEmitter {
this._closedWorld,
this._task,
this._emitter,
this._nativeEmitter,
this._sourceInformationStrategy,
RuntimeTypesEncoder rtiEncoder,
RecipeEncoder rtiRecipeEncoder,
Expand Down Expand Up @@ -189,6 +192,7 @@ class ModelEmitter {
_emitter,
_constantEmitter,
this,
_nativeEmitter,
_closedWorld,
codegenWorld);

Expand Down

0 comments on commit b5bf014

Please sign in to comment.