diff --git a/src/ic/ic-state.h b/src/ic/ic-state.h
new file mode 100644
index 0000000..b84bdb9
--- /dev/null
+++ b/src/ic/ic-state.h
@@ -0,0 +1,238 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_IC_STATE_H_
+#define V8_IC_STATE_H_
+
+#include "src/macro-assembler.h"
+
+namespace v8 {
+namespace internal {
+
+
+const int kMaxKeyedPolymorphism = 4;
+
+
+class ICUtility : public AllStatic {
+ public:
+  // Clear the inline cache to initial state.
+  static void Clear(Isolate* isolate, Address address,
+                    ConstantPoolArray* constant_pool);
+};
+
+
+class CallICState FINAL BASE_EMBEDDED {
+ public:
+  explicit CallICState(ExtraICState extra_ic_state);
+
+  enum CallType { METHOD, FUNCTION };
+
+  CallICState(int argc, CallType call_type)
+      : argc_(argc), call_type_(call_type) {}
+
+  ExtraICState GetExtraICState() const;
+
+  static void GenerateAheadOfTime(Isolate*,
+                                  void (*Generate)(Isolate*,
+                                                   const CallICState&));
+
+  int arg_count() const { return argc_; }
+  CallType call_type() const { return call_type_; }
+
+  bool CallAsMethod() const { return call_type_ == METHOD; }
+
+ private:
+  class ArgcBits : public BitField<int, 0, Code::kArgumentsBits> {};
+  class CallTypeBits : public BitField<CallType, Code::kArgumentsBits, 1> {};
+
+  const int argc_;
+  const CallType call_type_;
+};
+
+
+OStream& operator<<(OStream& os, const CallICState& s);
+
+
+// Mode to overwrite BinaryExpression values.
+enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };
+
+class BinaryOpICState FINAL BASE_EMBEDDED {
+ public:
+  BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state);
+
+  BinaryOpICState(Isolate* isolate, Token::Value op, OverwriteMode mode)
+      : op_(op),
+        mode_(mode),
+        left_kind_(NONE),
+        right_kind_(NONE),
+        result_kind_(NONE),
+        isolate_(isolate) {
+    DCHECK_LE(FIRST_TOKEN, op);
+    DCHECK_LE(op, LAST_TOKEN);
+  }
+
+  InlineCacheState GetICState() const {
+    if (Max(left_kind_, right_kind_) == NONE) {
+      return ::v8::internal::UNINITIALIZED;
+    }
+    if (Max(left_kind_, right_kind_) == GENERIC) {
+      return ::v8::internal::MEGAMORPHIC;
+    }
+    if (Min(left_kind_, right_kind_) == GENERIC) {
+      return ::v8::internal::GENERIC;
+    }
+    return ::v8::internal::MONOMORPHIC;
+  }
+
+  ExtraICState GetExtraICState() const;
+
+  static void GenerateAheadOfTime(Isolate*,
+                                  void (*Generate)(Isolate*,
+                                                   const BinaryOpICState&));
+
+  bool CanReuseDoubleBox() const {
+    return (result_kind_ > SMI && result_kind_ <= NUMBER) &&
+           ((mode_ == OVERWRITE_LEFT && left_kind_ > SMI &&
+             left_kind_ <= NUMBER) ||
+            (mode_ == OVERWRITE_RIGHT && right_kind_ > SMI &&
+             right_kind_ <= NUMBER));
+  }
+
+  // Returns true if the IC _could_ create allocation mementos.
+  bool CouldCreateAllocationMementos() const {
+    if (left_kind_ == STRING || right_kind_ == STRING) {
+      DCHECK_EQ(Token::ADD, op_);
+      return true;
+    }
+    return false;
+  }
+
+  // Returns true if the IC _should_ create allocation mementos.
+  bool ShouldCreateAllocationMementos() const {
+    return FLAG_allocation_site_pretenuring && CouldCreateAllocationMementos();
+  }
+
+  bool HasSideEffects() const {
+    return Max(left_kind_, right_kind_) == GENERIC;
+  }
+
+  // Returns true if the IC should enable the inline smi code (i.e. if either
+  // parameter may be a smi).
+  bool UseInlinedSmiCode() const {
+    return KindMaybeSmi(left_kind_) || KindMaybeSmi(right_kind_);
+  }
+
+  static const int FIRST_TOKEN = Token::BIT_OR;
+  static const int LAST_TOKEN = Token::MOD;
+
+  Token::Value op() const { return op_; }
+  OverwriteMode mode() const { return mode_; }
+  Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
+
+  Type* GetLeftType(Zone* zone) const { return KindToType(left_kind_, zone); }
+  Type* GetRightType(Zone* zone) const { return KindToType(right_kind_, zone); }
+  Type* GetResultType(Zone* zone) const;
+
+  void Update(Handle<Object> left, Handle<Object> right, Handle<Object> result);
+
+  Isolate* isolate() const { return isolate_; }
+
+ private:
+  friend OStream& operator<<(OStream& os, const BinaryOpICState& s);
+
+  enum Kind { NONE, SMI, INT32, NUMBER, STRING, GENERIC };
+
+  Kind UpdateKind(Handle<Object> object, Kind kind) const;
+
+  static const char* KindToString(Kind kind);
+  static Type* KindToType(Kind kind, Zone* zone);
+  static bool KindMaybeSmi(Kind kind) {
+    return (kind >= SMI && kind <= NUMBER) || kind == GENERIC;
+  }
+
+  // We truncate the last bit of the token.
+  STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 4));
+  class OpField : public BitField<int, 0, 4> {};
+  class OverwriteModeField : public BitField<OverwriteMode, 4, 2> {};
+  class ResultKindField : public BitField<Kind, 6, 3> {};
+  class LeftKindField : public BitField<Kind, 9, 3> {};
+  // When fixed right arg is set, we don't need to store the right kind.
+  // Thus the two fields can overlap.
+  class HasFixedRightArgField : public BitField<bool, 12, 1> {};
+  class FixedRightArgValueField : public BitField<int, 13, 4> {};
+  class RightKindField : public BitField<Kind, 13, 3> {};
+
+  Token::Value op_;
+  OverwriteMode mode_;
+  Kind left_kind_;
+  Kind right_kind_;
+  Kind result_kind_;
+  Maybe<int> fixed_right_arg_;
+  Isolate* isolate_;
+};
+
+
+OStream& operator<<(OStream& os, const BinaryOpICState& s);
+
+
+class CompareICState {
+ public:
+  // The type/state lattice is defined by the following inequations:
+  //   UNINITIALIZED < ...
+  //   ... < GENERIC
+  //   SMI < NUMBER
+  //   INTERNALIZED_STRING < STRING
+  //   KNOWN_OBJECT < OBJECT
+  enum State {
+    UNINITIALIZED,
+    SMI,
+    NUMBER,
+    STRING,
+    INTERNALIZED_STRING,
+    UNIQUE_NAME,   // Symbol or InternalizedString
+    OBJECT,        // JSObject
+    KNOWN_OBJECT,  // JSObject with specific map (faster check)
+    GENERIC
+  };
+
+  static Type* StateToType(Zone* zone, State state,
+                           Handle<Map> map = Handle<Map>());
+
+  static State NewInputState(State old_state, Handle<Object> value);
+
+  static const char* GetStateName(CompareICState::State state);
+
+  static State TargetState(State old_state, State old_left, State old_right,
+                           Token::Value op, bool has_inlined_smi_code,
+                           Handle<Object> x, Handle<Object> y);
+};
+
+
+class LoadICState FINAL BASE_EMBEDDED {
+ public:
+  explicit LoadICState(ExtraICState extra_ic_state) : state_(extra_ic_state) {}
+
+  explicit LoadICState(ContextualMode mode)
+      : state_(ContextualModeBits::encode(mode)) {}
+
+  ExtraICState GetExtraICState() const { return state_; }
+
+  ContextualMode contextual_mode() const {
+    return ContextualModeBits::decode(state_);
+  }
+
+  static ContextualMode GetContextualMode(ExtraICState state) {
+    return LoadICState(state).contextual_mode();
+  }
+
+ private:
+  class ContextualModeBits : public BitField<ContextualMode, 0, 1> {};
+  STATIC_ASSERT(static_cast<int>(NOT_CONTEXTUAL) == 0);
+
+  const ExtraICState state_;
+};
+}
+}
+
+#endif  // V8_IC_STATE_H_
