OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/objects.h" | 5 #include "src/objects.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 #include <iomanip> | 8 #include <iomanip> |
9 #include <memory> | 9 #include <memory> |
10 #include <sstream> | 10 #include <sstream> |
(...skipping 12117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12128 LiteralsArray::New(isolate, feedback_vector, shared->num_literals()); | 12128 LiteralsArray::New(isolate, feedback_vector, shared->num_literals()); |
12129 Handle<Code> code; | 12129 Handle<Code> code; |
12130 if (result.code != nullptr) { | 12130 if (result.code != nullptr) { |
12131 code = Handle<Code>(result.code, isolate); | 12131 code = Handle<Code>(result.code, isolate); |
12132 } | 12132 } |
12133 AddToOptimizedCodeMap(shared, native_context, code, literals, | 12133 AddToOptimizedCodeMap(shared, native_context, code, literals, |
12134 BailoutId::None()); | 12134 BailoutId::None()); |
12135 return literals; | 12135 return literals; |
12136 } | 12136 } |
12137 | 12137 |
| 12138 void SharedFunctionInfo::AddSharedCodeToOptimizedCodeMap( |
| 12139 Handle<SharedFunctionInfo> shared, Handle<Code> code) { |
| 12140 Isolate* isolate = shared->GetIsolate(); |
| 12141 if (isolate->serializer_enabled()) return; |
| 12142 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION); |
| 12143 // Empty code maps are unsupported. |
| 12144 if (!shared->OptimizedCodeMapIsCleared()) { |
| 12145 Handle<WeakCell> cell = isolate->factory()->NewWeakCell(code); |
| 12146 // A collection may have occured and cleared the optimized code map in the |
| 12147 // allocation above. |
| 12148 if (!shared->OptimizedCodeMapIsCleared()) { |
| 12149 shared->optimized_code_map()->set(kSharedCodeIndex, *cell); |
| 12150 } |
| 12151 } |
| 12152 } |
| 12153 |
12138 // static | 12154 // static |
12139 void SharedFunctionInfo::AddToOptimizedCodeMap( | 12155 void SharedFunctionInfo::AddToOptimizedCodeMap( |
12140 Handle<SharedFunctionInfo> shared, Handle<Context> native_context, | 12156 Handle<SharedFunctionInfo> shared, Handle<Context> native_context, |
12141 MaybeHandle<Code> code, Handle<LiteralsArray> literals, | 12157 MaybeHandle<Code> code, Handle<LiteralsArray> literals, |
12142 BailoutId osr_ast_id) { | 12158 BailoutId osr_ast_id) { |
12143 Isolate* isolate = shared->GetIsolate(); | 12159 Isolate* isolate = shared->GetIsolate(); |
12144 if (isolate->serializer_enabled()) return; | 12160 if (isolate->serializer_enabled()) return; |
12145 DCHECK(code.is_null() || | 12161 DCHECK(code.is_null() || |
12146 code.ToHandleChecked()->kind() == Code::OPTIMIZED_FUNCTION); | 12162 code.ToHandleChecked()->kind() == Code::OPTIMIZED_FUNCTION); |
12147 DCHECK(native_context->IsNativeContext()); | 12163 DCHECK(native_context->IsNativeContext()); |
12148 STATIC_ASSERT(kEntryLength == 4); | 12164 STATIC_ASSERT(kEntryLength == 4); |
12149 Handle<FixedArray> new_code_map; | 12165 Handle<FixedArray> new_code_map; |
12150 int entry; | 12166 int entry; |
12151 | 12167 |
12152 if (shared->OptimizedCodeMapIsCleared()) { | 12168 if (shared->OptimizedCodeMapIsCleared()) { |
12153 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); | 12169 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); |
| 12170 new_code_map->set(kSharedCodeIndex, *isolate->factory()->empty_weak_cell(), |
| 12171 SKIP_WRITE_BARRIER); |
12154 entry = kEntriesStart; | 12172 entry = kEntriesStart; |
12155 } else { | 12173 } else { |
12156 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate); | 12174 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate); |
12157 entry = shared->SearchOptimizedCodeMapEntry(*native_context, osr_ast_id); | 12175 entry = shared->SearchOptimizedCodeMapEntry(*native_context, osr_ast_id); |
12158 if (entry >= kEntriesStart) { | 12176 if (entry > kSharedCodeIndex) { |
12159 // Just set the code and literals of the entry. | 12177 // Just set the code and literals of the entry. |
12160 if (!code.is_null()) { | 12178 if (!code.is_null()) { |
12161 Handle<WeakCell> code_cell = | 12179 Handle<WeakCell> code_cell = |
12162 isolate->factory()->NewWeakCell(code.ToHandleChecked()); | 12180 isolate->factory()->NewWeakCell(code.ToHandleChecked()); |
12163 old_code_map->set(entry + kCachedCodeOffset, *code_cell); | 12181 old_code_map->set(entry + kCachedCodeOffset, *code_cell); |
12164 } | 12182 } |
12165 Handle<WeakCell> literals_cell = | 12183 Handle<WeakCell> literals_cell = |
12166 isolate->factory()->NewWeakCell(literals); | 12184 isolate->factory()->NewWeakCell(literals); |
12167 old_code_map->set(entry + kLiteralsOffset, *literals_cell); | 12185 old_code_map->set(entry + kLiteralsOffset, *literals_cell); |
12168 return; | 12186 return; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12218 #endif | 12236 #endif |
12219 | 12237 |
12220 FixedArray* old_code_map = shared->optimized_code_map(); | 12238 FixedArray* old_code_map = shared->optimized_code_map(); |
12221 if (old_code_map != *new_code_map) { | 12239 if (old_code_map != *new_code_map) { |
12222 shared->set_optimized_code_map(*new_code_map); | 12240 shared->set_optimized_code_map(*new_code_map); |
12223 } | 12241 } |
12224 } | 12242 } |
12225 | 12243 |
12226 | 12244 |
12227 void SharedFunctionInfo::ClearOptimizedCodeMap() { | 12245 void SharedFunctionInfo::ClearOptimizedCodeMap() { |
12228 FixedArray* empty_fixed_array = GetHeap()->empty_fixed_array(); | 12246 FixedArray* cleared_map = GetHeap()->cleared_optimized_code_map(); |
12229 set_optimized_code_map(empty_fixed_array, SKIP_WRITE_BARRIER); | 12247 set_optimized_code_map(cleared_map, SKIP_WRITE_BARRIER); |
12230 } | 12248 } |
12231 | 12249 |
12232 | 12250 |
12233 void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code, | 12251 void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code, |
12234 const char* reason) { | 12252 const char* reason) { |
12235 DisallowHeapAllocation no_gc; | 12253 DisallowHeapAllocation no_gc; |
12236 if (OptimizedCodeMapIsCleared()) return; | 12254 if (OptimizedCodeMapIsCleared()) return; |
12237 | 12255 |
12238 Heap* heap = GetHeap(); | 12256 Heap* heap = GetHeap(); |
12239 FixedArray* code_map = optimized_code_map(); | 12257 FixedArray* code_map = optimized_code_map(); |
(...skipping 29 matching lines...) Expand all Loading... |
12269 code_map->set(dst + kContextOffset, code_map->get(src + kContextOffset)); | 12287 code_map->set(dst + kContextOffset, code_map->get(src + kContextOffset)); |
12270 code_map->set(dst + kCachedCodeOffset, | 12288 code_map->set(dst + kCachedCodeOffset, |
12271 code_map->get(src + kCachedCodeOffset)); | 12289 code_map->get(src + kCachedCodeOffset)); |
12272 code_map->set(dst + kLiteralsOffset, | 12290 code_map->set(dst + kLiteralsOffset, |
12273 code_map->get(src + kLiteralsOffset)); | 12291 code_map->get(src + kLiteralsOffset)); |
12274 code_map->set(dst + kOsrAstIdOffset, | 12292 code_map->set(dst + kOsrAstIdOffset, |
12275 code_map->get(src + kOsrAstIdOffset)); | 12293 code_map->get(src + kOsrAstIdOffset)); |
12276 } | 12294 } |
12277 dst += kEntryLength; | 12295 dst += kEntryLength; |
12278 } | 12296 } |
| 12297 if (WeakCell::cast(code_map->get(kSharedCodeIndex))->value() == |
| 12298 optimized_code) { |
| 12299 // Evict context-independent code as well. |
| 12300 code_map->set(kSharedCodeIndex, heap->empty_weak_cell(), |
| 12301 SKIP_WRITE_BARRIER); |
| 12302 if (FLAG_trace_opt) { |
| 12303 PrintF("[evicting entry from optimizing code map (%s) for ", reason); |
| 12304 ShortPrint(); |
| 12305 PrintF(" (context-independent code)]\n"); |
| 12306 } |
| 12307 } |
12279 if (dst != length) { | 12308 if (dst != length) { |
12280 // Always trim even when array is cleared because of heap verifier. | 12309 // Always trim even when array is cleared because of heap verifier. |
12281 heap->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(code_map, | 12310 heap->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(code_map, |
12282 length - dst); | 12311 length - dst); |
12283 if (code_map->length() == kEntriesStart) { | 12312 if (code_map->length() == kEntriesStart && |
| 12313 WeakCell::cast(code_map->get(kSharedCodeIndex))->cleared()) { |
12284 ClearOptimizedCodeMap(); | 12314 ClearOptimizedCodeMap(); |
12285 } | 12315 } |
12286 } | 12316 } |
12287 } | 12317 } |
12288 | 12318 |
12289 | 12319 |
12290 void SharedFunctionInfo::TrimOptimizedCodeMap(int shrink_by) { | 12320 void SharedFunctionInfo::TrimOptimizedCodeMap(int shrink_by) { |
12291 FixedArray* code_map = optimized_code_map(); | 12321 FixedArray* code_map = optimized_code_map(); |
12292 DCHECK(shrink_by % kEntryLength == 0); | 12322 DCHECK(shrink_by % kEntryLength == 0); |
12293 DCHECK(shrink_by <= code_map->length() - kEntriesStart); | 12323 DCHECK(shrink_by <= code_map->length() - kEntriesStart); |
12294 // Always trim even when array is cleared because of heap verifier. | 12324 // Always trim even when array is cleared because of heap verifier. |
12295 GetHeap()->RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>(code_map, | 12325 GetHeap()->RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>(code_map, |
12296 shrink_by); | 12326 shrink_by); |
12297 if (code_map->length() == kEntriesStart) { | 12327 if (code_map->length() == kEntriesStart && |
| 12328 WeakCell::cast(code_map->get(kSharedCodeIndex))->cleared()) { |
12298 ClearOptimizedCodeMap(); | 12329 ClearOptimizedCodeMap(); |
12299 } | 12330 } |
12300 } | 12331 } |
12301 | 12332 |
12302 // static | 12333 // static |
12303 void JSFunction::EnsureLiterals(Handle<JSFunction> function) { | 12334 void JSFunction::EnsureLiterals(Handle<JSFunction> function) { |
12304 Handle<SharedFunctionInfo> shared(function->shared()); | 12335 Handle<SharedFunctionInfo> shared(function->shared()); |
12305 Handle<Context> native_context(function->context()->native_context()); | 12336 Handle<Context> native_context(function->context()->native_context()); |
12306 if (function->literals() == | 12337 if (function->literals() == |
12307 function->GetIsolate()->heap()->empty_literals_array()) { | 12338 function->GetIsolate()->heap()->empty_literals_array()) { |
(...skipping 1492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13800 FixedArray* optimized_code_map = this->optimized_code_map(); | 13831 FixedArray* optimized_code_map = this->optimized_code_map(); |
13801 int length = optimized_code_map->length(); | 13832 int length = optimized_code_map->length(); |
13802 Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt()); | 13833 Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt()); |
13803 for (int i = kEntriesStart; i < length; i += kEntryLength) { | 13834 for (int i = kEntriesStart; i < length; i += kEntryLength) { |
13804 if (WeakCell::cast(optimized_code_map->get(i + kContextOffset)) | 13835 if (WeakCell::cast(optimized_code_map->get(i + kContextOffset)) |
13805 ->value() == native_context && | 13836 ->value() == native_context && |
13806 optimized_code_map->get(i + kOsrAstIdOffset) == osr_ast_id_smi) { | 13837 optimized_code_map->get(i + kOsrAstIdOffset) == osr_ast_id_smi) { |
13807 return i; | 13838 return i; |
13808 } | 13839 } |
13809 } | 13840 } |
| 13841 Object* shared_code = |
| 13842 WeakCell::cast(optimized_code_map->get(kSharedCodeIndex))->value(); |
| 13843 if (shared_code->IsCode() && osr_ast_id.IsNone()) { |
| 13844 return kSharedCodeIndex; |
| 13845 } |
13810 } | 13846 } |
13811 return -1; | 13847 return -1; |
13812 } | 13848 } |
13813 | 13849 |
13814 void SharedFunctionInfo::ClearCodeFromOptimizedCodeMap() { | 13850 void SharedFunctionInfo::ClearCodeFromOptimizedCodeMap() { |
13815 if (!OptimizedCodeMapIsCleared()) { | 13851 if (!OptimizedCodeMapIsCleared()) { |
13816 FixedArray* optimized_code_map = this->optimized_code_map(); | 13852 FixedArray* optimized_code_map = this->optimized_code_map(); |
13817 int length = optimized_code_map->length(); | 13853 int length = optimized_code_map->length(); |
13818 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell(); | 13854 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell(); |
13819 for (int i = kEntriesStart; i < length; i += kEntryLength) { | 13855 for (int i = kEntriesStart; i < length; i += kEntryLength) { |
13820 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell, | 13856 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell, |
13821 SKIP_WRITE_BARRIER); | 13857 SKIP_WRITE_BARRIER); |
13822 } | 13858 } |
| 13859 optimized_code_map->set(kSharedCodeIndex, empty_weak_cell, |
| 13860 SKIP_WRITE_BARRIER); |
13823 } | 13861 } |
13824 } | 13862 } |
13825 | 13863 |
13826 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( | 13864 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( |
13827 Context* native_context, BailoutId osr_ast_id) { | 13865 Context* native_context, BailoutId osr_ast_id) { |
13828 CodeAndLiterals result = {nullptr, nullptr}; | 13866 CodeAndLiterals result = {nullptr, nullptr}; |
13829 int entry = SearchOptimizedCodeMapEntry(native_context, osr_ast_id); | 13867 int entry = SearchOptimizedCodeMapEntry(native_context, osr_ast_id); |
13830 if (entry != kNotFound) { | 13868 if (entry != kNotFound) { |
13831 FixedArray* code_map = optimized_code_map(); | 13869 FixedArray* code_map = optimized_code_map(); |
13832 DCHECK_LE(entry + kEntryLength, code_map->length()); | 13870 if (entry == kSharedCodeIndex) { |
13833 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset)); | 13871 // We know the weak cell isn't cleared because we made sure of it in |
13834 WeakCell* literals_cell = | 13872 // SearchOptimizedCodeMapEntry and performed no allocations since that |
13835 WeakCell::cast(code_map->get(entry + kLiteralsOffset)); | 13873 // call. |
| 13874 result = { |
| 13875 Code::cast(WeakCell::cast(code_map->get(kSharedCodeIndex))->value()), |
| 13876 nullptr}; |
| 13877 } else { |
| 13878 DCHECK_LE(entry + kEntryLength, code_map->length()); |
| 13879 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset)); |
| 13880 WeakCell* literals_cell = |
| 13881 WeakCell::cast(code_map->get(entry + kLiteralsOffset)); |
13836 | 13882 |
13837 result = {cell->cleared() ? nullptr : Code::cast(cell->value()), | 13883 result = {cell->cleared() ? nullptr : Code::cast(cell->value()), |
13838 literals_cell->cleared() ? nullptr : LiteralsArray::cast( | 13884 literals_cell->cleared() |
13839 literals_cell->value())}; | 13885 ? nullptr |
| 13886 : LiteralsArray::cast(literals_cell->value())}; |
| 13887 } |
13840 } | 13888 } |
13841 return result; | 13889 return result; |
13842 } | 13890 } |
13843 | 13891 |
13844 | 13892 |
13845 #define DECLARE_TAG(ignore1, name, ignore2) name, | 13893 #define DECLARE_TAG(ignore1, name, ignore2) name, |
13846 const char* const VisitorSynchronization::kTags[ | 13894 const char* const VisitorSynchronization::kTags[ |
13847 VisitorSynchronization::kNumberOfSyncTags] = { | 13895 VisitorSynchronization::kNumberOfSyncTags] = { |
13848 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG) | 13896 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG) |
13849 }; | 13897 }; |
(...skipping 6035 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19885 } | 19933 } |
19886 | 19934 |
19887 // Evaluation of module body. | 19935 // Evaluation of module body. |
19888 Handle<JSFunction> resume( | 19936 Handle<JSFunction> resume( |
19889 isolate->native_context()->generator_next_internal(), isolate); | 19937 isolate->native_context()->generator_next_internal(), isolate); |
19890 return Execution::Call(isolate, resume, generator, 0, nullptr); | 19938 return Execution::Call(isolate, resume, generator, 0, nullptr); |
19891 } | 19939 } |
19892 | 19940 |
19893 } // namespace internal | 19941 } // namespace internal |
19894 } // namespace v8 | 19942 } // namespace v8 |
OLD | NEW |