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

Side by Side Diff: src/objects.cc

Issue 2655853010: [TypeFeedbackVector] Combine the literals array and the feedback vector. (Closed)
Patch Set: partial serializer todo 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
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 10285 matching lines...) Expand 10 before | Expand all | Expand 10 after
10296 } 10296 }
10297 10297
10298 SharedFunctionInfo* DeoptimizationInputData::GetInlinedFunction(int index) { 10298 SharedFunctionInfo* DeoptimizationInputData::GetInlinedFunction(int index) {
10299 if (index == -1) { 10299 if (index == -1) {
10300 return SharedFunctionInfo::cast(SharedFunctionInfo()); 10300 return SharedFunctionInfo::cast(SharedFunctionInfo());
10301 } else { 10301 } else {
10302 return SharedFunctionInfo::cast(LiteralArray()->get(index)); 10302 return SharedFunctionInfo::cast(LiteralArray()->get(index));
10303 } 10303 }
10304 } 10304 }
10305 10305
10306 const int LiteralsArray::kFeedbackVectorOffset =
10307 LiteralsArray::OffsetOfElementAt(LiteralsArray::kVectorIndex);
10308
10309 const int LiteralsArray::kOffsetToFirstLiteral =
10310 LiteralsArray::OffsetOfElementAt(LiteralsArray::kFirstLiteralIndex);
10311
10312 // static
10313 Handle<LiteralsArray> LiteralsArray::New(Isolate* isolate,
10314 Handle<TypeFeedbackVector> vector,
10315 int number_of_literals,
10316 PretenureFlag pretenure) {
10317 if (vector->is_empty() && number_of_literals == 0) {
10318 return Handle<LiteralsArray>::cast(
10319 isolate->factory()->empty_literals_array());
10320 }
10321 Handle<FixedArray> literals = isolate->factory()->NewFixedArray(
10322 number_of_literals + kFirstLiteralIndex, pretenure);
10323 Handle<LiteralsArray> casted_literals = Handle<LiteralsArray>::cast(literals);
10324 casted_literals->set_feedback_vector(*vector);
10325 return casted_literals;
10326 }
10327
10328 int HandlerTable::LookupRange(int pc_offset, int* data_out, 10306 int HandlerTable::LookupRange(int pc_offset, int* data_out,
10329 CatchPrediction* prediction_out) { 10307 CatchPrediction* prediction_out) {
10330 int innermost_handler = -1; 10308 int innermost_handler = -1;
10331 #ifdef DEBUG 10309 #ifdef DEBUG
10332 // Assuming that ranges are well nested, we don't need to track the innermost 10310 // Assuming that ranges are well nested, we don't need to track the innermost
10333 // offsets. This is just to verify that the table is actually well nested. 10311 // offsets. This is just to verify that the table is actually well nested.
10334 int innermost_start = std::numeric_limits<int>::min(); 10312 int innermost_start = std::numeric_limits<int>::min();
10335 int innermost_end = std::numeric_limits<int>::max(); 10313 int innermost_end = std::numeric_limits<int>::max();
10336 #endif 10314 #endif
10337 for (int i = 0; i < length(); i += kRangeEntrySize) { 10315 for (int i = 0; i < length(); i += kRangeEntrySize) {
(...skipping 1704 matching lines...) Expand 10 before | Expand all | Expand 10 after
12042 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent)); 12020 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent));
12043 // No write barrier required, since the builtin is part of the root set. 12021 // No write barrier required, since the builtin is part of the root set.
12044 if (FLAG_mark_shared_functions_for_tier_up) { 12022 if (FLAG_mark_shared_functions_for_tier_up) {
12045 // TODO(leszeks): The compilation isn't concurrent if we trigger it using 12023 // TODO(leszeks): The compilation isn't concurrent if we trigger it using
12046 // this bit. 12024 // this bit.
12047 shared()->set_marked_for_tier_up(true); 12025 shared()->set_marked_for_tier_up(true);
12048 } 12026 }
12049 } 12027 }
12050 12028
12051 // static 12029 // static
12052 Handle<LiteralsArray> SharedFunctionInfo::FindOrCreateLiterals( 12030 Handle<TypeFeedbackVector> SharedFunctionInfo::FindOrCreateVector(
12053 Handle<SharedFunctionInfo> shared, Handle<Context> native_context) { 12031 Handle<SharedFunctionInfo> shared, Handle<Context> native_context) {
12054 Isolate* isolate = shared->GetIsolate(); 12032 Isolate* isolate = shared->GetIsolate();
12055 CodeAndLiterals result = 12033 CodeAndVector result =
12056 shared->SearchOptimizedCodeMap(*native_context, BailoutId::None()); 12034 shared->SearchOptimizedCodeMap(*native_context, BailoutId::None());
12057 if (result.literals != nullptr) { 12035 if (result.vector != nullptr) {
12058 DCHECK(shared->feedback_metadata()->is_empty() || 12036 DCHECK(shared->feedback_metadata()->is_empty() ||
12059 !result.literals->feedback_vector()->is_empty()); 12037 !result.vector->is_empty());
12060 return handle(result.literals, isolate); 12038 return handle(result.vector, isolate);
12061 } 12039 }
12062 12040
12063 Handle<TypeFeedbackVector> feedback_vector = 12041 Handle<TypeFeedbackVector> vector =
12064 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata())); 12042 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata()));
12065 Handle<LiteralsArray> literals =
12066 LiteralsArray::New(isolate, feedback_vector, shared->num_literals());
12067 Handle<Code> code; 12043 Handle<Code> code;
12068 if (result.code != nullptr) { 12044 if (result.code != nullptr) {
12069 code = Handle<Code>(result.code, isolate); 12045 code = Handle<Code>(result.code, isolate);
12070 } 12046 }
12071 AddToOptimizedCodeMap(shared, native_context, code, literals, 12047 AddToOptimizedCodeMap(shared, native_context, code, vector,
12072 BailoutId::None()); 12048 BailoutId::None());
12073 return literals; 12049 return vector;
12074 } 12050 }
12075 12051
12076 // static 12052 // static
12077 void SharedFunctionInfo::AddToOptimizedCodeMap( 12053 void SharedFunctionInfo::AddToOptimizedCodeMap(
12078 Handle<SharedFunctionInfo> shared, Handle<Context> native_context, 12054 Handle<SharedFunctionInfo> shared, Handle<Context> native_context,
12079 MaybeHandle<Code> code, Handle<LiteralsArray> literals, 12055 MaybeHandle<Code> code, Handle<TypeFeedbackVector> vector,
12080 BailoutId osr_ast_id) { 12056 BailoutId osr_ast_id) {
12081 Isolate* isolate = shared->GetIsolate(); 12057 Isolate* isolate = shared->GetIsolate();
12082 if (isolate->serializer_enabled()) return; 12058 if (isolate->serializer_enabled()) return;
12083 DCHECK(code.is_null() || 12059 DCHECK(code.is_null() ||
12084 code.ToHandleChecked()->kind() == Code::OPTIMIZED_FUNCTION); 12060 code.ToHandleChecked()->kind() == Code::OPTIMIZED_FUNCTION);
12085 DCHECK(native_context->IsNativeContext()); 12061 DCHECK(native_context->IsNativeContext());
12086 STATIC_ASSERT(kEntryLength == 3); 12062 STATIC_ASSERT(kEntryLength == 3);
12087 Handle<FixedArray> new_code_map; 12063 Handle<FixedArray> new_code_map;
12088 int entry; 12064 int entry;
12089 12065
12090 if (!osr_ast_id.IsNone()) { 12066 if (!osr_ast_id.IsNone()) {
12091 Context::AddToOptimizedCodeMap( 12067 Context::AddToOptimizedCodeMap(native_context, shared,
12092 native_context, shared, code.ToHandleChecked(), literals, osr_ast_id); 12068 code.ToHandleChecked(), vector, osr_ast_id);
12093 return; 12069 return;
12094 } 12070 }
12095 12071
12096 DCHECK(osr_ast_id.IsNone()); 12072 DCHECK(osr_ast_id.IsNone());
12097 if (shared->OptimizedCodeMapIsCleared()) { 12073 if (shared->OptimizedCodeMapIsCleared()) {
12098 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); 12074 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED);
12099 entry = kEntriesStart; 12075 entry = kEntriesStart;
12100 } else { 12076 } else {
12101 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate); 12077 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate);
12102 entry = shared->SearchOptimizedCodeMapEntry(*native_context); 12078 entry = shared->SearchOptimizedCodeMapEntry(*native_context);
12103 if (entry >= kEntriesStart) { 12079 if (entry >= kEntriesStart) {
12104 // Just set the code and literals of the entry. 12080 // Just set the code and vector of the entry.
12105 if (!code.is_null()) { 12081 if (!code.is_null()) {
12106 Handle<WeakCell> code_cell = 12082 Handle<WeakCell> code_cell =
12107 isolate->factory()->NewWeakCell(code.ToHandleChecked()); 12083 isolate->factory()->NewWeakCell(code.ToHandleChecked());
12108 old_code_map->set(entry + kCachedCodeOffset, *code_cell); 12084 old_code_map->set(entry + kCachedCodeOffset, *code_cell);
12109 } 12085 }
12110 Handle<WeakCell> literals_cell = 12086 Handle<WeakCell> vector_cell = isolate->factory()->NewWeakCell(vector);
12111 isolate->factory()->NewWeakCell(literals); 12087 old_code_map->set(entry + kFeedbackVectorOffset, *vector_cell);
12112 old_code_map->set(entry + kLiteralsOffset, *literals_cell);
12113 return; 12088 return;
12114 } 12089 }
12115 12090
12116 // Can we reuse an entry? 12091 // Can we reuse an entry?
12117 DCHECK(entry < kEntriesStart); 12092 DCHECK(entry < kEntriesStart);
12118 int length = old_code_map->length(); 12093 int length = old_code_map->length();
12119 for (int i = kEntriesStart; i < length; i += kEntryLength) { 12094 for (int i = kEntriesStart; i < length; i += kEntryLength) {
12120 if (WeakCell::cast(old_code_map->get(i + kContextOffset))->cleared()) { 12095 if (WeakCell::cast(old_code_map->get(i + kContextOffset))->cleared()) {
12121 new_code_map = old_code_map; 12096 new_code_map = old_code_map;
12122 entry = i; 12097 entry = i;
(...skipping 10 matching lines...) Expand all
12133 // holes. For now we just give up on adding the entry and pretend it got 12108 // holes. For now we just give up on adding the entry and pretend it got
12134 // flushed. 12109 // flushed.
12135 if (shared->OptimizedCodeMapIsCleared()) return; 12110 if (shared->OptimizedCodeMapIsCleared()) return;
12136 entry = old_code_map->length(); 12111 entry = old_code_map->length();
12137 } 12112 }
12138 } 12113 }
12139 12114
12140 Handle<WeakCell> code_cell = 12115 Handle<WeakCell> code_cell =
12141 code.is_null() ? isolate->factory()->empty_weak_cell() 12116 code.is_null() ? isolate->factory()->empty_weak_cell()
12142 : isolate->factory()->NewWeakCell(code.ToHandleChecked()); 12117 : isolate->factory()->NewWeakCell(code.ToHandleChecked());
12143 Handle<WeakCell> literals_cell = isolate->factory()->NewWeakCell(literals); 12118 Handle<WeakCell> vector_cell = isolate->factory()->NewWeakCell(vector);
12144 WeakCell* context_cell = native_context->self_weak_cell(); 12119 WeakCell* context_cell = native_context->self_weak_cell();
12145 12120
12146 new_code_map->set(entry + kContextOffset, context_cell); 12121 new_code_map->set(entry + kContextOffset, context_cell);
12147 new_code_map->set(entry + kCachedCodeOffset, *code_cell); 12122 new_code_map->set(entry + kCachedCodeOffset, *code_cell);
12148 new_code_map->set(entry + kLiteralsOffset, *literals_cell); 12123 new_code_map->set(entry + kFeedbackVectorOffset, *vector_cell);
12149 12124
12150 #ifdef DEBUG 12125 #ifdef DEBUG
12151 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) { 12126 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) {
12152 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset)); 12127 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset));
12153 DCHECK(cell->cleared() || cell->value()->IsNativeContext()); 12128 DCHECK(cell->cleared() || cell->value()->IsNativeContext());
12154 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset)); 12129 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset));
12155 DCHECK(cell->cleared() || 12130 DCHECK(cell->cleared() ||
12156 (cell->value()->IsCode() && 12131 (cell->value()->IsCode() &&
12157 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION)); 12132 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION));
12158 cell = WeakCell::cast(new_code_map->get(i + kLiteralsOffset)); 12133 cell = WeakCell::cast(new_code_map->get(i + kFeedbackVectorOffset));
12159 DCHECK(cell->cleared() || cell->value()->IsFixedArray()); 12134 DCHECK(cell->cleared() || cell->value()->IsFixedArray());
12160 } 12135 }
12161 #endif 12136 #endif
12162 12137
12163 FixedArray* old_code_map = shared->optimized_code_map(); 12138 FixedArray* old_code_map = shared->optimized_code_map();
12164 if (old_code_map != *new_code_map) { 12139 if (old_code_map != *new_code_map) {
12165 shared->set_optimized_code_map(*new_code_map); 12140 shared->set_optimized_code_map(*new_code_map);
12166 } 12141 }
12167 } 12142 }
12168 12143
(...skipping 18 matching lines...) Expand all
12187 DCHECK(WeakCell::cast(code_map->get(src))->cleared() || 12162 DCHECK(WeakCell::cast(code_map->get(src))->cleared() ||
12188 WeakCell::cast(code_map->get(src))->value()->IsNativeContext()); 12163 WeakCell::cast(code_map->get(src))->value()->IsNativeContext());
12189 found = WeakCell::cast(code_map->get(src + kCachedCodeOffset))->value() == 12164 found = WeakCell::cast(code_map->get(src + kCachedCodeOffset))->value() ==
12190 optimized_code; 12165 optimized_code;
12191 if (found) { 12166 if (found) {
12192 if (FLAG_trace_opt) { 12167 if (FLAG_trace_opt) {
12193 PrintF("[evicting entry from optimizing code map (%s) for ", reason); 12168 PrintF("[evicting entry from optimizing code map (%s) for ", reason);
12194 ShortPrint(); 12169 ShortPrint();
12195 PrintF("]\n"); 12170 PrintF("]\n");
12196 } 12171 }
12197 // Just clear the code in order to continue sharing literals. 12172 // Just clear the code in order to continue sharing a feedback vector.
12198 code_map->set(src + kCachedCodeOffset, heap->empty_weak_cell(), 12173 code_map->set(src + kCachedCodeOffset, heap->empty_weak_cell(),
12199 SKIP_WRITE_BARRIER); 12174 SKIP_WRITE_BARRIER);
12200 } 12175 }
12201 } 12176 }
12202 } 12177 }
12203 12178
12204 if (!found) { 12179 if (!found) {
12205 // We didn't find the code in here. It must be osr'd code. 12180 // We didn't find the code in here. It must be osr'd code.
12206 isolate->EvictOSROptimizedCode(optimized_code, reason); 12181 isolate->EvictOSROptimizedCode(optimized_code, reason);
12207 } 12182 }
12208 } 12183 }
12209 12184
12210 // static 12185 // static
12211 void JSFunction::EnsureLiterals(Handle<JSFunction> function) { 12186 void JSFunction::EnsureLiterals(Handle<JSFunction> function) {
12212 Handle<SharedFunctionInfo> shared(function->shared()); 12187 Handle<SharedFunctionInfo> shared(function->shared());
12213 Handle<Context> native_context(function->context()->native_context()); 12188 Handle<Context> native_context(function->context()->native_context());
12214 if (function->literals() == 12189 if (function->feedback_vector() ==
12215 function->GetIsolate()->heap()->empty_literals_array()) { 12190 function->GetIsolate()->heap()->empty_type_feedback_vector()) {
12216 Handle<LiteralsArray> literals = 12191 Handle<TypeFeedbackVector> vector =
12217 SharedFunctionInfo::FindOrCreateLiterals(shared, native_context); 12192 SharedFunctionInfo::FindOrCreateVector(shared, native_context);
12218 function->set_literals(*literals); 12193 function->set_feedback_vector(*vector);
12219 } 12194 }
12220 } 12195 }
12221 12196
12222 static void GetMinInobjectSlack(Map* map, void* data) { 12197 static void GetMinInobjectSlack(Map* map, void* data) {
12223 int slack = map->unused_property_fields(); 12198 int slack = map->unused_property_fields();
12224 if (*reinterpret_cast<int*>(data) > slack) { 12199 if (*reinterpret_cast<int*>(data) > slack) {
12225 *reinterpret_cast<int*>(data) = slack; 12200 *reinterpret_cast<int*>(data) = slack;
12226 } 12201 }
12227 } 12202 }
12228 12203
(...skipping 1559 matching lines...) Expand 10 before | Expand all | Expand 10 after
13788 FixedArray* optimized_code_map = this->optimized_code_map(); 13763 FixedArray* optimized_code_map = this->optimized_code_map();
13789 int length = optimized_code_map->length(); 13764 int length = optimized_code_map->length();
13790 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell(); 13765 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell();
13791 for (int i = kEntriesStart; i < length; i += kEntryLength) { 13766 for (int i = kEntriesStart; i < length; i += kEntryLength) {
13792 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell, 13767 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell,
13793 SKIP_WRITE_BARRIER); 13768 SKIP_WRITE_BARRIER);
13794 } 13769 }
13795 } 13770 }
13796 } 13771 }
13797 13772
13798 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( 13773 CodeAndVector SharedFunctionInfo::SearchOptimizedCodeMap(
13799 Context* native_context, BailoutId osr_ast_id) { 13774 Context* native_context, BailoutId osr_ast_id) {
13800 CodeAndLiterals result = {nullptr, nullptr}; 13775 CodeAndVector result = {nullptr, nullptr};
13801 if (!osr_ast_id.IsNone()) { 13776 if (!osr_ast_id.IsNone()) {
13802 Code* code; 13777 Code* code;
13803 LiteralsArray* literals; 13778 TypeFeedbackVector* vector;
13804 native_context->SearchOptimizedCodeMap(this, osr_ast_id, &code, &literals); 13779 native_context->SearchOptimizedCodeMap(this, osr_ast_id, &code, &vector);
13805 result = {code, literals}; 13780 result = {code, vector};
13806 return result; 13781 return result;
13807 } 13782 }
13808 13783
13809 DCHECK(osr_ast_id.IsNone()); 13784 DCHECK(osr_ast_id.IsNone());
13810 int entry = SearchOptimizedCodeMapEntry(native_context); 13785 int entry = SearchOptimizedCodeMapEntry(native_context);
13811 if (entry != kNotFound) { 13786 if (entry != kNotFound) {
13812 FixedArray* code_map = optimized_code_map(); 13787 FixedArray* code_map = optimized_code_map();
13813 DCHECK_LE(entry + kEntryLength, code_map->length()); 13788 DCHECK_LE(entry + kEntryLength, code_map->length());
13814 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset)); 13789 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset));
13815 WeakCell* literals_cell = 13790 WeakCell* vector_cell =
13816 WeakCell::cast(code_map->get(entry + kLiteralsOffset)); 13791 WeakCell::cast(code_map->get(entry + kFeedbackVectorOffset));
13817 13792
13818 result = {cell->cleared() ? nullptr : Code::cast(cell->value()), 13793 result = {cell->cleared() ? nullptr : Code::cast(cell->value()),
13819 literals_cell->cleared() ? nullptr : LiteralsArray::cast( 13794 vector_cell->cleared() ? nullptr : TypeFeedbackVector::cast(
13820 literals_cell->value())}; 13795 vector_cell->value())};
13821 } 13796 }
13822 return result; 13797 return result;
13823 } 13798 }
13824 13799
13825 13800
13826 #define DECLARE_TAG(ignore1, name, ignore2) name, 13801 #define DECLARE_TAG(ignore1, name, ignore2) name,
13827 const char* const VisitorSynchronization::kTags[ 13802 const char* const VisitorSynchronization::kTags[
13828 VisitorSynchronization::kNumberOfSyncTags] = { 13803 VisitorSynchronization::kNumberOfSyncTags] = {
13829 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG) 13804 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG)
13830 }; 13805 };
(...skipping 6235 matching lines...) Expand 10 before | Expand all | Expand 10 after
20066 // depend on this. 20041 // depend on this.
20067 return DICTIONARY_ELEMENTS; 20042 return DICTIONARY_ELEMENTS;
20068 } 20043 }
20069 DCHECK_LE(kind, LAST_ELEMENTS_KIND); 20044 DCHECK_LE(kind, LAST_ELEMENTS_KIND);
20070 return kind; 20045 return kind;
20071 } 20046 }
20072 } 20047 }
20073 20048
20074 } // namespace internal 20049 } // namespace internal
20075 } // namespace v8 20050 } // namespace v8
OLDNEW
« src/objects.h ('K') | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698