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 9892 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9903 Handle<FixedArray> result; | 9903 Handle<FixedArray> result; |
9904 if (number_of_deopt_points == 0) { | 9904 if (number_of_deopt_points == 0) { |
9905 result = isolate->factory()->empty_fixed_array(); | 9905 result = isolate->factory()->empty_fixed_array(); |
9906 } else { | 9906 } else { |
9907 result = isolate->factory()->NewFixedArray( | 9907 result = isolate->factory()->NewFixedArray( |
9908 LengthOfFixedArray(number_of_deopt_points), pretenure); | 9908 LengthOfFixedArray(number_of_deopt_points), pretenure); |
9909 } | 9909 } |
9910 return Handle<DeoptimizationOutputData>::cast(result); | 9910 return Handle<DeoptimizationOutputData>::cast(result); |
9911 } | 9911 } |
9912 | 9912 |
| 9913 const int LiteralsArray::kFeedbackVectorOffset = |
| 9914 LiteralsArray::OffsetOfElementAt(LiteralsArray::kVectorIndex); |
| 9915 |
| 9916 const int LiteralsArray::kOffsetToFirstLiteral = |
| 9917 LiteralsArray::OffsetOfElementAt(LiteralsArray::kFirstLiteralIndex); |
9913 | 9918 |
9914 // static | 9919 // static |
9915 Handle<LiteralsArray> LiteralsArray::New(Isolate* isolate, | 9920 Handle<LiteralsArray> LiteralsArray::New(Isolate* isolate, |
9916 Handle<TypeFeedbackVector> vector, | 9921 Handle<TypeFeedbackVector> vector, |
9917 int number_of_literals, | 9922 int number_of_literals, |
9918 PretenureFlag pretenure) { | 9923 PretenureFlag pretenure) { |
| 9924 if (vector->is_empty() && number_of_literals == 0) { |
| 9925 return Handle<LiteralsArray>::cast( |
| 9926 isolate->factory()->empty_literals_array()); |
| 9927 } |
9919 Handle<FixedArray> literals = isolate->factory()->NewFixedArray( | 9928 Handle<FixedArray> literals = isolate->factory()->NewFixedArray( |
9920 number_of_literals + kFirstLiteralIndex, pretenure); | 9929 number_of_literals + kFirstLiteralIndex, pretenure); |
9921 Handle<LiteralsArray> casted_literals = Handle<LiteralsArray>::cast(literals); | 9930 Handle<LiteralsArray> casted_literals = Handle<LiteralsArray>::cast(literals); |
9922 casted_literals->set_feedback_vector(*vector); | 9931 casted_literals->set_feedback_vector(*vector); |
9923 return casted_literals; | 9932 return casted_literals; |
9924 } | 9933 } |
9925 | 9934 |
9926 int HandlerTable::LookupRange(int pc_offset, int* data_out, | 9935 int HandlerTable::LookupRange(int pc_offset, int* data_out, |
9927 CatchPrediction* prediction_out) { | 9936 CatchPrediction* prediction_out) { |
9928 int innermost_handler = -1; | 9937 int innermost_handler = -1; |
(...skipping 1360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11289 if (FLAG_trace_concurrent_recompilation) { | 11298 if (FLAG_trace_concurrent_recompilation) { |
11290 PrintF(" ** Marking "); | 11299 PrintF(" ** Marking "); |
11291 ShortPrint(); | 11300 ShortPrint(); |
11292 PrintF(" for concurrent recompilation.\n"); | 11301 PrintF(" for concurrent recompilation.\n"); |
11293 } | 11302 } |
11294 set_code_no_write_barrier( | 11303 set_code_no_write_barrier( |
11295 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent)); | 11304 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent)); |
11296 // No write barrier required, since the builtin is part of the root set. | 11305 // No write barrier required, since the builtin is part of the root set. |
11297 } | 11306 } |
11298 | 11307 |
| 11308 // static |
| 11309 Handle<LiteralsArray> SharedFunctionInfo::FindOrCreateLiterals( |
| 11310 Handle<SharedFunctionInfo> shared, Handle<Context> native_context) { |
| 11311 Isolate* isolate = shared->GetIsolate(); |
| 11312 CodeAndLiterals result = |
| 11313 shared->SearchOptimizedCodeMap(*native_context, BailoutId::None()); |
| 11314 if (result.literals != nullptr) { |
| 11315 DCHECK(shared->feedback_metadata()->is_empty() || |
| 11316 !result.literals->feedback_vector()->is_empty()); |
| 11317 return handle(result.literals, isolate); |
| 11318 } |
| 11319 |
| 11320 Handle<TypeFeedbackVector> feedback_vector = |
| 11321 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata())); |
| 11322 Handle<LiteralsArray> literals = LiteralsArray::New( |
| 11323 isolate, feedback_vector, shared->num_literals(), TENURED); |
| 11324 Handle<Code> code; |
| 11325 if (result.code != nullptr) { |
| 11326 code = Handle<Code>(result.code, isolate); |
| 11327 } |
| 11328 AddToOptimizedCodeMap(shared, native_context, code, literals, |
| 11329 BailoutId::None()); |
| 11330 return literals; |
| 11331 } |
11299 | 11332 |
11300 void SharedFunctionInfo::AddSharedCodeToOptimizedCodeMap( | 11333 void SharedFunctionInfo::AddSharedCodeToOptimizedCodeMap( |
11301 Handle<SharedFunctionInfo> shared, Handle<Code> code) { | 11334 Handle<SharedFunctionInfo> shared, Handle<Code> code) { |
11302 Isolate* isolate = shared->GetIsolate(); | 11335 Isolate* isolate = shared->GetIsolate(); |
11303 if (isolate->serializer_enabled()) return; | 11336 if (isolate->serializer_enabled()) return; |
11304 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION); | 11337 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION); |
11305 // Empty code maps are unsupported. | 11338 // Empty code maps are unsupported. |
11306 if (!shared->OptimizedCodeMapIsCleared()) { | 11339 if (!shared->OptimizedCodeMapIsCleared()) { |
11307 Handle<WeakCell> cell = isolate->factory()->NewWeakCell(code); | 11340 Handle<WeakCell> cell = isolate->factory()->NewWeakCell(code); |
11308 // A collection may have occured and cleared the optimized code map in the | 11341 // A collection may have occured and cleared the optimized code map in the |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11485 DCHECK(shrink_by <= code_map->length() - kEntriesStart); | 11518 DCHECK(shrink_by <= code_map->length() - kEntriesStart); |
11486 // Always trim even when array is cleared because of heap verifier. | 11519 // Always trim even when array is cleared because of heap verifier. |
11487 GetHeap()->RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>(code_map, | 11520 GetHeap()->RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>(code_map, |
11488 shrink_by); | 11521 shrink_by); |
11489 if (code_map->length() == kEntriesStart && | 11522 if (code_map->length() == kEntriesStart && |
11490 WeakCell::cast(code_map->get(kSharedCodeIndex))->cleared()) { | 11523 WeakCell::cast(code_map->get(kSharedCodeIndex))->cleared()) { |
11491 ClearOptimizedCodeMap(); | 11524 ClearOptimizedCodeMap(); |
11492 } | 11525 } |
11493 } | 11526 } |
11494 | 11527 |
| 11528 // static |
| 11529 void JSFunction::EnsureLiterals(Handle<JSFunction> function) { |
| 11530 Handle<SharedFunctionInfo> shared(function->shared()); |
| 11531 Handle<Context> native_context(function->context()->native_context()); |
| 11532 if (function->literals() == |
| 11533 function->GetIsolate()->heap()->empty_literals_array()) { |
| 11534 Handle<LiteralsArray> literals = |
| 11535 SharedFunctionInfo::FindOrCreateLiterals(shared, native_context); |
| 11536 function->set_literals(*literals); |
| 11537 } |
| 11538 } |
11495 | 11539 |
11496 static void GetMinInobjectSlack(Map* map, void* data) { | 11540 static void GetMinInobjectSlack(Map* map, void* data) { |
11497 int slack = map->unused_property_fields(); | 11541 int slack = map->unused_property_fields(); |
11498 if (*reinterpret_cast<int*>(data) > slack) { | 11542 if (*reinterpret_cast<int*>(data) > slack) { |
11499 *reinterpret_cast<int*>(data) = slack; | 11543 *reinterpret_cast<int*>(data) = slack; |
11500 } | 11544 } |
11501 } | 11545 } |
11502 | 11546 |
11503 | 11547 |
11504 static void ShrinkInstanceSize(Map* map, void* data) { | 11548 static void ShrinkInstanceSize(Map* map, void* data) { |
(...skipping 1410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12915 if (isolate->serializer_enabled()) return; | 12959 if (isolate->serializer_enabled()) return; |
12916 | 12960 |
12917 if (unused_property_fields() == 0) return; | 12961 if (unused_property_fields() == 0) return; |
12918 | 12962 |
12919 set_construction_counter(Map::kSlackTrackingCounterStart); | 12963 set_construction_counter(Map::kSlackTrackingCounterStart); |
12920 } | 12964 } |
12921 | 12965 |
12922 | 12966 |
12923 void SharedFunctionInfo::ResetForNewContext(int new_ic_age) { | 12967 void SharedFunctionInfo::ResetForNewContext(int new_ic_age) { |
12924 code()->ClearInlineCaches(); | 12968 code()->ClearInlineCaches(); |
12925 // If we clear ICs, we need to clear the type feedback vector too, since | |
12926 // CallICs are synced with a feedback vector slot. | |
12927 ClearTypeFeedbackInfo(); | |
12928 set_ic_age(new_ic_age); | 12969 set_ic_age(new_ic_age); |
12929 if (code()->kind() == Code::FUNCTION) { | 12970 if (code()->kind() == Code::FUNCTION) { |
12930 code()->set_profiler_ticks(0); | 12971 code()->set_profiler_ticks(0); |
12931 if (optimization_disabled() && opt_count() >= FLAG_max_opt_count) { | 12972 if (optimization_disabled() && opt_count() >= FLAG_max_opt_count) { |
12932 // Re-enable optimizations if they were disabled due to opt_count limit. | 12973 // Re-enable optimizations if they were disabled due to opt_count limit. |
12933 set_optimization_disabled(false); | 12974 set_optimization_disabled(false); |
12934 } | 12975 } |
12935 set_opt_count(0); | 12976 set_opt_count(0); |
12936 set_deopt_count(0); | 12977 set_deopt_count(0); |
12937 } else if (code()->is_interpreter_trampoline_builtin()) { | 12978 } else if (code()->is_interpreter_trampoline_builtin()) { |
(...skipping 25 matching lines...) Expand all Loading... |
12963 } | 13004 } |
12964 Object* shared_code = | 13005 Object* shared_code = |
12965 WeakCell::cast(optimized_code_map->get(kSharedCodeIndex))->value(); | 13006 WeakCell::cast(optimized_code_map->get(kSharedCodeIndex))->value(); |
12966 if (shared_code->IsCode() && osr_ast_id.IsNone()) { | 13007 if (shared_code->IsCode() && osr_ast_id.IsNone()) { |
12967 return kSharedCodeIndex; | 13008 return kSharedCodeIndex; |
12968 } | 13009 } |
12969 } | 13010 } |
12970 return -1; | 13011 return -1; |
12971 } | 13012 } |
12972 | 13013 |
| 13014 void SharedFunctionInfo::ClearCodeFromOptimizedCodeMap() { |
| 13015 if (!OptimizedCodeMapIsCleared()) { |
| 13016 FixedArray* optimized_code_map = this->optimized_code_map(); |
| 13017 int length = optimized_code_map->length(); |
| 13018 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell(); |
| 13019 for (int i = kEntriesStart; i < length; i += kEntryLength) { |
| 13020 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell, |
| 13021 SKIP_WRITE_BARRIER); |
| 13022 } |
| 13023 optimized_code_map->set(kSharedCodeIndex, empty_weak_cell, |
| 13024 SKIP_WRITE_BARRIER); |
| 13025 } |
| 13026 } |
12973 | 13027 |
12974 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( | 13028 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( |
12975 Context* native_context, BailoutId osr_ast_id) { | 13029 Context* native_context, BailoutId osr_ast_id) { |
12976 CodeAndLiterals result = {nullptr, nullptr}; | 13030 CodeAndLiterals result = {nullptr, nullptr}; |
12977 int entry = SearchOptimizedCodeMapEntry(native_context, osr_ast_id); | 13031 int entry = SearchOptimizedCodeMapEntry(native_context, osr_ast_id); |
12978 if (entry != kNotFound) { | 13032 if (entry != kNotFound) { |
12979 FixedArray* code_map = optimized_code_map(); | 13033 FixedArray* code_map = optimized_code_map(); |
12980 if (entry == kSharedCodeIndex) { | 13034 if (entry == kSharedCodeIndex) { |
12981 // We know the weak cell isn't cleared because we made sure of it in | 13035 // We know the weak cell isn't cleared because we made sure of it in |
12982 // SearchOptimizedCodeMapEntry and performed no allocations since that | 13036 // SearchOptimizedCodeMapEntry and performed no allocations since that |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13297 int AbstractCode::SourcePosition(int offset) { | 13351 int AbstractCode::SourcePosition(int offset) { |
13298 return IsBytecodeArray() ? GetBytecodeArray()->SourcePosition(offset) | 13352 return IsBytecodeArray() ? GetBytecodeArray()->SourcePosition(offset) |
13299 : GetCode()->SourcePosition(offset); | 13353 : GetCode()->SourcePosition(offset); |
13300 } | 13354 } |
13301 | 13355 |
13302 int AbstractCode::SourceStatementPosition(int offset) { | 13356 int AbstractCode::SourceStatementPosition(int offset) { |
13303 return IsBytecodeArray() ? GetBytecodeArray()->SourceStatementPosition(offset) | 13357 return IsBytecodeArray() ? GetBytecodeArray()->SourceStatementPosition(offset) |
13304 : GetCode()->SourceStatementPosition(offset); | 13358 : GetCode()->SourceStatementPosition(offset); |
13305 } | 13359 } |
13306 | 13360 |
13307 void SharedFunctionInfo::ClearTypeFeedbackInfo() { | 13361 void JSFunction::ClearTypeFeedbackInfo() { |
13308 feedback_vector()->ClearSlots(this); | 13362 feedback_vector()->ClearSlots(shared()); |
13309 } | 13363 } |
13310 | 13364 |
13311 | 13365 void JSFunction::ClearTypeFeedbackInfoAtGCTime() { |
13312 void SharedFunctionInfo::ClearTypeFeedbackInfoAtGCTime() { | 13366 feedback_vector()->ClearSlotsAtGCTime(shared()); |
13313 feedback_vector()->ClearSlotsAtGCTime(this); | |
13314 } | 13367 } |
13315 | 13368 |
13316 | |
13317 BailoutId Code::TranslatePcOffsetToAstId(uint32_t pc_offset) { | 13369 BailoutId Code::TranslatePcOffsetToAstId(uint32_t pc_offset) { |
13318 DisallowHeapAllocation no_gc; | 13370 DisallowHeapAllocation no_gc; |
13319 DCHECK(kind() == FUNCTION); | 13371 DCHECK(kind() == FUNCTION); |
13320 BackEdgeTable back_edges(this, &no_gc); | 13372 BackEdgeTable back_edges(this, &no_gc); |
13321 for (uint32_t i = 0; i < back_edges.length(); i++) { | 13373 for (uint32_t i = 0; i < back_edges.length(); i++) { |
13322 if (back_edges.pc_offset(i) == pc_offset) return back_edges.ast_id(i); | 13374 if (back_edges.pc_offset(i) == pc_offset) return back_edges.ast_id(i); |
13323 } | 13375 } |
13324 return BailoutId::None(); | 13376 return BailoutId::None(); |
13325 } | 13377 } |
13326 | 13378 |
(...skipping 5114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18441 if (cell->value() != *new_value) { | 18493 if (cell->value() != *new_value) { |
18442 cell->set_value(*new_value); | 18494 cell->set_value(*new_value); |
18443 Isolate* isolate = cell->GetIsolate(); | 18495 Isolate* isolate = cell->GetIsolate(); |
18444 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18496 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
18445 isolate, DependentCode::kPropertyCellChangedGroup); | 18497 isolate, DependentCode::kPropertyCellChangedGroup); |
18446 } | 18498 } |
18447 } | 18499 } |
18448 | 18500 |
18449 } // namespace internal | 18501 } // namespace internal |
18450 } // namespace v8 | 18502 } // namespace v8 |
OLD | NEW |