Commit bd5fa9c9 authored by olivf@chromium.org's avatar olivf@chromium.org

Reland "Fix phis for non-sse2 double values"

Remove VerifyX87StackDepth from non-debug code.

BUG=
R=verwaest@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16682 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 151e5149
...@@ -382,11 +382,15 @@ bool LCodeGen::GenerateBody() { ...@@ -382,11 +382,15 @@ bool LCodeGen::GenerateBody() {
instr->CompileToNative(this); instr->CompileToNative(this);
if (!CpuFeatures::IsSupported(SSE2) && if (!CpuFeatures::IsSupported(SSE2)) {
FLAG_debug_code && FLAG_enable_slow_asserts) { if (instr->IsGoto()) {
x87_stack_.LeavingBlock(current_block_, LGoto::cast(instr));
} else if (FLAG_debug_code && FLAG_enable_slow_asserts &&
!instr->IsGap() && !instr->IsReturn()) {
__ VerifyX87StackDepth(x87_stack_.depth()); __ VerifyX87StackDepth(x87_stack_.depth());
} }
} }
}
EnsureSpaceForLazyDeopt(); EnsureSpaceForLazyDeopt();
return !is_aborted(); return !is_aborted();
} }
...@@ -682,6 +686,21 @@ void LCodeGen::X87Stack::FlushIfNecessary(LInstruction* instr, LCodeGen* cgen) { ...@@ -682,6 +686,21 @@ void LCodeGen::X87Stack::FlushIfNecessary(LInstruction* instr, LCodeGen* cgen) {
__ fstp(0); __ fstp(0);
stack_depth_--; stack_depth_--;
} }
if (FLAG_debug_code && FLAG_enable_slow_asserts) __ VerifyX87StackDepth(0);
}
}
void LCodeGen::X87Stack::LeavingBlock(int current_block_id, LGoto* goto_instr) {
ASSERT(stack_depth_ <= 1);
// If ever used for new stubs producing two pairs of doubles joined into two
// phis this assert hits. That situation is not handled, since the two stacks
// might have st0 and st1 swapped.
if (current_block_id + 1 != goto_instr->block_id()) {
// If we have a value on the x87 stack on leaving a block, it must be a
// phi input. If the next block we compile is not the join block, we have
// to discard the stack state.
stack_depth_ = 0;
} }
} }
...@@ -2486,6 +2505,10 @@ void LCodeGen::EmitGoto(int block) { ...@@ -2486,6 +2505,10 @@ void LCodeGen::EmitGoto(int block) {
} }
void LCodeGen::DoClobberDoubles(LClobberDoubles* instr) {
}
void LCodeGen::DoGoto(LGoto* instr) { void LCodeGen::DoGoto(LGoto* instr) {
EmitGoto(instr->block_id()); EmitGoto(instr->block_id());
} }
......
...@@ -471,6 +471,7 @@ class LCodeGen V8_FINAL BASE_EMBEDDED { ...@@ -471,6 +471,7 @@ class LCodeGen V8_FINAL BASE_EMBEDDED {
void PrepareToWrite(X87Register reg); void PrepareToWrite(X87Register reg);
void CommitWrite(X87Register reg); void CommitWrite(X87Register reg);
void FlushIfNecessary(LInstruction* instr, LCodeGen* cgen); void FlushIfNecessary(LInstruction* instr, LCodeGen* cgen);
void LeavingBlock(int current_block_id, LGoto* goto_instr);
int depth() const { return stack_depth_; } int depth() const { return stack_depth_; }
void pop() { void pop() {
ASSERT(is_mutable_); ASSERT(is_mutable_);
......
...@@ -954,6 +954,16 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) { ...@@ -954,6 +954,16 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
if (FLAG_stress_environments && !instr->HasEnvironment()) { if (FLAG_stress_environments && !instr->HasEnvironment()) {
instr = AssignEnvironment(instr); instr = AssignEnvironment(instr);
} }
if (!CpuFeatures::IsSafeForSnapshot(SSE2) && instr->IsGoto() &&
LGoto::cast(instr)->jumps_to_join()) {
// TODO(olivf) Since phis of spilled values are joined as registers
// (not in the stack slot), we need to allow the goto gaps to keep one
// x87 register alive. To ensure all other values are still spilled, we
// insert a fpu register barrier right before.
LClobberDoubles* clobber = new(zone()) LClobberDoubles();
clobber->set_hydrogen_value(current);
chunk_->AddInstruction(clobber, current_block_);
}
instr->set_hydrogen_value(current); instr->set_hydrogen_value(current);
chunk_->AddInstruction(instr, current_block_); chunk_->AddInstruction(instr, current_block_);
} }
...@@ -1046,7 +1056,7 @@ LEnvironment* LChunkBuilder::CreateEnvironment( ...@@ -1046,7 +1056,7 @@ LEnvironment* LChunkBuilder::CreateEnvironment(
LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
return new(zone()) LGoto(instr->FirstSuccessor()->block_id()); return new(zone()) LGoto(instr->FirstSuccessor());
} }
...@@ -1058,7 +1068,7 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { ...@@ -1058,7 +1068,7 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
HBasicBlock* successor = HConstant::cast(value)->BooleanValue() HBasicBlock* successor = HConstant::cast(value)->BooleanValue()
? instr->FirstSuccessor() ? instr->FirstSuccessor()
: instr->SecondSuccessor(); : instr->SecondSuccessor();
return new(zone()) LGoto(successor->block_id()); return new(zone()) LGoto(successor);
} }
ToBooleanStub::Types expected = instr->expected_input_types(); ToBooleanStub::Types expected = instr->expected_input_types();
......
...@@ -73,6 +73,7 @@ class LCodeGen; ...@@ -73,6 +73,7 @@ class LCodeGen;
V(ClampTToUint8) \ V(ClampTToUint8) \
V(ClampTToUint8NoSSE2) \ V(ClampTToUint8NoSSE2) \
V(ClassOfTestAndBranch) \ V(ClassOfTestAndBranch) \
V(ClobberDoubles) \
V(CompareNumericAndBranch) \ V(CompareNumericAndBranch) \
V(CmpObjectEqAndBranch) \ V(CmpObjectEqAndBranch) \
V(CmpHoleAndBranch) \ V(CmpHoleAndBranch) \
...@@ -406,19 +407,32 @@ class LInstructionGap V8_FINAL : public LGap { ...@@ -406,19 +407,32 @@ class LInstructionGap V8_FINAL : public LGap {
}; };
class LClobberDoubles V8_FINAL : public LTemplateInstruction<0, 0, 0> {
public:
LClobberDoubles() { ASSERT(!CpuFeatures::IsSafeForSnapshot(SSE2)); }
virtual bool ClobbersDoubleRegisters() const { return true; }
DECLARE_CONCRETE_INSTRUCTION(ClobberDoubles, "clobber-d")
};
class LGoto V8_FINAL : public LTemplateInstruction<0, 0, 0> { class LGoto V8_FINAL : public LTemplateInstruction<0, 0, 0> {
public: public:
explicit LGoto(int block_id) : block_id_(block_id) { } explicit LGoto(HBasicBlock* block) : block_(block) { }
virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE; virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE;
DECLARE_CONCRETE_INSTRUCTION(Goto, "goto") DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
virtual bool IsControl() const V8_OVERRIDE { return true; } virtual bool IsControl() const V8_OVERRIDE { return true; }
int block_id() const { return block_id_; } int block_id() const { return block_->block_id(); }
virtual bool ClobbersDoubleRegisters() const { return false; }
bool jumps_to_join() const { return block_->predecessors()->length() > 1; }
private: private:
int block_id_; HBasicBlock* block_;
}; };
......
...@@ -2798,6 +2798,8 @@ void MacroAssembler::Ret(int bytes_dropped, Register scratch) { ...@@ -2798,6 +2798,8 @@ void MacroAssembler::Ret(int bytes_dropped, Register scratch) {
void MacroAssembler::VerifyX87StackDepth(uint32_t depth) { void MacroAssembler::VerifyX87StackDepth(uint32_t depth) {
// Make sure the floating point stack is either empty or has depth items. // Make sure the floating point stack is either empty or has depth items.
ASSERT(depth <= 7); ASSERT(depth <= 7);
// This is very expensive.
ASSERT(FLAG_debug_code && FLAG_enable_slow_asserts);
// The top-of-stack (tos) is 7 if there is one item pushed. // The top-of-stack (tos) is 7 if there is one item pushed.
int tos = (8 - depth) % 8; int tos = (8 - depth) % 8;
......
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