Reviewers: ulan, mvstanton,

Description:
Added a special stack guard to deopt marked allocation sites.

BUG=

Please review this at https://codereview.chromium.org/169563002/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+53, -21 lines):
  M src/execution.h
  M src/execution.cc
  M src/heap.h
  M src/heap.cc
  M src/objects-inl.h
  M src/objects.h


Index: src/execution.cc
diff --git a/src/execution.cc b/src/execution.cc
index 081cfb61a439b0eb0cfc8bf78cfbadd7de8db521..690a4e3f4e6cd8570a0b052ee643b8fedb24aa69 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -516,15 +516,15 @@ void StackGuard::FullDeopt() {
 }


-bool StackGuard::IsDeoptMarkedCode() {
+bool StackGuard::IsDeoptMarkedAllocationSites() {
   ExecutionAccess access(isolate_);
-  return (thread_local_.interrupt_flags_ & DEOPT_MARKED_CODE) != 0;
+ return (thread_local_.interrupt_flags_ & DEOPT_MARKED_ALLOCATION_SITES) != 0;
 }


-void StackGuard::DeoptMarkedCode() {
+void StackGuard::DeoptMarkedAllocationSites() {
   ExecutionAccess access(isolate_);
-  thread_local_.interrupt_flags_ |= DEOPT_MARKED_CODE;
+  thread_local_.interrupt_flags_ |= DEOPT_MARKED_ALLOCATION_SITES;
   set_interrupt_limits(access);
 }

@@ -1040,9 +1040,9 @@ MaybeObject* Execution::HandleStackGuardInterrupt(Isolate* isolate) {
     stack_guard->Continue(FULL_DEOPT);
     Deoptimizer::DeoptimizeAll(isolate);
   }
-  if (stack_guard->IsDeoptMarkedCode()) {
-    stack_guard->Continue(DEOPT_MARKED_CODE);
-    Deoptimizer::DeoptimizeMarkedCode(isolate);
+  if (stack_guard->IsDeoptMarkedAllocationSites()) {
+    stack_guard->Continue(DEOPT_MARKED_ALLOCATION_SITES);
+    isolate->heap()->DeoptMarkedAllocationSites();
   }
   if (stack_guard->IsInstallCodeRequest()) {
     ASSERT(isolate->concurrent_recompilation_enabled());
Index: src/execution.h
diff --git a/src/execution.h b/src/execution.h
index e86337c6f59feeb57b95bddf75fc8c98ebefa174..b53a83358cd21ac0dfaa431bfa8e3092c960e02a 100644
--- a/src/execution.h
+++ b/src/execution.h
@@ -45,7 +45,7 @@ enum InterruptFlag {
   FULL_DEOPT = 1 << 6,
   INSTALL_CODE = 1 << 7,
   API_INTERRUPT = 1 << 8,
-  DEOPT_MARKED_CODE = 1 << 9
+  DEOPT_MARKED_ALLOCATION_SITES = 1 << 9
 };


@@ -223,8 +223,8 @@ class StackGuard {
   void RequestInstallCode();
   bool IsFullDeopt();
   void FullDeopt();
-  bool IsDeoptMarkedCode();
-  void DeoptMarkedCode();
+  bool IsDeoptMarkedAllocationSites();
+  void DeoptMarkedAllocationSites();
   void Continue(InterruptFlag after_what);

   void RequestInterrupt(InterruptCallback callback, void* data);
Index: src/heap.cc
diff --git a/src/heap.cc b/src/heap.cc
index c17794f99b394456583b5bf9d9241777f1bc0d63..66fbbeb1f1dbd6596f6f691d619e835b11b466b3 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -545,7 +545,9 @@ void Heap::ProcessPretenuringFeedback() {
       }
     }

-    if (trigger_deoptimization) isolate_->stack_guard()->DeoptMarkedCode();
+    if (trigger_deoptimization) {
+      isolate_->stack_guard()->DeoptMarkedAllocationSites();
+    }

     FlushAllocationSitesScratchpad();

@@ -567,6 +569,25 @@ void Heap::ProcessPretenuringFeedback() {
 }


+void Heap::DeoptMarkedAllocationSites() {
+  // TODO(hpayer): If iterating over the alloation sites list becomes a
+ // performance issue, use a cache heap data structure instead (similar to the
+  // allocation sites scratchpad).
+  Object* list_element = allocation_sites_list();
+  while (list_element->IsAllocationSite()) {
+    AllocationSite* site = AllocationSite::cast(list_element);
+    if (site->deopt_dependent_code()) {
+      site->dependent_code()->MarkCodeForDeoptimization(
+          isolate_,
+          DependentCode::kAllocationSiteTenuringChangedGroup);
+      site->set_deopt_dependent_code(false);
+    }
+    list_element = site->weak_next();
+  }
+  Deoptimizer::DeoptimizeMarkedCode(isolate_);
+}
+
+
 void Heap::GarbageCollectionEpilogue() {
   store_buffer()->GCEpilogue();

@@ -2000,14 +2021,12 @@ void Heap::ResetAllAllocationSitesDependentCode(PretenureFlag flag) {
     AllocationSite* casted = AllocationSite::cast(cur);
     if (casted->GetPretenureMode() == flag) {
       casted->ResetPretenureDecision();
- bool got_marked = casted->dependent_code()->MarkCodeForDeoptimization(
-          isolate_,
-          DependentCode::kAllocationSiteTenuringChangedGroup);
-      if (got_marked) marked = true;
+      casted->set_deopt_dependent_code(true);
+      marked = true;
     }
     cur = casted->weak_next();
   }
-  if (marked) isolate_->stack_guard()->DeoptMarkedCode();
+  if (marked) isolate_->stack_guard()->DeoptMarkedAllocationSites();
 }


Index: src/heap.h
diff --git a/src/heap.h b/src/heap.h
index eb3afd9fc4d94c6c119560b36a9fc6ec764225f1..ba481bccc4274dcc14e6302e73b0c91eaae83b96 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -1834,6 +1834,8 @@ class Heap {
     return amount_of_external_allocated_memory_;
   }

+  void DeoptMarkedAllocationSites();
+
// ObjectStats are kept in two arrays, counts and sizes. Related stats are // stored in a contiguous linear buffer. Stats groups are stored one after
   // another.
Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 97f00ade4da389da6f87be5f7f4fd2ea47fe983d..4cdc073f3760971b5e41a808b8ce4e92049d91dd 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1554,9 +1554,7 @@ inline bool AllocationSite::DigestPretenuringFeedback() {
     set_pretenure_decision(result);
     if (current_mode != GetPretenureMode()) {
       decision_changed = true;
-      dependent_code()->MarkCodeForDeoptimization(
-          GetIsolate(),
-          DependentCode::kAllocationSiteTenuringChangedGroup);
+      set_deopt_dependent_code(true);
     }
   }

Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index 62251fb32dbed76a7d3f7e510a41c94be01b5179..4b5462dc3985e72c44d8c5dd1b850ad408173db1 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -8252,8 +8252,9 @@ class AllocationSite: public Struct {
   class DoNotInlineBit:         public BitField<bool,         29,  1> {};

   // Bitfields for pretenure_data
-  class MementoFoundCountBits:  public BitField<int,          0, 28> {};
- class PretenureDecisionBits: public BitField<PretenureDecision, 28, 2> {}; + class MementoFoundCountBits: public BitField<int, 0, 27> {}; + class PretenureDecisionBits: public BitField<PretenureDecision, 27, 2> {}; + class DeoptDependentCodeBit: public BitField<bool, 29, 1> {}; STATIC_ASSERT(PretenureDecisionBits::kMax >= kLastPretenureDecisionValue);

   // Increments the mementos found counter and returns true when the first
@@ -8278,6 +8279,18 @@ class AllocationSite: public Struct {
         SKIP_WRITE_BARRIER);
   }

+  bool deopt_dependent_code() {
+    int value = pretenure_data()->value();
+    return DeoptDependentCodeBit::decode(value);
+  }
+
+  void set_deopt_dependent_code(bool deopt) {
+    int value = pretenure_data()->value();
+    set_pretenure_data(
+        Smi::FromInt(DeoptDependentCodeBit::update(value, deopt)),
+        SKIP_WRITE_BARRIER);
+  }
+
   int memento_found_count() {
     int value = pretenure_data()->value();
     return MementoFoundCountBits::decode(value);


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to