Commit a77411bc authored by whesse@chromium.org's avatar whesse@chromium.org

Revert changes 4088 and 4087 to fix build.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4089 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 8117a987
...@@ -364,8 +364,6 @@ class VirtualFrame : public ZoneObject { ...@@ -364,8 +364,6 @@ class VirtualFrame : public ZoneObject {
// the frame. Nip(k) is equivalent to x = Pop(), Drop(k), Push(x). // the frame. Nip(k) is equivalent to x = Pop(), Drop(k), Push(x).
inline void Nip(int num_dropped); inline void Nip(int num_dropped);
inline void SetTypeForLocalAt(int index, NumberInfo info);
private: private:
static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset; static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset;
static const int kFunctionOffset = JavaScriptFrameConstants::kFunctionOffset; static const int kFunctionOffset = JavaScriptFrameConstants::kFunctionOffset;
......
...@@ -58,27 +58,13 @@ AST_NODE_LIST(DECL_ACCEPT) ...@@ -58,27 +58,13 @@ AST_NODE_LIST(DECL_ACCEPT)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Implementation of other node functionality. // Implementation of other node functionality.
Assignment* ExpressionStatement::StatementAsSimpleAssignment() {
return (expression()->AsAssignment() != NULL &&
!expression()->AsAssignment()->is_compound())
? expression()->AsAssignment()
: NULL;
}
CountOperation* ExpressionStatement::StatementAsCountOperation() {
return expression()->AsCountOperation();
}
VariableProxy::VariableProxy(Handle<String> name, VariableProxy::VariableProxy(Handle<String> name,
bool is_this, bool is_this,
bool inside_with) bool inside_with)
: name_(name), : name_(name),
var_(NULL), var_(NULL),
is_this_(is_this), is_this_(is_this),
inside_with_(inside_with), inside_with_(inside_with) {
is_trivial_(false) {
// names must be canonicalized for fast equality checks // names must be canonicalized for fast equality checks
ASSERT(name->IsSymbol()); ASSERT(name->IsSymbol());
} }
......
...@@ -137,7 +137,6 @@ class AstNode: public ZoneObject { ...@@ -137,7 +137,6 @@ class AstNode: public ZoneObject {
virtual BreakableStatement* AsBreakableStatement() { return NULL; } virtual BreakableStatement* AsBreakableStatement() { return NULL; }
virtual IterationStatement* AsIterationStatement() { return NULL; } virtual IterationStatement* AsIterationStatement() { return NULL; }
virtual UnaryOperation* AsUnaryOperation() { return NULL; } virtual UnaryOperation* AsUnaryOperation() { return NULL; }
virtual CountOperation* AsCountOperation() { return NULL; }
virtual BinaryOperation* AsBinaryOperation() { return NULL; } virtual BinaryOperation* AsBinaryOperation() { return NULL; }
virtual Assignment* AsAssignment() { return NULL; } virtual Assignment* AsAssignment() { return NULL; }
virtual FunctionLiteral* AsFunctionLiteral() { return NULL; } virtual FunctionLiteral* AsFunctionLiteral() { return NULL; }
...@@ -162,9 +161,6 @@ class Statement: public AstNode { ...@@ -162,9 +161,6 @@ class Statement: public AstNode {
virtual Statement* AsStatement() { return this; } virtual Statement* AsStatement() { return this; }
virtual ReturnStatement* AsReturnStatement() { return NULL; } virtual ReturnStatement* AsReturnStatement() { return NULL; }
virtual Assignment* StatementAsSimpleAssignment() { return NULL; }
virtual CountOperation* StatementAsCountOperation() { return NULL; }
bool IsEmpty() { return AsEmptyStatement() != NULL; } bool IsEmpty() { return AsEmptyStatement() != NULL; }
void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; } void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; }
...@@ -325,16 +321,6 @@ class Block: public BreakableStatement { ...@@ -325,16 +321,6 @@ class Block: public BreakableStatement {
virtual void Accept(AstVisitor* v); virtual void Accept(AstVisitor* v);
virtual Assignment* StatementAsSimpleAssignment() {
if (statements_.length() != 1) return NULL;
return statements_[0]->StatementAsSimpleAssignment();
}
virtual CountOperation* StatementAsCountOperation() {
if (statements_.length() != 1) return NULL;
return statements_[0]->StatementAsCountOperation();
}
void AddStatement(Statement* statement) { statements_.Add(statement); } void AddStatement(Statement* statement) { statements_.Add(statement); }
ZoneList<Statement*>* statements() { return &statements_; } ZoneList<Statement*>* statements() { return &statements_; }
...@@ -456,8 +442,8 @@ class ForStatement: public IterationStatement { ...@@ -456,8 +442,8 @@ class ForStatement: public IterationStatement {
init_(NULL), init_(NULL),
cond_(NULL), cond_(NULL),
next_(NULL), next_(NULL),
may_have_function_literal_(true), may_have_function_literal_(true) {
loop_variable_(NULL) {} }
void Initialize(Statement* init, void Initialize(Statement* init,
Expression* cond, Expression* cond,
...@@ -478,17 +464,12 @@ class ForStatement: public IterationStatement { ...@@ -478,17 +464,12 @@ class ForStatement: public IterationStatement {
return may_have_function_literal_; return may_have_function_literal_;
} }
bool is_fast_smi_loop() { return loop_variable_ != NULL; }
Variable* loop_variable() { return loop_variable_; }
void set_loop_variable(Variable* var) { loop_variable_ = var; }
private: private:
Statement* init_; Statement* init_;
Expression* cond_; Expression* cond_;
Statement* next_; Statement* next_;
// True if there is a function literal subexpression in the condition. // True if there is a function literal subexpression in the condition.
bool may_have_function_literal_; bool may_have_function_literal_;
Variable* loop_variable_;
friend class AstOptimizer; friend class AstOptimizer;
}; };
...@@ -526,9 +507,6 @@ class ExpressionStatement: public Statement { ...@@ -526,9 +507,6 @@ class ExpressionStatement: public Statement {
// Type testing & conversion. // Type testing & conversion.
virtual ExpressionStatement* AsExpressionStatement() { return this; } virtual ExpressionStatement* AsExpressionStatement() { return this; }
virtual Assignment* StatementAsSimpleAssignment();
virtual CountOperation* StatementAsCountOperation();
void set_expression(Expression* e) { expression_ = e; } void set_expression(Expression* e) { expression_ = e; }
Expression* expression() { return expression_; } Expression* expression() { return expression_; }
...@@ -986,7 +964,7 @@ class VariableProxy: public Expression { ...@@ -986,7 +964,7 @@ class VariableProxy: public Expression {
// Reading from a mutable variable is a side effect, but 'this' is // Reading from a mutable variable is a side effect, but 'this' is
// immutable. // immutable.
virtual bool IsTrivial() { return is_trivial_; } virtual bool IsTrivial() { return is_this(); }
bool IsVariable(Handle<String> n) { bool IsVariable(Handle<String> n) {
return !is_this() && name().is_identical_to(n); return !is_this() && name().is_identical_to(n);
...@@ -1001,8 +979,6 @@ class VariableProxy: public Expression { ...@@ -1001,8 +979,6 @@ class VariableProxy: public Expression {
Variable* var() const { return var_; } Variable* var() const { return var_; }
bool is_this() const { return is_this_; } bool is_this() const { return is_this_; }
bool inside_with() const { return inside_with_; } bool inside_with() const { return inside_with_; }
bool is_trivial() { return is_trivial_; }
void set_is_trivial(bool b) { is_trivial_ = b; }
// Bind this proxy to the variable var. // Bind this proxy to the variable var.
void BindTo(Variable* var); void BindTo(Variable* var);
...@@ -1012,7 +988,6 @@ class VariableProxy: public Expression { ...@@ -1012,7 +988,6 @@ class VariableProxy: public Expression {
Variable* var_; // resolved variable, or NULL Variable* var_; // resolved variable, or NULL
bool is_this_; bool is_this_;
bool inside_with_; bool inside_with_;
bool is_trivial_;
VariableProxy(Handle<String> name, bool is_this, bool inside_with); VariableProxy(Handle<String> name, bool is_this, bool inside_with);
explicit VariableProxy(bool is_this); explicit VariableProxy(bool is_this);
...@@ -1271,8 +1246,6 @@ class CountOperation: public Expression { ...@@ -1271,8 +1246,6 @@ class CountOperation: public Expression {
virtual void Accept(AstVisitor* v); virtual void Accept(AstVisitor* v);
virtual CountOperation* AsCountOperation() { return this; }
bool is_prefix() const { return is_prefix_; } bool is_prefix() const { return is_prefix_; }
bool is_postfix() const { return !is_prefix_; } bool is_postfix() const { return !is_prefix_; }
Token::Value op() const { return op_; } Token::Value op() const { return op_; }
...@@ -1351,8 +1324,6 @@ class Assignment: public Expression { ...@@ -1351,8 +1324,6 @@ class Assignment: public Expression {
virtual void Accept(AstVisitor* v); virtual void Accept(AstVisitor* v);
virtual Assignment* AsAssignment() { return this; } virtual Assignment* AsAssignment() { return this; }
Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
Token::Value binary_op() const; Token::Value binary_op() const;
Token::Value op() const { return op_; } Token::Value op() const { return op_; }
......
...@@ -79,15 +79,6 @@ static Handle<Code> MakeCode(Handle<Context> context, CompilationInfo* info) { ...@@ -79,15 +79,6 @@ static Handle<Code> MakeCode(Handle<Context> context, CompilationInfo* info) {
return Handle<Code>::null(); return Handle<Code>::null();
} }
if (function->scope()->num_parameters() > 0 ||
function->scope()->num_stack_slots()) {
AssignedVariablesAnalyzer ava(function);
ava.Analyze();
if (ava.HasStackOverflow()) {
return Handle<Code>::null();
}
}
if (FLAG_use_flow_graph) { if (FLAG_use_flow_graph) {
FlowGraphBuilder builder; FlowGraphBuilder builder;
builder.Build(function); builder.Build(function);
...@@ -472,15 +463,6 @@ Handle<JSFunction> Compiler::BuildBoilerplate(FunctionLiteral* literal, ...@@ -472,15 +463,6 @@ Handle<JSFunction> Compiler::BuildBoilerplate(FunctionLiteral* literal,
return Handle<JSFunction>::null(); return Handle<JSFunction>::null();
} }
if (literal->scope()->num_parameters() > 0 ||
literal->scope()->num_stack_slots()) {
AssignedVariablesAnalyzer ava(literal);
ava.Analyze();
if (ava.HasStackOverflow()) {
return Handle<JSFunction>::null();
}
}
if (FLAG_use_flow_graph) { if (FLAG_use_flow_graph) {
FlowGraphBuilder builder; FlowGraphBuilder builder;
builder.Build(literal); builder.Build(literal);
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
#include "v8.h" #include "v8.h"
#include "data-flow.h" #include "data-flow.h"
#include "scopes.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -1036,445 +1035,6 @@ void LivenessAnalyzer::VisitThisFunction(ThisFunction* expr) { ...@@ -1036,445 +1035,6 @@ void LivenessAnalyzer::VisitThisFunction(ThisFunction* expr) {
} }
AssignedVariablesAnalyzer::AssignedVariablesAnalyzer(FunctionLiteral* fun)
: fun_(fun),
av_(fun->scope()->num_parameters() + fun->scope()->num_stack_slots()) {}
void AssignedVariablesAnalyzer::Analyze() {
ASSERT(av_.length() > 0);
VisitStatements(fun_->body());
}
Variable* AssignedVariablesAnalyzer::FindSmiLoopVariable(ForStatement* stmt) {
// The loop must have all necessary parts.
if (stmt->init() == NULL || stmt->cond() == NULL || stmt->next() == NULL) {
return NULL;
}
// The initialization statement has to be a simple assignment.
Assignment* init = stmt->init()->StatementAsSimpleAssignment();
if (init == NULL) return NULL;
// We only deal with local variables.
Variable* loop_var = init->target()->AsVariableProxy()->AsVariable();
if (!loop_var->IsStackAllocated()) return NULL;
// The initial value has to be a smi.
Literal* init_lit = init->value()->AsLiteral();
if (init_lit == NULL || !init_lit->handle()->IsSmi()) return NULL;
int init_value = Smi::cast(*init_lit->handle())->value();
// The condition must be a compare of variable with <, <=, >, or >=.
CompareOperation* cond = stmt->cond()->AsCompareOperation();
if (cond == NULL) return NULL;
if (cond->op() != Token::LT
&& cond->op() != Token::LTE
&& cond->op() != Token::GT
&& cond->op() != Token::GTE) return NULL;
// The lhs must be the same variable as in the init expression.
if (cond->left()->AsVariableProxy()->AsVariable() != loop_var) return NULL;
// The rhs must be a smi.
Literal* term_lit = cond->right()->AsLiteral();
if (term_lit == NULL || !term_lit->handle()->IsSmi()) return NULL;
int term_value = Smi::cast(*term_lit->handle())->value();
// The count operation updates the same variable as in the init expression.
CountOperation* update = stmt->next()->StatementAsCountOperation();
if (update == NULL) return NULL;
if (update->expression()->AsVariableProxy()->AsVariable() != loop_var) {
return NULL;
}
// The direction of the count operation must agree with the start and the end
// value. We currently do not allow the initial value to be the same as the
// terminal value. This _would_ be ok as long as the loop body never executes
// or executes exactly one time.
if (init_value == term_value) return NULL;
if (init_value < term_value && update->op() != Token::INC) return NULL;
if (init_value > term_value && update->op() != Token::DEC) return NULL;
// Found a smi loop variable.
return loop_var;
}
int AssignedVariablesAnalyzer::BitIndex(Variable* var) {
ASSERT(var != NULL);
ASSERT(var->IsStackAllocated());
Slot* slot = var->slot();
if (slot->type() == Slot::PARAMETER) {
return slot->index();
} else {
return fun_->scope()->num_parameters() + slot->index();
}
}
void AssignedVariablesAnalyzer::RecordAssignedVar(Variable* var) {
ASSERT(var != NULL);
if (var->IsStackAllocated()) {
av_.Add(BitIndex(var));
}
}
void AssignedVariablesAnalyzer::MarkIfTrivial(Expression* expr) {
Variable* var = expr->AsVariableProxy()->AsVariable();
if (var != NULL &&
var->IsStackAllocated() &&
(var->is_this() || !av_.Contains(BitIndex(var)))) {
expr->AsVariableProxy()->set_is_trivial(true);
}
}
void AssignedVariablesAnalyzer::ProcessExpression(Expression* expr) {
BitVector saved_av(av_);
av_.Clear();
Visit(expr);
av_.Union(saved_av);
}
void AssignedVariablesAnalyzer::VisitBlock(Block* stmt) {
VisitStatements(stmt->statements());
}
void AssignedVariablesAnalyzer::VisitExpressionStatement(
ExpressionStatement* stmt) {
ProcessExpression(stmt->expression());
}
void AssignedVariablesAnalyzer::VisitEmptyStatement(EmptyStatement* stmt) {
// Do nothing.
}
void AssignedVariablesAnalyzer::VisitIfStatement(IfStatement* stmt) {
ProcessExpression(stmt->condition());
Visit(stmt->then_statement());
Visit(stmt->else_statement());
}
void AssignedVariablesAnalyzer::VisitContinueStatement(
ContinueStatement* stmt) {
// Nothing to do.
}
void AssignedVariablesAnalyzer::VisitBreakStatement(BreakStatement* stmt) {
// Nothing to do.
}
void AssignedVariablesAnalyzer::VisitReturnStatement(ReturnStatement* stmt) {
ProcessExpression(stmt->expression());
}
void AssignedVariablesAnalyzer::VisitWithEnterStatement(
WithEnterStatement* stmt) {
ProcessExpression(stmt->expression());
}
void AssignedVariablesAnalyzer::VisitWithExitStatement(
WithExitStatement* stmt) {
// Nothing to do.
}
void AssignedVariablesAnalyzer::VisitSwitchStatement(SwitchStatement* stmt) {
BitVector result(av_);
av_.Clear();
Visit(stmt->tag());
result.Union(av_);
for (int i = 0; i < stmt->cases()->length(); i++) {
CaseClause* clause = stmt->cases()->at(i);
if (!clause->is_default()) {
av_.Clear();
Visit(clause->label());
result.Union(av_);
}
VisitStatements(clause->statements());
}
av_.Union(result);
}
void AssignedVariablesAnalyzer::VisitDoWhileStatement(DoWhileStatement* stmt) {
ProcessExpression(stmt->cond());
Visit(stmt->body());
}
void AssignedVariablesAnalyzer::VisitWhileStatement(WhileStatement* stmt) {
ProcessExpression(stmt->cond());
Visit(stmt->body());
}
void AssignedVariablesAnalyzer::VisitForStatement(ForStatement* stmt) {
if (stmt->init() != NULL) Visit(stmt->init());
if (stmt->cond() != NULL) ProcessExpression(stmt->cond());
if (stmt->next() != NULL) Visit(stmt->next());
// Process loop body. After visiting the loop body av_ contains
// the assigned variables of the loop body.
BitVector saved_av(av_);
av_.Clear();
Visit(stmt->body());
Variable* var = FindSmiLoopVariable(stmt);
if (var != NULL && !av_.Contains(BitIndex(var))) {
stmt->set_loop_variable(var);
}
av_.Union(saved_av);
}
void AssignedVariablesAnalyzer::VisitForInStatement(ForInStatement* stmt) {
ProcessExpression(stmt->each());
ProcessExpression(stmt->enumerable());
Visit(stmt->body());
}
void AssignedVariablesAnalyzer::VisitTryCatchStatement(
TryCatchStatement* stmt) {
Visit(stmt->try_block());
Visit(stmt->catch_block());
}
void AssignedVariablesAnalyzer::VisitTryFinallyStatement(
TryFinallyStatement* stmt) {
Visit(stmt->try_block());
Visit(stmt->finally_block());
}
void AssignedVariablesAnalyzer::VisitDebuggerStatement(
DebuggerStatement* stmt) {
// Nothing to do.
}
void AssignedVariablesAnalyzer::VisitFunctionLiteral(FunctionLiteral* expr) {
// Nothing to do.
ASSERT(av_.IsEmpty());
}
void AssignedVariablesAnalyzer::VisitFunctionBoilerplateLiteral(
FunctionBoilerplateLiteral* expr) {
// Nothing to do.
ASSERT(av_.IsEmpty());
}
void AssignedVariablesAnalyzer::VisitConditional(Conditional* expr) {
ASSERT(av_.IsEmpty());
Visit(expr->condition());
BitVector result(av_);
av_.Clear();
Visit(expr->then_expression());
result.Union(av_);
av_.Clear();
Visit(expr->else_expression());
av_.Union(result);
}
void AssignedVariablesAnalyzer::VisitSlot(Slot* expr) {
UNREACHABLE();
}
void AssignedVariablesAnalyzer::VisitVariableProxy(VariableProxy* expr) {
// Nothing to do.
ASSERT(av_.IsEmpty());
}
void AssignedVariablesAnalyzer::VisitLiteral(Literal* expr) {
// Nothing to do.
ASSERT(av_.IsEmpty());
}
void AssignedVariablesAnalyzer::VisitRegExpLiteral(RegExpLiteral* expr) {
// Nothing to do.
ASSERT(av_.IsEmpty());
}
void AssignedVariablesAnalyzer::VisitObjectLiteral(ObjectLiteral* expr) {
ASSERT(av_.IsEmpty());
BitVector result(av_.length());
for (int i = 0; i < expr->properties()->length(); i++) {
Visit(expr->properties()->at(i)->value());
result.Union(av_);
av_.Clear();
}
av_.CopyFrom(result);
}
void AssignedVariablesAnalyzer::VisitArrayLiteral(ArrayLiteral* expr) {
ASSERT(av_.IsEmpty());
BitVector result(av_.length());
for (int i = 0; i < expr->values()->length(); i++) {
Visit(expr->values()->at(i));
result.Union(av_);
av_.Clear();
}
av_.CopyFrom(result);
}
void AssignedVariablesAnalyzer::VisitCatchExtensionObject(
CatchExtensionObject* expr) {
ASSERT(av_.IsEmpty());
Visit(expr->key());
ProcessExpression(expr->value());
}
void AssignedVariablesAnalyzer::VisitAssignment(Assignment* expr) {
ASSERT(av_.IsEmpty());
Visit(expr->target());
ProcessExpression(expr->value());
Variable* var = expr->target()->AsVariableProxy()->AsVariable();
if (var != NULL) RecordAssignedVar(var);
// If we have a variable as a receiver in a property store, check if
// we can mark it as trivial.
if (expr->target()->AsProperty() != NULL) {
MarkIfTrivial(expr->target()->AsProperty()->obj());
}
}
void AssignedVariablesAnalyzer::VisitThrow(Throw* expr) {
ASSERT(av_.IsEmpty());
Visit(expr->exception());
}
void AssignedVariablesAnalyzer::VisitProperty(Property* expr) {
ASSERT(av_.IsEmpty());
Visit(expr->obj());
ProcessExpression(expr->key());
// In case we have a variable as a receiver, check if we can mark
// it as trivial.
MarkIfTrivial(expr->obj());
}
void AssignedVariablesAnalyzer::VisitCall(Call* expr) {
ASSERT(av_.IsEmpty());
Visit(expr->expression());
BitVector result(av_);
for (int i = 0; i < expr->arguments()->length(); i++) {
av_.Clear();
Visit(expr->arguments()->at(i));
result.Union(av_);
}
av_.CopyFrom(result);
}
void AssignedVariablesAnalyzer::VisitCallNew(CallNew* expr) {
ASSERT(av_.IsEmpty());
Visit(expr->expression());
BitVector result(av_);
for (int i = 0; i < expr->arguments()->length(); i++) {
av_.Clear();
Visit(expr->arguments()->at(i));
result.Union(av_);
}
av_.CopyFrom(result);
}
void AssignedVariablesAnalyzer::VisitCallRuntime(CallRuntime* expr) {
ASSERT(av_.IsEmpty());
BitVector result(av_);
for (int i = 0; i < expr->arguments()->length(); i++) {
av_.Clear();
Visit(expr->arguments()->at(i));
result.Union(av_);
}
av_.CopyFrom(result);
}
void AssignedVariablesAnalyzer::VisitUnaryOperation(UnaryOperation* expr) {
ASSERT(av_.IsEmpty());
Visit(expr->expression());
}
void AssignedVariablesAnalyzer::VisitCountOperation(CountOperation* expr) {
ASSERT(av_.IsEmpty());
Visit(expr->expression());
Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
if (var != NULL) RecordAssignedVar(var);
}
void AssignedVariablesAnalyzer::VisitBinaryOperation(BinaryOperation* expr) {
ASSERT(av_.IsEmpty());
Visit(expr->left());
ProcessExpression(expr->right());
// In case we have a variable on the left side, check if we can mark
// it as trivial.
MarkIfTrivial(expr->left());
}
void AssignedVariablesAnalyzer::VisitCompareOperation(CompareOperation* expr) {
ASSERT(av_.IsEmpty());
Visit(expr->left());
ProcessExpression(expr->right());
// In case we have a variable on the left side, check if we can mark
// it as trivial.
MarkIfTrivial(expr->left());
}
void AssignedVariablesAnalyzer::VisitThisFunction(ThisFunction* expr) {
// Nothing to do.
ASSERT(av_.IsEmpty());
}
void AssignedVariablesAnalyzer::VisitDeclaration(Declaration* decl) {
UNREACHABLE();
}
#ifdef DEBUG #ifdef DEBUG
// Print a textual representation of an instruction in a flow graph. Using // Print a textual representation of an instruction in a flow graph. Using
......
...@@ -43,6 +43,7 @@ class BitVector: public ZoneObject { ...@@ -43,6 +43,7 @@ class BitVector: public ZoneObject {
: length_(length), : length_(length),
data_length_(SizeFor(length)), data_length_(SizeFor(length)),
data_(Zone::NewArray<uint32_t>(data_length_)) { data_(Zone::NewArray<uint32_t>(data_length_)) {
ASSERT(length > 0);
Clear(); Clear();
} }
...@@ -485,41 +486,6 @@ class LivenessAnalyzer : public AstVisitor { ...@@ -485,41 +486,6 @@ class LivenessAnalyzer : public AstVisitor {
}; };
// Computes the set of assigned variables and annotates variables proxies
// that are trivial sub-expressions and for-loops where the loop variable
// is guaranteed to be a smi.
class AssignedVariablesAnalyzer : public AstVisitor {
public:
explicit AssignedVariablesAnalyzer(FunctionLiteral* fun);
void Analyze();
private:
Variable* FindSmiLoopVariable(ForStatement* stmt);
int BitIndex(Variable* var);
void RecordAssignedVar(Variable* var);
void MarkIfTrivial(Expression* expr);
// Visits an expression saving the accumulator before, clearing
// it before visting and restoring it after visiting.
void ProcessExpression(Expression* expr);
// AST node visit functions.
#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
AST_NODE_LIST(DECLARE_VISIT)
#undef DECLARE_VISIT
FunctionLiteral* fun_;
// Accumulator for assigned variables set.
BitVector av_;
DISALLOW_COPY_AND_ASSIGN(AssignedVariablesAnalyzer);
};
} } // namespace v8::internal } } // namespace v8::internal
......
...@@ -2286,12 +2286,6 @@ void CodeGenerator::Comparison(AstNode* node, ...@@ -2286,12 +2286,6 @@ void CodeGenerator::Comparison(AstNode* node,
// a jump target and branching to duplicate the virtual frame at // a jump target and branching to duplicate the virtual frame at
// the first split. We manually handle the off-frame references // the first split. We manually handle the off-frame references
// by reconstituting them on the non-fall-through path. // by reconstituting them on the non-fall-through path.
if (left_side.is_smi()) {
if (FLAG_debug_code) {
__ AbortIfNotSmi(left_side.reg(), "Argument not a smi");
}
} else {
JumpTarget is_smi; JumpTarget is_smi;
__ test(left_side.reg(), Immediate(kSmiTagMask)); __ test(left_side.reg(), Immediate(kSmiTagMask));
is_smi.Branch(zero, taken); is_smi.Branch(zero, taken);
...@@ -2347,8 +2341,6 @@ void CodeGenerator::Comparison(AstNode* node, ...@@ -2347,8 +2341,6 @@ void CodeGenerator::Comparison(AstNode* node,
dest->false_target()->Jump(); dest->false_target()->Jump();
is_smi.Bind(); is_smi.Bind();
}
left_side = Result(left_reg); left_side = Result(left_reg);
right_side = Result(right_val); right_side = Result(right_val);
// Test smi equality and comparison by signed int comparison. // Test smi equality and comparison by signed int comparison.
...@@ -3587,24 +3579,6 @@ void CodeGenerator::VisitForStatement(ForStatement* node) { ...@@ -3587,24 +3579,6 @@ void CodeGenerator::VisitForStatement(ForStatement* node) {
} }
CheckStack(); // TODO(1222600): ignore if body contains calls. CheckStack(); // TODO(1222600): ignore if body contains calls.
// If we have (a) a loop with a compile-time constant trip count
// and (b) the loop induction variable is not assignend inside the
// loop we update the number type of the induction variable to be smi.
if (node->is_fast_smi_loop()) {
// Set number type of the loop variable to smi.
Slot* slot = node->loop_variable()->slot();
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(), "Loop variable not a smi.");
}
}
Visit(node->body()); Visit(node->body());
// If there is an update expression, compile it if necessary. // If there is an update expression, compile it if necessary.
...@@ -6650,19 +6624,6 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) { ...@@ -6650,19 +6624,6 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) {
__ Set(tmp.reg(), Immediate(0)); __ Set(tmp.reg(), Immediate(0));
} }
if (is_increment) {
__ add(Operand(new_value.reg()), Immediate(Smi::FromInt(1)));
} else {
__ sub(Operand(new_value.reg()), Immediate(Smi::FromInt(1)));
}
if (new_value.is_smi()) {
if (FLAG_debug_code) {
__ AbortIfNotSmi(new_value.reg(), "Argument not a smi");
}
if (tmp.is_valid()) tmp.Unuse();
} else {
DeferredCode* deferred = NULL; DeferredCode* deferred = NULL;
if (is_postfix) { if (is_postfix) {
deferred = new DeferredPostfixCountOperation(new_value.reg(), deferred = new DeferredPostfixCountOperation(new_value.reg(),
...@@ -6673,6 +6634,12 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) { ...@@ -6673,6 +6634,12 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) {
is_increment); is_increment);
} }
if (is_increment) {
__ add(Operand(new_value.reg()), Immediate(Smi::FromInt(1)));
} else {
__ sub(Operand(new_value.reg()), Immediate(Smi::FromInt(1)));
}
// If the count operation didn't overflow and the result is a valid // If the count operation didn't overflow and the result is a valid
// smi, we're done. Otherwise, we jump to the deferred slow-case // smi, we're done. Otherwise, we jump to the deferred slow-case
// code. // code.
...@@ -6691,7 +6658,6 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) { ...@@ -6691,7 +6658,6 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) {
deferred->Branch(not_zero); deferred->Branch(not_zero);
} }
deferred->BindExit(); deferred->BindExit();
}
// Postfix: store the old value in the allocated slot under the // Postfix: store the old value in the allocated slot under the
// reference. // reference.
...@@ -6857,15 +6823,8 @@ void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) { ...@@ -6857,15 +6823,8 @@ void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) {
overwrite_mode = OVERWRITE_RIGHT; overwrite_mode = OVERWRITE_RIGHT;
} }
if (node->left()->IsTrivial()) {
Load(node->right());
Result right = frame_->Pop();
frame_->Push(node->left());
frame_->Push(&right);
} else {
Load(node->left()); Load(node->left());
Load(node->right()); Load(node->right());
}
GenericBinaryOperation(node->op(), node->type(), overwrite_mode); GenericBinaryOperation(node->op(), node->type(), overwrite_mode);
} }
} }
...@@ -7065,20 +7024,8 @@ void CodeGenerator::VisitCompareOperation(CompareOperation* node) { ...@@ -7065,20 +7024,8 @@ void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
default: default:
UNREACHABLE(); UNREACHABLE();
} }
if (left->IsTrivial()) {
if (!left_already_loaded) {
Load(right);
Result right_result = frame_->Pop();
frame_->Push(left);
frame_->Push(&right_result);
} else {
Load(right);
}
} else {
if (!left_already_loaded) Load(left); if (!left_already_loaded) Load(left);
Load(right); Load(right);
}
Comparison(node, cc, strict, destination()); Comparison(node, cc, strict, destination());
} }
......
...@@ -397,12 +397,6 @@ void MacroAssembler::AbortIfNotNumber(Register object, const char* msg) { ...@@ -397,12 +397,6 @@ void MacroAssembler::AbortIfNotNumber(Register object, const char* msg) {
} }
void MacroAssembler::AbortIfNotSmi(Register object, const char* msg) {
test(object, Immediate(kSmiTagMask));
Assert(equal, msg);
}
void MacroAssembler::EnterFrame(StackFrame::Type type) { void MacroAssembler::EnterFrame(StackFrame::Type type) {
push(ebp); push(ebp);
mov(ebp, Operand(esp)); mov(ebp, Operand(esp));
......
...@@ -179,9 +179,6 @@ class MacroAssembler: public Assembler { ...@@ -179,9 +179,6 @@ class MacroAssembler: public Assembler {
// Abort execution if argument is not a number. Used in debug code. // Abort execution if argument is not a number. Used in debug code.
void AbortIfNotNumber(Register object, const char* msg); void AbortIfNotNumber(Register object, const char* msg);
// Abort execution if argument is not a smi. Used in debug code.
void AbortIfNotSmi(Register object, const char* msg);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Exception handling // Exception handling
......
...@@ -1171,17 +1171,11 @@ void VirtualFrame::Push(Expression* expr) { ...@@ -1171,17 +1171,11 @@ void VirtualFrame::Push(Expression* expr) {
} }
VariableProxy* proxy = expr->AsVariableProxy(); VariableProxy* proxy = expr->AsVariableProxy();
if (proxy != NULL) { if (proxy != NULL && proxy->is_this()) {
Slot* slot = proxy->var()->slot(); PushParameterAt(-1);
if (slot->type() == Slot::LOCAL) {
PushLocalAt(slot->index());
return; return;
} }
if (slot->type() == Slot::PARAMETER) {
PushParameterAt(slot->index());
return;
}
}
UNREACHABLE(); UNREACHABLE();
} }
......
...@@ -422,9 +422,6 @@ class VirtualFrame: public ZoneObject { ...@@ -422,9 +422,6 @@ class VirtualFrame: public ZoneObject {
// the frame. Nip(k) is equivalent to x = Pop(), Drop(k), Push(x). // the frame. Nip(k) is equivalent to x = Pop(), Drop(k), Push(x).
inline void Nip(int num_dropped); inline void Nip(int num_dropped);
// Update the type information of a local variable frame element directly.
inline void SetTypeForLocalAt(int index, NumberInfo info);
private: private:
static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset; static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset;
static const int kFunctionOffset = JavaScriptFrameConstants::kFunctionOffset; static const int kFunctionOffset = JavaScriptFrameConstants::kFunctionOffset;
......
...@@ -277,6 +277,7 @@ class Scope: public ZoneObject { ...@@ -277,6 +277,7 @@ class Scope: public ZoneObject {
// The number of contexts between this and scope; zero if this == scope. // The number of contexts between this and scope; zero if this == scope.
int ContextChainLength(Scope* scope); int ContextChainLength(Scope* scope);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Debugging. // Debugging.
......
...@@ -119,12 +119,6 @@ bool VirtualFrame::Equals(VirtualFrame* other) { ...@@ -119,12 +119,6 @@ bool VirtualFrame::Equals(VirtualFrame* other) {
return true; return true;
} }
void VirtualFrame::SetTypeForLocalAt(int index, NumberInfo info) {
elements_[local0_index() + index].set_number_info(info);
}
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_VIRTUAL_FRAME_INL_H_ #endif // V8_VIRTUAL_FRAME_INL_H_
...@@ -416,8 +416,6 @@ class VirtualFrame : public ZoneObject { ...@@ -416,8 +416,6 @@ class VirtualFrame : public ZoneObject {
// the frame. Nip(k) is equivalent to x = Pop(), Drop(k), Push(x). // the frame. Nip(k) is equivalent to x = Pop(), Drop(k), Push(x).
inline void Nip(int num_dropped); inline void Nip(int num_dropped);
inline void SetTypeForLocalAt(int index, NumberInfo info);
private: private:
static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset; static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset;
static const int kFunctionOffset = JavaScriptFrameConstants::kFunctionOffset; static const int kFunctionOffset = JavaScriptFrameConstants::kFunctionOffset;
......
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