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 9882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9893 Handle<FixedArray> result; | 9893 Handle<FixedArray> result; |
9894 if (number_of_deopt_points == 0) { | 9894 if (number_of_deopt_points == 0) { |
9895 result = isolate->factory()->empty_fixed_array(); | 9895 result = isolate->factory()->empty_fixed_array(); |
9896 } else { | 9896 } else { |
9897 result = isolate->factory()->NewFixedArray( | 9897 result = isolate->factory()->NewFixedArray( |
9898 LengthOfFixedArray(number_of_deopt_points), pretenure); | 9898 LengthOfFixedArray(number_of_deopt_points), pretenure); |
9899 } | 9899 } |
9900 return Handle<DeoptimizationOutputData>::cast(result); | 9900 return Handle<DeoptimizationOutputData>::cast(result); |
9901 } | 9901 } |
9902 | 9902 |
| 9903 const int LiteralsArray::kFeedbackVectorOffset = |
| 9904 LiteralsArray::OffsetOfElementAt(LiteralsArray::kVectorIndex); |
| 9905 |
| 9906 const int LiteralsArray::kOffsetToFirstLiteral = |
| 9907 LiteralsArray::OffsetOfElementAt(LiteralsArray::kFirstLiteralIndex); |
9903 | 9908 |
9904 // static | 9909 // static |
9905 Handle<LiteralsArray> LiteralsArray::New(Isolate* isolate, | 9910 Handle<LiteralsArray> LiteralsArray::New(Isolate* isolate, |
9906 Handle<TypeFeedbackVector> vector, | 9911 Handle<TypeFeedbackVector> vector, |
9907 int number_of_literals, | 9912 int number_of_literals, |
9908 PretenureFlag pretenure) { | 9913 PretenureFlag pretenure) { |
| 9914 if (vector->is_empty() && number_of_literals == 0) { |
| 9915 return Handle<LiteralsArray>::cast( |
| 9916 isolate->factory()->empty_literals_array()); |
| 9917 } |
9909 Handle<FixedArray> literals = isolate->factory()->NewFixedArray( | 9918 Handle<FixedArray> literals = isolate->factory()->NewFixedArray( |
9910 number_of_literals + kFirstLiteralIndex, pretenure); | 9919 number_of_literals + kFirstLiteralIndex, pretenure); |
9911 Handle<LiteralsArray> casted_literals = Handle<LiteralsArray>::cast(literals); | 9920 Handle<LiteralsArray> casted_literals = Handle<LiteralsArray>::cast(literals); |
9912 casted_literals->set_feedback_vector(*vector); | 9921 casted_literals->set_feedback_vector(*vector); |
9913 return casted_literals; | 9922 return casted_literals; |
9914 } | 9923 } |
9915 | 9924 |
9916 int HandlerTable::LookupRange(int pc_offset, int* data_out, | 9925 int HandlerTable::LookupRange(int pc_offset, int* data_out, |
9917 CatchPrediction* prediction_out) { | 9926 CatchPrediction* prediction_out) { |
9918 int innermost_handler = -1; | 9927 int innermost_handler = -1; |
(...skipping 1360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11279 if (FLAG_trace_concurrent_recompilation) { | 11288 if (FLAG_trace_concurrent_recompilation) { |
11280 PrintF(" ** Marking "); | 11289 PrintF(" ** Marking "); |
11281 ShortPrint(); | 11290 ShortPrint(); |
11282 PrintF(" for concurrent recompilation.\n"); | 11291 PrintF(" for concurrent recompilation.\n"); |
11283 } | 11292 } |
11284 set_code_no_write_barrier( | 11293 set_code_no_write_barrier( |
11285 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent)); | 11294 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent)); |
11286 // No write barrier required, since the builtin is part of the root set. | 11295 // No write barrier required, since the builtin is part of the root set. |
11287 } | 11296 } |
11288 | 11297 |
| 11298 // static |
| 11299 Handle<LiteralsArray> SharedFunctionInfo::FindOrCreateLiterals( |
| 11300 Handle<SharedFunctionInfo> shared, Handle<Context> native_context) { |
| 11301 Isolate* isolate = shared->GetIsolate(); |
| 11302 CodeAndLiterals result = |
| 11303 shared->SearchOptimizedCodeMap(*native_context, BailoutId::None()); |
| 11304 if (result.literals != nullptr) { |
| 11305 DCHECK(shared->feedback_metadata()->is_empty() || |
| 11306 !result.literals->feedback_vector()->is_empty()); |
| 11307 return handle(result.literals, isolate); |
| 11308 } |
| 11309 |
| 11310 Handle<TypeFeedbackVector> feedback_vector = |
| 11311 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata())); |
| 11312 Handle<LiteralsArray> literals = LiteralsArray::New( |
| 11313 isolate, feedback_vector, shared->num_literals(), TENURED); |
| 11314 Handle<Code> code; |
| 11315 if (result.code != nullptr) { |
| 11316 code = Handle<Code>(result.code, isolate); |
| 11317 } |
| 11318 AddToOptimizedCodeMap(shared, native_context, code, literals, |
| 11319 BailoutId::None()); |
| 11320 return literals; |
| 11321 } |
11289 | 11322 |
11290 void SharedFunctionInfo::AddSharedCodeToOptimizedCodeMap( | 11323 void SharedFunctionInfo::AddSharedCodeToOptimizedCodeMap( |
11291 Handle<SharedFunctionInfo> shared, Handle<Code> code) { | 11324 Handle<SharedFunctionInfo> shared, Handle<Code> code) { |
11292 Isolate* isolate = shared->GetIsolate(); | 11325 Isolate* isolate = shared->GetIsolate(); |
11293 if (isolate->serializer_enabled()) return; | 11326 if (isolate->serializer_enabled()) return; |
11294 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION); | 11327 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION); |
11295 // Empty code maps are unsupported. | 11328 // Empty code maps are unsupported. |
11296 if (!shared->OptimizedCodeMapIsCleared()) { | 11329 if (!shared->OptimizedCodeMapIsCleared()) { |
11297 Handle<WeakCell> cell = isolate->factory()->NewWeakCell(code); | 11330 Handle<WeakCell> cell = isolate->factory()->NewWeakCell(code); |
11298 // A collection may have occured and cleared the optimized code map in the | 11331 // 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... |
11475 DCHECK(shrink_by <= code_map->length() - kEntriesStart); | 11508 DCHECK(shrink_by <= code_map->length() - kEntriesStart); |
11476 // Always trim even when array is cleared because of heap verifier. | 11509 // Always trim even when array is cleared because of heap verifier. |
11477 GetHeap()->RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>(code_map, | 11510 GetHeap()->RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>(code_map, |
11478 shrink_by); | 11511 shrink_by); |
11479 if (code_map->length() == kEntriesStart && | 11512 if (code_map->length() == kEntriesStart && |
11480 WeakCell::cast(code_map->get(kSharedCodeIndex))->cleared()) { | 11513 WeakCell::cast(code_map->get(kSharedCodeIndex))->cleared()) { |
11481 ClearOptimizedCodeMap(); | 11514 ClearOptimizedCodeMap(); |
11482 } | 11515 } |
11483 } | 11516 } |
11484 | 11517 |
| 11518 // static |
| 11519 void JSFunction::EnsureLiterals(Handle<JSFunction> function) { |
| 11520 Handle<SharedFunctionInfo> shared(function->shared()); |
| 11521 Handle<Context> native_context(function->context()->native_context()); |
| 11522 if (function->literals() == |
| 11523 function->GetIsolate()->heap()->empty_literals_array()) { |
| 11524 Handle<LiteralsArray> literals = |
| 11525 SharedFunctionInfo::FindOrCreateLiterals(shared, native_context); |
| 11526 function->set_literals(*literals); |
| 11527 } |
| 11528 } |
11485 | 11529 |
11486 static void GetMinInobjectSlack(Map* map, void* data) { | 11530 static void GetMinInobjectSlack(Map* map, void* data) { |
11487 int slack = map->unused_property_fields(); | 11531 int slack = map->unused_property_fields(); |
11488 if (*reinterpret_cast<int*>(data) > slack) { | 11532 if (*reinterpret_cast<int*>(data) > slack) { |
11489 *reinterpret_cast<int*>(data) = slack; | 11533 *reinterpret_cast<int*>(data) = slack; |
11490 } | 11534 } |
11491 } | 11535 } |
11492 | 11536 |
11493 | 11537 |
11494 static void ShrinkInstanceSize(Map* map, void* data) { | 11538 static void ShrinkInstanceSize(Map* map, void* data) { |
(...skipping 1410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12905 if (isolate->serializer_enabled()) return; | 12949 if (isolate->serializer_enabled()) return; |
12906 | 12950 |
12907 if (unused_property_fields() == 0) return; | 12951 if (unused_property_fields() == 0) return; |
12908 | 12952 |
12909 set_construction_counter(Map::kSlackTrackingCounterStart); | 12953 set_construction_counter(Map::kSlackTrackingCounterStart); |
12910 } | 12954 } |
12911 | 12955 |
12912 | 12956 |
12913 void SharedFunctionInfo::ResetForNewContext(int new_ic_age) { | 12957 void SharedFunctionInfo::ResetForNewContext(int new_ic_age) { |
12914 code()->ClearInlineCaches(); | 12958 code()->ClearInlineCaches(); |
12915 // If we clear ICs, we need to clear the type feedback vector too, since | |
12916 // CallICs are synced with a feedback vector slot. | |
12917 ClearTypeFeedbackInfo(); | |
12918 set_ic_age(new_ic_age); | 12959 set_ic_age(new_ic_age); |
12919 if (code()->kind() == Code::FUNCTION) { | 12960 if (code()->kind() == Code::FUNCTION) { |
12920 code()->set_profiler_ticks(0); | 12961 code()->set_profiler_ticks(0); |
12921 if (optimization_disabled() && opt_count() >= FLAG_max_opt_count) { | 12962 if (optimization_disabled() && opt_count() >= FLAG_max_opt_count) { |
12922 // Re-enable optimizations if they were disabled due to opt_count limit. | 12963 // Re-enable optimizations if they were disabled due to opt_count limit. |
12923 set_optimization_disabled(false); | 12964 set_optimization_disabled(false); |
12924 } | 12965 } |
12925 set_opt_count(0); | 12966 set_opt_count(0); |
12926 set_deopt_count(0); | 12967 set_deopt_count(0); |
12927 } else if (code()->is_interpreter_trampoline_builtin()) { | 12968 } else if (code()->is_interpreter_trampoline_builtin()) { |
(...skipping 25 matching lines...) Expand all Loading... |
12953 } | 12994 } |
12954 Object* shared_code = | 12995 Object* shared_code = |
12955 WeakCell::cast(optimized_code_map->get(kSharedCodeIndex))->value(); | 12996 WeakCell::cast(optimized_code_map->get(kSharedCodeIndex))->value(); |
12956 if (shared_code->IsCode() && osr_ast_id.IsNone()) { | 12997 if (shared_code->IsCode() && osr_ast_id.IsNone()) { |
12957 return kSharedCodeIndex; | 12998 return kSharedCodeIndex; |
12958 } | 12999 } |
12959 } | 13000 } |
12960 return -1; | 13001 return -1; |
12961 } | 13002 } |
12962 | 13003 |
| 13004 void SharedFunctionInfo::ClearCodeFromOptimizedCodeMap() { |
| 13005 if (!OptimizedCodeMapIsCleared()) { |
| 13006 FixedArray* optimized_code_map = this->optimized_code_map(); |
| 13007 int length = optimized_code_map->length(); |
| 13008 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell(); |
| 13009 for (int i = kEntriesStart; i < length; i += kEntryLength) { |
| 13010 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell, |
| 13011 SKIP_WRITE_BARRIER); |
| 13012 } |
| 13013 optimized_code_map->set(kSharedCodeIndex, empty_weak_cell, |
| 13014 SKIP_WRITE_BARRIER); |
| 13015 } |
| 13016 } |
12963 | 13017 |
12964 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( | 13018 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( |
12965 Context* native_context, BailoutId osr_ast_id) { | 13019 Context* native_context, BailoutId osr_ast_id) { |
12966 CodeAndLiterals result = {nullptr, nullptr}; | 13020 CodeAndLiterals result = {nullptr, nullptr}; |
12967 int entry = SearchOptimizedCodeMapEntry(native_context, osr_ast_id); | 13021 int entry = SearchOptimizedCodeMapEntry(native_context, osr_ast_id); |
12968 if (entry != kNotFound) { | 13022 if (entry != kNotFound) { |
12969 FixedArray* code_map = optimized_code_map(); | 13023 FixedArray* code_map = optimized_code_map(); |
12970 if (entry == kSharedCodeIndex) { | 13024 if (entry == kSharedCodeIndex) { |
12971 // We know the weak cell isn't cleared because we made sure of it in | 13025 // We know the weak cell isn't cleared because we made sure of it in |
12972 // SearchOptimizedCodeMapEntry and performed no allocations since that | 13026 // SearchOptimizedCodeMapEntry and performed no allocations since that |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13287 int AbstractCode::SourcePosition(int offset) { | 13341 int AbstractCode::SourcePosition(int offset) { |
13288 return IsBytecodeArray() ? GetBytecodeArray()->SourcePosition(offset) | 13342 return IsBytecodeArray() ? GetBytecodeArray()->SourcePosition(offset) |
13289 : GetCode()->SourcePosition(offset); | 13343 : GetCode()->SourcePosition(offset); |
13290 } | 13344 } |
13291 | 13345 |
13292 int AbstractCode::SourceStatementPosition(int offset) { | 13346 int AbstractCode::SourceStatementPosition(int offset) { |
13293 return IsBytecodeArray() ? GetBytecodeArray()->SourceStatementPosition(offset) | 13347 return IsBytecodeArray() ? GetBytecodeArray()->SourceStatementPosition(offset) |
13294 : GetCode()->SourceStatementPosition(offset); | 13348 : GetCode()->SourceStatementPosition(offset); |
13295 } | 13349 } |
13296 | 13350 |
13297 void SharedFunctionInfo::ClearTypeFeedbackInfo() { | 13351 void JSFunction::ClearTypeFeedbackInfo() { |
13298 feedback_vector()->ClearSlots(this); | 13352 feedback_vector()->ClearSlots(shared()); |
13299 } | 13353 } |
13300 | 13354 |
13301 | 13355 void JSFunction::ClearTypeFeedbackInfoAtGCTime() { |
13302 void SharedFunctionInfo::ClearTypeFeedbackInfoAtGCTime() { | 13356 feedback_vector()->ClearSlotsAtGCTime(shared()); |
13303 feedback_vector()->ClearSlotsAtGCTime(this); | |
13304 } | 13357 } |
13305 | 13358 |
13306 | |
13307 BailoutId Code::TranslatePcOffsetToAstId(uint32_t pc_offset) { | 13359 BailoutId Code::TranslatePcOffsetToAstId(uint32_t pc_offset) { |
13308 DisallowHeapAllocation no_gc; | 13360 DisallowHeapAllocation no_gc; |
13309 DCHECK(kind() == FUNCTION); | 13361 DCHECK(kind() == FUNCTION); |
13310 BackEdgeTable back_edges(this, &no_gc); | 13362 BackEdgeTable back_edges(this, &no_gc); |
13311 for (uint32_t i = 0; i < back_edges.length(); i++) { | 13363 for (uint32_t i = 0; i < back_edges.length(); i++) { |
13312 if (back_edges.pc_offset(i) == pc_offset) return back_edges.ast_id(i); | 13364 if (back_edges.pc_offset(i) == pc_offset) return back_edges.ast_id(i); |
13313 } | 13365 } |
13314 return BailoutId::None(); | 13366 return BailoutId::None(); |
13315 } | 13367 } |
13316 | 13368 |
(...skipping 5156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18473 if (cell->value() != *new_value) { | 18525 if (cell->value() != *new_value) { |
18474 cell->set_value(*new_value); | 18526 cell->set_value(*new_value); |
18475 Isolate* isolate = cell->GetIsolate(); | 18527 Isolate* isolate = cell->GetIsolate(); |
18476 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18528 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
18477 isolate, DependentCode::kPropertyCellChangedGroup); | 18529 isolate, DependentCode::kPropertyCellChangedGroup); |
18478 } | 18530 } |
18479 } | 18531 } |
18480 | 18532 |
18481 } // namespace internal | 18533 } // namespace internal |
18482 } // namespace v8 | 18534 } // namespace v8 |
OLD | NEW |