Version 1.10.0-dev.1.7

svn merge -c 45139 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 45182 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 45215 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 45223 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 45253 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 45254 https://dart.googlecode.com/svn/branches/bleeding_edge trunk


git-svn-id: https://dart.googlecode.com/svn/trunk@45268 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/dart/runtime/lib/bigint.dart b/dart/runtime/lib/bigint.dart
index 78b5cc5..f4ff408 100644
--- a/dart/runtime/lib/bigint.dart
+++ b/dart/runtime/lib/bigint.dart
@@ -1042,10 +1042,13 @@
     if (_compareDigits(r_digits, r_used, t_digits, t_used) >= 0) {
       assert(i == r_used);
       r_digits[r_used++] = 1;  // Quotient = 1.
-      r_digits[r_used] = 0;  // Leading zero.
       // Subtract divisor from remainder.
       _absSub(r_digits, r_used, t_digits, t_used, r_digits);
+    } else {
+      // Account for possible carry in _mulAdd step.
+      r_digits[r_used++] = 0;
     }
+    r_digits[r_used] = 0;  // Leading zero for 64-bit processing.
     // Negate y so we can later use _mulAdd instead of non-existent _mulSub.
     var ny_digits = new Uint32List(y_used + 2);
     ny_digits[y_used] = 1;
@@ -1137,10 +1140,13 @@
     if (_compareDigits(r_digits, r_used, t_digits, t_used) >= 0) {
       assert(i == r_used);
       r_digits[r_used++] = 1;  // Quotient = 1.
-      r_digits[r_used] = 0;  // Leading zero.
       // Subtract divisor from remainder.
       _absSub(r_digits, r_used, t_digits, t_used, r_digits);
+    } else {
+      // Account for possible carry in _mulAdd step.
+      r_digits[r_used++] = 0;
     }
+    r_digits[r_used] = 0;  // Leading zero for 64-bit processing.
     // Negated y_digits passed in ny_digits allow the use of _mulAdd instead of
     // unimplemented _mulSub.
     // ny_digits is read-only and has y_used digits (possibly including several
diff --git a/dart/runtime/observatory/lib/app.dart b/dart/runtime/observatory/lib/app.dart
index 6b0a4e1..9bb2df8 100644
--- a/dart/runtime/observatory/lib/app.dart
+++ b/dart/runtime/observatory/lib/app.dart
@@ -15,6 +15,7 @@
 import 'package:observatory/tracer.dart';
 import 'package:observatory/utils.dart';
 import 'package:polymer/polymer.dart';
+import 'package:usage/usage_html.dart';
 
 export 'package:observatory/utils.dart';
 
@@ -25,3 +26,4 @@
 part 'src/app/settings.dart';
 part 'src/app/target_manager.dart';
 part 'src/app/view_model.dart';
+part 'src/app/analytics.dart';
diff --git a/dart/runtime/observatory/lib/src/app/analytics.dart b/dart/runtime/observatory/lib/src/app/analytics.dart
new file mode 100644
index 0000000..fd04156
--- /dev/null
+++ b/dart/runtime/observatory/lib/src/app/analytics.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2015, 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.
+
+part of app;
+
+class Analytics {
+  static final _UA = 'UA-26406144-17';
+  static final _name = 'Observatory';
+  static final _version = '1.10';
+  static final _googleAnalytics = new AnalyticsHtml(_UA, _name, _version);
+
+  static initialize() {
+    // We only send screen views. This is allowed without user permission.
+    // Note, before flipping this to be true we need a UI to allow users to
+    // control this.
+    _googleAnalytics.optIn = false;
+  }
+
+  /// Called whenever an Observatory page is viewed.
+  static Future reportPageView(Uri uri) {
+    // The screen name is the uri's path. e.g. inspect, profile.
+    final screenName = uri.path;
+    return _googleAnalytics.sendScreenView(screenName);
+  }
+}
diff --git a/dart/runtime/observatory/lib/src/app/application.dart b/dart/runtime/observatory/lib/src/app/application.dart
index 090d300..d87d6fb 100644
--- a/dart/runtime/observatory/lib/src/app/application.dart
+++ b/dart/runtime/observatory/lib/src/app/application.dart
@@ -46,6 +46,7 @@
     assert(app == null);
     app = this;
     _registerPages();
