| Index: src/unique.h
 | 
| diff --git a/src/unique.h b/src/unique.h
 | 
| index 4668128e19c1e4f264e38d15bffec2c2f4291efc..3c1c0aab87aa375b75cba4621461199546f1f15b 100644
 | 
| --- a/src/unique.h
 | 
| +++ b/src/unique.h
 | 
| @@ -7,6 +7,7 @@
 | 
|  
 | 
|  #include "src/handles.h"
 | 
|  #include "src/objects.h"
 | 
| +#include "src/string-stream.h"
 | 
|  #include "src/utils.h"
 | 
|  #include "src/zone.h"
 | 
|  
 | 
| @@ -29,7 +30,7 @@ class UniqueSet;
 | 
|  // Careful! Comparison of two Uniques is only correct if both were created
 | 
|  // in the same "era" of GC or if at least one is a non-movable object.
 | 
|  template <typename T>
 | 
| -class Unique V8_FINAL {
 | 
| +class Unique {
 | 
|   public:
 | 
|    // TODO(titzer): make private and introduce a uniqueness scope.
 | 
|    explicit Unique(Handle<T> handle) {
 | 
| @@ -117,8 +118,10 @@ class Unique V8_FINAL {
 | 
|    friend class UniqueSet<T>;  // Uses internal details for speed.
 | 
|    template <class U>
 | 
|    friend class Unique;  // For comparing raw_address values.
 | 
| +  template <class U>
 | 
| +  friend class PrintableUnique;  // For automatic up casting.
 | 
|  
 | 
| - private:
 | 
| + protected:
 | 
|    Unique<T>() : raw_address_(NULL) { }
 | 
|  
 | 
|    Address raw_address_;
 | 
| @@ -128,6 +131,70 @@ class Unique V8_FINAL {
 | 
|  };
 | 
|  
 | 
|  
 | 
| +// TODO(danno): At some point if all of the uses of Unique end up using
 | 
| +// PrintableUnique, then we should merge PrintableUnique into Unique and
 | 
| +// predicate generating the printable string on a "am I tracing" check.
 | 
| +template <class T>
 | 
| +class PrintableUnique : public Unique<T> {
 | 
| + public:
 | 
| +  // TODO(titzer): make private and introduce a uniqueness scope.
 | 
| +  explicit PrintableUnique(Zone* zone, Handle<T> handle) : Unique<T>(handle) {
 | 
| +    InitializeString(zone);
 | 
| +  }
 | 
| +
 | 
| +  // TODO(titzer): this is a hack to migrate to Unique<T> incrementally.
 | 
| +  PrintableUnique(Zone* zone, Address raw_address, Handle<T> handle)
 | 
| +      : Unique<T>(raw_address, handle) {
 | 
| +    InitializeString(zone);
 | 
| +  }
 | 
| +
 | 
| +  // Constructor for handling automatic up casting.
 | 
| +  // Eg. PrintableUnique<JSFunction> can be passed when PrintableUnique<Object>
 | 
| +  // is expected.
 | 
| +  template <class S>
 | 
| +  PrintableUnique(PrintableUnique<S> uniq)  // NOLINT
 | 
| +      : Unique<T>(Handle<T>()) {
 | 
| +#ifdef DEBUG
 | 
| +    T* a = NULL;
 | 
| +    S* b = NULL;
 | 
| +    a = b;  // Fake assignment to enforce type checks.
 | 
| +    USE(a);
 | 
| +#endif
 | 
| +    this->raw_address_ = uniq.raw_address_;
 | 
| +    this->handle_ = uniq.handle_;
 | 
| +    string_ = uniq.string();
 | 
| +  }
 | 
| +
 | 
| +  // TODO(titzer): this is a hack to migrate to Unique<T> incrementally.
 | 
| +  static PrintableUnique<T> CreateUninitialized(Zone* zone, Handle<T> handle) {
 | 
| +    return PrintableUnique<T>(zone, reinterpret_cast<Address>(NULL), handle);
 | 
| +  }
 | 
| +
 | 
| +  static PrintableUnique<T> CreateImmovable(Zone* zone, Handle<T> handle) {
 | 
| +    return PrintableUnique<T>(zone, reinterpret_cast<Address>(*handle), handle);
 | 
| +  }
 | 
| +
 | 
| +  const char* string() { return string_; }
 | 
| +
 | 
| + private:
 | 
| +  const char* string_;
 | 
| +
 | 
| +  void InitializeString(Zone* zone) {
 | 
| +    // The stringified version of the parameter must be calculated when the
 | 
| +    // Operator is constructed to avoid accessing the heap.
 | 
| +    HeapStringAllocator temp_allocator;
 | 
| +    StringStream stream(&temp_allocator);
 | 
| +    this->handle_->ShortPrint(&stream);
 | 
| +    SmartArrayPointer<const char> desc_string = stream.ToCString();
 | 
| +    const char* desc_chars = desc_string.get();
 | 
| +    int length = strlen(desc_chars);
 | 
| +    char* desc_copy = zone->NewArray<char>(length + 1);
 | 
| +    memcpy(desc_copy, desc_chars, length + 1);
 | 
| +    string_ = desc_copy;
 | 
| +  }
 | 
| +};
 | 
| +
 | 
| +
 | 
|  template <typename T>
 | 
|  class UniqueSet V8_FINAL : public ZoneObject {
 | 
|   public:
 | 
| @@ -341,7 +408,6 @@ class UniqueSet V8_FINAL : public ZoneObject {
 | 
|    }
 | 
|  };
 | 
|  
 | 
| -
 | 
|  } }  // namespace v8::internal
 | 
|  
 | 
|  #endif  // V8_HYDROGEN_UNIQUE_H_
 | 
| 
 |