| 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/v8.h" | 5 #include "src/v8.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/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/compilation-cache.h" | 10 #include "src/compilation-cache.h" |
| (...skipping 850 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 861 SharedFunctionInfo* shared = candidate->shared(); | 861 SharedFunctionInfo* shared = candidate->shared(); |
| 862 | 862 |
| 863 Code* code = shared->code(); | 863 Code* code = shared->code(); |
| 864 MarkBit code_mark = Marking::MarkBitFrom(code); | 864 MarkBit code_mark = Marking::MarkBitFrom(code); |
| 865 if (Marking::IsWhite(code_mark)) { | 865 if (Marking::IsWhite(code_mark)) { |
| 866 if (FLAG_trace_code_flushing && shared->is_compiled()) { | 866 if (FLAG_trace_code_flushing && shared->is_compiled()) { |
| 867 PrintF("[code-flushing clears: "); | 867 PrintF("[code-flushing clears: "); |
| 868 shared->ShortPrint(); | 868 shared->ShortPrint(); |
| 869 PrintF(" - age: %d]\n", code->GetAge()); | 869 PrintF(" - age: %d]\n", code->GetAge()); |
| 870 } | 870 } |
| 871 // Always flush the optimized code map if requested by flag. | 871 // Always flush the optimized code map if there is one. |
| 872 if (FLAG_flush_optimized_code_cache && | 872 if (!shared->optimized_code_map()->IsSmi()) { |
| 873 !shared->optimized_code_map()->IsSmi()) { | |
| 874 shared->ClearOptimizedCodeMap(); | 873 shared->ClearOptimizedCodeMap(); |
| 875 } | 874 } |
| 876 shared->set_code(lazy_compile); | 875 shared->set_code(lazy_compile); |
| 877 candidate->set_code(lazy_compile); | 876 candidate->set_code(lazy_compile); |
| 878 } else { | 877 } else { |
| 879 DCHECK(Marking::IsBlack(code_mark)); | 878 DCHECK(Marking::IsBlack(code_mark)); |
| 880 candidate->set_code(code); | 879 candidate->set_code(code); |
| 881 } | 880 } |
| 882 | 881 |
| 883 // We are in the middle of a GC cycle so the write barrier in the code | 882 // We are in the middle of a GC cycle so the write barrier in the code |
| (...skipping 25 matching lines...) Expand all Loading... |
| 909 ClearNextCandidate(candidate); | 908 ClearNextCandidate(candidate); |
| 910 | 909 |
| 911 Code* code = candidate->code(); | 910 Code* code = candidate->code(); |
| 912 MarkBit code_mark = Marking::MarkBitFrom(code); | 911 MarkBit code_mark = Marking::MarkBitFrom(code); |
| 913 if (Marking::IsWhite(code_mark)) { | 912 if (Marking::IsWhite(code_mark)) { |
| 914 if (FLAG_trace_code_flushing && candidate->is_compiled()) { | 913 if (FLAG_trace_code_flushing && candidate->is_compiled()) { |
| 915 PrintF("[code-flushing clears: "); | 914 PrintF("[code-flushing clears: "); |
| 916 candidate->ShortPrint(); | 915 candidate->ShortPrint(); |
| 917 PrintF(" - age: %d]\n", code->GetAge()); | 916 PrintF(" - age: %d]\n", code->GetAge()); |
| 918 } | 917 } |
| 919 // Always flush the optimized code map if requested by flag. | 918 // Always flush the optimized code map if there is one. |
| 920 if (FLAG_flush_optimized_code_cache && | 919 if (!candidate->optimized_code_map()->IsSmi()) { |
| 921 !candidate->optimized_code_map()->IsSmi()) { | |
| 922 candidate->ClearOptimizedCodeMap(); | 920 candidate->ClearOptimizedCodeMap(); |
| 923 } | 921 } |
| 924 candidate->set_code(lazy_compile); | 922 candidate->set_code(lazy_compile); |
| 925 } | 923 } |
| 926 | 924 |
| 927 Object** code_slot = | 925 Object** code_slot = |
| 928 HeapObject::RawField(candidate, SharedFunctionInfo::kCodeOffset); | 926 HeapObject::RawField(candidate, SharedFunctionInfo::kCodeOffset); |
| 929 isolate_->heap()->mark_compact_collector()->RecordSlot(code_slot, code_slot, | 927 isolate_->heap()->mark_compact_collector()->RecordSlot(code_slot, code_slot, |
| 930 *code_slot); | 928 *code_slot); |
| 931 | 929 |
| 932 candidate = next_candidate; | 930 candidate = next_candidate; |
| 933 } | 931 } |
| 934 | 932 |
| 935 shared_function_info_candidates_head_ = NULL; | 933 shared_function_info_candidates_head_ = NULL; |
| 936 } | 934 } |
| 937 | 935 |
| 938 | 936 |
| 939 void CodeFlusher::ProcessOptimizedCodeMaps() { | 937 void CodeFlusher::ProcessOptimizedCodeMaps() { |
| 940 STATIC_ASSERT(SharedFunctionInfo::kEntryLength == 4); | 938 STATIC_ASSERT(SharedFunctionInfo::kEntryLength == 4); |
| 941 | 939 |
| 942 SharedFunctionInfo* holder = optimized_code_map_holder_head_; | 940 SharedFunctionInfo* holder = optimized_code_map_holder_head_; |
| 943 SharedFunctionInfo* next_holder; | 941 SharedFunctionInfo* next_holder; |
| 944 | 942 |
| 945 while (holder != NULL) { | 943 while (holder != NULL) { |
| 946 next_holder = GetNextCodeMap(holder); | 944 next_holder = GetNextCodeMap(holder); |
| 947 ClearNextCodeMap(holder); | 945 ClearNextCodeMap(holder); |
| 948 | 946 |
| 947 // Process context-dependent entries in the optimized code map. |
| 949 FixedArray* code_map = FixedArray::cast(holder->optimized_code_map()); | 948 FixedArray* code_map = FixedArray::cast(holder->optimized_code_map()); |
| 950 int new_length = SharedFunctionInfo::kEntriesStart; | 949 int new_length = SharedFunctionInfo::kEntriesStart; |
| 951 int old_length = code_map->length(); | 950 int old_length = code_map->length(); |
| 952 for (int i = SharedFunctionInfo::kEntriesStart; i < old_length; | 951 for (int i = SharedFunctionInfo::kEntriesStart; i < old_length; |
| 953 i += SharedFunctionInfo::kEntryLength) { | 952 i += SharedFunctionInfo::kEntryLength) { |
| 954 Code* code = | 953 Code* code = |
| 955 Code::cast(code_map->get(i + SharedFunctionInfo::kCachedCodeOffset)); | 954 Code::cast(code_map->get(i + SharedFunctionInfo::kCachedCodeOffset)); |
| 956 if (Marking::IsWhite(Marking::MarkBitFrom(code))) continue; | 955 if (Marking::IsWhite(Marking::MarkBitFrom(code))) continue; |
| 957 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(code))); | 956 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(code))); |
| 958 // Move every slot in the entry. | 957 // Move every slot in the entry. |
| 959 for (int j = 0; j < SharedFunctionInfo::kEntryLength; j++) { | 958 for (int j = 0; j < SharedFunctionInfo::kEntryLength; j++) { |
| 960 int dst_index = new_length++; | 959 int dst_index = new_length++; |
| 961 Object** slot = code_map->RawFieldOfElementAt(dst_index); | 960 Object** slot = code_map->RawFieldOfElementAt(dst_index); |
| 962 Object* object = code_map->get(i + j); | 961 Object* object = code_map->get(i + j); |
| 963 code_map->set(dst_index, object); | 962 code_map->set(dst_index, object); |
| 964 if (j == SharedFunctionInfo::kOsrAstIdOffset) { | 963 if (j == SharedFunctionInfo::kOsrAstIdOffset) { |
| 965 DCHECK(object->IsSmi()); | 964 DCHECK(object->IsSmi()); |
| 966 } else { | 965 } else { |
| 967 DCHECK( | 966 DCHECK( |
| 968 Marking::IsBlack(Marking::MarkBitFrom(HeapObject::cast(*slot)))); | 967 Marking::IsBlack(Marking::MarkBitFrom(HeapObject::cast(*slot)))); |
| 969 isolate_->heap()->mark_compact_collector()->RecordSlot(slot, slot, | 968 isolate_->heap()->mark_compact_collector()->RecordSlot(slot, slot, |
| 970 *slot); | 969 *slot); |
| 971 } | 970 } |
| 972 } | 971 } |
| 973 } | 972 } |
| 974 | 973 |
| 974 // Process context-independent entry in the optimized code map. |
| 975 Object* shared_object = code_map->get(SharedFunctionInfo::kSharedCodeIndex); |
| 976 if (shared_object->IsCode()) { |
| 977 Code* shared_code = Code::cast(shared_object); |
| 978 if (Marking::IsWhite(Marking::MarkBitFrom(shared_code))) { |
| 979 code_map->set_undefined(SharedFunctionInfo::kSharedCodeIndex); |
| 980 } else { |
| 981 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(shared_code))); |
| 982 Object** slot = |
| 983 code_map->RawFieldOfElementAt(SharedFunctionInfo::kSharedCodeIndex); |
| 984 isolate_->heap()->mark_compact_collector()->RecordSlot(slot, slot, |
| 985 *slot); |
| 986 } |
| 987 } |
| 988 |
| 975 // Trim the optimized code map if entries have been removed. | 989 // Trim the optimized code map if entries have been removed. |
| 976 if (new_length < old_length) { | 990 if (new_length < old_length) { |
| 977 holder->TrimOptimizedCodeMap(old_length - new_length); | 991 holder->TrimOptimizedCodeMap(old_length - new_length); |
| 978 } | 992 } |
| 979 | 993 |
| 980 holder = next_holder; | 994 holder = next_holder; |
| 981 } | 995 } |
| 982 | 996 |
| 983 optimized_code_map_holder_head_ = NULL; | 997 optimized_code_map_holder_head_ = NULL; |
| 984 } | 998 } |
| (...skipping 3639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4624 SlotsBuffer* buffer = *buffer_address; | 4638 SlotsBuffer* buffer = *buffer_address; |
| 4625 while (buffer != NULL) { | 4639 while (buffer != NULL) { |
| 4626 SlotsBuffer* next_buffer = buffer->next(); | 4640 SlotsBuffer* next_buffer = buffer->next(); |
| 4627 DeallocateBuffer(buffer); | 4641 DeallocateBuffer(buffer); |
| 4628 buffer = next_buffer; | 4642 buffer = next_buffer; |
| 4629 } | 4643 } |
| 4630 *buffer_address = NULL; | 4644 *buffer_address = NULL; |
| 4631 } | 4645 } |
| 4632 } // namespace internal | 4646 } // namespace internal |
| 4633 } // namespace v8 | 4647 } // namespace v8 |
| OLD | NEW |