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 12356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12367 // static | 12367 // static |
12368 void SharedFunctionInfo::AddToOptimizedCodeMap( | 12368 void SharedFunctionInfo::AddToOptimizedCodeMap( |
12369 Handle<SharedFunctionInfo> shared, Handle<Context> native_context, | 12369 Handle<SharedFunctionInfo> shared, Handle<Context> native_context, |
12370 MaybeHandle<Code> code, Handle<LiteralsArray> literals, | 12370 MaybeHandle<Code> code, Handle<LiteralsArray> literals, |
12371 BailoutId osr_ast_id) { | 12371 BailoutId osr_ast_id) { |
12372 Isolate* isolate = shared->GetIsolate(); | 12372 Isolate* isolate = shared->GetIsolate(); |
12373 if (isolate->serializer_enabled()) return; | 12373 if (isolate->serializer_enabled()) return; |
12374 DCHECK(code.is_null() || | 12374 DCHECK(code.is_null() || |
12375 code.ToHandleChecked()->kind() == Code::OPTIMIZED_FUNCTION); | 12375 code.ToHandleChecked()->kind() == Code::OPTIMIZED_FUNCTION); |
12376 DCHECK(native_context->IsNativeContext()); | 12376 DCHECK(native_context->IsNativeContext()); |
12377 STATIC_ASSERT(kEntryLength == 4); | 12377 STATIC_ASSERT(kEntryLength == 3); |
12378 Handle<FixedArray> new_code_map; | 12378 Handle<FixedArray> new_code_map; |
12379 int entry; | 12379 int entry; |
12380 | 12380 |
12381 if (!osr_ast_id.IsNone()) { | |
12382 Context::AddToOptimizedCodeMap( | |
12383 native_context, shared, code.ToHandleChecked(), literals, osr_ast_id); | |
12384 return; | |
12385 } | |
12386 | |
12387 DCHECK(osr_ast_id.IsNone()); | |
12381 if (shared->OptimizedCodeMapIsCleared()) { | 12388 if (shared->OptimizedCodeMapIsCleared()) { |
12382 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); | 12389 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); |
12383 entry = kEntriesStart; | 12390 entry = kEntriesStart; |
12384 } else { | 12391 } else { |
12385 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate); | 12392 Handle<FixedArray> old_code_map(shared->optimized_code_map(), isolate); |
12386 entry = shared->SearchOptimizedCodeMapEntry(*native_context, osr_ast_id); | 12393 entry = shared->SearchOptimizedCodeMapEntry(*native_context); |
12387 if (entry >= kEntriesStart) { | 12394 if (entry >= kEntriesStart) { |
12388 // Just set the code and literals of the entry. | 12395 // Just set the code and literals of the entry. |
12389 if (!code.is_null()) { | 12396 if (!code.is_null()) { |
12390 Handle<WeakCell> code_cell = | 12397 Handle<WeakCell> code_cell = |
12391 isolate->factory()->NewWeakCell(code.ToHandleChecked()); | 12398 isolate->factory()->NewWeakCell(code.ToHandleChecked()); |
12392 old_code_map->set(entry + kCachedCodeOffset, *code_cell); | 12399 old_code_map->set(entry + kCachedCodeOffset, *code_cell); |
12393 } | 12400 } |
12394 Handle<WeakCell> literals_cell = | 12401 Handle<WeakCell> literals_cell = |
12395 isolate->factory()->NewWeakCell(literals); | 12402 isolate->factory()->NewWeakCell(literals); |
12396 old_code_map->set(entry + kLiteralsOffset, *literals_cell); | 12403 old_code_map->set(entry + kLiteralsOffset, *literals_cell); |
(...skipping 26 matching lines...) Expand all Loading... | |
12423 | 12430 |
12424 Handle<WeakCell> code_cell = | 12431 Handle<WeakCell> code_cell = |
12425 code.is_null() ? isolate->factory()->empty_weak_cell() | 12432 code.is_null() ? isolate->factory()->empty_weak_cell() |
12426 : isolate->factory()->NewWeakCell(code.ToHandleChecked()); | 12433 : isolate->factory()->NewWeakCell(code.ToHandleChecked()); |
12427 Handle<WeakCell> literals_cell = isolate->factory()->NewWeakCell(literals); | 12434 Handle<WeakCell> literals_cell = isolate->factory()->NewWeakCell(literals); |
12428 WeakCell* context_cell = native_context->self_weak_cell(); | 12435 WeakCell* context_cell = native_context->self_weak_cell(); |
12429 | 12436 |
12430 new_code_map->set(entry + kContextOffset, context_cell); | 12437 new_code_map->set(entry + kContextOffset, context_cell); |
12431 new_code_map->set(entry + kCachedCodeOffset, *code_cell); | 12438 new_code_map->set(entry + kCachedCodeOffset, *code_cell); |
12432 new_code_map->set(entry + kLiteralsOffset, *literals_cell); | 12439 new_code_map->set(entry + kLiteralsOffset, *literals_cell); |
12433 new_code_map->set(entry + kOsrAstIdOffset, Smi::FromInt(osr_ast_id.ToInt())); | |
12434 | 12440 |
12435 #ifdef DEBUG | 12441 #ifdef DEBUG |
12436 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) { | 12442 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) { |
12437 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset)); | 12443 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kContextOffset)); |
12438 DCHECK(cell->cleared() || cell->value()->IsNativeContext()); | 12444 DCHECK(cell->cleared() || cell->value()->IsNativeContext()); |
12439 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset)); | 12445 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset)); |
12440 DCHECK(cell->cleared() || | 12446 DCHECK(cell->cleared() || |
12441 (cell->value()->IsCode() && | 12447 (cell->value()->IsCode() && |
12442 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION)); | 12448 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION)); |
12443 cell = WeakCell::cast(new_code_map->get(i + kLiteralsOffset)); | 12449 cell = WeakCell::cast(new_code_map->get(i + kLiteralsOffset)); |
12444 DCHECK(cell->cleared() || cell->value()->IsFixedArray()); | 12450 DCHECK(cell->cleared() || cell->value()->IsFixedArray()); |
12445 DCHECK(new_code_map->get(i + kOsrAstIdOffset)->IsSmi()); | |
12446 } | 12451 } |
12447 #endif | 12452 #endif |
12448 | 12453 |
12449 FixedArray* old_code_map = shared->optimized_code_map(); | 12454 FixedArray* old_code_map = shared->optimized_code_map(); |
12450 if (old_code_map != *new_code_map) { | 12455 if (old_code_map != *new_code_map) { |
12451 shared->set_optimized_code_map(*new_code_map); | 12456 shared->set_optimized_code_map(*new_code_map); |
12452 } | 12457 } |
12453 } | 12458 } |
12454 | 12459 |
12455 | 12460 |
12456 void SharedFunctionInfo::ClearOptimizedCodeMap() { | 12461 void SharedFunctionInfo::ClearOptimizedCodeMap() { |
12457 FixedArray* empty_fixed_array = GetHeap()->empty_fixed_array(); | 12462 FixedArray* empty_fixed_array = GetHeap()->empty_fixed_array(); |
12458 set_optimized_code_map(empty_fixed_array, SKIP_WRITE_BARRIER); | 12463 set_optimized_code_map(empty_fixed_array, SKIP_WRITE_BARRIER); |
12459 } | 12464 } |
12460 | 12465 |
12461 | 12466 |
12462 void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code, | 12467 void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code, |
12463 const char* reason) { | 12468 const char* reason) { |
12464 DisallowHeapAllocation no_gc; | 12469 DisallowHeapAllocation no_gc; |
12465 if (OptimizedCodeMapIsCleared()) return; | 12470 if (OptimizedCodeMapIsCleared()) return; |
12466 | 12471 |
12467 Heap* heap = GetHeap(); | 12472 Isolate* isolate = GetIsolate(); |
12473 Heap* heap = isolate->heap(); | |
12468 FixedArray* code_map = optimized_code_map(); | 12474 FixedArray* code_map = optimized_code_map(); |
12469 int dst = kEntriesStart; | |
12470 int length = code_map->length(); | 12475 int length = code_map->length(); |
12476 bool found = false; | |
12471 for (int src = kEntriesStart; src < length; src += kEntryLength) { | 12477 for (int src = kEntriesStart; src < length; src += kEntryLength) { |
12472 DCHECK(WeakCell::cast(code_map->get(src))->cleared() || | 12478 DCHECK(WeakCell::cast(code_map->get(src))->cleared() || |
12473 WeakCell::cast(code_map->get(src))->value()->IsNativeContext()); | 12479 WeakCell::cast(code_map->get(src))->value()->IsNativeContext()); |
12474 if (WeakCell::cast(code_map->get(src + kCachedCodeOffset))->value() == | 12480 found = WeakCell::cast(code_map->get(src + kCachedCodeOffset))->value() == |
ulan
2016/12/07 14:54:57
I think we need two flags here: found and match.
| |
12475 optimized_code) { | 12481 optimized_code; |
12476 BailoutId osr(Smi::cast(code_map->get(src + kOsrAstIdOffset))->value()); | 12482 if (found) { |
12477 if (FLAG_trace_opt) { | 12483 if (FLAG_trace_opt) { |
12478 PrintF("[evicting entry from optimizing code map (%s) for ", reason); | 12484 PrintF("[evicting entry from optimizing code map (%s) for ", reason); |
12479 ShortPrint(); | 12485 ShortPrint(); |
12480 if (osr.IsNone()) { | 12486 PrintF("]\n"); |
12481 PrintF("]\n"); | |
12482 } else { | |
12483 PrintF(" (osr ast id %d)]\n", osr.ToInt()); | |
12484 } | |
12485 } | 12487 } |
12486 if (!osr.IsNone()) { | 12488 // Just clear the code in order to continue sharing literals. |
12487 // Evict the src entry by not copying it to the dst entry. | |
12488 continue; | |
12489 } | |
12490 // In case of non-OSR entry just clear the code in order to proceed | |
12491 // sharing literals. | |
12492 code_map->set(src + kCachedCodeOffset, heap->empty_weak_cell(), | 12489 code_map->set(src + kCachedCodeOffset, heap->empty_weak_cell(), |
12493 SKIP_WRITE_BARRIER); | 12490 SKIP_WRITE_BARRIER); |
12494 } | 12491 } |
12492 } | |
12495 | 12493 |
12496 // Keep the src entry by copying it to the dst entry. | 12494 if (!found) { |
12497 if (dst != src) { | 12495 // We didn't find the code in here. It must be osr'd code. |
12498 code_map->set(dst + kContextOffset, code_map->get(src + kContextOffset)); | 12496 isolate->EvictOSROptimizedCode(optimized_code, reason); |
12499 code_map->set(dst + kCachedCodeOffset, | |
12500 code_map->get(src + kCachedCodeOffset)); | |
12501 code_map->set(dst + kLiteralsOffset, | |
12502 code_map->get(src + kLiteralsOffset)); | |
12503 code_map->set(dst + kOsrAstIdOffset, | |
12504 code_map->get(src + kOsrAstIdOffset)); | |
12505 } | |
12506 dst += kEntryLength; | |
12507 } | |
12508 if (dst != length) { | |
12509 // Always trim even when array is cleared because of heap verifier. | |
12510 heap->RightTrimFixedArray(code_map, length - dst); | |
12511 if (code_map->length() == kEntriesStart) { | |
12512 ClearOptimizedCodeMap(); | |
12513 } | |
12514 } | 12497 } |
12515 } | 12498 } |
12516 | 12499 |
12517 | 12500 |
12518 void SharedFunctionInfo::TrimOptimizedCodeMap(int shrink_by) { | 12501 void SharedFunctionInfo::TrimOptimizedCodeMap(int shrink_by) { |
12519 FixedArray* code_map = optimized_code_map(); | 12502 FixedArray* code_map = optimized_code_map(); |
12520 DCHECK(shrink_by % kEntryLength == 0); | 12503 DCHECK(shrink_by % kEntryLength == 0); |
12521 DCHECK(shrink_by <= code_map->length() - kEntriesStart); | 12504 DCHECK(shrink_by <= code_map->length() - kEntriesStart); |
12522 // Always trim even when array is cleared because of heap verifier. | 12505 // Always trim even when array is cleared because of heap verifier. |
12523 GetHeap()->RightTrimFixedArray(code_map, shrink_by); | 12506 GetHeap()->RightTrimFixedArray(code_map, shrink_by); |
(...skipping 1528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14052 set_profiler_ticks(0); | 14035 set_profiler_ticks(0); |
14053 if (optimization_disabled() && opt_count() >= FLAG_max_opt_count) { | 14036 if (optimization_disabled() && opt_count() >= FLAG_max_opt_count) { |
14054 // Re-enable optimizations if they were disabled due to opt_count limit. | 14037 // Re-enable optimizations if they were disabled due to opt_count limit. |
14055 set_optimization_disabled(false); | 14038 set_optimization_disabled(false); |
14056 } | 14039 } |
14057 set_opt_count(0); | 14040 set_opt_count(0); |
14058 set_deopt_count(0); | 14041 set_deopt_count(0); |
14059 } | 14042 } |
14060 } | 14043 } |
14061 | 14044 |
14062 | 14045 int SharedFunctionInfo::SearchOptimizedCodeMapEntry(Context* native_context) { |
14063 int SharedFunctionInfo::SearchOptimizedCodeMapEntry(Context* native_context, | |
14064 BailoutId osr_ast_id) { | |
14065 DisallowHeapAllocation no_gc; | 14046 DisallowHeapAllocation no_gc; |
14066 DCHECK(native_context->IsNativeContext()); | 14047 DCHECK(native_context->IsNativeContext()); |
14067 if (!OptimizedCodeMapIsCleared()) { | 14048 if (!OptimizedCodeMapIsCleared()) { |
14068 FixedArray* optimized_code_map = this->optimized_code_map(); | 14049 FixedArray* optimized_code_map = this->optimized_code_map(); |
14069 int length = optimized_code_map->length(); | 14050 int length = optimized_code_map->length(); |
14070 Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt()); | |
14071 for (int i = kEntriesStart; i < length; i += kEntryLength) { | 14051 for (int i = kEntriesStart; i < length; i += kEntryLength) { |
14072 if (WeakCell::cast(optimized_code_map->get(i + kContextOffset)) | 14052 if (WeakCell::cast(optimized_code_map->get(i + kContextOffset)) |
14073 ->value() == native_context && | 14053 ->value() == native_context) { |
14074 optimized_code_map->get(i + kOsrAstIdOffset) == osr_ast_id_smi) { | |
14075 return i; | 14054 return i; |
14076 } | 14055 } |
14077 } | 14056 } |
14078 } | 14057 } |
14079 return -1; | 14058 return -1; |
14080 } | 14059 } |
14081 | 14060 |
14082 void SharedFunctionInfo::ClearCodeFromOptimizedCodeMap() { | 14061 void SharedFunctionInfo::ClearCodeFromOptimizedCodeMap() { |
14083 if (!OptimizedCodeMapIsCleared()) { | 14062 if (!OptimizedCodeMapIsCleared()) { |
14084 FixedArray* optimized_code_map = this->optimized_code_map(); | 14063 FixedArray* optimized_code_map = this->optimized_code_map(); |
14085 int length = optimized_code_map->length(); | 14064 int length = optimized_code_map->length(); |
14086 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell(); | 14065 WeakCell* empty_weak_cell = GetHeap()->empty_weak_cell(); |
14087 for (int i = kEntriesStart; i < length; i += kEntryLength) { | 14066 for (int i = kEntriesStart; i < length; i += kEntryLength) { |
14088 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell, | 14067 optimized_code_map->set(i + kCachedCodeOffset, empty_weak_cell, |
14089 SKIP_WRITE_BARRIER); | 14068 SKIP_WRITE_BARRIER); |
14090 } | 14069 } |
14091 } | 14070 } |
14092 } | 14071 } |
14093 | 14072 |
14094 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( | 14073 CodeAndLiterals SharedFunctionInfo::SearchOptimizedCodeMap( |
14095 Context* native_context, BailoutId osr_ast_id) { | 14074 Context* native_context, BailoutId osr_ast_id) { |
14096 CodeAndLiterals result = {nullptr, nullptr}; | 14075 CodeAndLiterals result = {nullptr, nullptr}; |
14097 int entry = SearchOptimizedCodeMapEntry(native_context, osr_ast_id); | 14076 if (!osr_ast_id.IsNone()) { |
14077 Code* code; | |
14078 LiteralsArray* literals; | |
14079 native_context->SearchOptimizedCodeMap(this, osr_ast_id, &code, &literals); | |
14080 result = {code, literals}; | |
14081 return result; | |
14082 } | |
14083 | |
14084 DCHECK(osr_ast_id.IsNone()); | |
14085 int entry = SearchOptimizedCodeMapEntry(native_context); | |
14098 if (entry != kNotFound) { | 14086 if (entry != kNotFound) { |
14099 FixedArray* code_map = optimized_code_map(); | 14087 FixedArray* code_map = optimized_code_map(); |
14100 DCHECK_LE(entry + kEntryLength, code_map->length()); | 14088 DCHECK_LE(entry + kEntryLength, code_map->length()); |
14101 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset)); | 14089 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset)); |
14102 WeakCell* literals_cell = | 14090 WeakCell* literals_cell = |
14103 WeakCell::cast(code_map->get(entry + kLiteralsOffset)); | 14091 WeakCell::cast(code_map->get(entry + kLiteralsOffset)); |
14104 | 14092 |
14105 result = {cell->cleared() ? nullptr : Code::cast(cell->value()), | 14093 result = {cell->cleared() ? nullptr : Code::cast(cell->value()), |
14106 literals_cell->cleared() ? nullptr : LiteralsArray::cast( | 14094 literals_cell->cleared() ? nullptr : LiteralsArray::cast( |
14107 literals_cell->value())}; | 14095 literals_cell->value())}; |
(...skipping 6298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
20406 // depend on this. | 20394 // depend on this. |
20407 return DICTIONARY_ELEMENTS; | 20395 return DICTIONARY_ELEMENTS; |
20408 } | 20396 } |
20409 DCHECK_LE(kind, LAST_ELEMENTS_KIND); | 20397 DCHECK_LE(kind, LAST_ELEMENTS_KIND); |
20410 return kind; | 20398 return kind; |
20411 } | 20399 } |
20412 } | 20400 } |
20413 | 20401 |
20414 } // namespace internal | 20402 } // namespace internal |
20415 } // namespace v8 | 20403 } // namespace v8 |
OLD | NEW |