| 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 |