Version 2.17.0-176.0.dev

Merge commit '7039c5dc0cd4a2a94987ded69e80877a68f85d3e' into 'dev'
diff --git a/runtime/bin/platform_macos.cc b/runtime/bin/platform_macos.cc
index b78112e..0c22675 100644
--- a/runtime/bin/platform_macos.cc
+++ b/runtime/bin/platform_macos.cc
@@ -13,7 +13,6 @@
 #if !DART_HOST_OS_IOS
 #include <crt_externs.h>  // NOLINT
 #endif                    // !DART_HOST_OS_IOS
-#include <dlfcn.h>        // NOLINT
 #include <errno.h>        // NOLINT
 #include <mach-o/dyld.h>
 #include <signal.h>        // NOLINT
@@ -252,98 +251,7 @@
   return path_size;
 }
 
-void Platform::SetProcessName(const char* name) {
-  pthread_setname_np(name);
-
-#if !defined(DART_HOST_OS_IOS) && !defined(DART_PRECOMPILED_RUNTIME)
-  // Attempt to set the name displayed in ActivityMonitor.
-  // https://codereview.chromium.org/659007/
-
-  class ScopedDLHandle : public ValueObject {
-   public:
-    explicit ScopedDLHandle(void* handle) : handle_(handle) {}
-    ~ScopedDLHandle() {
-      if (handle_ != NULL) dlclose(handle_);
-    }
-    void* get() const { return handle_; }
-
-   private:
-    void* handle_;
-    DISALLOW_COPY_AND_ASSIGN(ScopedDLHandle);
-  };
-
-  class ScopedCFStringRef : public ValueObject {
-   public:
-    explicit ScopedCFStringRef(const char* s)
-        : ref_(CFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8)) {}
-    ~ScopedCFStringRef() {
-      if (ref_ != NULL) CFRelease(ref_);
-    }
-    CFStringRef get() const { return ref_; }
-
-   private:
-    CFStringRef ref_;
-    DISALLOW_COPY_AND_ASSIGN(ScopedCFStringRef);
-  };
-
-  ScopedDLHandle application_services_handle(
-      dlopen("/System/Library/Frameworks/ApplicationServices.framework/"
-             "Versions/A/ApplicationServices",
-             RTLD_LAZY | RTLD_LOCAL));
-  if (application_services_handle.get() == NULL) return;
-
-  ScopedCFStringRef launch_services_bundle_name("com.apple.LaunchServices");
-  CFBundleRef launch_services_bundle =
-      CFBundleGetBundleWithIdentifier(launch_services_bundle_name.get());
-  if (launch_services_bundle == NULL) return;
-
-#define GET_FUNC(name, cstr)                                                   \
-  ScopedCFStringRef name##_id(cstr);                                           \
-  *reinterpret_cast<void**>(&name) = CFBundleGetFunctionPointerForName(        \
-      launch_services_bundle, name##_id.get());                                \
-  if (name == NULL) return;
-
-#define GET_DATA(name, cstr)                                                   \
-  ScopedCFStringRef name##_id(cstr);                                           \
-  *reinterpret_cast<void**>(&name) =                                           \
-      CFBundleGetDataPointerForName(launch_services_bundle, name##_id.get());  \
-  if (name == NULL) return;
-
-  CFTypeRef (*_LSGetCurrentApplicationASN)(void);
-  GET_FUNC(_LSGetCurrentApplicationASN, "_LSGetCurrentApplicationASN");
-
-  OSStatus (*_LSSetApplicationInformationItem)(int, CFTypeRef, CFStringRef,
-                                               CFStringRef, CFDictionaryRef*);
-  GET_FUNC(_LSSetApplicationInformationItem,
-           "_LSSetApplicationInformationItem");
-
-  CFDictionaryRef (*_LSApplicationCheckIn)(int, CFDictionaryRef);
-  GET_FUNC(_LSApplicationCheckIn, "_LSApplicationCheckIn");
-
-  void (*_LSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t,
-                                                                void*);
-  GET_FUNC(_LSSetApplicationLaunchServicesServerConnectionStatus,
-           "_LSSetApplicationLaunchServicesServerConnectionStatus");
-
-  CFStringRef* _kLSDisplayNameKey;
-  GET_DATA(_kLSDisplayNameKey, "_kLSDisplayNameKey");
-  if (*_kLSDisplayNameKey == NULL) return;
-
-  _LSSetApplicationLaunchServicesServerConnectionStatus(0, NULL);
-
-  _LSApplicationCheckIn(-2, CFBundleGetInfoDictionary(CFBundleGetMainBundle()));
-
-  CFTypeRef asn;
-  asn = _LSGetCurrentApplicationASN();
-  if (asn == NULL) return;
-
-  ScopedCFStringRef cf_name(name);
-  _LSSetApplicationInformationItem(-2, asn, *_kLSDisplayNameKey, cf_name.get(),
-                                   NULL);
-#undef GET_DATA
-#undef GET_FUNC
-#endif  // !defined(DART_HOST_OS_IOS)
-}
+void Platform::SetProcessName(const char* name) {}
 
 void Platform::Exit(int exit_code) {
   Console::RestoreConfig();
diff --git a/runtime/tools/dartfuzz/gen_api_table.dart b/runtime/tools/dartfuzz/gen_api_table.dart
index 2eb9f52..784dfcb 100644
--- a/runtime/tools/dartfuzz/gen_api_table.dart
+++ b/runtime/tools/dartfuzz/gen_api_table.dart
@@ -382,7 +382,7 @@
           protoString(null, function.parameters));
     }
   }
