| Index: src/property-details.h
 | 
| diff --git a/src/property-details.h b/src/property-details.h
 | 
| index 2aa6dcfa959421d8c6e285d3b731fccb6dbc4b31..dc912c8a0566a123eb11d0907eee5bd3f1e9ab0d 100644
 | 
| --- a/src/property-details.h
 | 
| +++ b/src/property-details.h
 | 
| @@ -76,30 +76,118 @@ enum PropertyType {
 | 
|  };
 | 
|  
 | 
|  
 | 
| +class Representation {
 | 
| + public:
 | 
| +  enum Kind {
 | 
| +    kNone,
 | 
| +    kSmi,
 | 
| +    kInteger32,
 | 
| +    kDouble,
 | 
| +    kTagged,
 | 
| +    kExternal,
 | 
| +    kNumRepresentations
 | 
| +  };
 | 
| +
 | 
| +  Representation() : kind_(kNone) { }
 | 
| +
 | 
| +  static Representation None() { return Representation(kNone); }
 | 
| +  static Representation Tagged() { return Representation(kTagged); }
 | 
| +  static Representation Smi() { return Representation(kSmi); }
 | 
| +  static Representation Integer32() { return Representation(kInteger32); }
 | 
| +  static Representation Double() { return Representation(kDouble); }
 | 
| +  static Representation External() { return Representation(kExternal); }
 | 
| +
 | 
| +  static Representation FromKind(Kind kind) { return Representation(kind); }
 | 
| +
 | 
| +  bool Equals(const Representation& other) {
 | 
| +    return kind_ == other.kind_;
 | 
| +  }
 | 
| +
 | 
| +  bool is_more_general_than(const Representation& other) {
 | 
| +    ASSERT(kind_ != kExternal);
 | 
| +    ASSERT(other.kind_ != kExternal);
 | 
| +    return kind_ > other.kind_;
 | 
| +  }
 | 
| +
 | 
| +  Representation generalize(Representation other) {
 | 
| +    if (is_more_general_than(other)) {
 | 
| +      return *this;
 | 
| +    } else {
 | 
| +      return other;
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +  Kind kind() const { return static_cast<Kind>(kind_); }
 | 
| +  bool IsNone() const { return kind_ == kNone; }
 | 
| +  bool IsTagged() const { return kind_ == kTagged; }
 | 
| +  bool IsSmi() const { return kind_ == kSmi; }
 | 
| +  bool IsInteger32() const { return kind_ == kInteger32; }
 | 
| +  bool IsDouble() const { return kind_ == kDouble; }
 | 
| +  bool IsExternal() const { return kind_ == kExternal; }
 | 
| +  bool IsSpecialization() const {
 | 
| +    return kind_ == kInteger32 || kind_ == kDouble;
 | 
| +  }
 | 
| +  const char* Mnemonic() const;
 | 
| +
 | 
| + private:
 | 
| +  explicit Representation(Kind k) : kind_(k) { }
 | 
| +
 | 
| +  // Make sure kind fits in int8.
 | 
| +  STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
 | 
| +
 | 
| +  int8_t kind_;
 | 
| +};
 | 
| +
 | 
| +
 | 
|  // PropertyDetails captures type and attributes for a property.
 | 
|  // They are used both in property dictionaries and instance descriptors.
 | 
|  class PropertyDetails BASE_EMBEDDED {
 | 
|   public:
 | 
|    PropertyDetails(PropertyAttributes attributes,
 | 
|                    PropertyType type,
 | 
| +                  Representation representation,
 | 
|                    int index = 0) {
 | 
|      value_ = TypeField::encode(type)
 | 
|          | AttributesField::encode(attributes)
 | 
| +        | RepresentationField::encode(EncodeRepresentation(representation))
 | 
|          | DictionaryStorageField::encode(index);
 | 
|  
 | 
|      ASSERT(type == this->type());
 | 
|      ASSERT(attributes == this->attributes());
 | 
| -    ASSERT(index == this->dictionary_index());
 | 
| +    if (representation.IsNone()) {
 | 
| +      ASSERT(index == this->dictionary_index());
 | 
| +    } else {
 | 
| +      ASSERT(index == this->descriptor_index());
 | 
| +    }
 | 
|    }
 | 
|  
 | 
|    int pointer() { return DescriptorPointer::decode(value_); }
 | 
|  
 | 
|    PropertyDetails set_pointer(int i) { return PropertyDetails(value_, i); }
 | 
|  
 | 
| +  PropertyDetails CopyWithRepresentation(Representation representation) {
 | 
| +    return PropertyDetails(value_, representation);
 | 
| +  }
 | 
| +
 | 
|    // Conversion for storing details as Object*.
 | 
|    explicit inline PropertyDetails(Smi* smi);
 | 
|    inline Smi* AsSmi();
 | 
|  
 | 
| +  static uint8_t EncodeRepresentation(Representation representation) {
 | 
| +    ASSERT(representation.kind() <= Representation::kTagged);
 | 
| +    if (representation.kind() < Representation::kInteger32) {
 | 
| +      return representation.kind();
 | 
| +    } else {
 | 
| +      return representation.kind() - 1;
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +  static Representation DecodeRepresentation(uint32_t bits) {
 | 
| +    ASSERT(bits <= Representation::kTagged);
 | 
| +    if (bits >= Representation::kInteger32) bits += 1;
 | 
| +    return Representation::FromKind(static_cast<Representation::Kind>(bits));
 | 
| +  }
 | 
| +
 | 
|    PropertyType type() { return TypeField::decode(value_); }
 | 
|  
 | 
|    PropertyAttributes attributes() const {
 | 
| @@ -114,6 +202,10 @@ class PropertyDetails BASE_EMBEDDED {
 | 
|      return DescriptorStorageField::decode(value_);
 | 
|    }
 | 
|  
 | 
| +  Representation representation() {
 | 
| +    return DecodeRepresentation(RepresentationField::decode(value_));
 | 
| +  }
 | 
| +
 | 
|    inline PropertyDetails AsDeleted();
 | 
|  
 | 
|    static bool IsValidIndex(int index) {
 | 
| @@ -133,12 +225,17 @@ class PropertyDetails BASE_EMBEDDED {
 | 
|    class DictionaryStorageField:   public BitField<uint32_t,           7, 24> {};
 | 
|    class DescriptorStorageField:   public BitField<uint32_t,           7, 11> {};
 | 
|    class DescriptorPointer:        public BitField<uint32_t,          18, 11> {};
 | 
| +  class RepresentationField:      public BitField<uint32_t,          29,  2> {};
 | 
|  
 | 
|    static const int kInitialIndex = 1;
 | 
|  
 | 
|   private:
 | 
|    PropertyDetails(int value, int pointer) {
 | 
| -      value_ = DescriptorPointer::update(value, pointer);
 | 
| +    value_ = DescriptorPointer::update(value, pointer);
 | 
| +  }
 | 
| +  PropertyDetails(int value, Representation representation) {
 | 
| +    value_ = RepresentationField::update(
 | 
| +        value, EncodeRepresentation(representation));
 | 
|    }
 | 
|  
 | 
|    uint32_t value_;
 | 
| 
 |