OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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/contexts.h" | 5 #include "src/contexts.h" |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
9 #include "src/isolate-inl.h" | 9 #include "src/isolate-inl.h" |
10 | 10 |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 } while (follow_context_chain); | 403 } while (follow_context_chain); |
404 | 404 |
405 if (FLAG_trace_contexts) { | 405 if (FLAG_trace_contexts) { |
406 PrintF("=> no property/slot found\n"); | 406 PrintF("=> no property/slot found\n"); |
407 } | 407 } |
408 return Handle<Object>::null(); | 408 return Handle<Object>::null(); |
409 } | 409 } |
410 | 410 |
411 static const int kSharedOffset = 0; | 411 static const int kSharedOffset = 0; |
412 static const int kCachedCodeOffset = 1; | 412 static const int kCachedCodeOffset = 1; |
413 static const int kLiteralsOffset = 2; | 413 static const int kOsrAstIdOffset = 2; |
414 static const int kOsrAstIdOffset = 3; | 414 static const int kEntryLength = 3; |
415 static const int kEntryLength = 4; | |
416 static const int kInitialLength = kEntryLength; | 415 static const int kInitialLength = kEntryLength; |
417 | 416 |
418 int Context::SearchOptimizedCodeMapEntry(SharedFunctionInfo* shared, | 417 int Context::SearchOptimizedCodeMapEntry(SharedFunctionInfo* shared, |
419 BailoutId osr_ast_id) { | 418 BailoutId osr_ast_id) { |
420 DisallowHeapAllocation no_gc; | 419 DisallowHeapAllocation no_gc; |
421 DCHECK(this->IsNativeContext()); | 420 DCHECK(this->IsNativeContext()); |
422 if (!OptimizedCodeMapIsCleared()) { | 421 if (!OptimizedCodeMapIsCleared()) { |
423 FixedArray* optimized_code_map = this->osr_code_table(); | 422 FixedArray* optimized_code_map = this->osr_code_table(); |
424 int length = optimized_code_map->length(); | 423 int length = optimized_code_map->length(); |
425 Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt()); | 424 Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt()); |
426 for (int i = 0; i < length; i += kEntryLength) { | 425 for (int i = 0; i < length; i += kEntryLength) { |
427 if (WeakCell::cast(optimized_code_map->get(i + kSharedOffset))->value() == | 426 if (WeakCell::cast(optimized_code_map->get(i + kSharedOffset))->value() == |
428 shared && | 427 shared && |
429 optimized_code_map->get(i + kOsrAstIdOffset) == osr_ast_id_smi) { | 428 optimized_code_map->get(i + kOsrAstIdOffset) == osr_ast_id_smi) { |
430 return i; | 429 return i; |
431 } | 430 } |
432 } | 431 } |
433 } | 432 } |
434 return -1; | 433 return -1; |
435 } | 434 } |
436 | 435 |
437 void Context::SearchOptimizedCodeMap(SharedFunctionInfo* shared, | 436 Code* Context::SearchOptimizedCodeMap(SharedFunctionInfo* shared, |
438 BailoutId osr_ast_id, Code** pcode, | 437 BailoutId osr_ast_id) { |
439 LiteralsArray** pliterals) { | |
440 DCHECK(this->IsNativeContext()); | 438 DCHECK(this->IsNativeContext()); |
441 int entry = SearchOptimizedCodeMapEntry(shared, osr_ast_id); | 439 int entry = SearchOptimizedCodeMapEntry(shared, osr_ast_id); |
442 if (entry != -1) { | 440 if (entry != -1) { |
443 FixedArray* code_map = osr_code_table(); | 441 FixedArray* code_map = osr_code_table(); |
444 DCHECK_LE(entry + kEntryLength, code_map->length()); | 442 DCHECK_LE(entry + kEntryLength, code_map->length()); |
445 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset)); | 443 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset)); |
446 WeakCell* literals_cell = | |
447 WeakCell::cast(code_map->get(entry + kLiteralsOffset)); | |
448 | 444 |
449 *pcode = cell->cleared() ? nullptr : Code::cast(cell->value()); | 445 return cell->cleared() ? nullptr : Code::cast(cell->value()); |
450 *pliterals = literals_cell->cleared() | |
451 ? nullptr | |
452 : LiteralsArray::cast(literals_cell->value()); | |
453 } else { | |
454 *pcode = nullptr; | |
455 *pliterals = nullptr; | |
456 } | 446 } |
| 447 return nullptr; |
457 } | 448 } |
458 | 449 |
459 void Context::AddToOptimizedCodeMap(Handle<Context> native_context, | 450 void Context::AddToOptimizedCodeMap(Handle<Context> native_context, |
460 Handle<SharedFunctionInfo> shared, | 451 Handle<SharedFunctionInfo> shared, |
461 Handle<Code> code, | 452 Handle<Code> code, |
462 Handle<LiteralsArray> literals, | |
463 BailoutId osr_ast_id) { | 453 BailoutId osr_ast_id) { |
464 DCHECK(native_context->IsNativeContext()); | 454 DCHECK(native_context->IsNativeContext()); |
465 Isolate* isolate = native_context->GetIsolate(); | 455 Isolate* isolate = native_context->GetIsolate(); |
466 if (isolate->serializer_enabled()) return; | 456 if (isolate->serializer_enabled()) return; |
467 | 457 |
468 STATIC_ASSERT(kEntryLength == 4); | 458 STATIC_ASSERT(kEntryLength == 3); |
469 Handle<FixedArray> new_code_map; | 459 Handle<FixedArray> new_code_map; |
470 int entry; | 460 int entry; |
471 | 461 |
472 if (native_context->OptimizedCodeMapIsCleared()) { | 462 if (native_context->OptimizedCodeMapIsCleared()) { |
473 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); | 463 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); |
474 entry = 0; | 464 entry = 0; |
475 } else { | 465 } else { |
476 Handle<FixedArray> old_code_map(native_context->osr_code_table(), isolate); | 466 Handle<FixedArray> old_code_map(native_context->osr_code_table(), isolate); |
477 entry = native_context->SearchOptimizedCodeMapEntry(*shared, osr_ast_id); | 467 entry = native_context->SearchOptimizedCodeMapEntry(*shared, osr_ast_id); |
478 if (entry >= 0) { | 468 if (entry >= 0) { |
479 // Just set the code and literals of the entry. | 469 // Just set the code of the entry. |
480 Handle<WeakCell> code_cell = isolate->factory()->NewWeakCell(code); | 470 Handle<WeakCell> code_cell = isolate->factory()->NewWeakCell(code); |
481 old_code_map->set(entry + kCachedCodeOffset, *code_cell); | 471 old_code_map->set(entry + kCachedCodeOffset, *code_cell); |
482 Handle<WeakCell> literals_cell = | |
483 isolate->factory()->NewWeakCell(literals); | |
484 old_code_map->set(entry + kLiteralsOffset, *literals_cell); | |
485 return; | 472 return; |
486 } | 473 } |
487 | 474 |
488 // Can we reuse an entry? | 475 // Can we reuse an entry? |
489 DCHECK(entry < 0); | 476 DCHECK(entry < 0); |
490 int length = old_code_map->length(); | 477 int length = old_code_map->length(); |
491 for (int i = 0; i < length; i += kEntryLength) { | 478 for (int i = 0; i < length; i += kEntryLength) { |
492 if (WeakCell::cast(old_code_map->get(i + kSharedOffset))->cleared()) { | 479 if (WeakCell::cast(old_code_map->get(i + kSharedOffset))->cleared()) { |
493 new_code_map = old_code_map; | 480 new_code_map = old_code_map; |
494 entry = i; | 481 entry = i; |
495 break; | 482 break; |
496 } | 483 } |
497 } | 484 } |
498 | 485 |
499 if (entry < 0) { | 486 if (entry < 0) { |
500 // Copy old optimized code map and append one new entry. | 487 // Copy old optimized code map and append one new entry. |
501 new_code_map = isolate->factory()->CopyFixedArrayAndGrow( | 488 new_code_map = isolate->factory()->CopyFixedArrayAndGrow( |
502 old_code_map, kEntryLength, TENURED); | 489 old_code_map, kEntryLength, TENURED); |
503 entry = old_code_map->length(); | 490 entry = old_code_map->length(); |
504 } | 491 } |
505 } | 492 } |
506 | 493 |
507 Handle<WeakCell> code_cell = isolate->factory()->NewWeakCell(code); | 494 Handle<WeakCell> code_cell = isolate->factory()->NewWeakCell(code); |
508 Handle<WeakCell> literals_cell = isolate->factory()->NewWeakCell(literals); | |
509 Handle<WeakCell> shared_cell = isolate->factory()->NewWeakCell(shared); | 495 Handle<WeakCell> shared_cell = isolate->factory()->NewWeakCell(shared); |
510 | 496 |
511 new_code_map->set(entry + kSharedOffset, *shared_cell); | 497 new_code_map->set(entry + kSharedOffset, *shared_cell); |
512 new_code_map->set(entry + kCachedCodeOffset, *code_cell); | 498 new_code_map->set(entry + kCachedCodeOffset, *code_cell); |
513 new_code_map->set(entry + kLiteralsOffset, *literals_cell); | |
514 new_code_map->set(entry + kOsrAstIdOffset, Smi::FromInt(osr_ast_id.ToInt())); | 499 new_code_map->set(entry + kOsrAstIdOffset, Smi::FromInt(osr_ast_id.ToInt())); |
515 | 500 |
516 #ifdef DEBUG | 501 #ifdef DEBUG |
517 for (int i = 0; i < new_code_map->length(); i += kEntryLength) { | 502 for (int i = 0; i < new_code_map->length(); i += kEntryLength) { |
518 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kSharedOffset)); | 503 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kSharedOffset)); |
519 DCHECK(cell->cleared() || cell->value()->IsSharedFunctionInfo()); | 504 DCHECK(cell->cleared() || cell->value()->IsSharedFunctionInfo()); |
520 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset)); | 505 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset)); |
521 DCHECK(cell->cleared() || | 506 DCHECK(cell->cleared() || |
522 (cell->value()->IsCode() && | 507 (cell->value()->IsCode() && |
523 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION)); | 508 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION)); |
524 cell = WeakCell::cast(new_code_map->get(i + kLiteralsOffset)); | |
525 DCHECK(cell->cleared() || cell->value()->IsFixedArray()); | |
526 DCHECK(new_code_map->get(i + kOsrAstIdOffset)->IsSmi()); | 509 DCHECK(new_code_map->get(i + kOsrAstIdOffset)->IsSmi()); |
527 } | 510 } |
528 #endif | 511 #endif |
529 | 512 |
530 FixedArray* old_code_map = native_context->osr_code_table(); | 513 FixedArray* old_code_map = native_context->osr_code_table(); |
531 if (old_code_map != *new_code_map) { | 514 if (old_code_map != *new_code_map) { |
532 native_context->set_osr_code_table(*new_code_map); | 515 native_context->set_osr_code_table(*new_code_map); |
533 } | 516 } |
534 } | 517 } |
535 | 518 |
(...skipping 20 matching lines...) Expand all Loading... |
556 PrintF(" (osr ast id %d)]\n", osr.ToInt()); | 539 PrintF(" (osr ast id %d)]\n", osr.ToInt()); |
557 } | 540 } |
558 // Evict the src entry by not copying it to the dst entry. | 541 // Evict the src entry by not copying it to the dst entry. |
559 continue; | 542 continue; |
560 } | 543 } |
561 // Keep the src entry by copying it to the dst entry. | 544 // Keep the src entry by copying it to the dst entry. |
562 if (dst != src) { | 545 if (dst != src) { |
563 code_map->set(dst + kSharedOffset, code_map->get(src + kSharedOffset)); | 546 code_map->set(dst + kSharedOffset, code_map->get(src + kSharedOffset)); |
564 code_map->set(dst + kCachedCodeOffset, | 547 code_map->set(dst + kCachedCodeOffset, |
565 code_map->get(src + kCachedCodeOffset)); | 548 code_map->get(src + kCachedCodeOffset)); |
566 code_map->set(dst + kLiteralsOffset, | |
567 code_map->get(src + kLiteralsOffset)); | |
568 code_map->set(dst + kOsrAstIdOffset, | 549 code_map->set(dst + kOsrAstIdOffset, |
569 code_map->get(src + kOsrAstIdOffset)); | 550 code_map->get(src + kOsrAstIdOffset)); |
570 } | 551 } |
571 dst += kEntryLength; | 552 dst += kEntryLength; |
572 } | 553 } |
573 if (dst != length) { | 554 if (dst != length) { |
574 // Always trim even when array is cleared because of heap verifier. | 555 // Always trim even when array is cleared because of heap verifier. |
575 heap->RightTrimFixedArray(code_map, length - dst); | 556 heap->RightTrimFixedArray(code_map, length - dst); |
576 if (code_map->length() == 0) { | 557 if (code_map->length() == 0) { |
577 ClearOptimizedCodeMap(); | 558 ClearOptimizedCodeMap(); |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
768 | 749 |
769 int previous_value = errors_thrown()->value(); | 750 int previous_value = errors_thrown()->value(); |
770 set_errors_thrown(Smi::FromInt(previous_value + 1)); | 751 set_errors_thrown(Smi::FromInt(previous_value + 1)); |
771 } | 752 } |
772 | 753 |
773 | 754 |
774 int Context::GetErrorsThrown() { return errors_thrown()->value(); } | 755 int Context::GetErrorsThrown() { return errors_thrown()->value(); } |
775 | 756 |
776 } // namespace internal | 757 } // namespace internal |
777 } // namespace v8 | 758 } // namespace v8 |
OLD | NEW |