| Index: src/objects.h
 | 
| diff --git a/src/objects.h b/src/objects.h
 | 
| index 93f57333a150498810f73f264c74082e2147ff3b..12f220f144c2214e1b7695d0c749ae64cad55f17 100644
 | 
| --- a/src/objects.h
 | 
| +++ b/src/objects.h
 | 
| @@ -1555,15 +1555,35 @@ class HeapObject: public Object {
 | 
|      return reinterpret_cast<Address>(this) - kHeapObjectTag;
 | 
|    }
 | 
|  
 | 
| -  // Iterates over pointers contained in the object (including the Map)
 | 
| +  // Iterates over pointers contained in the object (including the Map).
 | 
| +  // If it's not performance critical iteration use the non-templatized
 | 
| +  // version.
 | 
|    void Iterate(ObjectVisitor* v);
 | 
|  
 | 
| +  template <typename ObjectVisitor>
 | 
| +  inline void IterateFast(ObjectVisitor* v);
 | 
| +
 | 
|    // Iterates over all pointers contained in the object except the
 | 
|    // first map pointer.  The object type is given in the first
 | 
|    // parameter. This function does not access the map pointer in the
 | 
|    // object, and so is safe to call while the map pointer is modified.
 | 
| +  // If it's not performance critical iteration use the non-templatized
 | 
| +  // version.
 | 
| +  void IterateBody(ObjectVisitor* v);
 | 
|    void IterateBody(InstanceType type, int object_size, ObjectVisitor* v);
 | 
|  
 | 
| +  template <typename ObjectVisitor>
 | 
| +  inline void IterateBodyFast(ObjectVisitor* v);
 | 
| +
 | 
| +  template <typename ObjectVisitor>
 | 
| +  inline void IterateBodyFast(InstanceType type, int object_size,
 | 
| +                              ObjectVisitor* v);
 | 
| +
 | 
| +  // Returns true if the object contains a tagged value at given offset.
 | 
| +  // It is used for invalid slots filtering. If the offset points outside
 | 
| +  // of the object or to the map word, the result is UNDEFINED (!!!).
 | 
| +  bool IsValidSlot(int offset);
 | 
| +
 | 
|    // Returns the heap object's size in bytes
 | 
|    inline int Size();
 | 
|  
 | 
| @@ -1623,90 +1643,17 @@ class HeapObject: public Object {
 | 
|  
 | 
|    STATIC_ASSERT(kMapOffset == Internals::kHeapObjectMapOffset);
 | 
|  
 | 
| - protected:
 | 
| -  // helpers for calling an ObjectVisitor to iterate over pointers in the
 | 
| -  // half-open range [start, end) specified as integer offsets
 | 
| -  inline void IteratePointers(ObjectVisitor* v, int start, int end);
 | 
| -  // as above, for the single element at "offset"
 | 
| -  inline void IteratePointer(ObjectVisitor* v, int offset);
 | 
| -  // as above, for the next code link of a code object.
 | 
| -  inline void IterateNextCodeLink(ObjectVisitor* v, int offset);
 | 
| -
 | 
|   private:
 | 
|    DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject);
 | 
|  };
 | 
|  
 | 
|  
 | 
| -// This is the base class for object's body descriptors.
 | 
| -class BodyDescriptorBase {
 | 
| - protected:
 | 
| -  static inline void IterateBodyImpl(HeapObject* obj, int start_offset,
 | 
| -                                     int end_offset, ObjectVisitor* v);
 | 
| -
 | 
| -  template <typename StaticVisitor>
 | 
| -  static inline void IterateBodyImpl(Heap* heap, HeapObject* obj,
 | 
| -                                     int start_offset, int end_offset);
 | 
| -
 | 
| -  static inline void IteratePointers(HeapObject* obj, int start_offset,
 | 
| -                                     int end_offset, ObjectVisitor* v);
 | 
| -
 | 
| -  template <typename StaticVisitor>
 | 
| -  static inline void IteratePointers(Heap* heap, HeapObject* obj,
 | 
| -                                     int start_offset, int end_offset);
 | 
| -};
 | 
