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

Side by Side Diff: src/objects.cc

Issue 2620753003: [TypeFeedbackVector] Root literal arrays in function literals slots (Closed)
Patch Set: GCSTRESS fix. 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 11930 matching lines...) Expand 10 before | Expand all | Expand 10 after
11941 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent)); 11941 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent));
11942 // No write barrier required, since the builtin is part of the root set. 11942 // No write barrier required, since the builtin is part of the root set.
11943 if (FLAG_mark_shared_functions_for_tier_up) { 11943 if (FLAG_mark_shared_functions_for_tier_up) {
11944 // TODO(leszeks): The compilation isn't concurrent if we trigger it using 11944 // TODO(leszeks): The compilation isn't concurrent if we trigger it using
11945 // this bit. 11945 // this bit.
11946 shared()->set_marked_for_tier_up(true); 11946 shared()->set_marked_for_tier_up(true);
11947 } 11947 }
11948 } 11948 }
11949 11949
11950 // static 11950 // static
11951 Handle<LiteralsArray> SharedFunctionInfo::FindOrCreateLiterals(
11952 Handle<SharedFunctionInfo> shared, Handle<Context> native_context) {
11953 Isolate* isolate = shared->GetIsolate();
11954 CodeAndLiterals result =
11955 shared->SearchOptimizedCodeMap(*native_context, BailoutId::None());
11956 if (result.literals != nullptr) {
11957 DCHECK(shared->feedback_metadata()->is_empty() ||
11958 !result.literals->feedback_vector()->is_empty());
11959 return handle(result.literals, isolate);
11960 }
11961
11962 Handle<TypeFeedbackVector> feedback_vector =
11963 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata()));
11964 Handle<LiteralsArray> literals =
11965 LiteralsArray::New(isolate, feedback_vector, shared->num_literals());
11966 Handle<Code> code;
11967 if (result.code != nullptr) {
11968 code = Handle<Code>(result.code, isolate);
11969 }
11970 AddToOptimizedCodeMap(shared, native_context, code, literals,
11971 BailoutId::None());
11972 return literals;
11973 }
11974
11975 // static
11976 void SharedFunctionInfo::AddToOptimizedCodeMap( 11951 void SharedFunctionInfo::AddToOptimizedCodeMap(
11977 Handle<SharedFunctionInfo> shared, Handle<Context> native_context, 11952 Handle<SharedFunctionInfo> shared, Handle<Context> native_context,
11978 MaybeHandle<Code> code, Handle<LiteralsArray> literals, 11953 Handle<Code> code, BailoutId osr_ast_id) {
11979 BailoutId osr_ast_id) {
11980 Isolate* isolate = shared->GetIsolate(); 11954 Isolate* isolate = shared->GetIsolate();
11981 if (isolate->serializer_enabled()) return; 11955 if (isolate->serializer_enabled()) return;
11982 DCHECK(code.is_null() || 11956 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
11983 code.ToHandleChecked()->kind() == Code::OPTIMIZED_FUNCTION);
11984 DCHECK(native_context->IsNativeContext()); 11957 DCHECK(native_context->IsNativeContext());
11985 STATIC_ASSERT(kEntryLength == 3); 11958 STATIC_ASSERT(kEntryLength == 2);
11986 Handle<FixedArray> new_code_map; 11959 Handle<FixedArray> new_code_map;
11987 int entry; 11960 int entry;
11988 11961
11989 if (!osr_ast_id.IsNone()) { 11962 if (!osr_ast_id.IsNone()) {
11990 Context::AddToOptimizedCodeMap( 11963 Context::AddToOptimizedCodeMap(native_context, shared, code, osr_ast_id);
11991 native_context, shared, code.ToHandleChecked(), literals, osr_ast_id);
11992 return; 11964 return;
11993 } 11965 }
11994 11966
11995 DCHECK(osr_ast_id.IsNone()); 11967 DCHECK(osr_ast_id.IsNone());
11996 if (shared->OptimizedCodeMapIsCleared()) { 11968 if (shared->OptimizedCodeMapIsCleared()) {
11997 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); 11969 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED);
11998 entry = kEntriesStart; 11970 entry = kEntriesStart;
11999 } else { 11971 } else {
12000 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate); 11972 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate);
12001 entry = shared->SearchOptimizedCodeMapEntry(*native_context); 11973 entry = shared->SearchOptimizedCodeMapEntry(*native_context);
12002 if (entry >= kEntriesStart) { 11974 if (entry >= kEntriesStart) {
12003 // Just set the code and literals of the entry. 11975 // Just set the code of the entry.
12004 if (!code.is_null()) { 11976 Handle<WeakCell> code_cell = isolate->factory()->NewWeakCell(code);
12005 Handle<WeakCell> code_cell = 11977 old_code_map->set(entry + kCachedCodeOffset, *code_cell);
12006 isolate->factory()->NewWeakCell(code.ToHandleChecked());
12007 old_code_map->set(entry + kCachedCodeOffset, *code_cell);
12008 }
12009 Handle<WeakCell> literals_cell =
12010 isolate->factory()->NewWeakCell(literals);
12011 old_code_map->set(entry + kLiteralsOffset, *literals_cell);
12012 return; 11978 return;
12013 } 11979 }
12014 11980
12015 // Can we reuse an entry? 11981 // Can we reuse an entry?
12016 DCHECK(entry < kEntriesStart); 11982 DCHECK(entry < kEntriesStart);
12017 int length = old_code_map->length(); 11983 int length = old_code_map->length();
12018 for (int i = kEntriesStart; i < length; i += kEntryLength) { 11984 for (int i = kEntriesStart; i < length; i += kEntryLength) {
12019 if (WeakCell::cast(old_code_map->get(i + kContextOffset))->cleared()) { 11985 if (WeakCell::cast(old_code_map->get(i + kContextOffset))->cleared()) {
12020 new_code_map = old_code_map; 11986 new_code_map = old_code_map;
12021 entry = i; 11987 entry = i;
12022 break; 11988 break;
12023 } 11989 }
12024 } 11990 }
12025 11991
12026 if (entry < kEntriesStart) { 11992 if (entry < kEntriesStart) {
12027 // Copy old optimized code map and append one new entry. 11993 // Copy old optimized code map and append one new entry.
12028 new_code_map = isolate->factory()->CopyFixedArrayAndGrow( 11994 new_code_map = isolate->factory()->CopyFixedArrayAndGrow(
12029 old_code_map, kEntryLength, TENURED); 11995 old_code_map, kEntryLength, TENURED);
12030 // TODO(mstarzinger): Temporary workaround. The allocation above might 11996 // TODO(mstarzinger): Temporary workaround. The allocation above might
12031 // have flushed the optimized code map and the copy we created is full of 11997 // have flushed the optimized code map and the copy we created is full of
12032 // holes. For now we just give up on adding the entry and pretend it got 11998 // holes. For now we just give up on adding the entry and pretend it got
12033 // flushed. 11999 // flushed.
12034 if (shared->OptimizedCodeMapIsCleared()) return; 12000 if (shared->OptimizedCodeMapIsCleared()) return;
12035 entry = old_code_map->length(); 12001 entry = old_code_map->length();
12036 } 12002 }
12037 } 12003 }
12038 12004
12039 Handle<WeakCell> code_cell = 12005 Handle<WeakCell> code_cell = isolate->factory()->NewWeakCell(code);
12040 code.is_null() ? isolate->factory()->empty_weak_cell()
12041 : isolate->factory()->NewWeakCell(code.ToHandleChecked());
12042 Handle<WeakCell> literals_cell = isolate->factory()->NewWeakCell(literals);
12043 WeakCell* context_cell = native_context->self_weak_cell(); 12006 WeakCell* context_cell = native_context->self_weak_cell();
12044 12007
12045 new_code_map->set(entry + kContextOffset, context_cell); 12008 new_code_map->set(entry + kContextOffset, context_cell);
12046 new_code_map->set(entry + kCachedCodeOffset, *code_cell); 12009 new_code_map->set(entry + kCachedCodeOffset, *code_cell);
12047 new_code_map->set(entry + kLiteralsOffset, *literals_cell);
12048 12010
12049 #ifdef DEBUG 12011 #ifdef DEBUG
12050 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) { 12012 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) {
12051 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset)); 12013 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset));
12052 DCHECK(cell->cleared() || cell->value()->IsNativeContext()); 12014 DCHECK(cell->cleared() || cell->value()->IsNativeContext());
12053 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset)); 12015 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset));
12054 DCHECK(cell->cleared() || 12016 DCHECK(cell->cleared() ||
12055 (cell->value()->IsCode() && 12017 (cell->value()->IsCode() &&
12056 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION)); 12018 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION));
12057 cell = WeakCell::cast(new_code_map->get(i + kLiteralsOffset));
12058 DCHECK(cell->cleared() || cell->value()->IsFixedArray());
12059 } 12019 }
12060 #endif 12020 #endif
12061 12021
12062 FixedArray* old_code_map = shared->optimized_code_map(); 12022 FixedArray* old_code_map = shared->optimized_code_map();
12063 if (old_code_map != *new_code_map) { 12023 if (old_code_map != *new_code_map) {
12064 shared->set_optimized_code_map(*new_code_map); 12024 shared->set_optimized_code_map(*new_code_map);
12065 } 12025 }
12066 } 12026 }
12067 12027
12068 12028
(...skipping 17 matching lines...) Expand all
12086 DCHECK(WeakCell::cast(code_map->get(src))->cleared() || 12046 DCHECK(WeakCell::cast(code_map->get(src))->cleared() ||
12087 WeakCell::cast(code_map->get(src))->value()->IsNativeContext()); 12047 WeakCell::cast(code_map->get(src))->value()->IsNativeContext());
12088 found = WeakCell::cast(code_map->get(src + kCachedCodeOffset))->value() == 12048 found = WeakCell::cast(code_map->get(src + kCachedCodeOffset))->value() ==
12089 optimized_code; 12049 optimized_code;
12090 if (found) { 12050 if (found) {
12091 if (FLAG_trace_opt) { 12051 if (FLAG_trace_opt) {
12092 PrintF("[evicting entry from optimizing code map (%s) for ", reason); 12052 PrintF("[evicting entry from optimizing code map (%s) for ", reason);
12093 ShortPrint(); 12053 ShortPrint();
12094 PrintF("]\n"); 12054 PrintF("]\n");
12095 } 12055 }
12096 // Just clear the code in order to continue sharing literals. 12056 // Just clear the code.
12097 code_map->set(src + kCachedCodeOffset, heap->empty_weak_cell(), 12057 code_map->set(src + kCachedCodeOffset, heap->empty_weak_cell(),
12098 SKIP_WRITE_BARRIER); 12058 SKIP_WRITE_BARRIER);
12099 } 12059 }
12100 } 12060 }
12101 } 12061 }
12102 12062
12103 if (!found) { 12063 if (!found) {
12104 // We didn't find the code in here. It must be osr'd code. 12064 // We didn't find the code in here. It must be osr'd code.
12105 isolate->EvictOSROptimizedCode(optimized_code, reason); 12065 isolate->EvictOSROptimizedCode(optimized_code, reason);
12106 } 12066 }
12107 } 12067 }
12108 12068
12109 // static 12069 // static
12110 void JSFunction::EnsureLiterals(Handle<JSFunction> function) { 12070 void JSFunction::EnsureLiterals(Handle<JSFunction> function) {
12111 Handle<SharedFunctionInfo> shared(function->shared()); 12071 Handle<SharedFunctionInfo> shared(function->shared());
12112 Handle<Context> native_context(function->context()->native_context()); 12072 Handle<Context> native_context(function->context()->native_context());
12113 if (function->literals() == 12073 Isolate* isolate = shared->GetIsolate();
12114 function->GetIsolate()->heap()->empty_literals_array()) { 12074
12115 Handle<LiteralsArray> literals = 12075 if (!function->has_literals_array()) {
12116 SharedFunctionInfo::FindOrCreateLiterals(shared, native_context); 12076 if (FLAG_trace_strong_rooted_literals) {
12117 function->set_literals(*literals); 12077 PrintF("EnsureLiterals: Installing literals array in %s %p\n",
12078 shared->DebugName()->ToCString().get(),
12079 reinterpret_cast<void*>(*function));
12080 }
12081 // Top level code didn't get it's literals installed.
12082 Handle<TypeFeedbackVector> feedback_vector =
12083 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata()));
12084 Handle<LiteralsArray> new_literals =
12085 LiteralsArray::New(isolate, feedback_vector, shared->num_literals());
12086 function->set_literals(*new_literals);
12087 } else if (!function->literals()->has_feedback_vector()) {
12088 if (FLAG_trace_strong_rooted_literals) {
12089 PrintF("EnsureLiterals: Installing feedback vector in %s %p\n",
12090 shared->DebugName()->ToCString().get(),
12091 reinterpret_cast<void*>(*function));
12092 }
12093 // If the feedback vector hasn't been installed, do that.
12094 Handle<TypeFeedbackVector> feedback_vector = TypeFeedbackVector::New(
12095 shared->GetIsolate(), handle(shared->feedback_metadata()));
12096 function->literals()->set_feedback_vector(*feedback_vector);
12097 } else {
12098 if (FLAG_trace_strong_rooted_literals) {
12099 PrintF("EnsureLiterals: did nothing for %s %p\n",
12100 shared->DebugName()->ToCString().get(),
12101 reinterpret_cast<void*>(*function));
12102 }
12118 } 12103 }
12104
12105 // No matter what, ensure some post-conditions.
12106 DCHECK(shared->feedback_metadata()->slot_count() != 0 ||
12107 function->feedback_vector() ==
12108 shared->GetIsolate()->heap()->empty_type_feedback_vector());
12109 DCHECK(shared->num_literals() == 0 ||
12110 function->literals() !=
12111 shared->GetIsolate()->heap()->empty_literals_array());
12119 } 12112 }
12120 12113
12121 static void GetMinInobjectSlack(Map* map, void* data) { 12114 static void GetMinInobjectSlack(Map* map, void* data) {
12122 int slack = map->unused_property_fields(); 12115 int slack = map->unused_property_fields();
12123 if (*reinterpret_cast<int*>(data) > slack) { 12116 if (*reinterpret_cast<int*>(data) > slack) {
12124 *reinterpret_cast<int*>(data) = slack; 12117 *reinterpret_cast<int*>(data) = slack;
12125 } 12118 }
12126 } 12119 }
12127 12120
12128 12121
(...skipping 1549 matching lines...) Expand 10 before | Expand all | Expand 10 after
13678 FixedArray* optimized_code_map = this->optimized_code_map(); 13671 FixedArray* optimized_code_map = this->optimized_code_map();
13679 int length = optimized_code_map->length(); 13672 int length = optimized_code_map->length();
13680 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell(); 13673 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell();
13681 for (int i = kEntriesStart; i < length; i += kEntryLength) { 13674 for (int i = kEntriesStart; i < length; i += kEntryLength) {
13682 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell, 13675 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell,
13683 SKIP_WRITE_BARRIER); 13676 SKIP_WRITE_BARRIER);
13684 } 13677 }
13685 } 13678 }
13686 } 13679 }
13687 13680
13688 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( 13681 Code* SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context,
13689 Context* native_context, BailoutId osr_ast_id) { 13682 BailoutId osr_ast_id) {
13690 CodeAndLiterals result = {nullptr, nullptr}; 13683 Code* result = nullptr;
13691 if (!osr_ast_id.IsNone()) { 13684 if (!osr_ast_id.IsNone()) {
13692 Code* code; 13685 return native_context->SearchOptimizedCodeMap(this, osr_ast_id);
13693 LiteralsArray* literals;
13694 native_context->SearchOptimizedCodeMap(this, osr_ast_id, &code, &literals);
13695 result = {code, literals};
13696 return result;
13697 } 13686 }
13698 13687
13699 DCHECK(osr_ast_id.IsNone()); 13688 DCHECK(osr_ast_id.IsNone());
13700 int entry = SearchOptimizedCodeMapEntry(native_context); 13689 int entry = SearchOptimizedCodeMapEntry(native_context);
13701 if (entry != kNotFound) { 13690 if (entry != kNotFound) {
13702 FixedArray* code_map = optimized_code_map(); 13691 FixedArray* code_map = optimized_code_map();
13703 DCHECK_LE(entry + kEntryLength, code_map->length()); 13692 DCHECK_LE(entry + kEntryLength, code_map->length());
13704 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset)); 13693 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset));
13705 WeakCell* literals_cell =
13706 WeakCell::cast(code_map->get(entry + kLiteralsOffset));
13707 13694
13708 result = {cell->cleared() ? nullptr : Code::cast(cell->value()), 13695 result = cell->cleared() ? nullptr : Code::cast(cell->value());
13709 literals_cell->cleared() ? nullptr : LiteralsArray::cast(
13710 literals_cell->value())};
13711 } 13696 }
13712 return result; 13697 return result;
13713 } 13698 }
13714 13699
13715 13700
13716 #define DECLARE_TAG(ignore1, name, ignore2) name, 13701 #define DECLARE_TAG(ignore1, name, ignore2) name,
13717 const char* const VisitorSynchronization::kTags[ 13702 const char* const VisitorSynchronization::kTags[
13718 VisitorSynchronization::kNumberOfSyncTags] = { 13703 VisitorSynchronization::kNumberOfSyncTags] = {
13719 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG) 13704 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG)
13720 }; 13705 };
(...skipping 6232 matching lines...) Expand 10 before | Expand all | Expand 10 after
19953 // depend on this. 19938 // depend on this.
19954 return DICTIONARY_ELEMENTS; 19939 return DICTIONARY_ELEMENTS;
19955 } 19940 }
19956 DCHECK_LE(kind, LAST_ELEMENTS_KIND); 19941 DCHECK_LE(kind, LAST_ELEMENTS_KIND);
19957 return kind; 19942 return kind;
19958 } 19943 }
19959 } 19944 }
19960 19945
19961 } // namespace internal 19946 } // namespace internal
19962 } // namespace v8 19947 } // 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