Fix code generation for fast smi loops to support parameters as well.

This change fixes an assert we hit when we recognized a fast smi loop
with a parameter as the loop variable.

BUG=650


Review URL: http://codereview.chromium.org/1138003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4202 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
fschneider@chromium.org 2010-03-22 11:55:12 +00:00
parent fafd5dd599
commit 03089b6644
7 changed files with 39 additions and 19 deletions

View File

@ -365,6 +365,7 @@ class VirtualFrame : public ZoneObject {
inline void Nip(int num_dropped); inline void Nip(int num_dropped);
inline void SetTypeForLocalAt(int index, NumberInfo info); inline void SetTypeForLocalAt(int index, NumberInfo info);
inline void SetTypeForParamAt(int index, NumberInfo info);
private: private:
static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset; static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset;

View File

@ -3652,6 +3652,26 @@ void CodeGenerator::VisitWhileStatement(WhileStatement* node) {
} }
void CodeGenerator::SetTypeForStackSlot(Slot* slot, NumberInfo info) {
ASSERT(slot->type() == Slot::LOCAL || slot->type() == Slot::PARAMETER);
if (slot->type() == Slot::LOCAL) {
frame_->SetTypeForLocalAt(slot->index(), info);
} else {
frame_->SetTypeForParamAt(slot->index(), info);
}
if (FLAG_debug_code && info.IsSmi()) {
if (slot->type() == Slot::LOCAL) {
frame_->PushLocalAt(slot->index());
} else {
frame_->PushParameterAt(slot->index());
}
Result var = frame_->Pop();
var.ToRegister();
__ AbortIfNotSmi(var.reg());
}
}
void CodeGenerator::VisitForStatement(ForStatement* node) { void CodeGenerator::VisitForStatement(ForStatement* node) {
ASSERT(!in_spilled_code()); ASSERT(!in_spilled_code());
Comment cmnt(masm_, "[ ForStatement"); Comment cmnt(masm_, "[ ForStatement");
@ -3752,15 +3772,7 @@ void CodeGenerator::VisitForStatement(ForStatement* node) {
// the bottom check of the loop condition. // the bottom check of the loop condition.
if (node->is_fast_smi_loop()) { if (node->is_fast_smi_loop()) {
// Set number type of the loop variable to smi. // Set number type of the loop variable to smi.
Slot* slot = node->loop_variable()->slot(); SetTypeForStackSlot(node->loop_variable()->slot(), NumberInfo::Smi());
ASSERT(slot->type() == Slot::LOCAL);
frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi());
if (FLAG_debug_code) {
frame_->PushLocalAt(slot->index());
Result var = frame_->Pop();
var.ToRegister();
__ AbortIfNotSmi(var.reg());
}
} }
Visit(node->body()); Visit(node->body());
@ -3786,15 +3798,7 @@ void CodeGenerator::VisitForStatement(ForStatement* node) {
// expression if we are in a fast smi loop condition. // expression if we are in a fast smi loop condition.
if (node->is_fast_smi_loop() && has_valid_frame()) { if (node->is_fast_smi_loop() && has_valid_frame()) {
// Set number type of the loop variable to smi. // Set number type of the loop variable to smi.
Slot* slot = node->loop_variable()->slot(); SetTypeForStackSlot(node->loop_variable()->slot(), NumberInfo::Smi());
ASSERT(slot->type() == Slot::LOCAL);
frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi());
if (FLAG_debug_code) {
frame_->PushLocalAt(slot->index());
Result var = frame_->Pop();
var.ToRegister();
__ AbortIfNotSmi(var.reg());
}
} }
// Based on the condition analysis, compile the backward jump as // Based on the condition analysis, compile the backward jump as

View File

@ -652,6 +652,8 @@ class CodeGenerator: public AstVisitor {
void CodeForDoWhileConditionPosition(DoWhileStatement* stmt); void CodeForDoWhileConditionPosition(DoWhileStatement* stmt);
void CodeForSourcePosition(int pos); void CodeForSourcePosition(int pos);
void SetTypeForStackSlot(Slot* slot, NumberInfo info);
#ifdef DEBUG #ifdef DEBUG
// True if the registers are valid for entry to a block. There should // True if the registers are valid for entry to a block. There should
// be no frame-external references to (non-reserved) registers. // be no frame-external references to (non-reserved) registers.

View File

@ -446,8 +446,9 @@ class VirtualFrame: public ZoneObject {
return true; return true;
} }
// Update the type information of a local variable frame element directly. // Update the type information of a variable frame element directly.
inline void SetTypeForLocalAt(int index, NumberInfo info); inline void SetTypeForLocalAt(int index, NumberInfo info);
inline void SetTypeForParamAt(int index, NumberInfo info);
private: private:
static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset; static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset;

View File

@ -125,6 +125,11 @@ void VirtualFrame::SetTypeForLocalAt(int index, NumberInfo info) {
} }
void VirtualFrame::SetTypeForParamAt(int index, NumberInfo info) {
elements_[param0_index() + index].set_number_info(info);
}
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_VIRTUAL_FRAME_INL_H_ #endif // V8_VIRTUAL_FRAME_INL_H_

View File

@ -417,6 +417,7 @@ class VirtualFrame : public ZoneObject {
inline void Nip(int num_dropped); inline void Nip(int num_dropped);
inline void SetTypeForLocalAt(int index, NumberInfo info); inline void SetTypeForLocalAt(int index, NumberInfo info);
inline void SetTypeForParamAt(int index, NumberInfo info);
private: private:
static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset; static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset;

View File

@ -84,3 +84,9 @@ function f9() {
} }
} }
assertEquals(42, f9()); assertEquals(42, f9());
function f10(x) {
for (x = 0; x < 4; x++) {}
}
f10(42);