From cee5773017617f55e9b8ab6b4ff565dd0d95c04c Mon Sep 17 00:00:00 2001 From: "titzer@chromium.org" Date: Tue, 24 Sep 2013 09:48:39 +0000 Subject: [PATCH] Use Unique in HConstant and remove UniqueValueId. 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 | 86 +++++++++--------------- src/hydrogen-instructions.h | 152 +++++++++++-------------------------------- src/hydrogen.cc | 9 ++- src/hydrogen.h | 2 +- src/unique.h | 18 +++-- 5 files changed, 88 insertions(+), 179 deletions(-) diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index a685198..d301036 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -2363,8 +2363,7 @@ static bool IsInteger32(double value) { HConstant::HConstant(Handle handle, Representation r) : HTemplateInstruction<0>(HType::TypeFromValue(handle)), - handle_(handle), - unique_id_(), + object_(Unique::CreateUninitialized(handle)), has_smi_value_(false), has_int32_value_(false), has_double_value_(false), @@ -2373,29 +2372,28 @@ HConstant::HConstant(Handle 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::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 handle, - UniqueValueId unique_id, +HConstant::HConstant(Unique unique, Representation r, HType type, bool is_internalize_string, @@ -2403,8 +2401,7 @@ HConstant::HConstant(Handle 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 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 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 optional_handle) - : handle_(optional_handle), - unique_id_(), + Unique 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 optional_handle) - : handle_(optional_handle), - unique_id_(), + Unique 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(Handle::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) { - if (!object->IsJSObject()) return; - Handle js_object = Handle::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_.handle(); + if (object->IsJSObject()) { + // Try to eagerly migrate JSObjects that have deprecated maps. + Handle js_object = Handle::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::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(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); diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index a5cfe3b..b06d6e5 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -306,65 +306,6 @@ class Range V8_FINAL : public ZoneObject { }; -class UniqueValueId V8_FINAL { - public: - UniqueValueId() : raw_address_(NULL) { } - - explicit UniqueValueId(Handle handle) { - ASSERT(!AllowHeapAllocation::IsAllowed()); - static const Address kEmptyHandleSentinel = reinterpret_cast
(1); - if (handle.is_null()) { - raw_address_ = kEmptyHandleSentinel; - } else { - raw_address_ = reinterpret_cast
(*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(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
(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(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); - DECLARE_INSTRUCTION_FACTORY_P2(HConstant, Handle, UniqueValueId); DECLARE_INSTRUCTION_FACTORY_P1(HConstant, ExternalReference); static HConstant* CreateAndInsertAfter(Zone* zone, @@ -3323,15 +3263,15 @@ class HConstant V8_FINAL : public HTemplateInstruction<0> { } Handle 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::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) { @@ -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 StringValue() const { ASSERT(HasStringValue()); - return Handle::cast(handle_); + return Handle::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(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_.handle()); } } - bool UniqueValueIdsMatch(UniqueValueId other) { - return !has_double_value_ && !has_external_reference_value_ && - unique_id_ == other; - } - Unique GetUnique() const { - // TODO(titzer): store a Unique inside the HConstant. - Address raw_address = reinterpret_cast
(unique_id_.Hashcode()); - return Unique(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 optional_handle = Handle::null()); + Unique optional = Unique(Handle::null())); HConstant(double value, Representation r = Representation::None(), bool is_not_in_new_space = true, - Handle optional_handle = Handle::null()); - HConstant(Handle handle, - UniqueValueId unique_id, + Unique optional = Unique(Handle::null())); + HConstant(Unique unique, Representation r, HType type, bool is_internalized_string, bool is_not_in_new_space, bool is_cell, bool boolean_value); - HConstant(Handle 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 handle_; - UniqueValueId unique_id_; + Unique 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_.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(cell_.handle()); } diff --git a/src/hydrogen.cc b/src/hydrogen.cc index f3f875e..0a7e9f0 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -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::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(); } } } diff --git a/src/hydrogen.h b/src/hydrogen.h index 35433bd..6aa8217 100644 --- a/src/hydrogen.h +++ b/src/hydrogen.h @@ -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(); diff --git a/src/unique.h b/src/unique.h index 6816654..fdb7016 100644 --- a/src/unique.h +++ b/src/unique.h @@ -54,7 +54,7 @@ class UniqueSet; template 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 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
(global); + } + inline Handle handle() const { return handle_; } @@ -123,7 +126,11 @@ class Unique V8_FINAL { // TODO(titzer): this is a hack to migrate to Unique incrementally. static Unique CreateUninitialized(Handle handle) { - return Unique(static_cast
(NULL), handle); + return Unique(reinterpret_cast
(NULL), handle); + } + + static Unique CreateImmovable(Handle handle) { + return Unique(reinterpret_cast
(*handle), handle); } friend class UniqueSet; // 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 bool Contains(Unique elem) const { - // TODO(titzer): use binary search for larger sets. for (int i = 0; i < size_; i++) { if (this->array_[i] == elem) return true; } -- 2.7.4