OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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_ |
OLD | NEW |