OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 __ bind(&ascii); | 570 __ bind(&ascii); |
571 __ movzxbl(result, FieldOperand(string, | 571 __ movzxbl(result, FieldOperand(string, |
572 index, | 572 index, |
573 times_1, | 573 times_1, |
574 SeqAsciiString::kHeaderSize)); | 574 SeqAsciiString::kHeaderSize)); |
575 __ bind(&done); | 575 __ bind(&done); |
576 } | 576 } |
577 | 577 |
578 #undef __ | 578 #undef __ |
579 | 579 |
| 580 |
| 581 static const int kNoCodeAgeSequenceLength = 6; |
| 582 |
| 583 static byte* GetNoCodeAgeSequence(uint32_t* length) { |
| 584 static bool initialized = false; |
| 585 static byte sequence[kNoCodeAgeSequenceLength]; |
| 586 *length = kNoCodeAgeSequenceLength; |
| 587 if (!initialized) { |
| 588 // The sequence of instructions that is patched out for aging code is the |
| 589 // following boilerplate stack-building prologue that is found both in |
| 590 // FUNCTION and OPTIMIZED_FUNCTION code: |
| 591 CodePatcher patcher(sequence, kNoCodeAgeSequenceLength); |
| 592 patcher.masm()->push(rbp); |
| 593 patcher.masm()->movq(rbp, rsp); |
| 594 patcher.masm()->push(rsi); |
| 595 patcher.masm()->push(rdi); |
| 596 initialized = true; |
| 597 } |
| 598 return sequence; |
| 599 } |
| 600 |
| 601 |
| 602 byte* Code::FindPlatformCodeAgeSequence() { |
| 603 byte* start = instruction_start(); |
| 604 uint32_t young_length; |
| 605 byte* young_sequence = GetNoCodeAgeSequence(&young_length); |
| 606 if (!memcmp(start, young_sequence, young_length) || |
| 607 *start == kCallOpcode) { |
| 608 return start; |
| 609 } else { |
| 610 byte* start_after_strict = NULL; |
| 611 if (kind() == FUNCTION) { |
| 612 start_after_strict = start + kSizeOfFullCodegenStrictModePrologue; |
| 613 } else { |
| 614 ASSERT(kind() == OPTIMIZED_FUNCTION); |
| 615 start_after_strict = start + kSizeOfOptimizedStrictModePrologue; |
| 616 } |
| 617 ASSERT(!memcmp(start_after_strict, young_sequence, young_length) || |
| 618 *start_after_strict == kCallOpcode); |
| 619 return start_after_strict; |
| 620 } |
| 621 } |
| 622 |
| 623 |
| 624 bool Code::IsYoungSequence(byte* sequence) { |
| 625 uint32_t young_length; |
| 626 byte* young_sequence = GetNoCodeAgeSequence(&young_length); |
| 627 bool result = (!memcmp(sequence, young_sequence, young_length)); |
| 628 ASSERT(result || *sequence == kCallOpcode); |
| 629 return result; |
| 630 } |
| 631 |
| 632 |
| 633 void Code::GetCodeAgeAndParity(byte* sequence, Age* age, |
| 634 MarkingParity* parity) { |
| 635 if (IsYoungSequence(sequence)) { |
| 636 *age = kNoAge; |
| 637 *parity = NO_MARKING_PARITY; |
| 638 } else { |
| 639 sequence++; // Skip the kCallOpcode byte |
| 640 Address target_address = sequence + *reinterpret_cast<int*>(sequence) + |
| 641 Assembler::kCallTargetAddressOffset; |
| 642 Code* stub = GetCodeFromTargetAddress(target_address); |
| 643 GetCodeAgeAndParity(stub, age, parity); |
| 644 } |
| 645 } |
| 646 |
| 647 |
| 648 void Code::PatchPlatformCodeAge(byte* sequence, |
| 649 Code::Age age, |
| 650 MarkingParity parity) { |
| 651 uint32_t young_length; |
| 652 byte* young_sequence = GetNoCodeAgeSequence(&young_length); |
| 653 if (age == kNoAge) { |
| 654 memcpy(sequence, young_sequence, young_length); |
| 655 CPU::FlushICache(sequence, young_length); |
| 656 } else { |
| 657 Code* stub = GetCodeAgeStub(age, parity); |
| 658 CodePatcher patcher(sequence, young_length); |
| 659 patcher.masm()->call(stub->instruction_start()); |
| 660 patcher.masm()->nop(); |
| 661 } |
| 662 } |
| 663 |
| 664 |
580 } } // namespace v8::internal | 665 } } // namespace v8::internal |
581 | 666 |
582 #endif // V8_TARGET_ARCH_X64 | 667 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |