Chromium Code Reviews| Index: src/ppc/assembler-ppc-inl.h |
| diff --git a/src/ppc/assembler-ppc-inl.h b/src/ppc/assembler-ppc-inl.h |
| index d95c7ec5968a5e8fec471bdabed8f6dcf84d01d4..c2e181e733f69cf7cf1bf7b8122c89ac9d0222b6 100644 |
| --- a/src/ppc/assembler-ppc-inl.h |
| +++ b/src/ppc/assembler-ppc-inl.h |
| @@ -94,6 +94,13 @@ Address RelocInfo::target_address_address() { |
| DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || |
| rmode_ == EMBEDDED_OBJECT || rmode_ == EXTERNAL_REFERENCE); |
| + if (FLAG_enable_embedded_constant_pool && |
| + Assembler::IsConstantPoolLoadStart(pc_)) { |
| + // We return the PC for ool constant pool since this function is used by the |
| + // serializer and expects the address to reside within the code object. |
| + return reinterpret_cast<Address>(pc_); |
| + } |
| + |
| // Read the address of the word containing the target_address in an |
| // instruction stream. |
| // The only architecture-independent user of this function is the serializer. |
| @@ -108,6 +115,13 @@ Address RelocInfo::target_address_address() { |
| Address RelocInfo::constant_pool_entry_address() { |
| + if (FLAG_enable_embedded_constant_pool) { |
| + Address constant_pool = host_->constant_pool(); |
| + DCHECK(constant_pool); |
| + return (pc_ >= constant_pool) |
| + ? pc_ |
| + : Assembler::target_constant_pool_address_at(pc_, constant_pool); |
| + } |
| UNREACHABLE(); |
| return NULL; |
| } |
| @@ -143,12 +157,21 @@ Address Assembler::target_address_from_return_address(Address pc) { |
| // mtlr ip |
| // blrl |
| // @ return address |
| - return pc - (kMovInstructions + 2) * kInstrSize; |
| + if (FLAG_enable_embedded_constant_pool && |
| + IsConstantPoolLoadEnd(pc - 3 * kInstrSize)) { |
| + return pc - (kMovInstructionsConstantPool + 2) * kInstrSize; |
| + } |
| + return pc - (kMovInstructionsNoConstantPool + 2) * kInstrSize; |
| } |
| Address Assembler::return_address_from_call_start(Address pc) { |
| - return pc + (kMovInstructions + 2) * kInstrSize; |
| + if (FLAG_enable_embedded_constant_pool) { |
| + Address load_address = pc + (kMovInstructionsConstantPool - 1) * kInstrSize; |
| + if (IsConstantPoolLoadEnd(load_address)) |
| + return pc + (kMovInstructionsConstantPool + 2) * kInstrSize; |
| + } |
| + return pc + (kMovInstructionsNoConstantPool + 2) * kInstrSize; |
| } |
| @@ -226,8 +249,10 @@ void RelocInfo::set_target_cell(Cell* cell, WriteBarrierMode write_barrier_mode, |
| } |
| -static const int kNoCodeAgeInstructions = 6; |
| -static const int kCodeAgingInstructions = Assembler::kMovInstructions + 3; |
| +static const int kNoCodeAgeInstructions = |
| + FLAG_enable_embedded_constant_pool ? 7 : 6; |
| +static const int kCodeAgingInstructions = |
| + Assembler::kMovInstructionsNoConstantPool + 3; |
| static const int kNoCodeAgeSequenceInstructions = |
| ((kNoCodeAgeInstructions >= kCodeAgingInstructions) |
| ? kNoCodeAgeInstructions |
| @@ -448,8 +473,14 @@ bool Operand::is_reg() const { return rm_.is_valid(); } |
| // Fetch the 32bit value from the FIXED_SEQUENCE lis/ori |
| -Address Assembler::target_address_at(Address pc, |
| - ConstantPoolArray* constant_pool) { |
| +Address Assembler::target_address_at(Address pc, Address constant_pool) { |
| + if (FLAG_enable_embedded_constant_pool && constant_pool) { |
| + if (pc >= constant_pool) return Memory::Address_at(pc); |
| + if (IsConstantPoolLoadStart(pc)) |
| + return Memory::Address_at( |
| + target_constant_pool_address_at(pc, constant_pool)); |
| + } |
| + |
| Instr instr1 = instr_at(pc); |
| Instr instr2 = instr_at(pc + kInstrSize); |
| // Interpret 2 instructions generated by lis/ori |
| @@ -475,6 +506,44 @@ Address Assembler::target_address_at(Address pc, |
| } |
| +bool Assembler::IsConstantPoolLoadStart(Address pc) { |
| + return GetRA(instr_at(pc)).is(kConstantPoolRegister); |
| +} |
| + |
| + |
| +bool Assembler::IsConstantPoolLoadEnd(Address pc) { |
| + return IsConstantPoolLoadStart(pc); |
| +} |
| + |
| + |
| +int Assembler::GetConstantPoolOffset(Address pc) { |
| + DCHECK(IsConstantPoolLoadStart(pc)); |
| + Instr instr = instr_at(pc); |
| + int offset = SIGN_EXT_IMM16((instr & kImm16Mask)); |
| + return offset; |
| +} |
| + |
| + |
| +void Assembler::SetConstantPoolOffset(int pos, int offset) { |
| + Address pc = buffer_ + pos; |
| + DCHECK(IsConstantPoolLoadStart(pc)); |
| + DCHECK(is_int16(offset)); |
| + Instr instr = instr_at(pc); |
| + instr &= ~kImm16Mask; |
| + instr |= (offset & kImm16Mask); |
| + instr_at_put(pc, instr); |
| +} |
| + |
| + |
| +Address Assembler::target_constant_pool_address_at(Address pc, |
| + Address constant_pool) { |
| + Address addr = constant_pool; |
| + DCHECK(addr); |
| + addr += GetConstantPoolOffset(pc); |
| + return addr; |
| +} |
| + |
| + |
| // This sets the branch destination (which gets loaded at the call address). |
| // This is for calls and branches within generated code. The serializer |
| // has already deserialized the mov instructions etc. |
| @@ -497,10 +566,21 @@ void Assembler::deserialization_set_target_internal_reference_at( |
| // This code assumes the FIXED_SEQUENCE of lis/ori |
| -void Assembler::set_target_address_at(Address pc, |
| - ConstantPoolArray* constant_pool, |
| +void Assembler::set_target_address_at(Address pc, Address constant_pool, |
| Address target, |
| ICacheFlushMode icache_flush_mode) { |
| + if (FLAG_enable_embedded_constant_pool && constant_pool) { |
| + if (pc >= constant_pool) { |
| + 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
|
| + return; |
| + } |
| + if (IsConstantPoolLoadStart(pc)) { |
| + Memory::Address_at(target_constant_pool_address_at(pc, constant_pool)) = |
| + target; |
| + return; |
| + } |
| + } |
| + |
| Instr instr1 = instr_at(pc); |
| Instr instr2 = instr_at(pc + kInstrSize); |
| // Interpret 2 instructions generated by lis/ori |