From 00709075ea9002866075b690f007d65c9cda61ef Mon Sep 17 00:00:00 2001 From: "danno@chromium.org" Date: Wed, 26 Jun 2013 16:17:12 +0000 Subject: [PATCH] Add DependentCode to PropertyCells R=mstarzinger@chromium.org, ulan@chromium.org Review URL: https://codereview.chromium.org/17895004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15341 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/lithium-codegen-arm.cc | 2 +- src/compiler.cc | 40 +++++++++++++++++++++++----------------- src/compiler.h | 27 ++++++++++++++------------- src/heap.cc | 7 +++++-- src/ia32/lithium-codegen-ia32.cc | 2 +- src/mark-compact.cc | 38 ++++++++++++++++---------------------- src/mark-compact.h | 2 +- src/mips/lithium-codegen-mips.cc | 2 +- src/objects-inl.h | 1 + src/objects-visiting-inl.h | 29 +++++++++++++++++++++++++---- src/objects-visiting.h | 1 + src/objects.cc | 36 ++++++++++++++++++++++++++++++++---- src/objects.h | 32 +++++++++++++++++++++++++------- src/x64/lithium-codegen-x64.cc | 2 +- 14 files changed, 147 insertions(+), 74 deletions(-) diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index abf93ba..df2063e 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -87,7 +87,7 @@ void LCodeGen::FinishCode(Handle code) { RegisterDependentCodeForEmbeddedMaps(code); } PopulateDeoptimizationData(code); - info()->CommitDependentMaps(code); + info()->CommitDependencies(code); } diff --git a/src/compiler.cc b/src/compiler.cc index fbceaf9..895c31c 100644 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -118,7 +118,7 @@ void CompilationInfo::Initialize(Isolate* isolate, no_frame_ranges_ = isolate->cpu_profiler()->is_profiling() ? new List(2) : NULL; for (int i = 0; i < DependentCode::kGroupCount; i++) { - dependent_maps_[i] = NULL; + dependencies_[i] = NULL; } if (mode == STUB) { mode_ = STUB; @@ -143,36 +143,42 @@ CompilationInfo::~CompilationInfo() { // Check that no dependent maps have been added or added dependent maps have // been rolled back or committed. for (int i = 0; i < DependentCode::kGroupCount; i++) { - ASSERT_EQ(NULL, dependent_maps_[i]); + ASSERT_EQ(NULL, dependencies_[i]); } #endif // DEBUG } -void CompilationInfo::CommitDependentMaps(Handle code) { +void CompilationInfo::CommitDependencies(Handle code) { for (int i = 0; i < DependentCode::kGroupCount; i++) { - ZoneList >* group_maps = dependent_maps_[i]; - if (group_maps == NULL) continue; + ZoneList >* group_objects = dependencies_[i]; + if (group_objects == NULL) continue; ASSERT(!object_wrapper_.is_null()); - for (int j = 0; j < group_maps->length(); j++) { - group_maps->at(j)->dependent_code()->UpdateToFinishedCode( - static_cast(i), this, *code); + for (int j = 0; j < group_objects->length(); j++) { + DependentCode::DependencyGroup group = + static_cast(i); + DependentCode* dependent_code = + DependentCode::ForObject(group_objects->at(j), group); + dependent_code->UpdateToFinishedCode(group, this, *code); } - dependent_maps_[i] = NULL; // Zone-allocated, no need to delete. + dependencies_[i] = NULL; // Zone-allocated, no need to delete. } } -void CompilationInfo::RollbackDependentMaps() { +void CompilationInfo::RollbackDependencies() { // Unregister from all dependent maps if not yet committed. for (int i = 0; i < DependentCode::kGroupCount; i++) { - ZoneList >* group_maps = dependent_maps_[i]; - if (group_maps == NULL) continue; - for (int j = 0; j < group_maps->length(); j++) { - group_maps->at(j)->dependent_code()->RemoveCompilationInfo( - static_cast(i), this); + ZoneList >* group_objects = dependencies_[i]; + if (group_objects == NULL) continue; + for (int j = 0; j < group_objects->length(); j++) { + DependentCode::DependencyGroup group = + static_cast(i); + DependentCode* dependent_code = + DependentCode::ForObject(group_objects->at(j), group); + dependent_code->RemoveCompilationInfo(group, this); } - dependent_maps_[i] = NULL; // Zone-allocated, no need to delete. + dependencies_[i] = NULL; // Zone-allocated, no need to delete. } } @@ -1052,7 +1058,7 @@ void Compiler::InstallOptimizedCode(OptimizingCompiler* optimizing_compiler) { // If crankshaft succeeded, install the optimized code else install // the unoptimized code. OptimizingCompiler::Status status = optimizing_compiler->last_status(); - if (info->HasAbortedDueToDependentMap()) { + if (info->HasAbortedDueToDependencyChange()) { info->set_bailout_reason("bailed out due to dependent map"); status = optimizing_compiler->AbortOptimization(); } else if (status != OptimizingCompiler::SUCCEEDED) { diff --git a/src/compiler.h b/src/compiler.h index 5afe653..2f47dce 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -240,16 +240,17 @@ class CompilationInfo { deferred_handles_ = deferred_handles; } - ZoneList >* dependent_maps(DependentCode::DependencyGroup group) { - if (dependent_maps_[group] == NULL) { - dependent_maps_[group] = new(zone_) ZoneList >(2, zone_); + ZoneList >* dependencies( + DependentCode::DependencyGroup group) { + if (dependencies_[group] == NULL) { + dependencies_[group] = new(zone_) ZoneList >(2, zone_); } - return dependent_maps_[group]; + return dependencies_[group]; } - void CommitDependentMaps(Handle code); + void CommitDependencies(Handle code); - void RollbackDependentMaps(); + void RollbackDependencies(); void SaveHandles() { SaveHandle(&closure_); @@ -292,12 +293,12 @@ class CompilationInfo { return object_wrapper_; } - void AbortDueToDependentMap() { - mode_ = DEPENDENT_MAP_ABORT; + void AbortDueToDependencyChange() { + mode_ = DEPENDENCY_CHANGE_ABORT; } - bool HasAbortedDueToDependentMap() { - return mode_ == DEPENDENT_MAP_ABORT; + bool HasAbortedDueToDependencyChange() { + return mode_ == DEPENDENCY_CHANGE_ABORT; } protected: @@ -325,7 +326,7 @@ class CompilationInfo { OPTIMIZE, NONOPT, STUB, - DEPENDENT_MAP_ABORT + DEPENDENCY_CHANGE_ABORT }; void Initialize(Isolate* isolate, Mode mode, Zone* zone, Zone* phase_zone); @@ -408,7 +409,7 @@ class CompilationInfo { DeferredHandles* deferred_handles_; - ZoneList >* dependent_maps_[DependentCode::kGroupCount]; + ZoneList >* dependencies_[DependentCode::kGroupCount]; template void SaveHandle(Handle *object) { @@ -459,7 +460,7 @@ class CompilationInfoWithZone: public CompilationInfo { // zone scope and get rid of dependent maps even when the destructor is // called when cast as a CompilationInfo. virtual ~CompilationInfoWithZone() { - RollbackDependentMaps(); + RollbackDependencies(); } private: diff --git a/src/heap.cc b/src/heap.cc index 005a5f8..6196228 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -2859,8 +2859,11 @@ MaybeObject* Heap::AllocatePropertyCell(Object* value) { } HeapObject::cast(result)->set_map_no_write_barrier( global_property_cell_map()); - PropertyCell::cast(result)->set_value(value); - PropertyCell::cast(result)->set_type(Type::None()); + PropertyCell* cell = PropertyCell::cast(result); + cell->set_dependent_code(DependentCode::cast(empty_fixed_array()), + SKIP_WRITE_BARRIER); + cell->set_value(value); + cell->set_type(Type::None()); return result; } diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 963894b..eaab558 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -109,7 +109,7 @@ void LCodeGen::FinishCode(Handle code) { if (!info()->IsStub()) { Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code); } - info()->CommitDependentMaps(code); + info()->CommitDependencies(code); } diff --git a/src/mark-compact.cc b/src/mark-compact.cc index b7054e4..cfcfb38 100644 --- a/src/mark-compact.cc +++ b/src/mark-compact.cc @@ -2251,14 +2251,7 @@ void MarkCompactCollector::MarkLiveObjects() { while ((cell = js_global_property_cell_iterator.Next()) != NULL) { ASSERT(cell->IsPropertyCell()); if (IsMarked(cell)) { - int offset = PropertyCell::kValueOffset; - MarkCompactMarkingVisitor::VisitPointer( - heap(), - reinterpret_cast(cell->address() + offset)); - offset = PropertyCell::kTypeOffset; - MarkCompactMarkingVisitor::VisitPointer( - heap(), - reinterpret_cast(cell->address() + offset)); + MarkCompactMarkingVisitor::VisitPropertyCell(cell->map(), cell); } } } @@ -2437,11 +2430,22 @@ void MarkCompactCollector::ClearNonLiveReferences() { ClearNonLiveMapTransitions(map, map_mark); if (map_mark.Get()) { - ClearNonLiveDependentCode(map); + ClearNonLiveDependentCode(map->dependent_code()); } else { ClearAndDeoptimizeDependentCode(map); } } + + // Iterate over property cell space, removing dependent code that is not + // otherwise kept alive by strong references. + HeapObjectIterator cell_iterator(heap_->property_cell_space()); + for (HeapObject* cell = cell_iterator.Next(); + cell != NULL; + cell = cell_iterator.Next()) { + if (IsMarked(cell)) { + ClearNonLiveDependentCode(PropertyCell::cast(cell)->dependent_code()); + } + } } @@ -2527,9 +2531,8 @@ void MarkCompactCollector::ClearAndDeoptimizeDependentCode(Map* map) { } -void MarkCompactCollector::ClearNonLiveDependentCode(Map* map) { +void MarkCompactCollector::ClearNonLiveDependentCode(DependentCode* entries) { DisallowHeapAllocation no_allocation; - DependentCode* entries = map->dependent_code(); DependentCode::GroupStartIndexes starts(entries); int number_of_entries = starts.number_of_entries(); if (number_of_entries == 0) return; @@ -3398,9 +3401,7 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { cell != NULL; cell = cell_iterator.Next()) { if (cell->IsCell()) { - Address value_address = reinterpret_cast
(cell) + - (Cell::kValueOffset - kHeapObjectTag); - updating_visitor.VisitPointer(reinterpret_cast(value_address)); + Cell::BodyDescriptor::IterateBody(cell, &updating_visitor); } } @@ -3410,14 +3411,7 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { cell != NULL; cell = js_global_property_cell_iterator.Next()) { if (cell->IsPropertyCell()) { - Address value_address = - reinterpret_cast
(cell) + - (PropertyCell::kValueOffset - kHeapObjectTag); - updating_visitor.VisitPointer(reinterpret_cast(value_address)); - Address type_address = - reinterpret_cast
(cell) + - (PropertyCell::kTypeOffset - kHeapObjectTag); - updating_visitor.VisitPointer(reinterpret_cast(type_address)); + PropertyCell::BodyDescriptor::IterateBody(cell, &updating_visitor); } } diff --git a/src/mark-compact.h b/src/mark-compact.h index 85c3008..db188ed 100644 --- a/src/mark-compact.h +++ b/src/mark-compact.h @@ -880,7 +880,7 @@ class MarkCompactCollector { void ClearNonLiveMapTransitions(Map* map, MarkBit map_mark); void ClearAndDeoptimizeDependentCode(Map* map); - void ClearNonLiveDependentCode(Map* map); + void ClearNonLiveDependentCode(DependentCode* dependent_code); // Marking detaches initial maps from SharedFunctionInfo objects // to make this reference weak. We need to reattach initial maps diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 27a38ea..00a7fcf 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -87,7 +87,7 @@ void LCodeGen::FinishCode(Handle code) { RegisterDependentCodeForEmbeddedMaps(code); } PopulateDeoptimizationData(code); - info()->CommitDependentMaps(code); + info()->CommitDependencies(code); } diff --git a/src/objects-inl.h b/src/objects-inl.h index 38de6ef..ff0e865 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -1641,6 +1641,7 @@ void Cell::set_value(Object* val, WriteBarrierMode ignored) { WRITE_FIELD(this, kValueOffset, val); } +ACCESSORS(PropertyCell, dependent_code, DependentCode, kDependentCodeOffset) Object* PropertyCell::type_raw() { return READ_FIELD(this, kTypeOffset); diff --git a/src/objects-visiting-inl.h b/src/objects-visiting-inl.h index e0f6b2d..cfb7d44 100644 --- a/src/objects-visiting-inl.h +++ b/src/objects-visiting-inl.h @@ -221,10 +221,7 @@ void StaticMarkingVisitor::Initialize() { Cell::BodyDescriptor, void>::Visit); - table_.Register(kVisitPropertyCell, - &FixedBodyVisitor::Visit); + table_.Register(kVisitPropertyCell, &VisitPropertyCell); table_.template RegisterSpecializations::VisitMap( template +void StaticMarkingVisitor::VisitPropertyCell( + Map* map, HeapObject* object) { + Heap* heap = map->GetHeap(); + + Object** slot = + HeapObject::RawField(object, PropertyCell::kDependentCodeOffset); + if (FLAG_collect_maps) { + // Mark property cell dependent codes array but do not push it onto marking + // stack, this will make references from it weak. We will clean dead + // codes when we iterate over property cells in ClearNonLiveReferences. + HeapObject* obj = HeapObject::cast(*slot); + heap->mark_compact_collector()->RecordSlot(slot, slot, obj); + StaticVisitor::MarkObjectWithoutPush(heap, obj); + } else { + StaticVisitor::VisitPointer(heap, slot); + } + + StaticVisitor::VisitPointers(heap, + HeapObject::RawField(object, PropertyCell::kPointerFieldsBeginOffset), + HeapObject::RawField(object, PropertyCell::kPointerFieldsEndOffset)); +} + + +template void StaticMarkingVisitor::VisitCode( Map* map, HeapObject* object) { Heap* heap = map->GetHeap(); diff --git a/src/objects-visiting.h b/src/objects-visiting.h index f59a37d..c2ab45d 100644 --- a/src/objects-visiting.h +++ b/src/objects-visiting.h @@ -395,6 +395,7 @@ class StaticMarkingVisitor : public StaticVisitorBase { table_.GetVisitor(map)(map, obj); } + INLINE(static void VisitPropertyCell(Map* map, HeapObject* object)); INLINE(static void VisitCodeEntry(Heap* heap, Address entry_address)); INLINE(static void VisitEmbeddedPointer(Heap* heap, RelocInfo* rinfo)); INLINE(static void VisitCell(Heap* heap, RelocInfo* rinfo)); diff --git a/src/objects.cc b/src/objects.cc index 0dc26b4..70019d8 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -661,8 +661,7 @@ MaybeObject* JSObject::SetNormalizedProperty(Name* name, Object* store_value = value; if (IsGlobalObject()) { Heap* heap = name->GetHeap(); - MaybeObject* maybe_store_value = - heap->AllocatePropertyCell(value); + MaybeObject* maybe_store_value = heap->AllocatePropertyCell(value); if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; } Object* dict; @@ -11060,7 +11059,7 @@ void Map::AddDependentCompilationInfo(DependentCode::DependencyGroup group, Handle codes = DependentCode::Insert(dep, group, info->object_wrapper()); if (*codes != dependent_code()) set_dependent_code(*codes); - info->dependent_maps(group)->Add(Handle(this), info->zone()); + info->dependencies(group)->Add(Handle(this), info->zone()); } @@ -11086,6 +11085,16 @@ void DependentCode::GroupStartIndexes::Recompute(DependentCode* entries) { } +DependentCode* DependentCode::ForObject(Handle object, + DependencyGroup group) { + AllowDeferredHandleDereference dependencies_are_safe; + if (group == DependentCode::kPropertyCellChangedGroup) { + return Handle::cast(object)->dependent_code(); + } + return Handle::cast(object)->dependent_code(); +} + + Handle DependentCode::Insert(Handle entries, DependencyGroup group, Handle object) { @@ -11224,7 +11233,7 @@ void DependentCode::DeoptimizeDependentCodeGroup( code->set_marked_for_deoptimization(true); } else { CompilationInfo* info = compilation_info_at(i); - info->AbortDueToDependentMap(); + info->AbortDueToDependencyChange(); } } // Compact the array by moving all subsequent groups to fill in the new holes. @@ -15757,4 +15766,23 @@ void PropertyCell::set_type(Type* type, WriteBarrierMode ignored) { } +void PropertyCell::AddDependentCompilationInfo(CompilationInfo* info) { + Handle dep(dependent_code()); + Handle codes = + DependentCode::Insert(dep, DependentCode::kPropertyCellChangedGroup, + info->object_wrapper()); + if (*codes != dependent_code()) set_dependent_code(*codes); + info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( + Handle(this), info->zone()); +} + + +void PropertyCell::AddDependentCode(Handle code) { + Handle codes = DependentCode::Insert( + Handle(dependent_code()), + DependentCode::kPropertyCellChangedGroup, code); + if (*codes != dependent_code()) set_dependent_code(*codes); +} + + } } // namespace v8::internal diff --git a/src/objects.h b/src/objects.h index 225c740..1afdddb 100644 --- a/src/objects.h +++ b/src/objects.h @@ -5027,7 +5027,10 @@ class DependentCode: public FixedArray { // Group of code that depends on elements not being added to objects with // this map. kElementsCantBeAddedGroup, - kGroupCount = kElementsCantBeAddedGroup + 1 + // Group of code that depends on global property values in property cells + // not being changed. + kPropertyCellChangedGroup, + kGroupCount = kPropertyCellChangedGroup + 1 }; // Array for holding the index of the first code object of each group. @@ -5069,6 +5072,9 @@ class DependentCode: public FixedArray { inline void copy(int from, int to); static inline DependentCode* cast(Object* object); + static DependentCode* ForObject(Handle object, + DependencyGroup group); + private: // Make a room at the end of the given group by moving out the first // code objects of the subsequent groups. @@ -5566,7 +5572,7 @@ class Map: public HeapObject { inline bool CanOmitPrototypeChecks(); void AddDependentCompilationInfo(DependentCode::DependencyGroup group, - CompilationInfo* info); + CompilationInfo* info); void AddDependentCode(DependentCode::DependencyGroup group, Handle code); @@ -8566,9 +8572,14 @@ class Cell: public HeapObject { class PropertyCell: public Cell { public: + // [type]: type of the global property. Type* type(); void set_type(Type* value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER); + // [dependent_code]: dependent code that depends on the type of the global + // property. + DECL_ACCESSORS(dependent_code, DependentCode) + // Casting. static inline PropertyCell* cast(Object* obj); @@ -8582,12 +8593,19 @@ class PropertyCell: public Cell { // Layout description. static const int kTypeOffset = kValueOffset + kPointerSize; - static const int kSize = kTypeOffset + kPointerSize; + static const int kDependentCodeOffset = kTypeOffset + kPointerSize; + static const int kSize = kDependentCodeOffset + kPointerSize; + + static const int kPointerFieldsBeginOffset = kValueOffset; + static const int kPointerFieldsEndOffset = kDependentCodeOffset; + + typedef FixedBodyDescriptor BodyDescriptor; + + void AddDependentCompilationInfo(CompilationInfo* info); - typedef FixedBodyDescriptor< - kValueOffset, - kTypeOffset + kPointerSize, - PropertyCell::kSize> BodyDescriptor; + void AddDependentCode(Handle code); private: DECL_ACCESSORS(type_raw, Object) diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index f37b2e6..1d4ab59 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -92,7 +92,7 @@ void LCodeGen::FinishCode(Handle code) { RegisterDependentCodeForEmbeddedMaps(code); } PopulateDeoptimizationData(code); - info()->CommitDependentMaps(code); + info()->CommitDependencies(code); } -- 2.7.4