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

Side by Side Diff: src/compiler.cc

Issue 273050: Initial infrastructure for fast compilation of top-level code. The... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 2 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/codegen.cc ('k') | src/fast-codegen.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 14 matching lines...) Expand all
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "bootstrapper.h" 30 #include "bootstrapper.h"
31 #include "codegen-inl.h" 31 #include "codegen-inl.h"
32 #include "compilation-cache.h" 32 #include "compilation-cache.h"
33 #include "compiler.h" 33 #include "compiler.h"
34 #include "debug.h" 34 #include "debug.h"
35 #include "fast-codegen.h"
35 #include "oprofile-agent.h" 36 #include "oprofile-agent.h"
36 #include "rewriter.h" 37 #include "rewriter.h"
37 #include "scopes.h" 38 #include "scopes.h"
38 #include "usage-analyzer.h" 39 #include "usage-analyzer.h"
39 40
40 namespace v8 { 41 namespace v8 {
41 namespace internal { 42 namespace internal {
42 43
44 #ifdef V8_TARGET_ARCH_IA32
45
46 class CodeGenSelector: public AstVisitor {
47 public:
48 enum CodeGenTag { NORMAL, FAST };
49
50 CodeGenSelector() : has_supported_syntax_(true) {}
51
52 CodeGenTag Select(FunctionLiteral* fun);
53
54 private:
55 void VisitStatements(ZoneList<Statement*>* stmts);
56
57 // AST node visit functions.
58 #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
59 AST_NODE_LIST(DECLARE_VISIT)
60 #undef DECLARE_VISIT
61
62 bool has_supported_syntax_;
63
64 DISALLOW_COPY_AND_ASSIGN(CodeGenSelector);
65 };
66
67 #endif
68
69
43 static Handle<Code> MakeCode(FunctionLiteral* literal, 70 static Handle<Code> MakeCode(FunctionLiteral* literal,
44 Handle<Script> script, 71 Handle<Script> script,
45 Handle<Context> context, 72 Handle<Context> context,
46 bool is_eval) { 73 bool is_eval) {
47 ASSERT(literal != NULL); 74 ASSERT(literal != NULL);
48 75
49 // Rewrite the AST by introducing .result assignments where needed. 76 // Rewrite the AST by introducing .result assignments where needed.
50 if (!Rewriter::Process(literal) || !AnalyzeVariableUsage(literal)) { 77 if (!Rewriter::Process(literal) || !AnalyzeVariableUsage(literal)) {
51 // Signal a stack overflow by returning a null handle. The stack 78 // Signal a stack overflow by returning a null handle. The stack
52 // overflow exception will be thrown by the caller. 79 // overflow exception will be thrown by the caller.
(...skipping 19 matching lines...) Expand all
72 #endif 99 #endif
73 100
74 // Optimize the AST. 101 // Optimize the AST.
75 if (!Rewriter::Optimize(literal)) { 102 if (!Rewriter::Optimize(literal)) {
76 // Signal a stack overflow by returning a null handle. The stack 103 // Signal a stack overflow by returning a null handle. The stack
77 // overflow exception will be thrown by the caller. 104 // overflow exception will be thrown by the caller.
78 return Handle<Code>::null(); 105 return Handle<Code>::null();
79 } 106 }
80 107
81 // Generate code and return it. 108 // Generate code and return it.
82 Handle<Code> result = CodeGenerator::MakeCode(literal, script, is_eval); 109 #ifdef V8_TARGET_ARCH_IA32
83 return result; 110 if (FLAG_fast_compiler) {
111 CodeGenSelector selector;
112 CodeGenSelector::CodeGenTag code_gen = selector.Select(literal);
113 if (code_gen == CodeGenSelector::FAST) {
114 return FastCodeGenerator::MakeCode(literal, script);
115 }
116 ASSERT(code_gen == CodeGenSelector::NORMAL);
117 }
118 #endif
119
120 return CodeGenerator::MakeCode(literal, script, is_eval);
84 } 121 }
85 122
86 123
87 static bool IsValidJSON(FunctionLiteral* lit) { 124 static bool IsValidJSON(FunctionLiteral* lit) {
88 if (lit->body()->length() != 1) 125 if (lit->body()->length() != 1)
89 return false; 126 return false;
90 Statement* stmt = lit->body()->at(0); 127 Statement* stmt = lit->body()->at(0);
91 if (stmt->AsExpressionStatement() == NULL) 128 if (stmt->AsExpressionStatement() == NULL)
92 return false; 129 return false;
93 Expression* expr = stmt->AsExpressionStatement()->expression(); 130 Expression* expr = stmt->AsExpressionStatement()->expression();
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 lit->has_only_this_property_assignments(), 446 lit->has_only_this_property_assignments(),
410 lit->has_only_simple_this_property_assignments(), 447 lit->has_only_simple_this_property_assignments(),
411 *lit->this_property_assignments()); 448 *lit->this_property_assignments());
412 449
413 // Check the function has compiled code. 450 // Check the function has compiled code.
414 ASSERT(shared->is_compiled()); 451 ASSERT(shared->is_compiled());
415 return true; 452 return true;
416 } 453 }
417 454
418 455
456 #ifdef V8_TARGET_ARCH_IA32
457
458 CodeGenSelector::CodeGenTag CodeGenSelector::Select(FunctionLiteral* fun) {
459 Scope* scope = fun->scope();
460
461 if (!scope->is_global_scope()) return NORMAL;
462 ASSERT(scope->num_heap_slots() == 0);
463 ASSERT(scope->arguments() == NULL);
464
465 if (!scope->declarations()->is_empty()) return NORMAL;
466 if (fun->materialized_literal_count() > 0) return NORMAL;
467 if (fun->body()->is_empty()) return NORMAL;
468
469 has_supported_syntax_ = true;
470 VisitStatements(fun->body());
471 return has_supported_syntax_ ? FAST : NORMAL;
472 }
473
474
475 #define BAILOUT(reason) \
476 do { \
477 if (FLAG_trace_bailout) { \
478 PrintF("%s\n", reason); \
479 } \
480 has_supported_syntax_ = false; \
481 return; \
482 } while (false)
483
484
485 #define CHECK_BAILOUT \
486 do { \
487 if (!has_supported_syntax_) return; \
488 } while (false)
489
490
491 void CodeGenSelector::VisitStatements(ZoneList<Statement*>* stmts) {
492 for (int i = 0, len = stmts->length(); i < len; i++) {
493 CHECK_BAILOUT;
494 Visit(stmts->at(i));
495 }
496 }
497
498
499 void CodeGenSelector::VisitDeclaration(Declaration* decl) {
500 BAILOUT("Declaration");
501 }
502
503
504 void CodeGenSelector::VisitBlock(Block* stmt) {
505 BAILOUT("Block");
506 }
507
508
509 void CodeGenSelector::VisitExpressionStatement(ExpressionStatement* stmt) {
510 Visit(stmt->expression());
511 }
512
513
514 void CodeGenSelector::VisitEmptyStatement(EmptyStatement* stmt) {
515 BAILOUT("EmptyStatement");
516 }
517
518
519 void CodeGenSelector::VisitIfStatement(IfStatement* stmt) {
520 BAILOUT("IfStatement");
521 }
522
523
524 void CodeGenSelector::VisitContinueStatement(ContinueStatement* stmt) {
525 BAILOUT("ContinueStatement");
526 }
527
528
529 void CodeGenSelector::VisitBreakStatement(BreakStatement* stmt) {
530 BAILOUT("BreakStatement");
531 }
532
533
534 void CodeGenSelector::VisitReturnStatement(ReturnStatement* stmt) {
535 Visit(stmt->expression());
536 }
537
538
539 void CodeGenSelector::VisitWithEnterStatement(WithEnterStatement* stmt) {
540 BAILOUT("WithEnterStatement");
541 }
542
543
544 void CodeGenSelector::VisitWithExitStatement(WithExitStatement* stmt) {
545 BAILOUT("WithExitStatement");
546 }
547
548
549 void CodeGenSelector::VisitSwitchStatement(SwitchStatement* stmt) {
550 BAILOUT("SwitchStatement");
551 }
552
553
554 void CodeGenSelector::VisitDoWhileStatement(DoWhileStatement* stmt) {
555 BAILOUT("DoWhileStatement");
556 }
557
558
559 void CodeGenSelector::VisitWhileStatement(WhileStatement* stmt) {
560 BAILOUT("WhileStatement");
561 }
562
563
564 void CodeGenSelector::VisitForStatement(ForStatement* stmt) {
565 BAILOUT("ForStatement");
566 }
567
568
569 void CodeGenSelector::VisitForInStatement(ForInStatement* stmt) {
570 BAILOUT("ForInStatement");
571 }
572
573
574 void CodeGenSelector::VisitTryCatchStatement(TryCatchStatement* stmt) {
575 BAILOUT("TryCatchStatement");
576 }
577
578
579 void CodeGenSelector::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
580 BAILOUT("TryFinallyStatement");
581 }
582
583
584 void CodeGenSelector::VisitDebuggerStatement(DebuggerStatement* stmt) {
585 BAILOUT("DebuggerStatement");
586 }
587
588
589 void CodeGenSelector::VisitFunctionLiteral(FunctionLiteral* expr) {
590 BAILOUT("FunctionLiteral");
591 }
592
593
594 void CodeGenSelector::VisitFunctionBoilerplateLiteral(
595 FunctionBoilerplateLiteral* expr) {
596 BAILOUT("FunctionBoilerplateLiteral");
597 }
598
599
600 void CodeGenSelector::VisitConditional(Conditional* expr) {
601 BAILOUT("Conditional");
602 }
603
604
605 void CodeGenSelector::VisitSlot(Slot* expr) {
606 Slot::Type type = expr->type();
607 if (type != Slot::PARAMETER && type != Slot::LOCAL) {
608 BAILOUT("non-parameter/non-local slot reference");
609 }
610 }
611
612
613 void CodeGenSelector::VisitVariableProxy(VariableProxy* expr) {
614 Expression* rewrite = expr->var()->rewrite();
615 if (rewrite == NULL) BAILOUT("global variable reference");
616 Visit(rewrite);
617 }
618
619
620 void CodeGenSelector::VisitLiteral(Literal* expr) {
621 // All literals are supported.
622 }
623
624
625 void CodeGenSelector::VisitRegExpLiteral(RegExpLiteral* expr) {
626 BAILOUT("RegExpLiteral");
627 }
628
629
630 void CodeGenSelector::VisitObjectLiteral(ObjectLiteral* expr) {
631 BAILOUT("ObjectLiteral");
632 }
633
634
635 void CodeGenSelector::VisitArrayLiteral(ArrayLiteral* expr) {
636 BAILOUT("ArrayLiteral");
637 }
638
639
640 void CodeGenSelector::VisitCatchExtensionObject(CatchExtensionObject* expr) {
641 BAILOUT("CatchExtensionObject");
642 }
643
644
645 void CodeGenSelector::VisitAssignment(Assignment* expr) {
646 // We support plain non-compound assignments to parameters and
647 // non-context (stack-allocated) locals.
648 if (expr->starts_initialization_block()) BAILOUT("initialization block");
649
650 Token::Value op = expr->op();
651 if (op == Token::INIT_CONST) BAILOUT("initialize constant");
652 if (op != Token::ASSIGN && op != Token::INIT_VAR) {
653 BAILOUT("compound assignment");
654 }
655
656 Variable* var = expr->target()->AsVariableProxy()->AsVariable();
657 if (var == NULL || var->is_global()) BAILOUT("non-variable assignment");
658
659 ASSERT(var->slot() != NULL);
660 Slot::Type type = var->slot()->type();
661 if (type != Slot::PARAMETER && type != Slot::LOCAL) {
662 BAILOUT("non-parameter/non-local slot assignment");
663 }
664
665 Visit(expr->value());
666 }
667
668
669 void CodeGenSelector::VisitThrow(Throw* expr) {
670 BAILOUT("Throw");
671 }
672
673
674 void CodeGenSelector::VisitProperty(Property* expr) {
675 BAILOUT("Property");
676 }
677
678
679 void CodeGenSelector::VisitCall(Call* expr) {
680 BAILOUT("Call");
681 }
682
683
684 void CodeGenSelector::VisitCallNew(CallNew* expr) {
685 BAILOUT("CallNew");
686 }
687
688
689 void CodeGenSelector::VisitCallRuntime(CallRuntime* expr) {
690 BAILOUT("CallRuntime");
691 }
692
693
694 void CodeGenSelector::VisitUnaryOperation(UnaryOperation* expr) {
695 BAILOUT("UnaryOperation");
696 }
697
698
699 void CodeGenSelector::VisitCountOperation(CountOperation* expr) {
700 BAILOUT("CountOperation");
701 }
702
703
704 void CodeGenSelector::VisitBinaryOperation(BinaryOperation* expr) {
705 BAILOUT("BinaryOperation");
706 }
707
708
709 void CodeGenSelector::VisitCompareOperation(CompareOperation* expr) {
710 BAILOUT("CompareOperation");
711 }
712
713
714 void CodeGenSelector::VisitThisFunction(ThisFunction* expr) {
715 BAILOUT("ThisFunction");
716 }
717
718 #undef BAILOUT
719 #undef CHECK_BAILOUT
720
721 #endif // V8_TARGET_ARCH_IA32
722
723
419 } } // namespace v8::internal 724 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/codegen.cc ('k') | src/fast-codegen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698