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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 Address RelocInfo::target_address() { | 62 Address RelocInfo::target_address() { |
63 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 63 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); |
64 return Assembler::target_address_at(pc_, host_); | 64 return Assembler::target_address_at(pc_, host_); |
65 } | 65 } |
66 | 66 |
67 | 67 |
68 Address RelocInfo::target_address_address() { | 68 Address RelocInfo::target_address_address() { |
69 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || | 69 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || |
70 rmode_ == EMBEDDED_OBJECT || rmode_ == EXTERNAL_REFERENCE); | 70 rmode_ == EMBEDDED_OBJECT || rmode_ == EXTERNAL_REFERENCE); |
71 | 71 |
72 #if V8_OOL_CONSTANT_POOL | |
73 if (Assembler::IsConstantPoolLoadStart(pc_)) { | |
74 // We return the PC for ool constant pool since this function is used by the | |
75 // serializerer and expects the address to reside within the code object. | |
76 return reinterpret_cast<Address>(pc_); | |
77 } | |
78 #endif | |
79 | |
80 // Read the address of the word containing the target_address in an | 72 // Read the address of the word containing the target_address in an |
81 // instruction stream. | 73 // instruction stream. |
82 // The only architecture-independent user of this function is the serializer. | 74 // The only architecture-independent user of this function is the serializer. |
83 // The serializer uses it to find out how many raw bytes of instruction to | 75 // The serializer uses it to find out how many raw bytes of instruction to |
84 // output before the next target. | 76 // output before the next target. |
85 // For an instruction like LIS/ORI where the target bits are mixed into the | 77 // For an instruction like LIS/ORI where the target bits are mixed into the |
86 // instruction bits, the size of the target will be zero, indicating that the | 78 // instruction bits, the size of the target will be zero, indicating that the |
87 // serializer should not step forward in memory after a target is resolved | 79 // serializer should not step forward in memory after a target is resolved |
88 // and written. | 80 // and written. |
89 return reinterpret_cast<Address>(pc_); | 81 return reinterpret_cast<Address>(pc_); |
90 } | 82 } |
91 | 83 |
92 | 84 |
93 Address RelocInfo::constant_pool_entry_address() { | 85 Address RelocInfo::constant_pool_entry_address() { |
94 #if V8_OOL_CONSTANT_POOL | |
95 return Assembler::target_constant_pool_address_at(pc_, | |
96 host_->constant_pool()); | |
97 #else | |
98 UNREACHABLE(); | 86 UNREACHABLE(); |
99 return NULL; | 87 return NULL; |
100 #endif | |
101 } | 88 } |
102 | 89 |
103 | 90 |
104 int RelocInfo::target_address_size() { return Assembler::kSpecialTargetSize; } | 91 int RelocInfo::target_address_size() { return Assembler::kSpecialTargetSize; } |
105 | 92 |
106 | 93 |
107 void RelocInfo::set_target_address(Address target, | 94 void RelocInfo::set_target_address(Address target, |
108 WriteBarrierMode write_barrier_mode, | 95 WriteBarrierMode write_barrier_mode, |
109 ICacheFlushMode icache_flush_mode) { | 96 ICacheFlushMode icache_flush_mode) { |
110 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 97 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); |
(...skipping 13 matching lines...) Expand all Loading... |
124 | 111 |
125 | 112 |
126 Address Assembler::target_address_from_return_address(Address pc) { | 113 Address Assembler::target_address_from_return_address(Address pc) { |
127 // Returns the address of the call target from the return address that will | 114 // Returns the address of the call target from the return address that will |
128 // be returned to after a call. | 115 // be returned to after a call. |
129 // Call sequence is : | 116 // Call sequence is : |
130 // mov ip, @ call address | 117 // mov ip, @ call address |
131 // mtlr ip | 118 // mtlr ip |
132 // blrl | 119 // blrl |
133 // @ return address | 120 // @ return address |
134 #if V8_OOL_CONSTANT_POOL | 121 return pc - (kMovInstructions + 2) * kInstrSize; |
135 if (IsConstantPoolLoadEnd(pc - 3 * kInstrSize)) { | |
136 return pc - (kMovInstructionsConstantPool + 2) * kInstrSize; | |
137 } | |
138 #endif | |
139 return pc - (kMovInstructionsNoConstantPool + 2) * kInstrSize; | |
140 } | 122 } |
141 | 123 |
142 | 124 |
143 Address Assembler::return_address_from_call_start(Address pc) { | 125 Address Assembler::return_address_from_call_start(Address pc) { |
144 #if V8_OOL_CONSTANT_POOL | 126 return pc + (kMovInstructions + 2) * kInstrSize; |
145 Address load_address = pc + (kMovInstructionsConstantPool - 1) * kInstrSize; | |
146 if (IsConstantPoolLoadEnd(load_address)) | |
147 return pc + (kMovInstructionsConstantPool + 2) * kInstrSize; | |
148 #endif | |
149 return pc + (kMovInstructionsNoConstantPool + 2) * kInstrSize; | |
150 } | 127 } |
151 | 128 |
152 | 129 |
153 Object* RelocInfo::target_object() { | 130 Object* RelocInfo::target_object() { |
154 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 131 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); |
155 return reinterpret_cast<Object*>(Assembler::target_address_at(pc_, host_)); | 132 return reinterpret_cast<Object*>(Assembler::target_address_at(pc_, host_)); |
156 } | 133 } |
157 | 134 |
158 | 135 |
159 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) { | 136 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 Address address = cell->address() + Cell::kValueOffset; | 194 Address address = cell->address() + Cell::kValueOffset; |
218 Memory::Address_at(pc_) = address; | 195 Memory::Address_at(pc_) = address; |
219 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) { | 196 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) { |
220 // TODO(1550) We are passing NULL as a slot because cell can never be on | 197 // TODO(1550) We are passing NULL as a slot because cell can never be on |
221 // evacuation candidate. | 198 // evacuation candidate. |
222 host()->GetHeap()->incremental_marking()->RecordWrite(host(), NULL, cell); | 199 host()->GetHeap()->incremental_marking()->RecordWrite(host(), NULL, cell); |
223 } | 200 } |
224 } | 201 } |
225 | 202 |
226 | 203 |
227 #if V8_OOL_CONSTANT_POOL | |
228 static const int kNoCodeAgeInstructions = 7; | |
229 #else | |
230 static const int kNoCodeAgeInstructions = 6; | 204 static const int kNoCodeAgeInstructions = 6; |
231 #endif | 205 static const int kCodeAgingInstructions = Assembler::kMovInstructions + 3; |
232 static const int kCodeAgingInstructions = | |
233 Assembler::kMovInstructionsNoConstantPool + 3; | |
234 static const int kNoCodeAgeSequenceInstructions = | 206 static const int kNoCodeAgeSequenceInstructions = |
235 ((kNoCodeAgeInstructions >= kCodeAgingInstructions) | 207 ((kNoCodeAgeInstructions >= kCodeAgingInstructions) |
236 ? kNoCodeAgeInstructions | 208 ? kNoCodeAgeInstructions |
237 : kCodeAgingInstructions); | 209 : kCodeAgingInstructions); |
238 static const int kNoCodeAgeSequenceNops = | 210 static const int kNoCodeAgeSequenceNops = |
239 (kNoCodeAgeSequenceInstructions - kNoCodeAgeInstructions); | 211 (kNoCodeAgeSequenceInstructions - kNoCodeAgeInstructions); |
240 static const int kCodeAgingSequenceNops = | 212 static const int kCodeAgingSequenceNops = |
241 (kNoCodeAgeSequenceInstructions - kCodeAgingInstructions); | 213 (kNoCodeAgeSequenceInstructions - kCodeAgingInstructions); |
242 static const int kCodeAgingTargetDelta = 1 * Assembler::kInstrSize; | 214 static const int kCodeAgingTargetDelta = 1 * Assembler::kInstrSize; |
243 static const int kNoCodeAgeSequenceLength = | 215 static const int kNoCodeAgeSequenceLength = |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 static_cast<uint32_t>(instr2 & kImm16Mask)); | 421 static_cast<uint32_t>(instr2 & kImm16Mask)); |
450 uint64_t lo = (static_cast<uint32_t>((instr4 & kImm16Mask) << 16) | | 422 uint64_t lo = (static_cast<uint32_t>((instr4 & kImm16Mask) << 16) | |
451 static_cast<uint32_t>(instr5 & kImm16Mask)); | 423 static_cast<uint32_t>(instr5 & kImm16Mask)); |
452 return reinterpret_cast<Address>((hi << 32) | lo); | 424 return reinterpret_cast<Address>((hi << 32) | lo); |
453 #else | 425 #else |
454 // Assemble the 32 bit value. | 426 // Assemble the 32 bit value. |
455 return reinterpret_cast<Address>(((instr1 & kImm16Mask) << 16) | | 427 return reinterpret_cast<Address>(((instr1 & kImm16Mask) << 16) | |
456 (instr2 & kImm16Mask)); | 428 (instr2 & kImm16Mask)); |
457 #endif | 429 #endif |
458 } | 430 } |
459 #if V8_OOL_CONSTANT_POOL | 431 |
460 return Memory::Address_at(target_constant_pool_address_at(pc, constant_pool)); | 432 UNREACHABLE(); |
461 #else | 433 return NULL; |
462 DCHECK(false); | |
463 return (Address)0; | |
464 #endif | |
465 } | 434 } |
466 | 435 |
467 | 436 |
468 #if V8_OOL_CONSTANT_POOL | |
469 bool Assembler::IsConstantPoolLoadStart(Address pc) { | |
470 #if V8_TARGET_ARCH_PPC64 | |
471 if (!IsLi(instr_at(pc))) return false; | |
472 pc += kInstrSize; | |
473 #endif | |
474 return GetRA(instr_at(pc)).is(kConstantPoolRegister); | |
475 } | |
476 | |
477 | |
478 bool Assembler::IsConstantPoolLoadEnd(Address pc) { | |
479 #if V8_TARGET_ARCH_PPC64 | |
480 pc -= kInstrSize; | |
481 #endif | |
482 return IsConstantPoolLoadStart(pc); | |
483 } | |
484 | |
485 | |
486 int Assembler::GetConstantPoolOffset(Address pc) { | |
487 DCHECK(IsConstantPoolLoadStart(pc)); | |
488 Instr instr = instr_at(pc); | |
489 int offset = SIGN_EXT_IMM16((instr & kImm16Mask)); | |
490 return offset; | |
491 } | |
492 | |
493 | |
494 void Assembler::SetConstantPoolOffset(Address pc, int offset) { | |
495 DCHECK(IsConstantPoolLoadStart(pc)); | |
496 DCHECK(is_int16(offset)); | |
497 Instr instr = instr_at(pc); | |
498 instr &= ~kImm16Mask; | |
499 instr |= (offset & kImm16Mask); | |
500 instr_at_put(pc, instr); | |
501 } | |
502 | |
503 | |
504 Address Assembler::target_constant_pool_address_at( | |
505 Address pc, ConstantPoolArray* constant_pool) { | |
506 Address addr = reinterpret_cast<Address>(constant_pool); | |
507 DCHECK(addr); | |
508 addr += GetConstantPoolOffset(pc); | |
509 return addr; | |
510 } | |
511 #endif | |
512 | |
513 | |
514 // This sets the branch destination (which gets loaded at the call address). | 437 // This sets the branch destination (which gets loaded at the call address). |
515 // This is for calls and branches within generated code. The serializer | 438 // This is for calls and branches within generated code. The serializer |
516 // has already deserialized the mov instructions etc. | 439 // has already deserialized the mov instructions etc. |
517 // There is a FIXED_SEQUENCE assumption here | 440 // There is a FIXED_SEQUENCE assumption here |
518 void Assembler::deserialization_set_special_target_at( | 441 void Assembler::deserialization_set_special_target_at( |
519 Address instruction_payload, Code* code, Address target) { | 442 Address instruction_payload, Code* code, Address target) { |
520 set_target_address_at(instruction_payload, code, target); | 443 set_target_address_at(instruction_payload, code, target); |
521 } | 444 } |
522 | 445 |
523 // This code assumes the FIXED_SEQUENCE of lis/ori | 446 // This code assumes the FIXED_SEQUENCE of lis/ori |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
568 instr1 |= hi_word; | 491 instr1 |= hi_word; |
569 instr2 &= ~kImm16Mask; | 492 instr2 &= ~kImm16Mask; |
570 instr2 |= lo_word; | 493 instr2 |= lo_word; |
571 | 494 |
572 *p = instr1; | 495 *p = instr1; |
573 *(p + 1) = instr2; | 496 *(p + 1) = instr2; |
574 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 497 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
575 CpuFeatures::FlushICache(p, 2 * kInstrSize); | 498 CpuFeatures::FlushICache(p, 2 * kInstrSize); |
576 } | 499 } |
577 #endif | 500 #endif |
578 } else { | 501 return; |
579 #if V8_OOL_CONSTANT_POOL | |
580 Memory::Address_at(target_constant_pool_address_at(pc, constant_pool)) = | |
581 target; | |
582 #else | |
583 UNREACHABLE(); | |
584 #endif | |
585 } | 502 } |
| 503 UNREACHABLE(); |
586 } | 504 } |
587 } | 505 } |
588 } // namespace v8::internal | 506 } // namespace v8::internal |
589 | 507 |
590 #endif // V8_PPC_ASSEMBLER_PPC_INL_H_ | 508 #endif // V8_PPC_ASSEMBLER_PPC_INL_H_ |
OLD | NEW |