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

Side by Side Diff: src/objects.cc

Issue 2504153002: [TypeFeedbackVector] Root literal arrays in function literals slots (Closed)
Patch Set: REBASE. Created 4 years 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 12352 matching lines...) Expand 10 before | Expand all | Expand 10 after
12363 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent)); 12363 isolate->builtins()->builtin(Builtins::kCompileOptimizedConcurrent));
12364 // No write barrier required, since the builtin is part of the root set. 12364 // No write barrier required, since the builtin is part of the root set.
12365 if (FLAG_mark_shared_functions_for_tier_up) { 12365 if (FLAG_mark_shared_functions_for_tier_up) {
12366 // TODO(leszeks): The compilation isn't concurrent if we trigger it using 12366 // TODO(leszeks): The compilation isn't concurrent if we trigger it using
12367 // this bit. 12367 // this bit.
12368 shared()->set_marked_for_tier_up(true); 12368 shared()->set_marked_for_tier_up(true);
12369 } 12369 }
12370 } 12370 }
12371 12371
12372 // static 12372 // static
12373 Handle<LiteralsArray> SharedFunctionInfo::FindOrCreateLiterals(
12374 Handle<SharedFunctionInfo> shared, Handle<Context> native_context) {
12375 Isolate* isolate = shared->GetIsolate();
12376 CodeAndLiterals result =
12377 shared->SearchOptimizedCodeMap(*native_context, BailoutId::None());
12378 if (result.literals != nullptr) {
12379 DCHECK(shared->feedback_metadata()->is_empty() ||
12380 !result.literals->feedback_vector()->is_empty());
12381 return handle(result.literals, isolate);
12382 }
12383
12384 Handle<TypeFeedbackVector> feedback_vector =
12385 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata()));
12386 Handle<LiteralsArray> literals =
12387 LiteralsArray::New(isolate, feedback_vector, shared->num_literals());
12388 Handle<Code> code;
12389 if (result.code != nullptr) {
12390 code = Handle<Code>(result.code, isolate);
12391 }
12392 AddToOptimizedCodeMap(shared, native_context, code, literals,
12393 BailoutId::None());
12394 return literals;
12395 }
12396
12397 // static
12398 void SharedFunctionInfo::AddToOptimizedCodeMap( 12373 void SharedFunctionInfo::AddToOptimizedCodeMap(
12399 Handle<SharedFunctionInfo> shared, Handle<Context> native_context, 12374 Handle<SharedFunctionInfo> shared, Handle<Context> native_context,
12400 MaybeHandle<Code> code, Handle<LiteralsArray> literals, 12375 MaybeHandle<Code> code, BailoutId osr_ast_id) {
12401 BailoutId osr_ast_id) {
12402 Isolate* isolate = shared->GetIsolate(); 12376 Isolate* isolate = shared->GetIsolate();
12403 if (isolate->serializer_enabled()) return; 12377 if (isolate->serializer_enabled()) return;
12404 DCHECK(code.is_null() || 12378 DCHECK(code.is_null() ||
12405 code.ToHandleChecked()->kind() == Code::OPTIMIZED_FUNCTION); 12379 code.ToHandleChecked()->kind() == Code::OPTIMIZED_FUNCTION);
12406 DCHECK(native_context->IsNativeContext()); 12380 DCHECK(native_context->IsNativeContext());
12407 STATIC_ASSERT(kEntryLength == 3); 12381 STATIC_ASSERT(kEntryLength == 2);
12408 Handle<FixedArray> new_code_map; 12382 Handle<FixedArray> new_code_map;
12409 int entry; 12383 int entry;
12410 12384
12411 if (!osr_ast_id.IsNone()) { 12385 if (!osr_ast_id.IsNone()) {
12412 Context::AddToOptimizedCodeMap( 12386 Context::AddToOptimizedCodeMap(native_context, shared,
12413 native_context, shared, code.ToHandleChecked(), literals, osr_ast_id); 12387 code.ToHandleChecked(), osr_ast_id);
12414 return; 12388 return;
12415 } 12389 }
12416 12390
12417 DCHECK(osr_ast_id.IsNone()); 12391 DCHECK(osr_ast_id.IsNone());
12418 if (shared->OptimizedCodeMapIsCleared()) { 12392 if (shared->OptimizedCodeMapIsCleared()) {
12419 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); 12393 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED);
12420 entry = kEntriesStart; 12394 entry = kEntriesStart;
12421 } else { 12395 } else {
12422 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate); 12396 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate);
12423 entry = shared->SearchOptimizedCodeMapEntry(*native_context); 12397 entry = shared->SearchOptimizedCodeMapEntry(*native_context);
12424 if (entry >= kEntriesStart) { 12398 if (entry >= kEntriesStart) {
12425 // Just set the code and literals of the entry. 12399 // Just set the code of the entry.
12426 if (!code.is_null()) { 12400 if (!code.is_null()) {
12427 Handle<WeakCell> code_cell = 12401 Handle<WeakCell> code_cell =
12428 isolate->factory()->NewWeakCell(code.ToHandleChecked()); 12402 isolate->factory()->NewWeakCell(code.ToHandleChecked());
12429 old_code_map->set(entry + kCachedCodeOffset, *code_cell); 12403 old_code_map->set(entry + kCachedCodeOffset, *code_cell);
12430 } 12404 }
12431 Handle<WeakCell> literals_cell =
12432 isolate->factory()->NewWeakCell(literals);
12433 old_code_map->set(entry + kLiteralsOffset, *literals_cell);
12434 return; 12405 return;
12435 } 12406 }
12436 12407
12437 // Can we reuse an entry? 12408 // Can we reuse an entry?
12438 DCHECK(entry < kEntriesStart); 12409 DCHECK(entry < kEntriesStart);
12439 int length = old_code_map->length(); 12410 int length = old_code_map->length();
12440 for (int i = kEntriesStart; i < length; i += kEntryLength) { 12411 for (int i = kEntriesStart; i < length; i += kEntryLength) {
12441 if (WeakCell::cast(old_code_map->get(i + kContextOffset))->cleared()) { 12412 if (WeakCell::cast(old_code_map->get(i + kContextOffset))->cleared()) {
12442 new_code_map = old_code_map; 12413 new_code_map = old_code_map;
12443 entry = i; 12414 entry = i;
(...skipping 10 matching lines...) Expand all
12454 // holes. For now we just give up on adding the entry and pretend it got 12425 // holes. For now we just give up on adding the entry and pretend it got
12455 // flushed. 12426 // flushed.
12456 if (shared->OptimizedCodeMapIsCleared()) return; 12427 if (shared->OptimizedCodeMapIsCleared()) return;
12457 entry = old_code_map->length(); 12428 entry = old_code_map->length();
12458 } 12429 }
12459 } 12430 }
12460 12431
12461 Handle<WeakCell> code_cell = 12432 Handle<WeakCell> code_cell =
12462 code.is_null() ? isolate->factory()->empty_weak_cell() 12433 code.is_null() ? isolate->factory()->empty_weak_cell()
12463 : isolate->factory()->NewWeakCell(code.ToHandleChecked()); 12434 : isolate->factory()->NewWeakCell(code.ToHandleChecked());
12464 Handle<WeakCell> literals_cell = isolate->factory()->NewWeakCell(literals);
12465 WeakCell* context_cell = native_context->self_weak_cell(); 12435 WeakCell* context_cell = native_context->self_weak_cell();
12466 12436
12467 new_code_map->set(entry + kContextOffset, context_cell); 12437 new_code_map->set(entry + kContextOffset, context_cell);
12468 new_code_map->set(entry + kCachedCodeOffset, *code_cell); 12438 new_code_map->set(entry + kCachedCodeOffset, *code_cell);
12469 new_code_map->set(entry + kLiteralsOffset, *literals_cell);
12470 12439
12471 #ifdef DEBUG 12440 #ifdef DEBUG
12472 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) { 12441 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) {
12473 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset)); 12442 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset));
12474 DCHECK(cell->cleared() || cell->value()->IsNativeContext()); 12443 DCHECK(cell->cleared() || cell->value()->IsNativeContext());
12475 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset)); 12444 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset));
12476 DCHECK(cell->cleared() || 12445 DCHECK(cell->cleared() ||
12477 (cell->value()->IsCode() && 12446 (cell->value()->IsCode() &&
12478 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION)); 12447 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION));
12479 cell = WeakCell::cast(new_code_map->get(i + kLiteralsOffset));
12480 DCHECK(cell->cleared() || cell->value()->IsFixedArray());
12481 } 12448 }
12482 #endif 12449 #endif
12483 12450
12484 FixedArray* old_code_map = shared->optimized_code_map(); 12451 FixedArray* old_code_map = shared->optimized_code_map();
12485 if (old_code_map != *new_code_map) { 12452 if (old_code_map != *new_code_map) {
12486 shared->set_optimized_code_map(*new_code_map); 12453 shared->set_optimized_code_map(*new_code_map);
12487 } 12454 }
12488 } 12455 }
12489 12456
12490 12457
(...skipping 17 matching lines...) Expand all
12508 DCHECK(WeakCell::cast(code_map->get(src))->cleared() || 12475 DCHECK(WeakCell::cast(code_map->get(src))->cleared() ||
12509 WeakCell::cast(code_map->get(src))->value()->IsNativeContext()); 12476 WeakCell::cast(code_map->get(src))->value()->IsNativeContext());
12510 found = WeakCell::cast(code_map->get(src + kCachedCodeOffset))->value() == 12477 found = WeakCell::cast(code_map->get(src + kCachedCodeOffset))->value() ==
12511 optimized_code; 12478 optimized_code;
12512 if (found) { 12479 if (found) {
12513 if (FLAG_trace_opt) { 12480 if (FLAG_trace_opt) {
12514 PrintF("[evicting entry from optimizing code map (%s) for ", reason); 12481 PrintF("[evicting entry from optimizing code map (%s) for ", reason);
12515 ShortPrint(); 12482 ShortPrint();
12516 PrintF("]\n"); 12483 PrintF("]\n");
12517 } 12484 }
12518 // Just clear the code in order to continue sharing literals. 12485 // Just clear the code.
12519 code_map->set(src + kCachedCodeOffset, heap->empty_weak_cell(), 12486 code_map->set(src + kCachedCodeOffset, heap->empty_weak_cell(),
12520 SKIP_WRITE_BARRIER); 12487 SKIP_WRITE_BARRIER);
12521 } 12488 }
12522 } 12489 }
12523 } 12490 }
12524 12491
12525 if (!found) { 12492 if (!found) {
12526 // We didn't find the code in here. It must be osr'd code. 12493 // We didn't find the code in here. It must be osr'd code.
12527 isolate->EvictOSROptimizedCode(optimized_code, reason); 12494 isolate->EvictOSROptimizedCode(optimized_code, reason);
12528 } 12495 }
12529 } 12496 }
12530 12497
12531 // static 12498 // static
12532 void JSFunction::EnsureLiterals(Handle<JSFunction> function) { 12499 void JSFunction::EnsureLiterals(Handle<JSFunction> function) {
12533 Handle<SharedFunctionInfo> shared(function->shared()); 12500 Handle<SharedFunctionInfo> shared(function->shared());
12534 Handle<Context> native_context(function->context()->native_context()); 12501 Handle<Context> native_context(function->context()->native_context());
12535 if (function->literals() == 12502 Isolate* isolate = shared->GetIsolate();
12536 function->GetIsolate()->heap()->empty_literals_array()) { 12503
12537 Handle<LiteralsArray> literals = 12504 if (function->needs_literals_array()) {
12538 SharedFunctionInfo::FindOrCreateLiterals(shared, native_context); 12505 if (FLAG_trace_strong_rooted_literals) {
12539 function->set_literals(*literals); 12506 PrintF("EnsureLiterals: Installing literals array in %s %p\n",
12507 shared->DebugName()->ToCString().get(),
12508 reinterpret_cast<void*>(*function));
12509 }
12510 // Top level code didn't get it's literals installed.
12511 Handle<TypeFeedbackVector> feedback_vector =
12512 TypeFeedbackVector::New(isolate, handle(shared->feedback_metadata()));
12513 Handle<LiteralsArray> new_literals =
12514 LiteralsArray::New(isolate, feedback_vector, shared->num_literals());
12515 function->set_literals(*new_literals);
12516 } else if (function->literals()->needs_feedback_vector()) {
12517 if (FLAG_trace_strong_rooted_literals) {
12518 PrintF("EnsureLiterals: Installing feedback vector in %s %p\n",
12519 shared->DebugName()->ToCString().get(),
12520 reinterpret_cast<void*>(*function));
12521 }
12522 // If the feedback vector hasn't been installed, do that.
12523 Handle<TypeFeedbackVector> feedback_vector = TypeFeedbackVector::New(
12524 shared->GetIsolate(), handle(shared->feedback_metadata()));
12525 function->literals()->set_feedback_vector(*feedback_vector);
12526 } else {
12527 if (FLAG_trace_strong_rooted_literals) {
12528 PrintF("EnsureLiterals: did nothing for %s %p\n",
12529 shared->DebugName()->ToCString().get(),
12530 reinterpret_cast<void*>(*function));
12531 }
12540 } 12532 }
12533
12534 // No matter what, ensure some post-conditions.
12535 DCHECK(shared->feedback_metadata()->slot_count() != 0 ||
12536 function->feedback_vector() ==
12537 shared->GetIsolate()->heap()->empty_type_feedback_vector());
12538 DCHECK(shared->num_literals() == 0 ||
12539 function->literals() !=
12540 shared->GetIsolate()->heap()->empty_literals_array());
12541 } 12541 }
12542 12542
12543 static void GetMinInobjectSlack(Map* map, void* data) { 12543 static void GetMinInobjectSlack(Map* map, void* data) {
12544 int slack = map->unused_property_fields(); 12544 int slack = map->unused_property_fields();
12545 if (*reinterpret_cast<int*>(data) > slack) { 12545 if (*reinterpret_cast<int*>(data) > slack) {
12546 *reinterpret_cast<int*>(data) = slack; 12546 *reinterpret_cast<int*>(data) = slack;
12547 } 12547 }
12548 } 12548 }
12549 12549
12550 12550
(...skipping 1531 matching lines...) Expand 10 before | Expand all | Expand 10 after
14082 FixedArray* optimized_code_map = this->optimized_code_map(); 14082 FixedArray* optimized_code_map = this->optimized_code_map();
14083 int length = optimized_code_map->length(); 14083 int length = optimized_code_map->length();
14084 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell(); 14084 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell();
14085 for (int i = kEntriesStart; i < length; i += kEntryLength) { 14085 for (int i = kEntriesStart; i < length; i += kEntryLength) {
14086 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell, 14086 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell,
14087 SKIP_WRITE_BARRIER); 14087 SKIP_WRITE_BARRIER);
14088 } 14088 }
14089 } 14089 }
14090 } 14090 }
14091 14091
14092 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( 14092 Code* SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context,
14093 Context* native_context, BailoutId osr_ast_id) { 14093 BailoutId osr_ast_id) {
14094 CodeAndLiterals result = {nullptr, nullptr}; 14094 Code* result = nullptr;
14095 if (!osr_ast_id.IsNone()) { 14095 if (!osr_ast_id.IsNone()) {
14096 Code* code; 14096 return native_context->SearchOptimizedCodeMap(this, osr_ast_id);
14097 LiteralsArray* literals;
14098 native_context->SearchOptimizedCodeMap(this, osr_ast_id, &code, &literals);
14099 result = {code, literals};
14100 return result;
14101 } 14097 }
14102 14098
14103 DCHECK(osr_ast_id.IsNone()); 14099 DCHECK(osr_ast_id.IsNone());
14104 int entry = SearchOptimizedCodeMapEntry(native_context); 14100 int entry = SearchOptimizedCodeMapEntry(native_context);
14105 if (entry != kNotFound) { 14101 if (entry != kNotFound) {
14106 FixedArray* code_map = optimized_code_map(); 14102 FixedArray* code_map = optimized_code_map();
14107 DCHECK_LE(entry + kEntryLength, code_map->length()); 14103 DCHECK_LE(entry + kEntryLength, code_map->length());
14108 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset)); 14104 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset));
14109 WeakCell* literals_cell =
14110 WeakCell::cast(code_map->get(entry + kLiteralsOffset));
14111 14105
14112 result = {cell->cleared() ? nullptr : Code::cast(cell->value()), 14106 result = cell->cleared() ? nullptr : Code::cast(cell->value());
14113 literals_cell->cleared() ? nullptr : LiteralsArray::cast(
14114 literals_cell->value())};
14115 } 14107 }
14116 return result; 14108 return result;
14117 } 14109 }
14118 14110
14119 14111
14120 #define DECLARE_TAG(ignore1, name, ignore2) name, 14112 #define DECLARE_TAG(ignore1, name, ignore2) name,
14121 const char* const VisitorSynchronization::kTags[ 14113 const char* const VisitorSynchronization::kTags[
14122 VisitorSynchronization::kNumberOfSyncTags] = { 14114 VisitorSynchronization::kNumberOfSyncTags] = {
14123 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG) 14115 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG)
14124 }; 14116 };
(...skipping 6288 matching lines...) Expand 10 before | Expand all | Expand 10 after
20413 // depend on this. 20405 // depend on this.
20414 return DICTIONARY_ELEMENTS; 20406 return DICTIONARY_ELEMENTS;
20415 } 20407 }
20416 DCHECK_LE(kind, LAST_ELEMENTS_KIND); 20408 DCHECK_LE(kind, LAST_ELEMENTS_KIND);
20417 return kind; 20409 return kind;
20418 } 20410 }
20419 } 20411 }
20420 20412
20421 } // namespace internal 20413 } // namespace internal
20422 } // namespace v8 20414 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698