+    Analytics.initialize();
     locationManager._init(this);
   }
 
diff --git a/dart/runtime/observatory/lib/src/app/page.dart b/dart/runtime/observatory/lib/src/app/page.dart
index e79f3dc..858e75f 100644
--- a/dart/runtime/observatory/lib/src/app/page.dart
+++ b/dart/runtime/observatory/lib/src/app/page.dart
@@ -27,9 +27,9 @@
   }
 
   /// Called when the page should update its state based on [uri].
-  /// NOTE: Only called when the page is installed.
   void visit(Uri uri, Map argsMap) {
     args = toObservable(argsMap);
+    Analytics.reportPageView(uri);
     _visit(uri);
   }
 
diff --git a/dart/runtime/observatory/observatory_sources.gypi b/dart/runtime/observatory/observatory_sources.gypi
index d16cbd8..fadca29 100644
--- a/dart/runtime/observatory/observatory_sources.gypi
+++ b/dart/runtime/observatory/observatory_sources.gypi
@@ -17,6 +17,7 @@
     'lib/service_common.dart',
     'lib/service_io.dart',
     'lib/service_html.dart',
+    'lib/src/app/analytics.dart',
     'lib/src/app/application.dart',
     'lib/src/app/chart.dart',
     'lib/src/app/location_manager.dart',
diff --git a/dart/runtime/vm/assembler_ia32.cc b/dart/runtime/vm/assembler_ia32.cc
index c060bbf..d876feb 100644
--- a/dart/runtime/vm/assembler_ia32.cc
+++ b/dart/runtime/vm/assembler_ia32.cc
@@ -1771,8 +1771,9 @@
 }
 
 
-void Assembler::shldl(Register dst, Register src) {
+void Assembler::shldl(Register dst, Register src, Register shifter) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+  ASSERT(shifter == ECX);
   EmitUint8(0x0F);
   EmitUint8(0xA5);
   EmitRegisterOperand(src, dst);
@@ -1789,16 +1790,18 @@
 }
 
 
-void Assembler::shldl(const Address& operand, Register src) {
+void Assembler::shldl(const Address& operand, Register src, Register shifter) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+  ASSERT(shifter == ECX);
   EmitUint8(0x0F);
   EmitUint8(0xA5);
   EmitOperand(src, Operand(operand));
 }
 
 
-void Assembler::shrdl(Register dst, Register src) {
+void Assembler::shrdl(Register dst, Register src, Register shifter) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+  ASSERT(shifter == ECX);
   EmitUint8(0x0F);
   EmitUint8(0xAD);
   EmitRegisterOperand(src, dst);
@@ -1815,8 +1818,9 @@
 }
 
 
