Version 2.18.0-121.0.dev

Merge commit '7ff9b2fb5e76cbb9d8bf745a9d70647a5d46a8a4' into 'dev'
diff --git a/DEPS b/DEPS
index a5498ba..7b983ec 100644
--- a/DEPS
+++ b/DEPS
@@ -89,7 +89,7 @@
   "charcode_rev": "84ea427711e24abf3b832923959caa7dd9a8514b",
   "chrome_rev": "19997",
   "cli_util_rev": "b0adbba89442b2ea6fef39c7a82fe79cb31e1168",
-  "clock_rev": "5631a0612f4ac7e1b32f7c9a00fc7c00a41615e1",
+  "clock_rev": "f594d86da123015186d5680b0d0e8255c52fc162",
   "collection_rev": "e1407da23b9f17400b3a905aafe2b8fa10db3d86",
   "convert_rev": "e063fdca4bebffecbb5e6aa5525995120982d9ce",
   "crypto_rev": "4297d240b0e1e780ec0a9eab23eaf1ad491f3e68",
diff --git a/runtime/vm/app_snapshot.cc b/runtime/vm/app_snapshot.cc
index 19054a2..c718234 100644
--- a/runtime/vm/app_snapshot.cc
+++ b/runtime/vm/app_snapshot.cc
@@ -1424,9 +1424,7 @@
     }
     // Write out either the initial static value or field offset.
     if (Field::StaticBit::decode(field->untag()->kind_bits_)) {
-      const intptr_t field_id =
-          Smi::Value(field->untag()->host_offset_or_field_id());
-      s->Push(s->initial_field_table()->At(field_id));
+      s->Push(field->untag()->host_offset_or_field_id());
     } else {
       s->Push(Smi::New(Field::TargetOffsetOf(field)));
     }
@@ -1472,10 +1470,7 @@
 
       // Write out either the initial static value or field offset.
       if (Field::StaticBit::decode(field->untag()->kind_bits_)) {
-        const intptr_t field_id =
-            Smi::Value(field->untag()->host_offset_or_field_id());
-        WriteFieldValue("static value", s->initial_field_table()->At(field_id));
-        s->WriteUnsigned(field_id);
+        WriteFieldValue("id", field->untag()->host_offset_or_field_id());
       } else {
         WriteFieldValue("offset", Smi::New(Field::TargetOffsetOf(field)));
       }
@@ -1535,20 +1530,12 @@
 #endif
       field->untag()->kind_bits_ = d.Read<uint16_t>();
 
-      ObjectPtr value_or_offset = d.ReadRef();
-      if (Field::StaticBit::decode(field->untag()->kind_bits_)) {
-        const intptr_t field_id = d.ReadUnsigned();
-        d_->initial_field_table()->SetAt(
-            field_id, static_cast<InstancePtr>(value_or_offset));
-        field->untag()->host_offset_or_field_id_ = Smi::New(field_id);
-      } else {
-        field->untag()->host_offset_or_field_id_ =
-            Smi::RawCast(value_or_offset);
+      field->untag()->host_offset_or_field_id_ =
+          static_cast<SmiPtr>(d.ReadRef());
 #if !defined(DART_PRECOMPILED_RUNTIME)
-        field->untag()->target_offset_ =
-            Smi::Value(field->untag()->host_offset_or_field_id());
+      field->untag()->target_offset_ =
+          Smi::Value(field->untag()->host_offset_or_field_id());
 #endif  //  !defined(DART_PRECOMPILED_RUNTIME)
-      }
     }
   }
 
@@ -6019,6 +6006,12 @@
       s->Push(*p);
     }
 
+    FieldTable* initial_field_table =
+        s->thread()->isolate_group()->initial_field_table();
+    for (intptr_t i = 0, n = initial_field_table->NumFieldIds(); i < n; i++) {
+      s->Push(initial_field_table->At(i));
+    }
+
     dispatch_table_entries_ = object_store_->dispatch_table_code_entries();
     // We should only have a dispatch table in precompiled mode.
     ASSERT(dispatch_table_entries_.IsNull() || s->kind() == Snapshot::kFullAOT);
@@ -6043,6 +6036,14 @@
       s->WriteRootRef(*p, kObjectStoreFieldNames[p - from]);
     }
 
+    FieldTable* initial_field_table =
+        s->thread()->isolate_group()->initial_field_table();
+    intptr_t n = initial_field_table->NumFieldIds();
+    s->WriteUnsigned(n);
+    for (intptr_t i = 0; i < n; i++) {
+      s->WriteRootRef(initial_field_table->At(i), "some-static-field");
+    }
+
     // The dispatch table is serialized only for precompiled snapshots.
     s->WriteDispatchTable(dispatch_table_entries_);
   }
@@ -6087,6 +6088,14 @@
       *p = d->ReadRef();
     }
 
+    FieldTable* initial_field_table =
+        d->thread()->isolate_group()->initial_field_table();
+    intptr_t n = d->ReadUnsigned();
+    initial_field_table->AllocateIndex(n - 1);
+    for (intptr_t i = 0; i < n; i++) {
+      initial_field_table->SetAt(i, d->ReadRef());
+    }
+
     // Deserialize dispatch table (when applicable)
     d->ReadDispatchTable();
   }
