Revision: 11143
Author:   [email protected]
Date:     Mon Mar 26 06:08:08 2012
Log:      Reset function info counters after context disposal.

[email protected]
BUG=117767,V8:1902

Review URL: https://chromiumcodereview.appspot.com/9836091
http://code.google.com/p/v8/source/detail?r=11143

Modified:
 /branches/bleeding_edge/src/compiler.cc
 /branches/bleeding_edge/src/factory.cc
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/mark-compact.cc
 /branches/bleeding_edge/src/objects-inl.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/objects.h

=======================================
--- /branches/bleeding_edge/src/compiler.cc     Thu Mar 15 04:51:26 2012
+++ /branches/bleeding_edge/src/compiler.cc     Mon Mar 26 06:08:08 2012
@@ -531,6 +531,10 @@
     if (extension == NULL && !result.is_null()) {
       compilation_cache->PutScript(source, result);
     }
+  } else {
+    if (result->ic_age() != HEAP->global_ic_age()) {
+      result->ResetForNewContext(HEAP->global_ic_age());
+    }
   }

   if (result.is_null()) isolate->ReportPendingMessages();
@@ -586,6 +590,10 @@
       compilation_cache->PutEval(
           source, context, is_global, result, scope_position);
     }
+  } else {
+    if (result->ic_age() != HEAP->global_ic_age()) {
+      result->ResetForNewContext(HEAP->global_ic_age());
+    }
   }

   return result;
=======================================
--- /branches/bleeding_edge/src/factory.cc      Mon Mar 19 03:16:38 2012
+++ /branches/bleeding_edge/src/factory.cc      Mon Mar 26 06:08:08 2012
@@ -537,6 +537,10 @@
           : isolate()->strict_mode_function_map(),
       pretenure);

+  if (function_info->ic_age() != isolate()->heap()->global_ic_age()) {
+    function_info->ResetForNewContext(isolate()->heap()->global_ic_age());
+  }
+
   result->set_context(*context);
   if (!function_info->bound()) {
     int number_of_literals = function_info->num_literals();
=======================================
--- /branches/bleeding_edge/src/heap.cc Fri Mar 23 06:33:11 2012
+++ /branches/bleeding_edge/src/heap.cc Mon Mar 26 06:08:08 2012
@@ -2897,9 +2897,10 @@
   share->set_inferred_name(empty_string(), SKIP_WRITE_BARRIER);
   share->set_initial_map(undefined_value(), SKIP_WRITE_BARRIER);
share->set_this_property_assignments(undefined_value(), SKIP_WRITE_BARRIER);
+  share->set_ast_node_count(0);
   share->set_deopt_counter(FLAG_deopt_every_n_times);
   share->set_profiler_ticks(0);
-  share->set_ast_node_count(0);
+  share->set_ic_age(0);

   // Set integer fields (smi or int, depending on the architecture).
   share->set_length(0);
=======================================
--- /branches/bleeding_edge/src/mark-compact.cc Fri Mar 23 06:33:11 2012
+++ /branches/bleeding_edge/src/mark-compact.cc Mon Mar 26 06:08:08 2012
@@ -1406,6 +1406,10 @@

if (shared->IsInobjectSlackTrackingInProgress()) shared->DetachInitialMap();

+    if (shared->ic_age() != heap->global_ic_age()) {
+      shared->ResetForNewContext(heap->global_ic_age());
+    }
+
     if (!known_flush_code_candidate) {
       known_flush_code_candidate = IsFlushable(heap, shared);
       if (known_flush_code_candidate) {
=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Fri Mar 23 06:33:11 2012
+++ /branches/bleeding_edge/src/objects-inl.h   Mon Mar 26 06:08:08 2012
@@ -3508,7 +3508,6 @@
 ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
           kThisPropertyAssignmentsOffset)

-SMI_ACCESSORS(SharedFunctionInfo, profiler_ticks, kProfilerTicksOffset)

 BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
                kHiddenPrototypeBit)
@@ -3558,6 +3557,8 @@
 SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
 SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
 SMI_ACCESSORS(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
+SMI_ACCESSORS(SharedFunctionInfo, profiler_ticks, kProfilerTicksOffset)
+SMI_ACCESSORS(SharedFunctionInfo, ic_age, kICAgeOffset)
 #else

 #define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset)             \
@@ -3611,6 +3612,11 @@

PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset) PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
+
+PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
+                        profiler_ticks,
+                        kProfilerTicksOffset)
+PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, ic_age, kICAgeOffset)
 #endif


=======================================
--- /branches/bleeding_edge/src/objects.cc      Sun Mar 25 08:16:06 2012
+++ /branches/bleeding_edge/src/objects.cc      Mon Mar 26 06:08:08 2012
@@ -7867,6 +7867,14 @@
   // The map survived the gc, so there may be objects referencing it.
   set_live_objects_may_exist(true);
 }
