Chromium Code Reviews| Index: src/ppc/macro-assembler-ppc.cc |
| diff --git a/src/ppc/macro-assembler-ppc.cc b/src/ppc/macro-assembler-ppc.cc |
| index 60971096f00ca2f5ec5abb91a2c9e93ef21bc271..257d947b4529206b0a96367dae96929949a0fcdb 100644 |
| --- a/src/ppc/macro-assembler-ppc.cc |
| +++ b/src/ppc/macro-assembler-ppc.cc |
| @@ -104,14 +104,15 @@ void MacroAssembler::CallJSEntry(Register target) { |
| int MacroAssembler::CallSize(Address target, RelocInfo::Mode rmode, |
| Condition cond) { |
| - return (2 + kMovInstructions) * kInstrSize; |
| + Operand mov_operand = Operand(reinterpret_cast<intptr_t>(target), rmode); |
| + return (2 + instructions_required_for_mov(mov_operand)) * kInstrSize; |
| } |
| int MacroAssembler::CallSizeNotPredictableCodeSize(Address target, |
| RelocInfo::Mode rmode, |
| Condition cond) { |
| - return (2 + kMovInstructions) * kInstrSize; |
| + return (2 + kMovInstructionsNoConstantPool) * kInstrSize; |
| } |
| @@ -514,6 +515,15 @@ void MacroAssembler::RememberedSetHelper(Register object, // For debug tests. |
| void MacroAssembler::PushFixedFrame(Register marker_reg) { |
| mflr(r0); |
| + if (FLAG_enable_embedded_constant_pool) { |
| + if (marker_reg.is_valid()) { |
| + Push(r0, fp, kConstantPoolRegister, cp, marker_reg); |
| + } else { |
| + Push(r0, fp, kConstantPoolRegister, cp); |
| + } |
| + return; |
| + } |
| + |
| if (marker_reg.is_valid()) { |
| Push(r0, fp, cp, marker_reg); |
| } else { |
| @@ -523,6 +533,16 @@ void MacroAssembler::PushFixedFrame(Register marker_reg) { |
| void MacroAssembler::PopFixedFrame(Register marker_reg) { |
| + if (FLAG_enable_embedded_constant_pool) { |
| + if (marker_reg.is_valid()) { |
| + Pop(r0, fp, kConstantPoolRegister, cp, marker_reg); |
| + } else { |
| + Pop(r0, fp, kConstantPoolRegister, cp); |
| + } |
| + mtlr(r0); |
| + return; |
| + } |
| + |
| if (marker_reg.is_valid()) { |
| Pop(r0, fp, cp, marker_reg); |
| } else { |
| @@ -652,11 +672,34 @@ void MacroAssembler::ConvertDoubleToInt64(const DoubleRegister double_input, |
| } |
| +void MacroAssembler::LoadTargetConstantPoolPointerRegister(Register target) { |
| + lwz(kConstantPoolRegister, |
| + MemOperand(target, Code::kConstantPoolOffset - Code::kHeaderSize)); |
| + add(kConstantPoolRegister, kConstantPoolRegister, target); |
| +} |
| + |
| + |
| +void MacroAssembler::LoadOwnConstantPoolPointerRegister(Register base, |
| + int code_start_delta) { |
| + if (base.is(no_reg)) { |
| + mov_label_addr(kConstantPoolRegister, ConstantPoolPosition()); |
| + } else { |
|
rmcilroy
2015/04/08 12:38:55
I think these should be two separate functions (wi
MTBrandyberry
2015/05/07 20:38:32
Acknowledged.
|
| + add_label_offset(kConstantPoolRegister, base, ConstantPoolPosition(), |
| + code_start_delta); |
| + } |
| +} |
| + |
| + |
| void MacroAssembler::StubPrologue(int prologue_offset) { |
| LoadSmiLiteral(r11, Smi::FromInt(StackFrame::STUB)); |
| PushFixedFrame(r11); |
| // Adjust FP to point to saved FP. |
| addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); |
| + if (FLAG_enable_embedded_constant_pool) { |
| + // ip contains prologue address |
| + LoadOwnConstantPoolPointerRegister(ip, -prologue_offset); |
|
rmcilroy
2015/04/08 12:38:55
Where does ip get set to the prologue address?
MTBrandyberry
2015/05/07 20:38:32
All calls to JS code are done via the ip register.
|
| + set_constant_pool_available(true); |
| + } |
| } |
| @@ -689,13 +732,26 @@ void MacroAssembler::Prologue(bool code_pre_aging, int prologue_offset) { |
| } |
| } |
| } |
| + if (FLAG_enable_embedded_constant_pool) { |
| + // ip contains prologue address |
| + LoadOwnConstantPoolPointerRegister(ip, -prologue_offset); |
|
rmcilroy
2015/04/08 12:38:55
ditto
MTBrandyberry
2015/05/07 20:38:32
see above.
|
| + set_constant_pool_available(true); |
| + } |
| } |
| void MacroAssembler::EnterFrame(StackFrame::Type type, |
| bool load_constant_pool_pointer_reg) { |
| - LoadSmiLiteral(ip, Smi::FromInt(type)); |
| - PushFixedFrame(ip); |
| + if (FLAG_enable_embedded_constant_pool && load_constant_pool_pointer_reg) { |
| + PushFixedFrame(); |
| + // This path should not rely on ip containing code entry. |
| + LoadOwnConstantPoolPointerRegister(); |
| + LoadSmiLiteral(ip, Smi::FromInt(type)); |
| + push(ip); |
| + } else { |
| + LoadSmiLiteral(ip, Smi::FromInt(type)); |
| + PushFixedFrame(ip); |
| + } |
| // Adjust FP to point to saved FP. |
| addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); |
| @@ -705,6 +761,7 @@ void MacroAssembler::EnterFrame(StackFrame::Type type, |
| int MacroAssembler::LeaveFrame(StackFrame::Type type, int stack_adjustment) { |
| + ConstantPoolUnavailableScope constant_pool_unavailable(this); |
| // r3: preserved |
| // r4: preserved |
| // r5: preserved |
| @@ -714,6 +771,13 @@ int MacroAssembler::LeaveFrame(StackFrame::Type type, int stack_adjustment) { |
| int frame_ends; |
| LoadP(r0, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); |
| LoadP(ip, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
| + if (FLAG_enable_embedded_constant_pool) { |
| + const int exitOffset = ExitFrameConstants::kConstantPoolOffset; |
| + const int standardOffset = StandardFrameConstants::kConstantPoolOffset; |
| + const int offset = |
| + ((type == StackFrame::EXIT) ? exitOffset : standardOffset); |
| + LoadP(kConstantPoolRegister, MemOperand(fp, offset)); |
| + } |
| mtlr(r0); |
| frame_ends = pc_offset(); |
| Add(sp, fp, StandardFrameConstants::kCallerSPOffset + stack_adjustment, r0); |
| @@ -760,6 +824,10 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) { |
| li(r8, Operand::Zero()); |
| StoreP(r8, MemOperand(fp, ExitFrameConstants::kSPOffset)); |
| } |
| + if (FLAG_enable_embedded_constant_pool) { |
| + StoreP(kConstantPoolRegister, |
| + MemOperand(fp, ExitFrameConstants::kConstantPoolOffset)); |
| + } |
| mov(r8, Operand(CodeObject())); |
| StoreP(r8, MemOperand(fp, ExitFrameConstants::kCodeOffset)); |
| @@ -829,6 +897,7 @@ int MacroAssembler::ActivationFrameAlignment() { |
| void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count, |
| bool restore_context, |
| bool argument_count_is_length) { |
| + ConstantPoolUnavailableScope constant_pool_unavailable(this); |
| // Optionally restore all double registers. |
| if (save_doubles) { |
| // Calculate the stack location of the saved doubles and restore them. |
| @@ -1086,41 +1155,28 @@ void MacroAssembler::DebugBreak() { |
| } |
| -void MacroAssembler::PushTryHandler(StackHandler::Kind kind, |
| - int handler_index) { |
| +void MacroAssembler::PushStackHandler() { |
| // Adjust this code if not the case. |
| - STATIC_ASSERT(StackHandlerConstants::kSize == 3 * kPointerSize); |
| + STATIC_ASSERT(StackHandlerConstants::kSize == 1 * kPointerSize); |
| STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); |
| - STATIC_ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize); |
| - STATIC_ASSERT(StackHandlerConstants::kContextOffset == 2 * kPointerSize); |
| - |
| - // For the JSEntry handler, we must preserve r1-r7, r0,r8-r12 are available. |
| - // We want the stack to look like |
| - // sp -> NextOffset |
| - // index |
| - // context |
| // Link the current handler as the next handler. |
| + // Preserve r3-r7. |
| mov(r8, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); |
| LoadP(r0, MemOperand(r8)); |
| - StorePU(r0, MemOperand(sp, -StackHandlerConstants::kSize)); |
| + push(r0); |
| + |
| // Set this new handler as the current one. |
| StoreP(sp, MemOperand(r8)); |
| - |
| - mov(r8, Operand(handler_index)); |
| - if (kind == StackHandler::JS_ENTRY) { |
| - LoadSmiLiteral(cp, Smi::FromInt(0)); // Indicates no context. |
| - } |
| - StoreP(r8, MemOperand(sp, StackHandlerConstants::kStateOffset)); |
| - StoreP(cp, MemOperand(sp, StackHandlerConstants::kContextOffset)); |
| } |
| -void MacroAssembler::PopTryHandler() { |
| +void MacroAssembler::PopStackHandler() { |
| + STATIC_ASSERT(StackHandlerConstants::kSize == 1 * kPointerSize); |
| STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
| + |
| pop(r4); |
| mov(ip, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); |
| - addi(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize)); |
| StoreP(r4, MemOperand(ip)); |
| } |
| @@ -3191,6 +3247,21 @@ void MacroAssembler::SetRelocatedValue(Register location, Register scratch, |
| Register new_value) { |
| lwz(scratch, MemOperand(location)); |
| + if (FLAG_enable_embedded_constant_pool) { |
| + if (emit_debug_code()) { |
| + // Check that the instruction sequence is a load from the constant pool |
| + ExtractBitMask(scratch, scratch, 0x1f * B16); |
| + cmpi(scratch, Operand(kConstantPoolRegister.code())); |
| + Check(eq, kTheInstructionToPatchShouldBeALoadFromConstantPool); |
| + // Scratch was clobbered. Restore it. |
| + lwz(scratch, MemOperand(location)); |
| + } |
| + // Get the address of the constant and patch it. |
| + andi(scratch, scratch, Operand(kImm16Mask)); |
| + StorePX(new_value, MemOperand(kConstantPoolRegister, scratch)); |
| + return; |
| + } |
| + |
| // This code assumes a FIXED_SEQUENCE for lis/ori |
| // At this point scratch is a lis instruction. |
| @@ -3274,6 +3345,20 @@ void MacroAssembler::GetRelocatedValue(Register location, Register result, |
| Register scratch) { |
| lwz(result, MemOperand(location)); |
| + if (FLAG_enable_embedded_constant_pool) { |
| + if (emit_debug_code()) { |
| + // Check that the instruction sequence is a load from the constant pool |
| + ExtractBitMask(result, result, 0x1f * B16); |
| + cmpi(result, Operand(kConstantPoolRegister.code())); |
| + Check(eq, kTheInstructionToPatchShouldBeALoadFromConstantPool); |
| + lwz(result, MemOperand(location)); |
| + } |
| + // Get the address of the constant and retrieve it. |
| + andi(result, result, Operand(kImm16Mask)); |
| + LoadPX(result, MemOperand(kConstantPoolRegister, result)); |
| + return; |
| + } |
| + |
| // This code assumes a FIXED_SEQUENCE for lis/ori |
| if (emit_debug_code()) { |
| And(result, result, Operand(kOpcodeMask | (0x1f * B16))); |
| @@ -3711,6 +3796,13 @@ void MacroAssembler::LoadSmiLiteral(Register dst, Smi* smi) { |
| void MacroAssembler::LoadDoubleLiteral(DoubleRegister result, double value, |
| Register scratch) { |
| + if (FLAG_enable_embedded_constant_pool && is_constant_pool_available() && |
| + !is_constant_pool_full()) { |
| + ConstantPoolAddEntry(value); |
| + lfd(result, MemOperand(kConstantPoolRegister, 0)); |
| + return; |
| + } |
| + |
| // avoid gcc strict aliasing error using union cast |
| union { |
| double dval; |