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

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: removed VariableProxy::ast_properties_ 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
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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 // in JS. Sigh... 108 // in JS. Sigh...
109 var_ = var; 109 var_ = var;
110 var->set_is_used(true); 110 var->set_is_used(true);
111 } 111 }
112 112
113 113
114 Assignment::Assignment(Isolate* isolate, 114 Assignment::Assignment(Isolate* isolate,
115 Token::Value op, 115 Token::Value op,
116 Expression* target, 116 Expression* target,
117 Expression* value, 117 Expression* value,
118 int pos) 118 int pos,
119 AstNodeFactory* factory)
119 : Expression(isolate), 120 : Expression(isolate),
120 op_(op), 121 op_(op),
121 target_(target), 122 target_(target),
122 value_(value), 123 value_(value),
123 pos_(pos), 124 pos_(pos),
124 binary_operation_(NULL), 125 binary_operation_(NULL),
125 compound_load_id_(kNoNumber), 126 compound_load_id_(kNoNumber),
126 assignment_id_(GetNextId(isolate)), 127 assignment_id_(GetNextId(isolate)),
127 block_start_(false), 128 block_start_(false),
128 block_end_(false), 129 block_end_(false),
129 is_monomorphic_(false) { 130 is_monomorphic_(false) {
130 ASSERT(Token::IsAssignmentOp(op)); 131 ASSERT(Token::IsAssignmentOp(op));
131 if (is_compound()) { 132 if (is_compound()) {
132 binary_operation_ = 133 binary_operation_ =
133 new(isolate->zone()) BinaryOperation(isolate, 134 factory->NewBinaryOperation(binary_op(), target, value, pos + 1);
134 binary_op(),
135 target,
136 value,
137 pos + 1);
138 compound_load_id_ = GetNextId(isolate); 135 compound_load_id_ = GetNextId(isolate);
139 } 136 }
140 } 137 }
141 138
142 139
143 Token::Value Assignment::binary_op() const { 140 Token::Value Assignment::binary_op() const {
144 switch (op_) { 141 switch (op_) {
145 case Token::ASSIGN_BIT_OR: return Token::BIT_OR; 142 case Token::ASSIGN_BIT_OR: return Token::BIT_OR;
146 case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR; 143 case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR;
147 case Token::ASSIGN_BIT_AND: return Token::BIT_AND; 144 case Token::ASSIGN_BIT_AND: return Token::BIT_AND;
(...skipping 24 matching lines...) Expand all
172 int FunctionLiteral::end_position() const { 169 int FunctionLiteral::end_position() const {
173 return scope()->end_position(); 170 return scope()->end_position();
174 } 171 }
175 172
176 173
177 LanguageMode FunctionLiteral::language_mode() const { 174 LanguageMode FunctionLiteral::language_mode() const {
178 return scope()->language_mode(); 175 return scope()->language_mode();
179 } 176 }
180 177
181 178
179 bool FunctionLiteral::ShouldSelfOptimize() {
180 return !ast_properties()->flags()->Contains(kDontSelfOptimize);
181 }
182
183
184 int FunctionLiteral::AstNodeCount() {
185 return ast_properties()->node_count();
186 }
187
188
182 ObjectLiteral::Property::Property(Literal* key, Expression* value) { 189 ObjectLiteral::Property::Property(Literal* key, Expression* value) {
183 emit_store_ = true; 190 emit_store_ = true;
184 key_ = key; 191 key_ = key;
185 value_ = value; 192 value_ = value;
186 Object* k = *key->handle(); 193 Object* k = *key->handle();
187 if (k->IsSymbol() && HEAP->Proto_symbol()->Equals(String::cast(k))) { 194 if (k->IsSymbol() && HEAP->Proto_symbol()->Equals(String::cast(k))) {
188 kind_ = PROTOTYPE; 195 kind_ = PROTOTYPE;
189 } else if (value_->AsMaterializedLiteral() != NULL) { 196 } else if (value_->AsMaterializedLiteral() != NULL) {
190 kind_ = MATERIALIZED_LITERAL; 197 kind_ = MATERIALIZED_LITERAL;
191 } else if (value_->AsLiteral() != NULL) { 198 } else if (value_->AsLiteral() != NULL) {
192 kind_ = CONSTANT; 199 kind_ = CONSTANT;
193 } else { 200 } else {
194 kind_ = COMPUTED; 201 kind_ = COMPUTED;
195 } 202 }
196 } 203 }
197 204
198 205
199 ObjectLiteral::Property::Property(bool is_getter, FunctionLiteral* value) { 206 ObjectLiteral::Property::Property(bool is_getter,
200 Isolate* isolate = Isolate::Current(); 207 FunctionLiteral* value,
208 AstNodeFactory* factory) {
201 emit_store_ = true; 209 emit_store_ = true;
202 key_ = new(isolate->zone()) Literal(isolate, value->name()); 210 key_ = factory->NewLiteral(value->name());
203 value_ = value; 211 value_ = value;
204 kind_ = is_getter ? GETTER : SETTER; 212 kind_ = is_getter ? GETTER : SETTER;
205 } 213 }
206 214
207 215
208 bool ObjectLiteral::Property::IsCompileTimeValue() { 216 bool ObjectLiteral::Property::IsCompileTimeValue() {
209 return kind_ == CONSTANT || 217 return kind_ == CONSTANT ||
210 (kind_ == MATERIALIZED_LITERAL && 218 (kind_ == MATERIALIZED_LITERAL &&
211 CompileTimeValue::IsCompileTimeValue(value_)); 219 CompileTimeValue::IsCompileTimeValue(value_));
212 } 220 }
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 432
425 433
426 // ---------------------------------------------------------------------------- 434 // ----------------------------------------------------------------------------
427 // Inlining support 435 // Inlining support
428 436
429 bool Declaration::IsInlineable() const { 437 bool Declaration::IsInlineable() const {
430 return proxy()->var()->IsStackAllocated() && fun() == NULL; 438 return proxy()->var()->IsStackAllocated() && fun() == NULL;
431 } 439 }
432 440
433 441
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 // ---------------------------------------------------------------------------- 442 // ----------------------------------------------------------------------------
652 // Recording of type feedback 443 // Recording of type feedback
653 444
654 void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) { 445 void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
655 // Record type feedback from the oracle in the AST. 446 // Record type feedback from the oracle in the AST.
656 is_monomorphic_ = oracle->LoadIsMonomorphicNormal(this); 447 is_monomorphic_ = oracle->LoadIsMonomorphicNormal(this);
657 receiver_types_.Clear(); 448 receiver_types_.Clear();
658 if (key()->IsPropertyName()) { 449 if (key()->IsPropertyName()) {
659 if (oracle->LoadIsBuiltin(this, Builtins::kLoadIC_ArrayLength)) { 450 if (oracle->LoadIsBuiltin(this, Builtins::kLoadIC_ArrayLength)) {
660 is_array_length_ = true; 451 is_array_length_ = true;
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after
1208 ZoneList<Statement*>* statements, 999 ZoneList<Statement*>* statements,
1209 int pos) 1000 int pos)
1210 : label_(label), 1001 : label_(label),
1211 statements_(statements), 1002 statements_(statements),
1212 position_(pos), 1003 position_(pos),
1213 compare_type_(NONE), 1004 compare_type_(NONE),
1214 compare_id_(AstNode::GetNextId(isolate)), 1005 compare_id_(AstNode::GetNextId(isolate)),
1215 entry_id_(AstNode::GetNextId(isolate)) { 1006 entry_id_(AstNode::GetNextId(isolate)) {
1216 } 1007 }
1217 1008
1009
1010 AstProperties* AstConstructionVisitor::DetachAstProperties() {
1011 properties_->add_node_count(node_count_);
1012 properties_->flags()->Add(flags_);
1013 return properties_;
1014 }
1015
1016
1017 void AstConstructionVisitor::VisitDeclaration(Declaration* node) {
1018 increase_node_count();
1019 // TODO(jkummerow): Inlineable iff
1020 // proxy()->var()->IsStackAllocated() && fun() == NULL;
fschneider 2012/02/06 14:14:29 Forgotten commented code?
Jakob Kummerow 2012/02/07 12:38:37 No, two-line comment :-) It was intended as a remi
1021 }
1022
1023
1024 #define INCREASE_NODE_COUNT(NodeType) \
1025 void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
1026 increase_node_count(); \
1027 }
1028
1029 INCREASE_NODE_COUNT(Block)
1030 INCREASE_NODE_COUNT(ExpressionStatement)
1031 INCREASE_NODE_COUNT(EmptyStatement)
1032 INCREASE_NODE_COUNT(IfStatement)
1033 INCREASE_NODE_COUNT(ContinueStatement)
1034 INCREASE_NODE_COUNT(BreakStatement)
1035 INCREASE_NODE_COUNT(ReturnStatement)
1036 INCREASE_NODE_COUNT(Conditional)
1037 INCREASE_NODE_COUNT(Literal)
1038 INCREASE_NODE_COUNT(Assignment)
1039 INCREASE_NODE_COUNT(Throw)
1040 INCREASE_NODE_COUNT(Property)
1041 INCREASE_NODE_COUNT(UnaryOperation)
1042 INCREASE_NODE_COUNT(CountOperation)
1043 INCREASE_NODE_COUNT(BinaryOperation)
1044 INCREASE_NODE_COUNT(CompareOperation)
1045 INCREASE_NODE_COUNT(ThisFunction)
1046
1047 #undef INCREASE_NODE_COUNT
1048
1049
1050 void AstConstructionVisitor::VisitWithStatement(WithStatement* node) {
1051 increase_node_count();
1052 add_flag(kDontCrankshaft);
1053 add_flag(kDontInline);
1054 }
1055
1056
1057 void AstConstructionVisitor::VisitSwitchStatement(SwitchStatement* node) {
1058 increase_node_count();
1059 add_flag(kDontInline);
1060 }
1061
1062
1063 void AstConstructionVisitor::VisitDoWhileStatement(DoWhileStatement* node) {
1064 increase_node_count();
1065 add_flag(kDontSelfOptimize);
1066 }
1067
1068
1069 void AstConstructionVisitor::VisitWhileStatement(WhileStatement* node) {
1070 increase_node_count();
1071 add_flag(kDontSelfOptimize);
1072 }
1073
1074
1075 void AstConstructionVisitor::VisitForStatement(ForStatement* node) {
1076 increase_node_count();
1077 add_flag(kDontSelfOptimize);
1078 }
1079
1080
1081 void AstConstructionVisitor::VisitForInStatement(ForInStatement* node) {
1082 increase_node_count();
1083 add_flag(kDontCrankshaft);
1084 add_flag(kDontInline);
1085 add_flag(kDontSelfOptimize);
1086 }
1087
1088
1089 void AstConstructionVisitor::VisitTryCatchStatement(TryCatchStatement* node) {
1090 increase_node_count();
1091 add_flag(kDontCrankshaft);
1092 add_flag(kDontInline);
1093 }
1094
1095
1096 void AstConstructionVisitor::VisitTryFinallyStatement(
1097 TryFinallyStatement* node) {
1098 increase_node_count();
1099 add_flag(kDontCrankshaft);
1100 add_flag(kDontInline);
1101 }
1102
1103
1104 void AstConstructionVisitor::VisitDebuggerStatement(DebuggerStatement* node) {
1105 increase_node_count();
1106 add_flag(kDontCrankshaft);
1107 add_flag(kDontInline);
1108 }
1109
1110
1111 void AstConstructionVisitor::VisitFunctionLiteral(FunctionLiteral* node) {
1112 increase_node_count();
1113 add_flag(kDontInline);
1114 }
1115
1116
1117 void AstConstructionVisitor::VisitSharedFunctionInfoLiteral(
1118 SharedFunctionInfoLiteral* node) {
1119 increase_node_count();
1120 add_flag(kDontCrankshaft);
1121 add_flag(kDontInline);
1122 }
1123
1124
1125 void AstConstructionVisitor::VisitVariableProxy(VariableProxy* node) {
1126 increase_node_count();
1127 // In theory, we'd have to add:
1128 // if(node->var()->IsLookupSlot()) { add_flag(kDontInline); }
1129 // However, node->var() is usually not bound yet at VariableProxy creation
1130 // time, and LOOKUP variables only result from constructs that cannot
1131 // be inlined anyway.
1132 }
1133
1134
1135 void AstConstructionVisitor::VisitRegExpLiteral(RegExpLiteral* node) {
1136 increase_node_count();
1137 add_flag(kDontInline); // TODO(1322): Allow materialized literals.
1138 }
1139
1140
1141 void AstConstructionVisitor::VisitObjectLiteral(ObjectLiteral* node) {
1142 increase_node_count();
1143 add_flag(kDontInline); // TODO(1322): Allow materialized literals.
1144 }
1145
1146
1147 void AstConstructionVisitor::VisitArrayLiteral(ArrayLiteral* node) {
1148 increase_node_count();
1149 add_flag(kDontInline); // TODO(1322): Allow materialized literals.
1150 }
1151
1152
1153 void AstConstructionVisitor::VisitCall(Call* node) {
1154 increase_node_count();
1155 add_flag(kDontSelfOptimize);
1156 }
1157
1158
1159 void AstConstructionVisitor::VisitCallNew(CallNew* node) {
1160 increase_node_count();
1161 add_flag(kDontSelfOptimize);
1162 }
1163
1164
1165 void AstConstructionVisitor::VisitCallRuntime(CallRuntime* node) {
1166 increase_node_count();
1167 add_flag(kDontSelfOptimize);
1168 if (node->is_jsruntime()) {
1169 // Don't try to inline JS runtime calls because we don't (currently) even
1170 // optimize them.
1171 add_flag(kDontInline);
1172 } else if (node->function()->intrinsic_type == Runtime::INLINE &&
1173 (node->name()->IsEqualTo(CStrVector("_ArgumentsLength")) ||
1174 node->name()->IsEqualTo(CStrVector("_Arguments")))) {
1175 // Don't inline the %_ArgumentsLength or %_Arguments because their
1176 // implementation will not work. There is no stack frame to get them
1177 // from.
1178 add_flag(kDontInline);
1179 }
1180 }
1181
1218 } } // namespace v8::internal 1182 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698