Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(129)

Side by Side Diff: src/ppc/assembler-ppc.cc

Issue 1237213002: PPC: Limit unbound label tracking to branch references. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ppc/assembler-ppc.h ('k') | src/ppc/assembler-ppc-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions 5 // modification, are permitted provided that the following conditions
6 // are met: 6 // are met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) 205 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
206 : AssemblerBase(isolate, buffer, buffer_size), 206 : AssemblerBase(isolate, buffer, buffer_size),
207 recorded_ast_id_(TypeFeedbackId::None()), 207 recorded_ast_id_(TypeFeedbackId::None()),
208 constant_pool_builder_(kLoadPtrMaxReachBits, kLoadDoubleMaxReachBits), 208 constant_pool_builder_(kLoadPtrMaxReachBits, kLoadDoubleMaxReachBits),
209 positions_recorder_(this) { 209 positions_recorder_(this) {
210 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); 210 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
211 211
212 no_trampoline_pool_before_ = 0; 212 no_trampoline_pool_before_ = 0;
213 trampoline_pool_blocked_nesting_ = 0; 213 trampoline_pool_blocked_nesting_ = 0;
214 constant_pool_entry_sharing_blocked_nesting_ = 0; 214 constant_pool_entry_sharing_blocked_nesting_ = 0;
215 // We leave space (kMaxBlockTrampolineSectionSize) 215 next_trampoline_check_ = kMaxInt;
216 // for BlockTrampolinePoolScope buffer.
217 next_buffer_check_ =
218 FLAG_force_long_branches ? kMaxInt : kMaxCondBranchReach -
219 kMaxBlockTrampolineSectionSize;
220 internal_trampoline_exception_ = false; 216 internal_trampoline_exception_ = false;
221 last_bound_pos_ = 0; 217 last_bound_pos_ = 0;
222 optimizable_cmpi_pos_ = -1; 218 optimizable_cmpi_pos_ = -1;
223 trampoline_emitted_ = FLAG_force_long_branches; 219 trampoline_emitted_ = FLAG_force_long_branches;
224 unbound_labels_count_ = 0; 220 tracked_branch_count_ = 0;
225 ClearRecordedAstId(); 221 ClearRecordedAstId();
226 relocations_.reserve(128); 222 relocations_.reserve(128);
227 } 223 }
228 224
229 225
230 void Assembler::GetCode(CodeDesc* desc) { 226 void Assembler::GetCode(CodeDesc* desc) {
231 // Emit constant pool if necessary. 227 // Emit constant pool if necessary.
232 int constant_pool_offset = EmitConstantPool(); 228 int constant_pool_offset = EmitConstantPool();
233 229
234 EmitRelocations(); 230 EmitRelocations();
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 default: 416 default:
421 DCHECK(false); 417 DCHECK(false);
422 return -1; 418 return -1;
423 } 419 }
424 420
425 if (link == 0) return kEndOfChain; 421 if (link == 0) return kEndOfChain;
426 return pos + link; 422 return pos + link;
427 } 423 }
428 424
429 425
430 void Assembler::target_at_put(int pos, int target_pos) { 426 void Assembler::target_at_put(int pos, int target_pos, bool* is_branch) {
431 Instr instr = instr_at(pos); 427 Instr instr = instr_at(pos);
432 int opcode = instr & kOpcodeMask; 428 int opcode = instr & kOpcodeMask;
433 429
430 if (is_branch != nullptr) {
431 *is_branch = (opcode == BX || opcode == BCX);
432 }
433
434 switch (opcode) { 434 switch (opcode) {
435 case BX: { 435 case BX: {
436 int imm26 = target_pos - pos; 436 int imm26 = target_pos - pos;
437 CHECK(is_int26(imm26) && (imm26 & (kAAMask | kLKMask)) == 0); 437 CHECK(is_int26(imm26) && (imm26 & (kAAMask | kLKMask)) == 0);
438 if (imm26 == kInstrSize && !(instr & kLKMask)) { 438 if (imm26 == kInstrSize && !(instr & kLKMask)) {
439 // Branch to next instr without link. 439 // Branch to next instr without link.
440 instr = ORI; // nop: ori, 0,0,0 440 instr = ORI; // nop: ori, 0,0,0
441 } else { 441 } else {
442 instr &= ((~kImm26Mask) | kAAMask | kLKMask); 442 instr &= ((~kImm26Mask) | kAAMask | kLKMask);
443 instr |= (imm26 & kImm26Mask); 443 instr |= (imm26 & kImm26Mask);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 } 521 }
522 522
523 DCHECK(false); 523 DCHECK(false);
524 return 0; 524 return 0;
525 } 525 }
526 526
527 527
528 void Assembler::bind_to(Label* L, int pos) { 528 void Assembler::bind_to(Label* L, int pos) {
529 DCHECK(0 <= pos && pos <= pc_offset()); // must have a valid binding position 529 DCHECK(0 <= pos && pos <= pc_offset()); // must have a valid binding position
530 int32_t trampoline_pos = kInvalidSlotPos; 530 int32_t trampoline_pos = kInvalidSlotPos;
531 if (L->is_linked() && !trampoline_emitted_) { 531 bool is_branch = false;
532 unbound_labels_count_--;
533 next_buffer_check_ += kTrampolineSlotsSize;
534 }
535
536 while (L->is_linked()) { 532 while (L->is_linked()) {
537 int fixup_pos = L->pos(); 533 int fixup_pos = L->pos();
538 int32_t offset = pos - fixup_pos; 534 int32_t offset = pos - fixup_pos;
539 int maxReach = max_reach_from(fixup_pos); 535 int maxReach = max_reach_from(fixup_pos);
540 next(L); // call next before overwriting link with target at fixup_pos 536 next(L); // call next before overwriting link with target at fixup_pos
541 if (maxReach && is_intn(offset, maxReach) == false) { 537 if (maxReach && is_intn(offset, maxReach) == false) {
542 if (trampoline_pos == kInvalidSlotPos) { 538 if (trampoline_pos == kInvalidSlotPos) {
543 trampoline_pos = get_trampoline_entry(); 539 trampoline_pos = get_trampoline_entry();
544 CHECK(trampoline_pos != kInvalidSlotPos); 540 CHECK(trampoline_pos != kInvalidSlotPos);
545 target_at_put(trampoline_pos, pos); 541 target_at_put(trampoline_pos, pos);
546 } 542 }
547 target_at_put(fixup_pos, trampoline_pos); 543 target_at_put(fixup_pos, trampoline_pos);
548 } else { 544 } else {
549 target_at_put(fixup_pos, pos); 545 target_at_put(fixup_pos, pos, &is_branch);
550 } 546 }
551 } 547 }
552 L->bind_to(pos); 548 L->bind_to(pos);
553 549
550 if (!trampoline_emitted_ && is_branch) {
551 UntrackBranch();
552 }
553
554 // Keep track of the last bound label so we don't eliminate any instructions 554 // Keep track of the last bound label so we don't eliminate any instructions
555 // before a bound label. 555 // before a bound label.
556 if (pos > last_bound_pos_) last_bound_pos_ = pos; 556 if (pos > last_bound_pos_) last_bound_pos_ = pos;
557 } 557 }
558 558
559 559
560 void Assembler::bind(Label* L) { 560 void Assembler::bind(Label* L) {
561 DCHECK(!L->is_bound()); // label can only be bound once 561 DCHECK(!L->is_bound()); // label can only be bound once
562 bind_to(L, pc_offset()); 562 bind_to(L, pc_offset());
563 } 563 }
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 position = L->pos(); 666 position = L->pos();
667 } else { 667 } else {
668 if (L->is_linked()) { 668 if (L->is_linked()) {
669 position = L->pos(); // L's link 669 position = L->pos(); // L's link
670 } else { 670 } else {
671 // was: target_pos = kEndOfChain; 671 // was: target_pos = kEndOfChain;
672 // However, using self to mark the first reference 672 // However, using self to mark the first reference
673 // should avoid most instances of branch offset overflow. See 673 // should avoid most instances of branch offset overflow. See
674 // target_at() for where this is converted back to kEndOfChain. 674 // target_at() for where this is converted back to kEndOfChain.
675 position = pc_offset(); 675 position = pc_offset();
676 if (!trampoline_emitted_) {
677 unbound_labels_count_++;
678 next_buffer_check_ -= kTrampolineSlotsSize;
679 }
680 } 676 }
681 L->link_to(pc_offset()); 677 L->link_to(pc_offset());
682 } 678 }
683 679
684 return position; 680 return position;
685 } 681 }
686 682
687 683
688 // Branch instructions. 684 // Branch instructions.
689 685
(...skipping 1709 matching lines...) Expand 10 before | Expand all | Expand 10 after
2399 BlockTrampolinePoolBefore(pc_offset() + instructions * kInstrSize); 2395 BlockTrampolinePoolBefore(pc_offset() + instructions * kInstrSize);
2400 } 2396 }
2401 2397
2402 2398
2403 void Assembler::CheckTrampolinePool() { 2399 void Assembler::CheckTrampolinePool() {
2404 // Some small sequences of instructions must not be broken up by the 2400 // Some small sequences of instructions must not be broken up by the
2405 // insertion of a trampoline pool; such sequences are protected by setting 2401 // insertion of a trampoline pool; such sequences are protected by setting
2406 // either trampoline_pool_blocked_nesting_ or no_trampoline_pool_before_, 2402 // either trampoline_pool_blocked_nesting_ or no_trampoline_pool_before_,
2407 // which are both checked here. Also, recursive calls to CheckTrampolinePool 2403 // which are both checked here. Also, recursive calls to CheckTrampolinePool
2408 // are blocked by trampoline_pool_blocked_nesting_. 2404 // are blocked by trampoline_pool_blocked_nesting_.
2409 if ((trampoline_pool_blocked_nesting_ > 0) || 2405 if (trampoline_pool_blocked_nesting_ > 0) return;
2410 (pc_offset() < no_trampoline_pool_before_)) { 2406 if (pc_offset() < no_trampoline_pool_before_) {
2411 // Emission is currently blocked; make sure we try again as soon as 2407 next_trampoline_check_ = no_trampoline_pool_before_;
2412 // possible.
2413 if (trampoline_pool_blocked_nesting_ > 0) {
2414 next_buffer_check_ = pc_offset() + kInstrSize;
2415 } else {
2416 next_buffer_check_ = no_trampoline_pool_before_;
2417 }
2418 return; 2408 return;
2419 } 2409 }
2420 2410
2421 DCHECK(!trampoline_emitted_); 2411 DCHECK(!trampoline_emitted_);
2422 DCHECK(unbound_labels_count_ >= 0); 2412 if (tracked_branch_count_ > 0) {
2423 if (unbound_labels_count_ > 0) { 2413 int size = tracked_branch_count_ * kInstrSize;
2414
2415 // As we are only going to emit trampoline once, we need to prevent any
2416 // further emission.
2417 trampoline_emitted_ = true;
2418 next_trampoline_check_ = kMaxInt;
2419
2424 // First we emit jump, then we emit trampoline pool. 2420 // First we emit jump, then we emit trampoline pool.
2425 { 2421 b(size + kInstrSize, LeaveLK);
2426 BlockTrampolinePoolScope block_trampoline_pool(this); 2422 for (int i = size; i > 0; i -= kInstrSize) {
2427 Label after_pool; 2423 b(i, LeaveLK);
2428 b(&after_pool); 2424 }
2429 2425
2430 int pool_start = pc_offset(); 2426 trampoline_ = Trampoline(pc_offset() - size, tracked_branch_count_);
2431 for (int i = 0; i < unbound_labels_count_; i++) {
2432 b(&after_pool);
2433 }
2434 bind(&after_pool);
2435 trampoline_ = Trampoline(pool_start, unbound_labels_count_);
2436
2437 trampoline_emitted_ = true;
2438 // As we are only going to emit trampoline once, we need to prevent any
2439 // further emission.
2440 next_buffer_check_ = kMaxInt;
2441 }
2442 } else {
2443 // Number of branches to unbound label at this point is zero, so we can
2444 // move next buffer check to maximum.
2445 next_buffer_check_ =
2446 pc_offset() + kMaxCondBranchReach - kMaxBlockTrampolineSectionSize;
2447 } 2427 }
2448 return;
2449 } 2428 }
2450 2429
2451 2430
2452 } // namespace internal 2431 } // namespace internal
2453 } // namespace v8 2432 } // namespace v8
2454 2433
2455 #endif // V8_TARGET_ARCH_PPC 2434 #endif // V8_TARGET_ARCH_PPC
OLDNEW
« no previous file with comments | « src/ppc/assembler-ppc.h ('k') | src/ppc/assembler-ppc-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698