Commit e99ad691 authored by zhengxing.li's avatar zhengxing.li Committed by Commit bot

X87: [crankshaft] [ia32] Remove dynamic frame alignment optimization.

  port fcb83f20(r34273)

  original commit message:
  This optimization does not give us much (see perf try bot results associated with this CL) but complicates things a lot. The main motivation is to avoid additional complexity in tail call optim

  There are some pieces left in the deoptimizer, but I'll address this in a separate CL.

BUG=

Review URL: https://codereview.chromium.org/1750433002

Cr-Commit-Position: refs/heads/master@{#34353}
parent 2aa53410
......@@ -57,13 +57,6 @@ bool LCodeGen::GenerateCode() {
// the frame (that is done in GeneratePrologue).
FrameScope frame_scope(masm_, StackFrame::MANUAL);
support_aligned_spilled_doubles_ = info()->IsOptimizing();
dynamic_frame_alignment_ = info()->IsOptimizing() &&
((chunk()->num_double_slots() > 2 &&
!chunk()->graph()->is_recursive()) ||
!info()->osr_ast_id().IsNone());
return GeneratePrologue() &&
GenerateBody() &&
GenerateDeferredCode() &&
......@@ -98,31 +91,6 @@ bool LCodeGen::GeneratePrologue() {
if (info()->IsOptimizing()) {
ProfileEntryHookStub::MaybeCallEntryHook(masm_);
if (support_aligned_spilled_doubles_ && dynamic_frame_alignment_) {
// Move state of dynamic frame alignment into edx.
__ Move(edx, Immediate(kNoAlignmentPadding));
Label do_not_pad, align_loop;
STATIC_ASSERT(kDoubleSize == 2 * kPointerSize);
// Align esp + 4 to a multiple of 2 * kPointerSize.
__ test(esp, Immediate(kPointerSize));
__ j(not_zero, &do_not_pad, Label::kNear);
__ push(Immediate(0));
__ mov(ebx, esp);
__ mov(edx, Immediate(kAlignmentPaddingPushed));
// Copy arguments, receiver, and return address.
__ mov(ecx, Immediate(scope()->num_parameters() + 2));
__ bind(&align_loop);
__ mov(eax, Operand(ebx, 1 * kPointerSize));
__ mov(Operand(ebx, 0), eax);
__ add(Operand(ebx), Immediate(kPointerSize));
__ dec(ecx);
__ j(not_zero, &align_loop, Label::kNear);
__ mov(Operand(ebx, 0), Immediate(kAlignmentZapValue));
__ bind(&do_not_pad);
}
}
info()->set_prologue_offset(masm_->pc_offset());
......@@ -136,55 +104,23 @@ bool LCodeGen::GeneratePrologue() {
}
}
if (info()->IsOptimizing() &&
dynamic_frame_alignment_ &&
FLAG_debug_code) {
__ test(esp, Immediate(kPointerSize));
__ Assert(zero, kFrameIsExpectedToBeAligned);
}
// Reserve space for the stack slots needed by the code.
int slots = GetStackSlotCount();
DCHECK(slots != 0 || !info()->IsOptimizing());
if (slots > 0) {
if (slots == 1) {
if (dynamic_frame_alignment_) {
__ push(edx);
} else {
__ push(Immediate(kNoAlignmentPadding));
}
} else {
if (FLAG_debug_code) {
__ sub(Operand(esp), Immediate(slots * kPointerSize));
__ sub(Operand(esp), Immediate(slots * kPointerSize));
#ifdef _MSC_VER
MakeSureStackPagesMapped(slots * kPointerSize);
MakeSureStackPagesMapped(slots * kPointerSize);
#endif
__ push(eax);
__ mov(Operand(eax), Immediate(slots));
Label loop;
__ bind(&loop);
__ mov(MemOperand(esp, eax, times_4, 0),
Immediate(kSlotsZapValue));
__ dec(eax);
__ j(not_zero, &loop);
__ pop(eax);
} else {
__ sub(Operand(esp), Immediate(slots * kPointerSize));
#ifdef _MSC_VER
MakeSureStackPagesMapped(slots * kPointerSize);
#endif
}
if (support_aligned_spilled_doubles_) {
Comment(";;; Store dynamic frame alignment tag for spilled doubles");
// Store dynamic frame alignment state in the first local.
int offset = JavaScriptFrameConstants::kDynamicAlignmentStateOffset;
if (dynamic_frame_alignment_) {
__ mov(Operand(ebp, offset), edx);
} else {
__ mov(Operand(ebp, offset), Immediate(kNoAlignmentPadding));
}
}
if (FLAG_debug_code) {
__ push(eax);
__ mov(Operand(eax), Immediate(slots));
Label loop;
__ bind(&loop);
__ mov(MemOperand(esp, eax, times_4, 0), Immediate(kSlotsZapValue));
__ dec(eax);
__ j(not_zero, &loop);
__ pop(eax);
}
}
......@@ -265,50 +201,11 @@ void LCodeGen::GenerateOsrPrologue() {
osr_pc_offset_ = masm()->pc_offset();
// Move state of dynamic frame alignment into edx.
__ Move(edx, Immediate(kNoAlignmentPadding));
if (support_aligned_spilled_doubles_ && dynamic_frame_alignment_) {
Label do_not_pad, align_loop;
// Align ebp + 4 to a multiple of 2 * kPointerSize.
__ test(ebp, Immediate(kPointerSize));
__ j(zero, &do_not_pad, Label::kNear);
__ push(Immediate(0));
__ mov(ebx, esp);
__ mov(edx, Immediate(kAlignmentPaddingPushed));
// Move all parts of the frame over one word. The frame consists of:
// unoptimized frame slots, alignment state, context, frame pointer, return
// address, receiver, and the arguments.
__ mov(ecx, Immediate(scope()->num_parameters() +
5 + graph()->osr()->UnoptimizedFrameSlots()));
__ bind(&align_loop);
__ mov(eax, Operand(ebx, 1 * kPointerSize));
__ mov(Operand(ebx, 0), eax);
__ add(Operand(ebx), Immediate(kPointerSize));
__ dec(ecx);
__ j(not_zero, &align_loop, Label::kNear);
__ mov(Operand(ebx, 0), Immediate(kAlignmentZapValue));
__ sub(Operand(ebp), Immediate(kPointerSize));
__ bind(&do_not_pad);
}
// Save the first local, which is overwritten by the alignment state.
Operand alignment_loc = MemOperand(ebp, -3 * kPointerSize);
__ push(alignment_loc);
// Set the dynamic frame alignment state.
__ mov(alignment_loc, edx);
// Adjust the frame size, subsuming the unoptimized frame into the
// optimized frame.
int slots = GetStackSlotCount() - graph()->osr()->UnoptimizedFrameSlots();
DCHECK(slots >= 1);
__ sub(esp, Immediate((slots - 1) * kPointerSize));
// Initailize FPU state.
__ fninit();
DCHECK(slots >= 0);
__ sub(esp, Immediate(slots * kPointerSize));
}
......@@ -2749,18 +2646,11 @@ void LCodeGen::DoCmpT(LCmpT* instr) {
__ bind(&done);
}
void LCodeGen::EmitReturn(LReturn* instr, bool dynamic_frame_alignment) {
int extra_value_count = dynamic_frame_alignment ? 2 : 1;
void LCodeGen::EmitReturn(LReturn* instr) {
int extra_value_count = 1;
if (instr->has_constant_parameter_count()) {
int parameter_count = ToInteger32(instr->constant_parameter_count());
if (dynamic_frame_alignment && FLAG_debug_code) {
__ cmp(Operand(esp,
(parameter_count + extra_value_count) * kPointerSize),
Immediate(kAlignmentZapValue));
__ Assert(equal, kExpectedAlignmentMarker);
}
__ Ret((parameter_count + extra_value_count) * kPointerSize, ecx);
} else {
DCHECK(info()->IsStub()); // Functions would need to drop one more value.
......@@ -2768,19 +2658,9 @@ void LCodeGen::EmitReturn(LReturn* instr, bool dynamic_frame_alignment) {
// The argument count parameter is a smi
__ SmiUntag(reg);
Register return_addr_reg = reg.is(ecx) ? ebx : ecx;
if (dynamic_frame_alignment && FLAG_debug_code) {
DCHECK(extra_value_count == 2);
__ cmp(Operand(esp, reg, times_pointer_size,
extra_value_count * kPointerSize),
Immediate(kAlignmentZapValue));
__ Assert(equal, kExpectedAlignmentMarker);
}
// emit code to restore stack based on instr->parameter_count()
__ pop(return_addr_reg); // save return address
if (dynamic_frame_alignment) {
__ inc(reg); // 1 more for alignment
}
__ shl(reg, kPointerSizeLog2);
__ add(esp, reg);
__ jmp(return_addr_reg);
......@@ -2798,25 +2678,12 @@ void LCodeGen::DoReturn(LReturn* instr) {
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
__ CallRuntime(Runtime::kTraceExit);
}
if (dynamic_frame_alignment_) {
// Fetch the state of the dynamic frame alignment.
__ mov(edx, Operand(ebp,
JavaScriptFrameConstants::kDynamicAlignmentStateOffset));
}
if (NeedsEagerFrame()) {
__ mov(esp, ebp);
__ pop(ebp);
}
if (dynamic_frame_alignment_) {
Label no_padding;
__ cmp(edx, Immediate(kNoAlignmentPadding));
__ j(equal, &no_padding, Label::kNear);
EmitReturn(instr, true);
__ bind(&no_padding);
}
EmitReturn(instr, false);
EmitReturn(instr);
}
......
......@@ -31,8 +31,6 @@ class LCodeGen: public LCodeGenBase {
jump_table_(4, info->zone()),
scope_(info->scope()),
deferred_(8, info->zone()),
dynamic_frame_alignment_(false),
support_aligned_spilled_doubles_(false),
frame_is_built_(false),
x87_stack_(assembler),
safepoints_(info->zone()),
......@@ -329,7 +327,7 @@ class LCodeGen: public LCodeGenBase {
template <class T>
void EmitVectorStoreICRegisters(T* instr);
void EmitReturn(LReturn* instr, bool dynamic_frame_alignment);
void EmitReturn(LReturn* instr);
// Emits code for pushing either a tagged constant, a (non-double)
// register, or a stack slot operand.
......@@ -354,8 +352,6 @@ class LCodeGen: public LCodeGenBase {
ZoneList<Deoptimizer::JumpTableEntry> jump_table_;
Scope* const scope_;
ZoneList<LDeferredCode*> deferred_;
bool dynamic_frame_alignment_;
bool support_aligned_spilled_doubles_;
bool frame_is_built_;
class X87Stack : public ZoneObject {
......
......@@ -424,13 +424,6 @@ LPlatformChunk* LChunkBuilder::Build() {
LPhase phase("L_Building chunk", chunk_);
status_ = BUILDING;
// Reserve the first spill slot for the state of dynamic alignment.
if (info()->IsOptimizing()) {
int alignment_state_index = chunk_->GetNextSpillIndex(GENERAL_REGISTERS);
DCHECK_EQ(alignment_state_index, 4);
USE(alignment_state_index);
}
// If compiling for OSR, reserve space for the unoptimized frame,
// which will be subsumed into this frame.
if (graph()->has_osr()) {
......@@ -2465,11 +2458,6 @@ LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
Retry(kNotEnoughSpillSlotsForOsr);
spill_index = 0;
}
if (spill_index == 0) {
// The dynamic frame alignment state overwrites the first local.
// The first local is saved at the end of the unoptimized frame.
spill_index = graph()->osr()->UnoptimizedFrameSlots();
}
spill_index += StandardFrameConstants::kFixedSlotCount;
}
return DefineAsSpilled(new(zone()) LUnknownOSRValue, spill_index);
......
......@@ -187,16 +187,8 @@ void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) {
}
bool Deoptimizer::HasAlignmentPadding(SharedFunctionInfo* shared) {
int parameter_count = shared->internal_formal_parameter_count() + 1;
unsigned input_frame_size = input_->GetFrameSize();
unsigned alignment_state_offset =
input_frame_size - parameter_count * kPointerSize -
StandardFrameConstants::kFixedFrameSize -
kPointerSize;
DCHECK(JavaScriptFrameConstants::kDynamicAlignmentStateOffset ==
JavaScriptFrameConstants::kLocal0Offset);
int32_t alignment_state = input_->GetFrameSlot(alignment_state_offset);
return (alignment_state == kAlignmentPaddingPushed);
// There is no dynamic alignment padding on x87 in the input frame.
return false;
}
......@@ -337,18 +329,6 @@ void Deoptimizer::TableEntryGenerator::Generate() {
__ pop(eax);
__ pop(edi);
// If frame was dynamically aligned, pop padding.
Label no_padding;
__ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()),
Immediate(0));
__ j(equal, &no_padding);
__ pop(ecx);
if (FLAG_debug_code) {
__ cmp(ecx, Immediate(kAlignmentZapValue));
__ Assert(equal, kAlignmentMarkerExpected);
}
__ bind(&no_padding);
// Replace the current frame with the output frames.
Label outer_push_loop, inner_push_loop,
outer_loop_header, inner_loop_header;
......
......@@ -28,10 +28,6 @@ const int kNumJSCallerSaved = 5;
// Number of registers for which space is reserved in safepoints.
const int kNumSafepointRegisters = 8;
const int kNoAlignmentPadding = 0;
const int kAlignmentPaddingPushed = 2;
const int kAlignmentZapValue = 0x12345678; // Not heap object tagged.
// ----------------------------------------------------
......@@ -75,8 +71,6 @@ class JavaScriptFrameConstants : public AllStatic {
// Caller SP-relative.
static const int kParam0Offset = -2 * kPointerSize;
static const int kReceiverOffset = -1 * kPointerSize;
static const int kDynamicAlignmentStateOffset = kLocal0Offset;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment