OLD | NEW |
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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 } | 69 } |
70 | 70 |
71 | 71 |
72 VariableProxy::VariableProxy(Isolate* isolate, Variable* var) | 72 VariableProxy::VariableProxy(Isolate* isolate, Variable* var) |
73 : Expression(isolate), | 73 : Expression(isolate), |
74 name_(var->name()), | 74 name_(var->name()), |
75 var_(NULL), // Will be set by the call to BindTo. | 75 var_(NULL), // Will be set by the call to BindTo. |
76 is_this_(var->is_this()), | 76 is_this_(var->is_this()), |
77 is_trivial_(false), | 77 is_trivial_(false), |
78 is_lvalue_(false), | 78 is_lvalue_(false), |
79 position_(RelocInfo::kNoPosition) { | 79 position_(RelocInfo::kNoPosition), |
| 80 ast_properties_(NULL) { |
80 BindTo(var); | 81 BindTo(var); |
81 } | 82 } |
82 | 83 |
83 | 84 |
84 VariableProxy::VariableProxy(Isolate* isolate, | 85 VariableProxy::VariableProxy(Isolate* isolate, |
85 Handle<String> name, | 86 Handle<String> name, |
86 bool is_this, | 87 bool is_this, |
87 int position) | 88 int position) |
88 : Expression(isolate), | 89 : Expression(isolate), |
89 name_(name), | 90 name_(name), |
90 var_(NULL), | 91 var_(NULL), |
91 is_this_(is_this), | 92 is_this_(is_this), |
92 is_trivial_(false), | 93 is_trivial_(false), |
93 is_lvalue_(false), | 94 is_lvalue_(false), |
94 position_(position) { | 95 position_(position), |
| 96 ast_properties_(NULL) { |
95 // Names must be canonicalized for fast equality checks. | 97 // Names must be canonicalized for fast equality checks. |
96 ASSERT(name->IsSymbol()); | 98 ASSERT(name->IsSymbol()); |
97 } | 99 } |
98 | 100 |
99 | 101 |
100 void VariableProxy::BindTo(Variable* var) { | 102 void VariableProxy::BindTo(Variable* var) { |
101 ASSERT(var_ == NULL); // must be bound only once | 103 ASSERT(var_ == NULL); // must be bound only once |
102 ASSERT(var != NULL); // must bind | 104 ASSERT(var != NULL); // must bind |
103 ASSERT((is_this() && var->is_this()) || name_.is_identical_to(var->name())); | 105 ASSERT((is_this() && var->is_this()) || name_.is_identical_to(var->name())); |
104 // Ideally CONST-ness should match. However, this is very hard to achieve | 106 // Ideally CONST-ness should match. However, this is very hard to achieve |
105 // because we don't know the exact semantics of conflicting (const and | 107 // because we don't know the exact semantics of conflicting (const and |
106 // non-const) multiple variable declarations, const vars introduced via | 108 // non-const) multiple variable declarations, const vars introduced via |
107 // eval() etc. Const-ness and variable declarations are a complete mess | 109 // eval() etc. Const-ness and variable declarations are a complete mess |
108 // in JS. Sigh... | 110 // in JS. Sigh... |
109 var_ = var; | 111 var_ = var; |
110 var->set_is_used(true); | 112 var->set_is_used(true); |
| 113 if (ast_properties_!= NULL) { |
| 114 ast_properties_->RevisitVariableProxy(this); |
| 115 } |
111 } | 116 } |
112 | 117 |
113 | 118 |
114 Assignment::Assignment(Isolate* isolate, | 119 Assignment::Assignment(Isolate* isolate, |
115 Token::Value op, | 120 Token::Value op, |
116 Expression* target, | 121 Expression* target, |
117 Expression* value, | 122 Expression* value, |
118 int pos) | 123 int pos, |
| 124 AstNodeFactory* factory) |
119 : Expression(isolate), | 125 : Expression(isolate), |
120 op_(op), | 126 op_(op), |
121 target_(target), | 127 target_(target), |
122 value_(value), | 128 value_(value), |
123 pos_(pos), | 129 pos_(pos), |
124 binary_operation_(NULL), | 130 binary_operation_(NULL), |
125 compound_load_id_(kNoNumber), | 131 compound_load_id_(kNoNumber), |
126 assignment_id_(GetNextId(isolate)), | 132 assignment_id_(GetNextId(isolate)), |
127 block_start_(false), | 133 block_start_(false), |
128 block_end_(false), | 134 block_end_(false), |
129 is_monomorphic_(false) { | 135 is_monomorphic_(false) { |
130 ASSERT(Token::IsAssignmentOp(op)); | 136 ASSERT(Token::IsAssignmentOp(op)); |
131 if (is_compound()) { | 137 if (is_compound()) { |
132 binary_operation_ = | 138 binary_operation_ = |
133 new(isolate->zone()) BinaryOperation(isolate, | 139 factory->NewBinaryOperation(binary_op(), target, value, pos + 1); |
134 binary_op(), | |
135 target, | |
136 value, | |
137 pos + 1); | |
138 compound_load_id_ = GetNextId(isolate); | 140 compound_load_id_ = GetNextId(isolate); |
139 } | 141 } |
140 } | 142 } |
141 | 143 |
142 | 144 |
143 Token::Value Assignment::binary_op() const { | 145 Token::Value Assignment::binary_op() const { |
144 switch (op_) { | 146 switch (op_) { |
145 case Token::ASSIGN_BIT_OR: return Token::BIT_OR; | 147 case Token::ASSIGN_BIT_OR: return Token::BIT_OR; |
146 case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR; | 148 case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR; |
147 case Token::ASSIGN_BIT_AND: return Token::BIT_AND; | 149 case Token::ASSIGN_BIT_AND: return Token::BIT_AND; |
(...skipping 24 matching lines...) Expand all Loading... |
172 int FunctionLiteral::end_position() const { | 174 int FunctionLiteral::end_position() const { |
173 return scope()->end_position(); | 175 return scope()->end_position(); |
174 } | 176 } |
175 | 177 |
176 | 178 |
177 LanguageMode FunctionLiteral::language_mode() const { | 179 LanguageMode FunctionLiteral::language_mode() const { |
178 return scope()->language_mode(); | 180 return scope()->language_mode(); |
179 } | 181 } |
180 | 182 |
181 | 183 |
| 184 bool FunctionLiteral::ShouldSelfOptimize() { |
| 185 return !ast_properties()->flags()->Contains(kDontSelfOptimize); |
| 186 } |
| 187 |
| 188 |
| 189 int FunctionLiteral::AstNodeCount() { |
| 190 return ast_properties()->node_count(); |
| 191 } |
| 192 |
| 193 |
182 ObjectLiteral::Property::Property(Literal* key, Expression* value) { | 194 ObjectLiteral::Property::Property(Literal* key, Expression* value) { |
183 emit_store_ = true; | 195 emit_store_ = true; |
184 key_ = key; | 196 key_ = key; |
185 value_ = value; | 197 value_ = value; |
186 Object* k = *key->handle(); | 198 Object* k = *key->handle(); |
187 if (k->IsSymbol() && HEAP->Proto_symbol()->Equals(String::cast(k))) { | 199 if (k->IsSymbol() && HEAP->Proto_symbol()->Equals(String::cast(k))) { |
188 kind_ = PROTOTYPE; | 200 kind_ = PROTOTYPE; |
189 } else if (value_->AsMaterializedLiteral() != NULL) { | 201 } else if (value_->AsMaterializedLiteral() != NULL) { |
190 kind_ = MATERIALIZED_LITERAL; | 202 kind_ = MATERIALIZED_LITERAL; |
191 } else if (value_->AsLiteral() != NULL) { | 203 } else if (value_->AsLiteral() != NULL) { |
192 kind_ = CONSTANT; | 204 kind_ = CONSTANT; |
193 } else { | 205 } else { |
194 kind_ = COMPUTED; | 206 kind_ = COMPUTED; |
195 } | 207 } |
196 } | 208 } |
197 | 209 |
198 | 210 |
199 ObjectLiteral::Property::Property(bool is_getter, FunctionLiteral* value) { | 211 ObjectLiteral::Property::Property(bool is_getter, |
200 Isolate* isolate = Isolate::Current(); | 212 FunctionLiteral* value, |
| 213 AstNodeFactory* factory) { |
201 emit_store_ = true; | 214 emit_store_ = true; |
202 key_ = new(isolate->zone()) Literal(isolate, value->name()); | 215 key_ = factory->NewLiteral(value->name()); |
203 value_ = value; | 216 value_ = value; |
204 kind_ = is_getter ? GETTER : SETTER; | 217 kind_ = is_getter ? GETTER : SETTER; |
205 } | 218 } |
206 | 219 |
207 | 220 |
208 bool ObjectLiteral::Property::IsCompileTimeValue() { | 221 bool ObjectLiteral::Property::IsCompileTimeValue() { |
209 return kind_ == CONSTANT || | 222 return kind_ == CONSTANT || |
210 (kind_ == MATERIALIZED_LITERAL && | 223 (kind_ == MATERIALIZED_LITERAL && |
211 CompileTimeValue::IsCompileTimeValue(value_)); | 224 CompileTimeValue::IsCompileTimeValue(value_)); |
212 } | 225 } |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 | 437 |
425 | 438 |
426 // ---------------------------------------------------------------------------- | 439 // ---------------------------------------------------------------------------- |
427 // Inlining support | 440 // Inlining support |
428 | 441 |
429 bool Declaration::IsInlineable() const { | 442 bool Declaration::IsInlineable() const { |
430 return proxy()->var()->IsStackAllocated() && fun() == NULL; | 443 return proxy()->var()->IsStackAllocated() && fun() == NULL; |
431 } | 444 } |
432 | 445 |
433 | 446 |
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 // ---------------------------------------------------------------------------- | 447 // ---------------------------------------------------------------------------- |
652 // Recording of type feedback | 448 // Recording of type feedback |
653 | 449 |
654 void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) { | 450 void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) { |
655 // Record type feedback from the oracle in the AST. | 451 // Record type feedback from the oracle in the AST. |
656 is_monomorphic_ = oracle->LoadIsMonomorphicNormal(this); | 452 is_monomorphic_ = oracle->LoadIsMonomorphicNormal(this); |
657 receiver_types_.Clear(); | 453 receiver_types_.Clear(); |
658 if (key()->IsPropertyName()) { | 454 if (key()->IsPropertyName()) { |
659 if (oracle->LoadIsBuiltin(this, Builtins::kLoadIC_ArrayLength)) { | 455 if (oracle->LoadIsBuiltin(this, Builtins::kLoadIC_ArrayLength)) { |
660 is_array_length_ = true; | 456 is_array_length_ = true; |
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1208 ZoneList<Statement*>* statements, | 1004 ZoneList<Statement*>* statements, |
1209 int pos) | 1005 int pos) |
1210 : label_(label), | 1006 : label_(label), |
1211 statements_(statements), | 1007 statements_(statements), |
1212 position_(pos), | 1008 position_(pos), |
1213 compare_type_(NONE), | 1009 compare_type_(NONE), |
1214 compare_id_(AstNode::GetNextId(isolate)), | 1010 compare_id_(AstNode::GetNextId(isolate)), |
1215 entry_id_(AstNode::GetNextId(isolate)) { | 1011 entry_id_(AstNode::GetNextId(isolate)) { |
1216 } | 1012 } |
1217 | 1013 |
| 1014 |
| 1015 AstProperties::~AstProperties() {} |
| 1016 |
| 1017 |
| 1018 void AstConstructionVisitor::VisitDeclaration(Declaration* node) { |
| 1019 increase_node_count(); |
| 1020 // TODO(jkummerow): Inlineable iff |
| 1021 // proxy()->var()->IsStackAllocated() && fun() == NULL; |
| 1022 } |
| 1023 |
| 1024 |
| 1025 void AstConstructionVisitor::VisitBlock(Block* node) { |
| 1026 increase_node_count(); |
| 1027 } |
| 1028 |
| 1029 |
| 1030 void AstConstructionVisitor::VisitExpressionStatement( |
| 1031 ExpressionStatement* node) { |
| 1032 increase_node_count(); |
| 1033 } |
| 1034 |
| 1035 |
| 1036 void AstConstructionVisitor::VisitEmptyStatement(EmptyStatement* node) { |
| 1037 increase_node_count(); |
| 1038 } |
| 1039 |
| 1040 |
| 1041 void AstConstructionVisitor::VisitIfStatement(IfStatement* node) { |
| 1042 increase_node_count(); |
| 1043 } |
| 1044 |
| 1045 |
| 1046 void AstConstructionVisitor::VisitContinueStatement(ContinueStatement* node) { |
| 1047 increase_node_count(); |
| 1048 } |
| 1049 |
| 1050 |
| 1051 void AstConstructionVisitor::VisitBreakStatement(BreakStatement* node) { |
| 1052 increase_node_count(); |
| 1053 } |
| 1054 |
| 1055 |
| 1056 void AstConstructionVisitor::VisitReturnStatement(ReturnStatement* node) { |
| 1057 increase_node_count(); |
| 1058 } |
| 1059 |
| 1060 |
| 1061 void AstConstructionVisitor::VisitWithStatement(WithStatement* node) { |
| 1062 increase_node_count(); |
| 1063 add_flag(kDontCrankshaft); |
| 1064 add_flag(kDontInline); |
| 1065 } |
| 1066 |
| 1067 |
| 1068 void AstConstructionVisitor::VisitSwitchStatement(SwitchStatement* node) { |
| 1069 increase_node_count(); |
| 1070 add_flag(kDontInline); |
| 1071 } |
| 1072 |
| 1073 |
| 1074 void AstConstructionVisitor::VisitDoWhileStatement(DoWhileStatement* node) { |
| 1075 increase_node_count(); |
| 1076 add_flag(kDontSelfOptimize); |
| 1077 } |
| 1078 |
| 1079 |
| 1080 void AstConstructionVisitor::VisitWhileStatement(WhileStatement* node) { |
| 1081 increase_node_count(); |
| 1082 add_flag(kDontSelfOptimize); |
| 1083 } |
| 1084 |
| 1085 |
| 1086 void AstConstructionVisitor::VisitForStatement(ForStatement* node) { |
| 1087 increase_node_count(); |
| 1088 add_flag(kDontSelfOptimize); |
| 1089 } |
| 1090 |
| 1091 |
| 1092 void AstConstructionVisitor::VisitForInStatement(ForInStatement* node) { |
| 1093 increase_node_count(); |
| 1094 add_flag(kDontCrankshaft); |
| 1095 add_flag(kDontInline); |
| 1096 add_flag(kDontSelfOptimize); |
| 1097 } |
| 1098 |
| 1099 |
| 1100 void AstConstructionVisitor::VisitTryCatchStatement(TryCatchStatement* node) { |
| 1101 increase_node_count(); |
| 1102 add_flag(kDontCrankshaft); |
| 1103 add_flag(kDontInline); |
| 1104 } |
| 1105 |
| 1106 |
| 1107 void AstConstructionVisitor::VisitTryFinallyStatement( |
| 1108 TryFinallyStatement* node) { |
| 1109 increase_node_count(); |
| 1110 add_flag(kDontCrankshaft); |
| 1111 add_flag(kDontInline); |
| 1112 } |
| 1113 |
| 1114 |
| 1115 void AstConstructionVisitor::VisitDebuggerStatement(DebuggerStatement* node) { |
| 1116 increase_node_count(); |
| 1117 add_flag(kDontCrankshaft); |
| 1118 add_flag(kDontInline); |
| 1119 } |
| 1120 |
| 1121 |
| 1122 void AstConstructionVisitor::VisitFunctionLiteral(FunctionLiteral* node) { |
| 1123 increase_node_count(); |
| 1124 add_flag(kDontInline); |
| 1125 } |
| 1126 |
| 1127 |
| 1128 void AstConstructionVisitor::VisitSharedFunctionInfoLiteral( |
| 1129 SharedFunctionInfoLiteral* node) { |
| 1130 increase_node_count(); |
| 1131 add_flag(kDontCrankshaft); |
| 1132 add_flag(kDontInline); |
| 1133 } |
| 1134 |
| 1135 |
| 1136 void AstConstructionVisitor::VisitConditional(Conditional* node) { |
| 1137 increase_node_count(); |
| 1138 } |
| 1139 |
| 1140 |
| 1141 void AstConstructionVisitor::VisitVariableProxy(VariableProxy* node) { |
| 1142 increase_node_count(); |
| 1143 properties_->RevisitVariableProxy(node); |
| 1144 } |
| 1145 |
| 1146 |
| 1147 void AstProperties::RevisitVariableProxy(VariableProxy* node) { |
| 1148 node->set_ast_properties(this); |
| 1149 Variable* var = node->var(); |
| 1150 if (var != NULL && |
| 1151 !var->IsUnallocated() && |
| 1152 !var->IsStackAllocated() && |
| 1153 !var->IsContextSlot()) { |
| 1154 flags_.Add(kDontInline); |
| 1155 } |
| 1156 } |
| 1157 |
| 1158 |
| 1159 void AstConstructionVisitor::VisitLiteral(Literal* node) { |
| 1160 increase_node_count(); |
| 1161 } |
| 1162 |
| 1163 |
| 1164 void AstConstructionVisitor::VisitRegExpLiteral(RegExpLiteral* node) { |
| 1165 increase_node_count(); |
| 1166 add_flag(kDontInline); // TODO(1322): Allow materialized literals. |
| 1167 } |
| 1168 |
| 1169 |
| 1170 void AstConstructionVisitor::VisitObjectLiteral(ObjectLiteral* node) { |
| 1171 increase_node_count(); |
| 1172 add_flag(kDontInline); // TODO(1322): Allow materialized literals. |
| 1173 } |
| 1174 |
| 1175 |
| 1176 void AstConstructionVisitor::VisitArrayLiteral(ArrayLiteral* node) { |
| 1177 increase_node_count(); |
| 1178 add_flag(kDontInline); // TODO(1322): Allow materialized literals. |
| 1179 } |
| 1180 |
| 1181 |
| 1182 void AstConstructionVisitor::VisitAssignment(Assignment* node) { |
| 1183 increase_node_count(); |
| 1184 } |
| 1185 |
| 1186 |
| 1187 void AstConstructionVisitor::VisitThrow(Throw* node) { |
| 1188 increase_node_count(); |
| 1189 } |
| 1190 |
| 1191 |
| 1192 void AstConstructionVisitor::VisitProperty(Property* node) { |
| 1193 increase_node_count(); |
| 1194 } |
| 1195 |
| 1196 |
| 1197 void AstConstructionVisitor::VisitCall(Call* node) { |
| 1198 increase_node_count(); |
| 1199 add_flag(kDontSelfOptimize); |
| 1200 } |
| 1201 |
| 1202 |
| 1203 void AstConstructionVisitor::VisitCallNew(CallNew* node) { |
| 1204 increase_node_count(); |
| 1205 add_flag(kDontSelfOptimize); |
| 1206 } |
| 1207 |
| 1208 |
| 1209 void AstConstructionVisitor::VisitCallRuntime(CallRuntime* node) { |
| 1210 increase_node_count(); |
| 1211 add_flag(kDontSelfOptimize); |
| 1212 if (node->is_jsruntime()) { |
| 1213 // Don't try to inline JS runtime calls because we don't (currently) even |
| 1214 // optimize them. |
| 1215 add_flag(kDontInline); |
| 1216 } else if (node->function()->intrinsic_type == Runtime::INLINE && |
| 1217 (node->name()->IsEqualTo(CStrVector("_ArgumentsLength")) || |
| 1218 node->name()->IsEqualTo(CStrVector("_Arguments")))) { |
| 1219 // Don't inline the %_ArgumentsLength or %_Arguments because their |
| 1220 // implementation will not work. There is no stack frame to get them |
| 1221 // from. |
| 1222 add_flag(kDontInline); |
| 1223 } |
| 1224 } |
| 1225 |
| 1226 |
| 1227 void AstConstructionVisitor::VisitUnaryOperation(UnaryOperation* node) { |
| 1228 increase_node_count(); |
| 1229 } |
| 1230 |
| 1231 |
| 1232 void AstConstructionVisitor::VisitCountOperation(CountOperation* node) { |
| 1233 increase_node_count(); |
| 1234 } |
| 1235 |
| 1236 |
| 1237 void AstConstructionVisitor::VisitBinaryOperation(BinaryOperation* node) { |
| 1238 increase_node_count(); |
| 1239 } |
| 1240 |
| 1241 |
| 1242 void AstConstructionVisitor::VisitCompareOperation(CompareOperation* node) { |
| 1243 increase_node_count(); |
| 1244 } |
| 1245 |
| 1246 |
| 1247 void AstConstructionVisitor::VisitThisFunction(ThisFunction* node) { |
| 1248 increase_node_count(); |
| 1249 } |
| 1250 |
| 1251 |
| 1252 Block* AstNodeFactory::NewBlock(ZoneStringList* labels, |
| 1253 int capacity, |
| 1254 bool is_initializer_block) { |
| 1255 Block* block = new(zone_) Block( |
| 1256 isolate_, labels, capacity, is_initializer_block); |
| 1257 Visit(block); |
| 1258 return block; |
| 1259 } |
| 1260 |
| 1261 |
| 1262 Declaration* AstNodeFactory::NewDeclaration(VariableProxy* proxy, |
| 1263 VariableMode mode, |
| 1264 FunctionLiteral* fun, |
| 1265 Scope* scope) { |
| 1266 Declaration* decl = new(zone_) Declaration(proxy, mode, fun, scope); |
| 1267 Visit(decl); |
| 1268 return decl; |
| 1269 } |
| 1270 |
| 1271 |
| 1272 DoWhileStatement* AstNodeFactory::NewDoWhileStatement(ZoneStringList* labels) { |
| 1273 DoWhileStatement* stmt = new(zone_) DoWhileStatement(isolate_, labels); |
| 1274 Visit(stmt); |
| 1275 return stmt; |
| 1276 } |
| 1277 |
| 1278 |
| 1279 WhileStatement* AstNodeFactory::NewWhileStatement(ZoneStringList* labels) { |
| 1280 WhileStatement* stmt = new(zone_) WhileStatement(isolate_, labels); |
| 1281 Visit(stmt); |
| 1282 return stmt; |
| 1283 } |
| 1284 |
| 1285 |
| 1286 ForStatement* AstNodeFactory::NewForStatement(ZoneStringList* labels) { |
| 1287 ForStatement* stmt = new(zone_) ForStatement(isolate_, labels); |
| 1288 Visit(stmt); |
| 1289 return stmt; |
| 1290 } |
| 1291 |
| 1292 |
| 1293 ForInStatement* AstNodeFactory::NewForInStatement(ZoneStringList* labels) { |
| 1294 ForInStatement* stmt = new(zone_) ForInStatement(isolate_, labels); |
| 1295 Visit(stmt); |
| 1296 return stmt; |
| 1297 } |
| 1298 |
| 1299 |
| 1300 ExpressionStatement* AstNodeFactory::NewExpressionStatement( |
| 1301 Expression* expression) { |
| 1302 ExpressionStatement* stmt = new(zone_) ExpressionStatement(expression); |
| 1303 Visit(stmt); |
| 1304 return stmt; |
| 1305 } |
| 1306 |
| 1307 |
| 1308 ContinueStatement* AstNodeFactory::NewContinueStatement( |
| 1309 IterationStatement* target) { |
| 1310 ContinueStatement* stmt = new(zone_) ContinueStatement(target); |
| 1311 Visit(stmt); |
| 1312 return stmt; |
| 1313 } |
| 1314 |
| 1315 |
| 1316 BreakStatement* AstNodeFactory::NewBreakStatement(BreakableStatement* target) { |
| 1317 BreakStatement* stmt = new(zone_) BreakStatement(target); |
| 1318 Visit(stmt); |
| 1319 return stmt; |
| 1320 } |
| 1321 |
| 1322 |
| 1323 ReturnStatement* AstNodeFactory::NewReturnStatement(Expression* expression) { |
| 1324 ReturnStatement* stmt = new(zone_) ReturnStatement(expression); |
| 1325 Visit(stmt); |
| 1326 return stmt; |
| 1327 } |
| 1328 |
| 1329 |
| 1330 WithStatement* AstNodeFactory::NewWithStatement(Expression* expression, |
| 1331 Statement* statement) { |
| 1332 WithStatement* stmt = new(zone_) WithStatement(expression, statement); |
| 1333 Visit(stmt); |
| 1334 return stmt; |
| 1335 } |
| 1336 |
| 1337 |
| 1338 SwitchStatement* AstNodeFactory::NewSwitchStatement(ZoneStringList* labels) { |
| 1339 SwitchStatement* stmt = new(zone_) SwitchStatement(isolate_, labels); |
| 1340 Visit(stmt); |
| 1341 return stmt; |
| 1342 } |
| 1343 |
| 1344 |
| 1345 IfStatement* AstNodeFactory::NewIfStatement(Expression* condition, |
| 1346 Statement* then_statement, |
| 1347 Statement* else_statement) { |
| 1348 IfStatement* stmt = new(zone_) IfStatement( |
| 1349 isolate_, condition, then_statement, else_statement); |
| 1350 Visit(stmt); |
| 1351 return stmt; |
| 1352 } |
| 1353 |
| 1354 |
| 1355 TryCatchStatement* AstNodeFactory::NewTryCatchStatement(int index, |
| 1356 Block* try_block, |
| 1357 Scope* scope, |
| 1358 Variable* variable, |
| 1359 Block* catch_block) { |
| 1360 TryCatchStatement* stmt = new(zone_) TryCatchStatement( |
| 1361 index, try_block, scope, variable, catch_block); |
| 1362 Visit(stmt); |
| 1363 return stmt; |
| 1364 } |
| 1365 |
| 1366 |
| 1367 TryFinallyStatement* AstNodeFactory::NewTryFinallyStatement( |
| 1368 int index, |
| 1369 Block* try_block, |
| 1370 Block* finally_block) { |
| 1371 TryFinallyStatement* stmt = |
| 1372 new(zone_) TryFinallyStatement(index, try_block, finally_block); |
| 1373 Visit(stmt); |
| 1374 return stmt; |
| 1375 } |
| 1376 |
| 1377 |
| 1378 DebuggerStatement* AstNodeFactory::NewDebuggerStatement() { |
| 1379 DebuggerStatement* stmt = new(zone_) DebuggerStatement(); |
| 1380 Visit(stmt); |
| 1381 return stmt; |
| 1382 } |
| 1383 |
| 1384 |
| 1385 EmptyStatement* AstNodeFactory::NewEmptyStatement() { |
| 1386 static EmptyStatement* empty = ::new EmptyStatement(); |
| 1387 return empty; |
| 1388 } |
| 1389 |
| 1390 |
| 1391 Literal* AstNodeFactory::NewLiteral(Handle<Object> handle) { |
| 1392 Literal* lit = new(zone_) Literal(isolate_, handle); |
| 1393 Visit(lit); |
| 1394 return lit; |
| 1395 } |
| 1396 |
| 1397 |
| 1398 Literal* AstNodeFactory::NewNumberLiteral(double number) { |
| 1399 return NewLiteral(isolate_->factory()->NewNumber(number, TENURED)); |
| 1400 } |
| 1401 |
| 1402 |
| 1403 ObjectLiteral* AstNodeFactory::NewObjectLiteral( |
| 1404 Handle<FixedArray> constant_properties, |
| 1405 ZoneList<ObjectLiteral::Property*>* properties, |
| 1406 int literal_index, |
| 1407 bool is_simple, |
| 1408 bool fast_elements, |
| 1409 int depth, |
| 1410 bool has_function) { |
| 1411 ObjectLiteral* lit = new(zone_) ObjectLiteral( |
| 1412 isolate_, constant_properties, properties, literal_index, |
| 1413 is_simple, fast_elements, depth, has_function); |
| 1414 Visit(lit); |
| 1415 return lit; |
| 1416 } |
| 1417 |
| 1418 |
| 1419 RegExpLiteral* AstNodeFactory::NewRegExpLiteral(Handle<String> pattern, |
| 1420 Handle<String> flags, |
| 1421 int literal_index) { |
| 1422 RegExpLiteral* lit = |
| 1423 new(zone_) RegExpLiteral(isolate_, pattern, flags, literal_index); |
| 1424 Visit(lit); |
| 1425 return lit; |
| 1426 } |
| 1427 |
| 1428 |
| 1429 ArrayLiteral* AstNodeFactory::NewArrayLiteral( |
| 1430 Handle<FixedArray> constant_elements, |
| 1431 ZoneList<Expression*>* values, |
| 1432 int literal_index, |
| 1433 bool is_simple, |
| 1434 int depth) { |
| 1435 ArrayLiteral* lit = new(zone_) ArrayLiteral( |
| 1436 isolate_, constant_elements, values, literal_index, is_simple, depth); |
| 1437 Visit(lit); |
| 1438 return lit; |
| 1439 } |
| 1440 |
| 1441 |
| 1442 VariableProxy* AstNodeFactory::NewVariableProxy(Variable* var) { |
| 1443 VariableProxy* proxy = new(zone_) VariableProxy(isolate_, var); |
| 1444 Visit(proxy); |
| 1445 return proxy; |
| 1446 } |
| 1447 |
| 1448 |
| 1449 VariableProxy* AstNodeFactory::NewVariableProxy(Handle<String> name, |
| 1450 bool is_this, |
| 1451 int position) { |
| 1452 VariableProxy* proxy = |
| 1453 new(zone_) VariableProxy(isolate_, name, is_this, position); |
| 1454 Visit(proxy); |
| 1455 return proxy; |
| 1456 } |
| 1457 |
| 1458 |
| 1459 Property* AstNodeFactory::NewProperty(Expression* obj, |
| 1460 Expression* key, |
| 1461 int pos) { |
| 1462 Property* prop = new(zone_) Property(isolate_, obj, key, pos); |
| 1463 Visit(prop); |
| 1464 return prop; |
| 1465 } |
| 1466 |
| 1467 |
| 1468 Call* AstNodeFactory::NewCall(Expression* expression, |
| 1469 ZoneList<Expression*>* arguments, |
| 1470 int pos) { |
| 1471 Call* call = new(zone_) Call(isolate_, expression, arguments, pos); |
| 1472 Visit(call); |
| 1473 return call; |
| 1474 } |
| 1475 |
| 1476 |
| 1477 CallNew* AstNodeFactory::NewCallNew(Expression* expression, |
| 1478 ZoneList<Expression*>* arguments, |
| 1479 int pos) { |
| 1480 CallNew* call = new(zone_) CallNew(isolate_, expression, arguments, pos); |
| 1481 Visit(call); |
| 1482 return call; |
| 1483 } |
| 1484 |
| 1485 |
| 1486 CallRuntime* AstNodeFactory::NewCallRuntime(Handle<String> name, |
| 1487 const Runtime::Function* function, |
| 1488 ZoneList<Expression*>* arguments) { |
| 1489 CallRuntime* call = |
| 1490 new(zone_) CallRuntime(isolate_, name, function, arguments); |
| 1491 Visit(call); |
| 1492 return call; |
| 1493 } |
| 1494 |
| 1495 |
| 1496 UnaryOperation* AstNodeFactory::NewUnaryOperation(Token::Value op, |
| 1497 Expression* expression, |
| 1498 int pos) { |
| 1499 UnaryOperation* node = |
| 1500 new(zone_) UnaryOperation(isolate_, op, expression, pos); |
| 1501 Visit(node); |
| 1502 return node; |
| 1503 } |
| 1504 |
| 1505 |
| 1506 BinaryOperation* AstNodeFactory::NewBinaryOperation(Token::Value op, |
| 1507 Expression* left, |
| 1508 Expression* right, |
| 1509 int pos) { |
| 1510 BinaryOperation* node = |
| 1511 new(zone_) BinaryOperation(isolate_, op, left, right, pos); |
| 1512 Visit(node); |
| 1513 return node; |
| 1514 } |
| 1515 |
| 1516 |
| 1517 CountOperation* AstNodeFactory::NewCountOperation(Token::Value op, |
| 1518 bool is_prefix, |
| 1519 Expression* expr, |
| 1520 int pos) { |
| 1521 CountOperation* node = |
| 1522 new(zone_) CountOperation(isolate_, op, is_prefix, expr, pos); |
| 1523 Visit(node); |
| 1524 return node; |
| 1525 } |
| 1526 |
| 1527 |
| 1528 CompareOperation* AstNodeFactory::NewCompareOperation(Token::Value op, |
| 1529 Expression* left, |
| 1530 Expression* right, |
| 1531 int pos) { |
| 1532 CompareOperation* node = |
| 1533 new(zone_) CompareOperation(isolate_, op, left, right, pos); |
| 1534 Visit(node); |
| 1535 return node; |
| 1536 } |
| 1537 |
| 1538 |
| 1539 Conditional* AstNodeFactory::NewConditional(Expression* condition, |
| 1540 Expression* then_expression, |
| 1541 Expression* else_expression, |
| 1542 int then_expression_position, |
| 1543 int else_expression_position) { |
| 1544 Conditional* cond = new(zone_) Conditional( |
| 1545 isolate_, condition, then_expression, else_expression, |
| 1546 then_expression_position, else_expression_position); |
| 1547 Visit(cond); |
| 1548 return cond; |
| 1549 } |
| 1550 |
| 1551 |
| 1552 Assignment* AstNodeFactory::NewAssignment(Token::Value op, |
| 1553 Expression* target, |
| 1554 Expression* value, |
| 1555 int pos) { |
| 1556 Assignment* assign = |
| 1557 new(zone_) Assignment(isolate_, op, target, value, pos, this); |
| 1558 Visit(assign); |
| 1559 return assign; |
| 1560 } |
| 1561 |
| 1562 |
| 1563 Throw* AstNodeFactory::NewThrow(Expression* exception, int pos) { |
| 1564 Throw* t = new(zone_) Throw(isolate_, exception, pos); |
| 1565 Visit(t); |
| 1566 return t; |
| 1567 } |
| 1568 |
| 1569 FunctionLiteral* AstNodeFactory::NewFunctionLiteral( |
| 1570 Handle<String> name, |
| 1571 Scope* scope, |
| 1572 ZoneList<Statement*>* body, |
| 1573 int materialized_literal_count, |
| 1574 int expected_property_count, |
| 1575 int handler_count, |
| 1576 bool has_only_simple_this_property_assignments, |
| 1577 Handle<FixedArray> this_property_assignments, |
| 1578 int parameter_count, |
| 1579 FunctionLiteral::Type type, |
| 1580 bool has_duplicate_parameters, |
| 1581 bool visit_with_visitor) { |
| 1582 FunctionLiteral* lit = new(zone_) FunctionLiteral( |
| 1583 isolate_, name, scope, body, |
| 1584 materialized_literal_count, expected_property_count, handler_count, |
| 1585 has_only_simple_this_property_assignments, this_property_assignments, |
| 1586 parameter_count, type, has_duplicate_parameters); |
| 1587 if (visit_with_visitor) { |
| 1588 Visit(lit); |
| 1589 } |
| 1590 return lit; |
| 1591 } |
| 1592 |
| 1593 |
| 1594 SharedFunctionInfoLiteral* AstNodeFactory::NewSharedFunctionInfoLiteral( |
| 1595 Handle<SharedFunctionInfo> shared_function_info) { |
| 1596 SharedFunctionInfoLiteral* lit = |
| 1597 new(zone_) SharedFunctionInfoLiteral(isolate_, shared_function_info); |
| 1598 Visit(lit); |
| 1599 return lit; |
| 1600 } |
| 1601 |
| 1602 |
| 1603 ThisFunction* AstNodeFactory::NewThisFunction() { |
| 1604 ThisFunction* fun = new(zone_) ThisFunction(isolate_); |
| 1605 Visit(fun); |
| 1606 return fun; |
| 1607 } |
| 1608 |
| 1609 |
| 1610 void AstNodeFactory::Visit(AstNode* node) { |
| 1611 AstConstructionVisitor* visitor = |
| 1612 reinterpret_cast<AstConstructionVisitor*>(visitor_); |
| 1613 if (visitor_ != NULL && visitor->properties() != NULL) { |
| 1614 node->Accept(visitor_); |
| 1615 } |
| 1616 } |
| 1617 |
1218 } } // namespace v8::internal | 1618 } } // namespace v8::internal |
OLD | NEW |