Reviewers: Michael Starzinger,

Message:
PTAL

Description:
Only flush SharedFunctionInfo optimized code cache when necessary


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

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

Affected files:
  M src/arm/deoptimizer-arm.cc
  M src/ia32/deoptimizer-ia32.cc
  M src/objects-visiting-inl.h
  M src/objects.h
  M src/objects.cc
  M src/runtime.cc
  M src/x64/deoptimizer-x64.cc


Index: src/arm/deoptimizer-arm.cc
diff --git a/src/arm/deoptimizer-arm.cc b/src/arm/deoptimizer-arm.cc
index 41379d53e92f0045d609e4ec8b00227870dd32e9..39b30decc4c73faa3e1566ba698765465dfefc1b 100644
--- a/src/arm/deoptimizer-arm.cc
+++ b/src/arm/deoptimizer-arm.cc
@@ -53,14 +53,14 @@ void Deoptimizer::DeoptimizeFunctionWithPreparedFunctionList(
   ASSERT(function->IsOptimized());
   ASSERT(function->FunctionsInFunctionListShareSameCode());

-  // The optimized code is going to be patched, so we cannot use it
-  // any more.  Play safe and reset the whole cache.
-  function->shared()->ClearOptimizedCodeMap("deoptimized function");
-
   // Get the optimized code.
   Code* code = function->code();
   Address code_start_address = code->instruction_start();

+  // The optimized code is going to be patched, so we cannot use it
+  // any more.  Play safe and reset the whole cache.
+  function->shared()->ClearOptimizedCodeMap(code, "deoptimized function");
+
// Invalidate the relocation information, as it will become invalid by the
   // code patching below, and is not needed any more.
   code->InvalidateRelocation();
Index: src/ia32/deoptimizer-ia32.cc
diff --git a/src/ia32/deoptimizer-ia32.cc b/src/ia32/deoptimizer-ia32.cc
index 6718b8f85c40dbc3485e30cc45ccdc61c22732d6..ce18ccdcd9d75167387fded891168a5a9db09af4 100644
--- a/src/ia32/deoptimizer-ia32.cc
+++ b/src/ia32/deoptimizer-ia32.cc
@@ -123,14 +123,14 @@ void Deoptimizer::DeoptimizeFunctionWithPreparedFunctionList(
   ASSERT(function->IsOptimized());
   ASSERT(function->FunctionsInFunctionListShareSameCode());

-  // The optimized code is going to be patched, so we cannot use it
-  // any more.  Play safe and reset the whole cache.
-  function->shared()->ClearOptimizedCodeMap("deoptimized function");
-
   // Get the optimized code.
   Code* code = function->code();
   Address code_start_address = code->instruction_start();

+  // The optimized code is going to be patched, so we cannot use it
+  // any more.  Play safe and reset the whole cache.
+  function->shared()->ClearOptimizedCodeMap(code, "deoptimized function");
+
   // We will overwrite the code's relocation info in-place. Relocation info
   // is written backward. The relocation info is the payload of a byte
   // array.  Later on we will slide this to the start of the byte array and
Index: src/objects-visiting-inl.h
diff --git a/src/objects-visiting-inl.h b/src/objects-visiting-inl.h
index 4c9a4bd96bafd1bb49593fd412dba42547dec0c1..efb3a8d5560452f7892294371621f0093a135fd1 100644
--- a/src/objects-visiting-inl.h
+++ b/src/objects-visiting-inl.h
@@ -316,7 +316,7 @@ void StaticMarkingVisitor<StaticVisitor>::VisitSharedFunctionInfo(
     // TODO(mstarzinger): We may experiment with rebuilding it or with
     // retaining entries which should survive as we iterate through
     // optimized functions anyway.
-    shared->ClearOptimizedCodeMap("during full gc");
+    shared->ClearOptimizedCodeMap(NULL, "during full gc");
   }
   MarkCompactCollector* collector = heap->mark_compact_collector();
   if (collector->is_code_flushing_enabled()) {
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index dfcb29b6027aafbdfab53181fecb10d5f52b542c..3451239f555a0cc8a114addb5f9afc11b6c814d8 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -9031,14 +9031,52 @@ void SharedFunctionInfo::InstallFromOptimizedCodeMap(JSFunction* function,
 }


-void SharedFunctionInfo::ClearOptimizedCodeMap(const char* reason) {
+void SharedFunctionInfo::ClearOptimizedCodeMap(Code* optimized_code,
+                                               const char* reason) {
   if (!optimized_code_map()->IsSmi()) {
-    if (FLAG_trace_opt) {
-      PrintF("[clearing optimizing code map (%s) for ", reason);
-      ShortPrint();
-      PrintF("]\n");
+    if (optimized_code == NULL || true) {
+      if (FLAG_trace_opt) {
+        PrintF("[clearing entire optimizing code map (%s) for ", reason);
+        ShortPrint();
+        PrintF("]\n");
+      }
+      set_optimized_code_map(Smi::FromInt(0));
+    } else {
+      int i;
+      bool removed_entry = false;
+      FixedArray* code_map = FixedArray::cast(optimized_code_map());
+      for (i = 0; i < code_map->length(); i += kEntryLength) {
+        ASSERT(code_map->get(i)->IsNativeContext());
+        if (Code::cast(code_map->get(i + 1)) == optimized_code) {
+          if (FLAG_trace_opt) {
+            PrintF("[clearing optimizing code map (%s) for ", reason);
+            ShortPrint();
+            PrintF("]\n");
+          }
+          removed_entry = true;
+          break;
+        }
+      }
+      while (i < (code_map->length() - kEntryLength)) {
+        code_map->set(i, code_map->get(i + 1 + kEntryLength));
+        code_map->set(i + 1, code_map->get(i + 2 + kEntryLength));
+        code_map->set(i + 2, code_map->get(i + 3 + kEntryLength));
+        i += kEntryLength;
+      }
+      if (removed_entry) {
+        Heap* heap = GetHeap();
+        int new_length = code_map->length() - kEntryLength;
+        if (new_length == 0) {
+          set_optimized_code_map(Smi::FromInt(0));
+          return;
+        }
+        Address filler_start = reinterpret_cast<Address>(
+            code_map->GetFirstElementAddress() + new_length);
+        heap->CreateFillerObjectAt(filler_start,
+                                   kEntryLength * kPointerSize);
+        code_map->set_length(new_length);
+      }
     }
-    set_optimized_code_map(Smi::FromInt(0));
   }
 }

Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index eebf3c1b6675dd6dd4e686ade63fabb235e7f820..50bc8e752fe0522e37e7c3f1d6723bd1855b6cfc 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -5819,8 +5819,9 @@ class SharedFunctionInfo: public HeapObject {
   // index has to be consistent with a search result as defined above.
   void InstallFromOptimizedCodeMap(JSFunction* function, int index);

-  // Clear optimized code map.
-  void ClearOptimizedCodeMap(const char* reason);
+ // Removed a specific optimized code object from the optimized code map, or
+  // all code objects if |optimized_code| is null.
+  void ClearOptimizedCodeMap(Code* optimized_code, const char* reason);

   // Add a new entry to the optimized code map.
   static void AddToOptimizedCodeMap(Handle<SharedFunctionInfo> shared,
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index cb22670617de0f957157cf4c6a12ba7ee6395b49..8171cf01971a1a240761b6a3b51c0716bd39df0c 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -7973,6 +7973,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
   JavaScriptFrame* frame = it.frame();
   RUNTIME_ASSERT(frame->function()->IsJSFunction());
Handle<JSFunction> function(JSFunction::cast(frame->function()), isolate);
+  Handle<Code> optimized_code(function->code());
   RUNTIME_ASSERT(type != Deoptimizer::EAGER || function->IsOptimized());

   // Avoid doing too much work when running with --always-opt and keep
@@ -8011,7 +8012,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
     Deoptimizer::DeoptimizeFunction(*function);
   }
   // Flush optimized code cache for this function.
-  function->shared()->ClearOptimizedCodeMap("notify deoptimized");
+  function->shared()->ClearOptimizedCodeMap(*optimized_code,
+                                            "notify deoptimized");

   return isolate->heap()->undefined_value();
 }
Index: src/x64/deoptimizer-x64.cc
diff --git a/src/x64/deoptimizer-x64.cc b/src/x64/deoptimizer-x64.cc
index 36280ec8b4d516758f44a7a96e16af00fe6ecf14..98295ad11149299c68b05cd9c2db510b128855fd 100644
--- a/src/x64/deoptimizer-x64.cc
+++ b/src/x64/deoptimizer-x64.cc
@@ -55,13 +55,13 @@ void Deoptimizer::DeoptimizeFunctionWithPreparedFunctionList(
   ASSERT(function->IsOptimized());
   ASSERT(function->FunctionsInFunctionListShareSameCode());

-  // The optimized code is going to be patched, so we cannot use it
-  // any more.  Play safe and reset the whole cache.
-  function->shared()->ClearOptimizedCodeMap("deoptimized function");
-
   // Get the optimized code.
   Code* code = function->code();

+  // The optimized code is going to be patched, so we cannot use it
+  // any more.  Play safe and reset the whole cache.
+  function->shared()->ClearOptimizedCodeMap(code, "deoptimized function");
+
// Invalidate the relocation information, as it will become invalid by the
   // code patching below, and is not needed any more.
   code->InvalidateRelocation();


--
--
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