Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: src/objects.cc

Issue 2655853010: [TypeFeedbackVector] Combine the literals array and the feedback vector. (Closed)
Patch Set: more comments. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <memory> 9 #include <memory>
10 #include <sstream> 10 #include <sstream>
(...skipping 10245 matching lines...) Expand 10 before | Expand all | Expand 10 after
10256 } 10256 }
10257 10257
10258 SharedFunctionInfo* DeoptimizationInputData::GetInlinedFunction(int index) { 10258 SharedFunctionInfo* DeoptimizationInputData::GetInlinedFunction(int index) {
10259 if (index == -1) { 10259 if (index == -1) {
10260 return SharedFunctionInfo::cast(SharedFunctionInfo()); 10260 return SharedFunctionInfo::cast(SharedFunctionInfo());
10261 } else { 10261 } else {
10262 return SharedFunctionInfo::cast(LiteralArray()->get(index)); 10262 return SharedFunctionInfo::cast(LiteralArray()->get(index));
10263 } 10263 }
10264 } 10264 }
10265 10265
10266 const int LiteralsArray::kFeedbackVectorOffset =
10267 LiteralsArray::OffsetOfElementAt(LiteralsArray::kVectorIndex);
10268
10269 const int LiteralsArray::kOffsetToFirstLiteral =
10270 LiteralsArray::OffsetOfElementAt(LiteralsArray::kFirstLiteralIndex);
10271
10272 // static
10273 Handle<LiteralsArray> LiteralsArray::New(Isolate* isolate,
10274 Handle<TypeFeedbackVector> vector,
10275 int number_of_literals,
10276 PretenureFlag pretenure) {
10277 if (vector->is_empty() && number_of_literals == 0) {
10278 return Handle<LiteralsArray>::cast(
10279 isolate->factory()->empty_literals_array());
10280 }
10281 Handle<FixedArray> literals = isolate->factory()->NewFixedArray(
10282 number_of_literals + kFirstLiteralIndex, pretenure);
10283 Handle<LiteralsArray> casted_literals = Handle<LiteralsArray>::cast(literals);
10284 casted_literals->set_feedback_vector(*vector);
10285 return casted_literals;
10286 }
10287
10288 int HandlerTable::LookupRange(int pc_offset, int* data_out, 10266 int HandlerTable::LookupRange(int pc_offset, int* data_out,
10289 CatchPrediction* prediction_out) { 10267 CatchPrediction* prediction_out) {
10290 int innermost_handler = -1; 10268 int innermost_handler = -1;
10291 #ifdef DEBUG 10269 #ifdef DEBUG
10292 // Assuming that ranges are well nested, we don't need to track the innermost 10270 // Assuming that ranges are well nested, we don't need to track the innermost
10293 // offsets. This is just to verify that the table is actually well nested. 10271 // offsets. This is just to verify that the table is actually well nested.
10294 int innermost_start = std::numeric_limits<int>::min(); 10272 int innermost_start = std::numeric_limits<int>::min();
10295 int innermost_end = std::numeric_limits<int>::max(); 10273 int innermost_end = std::numeric_limits<int>::max();
10296 #endif 10274 #endif
10297 for (int i = 0; i < length(); i += kRangeEntrySize) { 10275 for (int i = 0; i < length(); i += kRangeEntrySize) {
(...skipping 1704 matching lines...) Expand 10 before | Expand all | Expand 10 after
12002 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent)); 11980 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent));
12003 // No write barrier required, since the builtin is part of the root set. 11981 // No write barrier required, since the builtin is part of the root set.
12004 if (FLAG_mark_shared_functions_for_tier_up) { 11982 if (FLAG_mark_shared_functions_for_tier_up) {
12005 // TODO(leszeks): The compilation isn't concurrent if we trigger it using 11983 // TODO(leszeks): The compilation isn't concurrent if we trigger it using
12006 // this bit. 11984 // this bit.
12007 shared()->set_marked_for_tier_up(true); 11985 shared()->set_marked_for_tier_up(true);
12008 } 11986 }
12009 } 11987 }
12010 11988
12011 // static 11989 // static
12012 Handle<LiteralsArray> SharedFunctionInfo::FindOrCreateLiterals( 11990 Handle<TypeFeedbackVector> SharedFunctionInfo::FindOrCreateVector(
12013 Handle<SharedFunctionInfo> shared, Handle<Context> native_context) { 11991 Handle<SharedFunctionInfo> shared, Handle<Context> native_context) {
12014 Isolate* isolate = shared->GetIsolate(); 11992 Isolate* isolate = shared->GetIsolate();
12015 CodeAndLiterals result = 11993 CodeAndVector result =
12016 shared->SearchOptimizedCodeMap(*native_context, BailoutId::None()); 11994 shared->SearchOptimizedCodeMap(*native_context, BailoutId::None());
12017 if (result.literals != nullptr) { 11995 if (result.vector != nullptr) {
12018 DCHECK(shared->feedback_metadata()->is_empty() || 11996 DCHECK(shared->feedback_metadata()->is_empty() ||
12019 !result.literals->feedback_vector()->is_empty()); 11997 !result.vector->is_empty());
12020 return handle(result.literals, isolate); 11998 return handle(result.vector, isolate);
12021 } 11999 }
12022 12000
12023 Handle<TypeFeedbackVector> feedback_vector = 12001 Handle<TypeFeedbackVector> vector =
12024 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata())); 12002 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata()));
12025 Handle<LiteralsArray> literals =
12026 LiteralsArray::New(isolate, feedback_vector, shared->num_literals());
12027 Handle<Code> code; 12003 Handle<Code> code;
12028 if (result.code != nullptr) { 12004 if (result.code != nullptr) {
12029 code = Handle<Code>(result.code, isolate); 12005 code = Handle<Code>(result.code, isolate);
12030 } 12006 }
12031 AddToOptimizedCodeMap(shared, native_context, code, literals, 12007 AddToOptimizedCodeMap(shared, native_context, code, vector,
12032 BailoutId::None()); 12008 BailoutId::None());
12033 return literals; 12009 return vector;
12034 } 12010 }
12035 12011
12036 // static 12012 // static
12037 void SharedFunctionInfo::AddToOptimizedCodeMap( 12013 void SharedFunctionInfo::AddToOptimizedCodeMap(
12038 Handle<SharedFunctionInfo> shared, Handle<Context> native_context, 12014 Handle<SharedFunctionInfo> shared, Handle<Context> native_context,
12039 MaybeHandle<Code> code, Handle<LiteralsArray> literals, 12015 MaybeHandle<Code> code, Handle<TypeFeedbackVector> vector,
12040 BailoutId osr_ast_id) { 12016 BailoutId osr_ast_id) {
12041 Isolate* isolate = shared->GetIsolate(); 12017 Isolate* isolate = shared->GetIsolate();
12042 if (isolate->serializer_enabled()) return; 12018 if (isolate->serializer_enabled()) return;
12043 DCHECK(code.is_null() || 12019 DCHECK(code.is_null() ||
12044 code.ToHandleChecked()->kind() == Code::OPTIMIZED_FUNCTION); 12020 code.ToHandleChecked()->kind() == Code::OPTIMIZED_FUNCTION);
12045 DCHECK(native_context->IsNativeContext()); 12021 DCHECK(native_context->IsNativeContext());
12046 STATIC_ASSERT(kEntryLength == 3); 12022 STATIC_ASSERT(kEntryLength == 3);
12047 Handle<FixedArray> new_code_map; 12023 Handle<FixedArray> new_code_map;
12048 int entry; 12024 int entry;
12049 12025
12050 if (!osr_ast_id.IsNone()) { 12026 if (!osr_ast_id.IsNone()) {
12051 Context::AddToOptimizedCodeMap( 12027 Context::AddToOptimizedCodeMap(native_context, shared,
12052 native_context, shared, code.ToHandleChecked(), literals, osr_ast_id); 12028 code.ToHandleChecked(), vector, osr_ast_id);
12053 return; 12029 return;
12054 } 12030 }
12055 12031
12056 DCHECK(osr_ast_id.IsNone()); 12032 DCHECK(osr_ast_id.IsNone());
12057 if (shared->OptimizedCodeMapIsCleared()) { 12033 if (shared->OptimizedCodeMapIsCleared()) {
12058 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); 12034 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED);
12059 entry = kEntriesStart; 12035 entry = kEntriesStart;
12060 } else { 12036 } else {
12061 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate); 12037 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate);
12062 entry = shared->SearchOptimizedCodeMapEntry(*native_context); 12038 entry = shared->SearchOptimizedCodeMapEntry(*native_context);
12063 if (entry >= kEntriesStart) { 12039 if (entry >= kEntriesStart) {
12064 // Just set the code and literals of the entry. 12040 // Just set the code and vector of the entry.
12065 if (!code.is_null()) { 12041 if (!code.is_null()) {
12066 Handle<WeakCell> code_cell = 12042 Handle<WeakCell> code_cell =
12067 isolate->factory()->NewWeakCell(code.ToHandleChecked()); 12043 isolate->factory()->NewWeakCell(code.ToHandleChecked());
12068 old_code_map->set(entry + kCachedCodeOffset, *code_cell); 12044 old_code_map->set(entry + kCachedCodeOffset, *code_cell);
12069 } 12045 }
12070 Handle<WeakCell> literals_cell = 12046 Handle<WeakCell> vector_cell = isolate->factory()->NewWeakCell(vector);
12071 isolate->factory()->NewWeakCell(literals); 12047 old_code_map->set(entry + kFeedbackVectorOffset, *vector_cell);
12072 old_code_map->set(entry + kLiteralsOffset, *literals_cell);
12073 return; 12048 return;
12074 } 12049 }
12075 12050
12076 // Can we reuse an entry? 12051 // Can we reuse an entry?
12077 DCHECK(entry < kEntriesStart); 12052 DCHECK(entry < kEntriesStart);
12078 int length = old_code_map->length(); 12053 int length = old_code_map->length();
12079 for (int i = kEntriesStart; i < length; i += kEntryLength) { 12054 for (int i = kEntriesStart; i < length; i += kEntryLength) {
12080 if (WeakCell::cast(old_code_map->get(i + kContextOffset))->cleared()) { 12055 if (WeakCell::cast(old_code_map->get(i + kContextOffset))->cleared()) {
12081 new_code_map = old_code_map; 12056 new_code_map = old_code_map;
12082 entry = i; 12057 entry = i;
(...skipping 10 matching lines...) Expand all
12093 // holes. For now we just give up on adding the entry and pretend it got 12068 // holes. For now we just give up on adding the entry and pretend it got
12094 // flushed. 12069 // flushed.
12095 if (shared->OptimizedCodeMapIsCleared()) return; 12070 if (shared->OptimizedCodeMapIsCleared()) return;
12096 entry = old_code_map->length(); 12071 entry = old_code_map->length();
12097 } 12072 }
12098 } 12073 }
12099 12074
12100 Handle<WeakCell> code_cell = 12075 Handle<WeakCell> code_cell =
12101 code.is_null() ? isolate->factory()->empty_weak_cell() 12076 code.is_null() ? isolate->factory()->empty_weak_cell()
12102 : isolate->factory()->NewWeakCell(code.ToHandleChecked()); 12077 : isolate->factory()->NewWeakCell(code.ToHandleChecked());
12103 Handle<WeakCell> literals_cell = isolate->factory()->NewWeakCell(literals); 12078 Handle<WeakCell> vector_cell = isolate->factory()->NewWeakCell(vector);
12104 WeakCell* context_cell = native_context->self_weak_cell(); 12079 WeakCell* context_cell = native_context->self_weak_cell();
12105 12080
12106 new_code_map->set(entry + kContextOffset, context_cell); 12081 new_code_map->set(entry + kContextOffset, context_cell);
12107 new_code_map->set(entry + kCachedCodeOffset, *code_cell); 12082 new_code_map->set(entry + kCachedCodeOffset, *code_cell);
12108 new_code_map->set(entry + kLiteralsOffset, *literals_cell); 12083 new_code_map->set(entry + kFeedbackVectorOffset, *vector_cell);
12109 12084
12110 #ifdef DEBUG 12085 #ifdef DEBUG
12111 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) { 12086 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) {
12112 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset)); 12087 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset));
12113 DCHECK(cell->cleared() || cell->value()->IsNativeContext()); 12088 DCHECK(cell->cleared() || cell->value()->IsNativeContext());
12114 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset)); 12089 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset));
12115 DCHECK(cell->cleared() || 12090 DCHECK(cell->cleared() ||
12116 (cell->value()->IsCode() && 12091 (cell->value()->IsCode() &&
12117 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION)); 12092 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION));
12118 cell = WeakCell::cast(new_code_map->get(i + kLiteralsOffset)); 12093 cell = WeakCell::cast(new_code_map->get(i + kFeedbackVectorOffset));
12119 DCHECK(cell->cleared() || cell->value()->IsFixedArray()); 12094 DCHECK(cell->cleared() || cell->value()->IsFixedArray());
12120 } 12095 }
12121 #endif 12096 #endif
12122 12097
12123 FixedArray* old_code_map = shared->optimized_code_map(); 12098 FixedArray* old_code_map = shared->optimized_code_map();
12124 if (old_code_map != *new_code_map) { 12099 if (old_code_map != *new_code_map) {
12125 shared->set_optimized_code_map(*new_code_map); 12100 shared->set_optimized_code_map(*new_code_map);
12126 } 12101 }
12127 } 12102 }
12128 12103
(...skipping 18 matching lines...) Expand all
12147 DCHECK(WeakCell::cast(code_map->get(src))->cleared() || 12122 DCHECK(WeakCell::cast(code_map->get(src))->cleared() ||
12148 WeakCell::cast(code_map->get(src))->value()->IsNativeContext()); 12123 WeakCell::cast(code_map->get(src))->value()->IsNativeContext());
12149 found = WeakCell::cast(code_map->get(src + kCachedCodeOffset))->value() == 12124 found = WeakCell::cast(code_map->get(src + kCachedCodeOffset))->value() ==
12150 optimized_code; 12125 optimized_code;
12151 if (found) { 12126 if (found) {
12152 if (FLAG_trace_opt) { 12127 if (FLAG_trace_opt) {
12153 PrintF("[evicting entry from optimizing code map (%s) for ", reason); 12128 PrintF("[evicting entry from optimizing code map (%s) for ", reason);
12154 ShortPrint(); 12129 ShortPrint();
12155 PrintF("]\n"); 12130 PrintF("]\n");
12156 } 12131 }
12157 // Just clear the code in order to continue sharing literals. 12132 // Just clear the code in order to continue sharing a feedback vector.
12158 code_map->set(src + kCachedCodeOffset, heap->empty_weak_cell(), 12133 code_map->set(src + kCachedCodeOffset, heap->empty_weak_cell(),
12159 SKIP_WRITE_BARRIER); 12134 SKIP_WRITE_BARRIER);
12160 } 12135 }
12161 } 12136 }
12162 } 12137 }
12163 12138
12164 if (!found) { 12139 if (!found) {
12165 // We didn't find the code in here. It must be osr'd code. 12140 // We didn't find the code in here. It must be osr'd code.
12166 isolate->EvictOSROptimizedCode(optimized_code, reason); 12141 isolate->EvictOSROptimizedCode(optimized_code, reason);
12167 } 12142 }
12168 } 12143 }
12169 12144
12170 // static 12145 // static
12171 void JSFunction::EnsureLiterals(Handle<JSFunction> function) { 12146 void JSFunction::EnsureLiterals(Handle<JSFunction> function) {
12172 Handle<SharedFunctionInfo> shared(function->shared()); 12147 Handle<SharedFunctionInfo> shared(function->shared());
12173 Handle<Context> native_context(function->context()->native_context()); 12148 Handle<Context> native_context(function->context()->native_context());
12174 if (function->literals() == 12149 if (function->feedback_vector() ==
12175 function->GetIsolate()->heap()->empty_literals_array()) { 12150 function->GetIsolate()->heap()->empty_type_feedback_vector()) {
12176 Handle<LiteralsArray> literals = 12151 Handle<TypeFeedbackVector> vector =
12177 SharedFunctionInfo::FindOrCreateLiterals(shared, native_context); 12152 SharedFunctionInfo::FindOrCreateVector(shared, native_context);
12178 function->set_literals(*literals); 12153 function->set_feedback_vector(*vector);
12179 } 12154 }
12180 } 12155 }
12181 12156
12182 static void GetMinInobjectSlack(Map* map, void* data) { 12157 static void GetMinInobjectSlack(Map* map, void* data) {
12183 int slack = map->unused_property_fields(); 12158 int slack = map->unused_property_fields();
12184 if (*reinterpret_cast<int*>(data) > slack) { 12159 if (*reinterpret_cast<int*>(data) > slack) {
12185 *reinterpret_cast<int*>(data) = slack; 12160 *reinterpret_cast<int*>(data) = slack;
12186 } 12161 }
12187 } 12162 }
12188 12163
(...skipping 1559 matching lines...) Expand 10 before | Expand all | Expand 10 after
13748 FixedArray* optimized_code_map = this->optimized_code_map(); 13723 FixedArray* optimized_code_map = this->optimized_code_map();
13749 int length = optimized_code_map->length(); 13724 int length = optimized_code_map->length();
13750 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell(); 13725 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell();
13751 for (int i = kEntriesStart; i < length; i += kEntryLength) { 13726 for (int i = kEntriesStart; i < length; i += kEntryLength) {
13752 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell, 13727 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell,
13753 SKIP_WRITE_BARRIER); 13728 SKIP_WRITE_BARRIER);
13754 } 13729 }
13755 } 13730 }
13756 } 13731 }
13757 13732
13758 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( 13733 CodeAndVector SharedFunctionInfo::SearchOptimizedCodeMap(
13759 Context* native_context, BailoutId osr_ast_id) { 13734 Context* native_context, BailoutId osr_ast_id) {
13760 CodeAndLiterals result = {nullptr, nullptr}; 13735 CodeAndVector result = {nullptr, nullptr};
13761 if (!osr_ast_id.IsNone()) { 13736 if (!osr_ast_id.IsNone()) {
13762 Code* code; 13737 Code* code;
13763 LiteralsArray* literals; 13738 TypeFeedbackVector* vector;
13764 native_context->SearchOptimizedCodeMap(this, osr_ast_id, &code, &literals); 13739 native_context->SearchOptimizedCodeMap(this, osr_ast_id, &code, &vector);
13765 result = {code, literals}; 13740 result = {code, vector};
13766 return result; 13741 return result;
13767 } 13742 }
13768 13743
13769 DCHECK(osr_ast_id.IsNone()); 13744 DCHECK(osr_ast_id.IsNone());
13770 int entry = SearchOptimizedCodeMapEntry(native_context); 13745 int entry = SearchOptimizedCodeMapEntry(native_context);
13771 if (entry != kNotFound) { 13746 if (entry != kNotFound) {
13772 FixedArray* code_map = optimized_code_map(); 13747 FixedArray* code_map = optimized_code_map();
13773 DCHECK_LE(entry + kEntryLength, code_map->length()); 13748 DCHECK_LE(entry + kEntryLength, code_map->length());
13774 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset)); 13749 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset));
13775 WeakCell* literals_cell = 13750 WeakCell* vector_cell =
13776 WeakCell::cast(code_map->get(entry + kLiteralsOffset)); 13751 WeakCell::cast(code_map->get(entry + kFeedbackVectorOffset));
13777 13752
13778 result = {cell->cleared() ? nullptr : Code::cast(cell->value()), 13753 result = {cell->cleared() ? nullptr : Code::cast(cell->value()),
13779 literals_cell->cleared() ? nullptr : LiteralsArray::cast( 13754 vector_cell->cleared() ? nullptr : TypeFeedbackVector::cast(
13780 literals_cell->value())}; 13755 vector_cell->value())};
13781 } 13756 }
13782 return result; 13757 return result;
13783 } 13758 }
13784 13759
13785 13760
13786 #define DECLARE_TAG(ignore1, name, ignore2) name, 13761 #define DECLARE_TAG(ignore1, name, ignore2) name,
13787 const char* const VisitorSynchronization::kTags[ 13762 const char* const VisitorSynchronization::kTags[
13788 VisitorSynchronization::kNumberOfSyncTags] = { 13763 VisitorSynchronization::kNumberOfSyncTags] = {
13789 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG) 13764 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG)
13790 }; 13765 };
(...skipping 6235 matching lines...) Expand 10 before | Expand all | Expand 10 after
20026 // depend on this. 20001 // depend on this.
20027 return DICTIONARY_ELEMENTS; 20002 return DICTIONARY_ELEMENTS;
20028 } 20003 }
20029 DCHECK_LE(kind, LAST_ELEMENTS_KIND); 20004 DCHECK_LE(kind, LAST_ELEMENTS_KIND);
20030 return kind; 20005 return kind;
20031 } 20006 }
20032 } 20007 }
20033 20008
20034 } // namespace internal 20009 } // namespace internal
20035 } // namespace v8 20010 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698