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

Side by Side Diff: src/objects.cc

Issue 2549753002: Store OSR'd optimized code on the native context. (Closed)
Patch Set: Improvements. 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 12356 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698