| Index: src/ppc/assembler-ppc.cc
|
| diff --git a/src/ppc/assembler-ppc.cc b/src/ppc/assembler-ppc.cc
|
| index e6acfbb4ac2d24da6e2cacde519e20cb8ccca206..b279440ddbb4f585ed76b0eb17e2f833aa950d43 100644
|
| --- a/src/ppc/assembler-ppc.cc
|
| +++ b/src/ppc/assembler-ppc.cc
|
| @@ -212,16 +212,12 @@ Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
|
| no_trampoline_pool_before_ = 0;
|
| trampoline_pool_blocked_nesting_ = 0;
|
| constant_pool_entry_sharing_blocked_nesting_ = 0;
|
| - // We leave space (kMaxBlockTrampolineSectionSize)
|
| - // for BlockTrampolinePoolScope buffer.
|
| - next_buffer_check_ =
|
| - FLAG_force_long_branches ? kMaxInt : kMaxCondBranchReach -
|
| - kMaxBlockTrampolineSectionSize;
|
| + next_trampoline_check_ = kMaxInt;
|
| internal_trampoline_exception_ = false;
|
| last_bound_pos_ = 0;
|
| optimizable_cmpi_pos_ = -1;
|
| trampoline_emitted_ = FLAG_force_long_branches;
|
| - unbound_labels_count_ = 0;
|
| + tracked_branch_count_ = 0;
|
| ClearRecordedAstId();
|
| relocations_.reserve(128);
|
| }
|
| @@ -427,10 +423,14 @@ int Assembler::target_at(int pos) {
|
| }
|
|
|
|
|
| -void Assembler::target_at_put(int pos, int target_pos) {
|
| +void Assembler::target_at_put(int pos, int target_pos, bool* is_branch) {
|
| Instr instr = instr_at(pos);
|
| int opcode = instr & kOpcodeMask;
|
|
|
| + if (is_branch != nullptr) {
|
| + *is_branch = (opcode == BX || opcode == BCX);
|
| + }
|
| +
|
| switch (opcode) {
|
| case BX: {
|
| int imm26 = target_pos - pos;
|
| @@ -528,11 +528,7 @@ int Assembler::max_reach_from(int pos) {
|
| void Assembler::bind_to(Label* L, int pos) {
|
| DCHECK(0 <= pos && pos <= pc_offset()); // must have a valid binding position
|
| int32_t trampoline_pos = kInvalidSlotPos;
|
| - if (L->is_linked() && !trampoline_emitted_) {
|
| - unbound_labels_count_--;
|
| - next_buffer_check_ += kTrampolineSlotsSize;
|
| - }
|
| -
|
| + bool is_branch = false;
|
| while (L->is_linked()) {
|
| int fixup_pos = L->pos();
|
| int32_t offset = pos - fixup_pos;
|
| @@ -546,11 +542,15 @@ void Assembler::bind_to(Label* L, int pos) {
|
| }
|
| target_at_put(fixup_pos, trampoline_pos);
|
| } else {
|
| - target_at_put(fixup_pos, pos);
|
| + target_at_put(fixup_pos, pos, &is_branch);
|
| }
|
| }
|
| L->bind_to(pos);
|
|
|
| + if (!trampoline_emitted_ && is_branch) {
|
| + UntrackBranch();
|
| + }
|
| +
|
| // Keep track of the last bound label so we don't eliminate any instructions
|
| // before a bound label.
|
| if (pos > last_bound_pos_) last_bound_pos_ = pos;
|
| @@ -673,10 +673,6 @@ int Assembler::link(Label* L) {
|
| // should avoid most instances of branch offset overflow. See
|
| // target_at() for where this is converted back to kEndOfChain.
|
| position = pc_offset();
|
| - if (!trampoline_emitted_) {
|
| - unbound_labels_count_++;
|
| - next_buffer_check_ -= kTrampolineSlotsSize;
|
| - }
|
| }
|
| L->link_to(pc_offset());
|
| }
|
| @@ -2406,46 +2402,29 @@ void Assembler::CheckTrampolinePool() {
|
| // either trampoline_pool_blocked_nesting_ or no_trampoline_pool_before_,
|
| // which are both checked here. Also, recursive calls to CheckTrampolinePool
|
| // are blocked by trampoline_pool_blocked_nesting_.
|
| - if ((trampoline_pool_blocked_nesting_ > 0) ||
|
| - (pc_offset() < no_trampoline_pool_before_)) {
|
| - // Emission is currently blocked; make sure we try again as soon as
|
| - // possible.
|
| - if (trampoline_pool_blocked_nesting_ > 0) {
|
| - next_buffer_check_ = pc_offset() + kInstrSize;
|
| - } else {
|
| - next_buffer_check_ = no_trampoline_pool_before_;
|
| - }
|
| + if (trampoline_pool_blocked_nesting_ > 0) return;
|
| + if (pc_offset() < no_trampoline_pool_before_) {
|
| + next_trampoline_check_ = no_trampoline_pool_before_;
|
| return;
|
| }
|
|
|
| DCHECK(!trampoline_emitted_);
|
| - DCHECK(unbound_labels_count_ >= 0);
|
| - if (unbound_labels_count_ > 0) {
|
| - // First we emit jump, then we emit trampoline pool.
|
| - {
|
| - BlockTrampolinePoolScope block_trampoline_pool(this);
|
| - Label after_pool;
|
| - b(&after_pool);
|
| -
|
| - int pool_start = pc_offset();
|
| - for (int i = 0; i < unbound_labels_count_; i++) {
|
| - b(&after_pool);
|
| - }
|
| - bind(&after_pool);
|
| - trampoline_ = Trampoline(pool_start, unbound_labels_count_);
|
| + if (tracked_branch_count_ > 0) {
|
| + int size = tracked_branch_count_ * kInstrSize;
|
| +
|
| + // As we are only going to emit trampoline once, we need to prevent any
|
| + // further emission.
|
| + trampoline_emitted_ = true;
|
| + next_trampoline_check_ = kMaxInt;
|
|
|
| - trampoline_emitted_ = true;
|
| - // As we are only going to emit trampoline once, we need to prevent any
|
| - // further emission.
|
| - next_buffer_check_ = kMaxInt;
|
| + // First we emit jump, then we emit trampoline pool.
|
| + b(size + kInstrSize, LeaveLK);
|
| + for (int i = size; i > 0; i -= kInstrSize) {
|
| + b(i, LeaveLK);
|
| }
|
| - } else {
|
| - // Number of branches to unbound label at this point is zero, so we can
|
| - // move next buffer check to maximum.
|
| - next_buffer_check_ =
|
| - pc_offset() + kMaxCondBranchReach - kMaxBlockTrampolineSectionSize;
|
| +
|
| + trampoline_ = Trampoline(pc_offset() - size, tracked_branch_count_);
|
| }
|
| - return;
|
| }
|
|
|
|
|
|
|