| Index: pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
|
| diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
|
| index 193c3b274273fb5557deb88181fde550acc935b2..7f2c08457d9e147c9d47d2914aa0c26cf0d17b54 100644
|
| --- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
|
| +++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
|
| @@ -110,10 +110,7 @@ class Emitter implements js_emitter.Emitter {
|
| final InterceptorEmitter interceptorEmitter;
|
|
|
| // TODO(johnniwinther): Wrap these fields in a caching strategy.
|
| - final Set<ConstantValue> cachedEmittedConstants;
|
| final List<jsAst.Statement> cachedEmittedConstantsAst = <jsAst.Statement>[];
|
| - final Map<Element, ClassBuilder> cachedClassBuilders;
|
| - final Set<Element> cachedElements;
|
|
|
| bool needsClassSupport = false;
|
| bool needsMixinSupport = false;
|
| @@ -180,9 +177,6 @@ class Emitter implements js_emitter.Emitter {
|
| this.generateSourceMap, this.task)
|
| : this.compiler = compiler,
|
| this.namer = namer,
|
| - cachedEmittedConstants = compiler.cacheStrategy.newSet(),
|
| - cachedClassBuilders = compiler.cacheStrategy.newMap(),
|
| - cachedElements = compiler.cacheStrategy.newSet(),
|
| classEmitter = new ClassEmitter(closedWorld),
|
| interceptorEmitter = new InterceptorEmitter(closedWorld),
|
| nsmEmitter = new NsmEmitter(closedWorld) {
|
| @@ -192,14 +186,6 @@ class Emitter implements js_emitter.Emitter {
|
| classEmitter.emitter = this;
|
| nsmEmitter.emitter = this;
|
| interceptorEmitter.emitter = this;
|
| - if (compiler.options.hasIncrementalSupport) {
|
| - // Much like a scout, an incremental compiler is always prepared. For
|
| - // mixins, classes, and lazy statics, at least.
|
| - needsClassSupport = true;
|
| - needsMixinSupport = true;
|
| - needsLazyInitializer = true;
|
| - needsStructuredMemberInfo = true;
|
| - }
|
| }
|
|
|
| DiagnosticReporter get reporter => compiler.reporter;
|
| @@ -215,13 +201,6 @@ class Emitter implements js_emitter.Emitter {
|
| outputUnit, () => new List<jsAst.Expression>());
|
| }
|
|
|
| - /// Erases the precompiled information for csp mode for all output units.
|
| - /// Used by the incremental compiler.
|
| - void clearCspPrecompiledNodes() {
|
| - _cspPrecompiledFunctions.clear();
|
| - _cspPrecompiledConstructorNames.clear();
|
| - }
|
| -
|
| @override
|
| bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) {
|
| if (constant.isFunction) return true; // Already emitted.
|
| @@ -596,21 +575,7 @@ class Emitter implements js_emitter.Emitter {
|
| Class cls, ClassBuilder enclosingBuilder, Fragment fragment) {
|
| ClassElement classElement = cls.element;
|
| reporter.withCurrentElement(classElement, () {
|
| - if (compiler.options.hasIncrementalSupport) {
|
| - ClassBuilder cachedBuilder =
|
| - cachedClassBuilders.putIfAbsent(classElement, () {
|
| - ClassBuilder builder = new ClassBuilder.forClass(classElement, namer);
|
| - classEmitter.emitClass(cls, builder, fragment);
|
| - return builder;
|
| - });
|
| - invariant(classElement, cachedBuilder.fields.isEmpty);
|
| - invariant(classElement, cachedBuilder.superName == null);
|
| - invariant(classElement, cachedBuilder.functionType == null);
|
| - invariant(classElement, cachedBuilder.fieldMetadata == null);
|
| - enclosingBuilder.properties.addAll(cachedBuilder.properties);
|
| - } else {
|
| - classEmitter.emitClass(cls, enclosingBuilder, fragment);
|
| - }
|
| + classEmitter.emitClass(cls, enclosingBuilder, fragment);
|
| });
|
| }
|
|
|
| @@ -741,50 +706,6 @@ class Emitter implements js_emitter.Emitter {
|
| return laziesInfo;
|
| }
|
|
|
| - // TODO(sra): Remove this unused function.
|
| - jsAst.Expression buildLazilyInitializedStaticField(VariableElement element,
|
| - {String isolateProperties}) {
|
| - jsAst.Expression code = backend.generatedCode[element];
|
| - // The code is null if we ended up not needing the lazily
|
| - // initialized field after all because of constant folding
|
| - // before code generation.
|
| - if (code == null) return null;
|
| - // The code only computes the initial value. We build the lazy-check
|
| - // here:
|
| - // lazyInitializer(fieldName, getterName, initial, name, prototype);
|
| - // The name is used for error reporting. The 'initial' must be a
|
| - // closure that constructs the initial value.
|
| - if (isolateProperties != null) {
|
| - // This is currently only used in incremental compilation to patch
|
| - // in new lazy values.
|
| - return js('#(#,#,#,#,#)', [
|
| - js(lazyInitializerName),
|
| - js.quoteName(namer.globalPropertyName(element)),
|
| - js.quoteName(namer.lazyInitializerName(element)),
|
| - code,
|
| - js.string(element.name),
|
| - isolateProperties
|
| - ]);
|
| - }
|
| -
|
| - if (compiler.options.enableMinification) {
|
| - return js('#(#,#,#)', [
|
| - js(lazyInitializerName),
|
| - js.quoteName(namer.globalPropertyName(element)),
|
| - js.quoteName(namer.lazyInitializerName(element)),
|
| - code
|
| - ]);
|
| - } else {
|
| - return js('#(#,#,#,#)', [
|
| - js(lazyInitializerName),
|
| - js.quoteName(namer.globalPropertyName(element)),
|
| - js.quoteName(namer.lazyInitializerName(element)),
|
| - code,
|
| - js.string(element.name)
|
| - ]);
|
| - }
|
| - }
|
| -
|
| jsAst.Statement buildMetadata(Program program, OutputUnit outputUnit) {
|
| List<jsAst.Statement> parts = <jsAst.Statement>[];
|
|
|
| @@ -811,15 +732,8 @@ class Emitter implements js_emitter.Emitter {
|
|
|
| if (constants.isEmpty) return js.comment("No constants in program.");
|
| List<jsAst.Statement> parts = <jsAst.Statement>[];
|
| - if (compiler.options.hasIncrementalSupport && isMainFragment) {
|
| - parts = cachedEmittedConstantsAst;
|
| - }
|
| for (Constant constant in constants) {
|
| ConstantValue constantValue = constant.value;
|
| - if (compiler.options.hasIncrementalSupport && isMainFragment) {
|
| - if (cachedEmittedConstants.contains(constantValue)) continue;
|
| - cachedEmittedConstants.add(constantValue);
|
| - }
|
| parts.add(buildConstantInitializer(constantValue));
|
| }
|
|
|
| @@ -1017,10 +931,6 @@ class Emitter implements js_emitter.Emitter {
|
| }
|
| Isolate.#functionThatReturnsNullProperty =
|
| oldIsolate.#functionThatReturnsNullProperty;
|
| - if (#hasIncrementalSupport) {
|
| - Isolate.#lazyInitializerProperty =
|
| - oldIsolate.#lazyInitializerProperty;
|
| - }
|
| return Isolate;
|
| }
|
|
|
| @@ -1039,8 +949,6 @@ class Emitter implements js_emitter.Emitter {
|
| 'makeConstListProperty': makeConstListProperty,
|
| 'functionThatReturnsNullProperty':
|
| backend.rtiEncoder.getFunctionThatReturnsNullName,
|
| - 'hasIncrementalSupport': compiler.options.hasIncrementalSupport,
|
| - 'lazyInitializerProperty': lazyInitializerProperty,
|
| });
|
| }
|
|
|
| @@ -1088,40 +996,34 @@ class Emitter implements js_emitter.Emitter {
|
| jsAst.Statement buildSupportsDirectProtoAccess() {
|
| jsAst.Statement supportsDirectProtoAccess;
|
|
|
| - if (compiler.options.hasIncrementalSupport) {
|
| - supportsDirectProtoAccess = js.statement(r'''
|
| - var supportsDirectProtoAccess = false;
|
| - ''');
|
| - } else {
|
| - supportsDirectProtoAccess = js.statement(r'''
|
| - var supportsDirectProtoAccess = (function () {
|
| - var cls = function () {};
|
| - cls.prototype = {'p': {}};
|
| - var object = new cls();
|
| - if (!(object.__proto__ && object.__proto__.p === cls.prototype.p))
|
| - return false;
|
| -
|
| - try {
|
| - // Are we running on a platform where the performance is good?
|
| - // (i.e. Chrome or d8).
|
| -
|
| - // Chrome userAgent?
|
| - if (typeof navigator != "undefined" &&
|
| - typeof navigator.userAgent == "string" &&
|
| - navigator.userAgent.indexOf("Chrome/") >= 0) return true;
|
| -
|
| - // d8 version() looks like "N.N.N.N", jsshell version() like "N".
|
| - if (typeof version == "function" &&
|
| - version.length == 0) {
|
| - var v = version();
|
| - if (/^\d+\.\d+\.\d+\.\d+$/.test(v)) return true;
|
| - }
|
| - } catch(_) {}
|
| -
|
| + supportsDirectProtoAccess = js.statement(r'''
|
| + var supportsDirectProtoAccess = (function () {
|
| + var cls = function () {};
|
| + cls.prototype = {'p': {}};
|
| + var object = new cls();
|
| + if (!(object.__proto__ && object.__proto__.p === cls.prototype.p))
|
| return false;
|
| - })();
|
| - ''');
|
| - }
|
| +
|
| + try {
|
| + // Are we running on a platform where the performance is good?
|
| + // (i.e. Chrome or d8).
|
| +
|
| + // Chrome userAgent?
|
| + if (typeof navigator != "undefined" &&
|
| + typeof navigator.userAgent == "string" &&
|
| + navigator.userAgent.indexOf("Chrome/") >= 0) return true;
|
| +
|
| + // d8 version() looks like "N.N.N.N", jsshell version() like "N".
|
| + if (typeof version == "function" &&
|
| + version.length == 0) {
|
| + var v = version();
|
| + if (/^\d+\.\d+\.\d+\.\d+$/.test(v)) return true;
|
| + }
|
| + } catch(_) {}
|
| +
|
| + return false;
|
| + })();
|
| + ''');
|
|
|
| return supportsDirectProtoAccess;
|
| }
|
| @@ -1379,14 +1281,11 @@ class Emitter implements js_emitter.Emitter {
|
| }
|
|
|
| void checkEverythingEmitted(Iterable<Element> elements) {
|
| - List<Element> pendingStatics;
|
| - if (!compiler.options.hasIncrementalSupport) {
|
| - pendingStatics =
|
| - Elements.sortedByPosition(elements.where((e) => !e.isLibrary));
|
| + List<Element> pendingStatics =
|
| + Elements.sortedByPosition(elements.where((e) => !e.isLibrary));
|
|
|
| - pendingStatics.forEach((element) => reporter.reportInfo(
|
| - element, MessageKind.GENERIC, {'text': 'Pending statics.'}));
|
| - }
|
| + pendingStatics.forEach((element) => reporter.reportInfo(
|
| + element, MessageKind.GENERIC, {'text': 'Pending statics.'}));
|
|
|
| if (pendingStatics != null && !pendingStatics.isEmpty) {
|
| reporter.internalError(
|
| @@ -1465,8 +1364,7 @@ class Emitter implements js_emitter.Emitter {
|
| // The program builder does not collect libraries that only
|
| // contain typedefs that are used for reflection.
|
| for (LibraryElement element in remainingLibraries) {
|
| - assert(element is LibraryElement ||
|
| - compiler.options.hasIncrementalSupport);
|
| + assert(element is LibraryElement);
|
| if (element is LibraryElement) {
|
| parts.add(generateLibraryDescriptor(element, mainFragment));
|
| descriptors.remove(element);
|
| @@ -1486,19 +1384,6 @@ class Emitter implements js_emitter.Emitter {
|
| #disableVariableRenaming;
|
| #supportsDirectProtoAccess;
|
|
|
| - if (#hasIncrementalSupport) {
|
| - #helper = #helper || Object.create(null);
|
| - #helper.patch = function(a) { eval(a)};
|
| - #helper.schemaChange = #schemaChange;
|
| - #helper.addMethod = #addMethod;
|
| - #helper.extractStubs =
|
| - function(array, name, isStatic, originalDescriptor) {
|
| - var descriptor = Object.create(null);
|
| - this.addStubs(descriptor, array, name, isStatic, []);
|
| - return descriptor;
|
| - };
|
| - }
|
| -
|
| if (#isProgramSplit) {
|
| /// We collect all the global state, so it can be passed to the
|
| /// initializer of deferred files.
|
| @@ -1591,10 +1476,6 @@ class Emitter implements js_emitter.Emitter {
|
| """,
|
| {
|
| "disableVariableRenaming": js.comment("/* ::norenaming:: */"),
|
| - "hasIncrementalSupport": compiler.options.hasIncrementalSupport,
|
| - "helper": js('this.#', [namer.incrementalHelperName]),
|
| - "schemaChange": buildSchemaChangeFunction(),
|
| - "addMethod": buildIncrementalAddMethod(),
|
| "isProgramSplit": isProgramSplit,
|
| "supportsDirectProtoAccess": buildSupportsDirectProtoAccess(),
|
| "globalsHolder": globalsHolder,
|
| @@ -1670,123 +1551,6 @@ class Emitter implements js_emitter.Emitter {
|
| }
|
| }
|
|
|
| - /// Used by incremental compilation to patch up the prototype of
|
| - /// [oldConstructor] for use as prototype of [newConstructor].
|
| - jsAst.Fun buildSchemaChangeFunction() {
|
| - if (!compiler.options.hasIncrementalSupport) return null;
|
| - return js('''
|
| -function(newConstructor, oldConstructor, superclass) {
|
| - // Invariant: newConstructor.prototype has no interesting properties besides
|
| - // generated accessors. These are copied to oldPrototype which will be
|
| - // updated by other incremental changes.
|
| - if (superclass != null) {
|
| - this.inheritFrom(newConstructor, superclass);
|
| - }
|
| - var oldPrototype = oldConstructor.prototype;
|
| - var newPrototype = newConstructor.prototype;
|
| - var hasOwnProperty = Object.prototype.hasOwnProperty;
|
| - for (var property in newPrototype) {
|
| - if (hasOwnProperty.call(newPrototype, property)) {
|
| - // Copy generated accessors.
|
| - oldPrototype[property] = newPrototype[property];
|
| - }
|
| - }
|
| - oldPrototype.__proto__ = newConstructor.prototype.__proto__;
|
| - oldPrototype.constructor = newConstructor;
|
| - newConstructor.prototype = oldPrototype;
|
| - return newConstructor;
|
| -}''');
|
| - }
|
| -
|
| - /// Used by incremental compilation to patch up an object ([holder]) with a
|
| - /// new (or updated) method. [arrayOrFunction] is either the new method, or
|
| - /// an array containing the method (see
|
| - /// [ContainerBuilder.addMemberMethodFromInfo]). [name] is the name of the
|
| - /// new method. [isStatic] tells if method is static (or
|
| - /// top-level). [globalFunctionsAccess] is a reference to
|
| - /// [embeddedNames.GLOBAL_FUNCTIONS].
|
| - jsAst.Fun buildIncrementalAddMethod() {
|
| - if (!compiler.options.hasIncrementalSupport) return null;
|
| - return js(r"""
|
| -function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) {
|
| - var arrayOrFunction = originalDescriptor[name];
|
| - var method;
|
| - if (arrayOrFunction.constructor === Array) {
|
| - var existing = holder[name];
|
| - var array = arrayOrFunction;
|
| -
|
| - // Each method may have a number of stubs associated. For example, if an
|
| - // instance method supports multiple arguments, a stub for each matching
|
| - // selector. There is also a getter stub for tear-off getters. For example,
|
| - // an instance method foo([a]) may have the following stubs: foo$0, foo$1,
|
| - // and get$foo (here exemplified using unminified names).
|
| - // [extractStubs] returns a JavaScript object whose own properties
|
| - // corresponds to the stubs.
|
| - var descriptor =
|
| - this.extractStubs(array, name, isStatic, originalDescriptor);
|
| - method = descriptor[name];
|
| -
|
| - // Iterate through the properties of descriptor and copy the stubs to the
|
| - // existing holder (for instance methods, a prototype).
|
| - for (var property in descriptor) {
|
| - if (!Object.prototype.hasOwnProperty.call(descriptor, property)) continue;
|
| - var stub = descriptor[property];
|
| - var existingStub = holder[property];
|
| - if (stub === method || !existingStub || !stub.$getterStub) {
|
| - // Not replacing an existing getter stub.
|
| - holder[property] = stub;
|
| - continue;
|
| - }
|
| - if (!stub.$getterStub) {
|
| - var error = new Error('Unexpected stub.');
|
| - error.stub = stub;
|
| - throw error;
|
| - }
|
| -
|
| - // Existing getter stubs need special treatment as they may already have
|
| - // been called and produced a closure.
|
| - this.pendingStubs = this.pendingStubs || [];
|
| - // It isn't safe to invoke the stub yet.
|
| - this.pendingStubs.push((function(holder, stub, existingStub, existing,
|
| - method) {
|
| - return function() {
|
| - var receiver = isStatic ? holder : new holder.constructor();
|
| - // Invoke the existing stub to obtain the tear-off closure.
|
| - existingStub = existingStub.call(receiver);
|
| - // Invoke the new stub to create a tear-off closure we can use as a
|
| - // prototype.
|
| - stub = stub.call(receiver);
|
| -
|
| - // Copy the properties from the new tear-off's prototype to the
|
| - // prototype of the existing tear-off.
|
| - var newProto = stub.constructor.prototype;
|
| - var existingProto = existingStub.constructor.prototype;
|
| - for (var stubProperty in newProto) {
|
| - if (!Object.prototype.hasOwnProperty.call(newProto, stubProperty))
|
| - continue;
|
| - existingProto[stubProperty] = newProto[stubProperty];
|
| - }
|
| -
|
| - // Update all the existing stub's references to [existing] to
|
| - // [method]. Instance tear-offs are call-by-name, so this isn't
|
| - // necessary for those.
|
| - if (!isStatic) return;
|
| - for (var reference in existingStub) {
|
| - if (existingStub[reference] === existing) {
|
| - existingStub[reference] = method;
|
| - }
|
| - }
|
| - }
|
| - })(holder, stub, existingStub, existing, method));
|
| - }
|
| - } else {
|
| - method = arrayOrFunction;
|
| - holder[name] = method;
|
| - }
|
| - if (isStatic) globalFunctionsAccess[name] = method;
|
| -}""");
|
| - }
|
| -
|
| Map<OutputUnit, jsAst.Expression> buildDescriptorsForOutputUnits(
|
| Program program) {
|
| Map<OutputUnit, jsAst.Expression> outputs =
|
| @@ -2178,14 +1942,4 @@ function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) {
|
| ..add(const JsonEncoder.withIndent(" ").convert(mapping))
|
| ..close();
|
| }
|
| -
|
| - void invalidateCaches() {
|
| - if (!compiler.options.hasIncrementalSupport) return;
|
| - if (cachedElements.isEmpty) return;
|
| - for (Element element in backend.codegenEnqueuer.newlyEnqueuedElements) {
|
| - if (element.isInstanceMember) {
|
| - cachedClassBuilders.remove(element.enclosingClass);
|
| - }
|
| - }
|
| - }
|
| }
|
|
|