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

Side by Side Diff: src/ppc/assembler-ppc-inl.h

Issue 1155703006: Revert of Embedded constant pools. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 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.cc ('k') | src/ppc/builtins-ppc.cc » ('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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 Address RelocInfo::target_address() { 87 Address RelocInfo::target_address() {
88 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); 88 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
89 return Assembler::target_address_at(pc_, host_); 89 return Assembler::target_address_at(pc_, host_);
90 } 90 }
91 91
92 92
93 Address RelocInfo::target_address_address() { 93 Address RelocInfo::target_address_address() {
94 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || 94 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) ||
95 rmode_ == EMBEDDED_OBJECT || rmode_ == EXTERNAL_REFERENCE); 95 rmode_ == EMBEDDED_OBJECT || rmode_ == EXTERNAL_REFERENCE);
96 96
97 if (FLAG_enable_embedded_constant_pool &&
98 Assembler::IsConstantPoolLoadStart(pc_)) {
99 // We return the PC for ool constant pool since this function is used by the
100 // serializer and expects the address to reside within the code object.
101 return reinterpret_cast<Address>(pc_);
102 }
103
104 // Read the address of the word containing the target_address in an 97 // Read the address of the word containing the target_address in an
105 // instruction stream. 98 // instruction stream.
106 // The only architecture-independent user of this function is the serializer. 99 // The only architecture-independent user of this function is the serializer.
107 // The serializer uses it to find out how many raw bytes of instruction to 100 // The serializer uses it to find out how many raw bytes of instruction to
108 // output before the next target. 101 // output before the next target.
109 // For an instruction like LIS/ORI where the target bits are mixed into the 102 // For an instruction like LIS/ORI where the target bits are mixed into the
110 // instruction bits, the size of the target will be zero, indicating that the 103 // instruction bits, the size of the target will be zero, indicating that the
111 // serializer should not step forward in memory after a target is resolved 104 // serializer should not step forward in memory after a target is resolved
112 // and written. 105 // and written.
113 return reinterpret_cast<Address>(pc_); 106 return reinterpret_cast<Address>(pc_);
114 } 107 }
115 108
116 109
117 Address RelocInfo::constant_pool_entry_address() { 110 Address RelocInfo::constant_pool_entry_address() {
118 if (FLAG_enable_embedded_constant_pool) {
119 Address constant_pool = host_->constant_pool();
120 DCHECK(constant_pool);
121 ConstantPoolEntry::Access access;
122 if (Assembler::IsConstantPoolLoadStart(pc_, &access))
123 return Assembler::target_constant_pool_address_at(
124 pc_, constant_pool, access, ConstantPoolEntry::INTPTR);
125 }
126 UNREACHABLE(); 111 UNREACHABLE();
127 return NULL; 112 return NULL;
128 } 113 }
129 114
130 115
131 int RelocInfo::target_address_size() { return Assembler::kSpecialTargetSize; } 116 int RelocInfo::target_address_size() { return Assembler::kSpecialTargetSize; }
132 117
133 118
134 void RelocInfo::set_target_address(Address target, 119 void RelocInfo::set_target_address(Address target,
135 WriteBarrierMode write_barrier_mode, 120 WriteBarrierMode write_barrier_mode,
(...skipping 15 matching lines...) Expand all
151 136
152 137
153 Address Assembler::target_address_from_return_address(Address pc) { 138 Address Assembler::target_address_from_return_address(Address pc) {
154 // Returns the address of the call target from the return address that will 139 // Returns the address of the call target from the return address that will
155 // be returned to after a call. 140 // be returned to after a call.
156 // Call sequence is : 141 // Call sequence is :
157 // mov ip, @ call address 142 // mov ip, @ call address
158 // mtlr ip 143 // mtlr ip
159 // blrl 144 // blrl
160 // @ return address 145 // @ return address
161 int len; 146 return pc - (kMovInstructions + 2) * kInstrSize;
162 ConstantPoolEntry::Access access;
163 if (FLAG_enable_embedded_constant_pool &&
164 IsConstantPoolLoadEnd(pc - 3 * kInstrSize, &access)) {
165 len = (access == ConstantPoolEntry::OVERFLOWED) ? 2 : 1;
166 } else {
167 len = kMovInstructionsNoConstantPool;
168 }
169 return pc - (len + 2) * kInstrSize;
170 } 147 }
171 148
172 149
173 Address Assembler::return_address_from_call_start(Address pc) { 150 Address Assembler::return_address_from_call_start(Address pc) {
174 int len; 151 return pc + (kMovInstructions + 2) * kInstrSize;
175 ConstantPoolEntry::Access access;
176 if (FLAG_enable_embedded_constant_pool &&
177 IsConstantPoolLoadStart(pc, &access)) {
178 len = (access == ConstantPoolEntry::OVERFLOWED) ? 2 : 1;
179 } else {
180 len = kMovInstructionsNoConstantPool;
181 }
182 return pc + (len + 2) * kInstrSize;
183 } 152 }
184 153
185 154
186 Object* RelocInfo::target_object() { 155 Object* RelocInfo::target_object() {
187 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 156 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
188 return reinterpret_cast<Object*>(Assembler::target_address_at(pc_, host_)); 157 return reinterpret_cast<Object*>(Assembler::target_address_at(pc_, host_));
189 } 158 }
190 159
191 160
192 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) { 161 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 Address address = cell->address() + Cell::kValueOffset; 219 Address address = cell->address() + Cell::kValueOffset;
251 Memory::Address_at(pc_) = address; 220 Memory::Address_at(pc_) = address;
252 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) { 221 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) {
253 // TODO(1550) We are passing NULL as a slot because cell can never be on 222 // TODO(1550) We are passing NULL as a slot because cell can never be on
254 // evacuation candidate. 223 // evacuation candidate.
255 host()->GetHeap()->incremental_marking()->RecordWrite(host(), NULL, cell); 224 host()->GetHeap()->incremental_marking()->RecordWrite(host(), NULL, cell);
256 } 225 }
257 } 226 }
258 227
259 228
260 static const int kNoCodeAgeInstructions = 229 static const int kNoCodeAgeInstructions = 6;
261 FLAG_enable_embedded_constant_pool ? 7 : 6; 230 static const int kCodeAgingInstructions = Assembler::kMovInstructions + 3;
262 static const int kCodeAgingInstructions =
263 Assembler::kMovInstructionsNoConstantPool + 3;
264 static const int kNoCodeAgeSequenceInstructions = 231 static const int kNoCodeAgeSequenceInstructions =
265 ((kNoCodeAgeInstructions >= kCodeAgingInstructions) 232 ((kNoCodeAgeInstructions >= kCodeAgingInstructions)
266 ? kNoCodeAgeInstructions 233 ? kNoCodeAgeInstructions
267 : kCodeAgingInstructions); 234 : kCodeAgingInstructions);
268 static const int kNoCodeAgeSequenceNops = 235 static const int kNoCodeAgeSequenceNops =
269 (kNoCodeAgeSequenceInstructions - kNoCodeAgeInstructions); 236 (kNoCodeAgeSequenceInstructions - kNoCodeAgeInstructions);
270 static const int kCodeAgingSequenceNops = 237 static const int kCodeAgingSequenceNops =
271 (kNoCodeAgeSequenceInstructions - kCodeAgingInstructions); 238 (kNoCodeAgeSequenceInstructions - kCodeAgingInstructions);
272 static const int kCodeAgingTargetDelta = 1 * Assembler::kInstrSize; 239 static const int kCodeAgingTargetDelta = 1 * Assembler::kInstrSize;
273 static const int kNoCodeAgeSequenceLength = 240 static const int kNoCodeAgeSequenceLength =
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 CheckBuffer(); 441 CheckBuffer();
475 *reinterpret_cast<Instr*>(pc_) = x; 442 *reinterpret_cast<Instr*>(pc_) = x;
476 pc_ += kInstrSize; 443 pc_ += kInstrSize;
477 CheckTrampolinePoolQuick(); 444 CheckTrampolinePoolQuick();
478 } 445 }
479 446
480 bool Operand::is_reg() const { return rm_.is_valid(); } 447 bool Operand::is_reg() const { return rm_.is_valid(); }
481 448
482 449
483 // Fetch the 32bit value from the FIXED_SEQUENCE lis/ori 450 // Fetch the 32bit value from the FIXED_SEQUENCE lis/ori
484 Address Assembler::target_address_at(Address pc, Address constant_pool) { 451 Address Assembler::target_address_at(Address pc,
485 if (FLAG_enable_embedded_constant_pool && constant_pool) { 452 ConstantPoolArray* constant_pool) {
486 ConstantPoolEntry::Access access;
487 if (IsConstantPoolLoadStart(pc, &access))
488 return Memory::Address_at(target_constant_pool_address_at(
489 pc, constant_pool, access, ConstantPoolEntry::INTPTR));
490 }
491
492 Instr instr1 = instr_at(pc); 453 Instr instr1 = instr_at(pc);
493 Instr instr2 = instr_at(pc + kInstrSize); 454 Instr instr2 = instr_at(pc + kInstrSize);
494 // Interpret 2 instructions generated by lis/ori 455 // Interpret 2 instructions generated by lis/ori
495 if (IsLis(instr1) && IsOri(instr2)) { 456 if (IsLis(instr1) && IsOri(instr2)) {
496 #if V8_TARGET_ARCH_PPC64 457 #if V8_TARGET_ARCH_PPC64
497 Instr instr4 = instr_at(pc + (3 * kInstrSize)); 458 Instr instr4 = instr_at(pc + (3 * kInstrSize));
498 Instr instr5 = instr_at(pc + (4 * kInstrSize)); 459 Instr instr5 = instr_at(pc + (4 * kInstrSize));
499 // Assemble the 64 bit value. 460 // Assemble the 64 bit value.
500 uint64_t hi = (static_cast<uint32_t>((instr1 & kImm16Mask) << 16) | 461 uint64_t hi = (static_cast<uint32_t>((instr1 & kImm16Mask) << 16) |
501 static_cast<uint32_t>(instr2 & kImm16Mask)); 462 static_cast<uint32_t>(instr2 & kImm16Mask));
502 uint64_t lo = (static_cast<uint32_t>((instr4 & kImm16Mask) << 16) | 463 uint64_t lo = (static_cast<uint32_t>((instr4 & kImm16Mask) << 16) |
503 static_cast<uint32_t>(instr5 & kImm16Mask)); 464 static_cast<uint32_t>(instr5 & kImm16Mask));
504 return reinterpret_cast<Address>((hi << 32) | lo); 465 return reinterpret_cast<Address>((hi << 32) | lo);
505 #else 466 #else
506 // Assemble the 32 bit value. 467 // Assemble the 32 bit value.
507 return reinterpret_cast<Address>(((instr1 & kImm16Mask) << 16) | 468 return reinterpret_cast<Address>(((instr1 & kImm16Mask) << 16) |
508 (instr2 & kImm16Mask)); 469 (instr2 & kImm16Mask));
509 #endif 470 #endif
510 } 471 }
511 472
512 UNREACHABLE(); 473 UNREACHABLE();
513 return NULL; 474 return NULL;
514 } 475 }
515 476
516 477
517 #if V8_TARGET_ARCH_PPC64
518 const int kLoadIntptrOpcode = LD;
519 #else
520 const int kLoadIntptrOpcode = LWZ;
521 #endif
522
523 // Constant pool load sequence detection:
524 // 1) REGULAR access:
525 // load <dst>, kConstantPoolRegister + <offset>
526 //
527 // 2) OVERFLOWED access:
528 // addis <scratch>, kConstantPoolRegister, <offset_high>
529 // load <dst>, <scratch> + <offset_low>
530 bool Assembler::IsConstantPoolLoadStart(Address pc,
531 ConstantPoolEntry::Access* access) {
532 Instr instr = instr_at(pc);
533 int opcode = instr & kOpcodeMask;
534 if (!GetRA(instr).is(kConstantPoolRegister)) return false;
535 bool overflowed = (opcode == ADDIS);
536 #ifdef DEBUG
537 if (overflowed) {
538 opcode = instr_at(pc + kInstrSize) & kOpcodeMask;
539 }
540 DCHECK(opcode == kLoadIntptrOpcode || opcode == LFD);
541 #endif
542 if (access) {
543 *access = (overflowed ? ConstantPoolEntry::OVERFLOWED
544 : ConstantPoolEntry::REGULAR);
545 }
546 return true;
547 }
548
549
550 bool Assembler::IsConstantPoolLoadEnd(Address pc,
551 ConstantPoolEntry::Access* access) {
552 Instr instr = instr_at(pc);
553 int opcode = instr & kOpcodeMask;
554 if (!(opcode == kLoadIntptrOpcode || opcode == LFD)) return false;
555 bool overflowed = !GetRA(instr).is(kConstantPoolRegister);
556 #ifdef DEBUG
557 if (overflowed) {
558 instr = instr_at(pc - kInstrSize);
559 opcode = instr & kOpcodeMask;
560 DCHECK((opcode == ADDIS) && GetRA(instr).is(kConstantPoolRegister));
561 }
562 #endif
563 if (access) {
564 *access = (overflowed ? ConstantPoolEntry::OVERFLOWED
565 : ConstantPoolEntry::REGULAR);
566 }
567 return true;
568 }
569
570
571 int Assembler::GetConstantPoolOffset(Address pc,
572 ConstantPoolEntry::Access access,
573 ConstantPoolEntry::Type type) {
574 bool overflowed = (access == ConstantPoolEntry::OVERFLOWED);
575 #ifdef DEBUG
576 ConstantPoolEntry::Access access_check;
577 DCHECK(IsConstantPoolLoadStart(pc, &access_check));
578 DCHECK(access_check == access);
579 #endif
580 int offset;
581 if (overflowed) {
582 offset = (instr_at(pc) & kImm16Mask) << 16;
583 offset += SIGN_EXT_IMM16(instr_at(pc + kInstrSize) & kImm16Mask);
584 DCHECK(!is_int16(offset));
585 } else {
586 offset = SIGN_EXT_IMM16((instr_at(pc) & kImm16Mask));
587 }
588 return offset;
589 }
590
591
592 void Assembler::PatchConstantPoolAccessInstruction(
593 int pc_offset, int offset, ConstantPoolEntry::Access access,
594 ConstantPoolEntry::Type type) {
595 Address pc = buffer_ + pc_offset;
596 bool overflowed = (access == ConstantPoolEntry::OVERFLOWED);
597 #ifdef DEBUG
598 ConstantPoolEntry::Access access_check;
599 DCHECK(IsConstantPoolLoadStart(pc, &access_check));
600 DCHECK(access_check == access);
601 DCHECK(overflowed != is_int16(offset));
602 #endif
603 if (overflowed) {
604 int hi_word = static_cast<int>(offset >> 16);
605 int lo_word = static_cast<int>(offset & 0xffff);
606 if (lo_word & 0x8000) hi_word++;
607
608 Instr instr1 = instr_at(pc);
609 Instr instr2 = instr_at(pc + kInstrSize);
610 instr1 &= ~kImm16Mask;
611 instr1 |= (hi_word & kImm16Mask);
612 instr2 &= ~kImm16Mask;
613 instr2 |= (lo_word & kImm16Mask);
614 instr_at_put(pc, instr1);
615 instr_at_put(pc + kInstrSize, instr2);
616 } else {
617 Instr instr = instr_at(pc);
618 instr &= ~kImm16Mask;
619 instr |= (offset & kImm16Mask);
620 instr_at_put(pc, instr);
621 }
622 }
623
624
625 Address Assembler::target_constant_pool_address_at(
626 Address pc, Address constant_pool, ConstantPoolEntry::Access access,
627 ConstantPoolEntry::Type type) {
628 Address addr = constant_pool;
629 DCHECK(addr);
630 addr += GetConstantPoolOffset(pc, access, type);
631 return addr;
632 }
633
634
635 // This sets the branch destination (which gets loaded at the call address). 478 // This sets the branch destination (which gets loaded at the call address).
636 // This is for calls and branches within generated code. The serializer 479 // This is for calls and branches within generated code. The serializer
637 // has already deserialized the mov instructions etc. 480 // has already deserialized the mov instructions etc.
638 // There is a FIXED_SEQUENCE assumption here 481 // There is a FIXED_SEQUENCE assumption here
639 void Assembler::deserialization_set_special_target_at( 482 void Assembler::deserialization_set_special_target_at(
640 Address instruction_payload, Code* code, Address target) { 483 Address instruction_payload, Code* code, Address target) {
641 set_target_address_at(instruction_payload, code, target); 484 set_target_address_at(instruction_payload, code, target);
642 } 485 }
643 486
644 487
645 void Assembler::deserialization_set_target_internal_reference_at( 488 void Assembler::deserialization_set_target_internal_reference_at(
646 Address pc, Address target, RelocInfo::Mode mode) { 489 Address pc, Address target, RelocInfo::Mode mode) {
647 if (RelocInfo::IsInternalReferenceEncoded(mode)) { 490 if (RelocInfo::IsInternalReferenceEncoded(mode)) {
648 Code* code = NULL; 491 Code* code = NULL;
649 set_target_address_at(pc, code, target, SKIP_ICACHE_FLUSH); 492 set_target_address_at(pc, code, target, SKIP_ICACHE_FLUSH);
650 } else { 493 } else {
651 Memory::Address_at(pc) = target; 494 Memory::Address_at(pc) = target;
652 } 495 }
653 } 496 }
654 497
655 498
656 // This code assumes the FIXED_SEQUENCE of lis/ori 499 // This code assumes the FIXED_SEQUENCE of lis/ori
657 void Assembler::set_target_address_at(Address pc, Address constant_pool, 500 void Assembler::set_target_address_at(Address pc,
501 ConstantPoolArray* constant_pool,
658 Address target, 502 Address target,
659 ICacheFlushMode icache_flush_mode) { 503 ICacheFlushMode icache_flush_mode) {
660 if (FLAG_enable_embedded_constant_pool && constant_pool) {
661 ConstantPoolEntry::Access access;
662 if (IsConstantPoolLoadStart(pc, &access)) {
663 Memory::Address_at(target_constant_pool_address_at(
664 pc, constant_pool, access, ConstantPoolEntry::INTPTR)) = target;
665 return;
666 }
667 }
668
669 Instr instr1 = instr_at(pc); 504 Instr instr1 = instr_at(pc);
670 Instr instr2 = instr_at(pc + kInstrSize); 505 Instr instr2 = instr_at(pc + kInstrSize);
671 // Interpret 2 instructions generated by lis/ori 506 // Interpret 2 instructions generated by lis/ori
672 if (IsLis(instr1) && IsOri(instr2)) { 507 if (IsLis(instr1) && IsOri(instr2)) {
673 #if V8_TARGET_ARCH_PPC64 508 #if V8_TARGET_ARCH_PPC64
674 Instr instr4 = instr_at(pc + (3 * kInstrSize)); 509 Instr instr4 = instr_at(pc + (3 * kInstrSize));
675 Instr instr5 = instr_at(pc + (4 * kInstrSize)); 510 Instr instr5 = instr_at(pc + (4 * kInstrSize));
676 // Needs to be fixed up when mov changes to handle 64-bit values. 511 // Needs to be fixed up when mov changes to handle 64-bit values.
677 uint32_t* p = reinterpret_cast<uint32_t*>(pc); 512 uint32_t* p = reinterpret_cast<uint32_t*>(pc);
678 uintptr_t itarget = reinterpret_cast<uintptr_t>(target); 513 uintptr_t itarget = reinterpret_cast<uintptr_t>(target);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 } 552 }
718 #endif 553 #endif
719 return; 554 return;
720 } 555 }
721 UNREACHABLE(); 556 UNREACHABLE();
722 } 557 }
723 } 558 }
724 } // namespace v8::internal 559 } // namespace v8::internal
725 560
726 #endif // V8_PPC_ASSEMBLER_PPC_INL_H_ 561 #endif // V8_PPC_ASSEMBLER_PPC_INL_H_
OLDNEW
« no previous file with comments | « src/ppc/assembler-ppc.cc ('k') | src/ppc/builtins-ppc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698