-void Assembler::shrdl(const Address& dst, Register src) {
+void Assembler::shrdl(const Address& dst, Register src, Register shifter) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+  ASSERT(shifter == ECX);
   EmitUint8(0x0F);
   EmitUint8(0xAD);
   EmitOperand(src, Operand(dst));
diff --git a/dart/runtime/vm/assembler_ia32.h b/dart/runtime/vm/assembler_ia32.h
index a0d03de..edf7634 100644
--- a/dart/runtime/vm/assembler_ia32.h
+++ b/dart/runtime/vm/assembler_ia32.h
@@ -603,12 +603,12 @@
   void sarl(Register reg, const Immediate& imm);
   void sarl(Register operand, Register shifter);
   void sarl(const Address& address, Register shifter);
-  void shldl(Register dst, Register src);
+  void shldl(Register dst, Register src, Register shifter);
   void shldl(Register dst, Register src, const Immediate& imm);
-  void shldl(const Address& operand, Register src);
-  void shrdl(Register dst, Register src);
+  void shldl(const Address& operand, Register src, Register shifter);
+  void shrdl(Register dst, Register src, Register shifter);
   void shrdl(Register dst, Register src, const Immediate& imm);
-  void shrdl(const Address& dst, Register src);
+  void shrdl(const Address& dst, Register src, Register shifter);
 
   void negl(Register reg);
   void notl(Register reg);
diff --git a/dart/runtime/vm/assembler_ia32_test.cc b/dart/runtime/vm/assembler_ia32_test.cc
index 6492625..2fd2866 100644
--- a/dart/runtime/vm/assembler_ia32_test.cc
+++ b/dart/runtime/vm/assembler_ia32_test.cc
@@ -579,7 +579,7 @@
   __ movl(EAX, Immediate(0));
   __ movl(ECX, Immediate(3));
   __ sarl(Address(ESP, 0), ECX);
-  __ shrdl(Address(ESP, 0), EAX);
+  __ shrdl(Address(ESP, 0), EAX, ECX);
   __ cmpl(Address(ESP, 0), Immediate(0x1e000000));
   __ j(EQUAL, &donetest14);
   __ int3();
@@ -592,7 +592,7 @@
   __ movl(EAX, Immediate(-1));
   __ movl(ECX, Immediate(2));
   __ shll(Address(ESP, 0), ECX);
-  __ shldl(Address(ESP, 0), EAX);
+  __ shldl(Address(ESP, 0), EAX, ECX);
   __ cmpl(Address(ESP, 0), Immediate(0xF0000003));
   __ j(EQUAL, &donetest15);
   __ int3();
diff --git a/dart/runtime/vm/assembler_x64.cc b/dart/runtime/vm/assembler_x64.cc
index 7b2d914..410d43b 100644
--- a/dart/runtime/vm/assembler_x64.cc
+++ b/dart/runtime/vm/assembler_x64.cc
@@ -2248,11 +2248,11 @@
 void Assembler::shldl(Register dst, Register src, const Immediate& imm) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   ASSERT(imm.is_int8());
-  Operand operand(src);
-  EmitOperandREX(dst, operand, REX_NONE);
+  Operand operand(dst);
+  EmitOperandREX(src, operand, REX_NONE);
   EmitUint8(0x0F);
   EmitUint8(0xA4);
-  EmitOperand(src & 7, Operand(dst));
+  EmitOperand(src & 7, operand);
   EmitUint8(imm.value() & 0xFF);
 }
 
@@ -2290,11 +2290,11 @@
 void Assembler::shldq(Register dst, Register src, const Immediate& imm) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   ASSERT(imm.is_int8());
-  Operand operand(src);
-  EmitOperandREX(dst, operand, REX_W);
+  Operand operand(dst);
+  EmitOperandREX(src, operand, REX_W);
   EmitUint8(0x0F);
   EmitUint8(0xA4);
-  EmitOperand(src & 7, Operand(dst));
+  EmitOperand(src & 7, operand);
   EmitUint8(imm.value() & 0xFF);
 }
 
@@ -2302,22 +2302,22 @@
 void Assembler::shldq(Register dst, Register src, Register shifter) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   ASSERT(shifter == RCX);
-  Operand operand(src);
-  EmitOperandREX(dst, operand, REX_W);
+  Operand operand(dst);
+  EmitOperandREX(src, operand, REX_W);
   EmitUint8(0x0F);
   EmitUint8(0xA5);
-  EmitOperand(src & 7, Operand(dst));
+  EmitOperand(src & 7, operand);
 }
 
 
 void Assembler::shrdq(Register dst, Register src, Register shifter) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   ASSERT(shifter == RCX);
-  Operand operand(src);
-  EmitOperandREX(dst, operand, REX_W);
+  Operand operand(dst);
+  EmitOperandREX(src, operand, REX_W);
   EmitUint8(0x0F);
   EmitUint8(0xAD);
-  EmitOperand(src & 7, Operand(dst));
+  EmitOperand(src & 7, operand);
 }
 
 
diff --git a/dart/runtime/vm/assembler_x64_test.cc b/dart/runtime/vm/assembler_x64_test.cc
index 85ee637..9989e3b 100644
--- a/dart/runtime/vm/assembler_x64_test.cc
+++ b/dart/runtime/vm/assembler_x64_test.cc
@@ -1360,10 +1360,10 @@
     const int32_t right = 0xffffffff;
     const int32_t shifted = 0xf0000003;
     __ movl(RDX, Immediate(left));
