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