Treat pointers in optimized code as strong before all weak dependencies are registered.
authorulan <ulan@chromium.org>
Thu, 22 Jan 2015 15:30:48 +0000 (07:30 -0800)
committerCommit bot <commit-bot@chromium.org>
Thu, 22 Jan 2015 15:31:04 +0000 (15:31 +0000)
This prevents GC from observing code objects with out-of-sync weak dependencies.

BUG=v8:3823
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#26225}

14 files changed:
src/arm/lithium-codegen-arm.cc
src/arm64/lithium-codegen-arm64.cc
src/heap/heap-inl.h
src/heap/heap.h
src/ia32/lithium-codegen-ia32.cc
src/lithium-codegen.cc
src/lithium.cc
src/lithium.h
src/mips/lithium-codegen-mips.cc
src/mips64/lithium-codegen-mips64.cc
src/objects-inl.h
src/objects.h
src/x64/lithium-codegen-x64.cc
src/x87/lithium-codegen-x87.cc

index 26be241..7c2ba97 100644 (file)
@@ -61,7 +61,6 @@ void LCodeGen::FinishCode(Handle<Code> code) {
   DCHECK(is_done());
   code->set_stack_slots(GetStackSlotCount());
   code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
-  if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
   PopulateDeoptimizationData(code);
 }
 
index 2c41989..53793f8 100644 (file)
@@ -918,7 +918,6 @@ void LCodeGen::FinishCode(Handle<Code> code) {
   DCHECK(is_done());
   code->set_stack_slots(GetStackSlotCount());
   code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
-  if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
   PopulateDeoptimizationData(code);
 }
 
index 549ecbc..6048d3e 100644 (file)
@@ -729,20 +729,6 @@ AlwaysAllocateScope::~AlwaysAllocateScope() {
 }
 
 
-#ifdef VERIFY_HEAP
-NoWeakObjectVerificationScope::NoWeakObjectVerificationScope() {
-  Isolate* isolate = Isolate::Current();
-  isolate->heap()->no_weak_object_verification_scope_depth_++;
-}
-
-
-NoWeakObjectVerificationScope::~NoWeakObjectVerificationScope() {
-  Isolate* isolate = Isolate::Current();
-  isolate->heap()->no_weak_object_verification_scope_depth_--;
-}
-#endif
-
-
 GCCallbacksScope::GCCallbacksScope(Heap* heap) : heap_(heap) {
   heap_->gc_callbacks_depth_++;
 }