-    __ movl(RAX, Immediate(right));
+    __ movl(R8, Immediate(right));
     __ movl(RCX, Immediate(2));
     __ shll(RDX, RCX);  // RDX = 0xff000000 << 2 == 0xfc000000
-    __ shldl(RDX, RAX, Immediate(2));
+    __ shldl(RDX, R8, Immediate(2));
     // RDX = high32(0xfc000000:0xffffffff << 2) == 0xf0000003
     __ cmpl(RDX, Immediate(shifted));
     __ j(EQUAL, &donetest15a);
@@ -1377,10 +1377,10 @@
     const int64_t right = 0xffffffffffffffff;
     const int64_t shifted = 0xf000000000000003;
     __ movq(RDX, Immediate(left));
-    __ movq(RAX, Immediate(right));
+    __ movq(R8, Immediate(right));
     __ movq(RCX, Immediate(2));
     __ shlq(RDX, RCX);  // RDX = 0xff00000000000000 << 2 == 0xfc00000000000000
-    __ shldq(RDX, RAX, Immediate(2));
+    __ shldq(RDX, R8, Immediate(2));
     // RDX = high64(0xfc00000000000000:0xffffffffffffffff << 2)
     //     == 0xf000000000000003
     __ cmpq(RDX, Immediate(shifted));
@@ -1395,10 +1395,10 @@
     const int64_t right = 0xffffffffffffffff;
     const int64_t shifted = 0xf000000000000003;
     __ movq(RDX, Immediate(left));
-    __ movq(RAX, Immediate(right));
+    __ movq(R8, Immediate(right));
     __ movq(RCX, Immediate(2));
     __ shlq(RDX, RCX);  // RDX = 0xff00000000000000 << 2 == 0xfc00000000000000
-    __ shldq(RDX, RAX, RCX);
+    __ shldq(RDX, R8, RCX);
     // RDX = high64(0xfc00000000000000:0xffffffffffffffff << 2)
     //     == 0xf000000000000003
     __ cmpq(RDX, Immediate(shifted));
@@ -1413,10 +1413,10 @@
     const int64_t right = 0xffffffffffffffff;
     const int64_t shifted = 0xcff0000000000000;
     __ movq(RDX, Immediate(left));
-    __ movq(RAX, Immediate(right));
+    __ movq(R8, Immediate(right));
     __ movq(RCX, Immediate(2));
     __ shrq(RDX, RCX);  // RDX = 0xff00000000000000 >> 2 == 0x3fc0000000000000
-    __ shrdq(RDX, RAX, RCX);
+    __ shrdq(RDX, R8, RCX);
     // RDX = low64(0xffffffffffffffff:0x3fc0000000000000 >> 2)
     //     == 0xcff0000000000000
     __ cmpq(RDX, Immediate(shifted));
diff --git a/dart/runtime/vm/code_generator.cc b/dart/runtime/vm/code_generator.cc
index aa4671f..755cc40 100644
--- a/dart/runtime/vm/code_generator.cc
+++ b/dart/runtime/vm/code_generator.cc
@@ -113,7 +113,7 @@
     Exceptions::ThrowArgumentError(error);
   }
   const intptr_t len = Smi::Cast(length).Value();
