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

Side by Side Diff: src/objects.cc

Issue 2620753003: [TypeFeedbackVector] Root literal arrays in function literals slots (Closed)
Patch Set: Code comments. 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
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 12521 matching lines...) Expand 10 before | Expand all | Expand 10 after
12532 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent)); 12532 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent));
12533 // No write barrier required, since the builtin is part of the root set. 12533 // No write barrier required, since the builtin is part of the root set.
12534 if (FLAG_mark_shared_functions_for_tier_up) { 12534 if (FLAG_mark_shared_functions_for_tier_up) {
12535 // TODO(leszeks): The compilation isn't concurrent if we trigger it using 12535 // TODO(leszeks): The compilation isn't concurrent if we trigger it using
12536 // this bit. 12536 // this bit.
12537 shared()->set_marked_for_tier_up(true); 12537 shared()->set_marked_for_tier_up(true);
12538 } 12538 }
12539 } 12539 }
12540 12540
12541 // static 12541 // static
12542 Handle<LiteralsArray> SharedFunctionInfo::FindOrCreateLiterals(
12543 Handle<SharedFunctionInfo> shared, Handle<Context> native_context) {
12544 Isolate* isolate = shared->GetIsolate();
12545 CodeAndLiterals result =
12546 shared->SearchOptimizedCodeMap(*native_context, BailoutId::None());
12547 if (result.literals != nullptr) {
12548 DCHECK(shared->feedback_metadata()->is_empty() ||
12549 !result.literals->feedback_vector()->is_empty());
12550 return handle(result.literals, isolate);
12551 }
12552
12553 Handle<TypeFeedbackVector> feedback_vector =
12554 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata()));
12555 Handle<LiteralsArray> literals =
12556 LiteralsArray::New(isolate, feedback_vector, shared->num_literals());
12557 Handle<Code> code;
12558 if (result.code != nullptr) {
12559 code = Handle<Code>(result.code, isolate);
12560 }
12561 AddToOptimizedCodeMap(shared, native_context, code, literals,
12562 BailoutId::None());
12563 return literals;
12564 }
12565
12566 // static
12567 void SharedFunctionInfo::AddToOptimizedCodeMap( 12542 void SharedFunctionInfo::AddToOptimizedCodeMap(
12568 Handle<SharedFunctionInfo> shared, Handle<Context> native_context, 12543 Handle<SharedFunctionInfo> shared, Handle<Context> native_context,
12569 MaybeHandle<Code> code, Handle<LiteralsArray> literals, 12544 Handle<Code> code, BailoutId osr_ast_id) {
12570 BailoutId osr_ast_id) {
12571 Isolate* isolate = shared->GetIsolate(); 12545 Isolate* isolate = shared->GetIsolate();
12572 if (isolate->serializer_enabled()) return; 12546 if (isolate->serializer_enabled()) return;
12573 DCHECK(code.is_null() || 12547 DCHECK(code.is_null() || code->kind() == Code::OPTIMIZED_FUNCTION);
Michael Starzinger 2017/01/11 13:22:44 nit: First half of the predicate should always hol
mvstanton 2017/01/11 14:52:06 Done.
12574 code.ToHandleChecked()->kind() == Code::OPTIMIZED_FUNCTION);
12575 DCHECK(native_context->IsNativeContext()); 12548 DCHECK(native_context->IsNativeContext());
12576 STATIC_ASSERT(kEntryLength == 3); 12549 STATIC_ASSERT(kEntryLength == 2);
12577 Handle<FixedArray> new_code_map; 12550 Handle<FixedArray> new_code_map;
12578 int entry; 12551 int entry;
12579 12552
12580 if (!osr_ast_id.IsNone()) { 12553 if (!osr_ast_id.IsNone()) {
12581 Context::AddToOptimizedCodeMap( 12554 Context::AddToOptimizedCodeMap(native_context, shared, code, osr_ast_id);
12582 native_context, shared, code.ToHandleChecked(), literals, osr_ast_id);
12583 return; 12555 return;
12584 } 12556 }
12585 12557
12586 DCHECK(osr_ast_id.IsNone()); 12558 DCHECK(osr_ast_id.IsNone());
12587 if (shared->OptimizedCodeMapIsCleared()) { 12559 if (shared->OptimizedCodeMapIsCleared()) {
12588 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); 12560 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED);
12589 entry = kEntriesStart; 12561 entry = kEntriesStart;
12590 } else { 12562 } else {
12591 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate); 12563 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate);
12592 entry = shared->SearchOptimizedCodeMapEntry(*native_context); 12564 entry = shared->SearchOptimizedCodeMapEntry(*native_context);
12593 if (entry >= kEntriesStart) { 12565 if (entry >= kEntriesStart) {
12594 // Just set the code and literals of the entry. 12566 // Just set the code of the entry.
12595 if (!code.is_null()) { 12567 if (!code.is_null()) {
Michael Starzinger 2017/01/11 13:22:44 nit: Should always hold now AFAICT.
mvstanton 2017/01/11 14:52:06 Done.
12596 Handle<WeakCell> code_cell = 12568 Handle<WeakCell> code_cell = isolate->factory()->NewWeakCell(code);
12597 isolate->factory()->NewWeakCell(code.ToHandleChecked());
12598 old_code_map->set(entry + kCachedCodeOffset, *code_cell); 12569 old_code_map->set(entry + kCachedCodeOffset, *code_cell);
12599 } 12570 }
12600 Handle<WeakCell> literals_cell =
12601 isolate->factory()->NewWeakCell(literals);
12602 old_code_map->set(entry + kLiteralsOffset, *literals_cell);
12603 return; 12571 return;
12604 } 12572 }
12605 12573
12606 // Can we reuse an entry? 12574 // Can we reuse an entry?
12607 DCHECK(entry < kEntriesStart); 12575 DCHECK(entry < kEntriesStart);
12608 int length = old_code_map->length(); 12576 int length = old_code_map->length();
12609 for (int i = kEntriesStart; i < length; i += kEntryLength) { 12577 for (int i = kEntriesStart; i < length; i += kEntryLength) {
12610 if (WeakCell::cast(old_code_map->get(i + kContextOffset))->cleared()) { 12578 if (WeakCell::cast(old_code_map->get(i + kContextOffset))->cleared()) {
12611 new_code_map = old_code_map; 12579 new_code_map = old_code_map;
12612 entry = i; 12580 entry = i;
12613 break; 12581 break;
12614 } 12582 }
12615 } 12583 }
12616 12584
12617 if (entry < kEntriesStart) { 12585 if (entry < kEntriesStart) {
12618 // Copy old optimized code map and append one new entry. 12586 // Copy old optimized code map and append one new entry.
12619 new_code_map = isolate->factory()->CopyFixedArrayAndGrow( 12587 new_code_map = isolate->factory()->CopyFixedArrayAndGrow(
12620 old_code_map, kEntryLength, TENURED); 12588 old_code_map, kEntryLength, TENURED);
12621 // TODO(mstarzinger): Temporary workaround. The allocation above might 12589 // TODO(mstarzinger): Temporary workaround. The allocation above might
12622 // have flushed the optimized code map and the copy we created is full of 12590 // have flushed the optimized code map and the copy we created is full of
12623 // holes. For now we just give up on adding the entry and pretend it got 12591 // holes. For now we just give up on adding the entry and pretend it got
12624 // flushed. 12592 // flushed.
12625 if (shared->OptimizedCodeMapIsCleared()) return; 12593 if (shared->OptimizedCodeMapIsCleared()) return;
12626 entry = old_code_map->length(); 12594 entry = old_code_map->length();
12627 } 12595 }
12628 } 12596 }
12629 12597
12630 Handle<WeakCell> code_cell = 12598 Handle<WeakCell> code_cell = code.is_null()
Michael Starzinger 2017/01/11 13:22:44 nit: Should always hold now AFAICT.
mvstanton 2017/01/11 14:52:06 Done.
12631 code.is_null() ? isolate->factory()->empty_weak_cell() 12599 ? isolate->factory()->empty_weak_cell()
12632 : isolate->factory()->NewWeakCell(code.ToHandleChecked()); 12600 : isolate->factory()->NewWeakCell(code);
12633 Handle<WeakCell> literals_cell = isolate->factory()->NewWeakCell(literals);
12634 WeakCell* context_cell = native_context->self_weak_cell(); 12601 WeakCell* context_cell = native_context->self_weak_cell();
12635 12602
12636 new_code_map->set(entry + kContextOffset, context_cell); 12603 new_code_map->set(entry + kContextOffset, context_cell);
12637 new_code_map->set(entry + kCachedCodeOffset, *code_cell); 12604 new_code_map->set(entry + kCachedCodeOffset, *code_cell);
12638 new_code_map->set(entry + kLiteralsOffset, *literals_cell);
12639 12605
12640 #ifdef DEBUG 12606 #ifdef DEBUG
12641 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) { 12607 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) {
12642 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset)); 12608 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset));
12643 DCHECK(cell->cleared() || cell->value()->IsNativeContext()); 12609 DCHECK(cell->cleared() || cell->value()->IsNativeContext());
12644 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset)); 12610 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset));
12645 DCHECK(cell->cleared() || 12611 DCHECK(cell->cleared() ||
12646 (cell->value()->IsCode() && 12612 (cell->value()->IsCode() &&
12647 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION)); 12613 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION));
12648 cell = WeakCell::cast(new_code_map->get(i + kLiteralsOffset));
12649 DCHECK(cell->cleared() || cell->value()->IsFixedArray());
12650 } 12614 }
12651 #endif 12615 #endif
12652 12616
12653 FixedArray* old_code_map = shared->optimized_code_map(); 12617 FixedArray* old_code_map = shared->optimized_code_map();
12654 if (old_code_map != *new_code_map) { 12618 if (old_code_map != *new_code_map) {
12655 shared->set_optimized_code_map(*new_code_map); 12619 shared->set_optimized_code_map(*new_code_map);
12656 } 12620 }
12657 } 12621 }
12658 12622
12659 12623
(...skipping 17 matching lines...) Expand all
12677 DCHECK(WeakCell::cast(code_map->get(src))->cleared() || 12641 DCHECK(WeakCell::cast(code_map->get(src))->cleared() ||
12678 WeakCell::cast(code_map->get(src))->value()->IsNativeContext()); 12642 WeakCell::cast(code_map->get(src))->value()->IsNativeContext());
12679 found = WeakCell::cast(code_map->get(src + kCachedCodeOffset))->value() == 12643 found = WeakCell::cast(code_map->get(src + kCachedCodeOffset))->value() ==
12680 optimized_code; 12644 optimized_code;
12681 if (found) { 12645 if (found) {
12682 if (FLAG_trace_opt) { 12646 if (FLAG_trace_opt) {
12683 PrintF("[evicting entry from optimizing code map (%s) for ", reason); 12647 PrintF("[evicting entry from optimizing code map (%s) for ", reason);
12684 ShortPrint(); 12648 ShortPrint();
12685 PrintF("]\n"); 12649 PrintF("]\n");
12686 } 12650 }
12687 // Just clear the code in order to continue sharing literals. 12651 // Just clear the code.
12688 code_map->set(src + kCachedCodeOffset, heap->empty_weak_cell(), 12652 code_map->set(src + kCachedCodeOffset, heap->empty_weak_cell(),
12689 SKIP_WRITE_BARRIER); 12653 SKIP_WRITE_BARRIER);
12690 } 12654 }
12691 } 12655 }
12692 } 12656 }
12693 12657
12694 if (!found) { 12658 if (!found) {
12695 // We didn't find the code in here. It must be osr'd code. 12659 // We didn't find the code in here. It must be osr'd code.
12696 isolate->EvictOSROptimizedCode(optimized_code, reason); 12660 isolate->EvictOSROptimizedCode(optimized_code, reason);
12697 } 12661 }
12698 } 12662 }
12699 12663
12700 // static 12664 // static
12701 void JSFunction::EnsureLiterals(Handle<JSFunction> function) { 12665 void JSFunction::EnsureLiterals(Handle<JSFunction> function) {
12702 Handle<SharedFunctionInfo> shared(function->shared()); 12666 Handle<SharedFunctionInfo> shared(function->shared());
12703 Handle<Context> native_context(function->context()->native_context()); 12667 Handle<Context> native_context(function->context()->native_context());
12704 if (function->literals() == 12668 Isolate* isolate = shared->GetIsolate();
12705 function->GetIsolate()->heap()->empty_literals_array()) { 12669
12706 Handle<LiteralsArray> literals = 12670 if (!function->has_literals_array()) {
12707 SharedFunctionInfo::FindOrCreateLiterals(shared, native_context); 12671 if (FLAG_trace_strong_rooted_literals) {
12708 function->set_literals(*literals); 12672 PrintF("EnsureLiterals: Installing literals array in %s %p\n",
12673 shared->DebugName()->ToCString().get(),
12674 reinterpret_cast<void*>(*function));
12675 }
12676 // Top level code didn't get it's literals installed.
12677 Handle<TypeFeedbackVector> feedback_vector =
12678 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata()));
12679 Handle<LiteralsArray> new_literals =
12680 LiteralsArray::New(isolate, feedback_vector, shared->num_literals());
12681 function->set_literals(*new_literals);
12682 } else if (!function->literals()->has_feedback_vector()) {
12683 if (FLAG_trace_strong_rooted_literals) {
12684 PrintF("EnsureLiterals: Installing feedback vector in %s %p\n",
12685 shared->DebugName()->ToCString().get(),
12686 reinterpret_cast<void*>(*function));
12687 }
12688 // If the feedback vector hasn't been installed, do that.
12689 Handle<TypeFeedbackVector> feedback_vector = TypeFeedbackVector::New(
12690 shared->GetIsolate(), handle(shared->feedback_metadata()));
12691 function->literals()->set_feedback_vector(*feedback_vector);
12692 } else {
12693 if (FLAG_trace_strong_rooted_literals) {
12694 PrintF("EnsureLiterals: did nothing for %s %p\n",
12695 shared->DebugName()->ToCString().get(),
12696 reinterpret_cast<void*>(*function));
12697 }
12709 } 12698 }
12699
12700 // No matter what, ensure some post-conditions.
12701 DCHECK(shared->feedback_metadata()->slot_count() != 0 ||
12702 function->feedback_vector() ==
12703 shared->GetIsolate()->heap()->empty_type_feedback_vector());
12704 DCHECK(shared->num_literals() == 0 ||
12705 function->literals() !=
12706 shared->GetIsolate()->heap()->empty_literals_array());
12710 } 12707 }
12711 12708
12712 static void GetMinInobjectSlack(Map* map, void* data) { 12709 static void GetMinInobjectSlack(Map* map, void* data) {
12713 int slack = map->unused_property_fields(); 12710 int slack = map->unused_property_fields();
12714 if (*reinterpret_cast<int*>(data) > slack) { 12711 if (*reinterpret_cast<int*>(data) > slack) {
12715 *reinterpret_cast<int*>(data) = slack; 12712 *reinterpret_cast<int*>(data) = slack;
12716 } 12713 }
12717 } 12714 }
12718 12715
12719 12716
(...skipping 1549 matching lines...) Expand 10 before | Expand all | Expand 10 after
14269 FixedArray* optimized_code_map = this->optimized_code_map(); 14266 FixedArray* optimized_code_map = this->optimized_code_map();
14270 int length = optimized_code_map->length(); 14267 int length = optimized_code_map->length();
14271 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell(); 14268 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell();
14272 for (int i = kEntriesStart; i < length; i += kEntryLength) { 14269 for (int i = kEntriesStart; i < length; i += kEntryLength) {
14273 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell, 14270 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell,
14274 SKIP_WRITE_BARRIER); 14271 SKIP_WRITE_BARRIER);
14275 } 14272 }
14276 } 14273 }
14277 } 14274 }
14278 14275
14279 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( 14276 Code* SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context,
14280 Context* native_context, BailoutId osr_ast_id) { 14277 BailoutId osr_ast_id) {
14281 CodeAndLiterals result = {nullptr, nullptr}; 14278 Code* result = nullptr;
14282 if (!osr_ast_id.IsNone()) { 14279 if (!osr_ast_id.IsNone()) {
14283 Code* code; 14280 return native_context->SearchOptimizedCodeMap(this, osr_ast_id);
14284 LiteralsArray* literals;
14285 native_context->SearchOptimizedCodeMap(this, osr_ast_id, &code, &literals);
14286 result = {code, literals};
14287 return result;
14288 } 14281 }
14289 14282
14290 DCHECK(osr_ast_id.IsNone()); 14283 DCHECK(osr_ast_id.IsNone());
14291 int entry = SearchOptimizedCodeMapEntry(native_context); 14284 int entry = SearchOptimizedCodeMapEntry(native_context);
14292 if (entry != kNotFound) { 14285 if (entry != kNotFound) {
14293 FixedArray* code_map = optimized_code_map(); 14286 FixedArray* code_map = optimized_code_map();
14294 DCHECK_LE(entry + kEntryLength, code_map->length()); 14287 DCHECK_LE(entry + kEntryLength, code_map->length());
14295 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset)); 14288 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset));
14296 WeakCell* literals_cell =
14297 WeakCell::cast(code_map->get(entry + kLiteralsOffset));
14298 14289
14299 result = {cell->cleared() ? nullptr : Code::cast(cell->value()), 14290 result = cell->cleared() ? nullptr : Code::cast(cell->value());
14300 literals_cell->cleared() ? nullptr : LiteralsArray::cast(
14301 literals_cell->value())};
14302 } 14291 }
14303 return result; 14292 return result;
14304 } 14293 }
14305 14294
14306 14295
14307 #define DECLARE_TAG(ignore1, name, ignore2) name, 14296 #define DECLARE_TAG(ignore1, name, ignore2) name,
14308 const char* const VisitorSynchronization::kTags[ 14297 const char* const VisitorSynchronization::kTags[
14309 VisitorSynchronization::kNumberOfSyncTags] = { 14298 VisitorSynchronization::kNumberOfSyncTags] = {
14310 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG) 14299 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG)
14311 }; 14300 };
(...skipping 6179 matching lines...) Expand 10 before | Expand all | Expand 10 after
20491 // depend on this. 20480 // depend on this.
20492 return DICTIONARY_ELEMENTS; 20481 return DICTIONARY_ELEMENTS;
20493 } 20482 }
20494 DCHECK_LE(kind, LAST_ELEMENTS_KIND); 20483 DCHECK_LE(kind, LAST_ELEMENTS_KIND);
20495 return kind; 20484 return kind;
20496 } 20485 }
20497 } 20486 }
20498 20487
20499 } // namespace internal 20488 } // namespace internal
20500 } // namespace v8 20489 } // 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