Version 2.6.0-dev.8.2

* Cherry-pick 8b3d76dff19e8ff67169db867a51d9a9d4d19f7b to dev
* Cherry-pick 5fd6c8a3c19b062887b5830b37bfeb2347eb4d17 to dev
* Cherry-pick b359ac0a1e5b2fa16ec71d6e5788f53b82903057 to dev
* Cherry-pick 2be376385cf06bcf787614fa990c955973eded45 to dev
* Cherry-pick 1a747c6546a1713679266e41828680c14f2305e0 to dev
* Cherry-pick 9e06f24c92b879ee9c6062958e74d07ca6c895c7 to dev
* Cherry-pick 2c1d405c15bcfb2f325d4ac8b89c7452e710a8ba to dev
* Cherry-pick c8b903c2f94f57b666d543bba7890c4940f03994 to dev
* Cherry-pick c49378aadf30cc81f90bf56b2d0dbb969c64e80e to dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6ee98ea..c77e474 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,12 +1,12 @@
-## Next release
-(Add new changes here, and they will be copied to the change section for the
- next release)
+## 2.6.0 - 2019-11-05
 
 ### Language
 
-*   [Static extension members][]: A new language feature allowing
+*   **[IN PREVIEW]** [Static extension members][]: A new language feature allowing
     specially declared static functions to be invoked
