| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |