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