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