Update trunk to version 0.4.6.1
svn merge -r 21363:21386 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

--This line, and thsss below, will be ignored--

_M   .
_M   dart
M    dart/editor/tools/plugins/com.google.dart.tools.deploy/themes/default.xml
M    dart/editor/tools/plugins/com.google.dart.tools.deploy/themes/dartboard.xml
M    dart/editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/parser/SimpleParserTest.java
M    dart/editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/resolver/NonErrorResolverTest.java
M    dart/editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/resolver/StaticTypeWarningCodeTest.java
M    dart/editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/resolver/CompileTimeErrorCodeTest.java
M    dart/editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/resolver/ResolverTestCase.java
A  + dart/editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/resolver/TypePropagationTest.java
M    dart/editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/internal/resolver/TestAll.java
A  + dart/editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/internal/resolver/TypeOverrideManagerTest.java
M    dart/editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/internal/resolver/StaticTypeAnalyzerTest.java
A  + dart/editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/timing/SDKAnalysisTest.java
M    dart/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/parser/Parser.java
M    dart/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/element/member/ParameterMember.java
A  + dart/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/element/member/FieldMember.java
A  + dart/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/element/member/VariableMember.java
M    dart/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/element/member/PropertyAccessorMember.java
M    dart/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/resolver/LibraryResolver.java
M    dart/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/resolver/ElementResolver.java
A  + dart/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/resolver/TypeOverrideManager.java
M    dart/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/resolver/StaticTypeAnalyzer.java
M    dart/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/resolver/ResolverVisitor.java
M    dart/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/resolver/TypeResolverVisitor.java
M    dart/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/scanner/AbstractScanner.java
M    dart/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/error/StaticTypeWarningCode.java
M    dart/editor/tools/plugins/com.google.dart.tools.debug.core/src/com/google/dart/tools/debug/core/webkit/WebkitConnection.java
M    dart/editor/tools/plugins/com.google.dart.tools.core_test/src/com/google/dart/tools/core/internal/analysis/model/ProjectImplTest.java
M    dart/editor/tools/plugins/com.google.dart.tools.core_test/src/com/google/dart/tools/core/generator/GeneratorUtils.java
M    dart/editor/tools/plugins/com.google.dart.tools.core/src/com/google/dart/tools/core/internal/analysis/model/ProjectImpl.java
M    dart/editor/tools/plugins/com.google.dart.tools.core/src/com/google/dart/tools/core/pub/PubBuildParticipant.java
M    dart/editor/util/plugins/com.google.dart.java2dart/resources/java_core.dart
M    dart/tools/VERSION
M    dart/tools/dom/scripts/fremontcutbuilder.py
M    dart/tests/language/if_conversion_vm_test.dart
M    dart/tests/language/language_dart2js.status
M    dart/tests/language/language.status
M    dart/tests/language/rethrow_test.dart
M    dart/samples/third_party/todomvc/pubspec.yaml
M    dart/samples/third_party/todomvc/web/todo_row.html
M    dart/samples/third_party/todomvc/web/model.dart
M    dart/samples/third_party/todomvc/web/editable_label.html
M    dart/pkg/analyzer_experimental/lib/src/generated/java_core.dart
M    dart/pkg/pkg.status
M    dart/runtime/vm/os_win.cc
M    dart/runtime/vm/simulator_mips.cc
M    dart/runtime/vm/isolate.cc
M    dart/runtime/vm/intrinsifier_x64.cc
M    dart/runtime/vm/intrinsifier.h
M    dart/runtime/vm/assembler_mips.h
M    dart/runtime/vm/intrinsifier_ia32.cc
M    dart/runtime/vm/parser.cc
M    dart/runtime/vm/assembler_mips_test.cc
M    dart/runtime/vm/constants_mips.h
M    dart/runtime/vm/intermediate_language_x64.cc
M    dart/runtime/vm/os_linux.cc
M    dart/runtime/vm/object.h
M    dart/runtime/vm/code_generator.cc
M    dart/runtime/vm/token.h
M    dart/runtime/vm/object.cc
M    dart/runtime/vm/flow_graph_builder.cc
M    dart/runtime/vm/simulator_mips.h
M    dart/runtime/vm/disassembler_mips.cc
M    dart/runtime/vm/os.h
M    dart/runtime/vm/os_macos.cc
M    dart/runtime/vm/intermediate_language.h
M    dart/runtime/vm/intermediate_language_ia32.cc
M    dart/runtime/vm/os_android.cc
M    dart/runtime/platform/globals.h

git-svn-id: http://dart.googlecode.com/svn/trunk@21388 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/analyzer_experimental/lib/src/generated/java_core.dart b/pkg/analyzer_experimental/lib/src/generated/java_core.dart
index f293998..995fa42 100644
--- a/pkg/analyzer_experimental/lib/src/generated/java_core.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/java_core.dart
@@ -375,7 +375,7 @@
       _coPos--;
       (_iterable as List).remove(_coPos);
     } else if (_iterable is Set) {
-      _iterable.remove(_current);
+      (_iterable as Set).remove(_current);
     } else {
       throw new StateError("Unsupported iterable ${_iterable.runtimeType}");
     }
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 0c0512c..959a310 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -9,6 +9,13 @@
 # arithmetic natively, i.e., the VM.
 fixnum/test/int_64_vm_test: Skip
 
