| 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 |