Use Unique<Object> in HConstant and remove UniqueValueId.
authortitzer@chromium.org <titzer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 24 Sep 2013 09:48:39 +0000 (09:48 +0000)
committertitzer@chromium.org <titzer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 24 Sep 2013 09:48:39 +0000 (09:48 +0000)
BUG=
R=verwaest@chromium.org

Review URL: https://codereview.chromium.org/24350014

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16911 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/hydrogen-instructions.cc
src/hydrogen-instructions.h
src/hydrogen.cc
src/hydrogen.h
src/unique.h

index a685198..d301036 100644 (file)
@@ -2363,8 +2363,7 @@ static bool IsInteger32(double value) {
 
 HConstant::HConstant(Handle<Object> handle, Representation r)
   : HTemplateInstruction<0>(HType::TypeFromValue(handle)),
-    handle_(handle),
-    unique_id_(),
+    object_(Unique<Object>::CreateUninitialized(handle)),
     has_smi_value_(false),
     has_int32_value_(false),
     has_double_value_(false),
@@ -2373,29 +2372,28 @@ HConstant::HConstant(Handle<Object> handle, Representation r)
     is_not_in_new_space_(true),
     is_cell_(false),
     boolean_value_(handle->BooleanValue()) {
-  if (handle_->IsHeapObject()) {
+  if (handle->IsHeapObject()) {
     Heap* heap = Handle<HeapObject>::cast(handle)->GetHeap();
     is_not_in_new_space_ = !heap->InNewSpace(*handle);
   }
-  if (handle_->IsNumber()) {
-    double n = handle_->Number();
+  if (handle->IsNumber()) {
+    double n = handle->Number();
     has_int32_value_ = IsInteger32(n);
     int32_value_ = DoubleToInt32(n);
     has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_);
     double_value_ = n;
     has_double_value_ = true;
   } else {
-    is_internalized_string_ = handle_->IsInternalizedString();
+    is_internalized_string_ = handle->IsInternalizedString();
   }
 
-  is_cell_ = !handle_.is_null() &&
-      (handle_->IsCell() || handle_->IsPropertyCell());
+  is_cell_ = !handle.is_null() &&
+      (handle->IsCell() || handle->IsPropertyCell());
   Initialize(r);
 }
 
 
-HConstant::HConstant(Handle<Object> handle,
-                     UniqueValueId unique_id,
+HConstant::HConstant(Unique<Object> unique,
                      Representation r,
                      HType type,
                      bool is_internalize_string,
@@ -2403,8 +2401,7 @@ HConstant::HConstant(Handle<Object> handle,
                      bool is_cell,
                      bool boolean_value)
   : HTemplateInstruction<0>(type),
-    handle_(handle),
-    unique_id_(unique_id),
+    object_(unique),
     has_smi_value_(false),
     has_int32_value_(false),
     has_double_value_(false),
@@ -2413,36 +2410,17 @@ HConstant::HConstant(Handle<Object> handle,
     is_not_in_new_space_(is_not_in_new_space),
     is_cell_(is_cell),
     boolean_value_(boolean_value) {
-  ASSERT(!handle.is_null());
+  ASSERT(!unique.handle().is_null());
   ASSERT(!type.IsTaggedNumber());
   Initialize(r);
 }
 
 
-HConstant::HConstant(Handle<Map> handle,
-                     UniqueValueId unique_id)
-  : HTemplateInstruction<0>(HType::Tagged()),
-    handle_(handle),
-    unique_id_(unique_id),
-    has_smi_value_(false),
-    has_int32_value_(false),
-    has_double_value_(false),
-    has_external_reference_value_(false),
-    is_internalized_string_(false),
-    is_not_in_new_space_(true),
-    is_cell_(false),
-    boolean_value_(false) {
-  ASSERT(!handle.is_null());
-  Initialize(Representation::Tagged());
-}
-
-
 HConstant::HConstant(int32_t integer_value,
                      Representation r,
                      bool is_not_in_new_space,
-                     Handle<Object> optional_handle)
-  : handle_(optional_handle),
-    unique_id_(),
+                     Unique<Object> object)
+  : object_(object),
     has_smi_value_(Smi::IsValid(integer_value)),
     has_int32_value_(true),
     has_double_value_(true),
@@ -2461,9 +2439,8 @@ HConstant::HConstant(int32_t integer_value,
 HConstant::HConstant(double double_value,
                      Representation r,
                      bool is_not_in_new_space,
-                     Handle<Object> optional_handle)
-  : handle_(optional_handle),
-    unique_id_(),
+                     Unique<Object> object)
+  : object_(object),
     has_int32_value_(IsInteger32(double_value)),
     has_double_value_(true),
     has_external_reference_value_(false),
@@ -2481,6 +2458,7 @@ HConstant::HConstant(double double_value,
 
 HConstant::HConstant(ExternalReference reference)
   : HTemplateInstruction<0>(HType::None()),
+    object_(Unique<Object>(Handle<Object>::null())),
     has_smi_value_(false),
     has_int32_value_(false),
     has_double_value_(false),
@@ -2494,14 +2472,6 @@ HConstant::HConstant(ExternalReference reference)
 }
 
 
-static void PrepareConstant(Handle<Object> object) {
-  if (!object->IsJSObject()) return;
-  Handle<JSObject> js_object = Handle<JSObject>::cast(object);
-  if (!js_object->map()->is_deprecated()) return;
-  JSObject::TryMigrateInstance(js_object);
-}
-
-
 void HConstant::Initialize(Representation r) {
   if (r.IsNone()) {
     if (has_smi_value_ && SmiValuesAre31Bits()) {
@@ -2513,7 +2483,14 @@ void HConstant::Initialize(Representation r) {
     } else if (has_external_reference_value_) {
       r = Representation::External();
     } else {
-      PrepareConstant(handle_);
+      Handle<Object> object = object_.handle();
+      if (object->IsJSObject()) {
+        // Try to eagerly migrate JSObjects that have deprecated maps.
+        Handle<JSObject> js_object = Handle<JSObject>::cast(object);
+        if (js_object->map()->is_deprecated()) {
+          JSObject::TryMigrateInstance(js_object);
+        }
+      }
       r = Representation::Tagged();
     }
   }
@@ -2541,17 +2518,16 @@ HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const {
   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_, handle_);
+    return new(zone) HConstant(int32_value_, r, is_not_in_new_space_, object_);
   }
   if (has_double_value_) {
-    return new(zone) HConstant(double_value_, r, is_not_in_new_space_, handle_);
+    return new(zone) HConstant(double_value_, r, is_not_in_new_space_, object_);
   }
   if (has_external_reference_value_) {
     return new(zone) HConstant(external_reference_value_);
   }
-  ASSERT(!handle_.is_null());
-  return new(zone) HConstant(handle_,
-                             unique_id_,
+  ASSERT(!object_.handle().is_null());
+  return new(zone) HConstant(object_,
                              r,
                              type_,
                              is_internalized_string_,
@@ -2567,12 +2543,12 @@ Maybe<HConstant*> HConstant::CopyToTruncatedInt32(Zone* zone) {
     res = new(zone) HConstant(int32_value_,
                               Representation::Integer32(),
                               is_not_in_new_space_,
-                              handle_);
+                              object_);
   } else if (has_double_value_) {
     res = new(zone) HConstant(DoubleToInt32(double_value_),
                               Representation::Integer32(),
                               is_not_in_new_space_,
-                              handle_);
+                              object_);
   }
   return Maybe<HConstant*>(res != NULL, res);
 }
@@ -3439,8 +3415,8 @@ void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) {
   HConstant* filler_map = HConstant::New(
       zone,
       context(),
-      isolate()->factory()->free_space_map(),
-      UniqueValueId::free_space_map(isolate()->heap()));
+      isolate()->factory()->free_space_map());
+  filler_map->FinalizeUniqueness();  // TODO(titzer): should be init'd a'ready
   filler_map->InsertAfter(free_space_instr);
   HInstruction* store_map = HStoreNamedField::New(zone, context(),
       free_space_instr, HObjectAccess::ForMap(), filler_map);
index a5cfe3b..b06d6e5 100644 (file)
@@ -306,65 +306,6 @@ class Range V8_FINAL : public ZoneObject {
 };
 
 
-class UniqueValueId V8_FINAL {
- public:
-  UniqueValueId() : raw_address_(NULL) { }
-
-  explicit UniqueValueId(Handle<Object> handle) {
-    ASSERT(!AllowHeapAllocation::IsAllowed());
-    static const Address kEmptyHandleSentinel = reinterpret_cast<Address>(1);
-    if (handle.is_null()) {
-      raw_address_ = kEmptyHandleSentinel;
-    } else {
-      raw_address_ = reinterpret_cast<Address>(*handle);
-      ASSERT_NE(kEmptyHandleSentinel, raw_address_);
-    }
-    ASSERT(IsInitialized());
-  }
-
-  bool IsInitialized() const { return raw_address_ != NULL; }
-
-  bool operator==(const UniqueValueId& other) const {
-    ASSERT(IsInitialized() && other.IsInitialized());
-    return raw_address_ == other.raw_address_;
-  }
-
-  bool operator!=(const UniqueValueId& other) const {
-    ASSERT(IsInitialized() && other.IsInitialized());
-    return raw_address_ != other.raw_address_;
-  }
-
-  intptr_t Hashcode() const {
-    ASSERT(IsInitialized());
-    return reinterpret_cast<intptr_t>(raw_address_);
-  }
-
-#define IMMOVABLE_UNIQUE_VALUE_ID(name)   \
-  static UniqueValueId name(Heap* heap) { return UniqueValueId(heap->name()); }
-
-  IMMOVABLE_UNIQUE_VALUE_ID(free_space_map)
-  IMMOVABLE_UNIQUE_VALUE_ID(minus_zero_value)
-  IMMOVABLE_UNIQUE_VALUE_ID(nan_value)
-  IMMOVABLE_UNIQUE_VALUE_ID(undefined_value)
-  IMMOVABLE_UNIQUE_VALUE_ID(null_value)
-  IMMOVABLE_UNIQUE_VALUE_ID(true_value)
-  IMMOVABLE_UNIQUE_VALUE_ID(false_value)
-  IMMOVABLE_UNIQUE_VALUE_ID(the_hole_value)
-  IMMOVABLE_UNIQUE_VALUE_ID(empty_string)
-  IMMOVABLE_UNIQUE_VALUE_ID(empty_fixed_array)
-
-#undef IMMOVABLE_UNIQUE_VALUE_ID
-
- private:
-  Address raw_address_;
-
-  explicit UniqueValueId(Object* object) {
-    raw_address_ = reinterpret_cast<Address>(object);
-    ASSERT(IsInitialized());
-  }
-};
-
-
 class HType V8_FINAL {
  public:
   static HType None() { return HType(kNone); }
@@ -904,7 +845,7 @@ class HValue : public ZoneObject {
   virtual intptr_t Hashcode();
 
   // Compute unique ids upfront that is safe wrt GC and concurrent compilation.
-  virtual void FinalizeUniqueValueId() { }
+  virtual void FinalizeUniqueness() { }
 
   // Printing support.
   virtual void PrintTo(StringStream* stream) = 0;
@@ -2691,7 +2632,7 @@ class HCheckValue V8_FINAL : public HUnaryOperation {
     return new(zone) HCheckValue(value, target, object_in_new_space);
   }
 
-  virtual void FinalizeUniqueValueId() V8_OVERRIDE {
+  virtual void FinalizeUniqueness() V8_OVERRIDE {
     object_ = Unique<HeapObject>(object_.handle());
   }
 
@@ -3297,7 +3238,6 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
   DECLARE_INSTRUCTION_FACTORY_P2(HConstant, int32_t, Representation);
   DECLARE_INSTRUCTION_FACTORY_P1(HConstant, double);
   DECLARE_INSTRUCTION_FACTORY_P1(HConstant, Handle<Object>);
-  DECLARE_INSTRUCTION_FACTORY_P2(HConstant, Handle<Map>, UniqueValueId);
   DECLARE_INSTRUCTION_FACTORY_P1(HConstant, ExternalReference);
 
   static HConstant* CreateAndInsertAfter(Zone* zone,
@@ -3323,15 +3263,15 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
   }
 
   Handle<Object> handle(Isolate* isolate) {
-    if (handle_.is_null()) {
-      Factory* factory = isolate->factory();
+    if (object_.handle().is_null()) {
       // Default arguments to is_not_in_new_space depend on this heap number
-      // to be tenured so that it's guaranteed not be be located in new space.
-      handle_ = factory->NewNumber(double_value_, TENURED);
+      // to be tenured so that it's guaranteed not to be located in new space.
+      object_ = Unique<Object>::CreateUninitialized(
+          isolate->factory()->NewNumber(double_value_, TENURED));
     }
     AllowDeferredHandleDereference smi_check;
-    ASSERT(has_int32_value_ || !handle_->IsSmi());
-    return handle_;
+    ASSERT(has_int32_value_ || !object_.handle()->IsSmi());
+    return object_.handle();
   }
 
   bool HasMap(Handle<Map> map) {
@@ -3365,17 +3305,18 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
       return false;
     }
 
-    ASSERT(!handle_.is_null());
+    ASSERT(!object_.handle().is_null());
     Heap* heap = isolate()->heap();
-    ASSERT(unique_id_ != UniqueValueId::minus_zero_value(heap));
-    ASSERT(unique_id_ != UniqueValueId::nan_value(heap));
-    return unique_id_ == UniqueValueId::undefined_value(heap) ||
-           unique_id_ == UniqueValueId::null_value(heap) ||
-           unique_id_ == UniqueValueId::true_value(heap) ||
-           unique_id_ == UniqueValueId::false_value(heap) ||
-           unique_id_ == UniqueValueId::the_hole_value(heap) ||
-           unique_id_ == UniqueValueId::empty_string(heap) ||
-           unique_id_ == UniqueValueId::empty_fixed_array(heap);
+    ASSERT(!object_.IsKnownGlobal(heap->minus_zero_value()));
+    ASSERT(!object_.IsKnownGlobal(heap->nan_value()));
+    return
+        object_.IsKnownGlobal(heap->undefined_value()) ||
+        object_.IsKnownGlobal(heap->null_value()) ||
+        object_.IsKnownGlobal(heap->true_value()) ||
+        object_.IsKnownGlobal(heap->false_value()) ||
+        object_.IsKnownGlobal(heap->the_hole_value()) ||
+        object_.IsKnownGlobal(heap->empty_string()) ||
+        object_.IsKnownGlobal(heap->empty_fixed_array());
   }
 
   bool IsCell() const {
@@ -3414,11 +3355,7 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
     if (HasDoubleValue() && FixedDoubleArray::is_the_hole_nan(double_value_)) {
       return true;
     }
-    Heap* heap = isolate()->heap();
-    if (!handle_.is_null() && *handle_ == heap->the_hole_value()) {
-      return true;
-    }
-    return false;
+    return object_.IsKnownGlobal(isolate()->heap()->the_hole_value());
   }
   bool HasNumberValue() const { return has_double_value_; }
   int32_t NumberValueAsInteger32() const {
@@ -3430,12 +3367,12 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
   }
   bool HasStringValue() const {
     if (has_double_value_ || has_int32_value_) return false;
-    ASSERT(!handle_.is_null());
+    ASSERT(!object_.handle().is_null());
     return type_.IsString();
   }
   Handle<String> StringValue() const {
     ASSERT(HasStringValue());
-    return Handle<String>::cast(handle_);
+    return Handle<String>::cast(object_.handle());
   }
   bool HasInternalizedStringValue() const {
     return HasStringValue() && is_internalized_string_;
@@ -3459,27 +3396,20 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
     } else if (has_external_reference_value_) {
       return reinterpret_cast<intptr_t>(external_reference_value_.address());
     } else {
-      ASSERT(!handle_.is_null());
-      return unique_id_.Hashcode();
+      ASSERT(!object_.handle().is_null());
+      return object_.Hashcode();
     }
   }
 
-  virtual void FinalizeUniqueValueId() V8_OVERRIDE {
+  virtual void FinalizeUniqueness() V8_OVERRIDE {
     if (!has_double_value_ && !has_external_reference_value_) {
-      ASSERT(!handle_.is_null());
-      unique_id_ = UniqueValueId(handle_);
+      ASSERT(!object_.handle().is_null());
+      object_ = Unique<Object>(object_.handle());
     }
   }
 
-  bool UniqueValueIdsMatch(UniqueValueId other) {
-    return !has_double_value_ && !has_external_reference_value_ &&
-        unique_id_ == other;
-  }
-
   Unique<Object> GetUnique() const {
-    // TODO(titzer): store a Unique<HeapObject> inside the HConstant.
-    Address raw_address = reinterpret_cast<Address>(unique_id_.Hashcode());
-    return Unique<Object>(raw_address, handle_);
+    return object_;
   }
 
 #ifdef DEBUG
@@ -3505,9 +3435,8 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
           external_reference_value_ ==
           other_constant->external_reference_value_;
     } else {
-      ASSERT(!handle_.is_null());
-      return !other_constant->handle_.is_null() &&
-             unique_id_ == other_constant->unique_id_;
+      ASSERT(!object_.handle().is_null());
+      return other_constant->object_ == object_;
     }
   }
 
@@ -3517,33 +3446,30 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> {
   HConstant(int32_t value,
             Representation r = Representation::None(),
             bool is_not_in_new_space = true,
-            Handle<Object> optional_handle = Handle<Object>::null());
+            Unique<Object> optional = Unique<Object>(Handle<Object>::null()));
   HConstant(double value,
             Representation r = Representation::None(),
             bool is_not_in_new_space = true,
-            Handle<Object> optional_handle = Handle<Object>::null());
-  HConstant(Handle<Object> handle,
-            UniqueValueId unique_id,
+            Unique<Object> optional = Unique<Object>(Handle<Object>::null()));
+  HConstant(Unique<Object> unique,
             Representation r,
             HType type,
             bool is_internalized_string,
             bool is_not_in_new_space,
             bool is_cell,
             bool boolean_value);
-  HConstant(Handle<Map> handle,
-            UniqueValueId unique_id);
+
   explicit HConstant(ExternalReference reference);
 
   void Initialize(Representation r);
 
   virtual bool IsDeletable() const V8_OVERRIDE { return true; }
 
-  // If this is a numerical constant, handle_ either points to to the
+  // 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, handle_ always points to a valid
+  // constant is non-numeric, object_ always points to a valid
   // constant HeapObject.
-  Handle<Object> handle_;
-  UniqueValueId unique_id_;
+  Unique<Object> object_;
 
   // We store the HConstant in the most specific form safely possible.
   // The two flags, has_int32_value_ and has_double_value_ tell us if
@@ -5137,7 +5063,7 @@ class HLoadGlobalCell V8_FINAL : public HTemplateInstruction<0> {
     return cell_.Hashcode();
   }
 
-  virtual void FinalizeUniqueValueId() V8_OVERRIDE {
+  virtual void FinalizeUniqueness() V8_OVERRIDE {
     cell_ = Unique<Cell>(cell_.handle());
   }
 
@@ -5435,7 +5361,7 @@ class HStoreGlobalCell V8_FINAL : public HUnaryOperation {
     return StoringValueNeedsWriteBarrier(value());
   }
 
-  virtual void FinalizeUniqueValueId() V8_OVERRIDE {
+  virtual void FinalizeUniqueness() V8_OVERRIDE {
     cell_ = Unique<PropertyCell>(cell_.handle());
   }
 
index f3f875e..0a7e9f0 100644 (file)
@@ -649,8 +649,7 @@ HConstant* HGraph::GetConstantMinus1() {
 HConstant* HGraph::GetConstant##Name() {                                       \
   if (!constant_##name##_.is_set()) {                                          \
     HConstant* constant = new(zone()) HConstant(                               \
-        isolate()->factory()->name##_value(),                                  \
-        UniqueValueId::name##_value(isolate()->heap()),                        \
+        Unique<Object>::CreateImmovable(isolate()->factory()->name##_value()), \
         Representation::Tagged(),                                              \
         htype,                                                                 \
         false,                                                                 \
@@ -1039,7 +1038,7 @@ HGraph* HGraphBuilder::CreateGraph() {
   CompilationPhase phase("H_Block building", info_);
   set_current_block(graph()->entry_block());
   if (!BuildGraph()) return NULL;
-  graph()->FinalizeUniqueValueIds();
+  graph()->FinalizeUniqueness();
   return graph_;
 }
 
@@ -2293,12 +2292,12 @@ HBasicBlock* HGraph::CreateBasicBlock() {
 }
 
 
-void HGraph::FinalizeUniqueValueIds() {
+void HGraph::FinalizeUniqueness() {
   DisallowHeapAllocation no_gc;
   ASSERT(!isolate()->optimizing_compiler_thread()->IsOptimizerThread());
   for (int i = 0; i < blocks()->length(); ++i) {
     for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) {
-      it.Current()->FinalizeUniqueValueId();
+      it.Current()->FinalizeUniqueness();
     }
   }
 }
index 35433bd..6aa8217 100644 (file)
@@ -316,7 +316,7 @@ class HGraph V8_FINAL : public ZoneObject {
   HBasicBlock* entry_block() const { return entry_block_; }
   HEnvironment* start_environment() const { return start_environment_; }
 
-  void FinalizeUniqueValueIds();
+  void FinalizeUniqueness();
   bool ProcessArgumentsObject();
   void OrderBlocks();
   void AssignDominators();
index 6816654..fdb7016 100644 (file)
@@ -54,7 +54,7 @@ class UniqueSet;
 template <typename T>
 class Unique V8_FINAL {
  public:
-  // TODO(titzer): make private and introduce a factory.
+  // TODO(titzer): make private and introduce a uniqueness scope.
   explicit Unique(Handle<T> handle) {
     if (handle.is_null()) {
       raw_address_ = NULL;
@@ -111,8 +111,11 @@ class Unique V8_FINAL {
     return raw_address_ == NULL;
   }
 
-  // Extract the handle from this Unique in order to dereference it.
-  // WARNING: Only do this if you have access to the heap.
+  inline bool IsKnownGlobal(void* global) const {
+    ASSERT(IsInitialized());
+    return raw_address_ == reinterpret_cast<Address>(global);
+  }
+
   inline Handle<T> handle() const {
     return handle_;
   }
@@ -123,7 +126,11 @@ class Unique V8_FINAL {
 
   // TODO(titzer): this is a hack to migrate to Unique<T> incrementally.
   static Unique<T> CreateUninitialized(Handle<T> handle) {
-    return Unique<T>(static_cast<Address>(NULL), handle);
+    return Unique<T>(reinterpret_cast<Address>(NULL), handle);
+  }
+
+  static Unique<T> CreateImmovable(Handle<T> handle) {
+    return Unique<T>(reinterpret_cast<Address>(*handle), handle);
   }
 
   friend class UniqueSet<T>;  // Uses internal details for speed.
@@ -171,9 +178,10 @@ class UniqueSet V8_FINAL : public ZoneObject {
     return true;
   }
 
+  // Check whether this set contains the given element. O(|this|)
+  // TODO(titzer): use binary search for large sets to make this O(log|this|)
   template <typename U>
   bool Contains(Unique<U> elem) const {
-    // TODO(titzer): use binary search for larger sets.
     for (int i = 0; i < size_; i++) {
       if (this->array_[i] == elem) return true;
     }