| 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 |