| -
 | 
| -
 | 
| -// This class describes a body of an object of a fixed size
 | 
| -// in which all pointer fields are located in the [start_offset, end_offset)
 | 
| -// interval.
 | 
|  template <int start_offset, int end_offset, int size>
 | 
| -class FixedBodyDescriptor : public BodyDescriptorBase {
 | 
| - public:
 | 
| -  static const int kStartOffset = start_offset;
 | 
| -  static const int kEndOffset = end_offset;
 | 
| -  static const int kSize = size;
 | 
| +class FixedBodyDescriptor;
 | 
|  
 | 
| -  static inline void IterateBody(HeapObject* obj, ObjectVisitor* v) {
 | 
| -    IterateBodyImpl(obj, start_offset, end_offset, v);
 | 
| -  }
 | 
|  
 | 
| -  template <typename StaticVisitor>
 | 
| -  static inline void IterateBody(HeapObject* obj) {
 | 
| -    Heap* heap = obj->GetHeap();
 | 
| -    IterateBodyImpl<StaticVisitor>(heap, obj, start_offset, end_offset);
 | 
| -  }
 | 
| -};
 | 
| -
 | 
| -
 | 
| -// This base class describes a body of an object of a variable size
 | 
| -// in which all pointer fields are located in the [start_offset, object_size)
 | 
| -// interval.
 | 
|  template <int start_offset>
 | 
| -class FlexibleBodyDescriptorBase : public BodyDescriptorBase {
 | 
| - public:
 | 
| -  static const int kStartOffset = start_offset;
 | 
| -
 | 
| -  static inline void IterateBody(HeapObject* obj, int object_size,
 | 
| -                                 ObjectVisitor* v) {
 | 
| -    IterateBodyImpl(obj, start_offset, object_size, v);
 | 
| -  }
 | 
| -
 | 
| -  template <typename StaticVisitor>
 | 
| -  static inline void IterateBody(HeapObject* obj, int object_size) {
 | 
| -    Heap* heap = obj->GetHeap();
 | 
| -    IterateBodyImpl<StaticVisitor>(heap, obj, start_offset, object_size);
 | 
| -  }
 | 
| -};
 | 
| -
 | 
| -
 | 
| -// This class describes a body of an object of a variable size
 | 
| -// in which all pointer fields are located in the [start_offset, object_size)
 | 
| -// interval. The size of the object is taken from the map.
 | 
| -template <int start_offset>
 | 
| -class FlexibleBodyDescriptor : public FlexibleBodyDescriptorBase<start_offset> {
 | 
| - public:
 | 
| -  static inline int SizeOf(Map* map, HeapObject* object);
 | 
| -};
 | 
| +class FlexibleBodyDescriptor;
 | 
|  
 | 
|  
 | 
|  // The HeapNumber class describes heap allocated numbers that cannot be
 | 
