Index: src/mark-compact.h |
diff --git a/src/mark-compact.h b/src/mark-compact.h |
index ac26ce8230bb6f57d0d11ca2812ab8df2967b458..5acca58717812f2f87a0cdc1ca7b412e98a48812 100644 |
--- a/src/mark-compact.h |
+++ b/src/mark-compact.h |
@@ -432,6 +432,81 @@ class SlotsBuffer { |
}; |
+// CodeFlusher collects candidates for code flushing during marking and |
+// processes those candidates after marking has completed in order to |
+// reset those functions referencing code objects that would otherwise |
+// be unreachable. Code objects can be referenced in two ways: |
+// - SharedFunctionInfo references unoptimized code. |
+// - JSFunction references either unoptimized or optimized code. |
+// We are not allowed to flush unoptimized code for functions that got |
+// optimized or inlined into optimized code, because we might bailout |
+// into the unoptimized code again during deoptimization. |
+class CodeFlusher { |
+ public: |
+ explicit CodeFlusher(Isolate* isolate) |
+ : isolate_(isolate), |
+ jsfunction_candidates_head_(NULL), |
+ shared_function_info_candidates_head_(NULL) {} |
+ |
+ void AddCandidate(SharedFunctionInfo* shared_info) { |
+ SetNextCandidate(shared_info, shared_function_info_candidates_head_); |
+ shared_function_info_candidates_head_ = shared_info; |
+ } |
+ |
+ void AddCandidate(JSFunction* function) { |
+ ASSERT(function->code() == function->shared()->code()); |
+ SetNextCandidate(function, jsfunction_candidates_head_); |
+ jsfunction_candidates_head_ = function; |
+ } |
+ |
+ void ProcessCandidates() { |
+ ProcessSharedFunctionInfoCandidates(); |
+ ProcessJSFunctionCandidates(); |
+ } |
+ |
+ private: |
+ 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); |
+ } |
+ |
+ static void SetNextCandidate(JSFunction* candidate, |
+ JSFunction* next_candidate) { |
+ *GetNextCandidateField(candidate) = next_candidate; |
+ } |
+ |
+ static SharedFunctionInfo** GetNextCandidateField( |
+ SharedFunctionInfo* candidate) { |
+ Code* code = candidate->code(); |
+ return reinterpret_cast<SharedFunctionInfo**>( |
+ code->address() + Code::kGCMetadataOffset); |
+ } |
+ |
+ static SharedFunctionInfo* GetNextCandidate(SharedFunctionInfo* candidate) { |
+ return reinterpret_cast<SharedFunctionInfo*>( |
+ candidate->code()->gc_metadata()); |
+ } |
+ |
+ static void SetNextCandidate(SharedFunctionInfo* candidate, |
+ SharedFunctionInfo* next_candidate) { |
+ candidate->code()->set_gc_metadata(next_candidate); |
+ } |
+ |
+ Isolate* isolate_; |
+ JSFunction* jsfunction_candidates_head_; |
+ SharedFunctionInfo* shared_function_info_candidates_head_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(CodeFlusher); |
+}; |
+ |
+ |
// Defined in isolate.h. |
class ThreadLocalTop; |
@@ -663,10 +738,6 @@ class MarkCompactCollector { |
friend class CodeMarkingVisitor; |
friend class SharedFunctionInfoMarkingVisitor; |
- // Mark non-optimize code for functions inlined into the given optimized |
- // code. This will prevent it from being flushed. |
- void MarkInlinedFunctionsCode(Code* code); |
- |
// Mark code objects that are active on the stack to prevent them |
// from being flushed. |
void PrepareThreadForCodeFlushing(Isolate* isolate, ThreadLocalTop* top); |