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 14398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14409 DCHECK(kind() == FUNCTION); | 14409 DCHECK(kind() == FUNCTION); |
14410 BackEdgeTable back_edges(this, &no_gc); | 14410 BackEdgeTable back_edges(this, &no_gc); |
14411 for (uint32_t i = 0; i < back_edges.length(); i++) { | 14411 for (uint32_t i = 0; i < back_edges.length(); i++) { |
14412 if (back_edges.ast_id(i) == ast_id) return back_edges.pc_offset(i); | 14412 if (back_edges.ast_id(i) == ast_id) return back_edges.pc_offset(i); |
14413 } | 14413 } |
14414 UNREACHABLE(); // We expect to find the back edge. | 14414 UNREACHABLE(); // We expect to find the back edge. |
14415 return 0; | 14415 return 0; |
14416 } | 14416 } |
14417 | 14417 |
14418 void Code::MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate) { | 14418 void Code::MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate) { |
14419 PatchPlatformCodeAge(isolate, sequence, kNoAgeCodeAge, NO_MARKING_PARITY); | 14419 PatchPlatformCodeAge(isolate, sequence, kNoAgeCodeAge); |
14420 } | 14420 } |
14421 | 14421 |
14422 | 14422 |
14423 void Code::MarkCodeAsExecuted(byte* sequence, Isolate* isolate) { | 14423 void Code::MarkCodeAsExecuted(byte* sequence, Isolate* isolate) { |
14424 PatchPlatformCodeAge(isolate, sequence, kExecutedOnceCodeAge, | 14424 PatchPlatformCodeAge(isolate, sequence, kExecutedOnceCodeAge); |
14425 NO_MARKING_PARITY); | |
14426 } | 14425 } |
14427 | 14426 |
14428 | 14427 |
14429 // NextAge defines the Code::Age state transitions during a GC cycle. | 14428 // NextAge defines the Code::Age state transitions during a GC cycle. |
14430 static Code::Age NextAge(Code::Age age) { | 14429 static Code::Age NextAge(Code::Age age) { |
14431 switch (age) { | 14430 switch (age) { |
14432 case Code::kNotExecutedCodeAge: // Keep, until we've been executed. | 14431 case Code::kNotExecutedCodeAge: // Keep, until we've been executed. |
14433 case Code::kToBeExecutedOnceCodeAge: // Keep, until we've been executed. | 14432 case Code::kToBeExecutedOnceCodeAge: // Keep, until we've been executed. |
14434 case Code::kLastCodeAge: // Clamp at last Code::Age value. | 14433 case Code::kLastCodeAge: // Clamp at last Code::Age value. |
14435 return age; | 14434 return age; |
(...skipping 13 matching lines...) Expand all Loading... |
14449 | 14448 |
14450 | 14449 |
14451 void Code::MakeYoung(Isolate* isolate) { | 14450 void Code::MakeYoung(Isolate* isolate) { |
14452 byte* sequence = FindCodeAgeSequence(); | 14451 byte* sequence = FindCodeAgeSequence(); |
14453 if (sequence != NULL) MakeCodeAgeSequenceYoung(sequence, isolate); | 14452 if (sequence != NULL) MakeCodeAgeSequenceYoung(sequence, isolate); |
14454 } | 14453 } |
14455 | 14454 |
14456 void Code::PreAge(Isolate* isolate) { | 14455 void Code::PreAge(Isolate* isolate) { |
14457 byte* sequence = FindCodeAgeSequence(); | 14456 byte* sequence = FindCodeAgeSequence(); |
14458 if (sequence != NULL) { | 14457 if (sequence != NULL) { |
14459 PatchPlatformCodeAge(isolate, sequence, kPreAgedCodeAge, NO_MARKING_PARITY); | 14458 PatchPlatformCodeAge(isolate, sequence, kPreAgedCodeAge); |
14460 } | 14459 } |
14461 } | 14460 } |
14462 | 14461 |
14463 void Code::MarkToBeExecutedOnce(Isolate* isolate) { | 14462 void Code::MarkToBeExecutedOnce(Isolate* isolate) { |
14464 byte* sequence = FindCodeAgeSequence(); | 14463 byte* sequence = FindCodeAgeSequence(); |
14465 if (sequence != NULL) { | 14464 if (sequence != NULL) { |
14466 PatchPlatformCodeAge(isolate, sequence, kToBeExecutedOnceCodeAge, | 14465 PatchPlatformCodeAge(isolate, sequence, kToBeExecutedOnceCodeAge); |
14467 NO_MARKING_PARITY); | |
14468 } | 14466 } |
14469 } | 14467 } |
14470 | 14468 |
14471 void Code::MakeOlder(MarkingParity current_parity) { | 14469 void Code::MakeOlder() { |
14472 byte* sequence = FindCodeAgeSequence(); | 14470 byte* sequence = FindCodeAgeSequence(); |
14473 if (sequence != NULL) { | 14471 if (sequence != NULL) { |
14474 Age age; | |
14475 MarkingParity code_parity; | |
14476 Isolate* isolate = GetIsolate(); | 14472 Isolate* isolate = GetIsolate(); |
14477 GetCodeAgeAndParity(isolate, sequence, &age, &code_parity); | 14473 Age age = GetCodeAge(isolate, sequence); |
14478 Age next_age = NextAge(age); | 14474 Age next_age = NextAge(age); |
14479 if (age != next_age && code_parity != current_parity) { | 14475 if (age != next_age) { |
14480 PatchPlatformCodeAge(isolate, sequence, next_age, current_parity); | 14476 PatchPlatformCodeAge(isolate, sequence, next_age); |
14481 } | 14477 } |
14482 } | 14478 } |
14483 } | 14479 } |
14484 | 14480 |
14485 | 14481 |
14486 bool Code::IsOld() { | 14482 bool Code::IsOld() { |
14487 return IsOldAge(GetAge()); | 14483 return IsOldAge(GetAge()); |
14488 } | 14484 } |
14489 | 14485 |
14490 | 14486 |
14491 byte* Code::FindCodeAgeSequence() { | 14487 byte* Code::FindCodeAgeSequence() { |
14492 return FLAG_age_code && | 14488 return FLAG_age_code && |
14493 prologue_offset() != Code::kPrologueOffsetNotSet && | 14489 prologue_offset() != Code::kPrologueOffsetNotSet && |
14494 (kind() == OPTIMIZED_FUNCTION || | 14490 (kind() == OPTIMIZED_FUNCTION || |
14495 (kind() == FUNCTION && !has_debug_break_slots())) | 14491 (kind() == FUNCTION && !has_debug_break_slots())) |
14496 ? instruction_start() + prologue_offset() | 14492 ? instruction_start() + prologue_offset() |
14497 : NULL; | 14493 : NULL; |
14498 } | 14494 } |
14499 | 14495 |
14500 | 14496 |
14501 Code::Age Code::GetAge() { | 14497 Code::Age Code::GetAge() { |
14502 byte* sequence = FindCodeAgeSequence(); | 14498 byte* sequence = FindCodeAgeSequence(); |
14503 if (sequence == NULL) { | 14499 if (sequence == NULL) { |
14504 return kNoAgeCodeAge; | 14500 return kNoAgeCodeAge; |
14505 } | 14501 } |
14506 Age age; | 14502 return GetCodeAge(GetIsolate(), sequence); |
14507 MarkingParity parity; | |
14508 GetCodeAgeAndParity(GetIsolate(), sequence, &age, &parity); | |
14509 return age; | |
14510 } | 14503 } |
14511 | 14504 |
14512 | 14505 Code::Age Code::GetAgeOfCodeAgeStub(Code* code) { |
14513 void Code::GetCodeAgeAndParity(Code* code, Age* age, | |
14514 MarkingParity* parity) { | |
14515 Isolate* isolate = code->GetIsolate(); | 14506 Isolate* isolate = code->GetIsolate(); |
14516 Builtins* builtins = isolate->builtins(); | 14507 Builtins* builtins = isolate->builtins(); |
14517 Code* stub = NULL; | 14508 #define HANDLE_CODE_AGE(AGE) \ |
14518 #define HANDLE_CODE_AGE(AGE) \ | 14509 if (code == *builtins->Make##AGE##CodeYoungAgain()) { \ |
14519 stub = *builtins->Make##AGE##CodeYoungAgainEvenMarking(); \ | 14510 return k##AGE##CodeAge; \ |
14520 if (code == stub) { \ | |
14521 *age = k##AGE##CodeAge; \ | |
14522 *parity = EVEN_MARKING_PARITY; \ | |
14523 return; \ | |
14524 } \ | |
14525 stub = *builtins->Make##AGE##CodeYoungAgainOddMarking(); \ | |
14526 if (code == stub) { \ | |
14527 *age = k##AGE##CodeAge; \ | |
14528 *parity = ODD_MARKING_PARITY; \ | |
14529 return; \ | |
14530 } | 14511 } |
14531 CODE_AGE_LIST(HANDLE_CODE_AGE) | 14512 CODE_AGE_LIST(HANDLE_CODE_AGE) |
14532 #undef HANDLE_CODE_AGE | 14513 #undef HANDLE_CODE_AGE |
14533 stub = *builtins->MarkCodeAsExecutedOnce(); | 14514 if (code == *builtins->MarkCodeAsExecutedOnce()) { |
14534 if (code == stub) { | 14515 return kNotExecutedCodeAge; |
14535 *age = kNotExecutedCodeAge; | |
14536 *parity = NO_MARKING_PARITY; | |
14537 return; | |
14538 } | 14516 } |
14539 stub = *builtins->MarkCodeAsExecutedTwice(); | 14517 if (code == *builtins->MarkCodeAsExecutedTwice()) { |
14540 if (code == stub) { | 14518 return kExecutedOnceCodeAge; |
14541 *age = kExecutedOnceCodeAge; | |
14542 *parity = NO_MARKING_PARITY; | |
14543 return; | |
14544 } | 14519 } |
14545 stub = *builtins->MarkCodeAsToBeExecutedOnce(); | 14520 if (code == *builtins->MarkCodeAsToBeExecutedOnce()) { |
14546 if (code == stub) { | 14521 return kToBeExecutedOnceCodeAge; |
14547 *age = kToBeExecutedOnceCodeAge; | |
14548 *parity = NO_MARKING_PARITY; | |
14549 return; | |
14550 } | 14522 } |
14551 UNREACHABLE(); | 14523 UNREACHABLE(); |
| 14524 return kNoAgeCodeAge; |
14552 } | 14525 } |
14553 | 14526 |
14554 | 14527 Code* Code::GetCodeAgeStub(Isolate* isolate, Age age) { |
14555 Code* Code::GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity) { | |
14556 Builtins* builtins = isolate->builtins(); | 14528 Builtins* builtins = isolate->builtins(); |
14557 switch (age) { | 14529 switch (age) { |
14558 #define HANDLE_CODE_AGE(AGE) \ | 14530 #define HANDLE_CODE_AGE(AGE) \ |
14559 case k##AGE##CodeAge: { \ | 14531 case k##AGE##CodeAge: { \ |
14560 Code* stub = parity == EVEN_MARKING_PARITY \ | 14532 return *builtins->Make##AGE##CodeYoungAgain(); \ |
14561 ? *builtins->Make##AGE##CodeYoungAgainEvenMarking() \ | 14533 } |
14562 : *builtins->Make##AGE##CodeYoungAgainOddMarking(); \ | |
14563 return stub; \ | |
14564 } | |
14565 CODE_AGE_LIST(HANDLE_CODE_AGE) | 14534 CODE_AGE_LIST(HANDLE_CODE_AGE) |
14566 #undef HANDLE_CODE_AGE | 14535 #undef HANDLE_CODE_AGE |
14567 case kNotExecutedCodeAge: { | 14536 case kNotExecutedCodeAge: { |
14568 DCHECK(parity == NO_MARKING_PARITY); | |
14569 return *builtins->MarkCodeAsExecutedOnce(); | 14537 return *builtins->MarkCodeAsExecutedOnce(); |
14570 } | 14538 } |
14571 case kExecutedOnceCodeAge: { | 14539 case kExecutedOnceCodeAge: { |
14572 DCHECK(parity == NO_MARKING_PARITY); | |
14573 return *builtins->MarkCodeAsExecutedTwice(); | 14540 return *builtins->MarkCodeAsExecutedTwice(); |
14574 } | 14541 } |
14575 case kToBeExecutedOnceCodeAge: { | 14542 case kToBeExecutedOnceCodeAge: { |
14576 DCHECK(parity == NO_MARKING_PARITY); | |
14577 return *builtins->MarkCodeAsToBeExecutedOnce(); | 14543 return *builtins->MarkCodeAsToBeExecutedOnce(); |
14578 } | 14544 } |
14579 default: | 14545 default: |
14580 UNREACHABLE(); | 14546 UNREACHABLE(); |
14581 break; | 14547 break; |
14582 } | 14548 } |
14583 return NULL; | 14549 return NULL; |
14584 } | 14550 } |
14585 | 14551 |
14586 | 14552 |
(...skipping 5946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
20533 // depend on this. | 20499 // depend on this. |
20534 return DICTIONARY_ELEMENTS; | 20500 return DICTIONARY_ELEMENTS; |
20535 } | 20501 } |
20536 DCHECK_LE(kind, LAST_ELEMENTS_KIND); | 20502 DCHECK_LE(kind, LAST_ELEMENTS_KIND); |
20537 return kind; | 20503 return kind; |
20538 } | 20504 } |
20539 } | 20505 } |
20540 | 20506 |
20541 } // namespace internal | 20507 } // namespace internal |
20542 } // namespace v8 | 20508 } // namespace v8 |
OLD | NEW |