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

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

Issue 1131783003: Embedded constant pools. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix debug-mode Arm issue. 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
97 // Read the address of the word containing the target_address in an 104 // Read the address of the word containing the target_address in an
98 // instruction stream. 105 // instruction stream.
99 // The only architecture-independent user of this function is the serializer. 106 // The only architecture-independent user of this function is the serializer.
100 // The serializer uses it to find out how many raw bytes of instruction to 107 // The serializer uses it to find out how many raw bytes of instruction to
101 // output before the next target. 108 // output before the next target.
102 // For an instruction like LIS/ORI where the target bits are mixed into the 109 // For an instruction like LIS/ORI where the target bits are mixed into the
103 // instruction bits, the size of the target will be zero, indicating that the 110 // instruction bits, the size of the target will be zero, indicating that the
104 // serializer should not step forward in memory after a target is resolved 111 // serializer should not step forward in memory after a target is resolved
105 // and written. 112 // and written.
106 return reinterpret_cast<Address>(pc_); 113 return reinterpret_cast<Address>(pc_);
107 } 114 }
108 115
109 116
110 Address RelocInfo::constant_pool_entry_address() { 117 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 }
111 UNREACHABLE(); 126 UNREACHABLE();
112 return NULL; 127 return NULL;
113 } 128 }
114 129
115 130
116 int RelocInfo::target_address_size() { return Assembler::kSpecialTargetSize; } 131 int RelocInfo::target_address_size() { return Assembler::kSpecialTargetSize; }
117 132
118 133
119 void RelocInfo::set_target_address(Address target, 134 void RelocInfo::set_target_address(Address target,
120 WriteBarrierMode write_barrier_mode, 135 WriteBarrierMode write_barrier_mode,
(...skipping 15 matching lines...) Expand all
136 151
137 152
138 Address Assembler::target_address_from_return_address(Address pc) { 153 Address Assembler::target_address_from_return_address(Address pc) {
139 // Returns the address of the call target from the return address that will 154 // Returns the address of the call target from the return address that will
140 // be returned to after a call. 155 // be returned to after a call.
141 // Call sequence is : 156 // Call sequence is :
142 // mov ip, @ call address 157 // mov ip, @ call address
143 // mtlr ip 158 // mtlr ip
144 // blrl 159 // blrl
145 // @ return address 160 // @ return address
146 return pc - (kMovInstructions + 2) * kInstrSize; 161 int len;
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;
147 } 170 }
148 171
149 172
150 Address Assembler::return_address_from_call_start(Address pc) { 173 Address Assembler::return_address_from_call_start(Address pc) {
151 return pc + (kMovInstructions + 2) * kInstrSize; 174 int len;
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;
152 } 183 }
153 184
154 185
155 Object* RelocInfo::target_object() { 186 Object* RelocInfo::target_object() {
156 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 187 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
157 return reinterpret_cast<Object*>(Assembler::target_address_at(pc_, host_)); 188 return reinterpret_cast<Object*>(Assembler::target_address_at(pc_, host_));
158 } 189 }
159 190
160 191
161 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) { 192 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 Address address = cell->address() + Cell::kValueOffset; 250 Address address = cell->address() + Cell::kValueOffset;
220 Memory::Address_at(pc_) = address; 251 Memory::Address_at(pc_) = address;
221 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) { 252 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) {
222 // TODO(1550) We are passing NULL as a slot because cell can never be on 253 // TODO(1550) We are passing NULL as a slot because cell can never be on
223 // evacuation candidate. 254 // evacuation candidate.
224 host()->GetHeap()->incremental_marking()->RecordWrite(host(), NULL, cell); 255 host()->GetHeap()->incremental_marking()->RecordWrite(host(), NULL, cell);
225 } 256 }
226 } 257 }
227 258
228 259
229 static const int kNoCodeAgeInstructions = 6; 260 static const int kNoCodeAgeInstructions =
230 static const int kCodeAgingInstructions = Assembler::kMovInstructions + 3; 261 FLAG_enable_embedded_constant_pool ? 7 : 6;
262 static const int kCodeAgingInstructions =
263 Assembler::kMovInstructionsNoConstantPool + 3;
231 static const int kNoCodeAgeSequenceInstructions = 264 static const int kNoCodeAgeSequenceInstructions =
232 ((kNoCodeAgeInstructions >= kCodeAgingInstructions) 265 ((kNoCodeAgeInstructions >= kCodeAgingInstructions)
233 ? kNoCodeAgeInstructions 266 ? kNoCodeAgeInstructions
234 : kCodeAgingInstructions); 267 : kCodeAgingInstructions);
235 static const int kNoCodeAgeSequenceNops = 268 static const int kNoCodeAgeSequenceNops =
236 (kNoCodeAgeSequenceInstructions - kNoCodeAgeInstructions); 269 (kNoCodeAgeSequenceInstructions - kNoCodeAgeInstructions);
237 static const int kCodeAgingSequenceNops = 270 static const int kCodeAgingSequenceNops =
238 (kNoCodeAgeSequenceInstructions - kCodeAgingInstructions); 271 (kNoCodeAgeSequenceInstructions - kCodeAgingInstructions);
239 static const int kCodeAgingTargetDelta = 1 * Assembler::kInstrSize; 272 static const int kCodeAgingTargetDelta = 1 * Assembler::kInstrSize;
240 static const int kNoCodeAgeSequenceLength = 273 static const int kNoCodeAgeSequenceLength =
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 CheckBuffer(); 474 CheckBuffer();
442 *reinterpret_cast<Instr*>(pc_) = x; 475 *reinterpret_cast<Instr*>(pc_) = x;
443 pc_ += kInstrSize; 476 pc_ += kInstrSize;
444 CheckTrampolinePoolQuick(); 477 CheckTrampolinePoolQuick();
445 } 478 }
446 479
447 bool Operand::is_reg() const { return rm_.is_valid(); } 480 bool Operand::is_reg() const { return rm_.is_valid(); }
448 481
449 482
450 // Fetch the 32bit value from the FIXED_SEQUENCE lis/ori 483 // Fetch the 32bit value from the FIXED_SEQUENCE lis/ori
451 Address Assembler::target_address_at(Address pc, 484 Address Assembler::target_address_at(Address pc, Address constant_pool) {
452 ConstantPoolArray* constant_pool) { 485 if (FLAG_enable_embedded_constant_pool && 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
453 Instr instr1 = instr_at(pc); 492 Instr instr1 = instr_at(pc);
454 Instr instr2 = instr_at(pc + kInstrSize); 493 Instr instr2 = instr_at(pc + kInstrSize);
455 // Interpret 2 instructions generated by lis/ori 494 // Interpret 2 instructions generated by lis/ori
456 if (IsLis(instr1) && IsOri(instr2)) { 495 if (IsLis(instr1) && IsOri(instr2)) {
457 #if V8_TARGET_ARCH_PPC64 496 #if V8_TARGET_ARCH_PPC64
458 Instr instr4 = instr_at(pc + (3 * kInstrSize)); 497 Instr instr4 = instr_at(pc + (3 * kInstrSize));
459 Instr instr5 = instr_at(pc + (4 * kInstrSize)); 498 Instr instr5 = instr_at(pc + (4 * kInstrSize));
460 // Assemble the 64 bit value. 499 // Assemble the 64 bit value.
461 uint64_t hi = (static_cast<uint32_t>((instr1 & kImm16Mask) << 16) | 500 uint64_t hi = (static_cast<uint32_t>((instr1 & kImm16Mask) << 16) |
462 static_cast<uint32_t>(instr2 & kImm16Mask)); 501 static_cast<uint32_t>(instr2 & kImm16Mask));
463 uint64_t lo = (static_cast<uint32_t>((instr4 & kImm16Mask) << 16) | 502 uint64_t lo = (static_cast<uint32_t>((instr4 & kImm16Mask) << 16) |
464 static_cast<uint32_t>(instr5 & kImm16Mask)); 503 static_cast<uint32_t>(instr5 & kImm16Mask));
465 return reinterpret_cast<Address>((hi << 32) | lo); 504 return reinterpret_cast<Address>((hi << 32) | lo);
466 #else 505 #else
467 // Assemble the 32 bit value. 506 // Assemble the 32 bit value.
468 return reinterpret_cast<Address>(((instr1 & kImm16Mask) << 16) | 507 return reinterpret_cast<Address>(((instr1 & kImm16Mask) << 16) |
469 (instr2 & kImm16Mask)); 508 (instr2 & kImm16Mask));
470 #endif 509 #endif
471 } 510 }
472 511
473 UNREACHABLE(); 512 UNREACHABLE();
474 return NULL; 513 return NULL;
475 } 514 }
476 515
477 516
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
478 // This sets the branch destination (which gets loaded at the call address). 635 // This sets the branch destination (which gets loaded at the call address).
479 // This is for calls and branches within generated code. The serializer 636 // This is for calls and branches within generated code. The serializer
480 // has already deserialized the mov instructions etc. 637 // has already deserialized the mov instructions etc.
481 // There is a FIXED_SEQUENCE assumption here 638 // There is a FIXED_SEQUENCE assumption here
482 void Assembler::deserialization_set_special_target_at( 639 void Assembler::deserialization_set_special_target_at(
483 Address instruction_payload, Code* code, Address target) { 640 Address instruction_payload, Code* code, Address target) {
484 set_target_address_at(instruction_payload, code, target); 641 set_target_address_at(instruction_payload, code, target);
485 } 642 }
486 643
487 644
488 void Assembler::deserialization_set_target_internal_reference_at( 645 void Assembler::deserialization_set_target_internal_reference_at(
489 Address pc, Address target, RelocInfo::Mode mode) { 646 Address pc, Address target, RelocInfo::Mode mode) {
490 if (RelocInfo::IsInternalReferenceEncoded(mode)) { 647 if (RelocInfo::IsInternalReferenceEncoded(mode)) {
491 Code* code = NULL; 648 Code* code = NULL;
492 set_target_address_at(pc, code, target, SKIP_ICACHE_FLUSH); 649 set_target_address_at(pc, code, target, SKIP_ICACHE_FLUSH);
493 } else { 650 } else {
494 Memory::Address_at(pc) = target; 651 Memory::Address_at(pc) = target;
495 } 652 }
496 } 653 }
497 654
498 655
499 // This code assumes the FIXED_SEQUENCE of lis/ori 656 // This code assumes the FIXED_SEQUENCE of lis/ori
500 void Assembler::set_target_address_at(Address pc, 657 void Assembler::set_target_address_at(Address pc, Address constant_pool,
501 ConstantPoolArray* constant_pool,
502 Address target, 658 Address target,
503 ICacheFlushMode icache_flush_mode) { 659 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
504 Instr instr1 = instr_at(pc); 669 Instr instr1 = instr_at(pc);
505 Instr instr2 = instr_at(pc + kInstrSize); 670 Instr instr2 = instr_at(pc + kInstrSize);
506 // Interpret 2 instructions generated by lis/ori 671 // Interpret 2 instructions generated by lis/ori
507 if (IsLis(instr1) && IsOri(instr2)) { 672 if (IsLis(instr1) && IsOri(instr2)) {
508 #if V8_TARGET_ARCH_PPC64 673 #if V8_TARGET_ARCH_PPC64
509 Instr instr4 = instr_at(pc + (3 * kInstrSize)); 674 Instr instr4 = instr_at(pc + (3 * kInstrSize));
510 Instr instr5 = instr_at(pc + (4 * kInstrSize)); 675 Instr instr5 = instr_at(pc + (4 * kInstrSize));
511 // Needs to be fixed up when mov changes to handle 64-bit values. 676 // Needs to be fixed up when mov changes to handle 64-bit values.
512 uint32_t* p = reinterpret_cast<uint32_t*>(pc); 677 uint32_t* p = reinterpret_cast<uint32_t*>(pc);
513 uintptr_t itarget = reinterpret_cast<uintptr_t>(target); 678 uintptr_t itarget = reinterpret_cast<uintptr_t>(target);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 } 717 }
553 #endif 718 #endif
554 return; 719 return;
555 } 720 }
556 UNREACHABLE(); 721 UNREACHABLE();
557 } 722 }
558 } 723 }
559 } // namespace v8::internal 724 } // namespace v8::internal
560 725
561 #endif // V8_PPC_ASSEMBLER_PPC_INL_H_ 726 #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