Skip to content

Commit 0122901

Browse files
fishythefishcommit-bot@chromium.org
authored andcommitted
[dart2js] New RTI: Replace $ti._eval$1("1") with $ti._rest[0].
Change-Id: I518a92317f7b3168a02820ee0a5af132ce56568c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/119502 Reviewed-by: Stephen Adams <sra@google.com>
1 parent 9461df2 commit 0122901

File tree

2 files changed

+81
-49
lines changed

2 files changed

+81
-49
lines changed

pkg/compiler/lib/src/js_backend/runtime_types_new.dart

Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,6 @@ class _RecipeGenerator implements DartTypeVisitor<void, void> {
141141
final List<jsAst.Literal> _fragments = [];
142142
final List<int> _codes = [];
143143

144-
RuntimeTypesNeed get _rtiNeed => _encoder._rtiNeed;
145-
146144
_RecipeGenerator(
147145
this._encoder, this._emitter, this._environment, this._recipe,
148146
{this.metadata = false, this.hackTypeVariablesToAny = false});
@@ -260,26 +258,14 @@ class _RecipeGenerator implements DartTypeVisitor<void, void> {
260258
}
261259
}
262260
if (environment is FullTypeEnvironmentStructure) {
263-
int i = environment.bindings.indexOf(type);
264-
if (i >= 0) {
265-
// Indexes are 1-based since '0' encodes using the entire type for the
266-
// singleton structure.
267-
_emitInteger(i + 1);
268-
return;
269-
}
270-
271-
int index = _indexIntoClassTypeVariables(type);
261+
int index = indexTypeVariable(
262+
_closedWorld, _rtiSubstitutions, environment, type,
263+
metadata: metadata);
272264
if (index != null) {
273-
// We should only observe erased type arguments if we're generating
274-
// subtype metadata.
275-
assert(metadata ||
276-
_rtiNeed.classNeedsTypeArguments(environment.classType.element));
277-
278-
// Indexed class type variables come after the bound function type
279-
// variables.
280-
_emitInteger(1 + environment.bindings.length + index);
265+
_emitInteger(index);
281266
return;
282267
}
268+
283269
jsAst.Name name = _emitter.typeVariableAccessNewRti(type.element);
284270
_emitName(name);
285271
typeVariables.add(type);
@@ -290,35 +276,6 @@ class _RecipeGenerator implements DartTypeVisitor<void, void> {
290276
'`$type`'.codeUnits.forEach(_emitCode);
291277
}
292278

293-
int /*?*/ _indexIntoClassTypeVariables(TypeVariableType variable) {
294-
TypeVariableEntity element = variable.element;
295-
ClassEntity cls = element.typeDeclaration;
296-
297-
if (metadata) {
298-
TypeEnvironmentStructure environment = _environment;
299-
if (environment is FullTypeEnvironmentStructure) {
300-
if (identical(environment.classType.element, cls)) {
301-
return element.index;
302-
}
303-
}
304-
}
305-
306-
// TODO(sra): We might be in a context where the class type variable has an
307-
// index, even though in the general case it is not at a specific index.
308-
309-
ClassHierarchy classHierarchy = _closedWorld.classHierarchy;
310-
var test = mustCheckAllSubtypes(_closedWorld, cls)
311-
? classHierarchy.anyStrictSubtypeOf
312-
: classHierarchy.anyStrictSubclassOf;
313-
314-
if (test(cls, (ClassEntity subclass) {
315-
return !_rtiSubstitutions.isTrivialSubstitution(subclass, cls);
316-
})) {
317-
return null;
318-
}
319-
return element.index;
320-
}
321-
322279
@override
323280
void visitFunctionTypeVariable(FunctionTypeVariable type, _) {
324281
int position = functionTypeVariables.indexOf(type);
@@ -479,6 +436,49 @@ bool mustCheckAllSubtypes(JClosedWorld world, ClassEntity cls) =>
479436
world.isUsedAsMixin(cls) ||
480437
world.extractTypeArgumentsInterfacesNewRti.contains(cls);
481438

439+
int indexTypeVariable(
440+
JClosedWorld world,
441+
RuntimeTypesSubstitutions rtiSubstitutions,
442+
FullTypeEnvironmentStructure environment,
443+
TypeVariableType type,
444+
{bool metadata = false}) {
445+
int i = environment.bindings.indexOf(type);
446+
if (i >= 0) {
447+
// Indices are 1-based since '0' encodes using the entire type for the
448+
// singleton structure.
449+
return i + 1;
450+
}
451+
452+
TypeVariableEntity element = type.element;
453+
ClassEntity cls = element.typeDeclaration;
454+
455+
if (metadata) {
456+
if (identical(environment.classType.element, cls)) {
457+
// Indexed class type variables come after the bound function type
458+
// variables.
459+
return 1 + environment.bindings.length + element.index;
460+
}
461+
}
462+
463+
// TODO(sra): We might be in a context where the class type variable has an
464+
// index, even though in the general case it is not at a specific index.
465+
466+
ClassHierarchy classHierarchy = world.classHierarchy;
467+
var test = mustCheckAllSubtypes(world, cls)
468+
? classHierarchy.anyStrictSubtypeOf
469+
: classHierarchy.anyStrictSubclassOf;
470+
if (test(cls, (ClassEntity subclass) {
471+
return !rtiSubstitutions.isTrivialSubstitution(subclass, cls);
472+
})) {
473+
return null;
474+
}
475+
476+
assert(world.rtiNeed.classNeedsTypeArguments(environment.classType.element));
477+
// Indexed class type variables come after the bound function type
478+
// variables.
479+
return 1 + environment.bindings.length + element.index;
480+
}
481+
482482
class _RulesetEntry {
483483
Set<InterfaceType> _supertypes = {};
484484
Map<TypeVariableType, DartType> _typeVariables = {};

pkg/compiler/lib/src/ssa/codegen.dart

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@ import '../js_backend/namer.dart' show ModularNamer;
2828
import '../js_backend/runtime_types.dart';
2929
import '../js_backend/runtime_types_codegen.dart';
3030
import '../js_backend/runtime_types_new.dart'
31-
show RecipeEncoder, RecipeEncoding;
31+
show RecipeEncoder, RecipeEncoding, indexTypeVariable;
3232
import '../js_emitter/code_emitter_task.dart' show ModularEmitter;
3333
import '../js_model/elements.dart' show JGeneratorBody;
34+
import '../js_model/type_recipe.dart';
3435
import '../native/behavior.dart';
3536
import '../options.dart';
3637
import '../tracer.dart';
@@ -3472,6 +3473,37 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
34723473
// Call `env._eval("recipe")`.
34733474
use(node.inputs[0]);
34743475
js.Expression environment = pop();
3476+
3477+
// Instead of generating `env._eval("$n")`, generate appropriate field
3478+
// accesses where possible.
3479+
TypeEnvironmentStructure envStructure = node.envStructure;
3480+
TypeRecipe typeExpression = node.typeExpression;
3481+
if (envStructure is FullTypeEnvironmentStructure &&
3482+
typeExpression is TypeExpressionRecipe) {
3483+
if (typeExpression.type.isTypeVariable) {
3484+
TypeVariableType type = typeExpression.type;
3485+
int index = indexTypeVariable(
3486+
_closedWorld, _rtiSubstitutions, envStructure, type);
3487+
if (index != null) {
3488+
assert(index >= 1);
3489+
List<TypeVariableType> bindings = envStructure.bindings;
3490+
if (bindings.isNotEmpty) {
3491+
// If the environment is a binding RTI, we should never index past
3492+
// its length (i.e. into its base), since in that case, we could
3493+
// eval against the base directly.
3494+
assert(index <= bindings.length);
3495+
}
3496+
js.Expression access = js.js('#.#[#]', [
3497+
environment,
3498+
_namer.instanceFieldPropertyName(_commonElements.rtiRestField),
3499+
js.number(index - 1),
3500+
]);
3501+
push(access.withSourceInformation(node.sourceInformation));
3502+
return;
3503+
}
3504+
}
3505+
}
3506+
34753507
RecipeEncoding encoding = _rtiRecipeEncoder.encodeRecipe(
34763508
_emitter, node.envStructure, node.typeExpression);
34773509
js.Expression recipe = encoding.recipe;

0 commit comments

Comments
 (0)