Upgrade V8 to version 4.9.385.28

https://chromium.googlesource.com/v8/v8/+/4.9.385.28

FPIIM-449

Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/src/ic/ic-state.cc b/src/ic/ic-state.cc
index 9c883ad..4bdaf3f 100644
--- a/src/ic/ic-state.cc
+++ b/src/ic/ic-state.cc
@@ -2,54 +2,46 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
+#include "src/ic/ic-state.h"
 
 #include "src/ic/ic.h"
-#include "src/ic/ic-state.h"
 
 namespace v8 {
 namespace internal {
 
 // static
 void ICUtility::Clear(Isolate* isolate, Address address,
-                      ConstantPoolArray* constant_pool) {
+                      Address constant_pool) {
   IC::Clear(isolate, address, constant_pool);
 }
 
 
-CallICState::CallICState(ExtraICState extra_ic_state)
-    : argc_(ArgcBits::decode(extra_ic_state)),
-      call_type_(CallTypeBits::decode(extra_ic_state)) {}
-
-
-ExtraICState CallICState::GetExtraICState() const {
-  ExtraICState extra_ic_state =
-      ArgcBits::encode(argc_) | CallTypeBits::encode(call_type_);
-  return extra_ic_state;
-}
-
-
 std::ostream& operator<<(std::ostream& os, const CallICState& s) {
-  return os << "(args(" << s.arg_count() << "), "
-            << (s.call_type() == CallICState::METHOD ? "METHOD" : "FUNCTION")
-            << ", ";
+  return os << "(args(" << s.argc() << "), " << s.convert_mode() << ", ";
 }
 
 
+// static
+STATIC_CONST_MEMBER_DEFINITION const int BinaryOpICState::FIRST_TOKEN;
+
+
+// static
+STATIC_CONST_MEMBER_DEFINITION const int BinaryOpICState::LAST_TOKEN;
+
+
 BinaryOpICState::BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state)
-    : isolate_(isolate) {
+    : fixed_right_arg_(
+          HasFixedRightArgField::decode(extra_ic_state)
+              ? Just(1 << FixedRightArgValueField::decode(extra_ic_state))
+              : Nothing<int>()),
+      isolate_(isolate) {
   op_ =
       static_cast<Token::Value>(FIRST_TOKEN + OpField::decode(extra_ic_state));
-  mode_ = OverwriteModeField::decode(extra_ic_state);
-  fixed_right_arg_ =
-      Maybe<int>(HasFixedRightArgField::decode(extra_ic_state),
-                 1 << FixedRightArgValueField::decode(extra_ic_state));
+  strong_ = StrengthField::decode(extra_ic_state);
   left_kind_ = LeftKindField::decode(extra_ic_state);
-  if (fixed_right_arg_.has_value) {
-    right_kind_ = Smi::IsValid(fixed_right_arg_.value) ? SMI : INT32;
-  } else {
-    right_kind_ = RightKindField::decode(extra_ic_state);
-  }
+  right_kind_ = fixed_right_arg_.IsJust()
+                    ? (Smi::IsValid(fixed_right_arg_.FromJust()) ? SMI : INT32)
+                    : RightKindField::decode(extra_ic_state);
   result_kind_ = ResultKindField::decode(extra_ic_state);
   DCHECK_LE(FIRST_TOKEN, op_);
   DCHECK_LE(op_, LAST_TOKEN);
@@ -58,13 +50,12 @@
 
 ExtraICState BinaryOpICState::GetExtraICState() const {
   ExtraICState extra_ic_state =
-      OpField::encode(op_ - FIRST_TOKEN) | OverwriteModeField::encode(mode_) |
-      LeftKindField::encode(left_kind_) |
-      ResultKindField::encode(result_kind_) |
-      HasFixedRightArgField::encode(fixed_right_arg_.has_value);
-  if (fixed_right_arg_.has_value) {
+      OpField::encode(op_ - FIRST_TOKEN) | LeftKindField::encode(left_kind_) |
+      ResultKindField::encode(result_kind_) | StrengthField::encode(strong_) |
+      HasFixedRightArgField::encode(fixed_right_arg_.IsJust());
+  if (fixed_right_arg_.IsJust()) {
     extra_ic_state = FixedRightArgValueField::update(
-        extra_ic_state, WhichPowerOf2(fixed_right_arg_.value));
+        extra_ic_state, WhichPowerOf2(fixed_right_arg_.FromJust()));
   } else {
     extra_ic_state = RightKindField::update(extra_ic_state, right_kind_);
   }
@@ -79,246 +70,148 @@
 // expensive at runtime. When solved we should be able to add most binops to
 // the snapshot instead of hand-picking them.
 // Generated list of commonly used stubs
-#define GENERATE(op, left_kind, right_kind, result_kind, mode) \
-  do {                                                         \
-    BinaryOpICState state(isolate, op, mode);                  \
-    state.left_kind_ = left_kind;                              \
-    state.fixed_right_arg_.has_value = false;                  \
-    state.right_kind_ = right_kind;                            \
-    state.result_kind_ = result_kind;                          \
-    Generate(isolate, state);                                  \
+#define GENERATE(op, left_kind, right_kind, result_kind) \
+  do {                                                   \
+    BinaryOpICState state(isolate, op, Strength::WEAK);  \
+    state.left_kind_ = left_kind;                        \
+    state.fixed_right_arg_ = Nothing<int>();             \
+    state.right_kind_ = right_kind;                      \
+    state.result_kind_ = result_kind;                    \
+    Generate(isolate, state);                            \
   } while (false)
-  GENERATE(Token::ADD, INT32, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::ADD, INT32, INT32, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::ADD, INT32, INT32, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::ADD, INT32, INT32, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::ADD, INT32, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::ADD, INT32, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::ADD, INT32, SMI, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::ADD, INT32, SMI, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::ADD, NUMBER, INT32, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::ADD, NUMBER, SMI, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::ADD, SMI, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::ADD, SMI, INT32, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::ADD, SMI, INT32, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::ADD, SMI, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::ADD, SMI, SMI, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::ADD, SMI, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_AND, INT32, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_AND, INT32, INT32, SMI, NO_OVERWRITE);
-  GENERATE(Token::BIT_AND, INT32, INT32, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_AND, INT32, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::BIT_AND, INT32, SMI, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_AND, INT32, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_AND, NUMBER, INT32, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_AND, NUMBER, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::BIT_AND, NUMBER, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_AND, SMI, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::BIT_AND, SMI, INT32, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_AND, SMI, NUMBER, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_AND, SMI, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_OR, INT32, INT32, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_OR, INT32, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_OR, INT32, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::BIT_OR, INT32, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_OR, NUMBER, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::BIT_OR, NUMBER, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_OR, SMI, INT32, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_XOR, INT32, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_XOR, INT32, INT32, SMI, NO_OVERWRITE);
-  GENERATE(Token::BIT_XOR, INT32, INT32, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_XOR, INT32, NUMBER, SMI, NO_OVERWRITE);
-  GENERATE(Token::BIT_XOR, INT32, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::BIT_XOR, NUMBER, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::BIT_XOR, NUMBER, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::BIT_XOR, NUMBER, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::BIT_XOR, SMI, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::BIT_XOR, SMI, INT32, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_XOR, SMI, INT32, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_XOR, SMI, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::DIV, INT32, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::DIV, INT32, INT32, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::DIV, INT32, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::DIV, INT32, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::DIV, INT32, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::DIV, INT32, SMI, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::DIV, NUMBER, INT32, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::DIV, NUMBER, INT32, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::DIV, NUMBER, SMI, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::DIV, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::DIV, SMI, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::DIV, SMI, INT32, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::DIV, SMI, INT32, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::DIV, SMI, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::DIV, SMI, SMI, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::DIV, SMI, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::DIV, SMI, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::DIV, SMI, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::MOD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::MOD, SMI, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::MOD, SMI, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::MUL, INT32, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::MUL, INT32, INT32, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::MUL, INT32, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::MUL, INT32, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::MUL, INT32, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::MUL, INT32, SMI, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::MUL, INT32, SMI, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::MUL, NUMBER, INT32, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::MUL, NUMBER, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::MUL, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::MUL, NUMBER, SMI, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::MUL, SMI, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::MUL, SMI, INT32, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::MUL, SMI, INT32, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::MUL, SMI, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::MUL, SMI, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::MUL, SMI, SMI, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::MUL, SMI, SMI, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::MUL, SMI, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::MUL, SMI, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::MUL, SMI, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::SAR, INT32, SMI, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::SAR, INT32, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::SAR, INT32, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::SAR, NUMBER, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::SAR, NUMBER, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::SAR, SMI, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::SAR, SMI, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::SHL, INT32, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::SHL, INT32, SMI, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::SHL, INT32, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::SHL, INT32, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::SHL, NUMBER, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::SHL, SMI, SMI, INT32, NO_OVERWRITE);
-  GENERATE(Token::SHL, SMI, SMI, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::SHL, SMI, SMI, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::SHL, SMI, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::SHL, SMI, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::SHL, SMI, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::SHR, INT32, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::SHR, INT32, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::SHR, INT32, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::SHR, NUMBER, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::SHR, NUMBER, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::SHR, NUMBER, SMI, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::SHR, SMI, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::SHR, SMI, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::SHR, SMI, SMI, SMI, OVERWRITE_RIGHT);
-  GENERATE(Token::SUB, INT32, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::SUB, INT32, INT32, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::SUB, INT32, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::SUB, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::SUB, INT32, SMI, INT32, OVERWRITE_LEFT);
-  GENERATE(Token::SUB, INT32, SMI, INT32, OVERWRITE_RIGHT);
-  GENERATE(Token::SUB, NUMBER, INT32, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::SUB, NUMBER, INT32, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::SUB, NUMBER, SMI, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::SUB, SMI, INT32, INT32, NO_OVERWRITE);
-  GENERATE(Token::SUB, SMI, NUMBER, NUMBER, NO_OVERWRITE);
-  GENERATE(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_LEFT);
-  GENERATE(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
-  GENERATE(Token::SUB, SMI, SMI, SMI, NO_OVERWRITE);
-  GENERATE(Token::SUB, SMI, SMI, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::SUB, SMI, SMI, SMI, OVERWRITE_RIGHT);
+  GENERATE(Token::ADD, INT32, INT32, INT32);
+  GENERATE(Token::ADD, INT32, INT32, NUMBER);
+  GENERATE(Token::ADD, INT32, NUMBER, NUMBER);
+  GENERATE(Token::ADD, INT32, SMI, INT32);
+  GENERATE(Token::ADD, NUMBER, INT32, NUMBER);
+  GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER);
+  GENERATE(Token::ADD, NUMBER, SMI, NUMBER);
+  GENERATE(Token::ADD, SMI, INT32, INT32);
+  GENERATE(Token::ADD, SMI, INT32, NUMBER);
+  GENERATE(Token::ADD, SMI, NUMBER, NUMBER);
+  GENERATE(Token::ADD, SMI, SMI, INT32);
+  GENERATE(Token::ADD, SMI, SMI, SMI);
+  GENERATE(Token::BIT_AND, INT32, INT32, INT32);
+  GENERATE(Token::BIT_AND, INT32, INT32, SMI);
+  GENERATE(Token::BIT_AND, INT32, SMI, INT32);
+  GENERATE(Token::BIT_AND, INT32, SMI, SMI);
+  GENERATE(Token::BIT_AND, NUMBER, INT32, INT32);
+  GENERATE(Token::BIT_AND, NUMBER, SMI, SMI);
+  GENERATE(Token::BIT_AND, SMI, INT32, INT32);
+  GENERATE(Token::BIT_AND, SMI, INT32, SMI);
+  GENERATE(Token::BIT_AND, SMI, NUMBER, SMI);
+  GENERATE(Token::BIT_AND, SMI, SMI, SMI);
+  GENERATE(Token::BIT_OR, INT32, INT32, INT32);
+  GENERATE(Token::BIT_OR, INT32, INT32, SMI);
+  GENERATE(Token::BIT_OR, INT32, SMI, INT32);
+  GENERATE(Token::BIT_OR, INT32, SMI, SMI);
+  GENERATE(Token::BIT_OR, NUMBER, SMI, INT32);
+  GENERATE(Token::BIT_OR, NUMBER, SMI, SMI);
+  GENERATE(Token::BIT_OR, SMI, INT32, INT32);
+  GENERATE(Token::BIT_OR, SMI, INT32, SMI);
+  GENERATE(Token::BIT_OR, SMI, SMI, SMI);
+  GENERATE(Token::BIT_XOR, INT32, INT32, INT32);
+  GENERATE(Token::BIT_XOR, INT32, INT32, SMI);
+  GENERATE(Token::BIT_XOR, INT32, NUMBER, SMI);
+  GENERATE(Token::BIT_XOR, INT32, SMI, INT32);
+  GENERATE(Token::BIT_XOR, NUMBER, INT32, INT32);
+  GENERATE(Token::BIT_XOR, NUMBER, SMI, INT32);
+  GENERATE(Token::BIT_XOR, NUMBER, SMI, SMI);
+  GENERATE(Token::BIT_XOR, SMI, INT32, INT32);
+  GENERATE(Token::BIT_XOR, SMI, INT32, SMI);
+  GENERATE(Token::BIT_XOR, SMI, SMI, SMI);
+  GENERATE(Token::DIV, INT32, INT32, INT32);
+  GENERATE(Token::DIV, INT32, INT32, NUMBER);
+  GENERATE(Token::DIV, INT32, NUMBER, NUMBER);
+  GENERATE(Token::DIV, INT32, SMI, INT32);
+  GENERATE(Token::DIV, INT32, SMI, NUMBER);
+  GENERATE(Token::DIV, NUMBER, INT32, NUMBER);
+  GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER);
+  GENERATE(Token::DIV, NUMBER, SMI, NUMBER);
+  GENERATE(Token::DIV, SMI, INT32, INT32);
+  GENERATE(Token::DIV, SMI, INT32, NUMBER);
+  GENERATE(Token::DIV, SMI, NUMBER, NUMBER);
+  GENERATE(Token::DIV, SMI, SMI, NUMBER);
+  GENERATE(Token::DIV, SMI, SMI, SMI);
+  GENERATE(Token::MOD, NUMBER, SMI, NUMBER);
+  GENERATE(Token::MOD, SMI, SMI, SMI);
+  GENERATE(Token::MUL, INT32, INT32, INT32);
+  GENERATE(Token::MUL, INT32, INT32, NUMBER);
+  GENERATE(Token::MUL, INT32, NUMBER, NUMBER);
+  GENERATE(Token::MUL, INT32, SMI, INT32);
+  GENERATE(Token::MUL, INT32, SMI, NUMBER);
+  GENERATE(Token::MUL, NUMBER, INT32, NUMBER);
+  GENERATE(Token::MUL, NUMBER, NUMBER, NUMBER);
+  GENERATE(Token::MUL, NUMBER, SMI, NUMBER);
+  GENERATE(Token::MUL, SMI, INT32, INT32);
+  GENERATE(Token::MUL, SMI, INT32, NUMBER);
+  GENERATE(Token::MUL, SMI, NUMBER, NUMBER);
+  GENERATE(Token::MUL, SMI, SMI, INT32);
+  GENERATE(Token::MUL, SMI, SMI, NUMBER);
+  GENERATE(Token::MUL, SMI, SMI, SMI);
+  GENERATE(Token::SAR, INT32, SMI, INT32);
+  GENERATE(Token::SAR, INT32, SMI, SMI);
+  GENERATE(Token::SAR, NUMBER, SMI, SMI);
+  GENERATE(Token::SAR, SMI, SMI, SMI);
+  GENERATE(Token::SHL, INT32, SMI, INT32);
+  GENERATE(Token::SHL, INT32, SMI, SMI);
+  GENERATE(Token::SHL, NUMBER, SMI, SMI);
+  GENERATE(Token::SHL, SMI, SMI, INT32);
+  GENERATE(Token::SHL, SMI, SMI, SMI);
+  GENERATE(Token::SHR, INT32, SMI, SMI);
+  GENERATE(Token::SHR, NUMBER, SMI, INT32);
+  GENERATE(Token::SHR, NUMBER, SMI, SMI);
+  GENERATE(Token::SHR, SMI, SMI, SMI);
+  GENERATE(Token::SUB, INT32, INT32, INT32);
+  GENERATE(Token::SUB, INT32, NUMBER, NUMBER);
+  GENERATE(Token::SUB, INT32, SMI, INT32);
+  GENERATE(Token::SUB, NUMBER, INT32, NUMBER);
+  GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER);
+  GENERATE(Token::SUB, NUMBER, SMI, NUMBER);
+  GENERATE(Token::SUB, SMI, INT32, INT32);
+  GENERATE(Token::SUB, SMI, NUMBER, NUMBER);
+  GENERATE(Token::SUB, SMI, SMI, SMI);
 #undef GENERATE
-#define GENERATE(op, left_kind, fixed_right_arg_value, result_kind, mode) \
-  do {                                                                    \
-    BinaryOpICState state(isolate, op, mode);                             \
-    state.left_kind_ = left_kind;                                         \
-    state.fixed_right_arg_.has_value = true;                              \
-    state.fixed_right_arg_.value = fixed_right_arg_value;                 \
-    state.right_kind_ = SMI;                                              \
-    state.result_kind_ = result_kind;                                     \
-    Generate(isolate, state);                                             \
+#define GENERATE(op, left_kind, fixed_right_arg_value, result_kind) \
+  do {                                                              \
+    BinaryOpICState state(isolate, op, Strength::WEAK);             \
+    state.left_kind_ = left_kind;                                   \
+    state.fixed_right_arg_ = Just(fixed_right_arg_value);           \
+    state.right_kind_ = SMI;                                        \
+    state.result_kind_ = result_kind;                               \
+    Generate(isolate, state);                                       \
   } while (false)
-  GENERATE(Token::MOD, SMI, 2, SMI, NO_OVERWRITE);
-  GENERATE(Token::MOD, SMI, 4, SMI, NO_OVERWRITE);
-  GENERATE(Token::MOD, SMI, 4, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::MOD, SMI, 8, SMI, NO_OVERWRITE);
-  GENERATE(Token::MOD, SMI, 16, SMI, OVERWRITE_LEFT);
-  GENERATE(Token::MOD, SMI, 32, SMI, NO_OVERWRITE);
-  GENERATE(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE);
+  GENERATE(Token::MOD, SMI, 2, SMI);
+  GENERATE(Token::MOD, SMI, 4, SMI);
+  GENERATE(Token::MOD, SMI, 8, SMI);
+  GENERATE(Token::MOD, SMI, 16, SMI);
+  GENERATE(Token::MOD, SMI, 32, SMI);
+  GENERATE(Token::MOD, SMI, 2048, SMI);
 #undef GENERATE
 }
 
 
-Type* BinaryOpICState::GetResultType(Zone* zone) const {
+Type* BinaryOpICState::GetResultType() const {
   Kind result_kind = result_kind_;
   if (HasSideEffects()) {
     result_kind = NONE;
   } else if (result_kind == GENERIC && op_ == Token::ADD) {
-    return Type::Union(Type::Number(zone), Type::String(zone), zone);
+    return Type::NumberOrString();
   } else if (result_kind == NUMBER && op_ == Token::SHR) {
-    return Type::Unsigned32(zone);
+    return Type::Unsigned32();
   }
   DCHECK_NE(GENERIC, result_kind);
-  return KindToType(result_kind, zone);
+  return KindToType(result_kind);
 }
 
 
 std::ostream& operator<<(std::ostream& os, const BinaryOpICState& s) {
   os << "(" << Token::Name(s.op_);
-  if (s.mode_ == OVERWRITE_LEFT)
-    os << "_ReuseLeft";
-  else if (s.mode_ == OVERWRITE_RIGHT)
-    os << "_ReuseRight";
   if (s.CouldCreateAllocationMementos()) os << "_CreateAllocationMementos";
+  if (is_strong(s.strength())) os << "_Strong";
   os << ":" << BinaryOpICState::KindToString(s.left_kind_) << "*";
-  if (s.fixed_right_arg_.has_value) {
-    os << s.fixed_right_arg_.value;
+  if (s.fixed_right_arg_.IsJust()) {
+    os << s.fixed_right_arg_.FromJust();
   } else {
     os << BinaryOpICState::KindToString(s.right_kind_);
   }
@@ -340,9 +233,9 @@
       base::bits::IsPowerOfTwo32(fixed_right_arg_value) &&
       FixedRightArgValueField::is_valid(WhichPowerOf2(fixed_right_arg_value)) &&
       (left_kind_ == SMI || left_kind_ == INT32) &&
-      (result_kind_ == NONE || !fixed_right_arg_.has_value);
-  fixed_right_arg_ = Maybe<int32_t>(has_fixed_right_arg, fixed_right_arg_value);
-
+      (result_kind_ == NONE || !fixed_right_arg_.IsJust());
+  fixed_right_arg_ =
+      has_fixed_right_arg ? Just(fixed_right_arg_value) : Nothing<int32_t>();
   result_kind_ = UpdateKind(result, result_kind_);
 
   if (!Token::IsTruncatingBinaryOp(op_)) {
@@ -364,14 +257,6 @@
     left_kind_ = NUMBER;
   }
 
-  // Reset overwrite mode unless we can actually make use of it, or may be able
-  // to make use of it at some point in the future.
-  if ((mode_ == OVERWRITE_LEFT && left_kind_ > NUMBER) ||
-      (mode_ == OVERWRITE_RIGHT && right_kind_ > NUMBER) ||
-      result_kind_ > NUMBER) {
-    mode_ = NO_OVERWRITE;
-  }
-
   if (old_extra_ic_state == GetExtraICState()) {
     // Tagged operations can lead to non-truncating HChanges
     if (left->IsUndefined() || left->IsBoolean()) {
@@ -435,20 +320,20 @@
 
 
 // static
-Type* BinaryOpICState::KindToType(Kind kind, Zone* zone) {
+Type* BinaryOpICState::KindToType(Kind kind) {
   switch (kind) {
     case NONE:
-      return Type::None(zone);
+      return Type::None();
     case SMI:
-      return Type::SignedSmall(zone);
+      return Type::SignedSmall();
     case INT32:
-      return Type::Signed32(zone);
+      return Type::Signed32();
     case NUMBER:
-      return Type::Number(zone);
+      return Type::Number();
     case STRING:
-      return Type::String(zone);
+      return Type::String();
     case GENERIC:
-      return Type::Any(zone);
+      return Type::Any();
   }
   UNREACHABLE();
   return NULL;
@@ -459,6 +344,8 @@
   switch (state) {
     case UNINITIALIZED:
       return "UNINITIALIZED";
+    case BOOLEAN:
+      return "BOOLEAN";
     case SMI:
       return "SMI";
     case NUMBER:
@@ -469,10 +356,10 @@
       return "STRING";
     case UNIQUE_NAME:
       return "UNIQUE_NAME";
-    case OBJECT:
-      return "OBJECT";
-    case KNOWN_OBJECT:
-      return "KNOWN_OBJECT";
+    case RECEIVER:
+      return "RECEIVER";
+    case KNOWN_RECEIVER:
+      return "KNOWN_RECEIVER";
     case GENERIC:
       return "GENERIC";
   }
@@ -485,6 +372,8 @@
   switch (state) {
     case UNINITIALIZED:
       return Type::None(zone);
+    case BOOLEAN:
+      return Type::Boolean(zone);
     case SMI:
       return Type::SignedSmall(zone);
     case NUMBER:
@@ -495,9 +384,9 @@
       return Type::InternalizedString(zone);
     case UNIQUE_NAME:
       return Type::UniqueName(zone);
-    case OBJECT:
+    case RECEIVER:
       return Type::Receiver(zone);
-    case KNOWN_OBJECT:
+    case KNOWN_RECEIVER:
       return map.is_null() ? Type::Receiver(zone) : Type::Class(map, zone);
     case GENERIC:
       return Type::Any(zone);
@@ -511,12 +400,16 @@
                                                     Handle<Object> value) {
   switch (old_state) {
     case UNINITIALIZED:
+      if (value->IsBoolean()) return BOOLEAN;
       if (value->IsSmi()) return SMI;
       if (value->IsHeapNumber()) return NUMBER;
       if (value->IsInternalizedString()) return INTERNALIZED_STRING;
       if (value->IsString()) return STRING;
       if (value->IsSymbol()) return UNIQUE_NAME;
-      if (value->IsJSObject()) return OBJECT;
+      if (value->IsJSReceiver()) return RECEIVER;
+      break;
+    case BOOLEAN:
+      if (value->IsBoolean()) return BOOLEAN;
       break;
     case SMI:
       if (value->IsSmi()) return SMI;
@@ -536,12 +429,12 @@
     case UNIQUE_NAME:
       if (value->IsUniqueName()) return UNIQUE_NAME;
       break;
-    case OBJECT:
-      if (value->IsJSObject()) return OBJECT;
+    case RECEIVER:
+      if (value->IsJSReceiver()) return RECEIVER;
       break;
     case GENERIC:
       break;
-    case KNOWN_OBJECT:
+    case KNOWN_RECEIVER:
       UNREACHABLE();
       break;
   }
@@ -555,6 +448,7 @@
     bool has_inlined_smi_code, Handle<Object> x, Handle<Object> y) {
   switch (old_state) {
     case UNINITIALIZED:
+      if (x->IsBoolean() && y->IsBoolean()) return BOOLEAN;
       if (x->IsSmi() && y->IsSmi()) return SMI;
       if (x->IsNumber() && y->IsNumber()) return NUMBER;
       if (Token::IsOrderedRelationalCompareOp(op)) {
@@ -571,16 +465,16 @@
         return Token::IsEqualityOp(op) ? INTERNALIZED_STRING : STRING;
       }
       if (x->IsString() && y->IsString()) return STRING;
-      if (!Token::IsEqualityOp(op)) return GENERIC;
-      if (x->IsUniqueName() && y->IsUniqueName()) return UNIQUE_NAME;
-      if (x->IsJSObject() && y->IsJSObject()) {
-        if (Handle<JSObject>::cast(x)->map() ==
-            Handle<JSObject>::cast(y)->map()) {
-          return KNOWN_OBJECT;
+      if (x->IsJSReceiver() && y->IsJSReceiver()) {
+        if (Handle<JSReceiver>::cast(x)->map() ==
+            Handle<JSReceiver>::cast(y)->map()) {
+          return KNOWN_RECEIVER;
         } else {
-          return OBJECT;
+          return Token::IsEqualityOp(op) ? RECEIVER : GENERIC;
         }
       }
+      if (!Token::IsEqualityOp(op)) return GENERIC;
+      if (x->IsUniqueName() && y->IsUniqueName()) return UNIQUE_NAME;
       return GENERIC;
     case SMI:
       return x->IsNumber() && y->IsNumber() ? NUMBER : GENERIC;
@@ -596,20 +490,21 @@
       if (old_left == SMI && x->IsHeapNumber()) return NUMBER;
       if (old_right == SMI && y->IsHeapNumber()) return NUMBER;
       return GENERIC;
-    case KNOWN_OBJECT:
-      DCHECK(Token::IsEqualityOp(op));
-      if (x->IsJSObject() && y->IsJSObject()) {
-        return OBJECT;
+    case KNOWN_RECEIVER:
+      if (x->IsJSReceiver() && y->IsJSReceiver()) {
+        return Token::IsEqualityOp(op) ? RECEIVER : GENERIC;
       }
       return GENERIC;
+    case BOOLEAN:
     case STRING:
     case UNIQUE_NAME:
-    case OBJECT:
+    case RECEIVER:
     case GENERIC:
       return GENERIC;
   }
   UNREACHABLE();
   return GENERIC;  // Make the compiler happy.
 }
-}
-}  // namespace v8::internal
+
+}  // namespace internal
+}  // namespace v8