-  if (len < 0) {
+  if ((len < 0) || (len > Array::kMaxElements)) {
     const String& error = String::Handle(String::NewFormatted(
         "Length (%" Pd ") must be an integer in the range [0..%" Pd "].",
         len, Array::kMaxElements));
diff --git a/dart/runtime/vm/intermediate_language_ia32.cc b/dart/runtime/vm/intermediate_language_ia32.cc
index 6d70aa4..5ea1fa2 100644
--- a/dart/runtime/vm/intermediate_language_ia32.cc
+++ b/dart/runtime/vm/intermediate_language_ia32.cc
@@ -6171,7 +6171,7 @@
         __ cmpl(ECX, Immediate(31));
         __ j(ABOVE, &large_shift);
 
-        __ shrdl(left_lo, left_hi);  // Shift count in CL.
+        __ shrdl(left_lo, left_hi, ECX);  // Shift count in CL.
         __ sarl(left_hi, ECX);  // Shift count in CL.
         __ jmp(&done, Assembler::kNearJump);
 
@@ -6190,7 +6190,7 @@
           __ cmpl(ECX, Immediate(31));
           __ j(ABOVE, &large_shift);
 
-          __ shldl(left_hi, left_lo);  // Shift count in CL.
+          __ shldl(left_hi, left_lo, ECX);  // Shift count in CL.
           __ shll(left_lo, ECX);  // Shift count in CL.
           // Check for overflow by shifting back the high 32 bits
           // and comparing with the input.
@@ -6221,7 +6221,7 @@
           __ cmpl(ECX, Immediate(31));
           __ j(ABOVE, &large_shift);
 
-          __ shldl(left_hi, left_lo);  // Shift count in CL.
+          __ shldl(left_hi, left_lo, ECX);  // Shift count in CL.
           __ shll(left_lo, ECX);  // Shift count in CL.
           __ jmp(&done, Assembler::kNearJump);
 
diff --git a/dart/runtime/vm/intrinsifier_arm.cc b/dart/runtime/vm/intrinsifier_arm.cc
index 5705f29..ffd6655 100644
--- a/dart/runtime/vm/intrinsifier_arm.cc
+++ b/dart/runtime/vm/intrinsifier_arm.cc
@@ -20,6 +20,13 @@
 
 DECLARE_FLAG(bool, enable_type_checks);
 
+// When entering intrinsics code:
+// R5: IC Data
+// R4: Arguments descriptor
+// LR: Return address
+// The R5, R4 registers can be destroyed only if there is no slow-path, i.e.
+// if the intrinsified method always executes a return.
+// The FP register should not be modified, because it is used by the profiler.
 
 #define __ assembler->
 
diff --git a/dart/runtime/vm/intrinsifier_arm64.cc b/dart/runtime/vm/intrinsifier_arm64.cc
index baf7a66..402c262 100644
--- a/dart/runtime/vm/intrinsifier_arm64.cc
+++ b/dart/runtime/vm/intrinsifier_arm64.cc
@@ -19,6 +19,13 @@
 
 DECLARE_FLAG(bool, enable_type_checks);
 
+// When entering intrinsics code:
+// R5: IC Data
+// R4: Arguments descriptor
+// LR: Return address
+// The R5, R4 registers can be destroyed only if there is no slow-path, i.e.
+// if the intrinsified method always executes a return.
+// The FP register should not be modified, because it is used by the profiler.
 
 #define __ assembler->
 
diff --git a/dart/runtime/vm/intrinsifier_ia32.cc b/dart/runtime/vm/intrinsifier_ia32.cc
index a73612d..66ea7d0 100644
--- a/dart/runtime/vm/intrinsifier_ia32.cc
+++ b/dart/runtime/vm/intrinsifier_ia32.cc
@@ -26,6 +26,13 @@
 
 DECLARE_FLAG(bool, enable_type_checks);
 
+// When entering intrinsics code:
+// ECX: IC Data
+// EDX: Arguments descriptor
+// TOS: Return address
+// The ECX, EDX registers can be destroyed only if there is no slow-path, i.e.
+// if the intrinsified method always executes a return.
+// The EBP register should not be modified, because it is used by the profiler.
 
 #define __ assembler->
 
@@ -572,7 +579,7 @@
   __ movl(EAX, EBX);
   __ shll(EBX, ECX);
   __ xorl(EDI, EDI);
-  __ shldl(EDI, EAX);
+  __ shldl(EDI, EAX, ECX);
   // Result in EDI (high) and EBX (low).
   const Class& mint_class = Class::Handle(
       Isolate::Current()->object_store()->mint_class());
@@ -806,12 +813,80 @@
 
 
 void Intrinsifier::Bigint_lsh(Assembler* assembler) {
-  // TODO(regis): Implement.
+  // static void _lsh(Uint32List x_digits, int x_used, int n,
+  //                  Uint32List r_digits)
+
+  __ movl(EDI, Address(ESP, 4 * kWordSize));  // x_digits
+  __ movl(ECX, Address(ESP, 2 * kWordSize));  // n is Smi
+  __ SmiUntag(ECX);
+  __ movl(EBX, Address(ESP, 1 * kWordSize));  // r_digits
+  __ movl(ESI, ECX);
+  __ sarl(ESI, Immediate(5));  // ESI = n ~/ _DIGIT_BITS.
+  __ leal(EBX, FieldAddress(EBX, ESI, TIMES_4, TypedData::data_offset()));
+  __ movl(ESI, Address(ESP, 3 * kWordSize));  // x_used > 0, Smi.
+  __ SmiUntag(ESI);
+  __ decl(ESI);
+  __ xorl(EAX, EAX);  // EAX = 0.
+  __ movl(EDX, FieldAddress(EDI, ESI, TIMES_4, TypedData::data_offset()));
+  __ shldl(EAX, EDX, ECX);
+  __ movl(Address(EBX, ESI, TIMES_4, Bigint::kBytesPerDigit), EAX);
+  Label last;
+  __ cmpl(ESI, Immediate(0));
+  __ j(EQUAL, &last, Assembler::kNearJump);
+  Label loop;
+  __ Bind(&loop);
+  __ movl(EAX, EDX);
+  __ movl(EDX,
+          FieldAddress(EDI, ESI, TIMES_4,
+                       TypedData::data_offset() - Bigint::kBytesPerDigit));
+  __ shldl(EAX, EDX, ECX);
+  __ movl(Address(EBX, ESI, TIMES_4, 0), EAX);
+  __ decl(ESI);
+  __ j(NOT_ZERO, &loop, Assembler::kNearJump);
+  __ Bind(&last);
+  __ shldl(EDX, ESI, ECX);  // ESI == 0.
+  __ movl(Address(EBX, 0), EDX);
+  // Returning Object::null() is not required, since this method is private.
+  __ ret();
 }
 
 
 void Intrinsifier::Bigint_rsh(Assembler* assembler) {
-  // TODO(regis): Implement.
+  // static void _rsh(Uint32List x_digits, int x_used, int n,
+  //                  Uint32List r_digits)
+
+  __ movl(EDI, Address(ESP, 4 * kWordSize));  // x_digits
+  __ movl(ECX, Address(ESP, 2 * kWordSize));  // n is Smi
+  __ SmiUntag(ECX);
+  __ movl(EBX, Address(ESP, 1 * kWordSize));  // r_digits
+  __ movl(EDX, ECX);
+  __ sarl(EDX, Immediate(5));  // EDX = n ~/ _DIGIT_BITS.
+  __ movl(ESI, Address(ESP, 3 * kWordSize));  // x_used > 0, Smi.
+  __ SmiUntag(ESI);
+  __ decl(ESI);
+  // EDI = &x_digits[x_used - 1].
+  __ leal(EDI, FieldAddress(EDI, ESI, TIMES_4, TypedData::data_offset()));
+  __ subl(ESI, EDX);
+  // EBX = &r_digits[x_used - 1 - (n ~/ 32)].
+  __ leal(EBX, FieldAddress(EBX, ESI, TIMES_4, TypedData::data_offset()));
+  __ negl(ESI);
+  __ movl(EDX, Address(EDI, ESI, TIMES_4, 0));
+  Label last;
+  __ cmpl(ESI, Immediate(0));
+  __ j(EQUAL, &last, Assembler::kNearJump);
+  Label loop;
+  __ Bind(&loop);
+  __ movl(EAX, EDX);
+  __ movl(EDX, Address(EDI, ESI, TIMES_4, Bigint::kBytesPerDigit));
+  __ shrdl(EAX, EDX, ECX);
+  __ movl(Address(EBX, ESI, TIMES_4, 0), EAX);
+  __ incl(ESI);
+  __ j(NOT_ZERO, &loop, Assembler::kNearJump);
+  __ Bind(&last);
+  __ shrdl(EDX, ESI, ECX);  // ESI == 0.
+  __ movl(Address(EBX, 0), EDX);
+  // Returning Object::null() is not required, since this method is private.
+  __ ret();
 }
 
 
diff --git a/dart/runtime/vm/intrinsifier_mips.cc b/dart/runtime/vm/intrinsifier_mips.cc
index 63c7ac0..54a63c0 100644
--- a/dart/runtime/vm/intrinsifier_mips.cc
+++ b/dart/runtime/vm/intrinsifier_mips.cc
@@ -19,6 +19,14 @@
 
 DECLARE_FLAG(bool, enable_type_checks);
 
+// When entering intrinsics code:
+// S5: IC Data
+// S4: Arguments descriptor
+// RA: Return address
+// The S5, S4 registers can be destroyed only if there is no slow-path, i.e.
+// if the intrinsified method always executes a return.
+// The FP register should not be modified, because it is used by the profiler.
+
 #define __ assembler->
 
 
diff --git a/dart/runtime/vm/intrinsifier_x64.cc b/dart/runtime/vm/intrinsifier_x64.cc
index 9a5baf3..d34759f 100644
--- a/dart/runtime/vm/intrinsifier_x64.cc
+++ b/dart/runtime/vm/intrinsifier_x64.cc
@@ -23,8 +23,9 @@
 // RBX: IC Data
 // R10: Arguments descriptor
 // TOS: Return address
-// The RBX, R10 registers can be destroyed only if there is no slow-path (i.e.,
-// the methods returns true).
+// The RBX, R10 registers can be destroyed only if there is no slow-path, i.e.
+// if the intrinsified method always executes a return.
+// The RBP register should not be modified, because it is used by the profiler.
 
 #define __ assembler->
 
@@ -757,8 +758,7 @@
   __ decq(R8);
   __ j(NOT_ZERO, &loop, Assembler::kNearJump);
   __ Bind(&last);
-  __ xorq(RAX, RAX);  // RAX = 0.
-  __ shldq(RDX, RAX, RCX);
+  __ shldq(RDX, R8, RCX);  // R8 == 0.
   __ movq(Address(RBX, 0), RDX);
   // Returning Object::null() is not required, since this method is private.
   __ ret();
@@ -770,34 +770,33 @@
   //                  Uint32List r_digits)
 
   __ movq(RDI, Address(RSP, 4 * kWordSize));  // x_digits
-  __ movq(R8, Address(RSP, 3 * kWordSize));  // x_used is Smi
-  __ subq(R8, Immediate(2));  // x_used > 0, Smi. R8 = x_used - 1, round up.
-  __ sarq(R8, Immediate(2));
   __ movq(RCX, Address(RSP, 2 * kWordSize));  // n is Smi
   __ SmiUntag(RCX);
   __ movq(RBX, Address(RSP, 1 * kWordSize));  // r_digits
-  __ movq(RSI, RCX);
-  __ sarq(RSI, Immediate(6));  // RSI = n ~/ (2*_DIGIT_BITS).
+  __ movq(RDX, RCX);
+  __ sarq(RDX, Immediate(6));  // RDX = n ~/ (2*_DIGIT_BITS).
+  __ movq(RSI, Address(RSP, 3 * kWordSize));  // x_used is Smi
+  __ subq(RSI, Immediate(2));  // x_used > 0, Smi. RSI = x_used - 1, round up.
+  __ sarq(RSI, Immediate(2));
   __ leaq(RDI, FieldAddress(RDI, RSI, TIMES_8, TypedData::data_offset()));
-  __ movq(RDX, Address(RDI, 0));
-  __ subq(R8, RSI);  // R8 + 1 = number of digit pairs to read.
+  __ subq(RSI, RDX);  // RSI + 1 = number of digit pairs to read.
+  __ leaq(RBX, FieldAddress(RBX, RSI, TIMES_8, TypedData::data_offset()));
+  __ negq(RSI);
+  __ movq(RDX, Address(RDI, RSI, TIMES_8, 0));
   Label last;
-  __ cmpq(R8, Immediate(0));
+  __ cmpq(RSI, Immediate(0));
   __ j(EQUAL, &last, Assembler::kNearJump);
-  __ xorq(R9, R9);  // R9 = 0.
   Label loop;
   __ Bind(&loop);
   __ movq(RAX, RDX);
-  __ movq(RDX, Address(RDI, R9, TIMES_8, 2 * Bigint::kBytesPerDigit));
+  __ movq(RDX, Address(RDI, RSI, TIMES_8, 2 * Bigint::kBytesPerDigit));
   __ shrdq(RAX, RDX, RCX);
-  __ movq(FieldAddress(RBX, R9, TIMES_8, TypedData::data_offset()), RAX);
-  __ incq(R9);
-  __ cmpq(R9, R8);
-  __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
+  __ movq(Address(RBX, RSI, TIMES_8, 0), RAX);
+  __ incq(RSI);
+  __ j(NOT_ZERO, &loop, Assembler::kNearJump);
   __ Bind(&last);
-  __ xorq(RAX, RAX);  // RAX = 0.
-  __ shrdq(RDX, RAX, RCX);
-  __ movq(FieldAddress(RBX, R8, TIMES_8, TypedData::data_offset()), RDX);
+  __ shrdq(RDX, RSI, RCX);  // RSI == 0.
+  __ movq(Address(RBX, 0), RDX);
   // Returning Object::null() is not required, since this method is private.
   __ ret();
 }
@@ -1782,7 +1781,7 @@
   const intptr_t kStartIndexOffset = 2 * kWordSize;
   const intptr_t kEndIndexOffset = 1 * kWordSize;
   Label fall_through, ok;
-  __ movq(RSI, Address(RSP, + kEndIndexOffset));
+  __ movq(RSI, Address(RSP, + kStartIndexOffset));
   __ movq(RDI, Address(RSP, + kEndIndexOffset));
   __ orq(RSI, RDI);
   __ testq(RSI, Immediate(kSmiTagMask));
diff --git a/dart/runtime/vm/object_test.cc b/dart/runtime/vm/object_test.cc
index 7b23600..4da8d3c 100644
--- a/dart/runtime/vm/object_test.cc
+++ b/dart/runtime/vm/object_test.cc
@@ -1951,6 +1951,27 @@
 }
 
 
