Chromium Code Reviews| Index: src/mark-compact.cc |
| diff --git a/src/mark-compact.cc b/src/mark-compact.cc |
| index 62dee4847265f489423b101d9dc708c410ebffbf..6e10054354c417e69e10e7bec193e1099dd1410e 100644 |
| --- a/src/mark-compact.cc |
| +++ b/src/mark-compact.cc |
| @@ -1054,6 +1054,67 @@ void CodeFlusher::ProcessSharedFunctionInfoCandidates() { |
| } |
| +void CodeFlusher::ProcessOptimizedCodeMaps() { |
| + static const int kEntriesStart = SharedFunctionInfo::kEntriesStart; |
| + static const int kEntryLength = SharedFunctionInfo::kEntryLength; |
| + STATIC_ASSERT(kEntryLength == 3); |
| + |
| + SharedFunctionInfo* holder = optimized_code_map_holder_head_; |
| + SharedFunctionInfo* next_holder; |
| + while (holder != NULL) { |
| + next_holder = GetNextCodeMap(holder); |
| + ClearNextCodeMap(holder); |
| + |
| + FixedArray* code_map = FixedArray::cast(holder->optimized_code_map()); |
| + int new_length = kEntriesStart; |
| + int old_length = code_map->length(); |
| + for (int i = kEntriesStart; i < old_length; i += kEntryLength) { |
| + Code* code = Code::cast(code_map->get(i + 1)); |
|
Hannes Payer (out of office)
2013/05/15 13:11:25
Can we use a constant like kCodeOffset = 1 here? T
Michael Starzinger
2013/05/15 15:09:57
Done.
|
| + MarkBit code_mark = Marking::MarkBitFrom(code); |
| + if (!code_mark.Get()) { |
| + continue; |
| + } |
| + |
| + // Update and record the context slot in the optimized code map. |
| + Object** context_slot = HeapObject::RawField(code_map, |
| + FixedArray::OffsetOfElementAt(new_length)); |
| + code_map->set(new_length++, code_map->get(i)); |
|
Hannes Payer (out of office)
2013/05/15 13:11:25
kContextOffset = 0
Michael Starzinger
2013/05/15 15:09:57
Done.
|
| + ASSERT(Marking::IsBlack( |
| + Marking::MarkBitFrom(HeapObject::cast(*context_slot)))); |
| + isolate_->heap()->mark_compact_collector()-> |
| + RecordSlot(context_slot, context_slot, *context_slot); |
| + |
| + // Update and record the code slot in the optimized code map. |
| + Object** code_slot = HeapObject::RawField(code_map, |
| + FixedArray::OffsetOfElementAt(new_length)); |
| + code_map->set(new_length++, code_map->get(i + 1)); |
|
Hannes Payer (out of office)
2013/05/15 13:11:25
kCodeOffset = 1
Michael Starzinger
2013/05/15 15:09:57
Done.
|
| + ASSERT(Marking::IsBlack( |
| + Marking::MarkBitFrom(HeapObject::cast(*code_slot)))); |
| + isolate_->heap()->mark_compact_collector()-> |
| + RecordSlot(code_slot, code_slot, *code_slot); |
| + |
| + // Update and record the literals slot in the optimized code map. |
| + Object** literals_slot = HeapObject::RawField(code_map, |
| + FixedArray::OffsetOfElementAt(new_length)); |
| + code_map->set(new_length++, code_map->get(i + 2)); |
|
Hannes Payer (out of office)
2013/05/15 13:11:25
kLiteralsOffset = 2
Michael Starzinger
2013/05/15 15:09:57
Done.
|
| + ASSERT(Marking::IsBlack( |
| + Marking::MarkBitFrom(HeapObject::cast(*literals_slot)))); |
| + isolate_->heap()->mark_compact_collector()-> |
| + RecordSlot(literals_slot, literals_slot, *literals_slot); |
| + } |
| + |
| + // Trim the optimized code map if entries have been removed. |
| + if (new_length < old_length) { |
| + holder->TrimOptimizedCodeMap(old_length - new_length); |
| + } |
| + |
| + holder = next_holder; |
| + } |
| + |
| + optimized_code_map_holder_head_ = NULL; |
| +} |
| + |
| + |
| void CodeFlusher::EvictCandidate(SharedFunctionInfo* shared_info) { |
| // Make sure previous flushing decisions are revisited. |
| isolate_->heap()->incremental_marking()->RecordWrites(shared_info); |
| @@ -1112,6 +1173,36 @@ void CodeFlusher::EvictCandidate(JSFunction* function) { |
| } |
| +void CodeFlusher::EvictOptimizedCodeMap(SharedFunctionInfo* code_map_holder) { |
| + ASSERT(!FixedArray::cast(code_map_holder->optimized_code_map())-> |
| + get(SharedFunctionInfo::kNextMapIndex)->IsUndefined()); |
| + |
| + // Make sure previous flushing decisions are revisited. |
| + isolate_->heap()->incremental_marking()->RecordWrites(code_map_holder); |
| + |
| + SharedFunctionInfo* holder = optimized_code_map_holder_head_; |
| + SharedFunctionInfo* next_holder; |
| + if (holder == code_map_holder) { |
| + next_holder = GetNextCodeMap(code_map_holder); |
| + optimized_code_map_holder_head_ = next_holder; |
| + ClearNextCodeMap(code_map_holder); |
| + } else { |
| + while (holder != NULL) { |
| + next_holder = GetNextCodeMap(holder); |
| + |
| + if (next_holder == code_map_holder) { |
| + next_holder = GetNextCodeMap(code_map_holder); |
| + SetNextCodeMap(holder, next_holder); |
| + ClearNextCodeMap(code_map_holder); |
| + break; |
| + } |
| + |
| + holder = next_holder; |
| + } |
| + } |
|
Hannes Payer (out of office)
2013/05/15 13:11:25
A follow-up CL could refactor the list handling co
Michael Starzinger
2013/05/15 15:09:57
Agreed. If have two ideas for cleanup:
1) Come up
|
| +} |
| + |
| + |
| void CodeFlusher::EvictJSFunctionCandidates() { |
| JSFunction* candidate = jsfunction_candidates_head_; |
| JSFunction* next_candidate; |
| @@ -1136,6 +1227,18 @@ void CodeFlusher::EvictSharedFunctionInfoCandidates() { |
| } |
| +void CodeFlusher::EvictOptimizedCodeMaps() { |
| + SharedFunctionInfo* holder = optimized_code_map_holder_head_; |
| + SharedFunctionInfo* next_holder; |
| + while (holder != NULL) { |
| + next_holder = GetNextCodeMap(holder); |
| + EvictOptimizedCodeMap(holder); |
| + holder = next_holder; |
| + } |
| + ASSERT(optimized_code_map_holder_head_ == NULL); |
| +} |
| + |
| + |
| void CodeFlusher::IteratePointersToFromSpace(ObjectVisitor* v) { |
| Heap* heap = isolate_->heap(); |
| @@ -3955,6 +4058,10 @@ void MarkCompactCollector::EnableCodeFlushing(bool enable) { |
| delete code_flusher_; |
| code_flusher_ = NULL; |
| } |
| + |
| + if (FLAG_trace_code_flushing) { |
| + PrintF("[code-flushing is now %s]\n", enable ? "on" : "off"); |
| + } |
| } |