| 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 |