+TEST_CASE(ArrayLength) {
+  const intptr_t kLength = Array::kMaxElements + 1;
+  ASSERT(kLength >= 0);
+  char buffer[1024];
+  OS::SNPrint(buffer, sizeof(buffer),
+      "main() {\n"
+      "  new List(%" Pd ");\n"
+      "}\n",
+      kLength);
+  Dart_Handle lib = TestCase::LoadTestScript(buffer, NULL);
+  EXPECT_VALID(lib);
+  Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
+  OS::SNPrint(buffer, sizeof(buffer),
+      "Unhandled exception:\n"
+      "Invalid argument(s): Length (%" Pd ") must be an integer "
+      "in the range [0..%" Pd "].",
+      kLength, Array::kMaxElements);
+  EXPECT_ERROR(result, buffer);
+}
+
+
 TEST_CASE(StringCodePointIterator) {
   const String& str0 = String::Handle(String::New(""));
   String::CodePointIterator it0(str0);
diff --git a/dart/tests/language/vm/regress_23238_test.dart b/dart/tests/language/vm/regress_23238_test.dart
new file mode 100644
index 0000000..88250b2
--- /dev/null
+++ b/dart/tests/language/vm/regress_23238_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2015, 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.
+
+import "package:expect/expect.dart";
+
+void main() {
+  int x = 327680;
+  int r = 65536;
+  for (var i = 0; i < 200; i++) {
+    Expect.equals(r, x ~/ 5);
+    x *= 10;
+    r *= 10;
+  }
+}
diff --git a/dart/tools/VERSION b/dart/tools/VERSION
index 30df61a..518e69f 100644
--- a/dart/tools/VERSION
+++ b/dart/tools/VERSION
@@ -28,4 +28,4 @@
 MINOR 10
 PATCH 0
 PRERELEASE 1
-PRERELEASE_PATCH 6
+PRERELEASE_PATCH 7