| @@ -2688,10 +2635,7 @@ class FixedArray: public FixedArrayBase {
 | 
|    // object, the prefix of this array is sorted.
 | 
|    void SortPairs(FixedArray* numbers, uint32_t len);
 | 
|  
 | 
| -  class BodyDescriptor : public FlexibleBodyDescriptorBase<kHeaderSize> {
 | 
| -   public:
 | 
| -    static inline int SizeOf(Map* map, HeapObject* object);
 | 
| -  };
 | 
| +  typedef FlexibleBodyDescriptor<kHeaderSize> BodyDescriptor;
 | 
|  
 | 
|   protected:
 | 
|    // Set operation on FixedArray without using write barriers. Can
 | 
| @@ -4423,7 +4367,6 @@ class BytecodeArray : public FixedArrayBase {
 | 
|  
 | 
|    // Dispatched behavior.
 | 
|    inline int BytecodeArraySize();
 | 
| -  inline void BytecodeArrayIterateBody(ObjectVisitor* v);
 | 
|  
 | 
|    DECLARE_PRINTER(BytecodeArray)
 | 
|    DECLARE_VERIFIER(BytecodeArray)
 | 
| @@ -4443,6 +4386,8 @@ class BytecodeArray : public FixedArrayBase {
 | 
|    // Maximal length of a single BytecodeArray.
 | 
|    static const int kMaxLength = kMaxSize - kHeaderSize;
 | 
|  
 | 
| +  class BodyDescriptor;
 | 
| +
 | 
|   private:
 | 
|    DISALLOW_IMPLICIT_CONSTRUCTORS(BytecodeArray);
 | 
|  };
 | 
| @@ -4508,11 +4453,6 @@ class FixedTypedArrayBase: public FixedArrayBase {
 | 
|    DECL_ACCESSORS(external_pointer, void)
 | 
|  
 | 
|    // Dispatched behavior.
 | 
| -  inline void FixedTypedArrayBaseIterateBody(ObjectVisitor* v);
 | 
| -
 | 
| -  template <typename StaticVisitor>
 | 
| -  inline void FixedTypedArrayBaseIterateBody();
 | 
| -
 | 
|    DECLARE_CAST(FixedTypedArrayBase)
 | 
|  
 | 
|    static const int kBasePointerOffset = FixedArrayBase::kHeaderSize;
 | 
| @@ -4522,6 +4462,8 @@ class FixedTypedArrayBase: public FixedArrayBase {
 | 
|  
 | 
|    static const int kDataOffset = kHeaderSize;
 | 
|  
 | 
| +  class BodyDescriptor;
 | 
| +
 | 
|    inline int size();
 | 
|  
 | 
|    static inline int TypedArraySize(InstanceType type, int length);
 | 
| @@ -5192,10 +5134,6 @@ class Code: public HeapObject {
 | 
|  
 | 
|    // Dispatched behavior.
 | 
|    inline int CodeSize();
 | 
| -  inline void CodeIterateBody(ObjectVisitor* v);
 | 
| -
 | 
| -  template<typename StaticVisitor>
 | 
| -  inline void CodeIterateBody(Heap* heap);
 | 
|  
 | 
|    DECLARE_PRINTER(Code)
 | 
|    DECLARE_VERIFIER(Code)
 | 
| @@ -5294,6 +5232,8 @@ class Code: public HeapObject {
 | 
|    static const int kHeaderSize =
 | 
|        (kHeaderPaddingStart + kCodeAlignmentMask) & ~kCodeAlignmentMask;
 | 
|  
 | 
| +  class BodyDescriptor;
 | 
| +
 | 
|    // Byte offsets within kKindSpecificFlags1Offset.
 | 
|    static const int kFullCodeFlags = kKindSpecificFlags1Offset;
 | 
|    class FullCodeFlagsHasDeoptimizationSupportField:
 | 
| @@ -9204,11 +9144,7 @@ class ExternalOneByteString : public ExternalString {
 | 
|  
 | 
|    DECLARE_CAST(ExternalOneByteString)
 | 
|  
 | 
| -  // Garbage collection support.
 | 
| -  inline void ExternalOneByteStringIterateBody(ObjectVisitor* v);
 | 
| -
 | 
| -  template <typename StaticVisitor>
 | 
| -  inline void ExternalOneByteStringIterateBody();
 | 
| +  class BodyDescriptor;
 | 
|  
 | 
|   private:
 | 
|    DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalOneByteString);
 | 
| @@ -9243,11 +9179,7 @@ class ExternalTwoByteString: public ExternalString {
 | 
|  
 | 
|    DECLARE_CAST(ExternalTwoByteString)
 | 
|  
 | 
| -  // Garbage collection support.
 | 
| -  inline void ExternalTwoByteStringIterateBody(ObjectVisitor* v);
 | 
| -
 | 
| -  template<typename StaticVisitor>
 | 
| -  inline void ExternalTwoByteStringIterateBody();
 | 
| +  class BodyDescriptor;
 | 
|  
 | 
|   private:
 | 
|    DISALLOW_IMPLICIT_CONSTRUCTORS(ExternalTwoByteString);
 | 
| @@ -9886,6 +9818,8 @@ class JSWeakCollection: public JSObject {
 | 
|    static const int kNextOffset = kTableOffset + kPointerSize;
 | 
|    static const int kSize = kNextOffset + kPointerSize;
 | 
|  
 | 
| +  class BodyDescriptor;
 | 
| +
 | 
|   private:
 | 
|    DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakCollection);
 | 
|  };
 | 
| @@ -9964,11 +9898,6 @@ class JSArrayBuffer: public JSObject {
 | 
|    DECLARE_VERIFIER(JSArrayBuffer)
 | 
|  
 | 
|    static const int kByteLengthOffset = JSObject::kHeaderSize;
 | 
| -
 | 
| -  // NOTE: GC will visit objects fields:
 | 
| -  // 1. From JSObject::BodyDescriptor::kStartOffset to kByteLengthOffset +
 | 
| -  //    kPointerSize
 | 
| -  // 2. From start of the internal fields and up to the end of them
 | 
|    static const int kBackingStoreOffset = kByteLengthOffset + kPointerSize;
 | 
|    static const int kBitFieldSlot = kBackingStoreOffset + kPointerSize;
 | 
|  #if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT
 | 
| @@ -9981,11 +9910,9 @@ class JSArrayBuffer: public JSObject {
 | 
|    static const int kSizeWithInternalFields =
 | 
|        kSize + v8::ArrayBuffer::kInternalFieldCount * kPointerSize;
 | 
|  
 | 
| -  template <typename StaticVisitor>
 | 
| -  static inline void JSArrayBufferIterateBody(Heap* heap, HeapObject* obj);
 | 
| -
 | 
| -  static inline void JSArrayBufferIterateBody(HeapObject* obj,
 | 
| -                                              ObjectVisitor* v);
 | 
| +  // Iterates all fields in the object including internal ones except
 | 
| +  // kBackingStoreOffset and kBitFieldSlot.
 | 
| +  class BodyDescriptor;
 | 
|  
 | 
|    class IsExternal : public BitField<bool, 1, 1> {};
 | 
|    class IsNeuterable : public BitField<bool, 2, 1> {};
 | 
| @@ -10091,12 +10018,6 @@ class Foreign: public HeapObject {
 | 
|    DECLARE_CAST(Foreign)
 | 
|  
 | 
|    // Dispatched behavior.
 | 
| -  inline void ForeignIterateBody(ObjectVisitor* v);
 | 
| -
 | 
| -  template<typename StaticVisitor>
 | 
| -  inline void ForeignIterateBody();
 | 
| -
 | 
| -  // Dispatched behavior.
 | 
|    DECLARE_PRINTER(Foreign)
 | 
|    DECLARE_VERIFIER(Foreign)
 | 
|  
 | 
| @@ -10107,6 +10028,8 @@ class Foreign: public HeapObject {
 | 
|  
 | 
|    STATIC_ASSERT(kForeignAddressOffset == Internals::kForeignAddressOffset);
 | 
|  
 | 
| +  class BodyDescriptor;
 | 
| +
 | 
|   private:
 | 
|    DISALLOW_IMPLICIT_CONSTRUCTORS(Foreign);
 | 
|  };
 | 
| @@ -10770,9 +10693,6 @@ class ObjectVisitor BASE_EMBEDDED {
 | 
|  };
 | 
|  
 | 
|  
 | 
| -typedef FlexibleBodyDescriptor<HeapObject::kHeaderSize> StructBodyDescriptor;
 | 
| -
 | 
| -
 | 
|  // BooleanBit is a helper class for setting and getting a bit in an integer.
 | 
|  class BooleanBit : public AllStatic {
 | 
|   public:
 | 
| 
 |