[vm] Cleanup the ability to specify entry points via JSON and text files

Entry points files (both JSON and text) are replaced with
@pragma("vm:entry-point") annotations.

This change removes obsolete:
* --embedder_entry_points_manifest option in gen_snapshot;
* --entry-points option in gen_kernel and frontend_server;
* --print_precompiler_entry_points VM option;
* 'entry_points' argument in Dart_Precompile() API.

Change-Id: I503f50f51df27e8e9635388c013058686b3b6ff1
Reviewed-on: https://dart-review.googlesource.com/75793
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
diff --git a/pkg/vm/bin/gen_kernel.dart b/pkg/vm/bin/gen_kernel.dart
index e15b46a..50d244a 100644
--- a/pkg/vm/bin/gen_kernel.dart
+++ b/pkg/vm/bin/gen_kernel.dart
@@ -44,8 +44,6 @@
   ..addFlag('enable-constant-evaluation',
       help: 'Whether kernel constant evaluation will be enabled.',
       defaultsTo: true)
-  ..addMultiOption('entry-points',
-      help: 'Path to JSON file with the list of entry points')
   ..addFlag('gen-bytecode', help: 'Generate bytecode', defaultsTo: false)
   ..addFlag('drop-ast',
       help: 'Drop AST for members with bytecode', defaultsTo: false);
@@ -95,8 +93,6 @@
     return _badUsageExitCode;
   }
 
-  final List<String> entryPoints = options['entry-points'] ?? <String>[];
-
   final errorPrinter = new ErrorPrinter();
   final errorDetector = new ErrorDetector(previousErrorHandler: errorPrinter);
 
@@ -118,7 +114,6 @@
       Uri.base.resolveUri(inputUri), compilerOptions,
       aot: aot,
       useGlobalTypeFlowAnalysis: tfa,
-      entryPoints: entryPoints,
       environmentDefines: environmentDefines,
       genBytecode: genBytecode,
       dropAST: dropAST,
diff --git a/pkg/vm/lib/frontend_server.dart b/pkg/vm/lib/frontend_server.dart
index f8ea33f..418ce4b 100644
--- a/pkg/vm/lib/frontend_server.dart
+++ b/pkg/vm/lib/frontend_server.dart
@@ -56,8 +56,6 @@
       help:
           'Enable global type flow analysis and related transformations in AOT mode.',
       defaultsTo: false)
-  ..addMultiOption('entry-points',
-      help: 'Path to JSON file with the list of entry points')
   ..addFlag('link-platform',
       help:
           'When in batch mode, link platform kernel file into result kernel file.'
@@ -349,7 +347,6 @@
           _mainSource, compilerOptions,
           aot: options['aot'],
           useGlobalTypeFlowAnalysis: options['tfa'],
-          entryPoints: options['entry-points'],
           environmentDefines: environmentDefines));
     }
     if (component != null) {
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 48b8330..941890e 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -45,7 +45,6 @@
 Future<Component> compileToKernel(Uri source, CompilerOptions options,
     {bool aot: false,
     bool useGlobalTypeFlowAnalysis: false,
-    List<String> entryPoints,
     Map<String, String> environmentDefines,
     bool genBytecode: false,
     bool dropAST: false,
@@ -66,7 +65,6 @@
         component,
         options.strongMode,
         useGlobalTypeFlowAnalysis,
-        entryPoints,
         environmentDefines,
         enableAsserts,
         enableConstantEvaluation,
@@ -94,7 +92,6 @@
     Component component,
     bool strongMode,
     bool useGlobalTypeFlowAnalysis,
-    List<String> entryPoints,
     Map<String, String> environmentDefines,
     bool enableAsserts,
     bool enableConstantEvaluation,
@@ -122,7 +119,7 @@
 
     if (useGlobalTypeFlowAnalysis) {
       globalTypeFlow.transformComponent(
-          compilerOptions.target, coreTypes, component, entryPoints);
+          compilerOptions.target, coreTypes, component);
     } else {
       devirtualization.transformComponent(coreTypes, component);
     }
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index d11f83c..ee93bf3 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -1191,7 +1191,7 @@
 
   TypeFlowAnalysis(this.target, Component component, CoreTypes coreTypes,
       ClosedWorldClassHierarchy hierarchy, this.environment, this.libraryIndex,
-      {List<String> entryPointsJSONFiles, PragmaAnnotationParser matcher})
+      {PragmaAnnotationParser matcher})
       : annotationMatcher =
             matcher ?? new ConstantPragmaAnnotationParser(coreTypes) {
     nativeCodeOracle = new NativeCodeOracle(libraryIndex, annotationMatcher);
@@ -1201,10 +1201,6 @@
     _invocationsCache = new _InvocationsCache(this);
     workList = new _WorkList(this);
 
-    if (entryPointsJSONFiles != null) {
-      nativeCodeOracle.processEntryPointsJSONFiles(entryPointsJSONFiles, this);
-    }
-
     component.accept(new PragmaEntryPointsVisitor(
         this, nativeCodeOracle, annotationMatcher));
   }
diff --git a/pkg/vm/lib/transformations/type_flow/native_code.dart b/pkg/vm/lib/transformations/type_flow/native_code.dart
index 2c38d28..6d6fe93 100644
--- a/pkg/vm/lib/transformations/type_flow/native_code.dart
+++ b/pkg/vm/lib/transformations/type_flow/native_code.dart
@@ -5,9 +5,7 @@
 /// Handling of native code and entry points.
 library vm.transformations.type_flow.native_code;
 
-import 'dart:convert' show json;
 import 'dart:core' hide Type;
-import 'dart:io' show File;
 
 import 'package:kernel/ast.dart';
 import 'package:kernel/core_types.dart' show CoreTypes;
@@ -281,20 +279,4 @@
       return new Type.fromStatic(member.function.returnType);
     }
   }
