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

Side by Side Diff: src/ast.cc

Issue 9221011: Collect AstNode type information (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: review feedback (embedded AstProperties and AstConstructionVisitor) Created 8 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 unified diff | Download patch | Annotate | Revision Log
« src/ast.h ('K') | « src/ast.h ('k') | src/compiler.cc » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 : Expression(isolate), 119 : Expression(isolate),
120 op_(op), 120 op_(op),
121 target_(target), 121 target_(target),
122 value_(value), 122 value_(value),
123 pos_(pos), 123 pos_(pos),
124 binary_operation_(NULL), 124 binary_operation_(NULL),
125 compound_load_id_(kNoNumber), 125 compound_load_id_(kNoNumber),
126 assignment_id_(GetNextId(isolate)), 126 assignment_id_(GetNextId(isolate)),
127 block_start_(false), 127 block_start_(false),
128 block_end_(false), 128 block_end_(false),
129 is_monomorphic_(false) { 129 is_monomorphic_(false) { }
130 ASSERT(Token::IsAssignmentOp(op));
131 if (is_compound()) {
132 binary_operation_ =
133 new(isolate->zone()) BinaryOperation(isolate,
134 binary_op(),
135 target,
136 value,
137 pos + 1);
138 compound_load_id_ = GetNextId(isolate);
139 }
140 }
141 130
142 131
143 Token::Value Assignment::binary_op() const { 132 Token::Value Assignment::binary_op() const {
144 switch (op_) { 133 switch (op_) {
145 case Token::ASSIGN_BIT_OR: return Token::BIT_OR; 134 case Token::ASSIGN_BIT_OR: return Token::BIT_OR;
146 case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR; 135 case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR;
147 case Token::ASSIGN_BIT_AND: return Token::BIT_AND; 136 case Token::ASSIGN_BIT_AND: return Token::BIT_AND;
148 case Token::ASSIGN_SHL: return Token::SHL; 137 case Token::ASSIGN_SHL: return Token::SHL;
149 case Token::ASSIGN_SAR: return Token::SAR; 138 case Token::ASSIGN_SAR: return Token::SAR;
150 case Token::ASSIGN_SHR: return Token::SHR; 139 case Token::ASSIGN_SHR: return Token::SHR;
(...skipping 21 matching lines...) Expand all
172 int FunctionLiteral::end_position() const { 161 int FunctionLiteral::end_position() const {
173 return scope()->end_position(); 162 return scope()->end_position();
174 } 163 }
175 164
176 165
177 LanguageMode FunctionLiteral::language_mode() const { 166 LanguageMode FunctionLiteral::language_mode() const {
178 return scope()->language_mode(); 167 return scope()->language_mode();
179 } 168 }
180 169
181 170
171 bool FunctionLiteral::ShouldSelfOptimize() {
172 return !flags()->Contains(kDontSelfOptimize);
173 }
174
175
182 ObjectLiteral::Property::Property(Literal* key, Expression* value) { 176 ObjectLiteral::Property::Property(Literal* key, Expression* value) {
183 emit_store_ = true; 177 emit_store_ = true;
184 key_ = key; 178 key_ = key;
185 value_ = value; 179 value_ = value;
186 Object* k = *key->handle(); 180 Object* k = *key->handle();
187 if (k->IsSymbol() && HEAP->Proto_symbol()->Equals(String::cast(k))) { 181 if (k->IsSymbol() && HEAP->Proto_symbol()->Equals(String::cast(k))) {
188 kind_ = PROTOTYPE; 182 kind_ = PROTOTYPE;
189 } else if (value_->AsMaterializedLiteral() != NULL) { 183 } else if (value_->AsMaterializedLiteral() != NULL) {
190 kind_ = MATERIALIZED_LITERAL; 184 kind_ = MATERIALIZED_LITERAL;
191 } else if (value_->AsLiteral() != NULL) { 185 } else if (value_->AsLiteral() != NULL) {
192 kind_ = CONSTANT; 186 kind_ = CONSTANT;
193 } else { 187 } else {
194 kind_ = COMPUTED; 188 kind_ = COMPUTED;
195 } 189 }
196 } 190 }
197 191
198 192
199 ObjectLiteral::Property::Property(bool is_getter, FunctionLiteral* value) { 193 ObjectLiteral::Property::Property(bool is_getter, FunctionLiteral* value) {
200 Isolate* isolate = Isolate::Current();
201 emit_store_ = true; 194 emit_store_ = true;
202 key_ = new(isolate->zone()) Literal(isolate, value->name());
203 value_ = value; 195 value_ = value;
204 kind_ = is_getter ? GETTER : SETTER; 196 kind_ = is_getter ? GETTER : SETTER;
205 } 197 }
206 198
207 199
208 bool ObjectLiteral::Property::IsCompileTimeValue() { 200 bool ObjectLiteral::Property::IsCompileTimeValue() {
209 return kind_ == CONSTANT || 201 return kind_ == CONSTANT ||
210 (kind_ == MATERIALIZED_LITERAL && 202 (kind_ == MATERIALIZED_LITERAL &&
211 CompileTimeValue::IsCompileTimeValue(value_)); 203 CompileTimeValue::IsCompileTimeValue(value_));
212 } 204 }
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 416
425 417
426 // ---------------------------------------------------------------------------- 418 // ----------------------------------------------------------------------------
427 // Inlining support 419 // Inlining support
428 420
429 bool Declaration::IsInlineable() const { 421 bool Declaration::IsInlineable() const {
430 return proxy()->var()->IsStackAllocated() && fun() == NULL; 422 return proxy()->var()->IsStackAllocated() && fun() == NULL;
431 } 423 }
432 424
433 425
434 bool TargetCollector::IsInlineable() const {
435 UNREACHABLE();
436 return false;
437 }
438
439
440 bool ForInStatement::IsInlineable() const {
441 return false;
442 }
443
444
445 bool WithStatement::IsInlineable() const {
446 return false;
447 }
448
449
450 bool SwitchStatement::IsInlineable() const {
451 return false;
452 }
453
454
455 bool TryStatement::IsInlineable() const {
456 return false;
457 }
458
459
460 bool TryCatchStatement::IsInlineable() const {
461 return false;
462 }
463
464
465 bool TryFinallyStatement::IsInlineable() const {
466 return false;
467 }
468
469
470 bool DebuggerStatement::IsInlineable() const {
471 return false;
472 }
473
474
475 bool Throw::IsInlineable() const {
476 return exception()->IsInlineable();
477 }
478
479
480 bool MaterializedLiteral::IsInlineable() const {
481 // TODO(1322): Allow materialized literals.
482 return false;
483 }
484
485
486 bool FunctionLiteral::IsInlineable() const {
487 // TODO(1322): Allow materialized literals.
488 return false;
489 }
490
491
492 bool ThisFunction::IsInlineable() const {
493 return true;
494 }
495
496
497 bool SharedFunctionInfoLiteral::IsInlineable() const {
498 return false;
499 }
500
501
502 bool ForStatement::IsInlineable() const {
503 return (init() == NULL || init()->IsInlineable())
504 && (cond() == NULL || cond()->IsInlineable())
505 && (next() == NULL || next()->IsInlineable())
506 && body()->IsInlineable();
507 }
508
509
510 bool WhileStatement::IsInlineable() const {
511 return cond()->IsInlineable()
512 && body()->IsInlineable();
513 }
514
515
516 bool DoWhileStatement::IsInlineable() const {
517 return cond()->IsInlineable()
518 && body()->IsInlineable();
519 }
520
521
522 bool ContinueStatement::IsInlineable() const {
523 return true;
524 }
525
526
527 bool BreakStatement::IsInlineable() const {
528 return true;
529 }
530
531
532 bool EmptyStatement::IsInlineable() const {
533 return true;
534 }
535
536
537 bool Literal::IsInlineable() const {
538 return true;
539 }
540
541
542 bool Block::IsInlineable() const {
543 const int count = statements_.length();
544 for (int i = 0; i < count; ++i) {
545 if (!statements_[i]->IsInlineable()) return false;
546 }
547 return true;
548 }
549
550
551 bool ExpressionStatement::IsInlineable() const {
552 return expression()->IsInlineable();
553 }
554
555
556 bool IfStatement::IsInlineable() const {
557 return condition()->IsInlineable()
558 && then_statement()->IsInlineable()
559 && else_statement()->IsInlineable();
560 }
561
562
563 bool ReturnStatement::IsInlineable() const {
564 return expression()->IsInlineable();
565 }
566
567
568 bool Conditional::IsInlineable() const {
569 return condition()->IsInlineable() && then_expression()->IsInlineable() &&
570 else_expression()->IsInlineable();
571 }
572
573
574 bool VariableProxy::IsInlineable() const {
575 return var()->IsUnallocated()
576 || var()->IsStackAllocated()
577 || var()->IsContextSlot();
578 }
579
580
581 bool Assignment::IsInlineable() const {
582 return target()->IsInlineable() && value()->IsInlineable();
583 }
584
585
586 bool Property::IsInlineable() const {
587 return obj()->IsInlineable() && key()->IsInlineable();
588 }
589
590
591 bool Call::IsInlineable() const {
592 if (!expression()->IsInlineable()) return false;
593 const int count = arguments()->length();
594 for (int i = 0; i < count; ++i) {
595 if (!arguments()->at(i)->IsInlineable()) return false;
596 }
597 return true;
598 }
599
600
601 bool CallNew::IsInlineable() const {
602 if (!expression()->IsInlineable()) return false;
603 const int count = arguments()->length();
604 for (int i = 0; i < count; ++i) {
605 if (!arguments()->at(i)->IsInlineable()) return false;
606 }
607 return true;
608 }
609
610
611 bool CallRuntime::IsInlineable() const {
612 // Don't try to inline JS runtime calls because we don't (currently) even
613 // optimize them.
614 if (is_jsruntime()) return false;
615 // Don't inline the %_ArgumentsLength or %_Arguments because their
616 // implementation will not work. There is no stack frame to get them
617 // from.
618 if (function()->intrinsic_type == Runtime::INLINE &&
619 (name()->IsEqualTo(CStrVector("_ArgumentsLength")) ||
620 name()->IsEqualTo(CStrVector("_Arguments")))) {
621 return false;
622 }
623 const int count = arguments()->length();
624 for (int i = 0; i < count; ++i) {
625 if (!arguments()->at(i)->IsInlineable()) return false;
626 }
627 return true;
628 }
629
630
631 bool UnaryOperation::IsInlineable() const {
632 return expression()->IsInlineable();
633 }
634
635
636 bool BinaryOperation::IsInlineable() const {
637 return left()->IsInlineable() && right()->IsInlineable();
638 }
639
640
641 bool CompareOperation::IsInlineable() const {
642 return left()->IsInlineable() && right()->IsInlineable();
643 }
644
645
646 bool CountOperation::IsInlineable() const {
647 return expression()->IsInlineable();
648 }
649
650
651 // ---------------------------------------------------------------------------- 426 // ----------------------------------------------------------------------------
652 // Recording of type feedback 427 // Recording of type feedback
653 428
654 void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) { 429 void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
655 // Record type feedback from the oracle in the AST. 430 // Record type feedback from the oracle in the AST.
656 is_monomorphic_ = oracle->LoadIsMonomorphicNormal(this); 431 is_monomorphic_ = oracle->LoadIsMonomorphicNormal(this);
657 receiver_types_.Clear(); 432 receiver_types_.Clear();
658 if (key()->IsPropertyName()) { 433 if (key()->IsPropertyName()) {
659 if (oracle->LoadIsBuiltin(this, Builtins::kLoadIC_ArrayLength)) { 434 if (oracle->LoadIsBuiltin(this, Builtins::kLoadIC_ArrayLength)) {
660 is_array_length_ = true; 435 is_array_length_ = true;
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after
1208 ZoneList<Statement*>* statements, 983 ZoneList<Statement*>* statements,
1209 int pos) 984 int pos)
1210 : label_(label), 985 : label_(label),
1211 statements_(statements), 986 statements_(statements),
1212 position_(pos), 987 position_(pos),
1213 compare_type_(NONE), 988 compare_type_(NONE),
1214 compare_id_(AstNode::GetNextId(isolate)), 989 compare_id_(AstNode::GetNextId(isolate)),
1215 entry_id_(AstNode::GetNextId(isolate)) { 990 entry_id_(AstNode::GetNextId(isolate)) {
1216 } 991 }
1217 992
993
994 #define INCREASE_NODE_COUNT(NodeType) \
995 void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
996 increase_node_count(); \
997 }
998
999 INCREASE_NODE_COUNT(Declaration)
1000 INCREASE_NODE_COUNT(Block)
1001 INCREASE_NODE_COUNT(ExpressionStatement)
1002 INCREASE_NODE_COUNT(EmptyStatement)
1003 INCREASE_NODE_COUNT(IfStatement)
1004 INCREASE_NODE_COUNT(ContinueStatement)
1005 INCREASE_NODE_COUNT(BreakStatement)
1006 INCREASE_NODE_COUNT(ReturnStatement)
1007 INCREASE_NODE_COUNT(Conditional)
1008 INCREASE_NODE_COUNT(Literal)
1009 INCREASE_NODE_COUNT(Assignment)
1010 INCREASE_NODE_COUNT(Throw)
1011 INCREASE_NODE_COUNT(Property)
1012 INCREASE_NODE_COUNT(UnaryOperation)
1013 INCREASE_NODE_COUNT(CountOperation)
1014 INCREASE_NODE_COUNT(BinaryOperation)
1015 INCREASE_NODE_COUNT(CompareOperation)
1016 INCREASE_NODE_COUNT(ThisFunction)
1017
1018 #undef INCREASE_NODE_COUNT
1019
1020
1021 void AstConstructionVisitor::VisitWithStatement(WithStatement* node) {
1022 increase_node_count();
1023 add_flag(kDontCrankshaft);
1024 add_flag(kDontInline);
1025 }
1026
1027
1028 void AstConstructionVisitor::VisitSwitchStatement(SwitchStatement* node) {
1029 increase_node_count();
1030 add_flag(kDontInline);
1031 }
1032
1033
1034 void AstConstructionVisitor::VisitDoWhileStatement(DoWhileStatement* node) {
1035 increase_node_count();
1036 add_flag(kDontSelfOptimize);
1037 }
1038
1039
1040 void AstConstructionVisitor::VisitWhileStatement(WhileStatement* node) {
1041 increase_node_count();
1042 add_flag(kDontSelfOptimize);
1043 }
1044
1045
1046 void AstConstructionVisitor::VisitForStatement(ForStatement* node) {
1047 increase_node_count();
1048 add_flag(kDontSelfOptimize);
1049 }
1050
1051
1052 void AstConstructionVisitor::VisitForInStatement(ForInStatement* node) {
1053 increase_node_count();
1054 add_flag(kDontCrankshaft);
1055 add_flag(kDontInline);
1056 add_flag(kDontSelfOptimize);
1057 }
1058
1059
1060 void AstConstructionVisitor::VisitTryCatchStatement(TryCatchStatement* node) {
1061 increase_node_count();
1062 add_flag(kDontCrankshaft);
1063 add_flag(kDontInline);
1064 }
1065
1066
1067 void AstConstructionVisitor::VisitTryFinallyStatement(
1068 TryFinallyStatement* node) {
1069 increase_node_count();
1070 add_flag(kDontCrankshaft);
1071 add_flag(kDontInline);
1072 }
1073
1074
1075 void AstConstructionVisitor::VisitDebuggerStatement(DebuggerStatement* node) {
1076 increase_node_count();
1077 add_flag(kDontCrankshaft);
1078 add_flag(kDontInline);
1079 }
1080
1081
1082 void AstConstructionVisitor::VisitFunctionLiteral(FunctionLiteral* node) {
1083 increase_node_count();
1084 add_flag(kDontInline);
1085 }
1086
1087
1088 void AstConstructionVisitor::VisitSharedFunctionInfoLiteral(
1089 SharedFunctionInfoLiteral* node) {
1090 increase_node_count();
1091 add_flag(kDontCrankshaft);
1092 add_flag(kDontInline);
1093 }
1094
1095
1096 void AstConstructionVisitor::VisitVariableProxy(VariableProxy* node) {
1097 increase_node_count();
1098 // In theory, we'd have to add:
1099 // if(node->var()->IsLookupSlot()) { add_flag(kDontInline); }
1100 // However, node->var() is usually not bound yet at VariableProxy creation
1101 // time, and LOOKUP variables only result from constructs that cannot
1102 // be inlined anyway.
1103 }
1104
1105
1106 void AstConstructionVisitor::VisitRegExpLiteral(RegExpLiteral* node) {
1107 increase_node_count();
1108 add_flag(kDontInline); // TODO(1322): Allow materialized literals.
1109 }
1110
1111
1112 void AstConstructionVisitor::VisitObjectLiteral(ObjectLiteral* node) {
1113 increase_node_count();
1114 add_flag(kDontInline); // TODO(1322): Allow materialized literals.
1115 }
1116
1117
1118 void AstConstructionVisitor::VisitArrayLiteral(ArrayLiteral* node) {
1119 increase_node_count();
1120 add_flag(kDontInline); // TODO(1322): Allow materialized literals.
1121 }
1122
1123
1124 void AstConstructionVisitor::VisitCall(Call* node) {
1125 increase_node_count();
1126 add_flag(kDontSelfOptimize);
1127 }
1128
1129
1130 void AstConstructionVisitor::VisitCallNew(CallNew* node) {
1131 increase_node_count();
1132 add_flag(kDontSelfOptimize);
1133 }
1134
1135
1136 void AstConstructionVisitor::VisitCallRuntime(CallRuntime* node) {
1137 increase_node_count();
1138 add_flag(kDontSelfOptimize);
1139 if (node->is_jsruntime()) {
1140 // Don't try to inline JS runtime calls because we don't (currently) even
1141 // optimize them.
1142 add_flag(kDontInline);
1143 } else if (node->function()->intrinsic_type == Runtime::INLINE &&
1144 (node->name()->IsEqualTo(CStrVector("_ArgumentsLength")) ||
1145 node->name()->IsEqualTo(CStrVector("_Arguments")))) {
1146 // Don't inline the %_ArgumentsLength or %_Arguments because their
1147 // implementation will not work. There is no stack frame to get them
1148 // from.
1149 add_flag(kDontInline);
1150 }
1151 }
1152
1218 } } // namespace v8::internal 1153 } } // namespace v8::internal
OLDNEW
« src/ast.h ('K') | « src/ast.h ('k') | src/compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698