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

Side by Side Diff: src/objects.cc

Issue 2504153002: [TypeFeedbackVector] Root literal arrays in function literals slots (Closed)
Patch Set: REBASE. Created 3 years, 12 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 12366 matching lines...) Expand 10 before | Expand all | Expand 10 after
12377 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent)); 12377 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent));
12378 // No write barrier required, since the builtin is part of the root set. 12378 // No write barrier required, since the builtin is part of the root set.
12379 if (FLAG_mark_shared_functions_for_tier_up) { 12379 if (FLAG_mark_shared_functions_for_tier_up) {
12380 // TODO(leszeks): The compilation isn't concurrent if we trigger it using 12380 // TODO(leszeks): The compilation isn't concurrent if we trigger it using
12381 // this bit. 12381 // this bit.
12382 shared()->set_marked_for_tier_up(true); 12382 shared()->set_marked_for_tier_up(true);
12383 } 12383 }
12384 } 12384 }
12385 12385
12386 // static 12386 // static
12387 Handle<LiteralsArray> SharedFunctionInfo::FindOrCreateLiterals(
12388 Handle<SharedFunctionInfo> shared, Handle<Context> native_context) {
12389 Isolate* isolate = shared->GetIsolate();
12390 CodeAndLiterals result =
12391 shared->SearchOptimizedCodeMap(*native_context, BailoutId::None());
12392 if (result.literals != nullptr) {
12393 DCHECK(shared->feedback_metadata()->is_empty() ||
12394 !result.literals->feedback_vector()->is_empty());
12395 return handle(result.literals, isolate);
12396 }
12397
12398 Handle<TypeFeedbackVector> feedback_vector =
12399 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata()));
12400 Handle<LiteralsArray> literals =
12401 LiteralsArray::New(isolate, feedback_vector, shared->num_literals());
12402 Handle<Code> code;
12403 if (result.code != nullptr) {
12404 code = Handle<Code>(result.code, isolate);
12405 }
12406 AddToOptimizedCodeMap(shared, native_context, code, literals,
12407 BailoutId::None());
12408 return literals;
12409 }
12410
12411 // static
12412 void SharedFunctionInfo::AddToOptimizedCodeMap( 12387 void SharedFunctionInfo::AddToOptimizedCodeMap(
12413 Handle<SharedFunctionInfo> shared, Handle<Context> native_context, 12388 Handle<SharedFunctionInfo> shared, Handle<Context> native_context,
12414 MaybeHandle<Code> code, Handle<LiteralsArray> literals, 12389 MaybeHandle<Code> code, BailoutId osr_ast_id) {
12415 BailoutId osr_ast_id) {
12416 Isolate* isolate = shared->GetIsolate(); 12390 Isolate* isolate = shared->GetIsolate();
12417 if (isolate->serializer_enabled()) return; 12391 if (isolate->serializer_enabled()) return;
12418 DCHECK(code.is_null() || 12392 DCHECK(code.is_null() ||
12419 code.ToHandleChecked()->kind() == Code::OPTIMIZED_FUNCTION); 12393 code.ToHandleChecked()->kind() == Code::OPTIMIZED_FUNCTION);
12420 DCHECK(native_context->IsNativeContext()); 12394 DCHECK(native_context->IsNativeContext());
12421 STATIC_ASSERT(kEntryLength == 3); 12395 STATIC_ASSERT(kEntryLength == 2);
12422 Handle<FixedArray> new_code_map; 12396 Handle<FixedArray> new_code_map;
12423 int entry; 12397 int entry;
12424 12398
12425 if (!osr_ast_id.IsNone()) { 12399 if (!osr_ast_id.IsNone()) {
12426 Context::AddToOptimizedCodeMap( 12400 Context::AddToOptimizedCodeMap(native_context, shared,
12427 native_context, shared, code.ToHandleChecked(), literals, osr_ast_id); 12401 code.ToHandleChecked(), osr_ast_id);
12428 return; 12402 return;
12429 } 12403 }
12430 12404
12431 DCHECK(osr_ast_id.IsNone()); 12405 DCHECK(osr_ast_id.IsNone());
12432 if (shared->OptimizedCodeMapIsCleared()) { 12406 if (shared->OptimizedCodeMapIsCleared()) {
12433 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); 12407 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED);
12434 entry = kEntriesStart; 12408 entry = kEntriesStart;
12435 } else { 12409 } else {
12436 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate); 12410 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate);
12437 entry = shared->SearchOptimizedCodeMapEntry(*native_context); 12411 entry = shared->SearchOptimizedCodeMapEntry(*native_context);
12438 if (entry >= kEntriesStart) { 12412 if (entry >= kEntriesStart) {
12439 // Just set the code and literals of the entry. 12413 // Just set the code of the entry.
12440 if (!code.is_null()) { 12414 if (!code.is_null()) {
12441 Handle<WeakCell> code_cell = 12415 Handle<WeakCell> code_cell =
12442 isolate->factory()->NewWeakCell(code.ToHandleChecked()); 12416 isolate->factory()->NewWeakCell(code.ToHandleChecked());
12443 old_code_map->set(entry + kCachedCodeOffset, *code_cell); 12417 old_code_map->set(entry + kCachedCodeOffset, *code_cell);
12444 } 12418 }
12445 Handle<WeakCell> literals_cell =
12446 isolate->factory()->NewWeakCell(literals);
12447 old_code_map->set(entry + kLiteralsOffset, *literals_cell);
12448 return; 12419 return;
12449 } 12420 }
12450 12421
12451 // Can we reuse an entry? 12422 // Can we reuse an entry?
12452 DCHECK(entry < kEntriesStart); 12423 DCHECK(entry < kEntriesStart);
12453 int length = old_code_map->length(); 12424 int length = old_code_map->length();
12454 for (int i = kEntriesStart; i < length; i += kEntryLength) { 12425 for (int i = kEntriesStart; i < length; i += kEntryLength) {
12455 if (WeakCell::cast(old_code_map->get(i + kContextOffset))->cleared()) { 12426 if (WeakCell::cast(old_code_map->get(i + kContextOffset))->cleared()) {
12456 new_code_map = old_code_map; 12427 new_code_map = old_code_map;
12457 entry = i; 12428 entry = i;
(...skipping 10 matching lines...) Expand all
12468 // holes. For now we just give up on adding the entry and pretend it got 12439 // holes. For now we just give up on adding the entry and pretend it got
12469 // flushed. 12440 // flushed.
12470 if (shared->OptimizedCodeMapIsCleared()) return; 12441 if (shared->OptimizedCodeMapIsCleared()) return;
12471 entry = old_code_map->length(); 12442 entry = old_code_map->length();
12472 } 12443 }
12473 } 12444 }
12474 12445
12475 Handle<WeakCell> code_cell = 12446 Handle<WeakCell> code_cell =
12476 code.is_null() ? isolate->factory()->empty_weak_cell() 12447 code.is_null() ? isolate->factory()->empty_weak_cell()
12477 : isolate->factory()->NewWeakCell(code.ToHandleChecked()); 12448 : isolate->factory()->NewWeakCell(code.ToHandleChecked());
12478 Handle<WeakCell> literals_cell = isolate->factory()->NewWeakCell(literals);
12479 WeakCell* context_cell = native_context->self_weak_cell(); 12449 WeakCell* context_cell = native_context->self_weak_cell();
12480 12450
12481 new_code_map->set(entry + kContextOffset, context_cell); 12451 new_code_map->set(entry + kContextOffset, context_cell);
12482 new_code_map->set(entry + kCachedCodeOffset, *code_cell); 12452 new_code_map->set(entry + kCachedCodeOffset, *code_cell);
12483 new_code_map->set(entry + kLiteralsOffset, *literals_cell);
12484 12453
12485 #ifdef DEBUG 12454 #ifdef DEBUG
12486 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) { 12455 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) {
12487 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset)); 12456 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset));
12488 DCHECK(cell->cleared() || cell->value()->IsNativeContext()); 12457 DCHECK(cell->cleared() || cell->value()->IsNativeContext());
12489 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset)); 12458 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset));
12490 DCHECK(cell->cleared() || 12459 DCHECK(cell->cleared() ||
12491 (cell->value()->IsCode() && 12460 (cell->value()->IsCode() &&
12492 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION)); 12461 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION));
12493 cell = WeakCell::cast(new_code_map->get(i + kLiteralsOffset));
12494 DCHECK(cell->cleared() || cell->value()->IsFixedArray());
12495 } 12462 }
12496 #endif 12463 #endif
12497 12464
12498 FixedArray* old_code_map = shared->optimized_code_map(); 12465 FixedArray* old_code_map = shared->optimized_code_map();
12499 if (old_code_map != *new_code_map) { 12466 if (old_code_map != *new_code_map) {
12500 shared->set_optimized_code_map(*new_code_map); 12467 shared->set_optimized_code_map(*new_code_map);
12501 } 12468 }
12502 } 12469 }
12503 12470
12504 12471
(...skipping 17 matching lines...) Expand all
12522 DCHECK(WeakCell::cast(code_map->get(src))->cleared() || 12489 DCHECK(WeakCell::cast(code_map->get(src))->cleared() ||
12523 WeakCell::cast(code_map->get(src))->value()->IsNativeContext()); 12490 WeakCell::cast(code_map->get(src))->value()->IsNativeContext());
12524 found = WeakCell::cast(code_map->get(src + kCachedCodeOffset))->value() == 12491 found = WeakCell::cast(code_map->get(src + kCachedCodeOffset))->value() ==
12525 optimized_code; 12492 optimized_code;
12526 if (found) { 12493 if (found) {
12527 if (FLAG_trace_opt) { 12494 if (FLAG_trace_opt) {
12528 PrintF("[evicting entry from optimizing code map (%s) for ", reason); 12495 PrintF("[evicting entry from optimizing code map (%s) for ", reason);
12529 ShortPrint(); 12496 ShortPrint();
12530 PrintF("]\n"); 12497 PrintF("]\n");
12531 } 12498 }
12532 // Just clear the code in order to continue sharing literals. 12499 // Just clear the code.
12533 code_map->set(src + kCachedCodeOffset, heap->empty_weak_cell(), 12500 code_map->set(src + kCachedCodeOffset, heap->empty_weak_cell(),
12534 SKIP_WRITE_BARRIER); 12501 SKIP_WRITE_BARRIER);
12535 } 12502 }
12536 } 12503 }
12537 } 12504 }
12538 12505
12539 if (!found) { 12506 if (!found) {
12540 // We didn't find the code in here. It must be osr'd code. 12507 // We didn't find the code in here. It must be osr'd code.
12541 isolate->EvictOSROptimizedCode(optimized_code, reason); 12508 isolate->EvictOSROptimizedCode(optimized_code, reason);
12542 } 12509 }
12543 } 12510 }
12544 12511
12545 // static 12512 // static
12546 void JSFunction::EnsureLiterals(Handle<JSFunction> function) { 12513 void JSFunction::EnsureLiterals(Handle<JSFunction> function) {
12547 Handle<SharedFunctionInfo> shared(function->shared()); 12514 Handle<SharedFunctionInfo> shared(function->shared());
12548 Handle<Context> native_context(function->context()->native_context()); 12515 Handle<Context> native_context(function->context()->native_context());
12549 if (function->literals() == 12516 Isolate* isolate = shared->GetIsolate();
12550 function->GetIsolate()->heap()->empty_literals_array()) { 12517
12551 Handle<LiteralsArray> literals = 12518 if (function->needs_literals_array()) {
12552 SharedFunctionInfo::FindOrCreateLiterals(shared, native_context); 12519 if (FLAG_trace_strong_rooted_literals) {
12553 function->set_literals(*literals); 12520 PrintF("EnsureLiterals: Installing literals array in %s %p\n",
12521 shared->DebugName()->ToCString().get(),
12522 reinterpret_cast<void*>(*function));
12523 }
12524 // Top level code didn't get it's literals installed.
12525 Handle<TypeFeedbackVector> feedback_vector =
12526 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata()));
12527 Handle<LiteralsArray> new_literals =
12528 LiteralsArray::New(isolate, feedback_vector, shared->num_literals());
12529 function->set_literals(*new_literals);
12530 } else if (function->literals()->needs_feedback_vector()) {
12531 if (FLAG_trace_strong_rooted_literals) {
12532 PrintF("EnsureLiterals: Installing feedback vector in %s %p\n",
12533 shared->DebugName()->ToCString().get(),
12534 reinterpret_cast<void*>(*function));
12535 }
12536 // If the feedback vector hasn't been installed, do that.
12537 Handle<TypeFeedbackVector> feedback_vector = TypeFeedbackVector::New(
12538 shared->GetIsolate(), handle(shared->feedback_metadata()));
12539 function->literals()->set_feedback_vector(*feedback_vector);
12540 } else {
12541 if (FLAG_trace_strong_rooted_literals) {
12542 PrintF("EnsureLiterals: did nothing for %s %p\n",
12543 shared->DebugName()->ToCString().get(),
12544 reinterpret_cast<void*>(*function));
12545 }
12554 } 12546 }
12547
12548 // No matter what, ensure some post-conditions.
12549 DCHECK(shared->feedback_metadata()->slot_count() != 0 ||
12550 function->feedback_vector() ==
12551 shared->GetIsolate()->heap()->empty_type_feedback_vector());
12552 DCHECK(shared->num_literals() == 0 ||
12553 function->literals() !=
12554 shared->GetIsolate()->heap()->empty_literals_array());
12555 } 12555 }
12556 12556
12557 static void GetMinInobjectSlack(Map* map, void* data) { 12557 static void GetMinInobjectSlack(Map* map, void* data) {
12558 int slack = map->unused_property_fields(); 12558 int slack = map->unused_property_fields();
12559 if (*reinterpret_cast<int*>(data) > slack) { 12559 if (*reinterpret_cast<int*>(data) > slack) {
12560 *reinterpret_cast<int*>(data) = slack; 12560 *reinterpret_cast<int*>(data) = slack;
12561 } 12561 }
12562 } 12562 }
12563 12563
12564 12564
(...skipping 1549 matching lines...) Expand 10 before | Expand all | Expand 10 after
14114 FixedArray* optimized_code_map = this->optimized_code_map(); 14114 FixedArray* optimized_code_map = this->optimized_code_map();
14115 int length = optimized_code_map->length(); 14115 int length = optimized_code_map->length();
14116 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell(); 14116 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell();
14117 for (int i = kEntriesStart; i < length; i += kEntryLength) { 14117 for (int i = kEntriesStart; i < length; i += kEntryLength) {
14118 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell, 14118 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell,
14119 SKIP_WRITE_BARRIER); 14119 SKIP_WRITE_BARRIER);
14120 } 14120 }
14121 } 14121 }
14122 } 14122 }
14123 14123
14124 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( 14124 Code* SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context,
14125 Context* native_context, BailoutId osr_ast_id) { 14125 BailoutId osr_ast_id) {
14126 CodeAndLiterals result = {nullptr, nullptr}; 14126 Code* result = nullptr;
14127 if (!osr_ast_id.IsNone()) { 14127 if (!osr_ast_id.IsNone()) {
14128 Code* code; 14128 return native_context->SearchOptimizedCodeMap(this, osr_ast_id);
14129 LiteralsArray* literals;
14130 native_context->SearchOptimizedCodeMap(this, osr_ast_id, &code, &literals);
14131 result = {code, literals};
14132 return result;
14133 } 14129 }
14134 14130
14135 DCHECK(osr_ast_id.IsNone()); 14131 DCHECK(osr_ast_id.IsNone());
14136 int entry = SearchOptimizedCodeMapEntry(native_context); 14132 int entry = SearchOptimizedCodeMapEntry(native_context);
14137 if (entry != kNotFound) { 14133 if (entry != kNotFound) {
14138 FixedArray* code_map = optimized_code_map(); 14134 FixedArray* code_map = optimized_code_map();
14139 DCHECK_LE(entry + kEntryLength, code_map->length()); 14135 DCHECK_LE(entry + kEntryLength, code_map->length());
14140 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset)); 14136 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset));
14141 WeakCell* literals_cell =
14142 WeakCell::cast(code_map->get(entry + kLiteralsOffset));
14143 14137
14144 result = {cell->cleared() ? nullptr : Code::cast(cell->value()), 14138 result = cell->cleared() ? nullptr : Code::cast(cell->value());
14145 literals_cell->cleared() ? nullptr : LiteralsArray::cast(
14146 literals_cell->value())};
14147 } 14139 }
14148 return result; 14140 return result;
14149 } 14141 }
14150 14142
14151 14143
14152 #define DECLARE_TAG(ignore1, name, ignore2) name, 14144 #define DECLARE_TAG(ignore1, name, ignore2) name,
14153 const char* const VisitorSynchronization::kTags[ 14145 const char* const VisitorSynchronization::kTags[
14154 VisitorSynchronization::kNumberOfSyncTags] = { 14146 VisitorSynchronization::kNumberOfSyncTags] = {
14155 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG) 14147 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG)
14156 }; 14148 };
(...skipping 6288 matching lines...) Expand 10 before | Expand all | Expand 10 after
20445 // depend on this. 20437 // depend on this.
20446 return DICTIONARY_ELEMENTS; 20438 return DICTIONARY_ELEMENTS;
20447 } 20439 }
20448 DCHECK_LE(kind, LAST_ELEMENTS_KIND); 20440 DCHECK_LE(kind, LAST_ELEMENTS_KIND);
20449 return kind; 20441 return kind;
20450 } 20442 }
20451 } 20443 }
20452 20444
20453 } // namespace internal 20445 } // namespace internal
20454 } // namespace v8 20446 } // 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