OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // | 2 // |
3 // Redistribution and use in source and binary forms, with or without | 3 // Redistribution and use in source and binary forms, with or without |
4 // modification, are permitted provided that the following conditions are | 4 // modification, are permitted provided that the following conditions are |
5 // met: | 5 // met: |
6 // | 6 // |
7 // * Redistributions of source code must retain the above copyright | 7 // * Redistributions of source code must retain the above copyright |
8 // notice, this list of conditions and the following disclaimer. | 8 // notice, this list of conditions and the following disclaimer. |
9 // * Redistributions in binary form must reproduce the above | 9 // * Redistributions in binary form must reproduce the above |
10 // copyright notice, this list of conditions and the following | 10 // copyright notice, this list of conditions and the following |
(...skipping 2530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2541 | 2541 |
2542 int jump_instr = require_jump ? kInstructionSize : 0; | 2542 int jump_instr = require_jump ? kInstructionSize : 0; |
2543 int size_pool_marker = kInstructionSize; | 2543 int size_pool_marker = kInstructionSize; |
2544 int size_pool_guard = kInstructionSize; | 2544 int size_pool_guard = kInstructionSize; |
2545 int pool_size = jump_instr + size_pool_marker + size_pool_guard + | 2545 int pool_size = jump_instr + size_pool_marker + size_pool_guard + |
2546 num_pending_reloc_info_ * kPointerSize; | 2546 num_pending_reloc_info_ * kPointerSize; |
2547 int needed_space = pool_size + kGap; | 2547 int needed_space = pool_size + kGap; |
2548 | 2548 |
2549 // Emit veneers for branches that would go out of range during emission of the | 2549 // Emit veneers for branches that would go out of range during emission of the |
2550 // constant pool. | 2550 // constant pool. |
2551 CheckVeneerPool(require_jump, kVeneerDistanceMargin + pool_size); | 2551 CheckVeneerPool(false, require_jump, kVeneerDistanceMargin + pool_size); |
2552 | 2552 |
2553 Label size_check; | 2553 Label size_check; |
2554 bind(&size_check); | 2554 bind(&size_check); |
2555 | 2555 |
2556 // Check that the code buffer is large enough before emitting the constant | 2556 // Check that the code buffer is large enough before emitting the constant |
2557 // pool (include the jump over the pool, the constant pool marker, the | 2557 // pool (include the jump over the pool, the constant pool marker, the |
2558 // constant pool guard, and the gap to the relocation information). | 2558 // constant pool guard, and the gap to the relocation information). |
2559 while (buffer_space() <= needed_space) { | 2559 while (buffer_space() <= needed_space) { |
2560 GrowBuffer(); | 2560 GrowBuffer(); |
2561 } | 2561 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2634 void Assembler::RecordVeneerPool(int location_offset, int size) { | 2634 void Assembler::RecordVeneerPool(int location_offset, int size) { |
2635 #ifdef ENABLE_DEBUGGER_SUPPORT | 2635 #ifdef ENABLE_DEBUGGER_SUPPORT |
2636 RelocInfo rinfo(buffer_ + location_offset, | 2636 RelocInfo rinfo(buffer_ + location_offset, |
2637 RelocInfo::VENEER_POOL, static_cast<intptr_t>(size), | 2637 RelocInfo::VENEER_POOL, static_cast<intptr_t>(size), |
2638 NULL); | 2638 NULL); |
2639 reloc_info_writer.Write(&rinfo); | 2639 reloc_info_writer.Write(&rinfo); |
2640 #endif | 2640 #endif |
2641 } | 2641 } |
2642 | 2642 |
2643 | 2643 |
2644 void Assembler::EmitVeneers(bool need_protection, int margin) { | 2644 void Assembler::EmitVeneers(bool force_emit, bool need_protection, int margin) { |
2645 BlockPoolsScope scope(this); | 2645 BlockPoolsScope scope(this); |
2646 RecordComment("[ Veneers"); | 2646 RecordComment("[ Veneers"); |
2647 | 2647 |
2648 // The exact size of the veneer pool must be recorded (see the comment at the | 2648 // The exact size of the veneer pool must be recorded (see the comment at the |
2649 // declaration site of RecordConstPool()), but computing the number of | 2649 // declaration site of RecordConstPool()), but computing the number of |
2650 // veneers that will be generated is not obvious. So instead we remember the | 2650 // veneers that will be generated is not obvious. So instead we remember the |
2651 // current position and will record the size after the pool has been | 2651 // current position and will record the size after the pool has been |
2652 // generated. | 2652 // generated. |
2653 Label size_check; | 2653 Label size_check; |
2654 bind(&size_check); | 2654 bind(&size_check); |
2655 int veneer_pool_relocinfo_loc = pc_offset(); | 2655 int veneer_pool_relocinfo_loc = pc_offset(); |
2656 | 2656 |
2657 Label end; | 2657 Label end; |
2658 if (need_protection) { | 2658 if (need_protection) { |
2659 b(&end); | 2659 b(&end); |
2660 } | 2660 } |
2661 | 2661 |
2662 EmitVeneersGuard(); | 2662 EmitVeneersGuard(); |
2663 | 2663 |
2664 Label veneer_size_check; | 2664 Label veneer_size_check; |
2665 | 2665 |
2666 std::multimap<int, FarBranchInfo>::iterator it, it_to_delete; | 2666 std::multimap<int, FarBranchInfo>::iterator it, it_to_delete; |
2667 | 2667 |
2668 it = unresolved_branches_.begin(); | 2668 it = unresolved_branches_.begin(); |
2669 while (it != unresolved_branches_.end()) { | 2669 while (it != unresolved_branches_.end()) { |
2670 if (ShouldEmitVeneer(it->first, margin)) { | 2670 if (force_emit || ShouldEmitVeneer(it->first, margin)) { |
2671 Instruction* branch = InstructionAt(it->second.pc_offset_); | 2671 Instruction* branch = InstructionAt(it->second.pc_offset_); |
2672 Label* label = it->second.label_; | 2672 Label* label = it->second.label_; |
2673 | 2673 |
2674 #ifdef DEBUG | 2674 #ifdef DEBUG |
2675 bind(&veneer_size_check); | 2675 bind(&veneer_size_check); |
2676 #endif | 2676 #endif |
2677 // Patch the branch to point to the current position, and emit a branch | 2677 // Patch the branch to point to the current position, and emit a branch |
2678 // to the label. | 2678 // to the label. |
2679 Instruction* veneer = reinterpret_cast<Instruction*>(pc_); | 2679 Instruction* veneer = reinterpret_cast<Instruction*>(pc_); |
2680 RemoveBranchFromLabelLinkChain(branch, label, veneer); | 2680 RemoveBranchFromLabelLinkChain(branch, label, veneer); |
(...skipping 22 matching lines...) Expand all Loading... |
2703 next_veneer_pool_check_ = | 2703 next_veneer_pool_check_ = |
2704 unresolved_branches_first_limit() - kVeneerDistanceCheckMargin; | 2704 unresolved_branches_first_limit() - kVeneerDistanceCheckMargin; |
2705 } | 2705 } |
2706 | 2706 |
2707 bind(&end); | 2707 bind(&end); |
2708 | 2708 |
2709 RecordComment("]"); | 2709 RecordComment("]"); |
2710 } | 2710 } |
2711 | 2711 |
2712 | 2712 |
2713 void Assembler::CheckVeneerPool(bool require_jump, | 2713 void Assembler::CheckVeneerPool(bool force_emit, bool require_jump, |
2714 int margin) { | 2714 int margin) { |
2715 // There is nothing to do if there are no pending veneer pool entries. | 2715 // There is nothing to do if there are no pending veneer pool entries. |
2716 if (unresolved_branches_.empty()) { | 2716 if (unresolved_branches_.empty()) { |
2717 ASSERT(next_veneer_pool_check_ == kMaxInt); | 2717 ASSERT(next_veneer_pool_check_ == kMaxInt); |
2718 return; | 2718 return; |
2719 } | 2719 } |
2720 | 2720 |
2721 ASSERT(pc_offset() < unresolved_branches_first_limit()); | 2721 ASSERT(pc_offset() < unresolved_branches_first_limit()); |
2722 | 2722 |
2723 // Some short sequence of instruction mustn't be broken up by veneer pool | 2723 // Some short sequence of instruction mustn't be broken up by veneer pool |
2724 // emission, such sequences are protected by calls to BlockVeneerPoolFor and | 2724 // emission, such sequences are protected by calls to BlockVeneerPoolFor and |
2725 // BlockVeneerPoolScope. | 2725 // BlockVeneerPoolScope. |
2726 if (is_veneer_pool_blocked()) { | 2726 if (is_veneer_pool_blocked()) { |
| 2727 ASSERT(!force_emit); |
2727 return; | 2728 return; |
2728 } | 2729 } |
2729 | 2730 |
2730 if (!require_jump) { | 2731 if (!require_jump) { |
2731 // Prefer emitting veneers protected by an existing instruction. | 2732 // Prefer emitting veneers protected by an existing instruction. |
2732 margin *= kVeneerNoProtectionFactor; | 2733 margin *= kVeneerNoProtectionFactor; |
2733 } | 2734 } |
2734 if (ShouldEmitVeneers(margin)) { | 2735 if (force_emit || ShouldEmitVeneers(margin)) { |
2735 EmitVeneers(require_jump, margin); | 2736 EmitVeneers(force_emit, require_jump, margin); |
2736 } else { | 2737 } else { |
2737 next_veneer_pool_check_ = | 2738 next_veneer_pool_check_ = |
2738 unresolved_branches_first_limit() - kVeneerDistanceCheckMargin; | 2739 unresolved_branches_first_limit() - kVeneerDistanceCheckMargin; |
2739 } | 2740 } |
2740 } | 2741 } |
2741 | 2742 |
2742 | 2743 |
2743 void Assembler::RecordComment(const char* msg) { | 2744 void Assembler::RecordComment(const char* msg) { |
2744 if (FLAG_code_comments) { | 2745 if (FLAG_code_comments) { |
2745 CheckBuffer(); | 2746 CheckBuffer(); |
(...skipping 26 matching lines...) Expand all Loading... |
2772 // code. | 2773 // code. |
2773 #ifdef ENABLE_DEBUGGER_SUPPORT | 2774 #ifdef ENABLE_DEBUGGER_SUPPORT |
2774 RecordRelocInfo(RelocInfo::CONST_POOL, static_cast<intptr_t>(size)); | 2775 RecordRelocInfo(RelocInfo::CONST_POOL, static_cast<intptr_t>(size)); |
2775 #endif | 2776 #endif |
2776 } | 2777 } |
2777 | 2778 |
2778 | 2779 |
2779 } } // namespace v8::internal | 2780 } } // namespace v8::internal |
2780 | 2781 |
2781 #endif // V8_TARGET_ARCH_A64 | 2782 #endif // V8_TARGET_ARCH_A64 |
OLD | NEW |