@@ -6303,7 +6312,6 @@
       num_base_objects_(0),
       num_written_objects_(0),
       next_ref_index_(kFirstReference),
-      initial_field_table_(thread->isolate_group()->initial_field_table()),
       vm_(vm),
       profile_writer_(profile_writer)
 #if defined(SNAPSHOT_BACKTRACE)
@@ -7508,12 +7516,6 @@
   WriteUnsigned(num_base_objects_);
   WriteUnsigned(num_objects);
   WriteUnsigned(clusters.length());
-  // TODO(dartbug.com/36097): Not every snapshot carries the field table.
-  if (current_loading_unit_id_ <= LoadingUnit::kRootId) {
-    WriteUnsigned(initial_field_table_->NumFieldIds());
-  } else {
-    WriteUnsigned(0);
-  }
   ASSERT((instructions_table_len_ == 0) || FLAG_precompiled_mode);
   WriteUnsigned(instructions_table_len_);
   WriteUnsigned(instructions_table_rodata_offset_);
@@ -7800,7 +7802,6 @@
       refs_(nullptr),
       next_ref_index_(kFirstReference),
       clusters_(nullptr),
-      initial_field_table_(thread->isolate_group()->initial_field_table()),
       is_non_root_unit_(is_non_root_unit),
       instructions_table_(InstructionsTable::Handle(thread->zone())) {
   if (Snapshot::IncludesCode(kind)) {
@@ -8316,17 +8317,12 @@
   num_base_objects_ = ReadUnsigned();
   num_objects_ = ReadUnsigned();
   num_clusters_ = ReadUnsigned();
-  const intptr_t initial_field_table_len = ReadUnsigned();
   const intptr_t instructions_table_len = ReadUnsigned();
   const uint32_t instruction_table_data_offset = ReadUnsigned();
   USE(instruction_table_data_offset);
 
   clusters_ = new DeserializationCluster*[num_clusters_];
   refs = Array::New(num_objects_ + kFirstReference, Heap::kOld);
-  if (initial_field_table_len > 0) {
-    initial_field_table_->AllocateIndex(initial_field_table_len - 1);
-    ASSERT_EQUAL(initial_field_table_->NumFieldIds(), initial_field_table_len);
-  }
 
 #if defined(DART_PRECOMPILED_RUNTIME)
   if (instructions_table_len > 0) {
diff --git a/runtime/vm/app_snapshot.h b/runtime/vm/app_snapshot.h
index 0356e09..922c8ac 100644
--- a/runtime/vm/app_snapshot.h
+++ b/runtime/vm/app_snapshot.h
@@ -266,8 +266,6 @@
   ZoneGrowableArray<Object*>* Serialize(SerializationRoots* roots);
   void PrintSnapshotSizes();
 
-  FieldTable* initial_field_table() const { return initial_field_table_; }
-
   NonStreamingWriteStream* stream() { return stream_; }
   intptr_t bytes_written() { return stream_->bytes_written(); }
   intptr_t bytes_heap_allocated() { return bytes_heap_allocated_; }
@@ -516,7 +514,6 @@
   intptr_t num_base_objects_;
   intptr_t num_written_objects_;
   intptr_t next_ref_index_;
-  FieldTable* initial_field_table_;
 
   intptr_t dispatch_table_size_ = 0;
   intptr_t bytes_heap_allocated_ = 0;
@@ -716,7 +713,6 @@
     return kind_;
 #endif
   }
-  FieldTable* initial_field_table() const { return initial_field_table_; }
   bool is_non_root_unit() const { return is_non_root_unit_; }
   void set_code_start_index(intptr_t value) { code_start_index_ = value; }
   intptr_t code_start_index() const { return code_start_index_; }
@@ -810,7 +806,6 @@
   intptr_t code_stop_index_ = 0;
   intptr_t instructions_index_ = 0;
   DeserializationCluster** clusters_;
-  FieldTable* initial_field_table_;
   const bool is_non_root_unit_;
   InstructionsTable& instructions_table_;
 };
diff --git a/sdk/lib/_internal/js_dev_runtime/private/js_number.dart b/sdk/lib/_internal/js_dev_runtime/private/js_number.dart
index b90d786..864aac7 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/js_number.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/js_number.dart
@@ -435,8 +435,7 @@
 
   @notNull
   static int _clz32(@notNull int uint32) {
-    // TODO(sra): Use `Math.clz32(uint32)` (not available on IE11).
-    return 32 - _bitCount(_spread(uint32));
+    return JS('!', 'Math.clz32(#)', uint32);
   }
 
   // Returns pow(this, e) % m.
@@ -581,54 +580,6 @@
     return _binaryGcd(x, y, false);
   }
 
