Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(185)

Unified Diff: src/fast-codegen.cc

Issue 660095: Merge revision 3813 to 3930 from bleeding_edge to partial snapshots branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: '' Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/fast-codegen.h ('k') | src/frame-element.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/fast-codegen.cc
===================================================================
--- src/fast-codegen.cc (revision 3935)
+++ src/fast-codegen.cc (working copy)
@@ -89,10 +89,10 @@
void FastCodeGenSyntaxChecker::VisitStatements(ZoneList<Statement*>* stmts) {
- for (int i = 0, len = stmts->length(); i < len; i++) {
- Visit(stmts->at(i));
- CHECK_BAILOUT;
+ if (stmts->length() != 1) {
+ BAILOUT("Function body is not a singleton statement.");
}
+ Visit(stmts->at(0));
}
@@ -220,9 +220,17 @@
if (info()->has_global_object()) {
LookupResult lookup;
info()->global_object()->Lookup(*expr->name(), &lookup);
- if (!lookup.IsValid() || !lookup.IsDontDelete()) {
- BAILOUT("Non-existing or deletable global variable");
+ if (!lookup.IsProperty()) {
+ BAILOUT("Non-existing global variable");
}
+ // We do not handle global variables with accessors or interceptors.
+ if (lookup.type() != NORMAL) {
+ BAILOUT("Global variable with accessors or interceptors.");
+ }
+ // We do not handle deletable global variables.
+ if (!lookup.IsDontDelete()) {
+ BAILOUT("Deletable global variable");
+ }
}
}
@@ -276,6 +284,9 @@
Handle<String> name = Handle<String>::cast(key->handle());
LookupResult lookup;
receiver->Lookup(*name, &lookup);
+ if (!lookup.IsProperty()) {
+ BAILOUT("Assigned property not found at compile time");
+ }
if (lookup.holder() != *receiver) BAILOUT("Non-own property assignment");
if (!lookup.type() == FIELD) BAILOUT("Non-field property assignment");
} else {
@@ -293,7 +304,33 @@
void FastCodeGenSyntaxChecker::VisitProperty(Property* expr) {
- BAILOUT("Property");
+ // We support named this property references.
+ VariableProxy* proxy = expr->obj()->AsVariableProxy();
+ if (proxy == NULL || !proxy->var()->is_this()) {
+ BAILOUT("Non-this-property reference");
+ }
+ if (!expr->key()->IsPropertyName()) {
+ BAILOUT("Non-named-property reference");
+ }
+
+ // We will only specialize for fields on the object itself.
+ // Expression::IsPropertyName implies that the name is a literal
+ // symbol but we do not assume that.
+ Literal* key = expr->key()->AsLiteral();
+ if (key != NULL && key->handle()->IsString()) {
+ Handle<Object> receiver = info()->receiver();
+ Handle<String> name = Handle<String>::cast(key->handle());
+ LookupResult lookup;
+ receiver->Lookup(*name, &lookup);
+ if (!lookup.IsProperty()) {
+ BAILOUT("Referenced property not found at compile time");
+ }
+ if (lookup.holder() != *receiver) BAILOUT("Non-own property reference");
+ if (!lookup.type() == FIELD) BAILOUT("Non-field property reference");
+ } else {
+ UNREACHABLE();
+ BAILOUT("Unexpected non-string-literal property key");
+ }
}
@@ -323,7 +360,58 @@
void FastCodeGenSyntaxChecker::VisitBinaryOperation(BinaryOperation* expr) {
- BAILOUT("BinaryOperation");
+ // We support bitwise OR.
+ switch (expr->op()) {
+ case Token::COMMA:
+ BAILOUT("BinaryOperation COMMA");
+ case Token::OR:
+ BAILOUT("BinaryOperation OR");
+ case Token::AND:
+ BAILOUT("BinaryOperation AND");
+
+ case Token::BIT_OR:
+ // We support expressions nested on the left because they only require
+ // a pair of registers to keep all intermediate values in registers
+ // (i.e., the expression stack has height no more than two).
+ if (!expr->right()->IsLeaf()) BAILOUT("expression nested on right");
+
+ // We do not allow subexpressions with side effects because we
+ // (currently) bail out to the beginning of the full function. The
+ // only expressions with side effects that we would otherwise handle
+ // are assignments.
+ if (expr->left()->AsAssignment() != NULL ||
+ expr->right()->AsAssignment() != NULL) {
+ BAILOUT("subexpression of binary operation has side effects");
+ }
+
+ Visit(expr->left());
+ CHECK_BAILOUT;
+ Visit(expr->right());
+ break;
+
+ case Token::BIT_XOR:
+ BAILOUT("BinaryOperation BIT_XOR");
+ case Token::BIT_AND:
+ BAILOUT("BinaryOperation BIT_AND");
+ case Token::SHL:
+ BAILOUT("BinaryOperation SHL");
+ case Token::SAR:
+ BAILOUT("BinaryOperation SAR");
+ case Token::SHR:
+ BAILOUT("BinaryOperation SHR");
+ case Token::ADD:
+ BAILOUT("BinaryOperation ADD");
+ case Token::SUB:
+ BAILOUT("BinaryOperation SUB");
+ case Token::MUL:
+ BAILOUT("BinaryOperation MUL");
+ case Token::DIV:
+ BAILOUT("BinaryOperation DIV");
+ case Token::MOD:
+ BAILOUT("BinaryOperation MOD");
+ default:
+ UNREACHABLE();
+ }
}
@@ -348,6 +436,9 @@
AstLabeler labeler;
labeler.Label(info);
+ LivenessAnalyzer analyzer;
+ analyzer.Analyze(info->function());
+
CodeGenerator::MakeCodePrologue(info);
const int kInitialBufferSize = 4 * KB;
@@ -365,7 +456,8 @@
// macro assembler.
CodeGenerator cgen(&masm);
CodeGeneratorScope scope(&cgen);
- cgen.Generate(info, CodeGenerator::SECONDARY);
+ info->set_mode(CompilationInfo::SECONDARY);
+ cgen.Generate(info);
if (cgen.HasStackOverflow()) {
ASSERT(!Top::has_pending_exception());
return Handle<Code>::null();
@@ -489,21 +581,28 @@
void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
ASSERT(expr->var()->is_global() && !expr->var()->is_this());
- Comment cmnt(masm(), ";; Global");
- if (FLAG_print_ir) {
- SmartPointer<char> name = expr->name()->ToCString();
- PrintF("%d: t%d = Global(%s)\n", expr->num(), expr->num(), *name);
- }
-
// Check if we can compile a global variable load directly from the cell.
ASSERT(info()->has_global_object());
LookupResult lookup;
info()->global_object()->Lookup(*expr->name(), &lookup);
- // We only support DontDelete properties for now.
- ASSERT(lookup.IsValid());
+ // We only support normal (non-accessor/interceptor) DontDelete properties
+ // for now.
+ ASSERT(lookup.IsProperty());
+ ASSERT_EQ(NORMAL, lookup.type());
ASSERT(lookup.IsDontDelete());
Handle<Object> cell(info()->global_object()->GetPropertyCell(&lookup));
- EmitGlobalVariableLoad(cell);
+
+ // Global variable lookups do not have side effects, so we do not need to
+ // emit code if we are in an effect context.
+ if (!destination().is(no_reg)) {
+ Comment cmnt(masm(), ";; Global");
+ if (FLAG_print_ir) {
+ SmartPointer<char> name = expr->name()->ToCString();
+ PrintF("%d: t%d = Global(%s) // last_use = %d\n", expr->num(),
+ expr->num(), *name, expr->var_def()->last_use()->num());
+ }
+ EmitGlobalVariableLoad(cell);
+ }
}
@@ -533,8 +632,13 @@
void FastCodeGenerator::VisitAssignment(Assignment* expr) {
- // Known to be a simple this property assignment.
- Visit(expr->value());
+ // Known to be a simple this property assignment. Effectively a unary
+ // operation.
+ { Register my_destination = destination();
+ set_destination(accumulator0());
+ Visit(expr->value());
+ set_destination(my_destination);
+ }
Property* prop = expr->target()->AsProperty();
ASSERT_NOT_NULL(prop);
@@ -544,11 +648,14 @@
Handle<String> name =
Handle<String>::cast(prop->key()->AsLiteral()->handle());
- Comment cmnt(masm(), ";; Store(this)");
+ Comment cmnt(masm(), ";; Store to this");
if (FLAG_print_ir) {
SmartPointer<char> name_string = name->ToCString();
- PrintF("%d: t%d = Store(this, \"%s\", t%d)\n",
- expr->num(), expr->num(), *name_string, expr->value()->num());
+ PrintF("%d: ", expr->num());
+ if (!destination().is(no_reg)) PrintF("t%d = ", expr->num());
+ PrintF("Store(this, \"%s\", t%d) // last_use(this) = %d\n", *name_string,
+ expr->value()->num(),
+ expr->var_def()->last_use()->num());
}
EmitThisPropertyStore(name);
@@ -561,7 +668,22 @@
void FastCodeGenerator::VisitProperty(Property* expr) {
- UNREACHABLE();
+ ASSERT_NOT_NULL(expr->obj()->AsVariableProxy());
+ ASSERT(expr->obj()->AsVariableProxy()->var()->is_this());
+ ASSERT(expr->key()->IsPropertyName());
+ if (!destination().is(no_reg)) {
+ Handle<String> name =
+ Handle<String>::cast(expr->key()->AsLiteral()->handle());
+
+ Comment cmnt(masm(), ";; Load from this");
+ if (FLAG_print_ir) {
+ SmartPointer<char> name_string = name->ToCString();
+ PrintF("%d: t%d = Load(this, \"%s\") // last_use(this) = %d\n",
+ expr->num(), expr->num(), *name_string,
+ expr->var_def()->last_use()->num());
+ }
+ EmitThisPropertyLoad(name);
+ }
}
@@ -591,7 +713,26 @@
void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
- UNREACHABLE();
+ // We support limited binary operations: bitwise OR only allowed to be
+ // nested on the left.
+ ASSERT(expr->op() == Token::BIT_OR);
+ ASSERT(expr->right()->IsLeaf());
+
+ { Register my_destination = destination();
+ set_destination(accumulator1());
+ Visit(expr->left());
+ set_destination(accumulator0());
+ Visit(expr->right());
+ set_destination(my_destination);
+ }
+
+ Comment cmnt(masm(), ";; BIT_OR");
+ if (FLAG_print_ir) {
+ PrintF("%d: ", expr->num());
+ if (!destination().is(no_reg)) PrintF("t%d = ", expr->num());
+ PrintF("BIT_OR(t%d, t%d)\n", expr->left()->num(), expr->right()->num());
+ }
+ EmitBitOr();
}
« no previous file with comments | « src/fast-codegen.h ('k') | src/frame-element.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698