+
+
+void SharedFunctionInfo::ResetForNewContext(int new_ic_age) {
+  code()->ClearInlineCaches();
+  set_ic_age(new_ic_age);
+  set_opt_count(0);
+  set_profiler_ticks(0);
+}


 static void GetMinInobjectSlack(Map* map, void* data) {
@@ -8114,6 +8122,21 @@
   }
   return NULL;
 }
+
+
+void Code::ClearInlineCaches() {
+  int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
+             RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) |
+             RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID) |
+             RelocInfo::ModeMask(RelocInfo::CODE_TARGET_CONTEXT);
+  for (RelocIterator it(this, mask); !it.done(); it.next()) {
+    RelocInfo* info = it.rinfo();
+    Code* target(Code::GetCodeFromTargetAddress(info->target_address()));
+    if (target->is_inline_cache_stub()) {
+      IC::Clear(info->pc());
+    }
+  }
+}


 #ifdef ENABLE_DISASSEMBLER
=======================================
--- /branches/bleeding_edge/src/objects.h       Fri Mar 23 06:33:11 2012
+++ /branches/bleeding_edge/src/objects.h       Mon Mar 26 06:08:08 2012
@@ -4423,6 +4423,7 @@
 #ifdef DEBUG
   void CodeVerify();
 #endif
+  void ClearInlineCaches();

   // Max loop nesting marker used to postpose OSR. We don't take loop
   // nesting that is deeper than 5 levels into account.
@@ -5323,6 +5324,9 @@
   inline int compiler_hints();
   inline void set_compiler_hints(int value);

+  inline int ast_node_count();
+  inline void set_ast_node_count(int count);
+
   // A counter used to determine when to stress the deoptimizer with a
   // deopt.
   inline int deopt_counter();
@@ -5331,8 +5335,10 @@
   inline int profiler_ticks();
   inline void set_profiler_ticks(int ticks);

-  inline int ast_node_count();
-  inline void set_ast_node_count(int count);
+ // Inline cache age is used to infer whether the function survived a context
+  // disposal or not. In the former case we reset the opt_count.
+  inline int ic_age();
+  inline void set_ic_age(int age);

   // Add information on assignments of the form this.x = ...;
   void SetThisPropertyAssignmentsInfo(
@@ -5478,6 +5484,8 @@
   void SharedFunctionInfoVerify();
 #endif

+  void ResetForNewContext(int new_ic_age);
+
   // Helpers to compile the shared code.  Returns true on success, false on
   // failure (e.g., stack overflow during compilation).
   static bool EnsureCompiled(Handle<SharedFunctionInfo> shared,
@@ -5508,12 +5516,10 @@
       kInferredNameOffset + kPointerSize;
   static const int kThisPropertyAssignmentsOffset =
       kInitialMapOffset + kPointerSize;
-  static const int kProfilerTicksOffset =
-      kThisPropertyAssignmentsOffset + kPointerSize;
 #if V8_HOST_ARCH_32_BIT
   // Smi fields.
   static const int kLengthOffset =
-      kProfilerTicksOffset + kPointerSize;
+      kThisPropertyAssignmentsOffset + kPointerSize;
static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize;
   static const int kExpectedNofPropertiesOffset =
       kFormalParameterCountOffset + kPointerSize;
@@ -5532,10 +5538,12 @@
   static const int kOptCountOffset =
       kThisPropertyAssignmentsCountOffset + kPointerSize;
   static const int kAstNodeCountOffset = kOptCountOffset + kPointerSize;
-  static const int kDeoptCounterOffset =
-      kAstNodeCountOffset + kPointerSize;
+ static const int kDeoptCounterOffset = kAstNodeCountOffset + kPointerSize; + static const int kProfilerTicksOffset = kDeoptCounterOffset + kPointerSize;
+  static const int kICAgeOffset = kProfilerTicksOffset + kPointerSize;
+
   // Total size.
-  static const int kSize = kDeoptCounterOffset + kPointerSize;
+  static const int kSize = kICAgeOffset + kPointerSize;
 #else
   // The only reason to use smi fields instead of int fields
   // is to allow iteration without maps decoding during
@@ -5547,7 +5555,7 @@
   // word is not set and thus this word cannot be treated as pointer
   // to HeapObject during old space traversal.
   static const int kLengthOffset =
-      kProfilerTicksOffset + kPointerSize;
+      kThisPropertyAssignmentsOffset + kPointerSize;
   static const int kFormalParameterCountOffset =
       kLengthOffset + kIntSize;

@@ -5574,8 +5582,12 @@
   static const int kAstNodeCountOffset = kOptCountOffset + kIntSize;
   static const int kDeoptCounterOffset = kAstNodeCountOffset + kIntSize;

+
+  static const int kProfilerTicksOffset = kDeoptCounterOffset + kIntSize;
+  static const int kICAgeOffset = kProfilerTicksOffset + kIntSize;
+
   // Total size.
-  static const int kSize = kDeoptCounterOffset + kIntSize;
+  static const int kSize = kICAgeOffset + kIntSize;

 #endif

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to