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

Side by Side Diff: src/objects.cc

Issue 2642933003: Revert of Revert [TypeFeedbackVector] Root literal arrays in function literal slots (Closed)
Patch Set: Created 3 years, 11 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 11954 matching lines...) Expand 10 before | Expand all | Expand 10 after
11965 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent)); 11965 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent));
11966 // No write barrier required, since the builtin is part of the root set. 11966 // No write barrier required, since the builtin is part of the root set.
11967 if (FLAG_mark_shared_functions_for_tier_up) { 11967 if (FLAG_mark_shared_functions_for_tier_up) {
11968 // TODO(leszeks): The compilation isn't concurrent if we trigger it using 11968 // TODO(leszeks): The compilation isn't concurrent if we trigger it using
11969 // this bit. 11969 // this bit.
11970 shared()->set_marked_for_tier_up(true); 11970 shared()->set_marked_for_tier_up(true);
11971 } 11971 }
11972 } 11972 }
11973 11973
11974 // static 11974 // static
11975 Handle<LiteralsArray> SharedFunctionInfo::FindOrCreateLiterals(
11976 Handle<SharedFunctionInfo> shared, Handle<Context> native_context) {
11977 Isolate* isolate = shared->GetIsolate();
11978 CodeAndLiterals result =
11979 shared->SearchOptimizedCodeMap(*native_context, BailoutId::None());
11980 if (result.literals != nullptr) {
11981 DCHECK(shared->feedback_metadata()->is_empty() ||
11982 !result.literals->feedback_vector()->is_empty());
11983 return handle(result.literals, isolate);
11984 }
11985
11986 Handle<TypeFeedbackVector> feedback_vector =
11987 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata()));
11988 Handle<LiteralsArray> literals =
11989 LiteralsArray::New(isolate, feedback_vector, shared->num_literals());
11990 Handle<Code> code;
11991 if (result.code != nullptr) {
11992 code = Handle<Code>(result.code, isolate);
11993 }
11994 AddToOptimizedCodeMap(shared, native_context, code, literals,
11995 BailoutId::None());
11996 return literals;
11997 }
11998
11999 // static
12000 void SharedFunctionInfo::AddToOptimizedCodeMap( 11975 void SharedFunctionInfo::AddToOptimizedCodeMap(
12001 Handle<SharedFunctionInfo> shared, Handle<Context> native_context, 11976 Handle<SharedFunctionInfo> shared, Handle<Context> native_context,
12002 MaybeHandle<Code> code, Handle<LiteralsArray> literals, 11977 Handle<Code> code, BailoutId osr_ast_id) {
12003 BailoutId osr_ast_id) {
12004 Isolate* isolate = shared->GetIsolate(); 11978 Isolate* isolate = shared->GetIsolate();
12005 if (isolate->serializer_enabled()) return; 11979 if (isolate->serializer_enabled()) return;
12006 DCHECK(code.is_null() || 11980 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
12007 code.ToHandleChecked()->kind() == Code::OPTIMIZED_FUNCTION);
12008 DCHECK(native_context->IsNativeContext()); 11981 DCHECK(native_context->IsNativeContext());
12009 STATIC_ASSERT(kEntryLength == 3); 11982 STATIC_ASSERT(kEntryLength == 2);
12010 Handle<FixedArray> new_code_map; 11983 Handle<FixedArray> new_code_map;
12011 int entry; 11984 int entry;
12012 11985
12013 if (!osr_ast_id.IsNone()) { 11986 if (!osr_ast_id.IsNone()) {
12014 Context::AddToOptimizedCodeMap( 11987 Context::AddToOptimizedCodeMap(native_context, shared, code, osr_ast_id);
12015 native_context, shared, code.ToHandleChecked(), literals, osr_ast_id);
12016 return; 11988 return;
12017 } 11989 }
12018 11990
12019 DCHECK(osr_ast_id.IsNone()); 11991 DCHECK(osr_ast_id.IsNone());
12020 if (shared->OptimizedCodeMapIsCleared()) { 11992 if (shared->OptimizedCodeMapIsCleared()) {
12021 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); 11993 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED);
12022 entry = kEntriesStart; 11994 entry = kEntriesStart;
12023 } else { 11995 } else {
12024 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate); 11996 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate);
12025 entry = shared->SearchOptimizedCodeMapEntry(*native_context); 11997 entry = shared->SearchOptimizedCodeMapEntry(*native_context);
12026 if (entry >= kEntriesStart) { 11998 if (entry >= kEntriesStart) {
12027 // Just set the code and literals of the entry. 11999 // Just set the code of the entry.
12028 if (!code.is_null()) { 12000 Handle<WeakCell> code_cell = isolate->factory()->NewWeakCell(code);
12029 Handle<WeakCell> code_cell = 12001 old_code_map->set(entry + kCachedCodeOffset, *code_cell);
12030 isolate->factory()->NewWeakCell(code.ToHandleChecked());
12031 old_code_map->set(entry + kCachedCodeOffset, *code_cell);
12032 }
12033 Handle<WeakCell> literals_cell =
12034 isolate->factory()->NewWeakCell(literals);
12035 old_code_map->set(entry + kLiteralsOffset, *literals_cell);
12036 return; 12002 return;
12037 } 12003 }
12038 12004
12039 // Can we reuse an entry? 12005 // Can we reuse an entry?
12040 DCHECK(entry < kEntriesStart); 12006 DCHECK(entry < kEntriesStart);
12041 int length = old_code_map->length(); 12007 int length = old_code_map->length();
12042 for (int i = kEntriesStart; i < length; i += kEntryLength) { 12008 for (int i = kEntriesStart; i < length; i += kEntryLength) {
12043 if (WeakCell::cast(old_code_map->get(i + kContextOffset))->cleared()) { 12009 if (WeakCell::cast(old_code_map->get(i + kContextOffset))->cleared()) {
12044 new_code_map = old_code_map; 12010 new_code_map = old_code_map;
12045 entry = i; 12011 entry = i;
12046 break; 12012 break;
12047 } 12013 }
12048 } 12014 }
12049 12015
12050 if (entry < kEntriesStart) { 12016 if (entry < kEntriesStart) {
12051 // Copy old optimized code map and append one new entry. 12017 // Copy old optimized code map and append one new entry.
12052 new_code_map = isolate->factory()->CopyFixedArrayAndGrow( 12018 new_code_map = isolate->factory()->CopyFixedArrayAndGrow(
12053 old_code_map, kEntryLength, TENURED); 12019 old_code_map, kEntryLength, TENURED);
12054 // TODO(mstarzinger): Temporary workaround. The allocation above might 12020 // TODO(mstarzinger): Temporary workaround. The allocation above might
12055 // have flushed the optimized code map and the copy we created is full of 12021 // have flushed the optimized code map and the copy we created is full of
12056 // holes. For now we just give up on adding the entry and pretend it got 12022 // holes. For now we just give up on adding the entry and pretend it got
12057 // flushed. 12023 // flushed.
12058 if (shared->OptimizedCodeMapIsCleared()) return; 12024 if (shared->OptimizedCodeMapIsCleared()) return;
12059 entry = old_code_map->length(); 12025 entry = old_code_map->length();
12060 } 12026 }
12061 } 12027 }
12062 12028
12063 Handle<WeakCell> code_cell = 12029 Handle<WeakCell> code_cell = isolate->factory()->NewWeakCell(code);
12064 code.is_null() ? isolate->factory()->empty_weak_cell()
12065 : isolate->factory()->NewWeakCell(code.ToHandleChecked());
12066 Handle<WeakCell> literals_cell = isolate->factory()->NewWeakCell(literals);
12067 WeakCell* context_cell = native_context->self_weak_cell(); 12030 WeakCell* context_cell = native_context->self_weak_cell();
12068 12031
12069 new_code_map->set(entry + kContextOffset, context_cell); 12032 new_code_map->set(entry + kContextOffset, context_cell);
12070 new_code_map->set(entry + kCachedCodeOffset, *code_cell); 12033 new_code_map->set(entry + kCachedCodeOffset, *code_cell);
12071 new_code_map->set(entry + kLiteralsOffset, *literals_cell);
12072 12034
12073 #ifdef DEBUG 12035 #ifdef DEBUG
12074 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) { 12036 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) {
12075 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset)); 12037 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset));
12076 DCHECK(cell->cleared() || cell->value()->IsNativeContext()); 12038 DCHECK(cell->cleared() || cell->value()->IsNativeContext());
12077 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset)); 12039 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset));
12078 DCHECK(cell->cleared() || 12040 DCHECK(cell->cleared() ||
12079 (cell->value()->IsCode() && 12041 (cell->value()->IsCode() &&
12080 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION)); 12042 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION));
12081 cell = WeakCell::cast(new_code_map->get(i + kLiteralsOffset));
12082 DCHECK(cell->cleared() || cell->value()->IsFixedArray());
12083 } 12043 }
12084 #endif 12044 #endif
12085 12045
12086 FixedArray* old_code_map = shared->optimized_code_map(); 12046 FixedArray* old_code_map = shared->optimized_code_map();
12087 if (old_code_map != *new_code_map) { 12047 if (old_code_map != *new_code_map) {
12088 shared->set_optimized_code_map(*new_code_map); 12048 shared->set_optimized_code_map(*new_code_map);
12089 } 12049 }
12090 } 12050 }
12091 12051
12092 12052
(...skipping 17 matching lines...) Expand all
12110 DCHECK(WeakCell::cast(code_map->get(src))->cleared() || 12070 DCHECK(WeakCell::cast(code_map->get(src))->cleared() ||
12111 WeakCell::cast(code_map->get(src))->value()->IsNativeContext()); 12071 WeakCell::cast(code_map->get(src))->value()->IsNativeContext());
12112 found = WeakCell::cast(code_map->get(src + kCachedCodeOffset))->value() == 12072 found = WeakCell::cast(code_map->get(src + kCachedCodeOffset))->value() ==
12113 optimized_code; 12073 optimized_code;
12114 if (found) { 12074 if (found) {
12115 if (FLAG_trace_opt) { 12075 if (FLAG_trace_opt) {
12116 PrintF("[evicting entry from optimizing code map (%s) for ", reason); 12076 PrintF("[evicting entry from optimizing code map (%s) for ", reason);
12117 ShortPrint(); 12077 ShortPrint();
12118 PrintF("]\n"); 12078 PrintF("]\n");
12119 } 12079 }
12120 // Just clear the code in order to continue sharing literals. 12080 // Just clear the code.
12121 code_map->set(src + kCachedCodeOffset, heap->empty_weak_cell(), 12081 code_map->set(src + kCachedCodeOffset, heap->empty_weak_cell(),
12122 SKIP_WRITE_BARRIER); 12082 SKIP_WRITE_BARRIER);
12123 } 12083 }
12124 } 12084 }
12125 } 12085 }
12126 12086
12127 if (!found) { 12087 if (!found) {
12128 // We didn't find the code in here. It must be osr'd code. 12088 // We didn't find the code in here. It must be osr'd code.
12129 isolate->EvictOSROptimizedCode(optimized_code, reason); 12089 isolate->EvictOSROptimizedCode(optimized_code, reason);
12130 } 12090 }
12131 } 12091 }
12132 12092
12133 // static 12093 // static
12134 void JSFunction::EnsureLiterals(Handle<JSFunction> function) { 12094 void JSFunction::EnsureLiterals(Handle<JSFunction> function) {
12135 Handle<SharedFunctionInfo> shared(function->shared()); 12095 Handle<SharedFunctionInfo> shared(function->shared());
12136 Handle<Context> native_context(function->context()->native_context()); 12096 Handle<Context> native_context(function->context()->native_context());
12137 if (function->literals() == 12097 Isolate* isolate = shared->GetIsolate();
12138 function->GetIsolate()->heap()->empty_literals_array()) { 12098
12139 Handle<LiteralsArray> literals = 12099 if (!function->has_literals_array()) {
12140 SharedFunctionInfo::FindOrCreateLiterals(shared, native_context); 12100 if (FLAG_trace_strong_rooted_literals) {
12141 function->set_literals(*literals); 12101 PrintF("EnsureLiterals: Installing literals array in %s %p\n",
12102 shared->DebugName()->ToCString().get(),
12103 reinterpret_cast<void*>(*function));
12104 }
12105 // Top level code didn't get it's literals installed.
12106 Handle<TypeFeedbackVector> feedback_vector =
12107 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata()));
12108 Handle<LiteralsArray> new_literals =
12109 LiteralsArray::New(isolate, feedback_vector, shared->num_literals());
12110 function->set_literals(*new_literals);
12111 } else if (!function->literals()->has_feedback_vector()) {
12112 if (FLAG_trace_strong_rooted_literals) {
12113 PrintF("EnsureLiterals: Installing feedback vector in %s %p\n",
12114 shared->DebugName()->ToCString().get(),
12115 reinterpret_cast<void*>(*function));
12116 }
12117 // If the feedback vector hasn't been installed, do that.
12118 Handle<TypeFeedbackVector> feedback_vector = TypeFeedbackVector::New(
12119 shared->GetIsolate(), handle(shared->feedback_metadata()));
12120 function->literals()->set_feedback_vector(*feedback_vector);
12121 } else {
12122 if (FLAG_trace_strong_rooted_literals) {
12123 PrintF("EnsureLiterals: did nothing for %s %p\n",
12124 shared->DebugName()->ToCString().get(),
12125 reinterpret_cast<void*>(*function));
12126 }
12142 } 12127 }
12128
12129 // No matter what, ensure some post-conditions.
12130 DCHECK(shared->feedback_metadata()->slot_count() != 0 ||
12131 function->feedback_vector() ==
12132 shared->GetIsolate()->heap()->empty_type_feedback_vector());
12133 DCHECK(shared->num_literals() == 0 ||
12134 function->literals() !=
12135 shared->GetIsolate()->heap()->empty_literals_array());
12143 } 12136 }
12144 12137
12145 static void GetMinInobjectSlack(Map* map, void* data) { 12138 static void GetMinInobjectSlack(Map* map, void* data) {
12146 int slack = map->unused_property_fields(); 12139 int slack = map->unused_property_fields();
12147 if (*reinterpret_cast<int*>(data) > slack) { 12140 if (*reinterpret_cast<int*>(data) > slack) {
12148 *reinterpret_cast<int*>(data) = slack; 12141 *reinterpret_cast<int*>(data) = slack;
12149 } 12142 }
12150 } 12143 }
12151 12144
12152 12145
(...skipping 1558 matching lines...) Expand 10 before | Expand all | Expand 10 after
13711 FixedArray* optimized_code_map = this->optimized_code_map(); 13704 FixedArray* optimized_code_map = this->optimized_code_map();
13712 int length = optimized_code_map->length(); 13705 int length = optimized_code_map->length();
13713 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell(); 13706 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell();
13714 for (int i = kEntriesStart; i < length; i += kEntryLength) { 13707 for (int i = kEntriesStart; i < length; i += kEntryLength) {
13715 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell, 13708 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell,
13716 SKIP_WRITE_BARRIER); 13709 SKIP_WRITE_BARRIER);
13717 } 13710 }
13718 } 13711 }
13719 } 13712 }
13720 13713
13721 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( 13714 Code* SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context,
13722 Context* native_context, BailoutId osr_ast_id) { 13715 BailoutId osr_ast_id) {
13723 CodeAndLiterals result = {nullptr, nullptr}; 13716 Code* result = nullptr;
13724 if (!osr_ast_id.IsNone()) { 13717 if (!osr_ast_id.IsNone()) {
13725 Code* code; 13718 return native_context->SearchOptimizedCodeMap(this, osr_ast_id);
13726 LiteralsArray* literals;
13727 native_context->SearchOptimizedCodeMap(this, osr_ast_id, &code, &literals);
13728 result = {code, literals};
13729 return result;
13730 } 13719 }
13731 13720
13732 DCHECK(osr_ast_id.IsNone()); 13721 DCHECK(osr_ast_id.IsNone());
13733 int entry = SearchOptimizedCodeMapEntry(native_context); 13722 int entry = SearchOptimizedCodeMapEntry(native_context);
13734 if (entry != kNotFound) { 13723 if (entry != kNotFound) {
13735 FixedArray* code_map = optimized_code_map(); 13724 FixedArray* code_map = optimized_code_map();
13736 DCHECK_LE(entry + kEntryLength, code_map->length()); 13725 DCHECK_LE(entry + kEntryLength, code_map->length());
13737 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset)); 13726 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset));
13738 WeakCell* literals_cell =
13739 WeakCell::cast(code_map->get(entry + kLiteralsOffset));
13740 13727
13741 result = {cell->cleared() ? nullptr : Code::cast(cell->value()), 13728 result = cell->cleared() ? nullptr : Code::cast(cell->value());
13742 literals_cell->cleared() ? nullptr : LiteralsArray::cast(
13743 literals_cell->value())};
13744 } 13729 }
13745 return result; 13730 return result;
13746 } 13731 }
13747 13732
13748 13733
13749 #define DECLARE_TAG(ignore1, name, ignore2) name, 13734 #define DECLARE_TAG(ignore1, name, ignore2) name,
13750 const char* const VisitorSynchronization::kTags[ 13735 const char* const VisitorSynchronization::kTags[
13751 VisitorSynchronization::kNumberOfSyncTags] = { 13736 VisitorSynchronization::kNumberOfSyncTags] = {
13752 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG) 13737 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG)
13753 }; 13738 };
(...skipping 6177 matching lines...) Expand 10 before | Expand all | Expand 10 after
19931 // depend on this. 19916 // depend on this.
19932 return DICTIONARY_ELEMENTS; 19917 return DICTIONARY_ELEMENTS;
19933 } 19918 }
19934 DCHECK_LE(kind, LAST_ELEMENTS_KIND); 19919 DCHECK_LE(kind, LAST_ELEMENTS_KIND);
19935 return kind; 19920 return kind;
19936 } 19921 }
19937 } 19922 }
19938 19923
19939 } // namespace internal 19924 } // namespace internal
19940 } // namespace v8 19925 } // 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