Index: src/mark-compact.h |
diff --git a/src/mark-compact.h b/src/mark-compact.h |
index cbc8f410c69180d06e9fe0903410d0f002ba23ff..0f20440062710bbc0e9108a7e1092476ac04cdbe 100644 |
--- a/src/mark-compact.h |
+++ b/src/mark-compact.h |
@@ -406,9 +406,10 @@ 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: |
+// be unreachable. Code objects can be referenced in three ways: |
// - SharedFunctionInfo references unoptimized code. |
// - JSFunction references either unoptimized or optimized code. |
+// - OptimizedCodeMap references 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. |
@@ -417,7 +418,8 @@ class CodeFlusher { |
explicit CodeFlusher(Isolate* isolate) |
: isolate_(isolate), |
jsfunction_candidates_head_(NULL), |
- shared_function_info_candidates_head_(NULL) {} |
+ shared_function_info_candidates_head_(NULL), |
+ optimized_code_map_holder_head_(NULL) {} |
void AddCandidate(SharedFunctionInfo* shared_info) { |
if (GetNextCandidate(shared_info) == NULL) { |
@@ -434,15 +436,25 @@ class CodeFlusher { |
} |
} |
+ void AddOptimizedCodeMap(SharedFunctionInfo* code_map_holder) { |
+ if (GetNextCodeMap(code_map_holder)->IsUndefined()) { |
+ SetNextCodeMap(code_map_holder, optimized_code_map_holder_head_); |
+ optimized_code_map_holder_head_ = code_map_holder; |
+ } |
+ } |
+ |
+ void EvictOptimizedCodeMap(SharedFunctionInfo* code_map_holder); |
void EvictCandidate(SharedFunctionInfo* shared_info); |
void EvictCandidate(JSFunction* function); |
void ProcessCandidates() { |
+ ProcessOptimizedCodeMaps(); |
ProcessSharedFunctionInfoCandidates(); |
ProcessJSFunctionCandidates(); |
} |
void EvictAllCandidates() { |
+ EvictOptimizedCodeMaps(); |
EvictJSFunctionCandidates(); |
EvictSharedFunctionInfoCandidates(); |
} |
@@ -450,8 +462,10 @@ class CodeFlusher { |
void IteratePointersToFromSpace(ObjectVisitor* v); |
private: |
+ void ProcessOptimizedCodeMaps(); |
void ProcessJSFunctionCandidates(); |
void ProcessSharedFunctionInfoCandidates(); |
+ void EvictOptimizedCodeMaps(); |
void EvictJSFunctionCandidates(); |
void EvictSharedFunctionInfoCandidates(); |
@@ -489,9 +503,27 @@ class CodeFlusher { |
candidate->code()->set_gc_metadata(NULL, SKIP_WRITE_BARRIER); |
} |
+ static SharedFunctionInfo* GetNextCodeMap(SharedFunctionInfo* holder) { |
+ FixedArray* code_map = FixedArray::cast(holder->optimized_code_map()); |
+ Object* next_map = code_map->get(SharedFunctionInfo::kNextMapIndex); |
+ return reinterpret_cast<SharedFunctionInfo*>(next_map); |
+ } |
+ |
+ static void SetNextCodeMap(SharedFunctionInfo* holder, |
+ SharedFunctionInfo* next_holder) { |
+ FixedArray* code_map = FixedArray::cast(holder->optimized_code_map()); |
+ code_map->set(SharedFunctionInfo::kNextMapIndex, next_holder); |
+ } |
+ |
+ static void ClearNextCodeMap(SharedFunctionInfo* holder) { |
+ FixedArray* code_map = FixedArray::cast(holder->optimized_code_map()); |
+ code_map->set_undefined(SharedFunctionInfo::kNextMapIndex); |
+ } |
+ |
Isolate* isolate_; |
JSFunction* jsfunction_candidates_head_; |
SharedFunctionInfo* shared_function_info_candidates_head_; |
+ SharedFunctionInfo* optimized_code_map_holder_head_; |
DISALLOW_COPY_AND_ASSIGN(CodeFlusher); |
}; |