Add DependentCode to PropertyCells
authordanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 26 Jun 2013 16:17:12 +0000 (16:17 +0000)
committerdanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 26 Jun 2013 16:17:12 +0000 (16:17 +0000)
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

14 files changed:
src/arm/lithium-codegen-arm.cc
src/compiler.cc
src/compiler.h
src/heap.cc
src/ia32/lithium-codegen-ia32.cc
src/mark-compact.cc
src/mark-compact.h
src/mips/lithium-codegen-mips.cc
src/objects-inl.h
src/objects-visiting-inl.h
src/objects-visiting.h
src/objects.cc
src/objects.h
src/x64/lithium-codegen-x64.cc

index abf93ba..df2063e 100644 (file)
@@ -87,7 +87,7 @@ void LCodeGen::FinishCode(Handle<Code> code) {
     RegisterDependentCodeForEmbeddedMaps(code);
   }
   PopulateDeoptimizationData(code);
-  info()->CommitDependentMaps(code);
+  info()->CommitDependencies(code);
 }
 
 
index fbceaf9..895c31c 100644 (file)
@@ -118,7 +118,7 @@ void CompilationInfo::Initialize(Isolate* isolate,
   no_frame_ranges_ = isolate->cpu_profiler()->is_profiling()
                    ? new List<OffsetRange>(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> code) {
+void CompilationInfo::CommitDependencies(Handle<Code> code) {
   for (int i = 0; i < DependentCode::kGroupCount; i++) {
-    ZoneList<Handle<Map> >* group_maps = dependent_maps_[i];
-    if (group_maps == NULL) continue;
+    ZoneList<Handle<HeapObject> >* 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<DependentCode::DependencyGroup>(i), this, *code);
+    for (int j = 0; j < group_objects->length(); j++) {
+      DependentCode::DependencyGroup group =
+          static_cast<DependentCode::DependencyGroup>(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<Handle<Map> >* 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<DependentCode::DependencyGroup>(i), this);
+    ZoneList<Handle<HeapObject> >* group_objects = dependencies_[i];
+    if (group_objects == NULL) continue;
+    for (int j = 0; j < group_objects->length(); j++) {
+      DependentCode::DependencyGroup group =
+          static_cast<DependentCode::DependencyGroup>(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) {
index 5afe653..2f47dce 100644 (file)
@@ -240,16 +240,17 @@ class CompilationInfo {
     deferred_handles_ = deferred_handles;
   }
 
-  ZoneList<Handle<Map> >* dependent_maps(DependentCode::DependencyGroup group) {
-    if (dependent_maps_[group] == NULL) {
-      dependent_maps_[group] = new(zone_) ZoneList<Handle<Map> >(2, zone_);
+  ZoneList<Handle<HeapObject> >* dependencies(
+      DependentCode::DependencyGroup group) {
+    if (dependencies_[group] == NULL) {
+      dependencies_[group] = new(zone_) ZoneList<Handle<HeapObject> >(2, zone_);
     }
-    return dependent_maps_[group];
+    return dependencies_[group];
   }
 
-  void CommitDependentMaps(Handle<Code> code);
+  void CommitDependencies(Handle<Code> 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<Handle<Map> >* dependent_maps_[DependentCode::kGroupCount];
+  ZoneList<Handle<HeapObject> >* dependencies_[DependentCode::kGroupCount];
 
   template<typename T>
   void SaveHandle(Handle<T> *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:
index 005a5f8..6196228 100644 (file)
@@ -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;
 }
 
index 963894b..eaab558 100644 (file)
@@ -109,7 +109,7 @@ void LCodeGen::FinishCode(Handle<Code> code) {
   if (!info()->IsStub()) {
     Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);
   }
-  info()->CommitDependentMaps(code);
+  info()->CommitDependencies(code);
 }
 
 
index b7054e4..cfcfb38 100644 (file)
@@ -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<Object**>(cell->address() + offset));
-          offset = PropertyCell::kTypeOffset;
-          MarkCompactMarkingVisitor::VisitPointer(
-              heap(),
-              reinterpret_cast<Object**>(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<Address>(cell) +
-          (Cell::kValueOffset - kHeapObjectTag);
-      updating_visitor.VisitPointer(reinterpret_cast<Object**>(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<Address>(cell) +
-          (PropertyCell::kValueOffset - kHeapObjectTag);
-      updating_visitor.VisitPointer(reinterpret_cast<Object**>(value_address));
-      Address type_address =
-          reinterpret_cast<Address>(cell) +
-          (PropertyCell::kTypeOffset - kHeapObjectTag);
-      updating_visitor.VisitPointer(reinterpret_cast<Object**>(type_address));
+      PropertyCell::BodyDescriptor::IterateBody(cell, &updating_visitor);
     }
   }
 
index 85c3008..db188ed 100644 (file)
@@ -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
index 27a38ea..00a7fcf 100644 (file)
@@ -87,7 +87,7 @@ void LCodeGen::FinishCode(Handle<Code> code) {
     RegisterDependentCodeForEmbeddedMaps(code);
   }
   PopulateDeoptimizationData(code);
-  info()->CommitDependentMaps(code);
+  info()->CommitDependencies(code);
 }
 
 
index 38de6ef..ff0e865 100644 (file)
@@ -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);
index e0f6b2d..cfb7d44 100644 (file)
@@ -221,10 +221,7 @@ void StaticMarkingVisitor<StaticVisitor>::Initialize() {
                   Cell::BodyDescriptor,
                   void>::Visit);
 
-  table_.Register(kVisitPropertyCell,
-                  &FixedBodyVisitor<StaticVisitor,
-                  PropertyCell::BodyDescriptor,
-                  void>::Visit);
+  table_.Register(kVisitPropertyCell, &VisitPropertyCell);
 
   table_.template RegisterSpecializations<DataObjectVisitor,
                                           kVisitDataObject,
@@ -359,6 +356,30 @@ void StaticMarkingVisitor<StaticVisitor>::VisitMap(
 
 
 template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::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<typename StaticVisitor>
 void StaticMarkingVisitor<StaticVisitor>::VisitCode(
     Map* map, HeapObject* object) {
   Heap* heap = map->GetHeap();
index f59a37d..c2ab45d 100644 (file)
@@ -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));
index 0dc26b4..70019d8 100644 (file)
@@ -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<DependentCode> codes =
       DependentCode::Insert(dep, group, info->object_wrapper());
   if (*codes != dependent_code()) set_dependent_code(*codes);
-  info->dependent_maps(group)->Add(Handle<Map>(this), info->zone());
+  info->dependencies(group)->Add(Handle<HeapObject>(this), info->zone());
 }
 
 
@@ -11086,6 +11085,16 @@ void DependentCode::GroupStartIndexes::Recompute(DependentCode* entries) {
 }
 
 
+DependentCode* DependentCode::ForObject(Handle<HeapObject> object,
+                                        DependencyGroup group) {
+  AllowDeferredHandleDereference dependencies_are_safe;
+  if (group == DependentCode::kPropertyCellChangedGroup) {
+    return Handle<PropertyCell>::cast(object)->dependent_code();
+  }
+  return Handle<Map>::cast(object)->dependent_code();
+}
+
+
 Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries,
                                             DependencyGroup group,
                                             Handle<Object> 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<DependentCode> dep(dependent_code());
+  Handle<DependentCode> codes =
+      DependentCode::Insert(dep, DependentCode::kPropertyCellChangedGroup,
+                            info->object_wrapper());
+  if (*codes != dependent_code()) set_dependent_code(*codes);
+  info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add(
+      Handle<HeapObject>(this), info->zone());
+}
+
+
+void PropertyCell::AddDependentCode(Handle<Code> code) {
+  Handle<DependentCode> codes = DependentCode::Insert(
+      Handle<DependentCode>(dependent_code()),
+      DependentCode::kPropertyCellChangedGroup, code);
+  if (*codes != dependent_code()) set_dependent_code(*codes);
+}
+
+
 } }  // namespace v8::internal
index 225c740..1afdddb 100644 (file)
@@ -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<HeapObject> 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> 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<kValueOffset,
+                              kSize,
+                              kSize> BodyDescriptor;
+
+  void AddDependentCompilationInfo(CompilationInfo* info);
 
-  typedef FixedBodyDescriptor<
-      kValueOffset,
-      kTypeOffset + kPointerSize,
-      PropertyCell::kSize> BodyDescriptor;
+  void AddDependentCode(Handle<Code> code);
 
  private:
   DECL_ACCESSORS(type_raw, Object)
index f37b2e6..1d4ab59 100644 (file)
@@ -92,7 +92,7 @@ void LCodeGen::FinishCode(Handle<Code> code) {
     RegisterDependentCodeForEmbeddedMaps(code);
   }
   PopulateDeoptimizationData(code);
-  info()->CommitDependentMaps(code);
+  info()->CommitDependencies(code);
 }