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