Switch code flushing to use different JSFunction field.
authormstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 15 Oct 2012 14:43:57 +0000 (14:43 +0000)
committermstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 15 Oct 2012 14:43:57 +0000 (14:43 +0000)
This is another preparation for incremental code flushing. Instead of
linking candidates using the code entry field, we use the next pointer
that is also used to link optimized functions together. Since we only
support flushing of unoptimized code, this field can be shared.

R=ulan@chromium.org
BUG=v8:1609

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12734 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/mark-compact.cc
src/mark-compact.h
src/runtime.cc

index 37fec4e..0740ca0 100644 (file)
@@ -861,11 +861,13 @@ void MarkCompactCollector::Finish() {
 
 void CodeFlusher::ProcessJSFunctionCandidates() {
   Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile);
+  Object* undefined = isolate_->heap()->undefined_value();
 
   JSFunction* candidate = jsfunction_candidates_head_;
   JSFunction* next_candidate;
   while (candidate != NULL) {
     next_candidate = GetNextCandidate(candidate);
+    ClearNextCandidate(candidate, undefined);
 
     SharedFunctionInfo* shared = candidate->shared();
 
@@ -874,8 +876,8 @@ void CodeFlusher::ProcessJSFunctionCandidates() {
     if (!code_mark.Get()) {
       shared->set_code(lazy_compile);
       candidate->set_code(lazy_compile);
-    } else {
-      candidate->set_code(shared->code());
+    } else if (code == lazy_compile) {
+      candidate->set_code(lazy_compile);
     }
 
     // We are in the middle of a GC cycle so the write barrier in the code
@@ -904,7 +906,7 @@ void CodeFlusher::ProcessSharedFunctionInfoCandidates() {
   SharedFunctionInfo* next_candidate;
   while (candidate != NULL) {
     next_candidate = GetNextCandidate(candidate);
-    SetNextCandidate(candidate, NULL);
+    ClearNextCandidate(candidate);
 
     Code* code = candidate->code();
     MarkBit code_mark = Marking::MarkBitFrom(code);
index 1d17582..7c64800 100644 (file)
@@ -426,6 +426,7 @@ class CodeFlusher {
 
   void AddCandidate(JSFunction* function) {
     ASSERT(function->code() == function->shared()->code());
+    ASSERT(function->next_function_link()->IsUndefined());
     SetNextCandidate(function, jsfunction_candidates_head_);
     jsfunction_candidates_head_ = function;
   }
@@ -439,30 +440,24 @@ class CodeFlusher {
   void ProcessJSFunctionCandidates();
   void ProcessSharedFunctionInfoCandidates();
 
-  static JSFunction** GetNextCandidateField(JSFunction* candidate) {
-    return reinterpret_cast<JSFunction**>(
-        candidate->address() + JSFunction::kCodeEntryOffset);
-  }
-
   static JSFunction* GetNextCandidate(JSFunction* candidate) {
-    return *GetNextCandidateField(candidate);
+    Object* next_candidate = candidate->next_function_link();
+    return reinterpret_cast<JSFunction*>(next_candidate);
   }
 
   static void SetNextCandidate(JSFunction* candidate,
                                JSFunction* next_candidate) {
-    *GetNextCandidateField(candidate) = next_candidate;
+    candidate->set_next_function_link(next_candidate);
   }
 
-  static SharedFunctionInfo** GetNextCandidateField(
-      SharedFunctionInfo* candidate) {
-    Code* code = candidate->code();
-    return reinterpret_cast<SharedFunctionInfo**>(
-        code->address() + Code::kGCMetadataOffset);
+  static void ClearNextCandidate(JSFunction* candidate, Object* undefined) {
+    ASSERT(undefined->IsUndefined());
+    candidate->set_next_function_link(undefined, SKIP_WRITE_BARRIER);
   }
 
   static SharedFunctionInfo* GetNextCandidate(SharedFunctionInfo* candidate) {
-    return reinterpret_cast<SharedFunctionInfo*>(
-        candidate->code()->gc_metadata());
+    Object* next_candidate = candidate->code()->gc_metadata();
+    return reinterpret_cast<SharedFunctionInfo*>(next_candidate);
   }
 
   static void SetNextCandidate(SharedFunctionInfo* candidate,
@@ -470,6 +465,10 @@ class CodeFlusher {
     candidate->code()->set_gc_metadata(next_candidate);
   }
 
+  static void ClearNextCandidate(SharedFunctionInfo* candidate) {
+    candidate->code()->set_gc_metadata(NULL, SKIP_WRITE_BARRIER);
+  }
+
   Isolate* isolate_;
   JSFunction* jsfunction_candidates_head_;
   SharedFunctionInfo* shared_function_info_candidates_head_;
index 356b6fc..19d9a3f 100644 (file)
@@ -2254,6 +2254,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) {
 
   // Set the code of the target function.
   target->ReplaceCode(source_shared->code());
+  ASSERT(target->next_function_link()->IsUndefined());
 
   // Make sure we get a fresh copy of the literal vector to avoid cross
   // context contamination.
@@ -2267,7 +2268,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetCode) {
   }
   target->set_context(*context);
   target->set_literals(*literals);
-  target->set_next_function_link(isolate->heap()->undefined_value());
 
   if (isolate->logger()->is_logging_code_events() ||
       CpuProfiler::is_profiling(isolate)) {