-  for (var classElement in unit.types) {
+  for (var classElement in unit.classes) {
     if (classElement.isPublic) {
       visitClass(classElement);
     }
diff --git a/runtime/tools/dartfuzz/gen_type_table.dart b/runtime/tools/dartfuzz/gen_type_table.dart
index a8e0868..da29e56 100644
--- a/runtime/tools/dartfuzz/gen_type_table.dart
+++ b/runtime/tools/dartfuzz/gen_type_table.dart
@@ -1364,7 +1364,7 @@
   // classes. Note that `types` only returns classes. You can use
   // `mixins` to visit mixins, `enums` to visit enum, `functionTypeAliases`
   // to visit typedefs, etc.
-  for (var classElement in unit.types) {
+  for (var classElement in unit.classes) {
     if (classElement.isPublic) {
       // Hack: Filter out some difficult types, abstract types and types that
       // have methods with abstract type parameters.
diff --git a/runtime/vm/compiler/backend/flow_graph.h b/runtime/vm/compiler/backend/flow_graph.h
index cc0d964..614d19b 100644
--- a/runtime/vm/compiler/backend/flow_graph.h
+++ b/runtime/vm/compiler/backend/flow_graph.h
@@ -408,6 +408,12 @@
     unmatched_representations_allowed_ = false;
   }
 
+  // Returns true if this flow graph was built for a huge method
+  // and certain optimizations should be disabled.
+  bool is_huge_method() const { return huge_method_; }
+  // Mark this flow graph as huge and disable certain optimizations.
+  void mark_huge_method() { huge_method_ = true; }
+
   PrologueInfo prologue_info() const { return prologue_info_; }
 
   // Computes the loop hierarchy of the flow graph on demand.
@@ -634,6 +640,7 @@
 
   bool licm_allowed_;
   bool unmatched_representations_allowed_ = true;
+  bool huge_method_ = false;
 
   const PrologueInfo prologue_info_;
 
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index 337fcac..c9245a5 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -1792,7 +1792,7 @@
 
     // For now, bail out for large functions to avoid OOM situations.
     // TODO(fschneider): Fix the memory consumption issue.
-    if (graph->function().SourceSize() >= FLAG_huge_method_cutoff_in_tokens) {
+    if (graph->is_huge_method()) {
       return false;
     }
 
@@ -3019,7 +3019,7 @@
 
     // For now, bail out for large functions to avoid OOM situations.
     // TODO(fschneider): Fix the memory consumption issue.
-    if (graph->function().SourceSize() >= FLAG_huge_method_cutoff_in_tokens) {
+    if (graph->is_huge_method()) {
       return;
     }
 
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index b20723b..0af255f 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -1105,6 +1105,7 @@
 }
 
 Fragment StreamingFlowGraphBuilder::BuildExpression(TokenPosition* position) {
+  ++num_ast_nodes_;
   uint8_t payload = 0;
   Tag tag = ReadTag(&payload);  // read tag.
   switch (tag) {
@@ -1242,6 +1243,7 @@
 }
 
 Fragment StreamingFlowGraphBuilder::BuildStatement(TokenPosition* position) {
+  ++num_ast_nodes_;
   intptr_t offset = ReaderOffset();
   Tag tag = ReadTag();  // read tag.
   switch (tag) {
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 8fe4c5c..cc8a1f9 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -54,6 +54,8 @@
 
   Fragment BuildStatementAt(intptr_t kernel_offset);
 
+  intptr_t num_ast_nodes() const { return num_ast_nodes_; }
+
  private:
   Thread* thread() const { return flow_graph_builder_->thread_; }
 
@@ -436,6 +438,7 @@
   ProcedureAttributesMetadataHelper procedure_attributes_metadata_helper_;
   CallSiteAttributesMetadataHelper call_site_attributes_metadata_helper_;
   Object& closure_owner_;
+  intptr_t num_ast_nodes_ = 0;
 
   friend class KernelLoader;
 
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index a76ffdd..2fab100 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -36,6 +36,12 @@
 #include "vm/symbols.h"
 
 namespace dart {
+
+DEFINE_FLAG(bool,
+            print_huge_methods,
+            false,
+            "Print huge methods (less optimized)");
+
 namespace kernel {
 
 #define Z (zone_)
@@ -768,6 +774,23 @@
   FinalizeCoverageArray();
   result->set_coverage_array(coverage_array());
 
+  if (streaming_flow_graph_builder.num_ast_nodes() >
+      FLAG_huge_method_cutoff_in_ast_nodes) {
+    if (FLAG_print_huge_methods) {
+      OS::PrintErr(
+          "Warning: \'%s\' from \'%s\' is too large. Some optimizations have "
+          "been "
+          "disabled, and the compiler might run out of memory. "
+          "Consider refactoring this code into smaller components.\n",
+          function.QualifiedUserVisibleNameCString(),
+          String::Handle(Z, Library::Handle(
+                                Z, Class::Handle(Z, function.Owner()).library())
+                                .url())
+              .ToCString());
+    }
+    result->mark_huge_method();
+  }
+
   return result;
 }
 
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index b5cde40..1e77f74 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -127,8 +127,9 @@
     "Force cloning of objects needed in compiler (ICData and Field).")         \
   P(guess_icdata_cid, bool, true,                                              \
     "Artificially create type feedback for arithmetic etc. operations")        \
-  P(huge_method_cutoff_in_tokens, int, 20000,                                  \
-    "Huge method cutoff in tokens: Disables optimizations for huge methods.")  \
+  P(huge_method_cutoff_in_ast_nodes, int, 10000,                               \
+    "Huge method cutoff in AST nodes: Disables optimizations for huge "        \
+    "methods.")                                                                \
   P(idle_timeout_micros, int, 1000 * kMicrosecondsPerMillisecond,              \
     "Consider thread pool isolates for idle tasks after this long.")           \
   P(idle_duration_micros, int, 500 * kMicrosecondsPerMillisecond,              \
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index f68063a..00807b5 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -8032,8 +8032,7 @@
     // Native methods don't need to be optimized.
     return false;
   }
-  if (is_optimizable() && (script() != Script::null()) &&
-      SourceSize() < FLAG_huge_method_cutoff_in_tokens) {
+  if (is_optimizable() && (script() != Script::null())) {
     // Additional check needed for implicit getters.
     return (unoptimized_code() == Object::null()) ||
            (Code::Handle(unoptimized_code()).Size() <
diff --git a/tools/VERSION b/tools/VERSION
index 16ef2ea..c3193cb 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 175
+PRERELEASE 176
 PRERELEASE_PATCH 0
\ No newline at end of file