-
-  /// Reads JSON files [jsonFiles] describing entry points and native methods.
-  /// Currently just checks that JSON file is empty as it is deprecated.
-  void processEntryPointsJSONFiles(
-      List<String> jsonFiles, EntryPointsListener entryPointsListener) {
-    for (var file in jsonFiles) {
-      String jsonString = new File(file).readAsStringSync();
-      final jsonObject = json.decode(jsonString);
-
-      final roots = jsonObject['roots'];
-      if (roots != null && roots.isNotEmpty) {
-        throw "Error: Found non-empty entry points JSON file $file."
-            " Use the @pragma('vm:entry-point') annotation instead.";
-      }
-    }
-  }
 }
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index fcfd575..6233e44 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -32,8 +32,8 @@
 
 /// Whole-program type flow analysis and transformation.
 /// Assumes strong mode and closed world.
-Component transformComponent(Target target, CoreTypes coreTypes,
-    Component component, List<String> entryPoints,
+Component transformComponent(
+    Target target, CoreTypes coreTypes, Component component,
     [PragmaAnnotationParser matcher]) {
   void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
   final hierarchy = new ClassHierarchy(component,
@@ -52,7 +52,7 @@
 
   final typeFlowAnalysis = new TypeFlowAnalysis(
       target, component, coreTypes, hierarchy, types, libraryIndex,
-      entryPointsJSONFiles: entryPoints, matcher: matcher);
+      matcher: matcher);
 
   Procedure main = component.mainMethod;
   final Selector mainSelector = new DirectSelector(main);
diff --git a/pkg/vm/test/transformations/type_flow/transformer_test.dart b/pkg/vm/test/transformations/type_flow/transformer_test.dart
index 3f8da8d..ccd5956 100644
--- a/pkg/vm/test/transformations/type_flow/transformer_test.dart
+++ b/pkg/vm/test/transformations/type_flow/transformer_test.dart
@@ -24,7 +24,7 @@
 
   final coreTypes = new CoreTypes(component);
 
-  component = transformComponent(target, coreTypes, component, [],
+  component = transformComponent(target, coreTypes, component,
       new ExpressionPragmaAnnotationParser(coreTypes));
 
   final actual = kernelLibraryToString(component.mainMethod.enclosingLibrary);
diff --git a/runtime/bin/dart_io_entries.txt b/runtime/bin/dart_io_entries.txt
deleted file mode 100644
index b0f5fe4..0000000
--- a/runtime/bin/dart_io_entries.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (c) 2016, 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.
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 1a93dd0..690cf4d 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -81,10 +81,6 @@
 // of a generic snapshot that contains only the corelibs).
 static char* app_script_name = NULL;
 
-// Global state that captures the entry point manifest files specified on the
-// command line.
-static CommandLineOptions* entry_points_files = NULL;
-
 // The environment provided through the command line using -D options.
 static dart::SimpleHashMap* environment = NULL;
 
@@ -138,8 +134,12 @@
 #undef BOOL_OPTION_DEFINITION
 
 DEFINE_ENUM_OPTION(snapshot_kind, SnapshotKind, snapshot_kind);
-DEFINE_STRING_OPTION_CB(embedder_entry_points_manifest,
-                        { entry_points_files->AddArgument(value); });
+DEFINE_STRING_OPTION_CB(embedder_entry_points_manifest, {
+  Log::PrintErr(
+      "Option --embedder_entry_points_manifest is no longer supported."
+      " Use @pragma(\'vm:entry-point\') instead.\n");
+  exit(kErrorExitCode);
+});
 DEFINE_STRING_OPTION_CB(url_mapping,
                         { DartUtils::url_mapping->AddArgument(value); });
 DEFINE_CB_OPTION(ProcessEnvironmentOption);
@@ -203,7 +203,6 @@
 "--vm_snapshot_instructions=<output-file>                                    \n"
 "--isolate_snapshot_data=<output-file>                                       \n"
 "--isolate_snapshot_instructions=<output-file>                               \n"
-"{--embedder_entry_points_manifest=<input-file>}                             \n"
 "[--obfuscate]                                                               \n"
 "[--save-obfuscation-map=<map-filename>]                                     \n"
 " <dart-script-file>                                                         \n"
@@ -212,22 +211,10 @@
 "as a static or dynamic library:                                             \n"
 "--snapshot_kind=app-aot-assembly                                            \n"
 "--assembly=<output-file>                                                    \n"
-"{--embedder_entry_points_manifest=<input-file>}                             \n"
 "[--obfuscate]                                                               \n"
 "[--save-obfuscation-map=<map-filename>]                                     \n"
 "<dart-script-file>                                                          \n"
 "                                                                            \n"
-"AOT snapshots require entry points manifest files, which list the places    \n"
-"in the Dart program the embedder calls from the C API (Dart_Invoke, etc).   \n"
-"Not specifying these may cause the tree shaker to remove them from the      \n"
-"program. The format of this manifest is as follows. Each line in the        \n"
-"manifest is a comma separated list of three elements. The first entry is    \n"
-"the library URI, the second entry is the class name and the final entry     \n"
-"the function name. The file must be terminated with a newline character.    \n"
-"                                                                            \n"
-"Example:                                                                    \n"
-"    dart:something,SomeClass,doSomething                                    \n"
-"                                                                            \n"
 "AOT snapshots can be obfuscated: that is all identifiers will be renamed    \n"
 "during compilation. This mode is enabled with --obfuscate flag. Mapping     \n"
 "between original and obfuscated names can be serialized as a JSON array     \n"
@@ -776,300 +763,6 @@
   return lib;
 }
 
-static void LoadEntryPoint(size_t lib_index,
-                           const Dart_QualifiedFunctionName* entry) {
-  if (strcmp(entry->library_uri, "::") == 0) {
-    return;  // Root library always loaded; can't `import '::';`.
-  }
-
-  Dart_Handle library_string = Dart_NewStringFromCString(entry->library_uri);
-  DART_CHECK_VALID(library_string);
-  Dart_Handle library = Dart_LookupLibrary(library_string);
-  // Embedder entry points may be setup in libraries that have not been
-  // explicitly loaded by the application script. In such cases, library lookup
-  // will fail. Manually load those libraries.
-  if (Dart_IsError(library)) {
-    static const uint32_t kLoadBufferMaxSize = 128;
-    char* load_buffer =
-        reinterpret_cast<char*>(calloc(kLoadBufferMaxSize, sizeof(char)));
-    snprintf(load_buffer, kLoadBufferMaxSize, "import '%s';",
-             DartUtils::GetStringValue(library_string));
-    Dart_Handle script_handle = Dart_NewStringFromCString(load_buffer);
-    memset(load_buffer, 0, kLoadBufferMaxSize);
-    snprintf(load_buffer, kLoadBufferMaxSize, "dart:_snapshot_%zu", lib_index);
-    Dart_Handle script_url = Dart_NewStringFromCString(load_buffer);
-    free(load_buffer);
-    Dart_Handle loaded =
-        Dart_LoadLibrary(script_url, Dart_Null(), script_handle, 0, 0);
-    DART_CHECK_VALID(loaded);
-
-    // Do a fresh lookup
-    library = Dart_LookupLibrary(library_string);
-  }
-
-  DART_CHECK_VALID(library);
-}
-
-static void ImportNativeEntryPointLibrariesIntoRoot(
-    const Dart_QualifiedFunctionName* entries) {
-  if (entries == NULL) {
-    return;
-  }
-
-  size_t index = 0;
-  while (true) {
-    Dart_QualifiedFunctionName entry = entries[index++];
-    if (entry.library_uri == NULL) {
-      // The termination sentinel has null members.
-      break;
-    }
-    if (strcmp(entry.library_uri, "::") != 0) {
-      Dart_Handle entry_library =
-          Dart_LookupLibrary(Dart_NewStringFromCString(entry.library_uri));
-      DART_CHECK_VALID(entry_library);
-      Dart_Handle import_result = Dart_LibraryImportLibrary(
-          entry_library, Dart_RootLibrary(), Dart_EmptyString());
-      DART_CHECK_VALID(import_result);
-    }
-  }
-}
-
-static void LoadEntryPoints(const Dart_QualifiedFunctionName* entries) {
-  if (entries == NULL) {
-    return;
-  }
-
-  // Setup native resolvers for all libraries found in the manifest.
-  size_t index = 0;
-  while (true) {
-    Dart_QualifiedFunctionName entry = entries[index++];
-    if (entry.library_uri == NULL) {
-      // The termination sentinel has null members.
-      break;
-    }
-    // Ensure library named in entry point is loaded.
-    LoadEntryPoint(index, &entry);
-  }
-}
-
-static void CleanupEntryPointItem(const Dart_QualifiedFunctionName* entry) {
-  if (entry == NULL) {
-    return;
-  }
-  // The allocation used for these entries is zero'ed. So even in error cases,
-  // references to some entries will be null. Calling this on an already cleaned
-  // up entry is programmer error.
-  free(const_cast<char*>(entry->library_uri));
-  free(const_cast<char*>(entry->class_name));
-  free(const_cast<char*>(entry->function_name));
-}
-
-static void CleanupEntryPointsCollection(Dart_QualifiedFunctionName* entries) {
-  if (entries == NULL) {
-    return;
-  }
-
-  size_t index = 0;
-  while (true) {
-    Dart_QualifiedFunctionName entry = entries[index++];
-    if (entry.library_uri == NULL) {
-      break;
-    }
-    CleanupEntryPointItem(&entry);
-  }
-  free(entries);
-}
-
-char* ParserErrorStringCreate(const char* format, ...) {
-  static const size_t kErrorBufferSize = 256;
-
-  char* error_buffer =
-      reinterpret_cast<char*>(calloc(kErrorBufferSize, sizeof(char)));
-  va_list args;
-  va_start(args, format);
-  vsnprintf(error_buffer, kErrorBufferSize, format, args);
-  va_end(args);
-
-  // In case of error, the buffer is released by the caller
-  return error_buffer;
-}
-
-const char* ParseEntryNameForIndex(uint8_t index) {
-  switch (index) {
-    case 0:
-      return "Library";
-    case 1:
-      return "Class";
-    case 2:
-      return "Function";
-    default:
-      return "Unknown";
-  }
-  return NULL;
-}
-
-static bool ParseEntryPointsManifestSingleLine(
-    const char* line,
-    Dart_QualifiedFunctionName* entry,
-    char** error) {
-  bool success = true;
-  size_t offset = 0;
-  for (uint8_t i = 0; i < 3; i++) {
-    const char* component = strchr(line + offset, i == 2 ? '\n' : ',');
-    if (component == NULL) {
-      success = false;
-      *error = ParserErrorStringCreate(
-          "Manifest entries must be comma separated and newline terminated. "
-          "Could not parse '%s' on line '%s'",
-          ParseEntryNameForIndex(i), line);
-      break;
-    }
-
-    int64_t chars_read = component - (line + offset);
-    if (chars_read <= 0) {
-      success = false;
-      *error =
-          ParserErrorStringCreate("There is no '%s' specified on line '%s'",
-                                  ParseEntryNameForIndex(i), line);
-      break;
-    }
-
-    if (entry != NULL) {
-      // These allocations are collected in |CleanupEntryPointsCollection|.
-      char* entry_item =
-          reinterpret_cast<char*>(calloc(chars_read + 1, sizeof(char)));
-      memmove(entry_item, line + offset, chars_read);
-
-      switch (i) {
-        case 0:  // library
-          entry->library_uri = entry_item;
-          break;
-        case 1:  // class
-          entry->class_name = entry_item;
-          break;
-        case 2:  // function
-          entry->function_name = entry_item;
-          break;
-        default:
-          free(entry_item);
-          success = false;
-          *error = ParserErrorStringCreate("Internal parser error\n");
-          break;
-      }
-    }
-
-    offset += chars_read + 1;
-  }
-  return success;
-}
-
-int64_t ParseEntryPointsManifestLines(FILE* file,
-                                      Dart_QualifiedFunctionName* collection) {
-  int64_t entries = 0;
-
-  static const int kManifestMaxLineLength = 1024;
-  char* line = reinterpret_cast<char*>(malloc(kManifestMaxLineLength));
-  size_t line_number = 0;
-  while (true) {
-    line_number++;
-    char* read_line = fgets(line, kManifestMaxLineLength, file);
-
-    if (read_line == NULL) {
-      if ((feof(file) != 0) && (ferror(file) != 0)) {
-        Log::PrintErr(
-            "Error while reading line number %zu. The manifest must be "
-            "terminated by a newline\n",
-            line_number);
-        entries = -1;
-      }
-      break;
-    }
-
-    if ((read_line[0] == '\n') || (read_line[0] == '#')) {
-      // Blank or comment line.
-      continue;
-    }
-
-    Dart_QualifiedFunctionName* entry =
-        collection != NULL ? collection + entries : NULL;
-
-    char* error_buffer = NULL;
-    if (!ParseEntryPointsManifestSingleLine(read_line, entry, &error_buffer)) {
-      CleanupEntryPointItem(entry);
-      Log::PrintErr("Parser error on line %zu: %s\n", line_number,
-                    error_buffer);
-      free(error_buffer);
-      entries = -1;
-      break;
-    }
-
-    entries++;
-  }
-
-  free(line);
-
-  return entries;
-}
-
-static Dart_QualifiedFunctionName* ParseEntryPointsManifestFiles() {
-  // Total number of entries across all manifest files.
-  int64_t entry_count = 0;
-
-  // Parse the files once but don't store the results. This is done to first
-  // determine the number of entries in the manifest
-  for (intptr_t i = 0; i < entry_points_files->count(); i++) {
-    const char* path = entry_points_files->GetArgument(i);
-
-    FILE* file = fopen(path, "r");
-
-    if (file == NULL) {
-      Log::PrintErr("Could not open entry points manifest file `%s`\n", path);
-      return NULL;
-    }
-
-    int64_t entries = ParseEntryPointsManifestLines(file, NULL);
-    fclose(file);
-
-    if (entries < 0) {
-      Log::PrintErr("Manifest file `%s` specified is invalid\n", path);
-      return NULL;
-    }
-
-    entry_count += entries;
-  }
-
-  // Allocate enough storage for the entries in the file plus a termination
-  // sentinel and parse it again to populate the allocation
-  Dart_QualifiedFunctionName* entries =
-      reinterpret_cast<Dart_QualifiedFunctionName*>(
-          calloc(entry_count + 1, sizeof(Dart_QualifiedFunctionName)));
-
-  int64_t parsed_entry_count = 0;
-  for (intptr_t i = 0; i < entry_points_files->count(); i++) {
-    const char* path = entry_points_files->GetArgument(i);
-    FILE* file = fopen(path, "r");
-    parsed_entry_count +=
-        ParseEntryPointsManifestLines(file, &entries[parsed_entry_count]);
-    fclose(file);
-  }
-
-  ASSERT(parsed_entry_count == entry_count);
-
-  // The entries allocation must be explicitly cleaned up via
-  // |CleanupEntryPointsCollection|
-  return entries;
-}
-
-static Dart_QualifiedFunctionName* ParseEntryPointsManifestIfPresent() {
-  Dart_QualifiedFunctionName* entries = ParseEntryPointsManifestFiles();
-  if ((entries == NULL) && IsSnapshottingForPrecompilation()) {
-    Log::PrintErr(
-        "Could not find native embedder entry points during precompilation\n");
-    exit(kErrorExitCode);
-  }
-  return entries;
-}
-
 static void LoadCompilationTrace() {
   if ((load_compilation_trace_filename != NULL) &&
       (snapshot_kind == kCoreJIT)) {
@@ -1201,13 +894,12 @@
   return std::unique_ptr<MappedMemory>(mapping);
 }
 
-static void CreateAndWritePrecompiledSnapshot(
-    Dart_QualifiedFunctionName* standalone_entry_points) {
+static void CreateAndWritePrecompiledSnapshot() {
   ASSERT(IsSnapshottingForPrecompilation());
   Dart_Handle result;
 
   // Precompile with specified embedder entry points
-  result = Dart_Precompile(standalone_entry_points);
+  result = Dart_Precompile();
   CHECK_RESULT(result);
 
   // Create a precompiled snapshot.
@@ -1352,6 +1044,10 @@
   return isolate;
 }
 
+static Dart_QualifiedFunctionName no_entry_points[] = {
+    {NULL, NULL, NULL}  // Must be terminated with NULL entries.
+};
+
 static int GenerateSnapshotFromKernel(const uint8_t* kernel_buffer,
                                       intptr_t kernel_buffer_size) {
   ASSERT(SnapshotKindAllowedFromKernel());
@@ -1366,11 +1062,9 @@
   Dart_IsolateFlags isolate_flags;
   Dart_IsolateFlagsInitialize(&isolate_flags);
 
-  Dart_QualifiedFunctionName* entry_points = NULL;
   if (IsSnapshottingForPrecompilation()) {
-    entry_points = ParseEntryPointsManifestIfPresent();
     isolate_flags.obfuscate = obfuscate;
-    isolate_flags.entry_points = entry_points;
+    isolate_flags.entry_points = no_entry_points;
   }
 
   // We need to capture the vmservice library in the core snapshot, so load it
@@ -1418,12 +1112,10 @@
         return kErrorExitCode;
       }
 
-      CreateAndWritePrecompiledSnapshot(entry_points);
+      CreateAndWritePrecompiledSnapshot();
 
       CreateAndWriteDependenciesFile();
 
-      CleanupEntryPointsCollection(entry_points);
-
       break;
     }
     case kCore:
@@ -1456,10 +1148,6 @@
   CommandLineOptions cmdline_url_mapping(argc);
   DartUtils::url_mapping = &cmdline_url_mapping;
 
-  // Initialize the entrypoints array.
-  CommandLineOptions entry_points_files_array(argc);
-  entry_points_files = &entry_points_files_array;
-
   // When running from the command line we assume that we are optimizing for
   // throughput, and therefore use a larger new gen semi space size and a faster
   // new gen growth factor unless others have been specified.
@@ -1594,9 +1282,6 @@
   Dart_IsolateFlags flags;
   Dart_IsolateFlagsInitialize(&flags);
 
-  Dart_QualifiedFunctionName* entry_points =
-      ParseEntryPointsManifestIfPresent();
-
   IsolateData* isolate_data = new IsolateData(NULL, commandline_package_root,
                                               commandline_packages_file, NULL);
   Dart_Isolate isolate = Dart_CreateIsolate(NULL, NULL, isolate_snapshot_data,
@@ -1662,7 +1347,7 @@
 
     if (IsSnapshottingForPrecompilation()) {
       flags.obfuscate = obfuscate;
-      flags.entry_points = entry_points;
+      flags.entry_points = no_entry_points;
     }
 
     Dart_Isolate isolate = NULL;
@@ -1689,17 +1374,10 @@
 
     ASSERT(kernel_buffer == NULL);
 
-    // Load any libraries named in the entry points. Do this before loading the
-    // user's script to ensure conditional imports see the embedder-specific
-    // dart: libraries.
-    LoadEntryPoints(entry_points);
-
     // Load the specified script.
     library = LoadSnapshotCreationScript(app_script_name);
     CHECK_RESULT(library);
 
-    ImportNativeEntryPointLibrariesIntoRoot(entry_points);
-
     // Ensure that we mark all libraries as loaded.
     result = Dart_FinalizeLoading(false);
     CHECK_RESULT(result);
@@ -1718,7 +1396,7 @@
         break;
       case kAppAOTBlobs:
       case kAppAOTAssembly:
-        CreateAndWritePrecompiledSnapshot(entry_points);
+        CreateAndWritePrecompiledSnapshot();
         break;
       default:
         UNREACHABLE();
@@ -1729,8 +1407,6 @@
     Dart_ExitScope();
     Dart_ShutdownIsolate();
 
-    CleanupEntryPointsCollection(entry_points);
-
     Dart_EnterIsolate(UriResolverIsolateScope::isolate);
     Dart_ShutdownIsolate();
   } else {
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 992dd7f..3e5e6c5 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -974,7 +974,7 @@
     }
 
     if (Options::gen_snapshot_kind() == kAppAOT) {
-      result = Dart_Precompile(standalone_entry_points);
+      result = Dart_Precompile();
       CHECK_RESULT(result);
 
       if (Options::obfuscate() &&
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index c1c02df..a8df732 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -3368,17 +3368,16 @@
  */
 
 /**
- * Compiles all functions reachable from the provided entry points and marks
+ * Compiles all functions reachable from entry points and marks
  * the isolate to disallow future compilation.
  *
- * \param entry_points A list of functions that may be invoked through the
- * embedding API, e.g. Dart_Invoke/GetField/SetField/New/InvokeClosure.
+ * Entry points should be specified using `@pragma("vm:entry-point")`
+ * annotation.
  *
  * \return An error handle if a compilation error or runtime error running const
  * constructors was encountered.
  */
-DART_EXPORT Dart_Handle
-Dart_Precompile(Dart_QualifiedFunctionName entry_points[]);
+DART_EXPORT Dart_Handle Dart_Precompile();
 
 typedef void (*Dart_StreamingWriteCallback)(void* callback_data,
                                             const uint8_t* buffer,
diff --git a/runtime/tools/create_snapshot_bin.py b/runtime/tools/create_snapshot_bin.py
index 87c3a7d..599d17c 100755
--- a/runtime/tools/create_snapshot_bin.py
+++ b/runtime/tools/create_snapshot_bin.py
@@ -45,9 +45,6 @@
       action="store", type="string",
       help="output file name into which isolate snapshot in binary form " +
            "is generated")
-  result.add_option("--embedder_entry_points_manifest",
-      action="store", type="string",
-      help="input manifest with the vm entry points in a precompiled snapshot")
   result.add_option("--script",
       action="store", type="string",
       help="Dart script for which snapshot is to be generated")
@@ -146,11 +143,6 @@
     script_args.append(''.join([ "--isolate_snapshot_instructions=",
                                  options.isolate_instructions_output_bin ]))
 
-  # Specify the embedder entry points snapshot
-  if options.embedder_entry_points_manifest:
-    script_args.append(''.join([ "--embedder_entry_points_manifest=",
-                                 options.embedder_entry_points_manifest ]))
-
   # Next setup all url mapping options specified.
   for url_arg in options.url_mapping:
     url_mapping_argument = ''.join(["--url_mapping=", url_arg ])
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 76cf129..e554b4a 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -30,7 +30,6 @@
 #include "vm/flags.h"
 #include "vm/hash_table.h"
 #include "vm/isolate.h"
-#include "vm/json_writer.h"
 #include "vm/kernel_loader.h"  // For kernel::ParseStaticFieldInitializer.
 #include "vm/log.h"
 #include "vm/longjump.h"
@@ -252,12 +251,11 @@
   }
 }
 
-RawError* Precompiler::CompileAll(
-    Dart_QualifiedFunctionName embedder_entry_points[]) {
+RawError* Precompiler::CompileAll() {
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
     Precompiler precompiler(Thread::Current());
-    precompiler.DoCompileAll(embedder_entry_points);
+    precompiler.DoCompileAll();
     return Error::null();
   } else {
     Thread* thread = Thread::Current();
@@ -297,8 +295,7 @@
       error_(Error::Handle()),
       get_runtime_type_is_unique_(false) {}
 
-void Precompiler::DoCompileAll(
-    Dart_QualifiedFunctionName embedder_entry_points[]) {
+void Precompiler::DoCompileAll() {
   ASSERT(I->compilation_allowed());
 
   {
@@ -353,7 +350,7 @@
         CollectDynamicFunctionNames();
 
         // Start with the allocations and invocations that happen from C++.
-        AddRoots(embedder_entry_points);
+        AddRoots();
         AddAnnotatedRoots();
 
         // Compile newly found targets and add their callees until we reach a
@@ -533,173 +530,7 @@
   }
 }
 
-static Dart_QualifiedFunctionName vm_entry_points[] = {
-    // Fields
-    {NULL, NULL, NULL}  // Must be terminated with NULL entries.
-};
-
-class PrecompilerEntryPointsPrinter : public ValueObject {
- public:
-  explicit PrecompilerEntryPointsPrinter(Zone* zone);
-
-  void AddInstantiatedClass(const Class& cls);
-  void AddEntryPoint(const Object& entry_point);
-
-  void Print();
-
- private:
-  Zone* zone() const { return zone_; }
-
-  void DescribeClass(JSONWriter* writer, const Class& cls);
-
-  Zone* zone_;
-  const GrowableObjectArray& instantiated_classes_;
-  const GrowableObjectArray& entry_points_;
-};
-
-PrecompilerEntryPointsPrinter::PrecompilerEntryPointsPrinter(Zone* zone)
-    : zone_(zone),
-      instantiated_classes_(GrowableObjectArray::Handle(
-          zone,
-          FLAG_print_precompiler_entry_points ? GrowableObjectArray::New()
-                                              : GrowableObjectArray::null())),
-      entry_points_(GrowableObjectArray::Handle(
-          zone,
-          FLAG_print_precompiler_entry_points ? GrowableObjectArray::New()
-                                              : GrowableObjectArray::null())) {}
-
-void PrecompilerEntryPointsPrinter::AddInstantiatedClass(const Class& cls) {
-  if (!FLAG_print_precompiler_entry_points) {
-    return;
-  }
-
-  if (!cls.is_abstract()) {
-    instantiated_classes_.Add(cls);
-  }
-}
-
-void PrecompilerEntryPointsPrinter::AddEntryPoint(const Object& entry_point) {
-  ASSERT(entry_point.IsFunction() || entry_point.IsField());
-
-  if (!FLAG_print_precompiler_entry_points) {
-    return;
-  }
-  entry_points_.Add(entry_point);
-}
-
-// Prints precompiler entry points as JSON.
-// The format is described in [entry_points_json.md].
-void PrecompilerEntryPointsPrinter::Print() {
-  if (!FLAG_print_precompiler_entry_points) {
-    return;
-  }
-
-  JSONWriter writer;
-
-  writer.OpenObject();
-
-  writer.OpenArray("roots");
-
-  for (intptr_t i = 0; i < instantiated_classes_.Length(); ++i) {
-    const Class& cls = Class::CheckedHandle(Z, instantiated_classes_.At(i));
-
-    writer.OpenObject();
-    DescribeClass(&writer, cls);
-    writer.PrintProperty("action", "create-instance");
-    writer.CloseObject();
-  }
-
-  for (intptr_t i = 0; i < entry_points_.Length(); ++i) {
-    const Object& entry_point = Object::Handle(Z, entry_points_.At(i));
-
-    if (entry_point.IsFunction()) {
-      const Function& func = Function::Cast(entry_point);
-
-      writer.OpenObject();
-      DescribeClass(&writer, Class::Handle(Z, func.Owner()));
-
-      String& name = String::Handle(Z);
-      if (func.IsGetterFunction() || func.IsImplicitGetterFunction() ||
-          (func.kind() == RawFunction::kImplicitStaticFinalGetter)) {
-        name = func.name();
-        name = Field::NameFromGetter(name);
-        name = String::ScrubName(name);
-        writer.PrintPropertyStr("name", name);
-        writer.PrintProperty("action", "get");
-      } else if (func.IsSetterFunction() || func.IsImplicitSetterFunction()) {
-        name = func.name();
-        name = Field::NameFromSetter(name);
-        name = String::ScrubName(name);
-        writer.PrintPropertyStr("name", name);
-        writer.PrintProperty("action", "set");
-      } else {
-        name = func.UserVisibleName();
-        writer.PrintPropertyStr("name", name);
-        writer.PrintProperty("action", "call");
-      }
-      writer.CloseObject();
-    } else {
-      const Field& field = Field::Cast(entry_point);
-      const Class& owner = Class::Handle(Z, field.Owner());
-      const String& name = String::Handle(Z, field.UserVisibleName());
-
-      {
-        writer.OpenObject();
-        DescribeClass(&writer, owner);
-        writer.PrintPropertyStr("name", name);
-        writer.PrintProperty("action", "get");
-        writer.CloseObject();
-      }
-
-      {
-        writer.OpenObject();
-        DescribeClass(&writer, owner);
-        writer.PrintPropertyStr("name", name);
-        writer.PrintProperty("action", "set");
-        writer.CloseObject();
-      }
-    }
-  }
-
-  writer.CloseArray();  // roots
-  writer.CloseObject();  // top-level
-
-  const char* contents = writer.ToCString();
-
-  Dart_FileOpenCallback file_open = Dart::file_open_callback();
-  Dart_FileWriteCallback file_write = Dart::file_write_callback();
-  Dart_FileCloseCallback file_close = Dart::file_close_callback();
-  if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) {
-    FATAL(
-        "Unable to print precompiler entry points:"
-        " file callbacks are not provided by embedder");
-  }
-
-  void* out_stream =
-      file_open(FLAG_print_precompiler_entry_points, /* write = */ true);
-  if (out_stream == NULL) {
-    FATAL1(
-        "Unable to print precompiler entry points:"
-        " failed to open file \"%s\" for writing",
-        FLAG_print_precompiler_entry_points);
-  }
-  file_write(contents, strlen(contents), out_stream);
-  file_close(out_stream);
-}
-
-void PrecompilerEntryPointsPrinter::DescribeClass(JSONWriter* writer,
-                                                  const Class& cls) {
-  const Library& library = Library::Handle(Z, cls.library());
-  writer->PrintPropertyStr("library", String::Handle(Z, library.url()));
-
-  if (!cls.IsTopLevel()) {
-    writer->PrintPropertyStr("class", String::Handle(Z, cls.ScrubbedName()));
-  }
-}
-
-void Precompiler::AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]) {
-  PrecompilerEntryPointsPrinter entry_points_printer(zone());
-
+void Precompiler::AddRoots() {
   // Note that <rootlibrary>.main is not a root. The appropriate main will be
   // discovered through _getMainClosure.
 
@@ -707,11 +538,6 @@
 
   AddSelector(Symbols::Call());  // For speed, not correctness.
 
-  AddEntryPoints(vm_entry_points, &entry_points_printer);
-  AddEntryPoints(embedder_entry_points, &entry_points_printer);
-
-  entry_points_printer.Print();
-
   const Library& lib = Library::Handle(I->object_store()->root_library());
   if (lib.IsNull()) {
     const String& msg = String::Handle(
@@ -742,90 +568,6 @@
   }
 }
 
-void Precompiler::AddEntryPoints(
-    Dart_QualifiedFunctionName entry_points[],
-    PrecompilerEntryPointsPrinter* entry_points_printer) {
-  Library& lib = Library::Handle(Z);
-  Class& cls = Class::Handle(Z);
-  Function& func = Function::Handle(Z);
-  Field& field = Field::Handle(Z);
-  String& library_uri = String::Handle(Z);
-  String& class_name = String::Handle(Z);
-  String& function_name = String::Handle(Z);
-
-  for (intptr_t i = 0; entry_points[i].library_uri != NULL; i++) {
-    library_uri = Symbols::New(thread(), entry_points[i].library_uri);
-    class_name = Symbols::New(thread(), entry_points[i].class_name);
-    function_name = Symbols::New(thread(), entry_points[i].function_name);
-
-    if (library_uri.raw() == Symbols::TopLevel().raw()) {
-      lib = I->object_store()->root_library();
-    } else {
-      lib = Library::LookupLibrary(T, library_uri);
-    }
-    if (lib.IsNull()) {
-      String& msg = String::Handle(
-          Z, String::NewFormatted("Cannot find entry point '%s'\n",
-                                  entry_points[i].library_uri));
-      Jump(Error::Handle(Z, ApiError::New(msg)));
-      UNREACHABLE();
-    }
-
-    if (class_name.raw() == Symbols::TopLevel().raw()) {
-      if (Library::IsPrivate(function_name)) {
-        function_name = lib.PrivateName(function_name);
-      }
-      func = lib.LookupLocalFunction(function_name);
-      field = lib.LookupLocalField(function_name);
-    } else {
-      if (Library::IsPrivate(class_name)) {
-        class_name = lib.PrivateName(class_name);
-      }
-      cls = lib.LookupLocalClass(class_name);
-      if (cls.IsNull()) {
-        String& msg = String::Handle(
-            Z, String::NewFormatted("Cannot find entry point '%s' '%s'\n",
-                                    entry_points[i].library_uri,
-                                    entry_points[i].class_name));
-        Jump(Error::Handle(Z, ApiError::New(msg)));
-        UNREACHABLE();
-      }
-
-      ASSERT(!cls.IsNull());
-      func = cls.LookupFunctionAllowPrivate(function_name);
-      field = cls.LookupFieldAllowPrivate(function_name);
-    }
-
-    if (func.IsNull() && field.IsNull()) {
-      String& msg = String::Handle(
-          Z, String::NewFormatted("Cannot find entry point '%s' '%s' '%s'\n",
-                                  entry_points[i].library_uri,
-                                  entry_points[i].class_name,
-                                  entry_points[i].function_name));
-      Jump(Error::Handle(Z, ApiError::New(msg)));
-      UNREACHABLE();
-    }
-
-    if (!func.IsNull()) {
-      AddFunction(func);
-      entry_points_printer->AddEntryPoint(func);
-      if (func.IsGenerativeConstructor()) {
-        // Allocation stubs are referenced from the call site of the
-        // constructor, not in the constructor itself. So compiling the
-        // constructor isn't enough for us to discover the class is
-        // instantiated if the class isn't otherwise instantiated from Dart
-        // code and only instantiated from C++.
-        AddInstantiatedClass(cls);
-        entry_points_printer->AddInstantiatedClass(cls);
-      }
-    }
-    if (!field.IsNull()) {
-      AddField(field);
-      entry_points_printer->AddEntryPoint(field);
-    }
-  }
-}
-
 void Precompiler::Iterate() {
   Function& function = Function::Handle(Z);
 
@@ -3082,7 +2824,6 @@
 void Obfuscator::InitializeRenamingMap(Isolate* isolate) {
   // Prevent renaming of classes and method names mentioned in the
   // entry points lists.
-  PreventRenaming(vm_entry_points);
   PreventRenaming(isolate->embedder_entry_points());
 
 // Prevent renaming of all pseudo-keywords and operators.
diff --git a/runtime/vm/compiler/aot/precompiler.h b/runtime/vm/compiler/aot/precompiler.h
index 95c45d4..cfa8b7e 100644
--- a/runtime/vm/compiler/aot/precompiler.h
+++ b/runtime/vm/compiler/aot/precompiler.h
@@ -338,8 +338,7 @@
 
 class Precompiler : public ValueObject {
  public:
-  static RawError* CompileAll(
-      Dart_QualifiedFunctionName embedder_entry_points[]);
+  static RawError* CompileAll();
 
   static RawError* CompileFunction(Precompiler* precompiler,
                                    Thread* thread,
@@ -363,11 +362,9 @@
  private:
   explicit Precompiler(Thread* thread);
 
-  void DoCompileAll(Dart_QualifiedFunctionName embedder_entry_points[]);
-  void AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]);
+  void DoCompileAll();
+  void AddRoots();
   void AddAnnotatedRoots();
-  void AddEntryPoints(Dart_QualifiedFunctionName entry_points[],
-                      PrecompilerEntryPointsPrinter* entry_points_printer);
   void Iterate();
 
   void AddType(const AbstractType& type);
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 717daf3..7a079a0 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -6368,8 +6368,7 @@
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
-DART_EXPORT Dart_Handle
-Dart_Precompile(Dart_QualifiedFunctionName entry_points[]) {
+DART_EXPORT Dart_Handle Dart_Precompile() {
 #if defined(TARGET_ARCH_IA32)
   return Api::NewError("AOT compilation is not supported on IA32.");
 #elif defined(TARGET_ARCH_DBC)
@@ -6388,7 +6387,7 @@
     return result;
   }
   CHECK_CALLBACK_STATE(T);
-  const Error& error = Error::Handle(Precompiler::CompileAll(entry_points));
+  const Error& error = Error::Handle(Precompiler::CompileAll());
   if (!error.IsNull()) {
     return Api::NewHandle(T, error.raw());
   }
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index e631158..428b223 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -141,9 +141,6 @@
   P(polymorphic_with_deopt, bool, true,                                        \
     "Polymorphic calls with deoptimization / megamorphic call")                \
   P(precompiled_mode, bool, false, "Precompilation compiler mode")             \
-  P(print_precompiler_entry_points, charp, NULL,                               \
-    "Print entry points and info about recognized methods used by "            \
-    "precompiler.")                                                            \
   P(print_snapshot_sizes, bool, false, "Print sizes of generated snapshots.")  \
   P(print_snapshot_sizes_verbose, bool, false,                                 \
     "Print cluster sizes of generated snapshots.")                             \