Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(699)

Unified Diff: pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart

Issue 2818463002: Remove Compiler and JavaScriptBackend from interceptor_stub_generator. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
diff --git a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
index 6036711be963411c17086727877199f0a92447d9..7b8e1eb03fdb473f7f90123dd1c77707bd029c25 100644
--- a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
@@ -4,37 +4,62 @@
library dart2js.js_emitter.interceptor_stub_generator;
-import '../compiler.dart' show Compiler;
+import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames;
+
+import '../common_elements.dart';
import '../constants/values.dart';
import '../elements/entities.dart';
import '../elements/types.dart' show InterfaceType;
import '../js/js.dart' as jsAst;
import '../js/js.dart' show js;
-import '../js_backend/js_backend.dart'
- show
- CustomElementsCodegenAnalysis,
- JavaScriptBackend,
- JavaScriptConstantCompiler,
- Namer;
+import '../js_backend/namer.dart' show Namer;
+import '../js_backend/constant_handler_javascript.dart'
+ show JavaScriptConstantCompiler;
+import '../js_backend/custom_elements_analysis.dart'
+ show CustomElementsCodegenAnalysis;
+import '../js_backend/native_data.dart';
+import '../js_backend/interceptor_data.dart';
+import '../native/enqueue.dart';
+import '../options.dart';
import '../universe/selector.dart' show Selector;
+import '../universe/world_builder.dart' show CodegenWorldBuilder;
import '../world.dart' show ClosedWorld;
-import 'code_emitter_task.dart' show Emitter;
+import 'code_emitter_task.dart' show CodeEmitterTask, Emitter;
class InterceptorStubGenerator {
- final Compiler compiler;
- final Namer namer;
- final JavaScriptBackend backend;
- final ClosedWorld closedWorld;
+ final CompilerOptions _options;
+ final CommonElements _commonElements;
+ final CodeEmitterTask _emitterTask;
+ final NativeCodegenEnqueuer _nativeCodegenEnqueuer;
+ final JavaScriptConstantCompiler _constants;
+ final Namer _namer;
+ final NativeData _nativeData;
+ final InterceptorData _interceptorData;
+ final OneShotInterceptorData _oneShotInterceptorData;
+ final CustomElementsCodegenAnalysis _customElementsCodegenAnalysis;
+ final CodegenWorldBuilder _codegenWorldBuilder;
+ final ClosedWorld _closedWorld;
InterceptorStubGenerator(
- this.compiler, this.namer, this.backend, this.closedWorld);
-
- Emitter get emitter => backend.emitter.emitter;
+ this._options,
+ this._commonElements,
+ this._emitterTask,
+ this._nativeCodegenEnqueuer,
+ this._constants,
+ this._namer,
+ this._nativeData,
+ this._interceptorData,
+ this._oneShotInterceptorData,
+ this._customElementsCodegenAnalysis,
+ this._codegenWorldBuilder,
+ this._closedWorld);
+
+ Emitter get _emitter => _emitterTask.emitter;
jsAst.Expression generateGetInterceptorMethod(Set<ClassEntity> classes) {
jsAst.Expression interceptorFor(ClassEntity cls) {
- return backend.emitter.interceptorPrototypeAccess(cls);
+ return _emitterTask.interceptorPrototypeAccess(cls);
}
/**
@@ -43,21 +68,21 @@ class InterceptorStubGenerator {
*/
jsAst.Statement buildInterceptorCheck(ClassEntity cls) {
jsAst.Expression condition;
- assert(backend.interceptorData.isInterceptedClass(cls));
- if (cls == compiler.commonElements.jsBoolClass) {
+ assert(_interceptorData.isInterceptedClass(cls));
+ if (cls == _commonElements.jsBoolClass) {
condition = js('(typeof receiver) == "boolean"');
- } else if (cls == compiler.commonElements.jsIntClass ||
- cls == compiler.commonElements.jsDoubleClass ||
- cls == compiler.commonElements.jsNumberClass) {
+ } else if (cls == _commonElements.jsIntClass ||
+ cls == _commonElements.jsDoubleClass ||
+ cls == _commonElements.jsNumberClass) {
throw 'internal error';
- } else if (cls == compiler.commonElements.jsArrayClass ||
- cls == compiler.commonElements.jsMutableArrayClass ||
- cls == compiler.commonElements.jsFixedArrayClass ||
- cls == compiler.commonElements.jsExtendableArrayClass) {
+ } else if (cls == _commonElements.jsArrayClass ||
+ cls == _commonElements.jsMutableArrayClass ||
+ cls == _commonElements.jsFixedArrayClass ||
+ cls == _commonElements.jsExtendableArrayClass) {
condition = js('receiver.constructor == Array');
- } else if (cls == compiler.commonElements.jsStringClass) {
+ } else if (cls == _commonElements.jsStringClass) {
condition = js('(typeof receiver) == "string"');
- } else if (cls == compiler.commonElements.jsNullClass) {
+ } else if (cls == _commonElements.jsNullClass) {
condition = js('receiver == null');
} else {
throw 'internal error';
@@ -73,26 +98,25 @@ class InterceptorStubGenerator {
bool hasNumber = false;
bool hasString = false;
bool hasNative = false;
- bool anyNativeClasses =
- backend.nativeCodegenEnqueuer.hasInstantiatedNativeClasses;
+ bool anyNativeClasses = _nativeCodegenEnqueuer.hasInstantiatedNativeClasses;
for (ClassEntity cls in classes) {
- if (cls == compiler.commonElements.jsArrayClass ||
- cls == compiler.commonElements.jsMutableArrayClass ||
- cls == compiler.commonElements.jsFixedArrayClass ||
- cls == compiler.commonElements.jsExtendableArrayClass)
+ if (cls == _commonElements.jsArrayClass ||
+ cls == _commonElements.jsMutableArrayClass ||
+ cls == _commonElements.jsFixedArrayClass ||
+ cls == _commonElements.jsExtendableArrayClass)
hasArray = true;
- else if (cls == compiler.commonElements.jsBoolClass)
+ else if (cls == _commonElements.jsBoolClass)
hasBool = true;
- else if (cls == compiler.commonElements.jsDoubleClass)
+ else if (cls == _commonElements.jsDoubleClass)
hasDouble = true;
- else if (cls == compiler.commonElements.jsIntClass)
+ else if (cls == _commonElements.jsIntClass)
hasInt = true;
- else if (cls == compiler.commonElements.jsNullClass)
+ else if (cls == _commonElements.jsNullClass)
hasNull = true;
- else if (cls == compiler.commonElements.jsNumberClass)
+ else if (cls == _commonElements.jsNumberClass)
hasNumber = true;
- else if (cls == compiler.commonElements.jsStringClass)
+ else if (cls == _commonElements.jsStringClass)
hasString = true;
else {
// The set of classes includes classes mixed-in to interceptor classes
@@ -105,7 +129,7 @@ class InterceptorStubGenerator {
// unresolved PlainJavaScriptObject by testing for anyNativeClasses.
if (anyNativeClasses) {
- if (backend.nativeData.isNativeOrExtendsNative(cls)) hasNative = true;
+ if (_nativeData.isNativeOrExtendsNative(cls)) hasNative = true;
}
}
}
@@ -114,7 +138,7 @@ class InterceptorStubGenerator {
}
if (hasInt) hasNumber = true;
- if (classes.containsAll(backend.interceptorData.interceptedClasses)) {
+ if (classes.containsAll(_interceptorData.interceptedClasses)) {
// I.e. this is the general interceptor.
hasNative = anyNativeClasses;
}
@@ -129,8 +153,8 @@ class InterceptorStubGenerator {
/// is the fallback used when we have determined that receiver
/// is a JavaScript Number.
jsAst.Expression interceptorForNumber = interceptorFor(hasDouble
- ? compiler.commonElements.jsDoubleClass
- : compiler.commonElements.jsNumberClass);
+ ? _commonElements.jsDoubleClass
+ : _commonElements.jsNumberClass);
if (hasInt) {
whenNumber = js.statement(
@@ -138,10 +162,7 @@ class InterceptorStubGenerator {
if (Math.floor(receiver) == receiver) return #;
return #;
}''',
- [
- interceptorFor(compiler.commonElements.jsIntClass),
- interceptorForNumber
- ]);
+ [interceptorFor(_commonElements.jsIntClass), interceptorForNumber]);
} else {
whenNumber = js.statement('return #', interceptorForNumber);
}
@@ -150,12 +171,10 @@ class InterceptorStubGenerator {
}
if (hasString) {
- statements
- .add(buildInterceptorCheck(compiler.commonElements.jsStringClass));
+ statements.add(buildInterceptorCheck(_commonElements.jsStringClass));
}
if (hasNull) {
- statements
- .add(buildInterceptorCheck(compiler.commonElements.jsNullClass));
+ statements.add(buildInterceptorCheck(_commonElements.jsNullClass));
} else {
// Returning "undefined" or "null" here will provoke a JavaScript
// TypeError which is later identified as a null-error by
@@ -163,14 +182,12 @@ class InterceptorStubGenerator {
statements.add(js.statement('if (receiver == null) return receiver'));
}
if (hasBool) {
- statements
- .add(buildInterceptorCheck(compiler.commonElements.jsBoolClass));
+ statements.add(buildInterceptorCheck(_commonElements.jsBoolClass));
}
// TODO(ahe): It might be faster to check for Array before
// function and bool.
if (hasArray) {
- statements
- .add(buildInterceptorCheck(compiler.commonElements.jsArrayClass));
+ statements.add(buildInterceptorCheck(_commonElements.jsArrayClass));
}
if (hasNative) {
@@ -184,20 +201,17 @@ class InterceptorStubGenerator {
return #(receiver);
}''',
[
- interceptorFor(compiler.commonElements.jsJavaScriptFunctionClass),
- backend.emitter
- .constructorAccess(compiler.commonElements.objectClass),
- backend.emitter.staticFunctionAccess(
- compiler.commonElements.getNativeInterceptorMethod)
+ interceptorFor(_commonElements.jsJavaScriptFunctionClass),
+ _emitter.constructorAccess(_commonElements.objectClass),
+ _emitter.staticFunctionAccess(
+ _commonElements.getNativeInterceptorMethod)
]));
} else {
- ClassEntity jsUnknown =
- compiler.commonElements.jsUnknownJavaScriptObjectClass;
- if (compiler.codegenWorldBuilder.directlyInstantiatedClasses
+ ClassEntity jsUnknown = _commonElements.jsUnknownJavaScriptObjectClass;
+ if (_codegenWorldBuilder.directlyInstantiatedClasses
.contains(jsUnknown)) {
statements.add(js.statement('if (!(receiver instanceof #)) return #;', [
- backend.emitter
- .constructorAccess(compiler.commonElements.objectClass),
+ _emitter.constructorAccess(_commonElements.objectClass),
interceptorFor(jsUnknown)
]));
}
@@ -208,6 +222,24 @@ class InterceptorStubGenerator {
return js('''function(receiver) { #; }''', new jsAst.Block(statements));
}
+ jsAst.Call _generateIsJsIndexableCall(
+ jsAst.Expression use1, jsAst.Expression use2) {
+ String dispatchPropertyName = embeddedNames.DISPATCH_PROPERTY_NAME;
+ jsAst.Expression dispatchProperty =
+ _emitter.generateEmbeddedGlobalAccess(dispatchPropertyName);
+
+ // We pass the dispatch property record to the isJsIndexable
+ // helper rather than reading it inside the helper to increase the
+ // chance of making the dispatch record access monomorphic.
+ jsAst.PropertyAccess record =
+ new jsAst.PropertyAccess(use2, dispatchProperty);
+
+ List<jsAst.Expression> arguments = <jsAst.Expression>[use1, record];
+ FunctionEntity helper = _commonElements.isJsIndexable;
+ jsAst.Expression helperExpression = _emitter.staticFunctionAccess(helper);
+ return new jsAst.Call(helperExpression, arguments);
+ }
+
// Returns a statement that takes care of performance critical
// common case for a one-shot interceptor, or null if there is no
// fast path.
@@ -222,9 +254,9 @@ class InterceptorStubGenerator {
return a0 != null && receiver === a0;
}''');
}
- if (!classes.contains(compiler.commonElements.jsIntClass) &&
- !classes.contains(compiler.commonElements.jsNumberClass) &&
- !classes.contains(compiler.commonElements.jsDoubleClass)) {
+ if (!classes.contains(_commonElements.jsIntClass) &&
+ !classes.contains(_commonElements.jsNumberClass) &&
+ !classes.contains(_commonElements.jsDoubleClass)) {
return null;
}
if (selector.argumentCount == 1) {
@@ -271,21 +303,19 @@ class InterceptorStubGenerator {
// }
// }
// }
- bool containsArray =
- classes.contains(compiler.commonElements.jsArrayClass);
- bool containsString =
- classes.contains(compiler.commonElements.jsStringClass);
- bool containsJsIndexable = closedWorld.isImplemented(
- compiler.commonElements.jsIndexingBehaviorInterface) &&
+ bool containsArray = classes.contains(_commonElements.jsArrayClass);
+ bool containsString = classes.contains(_commonElements.jsStringClass);
+ bool containsJsIndexable = _closedWorld
+ .isImplemented(_commonElements.jsIndexingBehaviorInterface) &&
classes.any((cls) {
- return closedWorld.isSubtypeOf(
- cls, compiler.commonElements.jsIndexingBehaviorInterface);
+ return _closedWorld.isSubtypeOf(
+ cls, _commonElements.jsIndexingBehaviorInterface);
});
// The index set operator requires a check on its set value in
// checked mode, so we don't optimize the interceptor if the
- // compiler has type assertions enabled.
+ // _compiler has type assertions enabled.
if (selector.isIndexSet &&
- (compiler.options.enableTypeAssertions || !containsArray)) {
+ (_options.enableTypeAssertions || !containsArray)) {
return null;
}
if (!containsArray && !containsString) {
@@ -293,7 +323,7 @@ class InterceptorStubGenerator {
}
jsAst.Expression arrayCheck = js('receiver.constructor == Array');
jsAst.Expression indexableCheck =
- backend.generateIsJsIndexableCall(js('receiver'), js('receiver'));
+ _generateIsJsIndexableCall(js('receiver'), js('receiver'));
jsAst.Expression orExp(left, right) {
return left == null ? right : js('# || #', [left, right]);
@@ -346,10 +376,10 @@ class InterceptorStubGenerator {
jsAst.Expression generateOneShotInterceptor(jsAst.Name name) {
Selector selector =
- backend.oneShotInterceptorData.getOneShotInterceptorSelector(name);
+ _oneShotInterceptorData.getOneShotInterceptorSelector(name);
Set<ClassEntity> classes =
- backend.interceptorData.getInterceptedClassesOn(selector.name);
- jsAst.Name getInterceptorName = namer.nameForGetInterceptor(classes);
+ _interceptorData.getInterceptedClassesOn(selector.name);
+ jsAst.Name getInterceptorName = _namer.nameForGetInterceptor(classes);
List<String> parameterNames = <String>[];
parameterNames.add('receiver');
@@ -362,9 +392,9 @@ class InterceptorStubGenerator {
}
}
- jsAst.Name invocationName = backend.namer.invocationName(selector);
- String globalObject = namer
- .globalObjectForLibrary(compiler.commonElements.interceptorsLibrary);
+ jsAst.Name invocationName = _namer.invocationName(selector);
+ String globalObject =
+ _namer.globalObjectForLibrary(_commonElements.interceptorsLibrary);
jsAst.Statement optimizedPath =
_fastPathForOneShotInterceptor(selector, classes);
@@ -382,14 +412,12 @@ class InterceptorStubGenerator {
jsAst.ArrayInitializer generateTypeToInterceptorMap() {
// TODO(sra): Perhaps inject a constant instead?
- CustomElementsCodegenAnalysis analysis =
- backend.customElementsCodegenAnalysis;
+ CustomElementsCodegenAnalysis analysis = _customElementsCodegenAnalysis;
if (!analysis.needsTable) return null;
List<jsAst.Expression> elements = <jsAst.Expression>[];
- JavaScriptConstantCompiler handler = backend.constants;
List<ConstantValue> constants =
- handler.getConstantsForEmission(emitter.compareConstants);
+ _constants.getConstantsForEmission(_emitter.compareConstants);
for (ConstantValue constant in constants) {
if (constant is TypeConstantValue &&
constant.representedType is InterfaceType) {
@@ -397,8 +425,8 @@ class InterceptorStubGenerator {
ClassEntity classElement = type.element;
if (!analysis.needsClass(classElement)) continue;
- elements.add(emitter.constantReference(constant));
- elements.add(backend.emitter.interceptorClassAccess(classElement));
+ elements.add(_emitter.constantReference(constant));
+ elements.add(_emitter.interceptorClassAccess(classElement));
// Create JavaScript Object map for by-name lookup of generative
// constructors. For example, the class A has three generative
@@ -417,8 +445,8 @@ class InterceptorStubGenerator {
// We expect most of the time the map will be a singleton.
var properties = [];
for (ConstructorEntity member in analysis.constructors(classElement)) {
- properties.add(new jsAst.Property(js.string(member.name),
- backend.emitter.staticFunctionAccess(member)));
+ properties.add(new jsAst.Property(
+ js.string(member.name), _emitter.staticFunctionAccess(member)));
}
var map = new jsAst.ObjectInitializer(properties);

Powered by Google App Engine
This is Rietveld 408576698