-    like instance members on expressions of appropriate static types.
+    like instance members on expressions of appropriate static types
+    is available in preview.
+
     Static extension members are declared using a new `extension`
     declaration. Example:
     ```dart
@@ -85,6 +85,26 @@
 * Added a new tool for AOT compiling Dart programs to native, self-contained
 executables. See https://dart.dev/tools/dart2native for additional details.
 
+### Foreign Function Interface (`dart:ffi`)
+
+*   **Breaking change**: The API now makes use of static extension members.
+    Static extension members enable the `dart:ffi` API to be more precise with
+    types, and provide convenient access to memory through extension getters and
+    setters. The extension members on `Pointer` provide `.value` and `.value =`
+    for accessing the value in native memory and `[]` and `[]=` for indexed access.
+    The method `asExternalTypedData` has been replaced with `asTypedList` extension
+    methods. And finally, `Structs` do no longer have a type argument and are
+    accessed the extension member `.ref` on `Pointer`.
+    These changes makes the code using `dart:ffi` much more concise.
+*   **Breaking change**: The memory management has been removed (`Pointer.allocate`
+    and `Pointer.free`). Instead, memory management is available in
+    [package:ffi](https://pub.dev/packages/ffi).
+*   **Breaking change**: `Pointer.offsetBy` was removed, use `cast` and `elementAt`
+    instead.
+*   Faster memory load and stores.
+*   The dartanalyzer (commandline and IDEs) now reports `dart:ffi` static errors.
+*   Callbacks are now supported in AOT (ahead-of-time) compiled code.
+
 ### Dart for the Web
 
 #### Dart Dev Compiler (DDC)
@@ -94,8 +114,6 @@
 
 ### Tools
 
-#### Pub
-
 #### Linter
 
 The Linter was updated to `0.1.101`, which includes:
diff --git a/pkg/analyzer/lib/src/generated/ffi_verifier.dart b/pkg/analyzer/lib/src/generated/ffi_verifier.dart
index 467f542..38a0dbe 100644
--- a/pkg/analyzer/lib/src/generated/ffi_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/ffi_verifier.dart
@@ -141,7 +141,7 @@
       element.name == 'DynamicLibrary' && element.library.name == 'dart.ffi';
 
   /// Return `true` if the given [element] represents the class `Pointer`.
-  bool _isPointer(ClassElement element) =>
+  bool _isPointer(Element element) =>
       element.name == 'Pointer' && element.library.name == 'dart.ffi';
 
   /// Return `true` if the [typeName] represents a subtype of `Struct`.
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi_definitions.dart
index d48f9fc..78d3d6a 100644
--- a/pkg/vm/lib/transformations/ffi_definitions.dart
+++ b/pkg/vm/lib/transformations/ffi_definitions.dart
@@ -312,7 +312,9 @@
         FunctionNode(
             ReturnStatement(MethodInvocation(pointer, castMethod.name,
                 Arguments([], types: [nativeType]), castMethod)),
-            returnType: pointerType));
+            returnType: pointerType),
+        fileUri: field.fileUri)
+      ..fileOffset = field.fileOffset;
 
     // Sample output:
     // double get x => _xPtr.value;
@@ -328,7 +330,9 @@
                   PropertyGet(ThisExpression(), pointerName, pointerGetter),
                   ConstantExpression(IntConstant(0))
                 ], types: typeArguments))),
-            returnType: field.type));
+            returnType: field.type),
+        fileUri: field.fileUri)
+      ..fileOffset = field.fileOffset;
 
     // Sample output:
     // set x(double v) { _xPtr.value = v; };
@@ -349,7 +353,9 @@
                     VariableGet(argument)
                   ], types: typeArguments))),
               returnType: VoidType(),
-              positionalParameters: [argument]));
+              positionalParameters: [argument]),
+          fileUri: field.fileUri)
+        ..fileOffset = field.fileOffset;
     }
 
     replacedGetters[field] = getter;
diff --git a/runtime/bin/ffi_test/ffi_test_functions.cc b/runtime/bin/ffi_test/ffi_test_functions.cc
index 784093e..82ac14a 100644
--- a/runtime/bin/ffi_test/ffi_test_functions.cc
+++ b/runtime/bin/ffi_test/ffi_test_functions.cc
@@ -120,6 +120,14 @@
   return retval;
 }
 
+// Used in regress_39044_test.dart.
+DART_EXPORT int64_t Regress39044(int64_t a, int8_t b) {
+  std::cout << "Regress39044(" << a << ", " << static_cast<int>(b) << ")\n";
+  const int64_t retval = a - b;
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
 // Performs some computation on various sized unsigned ints.
 // Used for testing value ranges for unsigned ints.
 DART_EXPORT int64_t UintComputation(uint8_t a,
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 671ebd3..6990780 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -1106,7 +1106,8 @@
 bool ConstantInstr::AttributesEqual(Instruction* other) const {
   ConstantInstr* other_constant = other->AsConstant();
   ASSERT(other_constant != NULL);
-  return (value().raw() == other_constant->value().raw());
+  return (value().raw() == other_constant->value().raw() &&
+          representation() == other_constant->representation());
 }
 
 UnboxedConstantInstr::UnboxedConstantInstr(const Object& value,
@@ -5741,12 +5742,10 @@
   ASSERT(((1 << CallingConventions::kFirstCalleeSavedCpuReg) &
           CallingConventions::kArgumentRegisters) == 0);
 
-#if defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_IA32)
-  constexpr intptr_t kNumTemps = 2;
-#elif defined(TARGET_ARCH_ARM)
+#if defined(TARGET_ARCH_ARM)
   constexpr intptr_t kNumTemps = 3;
 #else
-  constexpr intptr_t kNumTemps = 1;
+  constexpr intptr_t kNumTemps = 2;
 #endif
 
   LocationSummary* summary = new (zone)
@@ -5758,11 +5757,8 @@
                       CallingConventions::kFirstNonArgumentRegister));
   summary->set_temp(0, Location::RegisterLocation(
                            CallingConventions::kSecondNonArgumentRegister));
-#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM64) ||                 \
-    defined(TARGET_ARCH_ARM)
   summary->set_temp(1, Location::RegisterLocation(
                            CallingConventions::kFirstCalleeSavedCpuReg));
-#endif
 #if defined(TARGET_ARCH_ARM)
   summary->set_temp(2, Location::RegisterLocation(
                            CallingConventions::kSecondCalleeSavedCpuReg));
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 8a986f7..1d09580 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -997,6 +997,7 @@
 
 void FfiCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const Register saved_fp = locs()->temp(0).reg();
+  const Register temp = locs()->temp(1).reg();
   const Register branch = locs()->in(TargetAddressIndex()).reg();
 
   // Save frame pointer because we're going to update it when we enter the exit
@@ -1020,8 +1021,8 @@
   for (intptr_t i = 0, n = NativeArgCount(); i < n; ++i) {
     const Location origin = rebase.Rebase(locs()->in(i));
     const Location target = arg_locations_[i];
-    NoTemporaryAllocator no_temp;
-    compiler->EmitMove(target, origin, &no_temp);
+    ConstantTemporaryAllocator temp_alloc(temp);
+    compiler->EmitMove(target, origin, &temp_alloc);
   }
 
   // We need to copy the return address up into the dummy stack frame so the
@@ -1037,15 +1038,14 @@
                                  RawPcDescriptors::Kind::kOther, locs());
 
   // Update information in the thread object and enter a safepoint.
-  const Register tmp = locs()->temp(1).reg();
   if (CanExecuteGeneratedCodeInSafepoint()) {
-    __ TransitionGeneratedToNative(branch, FPREG, saved_fp, tmp,
+    __ TransitionGeneratedToNative(branch, FPREG, saved_fp, temp,
                                    /*enter_safepoint=*/true);
 
     __ blx(branch);
 
     // Update information in the thread object and leave the safepoint.
-    __ TransitionNativeToGenerated(saved_fp, tmp, /*leave_safepoint=*/true);
+    __ TransitionNativeToGenerated(saved_fp, temp, /*leave_safepoint=*/true);
   } else {
     // We cannot trust that this code will be executable within a safepoint.
     // Therefore we delegate the responsibility of entering/exiting the
@@ -1057,7 +1057,7 @@
                         call_native_through_safepoint_entry_point_offset()));
 
     // Calls R8 in a safepoint and clobbers NOTFP and R4.
-    ASSERT(branch == R8 && tmp == NOTFP && locs()->temp(2).reg() == R4);
+    ASSERT(branch == R8 && temp == NOTFP && locs()->temp(2).reg() == R4);
     __ blx(TMP);
   }
 
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 1d934ec..220940e 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -874,9 +874,9 @@
 }
 
 void FfiCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register saved_fp = locs()->temp(0).reg();
-  Register temp = locs()->temp(1).reg();
-  Register branch = locs()->in(TargetAddressIndex()).reg();
+  const Register saved_fp = locs()->temp(0).reg();
+  const Register temp = locs()->temp(1).reg();
+  const Register branch = locs()->in(TargetAddressIndex()).reg();
 
   // Save frame pointer because we're going to update it when we enter the exit
   // frame.
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index b6daf52..3e7d0eb 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -924,9 +924,9 @@
 }
 
 void FfiCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register saved_fp = locs()->temp(0).reg();  // volatile
+  const Register saved_fp = locs()->temp(0).reg();
+  const Register temp = locs()->temp(1).reg();
   const Register branch = locs()->in(TargetAddressIndex()).reg();
-  const Register tmp = locs()->temp(1).reg();  // callee-saved
 
   // Save frame pointer because we're going to update it when we enter the exit
   // frame.
@@ -949,8 +949,8 @@
   for (intptr_t i = 0, n = NativeArgCount(); i < n; ++i) {
     const Location origin = rebase.Rebase(locs()->in(i));
     const Location target = arg_locations_[i];
-    ConstantTemporaryAllocator tmp_alloc(tmp);
-    compiler->EmitMove(target, origin, &tmp_alloc);
+    ConstantTemporaryAllocator temp_alloc(temp);
+    compiler->EmitMove(target, origin, &temp_alloc);
   }
 
   // We need to copy a dummy return address up into the dummy stack frame so the
@@ -961,27 +961,27 @@
   compiler->EmitCallsiteMetadata(TokenPosition::kNoSource, DeoptId::kNone,
                                  RawPcDescriptors::Kind::kOther, locs());
   __ Bind(&get_pc);
-  __ popl(tmp);
-  __ movl(compiler::Address(FPREG, kSavedCallerPcSlotFromFp * kWordSize), tmp);
+  __ popl(temp);
+  __ movl(compiler::Address(FPREG, kSavedCallerPcSlotFromFp * kWordSize), temp);
 
   if (CanExecuteGeneratedCodeInSafepoint()) {
-    __ TransitionGeneratedToNative(branch, FPREG, tmp,
+    __ TransitionGeneratedToNative(branch, FPREG, temp,
                                    /*enter_safepoint=*/true);
     __ call(branch);
-    __ TransitionNativeToGenerated(tmp, /*leave_safepoint=*/true);
+    __ TransitionNativeToGenerated(temp, /*leave_safepoint=*/true);
   } else {
     // We cannot trust that this code will be executable within a safepoint.
     // Therefore we delegate the responsibility of entering/exiting the
     // safepoint to a stub which in the VM isolate's heap, which will never lose
     // execute permission.
-    __ movl(tmp,
+    __ movl(temp,
             compiler::Address(
                 THR, compiler::target::Thread::
                          call_native_through_safepoint_entry_point_offset()));
 
     // Calls EAX within a safepoint and clobbers EBX.
-    ASSERT(tmp == EBX && branch == EAX);
-    __ call(tmp);
+    ASSERT(temp == EBX && branch == EAX);
+    __ call(temp);
   }
 
   // The x86 calling convention requires floating point values to be returned on
@@ -1000,7 +1000,7 @@
   __ LeaveFrame();
 
   // Instead of returning to the "fake" return address, we just pop it.
-  __ popl(tmp);
+  __ popl(temp);
 }
 
 void NativeEntryInstr::SaveArgument(FlowGraphCompiler* compiler,
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index dc394bf..e1beb73 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -933,8 +933,9 @@
 }
 
 void FfiCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register saved_fp = locs()->temp(0).reg();
-  Register target_address = locs()->in(TargetAddressIndex()).reg();
+  const Register saved_fp = locs()->temp(0).reg();
+  const Register temp = locs()->temp(1).reg();
+  const Register target_address = locs()->in(TargetAddressIndex()).reg();
 
   // Save frame pointer because we're going to update it when we enter the exit
   // frame.
@@ -960,8 +961,8 @@
   for (intptr_t i = 0, n = NativeArgCount(); i < n; ++i) {
     const Location origin = rebase.Rebase(locs()->in(i));
     const Location target = arg_locations_[i];
-    NoTemporaryAllocator temp;
-    compiler->EmitMove(target, rebase.Rebase(origin), &temp);
+    ConstantTemporaryAllocator temp_alloc(temp);
+    compiler->EmitMove(target, rebase.Rebase(origin), &temp_alloc);
   }
 
   // We need to copy a dummy return address up into the dummy stack frame so the
diff --git a/runtime/vm/compiler/backend/locations.cc b/runtime/vm/compiler/backend/locations.cc
index 37b17c7..210cd37 100644
--- a/runtime/vm/compiler/backend/locations.cc
+++ b/runtime/vm/compiler/backend/locations.cc
@@ -306,7 +306,8 @@
     intptr_t index = fpu_reg_slots[loc.fpu_reg()];
     ASSERT(index >= 0);
     switch (def->representation()) {
-      case kUnboxedDouble:
+      case kUnboxedDouble:  // SlowPathEnvironmentFor sees _one_ register
+      case kUnboxedFloat:   // both for doubles and floats.
         return Location::DoubleStackSlot(
             compiler::target::frame_layout.FrameSlotForVariableIndex(-index),
             FPREG);
diff --git a/runtime/vm/heap/freelist.cc b/runtime/vm/heap/freelist.cc
index c98af37..e77f199 100644
--- a/runtime/vm/heap/freelist.cc
+++ b/runtime/vm/heap/freelist.cc
@@ -323,14 +323,24 @@
   intptr_t remainder_index = IndexForSize(remainder_size);
   EnqueueElement(element, remainder_index);
 
-  // Postcondition: when allocating in a protected page, the remainder
-  // element is no longer writable unless it is in the same page as the
-  // allocated element.  (The allocated element is still writable, and the
-  // remainder element will be protected when the allocated one is).
-  if (is_protected &&
-      !VirtualMemory::InSamePage(remainder_address - 1, remainder_address)) {
-    VirtualMemory::Protect(reinterpret_cast<void*>(remainder_address),
-                           remainder_size, VirtualMemory::kReadExecute);
+  // Postcondition: when allocating in a protected page, the fraction of the
+  // remainder element which does not share a page with the allocated element is
+  // no longer writable. This means that if the remainder's header is not fully
+  // contained in the last page of the allocation, we need to re-protect the
+  // page it ends on.
+  if (is_protected) {
+    const uword remainder_header_size =
+        FreeListElement::HeaderSizeFor(remainder_size);
+    if (!VirtualMemory::InSamePage(
+            remainder_address - 1,
+            remainder_address + remainder_header_size - 1)) {
+      VirtualMemory::Protect(
+          reinterpret_cast<void*>(
+              Utils::RoundUp(remainder_address, VirtualMemory::PageSize())),
+          remainder_address + remainder_header_size -
+              Utils::RoundUp(remainder_address, VirtualMemory::PageSize()),
+          VirtualMemory::kReadExecute);
+    }
   }
 }
 
diff --git a/tests/ffi/regress_38993_test.dart b/tests/ffi/regress_38993_test.dart
new file mode 100644
index 0000000..8c9972f
--- /dev/null
+++ b/tests/ffi/regress_38993_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2019, 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.
+//
+// Tests a compile time error that should not crash the analyzer or CFE.
+
+import "dart:ffi";
+
+class C extends Struct {
+  dynamic x; //# 1: compile-time error
+}
+
+main() {}
diff --git a/tests/ffi/regress_39044_test.dart b/tests/ffi/regress_39044_test.dart
new file mode 100644
index 0000000..785500d
--- /dev/null
+++ b/tests/ffi/regress_39044_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2019, 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.
+//
+// Check that the optimizer does not fuse constants with different
+// representations.
+//
+// SharedObjects=ffi_test_functions
+
+import "dart:ffi";
+
+import "package:expect/expect.dart";
+
+import "dylib_utils.dart";
+
+main() {
+  final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+
+  final intComputation = ffiTestFunctions.lookupFunction<
+      Int64 Function(Int64, Int8), int Function(int, int)>("Regress39044");
+
+  // The arguments are the same Smi constant, however they are different sizes.
+  final result = intComputation(
+      /* dart::kUnboxedInt64 --> int64_t             */ 1,
+      /* dart::kUnboxedInt32 --> truncated to int8_t */ 1);
+
+  Expect.equals(0, result);
+}
diff --git a/tests/ffi/regress_39063_test.dart b/tests/ffi/regress_39063_test.dart
new file mode 100644
index 0000000..52dca18
--- /dev/null
+++ b/tests/ffi/regress_39063_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2019, 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.
+//
+// Check that the optimizer does not fuse constants with different
+// representations.
+//
+// SharedObjects=ffi_test_functions
+
+import "dart:ffi";
+
+import "package:expect/expect.dart";
+
+import "dylib_utils.dart";
+
+typedef VigesimalOp = double Function(
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double);
+
+typedef NativeVigesimalOp = Double Function(
+    IntPtr,
+    Float,
+    IntPtr,
+    Double,
+    IntPtr,
+    Float,
+    IntPtr,
+    Double,
+    IntPtr,
+    Float,
+    IntPtr,
+    Double,
+    IntPtr,
+    Float,
+    IntPtr,
+    Double,
+    IntPtr,
+    Float,
+    IntPtr,
+    Double);
+
+main() {
+  final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+
+  final sumManyNumbers = ffiTestFunctions
+      .lookupFunction<NativeVigesimalOp, VigesimalOp>("SumManyNumbers");
+
+  // Should not crash.
+  sumManyNumbers(1, 2.0, 3, 4.0, 5, 6.0, 7, 8.0, 9, 10.0, 11, 12.0, 13, 14.0,
+      15, 16.0, 17, 18.0, 19, 20.0);
+}
diff --git a/tests/ffi/regress_39068_test.dart b/tests/ffi/regress_39068_test.dart
new file mode 100644
index 0000000..fbfca38
--- /dev/null
+++ b/tests/ffi/regress_39068_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2019, 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.
+//
+// SharedObjects=ffi_test_functions
+
+import "dart:ffi";
+
+import "package:expect/expect.dart";
+
+import "dylib_utils.dart";
+
+typedef VigesimalOp = double Function(
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double);
+
+typedef NativeVigesimalOp = Double Function(
+    IntPtr,
+    Float,
+    IntPtr,
+    Double,
+    IntPtr,
+    Float,
+    IntPtr,
+    Double,
+    IntPtr,
+    Float,
+    IntPtr,
+    Double,
+    IntPtr,
+    Float,
+    IntPtr,
+    Double,
+    IntPtr,
+    Float,
+    IntPtr,
+    Double);
+
+main() {
+  final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+
+  final sumManyNumbers = ffiTestFunctions
+      .lookupFunction<NativeVigesimalOp, VigesimalOp>("SumManyNumbers");
+
+  try {
+    sumManyNumbers(1, 2.0, 3, 4.0, 5, 6.0, 7, 8.0, 9, 10.0, 11, 12.0, 13, 14.0,
+        15, 16.0, 17, 18.0, null, 20.0);
+  } on Error {
+    print('Expected exception on passing null for int');
+  }
+}
diff --git a/tools/VERSION b/tools/VERSION
index 3393977..a6ba21a7 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -34,6 +34,6 @@
 MINOR 6
 PATCH 0
 PRERELEASE 8
-PRERELEASE_PATCH 1
+PRERELEASE_PATCH 2
 ABI_VERSION 19
 OLDEST_SUPPORTED_ABI_VERSION 18