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 <sstream> | 9 #include <sstream> |
10 | 10 |
(...skipping 12326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12337 if (FLAG_trace_concurrent_recompilation) { | 12337 if (FLAG_trace_concurrent_recompilation) { |
12338 PrintF(" ** Marking "); | 12338 PrintF(" ** Marking "); |
12339 ShortPrint(); | 12339 ShortPrint(); |
12340 PrintF(" for concurrent recompilation.\n"); | 12340 PrintF(" for concurrent recompilation.\n"); |
12341 } | 12341 } |
12342 set_code_no_write_barrier( | 12342 set_code_no_write_barrier( |
12343 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent)); | 12343 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent)); |
12344 // No write barrier required, since the builtin is part of the root set. | 12344 // No write barrier required, since the builtin is part of the root set. |
12345 } | 12345 } |
12346 | 12346 |
12347 // static | |
12348 Handle<LiteralsArray> SharedFunctionInfo::FindOrCreateLiterals( | |
12349 Handle<SharedFunctionInfo> shared, Handle<Context> native_context) { | |
12350 Isolate* isolate = shared->GetIsolate(); | |
12351 CodeAndLiterals result = | |
12352 shared->SearchOptimizedCodeMap(*native_context, BailoutId::None()); | |
12353 if (result.literals != nullptr) { | |
12354 return handle(result.literals, isolate); | |
12355 } | |
12356 Handle<TypeFeedbackVector> feedback_vector = | |
12357 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata())); | |
12358 Handle<LiteralsArray> literals = LiteralsArray::New( | |
12359 isolate, feedback_vector, shared->num_literals(), TENURED); | |
12360 AddLiteralsToOptimizedCodeMap(shared, native_context, literals); | |
12361 return literals; | |
12362 } | |
12363 | 12347 |
12364 void SharedFunctionInfo::AddSharedCodeToOptimizedCodeMap( | 12348 void SharedFunctionInfo::AddSharedCodeToOptimizedCodeMap( |
12365 Handle<SharedFunctionInfo> shared, Handle<Code> code) { | 12349 Handle<SharedFunctionInfo> shared, Handle<Code> code) { |
12366 Isolate* isolate = shared->GetIsolate(); | 12350 Isolate* isolate = shared->GetIsolate(); |
12367 if (isolate->serializer_enabled()) return; | 12351 if (isolate->serializer_enabled()) return; |
12368 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION); | 12352 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION); |
12369 // Empty code maps are unsupported. | 12353 // Empty code maps are unsupported. |
12370 if (!shared->OptimizedCodeMapIsCleared()) { | 12354 if (!shared->OptimizedCodeMapIsCleared()) { |
12371 Handle<WeakCell> cell = isolate->factory()->NewWeakCell(code); | 12355 Handle<WeakCell> cell = isolate->factory()->NewWeakCell(code); |
12372 // A collection may have occured and cleared the optimized code map in the | 12356 // A collection may have occured and cleared the optimized code map in the |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12556 DCHECK(shrink_by <= code_map->length() - kEntriesStart); | 12540 DCHECK(shrink_by <= code_map->length() - kEntriesStart); |
12557 // Always trim even when array is cleared because of heap verifier. | 12541 // Always trim even when array is cleared because of heap verifier. |
12558 GetHeap()->RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>(code_map, | 12542 GetHeap()->RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>(code_map, |
12559 shrink_by); | 12543 shrink_by); |
12560 if (code_map->length() == kEntriesStart && | 12544 if (code_map->length() == kEntriesStart && |
12561 WeakCell::cast(code_map->get(kSharedCodeIndex))->cleared()) { | 12545 WeakCell::cast(code_map->get(kSharedCodeIndex))->cleared()) { |
12562 ClearOptimizedCodeMap(); | 12546 ClearOptimizedCodeMap(); |
12563 } | 12547 } |
12564 } | 12548 } |
12565 | 12549 |
12566 // static | |
12567 void JSFunction::EnsureLiterals(Handle<JSFunction> function) { | |
12568 Handle<SharedFunctionInfo> shared(function->shared()); | |
12569 Handle<Context> native_context(function->context()->native_context()); | |
12570 Handle<LiteralsArray> literals = | |
12571 SharedFunctionInfo::FindOrCreateLiterals(shared, native_context); | |
12572 function->set_literals(*literals); | |
12573 } | |
12574 | 12550 |
12575 static void GetMinInobjectSlack(Map* map, void* data) { | 12551 static void GetMinInobjectSlack(Map* map, void* data) { |
12576 int slack = map->unused_property_fields(); | 12552 int slack = map->unused_property_fields(); |
12577 if (*reinterpret_cast<int*>(data) > slack) { | 12553 if (*reinterpret_cast<int*>(data) > slack) { |
12578 *reinterpret_cast<int*>(data) = slack; | 12554 *reinterpret_cast<int*>(data) = slack; |
12579 } | 12555 } |
12580 } | 12556 } |
12581 | 12557 |
12582 | 12558 |
12583 static void ShrinkInstanceSize(Map* map, void* data) { | 12559 static void ShrinkInstanceSize(Map* map, void* data) { |
(...skipping 1257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13841 if (isolate->serializer_enabled()) return; | 13817 if (isolate->serializer_enabled()) return; |
13842 | 13818 |
13843 if (unused_property_fields() == 0) return; | 13819 if (unused_property_fields() == 0) return; |
13844 | 13820 |
13845 set_construction_counter(Map::kSlackTrackingCounterStart); | 13821 set_construction_counter(Map::kSlackTrackingCounterStart); |
13846 } | 13822 } |
13847 | 13823 |
13848 | 13824 |
13849 void SharedFunctionInfo::ResetForNewContext(int new_ic_age) { | 13825 void SharedFunctionInfo::ResetForNewContext(int new_ic_age) { |
13850 code()->ClearInlineCaches(); | 13826 code()->ClearInlineCaches(); |
| 13827 // If we clear ICs, we need to clear the type feedback vector too, since |
| 13828 // CallICs are synced with a feedback vector slot. |
| 13829 ClearTypeFeedbackInfo(); |
13851 set_ic_age(new_ic_age); | 13830 set_ic_age(new_ic_age); |
13852 if (code()->kind() == Code::FUNCTION) { | 13831 if (code()->kind() == Code::FUNCTION) { |
13853 code()->set_profiler_ticks(0); | 13832 code()->set_profiler_ticks(0); |
13854 if (optimization_disabled() && | 13833 if (optimization_disabled() && |
13855 opt_count() >= FLAG_max_opt_count) { | 13834 opt_count() >= FLAG_max_opt_count) { |
13856 // Re-enable optimizations if they were disabled due to opt_count limit. | 13835 // Re-enable optimizations if they were disabled due to opt_count limit. |
13857 set_optimization_disabled(false); | 13836 set_optimization_disabled(false); |
13858 } | 13837 } |
13859 set_opt_count(0); | 13838 set_opt_count(0); |
13860 set_deopt_count(0); | 13839 set_deopt_count(0); |
(...skipping 18 matching lines...) Expand all Loading... |
13879 } | 13858 } |
13880 Object* shared_code = | 13859 Object* shared_code = |
13881 WeakCell::cast(optimized_code_map->get(kSharedCodeIndex))->value(); | 13860 WeakCell::cast(optimized_code_map->get(kSharedCodeIndex))->value(); |
13882 if (shared_code->IsCode() && osr_ast_id.IsNone()) { | 13861 if (shared_code->IsCode() && osr_ast_id.IsNone()) { |
13883 return kSharedCodeIndex; | 13862 return kSharedCodeIndex; |
13884 } | 13863 } |
13885 } | 13864 } |
13886 return -1; | 13865 return -1; |
13887 } | 13866 } |
13888 | 13867 |
13889 void SharedFunctionInfo::ClearCodeFromOptimizedCodeMap() { | |
13890 if (!OptimizedCodeMapIsCleared()) { | |
13891 FixedArray* optimized_code_map = this->optimized_code_map(); | |
13892 int length = optimized_code_map->length(); | |
13893 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell(); | |
13894 for (int i = kEntriesStart; i < length; i += kEntryLength) { | |
13895 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell, | |
13896 SKIP_WRITE_BARRIER); | |
13897 } | |
13898 optimized_code_map->set(kSharedCodeIndex, empty_weak_cell, | |
13899 SKIP_WRITE_BARRIER); | |
13900 } | |
13901 } | |
13902 | 13868 |
13903 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( | 13869 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( |
13904 Context* native_context, BailoutId osr_ast_id) { | 13870 Context* native_context, BailoutId osr_ast_id) { |
13905 CodeAndLiterals result = {nullptr, nullptr}; | 13871 CodeAndLiterals result = {nullptr, nullptr}; |
13906 int entry = SearchOptimizedCodeMapEntry(native_context, osr_ast_id); | 13872 int entry = SearchOptimizedCodeMapEntry(native_context, osr_ast_id); |
13907 if (entry != kNotFound) { | 13873 if (entry != kNotFound) { |
13908 FixedArray* code_map = optimized_code_map(); | 13874 FixedArray* code_map = optimized_code_map(); |
13909 if (entry == kSharedCodeIndex) { | 13875 if (entry == kSharedCodeIndex) { |
13910 // We know the weak cell isn't cleared because we made sure of it in | 13876 // We know the weak cell isn't cleared because we made sure of it in |
13911 // SearchOptimizedCodeMapEntry and performed no allocations since that | 13877 // SearchOptimizedCodeMapEntry and performed no allocations since that |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14330 Code* target(Code::GetCodeFromTargetAddress(info->target_address())); | 14296 Code* target(Code::GetCodeFromTargetAddress(info->target_address())); |
14331 if (target->is_inline_cache_stub()) { | 14297 if (target->is_inline_cache_stub()) { |
14332 if (kind == NULL || *kind == target->kind()) { | 14298 if (kind == NULL || *kind == target->kind()) { |
14333 IC::Clear(this->GetIsolate(), info->pc(), | 14299 IC::Clear(this->GetIsolate(), info->pc(), |
14334 info->host()->constant_pool()); | 14300 info->host()->constant_pool()); |
14335 } | 14301 } |
14336 } | 14302 } |
14337 } | 14303 } |
14338 } | 14304 } |
14339 | 14305 |
14340 void JSFunction::ClearTypeFeedbackInfo() { | |
14341 feedback_vector()->ClearSlots(shared()); | |
14342 } | |
14343 | 14306 |
14344 void JSFunction::ClearTypeFeedbackInfoAtGCTime() { | 14307 void SharedFunctionInfo::ClearTypeFeedbackInfo() { |
14345 feedback_vector()->ClearSlotsAtGCTime(shared()); | 14308 feedback_vector()->ClearSlots(this); |
14346 } | 14309 } |
14347 | 14310 |
14348 | 14311 |
| 14312 void SharedFunctionInfo::ClearTypeFeedbackInfoAtGCTime() { |
| 14313 feedback_vector()->ClearSlotsAtGCTime(this); |
| 14314 } |
| 14315 |
| 14316 |
14349 BailoutId Code::TranslatePcOffsetToAstId(uint32_t pc_offset) { | 14317 BailoutId Code::TranslatePcOffsetToAstId(uint32_t pc_offset) { |
14350 DisallowHeapAllocation no_gc; | 14318 DisallowHeapAllocation no_gc; |
14351 DCHECK(kind() == FUNCTION); | 14319 DCHECK(kind() == FUNCTION); |
14352 BackEdgeTable back_edges(this, &no_gc); | 14320 BackEdgeTable back_edges(this, &no_gc); |
14353 for (uint32_t i = 0; i < back_edges.length(); i++) { | 14321 for (uint32_t i = 0; i < back_edges.length(); i++) { |
14354 if (back_edges.pc_offset(i) == pc_offset) return back_edges.ast_id(i); | 14322 if (back_edges.pc_offset(i) == pc_offset) return back_edges.ast_id(i); |
14355 } | 14323 } |
14356 return BailoutId::None(); | 14324 return BailoutId::None(); |
14357 } | 14325 } |
14358 | 14326 |
(...skipping 5420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19779 if (cell->value() != *new_value) { | 19747 if (cell->value() != *new_value) { |
19780 cell->set_value(*new_value); | 19748 cell->set_value(*new_value); |
19781 Isolate* isolate = cell->GetIsolate(); | 19749 Isolate* isolate = cell->GetIsolate(); |
19782 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19750 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
19783 isolate, DependentCode::kPropertyCellChangedGroup); | 19751 isolate, DependentCode::kPropertyCellChangedGroup); |
19784 } | 19752 } |
19785 } | 19753 } |
19786 | 19754 |
19787 } // namespace internal | 19755 } // namespace internal |
19788 } // namespace v8 | 19756 } // namespace v8 |
OLD | NEW |