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

Side by Side Diff: src/ast/ast.cc

Issue 2126233002: Devirtualize AstNode and subclasses, except for visiting-related methods. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: And call again Created 4 years, 5 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/ast/ast.h" 5 #include "src/ast/ast.h"
6 6
7 #include <cmath> // For isfinite. 7 #include <cmath> // For isfinite.
8 8
9 #include "src/ast/prettyprinter.h" 9 #include "src/ast/prettyprinter.h"
10 #include "src/ast/scopes.h" 10 #include "src/ast/scopes.h"
(...skipping 29 matching lines...) Expand all
40 AstPrinter::PrintOut(isolate, this); 40 AstPrinter::PrintOut(isolate, this);
41 } 41 }
42 42
43 43
44 void AstNode::PrettyPrint(Isolate* isolate) { 44 void AstNode::PrettyPrint(Isolate* isolate) {
45 PrettyPrinter::PrintOut(isolate, this); 45 PrettyPrinter::PrintOut(isolate, this);
46 } 46 }
47 47
48 #endif // DEBUG 48 #endif // DEBUG
49 49
50 #define RETURN_NODE(Node) \
51 case k##Node: \
52 return static_cast<Node*>(this);
53
54 IterationStatement* AstNode::AsIterationStatement() {
55 switch (node_type()) {
56 ITERATION_NODE_LIST(RETURN_NODE);
57 default:
58 return nullptr;
59 }
60 }
61
62 BreakableStatement* AstNode::AsBreakableStatement() {
63 switch (node_type()) {
64 BREAKABLE_NODE_LIST(RETURN_NODE);
65 ITERATION_NODE_LIST(RETURN_NODE);
66 default:
67 return nullptr;
68 }
69 }
70
71 MaterializedLiteral* AstNode::AsMaterializedLiteral() {
72 switch (node_type()) {
73 LITERAL_NODE_LIST(RETURN_NODE);
74 default:
75 return nullptr;
76 }
77 }
78
79 #undef RETURN_NODE
80
81 InitializationFlag Declaration::initialization() const {
82 switch (node_type()) {
83 #define GENERATE_CASE(Node) \
84 case k##Node: \
Igor Sheludko 2016/07/14 14:02:33 How about adding something like STATIC_ASSERT(&
Toon Verwaest 2016/07/14 14:19:39 I'd add STATIC_ASSERT(k##Node != kExpression), how
Igor Sheludko 2016/07/14 14:49:30 No, the idea is to ensure that when you call a foo
85 return static_cast<const Node*>(this)->initialization();
86 DECLARATION_NODE_LIST(GENERATE_CASE);
87 #undef GENERATE_CASE
88 default:
89 UNREACHABLE();
90 return kNeedsInitialization;
91 }
92 }
50 93
51 bool Expression::IsSmiLiteral() const { 94 bool Expression::IsSmiLiteral() const {
52 return IsLiteral() && AsLiteral()->value()->IsSmi(); 95 return IsLiteral() && AsLiteral()->value()->IsSmi();
53 } 96 }
54 97
55 98
56 bool Expression::IsStringLiteral() const { 99 bool Expression::IsStringLiteral() const {
57 return IsLiteral() && AsLiteral()->value()->IsString(); 100 return IsLiteral() && AsLiteral()->value()->IsString();
58 } 101 }
59 102
103 bool Expression::IsPropertyName() const {
104 return IsLiteral() && AsLiteral()->IsPropertyName();
105 }
60 106
61 bool Expression::IsNullLiteral() const { 107 bool Expression::IsNullLiteral() const {
62 if (!IsLiteral()) return false; 108 if (!IsLiteral()) return false;
63 Handle<Object> value = AsLiteral()->value(); 109 Handle<Object> value = AsLiteral()->value();
64 return !value->IsSmi() && 110 return !value->IsSmi() &&
65 value->IsNull(HeapObject::cast(*value)->GetIsolate()); 111 value->IsNull(HeapObject::cast(*value)->GetIsolate());
66 } 112 }
67 113
68 bool Expression::IsUndefinedLiteral() const { 114 bool Expression::IsUndefinedLiteral() const {
69 if (IsLiteral()) { 115 if (IsLiteral()) {
70 Handle<Object> value = AsLiteral()->value(); 116 Handle<Object> value = AsLiteral()->value();
71 if (!value->IsSmi() && 117 if (!value->IsSmi() &&
72 value->IsUndefined(HeapObject::cast(*value)->GetIsolate())) { 118 value->IsUndefined(HeapObject::cast(*value)->GetIsolate())) {
73 return true; 119 return true;
74 } 120 }
75 } 121 }
76 122
77 const VariableProxy* var_proxy = AsVariableProxy(); 123 const VariableProxy* var_proxy = AsVariableProxy();
78 if (var_proxy == NULL) return false; 124 if (var_proxy == NULL) return false;
79 Variable* var = var_proxy->var(); 125 Variable* var = var_proxy->var();
80 // The global identifier "undefined" is immutable. Everything 126 // The global identifier "undefined" is immutable. Everything
81 // else could be reassigned. 127 // else could be reassigned.
82 return var != NULL && var->IsUnallocatedOrGlobalSlot() && 128 return var != NULL && var->IsUnallocatedOrGlobalSlot() &&
83 var_proxy->raw_name()->IsOneByteEqualTo("undefined"); 129 var_proxy->raw_name()->IsOneByteEqualTo("undefined");
84 } 130 }
85 131
132 bool Expression::ToBooleanIsTrue() const {
133 return IsLiteral() && AsLiteral()->ToBooleanIsTrue();
134 }
135
136 bool Expression::ToBooleanIsFalse() const {
137 return IsLiteral() && AsLiteral()->ToBooleanIsFalse();
138 }
139
140 bool Expression::IsValidReferenceExpression() const {
141 return IsProperty() ||
142 (IsVariableProxy() && AsVariableProxy()->IsValidReferenceExpression());
143 }
86 144
87 bool Expression::IsValidReferenceExpressionOrThis() const { 145 bool Expression::IsValidReferenceExpressionOrThis() const {
88 return IsValidReferenceExpression() || 146 return IsValidReferenceExpression() ||
89 (IsVariableProxy() && AsVariableProxy()->is_this()); 147 (IsVariableProxy() && AsVariableProxy()->is_this());
90 } 148 }
91 149
150 bool Expression::IsAnonymousFunctionDefinition() const {
151 return (IsFunctionLiteral() &&
152 AsFunctionLiteral()->IsAnonymousFunctionDefinition()) ||
153 (IsClassLiteral() &&
154 AsClassLiteral()->IsAnonymousFunctionDefinition());
155 }
156
157 void Expression::MarkTail() {
158 if (IsConditional()) {
159 AsConditional()->MarkTail();
160 } else if (IsCall()) {
161 AsCall()->MarkTail();
162 } else if (IsBinaryOperation()) {
163 AsBinaryOperation()->MarkTail();
164 }
165 }
166
167 bool Statement::IsJump() const {
168 return (IsBlock() && AsBlock()->IsJump()) ||
169 (IsExpressionStatement() && AsExpressionStatement()->IsJump()) ||
170 IsContinueStatement() || IsBreakStatement() || IsReturnStatement() ||
Igor Sheludko 2016/07/14 14:02:33 How about following same pattern for all JumpState
Toon Verwaest 2016/07/14 14:19:39 Done.
171 (IsIfStatement() && AsIfStatement()->IsJump());
172 }
92 173
93 VariableProxy::VariableProxy(Zone* zone, Variable* var, int start_position, 174 VariableProxy::VariableProxy(Zone* zone, Variable* var, int start_position,
94 int end_position) 175 int end_position)
95 : Expression(zone, start_position), 176 : Expression(zone, start_position),
96 bit_field_(IsThisField::encode(var->is_this()) | 177 bit_field_(IsThisField::encode(var->is_this()) |
97 IsAssignedField::encode(false) | 178 IsAssignedField::encode(false) |
98 IsResolvedField::encode(false)), 179 IsResolvedField::encode(false)),
99 raw_name_(var->raw_name()), 180 raw_name_(var->raw_name()),
100 end_position_(end_position) { 181 end_position_(end_position) {
101 BindTo(var); 182 BindTo(var);
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 } 793 }
713 794
714 795
715 // ---------------------------------------------------------------------------- 796 // ----------------------------------------------------------------------------
716 // Recording of type feedback 797 // Recording of type feedback
717 798
718 // TODO(rossberg): all RecordTypeFeedback functions should disappear 799 // TODO(rossberg): all RecordTypeFeedback functions should disappear
719 // once we use the common type field in the AST consistently. 800 // once we use the common type field in the AST consistently.
720 801
721 void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { 802 void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) {
722 set_to_boolean_types(oracle->ToBooleanTypes(test_id())); 803 if (IsUnaryOperation()) {
804 AsUnaryOperation()->RecordToBooleanTypeFeedback(oracle);
805 } else if (IsBinaryOperation()) {
806 AsBinaryOperation()->RecordToBooleanTypeFeedback(oracle);
807 } else {
808 set_to_boolean_types(oracle->ToBooleanTypes(test_id()));
809 }
723 } 810 }
724 811
812 SmallMapList* Expression::GetReceiverTypes() {
813 switch (node_type()) {
814 #define NODE_LIST(V) \
815 PROPERTY_NODE_LIST(V) \
816 V(Call)
817 #define GENERATE_CASE(Node) \
818 case k##Node: \
819 return static_cast<Node*>(this)->GetReceiverTypes();
820 NODE_LIST(GENERATE_CASE)
821 #undef NODE_LIST
822 #undef GENERATE_CASE
823 default:
824 UNREACHABLE();
825 return nullptr;
826 }
827 }
828
829 KeyedAccessStoreMode Expression::GetStoreMode() const {
830 switch (node_type()) {
831 #define GENERATE_CASE(Node) \
832 case k##Node: \
833 return static_cast<const Node*>(this)->GetStoreMode();
834 PROPERTY_NODE_LIST(GENERATE_CASE)
835 #undef GENERATE_CASE
836 default:
837 UNREACHABLE();
838 return STANDARD_STORE;
839 }
840 }
841
842 IcCheckType Expression::GetKeyType() const {
843 switch (node_type()) {
844 #define GENERATE_CASE(Node) \
845 case k##Node: \
846 return static_cast<const Node*>(this)->GetKeyType();
847 PROPERTY_NODE_LIST(GENERATE_CASE)
848 #undef GENERATE_CASE
849 default:
850 UNREACHABLE();
851 return PROPERTY;
852 }
853 }
854
855 bool Expression::IsMonomorphic() const {
856 switch (node_type()) {
857 #define GENERATE_CASE(Node) \
858 case k##Node: \
859 return static_cast<const Node*>(this)->IsMonomorphic();
860 PROPERTY_NODE_LIST(GENERATE_CASE)
861 CALL_NODE_LIST(GENERATE_CASE)
Igor Sheludko 2016/07/14 14:02:33 GENERATE_CASE(ObjectLiteralProperty) ?
Toon Verwaest 2016/07/14 14:19:39 ObjectLiteralProperty is not an AstNode. It derive
Igor Sheludko 2016/07/14 14:49:30 Ah, indeed.
862 #undef GENERATE_CASE
863 default:
864 UNREACHABLE();
865 return false;
866 }
867 }
725 868
726 bool Call::IsUsingCallFeedbackICSlot(Isolate* isolate) const { 869 bool Call::IsUsingCallFeedbackICSlot(Isolate* isolate) const {
727 CallType call_type = GetCallType(isolate); 870 CallType call_type = GetCallType(isolate);
728 if (call_type == POSSIBLY_EVAL_CALL) { 871 if (call_type == POSSIBLY_EVAL_CALL) {
729 return false; 872 return false;
730 } 873 }
731 return true; 874 return true;
732 } 875 }
733 876
734 877
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
1127 bool Literal::Match(void* literal1, void* literal2) { 1270 bool Literal::Match(void* literal1, void* literal2) {
1128 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); 1271 const AstValue* x = static_cast<Literal*>(literal1)->raw_value();
1129 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); 1272 const AstValue* y = static_cast<Literal*>(literal2)->raw_value();
1130 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || 1273 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) ||
1131 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); 1274 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber());
1132 } 1275 }
1133 1276
1134 1277
1135 } // namespace internal 1278 } // namespace internal
1136 } // namespace v8 1279 } // namespace v8
OLDNEW
« src/ast/ast.h ('K') | « src/ast/ast.h ('k') | src/compiler/ast-graph-builder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698