-  // Assumes i is <= 32-bit and unsigned.
-  @notNull
-  static int _bitCount(@notNull int i) {
-    // See "Hacker's Delight", section 5-1, "Counting 1-Bits".
-
-    // The basic strategy is to use "divide and conquer" to
-    // add pairs (then quads, etc.) of bits together to obtain
-    // sub-counts.
-    //
-    // A straightforward approach would look like:
-    //
-    // i = (i & 0x55555555) + ((i >>  1) & 0x55555555);
-    // i = (i & 0x33333333) + ((i >>  2) & 0x33333333);
-    // i = (i & 0x0F0F0F0F) + ((i >>  4) & 0x0F0F0F0F);
-    // i = (i & 0x00FF00FF) + ((i >>  8) & 0x00FF00FF);
-    // i = (i & 0x0000FFFF) + ((i >> 16) & 0x0000FFFF);
-    //
-    // The code below removes unnecessary &'s and uses a
-    // trick to remove one instruction in the first line.
-
-    i = _shru(i, 0) - (_shru(i, 1) & 0x55555555);
-    i = (i & 0x33333333) + (_shru(i, 2) & 0x33333333);
-    i = 0x0F0F0F0F & (i + _shru(i, 4));
-    i += _shru(i, 8);
-    i += _shru(i, 16);
-    return (i & 0x0000003F);
-  }
-
-  @notNull
-  static int _shru(int value, int shift) =>
-      JS<int>('!', '# >>> #', value, shift);
-  @notNull
-  static int _shrs(int value, int shift) =>
-      JS<int>('!', '# >> #', value, shift);
-  @notNull
-  static int _ors(int a, int b) => JS<int>('!', '# | #', a, b);
-
-  // Assumes i is <= 32-bit
-  @notNull
-  static int _spread(@notNull int i) {
-    i = _ors(i, _shrs(i, 1));
-    i = _ors(i, _shrs(i, 2));
-    i = _ors(i, _shrs(i, 4));
-    i = _ors(i, _shrs(i, 8));
-    i = _shru(_ors(i, _shrs(i, 16)), 0);
-    return i;
-  }
-
   @notNull
   int operator ~() => JS<int>('!', r'(~#) >>> 0', this);
 }
diff --git a/sdk/lib/_internal/js_runtime/lib/js_number.dart b/sdk/lib/_internal/js_runtime/lib/js_number.dart
index f217b53..356a4c0 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_number.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_number.dart
@@ -531,8 +531,7 @@
   }
 
   static int _clz32(int uint32) {
-    // TODO(sra): Use `Math.clz32(uint32)` (not available on IE11).
-    return 32 - _bitCount(_spread(uint32));
+    return JS('JSUInt31', 'Math.clz32(#)', uint32);
   }
 
   // Returns pow(this, e) % m.
@@ -684,47 +683,6 @@
     return _binaryGcd(x, y, false);
   }
 
-  // Assumes i is <= 32-bit and unsigned.
-  static int _bitCount(int i) {
-    // See "Hacker's Delight", section 5-1, "Counting 1-Bits".
-
-    // The basic strategy is to use "divide and conquer" to
-    // add pairs (then quads, etc.) of bits together to obtain
-    // sub-counts.
-    //
-    // A straightforward approach would look like:
-    //
-    // i = (i & 0x55555555) + ((i >>  1) & 0x55555555);
-    // i = (i & 0x33333333) + ((i >>  2) & 0x33333333);
-    // i = (i & 0x0F0F0F0F) + ((i >>  4) & 0x0F0F0F0F);
-    // i = (i & 0x00FF00FF) + ((i >>  8) & 0x00FF00FF);
-    // i = (i & 0x0000FFFF) + ((i >> 16) & 0x0000FFFF);
-    //
-    // The code below removes unnecessary &'s and uses a
-    // trick to remove one instruction in the first line.
-
-    i = _shru(i, 0) - (_shru(i, 1) & 0x55555555);
-    i = (i & 0x33333333) + (_shru(i, 2) & 0x33333333);
-    i = 0x0F0F0F0F & (i + _shru(i, 4));
-    i += _shru(i, 8);
-    i += _shru(i, 16);
-    return (i & 0x0000003F);
-  }
-
-  static int _shru(int value, int shift) => JS('int', '# >>> #', value, shift);
-  static int _shrs(int value, int shift) => JS('int', '# >> #', value, shift);
-  static int _ors(int a, int b) => JS('int', '# | #', a, b);
-
-  // Assumes i is <= 32-bit
-  static int _spread(int i) {
-    i = _ors(i, _shrs(i, 1));
-    i = _ors(i, _shrs(i, 2));
-    i = _ors(i, _shrs(i, 4));
-    i = _ors(i, _shrs(i, 8));
-    i = _shru(_ors(i, _shrs(i, 16)), 0);
-    return i;
-  }
-
   Type get runtimeType => int;
 
   int operator ~() => JS('JSUInt32', r'(~#) >>> 0', this);
diff --git a/tools/VERSION b/tools/VERSION
index 8f16444..9a42697 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 18
 PATCH 0
-PRERELEASE 120
+PRERELEASE 121
 PRERELEASE_PATCH 0
\ No newline at end of file