+# Don't run any test-like files that show up in packages directories. It
+# shouldn't be necessary to run "pub install" in these packages, but if you do
+# it shouldn't break the tests.
+*/packages/*/*: Skip
+*/*/packages/*/*: Skip
+*/*/*/packages/*/*: Skip
+
 # Skip non-test files ending with "_test".
 scheduled_test/lib/*: Skip
 
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index ef56ad4..2d566bb 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -396,36 +396,6 @@
 }
 
 
-// Some platforms do not support strndup. We add it below as necessary.
-#if defined(TARGET_OS_MACOS)
-// strndup has only been added to Mac OS X in 10.7. We are supplying
-// our own copy here.
-#if !defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) || \
-    __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ <= 1060
-#define NEEDS_STRNDUP 1
-#endif  // !defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
-#elif defined(TARGET_OS_WINDOWS)
-#define NEEDS_STRNDUP 1
-#endif  // defined(TARGET_OS_MACOS)
-
-#if defined(NEEDS_STRNDUP)
-// size_t used to match function signature on other platforms.
-inline char* strndup(const char* s, size_t n) {
-  size_t len = strlen(s);
-  if (n < len) {
-    len = n;
-  }
-  char* result = reinterpret_cast<char*>(malloc(len + 1));
-  if (!result) {
-    return NULL;
-  }
-  result[len] = '\0';
-  return reinterpret_cast<char*>(memcpy(result, s, len));
-}
-#endif  // defined(NEEDS_STRNDUP)
-#undef NEEDS_STRNDUP
-
-
 // A macro to ensure that memcpy cannot be called. memcpy does not handle
 // overlapping memory regions. Even though this is well documented it seems
 // to be used in error quite often. To avoid problems we disallow the direct
diff --git a/runtime/vm/assembler_mips.h b/runtime/vm/assembler_mips.h
index 8f430a6..f21d030 100644
--- a/runtime/vm/assembler_mips.h
+++ b/runtime/vm/assembler_mips.h
@@ -223,12 +223,23 @@
   }
 
   // CPU instructions in alphabetical order.
+  void addd(FRegister fd, FRegister fs, FRegister ft) {
+    ASSERT(EvenFPURegister(fd));
+    ASSERT(EvenFPURegister(fs));
+    ASSERT(EvenFPURegister(ft));
+    EmitFpuRType(COP1, FMT_D, ft, fs, fd, COP1_ADD);
+  }
+
   void addiu(Register rt, Register rs, const Immediate& imm) {
     ASSERT(Utils::IsInt(kImmBits, imm.value()));
     const uint16_t imm_value = static_cast<uint16_t>(imm.value());
     EmitIType(ADDIU, rs, rt, imm_value);
   }
 
+  void adds(FRegister fd, FRegister fs, FRegister ft) {
+    EmitFpuRType(COP1, FMT_S, ft, fs, fd, COP1_ADD);
+  }
+
   void addu(Register rd, Register rs, Register rt) {
     EmitRType(SPECIAL, rs, rt, rd, 0, ADDU);
   }
@@ -388,6 +399,11 @@
     EmitLoadStore(LBU, rt, addr);
   }
 
+  void ldc1(FRegister ft, const Address& addr) {
+    ASSERT(EvenFPURegister(ft));
+    EmitFpuLoadStore(LDC1, ft, addr);
+  }
+
   void lh(Register rt, const Address& addr) {
     EmitLoadStore(LH, rt, addr);
   }
@@ -406,6 +422,17 @@
     EmitLoadStore(LW, rt, addr);
   }
 
+  void lwc1(FRegister ft, const Address& addr) {
+    EmitFpuLoadStore(LWC1, ft, addr);
+  }
+
+  void mfc1(Register rt, FRegister fs) {
+    Emit(COP1 << kOpcodeShift |
+         COP1_MF << kCop1SubShift |
+         rt << kRtShift |
+         fs << kFsShift);
+  }
+
   void mfhi(Register rd) {
     EmitRType(SPECIAL, R0, R0, rd, 0, MFHI);
   }
@@ -418,6 +445,12 @@
     or_(rd, rs, ZR);
   }
 
+  void movd(FRegister fd, FRegister fs) {
+    ASSERT(EvenFPURegister(fd));
+    ASSERT(EvenFPURegister(fs));
+    EmitFpuRType(COP1, FMT_D, F0, fs, fd, COP1_MOV);
+  }
+
   void movn(Register rd, Register rs, Register rt) {
     EmitRType(SPECIAL, rs, rt, rd, 0, MOVN);
   }
@@ -426,6 +459,17 @@
     EmitRType(SPECIAL, rs, rt, rd, 0, MOVZ);
   }
 
+  void movs(FRegister fd, FRegister fs) {
+    EmitFpuRType(COP1, FMT_S, F0, fs, fd, COP1_MOV);
+  }
+
+  void mtc1(Register rt, FRegister fs) {
+    Emit(COP1 << kOpcodeShift |
+         COP1_MT << kCop1SubShift |
+         rt << kRtShift |
+         fs << kFsShift);
+  }
+
   void mult(Register rs, Register rt) {
     EmitRType(SPECIAL, rs, rt, R0, 0, MULT);
   }
@@ -456,6 +500,11 @@
     EmitLoadStore(SB, rt, addr);
   }
 
+  void sdc1(FRegister ft, const Address& addr) {
+    ASSERT(EvenFPURegister(ft));
+    EmitFpuLoadStore(SDC1, ft, addr);
+  }
+
   void sh(Register rt, const Address& addr) {
     EmitLoadStore(SH, rt, addr);
   }
@@ -500,6 +549,10 @@
     EmitLoadStore(SW, rt, addr);
   }
 
+  void swc1(FRegister ft, const Address& addr) {
+    EmitFpuLoadStore(SWC1, ft, addr);
+  }
+
   void xor_(Register rd, Register rs, Register rt) {
     EmitRType(SPECIAL, rs, rt, rd, 0, XOR);
   }
@@ -565,6 +618,36 @@
     }
   }
 
+  void LoadImmediate(FRegister rd, double value) {
+    ASSERT(EvenFPURegister(rd));
+    const int64_t ival = bit_cast<uint64_t, double>(value);
+    const int32_t low = Utils::Low32Bits(ival);
+    const int32_t high = Utils::High32Bits(ival);
+    if (low != 0) {
+      LoadImmediate(TMP1, low);
+      mtc1(TMP1, rd);
+    } else {
+      mtc1(ZR, rd);
+    }
+
+    if (high != 0) {
+      LoadImmediate(TMP1, high);
+      mtc1(TMP1, static_cast<FRegister>(rd + 1));
+    } else {
+      mtc1(ZR, static_cast<FRegister>(rd + 1));
+    }
+  }
+
+  void LoadImmediate(FRegister rd, float value) {
+    const int32_t ival = bit_cast<int32_t, float>(value);
+    if (ival == 0) {
+      mtc1(ZR, rd);
+    } else {
+      LoadImmediate(TMP1, ival);
+      mtc1(TMP1, rd);
+    }
+  }
+
   void AddImmediate(Register rd, Register rs, int32_t value) {
     if (Utils::IsInt(kImmBits, value)) {
       addiu(rd, rs, Immediate(value));
@@ -734,6 +817,10 @@
 
   GrowableArray<CodeComment*> comments_;
 
+  bool EvenFPURegister(FRegister reg) {
+    return (static_cast<int>(reg) & 1) == 0;
+  }
+
   void Emit(int32_t value) {
     // Emitting an instruction clears the delay slot state.
     in_delay_slot_ = false;
@@ -761,6 +848,13 @@
          addr.encoding());
   }
 
+  void EmitFpuLoadStore(Opcode opcode, FRegister ft,
+                        const Address &addr) {
+    Emit(opcode << kOpcodeShift |
+         ft << kFtShift |
+         addr.encoding());
+  }
+
   void EmitRegImmType(Opcode opcode,
                       Register rs,
                       RtRegImm code,
@@ -790,6 +884,20 @@
          func << kFunctionShift);
   }
 
+  void EmitFpuRType(Opcode opcode,
+                    Format fmt,
+                    FRegister ft,
+                    FRegister fs,
+                    FRegister fd,
+                    Cop1Function func) {
+    Emit(opcode << kOpcodeShift |
+         fmt << kFmtShift |
+         ft << kFtShift |
+         fs << kFsShift |
+         fd << kFdShift |
+         func << kCop1FnShift);
+  }
+
   void EmitBranch(Opcode b, Register rs, Register rt, Label* label) {
     if (label->IsBound()) {
       // Relative destination from an instruction after the branch.
diff --git a/runtime/vm/assembler_mips_test.cc b/runtime/vm/assembler_mips_test.cc
index 88d6472..0bd651c 100644
--- a/runtime/vm/assembler_mips_test.cc
+++ b/runtime/vm/assembler_mips_test.cc
@@ -1107,6 +1107,164 @@
   EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
 }
 
+
+ASSEMBLER_TEST_GENERATE(Mtc1Mfc1, assembler) {
+  __ mtc1(ZR, F0);
+  __ mfc1(V0, F0);
+  __ Ret();
+}
+
+
+ASSEMBLER_TEST_RUN(Mtc1Mfc1, test) {
+  typedef double (*SimpleCode)();
+  EXPECT(test != NULL);
+  double res = EXECUTE_TEST_CODE_FLOAT(SimpleCode, test->entry());
+  EXPECT_FLOAT_EQ(0.0, res, 0.001);
+}
+
+
+ASSEMBLER_TEST_GENERATE(Addd, assembler) {
+  __ LoadImmediate(F0, 1.0);
+  __ LoadImmediate(F2, 2.0);
+  __ addd(F4, F0, F2);
+  __ mfc1(V0, F4);
+  __ mfc1(V1, F5);
+  __ Ret();
+}
+
+
+ASSEMBLER_TEST_RUN(Addd, test) {
+  typedef double (*SimpleCode)();
+  EXPECT(test != NULL);
+  double res = EXECUTE_TEST_CODE_DOUBLE(SimpleCode, test->entry());
+  EXPECT_FLOAT_EQ(3.0, res, 0.001);
+}
+
+
+ASSEMBLER_TEST_GENERATE(Adds, assembler) {
+  __ LoadImmediate(F0, 1.0f);
+  __ LoadImmediate(F2, 2.0f);
+  __ adds(F4, F0, F2);
+  __ mfc1(V0, F4);
+  __ Ret();
+}
+
+
+ASSEMBLER_TEST_RUN(Adds, test) {
+  typedef double (*SimpleCode)();
+  EXPECT(test != NULL);
+  double res = EXECUTE_TEST_CODE_FLOAT(SimpleCode, test->entry());
+  EXPECT_FLOAT_EQ(3.0, res, 0.001);
+}
+
+
+ASSEMBLER_TEST_GENERATE(Movd, assembler) {
+  __ LoadImmediate(F0, 1.0);
+  __ movd(F2, F0);
+  __ mfc1(V0, F2);
+  __ mfc1(V1, F3);
+  __ Ret();
+}
+
+
+ASSEMBLER_TEST_RUN(Movd, test) {
+  typedef double (*SimpleCode)();
+  EXPECT(test != NULL);
+  double res = EXECUTE_TEST_CODE_DOUBLE(SimpleCode, test->entry());
+  EXPECT_FLOAT_EQ(1.0, res, 0.001);
+}
+
+
+ASSEMBLER_TEST_GENERATE(Movs, assembler) {
+  __ LoadImmediate(F0, 1.0f);
+  __ movd(F2, F0);
+  __ mfc1(V0, F2);
+  __ Ret();
+}
+
+
+ASSEMBLER_TEST_RUN(Movs, test) {
+  typedef double (*SimpleCode)();
+  EXPECT(test != NULL);
+  double res = EXECUTE_TEST_CODE_FLOAT(SimpleCode, test->entry());
+  EXPECT_FLOAT_EQ(1.0, res, 0.001);
+}
+
+
+ASSEMBLER_TEST_GENERATE(Sdc1Ldc1, assembler) {
+  __ AddImmediate(SP, -8 * kWordSize);
+  __ LoadImmediate(T1, ~(8 - 1));
+  __ and_(T0, SP, T1);  // Need 8 byte alignment.
+  __ LoadImmediate(F0, 1.0);
+  __ sdc1(F0, Address(T0));
+  __ ldc1(F2, Address(T0));
+  __ mfc1(V0, F2);
+  __ mfc1(V1, F3);
+  __ Ret();
+}
+
+
+ASSEMBLER_TEST_RUN(Sdc1Ldc1, test) {
+  typedef double (*SimpleCode)();
+  EXPECT(test != NULL);
+  double res = EXECUTE_TEST_CODE_DOUBLE(SimpleCode, test->entry());
+  EXPECT_FLOAT_EQ(1.0, res, 0.001);
+}
+
+
+ASSEMBLER_TEST_GENERATE(Swc1Lwc1, assembler) {
+  __ AddImmediate(SP, -1 * kWordSize);
+  __ LoadImmediate(F0, 1.0f);
+  __ swc1(F0, Address(SP));
+  __ lwc1(F1, Address(SP));
+  __ mfc1(V0, F1);
+  __ AddImmediate(SP, 1 * kWordSize);
+  __ Ret();
+}
+
+ASSEMBLER_TEST_RUN(Swc1Lwc1, test) {
+  typedef double (*SimpleCode)();
+  EXPECT(test != NULL);
+  double res = EXECUTE_TEST_CODE_FLOAT(SimpleCode, test->entry());
+  EXPECT_FLOAT_EQ(1.0, res, 0.001);
+}
+
+
+ASSEMBLER_TEST_GENERATE(Adds_NaN, assembler) {
+  __ LoadImmediate(F0, 1.0f);
+  __ LoadImmediate(T0, 0x7f800001);  // NaN
+  __ mtc1(T0, F2);
+  __ adds(F4, F0, F2);
+  __ mfc1(V0, F4);
+  __ Ret();
+}
+
+
+ASSEMBLER_TEST_RUN(Adds_NaN, test) {
+  typedef double (*SimpleCode)();
+  EXPECT(test != NULL);
+  float res = EXECUTE_TEST_CODE_FLOAT(SimpleCode, test->entry());
+  EXPECT_EQ(isnan(res), true);
+}
+
+
+ASSEMBLER_TEST_GENERATE(Adds_Inf, assembler) {
+  __ LoadImmediate(F0, 1.0f);
+  __ LoadImmediate(T0, 0x7f800000);  // +inf
+  __ mtc1(T0, F2);
+  __ adds(F4, F0, F2);
+  __ mfc1(V0, F4);
+  __ Ret();
+}
+
+
+ASSEMBLER_TEST_RUN(Adds_Inf, test) {
+  typedef double (*SimpleCode)();
+  EXPECT(test != NULL);
+  float res = EXECUTE_TEST_CODE_FLOAT(SimpleCode, test->entry());
+  EXPECT_EQ(isfinite(res), false);
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_MIPS
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 4bbb77e..6ae0afa 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -1014,8 +1014,9 @@
   const MegamorphicCache& cache = MegamorphicCache::Handle(
       isolate->megamorphic_cache_table()->Lookup(name, descriptor));
   Class& cls = Class::Handle(receiver.clazz());
+  const bool is_null = cls.IsNullClass();
   // For lookups treat null as an instance of class Object.
-  if (cls.IsNullClass()) {
+  if (is_null) {
     cls = isolate->object_store()->object_class();
   }
   ASSERT(!cls.IsNull());
@@ -1049,7 +1050,8 @@
   if (instructions.IsNull()) return;
 
   cache.EnsureCapacity();
-  const Smi& class_id = Smi::Handle(Smi::New(cls.id()));
+  const Smi& class_id = Smi::Handle(Smi::New(
+      is_null ? static_cast<intptr_t>(kNullCid) : cls.id()));
   cache.Insert(class_id, target);
   return;
 }
diff --git a/runtime/vm/constants_mips.h b/runtime/vm/constants_mips.h
index 9a47410..435b7d8 100644
--- a/runtime/vm/constants_mips.h
+++ b/runtime/vm/constants_mips.h
@@ -88,7 +88,8 @@
 };
 
 
-// Values for double-precision floating point registers.
+// Values for floating point registers.
+// Double-precision values use register pairs.
 enum FRegister {
   F0  =  0,
   F1  =  1,
@@ -161,6 +162,16 @@
 const int kAbiPreservedCpuRegCount = 8;
 
 
+// FPU registers 20 - 31 are preserved across calls.
+const FRegister kAbiFirstPreservedFpuReg = F20;
+const FRegister kAbiLastPreservedFpuReg =
+    static_cast<FRegister>(kNumberOfFRegisters - 1);
+
+// FPU registers 0 - 19 are not preserved across calls.
+const FRegister kDartFirstVolatileFpuReg = F0;
+const FRegister kDartLastVolatileFpuReg = F19;
+const int kDartVolatileFpuRegCount = 20;
+
 // Dart stack frame layout.
 static const int kLastParamSlotIndex = 3;
 static const int kFirstLocalSlotIndex = -2;
@@ -182,14 +193,26 @@
   kOpcodeBits = 6,
   kRsShift = 21,
   kRsBits = 5,
+  kFmtShift = 21,
+  kFmtBits = 5,
   kRtShift = 16,
   kRtBits = 5,
+  kFtShift = 16,
+  kFtBits = 5,
   kRdShift = 11,
   kRdBits = 5,
+  kFsShift = 11,
+  kFsBits = 5,
   kSaShift = 6,
   kSaBits = 5,
+  kFdShift = 6,
+  kFdBits = 5,
   kFunctionShift = 0,
   kFunctionBits = 6,
+  kCop1FnShift = 0,
+  kCop1FnBits = 6,
+  kCop1SubShift = 21,
+  kCop1SubBits = 5,
   kImmShift = 0,
   kImmBits = 16,
   kInstrShift = 0,
@@ -322,6 +345,24 @@
 };
 
 
+enum Cop1Function {
+  COP1_ADD = 0,
+  COP1_MOV = 6,
+};
+
+enum Cop1Sub {
+  COP1_MF = 0,
+  COP1_MT = 4,
+};
+
+enum Format {
+  FMT_S = 16,
+  FMT_D = 17,
+  FMT_W = 20,
+  FMT_L = 21,
+  FMT_PS = 22,
+};
+
 class Instr {
  public:
   enum {
@@ -371,6 +412,18 @@
     return static_cast<Register>(Bits(kRdShift, kRdBits));
   }
 
+  inline FRegister FsField() const {
+    return static_cast<FRegister>(Bits(kFsShift, kFsBits));
+  }
+
+  inline FRegister FtField() const {
+    return static_cast<FRegister>(Bits(kFtShift, kFtBits));
+  }
+
+  inline FRegister FdField() const {
+    return static_cast<FRegister>(Bits(kFdShift, kFdBits));
+  }
+
   inline int SaField() const {
     return Bits(kSaShift, kSaBits);
   }
@@ -400,6 +453,22 @@
     return (OpcodeField() == SPECIAL) && (FunctionField() == BREAK);
   }
 
+  inline Cop1Function Cop1FunctionField() const {
+    return static_cast<Cop1Function>(Bits(kCop1FnShift, kCop1FnBits));
+  }
+
+  inline Cop1Sub Cop1SubField() const {
+    return static_cast<Cop1Sub>(Bits(kCop1SubShift, kCop1SubBits));
+  }
+
+  inline bool HasFormat() const {
+    return (OpcodeField() == COP1) && (Bit(25) == 1);
+  }
+
+  inline Format FormatField() const {
+    return static_cast<Format>(Bits(kFmtShift, kFmtBits));
+  }
+
   // Instructions are read out of a code stream. The only way to get a
   // reference to an instruction is to convert a pc. There is no way
   // to allocate or create instances of class Instr.
diff --git a/runtime/vm/disassembler_mips.cc b/runtime/vm/disassembler_mips.cc
index 8233de7..717acbf 100644
--- a/runtime/vm/disassembler_mips.cc
+++ b/runtime/vm/disassembler_mips.cc
@@ -31,8 +31,11 @@
 
   // Printing of common values.
   void PrintRegister(Register reg);
+  void PrintFRegister(FRegister reg);
+  void PrintFormat(Instr* instr);
 
   int FormatRegister(Instr* instr, const char* format);
+  int FormatFRegister(Instr* instr, const char* format);
   int FormatOption(Instr* instr, const char* format);
   void Format(Instr* instr, const char* format);
   void Unknown(Instr* instr);
@@ -40,6 +43,7 @@
   void DecodeSpecial(Instr* instr);
   void DecodeSpecial2(Instr* instr);
   void DecodeRegImm(Instr* instr);
+  void DecodeCop1(Instr* instr);
 
   // Convenience functions.
   char* get_buffer() const { return buffer_; }
@@ -79,6 +83,14 @@
 };
 
 
+static const char* freg_names[kNumberOfFRegisters] = {
+  "f0" , "f1" , "f2" , "f3" , "f4" , "f5" , "f6" , "f7" ,
+  "f8" , "f9" , "f10", "f11", "f12", "f13", "f14", "f15",
+  "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+  "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+};
+
+
 void MIPSDecoder::PrintRegister(Register reg) {
   ASSERT(0 <= reg);
   ASSERT(reg < kNumberOfCpuRegisters);
@@ -86,6 +98,13 @@
 }
 
 
+void MIPSDecoder::PrintFRegister(FRegister reg) {
+  ASSERT(0 <= reg);
+  ASSERT(reg < kNumberOfFRegisters);
+  Print(freg_names[reg]);
+}
+
+
 // Handle all register based formatting in these functions to reduce the
 // complexity of FormatOption.
 int MIPSDecoder::FormatRegister(Instr* instr, const char* format) {
@@ -109,6 +128,57 @@
 }
 
 
+int MIPSDecoder::FormatFRegister(Instr* instr, const char* format) {
+  ASSERT(format[0] == 'f');
+  switch (format[1]) {
+    case 's': {  // 'fs: Fs register
+      PrintFRegister(instr->FsField());
+      return 2;
+    }
+    case 't': {  // 'ft: Ft register
+      PrintFRegister(instr->FtField());
+      return 2;
+    }
+    case 'd': {  // 'fd: Fd register
+      PrintFRegister(instr->FdField());
+      return 2;
+    }
+  }
+  UNREACHABLE();
+  return -1;
+}
+
+
+void MIPSDecoder::PrintFormat(Instr *instr) {
+  switch (instr->FormatField()) {
+    case FMT_S: {
+      Print("s");
+      break;
+    }
+    case FMT_D: {
+      Print("d");
+      break;
+    }
+    case FMT_W: {
+      Print("w");
+      break;
+    }
+    case FMT_L: {
+      Print("l");
+      break;
+    }
+    case FMT_PS: {
+      Print("ps");
+      break;
+    }
+    default: {
+      Print("unknown");
+      break;
+    }
+  }
+}
+
+
 // FormatOption takes a formatting string and interprets it based on
 // the current instructions. The format string points to the first
 // character of the option string (the option escape has already been
@@ -170,6 +240,15 @@
     case 'r': {
       return FormatRegister(instr, format);
     }
+    case 'f': {
+      if (format[1] == 'm') {
+        ASSERT(STRING_STARTS_WITH(format, "fmt"));
+        PrintFormat(instr);
+        return 3;
+      } else {
+        return FormatFRegister(instr, format);
+      }
+    }
     case 's': {
       ASSERT(STRING_STARTS_WITH(format, "sa"));
       buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
@@ -397,6 +476,51 @@
   }
 }
 
+void MIPSDecoder::DecodeCop1(Instr* instr) {
+  ASSERT(instr->OpcodeField() == COP1);
+  if (instr->HasFormat()) {
+    // If the rs field is a valid format, then the function field identifies
+    // the instruction.
+    switch (instr->Cop1FunctionField()) {
+      case COP1_ADD: {
+        Format(instr, "add.'fmt 'fd, 'fs, 'ft");
+        break;
+      }
+      case COP1_MOV: {
+        Format(instr, "mov.'fmt 'fd, 'fs");
+        break;
+      }
+      default: {
+        Unknown(instr);
+        break;
+      }
+    }
+  } else {
+    // If the rs field isn't a valid format, then it must be a sub-opcode.
+    switch (instr->Cop1SubField()) {
+      case COP1_MF: {
+        if (instr->Bits(0, 11) != 0) {
+          Unknown(instr);
+        } else {
+          Format(instr, "mfc1 'rt, 'fs");
+        }
+        break;
+      }
+      case COP1_MT: {
+        if (instr->Bits(0, 11) != 0) {
+          Unknown(instr);
+        } else {
+          Format(instr, "mtc1 'rt, 'fs");
+        }
+        break;
+      }
+      default: {
+        Unknown(instr);
+        break;
+      }
+    }
+  }
+}
 
 void MIPSDecoder::InstructionDecode(Instr* instr) {
   switch (instr->OpcodeField()) {
@@ -412,6 +536,10 @@
       DecodeRegImm(instr);
       break;
     }
+    case COP1: {
+      DecodeCop1(instr);
+      break;
+    }
     case ADDIU: {
       Format(instr, "addiu 'rt, 'rs, 'imms");
       break;
@@ -460,6 +588,10 @@
       Format(instr, "lbu 'rt, 'imms('rs)");
       break;
     }
+    case LDC1: {
+      Format(instr, "ldc1 'ft, 'imms('rs)");
+      break;
+    }
     case LH: {
       Format(instr, "lh 'rt, 'imms('rs)");
       break;
@@ -472,6 +604,10 @@
       Format(instr, "lw 'rt, 'imms('rs)");
       break;
     }
+    case LWC1: {
+      Format(instr, "lwc1 'ft, 'imms('rs)");
+      break;
+    }
     case ORI: {
       Format(instr, "ori 'rt, 'rs, 'immu");
       break;
@@ -484,10 +620,18 @@
       Format(instr, "sh 'rt, 'imms('rs)");
       break;
     }
+    case SDC1: {
+      Format(instr, "sdc1 'ft, 'imms('rs)");
+      break;
+    }
     case SW: {
       Format(instr, "sw 'rt, 'imms('rs)");
       break;
     }
+    case SWC1: {
+      Format(instr, "swc1 'ft, 'imms('rs)");
+      break;
+    }
     default: {
       Unknown(instr);
       break;
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 00b3932..21a3a35 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -2079,18 +2079,18 @@
 #define RECOGNIZED_LIST_FACTORY_LIST(V)                                        \
   V(ObjectArrayFactory, kArrayCid, 97987288)                                   \
   V(GrowableObjectArrayWithData, kGrowableObjectArrayCid, 816132033)           \
-  V(GrowableObjectArrayFactory, kGrowableObjectArrayCid, 224791427)            \
-  V(Int8ListFactory, kTypedDataInt8ArrayCid, 1178498933)                       \
-  V(Uint8ListFactory, kTypedDataUint8ArrayCid, 996047641)                      \
-  V(Uint8ClampedListFactory, kTypedDataUint8ClampedArrayCid, 1504313643)       \
-  V(Int16ListFactory, kTypedDataInt16ArrayCid, 1595869856)                     \
-  V(Uint16ListFactory, kTypedDataUint16ArrayCid, 665298027)                    \
-  V(Int32ListFactory, kTypedDataInt32ArrayCid, 728173538)                      \
-  V(Uint32ListFactory, kTypedDataUint32ArrayCid, 352036624)                    \
-  V(Int64ListFactory, kTypedDataInt64ArrayCid, 105935265)                      \
-  V(Uint64ListFactory, kTypedDataUint64ArrayCid, 943403644)                    \
-  V(Float64ListFactory, kTypedDataFloat64ArrayCid, 348533743)                  \
-  V(Float32ListFactory, kTypedDataFloat32ArrayCid, 1830794379)                 \
+  V(GrowableObjectArrayFactory, kGrowableObjectArrayCid, 369608996)            \
+  V(Int8ListFactory, kTypedDataInt8ArrayCid, 2066002614)                       \
+  V(Uint8ListFactory, kTypedDataUint8ArrayCid, 1883551322)                     \
+  V(Uint8ClampedListFactory, kTypedDataUint8ClampedArrayCid, 244333676)        \
+  V(Int16ListFactory, kTypedDataInt16ArrayCid, 335889889)                      \
+  V(Uint16ListFactory, kTypedDataUint16ArrayCid, 1552801708)                   \
+  V(Int32ListFactory, kTypedDataInt32ArrayCid, 1615677219)                     \
+  V(Uint32ListFactory, kTypedDataUint32ArrayCid, 1239540305)                   \
+  V(Int64ListFactory, kTypedDataInt64ArrayCid, 993438946)                      \
+  V(Uint64ListFactory, kTypedDataUint64ArrayCid, 1830907325)                   \
+  V(Float64ListFactory, kTypedDataFloat64ArrayCid, 1236037424)                 \
+  V(Float32ListFactory, kTypedDataFloat32ArrayCid, 570814412)                  \
 
 
 // Class that recognizes factories and returns corresponding result cid.
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 9ac45c1..fd21acf 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -59,16 +59,16 @@
   V(_GrowableObjectArray, get:length, GrowableArrayLength, 725548050)          \
   V(_GrowableObjectArray, get:_capacity, GrowableArrayCapacity, 725548050)     \
   V(_StringBase, get:length, StringBaseLength, 320803993)                      \
-  V(_StringBase, get:isEmpty, StringBaseIsEmpty, 110632481)                    \
+  V(_StringBase, get:isEmpty, StringBaseIsEmpty, 1026765313)                   \
   V(_StringBase, codeUnitAt, StringBaseCodeUnitAt, 984449525)                  \
   V(_StringBase, [], StringBaseCharAt, 1062366987)                             \
-  V(_IntegerImplementation, toDouble, IntegerToDouble, 927078825)              \
+  V(_IntegerImplementation, toDouble, IntegerToDouble, 1267108971)             \
   V(_Double, toInt, DoubleToInteger, 362666636)                                \
   V(_Double, truncateToDouble, DoubleTruncate, 620870996)                      \
   V(_Double, roundToDouble, DoubleRound, 620870996)                            \
   V(_Double, floorToDouble, DoubleFloor, 620870996)                            \
   V(_Double, ceilToDouble, DoubleCeil, 620870996)                              \
-  V(_Double, pow, DoublePow, 1229411686)                                       \
+  V(_Double, pow, DoublePow, 631903778)                                        \
   V(_Double, _modulo, DoubleMod, 437099337)                                    \
   V(::, sqrt, MathSqrt, 1662640002)                                            \
 
@@ -2774,7 +2774,10 @@
   virtual bool HasSideEffect() const { return false; }
 
   virtual bool AttributesEqual(Instruction* other) const {
-    return kind_ == other->AsIfThenElse()->kind_;
+    IfThenElseInstr* other_if_then_else = other->AsIfThenElse();
+    return (kind_ == other_if_then_else->kind_) &&
+           (if_true_ == other_if_then_else->if_true_) &&
+           (if_false_ == other_if_then_else->if_false_);
   }
 
   virtual bool AffectedBySideEffect() const {
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 96e14fa..689f965 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -3724,12 +3724,6 @@
 }
 
 
-// Detect pattern when one value is increment of another.
-static bool IsIncrementKind(intptr_t v1, intptr_t v2) {
-  return ((v1 == v2 + 1) || (v1 + 1 == v2));
-}
-
-
 bool IfThenElseInstr::IsSupported() {
   return true;
 }
@@ -3752,12 +3746,7 @@
     return false;
   }
 
-  if (IsPowerOfTwoKind(v1_value, v2_value) ||
-      IsIncrementKind(v1_value, v2_value)) {
-    return true;
-  }
-
-  return false;
+  return true;
 }
 
 
@@ -3803,22 +3792,38 @@
 
   const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
 
-  const intptr_t base = Utils::Minimum(if_true_, if_false_);
+  intptr_t true_value = if_true_;
+  intptr_t false_value = if_false_;
 
-  if (if_true_ == base) {
-    // We need to have zero in EDX on true_condition.
-    true_condition = NegateCondition(true_condition);
+  if (is_power_of_two_kind) {
+    if (true_value == 0) {
+      // We need to have zero in EDX on true_condition.
+      true_condition = NegateCondition(true_condition);
+    }
+  } else {
+    if (true_value == 0) {
+      // Swap values so that false_value is zero.
+      intptr_t temp = true_value;
+      true_value = false_value;
+      false_value = temp;
+    } else {
+      true_condition = NegateCondition(true_condition);
+    }
   }
 
   __ setcc(true_condition, DL);
 
   if (is_power_of_two_kind) {
     const intptr_t shift =
-        Utils::ShiftForPowerOfTwo(Utils::Maximum(if_true_, if_false_));
+        Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value));
     __ shll(EDX, Immediate(shift + kSmiTagSize));
   } else {
-    ASSERT(kSmiTagSize == 1);
-    __ leal(EDX, Address(EDX, TIMES_2, base << kSmiTagSize));
+    __ subl(EDX, Immediate(1));
+    __ andl(EDX, Immediate(
+        Smi::RawValue(true_value) - Smi::RawValue(false_value)));
+    if (false_value != 0) {
+      __ addl(EDX, Immediate(Smi::RawValue(false_value)));
+    }
   }
 }
 
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 264c3199..3a7a6e1 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -155,12 +155,6 @@
 }
 
 
-// Detect pattern when one value is increment of another.
-static bool IsIncrementKind(intptr_t v1, intptr_t v2) {
-  return ((v1 == v2 + 1) || (v1 + 1 == v2));
-}
-
-
 bool IfThenElseInstr::IsSupported() {
   return true;
 }
@@ -183,11 +177,6 @@
     return false;
   }
 
-  if (IsPowerOfTwoKind(v1_value, v2_value) ||
-      IsIncrementKind(v1_value, v2_value)) {
-    return true;
-  }
-
   return false;
 }
 
@@ -234,22 +223,38 @@
 
   const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
 
-  const intptr_t base = Utils::Minimum(if_true_, if_false_);
+  intptr_t true_value = if_true_;
+  intptr_t false_value = if_false_;
 
-  if (if_true_ == base) {
-    // We need to have zero in RDX on true_condition.
-    true_condition = NegateCondition(true_condition);
+  if (is_power_of_two_kind) {
+    if (true_value == 0) {
+      // We need to have zero in RDX on true_condition.
+      true_condition = NegateCondition(true_condition);
+    }
+  } else {
+    if (true_value == 0) {
+      // Swap values so that false_value is zero.
+      intptr_t temp = true_value;
+      true_value = false_value;
+      false_value = temp;
+    } else {
+      true_condition = NegateCondition(true_condition);
+    }
   }
 
   __ setcc(true_condition, DL);
 
   if (is_power_of_two_kind) {
     const intptr_t shift =
-        Utils::ShiftForPowerOfTwo(Utils::Maximum(if_true_, if_false_));
+        Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value));
     __ shlq(RDX, Immediate(shift + kSmiTagSize));
   } else {
-    ASSERT(kSmiTagSize == 1);
-    __ leaq(RDX, Address(RDX, TIMES_2, base << kSmiTagSize));
+    __ subq(RDX, Immediate(1));
+    __ andq(RDX, Immediate(
+        Smi::RawValue(true_value) - Smi::RawValue(false_value)));
+    if (false_value != 0) {
+      __ addq(RDX, Immediate(Smi::RawValue(false_value)));
+    }
   }
 }
 
diff --git a/runtime/vm/intrinsifier.h b/runtime/vm/intrinsifier.h
index 0716629..0a1afd9 100644
--- a/runtime/vm/intrinsifier.h
+++ b/runtime/vm/intrinsifier.h
@@ -17,47 +17,47 @@
 // build and run to get the correct fingerprint from the mismatch error.
 #define CORE_LIB_INTRINSIC_LIST(V)                                             \
   V(_IntegerImplementation, _addFromInteger, Integer_addFromInteger, 726019207)\
-  V(_IntegerImplementation, +, Integer_add, 25837296)                          \
+  V(_IntegerImplementation, +, Integer_add, 1768648592)                        \
   V(_IntegerImplementation, _subFromInteger, Integer_subFromInteger, 726019207)\
-  V(_IntegerImplementation, -, Integer_sub, 1697139934)                        \
+  V(_IntegerImplementation, -, Integer_sub, 1292467582)                        \
   V(_IntegerImplementation, _mulFromInteger, Integer_mulFromInteger, 726019207)\
-  V(_IntegerImplementation, *, Integer_mul, 110370751)                         \
-  V(_IntegerImplementation, %, Integer_modulo, 108639519)                      \
-  V(_IntegerImplementation, ~/, Integer_truncDivide, 1187354250)               \
-  V(_IntegerImplementation, unary-, Integer_negate, 675709702)                 \
+  V(_IntegerImplementation, *, Integer_mul, 1853182047)                        \
+  V(_IntegerImplementation, %, Integer_modulo, 1211518976)                     \
+  V(_IntegerImplementation, ~/, Integer_truncDivide, 142750059)                \
+  V(_IntegerImplementation, unary-, Integer_negate, 676633254)                 \
   V(_IntegerImplementation, _bitAndFromInteger,                                \
     Integer_bitAndFromInteger, 726019207)                                      \
-  V(_IntegerImplementation, &, Integer_bitAnd, 759019505)                      \
+  V(_IntegerImplementation, &, Integer_bitAnd, 354347153)                      \
   V(_IntegerImplementation, _bitOrFromInteger,                                 \
     Integer_bitOrFromInteger, 726019207)                                       \
-  V(_IntegerImplementation, |, Integer_bitOr, 1280367298)                      \
+  V(_IntegerImplementation, |, Integer_bitOr, 875694946)                       \
   V(_IntegerImplementation, _bitXorFromInteger,                                \
     Integer_bitXorFromInteger, 726019207)                                      \
-  V(_IntegerImplementation, ^, Integer_bitXor, 686827811)                      \
+  V(_IntegerImplementation, ^, Integer_bitXor, 282155459)                      \
   V(_IntegerImplementation,                                                    \
     _greaterThanFromInteger,                                                   \
     Integer_greaterThanFromInt, 79222670)                                      \
-  V(_IntegerImplementation, >, Integer_greaterThan, 866987265)                 \
-  V(_IntegerImplementation, ==, Integer_equal, 408178104)                      \
+  V(_IntegerImplementation, >, Integer_greaterThan, 462314913)                 \
+  V(_IntegerImplementation, ==, Integer_equal, 1424765465)                     \
   V(_IntegerImplementation, _equalToInteger, Integer_equalToInteger, 79222670) \
-  V(_IntegerImplementation, <, Integer_lessThan, 1423914919)                   \
-  V(_IntegerImplementation, <=, Integer_lessEqualThan, 890963352)              \
-  V(_IntegerImplementation, >=, Integer_greaterEqualThan, 890993143)           \
-  V(_IntegerImplementation, <<, Integer_shl, 1600590181)                       \
-  V(_IntegerImplementation, >>, Integer_sar, 237416447)                        \
+  V(_IntegerImplementation, <, Integer_lessThan, 1424838471)                   \
+  V(_IntegerImplementation, <=, Integer_lessEqualThan, 949016155)              \
+  V(_IntegerImplementation, >=, Integer_greaterEqualThan, 949045946)           \
+  V(_IntegerImplementation, <<, Integer_shl, 1195917829)                       \
+  V(_IntegerImplementation, >>, Integer_sar, 1980227743)                       \
   V(_Smi, ~, Smi_bitNegate, 882629793)                                         \
-  V(_Double, >, Double_greaterThan, 498448864)                                 \
-  V(_Double, >=, Double_greaterEqualThan, 1126476149)                          \
-  V(_Double, <, Double_lessThan, 1595327781)                                   \
-  V(_Double, <=, Double_lessEqualThan, 1126446358)                             \
-  V(_Double, ==, Double_equal, 48480576)                                       \
-  V(_Double, +, Double_add, 407090160)                                         \
-  V(_Double, -, Double_sub, 1801868246)                                        \
-  V(_Double, *, Double_mul, 984784342)                                         \
-  V(_Double, /, Double_div, 1399344917)                                        \
+  V(_Double, >, Double_greaterThan, 301935359)                                 \
+  V(_Double, >=, Double_greaterEqualThan, 1184528952)                          \
+  V(_Double, <, Double_lessThan, 1596251333)                                   \
+  V(_Double, <=, Double_lessEqualThan, 1184499161)                             \
+  V(_Double, ==, Double_equal, 1706047712)                                     \
+  V(_Double, +, Double_add, 210576655)                                         \
+  V(_Double, -, Double_sub, 1605354741)                                        \
+  V(_Double, *, Double_mul, 788270837)                                         \
+  V(_Double, /, Double_div, 1202831412)                                        \
   V(_Double, get:isNaN, Double_getIsNaN, 54462366)                             \
   V(_Double, get:isNegative, Double_getIsNegative, 54462366)                   \
-  V(_Double, _mulFromInteger, Double_mulFromInteger, 353781714)                \
+  V(_Double, _mulFromInteger, Double_mulFromInteger, 704314034)                \
   V(_Double, .fromInteger, Double_fromInteger, 842078193)                      \
   V(_Double, toInt, Double_toInt, 362666636)                                   \
   V(_ObjectArray, ., ObjectArray_Allocate, 97987288)                           \
@@ -71,12 +71,12 @@
   V(_GrowableObjectArray, []=, GrowableArray_setIndexed, 1048007636)           \
   V(_GrowableObjectArray, _setLength, GrowableArray_setLength, 796709584)      \
   V(_GrowableObjectArray, _setData, GrowableArray_setData, 629110947)          \
-  V(_GrowableObjectArray, add, GrowableArray_add, 2139340847)                  \
+  V(_GrowableObjectArray, add, GrowableArray_add, 1904852879)                  \
   V(_ImmutableArray, [], ImmutableArray_getIndexed, 486821199)                 \
   V(_ImmutableArray, get:length, ImmutableArray_getLength, 433698233)          \
-  V(Object, ==, Object_equal, 2126867222)                                      \
+  V(Object, ==, Object_equal, 2126897013)                                      \
   V(_StringBase, get:hashCode, String_getHashCode, 320803993)                  \
-  V(_StringBase, get:isEmpty, String_getIsEmpty, 110632481)                    \
+  V(_StringBase, get:isEmpty, String_getIsEmpty, 1026765313)                   \
   V(_StringBase, get:length, String_getLength, 320803993)                      \
   V(_StringBase, codeUnitAt, String_codeUnitAt, 984449525)                     \
   V(_OneByteString, get:hashCode, OneByteString_getHashCode, 682660413)        \
@@ -104,18 +104,18 @@
   V(_Float32Array, _new, TypedData_Float32Array_new, 1053133615)               \
   V(_Float64Array, _new, TypedData_Float64Array_new, 936673303)                \
   V(_Float32x4Array, _new, TypedData_Float32x4Array_new, 212088644)            \
-  V(_Int8Array, ., TypedData_Int8Array_factory, 632939448)                     \
-  V(_Uint8Array, ., TypedData_Uint8Array_factory, 1942390430)                  \
-  V(_Uint8ClampedArray, ., TypedData_Uint8ClampedArray_factory, 1447100174)    \
-  V(_Int16Array, ., TypedData_Int16Array_factory, 1997238698)                  \
-  V(_Uint16Array, ., TypedData_Uint16Array_factory, 672422545)                 \
-  V(_Int32Array, ., TypedData_Int32Array_factory, 504367176)                   \
-  V(_Uint32Array, ., TypedData_Uint32Array_factory, 31896861)                  \
-  V(_Int64Array, ., TypedData_Int64Array_factory, 702290418)                   \
-  V(_Uint64Array, ., TypedData_Uint64Array_factory, 59820857)                  \
-  V(_Float32Array, ., TypedData_Float32Array_factory, 1040427868)              \
-  V(_Float64Array, ., TypedData_Float64Array_factory, 969149770)               \
-  V(_Float32x4Array, ., TypedData_Float32x4Array_factory, 175242544)           \
+  V(_Int8Array, ., TypedData_Int8Array_factory, 156009974)                     \
+  V(_Uint8Array, ., TypedData_Uint8Array_factory, 1465460956)                  \
+  V(_Uint8ClampedArray, ., TypedData_Uint8ClampedArray_factory, 970170700)     \
+  V(_Int16Array, ., TypedData_Int16Array_factory, 1520309224)                  \
+  V(_Uint16Array, ., TypedData_Uint16Array_factory, 195493071)                 \
+  V(_Int32Array, ., TypedData_Int32Array_factory, 27437702)                    \
+  V(_Uint32Array, ., TypedData_Uint32Array_factory, 1702451035)                \
+  V(_Int64Array, ., TypedData_Int64Array_factory, 225360944)                   \
+  V(_Uint64Array, ., TypedData_Uint64Array_factory, 1730375031)                \
+  V(_Float32Array, ., TypedData_Float32Array_factory, 563498394)               \
+  V(_Float64Array, ., TypedData_Float64Array_factory, 492220296)               \
+  V(_Float32x4Array, ., TypedData_Float32x4Array_factory, 1845796718)          \
 
 // TODO(srdjan): Implement _FixedSizeArrayIterator, get:current and
 //   _FixedSizeArrayIterator, moveNext.
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index 3a00aed..f99d22b 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -384,7 +384,8 @@
 }
 
 
-// Set length of growable object array.
+// Set length of growable object array. The length cannot
+// be greater than the length of the data container.
 // On stack: growable array (+2), length (+1), return-address (+0).
 bool Intrinsifier::GrowableArray_setLength(Assembler* assembler) {
   Label fall_through;
@@ -392,9 +393,6 @@
   __ movl(EBX, Address(ESP, + 1 * kWordSize));  // Length value.
   __ testl(EBX, Immediate(kSmiTagMask));
   __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);  // Non-smi length.
-  __ movl(EDI, FieldAddress(EAX, GrowableObjectArray::data_offset()));
-  __ cmpl(EBX, FieldAddress(EDI, Array::length_offset()));
-  __ j(ABOVE, &fall_through, Assembler::kNearJump);
   __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), EBX);
   __ ret();
   __ Bind(&fall_through);
@@ -1589,14 +1587,21 @@
   __ movl(ECX, Address(ESP, + kEndIndexOffset));
   __ SmiUntag(ECX);
   __ subl(ECX, EBX);
+  __ xorl(EDX, EDX);
+  // EDI: Start address to copy from (untagged).
   // ECX: Untagged number of bytes to copy.
-  ASSERT(CTX == ESI);
-  __ pushl(ESI);  // Preserve CTX.
-  __ movl(ESI, EDI);  // from.
-  __ leal(EDI, FieldAddress(EAX, OneByteString::data_offset()));  // to.
-  __ rep_movsb();
-  __ popl(ESI);  // Restore CTX.
-
+  // EAX: Tagged result string.
+  // EDX: Loop counter.
+  // EBX: Scratch register.
+  Label loop, check;
+  __ jmp(&check, Assembler::kNearJump);
+  __ Bind(&loop);
+  __ movzxb(EBX, Address(EDI, EDX, TIMES_1, 0));
+  __ movb(FieldAddress(EAX, EDX, TIMES_1, OneByteString::data_offset()), BL);
+  __ incl(EDX);
+  __ Bind(&check);
+  __ cmpl(EDX, ECX);
+  __ j(LESS, &loop, Assembler::kNearJump);
   __ ret();
   __ Bind(&fall_through);
   return false;
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index 3e65b9f..d92086b 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -338,7 +338,8 @@
 }
 
 
-// Set length of growable object array.
+// Set length of growable object array. The length cannot
+// be greater than the length of the data container.
 // On stack: growable array (+2), length (+1), return-address (+0).
 bool Intrinsifier::GrowableArray_setLength(Assembler* assembler) {
   Label fall_through;
@@ -346,9 +347,6 @@
   __ movq(RCX, Address(RSP, + 1 * kWordSize));  // Length value.
   __ testq(RCX, Immediate(kSmiTagMask));
   __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);  // Non-smi length.
-  __ movq(RDX, FieldAddress(RAX, GrowableObjectArray::data_offset()));
-  __ cmpq(RCX, FieldAddress(RDX, Array::length_offset()));
-  __ j(ABOVE, &fall_through, Assembler::kNearJump);
   __ movq(FieldAddress(RAX, GrowableObjectArray::length_offset()), RCX);
   __ ret();
   __ Bind(&fall_through);
@@ -1507,16 +1505,26 @@
   __ movq(RBX, Address(RSP, + kStartIndexOffset));
   __ SmiUntag(RBX);
   __ leaq(RSI, FieldAddress(RSI, RBX, TIMES_1, OneByteString::data_offset()));
-  // RDI: Start address to copy from (untagged).
+  // RSI: Start address to copy from (untagged).
   // RBX: Untagged start index.
   __ movq(RCX, Address(RSP, + kEndIndexOffset));
   __ SmiUntag(RCX);
   __ subq(RCX, RBX);
+  __ xorq(RDX, RDX);
+  // RSI: Start address to copy from (untagged).
   // RCX: Untagged number of bytes to copy.
-
-  __ leaq(RDI, FieldAddress(RAX, OneByteString::data_offset()));  // to.
-  __ rep_movsb();
-
+  // RAX: Tagged result string
+  // RDX: Loop counter.
+  // RBX: Scratch register.
+  Label loop, check;
+  __ jmp(&check, Assembler::kNearJump);
+  __ Bind(&loop);
+  __ movzxb(RBX, Address(RSI, RDX, TIMES_1, 0));
+  __ movb(FieldAddress(RAX, RDX, TIMES_1, OneByteString::data_offset()), RBX);
+  __ incq(RDX);
+  __ Bind(&check);
+  __ cmpq(RDX, RCX);
+  __ j(LESS, &loop, Assembler::kNearJump);
   __ ret();
   __ Bind(&fall_through);
   return false;
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index d67b4e1..a4369d9 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -828,7 +828,7 @@
         code.is_optimized() ? "false" : "true");
   }
   buffer.Printf("]}");
-  isolate->stacktrace_ = strndup(buffer.buf(), buffer.length());
+  isolate->stacktrace_ = OS::StrNDup(buffer.buf(), buffer.length());
   ml.Notify();
   return true;
 }
@@ -872,7 +872,7 @@
         var_name.ToCString(), token_pos, end_pos, value.ToCString());
   }
   buffer.Printf("]}");
-  isolate->stacktrace_ = strndup(buffer.buf(), buffer.length());
+  isolate->stacktrace_ = OS::StrNDup(buffer.buf(), buffer.length());
   ml.Notify();
   return true;
 }
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index ded68b8..8b7c816 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -4461,14 +4461,22 @@
 }
 
 
-bool Function::CheckSourceFingerprint(intptr_t fp) const {
+bool Function::CheckSourceFingerprint(int32_t fp) const {
   if (SourceFingerprint() != fp) {
-    OS::Print("FP mismatch while recognizing method %s:"
-      " expecting %"Pd" found %d\n",
-      ToFullyQualifiedCString(),
-      fp,
-      SourceFingerprint());
-    return false;
+    const bool recalculatingFingerprints = false;
+    if (recalculatingFingerprints) {
+      // This output can be copied into a file, then used with sed
+      // to replace the old values.
+      // sed -i .bak -f /tmp/newkeys runtime/vm/intrinsifier.h
+      OS::Print("s/%d/%d/\n", fp, SourceFingerprint());
+    } else {
+      OS::Print("FP mismatch while recognizing method %s:"
+                " expecting %d found %d\n",
+                ToFullyQualifiedCString(),
+                fp,
+                SourceFingerprint());
+      return false;
+    }
   }
   return true;
 }
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 5473069..a81aaa0 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -1588,7 +1588,7 @@
   int32_t SourceFingerprint() const;
 
   // Return false and report an error if the fingerprint does not match.
-  bool CheckSourceFingerprint(intptr_t fp) const;
+  bool CheckSourceFingerprint(int32_t fp) const;
 
   static const int kCtorPhaseInit = 1 << 0;
   static const int kCtorPhaseBody = 1 << 1;
diff --git a/runtime/vm/os.h b/runtime/vm/os.h
index 52e575d..a41e3bd 100644
--- a/runtime/vm/os.h
+++ b/runtime/vm/os.h
@@ -81,6 +81,9 @@
   // Debug break.
   static void DebugBreak();
 
+  // Not all platform support strndup.
+  static char* StrNDup(const char* s, intptr_t n);
+
   // Print formatted output to stdout/stderr for debugging.
   static void Print(const char* format, ...) PRINTF_ATTRIBUTE(1, 2);
   static void PrintErr(const char* format, ...) PRINTF_ATTRIBUTE(1, 2);
diff --git a/runtime/vm/os_android.cc b/runtime/vm/os_android.cc
index 6b19878..c77ff51 100644
--- a/runtime/vm/os_android.cc
+++ b/runtime/vm/os_android.cc
@@ -318,6 +318,11 @@
 }
 
 
+char* OS::StrNDup(const char* s, intptr_t n) {
+  return strndup(s, n);
+}
+
+
 void OS::Print(const char* format, ...) {
   va_list args;
   va_start(args, format);
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index cf113b6..9d8a8f7 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -413,6 +413,11 @@
 }
 
 
+char* OS::StrNDup(const char* s, intptr_t n) {
+  return strndup(s, n);
+}
+
+
 void OS::Print(const char* format, ...) {
   va_list args;
   va_start(args, format);
diff --git a/runtime/vm/os_macos.cc b/runtime/vm/os_macos.cc
index fd530de..cd0b53e 100644
--- a/runtime/vm/os_macos.cc
+++ b/runtime/vm/os_macos.cc
@@ -135,6 +135,30 @@
 }
 
 
+char* OS::StrNDup(const char* s, intptr_t n) {
+  // strndup has only been added to Mac OS X in 10.7. We are supplying
+  // our own copy here if needed.
+#if !defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) || \
+    __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ <= 1060
+  intptr_t len = strlen(s);
+  if ((n < 0) || (len < 0)) {
+    return NULL;
+  }
+  if (n < len) {
+    len = n;
+  }
+  char* result = reinterpret_cast<char*>(malloc(len + 1));
+  if (result == NULL) {
+    return NULL;
+  }
+  result[len] = '\0';
+  return reinterpret_cast<char*>(memmove(result, s, len));
+#else  // !defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) || ...
+  return strndup(s, n);
+#endif  // !defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) || ...
+}
+
+
 void OS::Print(const char* format, ...) {
   va_list args;
   va_start(args, format);
diff --git a/runtime/vm/os_win.cc b/runtime/vm/os_win.cc
index 2e1a398..1c81e16 100644
--- a/runtime/vm/os_win.cc
+++ b/runtime/vm/os_win.cc
@@ -178,6 +178,23 @@
 }
 
 
+char* OS::StrNDup(const char* s, intptr_t n) {
+  intptr_t len = strlen(s);
+  if ((n < 0) || (len < 0)) {
+    return NULL;
+  }
+  if (n < len) {
+    len = n;
+  }
+  char* result = reinterpret_cast<char*>(malloc(len + 1));
+  if (result == NULL) {
+    return NULL;
+  }
+  result[len] = '\0';
+  return reinterpret_cast<char*>(memcpy(result, s, len));
+}
+
+
 void OS::Print(const char* format, ...) {
   va_list args;
   va_start(args, format);
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 83dcbcf..09da9c6 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -6411,10 +6411,12 @@
   } else if (CurrentToken() == Token::kSEMICOLON) {
     // Empty statement, nothing to do.
     ConsumeToken();
-  } else if ((CurrentToken() == Token::kTHROW) &&
-             (LookaheadToken(1) == Token::kSEMICOLON)) {
+  } else if ((CurrentToken() == Token::kRETHROW) ||
+            ((CurrentToken() == Token::kTHROW) &&
+             (LookaheadToken(1) == Token::kSEMICOLON))) {
     // Rethrow of current exception. Throwing of an exception object
     // is an expression and is handled in ParseExpr().
+    // TODO(hausner): remove support for 'throw;'.
     ConsumeToken();
     ExpectSemicolon();
     // Check if it is ok to do a rethrow.
diff --git a/runtime/vm/simulator_mips.cc b/runtime/vm/simulator_mips.cc
index c868443..7405738 100644
--- a/runtime/vm/simulator_mips.cc
+++ b/runtime/vm/simulator_mips.cc
@@ -642,8 +642,7 @@
 }
 
 
-// Sets the register in the architecture state. It will also deal with updating
-// Simulator internal state for special registers such as PC.
+// Sets the register in the architecture state.
 void Simulator::set_register(Register reg, int32_t value) {
   if (reg != R0) {
     registers_[reg] = value;
@@ -651,8 +650,36 @@
 }
 
 
-// Get the register from the architecture state. This function does handle
-// the special case of accessing the PC register.
+void Simulator::set_fregister(FRegister reg, int32_t value) {
+  ASSERT(reg >= 0);
+  ASSERT(reg < kNumberOfFRegisters);
+  fregisters_[reg] = value;
+}
+
+
+void Simulator::set_fregister_float(FRegister reg, float value) {
+  ASSERT(reg >= 0);
+  ASSERT(reg < kNumberOfFRegisters);
+  fregisters_[reg] = bit_cast<int32_t, float>(value);
+}
+
+
+void Simulator::set_fregister_long(FRegister reg, int64_t value) {
+  ASSERT(reg >= 0);
+  ASSERT(reg < kNumberOfFRegisters);
+  ASSERT((reg & 1) == 0);
+  fregisters_[reg] = Utils::Low32Bits(value);
+  fregisters_[reg + 1] = Utils::High32Bits(value);
+}
+
+
+void Simulator::set_fregister_double(FRegister reg, double value) {
+  const int64_t ival = bit_cast<int64_t, double>(value);
+  set_fregister_long(reg, ival);
+}
+
+
+// Get the register from the architecture state.
 int32_t Simulator::get_register(Register reg) const {
   if (reg == R0) {
     return 0;
@@ -661,15 +688,36 @@
 }
 
 
-void Simulator::set_fregister(FRegister reg, double value) {
+int32_t Simulator::get_fregister(FRegister reg) const {
   ASSERT((reg >= 0) && (reg < kNumberOfFRegisters));
-  fregisters_[reg] = value;
+  return fregisters_[reg];
 }
 
 
-double Simulator::get_fregister(FRegister reg) const {
-  ASSERT((reg >= 0) && (reg < kNumberOfFRegisters));
-  return fregisters_[reg];
+float Simulator::get_fregister_float(FRegister reg) const {
+  ASSERT(reg >= 0);
+  ASSERT(reg < kNumberOfFRegisters);
+  return bit_cast<float, int32_t>(fregisters_[reg]);
+}
+
+
+int64_t Simulator::get_fregister_long(FRegister reg) const {
+  ASSERT(reg >= 0);
+  ASSERT(reg < kNumberOfFRegisters);
+  ASSERT((reg & 1) == 0);
+  const int32_t low = fregisters_[reg];
+  const int32_t high = fregisters_[reg + 1];
+  const int64_t value = Utils::LowHighTo64Bits(low, high);
+  return value;
+}
+
+
+double Simulator::get_fregister_double(FRegister reg) const {
+  ASSERT(reg >= 0);
+  ASSERT(reg < kNumberOfFRegisters);
+  ASSERT((reg & 1) == 0);
+  const int64_t value = get_fregister_long(reg);
+  return bit_cast<double, int64_t>(value);
 }
 
 
@@ -794,6 +842,26 @@
 }
 
 
+double Simulator::ReadD(uword addr, Instr* instr) {
+  if ((addr & 7) == 0) {
+    double* ptr = reinterpret_cast<double*>(addr);
+    return *ptr;
+  }
+  UnalignedAccess("double-precision floating point read", addr, instr);
+  return 0.0;
+}
+
+
+void Simulator::WriteD(uword addr, double value, Instr* instr) {
+  if ((addr & 7) == 0) {
+    double* ptr = reinterpret_cast<double*>(addr);
+    *ptr = value;
+    return;
+  }
+  UnalignedAccess("double-precision floating point write", addr, instr);
+}
+
+
 bool Simulator::OverflowFrom(int32_t alu_out,
                              int32_t left, int32_t right, bool addition) {
   bool overflow;
@@ -905,7 +973,7 @@
       set_register(RA, icount_);
 
       // Zap floating point registers.
-      double zap_dvalue = static_cast<double>(icount_);
+      int32_t zap_dvalue = icount_;
       for (int i = F0; i <= F31; i++) {
         set_fregister(static_cast<FRegister>(i), zap_dvalue);
       }
@@ -1286,6 +1354,72 @@
 }
 
 
+void Simulator::DecodeCop1(Instr* instr) {
+  ASSERT(instr->OpcodeField() == COP1);
+  if (instr->HasFormat()) {
+    // If the rs field is a valid format, then the function field identifies the
+    // instruction.
+    switch (instr->Cop1FunctionField()) {
+      case COP1_ADD: {
+        // Format(instr, "add.'fmt 'fd, 'fs, 'ft");
+        if (instr->FormatField() == FMT_S) {
+          float fs_val = get_fregister_float(instr->FsField());
+          float ft_val = get_fregister_float(instr->FtField());
+          set_fregister_float(instr->FdField(), fs_val + ft_val);
+        } else {
+          ASSERT(instr->FormatField() == FMT_D);  // Only S and D supported.
+          double fs_val = get_fregister_double(instr->FsField());
+          double ft_val = get_fregister_double(instr->FtField());
+          set_fregister_double(instr->FdField(), fs_val + ft_val);
+        }
+        break;
+      }
+      case COP1_MOV: {
+        // Format(instr, "mov.'fmt 'fd, 'fs");
+        ASSERT(instr->FtField() == F0);
+        if (instr->FormatField() == FMT_S) {
+          float fs_val = get_fregister_float(instr->FsField());
+          set_fregister_float(instr->FdField(), fs_val);
+        } else {
+          ASSERT(instr->FormatField() == FMT_D);
+          double fs_val = get_fregister_double(instr->FsField());
+          set_fregister_double(instr->FdField(), fs_val);
+        }
+        break;
+      }
+      default: {
+        OS::PrintErr("DecodeCop1: 0x%x\n", instr->InstructionBits());
+        UnimplementedInstruction(instr);
+        break;
+      }
+    }
+  } else {
+    // If the rs field isn't a valid format, then it must be a sub-op.
+    switch (instr->Cop1SubField()) {
+      case COP1_MF: {
+        // Format(instr, "mfc1 'rt, 'fs");
+        ASSERT(instr->Bits(0, 11) == 0);
+        int32_t fs_val = get_fregister(instr->FsField());
+        set_register(instr->RtField(), fs_val);
+        break;
+      }
+      case COP1_MT: {
+        // Format(instr, "mtc1 'rt, 'fs");
+        ASSERT(instr->Bits(0, 11) == 0);
+        int32_t rt_val = get_register(instr->RtField());
+        set_fregister(instr->FsField(), rt_val);
+        break;
+      }
+      default: {
+        OS::PrintErr("DecodeCop1: 0x%x\n", instr->InstructionBits());
+        UnimplementedInstruction(instr);
+        break;
+      }
+    }
+  }
+}
+
+
 void Simulator::InstructionDecode(Instr* instr) {
   if (FLAG_trace_sim) {
     const uword start = reinterpret_cast<uword>(instr);
@@ -1306,6 +1440,10 @@
       DecodeRegImm(instr);
       break;
     }
+    case COP1: {
+      DecodeCop1(instr);
+      break;
+    }
     case ADDIU: {
       // Format(instr, "addiu 'rt, 'rs, 'imms");
       int32_t rs_val = get_register(instr->RsField());
@@ -1403,6 +1541,19 @@
       }
       break;
     }
+    case LDC1: {
+      // Format(instr, "ldc1 'ft, 'imms('rs)");
+      int32_t base_val = get_register(instr->RsField());
+      int32_t imm_val = instr->SImmField();
+      uword addr = base_val + imm_val;
+      if (Simulator::IsIllegalAddress(addr)) {
+        HandleIllegalAccess(addr, instr);
+      } else {
+        double value = ReadD(addr, instr);
+        set_fregister_double(instr->FtField(), value);
+      }
+      break;
+    }
     case LH: {
       // Format(instr, "lh 'rt, 'imms('rs)");
       int32_t base_val = get_register(instr->RsField());
@@ -1447,6 +1598,19 @@
       }
       break;
     }
+    case LWC1: {
+      // Format(instr, "lwc1 'ft, 'imms('rs)");
+      int32_t base_val = get_register(instr->RsField());
+      int32_t imm_val = instr->SImmField();
+      uword addr = base_val + imm_val;
+      if (Simulator::IsIllegalAddress(addr)) {
+        HandleIllegalAccess(addr, instr);
+      } else {
+        int32_t value = ReadW(addr, instr);
+        set_fregister(instr->FtField(), value);
+      }
+      break;
+    }
     case ORI: {
       // Format(instr, "ori 'rt, 'rs, 'immu");
       int32_t rs_val = get_register(instr->RsField());
@@ -1466,6 +1630,19 @@
       }
       break;
     }
+    case SDC1: {
+      // Format(instr, "sdc1 'ft, 'imms('rs)");
+      int32_t base_val = get_register(instr->RsField());
+      int32_t imm_val = instr->SImmField();
+      uword addr = base_val + imm_val;
+      if (Simulator::IsIllegalAddress(addr)) {
+        HandleIllegalAccess(addr, instr);
+      } else {
+        double value = get_fregister_double(instr->FtField());
+        WriteD(addr, value, instr);
+      }
+      break;
+    }
     case SH: {
       // Format(instr, "sh 'rt, 'imms('rs)");
       int32_t rt_val = get_register(instr->RtField());
@@ -1492,6 +1669,19 @@
       }
       break;
     }
+    case SWC1: {
+      // Format(instr, "swc1 'ft, 'imms('rs)");
+      int32_t base_val = get_register(instr->RsField());
+      int32_t imm_val = instr->SImmField();
+      uword addr = base_val + imm_val;
+      if (Simulator::IsIllegalAddress(addr)) {
+        HandleIllegalAccess(addr, instr);
+      } else {
+        int32_t value = get_fregister(instr->FtField());
+        WriteW(addr, value, instr);
+      }
+      break;
+    }
     default: {
       OS::PrintErr("Undecoded instruction: 0x%x at %p\n",
                     instr->InstructionBits(), instr);
diff --git a/runtime/vm/simulator_mips.h b/runtime/vm/simulator_mips.h
index f5695fb..a3bd6c7 100644
--- a/runtime/vm/simulator_mips.h
+++ b/runtime/vm/simulator_mips.h
@@ -39,8 +39,16 @@
   int32_t get_register(Register reg) const;
 
   // Accessors for floating point register state.
-  void set_fregister(FRegister freg, double value);
-  double get_fregister(FRegister) const;
+  void set_fregister(FRegister freg, int32_t value);
+  void set_fregister_float(FRegister freg, float value);
+  void set_fregister_double(FRegister freg, double value);
+  void set_fregister_long(FRegister freg, int64_t value);
+
+  int32_t get_fregister(FRegister freg) const;
+  float get_fregister_float(FRegister freg) const;
+  double get_fregister_double(FRegister freg) const;
+  int64_t get_fregister_long(FRegister freg) const;
+
 
   // Accessor for the pc.
   void set_pc(int32_t value) { pc_ = value; }
@@ -93,7 +101,7 @@
   int32_t lo_reg_;
 
   int32_t registers_[kNumberOfCpuRegisters];
-  double fregisters_[kNumberOfFRegisters];
+  int32_t fregisters_[kNumberOfFRegisters];
   uword pc_;
 
   // Simulator support.
@@ -138,12 +146,16 @@
   inline void WriteH(uword addr, uint16_t value, Instr* isntr);
   inline void WriteW(uword addr, int value, Instr* instr);
 
+  inline double ReadD(uword addr, Instr* instr);
+  inline void WriteD(uword addr, double value, Instr* instr);
+
   void DoBranch(Instr* instr, bool taken, bool likely);
   void DoBreak(Instr *instr);
 
   void DecodeSpecial(Instr* instr);
   void DecodeSpecial2(Instr* instr);
   void DecodeRegImm(Instr* instr);
+  void DecodeCop1(Instr* instr);
   void InstructionDecode(Instr* instr);
 
   void Execute();
diff --git a/runtime/vm/token.h b/runtime/vm/token.h
index daf8cea..c568ddd 100644
--- a/runtime/vm/token.h
+++ b/runtime/vm/token.h
@@ -170,6 +170,7 @@
   KW(kNULL, "null", 0, kKeyword)                                               \
   KW(kOPERATOR, "operator", 0, kPseudoKeyword)                                 \
   KW(kPART, "part", 0, kPseudoKeyword)                                         \
+  KW(kRETHROW, "rethrow", 0, kKeyword)                                         \
   KW(kRETURN, "return", 0, kKeyword)                                           \
   KW(kSET, "set", 0, kPseudoKeyword)                                           \
   KW(kSTATIC, "static", 0, kPseudoKeyword)                                     \
diff --git a/tests/language/if_conversion_vm_test.dart b/tests/language/if_conversion_vm_test.dart
index 22e6203..3ed12a1 100644
--- a/tests/language/if_conversion_vm_test.dart
+++ b/tests/language/if_conversion_vm_test.dart
@@ -30,6 +30,15 @@
 
 bigPower(i) => (i == 11) ? 0 : POWER_OF_2;
 
+cse(i) {
+  final a = i == 0 ? 0 : 1;
+  final b = i == 0 ? 2 : 3;
+  return a + b;
+}
+
+f17(b) => b ? 0 : 11;
+f18(b) => b ? 2 : 0;
+
 main() {
   for (var i = 0; i < 10000; i++) {
     f1(i);
@@ -48,7 +57,10 @@
     f14(i);
     f15(i);
     f16(i);
+    cse(i);
     bigPower(i);
+    f17(true);
+    f18(true);
   }
 
   Expect.equals(0, f1(0));
@@ -89,4 +101,13 @@
 
   Expect.equals(0, bigPower(11));
   Expect.equals(POWER_OF_2, bigPower(12));
+
+  Expect.equals(2, cse(0));
+  Expect.equals(4, cse(1));
+
+  Expect.equals(11, f17(false));
+  Expect.equals(0, f17(true));
+
+  Expect.equals(0, f18(false));
+  Expect.equals(2, f18(true));
 }
\ No newline at end of file
diff --git a/tests/language/language.status b/tests/language/language.status
index 13347e4..f732024 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -555,6 +555,8 @@
 
 [ $compiler == dart2dart && $minified ]
 
+rethrow_test: Fail
+
 # TODO(tball): Assign proper bug numbers.
 class_literal_test/none: Fail
 
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 10d7d8d..ff16206 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -133,6 +133,7 @@
 constructor_negative_test: Pass # Wrong reason: the expression 'C()' is valid with class literals.
 
 throw_expr_test: Fail
+rethrow_test: Fail
 metadata_test: Fail # Metadata on type parameters not supported.
 infinity_test: Fail # Issue 4984
 positive_bit_operations_test: Fail # (floitsch): This will be fixed when dart2js uses unsigned input for >>.
diff --git a/tests/language/rethrow_test.dart b/tests/language/rethrow_test.dart
index 7c3bf04..4b535c9 100644
--- a/tests/language/rethrow_test.dart
+++ b/tests/language/rethrow_test.dart
@@ -29,7 +29,7 @@
           Expect.fail("Should have thrown an exception");
         } catch (e) {
           Expect.equals(true, identical(e, currentException));
-          throw;
+          rethrow;
           Expect.fail("Should have thrown an exception");
         }
       } on OtherException catch (e) {
@@ -47,7 +47,7 @@
         Expect.fail("Should have thrown an exception");
       } catch (e) {
         Expect.equals(true, identical(e, currentException));
-        throw;
+        rethrow;
         Expect.fail("Should have thrown an exception");
       }
     } catch (e) {
diff --git a/tools/VERSION b/tools/VERSION
index e4e6452..971672e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
 MINOR 4
 BUILD 6
-PATCH 0
+PATCH 1
diff --git a/tools/dom/scripts/fremontcutbuilder.py b/tools/dom/scripts/fremontcutbuilder.py
index c0919fb..bb82b26 100755
--- a/tools/dom/scripts/fremontcutbuilder.py
+++ b/tools/dom/scripts/fremontcutbuilder.py
@@ -148,36 +148,6 @@
 def main(parallel=False):
   current_dir = os.path.dirname(__file__)
 
-  webkit_dirs = [
-    'css',
-    'dom',
-    'fileapi',
-    'html',
-    'html/canvas',
-    'inspector',
-    'loader',
-    'loader/appcache',
-    'Modules/battery',
-    'Modules/filesystem',
-    'Modules/gamepad',
-    'Modules/geolocation',
-    'Modules/indexeddb',
-    'Modules/mediasource',
-    'Modules/mediastream',
-    'Modules/notifications',
-    'Modules/quota',
-    'Modules/speech',
-    'Modules/webaudio',
-    'Modules/webdatabase',
-    'Modules/websockets',
-    'page',
-    'plugins',
-    'storage',
-    'svg',
-    'workers',
-    'xml',
-    ]
-
   ignored_idls = [
     'AbstractView.idl',
     ]
@@ -190,15 +160,15 @@
     raise RuntimeError('directory not found: %s' % webcore_dir)
 
   def visitor(arg, dir_name, names):
+    if os.path.basename(dir_name) in ['bindings', 'testing']:
+      names[:] = [] # Do not go underneath
     for name in names:
       file_name = os.path.join(dir_name, name)
       (interface, ext) = os.path.splitext(file_name)
       if ext == '.idl' and name not in ignored_idls:
         idl_files.append(file_name)
 
-  for dir_name in webkit_dirs:
-    dir_path = os.path.join(webcore_dir, dir_name)
-    os.path.walk(dir_path, visitor, None)
+  os.path.walk(webcore_dir, visitor, webcore_dir)
 
   database_dir = os.path.join(current_dir, '..', 'database')
   return build_database(idl_files, database_dir, parallel=parallel)