index 5fc3f07..2ae4165 100644 (file)
@@ -2133,9 +2133,6 @@ class Heap {
   friend class MarkCompactCollector;
   friend class MarkCompactMarkingVisitor;
   friend class MapCompact;
-#ifdef VERIFY_HEAP
-  friend class NoWeakObjectVerificationScope;
-#endif
   friend class Page;
 
   DISALLOW_COPY_AND_ASSIGN(Heap);
@@ -2189,15 +2186,6 @@ class AlwaysAllocateScope {
 };
 
 
-#ifdef VERIFY_HEAP
-class NoWeakObjectVerificationScope {
- public:
-  inline NoWeakObjectVerificationScope();
-  inline ~NoWeakObjectVerificationScope();
-};
-#endif
-
-
 class GCCallbacksScope {
  public:
   explicit inline GCCallbacksScope(Heap* heap);
index 076ae72..ff35b8a 100644 (file)
@@ -75,7 +75,6 @@ void LCodeGen::FinishCode(Handle<Code> code) {
   DCHECK(is_done());
   code->set_stack_slots(GetStackSlotCount());
   code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
-  if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
   PopulateDeoptimizationData(code);
   if (!info()->IsStub()) {
     Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);
index 27c5c01..3ca47e1 100644 (file)
@@ -170,66 +170,6 @@ int LCodeGenBase::GetNextEmittedBlock() const {
 }
 
 
-static void AddWeakObjectToCodeDependency(Isolate* isolate,
-                                          Handle<Object> object,
-                                          Handle<Code> code) {
-  Heap* heap = isolate->heap();
-  heap->EnsureWeakObjectToCodeTable();
-  Handle<DependentCode> dep(heap->LookupWeakObjectToCodeDependency(object));
-  dep = DependentCode::Insert(dep, DependentCode::kWeakCodeGroup, code);
-  heap->AddWeakObjectToCodeDependency(object, dep);
-}
-
-
-void LCodeGenBase::RegisterWeakObjectsInOptimizedCode(Handle<Code> code) {
-  DCHECK(code->is_optimized_code());
-  ZoneList<Handle<Map> > maps(1, zone());
-  ZoneList<Handle<JSObject> > objects(1, zone());
-  ZoneList<Handle<Cell> > cells(1, zone());
-  int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
-                  RelocInfo::ModeMask(RelocInfo::CELL);
-  for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
-    RelocInfo::Mode mode = it.rinfo()->rmode();
-    if (mode == RelocInfo::CELL &&
-        code->IsWeakObjectInOptimizedCode(it.rinfo()->target_cell())) {
-      Handle<Cell> cell(it.rinfo()->target_cell());
-      cells.Add(cell, zone());
-    } else if (mode == RelocInfo::EMBEDDED_OBJECT &&
-               code->IsWeakObjectInOptimizedCode(it.rinfo()->target_object())) {
-      if (it.rinfo()->target_object()->IsMap()) {
-        Handle<Map> map(Map::cast(it.rinfo()->target_object()));
-        maps.Add(map, zone());
-      } else if (it.rinfo()->target_object()->IsJSObject()) {
-        Handle<JSObject> object(JSObject::cast(it.rinfo()->target_object()));
-        objects.Add(object, zone());
-      } else if (it.rinfo()->target_object()->IsCell()) {
-        Handle<Cell> cell(Cell::cast(it.rinfo()->target_object()));
-        cells.Add(cell, zone());
-      }
-    }
-  }
-  if (FLAG_enable_ool_constant_pool) {
-    code->constant_pool()->set_weak_object_state(
-        ConstantPoolArray::WEAK_OBJECTS_IN_OPTIMIZED_CODE);
-  }
-#ifdef VERIFY_HEAP
-  // This disables verification of weak embedded objects after full GC.
-  // AddDependentCode can cause a GC, which would observe the state where
-  // this code is not yet in the depended code lists of the embedded maps.
-  NoWeakObjectVerificationScope disable_verification_of_embedded_objects;
-#endif
-  for (int i = 0; i < maps.length(); i++) {
-    Map::AddDependentCode(maps.at(i), DependentCode::kWeakCodeGroup, code);
-  }
-  for (int i = 0; i < objects.length(); i++) {
-    AddWeakObjectToCodeDependency(isolate(), objects.at(i), code);
-  }
-  for (int i = 0; i < cells.length(); i++) {
-    AddWeakObjectToCodeDependency(isolate(), cells.at(i), code);
-  }
-}
-
-
 void LCodeGenBase::Abort(BailoutReason reason) {
   info()->AbortOptimization(reason);
   status_ = ABORTED;
index 7e2f1a6..43d690c 100644 (file)
@@ -413,6 +413,61 @@ Representation LChunk::LookupLiteralRepresentation(
 }
 
 
+static void AddWeakObjectToCodeDependency(Isolate* isolate,
+                                          Handle<Object> object,
+                                          Handle<Code> code) {
+  Heap* heap = isolate->heap();
+  heap->EnsureWeakObjectToCodeTable();
+  Handle<DependentCode> dep(heap->LookupWeakObjectToCodeDependency(object));
+  dep = DependentCode::Insert(dep, DependentCode::kWeakCodeGroup, code);
+  heap->AddWeakObjectToCodeDependency(object, dep);
+}
+
+
+void LChunk::RegisterWeakObjectsInOptimizedCode(Handle<Code> code) const {
+  DCHECK(code->is_optimized_code());
+  ZoneList<Handle<Map> > maps(1, zone());
+  ZoneList<Handle<JSObject> > objects(1, zone());
+  ZoneList<Handle<Cell> > cells(1, zone());
+  int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
+                  RelocInfo::ModeMask(RelocInfo::CELL);
+  for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
+    RelocInfo::Mode mode = it.rinfo()->rmode();
+    if (mode == RelocInfo::CELL &&
+        code->IsWeakObjectInOptimizedCode(it.rinfo()->target_cell())) {
+      Handle<Cell> cell(it.rinfo()->target_cell());
+      cells.Add(cell, zone());
+    } else if (mode == RelocInfo::EMBEDDED_OBJECT &&
+               code->IsWeakObjectInOptimizedCode(it.rinfo()->target_object())) {
+      if (it.rinfo()->target_object()->IsMap()) {
+        Handle<Map> map(Map::cast(it.rinfo()->target_object()));
+        maps.Add(map, zone());
+      } else if (it.rinfo()->target_object()->IsJSObject()) {
+        Handle<JSObject> object(JSObject::cast(it.rinfo()->target_object()));
+        objects.Add(object, zone());
+      } else if (it.rinfo()->target_object()->IsCell()) {
+        Handle<Cell> cell(Cell::cast(it.rinfo()->target_object()));
+        cells.Add(cell, zone());
+      }
+    }
+  }
+  for (int i = 0; i < maps.length(); i++) {
+    Map::AddDependentCode(maps.at(i), DependentCode::kWeakCodeGroup, code);
+  }
+  for (int i = 0; i < objects.length(); i++) {
+    AddWeakObjectToCodeDependency(isolate(), objects.at(i), code);
+  }
+  for (int i = 0; i < cells.length(); i++) {
+    AddWeakObjectToCodeDependency(isolate(), cells.at(i), code);
+  }
+  if (FLAG_enable_ool_constant_pool) {
+    code->constant_pool()->set_weak_object_state(
+        ConstantPoolArray::WEAK_OBJECTS_IN_OPTIMIZED_CODE);
+  }
+  code->set_can_have_weak_objects(true);
+}
+
+
 void LChunk::CommitDependencies(Handle<Code> code) const {
   for (MapSet::const_iterator it = deprecation_dependencies_.begin(),
        iend = deprecation_dependencies_.end(); it != iend; ++it) {
@@ -431,6 +486,7 @@ void LChunk::CommitDependencies(Handle<Code> code) const {
   }
 
   info_->CommitDependencies(code);
+  if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
 }
 
 
index 83f760d..991bcf0 100644 (file)
@@ -683,6 +683,7 @@ class LChunk : public ZoneObject {
   typedef zone_allocator<Handle<Map> > MapAllocator;
   typedef std::set<Handle<Map>, MapLess, MapAllocator> MapSet;
 
+  void RegisterWeakObjectsInOptimizedCode(Handle<Code> code) const;
   void CommitDependencies(Handle<Code> code) const;
 
   CompilationInfo* info_;
index 2c5e7f1..7711cc7 100644 (file)
@@ -85,7 +85,6 @@ void LCodeGen::FinishCode(Handle<Code> code) {
   DCHECK(is_done());
   code->set_stack_slots(GetStackSlotCount());
   code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
-  if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
   PopulateDeoptimizationData(code);
 }
 
index 16e497d..c7fe98a 100644 (file)
@@ -60,7 +60,6 @@ void LCodeGen::FinishCode(Handle<Code> code) {
   DCHECK(is_done());
   code->set_stack_slots(GetStackSlotCount());
   code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
-  if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
   PopulateDeoptimizationData(code);
 }
 
index 613bc60..b12b1b1 100644 (file)
@@ -4857,6 +4857,21 @@ inline void Code::set_is_turbofanned(bool value) {
 }
 
 
+inline bool Code::can_have_weak_objects() {
+  DCHECK(kind() == OPTIMIZED_FUNCTION);
+  return CanHaveWeakObjectsField::decode(
+      READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
+}
+
+
+inline void Code::set_can_have_weak_objects(bool value) {
+  DCHECK(kind() == OPTIMIZED_FUNCTION);
+  int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
+  int updated = CanHaveWeakObjectsField::update(previous, value);
+  WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
+}
+
+
 bool Code::optimizable() {
   DCHECK_EQ(FUNCTION, kind());
   return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
index 3f485e5..5658c8f 100644 (file)
@@ -5132,6 +5132,11 @@ class Code: public HeapObject {
   inline bool is_turbofanned();
   inline void set_is_turbofanned(bool value);
 
+  // [can_have_weak_objects]: For kind OPTIMIZED_FUNCTION, tells whether the
+  // embedded objects in code should be treated weakly.
+  inline bool can_have_weak_objects();
+  inline void set_can_have_weak_objects(bool value);
+
   // [optimizable]: For FUNCTION kind, tells if it is optimizable.
   inline bool optimizable();
   inline void set_optimizable(bool value);
@@ -5389,11 +5394,15 @@ class Code: public HeapObject {
   void VerifyEmbeddedObjectsInFullCode();
 #endif  // DEBUG
 
-  inline bool CanContainWeakObjects() { return is_optimized_code(); }
+  inline bool CanContainWeakObjects() {
+    // is_turbofanned() implies !can_have_weak_objects().
+    DCHECK(!is_optimized_code() || !is_turbofanned() ||
+           !can_have_weak_objects());
+    return is_optimized_code() && can_have_weak_objects();
+  }
 
   inline bool IsWeakObject(Object* object) {
-    return (is_optimized_code() && !is_turbofanned() &&
-            IsWeakObjectInOptimizedCode(object));
+    return (CanContainWeakObjects() && IsWeakObjectInOptimizedCode(object));
   }
 
   static inline bool IsWeakObjectInOptimizedCode(Object* object);
@@ -5459,9 +5468,10 @@ class Code: public HeapObject {
       kStackSlotsFirstBit + kStackSlotsBitCount;
   static const int kMarkedForDeoptimizationBit = kHasFunctionCacheBit + 1;
   static const int kIsTurbofannedBit = kMarkedForDeoptimizationBit + 1;
+  static const int kCanHaveWeakObjects = kIsTurbofannedBit + 1;
 
   STATIC_ASSERT(kStackSlotsFirstBit + kStackSlotsBitCount <= 32);
-  STATIC_ASSERT(kIsTurbofannedBit + 1 <= 32);
+  STATIC_ASSERT(kCanHaveWeakObjects + 1 <= 32);
 
   class StackSlotsField: public BitField<int,
       kStackSlotsFirstBit, kStackSlotsBitCount> {};  // NOLINT
@@ -5471,6 +5481,8 @@ class Code: public HeapObject {
       : public BitField<bool, kMarkedForDeoptimizationBit, 1> {};   // NOLINT
   class IsTurbofannedField : public BitField<bool, kIsTurbofannedBit, 1> {
   };  // NOLINT
+  class CanHaveWeakObjectsField
+      : public BitField<bool, kCanHaveWeakObjects, 1> {};  // NOLINT
 
   // KindSpecificFlags2 layout (ALL)
   static const int kIsCrankshaftedBit = 0;
index 7716eae..c9ac471 100644 (file)
@@ -67,7 +67,6 @@ void LCodeGen::FinishCode(Handle<Code> code) {
   DCHECK(is_done());
   code->set_stack_slots(GetStackSlotCount());
   code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
-  if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
   PopulateDeoptimizationData(code);
 }
 
index d30a908..5cd70b1 100644 (file)
@@ -76,7 +76,6 @@ void LCodeGen::FinishCode(Handle<Code> code) {
   DCHECK(is_done());
   code->set_stack_slots(GetStackSlotCount());
   code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
-  if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
   PopulateDeoptimizationData(code);
   if (!info()->IsStub()) {
     Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);