Version 3.30.36 (based on e55a95d10dcb581a12ddddbab5c224b18c1e1fb2)

git-svn-id: https://v8.googlecode.com/svn/trunk@25175 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/arm64/delayed-masm-arm64.cc b/src/arm64/delayed-masm-arm64.cc
index c3bda91..b51e77e 100644
--- a/src/arm64/delayed-masm-arm64.cc
+++ b/src/arm64/delayed-masm-arm64.cc
@@ -16,8 +16,8 @@
 
 
 void DelayedMasm::StackSlotMove(LOperand* src, LOperand* dst) {
-  DCHECK(src->IsStackSlot());
-  DCHECK(dst->IsStackSlot());
+  DCHECK((src->IsStackSlot() && dst->IsStackSlot()) ||
+         (src->IsDoubleStackSlot() && dst->IsDoubleStackSlot()));
   MemOperand src_operand = cgen_->ToMemOperand(src);
   MemOperand dst_operand = cgen_->ToMemOperand(dst);
   if (pending_ == kStackSlotMove) {
diff --git a/src/ast.cc b/src/ast.cc
index 1df668d..26bc491 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -61,9 +61,9 @@
 
 VariableProxy::VariableProxy(Zone* zone, Variable* var, int position)
     : Expression(zone, position),
-      is_this_(var->is_this()),
-      is_assigned_(false),
-      is_resolved_(false),
+      bit_field_(IsThisField::encode(var->is_this()) |
+                 IsAssignedField::encode(false) |
+                 IsResolvedField::encode(false)),
       variable_feedback_slot_(FeedbackVectorICSlot::Invalid()),
       raw_name_(var->raw_name()),
       interface_(var->interface()) {
@@ -74,9 +74,8 @@
 VariableProxy::VariableProxy(Zone* zone, const AstRawString* name, bool is_this,
                              Interface* interface, int position)
     : Expression(zone, position),
-      is_this_(is_this),
-      is_assigned_(false),
-      is_resolved_(false),
+      bit_field_(IsThisField::encode(is_this) | IsAssignedField::encode(false) |
+                 IsResolvedField::encode(false)),
       variable_feedback_slot_(FeedbackVectorICSlot::Invalid()),
       raw_name_(name),
       interface_(interface) {}
@@ -99,17 +98,17 @@
 Assignment::Assignment(Zone* zone, Token::Value op, Expression* target,
                        Expression* value, int pos)
     : Expression(zone, pos),
-      is_uninitialized_(false),
-      key_type_(ELEMENT),
-      store_mode_(STANDARD_STORE),
-      op_(op),
+      bit_field_(IsUninitializedField::encode(false) |
+                 KeyTypeField::encode(ELEMENT) |
+                 StoreModeField::encode(STANDARD_STORE) |
+                 TokenField::encode(op)),
       target_(target),
       value_(value),
       binary_operation_(NULL) {}
 
 
 Token::Value Assignment::binary_op() const {
-  switch (op_) {
+  switch (op()) {
     case Token::ASSIGN_BIT_OR: return Token::BIT_OR;
     case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR;
     case Token::ASSIGN_BIT_AND: return Token::BIT_AND;
diff --git a/src/ast.h b/src/ast.h
index aa23b4e..749e579 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -359,11 +359,16 @@
   void set_bounds(Bounds bounds) { bounds_ = bounds; }
 
   // Whether the expression is parenthesized
-  bool is_parenthesized() const { return is_parenthesized_; }
-  bool is_multi_parenthesized() const { return is_multi_parenthesized_; }
+  bool is_parenthesized() const {
+    return IsParenthesizedField::decode(bit_field_);
+  }
+  bool is_multi_parenthesized() const {
+    return IsMultiParenthesizedField::decode(bit_field_);
+  }
   void increase_parenthesization_level() {
-    is_multi_parenthesized_ = is_parenthesized_;
-    is_parenthesized_ = true;
+    bit_field_ =
+        IsMultiParenthesizedField::update(bit_field_, is_parenthesized());
+    bit_field_ = IsParenthesizedField::update(bit_field_, true);
   }
 
   // Type feedback information for assignments and properties.
@@ -375,18 +380,20 @@
     UNREACHABLE();
     return NULL;
   }
-  virtual KeyedAccessStoreMode GetStoreMode() {
+  virtual KeyedAccessStoreMode GetStoreMode() const {
     UNREACHABLE();
     return STANDARD_STORE;
   }
-  virtual IcCheckType GetKeyType() {
+  virtual IcCheckType GetKeyType() const {
     UNREACHABLE();
     return ELEMENT;
   }
 
   // TODO(rossberg): this should move to its own AST node eventually.
   virtual void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle);
-  byte to_boolean_types() const { return to_boolean_types_; }
+  byte to_boolean_types() const {
+    return ToBooleanTypesField::decode(bit_field_);
+  }
 
   void set_base_id(int id) { base_id_ = id; }
   static int num_ids() { return parent_num_ids() + 2; }
@@ -398,10 +405,11 @@
       : AstNode(pos),
         base_id_(BailoutId::None().ToInt()),
         bounds_(Bounds::Unbounded(zone)),
-        is_parenthesized_(false),
-        is_multi_parenthesized_(false) {}
+        bit_field_(0) {}
   static int parent_num_ids() { return 0; }
-  void set_to_boolean_types(byte types) { to_boolean_types_ = types; }
+  void set_to_boolean_types(byte types) {
+    bit_field_ = ToBooleanTypesField::update(bit_field_, types);
+  }
 
   int base_id() const {
     DCHECK(!BailoutId(base_id_).IsNone());
@@ -413,9 +421,12 @@
 
   int base_id_;
   Bounds bounds_;
-  byte to_boolean_types_;
-  bool is_parenthesized_ : 1;
-  bool is_multi_parenthesized_ : 1;
+  class ToBooleanTypesField : public BitField16<byte, 0, 8> {};
+  class IsParenthesizedField : public BitField16<bool, 8, 1> {};
+  class IsMultiParenthesizedField : public BitField16<bool, 9, 1> {};
+  uint16_t bit_field_;
+  // Ends with 16-bit field; deriving classes in turn begin with
+  // 16-bit fields for optimum packing efficiency.
 };
 
 
@@ -1697,13 +1708,17 @@
     var_ = v;
   }
 
-  bool is_this() const { return is_this_; }
+  bool is_this() const { return IsThisField::decode(bit_field_); }
 
-  bool is_assigned() const { return is_assigned_; }
-  void set_is_assigned() { is_assigned_ = true; }
+  bool is_assigned() const { return IsAssignedField::decode(bit_field_); }
+  void set_is_assigned() {
+    bit_field_ = IsAssignedField::update(bit_field_, true);
+  }
 
-  bool is_resolved() const { return is_resolved_; }
-  void set_is_resolved() { is_resolved_ = true; }
+  bool is_resolved() const { return IsResolvedField::decode(bit_field_); }
+  void set_is_resolved() {
+    bit_field_ = IsResolvedField::update(bit_field_, true);
+  }
 
   Interface* interface() const { return interface_; }
 
@@ -1727,9 +1742,13 @@
   VariableProxy(Zone* zone, const AstRawString* name, bool is_this,
                 Interface* interface, int position);
 
-  bool is_this_ : 1;
-  bool is_assigned_ : 1;
-  bool is_resolved_ : 1;
+  class IsThisField : public BitField8<bool, 0, 1> {};
+  class IsAssignedField : public BitField8<bool, 1, 1> {};
+  class IsResolvedField : public BitField8<bool, 2, 1> {};
+
+  // Start with 16-bit (or smaller) field, which should get packed together
+  // with Expression's trailing 16-bit field.
+  uint8_t bit_field_;
   FeedbackVectorICSlot variable_feedback_slot_;
   union {
     const AstRawString* raw_name_;  // if !is_resolved_
@@ -1752,7 +1771,9 @@
   BailoutId LoadId() const { return BailoutId(local_id(0)); }
   TypeFeedbackId PropertyFeedbackId() { return TypeFeedbackId(local_id(1)); }
 
-  bool IsStringAccess() const { return is_string_access_; }
+  bool IsStringAccess() const {
+    return IsStringAccessField::decode(bit_field_);
+  }
 
   // Type feedback information.
   virtual bool IsMonomorphic() OVERRIDE {
@@ -1761,21 +1782,29 @@
   virtual SmallMapList* GetReceiverTypes() OVERRIDE {
     return &receiver_types_;
   }
-  virtual KeyedAccessStoreMode GetStoreMode() OVERRIDE {
+  virtual KeyedAccessStoreMode GetStoreMode() const OVERRIDE {
     return STANDARD_STORE;
   }
-  virtual IcCheckType GetKeyType() OVERRIDE {
+  virtual IcCheckType GetKeyType() const OVERRIDE {
     // PROPERTY key types currently aren't implemented for KeyedLoadICs.
     return ELEMENT;
   }
-  bool IsUninitialized() { return !is_for_call_ && is_uninitialized_; }
-  bool HasNoTypeInformation() {
-    return is_uninitialized_;
+  bool IsUninitialized() const {
+    return !is_for_call() && HasNoTypeInformation();
   }
-  void set_is_uninitialized(bool b) { is_uninitialized_ = b; }
-  void set_is_string_access(bool b) { is_string_access_ = b; }
-  void mark_for_call() { is_for_call_ = true; }
-  bool IsForCall() { return is_for_call_; }
+  bool HasNoTypeInformation() const {
+    return IsUninitializedField::decode(bit_field_);
+  }
+  void set_is_uninitialized(bool b) {
+    bit_field_ = IsUninitializedField::update(bit_field_, b);
+  }
+  void set_is_string_access(bool b) {
+    bit_field_ = IsStringAccessField::update(bit_field_, b);
+  }
+  void mark_for_call() {
+    bit_field_ = IsForCallField::update(bit_field_, true);
+  }
+  bool is_for_call() const { return IsForCallField::decode(bit_field_); }
 
   bool IsSuperAccess() {
     return obj()->IsSuperReference();
@@ -1795,9 +1824,9 @@
  protected:
   Property(Zone* zone, Expression* obj, Expression* key, int pos)
       : Expression(zone, pos),
-        is_for_call_(false),
-        is_uninitialized_(false),
-        is_string_access_(false),
+        bit_field_(IsForCallField::encode(false) |
+                   IsUninitializedField::encode(false) |
+                   IsStringAccessField::encode(false)),
         property_feedback_slot_(FeedbackVectorICSlot::Invalid()),
         obj_(obj),
         key_(key) {}
@@ -1806,9 +1835,10 @@
  private:
   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
 
-  bool is_for_call_ : 1;
-  bool is_uninitialized_ : 1;
-  bool is_string_access_ : 1;
+  class IsForCallField : public BitField8<bool, 0, 1> {};
+  class IsUninitializedField : public BitField8<bool, 1, 1> {};
+  class IsStringAccessField : public BitField8<bool, 2, 1> {};
+  uint8_t bit_field_;
   FeedbackVectorICSlot property_feedback_slot_;
   Expression* obj_;
   Expression* key_;
@@ -2120,10 +2150,10 @@
  public:
   DECLARE_NODE_TYPE(CountOperation)
 
-  bool is_prefix() const { return is_prefix_; }
-  bool is_postfix() const { return !is_prefix_; }
+  bool is_prefix() const { return IsPrefixField::decode(bit_field_); }
+  bool is_postfix() const { return !is_prefix(); }
 
-  Token::Value op() const { return op_; }
+  Token::Value op() const { return TokenField::decode(bit_field_); }
   Token::Value binary_op() {
     return (op() == Token::INC) ? Token::ADD : Token::SUB;
   }
@@ -2136,13 +2166,19 @@
   virtual SmallMapList* GetReceiverTypes() OVERRIDE {
     return &receiver_types_;
   }
-  virtual IcCheckType GetKeyType() OVERRIDE { return key_type_; }
-  virtual KeyedAccessStoreMode GetStoreMode() OVERRIDE {
-    return store_mode_;
+  virtual IcCheckType GetKeyType() const OVERRIDE {
+    return KeyTypeField::decode(bit_field_);
+  }
+  virtual KeyedAccessStoreMode GetStoreMode() const OVERRIDE {
+    return StoreModeField::decode(bit_field_);
   }
   Type* type() const { return type_; }
-  void set_key_type(IcCheckType type) { key_type_ = type; }
-  void set_store_mode(KeyedAccessStoreMode mode) { store_mode_ = mode; }
+  void set_key_type(IcCheckType type) {
+    bit_field_ = KeyTypeField::update(bit_field_, type);
+  }
+  void set_store_mode(KeyedAccessStoreMode mode) {
+    bit_field_ = StoreModeField::update(bit_field_, mode);
+  }
   void set_type(Type* type) { type_ = type; }
 
   static int num_ids() { return parent_num_ids() + 3; }
@@ -2158,21 +2194,25 @@
   CountOperation(Zone* zone, Token::Value op, bool is_prefix, Expression* expr,
                  int pos)
       : Expression(zone, pos),
-        op_(op),
-        is_prefix_(is_prefix),
-        key_type_(ELEMENT),
-        store_mode_(STANDARD_STORE),
+        bit_field_(IsPrefixField::encode(is_prefix) |
+                   KeyTypeField::encode(ELEMENT) |
+                   StoreModeField::encode(STANDARD_STORE) |
+                   TokenField::encode(op)),
+        type_(NULL),
         expression_(expr) {}
   static int parent_num_ids() { return Expression::num_ids(); }
 
  private:
   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
 
-  Token::Value op_;
-  bool is_prefix_ : 1;
-  IcCheckType key_type_ : 1;
-  KeyedAccessStoreMode store_mode_ : 5;  // Windows treats as signed,
-                                         // must have extra bit.
+  class IsPrefixField : public BitField16<bool, 0, 1> {};
+  class KeyTypeField : public BitField16<IcCheckType, 1, 1> {};
+  class StoreModeField : public BitField16<KeyedAccessStoreMode, 2, 4> {};
+  class TokenField : public BitField16<Token::Value, 6, 8> {};
+
+  // Starts with 16-bit field, which should get packed together with
+  // Expression's trailing 16-bit field.
+  uint16_t bit_field_;
   Type* type_;
   Expression* expression_;
   SmallMapList receiver_types_;
@@ -2261,7 +2301,7 @@
 
   Token::Value binary_op() const;
 
-  Token::Value op() const { return op_; }
+  Token::Value op() const { return TokenField::decode(bit_field_); }
   Expression* target() const { return target_; }
   Expression* value() const { return value_; }
   BinaryOperation* binary_operation() const { return binary_operation_; }
@@ -2277,20 +2317,30 @@
   virtual bool IsMonomorphic() OVERRIDE {
     return receiver_types_.length() == 1;
   }
-  bool IsUninitialized() { return is_uninitialized_; }
+  bool IsUninitialized() const {
+    return IsUninitializedField::decode(bit_field_);
+  }
   bool HasNoTypeInformation() {
-    return is_uninitialized_;
+    return IsUninitializedField::decode(bit_field_);
   }
   virtual SmallMapList* GetReceiverTypes() OVERRIDE {
     return &receiver_types_;
   }
-  virtual IcCheckType GetKeyType() OVERRIDE { return key_type_; }
-  virtual KeyedAccessStoreMode GetStoreMode() OVERRIDE {
-    return store_mode_;
+  virtual IcCheckType GetKeyType() const OVERRIDE {
+    return KeyTypeField::decode(bit_field_);
   }
-  void set_is_uninitialized(bool b) { is_uninitialized_ = b; }
-  void set_key_type(IcCheckType key_type) { key_type_ = key_type; }
-  void set_store_mode(KeyedAccessStoreMode mode) { store_mode_ = mode; }
+  virtual KeyedAccessStoreMode GetStoreMode() const OVERRIDE {
+    return StoreModeField::decode(bit_field_);
+  }
+  void set_is_uninitialized(bool b) {
+    bit_field_ = IsUninitializedField::update(bit_field_, b);
+  }
+  void set_key_type(IcCheckType key_type) {
+    bit_field_ = KeyTypeField::update(bit_field_, key_type);
+  }
+  void set_store_mode(KeyedAccessStoreMode mode) {
+    bit_field_ = StoreModeField::update(bit_field_, mode);
+  }
 
  protected:
   Assignment(Zone* zone, Token::Value op, Expression* target, Expression* value,
@@ -2299,7 +2349,7 @@
 
   template <class Visitor>
   void Init(AstNodeFactory<Visitor>* factory) {
-    DCHECK(Token::IsAssignmentOp(op_));
+    DCHECK(Token::IsAssignmentOp(op()));
     if (is_compound()) {
       binary_operation_ = factory->NewBinaryOperation(
           binary_op(), target_, value_, position() + 1);
@@ -2309,11 +2359,14 @@
  private:
   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
 
-  bool is_uninitialized_ : 1;
-  IcCheckType key_type_ : 1;
-  KeyedAccessStoreMode store_mode_ : 5;  // Windows treats as signed,
-                                         // must have extra bit.
-  Token::Value op_;
+  class IsUninitializedField : public BitField16<bool, 0, 1> {};
+  class KeyTypeField : public BitField16<IcCheckType, 1, 1> {};
+  class StoreModeField : public BitField16<KeyedAccessStoreMode, 2, 4> {};
+  class TokenField : public BitField16<Token::Value, 6, 8> {};
+
+  // Starts with 16-bit field, which should get packed together with
+  // Expression's trailing 16-bit field.
+  uint16_t bit_field_;
   Expression* target_;
   Expression* value_;
   BinaryOperation* binary_operation_;
diff --git a/src/base/atomicops_internals_mac.h b/src/base/atomicops_internals_mac.h
index a046872..84f9dbc 100644
--- a/src/base/atomicops_internals_mac.h
+++ b/src/base/atomicops_internals_mac.h
@@ -12,6 +12,20 @@
 namespace v8 {
 namespace base {
 
+#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
+
+inline void MemoryBarrier() { OSMemoryBarrier(); }
+
+inline void AcquireMemoryBarrier() {
+// On x86 processors, loads already have acquire semantics, so
+// there is no need to put a full barrier here.
+#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
+  ATOMICOPS_COMPILER_BARRIER();
+#else
+  MemoryBarrier();
+#endif
+}
+
 inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
                                          Atomic32 old_value,
                                          Atomic32 new_value) {
@@ -46,10 +60,6 @@
   return OSAtomicAdd32Barrier(increment, const_cast<Atomic32*>(ptr));
 }
 
-inline void MemoryBarrier() {
-  OSMemoryBarrier();
-}
-
 inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
                                        Atomic32 old_value,
                                        Atomic32 new_value) {
@@ -98,7 +108,7 @@
 
 inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
   Atomic32 value = *ptr;
-  MemoryBarrier();
+  AcquireMemoryBarrier();
   return value;
 }
 
@@ -188,7 +198,7 @@
 
 inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
   Atomic64 value = *ptr;
-  MemoryBarrier();
+  AcquireMemoryBarrier();
   return value;
 }
 
@@ -199,6 +209,7 @@
 
 #endif  // defined(__LP64__)
 
+#undef ATOMICOPS_COMPILER_BARRIER
 } }  // namespace v8::base
 
 #endif  // V8_BASE_ATOMICOPS_INTERNALS_MAC_H_
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc
index 7b5abd1..805afc5 100644
--- a/src/compiler/ast-graph-builder.cc
+++ b/src/compiler/ast-graph-builder.cc
@@ -1173,8 +1173,8 @@
   switch (assign_type) {
     case VARIABLE: {
       Variable* variable = expr->target()->AsVariableProxy()->var();
-      BuildVariableAssignment(variable, value, expr->op(),
-                              expr->AssignmentId());
+      BuildVariableAssignment(variable, value, expr->op(), expr->AssignmentId(),
+                              ast_context()->GetStateCombine());
       break;
     }
     case NAMED_PROPERTY: {
@@ -1183,7 +1183,8 @@
           MakeUnique(property->key()->AsLiteral()->AsPropertyName());
       Node* store =
           NewNode(javascript()->StoreNamed(strict_mode(), name), object, value);
-      PrepareFrameState(store, expr->AssignmentId());
+      PrepareFrameState(store, expr->AssignmentId(),
+                        ast_context()->GetStateCombine());
       break;
     }
     case KEYED_PROPERTY: {
@@ -1191,7 +1192,8 @@
       Node* object = environment()->Pop();
       Node* store = NewNode(javascript()->StoreProperty(strict_mode()), object,
                             key, value);
-      PrepareFrameState(store, expr->AssignmentId());
+      PrepareFrameState(store, expr->AssignmentId(),
+                        ast_context()->GetStateCombine());
       break;
     }
   }
@@ -1957,9 +1959,9 @@
 }
 
 
-Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value,
-                                               Token::Value op,
-                                               BailoutId bailout_id) {
+Node* AstGraphBuilder::BuildVariableAssignment(
+    Variable* variable, Node* value, Token::Value op, BailoutId bailout_id,
+    OutputFrameStateCombine combine) {
   Node* the_hole = jsgraph()->TheHoleConstant();
   VariableMode mode = variable->mode();
   switch (variable->location()) {
@@ -1969,7 +1971,7 @@
       Unique<Name> name = MakeUnique(variable->name());
       const Operator* op = javascript()->StoreNamed(strict_mode(), name);
       Node* store = NewNode(op, global, value);
-      PrepareFrameState(store, bailout_id);
+      PrepareFrameState(store, bailout_id, combine);
       return store;
     }
     case Variable::PARAMETER:
@@ -2035,7 +2037,7 @@
       const Operator* op =
           javascript()->CallRuntime(Runtime::kStoreLookupSlot, 4);
       Node* store = NewNode(op, value, current_context(), name, strict);
-      PrepareFrameState(store, bailout_id);
+      PrepareFrameState(store, bailout_id, combine);
       return store;
     }
   }
diff --git a/src/compiler/ast-graph-builder.h b/src/compiler/ast-graph-builder.h
index 6e51723..518f23f 100644
--- a/src/compiler/ast-graph-builder.h
+++ b/src/compiler/ast-graph-builder.h
@@ -80,7 +80,9 @@
 
   // Builders for variable load and assignment.
   Node* BuildVariableAssignment(Variable* var, Node* value, Token::Value op,
-                                BailoutId bailout_id);
+                                BailoutId bailout_id,
+                                OutputFrameStateCombine state_combine =
+                                    OutputFrameStateCombine::Ignore());
   Node* BuildVariableDelete(Variable* var, BailoutId bailout_id,
                             OutputFrameStateCombine state_combine);
   Node* BuildVariableLoad(Variable* var, BailoutId bailout_id,
diff --git a/src/compiler/register-allocator.cc b/src/compiler/register-allocator.cc
index 7a82768..c65b906 100644
--- a/src/compiler/register-allocator.cc
+++ b/src/compiler/register-allocator.cc
@@ -199,7 +199,7 @@
 }
 
 
-InstructionOperand* LiveRange::CreateAssignedOperand(Zone* zone) {
+InstructionOperand* LiveRange::CreateAssignedOperand(Zone* zone) const {
   InstructionOperand* op = NULL;
   if (HasRegisterAssigned()) {
     DCHECK(!IsSpilled());
@@ -507,23 +507,24 @@
 
 
 RegisterAllocator::RegisterAllocator(const RegisterConfiguration* config,
-                                     Zone* local_zone, Frame* frame,
+                                     Zone* zone, Frame* frame,
                                      InstructionSequence* code,
                                      const char* debug_name)
-    : zone_(local_zone),
+    : local_zone_(zone),
       frame_(frame),
       code_(code),
       debug_name_(debug_name),
       config_(config),
-      live_in_sets_(code->InstructionBlockCount(), zone()),
-      live_ranges_(code->VirtualRegisterCount() * 2, zone()),
-      fixed_live_ranges_(this->config()->num_general_registers(), NULL, zone()),
+      live_in_sets_(code->InstructionBlockCount(), local_zone()),
+      live_ranges_(code->VirtualRegisterCount() * 2, local_zone()),
+      fixed_live_ranges_(this->config()->num_general_registers(), NULL,
+                         local_zone()),
       fixed_double_live_ranges_(this->config()->num_double_registers(), NULL,
-                                zone()),
-      unhandled_live_ranges_(code->VirtualRegisterCount() * 2, zone()),
-      active_live_ranges_(8, zone()),
-      inactive_live_ranges_(8, zone()),
-      reusable_slots_(8, zone()),
+                                local_zone()),
+      unhandled_live_ranges_(code->VirtualRegisterCount() * 2, local_zone()),
+      active_live_ranges_(8, local_zone()),
+      inactive_live_ranges_(8, local_zone()),
+      reusable_slots_(8, local_zone()),
       mode_(UNALLOCATED_REGISTERS),
       num_registers_(-1),
       allocation_ok_(true) {
@@ -541,16 +542,16 @@
 void RegisterAllocator::InitializeLivenessAnalysis() {
   // Initialize the live_in sets for each block to NULL.
   int block_count = code()->InstructionBlockCount();
-  live_in_sets_.Initialize(block_count, zone());
-  live_in_sets_.AddBlock(NULL, block_count, zone());
+  live_in_sets_.Initialize(block_count, local_zone());
+  live_in_sets_.AddBlock(NULL, block_count, local_zone());
 }
 
 
 BitVector* RegisterAllocator::ComputeLiveOut(const InstructionBlock* block) {
   // Compute live out for the given block, except not including backward
   // successor edges.
-  BitVector* live_out =
-      new (zone()) BitVector(code()->VirtualRegisterCount(), zone());
+  BitVector* live_out = new (local_zone())
+      BitVector(code()->VirtualRegisterCount(), local_zone());
 
   // Process all successor blocks.
   for (auto succ : block->successors()) {
@@ -584,7 +585,7 @@
   while (!iterator.Done()) {
     int operand_index = iterator.Current();
     LiveRange* range = LiveRangeFor(operand_index);
-    range->AddUseInterval(start, end, zone());
+    range->AddUseInterval(start, end, local_zone());
     iterator.Advance();
   }
 }
@@ -630,7 +631,7 @@
     // The LiveRange object itself can go in this zone, but the
     // InstructionOperand needs
     // to go in the code zone, since it may survive register allocation.
-    result = new (zone()) LiveRange(FixedLiveRangeID(index), code_zone());
+    result = new (local_zone()) LiveRange(FixedLiveRangeID(index), code_zone());
     DCHECK(result->IsFixed());
     result->kind_ = GENERAL_REGISTERS;
     SetLiveRangeAssignedRegister(result, index);
@@ -644,7 +645,8 @@
   DCHECK(index < config()->num_aliased_double_registers());
   LiveRange* result = fixed_double_live_ranges_[index];
   if (result == NULL) {
-    result = new (zone()) LiveRange(FixedDoubleLiveRangeID(index), code_zone());
+    result = new (local_zone())
+        LiveRange(FixedDoubleLiveRangeID(index), code_zone());
     DCHECK(result->IsFixed());
     result->kind_ = DOUBLE_REGISTERS;
     SetLiveRangeAssignedRegister(result, index);
@@ -656,11 +658,12 @@
 
 LiveRange* RegisterAllocator::LiveRangeFor(int index) {
   if (index >= live_ranges_.length()) {
-    live_ranges_.AddBlock(NULL, index - live_ranges_.length() + 1, zone());
+    live_ranges_.AddBlock(NULL, index - live_ranges_.length() + 1,
+                          local_zone());
   }
   LiveRange* result = live_ranges_[index];
   if (result == NULL) {
-    result = new (zone()) LiveRange(index, code_zone());
+    result = new (local_zone()) LiveRange(index, code_zone());
     live_ranges_[index] = result;
   }
   return result;
@@ -694,15 +697,15 @@
 
   if (range->IsEmpty() || range->Start().Value() > position.Value()) {
     // Can happen if there is a definition without use.
-    range->AddUseInterval(position, position.NextInstruction(), zone());
-    range->AddUsePosition(position.NextInstruction(), NULL, NULL, zone());
+    range->AddUseInterval(position, position.NextInstruction(), local_zone());
+    range->AddUsePosition(position.NextInstruction(), NULL, NULL, local_zone());
   } else {
     range->ShortenTo(position);
   }
 
   if (operand->IsUnallocated()) {
     UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand);
-    range->AddUsePosition(position, unalloc_operand, hint, zone());
+    range->AddUsePosition(position, unalloc_operand, hint, local_zone());
   }
 }
 
@@ -715,9 +718,9 @@
   if (range == NULL) return;
   if (operand->IsUnallocated()) {
     UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand);
-    range->AddUsePosition(position, unalloc_operand, hint, zone());
+    range->AddUsePosition(position, unalloc_operand, hint, local_zone());
   }
-  range->AddUseInterval(block_start, position, zone());
+  range->AddUseInterval(block_start, position, local_zone());
 }
 
 
@@ -1023,7 +1026,7 @@
           if (!IsOutputRegisterOf(instr, i)) {
             LiveRange* range = FixedLiveRangeFor(i);
             range->AddUseInterval(curr_position, curr_position.InstructionEnd(),
-                                  zone());
+                                  local_zone());
           }
         }
       }
@@ -1033,7 +1036,7 @@
           if (!IsOutputDoubleRegisterOf(instr, i)) {
             LiveRange* range = FixedDoubleLiveRangeFor(i);
             range->AddUseInterval(curr_position, curr_position.InstructionEnd(),
-                                  zone());
+                                  local_zone());
           }
         }
       }
@@ -1160,9 +1163,8 @@
 
 
 void RegisterAllocator::MeetRegisterConstraints() {
-  for (int i = 0; i < code()->InstructionBlockCount(); ++i) {
-    MeetRegisterConstraints(
-        code()->InstructionBlockAt(BasicBlock::RpoNumber::FromInt(i)));
+  for (auto block : code()->instruction_blocks()) {
+    MeetRegisterConstraints(block);
     if (!AllocationOk()) return;
   }
 }
@@ -1170,55 +1172,9 @@
 
 void RegisterAllocator::ResolvePhis() {
   // Process the blocks in reverse order.
-  for (int i = code()->InstructionBlockCount() - 1; i >= 0; --i) {
-    ResolvePhis(code()->InstructionBlockAt(BasicBlock::RpoNumber::FromInt(i)));
-  }
-}
-
-
-void RegisterAllocator::ResolveControlFlow(LiveRange* range,
-                                           const InstructionBlock* block,
-                                           const InstructionBlock* pred) {
-  LifetimePosition pred_end =
-      LifetimePosition::FromInstructionIndex(pred->last_instruction_index());
-  LifetimePosition cur_start =
-      LifetimePosition::FromInstructionIndex(block->first_instruction_index());
-  LiveRange* pred_cover = NULL;
-  LiveRange* cur_cover = NULL;
-  LiveRange* cur_range = range;
-  while (cur_range != NULL && (cur_cover == NULL || pred_cover == NULL)) {
-    if (cur_range->CanCover(cur_start)) {
-      DCHECK(cur_cover == NULL);
-      cur_cover = cur_range;
-    }
-    if (cur_range->CanCover(pred_end)) {
-      DCHECK(pred_cover == NULL);
-      pred_cover = cur_range;
-    }
-    cur_range = cur_range->next();
-  }
-
-  if (cur_cover->IsSpilled()) return;
-  DCHECK(pred_cover != NULL && cur_cover != NULL);
-  if (pred_cover != cur_cover) {
-    InstructionOperand* pred_op =
-        pred_cover->CreateAssignedOperand(code_zone());
-    InstructionOperand* cur_op = cur_cover->CreateAssignedOperand(code_zone());
-    if (!pred_op->Equals(cur_op)) {
-      GapInstruction* gap = NULL;
-      if (block->PredecessorCount() == 1) {
-        gap = code()->GapAt(block->first_instruction_index());
-      } else {
-        DCHECK(pred->SuccessorCount() == 1);
-        gap = GetLastGap(pred);
-
-        Instruction* branch = InstructionAt(pred->last_instruction_index());
-        DCHECK(!branch->HasPointerMap());
-        USE(branch);
-      }
-      gap->GetOrCreateParallelMove(GapInstruction::START, code_zone())
-          ->AddMove(pred_op, cur_op, code_zone());
-    }
+  for (auto i = code()->instruction_blocks().rbegin();
+       i != code()->instruction_blocks().rend(); ++i) {
+    ResolvePhis(*i);
   }
 }
 
@@ -1288,20 +1244,146 @@
 }
 
 
+namespace {
+
+class LiveRangeBound {
+ public:
+  explicit LiveRangeBound(const LiveRange* range)
+      : range_(range), start_(range->Start()), end_(range->End()) {
+    DCHECK(!range->IsEmpty());
+  }
+
+  bool CanCover(LifetimePosition position) {
+    return start_.Value() <= position.Value() &&
+           position.Value() < end_.Value();
+  }
+
+  const LiveRange* const range_;
+  const LifetimePosition start_;
+  const LifetimePosition end_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(LiveRangeBound);
+};
+
+
+struct FindResult {
+  const LiveRange* cur_cover_;
+  const LiveRange* pred_cover_;
+};
+
+
+class LiveRangeBoundArray {
+ public:
+  LiveRangeBoundArray() : length_(0), start_(nullptr) {}
+
+  bool ShouldInitialize() { return start_ == NULL; }
+
+  void Initialize(Zone* zone, const LiveRange* const range) {
+    size_t length = 0;
+    for (const LiveRange* i = range; i != NULL; i = i->next()) length++;
+    start_ = zone->NewArray<LiveRangeBound>(static_cast<int>(length));
+    length_ = length;
+    LiveRangeBound* curr = start_;
+    for (const LiveRange* i = range; i != NULL; i = i->next(), ++curr) {
+      new (curr) LiveRangeBound(i);
+    }
+  }
+
+  LiveRangeBound* Find(const LifetimePosition position) const {
+    size_t left_index = 0;
+    size_t right_index = length_;
+    while (true) {
+      size_t current_index = left_index + (right_index - left_index) / 2;
+      DCHECK(right_index > current_index);
+      LiveRangeBound* bound = &start_[current_index];
+      if (bound->start_.Value() <= position.Value()) {
+        if (position.Value() < bound->end_.Value()) return bound;
+        DCHECK(left_index < current_index);
+        left_index = current_index;
+      } else {
+        right_index = current_index;
+      }
+    }
+  }
+
+  void Find(const InstructionBlock* block, const InstructionBlock* pred,
+            FindResult* result) const {
+    const LifetimePosition pred_end =
+        LifetimePosition::FromInstructionIndex(pred->last_instruction_index());
+    LiveRangeBound* bound = Find(pred_end);
+    result->pred_cover_ = bound->range_;
+    const LifetimePosition cur_start = LifetimePosition::FromInstructionIndex(
+        block->first_instruction_index());
+    // Common case.
+    if (bound->CanCover(cur_start)) {
+      result->cur_cover_ = bound->range_;
+      return;
+    }
+    result->cur_cover_ = Find(cur_start)->range_;
+    DCHECK(result->pred_cover_ != NULL && result->cur_cover_ != NULL);
+  }
+
+ private:
+  size_t length_;
+  LiveRangeBound* start_;
+
+  DISALLOW_COPY_AND_ASSIGN(LiveRangeBoundArray);
+};
+
+
+class LiveRangeFinder {
+ public:
+  explicit LiveRangeFinder(const RegisterAllocator& allocator)
+      : allocator_(allocator),
+        bounds_length_(allocator.live_ranges().length()),
+        bounds_(allocator.local_zone()->NewArray<LiveRangeBoundArray>(
+            bounds_length_)) {
+    for (int i = 0; i < bounds_length_; ++i) {
+      new (&bounds_[i]) LiveRangeBoundArray();
+    }
+  }
+
+  LiveRangeBoundArray* ArrayFor(int operand_index) {
+    DCHECK(operand_index < bounds_length_);
+    const LiveRange* range = allocator_.live_ranges()[operand_index];
+    DCHECK(range != nullptr && !range->IsEmpty());
+    LiveRangeBoundArray* array = &bounds_[operand_index];
+    if (array->ShouldInitialize()) {
+      array->Initialize(allocator_.local_zone(), range);
+    }
+    return array;
+  }
+
+ private:
+  const RegisterAllocator& allocator_;
+  const int bounds_length_;
+  LiveRangeBoundArray* const bounds_;
+
+  DISALLOW_COPY_AND_ASSIGN(LiveRangeFinder);
+};
+
+}  // namespace
+
+
 void RegisterAllocator::ResolveControlFlow() {
-  for (int block_id = 1; block_id < code()->InstructionBlockCount();
-       ++block_id) {
-    const InstructionBlock* block =
-        code()->InstructionBlockAt(BasicBlock::RpoNumber::FromInt(block_id));
+  // Lazily linearize live ranges in memory for fast lookup.
+  LiveRangeFinder finder(*this);
+  for (auto block : code()->instruction_blocks()) {
     if (CanEagerlyResolveControlFlow(block)) continue;
     BitVector* live = live_in_sets_[block->rpo_number().ToInt()];
     BitVector::Iterator iterator(live);
     while (!iterator.Done()) {
-      int operand_index = iterator.Current();
+      LiveRangeBoundArray* array = finder.ArrayFor(iterator.Current());
       for (auto pred : block->predecessors()) {
-        const InstructionBlock* cur = code()->InstructionBlockAt(pred);
-        LiveRange* cur_range = LiveRangeFor(operand_index);
-        ResolveControlFlow(cur_range, block, cur);
+        FindResult result;
+        const InstructionBlock* pred_block = code()->InstructionBlockAt(pred);
+        array->Find(block, pred_block, &result);
+        if (result.cur_cover_ == result.pred_cover_ ||
+            result.cur_cover_->IsSpilled())
+          continue;
+        ResolveControlFlow(block, result.cur_cover_, pred_block,
+                           result.pred_cover_);
       }
       iterator.Advance();
     }
@@ -1309,6 +1391,30 @@
 }
 
 
+void RegisterAllocator::ResolveControlFlow(const InstructionBlock* block,
+                                           const LiveRange* cur_cover,
+                                           const InstructionBlock* pred,
+                                           const LiveRange* pred_cover) {
+  InstructionOperand* pred_op = pred_cover->CreateAssignedOperand(code_zone());
+  InstructionOperand* cur_op = cur_cover->CreateAssignedOperand(code_zone());
+  if (!pred_op->Equals(cur_op)) {
+    GapInstruction* gap = NULL;
+    if (block->PredecessorCount() == 1) {
+      gap = code()->GapAt(block->first_instruction_index());
+    } else {
+      DCHECK(pred->SuccessorCount() == 1);
+      gap = GetLastGap(pred);
+
+      Instruction* branch = InstructionAt(pred->last_instruction_index());
+      DCHECK(!branch->HasPointerMap());
+      USE(branch);
+    }
+    gap->GetOrCreateParallelMove(GapInstruction::START, code_zone())
+        ->AddMove(pred_op, cur_op, code_zone());
+  }
+}
+
+
 void RegisterAllocator::BuildLiveRanges() {
   InitializeLivenessAnalysis();
   // Process the blocks in reverse order.
@@ -1371,7 +1477,7 @@
       while (!iterator.Done()) {
         int operand_index = iterator.Current();
         LiveRange* range = LiveRangeFor(operand_index);
-        range->EnsureInterval(start, end, zone());
+        range->EnsureInterval(start, end, local_zone());
         iterator.Advance();
       }
 
@@ -1667,13 +1773,13 @@
 
 void RegisterAllocator::AddToActive(LiveRange* range) {
   TraceAlloc("Add live range %d to active\n", range->id());
-  active_live_ranges_.Add(range, zone());
+  active_live_ranges_.Add(range, local_zone());
 }
 
 
 void RegisterAllocator::AddToInactive(LiveRange* range) {
   TraceAlloc("Add live range %d to inactive\n", range->id());
-  inactive_live_ranges_.Add(range, zone());
+  inactive_live_ranges_.Add(range, local_zone());
 }
 
 
@@ -1685,13 +1791,13 @@
     LiveRange* cur_range = unhandled_live_ranges_.at(i);
     if (range->ShouldBeAllocatedBefore(cur_range)) {
       TraceAlloc("Add live range %d to unhandled at %d\n", range->id(), i + 1);
-      unhandled_live_ranges_.InsertAt(i + 1, range, zone());
+      unhandled_live_ranges_.InsertAt(i + 1, range, local_zone());
       DCHECK(UnhandledIsSorted());
       return;
     }
   }
   TraceAlloc("Add live range %d to unhandled at start\n", range->id());
-  unhandled_live_ranges_.InsertAt(0, range, zone());
+  unhandled_live_ranges_.InsertAt(0, range, local_zone());
   DCHECK(UnhandledIsSorted());
 }
 
@@ -1700,7 +1806,7 @@
   if (range == NULL || range->IsEmpty()) return;
   DCHECK(!range->HasRegisterAssigned() && !range->IsSpilled());
   TraceAlloc("Add live range %d to unhandled unsorted at end\n", range->id());
-  unhandled_live_ranges_.Add(range, zone());
+  unhandled_live_ranges_.Add(range, local_zone());
 }
 
 
@@ -1742,7 +1848,7 @@
   InstructionOperand* spill_operand = range->TopLevel()->GetSpillOperand();
   if (spill_operand->IsConstant()) return;
   if (spill_operand->index() >= 0) {
-    reusable_slots_.Add(range, zone());
+    reusable_slots_.Add(range, local_zone());
   }
 }
 
@@ -1771,7 +1877,7 @@
 void RegisterAllocator::ActiveToInactive(LiveRange* range) {
   DCHECK(active_live_ranges_.Contains(range));
   active_live_ranges_.RemoveElement(range);
-  inactive_live_ranges_.Add(range, zone());
+  inactive_live_ranges_.Add(range, local_zone());
   TraceAlloc("Moving live range %d from active to inactive\n", range->id());
 }
 
@@ -1787,7 +1893,7 @@
 void RegisterAllocator::InactiveToActive(LiveRange* range) {
   DCHECK(inactive_live_ranges_.Contains(range));
   inactive_live_ranges_.RemoveElement(range);
-  active_live_ranges_.Add(range, zone());
+  active_live_ranges_.Add(range, local_zone());
   TraceAlloc("Moving live range %d from inactive to active\n", range->id());
 }
 
@@ -2063,7 +2169,7 @@
   int vreg = GetVirtualRegister();
   if (!AllocationOk()) return NULL;
   LiveRange* result = LiveRangeFor(vreg);
-  range->SplitAt(pos, result, zone());
+  range->SplitAt(pos, result, local_zone());
   return result;
 }
 
@@ -2171,10 +2277,10 @@
       RegisterKind kind = range->Kind();
       int index = frame()->AllocateSpillSlot(kind == DOUBLE_REGISTERS);
       if (kind == DOUBLE_REGISTERS) {
-        op = DoubleStackSlotOperand::Create(index, zone());
+        op = DoubleStackSlotOperand::Create(index, local_zone());
       } else {
         DCHECK(kind == GENERAL_REGISTERS);
-        op = StackSlotOperand::Create(index, zone());
+        op = StackSlotOperand::Create(index, local_zone());
       }
     }
     first->SetSpillOperand(op);
diff --git a/src/compiler/register-allocator.h b/src/compiler/register-allocator.h
index b167437..a6578af 100644
--- a/src/compiler/register-allocator.h
+++ b/src/compiler/register-allocator.h
@@ -186,12 +186,15 @@
   UsePosition* first_pos() const { return first_pos_; }
   LiveRange* parent() const { return parent_; }
   LiveRange* TopLevel() { return (parent_ == NULL) ? this : parent_; }
+  const LiveRange* TopLevel() const {
+    return (parent_ == NULL) ? this : parent_;
+  }
   LiveRange* next() const { return next_; }
   bool IsChild() const { return parent() != NULL; }
   int id() const { return id_; }
   bool IsFixed() const { return id_ < 0; }
   bool IsEmpty() const { return first_interval() == NULL; }
-  InstructionOperand* CreateAssignedOperand(Zone* zone);
+  InstructionOperand* CreateAssignedOperand(Zone* zone) const;
   int assigned_register() const { return assigned_register_; }
   int spill_start_index() const { return spill_start_index_; }
   void set_assigned_register(int reg, Zone* zone);
@@ -337,6 +340,8 @@
     return fixed_double_live_ranges_;
   }
   InstructionSequence* code() const { return code_; }
+  // This zone is for datastructures only needed during register allocation.
+  Zone* local_zone() const { return local_zone_; }
 
  private:
   int GetVirtualRegister() {
@@ -356,9 +361,6 @@
   // Returns the register kind required by the given virtual register.
   RegisterKind RequiredRegisterKind(int virtual_register) const;
 
-  // This zone is for datastructures only needed during register allocation.
-  Zone* zone() const { return zone_; }
-
   // This zone is for InstructionOperands and moves that live beyond register
   // allocation.
   Zone* code_zone() const { return code()->zone(); }
@@ -465,8 +467,10 @@
   bool IsBlockBoundary(LifetimePosition pos);
 
   // Helper methods for resolving control flow.
-  void ResolveControlFlow(LiveRange* range, const InstructionBlock* block,
-                          const InstructionBlock* pred);
+  void ResolveControlFlow(const InstructionBlock* block,
+                          const LiveRange* cur_cover,
+                          const InstructionBlock* pred,
+                          const LiveRange* pred_cover);
 
   void SetLiveRangeAssignedRegister(LiveRange* range, int reg);
 
@@ -494,7 +498,7 @@
   const char* debug_name() const { return debug_name_; }
   const RegisterConfiguration* config() const { return config_; }
 
-  Zone* const zone_;
+  Zone* const local_zone_;
   Frame* const frame_;
   InstructionSequence* const code_;
   const char* const debug_name_;
diff --git a/src/compiler/scheduler.cc b/src/compiler/scheduler.cc
index 9d0d730..92e05cb 100644
--- a/src/compiler/scheduler.cc
+++ b/src/compiler/scheduler.cc
@@ -922,9 +922,9 @@
       // TODO(jarin,svenpanne): Add formatting here once we have support for
       // that in streams (we want an equivalent of PrintF("%5d:", x) here).
       os << "  " << block->rpo_number() << ":";
-      for (size_t j = 0; j < loops_.size(); j++) {
-        bool membership = loops_[j].members->Contains(bid.ToInt());
-        bool range = loops_[j].header->LoopContains(block);
+      for (size_t i = 0; i < loops_.size(); i++) {
+        bool range = loops_[i].header->LoopContains(block);
+        bool membership = loops_[i].header != block && range;
         os << (membership ? " |" : "  ");
         os << (range ? "x" : " ");
       }
@@ -982,23 +982,18 @@
       DCHECK(end_found);
 
       // Check the contiguousness of loops.
-      // TODO(mstarzinger): Loop membership bit-vector becomes stale.
-      /*int count = 0;
+      int count = 0;
       for (int j = 0; j < static_cast<int>(order->size()); j++) {
         BasicBlock* block = order->at(j);
         DCHECK(block->rpo_number() == j);
         if (j < header->rpo_number() || j >= end->rpo_number()) {
-          DCHECK(!loop->members->Contains(block->id().ToInt()));
+          DCHECK(!header->LoopContains(block));
         } else {
-          if (block == header) {
-            DCHECK(!loop->members->Contains(block->id().ToInt()));
-          } else {
-            DCHECK(loop->members->Contains(block->id().ToInt()));
-          }
+          DCHECK(header->LoopContains(block));
           count++;
         }
       }
-      DCHECK(links == count);*/
+      DCHECK(links == count);
     }
   }
 #endif  // DEBUG
diff --git a/src/heap-snapshot-generator-inl.h b/src/heap-snapshot-generator-inl.h
index 3f7e622..ad95776 100644
--- a/src/heap-snapshot-generator-inl.h
+++ b/src/heap-snapshot-generator-inl.h
@@ -12,7 +12,7 @@
 
 
 HeapEntry* HeapGraphEdge::from() const {
-  return &snapshot()->entries()[from_index_];
+  return &snapshot()->entries()[from_index()];
 }
 
 
diff --git a/src/heap-snapshot-generator.cc b/src/heap-snapshot-generator.cc
index 68522fc..7f217bb 100644
--- a/src/heap-snapshot-generator.cc
+++ b/src/heap-snapshot-generator.cc
@@ -18,8 +18,7 @@
 
 
 HeapGraphEdge::HeapGraphEdge(Type type, const char* name, int from, int to)
-    : type_(type),
-      from_index_(from),
+    : bit_field_(TypeField::encode(type) | FromIndexField::encode(from)),
       to_index_(to),
       name_(name) {
   DCHECK(type == kContextVariable
@@ -31,8 +30,7 @@
 
 
 HeapGraphEdge::HeapGraphEdge(Type type, int index, int from, int to)
-    : type_(type),
-      from_index_(from),
+    : bit_field_(TypeField::encode(type) | FromIndexField::encode(from)),
       to_index_(to),
       index_(index) {
   DCHECK(type == kElement || type == kHidden);
diff --git a/src/heap-snapshot-generator.h b/src/heap-snapshot-generator.h
index 646d497..fb43876 100644
--- a/src/heap-snapshot-generator.h
+++ b/src/heap-snapshot-generator.h
@@ -28,22 +28,18 @@
     kWeak = v8::HeapGraphEdge::kWeak
   };
 
-  HeapGraphEdge() { }
   HeapGraphEdge(Type type, const char* name, int from, int to);
   HeapGraphEdge(Type type, int index, int from, int to);
   void ReplaceToIndexWithEntry(HeapSnapshot* snapshot);
 
-  Type type() const { return static_cast<Type>(type_); }
+  Type type() const { return TypeField::decode(bit_field_); }
   int index() const {
-    DCHECK(type_ == kElement || type_ == kHidden);
+    DCHECK(type() == kElement || type() == kHidden);
     return index_;
   }
   const char* name() const {
-    DCHECK(type_ == kContextVariable
-        || type_ == kProperty
-        || type_ == kInternal
-        || type_ == kShortcut
-        || type_ == kWeak);
+    DCHECK(type() == kContextVariable || type() == kProperty ||
+           type() == kInternal || type() == kShortcut || type() == kWeak);
     return name_;
   }
   INLINE(HeapEntry* from() const);
@@ -51,9 +47,11 @@
 
  private:
   INLINE(HeapSnapshot* snapshot() const);
+  int from_index() const { return FromIndexField::decode(bit_field_); }
 
-  unsigned type_ : 3;
-  int from_index_ : 29;
+  class TypeField : public BitField<Type, 0, 3> {};
+  class FromIndexField : public BitField<int, 3, 29> {};
+  uint32_t bit_field_;
   union {
     // During entries population |to_index_| is used for storing the index,
     // afterwards it is replaced with a pointer to the entry.
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 188119d..ce76fbe 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -1789,7 +1789,7 @@
 
 
 Range* HConstant::InferRange(Zone* zone) {
-  if (has_int32_value_) {
+  if (HasInteger32Value()) {
     Range* result = new(zone) Range(int32_value_, int32_value_);
     result->set_can_be_minus_zero(false);
     return result;
@@ -2606,7 +2606,7 @@
 
 
 void HSimulate::ReplayEnvironment(HEnvironment* env) {
-  if (done_with_replay_) return;
+  if (is_done_with_replay()) return;
   DCHECK(env != NULL);
   env->set_ast_id(ast_id());
   env->Drop(pop_count());
@@ -2618,7 +2618,7 @@
       env->Push(value);
     }
   }
-  done_with_replay_ = true;
+  set_done_with_replay();
 }
 
 
@@ -2674,36 +2674,41 @@
 
 
 HConstant::HConstant(Handle<Object> object, Representation r)
-  : HTemplateInstruction<0>(HType::FromValue(object)),
-    object_(Unique<Object>::CreateUninitialized(object)),
-    object_map_(Handle<Map>::null()),
-    has_stable_map_value_(false),
-    has_smi_value_(false),
-    has_int32_value_(false),
-    has_double_value_(false),
-    has_external_reference_value_(false),
-    is_not_in_new_space_(true),
-    boolean_value_(object->BooleanValue()),
-    is_undetectable_(false),
-    instance_type_(kUnknownInstanceType) {
+    : HTemplateInstruction<0>(HType::FromValue(object)),
+      object_(Unique<Object>::CreateUninitialized(object)),
+      object_map_(Handle<Map>::null()),
+      bit_field_(HasStableMapValueField::encode(false) |
+                 HasSmiValueField::encode(false) |
+                 HasInt32ValueField::encode(false) |
+                 HasDoubleValueField::encode(false) |
+                 HasExternalReferenceValueField::encode(false) |
+                 IsNotInNewSpaceField::encode(true) |
+                 BooleanValueField::encode(object->BooleanValue()) |
+                 IsUndetectableField::encode(false) |
+                 InstanceTypeField::encode(kUnknownInstanceType)) {
   if (object->IsHeapObject()) {
     Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object);
     Isolate* isolate = heap_object->GetIsolate();
     Handle<Map> map(heap_object->map(), isolate);
-    is_not_in_new_space_ = !isolate->heap()->InNewSpace(*object);
-    instance_type_ = map->instance_type();
-    is_undetectable_ = map->is_undetectable();
+    bit_field_ = IsNotInNewSpaceField::update(
+        bit_field_, !isolate->heap()->InNewSpace(*object));
+    bit_field_ = InstanceTypeField::update(bit_field_, map->instance_type());
+    bit_field_ =
+        IsUndetectableField::update(bit_field_, map->is_undetectable());
     if (map->is_stable()) object_map_ = Unique<Map>::CreateImmovable(map);
-    has_stable_map_value_ = (instance_type_ == MAP_TYPE &&
-                             Handle<Map>::cast(heap_object)->is_stable());
+    bit_field_ = HasStableMapValueField::update(
+        bit_field_,
+        HasMapValue() && Handle<Map>::cast(heap_object)->is_stable());
   }
   if (object->IsNumber()) {
     double n = object->Number();
-    has_int32_value_ = IsInteger32(n);
+    bool has_int32_value = IsInteger32(n);
+    bit_field_ = HasInt32ValueField::update(bit_field_, has_int32_value);
     int32_value_ = DoubleToInt32(n);
-    has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_);
+    bit_field_ = HasSmiValueField::update(
+        bit_field_, has_int32_value && Smi::IsValid(int32_value_));
     double_value_ = n;
-    has_double_value_ = true;
+    bit_field_ = HasDoubleValueField::update(bit_field_, true);
     // TODO(titzer): if this heap number is new space, tenure a new one.
   }
 
@@ -2711,112 +2716,104 @@
 }
 
 
-HConstant::HConstant(Unique<Object> object,
-                     Unique<Map> object_map,
-                     bool has_stable_map_value,
-                     Representation r,
-                     HType type,
-                     bool is_not_in_new_space,
-                     bool boolean_value,
-                     bool is_undetectable,
-                     InstanceType instance_type)
-  : HTemplateInstruction<0>(type),
-    object_(object),
-    object_map_(object_map),
-    has_stable_map_value_(has_stable_map_value),
-    has_smi_value_(false),
-    has_int32_value_(false),
-    has_double_value_(false),
-    has_external_reference_value_(false),
-    is_not_in_new_space_(is_not_in_new_space),
-    boolean_value_(boolean_value),
-    is_undetectable_(is_undetectable),
-    instance_type_(instance_type) {
+HConstant::HConstant(Unique<Object> object, Unique<Map> object_map,
+                     bool has_stable_map_value, Representation r, HType type,
+                     bool is_not_in_new_space, bool boolean_value,
+                     bool is_undetectable, InstanceType instance_type)
+    : HTemplateInstruction<0>(type),
+      object_(object),
+      object_map_(object_map),
+      bit_field_(HasStableMapValueField::encode(has_stable_map_value) |
+                 HasSmiValueField::encode(false) |
+                 HasInt32ValueField::encode(false) |
+                 HasDoubleValueField::encode(false) |
+                 HasExternalReferenceValueField::encode(false) |
+                 IsNotInNewSpaceField::encode(is_not_in_new_space) |
+                 BooleanValueField::encode(boolean_value) |
+                 IsUndetectableField::encode(is_undetectable) |
+                 InstanceTypeField::encode(instance_type)) {
   DCHECK(!object.handle().is_null());
   DCHECK(!type.IsTaggedNumber() || type.IsNone());
   Initialize(r);
 }
 
 
-HConstant::HConstant(int32_t integer_value,
-                     Representation r,
-                     bool is_not_in_new_space,
-                     Unique<Object> object)
-  : object_(object),
-    object_map_(Handle<Map>::null()),
-    has_stable_map_value_(false),
-    has_smi_value_(Smi::IsValid(integer_value)),
-    has_int32_value_(true),
-    has_double_value_(true),
-    has_external_reference_value_(false),
-    is_not_in_new_space_(is_not_in_new_space),
-    boolean_value_(integer_value != 0),
-    is_undetectable_(false),
-    int32_value_(integer_value),
-    double_value_(FastI2D(integer_value)),
-    instance_type_(kUnknownInstanceType) {
+HConstant::HConstant(int32_t integer_value, Representation r,
+                     bool is_not_in_new_space, Unique<Object> object)
+    : object_(object),
+      object_map_(Handle<Map>::null()),
+      bit_field_(HasStableMapValueField::encode(false) |
+                 HasSmiValueField::encode(Smi::IsValid(integer_value)) |
+                 HasInt32ValueField::encode(true) |
+                 HasDoubleValueField::encode(true) |
+                 HasExternalReferenceValueField::encode(false) |
+                 IsNotInNewSpaceField::encode(is_not_in_new_space) |
+                 BooleanValueField::encode(integer_value != 0) |
+                 IsUndetectableField::encode(false) |
+                 InstanceTypeField::encode(kUnknownInstanceType)),
+      int32_value_(integer_value),
+      double_value_(FastI2D(integer_value)) {
   // It's possible to create a constant with a value in Smi-range but stored
   // in a (pre-existing) HeapNumber. See crbug.com/349878.
   bool could_be_heapobject = r.IsTagged() && !object.handle().is_null();
-  bool is_smi = has_smi_value_ && !could_be_heapobject;
+  bool is_smi = HasSmiValue() && !could_be_heapobject;
   set_type(is_smi ? HType::Smi() : HType::TaggedNumber());
   Initialize(r);
 }
 
 
-HConstant::HConstant(double double_value,
-                     Representation r,
-                     bool is_not_in_new_space,
-                     Unique<Object> object)
-  : object_(object),
-    object_map_(Handle<Map>::null()),
-    has_stable_map_value_(false),
-    has_int32_value_(IsInteger32(double_value)),
-    has_double_value_(true),
-    has_external_reference_value_(false),
-    is_not_in_new_space_(is_not_in_new_space),
-    boolean_value_(double_value != 0 && !std::isnan(double_value)),
-    is_undetectable_(false),
-    int32_value_(DoubleToInt32(double_value)),
-    double_value_(double_value),
-    instance_type_(kUnknownInstanceType) {
-  has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_);
+HConstant::HConstant(double double_value, Representation r,
+                     bool is_not_in_new_space, Unique<Object> object)
+    : object_(object),
+      object_map_(Handle<Map>::null()),
+      bit_field_(HasStableMapValueField::encode(false) |
+                 HasInt32ValueField::encode(IsInteger32(double_value)) |
+                 HasDoubleValueField::encode(true) |
+                 HasExternalReferenceValueField::encode(false) |
+                 IsNotInNewSpaceField::encode(is_not_in_new_space) |
+                 BooleanValueField::encode(double_value != 0 &&
+                                           !std::isnan(double_value)) |
+                 IsUndetectableField::encode(false) |
+                 InstanceTypeField::encode(kUnknownInstanceType)),
+      int32_value_(DoubleToInt32(double_value)),
+      double_value_(double_value) {
+  bit_field_ = HasSmiValueField::update(
+      bit_field_, HasInteger32Value() && Smi::IsValid(int32_value_));
   // It's possible to create a constant with a value in Smi-range but stored
   // in a (pre-existing) HeapNumber. See crbug.com/349878.
   bool could_be_heapobject = r.IsTagged() && !object.handle().is_null();
-  bool is_smi = has_smi_value_ && !could_be_heapobject;
+  bool is_smi = HasSmiValue() && !could_be_heapobject;
   set_type(is_smi ? HType::Smi() : HType::TaggedNumber());
   Initialize(r);
 }
 
 
 HConstant::HConstant(ExternalReference reference)
-  : HTemplateInstruction<0>(HType::Any()),
-    object_(Unique<Object>(Handle<Object>::null())),
-    object_map_(Handle<Map>::null()),
-    has_stable_map_value_(false),
-    has_smi_value_(false),
-    has_int32_value_(false),
-    has_double_value_(false),
-    has_external_reference_value_(true),
-    is_not_in_new_space_(true),
-    boolean_value_(true),
-    is_undetectable_(false),
-    external_reference_value_(reference),
-    instance_type_(kUnknownInstanceType) {
+    : HTemplateInstruction<0>(HType::Any()),
+      object_(Unique<Object>(Handle<Object>::null())),
+      object_map_(Handle<Map>::null()),
+      bit_field_(
+          HasStableMapValueField::encode(false) |
+          HasSmiValueField::encode(false) | HasInt32ValueField::encode(false) |
+          HasDoubleValueField::encode(false) |
+          HasExternalReferenceValueField::encode(true) |
+          IsNotInNewSpaceField::encode(true) | BooleanValueField::encode(true) |
+          IsUndetectableField::encode(false) |
+          InstanceTypeField::encode(kUnknownInstanceType)),
+      external_reference_value_(reference) {
   Initialize(Representation::External());
 }
 
 
 void HConstant::Initialize(Representation r) {
   if (r.IsNone()) {
-    if (has_smi_value_ && SmiValuesAre31Bits()) {
+    if (HasSmiValue() && SmiValuesAre31Bits()) {
       r = Representation::Smi();
-    } else if (has_int32_value_) {
+    } else if (HasInteger32Value()) {
       r = Representation::Integer32();
-    } else if (has_double_value_) {
+    } else if (HasDoubleValue()) {
       r = Representation::Double();
-    } else if (has_external_reference_value_) {
+    } else if (HasExternalReferenceValue()) {
       r = Representation::External();
     } else {
       Handle<Object> object = object_.handle();
@@ -2843,16 +2840,16 @@
 
 
 bool HConstant::ImmortalImmovable() const {
-  if (has_int32_value_) {
+  if (HasInteger32Value()) {
     return false;
   }
-  if (has_double_value_) {
+  if (HasDoubleValue()) {
     if (IsSpecialDouble()) {
       return true;
     }
     return false;
   }
-  if (has_external_reference_value_) {
+  if (HasExternalReferenceValue()) {
     return false;
   }
 
@@ -2893,44 +2890,35 @@
 
 
 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const {
-  if (r.IsSmi() && !has_smi_value_) return NULL;
-  if (r.IsInteger32() && !has_int32_value_) return NULL;
-  if (r.IsDouble() && !has_double_value_) return NULL;
-  if (r.IsExternal() && !has_external_reference_value_) return NULL;
-  if (has_int32_value_) {
-    return new(zone) HConstant(int32_value_, r, is_not_in_new_space_, object_);
+  if (r.IsSmi() && !HasSmiValue()) return NULL;
+  if (r.IsInteger32() && !HasInteger32Value()) return NULL;
+  if (r.IsDouble() && !HasDoubleValue()) return NULL;
+  if (r.IsExternal() && !HasExternalReferenceValue()) return NULL;
+  if (HasInteger32Value()) {
+    return new (zone) HConstant(int32_value_, r, NotInNewSpace(), object_);
   }
-  if (has_double_value_) {
-    return new(zone) HConstant(double_value_, r, is_not_in_new_space_, object_);
+  if (HasDoubleValue()) {
+    return new (zone) HConstant(double_value_, r, NotInNewSpace(), object_);
   }
-  if (has_external_reference_value_) {
+  if (HasExternalReferenceValue()) {
     return new(zone) HConstant(external_reference_value_);
   }
   DCHECK(!object_.handle().is_null());
-  return new(zone) HConstant(object_,
-                             object_map_,
-                             has_stable_map_value_,
-                             r,
-                             type_,
-                             is_not_in_new_space_,
-                             boolean_value_,
-                             is_undetectable_,
-                             instance_type_);
+  return new (zone) HConstant(object_, object_map_, HasStableMapValue(), r,
+                              type_, NotInNewSpace(), BooleanValue(),
+                              IsUndetectable(), GetInstanceType());
 }
 
 
 Maybe<HConstant*> HConstant::CopyToTruncatedInt32(Zone* zone) {
   HConstant* res = NULL;
-  if (has_int32_value_) {
-    res = new(zone) HConstant(int32_value_,
-                              Representation::Integer32(),
-                              is_not_in_new_space_,
-                              object_);
-  } else if (has_double_value_) {
-    res = new(zone) HConstant(DoubleToInt32(double_value_),
-                              Representation::Integer32(),
-                              is_not_in_new_space_,
-                              object_);
+  if (HasInteger32Value()) {
+    res = new (zone) HConstant(int32_value_, Representation::Integer32(),
+                               NotInNewSpace(), object_);
+  } else if (HasDoubleValue()) {
+    res = new (zone)
+        HConstant(DoubleToInt32(double_value_), Representation::Integer32(),
+                  NotInNewSpace(), object_);
   }
   return Maybe<HConstant*>(res != NULL, res);
 }
@@ -2952,11 +2940,11 @@
 
 
 std::ostream& HConstant::PrintDataTo(std::ostream& os) const {  // NOLINT
-  if (has_int32_value_) {
+  if (HasInteger32Value()) {
     os << int32_value_ << " ";
-  } else if (has_double_value_) {
+  } else if (HasDoubleValue()) {
     os << double_value_ << " ";
-  } else if (has_external_reference_value_) {
+  } else if (HasExternalReferenceValue()) {
     os << reinterpret_cast<void*>(external_reference_value_.address()) << " ";
   } else {
     // The handle() method is silently and lazily mutating the object.
@@ -2965,7 +2953,7 @@
     if (HasStableMapValue()) os << "[stable-map] ";
     if (HasObjectMap()) os << "[map " << *ObjectMap().handle() << "] ";
   }
-  if (!is_not_in_new_space_) os << "[new space] ";
+  if (!NotInNewSpace()) os << "[new space] ";
   return os;
 }
 
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 810a2fd..233ca42 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -1497,13 +1497,18 @@
   virtual std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   static const int kNoKnownSuccessorIndex = -1;
-  int known_successor_index() const { return known_successor_index_; }
-  void set_known_successor_index(int known_successor_index) {
-    known_successor_index_ = known_successor_index;
+  int known_successor_index() const {
+    return KnownSuccessorIndexField::decode(bit_field_) -
+           kInternalKnownSuccessorOffset;
+  }
+  void set_known_successor_index(int index) {
+    DCHECK(index >= 0 - kInternalKnownSuccessorOffset);
+    bit_field_ = KnownSuccessorIndexField::update(
+        bit_field_, index + kInternalKnownSuccessorOffset);
   }
 
   Unique<Map> map() const { return map_; }
-  bool map_is_stable() const { return map_is_stable_; }
+  bool map_is_stable() const { return MapIsStableField::decode(bit_field_); }
 
   virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
@@ -1515,19 +1520,25 @@
   virtual int RedefinedOperandIndex() OVERRIDE { return 0; }
 
  private:
-  HCompareMap(HValue* value,
-              Handle<Map> map,
-              HBasicBlock* true_target = NULL,
+  HCompareMap(HValue* value, Handle<Map> map, HBasicBlock* true_target = NULL,
               HBasicBlock* false_target = NULL)
       : HUnaryControlInstruction(value, true_target, false_target),
-        known_successor_index_(kNoKnownSuccessorIndex),
-        map_is_stable_(map->is_stable()),
+        bit_field_(KnownSuccessorIndexField::encode(
+                       kNoKnownSuccessorIndex + kInternalKnownSuccessorOffset) |
+                   MapIsStableField::encode(map->is_stable())),
         map_(Unique<Map>::CreateImmovable(map)) {
     set_representation(Representation::Tagged());
   }
 
-  int known_successor_index_ : 31;
-  bool map_is_stable_ : 1;
+  // BitFields can only store unsigned values, so use an offset.
+  // Adding kInternalKnownSuccessorOffset must yield an unsigned value.
+  static const int kInternalKnownSuccessorOffset = 1;
+  STATIC_ASSERT(kNoKnownSuccessorIndex + kInternalKnownSuccessorOffset >= 0);
+
+  class KnownSuccessorIndexField : public BitField<int, 0, 31> {};
+  class MapIsStableField : public BitField<bool, 31, 1> {};
+
+  uint32_t bit_field_;
   Unique<Map> map_;
 };
 
@@ -1803,17 +1814,15 @@
 
 class HSimulate FINAL : public HInstruction {
  public:
-  HSimulate(BailoutId ast_id,
-            int pop_count,
-            Zone* zone,
+  HSimulate(BailoutId ast_id, int pop_count, Zone* zone,
             RemovableSimulate removable)
       : ast_id_(ast_id),
         pop_count_(pop_count),
         values_(2, zone),
         assigned_indexes_(2, zone),
         zone_(zone),
-        removable_(removable),
-        done_with_replay_(false) {}
+        bit_field_(RemovableField::encode(removable) |
+                   DoneWithReplayField::encode(false)) {}
   ~HSimulate() {}
 
   virtual std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
@@ -1857,7 +1866,9 @@
   }
 
   void MergeWith(ZoneList<HSimulate*>* list);
-  bool is_candidate_for_removal() { return removable_ == REMOVABLE_SIMULATE; }
+  bool is_candidate_for_removal() {
+    return RemovableField::decode(bit_field_) == REMOVABLE_SIMULATE;
+  }
 
   // Replay effects of this instruction on the given environment.
   void ReplayEnvironment(HEnvironment* env);
@@ -1891,13 +1902,22 @@
     }
     return false;
   }
+  bool is_done_with_replay() const {
+    return DoneWithReplayField::decode(bit_field_);
+  }
+  void set_done_with_replay() {
+    bit_field_ = DoneWithReplayField::update(bit_field_, true);
+  }
+
+  class RemovableField : public BitField<RemovableSimulate, 0, 1> {};
+  class DoneWithReplayField : public BitField<bool, 1, 1> {};
+
   BailoutId ast_id_;
   int pop_count_;
   ZoneList<HValue*> values_;
   ZoneList<int> assigned_indexes_;
   Zone* zone_;
-  RemovableSimulate removable_ : 2;
-  bool done_with_replay_ : 1;
+  uint32_t bit_field_;
 
 #ifdef DEBUG
   Handle<JSFunction> closure_;
@@ -2742,11 +2762,13 @@
     return new(zone) HCheckMaps(value, maps, typecheck);
   }
 
-  bool IsStabilityCheck() const { return is_stability_check_; }
+  bool IsStabilityCheck() const {
+    return IsStabilityCheckField::decode(bit_field_);
+  }
   void MarkAsStabilityCheck() {
-    maps_are_stable_ = true;
-    has_migration_target_ = false;
-    is_stability_check_ = true;
+    bit_field_ = MapsAreStableField::encode(true) |
+                 HasMigrationTargetField::encode(false) |
+                 IsStabilityCheckField::encode(true);
     ClearChangesFlag(kNewSpacePromotion);
     ClearDependsOnFlag(kElementsKind);
     ClearDependsOnFlag(kMaps);
@@ -2770,9 +2792,13 @@
   const UniqueSet<Map>* maps() const { return maps_; }
   void set_maps(const UniqueSet<Map>* maps) { maps_ = maps; }
 
-  bool maps_are_stable() const { return maps_are_stable_; }
+  bool maps_are_stable() const {
+    return MapsAreStableField::decode(bit_field_);
+  }
 
-  bool HasMigrationTarget() const { return has_migration_target_; }
+  bool HasMigrationTarget() const {
+    return HasMigrationTargetField::decode(bit_field_);
+  }
 
   virtual HValue* Canonicalize() OVERRIDE;
 
@@ -2804,9 +2830,11 @@
 
  private:
   HCheckMaps(HValue* value, const UniqueSet<Map>* maps, bool maps_are_stable)
-      : HTemplateInstruction<2>(HType::HeapObject()), maps_(maps),
-        has_migration_target_(false), is_stability_check_(false),
-        maps_are_stable_(maps_are_stable) {
+      : HTemplateInstruction<2>(HType::HeapObject()),
+        maps_(maps),
+        bit_field_(HasMigrationTargetField::encode(false) |
+                   IsStabilityCheckField::encode(false) |
+                   MapsAreStableField::encode(maps_are_stable)) {
     DCHECK_NE(0, maps->size());
     SetOperandAt(0, value);
     // Use the object value for the dependency.
@@ -2818,9 +2846,11 @@
   }
 
   HCheckMaps(HValue* value, const UniqueSet<Map>* maps, HValue* typecheck)
-      : HTemplateInstruction<2>(HType::HeapObject()), maps_(maps),
-        has_migration_target_(false), is_stability_check_(false),
-        maps_are_stable_(true) {
+      : HTemplateInstruction<2>(HType::HeapObject()),
+        maps_(maps),
+        bit_field_(HasMigrationTargetField::encode(false) |
+                   IsStabilityCheckField::encode(false) |
+                   MapsAreStableField::encode(true)) {
     DCHECK_NE(0, maps->size());
     SetOperandAt(0, value);
     // Use the object value for the dependency if NULL is passed.
@@ -2831,16 +2861,22 @@
     SetDependsOnFlag(kElementsKind);
     for (int i = 0; i < maps->size(); ++i) {
       Handle<Map> map = maps->at(i).handle();
-      if (map->is_migration_target()) has_migration_target_ = true;
-      if (!map->is_stable()) maps_are_stable_ = false;
+      if (map->is_migration_target()) {
+        bit_field_ = HasMigrationTargetField::update(bit_field_, true);
+      }
+      if (!map->is_stable()) {
+        bit_field_ = MapsAreStableField::update(bit_field_, false);
+      }
     }
-    if (has_migration_target_) SetChangesFlag(kNewSpacePromotion);
+    if (HasMigrationTarget()) SetChangesFlag(kNewSpacePromotion);
   }
 
+  class HasMigrationTargetField : public BitField<bool, 0, 1> {};
+  class IsStabilityCheckField : public BitField<bool, 1, 1> {};
+  class MapsAreStableField : public BitField<bool, 2, 1> {};
+
   const UniqueSet<Map>* maps_;
-  bool has_migration_target_ : 1;
-  bool is_stability_check_ : 1;
-  bool maps_are_stable_ : 1;
+  uint32_t bit_field_;
 };
 
 
@@ -3537,29 +3573,26 @@
           isolate->factory()->NewNumber(double_value_, TENURED));
     }
     AllowDeferredHandleDereference smi_check;
-    DCHECK(has_int32_value_ || !object_.handle()->IsSmi());
+    DCHECK(HasInteger32Value() || !object_.handle()->IsSmi());
     return object_.handle();
   }
 
   bool IsSpecialDouble() const {
-    return has_double_value_ &&
+    return HasDoubleValue() &&
            (bit_cast<int64_t>(double_value_) == bit_cast<int64_t>(-0.0) ||
             FixedDoubleArray::is_the_hole_nan(double_value_) ||
             std::isnan(double_value_));
   }
 
   bool NotInNewSpace() const {
-    return is_not_in_new_space_;
+    return IsNotInNewSpaceField::decode(bit_field_);
   }
 
   bool ImmortalImmovable() const;
 
   bool IsCell() const {
-    return instance_type_ == CELL_TYPE || instance_type_ == PROPERTY_CELL_TYPE;
-  }
-
-  bool IsMap() const {
-    return instance_type_ == MAP_TYPE;
+    InstanceType instance_type = GetInstanceType();
+    return instance_type == CELL_TYPE || instance_type == PROPERTY_CELL_TYPE;
   }
 
   virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
@@ -3579,13 +3612,17 @@
   HConstant* CopyToRepresentation(Representation r, Zone* zone) const;
   Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone);
   Maybe<HConstant*> CopyToTruncatedNumber(Zone* zone);
-  bool HasInteger32Value() const { return has_int32_value_; }
+  bool HasInteger32Value() const {
+    return HasInt32ValueField::decode(bit_field_);
+  }
   int32_t Integer32Value() const {
     DCHECK(HasInteger32Value());
     return int32_value_;
   }
-  bool HasSmiValue() const { return has_smi_value_; }
-  bool HasDoubleValue() const { return has_double_value_; }
+  bool HasSmiValue() const { return HasSmiValueField::decode(bit_field_); }
+  bool HasDoubleValue() const {
+    return HasDoubleValueField::decode(bit_field_);
+  }
   double DoubleValue() const {
     DCHECK(HasDoubleValue());
     return double_value_;
@@ -3597,7 +3634,7 @@
     return object_.IsInitialized() &&
            object_.IsKnownGlobal(isolate()->heap()->the_hole_value());
   }
-  bool HasNumberValue() const { return has_double_value_; }
+  bool HasNumberValue() const { return HasDoubleValue(); }
   int32_t NumberValueAsInteger32() const {
     DCHECK(HasNumberValue());
     // Irrespective of whether a numeric HConstant can be safely
@@ -3606,38 +3643,42 @@
     return int32_value_;
   }
   bool HasStringValue() const {
-    if (has_double_value_ || has_int32_value_) return false;
+    if (HasNumberValue()) return false;
     DCHECK(!object_.handle().is_null());
-    return instance_type_ < FIRST_NONSTRING_TYPE;
+    return GetInstanceType() < FIRST_NONSTRING_TYPE;
   }
   Handle<String> StringValue() const {
     DCHECK(HasStringValue());
     return Handle<String>::cast(object_.handle());
   }
   bool HasInternalizedStringValue() const {
-    return HasStringValue() && StringShape(instance_type_).IsInternalized();
+    return HasStringValue() && StringShape(GetInstanceType()).IsInternalized();
   }
 
   bool HasExternalReferenceValue() const {
-    return has_external_reference_value_;
+    return HasExternalReferenceValueField::decode(bit_field_);
   }
   ExternalReference ExternalReferenceValue() const {
     return external_reference_value_;
   }
 
   bool HasBooleanValue() const { return type_.IsBoolean(); }
-  bool BooleanValue() const { return boolean_value_; }
-  bool IsUndetectable() const { return is_undetectable_; }
-  InstanceType GetInstanceType() const { return instance_type_; }
+  bool BooleanValue() const { return BooleanValueField::decode(bit_field_); }
+  bool IsUndetectable() const {
+    return IsUndetectableField::decode(bit_field_);
+  }
+  InstanceType GetInstanceType() const {
+    return InstanceTypeField::decode(bit_field_);
+  }
 
-  bool HasMapValue() const { return instance_type_ == MAP_TYPE; }
+  bool HasMapValue() const { return GetInstanceType() == MAP_TYPE; }
   Unique<Map> MapValue() const {
     DCHECK(HasMapValue());
     return Unique<Map>::cast(GetUnique());
   }
   bool HasStableMapValue() const {
-    DCHECK(HasMapValue() || !has_stable_map_value_);
-    return has_stable_map_value_;
+    DCHECK(HasMapValue() || !HasStableMapValueField::decode(bit_field_));
+    return HasStableMapValueField::decode(bit_field_);
   }
 
   bool HasObjectMap() const { return !object_map_.IsNull(); }
@@ -3647,11 +3688,11 @@
   }
 
   virtual intptr_t Hashcode() OVERRIDE {
-    if (has_int32_value_) {
+    if (HasInteger32Value()) {
       return static_cast<intptr_t>(int32_value_);
-    } else if (has_double_value_) {
+    } else if (HasDoubleValue()) {
       return static_cast<intptr_t>(bit_cast<int64_t>(double_value_));
-    } else if (has_external_reference_value_) {
+    } else if (HasExternalReferenceValue()) {
       return reinterpret_cast<intptr_t>(external_reference_value_.address());
     } else {
       DCHECK(!object_.handle().is_null());
@@ -3660,7 +3701,7 @@
   }
 
   virtual void FinalizeUniqueness() OVERRIDE {
-    if (!has_double_value_ && !has_external_reference_value_) {
+    if (!HasDoubleValue() && !HasExternalReferenceValue()) {
       DCHECK(!object_.handle().is_null());
       object_ = Unique<Object>(object_.handle());
     }
@@ -3676,21 +3717,21 @@
 
   virtual bool DataEquals(HValue* other) OVERRIDE {
     HConstant* other_constant = HConstant::cast(other);
-    if (has_int32_value_) {
-      return other_constant->has_int32_value_ &&
-          int32_value_ == other_constant->int32_value_;
-    } else if (has_double_value_) {
-      return other_constant->has_double_value_ &&
+    if (HasInteger32Value()) {
+      return other_constant->HasInteger32Value() &&
+             int32_value_ == other_constant->int32_value_;
+    } else if (HasDoubleValue()) {
+      return other_constant->HasDoubleValue() &&
              bit_cast<int64_t>(double_value_) ==
                  bit_cast<int64_t>(other_constant->double_value_);
-    } else if (has_external_reference_value_) {
-      return other_constant->has_external_reference_value_ &&
-          external_reference_value_ ==
-          other_constant->external_reference_value_;
+    } else if (HasExternalReferenceValue()) {
+      return other_constant->HasExternalReferenceValue() &&
+             external_reference_value_ ==
+                 other_constant->external_reference_value_;
     } else {
-      if (other_constant->has_int32_value_ ||
-          other_constant->has_double_value_ ||
-          other_constant->has_external_reference_value_) {
+      if (other_constant->HasInteger32Value() ||
+          other_constant->HasDoubleValue() ||
+          other_constant->HasExternalReferenceValue()) {
         return false;
       }
       DCHECK(!object_.handle().is_null());
@@ -3735,6 +3776,25 @@
 
   virtual bool IsDeletable() const OVERRIDE { return true; }
 
+  // If object_ is a map, this indicates whether the map is stable.
+  class HasStableMapValueField : public BitField<bool, 0, 1> {};
+
+  // We store the HConstant in the most specific form safely possible.
+  // These flags tell us if the respective member fields hold valid, safe
+  // representations of the constant. More specific flags imply more general
+  // flags, but not the converse (i.e. smi => int32 => double).
+  class HasSmiValueField : public BitField<bool, 1, 1> {};
+  class HasInt32ValueField : public BitField<bool, 2, 1> {};
+  class HasDoubleValueField : public BitField<bool, 3, 1> {};
+
+  class HasExternalReferenceValueField : public BitField<bool, 4, 1> {};
+  class IsNotInNewSpaceField : public BitField<bool, 5, 1> {};
+  class BooleanValueField : public BitField<bool, 6, 1> {};
+  class IsUndetectableField : public BitField<bool, 7, 1> {};
+
+  static const InstanceType kUnknownInstanceType = FILLER_TYPE;
+  class InstanceTypeField : public BitField<InstanceType, 8, 8> {};
+
   // If this is a numerical constant, object_ either points to the
   // HeapObject the constant originated from or is null.  If the
   // constant is non-numeric, object_ always points to a valid
@@ -3744,27 +3804,11 @@
   // If object_ is a heap object, this points to the stable map of the object.
   Unique<Map> object_map_;
 
-  // If object_ is a map, this indicates whether the map is stable.
-  bool has_stable_map_value_ : 1;
+  uint32_t bit_field_;
 
-  // We store the HConstant in the most specific form safely possible.
-  // The two flags, has_int32_value_ and has_double_value_ tell us if
-  // int32_value_ and double_value_ hold valid, safe representations
-  // of the constant.  has_int32_value_ implies has_double_value_ but
-  // not the converse.
-  bool has_smi_value_ : 1;
-  bool has_int32_value_ : 1;
-  bool has_double_value_ : 1;
-  bool has_external_reference_value_ : 1;
-  bool is_not_in_new_space_ : 1;
-  bool boolean_value_ : 1;
-  bool is_undetectable_: 1;
   int32_t int32_value_;
   double double_value_;
   ExternalReference external_reference_value_;
-
-  static const InstanceType kUnknownInstanceType = FILLER_TYPE;
-  InstanceType instance_type_;
 };
 
 
@@ -5312,6 +5356,12 @@
     return Representation::None();
   }
 
+  virtual Representation KnownOptimalRepresentation() OVERRIDE {
+    // If a parameter is an input to a phi, that phi should not
+    // choose any more optimistic representation than Tagged.
+    return Representation::Tagged();
+  }
+
   DECLARE_CONCRETE_INSTRUCTION(Parameter)
 
  private:
@@ -6739,8 +6789,8 @@
     kStartIsDehoisted = kStartBaseOffset + kBitsForBaseOffset
   };
 
-  STATIC_ASSERT((kBitsForElementsKind + kBitsForBaseOffset +
-                 kBitsForIsDehoisted) <= sizeof(uint32_t)*8);
+  STATIC_ASSERT((kBitsForElementsKind + kBitsForHoleMode + kBitsForBaseOffset +
+                 kBitsForIsDehoisted) <= sizeof(uint32_t) * 8);
   STATIC_ASSERT(kElementsKindCount <= (1 << kBitsForElementsKind));
   class ElementsKindField:
     public BitField<ElementsKind, kStartElementsKind, kBitsForElementsKind>
@@ -6845,7 +6895,8 @@
       } else if (field_representation().IsDouble()) {
         return field_representation();
       } else if (field_representation().IsSmi()) {
-        if (SmiValuesAre32Bits() && store_mode_ == STORE_TO_INITIALIZED_ENTRY) {
+        if (SmiValuesAre32Bits() &&
+            store_mode() == STORE_TO_INITIALIZED_ENTRY) {
           return Representation::Integer32();
         }
         return field_representation();
@@ -6870,8 +6921,10 @@
 
   HObjectAccess access() const { return access_; }
   HValue* dominator() const { return dominator_; }
-  bool has_transition() const { return has_transition_; }
-  StoreFieldOrKeyedMode store_mode() const { return store_mode_; }
+  bool has_transition() const { return HasTransitionField::decode(bit_field_); }
+  StoreFieldOrKeyedMode store_mode() const {
+    return StoreModeField::decode(bit_field_);
+  }
 
   Handle<Map> transition_map() const {
     if (has_transition()) {
@@ -6885,7 +6938,7 @@
   void SetTransition(HConstant* transition) {
     DCHECK(!has_transition());  // Only set once.
     SetOperandAt(2, transition);
-    has_transition_ = true;
+    bit_field_ = HasTransitionField::update(bit_field_, true);
     SetChangesFlag(kMaps);
   }
 
@@ -6936,14 +6989,12 @@
   }
 
  private:
-  HStoreNamedField(HValue* obj,
-                   HObjectAccess access,
-                   HValue* val,
+  HStoreNamedField(HValue* obj, HObjectAccess access, HValue* val,
                    StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE)
       : access_(access),
         dominator_(NULL),
-        has_transition_(false),
-        store_mode_(store_mode) {
+        bit_field_(HasTransitionField::encode(false) |
+                   StoreModeField::encode(store_mode)) {
     // Stores to a non existing in-object property are allowed only to the
     // newly allocated objects (via HAllocate or HInnerAllocatedObject).
     DCHECK(!access.IsInobject() || access.existing_inobject_property() ||
@@ -6954,10 +7005,12 @@
     access.SetGVNFlags(this, STORE);
   }
 
+  class HasTransitionField : public BitField<bool, 0, 1> {};
+  class StoreModeField : public BitField<StoreFieldOrKeyedMode, 1, 1> {};
+
   HObjectAccess access_;
   HValue* dominator_;
-  bool has_transition_ : 1;
-  StoreFieldOrKeyedMode store_mode_ : 1;
+  uint32_t bit_field_;
 };
 
 
@@ -7024,7 +7077,7 @@
     }
 
     DCHECK_EQ(index, 2);
-    return RequiredValueRepresentation(elements_kind_, store_mode_);
+    return RequiredValueRepresentation(elements_kind(), store_mode());
   }
 
   static Representation RequiredValueRepresentation(
@@ -7065,7 +7118,8 @@
     if (IsUninitialized()) {
       return Representation::None();
     }
-    Representation r = RequiredValueRepresentation(elements_kind_, store_mode_);
+    Representation r =
+        RequiredValueRepresentation(elements_kind(), store_mode());
     // For fast object elements kinds, don't assume anything.
     if (r.IsTagged()) return Representation::None();
     return r;
@@ -7074,22 +7128,26 @@
   HValue* elements() const { return OperandAt(0); }
   HValue* key() const { return OperandAt(1); }
   HValue* value() const { return OperandAt(2); }
-  bool value_is_smi() const {
-    return IsFastSmiElementsKind(elements_kind_);
+  bool value_is_smi() const { return IsFastSmiElementsKind(elements_kind()); }
+  StoreFieldOrKeyedMode store_mode() const {
+    return StoreModeField::decode(bit_field_);
   }
-  StoreFieldOrKeyedMode store_mode() const { return store_mode_; }
-  ElementsKind elements_kind() const OVERRIDE { return elements_kind_; }
+  ElementsKind elements_kind() const OVERRIDE {
+    return ElementsKindField::decode(bit_field_);
+  }
   uint32_t base_offset() const { return base_offset_; }
   bool TryIncreaseBaseOffset(uint32_t increase_by_value) OVERRIDE;
   HValue* GetKey() OVERRIDE { return key(); }
   void SetKey(HValue* key) OVERRIDE { SetOperandAt(1, key); }
-  bool IsDehoisted() const OVERRIDE { return is_dehoisted_; }
-  void SetDehoisted(bool is_dehoisted) OVERRIDE {
-    is_dehoisted_ = is_dehoisted;
+  bool IsDehoisted() const OVERRIDE {
+    return IsDehoistedField::decode(bit_field_);
   }
-  bool IsUninitialized() { return is_uninitialized_; }
+  void SetDehoisted(bool is_dehoisted) OVERRIDE {
+    bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted);
+  }
+  bool IsUninitialized() { return IsUninitializedField::decode(bit_field_); }
   void SetUninitialized(bool is_uninitialized) {
-    is_uninitialized_ = is_uninitialized;
+    bit_field_ = IsUninitializedField::update(bit_field_, is_uninitialized);
   }
 
   bool IsConstantHoleStore() {
@@ -7125,18 +7183,17 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyed)
 
  private:
-  HStoreKeyed(HValue* obj, HValue* key, HValue* val,
-              ElementsKind elements_kind,
+  HStoreKeyed(HValue* obj, HValue* key, HValue* val, ElementsKind elements_kind,
               StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE,
               int offset = kDefaultKeyedHeaderOffsetSentinel)
-      : elements_kind_(elements_kind),
-      base_offset_(offset == kDefaultKeyedHeaderOffsetSentinel
-          ? GetDefaultHeaderSizeForElementsKind(elements_kind)
-          : offset),
-      is_dehoisted_(false),
-      is_uninitialized_(false),
-      store_mode_(store_mode),
-      dominator_(NULL) {
+      : base_offset_(offset == kDefaultKeyedHeaderOffsetSentinel
+                         ? GetDefaultHeaderSizeForElementsKind(elements_kind)
+                         : offset),
+        bit_field_(IsDehoistedField::encode(false) |
+                   IsUninitializedField::encode(false) |
+                   StoreModeField::encode(store_mode) |
+                   ElementsKindField::encode(elements_kind)),
+        dominator_(NULL) {
     SetOperandAt(0, obj);
     SetOperandAt(1, key);
     SetOperandAt(2, val);
@@ -7168,11 +7225,13 @@
     }
   }
 
-  ElementsKind elements_kind_;
+  class IsDehoistedField : public BitField<bool, 0, 1> {};
+  class IsUninitializedField : public BitField<bool, 1, 1> {};
+  class StoreModeField : public BitField<StoreFieldOrKeyedMode, 2, 1> {};
+  class ElementsKindField : public BitField<ElementsKind, 3, 5> {};
+
   uint32_t base_offset_;
-  bool is_dehoisted_ : 1;
-  bool is_uninitialized_ : 1;
-  StoreFieldOrKeyedMode store_mode_: 1;
+  uint32_t bit_field_;
   HValue* dominator_;
 };
 
@@ -7496,23 +7555,25 @@
   DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
 
   Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
-  bool pretenure() const { return pretenure_; }
-  bool has_no_literals() const { return has_no_literals_; }
-  bool is_arrow() const { return IsArrowFunction(kind_); }
-  bool is_generator() const { return IsGeneratorFunction(kind_); }
-  bool is_concise_method() const { return IsConciseMethod(kind_); }
-  FunctionKind kind() const { return kind_; }
-  StrictMode strict_mode() const { return strict_mode_; }
+  bool pretenure() const { return PretenureField::decode(bit_field_); }
+  bool has_no_literals() const {
+    return HasNoLiteralsField::decode(bit_field_);
+  }
+  bool is_arrow() const { return IsArrowFunction(kind()); }
+  bool is_generator() const { return IsGeneratorFunction(kind()); }
+  bool is_concise_method() const { return IsConciseMethod(kind()); }
+  FunctionKind kind() const { return FunctionKindField::decode(bit_field_); }
+  StrictMode strict_mode() const { return StrictModeField::decode(bit_field_); }
 
  private:
   HFunctionLiteral(HValue* context, Handle<SharedFunctionInfo> shared,
                    bool pretenure)
       : HTemplateInstruction<1>(HType::JSObject()),
         shared_info_(shared),
-        kind_(shared->kind()),
-        pretenure_(pretenure),
-        has_no_literals_(shared->num_literals() == 0),
-        strict_mode_(shared->strict_mode()) {
+        bit_field_(FunctionKindField::encode(shared->kind()) |
+                   PretenureField::encode(pretenure) |
+                   HasNoLiteralsField::encode(shared->num_literals() == 0) |
+                   StrictModeField::encode(shared->strict_mode())) {
     SetOperandAt(0, context);
     set_representation(Representation::Tagged());
     SetChangesFlag(kNewSpacePromotion);
@@ -7520,11 +7581,13 @@
 
   virtual bool IsDeletable() const OVERRIDE { return true; }
 
+  class FunctionKindField : public BitField<FunctionKind, 0, 3> {};
+  class PretenureField : public BitField<bool, 3, 1> {};
+  class HasNoLiteralsField : public BitField<bool, 4, 1> {};
+  class StrictModeField : public BitField<StrictMode, 5, 1> {};
+
   Handle<SharedFunctionInfo> shared_info_;
-  FunctionKind kind_;
-  bool pretenure_ : 1;
-  bool has_no_literals_ : 1;
-  StrictMode strict_mode_;
+  uint32_t bit_field_;
 };
 
 
diff --git a/src/profile-generator-inl.h b/src/profile-generator-inl.h
index 58c124f..b638857 100644
--- a/src/profile-generator-inl.h
+++ b/src/profile-generator-inl.h
@@ -10,14 +10,11 @@
 namespace v8 {
 namespace internal {
 
-CodeEntry::CodeEntry(Logger::LogEventsAndTags tag,
-                     const char* name,
-                     const char* name_prefix,
-                     const char* resource_name,
-                     int line_number,
-                     int column_number)
-    : tag_(tag),
-      builtin_id_(Builtins::builtin_count),
+CodeEntry::CodeEntry(Logger::LogEventsAndTags tag, const char* name,
+                     const char* name_prefix, const char* resource_name,
+                     int line_number, int column_number)
+    : bit_field_(TagField::encode(tag) |
+                 BuiltinIdField::encode(Builtins::builtin_count)),
       name_prefix_(name_prefix),
       name_(name),
       resource_name_(resource_name),
@@ -26,7 +23,7 @@
       shared_id_(0),
       script_id_(v8::UnboundScript::kNoScriptId),
       no_frame_ranges_(NULL),
-      bailout_reason_(kEmptyBailoutReason) { }
+      bailout_reason_(kEmptyBailoutReason) {}
 
 
 bool CodeEntry::is_js_function_tag(Logger::LogEventsAndTags tag) {
diff --git a/src/profile-generator.cc b/src/profile-generator.cc
index 6017f12..4607156 100644
--- a/src/profile-generator.cc
+++ b/src/profile-generator.cc
@@ -143,7 +143,7 @@
 
 
 uint32_t CodeEntry::GetCallUid() const {
-  uint32_t hash = ComputeIntegerHash(tag_, v8::internal::kZeroHashSeed);
+  uint32_t hash = ComputeIntegerHash(tag(), v8::internal::kZeroHashSeed);
   if (shared_id_ != 0) {
     hash ^= ComputeIntegerHash(static_cast<uint32_t>(shared_id_),
                                v8::internal::kZeroHashSeed);
@@ -164,20 +164,18 @@
 
 
 bool CodeEntry::IsSameAs(CodeEntry* entry) const {
-  return this == entry
-      || (tag_ == entry->tag_
-          && shared_id_ == entry->shared_id_
-          && (shared_id_ != 0
-              || (name_prefix_ == entry->name_prefix_
-                  && name_ == entry->name_
-                  && resource_name_ == entry->resource_name_
-                  && line_number_ == entry->line_number_)));
+  return this == entry ||
+         (tag() == entry->tag() && shared_id_ == entry->shared_id_ &&
+          (shared_id_ != 0 ||
+           (name_prefix_ == entry->name_prefix_ && name_ == entry->name_ &&
+            resource_name_ == entry->resource_name_ &&
+            line_number_ == entry->line_number_)));
 }
 
 
 void CodeEntry::SetBuiltinId(Builtins::Name id) {
-  tag_ = Logger::BUILTIN_TAG;
-  builtin_id_ = id;
+  bit_field_ = TagField::update(bit_field_, Logger::BUILTIN_TAG);
+  bit_field_ = BuiltinIdField::update(bit_field_, id);
 }
 
 
diff --git a/src/profile-generator.h b/src/profile-generator.h
index 5ebb92b..f78beb0 100644
--- a/src/profile-generator.h
+++ b/src/profile-generator.h
@@ -55,7 +55,7 @@
                    int column_number = v8::CpuProfileNode::kNoColumnNumberInfo);
   ~CodeEntry();
 
-  bool is_js_function() const { return is_js_function_tag(tag_); }
+  bool is_js_function() const { return is_js_function_tag(tag()); }
   const char* name_prefix() const { return name_prefix_; }
   bool has_name_prefix() const { return name_prefix_[0] != '\0'; }
   const char* name() const { return name_; }
@@ -78,7 +78,9 @@
   }
 
   void SetBuiltinId(Builtins::Name id);
-  Builtins::Name builtin_id() const { return builtin_id_; }
+  Builtins::Name builtin_id() const {
+    return BuiltinIdField::decode(bit_field_);
+  }
 
   uint32_t GetCallUid() const;
   bool IsSameAs(CodeEntry* entry) const;
@@ -88,8 +90,11 @@
   static const char* const kEmptyBailoutReason;
 
  private:
-  Logger::LogEventsAndTags tag_ : 8;
-  Builtins::Name builtin_id_ : 8;
+  class TagField : public BitField<Logger::LogEventsAndTags, 0, 8> {};
+  class BuiltinIdField : public BitField<Builtins::Name, 8, 8> {};
+  Logger::LogEventsAndTags tag() const { return TagField::decode(bit_field_); }
+
+  uint32_t bit_field_;
   const char* name_prefix_;
   const char* name_;
   const char* resource_name_;
diff --git a/src/runtime/runtime-array.cc b/src/runtime/runtime-array.cc
index c3a6d80..523d8f5 100644
--- a/src/runtime/runtime-array.cc
+++ b/src/runtime/runtime-array.cc
@@ -104,19 +104,19 @@
         storage_(Handle<FixedArray>::cast(
             isolate->global_handles()->Create(*storage))),
         index_offset_(0u),
-        fast_elements_(fast_elements),
-        exceeds_array_limit_(false) {}
+        bit_field_(FastElementsField::encode(fast_elements) |
+                   ExceedsLimitField::encode(false)) {}
 
   ~ArrayConcatVisitor() { clear_storage(); }
 
   void visit(uint32_t i, Handle<Object> elm) {
     if (i > JSObject::kMaxElementCount - index_offset_) {
-      exceeds_array_limit_ = true;
+      set_exceeds_array_limit(true);
       return;
     }
     uint32_t index = index_offset_ + i;
 
-    if (fast_elements_) {
+    if (fast_elements()) {
       if (index < static_cast<uint32_t>(storage_->length())) {
         storage_->set(index, *elm);
         return;
@@ -128,7 +128,7 @@
       SetDictionaryMode();
       // Fall-through to dictionary mode.
     }
-    DCHECK(!fast_elements_);
+    DCHECK(!fast_elements());
     Handle<SeededNumberDictionary> dict(
         SeededNumberDictionary::cast(*storage_));
     Handle<SeededNumberDictionary> result =
@@ -149,21 +149,23 @@
     // If the initial length estimate was off (see special case in visit()),
     // but the array blowing the limit didn't contain elements beyond the
     // provided-for index range, go to dictionary mode now.
-    if (fast_elements_ &&
+    if (fast_elements() &&
         index_offset_ >
             static_cast<uint32_t>(FixedArrayBase::cast(*storage_)->length())) {
       SetDictionaryMode();
     }
   }
 
-  bool exceeds_array_limit() { return exceeds_array_limit_; }
+  bool exceeds_array_limit() const {
+    return ExceedsLimitField::decode(bit_field_);
+  }
 
   Handle<JSArray> ToArray() {
     Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
     Handle<Object> length =
         isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
     Handle<Map> map = JSObject::GetElementsTransitionMap(
-        array, fast_elements_ ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS);
+        array, fast_elements() ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS);
     array->set_map(*map);
     array->set_length(*length);
     array->set_elements(*storage_);
@@ -173,7 +175,7 @@
  private:
   // Convert storage to dictionary mode.
   void SetDictionaryMode() {
-    DCHECK(fast_elements_);
+    DCHECK(fast_elements());
     Handle<FixedArray> current_storage(*storage_);
     Handle<SeededNumberDictionary> slow_storage(
         SeededNumberDictionary::New(isolate_, current_storage->length()));
@@ -191,7 +193,7 @@
     }
     clear_storage();
     set_storage(*slow_storage);
-    fast_elements_ = false;
+    set_fast_elements(false);
   }
 
   inline void clear_storage() {
@@ -203,13 +205,23 @@
         Handle<FixedArray>::cast(isolate_->global_handles()->Create(storage));
   }
 
+  class FastElementsField : public BitField<bool, 0, 1> {};
+  class ExceedsLimitField : public BitField<bool, 1, 1> {};
+
+  bool fast_elements() const { return FastElementsField::decode(bit_field_); }
+  void set_fast_elements(bool fast) {
+    bit_field_ = FastElementsField::update(bit_field_, fast);
+  }
+  void set_exceeds_array_limit(bool exceeds) {
+    bit_field_ = ExceedsLimitField::update(bit_field_, exceeds);
+  }
+
   Isolate* isolate_;
   Handle<FixedArray> storage_;  // Always a global handle.
   // Index after last seen index. Always less than or equal to
   // JSObject::kMaxElementCount.
   uint32_t index_offset_;
-  bool fast_elements_ : 1;
-  bool exceeds_array_limit_ : 1;
+  uint32_t bit_field_;
 };
 
 
diff --git a/src/scanner.cc b/src/scanner.cc
index 8062faa..e63239d 100644
--- a/src/scanner.cc
+++ b/src/scanner.cc
@@ -245,6 +245,8 @@
 
   while (true) {
     while (true) {
+      // The unicode cache accepts unsigned inputs.
+      if (c0_ < 0) break;
       // Advance as long as character is a WhiteSpace or LineTerminator.
       // Remember if the latter is the case.
       if (unicode_cache_->IsLineTerminator(c0_)) {
@@ -365,7 +367,7 @@
   while (c0_ >= 0) {
     uc32 ch = c0_;
     Advance();
-    if (unicode_cache_->IsLineTerminator(ch)) {
+    if (c0_ >= 0 && unicode_cache_->IsLineTerminator(ch)) {
       // Following ECMA-262, section 7.4, a comment containing
       // a newline will make the comment count as a line-terminator.
       has_multiline_comment_before_next_ = true;
@@ -625,14 +627,14 @@
         break;
 
       default:
-        if (unicode_cache_->IsIdentifierStart(c0_)) {
+        if (c0_ < 0) {
+          token = Token::EOS;
+        } else if (unicode_cache_->IsIdentifierStart(c0_)) {
           token = ScanIdentifierOrKeyword();
         } else if (IsDecimalDigit(c0_)) {
           token = ScanNumber(false);
         } else if (SkipWhiteSpace()) {
           token = Token::WHITESPACE;
-        } else if (c0_ < 0) {
-          token = Token::EOS;
         } else {
           token = Select(Token::ILLEGAL);
         }
@@ -674,7 +676,7 @@
   Advance();
 
   // Skip escaped newlines.
-  if (unicode_cache_->IsLineTerminator(c)) {
+  if (c0_ >= 0 && unicode_cache_->IsLineTerminator(c)) {
     // Allow CR+LF newlines in multiline string literals.
     if (IsCarriageReturn(c) && IsLineFeed(c0_)) Advance();
     // Allow LF+CR newlines in multiline string literals.
@@ -871,7 +873,8 @@
   // not be an identifier start or a decimal digit; see ECMA-262
   // section 7.8.3, page 17 (note that we read only one decimal digit
   // if the value is 0).
-  if (IsDecimalDigit(c0_) || unicode_cache_->IsIdentifierStart(c0_))
+  if (IsDecimalDigit(c0_) ||
+      (c0_ >= 0 && unicode_cache_->IsIdentifierStart(c0_)))
     return Token::ILLEGAL;
 
   literal.Complete();
@@ -1039,7 +1042,7 @@
   AddLiteralChar(first_char);
 
   // Scan the rest of the identifier characters.
-  while (unicode_cache_->IsIdentifierPart(c0_)) {
+  while (c0_ >= 0 && unicode_cache_->IsIdentifierPart(c0_)) {
     if (c0_ != '\\') {
       uc32 next_char = c0_;
       Advance();
@@ -1067,7 +1070,7 @@
 
 Token::Value Scanner::ScanIdentifierSuffix(LiteralScope* literal) {
   // Scan the rest of the identifier characters.
-  while (unicode_cache_->IsIdentifierPart(c0_)) {
+  while (c0_ >= 0 && unicode_cache_->IsIdentifierPart(c0_)) {
     if (c0_ == '\\') {
       uc32 c = ScanIdentifierUnicodeEscape();
       // Only allow legal identifier part characters.
@@ -1106,10 +1109,10 @@
   }
 
   while (c0_ != '/' || in_character_class) {
-    if (unicode_cache_->IsLineTerminator(c0_) || c0_ < 0) return false;
+    if (c0_ < 0 || unicode_cache_->IsLineTerminator(c0_)) return false;
     if (c0_ == '\\') {  // Escape sequence.
       AddLiteralCharAdvance();
-      if (unicode_cache_->IsLineTerminator(c0_) || c0_ < 0) return false;
+      if (c0_ < 0 || unicode_cache_->IsLineTerminator(c0_)) return false;
       AddLiteralCharAdvance();
       // If the escape allows more characters, i.e., \x??, \u????, or \c?,
       // only "safe" characters are allowed (letters, digits, underscore),
@@ -1156,7 +1159,7 @@
 bool Scanner::ScanRegExpFlags() {
   // Scan regular expression flags.
   LiteralScope literal(this);
-  while (unicode_cache_->IsIdentifierPart(c0_)) {
+  while (c0_ >= 0 && unicode_cache_->IsIdentifierPart(c0_)) {
     if (c0_ != '\\') {
       AddLiteralCharAdvance();
     } else {
diff --git a/src/unicode-inl.h b/src/unicode-inl.h
index d47ee3e..0f78d39 100644
--- a/src/unicode-inl.h
+++ b/src/unicode-inl.h
@@ -13,7 +13,7 @@
 
 template <class T, int s> bool Predicate<T, s>::get(uchar code_point) {
   CacheEntry entry = entries_[code_point & kMask];
-  if (entry.code_point_ == code_point) return entry.value_;
+  if (entry.code_point() == code_point) return entry.value();
   return CalculateValue(code_point);
 }
 
diff --git a/src/unicode.h b/src/unicode.h
index 1af6170..1666814 100644
--- a/src/unicode.h
+++ b/src/unicode.h
@@ -7,6 +7,7 @@
 
 #include <sys/types.h>
 #include "src/globals.h"
+#include "src/utils.h"
 /**
  * \file
  * Definitions and convenience functions for working with unicode.
@@ -28,16 +29,26 @@
  public:
   inline Predicate() { }
   inline bool get(uchar c);
+
  private:
   friend class Test;
   bool CalculateValue(uchar c);
-  struct CacheEntry {
-    inline CacheEntry() : code_point_(0), value_(0) { }
+  class CacheEntry {
+   public:
+    inline CacheEntry()
+        : bit_field_(CodePointField::encode(0) | ValueField::encode(0)) {}
     inline CacheEntry(uchar code_point, bool value)
-      : code_point_(code_point),
-        value_(value) { }
-    uchar code_point_ : 21;
-    bool value_ : 1;
+        : bit_field_(CodePointField::encode(code_point) |
+                     ValueField::encode(value)) {}
+
+    uchar code_point() const { return CodePointField::decode(bit_field_); }
+    bool value() const { return ValueField::decode(bit_field_); }
+
+   private:
+    class CodePointField : public v8::internal::BitField<uchar, 0, 21> {};
+    class ValueField : public v8::internal::BitField<bool, 21, 1> {};
+
+    uint32_t bit_field_;
   };
   static const int kSize = size;
   static const int kMask = kSize - 1;
diff --git a/src/utils.h b/src/utils.h
index dcefa44..d5685c9 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -230,6 +230,14 @@
 };
 
 
+template <class T, int shift, int size>
+class BitField8 : public BitFieldBase<T, shift, size, uint8_t> {};
+
+
+template <class T, int shift, int size>
+class BitField16 : public BitFieldBase<T, shift, size, uint16_t> {};
+
+
 template<class T, int shift, int size>
 class BitField : public BitFieldBase<T, shift, size, uint32_t> { };
 
diff --git a/src/version.cc b/src/version.cc
index c348bc0..6b9481c 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     30
-#define BUILD_NUMBER      35
+#define BUILD_NUMBER      36
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status
index 723f0e8..8bd03e6 100644
--- a/test/mjsunit/mjsunit.status
+++ b/test/mjsunit/mjsunit.status
@@ -202,7 +202,7 @@
   'math-floor-of-div-nosudiv': [PASS, SLOW, ['arch not in [arm, arm64, android_arm, android_arm64]', SKIP]],
 
   # Too slow for slow variants.
-  'asm/embenchen/*': [PASS, FAST_VARIANTS]
+  'asm/embenchen/*': [PASS, FAST_VARIANTS],
 }],  # ALWAYS
 
 ##############################################################################
@@ -245,6 +245,9 @@
   'math-floor-of-div': [PASS, NO_VARIANTS],
   'unicodelctest': [PASS, NO_VARIANTS],
   'unicodelctest-no-optimization': [PASS, NO_VARIANTS],
+
+  # Too slow for gc stress.
+  'asm/embenchen/box2d': [SKIP],
 }],  # 'gc_stress == True'
 
 ##############################################################################
@@ -296,6 +299,8 @@
   'array-reduce': [PASS, SLOW],
   'array-sort': [PASS, SLOW],
   'array-splice': [PASS, SLOW],
+  'asm/embenchen/box2d': [PASS, TIMEOUT],
+  'asm/embenchen/lua_binarytrees': [PASS, TIMEOUT],
   'bit-not': [PASS, SLOW],
   'compiler/alloc-number': [PASS, SLOW],
   'compiler/osr-assert': [PASS, SLOW],
diff --git a/test/mjsunit/regress/regress-assignment-in-test-context.js b/test/mjsunit/regress/regress-assignment-in-test-context.js
new file mode 100644
index 0000000..bc40985
--- /dev/null
+++ b/test/mjsunit/regress/regress-assignment-in-test-context.js
@@ -0,0 +1,20 @@
+// Copyright 2014 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.
+
+// Flags: --allow-natives-syntax --always-opt
+// Flags: --turbo-filter=* --turbo-deoptimization
+
+function assertEquals() {}
+
+function f(o) {
+  if (o.setterProperty = 0) {
+    return 1;
+  }
+  return 2;
+}
+
+function deopt() { %DeoptimizeFunction(f); }
+
+assertEquals(2,
+             f(Object.defineProperty({}, "setterProperty", { set: deopt })));
diff --git a/test/unittests/compiler/mips/instruction-selector-mips-unittest.cc b/test/unittests/compiler/mips/instruction-selector-mips-unittest.cc
index f5891d2..0b3a0f5 100644
--- a/test/unittests/compiler/mips/instruction-selector-mips-unittest.cc
+++ b/test/unittests/compiler/mips/instruction-selector-mips-unittest.cc
@@ -161,12 +161,12 @@
 const IntCmp kCmpInstructions[] = {
     {{&RawMachineAssembler::WordEqual, "WordEqual", kMipsCmp, kMachInt16}, 1U},
     {{&RawMachineAssembler::WordNotEqual, "WordNotEqual", kMipsCmp, kMachInt16},
-     2U},
+     1U},
     {{&RawMachineAssembler::Word32Equal, "Word32Equal", kMipsCmp, kMachInt32},
      1U},
     {{&RawMachineAssembler::Word32NotEqual, "Word32NotEqual", kMipsCmp,
       kMachInt32},
-     2U},
+     1U},
     {{&RawMachineAssembler::Int32LessThan, "Int32LessThan", kMipsCmp,
       kMachInt32},
      1U},
@@ -779,10 +779,9 @@
     m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0)));
     Stream s = m.Build();
     ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kMipsTst, s[0]->arch_opcode());
+    EXPECT_EQ(kMipsCmp, s[0]->arch_opcode());
     EXPECT_EQ(kMode_None, s[0]->addressing_mode());
     ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
     EXPECT_EQ(1U, s[0]->OutputCount());
     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
     EXPECT_EQ(kEqual, s[0]->flags_condition());
@@ -792,10 +791,9 @@
     m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0)));
     Stream s = m.Build();
     ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kMipsTst, s[0]->arch_opcode());
+    EXPECT_EQ(kMipsCmp, s[0]->arch_opcode());
     EXPECT_EQ(kMode_None, s[0]->addressing_mode());
     ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
     EXPECT_EQ(1U, s[0]->OutputCount());
     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
     EXPECT_EQ(kEqual, s[0]->flags_condition());
diff --git a/tools/push-to-trunk/merge_to_branch.py b/tools/push-to-trunk/merge_to_branch.py
index 927e504..da9d310 100755
--- a/tools/push-to-trunk/merge_to_branch.py
+++ b/tools/push-to-trunk/merge_to_branch.py
@@ -32,6 +32,9 @@
 
 from common_includes import *
 
+def IsSvnNumber(rev):
+  return rev.isdigit() and len(rev) < 8
+
 class Preparation(Step):
   MESSAGE = "Preparation."
 
@@ -72,24 +75,21 @@
         self._options.revisions))
     port_revision_list = []
     for revision in self["full_revision_list"]:
-      # Search for commits which matches the "Port rXXX" pattern.
+      # Search for commits which matches the "Port XXX" pattern.
       git_hashes = self.GitLog(reverse=True, format="%H",
-                               grep="Port r%d" % int(revision),
+                               grep="Port %s" % revision,
                                branch=self.vc.RemoteMasterBranch())
       for git_hash in git_hashes.splitlines():
-        svn_revision = self.vc.GitSvn(git_hash, self.vc.RemoteMasterBranch())
-        if not svn_revision:  # pragma: no cover
-          self.Die("Cannot determine svn revision for %s" % git_hash)
         revision_title = self.GitLog(n=1, format="%s", git_hash=git_hash)
 
         # Is this revision included in the original revision list?
-        if svn_revision in self["full_revision_list"]:
-          print("Found port of r%s -> r%s (already included): %s"
-                % (revision, svn_revision, revision_title))
+        if git_hash in self["full_revision_list"]:
+          print("Found port of %s -> %s (already included): %s"
+                % (revision, git_hash, revision_title))
         else:
-          print("Found port of r%s -> r%s: %s"
-                % (revision, svn_revision, revision_title))
-          port_revision_list.append(svn_revision)
+          print("Found port of %s -> %s: %s"
+                % (revision, git_hash, revision_title))
+          port_revision_list.append(git_hash)
 
     # Do we find any port?
     if len(port_revision_list) > 0:
@@ -99,16 +99,10 @@
         self["full_revision_list"].extend(port_revision_list)
 
 
-class FindGitRevisions(Step):
-  MESSAGE = "Find the git revisions associated with the patches."
+class CreateCommitMessage(Step):
+  MESSAGE = "Create commit message."
 
   def RunStep(self):
-    self["patch_commit_hashes"] = []
-    for revision in self["full_revision_list"]:
-      next_hash = self.vc.SvnGit(revision, self.vc.RemoteMasterBranch())
-      if not next_hash:  # pragma: no cover
-        self.Die("Cannot determine git hash for r%s" % revision)
-      self["patch_commit_hashes"].append(next_hash)
 
     # Stringify: [123, 234] -> "r123, r234"
     self["revision_list"] = ", ".join(map(lambda s: "r%s" % s,
@@ -117,29 +111,38 @@
     if not self["revision_list"]:  # pragma: no cover
       self.Die("Revision list is empty.")
 
-    # The commit message title is added below after the version is specified.
-    self["new_commit_msg"] = ""
+    if self._options.revert and not self._options.revert_bleeding_edge:
+      action_text = "Rollback of %s"
+    else:
+      action_text = "Merged %s"
 
-    for commit_hash in self["patch_commit_hashes"]:
+    # The commit message title is added below after the version is specified.
+    msg_pieces = [
+      "\n".join(action_text % s for s in self["full_revision_list"]),
+    ]
+    msg_pieces.append("\n\n")
+
+    for commit_hash in self["full_revision_list"]:
       patch_merge_desc = self.GitLog(n=1, format="%s", git_hash=commit_hash)
-      self["new_commit_msg"] += "%s\n\n" % patch_merge_desc
+      msg_pieces.append("%s\n\n" % patch_merge_desc)
 
     bugs = []
-    for commit_hash in self["patch_commit_hashes"]:
+    for commit_hash in self["full_revision_list"]:
       msg = self.GitLog(n=1, git_hash=commit_hash)
-      for bug in re.findall(r"^[ \t]*BUG[ \t]*=[ \t]*(.*?)[ \t]*$", msg,
-                            re.M):
-        bugs.extend(map(lambda s: s.strip(), bug.split(",")))
+      for bug in re.findall(r"^[ \t]*BUG[ \t]*=[ \t]*(.*?)[ \t]*$", msg, re.M):
+        bugs.extend(s.strip() for s in bug.split(","))
     bug_aggregate = ",".join(sorted(filter(lambda s: s and s != "none", bugs)))
     if bug_aggregate:
-      self["new_commit_msg"] += "BUG=%s\nLOG=N\n" % bug_aggregate
+      msg_pieces.append("BUG=%s\nLOG=N\n" % bug_aggregate)
+
+    self["new_commit_msg"] = "".join(msg_pieces)
 
 
 class ApplyPatches(Step):
   MESSAGE = "Apply patches for selected revisions."
 
   def RunStep(self):
-    for commit_hash in self["patch_commit_hashes"]:
+    for commit_hash in self["full_revision_list"]:
       print("Applying patch for %s to %s..."
             % (commit_hash, self["merge_to_branch"]))
       patch = self.GitGetPatch(commit_hash)
@@ -189,17 +192,14 @@
 
   def RunStep(self):
     # Add a commit message title.
-    if self._options.revert:
-      if not self._options.revert_bleeding_edge:
-        title = ("Version %s (rollback of %s)"
-                 % (self["version"], self["revision_list"]))
-      else:
-        title = "Revert %s." % self["revision_list"]
+    if self._options.revert and self._options.revert_bleeding_edge:
+      # TODO(machenbach): Find a better convention if multiple patches are
+      # reverted in one CL.
+      self["commit_title"] = "Revert on master"
     else:
-      title = ("Version %s (merged %s)"
-               % (self["version"], self["revision_list"]))
-    self["commit_title"] = title
-    self["new_commit_msg"] = "%s\n\n%s" % (title, self["new_commit_msg"])
+      self["commit_title"] = "Version %s (cherry-pick)" % self["version"]
+    self["new_commit_msg"] = "%s\n\n%s" % (self["commit_title"],
+                                           self["new_commit_msg"])
     TextToFile(self["new_commit_msg"], self.Config("COMMITMSG_FILE"))
     self.GitCommit(file_name=self.Config("COMMITMSG_FILE"))
 
@@ -275,6 +275,17 @@
     options.bypass_upload_hooks = True
     # CC ulan to make sure that fixes are merged to Google3.
     options.cc = "ulan@chromium.org"
+
+    # Thd old git-svn workflow is deprecated for this script.
+    assert options.vc_interface != "git_svn"
+
+    # Make sure to use git hashes in the new workflows.
+    for revision in options.revisions:
+      if (IsSvnNumber(revision) or
+          (revision[0:1] == "r" and IsSvnNumber(revision[1:]))):
+        print "Please provide full git hashes of the patches to merge."
+        print "Got: %s" % revision
+        return False
     return True
 
   def _Config(self):
@@ -292,7 +303,7 @@
       Preparation,
       CreateBranch,
       SearchArchitecturePorts,
-      FindGitRevisions,
+      CreateCommitMessage,
       ApplyPatches,
       PrepareVersion,
       IncrementVersion,
diff --git a/tools/push-to-trunk/releases.py b/tools/push-to-trunk/releases.py
index 53648a6..2090c00 100755
--- a/tools/push-to-trunk/releases.py
+++ b/tools/push-to-trunk/releases.py
@@ -33,10 +33,18 @@
 # (old and new format).
 MERGE_MESSAGE_RE = re.compile(r"^.*[M|m]erged (.+)(\)| into).*$", re.M)
 
+CHERRY_PICK_TITLE_GIT_RE = re.compile(r"^.* \(cherry\-pick\)\.?$")
+
+# New git message for cherry-picked CLs. One message per line.
+MERGE_MESSAGE_GIT_RE = re.compile(r"^Merged ([a-fA-F0-9]+)\.?$")
+
 # Expression for retrieving reverted patches from a commit message (old and
 # new format).
 ROLLBACK_MESSAGE_RE = re.compile(r"^.*[R|r]ollback of (.+)(\)| in).*$", re.M)
 
+# New git message for reverted CLs. One message per line.
+ROLLBACK_MESSAGE_GIT_RE = re.compile(r"^Rollback of ([a-fA-F0-9]+)\.?$")
+
 # Expression for retrieving the code review link.
 REVIEW_LINK_RE = re.compile(r"^Review URL: (.+)$", re.M)
 
@@ -143,6 +151,18 @@
         patches = "-%s" % patches
     return patches
 
+  def GetMergedPatchesGit(self, body):
+    patches = []
+    for line in body.splitlines():
+      patch = MatchSafe(MERGE_MESSAGE_GIT_RE.match(line))
+      if patch:
+        patches.append(patch)
+      patch = MatchSafe(ROLLBACK_MESSAGE_GIT_RE.match(line))
+      if patch:
+        patches.append("-%s" % patch)
+    return ", ".join(patches)
+
+
   def GetReleaseDict(
       self, git_hash, bleeding_edge_rev, bleeding_edge_git, branch, version,
       patches, cl_body):
@@ -185,7 +205,10 @@
     patches = ""
     if self["patch"] != "0":
       version += ".%s" % self["patch"]
-      patches = self.GetMergedPatches(body)
+      if CHERRY_PICK_TITLE_GIT_RE.match(body.splitlines()[0]):
+        patches = self.GetMergedPatchesGit(body)
+      else:
+        patches = self.GetMergedPatches(body)
 
     title = self.GitLog(n=1, format="%s", git_hash=git_hash)
     bleeding_edge_revision = self.GetBleedingEdgeFromPush(title)
diff --git a/tools/push-to-trunk/test_scripts.py b/tools/push-to-trunk/test_scripts.py
index f31c491..41cc97f 100644
--- a/tools/push-to-trunk/test_scripts.py
+++ b/tools/push-to-trunk/test_scripts.py
@@ -503,7 +503,7 @@
       Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
     ])
     args = ["--branch", "candidates", "--vc-interface", "git_read_svn_write",
-            "12345"]
+            "ab12345"]
     self._state["version"] = "tag_name"
     self._state["commit_title"] = "Title"
     self.assertRaises(Exception,
@@ -1225,137 +1225,13 @@
       return lambda: self.assertEquals(patch,
           FileToText(TEST_CONFIG["TEMPORARY_PATCH_FILE"]))
 
-    msg = """Version 3.22.5.1 (merged r12345, r23456, r34567, r45678, r56789)
+    msg = """Version 3.22.5.1 (cherry-pick)
 
-Title4
-
-Title2
-
-Title3
-
-Title1
-
-Revert "Something"
-
-BUG=123,234,345,456,567,v8:123
-LOG=N
-"""
-
-    def VerifySVNCommit():
-      commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"])
-      self.assertEquals(msg, commit)
-      version = FileToText(
-          os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE))
-      self.assertTrue(re.search(r"#define MINOR_VERSION\s+22", version))
-      self.assertTrue(re.search(r"#define BUILD_NUMBER\s+5", version))
-      self.assertTrue(re.search(r"#define PATCH_LEVEL\s+1", version))
-      self.assertTrue(re.search(r"#define IS_CANDIDATE_VERSION\s+0", version))
-
-    self.Expect([
-      Cmd("git status -s -uno", ""),
-      Cmd("git status -s -b -uno", "## some_branch\n"),
-      Cmd("git svn fetch", ""),
-      Cmd("git branch", "  branch1\n* branch2\n"),
-      Cmd("git new-branch %s --upstream svn/trunk" % TEST_CONFIG["BRANCHNAME"],
-          ""),
-      Cmd(("git log --format=%H --grep=\"Port r12345\" "
-           "--reverse svn/bleeding_edge"),
-          "hash1\nhash2"),
-      Cmd("git svn find-rev hash1 svn/bleeding_edge", "45678"),
-      Cmd("git log -1 --format=%s hash1", "Title1"),
-      Cmd("git svn find-rev hash2 svn/bleeding_edge", "23456"),
-      Cmd("git log -1 --format=%s hash2", "Title2"),
-      Cmd(("git log --format=%H --grep=\"Port r23456\" "
-           "--reverse svn/bleeding_edge"),
-          ""),
-      Cmd(("git log --format=%H --grep=\"Port r34567\" "
-           "--reverse svn/bleeding_edge"),
-          "hash3"),
-      Cmd("git svn find-rev hash3 svn/bleeding_edge", "56789"),
-      Cmd("git log -1 --format=%s hash3", "Title3"),
-      RL("Y"),  # Automatically add corresponding ports (34567, 56789)?
-      Cmd("git svn find-rev r12345 svn/bleeding_edge", "hash4"),
-      # Simulate svn being down which stops the script.
-      Cmd("git svn find-rev r23456 svn/bleeding_edge", None),
-      # Restart script in the failing step.
-      Cmd("git svn find-rev r12345 svn/bleeding_edge", "hash4"),
-      Cmd("git svn find-rev r23456 svn/bleeding_edge", "hash2"),
-      Cmd("git svn find-rev r34567 svn/bleeding_edge", "hash3"),
-      Cmd("git svn find-rev r45678 svn/bleeding_edge", "hash1"),
-      Cmd("git svn find-rev r56789 svn/bleeding_edge", "hash5"),
-      Cmd("git log -1 --format=%s hash4", "Title4"),
-      Cmd("git log -1 --format=%s hash2", "Title2"),
-      Cmd("git log -1 --format=%s hash3", "Title3"),
-      Cmd("git log -1 --format=%s hash1", "Title1"),
-      Cmd("git log -1 --format=%s hash5", "Revert \"Something\""),
-      Cmd("git log -1 hash4", "Title4\nBUG=123\nBUG=234"),
-      Cmd("git log -1 hash2", "Title2\n BUG = v8:123,345"),
-      Cmd("git log -1 hash3", "Title3\nLOG=n\nBUG=567, 456"),
-      Cmd("git log -1 hash1", "Title1\nBUG="),
-      Cmd("git log -1 hash5", "Revert \"Something\"\nBUG=none"),
-      Cmd("git log -1 -p hash4", "patch4"),
-      Cmd(("git apply --index --reject \"%s\"" %
-           TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
-          "", cb=VerifyPatch("patch4")),
-      Cmd("git log -1 -p hash2", "patch2"),
-      Cmd(("git apply --index --reject \"%s\"" %
-           TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
-          "", cb=VerifyPatch("patch2")),
-      Cmd("git log -1 -p hash3", "patch3"),
-      Cmd(("git apply --index --reject \"%s\"" %
-           TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
-          "", cb=VerifyPatch("patch3")),
-      Cmd("git log -1 -p hash1", "patch1"),
-      Cmd(("git apply --index --reject \"%s\"" %
-           TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
-          "", cb=VerifyPatch("patch1")),
-      Cmd("git log -1 -p hash5", "patch5\n"),
-      Cmd(("git apply --index --reject \"%s\"" %
-           TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
-          "", cb=VerifyPatch("patch5\n")),
-      Cmd("git apply --index --reject \"%s\"" % extra_patch, ""),
-      RL("Y"),  # Automatically increment patch level?
-      Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], ""),
-      RL("reviewer@chromium.org"),  # V8 reviewer.
-      Cmd("git cl upload --send-mail -r \"reviewer@chromium.org\" "
-          "--bypass-hooks --cc \"ulan@chromium.org\"", ""),
-      Cmd("git checkout -f %s" % TEST_CONFIG["BRANCHNAME"], ""),
-      RL("LGTM"),  # Enter LGTM for V8 CL.
-      Cmd("git cl presubmit", "Presubmit successfull\n"),
-      Cmd("git cl dcommit -f --bypass-hooks", "Closing issue\n",
-          cb=VerifySVNCommit),
-      Cmd("git svn fetch", ""),
-      Cmd("git rebase svn/trunk", ""),
-      Cmd("git svn tag 3.22.5.1 -m \"Tagging version 3.22.5.1\"", ""),
-      Cmd("git checkout -f some_branch", ""),
-      Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
-    ])
-
-    # r12345 and r34567 are patches. r23456 (included) and r45678 are the MIPS
-    # ports of r12345. r56789 is the MIPS port of r34567.
-    args = ["-f", "-p", extra_patch, "--branch", "trunk",
-            "--vc-interface", "git_svn", "12345", "23456", "34567"]
-
-    # The first run of the script stops because of the svn being down.
-    self.assertRaises(GitFailedException,
-        lambda: MergeToBranch(TEST_CONFIG, self).Run(args))
-
-    # Test that state recovery after restarting the script works.
-    args += ["-s", "4"]
-    MergeToBranch(TEST_CONFIG, self).Run(args)
-
-  def testMergeToBranchNewGit(self):
-    TEST_CONFIG["ALREADY_MERGING_SENTINEL_FILE"] = self.MakeEmptyTempFile()
-    TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
-    self.WriteFakeVersionFile(build=5)
-    os.environ["EDITOR"] = "vi"
-    extra_patch = self.MakeEmptyTempFile()
-
-    def VerifyPatch(patch):
-      return lambda: self.assertEquals(patch,
-          FileToText(TEST_CONFIG["TEMPORARY_PATCH_FILE"]))
-
-    msg = """Version 3.22.5.1 (merged r12345, r23456, r34567, r45678, r56789)
+Merged ab12345
+Merged ab23456
+Merged ab34567
+Merged ab45678
+Merged ab56789
 
 Title4
 
@@ -1389,59 +1265,49 @@
       Cmd("git branch", "  branch1\n* branch2\n"),
       Cmd("git new-branch %s --upstream origin/candidates" %
           TEST_CONFIG["BRANCHNAME"], ""),
-      Cmd(("git log --format=%H --grep=\"Port r12345\" "
+      Cmd(("git log --format=%H --grep=\"Port ab12345\" "
            "--reverse origin/master"),
-          "hash1\nhash2"),
-      Cmd("git svn find-rev hash1 origin/master", "45678"),
-      Cmd("git log -1 --format=%s hash1", "Title1"),
-      Cmd("git svn find-rev hash2 origin/master", "23456"),
-      Cmd("git log -1 --format=%s hash2", "Title2"),
-      Cmd(("git log --format=%H --grep=\"Port r23456\" "
+          "ab45678\nab23456"),
+      Cmd("git log -1 --format=%s ab45678", "Title1"),
+      Cmd("git log -1 --format=%s ab23456", "Title2"),
+      Cmd(("git log --format=%H --grep=\"Port ab23456\" "
            "--reverse origin/master"),
           ""),
-      Cmd(("git log --format=%H --grep=\"Port r34567\" "
+      Cmd(("git log --format=%H --grep=\"Port ab34567\" "
            "--reverse origin/master"),
-          "hash3"),
-      Cmd("git svn find-rev hash3 origin/master", "56789"),
-      Cmd("git log -1 --format=%s hash3", "Title3"),
-      RL("Y"),  # Automatically add corresponding ports (34567, 56789)?
-      Cmd("git svn find-rev r12345 origin/master",
-          "Partial-rebuilding bla\nDone rebuilding blub\nhash4"),
-      # Simulate svn being down which stops the script.
-      Cmd("git svn find-rev r23456 origin/master", None),
+          "ab56789"),
+      Cmd("git log -1 --format=%s ab56789", "Title3"),
+      RL("Y"),  # Automatically add corresponding ports (ab34567, ab56789)?
+      # Simulate git being down which stops the script.
+      Cmd("git log -1 --format=%s ab12345", None),
       # Restart script in the failing step.
-      Cmd("git svn find-rev r12345 origin/master", "hash4"),
-      Cmd("git svn find-rev r23456 origin/master", "hash2"),
-      Cmd("git svn find-rev r34567 origin/master", "hash3"),
-      Cmd("git svn find-rev r45678 origin/master", "hash1"),
-      Cmd("git svn find-rev r56789 origin/master", "hash5"),
-      Cmd("git log -1 --format=%s hash4", "Title4"),
-      Cmd("git log -1 --format=%s hash2", "Title2"),
-      Cmd("git log -1 --format=%s hash3", "Title3"),
-      Cmd("git log -1 --format=%s hash1", "Title1"),
-      Cmd("git log -1 --format=%s hash5", "Revert \"Something\""),
-      Cmd("git log -1 hash4", "Title4\nBUG=123\nBUG=234"),
-      Cmd("git log -1 hash2", "Title2\n BUG = v8:123,345"),
-      Cmd("git log -1 hash3", "Title3\nLOG=n\nBUG=567, 456"),
-      Cmd("git log -1 hash1", "Title1\nBUG="),
-      Cmd("git log -1 hash5", "Revert \"Something\"\nBUG=none"),
-      Cmd("git log -1 -p hash4", "patch4"),
+      Cmd("git log -1 --format=%s ab12345", "Title4"),
+      Cmd("git log -1 --format=%s ab23456", "Title2"),
+      Cmd("git log -1 --format=%s ab34567", "Title3"),
+      Cmd("git log -1 --format=%s ab45678", "Title1"),
+      Cmd("git log -1 --format=%s ab56789", "Revert \"Something\""),
+      Cmd("git log -1 ab12345", "Title4\nBUG=123\nBUG=234"),
+      Cmd("git log -1 ab23456", "Title2\n BUG = v8:123,345"),
+      Cmd("git log -1 ab34567", "Title3\nLOG=n\nBUG=567, 456"),
+      Cmd("git log -1 ab45678", "Title1\nBUG="),
+      Cmd("git log -1 ab56789", "Revert \"Something\"\nBUG=none"),
+      Cmd("git log -1 -p ab12345", "patch4"),
       Cmd(("git apply --index --reject \"%s\"" %
            TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
           "", cb=VerifyPatch("patch4")),
-      Cmd("git log -1 -p hash2", "patch2"),
+      Cmd("git log -1 -p ab23456", "patch2"),
       Cmd(("git apply --index --reject \"%s\"" %
            TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
           "", cb=VerifyPatch("patch2")),
-      Cmd("git log -1 -p hash3", "patch3"),
+      Cmd("git log -1 -p ab34567", "patch3"),
       Cmd(("git apply --index --reject \"%s\"" %
            TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
           "", cb=VerifyPatch("patch3")),
-      Cmd("git log -1 -p hash1", "patch1"),
+      Cmd("git log -1 -p ab45678", "patch1"),
       Cmd(("git apply --index --reject \"%s\"" %
            TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
           "", cb=VerifyPatch("patch1")),
-      Cmd("git log -1 -p hash5", "patch5\n"),
+      Cmd("git log -1 -p ab56789", "patch5\n"),
       Cmd(("git apply --index --reject \"%s\"" %
            TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
           "", cb=VerifyPatch("patch5\n")),
@@ -1458,12 +1324,12 @@
           cb=VerifySVNCommit),
       Cmd("git fetch", ""),
       Cmd("git log -1 --format=%H --grep=\""
-          "Version 3.22.5.1 (merged r12345, r23456, r34567, r45678, r56789)"
+          "Version 3.22.5.1 (cherry-pick)"
           "\" origin/candidates",
           ""),
       Cmd("git fetch", ""),
       Cmd("git log -1 --format=%H --grep=\""
-          "Version 3.22.5.1 (merged r12345, r23456, r34567, r45678, r56789)"
+          "Version 3.22.5.1 (cherry-pick)"
           "\" origin/candidates",
           "hsh_to_tag"),
       Cmd("git tag 3.22.5.1 hsh_to_tag", ""),
@@ -1472,12 +1338,12 @@
       Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
     ])
 
-    # r12345 and r34567 are patches. r23456 (included) and r45678 are the MIPS
-    # ports of r12345. r56789 is the MIPS port of r34567.
+    # ab12345 and ab34567 are patches. ab23456 (included) and ab45678 are the
+    # MIPS ports of ab12345. ab56789 is the MIPS port of ab34567.
     args = ["-f", "-p", extra_patch, "--branch", "candidates",
-            "--vc-interface", "git_read_svn_write", "12345", "23456", "34567"]
+            "ab12345", "ab23456", "ab34567"]
 
-    # The first run of the script stops because of the svn being down.
+    # The first run of the script stops because of git being down.
     self.assertRaises(GitFailedException,
         lambda: MergeToBranch(TEST_CONFIG, self).Run(args))
 
@@ -1569,7 +1435,9 @@
       Cmd("git checkout -f hash_234 -- %s" % VERSION_FILE, "",
           cb=ResetVersion(3, 1, 1)),
       Cmd("git log -1 --format=%B hash_234",
-          "Version 3.3.1.1 (merged 12)\n\nReview URL: fake.com\n"),
+          "Version 3.3.1.1 (cherry-pick).\n\n"
+          "Merged abc12.\n\n"
+          "Review URL: fake.com\n"),
       Cmd("git log -1 --format=%s hash_234", ""),
       Cmd("git svn find-rev hash_234", "234"),
       Cmd("git log -1 --format=%ci hash_234", "18:15"),
@@ -1655,7 +1523,7 @@
            "3.28.40,master,22624,4567,\r\n"
            "3.22.3,candidates,345,3456:4566,\r\n"
            "3.21.2,3.21,123,,\r\n"
-           "3.3.1.1,3.3,234,,12\r\n")
+           "3.3.1.1,3.3,234,,abc12\r\n")
     self.assertEquals(csv, FileToText(csv_output))
 
     expected_json = [
@@ -1718,7 +1586,7 @@
       {
         "revision": "234",
         "revision_git": "hash_234",
-        "patches_merged": "12",
+        "patches_merged": "abc12",
         "bleeding_edge": "",
         "bleeding_edge_git": "",
         "version": "3.3.1.1",
diff --git a/tools/run-tests.py b/tools/run-tests.py
index dc73a40..20f3679 100755
--- a/tools/run-tests.py
+++ b/tools/run-tests.py
@@ -44,6 +44,7 @@
 from testrunner.local import execution
 from testrunner.local import progress
 from testrunner.local import testsuite
+from testrunner.local.testsuite import VARIANT_FLAGS
 from testrunner.local import utils
 from testrunner.local import verbose
 from testrunner.network import network_execution
@@ -83,13 +84,6 @@
 TIMEOUT_SCALEFACTOR = {"debug"   : 4,
                        "release" : 1 }
 
-# Use this to run several variants of the tests.
-VARIANT_FLAGS = {
-    "default": [],
-    "stress": ["--stress-opt", "--always-opt"],
-    "turbofan": ["--turbo-asm", "--turbo-filter=*", "--always-opt"],
-    "nocrankshaft": ["--nocrankshaft"]}
-
 VARIANTS = ["default", "stress", "turbofan", "nocrankshaft"]
 
 MODE_FLAGS = {
diff --git a/tools/testrunner/local/testsuite.py b/tools/testrunner/local/testsuite.py
index 24161f3..6ff97b3 100644
--- a/tools/testrunner/local/testsuite.py
+++ b/tools/testrunner/local/testsuite.py
@@ -34,6 +34,17 @@
 from . import utils
 from ..objects import testcase
 
+# Use this to run several variants of the tests.
+VARIANT_FLAGS = {
+    "default": [],
+    "stress": ["--stress-opt", "--always-opt"],
+    "turbofan": ["--turbo-asm", "--turbo-filter=*", "--always-opt"],
+    "nocrankshaft": ["--nocrankshaft"]}
+
+FAST_VARIANT_FLAGS = [
+    f for v, f in VARIANT_FLAGS.iteritems() if v in ["default", "turbofan"]
+]
+
 class TestSuite(object):
 
   @staticmethod
@@ -82,7 +93,7 @@
     if testcase.outcomes and statusfile.OnlyStandardVariant(testcase.outcomes):
       return [[]]
     if testcase.outcomes and statusfile.OnlyFastVariants(testcase.outcomes):
-      return filter(lambda v: v in ["default", "turbofan"], default_flags)
+      return filter(lambda flags: flags in FAST_VARIANT_FLAGS, default_flags)
     return default_flags
 
   def DownloadData(self):
diff --git a/tools/whitespace.txt b/tools/whitespace.txt
index 19a7325..55592a9 100644
--- a/tools/whitespace.txt
+++ b/tools/whitespace.txt
@@ -5,4 +5,4 @@
 A Smi walks into a bar and says:
 "I'm so deoptimized today!"
 The doubles heard this and started to unbox.
-The Smi looked at them when a crazy v8-autoroll account showed up.......
+The Smi looked at them when a crazy v8-autoroll account showed up........