From: yangguo@chromium.org Date: Tue, 16 Apr 2013 11:00:02 +0000 (+0000) Subject: Remove relocation lock. X-Git-Tag: upstream/4.7.83~14577 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e1742a67169f858a2874417323d1075aef1c3608;p=platform%2Fupstream%2Fv8.git Remove relocation lock. Freeze HValue hash codes that are based on object addresses. R=svenpanne@chromium.org BUG= Review URL: https://chromiumcodereview.appspot.com/14040006 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14273 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/handles-inl.h b/src/handles-inl.h index b763c86..bb11311 100644 --- a/src/handles-inl.h +++ b/src/handles-inl.h @@ -59,7 +59,6 @@ inline bool Handle::is_identical_to(const Handle other) const { if (FLAG_enable_slow_asserts) { Isolate* isolate = Isolate::Current(); CHECK(isolate->AllowHandleDereference() || - Heap::RelocationLock::IsLocked(isolate->heap()) || !isolate->optimizing_compiler_thread()->IsOptimizerThread()); } #endif // DEBUG diff --git a/src/heap.cc b/src/heap.cc index 7eb6881..697261f 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -162,8 +162,7 @@ Heap::Heap() #endif promotion_queue_(this), configured_(false), - chunks_queued_for_free_(NULL), - relocation_mutex_(NULL) { + chunks_queued_for_free_(NULL) { // Allow build-time customization of the max semispace size. Building // V8 with snapshots and a non-default max semispace size is much // easier if you can define it as part of the build environment. @@ -1294,8 +1293,6 @@ class ScavengeWeakObjectRetainer : public WeakObjectRetainer { void Heap::Scavenge() { - RelocationLock relocation_lock(this); - #ifdef VERIFY_HEAP if (FLAG_verify_heap) VerifyNonPointerSpacePointers(); #endif @@ -6628,11 +6625,6 @@ bool Heap::SetUp() { store_buffer()->SetUp(); - if (FLAG_parallel_recompilation) relocation_mutex_ = OS::CreateMutex(); -#ifdef DEBUG - relocation_mutex_locked_ = false; -#endif // DEBUG - return true; } @@ -6735,8 +6727,6 @@ void Heap::TearDown() { incremental_marking()->TearDown(); isolate_->memory_allocator()->TearDown(); - - delete relocation_mutex_; } diff --git a/src/heap.h b/src/heap.h index 5f54b6c..7b4b70d 100644 --- a/src/heap.h +++ b/src/heap.h @@ -1846,38 +1846,6 @@ class Heap { void CheckpointObjectStats(); - // We don't use a ScopedLock here since we want to lock the heap - // only when FLAG_parallel_recompilation is true. - class RelocationLock { - public: - explicit RelocationLock(Heap* heap) : heap_(heap) { - if (FLAG_parallel_recompilation) { - heap_->relocation_mutex_->Lock(); -#ifdef DEBUG - heap_->relocation_mutex_locked_ = true; -#endif // DEBUG - } - } - - ~RelocationLock() { - if (FLAG_parallel_recompilation) { -#ifdef DEBUG - heap_->relocation_mutex_locked_ = false; -#endif // DEBUG - heap_->relocation_mutex_->Unlock(); - } - } - -#ifdef DEBUG - static bool IsLocked(Heap* heap) { - return heap->relocation_mutex_locked_; - } -#endif // DEBUG - - private: - Heap* heap_; - }; - private: Heap(); @@ -2347,11 +2315,6 @@ class Heap { MemoryChunk* chunks_queued_for_free_; - Mutex* relocation_mutex_; -#ifdef DEBUG - bool relocation_mutex_locked_; -#endif // DEBUG; - friend class Factory; friend class GCTracer; friend class DisallowAllocationFailure; diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index 36d1e11..60a6912 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -1584,10 +1584,10 @@ void HCheckMaps::SetSideEffectDominator(GVNFlag side_effect, // for which the map is known. if (HasNoUses() && dominator->IsStoreNamedField()) { HStoreNamedField* store = HStoreNamedField::cast(dominator); - Handle map = store->transition(); - if (map.is_null() || store->object() != value()) return; + UniqueValueId map_unique_id = store->transition_unique_id(); + if (!map_unique_id.IsInitialized() || store->object() != value()) return; for (int i = 0; i < map_set()->length(); i++) { - if (map.is_identical_to(map_set()->at(i))) { + if (map_unique_id == map_unique_ids_.at(i)) { DeleteAndReplaceWith(NULL); return; } @@ -2047,6 +2047,7 @@ static bool IsInteger32(double value) { HConstant::HConstant(Handle handle, Representation r) : handle_(handle), + unique_id_(), has_int32_value_(false), has_double_value_(false), is_internalized_string_(false), @@ -2075,11 +2076,13 @@ HConstant::HConstant(Handle handle, Representation r) HConstant::HConstant(Handle handle, + UniqueValueId unique_id, Representation r, HType type, bool is_internalize_string, bool boolean_value) : handle_(handle), + unique_id_(unique_id), has_int32_value_(false), has_double_value_(false), is_internalized_string_(is_internalize_string), @@ -2095,7 +2098,9 @@ HConstant::HConstant(Handle handle, HConstant::HConstant(int32_t integer_value, Representation r, Handle optional_handle) - : has_int32_value_(true), + : handle_(optional_handle), + unique_id_(), + has_int32_value_(true), has_double_value_(true), is_internalized_string_(false), boolean_value_(integer_value != 0), @@ -2108,7 +2113,9 @@ HConstant::HConstant(int32_t integer_value, HConstant::HConstant(double double_value, Representation r, Handle optional_handle) - : has_int32_value_(IsInteger32(double_value)), + : handle_(optional_handle), + unique_id_(), + has_int32_value_(IsInteger32(double_value)), has_double_value_(true), is_internalized_string_(false), boolean_value_(double_value != 0 && !isnan(double_value)), @@ -2133,8 +2140,12 @@ HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const { if (has_int32_value_) return new(zone) HConstant(int32_value_, r, handle_); if (has_double_value_) return new(zone) HConstant(double_value_, r, handle_); ASSERT(!handle_.is_null()); - return new(zone) HConstant( - handle_, r, type_from_value_, is_internalized_string_, boolean_value_); + return new(zone) HConstant(handle_, + unique_id_, + r, + type_from_value_, + is_internalized_string_, + boolean_value_); } @@ -2459,6 +2470,8 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context, Zone* zone) : types_(Min(types->length(), kMaxLoadPolymorphism), zone), name_(name), + types_unique_ids_(0, zone), + name_unique_id_(), need_generic_(false) { SetOperandAt(0, context); SetOperandAt(1, object); @@ -2525,15 +2538,39 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context, } +void HCheckMaps::FinalizeUniqueValueId() { + if (!map_unique_ids_.is_empty()) return; + Zone* zone = block()->zone(); + map_unique_ids_.Initialize(map_set_.length(), zone); + for (int i = 0; i < map_set_.length(); i++) { + map_unique_ids_.Add(UniqueValueId(map_set_.at(i)), zone); + } +} + + +void HLoadNamedFieldPolymorphic::FinalizeUniqueValueId() { + if (!types_unique_ids_.is_empty()) return; + Zone* zone = block()->zone(); + types_unique_ids_.Initialize(types_.length(), zone); + for (int i = 0; i < types_.length(); i++) { + types_unique_ids_.Add(UniqueValueId(types_.at(i)), zone); + } + name_unique_id_ = UniqueValueId(name_); +} + + bool HLoadNamedFieldPolymorphic::DataEquals(HValue* value) { + ASSERT_EQ(types_.length(), types_unique_ids_.length()); HLoadNamedFieldPolymorphic* other = HLoadNamedFieldPolymorphic::cast(value); - if (types_.length() != other->types()->length()) return false; - if (!name_.is_identical_to(other->name())) return false; + if (name_unique_id_ != other->name_unique_id_) return false; + if (types_unique_ids_.length() != other->types_unique_ids_.length()) { + return false; + } if (need_generic_ != other->need_generic_) return false; - for (int i = 0; i < types_.length(); i++) { + for (int i = 0; i < types_unique_ids_.length(); i++) { bool found = false; - for (int j = 0; j < types_.length(); j++) { - if (types_.at(j).is_identical_to(other->types()->at(i))) { + for (int j = 0; j < types_unique_ids_.length(); j++) { + if (types_unique_ids_.at(j) == other->types_unique_ids_.at(i)) { found = true; break; } diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index ae118a1..6853dfe 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -234,14 +234,6 @@ class LChunkBuilder; virtual Opcode opcode() const { return HValue::k##type; } -#ifdef DEBUG -#define ASSERT_ALLOCATION_DISABLED \ - ASSERT(isolate()->optimizing_compiler_thread()->IsOptimizerThread() || \ - !isolate()->heap()->IsAllocationAllowed()) -#else -#define ASSERT_ALLOCATION_DISABLED do {} while (0) -#endif - class Range: public ZoneObject { public: Range() @@ -364,6 +356,48 @@ class Representation { }; +class UniqueValueId { + public: + UniqueValueId() : raw_address_(NULL) { } + + explicit UniqueValueId(Object* object) { + raw_address_ = reinterpret_cast
(object); + ASSERT(IsInitialized()); + } + + explicit UniqueValueId(Handle handle) { + 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_); + } + + private: + Address raw_address_; +}; + + class HType { public: HType() : type_(kUninitialized) { } @@ -1057,6 +1091,9 @@ class HValue: public ZoneObject { bool Equals(HValue* other); virtual intptr_t Hashcode(); + // Compute unique ids upfront that is safe wrt GC and parallel recompilation. + virtual void FinalizeUniqueValueId() { } + // Printing support. virtual void PrintTo(StringStream* stream) = 0; void PrintNameTo(StringStream* stream); @@ -2643,7 +2680,8 @@ class HLoadExternalArrayPointer: public HUnaryOperation { class HCheckMaps: public HTemplateInstruction<2> { public: HCheckMaps(HValue* value, Handle map, Zone* zone, - HValue* typecheck = NULL) { + HValue* typecheck = NULL) + : map_unique_ids_(0, zone) { SetOperandAt(0, value); // If callers don't depend on a typecheck, they can pass in NULL. In that // case we use a copy of the |value| argument as a dummy value. @@ -2655,7 +2693,8 @@ class HCheckMaps: public HTemplateInstruction<2> { SetGVNFlag(kDependsOnElementsKind); map_set()->Add(map, zone); } - HCheckMaps(HValue* value, SmallMapList* maps, Zone* zone) { + HCheckMaps(HValue* value, SmallMapList* maps, Zone* zone) + : map_unique_ids_(0, zone) { SetOperandAt(0, value); SetOperandAt(1, value); set_representation(Representation::Tagged()); @@ -2702,28 +2741,36 @@ class HCheckMaps: public HTemplateInstruction<2> { HValue* value() { return OperandAt(0); } SmallMapList* map_set() { return &map_set_; } + virtual void FinalizeUniqueValueId(); + DECLARE_CONCRETE_INSTRUCTION(CheckMaps) protected: virtual bool DataEquals(HValue* other) { + ASSERT_EQ(map_set_.length(), map_unique_ids_.length()); HCheckMaps* b = HCheckMaps::cast(other); // Relies on the fact that map_set has been sorted before. - if (map_set()->length() != b->map_set()->length()) return false; - for (int i = 0; i < map_set()->length(); i++) { - if (!map_set()->at(i).is_identical_to(b->map_set()->at(i))) return false; + if (map_unique_ids_.length() != b->map_unique_ids_.length()) { + return false; + } + for (int i = 0; i < map_unique_ids_.length(); i++) { + if (map_unique_ids_.at(i) != b->map_unique_ids_.at(i)) { + return false; + } } return true; } private: SmallMapList map_set_; + ZoneList map_unique_ids_; }; class HCheckFunction: public HUnaryOperation { public: HCheckFunction(HValue* value, Handle function) - : HUnaryOperation(value), target_(function) { + : HUnaryOperation(value), target_(function), target_unique_id_() { set_representation(Representation::Tagged()); SetFlag(kUseGVN); target_in_new_space_ = Isolate::Current()->heap()->InNewSpace(*function); @@ -2739,6 +2786,10 @@ class HCheckFunction: public HUnaryOperation { virtual void Verify(); #endif + virtual void FinalizeUniqueValueId() { + target_unique_id_ = UniqueValueId(target_); + } + Handle target() const { return target_; } bool target_in_new_space() const { return target_in_new_space_; } @@ -2747,11 +2798,12 @@ class HCheckFunction: public HUnaryOperation { protected: virtual bool DataEquals(HValue* other) { HCheckFunction* b = HCheckFunction::cast(other); - return target_.is_identical_to(b->target()); + return target_unique_id_ == b->target_unique_id_; } private: Handle target_; + UniqueValueId target_unique_id_; bool target_in_new_space_; }; @@ -2856,7 +2908,11 @@ class HCheckPrototypeMaps: public HTemplateInstruction<0> { public: HCheckPrototypeMaps(Handle prototype, Handle holder, - Zone* zone) : prototypes_(2, zone), maps_(2, zone) { + Zone* zone) + : prototypes_(2, zone), + maps_(2, zone), + first_prototype_unique_id_(), + last_prototype_unique_id_() { SetFlag(kUseGVN); SetGVNFlag(kDependsOnMaps); // Keep a list of all objects on the prototype chain up to the holder @@ -2882,18 +2938,13 @@ class HCheckPrototypeMaps: public HTemplateInstruction<0> { virtual void PrintDataTo(StringStream* stream); virtual intptr_t Hashcode() { - ASSERT_ALLOCATION_DISABLED; - // Dereferencing to use the object's raw address for hashing is safe. - HandleDereferenceGuard allow_handle_deref(isolate(), - HandleDereferenceGuard::ALLOW); - SLOW_ASSERT(Heap::RelocationLock::IsLocked(isolate()->heap()) || - !isolate()->optimizing_compiler_thread()->IsOptimizerThread()); - intptr_t hash = 0; - for (int i = 0; i < prototypes_.length(); i++) { - hash = 17 * hash + reinterpret_cast(*prototypes_[i]); - hash = 17 * hash + reinterpret_cast(*maps_[i]); - } - return hash; + return first_prototype_unique_id_.Hashcode() * 17 + + last_prototype_unique_id_.Hashcode(); + } + + virtual void FinalizeUniqueValueId() { + first_prototype_unique_id_ = UniqueValueId(prototypes_.first()); + last_prototype_unique_id_ = UniqueValueId(prototypes_.last()); } bool CanOmitPrototypeChecks() { @@ -2906,22 +2957,15 @@ class HCheckPrototypeMaps: public HTemplateInstruction<0> { protected: virtual bool DataEquals(HValue* other) { HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other); -#ifdef DEBUG - if (prototypes_.length() != b->prototypes()->length()) return false; - for (int i = 0; i < prototypes_.length(); i++) { - if (!prototypes_[i].is_identical_to(b->prototypes()->at(i))) return false; - if (!maps_[i].is_identical_to(b->maps()->at(i))) return false; - } - return true; -#else - return prototypes_.first().is_identical_to(b->prototypes()->first()) && - prototypes_.last().is_identical_to(b->prototypes()->last()); -#endif // DEBUG + return first_prototype_unique_id_ == b->first_prototype_unique_id_ && + last_prototype_unique_id_ == b->last_prototype_unique_id_; } private: ZoneList > prototypes_; ZoneList > maps_; + UniqueValueId first_prototype_unique_id_; + UniqueValueId last_prototype_unique_id_; }; @@ -3176,6 +3220,7 @@ class HConstant: public HTemplateInstruction<0> { Representation r, Handle optional_handle = Handle::null()); HConstant(Handle handle, + UniqueValueId unique_id, Representation r, HType type, bool is_internalized_string, @@ -3189,8 +3234,6 @@ class HConstant: public HTemplateInstruction<0> { return handle_; } - bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); } - bool IsSpecialDouble() const { return has_double_value_ && (BitCast(double_value_) == BitCast(-0.0) || @@ -3210,20 +3253,17 @@ class HConstant: public HTemplateInstruction<0> { } ASSERT(!handle_.is_null()); + HandleDereferenceGuard allow_dereference_for_immovable_check( + isolate(), HandleDereferenceGuard::ALLOW); Heap* heap = isolate()->heap(); - // We should have handled minus_zero_value and nan_value in the - // has_double_value_ clause above. - // Dereferencing is safe to compare against immovable singletons. - HandleDereferenceGuard allow_handle_deref(isolate(), - HandleDereferenceGuard::ALLOW); - ASSERT(*handle_ != heap->minus_zero_value()); - ASSERT(*handle_ != heap->nan_value()); - return *handle_ == heap->undefined_value() || - *handle_ == heap->null_value() || - *handle_ == heap->true_value() || - *handle_ == heap->false_value() || - *handle_ == heap->the_hole_value() || - *handle_ == heap->empty_string(); + ASSERT(unique_id_ != UniqueValueId(heap->minus_zero_value())); + ASSERT(unique_id_ != UniqueValueId(heap->nan_value())); + return unique_id_ == UniqueValueId(heap->undefined_value()) || + unique_id_ == UniqueValueId(heap->null_value()) || + unique_id_ == UniqueValueId(heap->true_value()) || + unique_id_ == UniqueValueId(heap->false_value()) || + unique_id_ == UniqueValueId(heap->the_hole_value()) || + unique_id_ == UniqueValueId(heap->empty_string()); } virtual Representation RequiredInputRepresentation(int index) { @@ -3293,24 +3333,21 @@ class HConstant: public HTemplateInstruction<0> { } virtual intptr_t Hashcode() { - ASSERT_ALLOCATION_DISABLED; - intptr_t hash; - if (has_int32_value_) { - hash = static_cast(int32_value_); + return static_cast(int32_value_); } else if (has_double_value_) { - hash = static_cast(BitCast(double_value_)); + return static_cast(BitCast(double_value_)); } else { ASSERT(!handle_.is_null()); - // Dereferencing to use the object's raw address for hashing is safe. - HandleDereferenceGuard allow_handle_deref(isolate(), - HandleDereferenceGuard::ALLOW); - SLOW_ASSERT(Heap::RelocationLock::IsLocked(isolate()->heap()) || - !isolate()->optimizing_compiler_thread()->IsOptimizerThread()); - hash = reinterpret_cast(*handle_); + return unique_id_.Hashcode(); } + } - return hash; + virtual void FinalizeUniqueValueId() { + if (!has_double_value_) { + ASSERT(!handle_.is_null()); + unique_id_ = UniqueValueId(handle_); + } } #ifdef DEBUG @@ -3334,7 +3371,7 @@ class HConstant: public HTemplateInstruction<0> { } else { ASSERT(!handle_.is_null()); return !other_constant->handle_.is_null() && - handle_.is_identical_to(other_constant->handle_); + unique_id_ == other_constant->unique_id_; } } @@ -3348,6 +3385,7 @@ class HConstant: public HTemplateInstruction<0> { // constant is non-numeric, handle_ always points to a valid // constant HeapObject. Handle handle_; + UniqueValueId unique_id_; // We store the HConstant in the most specific form safely possible. // The two flags, has_int32_value_ and has_double_value_ tell us if @@ -4759,7 +4797,7 @@ class HUnknownOSRValue: public HTemplateInstruction<0> { class HLoadGlobalCell: public HTemplateInstruction<0> { public: HLoadGlobalCell(Handle cell, PropertyDetails details) - : cell_(cell), details_(details) { + : cell_(cell), details_(details), unique_id_() { set_representation(Representation::Tagged()); SetFlag(kUseGVN); SetGVNFlag(kDependsOnGlobalVars); @@ -4771,13 +4809,11 @@ class HLoadGlobalCell: public HTemplateInstruction<0> { virtual void PrintDataTo(StringStream* stream); virtual intptr_t Hashcode() { - ASSERT_ALLOCATION_DISABLED; - // Dereferencing to use the object's raw address for hashing is safe. - HandleDereferenceGuard allow_handle_deref(isolate(), - HandleDereferenceGuard::ALLOW); - SLOW_ASSERT(Heap::RelocationLock::IsLocked(isolate()->heap()) || - !isolate()->optimizing_compiler_thread()->IsOptimizerThread()); - return reinterpret_cast(*cell_); + return unique_id_.Hashcode(); + } + + virtual void FinalizeUniqueValueId() { + unique_id_ = UniqueValueId(cell_); } virtual Representation RequiredInputRepresentation(int index) { @@ -4789,7 +4825,7 @@ class HLoadGlobalCell: public HTemplateInstruction<0> { protected: virtual bool DataEquals(HValue* other) { HLoadGlobalCell* b = HLoadGlobalCell::cast(other); - return cell_.is_identical_to(b->cell()); + return unique_id_ == b->unique_id_; } private: @@ -4797,6 +4833,7 @@ class HLoadGlobalCell: public HTemplateInstruction<0> { Handle cell_; PropertyDetails details_; + UniqueValueId unique_id_; }; @@ -5255,12 +5292,16 @@ class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> { static const int kMaxLoadPolymorphism = 4; + virtual void FinalizeUniqueValueId(); + protected: virtual bool DataEquals(HValue* value); private: SmallMapList types_; Handle name_; + ZoneList types_unique_ids_; + UniqueValueId name_unique_id_; bool need_generic_; }; @@ -5524,6 +5565,7 @@ class HStoreNamedField: public HTemplateInstruction<2> { : name_(name), is_in_object_(in_object), offset_(offset), + transition_unique_id_(), new_space_dominator_(NULL) { SetOperandAt(0, obj); SetOperandAt(1, val); @@ -5554,6 +5596,7 @@ class HStoreNamedField: public HTemplateInstruction<2> { bool is_in_object() const { return is_in_object_; } int offset() const { return offset_; } Handle transition() const { return transition_; } + UniqueValueId transition_unique_id() const { return transition_unique_id_; } void set_transition(Handle map) { transition_ = map; } HValue* new_space_dominator() const { return new_space_dominator_; } @@ -5566,11 +5609,16 @@ class HStoreNamedField: public HTemplateInstruction<2> { return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); } + virtual void FinalizeUniqueValueId() { + transition_unique_id_ = UniqueValueId(transition_); + } + private: Handle name_; bool is_in_object_; int offset_; Handle transition_; + UniqueValueId transition_unique_id_; HValue* new_space_dominator_; }; @@ -5771,6 +5819,8 @@ class HTransitionElementsKind: public HTemplateInstruction<2> { Handle transitioned_map) : original_map_(original_map), transitioned_map_(transitioned_map), + original_map_unique_id_(), + transitioned_map_unique_id_(), from_kind_(original_map->elements_kind()), to_kind_(transitioned_map->elements_kind()) { SetOperandAt(0, object); @@ -5801,18 +5851,25 @@ class HTransitionElementsKind: public HTemplateInstruction<2> { virtual void PrintDataTo(StringStream* stream); + virtual void FinalizeUniqueValueId() { + original_map_unique_id_ = UniqueValueId(original_map_); + transitioned_map_unique_id_ = UniqueValueId(transitioned_map_); + } + DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind) protected: virtual bool DataEquals(HValue* other) { HTransitionElementsKind* instr = HTransitionElementsKind::cast(other); - return original_map_.is_identical_to(instr->original_map()) && - transitioned_map_.is_identical_to(instr->transitioned_map()); + return original_map_unique_id_ == instr->original_map_unique_id_ && + transitioned_map_unique_id_ == instr->transitioned_map_unique_id_; } private: Handle original_map_; Handle transitioned_map_; + UniqueValueId original_map_unique_id_; + UniqueValueId transitioned_map_unique_id_; ElementsKind from_kind_; ElementsKind to_kind_; }; diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 9bfc110..ee6e346 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -517,7 +517,6 @@ class ReachabilityAnalyzer BASE_EMBEDDED { void HGraph::Verify(bool do_full_verify) const { // Allow dereferencing for debug mode verification. - Heap::RelocationLock(isolate()->heap()); HandleDereferenceGuard allow_handle_deref(isolate(), HandleDereferenceGuard::ALLOW); for (int i = 0; i < blocks_.length(); i++) { @@ -619,6 +618,7 @@ HConstant* HGraph::GetConstant##Name() { \ if (!constant_##name##_.is_set()) { \ HConstant* constant = new(zone()) HConstant( \ isolate()->factory()->name##_value(), \ + UniqueValueId(isolate()->heap()->name##_value()), \ Representation::Tagged(), \ htype, \ false, \ @@ -880,6 +880,7 @@ HGraph* HGraphBuilder::CreateGraph() { HPhase phase("H_Block building", isolate()); set_current_block(graph()->entry_block()); if (!BuildGraph()) return NULL; + graph()->FinalizeUniqueValueIds(); return graph_; } @@ -1696,6 +1697,19 @@ HBasicBlock* HGraph::CreateBasicBlock() { } +void HGraph::FinalizeUniqueValueIds() { + AssertNoAllocation no_gc; + ASSERT(!isolate()->optimizing_compiler_thread()->IsOptimizerThread()); + for (int i = 0; i < blocks()->length(); ++i) { + for (HInstruction* instr = blocks()->at(i)->first(); + instr != NULL; + instr = instr->next()) { + instr->FinalizeUniqueValueId(); + } + } +} + + void HGraph::Canonicalize() { if (!FLAG_use_canonicalizing) return; HPhase phase("H_Canonicalize", this); @@ -4327,8 +4341,6 @@ bool HOptimizedGraphBuilder::BuildGraph() { void HGraph::GlobalValueNumbering() { // Perform common subexpression elimination and loop-invariant code motion. if (FLAG_use_gvn) { - // We use objects' raw addresses for identification, so they must not move. - Heap::RelocationLock relocation_lock(isolate()->heap()); HPhase phase("H_Global value numbering", this); HGlobalValueNumberer gvn(this, info()); bool removed_side_effects = gvn.Analyze(); diff --git a/src/hydrogen.h b/src/hydrogen.h index 0d5f5c9..3dbca3c 100644 --- a/src/hydrogen.h +++ b/src/hydrogen.h @@ -260,6 +260,7 @@ class HGraph: public ZoneObject { HBasicBlock* entry_block() const { return entry_block_; } HEnvironment* start_environment() const { return start_environment_; } + void FinalizeUniqueValueIds(); void InitializeInferredTypes(); void InsertTypeConversions(); void MergeRemovableSimulates(); diff --git a/src/mark-compact.cc b/src/mark-compact.cc index 63263ba..f49179f 100644 --- a/src/mark-compact.cc +++ b/src/mark-compact.cc @@ -3125,8 +3125,6 @@ void MarkCompactCollector::ProcessInvalidatedCode(ObjectVisitor* visitor) { void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { - Heap::RelocationLock relocation_lock(heap()); - bool code_slots_filtering_required; { GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP_NEWSPACE); code_slots_filtering_required = MarkInvalidatedCode();