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

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

Issue 1030353003: Enable constant pool support. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 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
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 return (pc_ >= constant_pool)
122 ? pc_
123 : Assembler::target_constant_pool_address_at(pc_, constant_pool);
124 }
111 UNREACHABLE(); 125 UNREACHABLE();
112 return NULL; 126 return NULL;
113 } 127 }
114 128
115 129
116 int RelocInfo::target_address_size() { return Assembler::kSpecialTargetSize; } 130 int RelocInfo::target_address_size() { return Assembler::kSpecialTargetSize; }
117 131
118 132
119 void RelocInfo::set_target_address(Address target, 133 void RelocInfo::set_target_address(Address target,
120 WriteBarrierMode write_barrier_mode, 134 WriteBarrierMode write_barrier_mode,
(...skipping 15 matching lines...) Expand all
136 150
137 151
138 Address Assembler::target_address_from_return_address(Address pc) { 152 Address Assembler::target_address_from_return_address(Address pc) {
139 // Returns the address of the call target from the return address that will 153 // Returns the address of the call target from the return address that will
140 // be returned to after a call. 154 // be returned to after a call.
141 // Call sequence is : 155 // Call sequence is :
142 // mov ip, @ call address 156 // mov ip, @ call address
143 // mtlr ip 157 // mtlr ip
144 // blrl 158 // blrl
145 // @ return address 159 // @ return address
146 return pc - (kMovInstructions + 2) * kInstrSize; 160 if (FLAG_enable_embedded_constant_pool &&
161 IsConstantPoolLoadEnd(pc - 3 * kInstrSize)) {
162 return pc - (kMovInstructionsConstantPool + 2) * kInstrSize;
163 }
164 return pc - (kMovInstructionsNoConstantPool + 2) * kInstrSize;
147 } 165 }
148 166
149 167
150 Address Assembler::return_address_from_call_start(Address pc) { 168 Address Assembler::return_address_from_call_start(Address pc) {
151 return pc + (kMovInstructions + 2) * kInstrSize; 169 if (FLAG_enable_embedded_constant_pool) {
170 Address load_address = pc + (kMovInstructionsConstantPool - 1) * kInstrSize;
171 if (IsConstantPoolLoadEnd(load_address))
172 return pc + (kMovInstructionsConstantPool + 2) * kInstrSize;
173 }
174 return pc + (kMovInstructionsNoConstantPool + 2) * kInstrSize;
152 } 175 }
153 176
154 177
155 Object* RelocInfo::target_object() { 178 Object* RelocInfo::target_object() {
156 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 179 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
157 return reinterpret_cast<Object*>(Assembler::target_address_at(pc_, host_)); 180 return reinterpret_cast<Object*>(Assembler::target_address_at(pc_, host_));
158 } 181 }
159 182
160 183
161 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) { 184 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; 242 Address address = cell->address() + Cell::kValueOffset;
220 Memory::Address_at(pc_) = address; 243 Memory::Address_at(pc_) = address;
221 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) { 244 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 245 // TODO(1550) We are passing NULL as a slot because cell can never be on
223 // evacuation candidate. 246 // evacuation candidate.
224 host()->GetHeap()->incremental_marking()->RecordWrite(host(), NULL, cell); 247 host()->GetHeap()->incremental_marking()->RecordWrite(host(), NULL, cell);
225 } 248 }
226 } 249 }
227 250
228 251
229 static const int kNoCodeAgeInstructions = 6; 252 static const int kNoCodeAgeInstructions =
230 static const int kCodeAgingInstructions = Assembler::kMovInstructions + 3; 253 FLAG_enable_embedded_constant_pool ? 7 : 6;
254 static const int kCodeAgingInstructions =
255 Assembler::kMovInstructionsNoConstantPool + 3;
231 static const int kNoCodeAgeSequenceInstructions = 256 static const int kNoCodeAgeSequenceInstructions =
232 ((kNoCodeAgeInstructions >= kCodeAgingInstructions) 257 ((kNoCodeAgeInstructions >= kCodeAgingInstructions)
233 ? kNoCodeAgeInstructions 258 ? kNoCodeAgeInstructions
234 : kCodeAgingInstructions); 259 : kCodeAgingInstructions);
235 static const int kNoCodeAgeSequenceNops = 260 static const int kNoCodeAgeSequenceNops =
236 (kNoCodeAgeSequenceInstructions - kNoCodeAgeInstructions); 261 (kNoCodeAgeSequenceInstructions - kNoCodeAgeInstructions);
237 static const int kCodeAgingSequenceNops = 262 static const int kCodeAgingSequenceNops =
238 (kNoCodeAgeSequenceInstructions - kCodeAgingInstructions); 263 (kNoCodeAgeSequenceInstructions - kCodeAgingInstructions);
239 static const int kCodeAgingTargetDelta = 1 * Assembler::kInstrSize; 264 static const int kCodeAgingTargetDelta = 1 * Assembler::kInstrSize;
240 static const int kNoCodeAgeSequenceLength = 265 static const int kNoCodeAgeSequenceLength =
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 CheckBuffer(); 466 CheckBuffer();
442 *reinterpret_cast<Instr*>(pc_) = x; 467 *reinterpret_cast<Instr*>(pc_) = x;
443 pc_ += kInstrSize; 468 pc_ += kInstrSize;
444 CheckTrampolinePoolQuick(); 469 CheckTrampolinePoolQuick();
445 } 470 }
446 471
447 bool Operand::is_reg() const { return rm_.is_valid(); } 472 bool Operand::is_reg() const { return rm_.is_valid(); }
448 473
449 474
450 // Fetch the 32bit value from the FIXED_SEQUENCE lis/ori 475 // Fetch the 32bit value from the FIXED_SEQUENCE lis/ori
451 Address Assembler::target_address_at(Address pc, 476 Address Assembler::target_address_at(Address pc, Address constant_pool) {
452 ConstantPoolArray* constant_pool) { 477 if (FLAG_enable_embedded_constant_pool && constant_pool) {
478 if (pc >= constant_pool) return Memory::Address_at(pc);
479 if (IsConstantPoolLoadStart(pc))
480 return Memory::Address_at(
481 target_constant_pool_address_at(pc, constant_pool));
482 }
483
453 Instr instr1 = instr_at(pc); 484 Instr instr1 = instr_at(pc);
454 Instr instr2 = instr_at(pc + kInstrSize); 485 Instr instr2 = instr_at(pc + kInstrSize);
455 // Interpret 2 instructions generated by lis/ori 486 // Interpret 2 instructions generated by lis/ori
456 if (IsLis(instr1) && IsOri(instr2)) { 487 if (IsLis(instr1) && IsOri(instr2)) {
457 #if V8_TARGET_ARCH_PPC64 488 #if V8_TARGET_ARCH_PPC64
458 Instr instr4 = instr_at(pc + (3 * kInstrSize)); 489 Instr instr4 = instr_at(pc + (3 * kInstrSize));
459 Instr instr5 = instr_at(pc + (4 * kInstrSize)); 490 Instr instr5 = instr_at(pc + (4 * kInstrSize));
460 // Assemble the 64 bit value. 491 // Assemble the 64 bit value.
461 uint64_t hi = (static_cast<uint32_t>((instr1 & kImm16Mask) << 16) | 492 uint64_t hi = (static_cast<uint32_t>((instr1 & kImm16Mask) << 16) |
462 static_cast<uint32_t>(instr2 & kImm16Mask)); 493 static_cast<uint32_t>(instr2 & kImm16Mask));
463 uint64_t lo = (static_cast<uint32_t>((instr4 & kImm16Mask) << 16) | 494 uint64_t lo = (static_cast<uint32_t>((instr4 & kImm16Mask) << 16) |
464 static_cast<uint32_t>(instr5 & kImm16Mask)); 495 static_cast<uint32_t>(instr5 & kImm16Mask));
465 return reinterpret_cast<Address>((hi << 32) | lo); 496 return reinterpret_cast<Address>((hi << 32) | lo);
466 #else 497 #else
467 // Assemble the 32 bit value. 498 // Assemble the 32 bit value.
468 return reinterpret_cast<Address>(((instr1 & kImm16Mask) << 16) | 499 return reinterpret_cast<Address>(((instr1 & kImm16Mask) << 16) |
469 (instr2 & kImm16Mask)); 500 (instr2 & kImm16Mask));
470 #endif 501 #endif
471 } 502 }
472 503
473 UNREACHABLE(); 504 UNREACHABLE();
474 return NULL; 505 return NULL;
475 } 506 }
476 507
477 508
509 bool Assembler::IsConstantPoolLoadStart(Address pc) {
510 return GetRA(instr_at(pc)).is(kConstantPoolRegister);
511 }
512
513
514 bool Assembler::IsConstantPoolLoadEnd(Address pc) {
515 return IsConstantPoolLoadStart(pc);
516 }
517
518
519 int Assembler::GetConstantPoolOffset(Address pc) {
520 DCHECK(IsConstantPoolLoadStart(pc));
521 Instr instr = instr_at(pc);
522 int offset = SIGN_EXT_IMM16((instr & kImm16Mask));
523 return offset;
524 }
525
526
527 void Assembler::SetConstantPoolOffset(int pos, int offset) {
528 Address pc = buffer_ + pos;
529 DCHECK(IsConstantPoolLoadStart(pc));
530 DCHECK(is_int16(offset));
531 Instr instr = instr_at(pc);
532 instr &= ~kImm16Mask;
533 instr |= (offset & kImm16Mask);
534 instr_at_put(pc, instr);
535 }
536
537
538 Address Assembler::target_constant_pool_address_at(Address pc,
539 Address constant_pool) {
540 Address addr = constant_pool;
541 DCHECK(addr);
542 addr += GetConstantPoolOffset(pc);
543 return addr;
544 }
545
546
478 // This sets the branch destination (which gets loaded at the call address). 547 // This sets the branch destination (which gets loaded at the call address).
479 // This is for calls and branches within generated code. The serializer 548 // This is for calls and branches within generated code. The serializer
480 // has already deserialized the mov instructions etc. 549 // has already deserialized the mov instructions etc.
481 // There is a FIXED_SEQUENCE assumption here 550 // There is a FIXED_SEQUENCE assumption here
482 void Assembler::deserialization_set_special_target_at( 551 void Assembler::deserialization_set_special_target_at(
483 Address instruction_payload, Code* code, Address target) { 552 Address instruction_payload, Code* code, Address target) {
484 set_target_address_at(instruction_payload, code, target); 553 set_target_address_at(instruction_payload, code, target);
485 } 554 }
486 555
487 556
488 void Assembler::deserialization_set_target_internal_reference_at( 557 void Assembler::deserialization_set_target_internal_reference_at(
489 Address pc, Address target, RelocInfo::Mode mode) { 558 Address pc, Address target, RelocInfo::Mode mode) {
490 if (RelocInfo::IsInternalReferenceEncoded(mode)) { 559 if (RelocInfo::IsInternalReferenceEncoded(mode)) {
491 Code* code = NULL; 560 Code* code = NULL;
492 set_target_address_at(pc, code, target, SKIP_ICACHE_FLUSH); 561 set_target_address_at(pc, code, target, SKIP_ICACHE_FLUSH);
493 } else { 562 } else {
494 Memory::Address_at(pc) = target; 563 Memory::Address_at(pc) = target;
495 } 564 }
496 } 565 }
497 566
498 567
499 // This code assumes the FIXED_SEQUENCE of lis/ori 568 // This code assumes the FIXED_SEQUENCE of lis/ori
500 void Assembler::set_target_address_at(Address pc, 569 void Assembler::set_target_address_at(Address pc, Address constant_pool,
501 ConstantPoolArray* constant_pool,
502 Address target, 570 Address target,
503 ICacheFlushMode icache_flush_mode) { 571 ICacheFlushMode icache_flush_mode) {
572 if (FLAG_enable_embedded_constant_pool && constant_pool) {
573 if (pc >= constant_pool) {
574 Memory::Address_at(pc) = target;
rmcilroy 2015/04/08 12:38:55 What is this branch for? It looks like pc is point
MTBrandyberry 2015/05/07 20:38:32 I was experimenting at one point with associating
575 return;
576 }
577 if (IsConstantPoolLoadStart(pc)) {
578 Memory::Address_at(target_constant_pool_address_at(pc, constant_pool)) =
579 target;
580 return;
581 }
582 }
583
504 Instr instr1 = instr_at(pc); 584 Instr instr1 = instr_at(pc);
505 Instr instr2 = instr_at(pc + kInstrSize); 585 Instr instr2 = instr_at(pc + kInstrSize);
506 // Interpret 2 instructions generated by lis/ori 586 // Interpret 2 instructions generated by lis/ori
507 if (IsLis(instr1) && IsOri(instr2)) { 587 if (IsLis(instr1) && IsOri(instr2)) {
508 #if V8_TARGET_ARCH_PPC64 588 #if V8_TARGET_ARCH_PPC64
509 Instr instr4 = instr_at(pc + (3 * kInstrSize)); 589 Instr instr4 = instr_at(pc + (3 * kInstrSize));
510 Instr instr5 = instr_at(pc + (4 * kInstrSize)); 590 Instr instr5 = instr_at(pc + (4 * kInstrSize));
511 // Needs to be fixed up when mov changes to handle 64-bit values. 591 // Needs to be fixed up when mov changes to handle 64-bit values.
512 uint32_t* p = reinterpret_cast<uint32_t*>(pc); 592 uint32_t* p = reinterpret_cast<uint32_t*>(pc);
513 uintptr_t itarget = reinterpret_cast<uintptr_t>(target); 593 uintptr_t itarget = reinterpret_cast<uintptr_t>(target);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 } 632 }
553 #endif 633 #endif
554 return; 634 return;
555 } 635 }
556 UNREACHABLE(); 636 UNREACHABLE();
557 } 637 }
558 } 638 }
559 } // namespace v8::internal 639 } // namespace v8::internal
560 640
561 #endif // V8_PPC_ASSEMBLER_PPC_INL_H_ 641 #endif // V8_PPC_ASSEMBLER_PPC_INL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698