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