OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/heap/mark-compact.h" | 5 #include "src/heap/mark-compact.h" |
6 | 6 |
7 #include "src/base/atomicops.h" | 7 #include "src/base/atomicops.h" |
8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
9 #include "src/base/sys-info.h" | 9 #include "src/base/sys-info.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
897 // the marking stack. Instead, we mark them as both marked and overflowed. | 897 // the marking stack. Instead, we mark them as both marked and overflowed. |
898 // When the stack is in the overflowed state, objects marked as overflowed | 898 // When the stack is in the overflowed state, objects marked as overflowed |
899 // have been reached and marked but their children have not been visited yet. | 899 // have been reached and marked but their children have not been visited yet. |
900 // After emptying the marking stack, we clear the overflow flag and traverse | 900 // After emptying the marking stack, we clear the overflow flag and traverse |
901 // the heap looking for objects marked as overflowed, push them on the stack, | 901 // the heap looking for objects marked as overflowed, push them on the stack, |
902 // and continue with marking. This process repeats until all reachable | 902 // and continue with marking. This process repeats until all reachable |
903 // objects have been marked. | 903 // objects have been marked. |
904 | 904 |
905 void CodeFlusher::ProcessJSFunctionCandidates() { | 905 void CodeFlusher::ProcessJSFunctionCandidates() { |
906 Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kCompileLazy); | 906 Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kCompileLazy); |
| 907 Code* interpreter_entry_trampoline = |
| 908 isolate_->builtins()->builtin(Builtins::kInterpreterEntryTrampoline); |
907 Object* undefined = isolate_->heap()->undefined_value(); | 909 Object* undefined = isolate_->heap()->undefined_value(); |
908 | 910 |
909 JSFunction* candidate = jsfunction_candidates_head_; | 911 JSFunction* candidate = jsfunction_candidates_head_; |
910 JSFunction* next_candidate; | 912 JSFunction* next_candidate; |
911 while (candidate != NULL) { | 913 while (candidate != NULL) { |
912 next_candidate = GetNextCandidate(candidate); | 914 next_candidate = GetNextCandidate(candidate); |
913 ClearNextCandidate(candidate, undefined); | 915 ClearNextCandidate(candidate, undefined); |
914 | 916 |
915 SharedFunctionInfo* shared = candidate->shared(); | 917 SharedFunctionInfo* shared = candidate->shared(); |
916 | 918 |
917 Code* code = shared->code(); | 919 Code* code = shared->code(); |
918 MarkBit code_mark = ObjectMarking::MarkBitFrom(code); | 920 MarkBit code_mark = ObjectMarking::MarkBitFrom(code); |
919 if (Marking::IsWhite(code_mark)) { | 921 if (Marking::IsWhite(code_mark)) { |
920 if (FLAG_trace_code_flushing && shared->is_compiled()) { | 922 if (FLAG_trace_code_flushing && shared->is_compiled()) { |
921 PrintF("[code-flushing clears: "); | 923 PrintF("[code-flushing clears: "); |
922 shared->ShortPrint(); | 924 shared->ShortPrint(); |
923 PrintF(" - age: %d]\n", code->GetAge()); | 925 PrintF(" - age: %d]\n", code->GetAge()); |
924 } | 926 } |
925 // Always flush the optimized code map if there is one. | 927 // Always flush the optimized code map if there is one. |
926 if (!shared->OptimizedCodeMapIsCleared()) { | 928 if (!shared->OptimizedCodeMapIsCleared()) { |
927 shared->ClearOptimizedCodeMap(); | 929 shared->ClearOptimizedCodeMap(); |
928 } | 930 } |
929 shared->set_code(lazy_compile); | 931 if (shared->HasBytecodeArray()) { |
930 candidate->set_code(lazy_compile); | 932 shared->set_code(interpreter_entry_trampoline); |
| 933 candidate->set_code(interpreter_entry_trampoline); |
| 934 } else { |
| 935 shared->set_code(lazy_compile); |
| 936 candidate->set_code(lazy_compile); |
| 937 } |
931 } else { | 938 } else { |
932 DCHECK(Marking::IsBlack(code_mark)); | 939 DCHECK(Marking::IsBlack(code_mark)); |
933 candidate->set_code(code); | 940 candidate->set_code(code); |
934 } | 941 } |
935 | 942 |
936 // We are in the middle of a GC cycle so the write barrier in the code | 943 // We are in the middle of a GC cycle so the write barrier in the code |
937 // setter did not record the slot update and we have to do that manually. | 944 // setter did not record the slot update and we have to do that manually. |
938 Address slot = candidate->address() + JSFunction::kCodeEntryOffset; | 945 Address slot = candidate->address() + JSFunction::kCodeEntryOffset; |
939 Code* target = Code::cast(Code::GetObjectFromEntryAddress(slot)); | 946 Code* target = Code::cast(Code::GetObjectFromEntryAddress(slot)); |
940 isolate_->heap()->mark_compact_collector()->RecordCodeEntrySlot( | 947 isolate_->heap()->mark_compact_collector()->RecordCodeEntrySlot( |
941 candidate, slot, target); | 948 candidate, slot, target); |
942 | 949 |
943 Object** shared_code_slot = | 950 Object** shared_code_slot = |
944 HeapObject::RawField(shared, SharedFunctionInfo::kCodeOffset); | 951 HeapObject::RawField(shared, SharedFunctionInfo::kCodeOffset); |
945 isolate_->heap()->mark_compact_collector()->RecordSlot( | 952 isolate_->heap()->mark_compact_collector()->RecordSlot( |
946 shared, shared_code_slot, *shared_code_slot); | 953 shared, shared_code_slot, *shared_code_slot); |
947 | 954 |
948 candidate = next_candidate; | 955 candidate = next_candidate; |
949 } | 956 } |
950 | 957 |
951 jsfunction_candidates_head_ = NULL; | 958 jsfunction_candidates_head_ = NULL; |
952 } | 959 } |
953 | 960 |
954 | 961 |
955 void CodeFlusher::ProcessSharedFunctionInfoCandidates() { | 962 void CodeFlusher::ProcessSharedFunctionInfoCandidates() { |
956 Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kCompileLazy); | 963 Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kCompileLazy); |
957 | 964 Code* interpreter_entry_trampoline = |
| 965 isolate_->builtins()->builtin(Builtins::kInterpreterEntryTrampoline); |
958 SharedFunctionInfo* candidate = shared_function_info_candidates_head_; | 966 SharedFunctionInfo* candidate = shared_function_info_candidates_head_; |
959 SharedFunctionInfo* next_candidate; | 967 SharedFunctionInfo* next_candidate; |
960 while (candidate != NULL) { | 968 while (candidate != NULL) { |
961 next_candidate = GetNextCandidate(candidate); | 969 next_candidate = GetNextCandidate(candidate); |
962 ClearNextCandidate(candidate); | 970 ClearNextCandidate(candidate); |
963 | 971 |
964 Code* code = candidate->code(); | 972 Code* code = candidate->code(); |
965 MarkBit code_mark = ObjectMarking::MarkBitFrom(code); | 973 MarkBit code_mark = ObjectMarking::MarkBitFrom(code); |
966 if (Marking::IsWhite(code_mark)) { | 974 if (Marking::IsWhite(code_mark)) { |
967 if (FLAG_trace_code_flushing && candidate->is_compiled()) { | 975 if (FLAG_trace_code_flushing && candidate->is_compiled()) { |
968 PrintF("[code-flushing clears: "); | 976 PrintF("[code-flushing clears: "); |
969 candidate->ShortPrint(); | 977 candidate->ShortPrint(); |
970 PrintF(" - age: %d]\n", code->GetAge()); | 978 PrintF(" - age: %d]\n", code->GetAge()); |
971 } | 979 } |
972 // Always flush the optimized code map if there is one. | 980 // Always flush the optimized code map if there is one. |
973 if (!candidate->OptimizedCodeMapIsCleared()) { | 981 if (!candidate->OptimizedCodeMapIsCleared()) { |
974 candidate->ClearOptimizedCodeMap(); | 982 candidate->ClearOptimizedCodeMap(); |
975 } | 983 } |
976 candidate->set_code(lazy_compile); | 984 if (candidate->HasBytecodeArray()) { |
| 985 candidate->set_code(interpreter_entry_trampoline); |
| 986 } else { |
| 987 candidate->set_code(lazy_compile); |
| 988 } |
977 } | 989 } |
978 | 990 |
979 Object** code_slot = | 991 Object** code_slot = |
980 HeapObject::RawField(candidate, SharedFunctionInfo::kCodeOffset); | 992 HeapObject::RawField(candidate, SharedFunctionInfo::kCodeOffset); |
981 isolate_->heap()->mark_compact_collector()->RecordSlot(candidate, code_slot, | 993 isolate_->heap()->mark_compact_collector()->RecordSlot(candidate, code_slot, |
982 *code_slot); | 994 *code_slot); |
983 | 995 |
984 candidate = next_candidate; | 996 candidate = next_candidate; |
985 } | 997 } |
986 | 998 |
(...skipping 3081 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4068 // The target is always in old space, we don't have to record the slot in | 4080 // The target is always in old space, we don't have to record the slot in |
4069 // the old-to-new remembered set. | 4081 // the old-to-new remembered set. |
4070 DCHECK(!heap()->InNewSpace(target)); | 4082 DCHECK(!heap()->InNewSpace(target)); |
4071 RecordRelocSlot(host, &rinfo, target); | 4083 RecordRelocSlot(host, &rinfo, target); |
4072 } | 4084 } |
4073 } | 4085 } |
4074 } | 4086 } |
4075 | 4087 |
4076 } // namespace internal | 4088 } // namespace internal |
4077 } // namespace v8 | 4089 } // namespace v8 |
OLD | NEW |