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

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

Issue 2266493002: Used a BitField to improve packing of AstNode and subclasses (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 4 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
« src/ast/ast.h ('K') | « src/ast/ast.h ('k') | no next file » | 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 // 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 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 #undef GENERATE_CASE 159 #undef GENERATE_CASE
160 #undef JUMP_NODE_LIST 160 #undef JUMP_NODE_LIST
161 default: 161 default:
162 return false; 162 return false;
163 } 163 }
164 } 164 }
165 165
166 VariableProxy::VariableProxy(Variable* var, int start_position, 166 VariableProxy::VariableProxy(Variable* var, int start_position,
167 int end_position) 167 int end_position)
168 : Expression(start_position, kVariableProxy), 168 : Expression(start_position, kVariableProxy),
169 bit_field_(IsThisField::encode(var->is_this()) |
170 IsAssignedField::encode(false) |
171 IsResolvedField::encode(false)),
172 end_position_(end_position), 169 end_position_(end_position),
173 raw_name_(var->raw_name()), 170 raw_name_(var->raw_name()),
174 next_unresolved_(nullptr) { 171 next_unresolved_(nullptr) {
172 bit_field_ |= IsThisField::encode(var->is_this()) |
173 IsAssignedField::encode(false) | IsResolvedField::encode(false);
175 BindTo(var); 174 BindTo(var);
176 } 175 }
177 176
178 VariableProxy::VariableProxy(const AstRawString* name, 177 VariableProxy::VariableProxy(const AstRawString* name,
179 Variable::Kind variable_kind, int start_position, 178 Variable::Kind variable_kind, int start_position,
180 int end_position) 179 int end_position)
181 : Expression(start_position, kVariableProxy), 180 : Expression(start_position, kVariableProxy),
182 bit_field_(IsThisField::encode(variable_kind == Variable::THIS) |
183 IsAssignedField::encode(false) |
184 IsResolvedField::encode(false)),
185 end_position_(end_position), 181 end_position_(end_position),
186 raw_name_(name), 182 raw_name_(name),
187 next_unresolved_(nullptr) {} 183 next_unresolved_(nullptr) {
184 bit_field_ |= IsThisField::encode(variable_kind == Variable::THIS) |
185 IsAssignedField::encode(false) | IsResolvedField::encode(false);
186 }
188 187
189 VariableProxy::VariableProxy(const VariableProxy* copy_from) 188 VariableProxy::VariableProxy(const VariableProxy* copy_from)
190 : Expression(copy_from->position(), kVariableProxy), 189 : Expression(copy_from->position(), kVariableProxy),
191 bit_field_(copy_from->bit_field_),
192 end_position_(copy_from->end_position_), 190 end_position_(copy_from->end_position_),
193 next_unresolved_(nullptr) { 191 next_unresolved_(nullptr) {
192 bit_field_ = copy_from->bit_field_;
194 if (copy_from->is_resolved()) { 193 if (copy_from->is_resolved()) {
195 var_ = copy_from->var_; 194 var_ = copy_from->var_;
196 } else { 195 } else {
197 raw_name_ = copy_from->raw_name_; 196 raw_name_ = copy_from->raw_name_;
198 } 197 }
199 } 198 }
200 199
201 void VariableProxy::BindTo(Variable* var) { 200 void VariableProxy::BindTo(Variable* var) {
202 DCHECK((is_this() && var->is_this()) || raw_name() == var->raw_name()); 201 DCHECK((is_this() && var->is_this()) || raw_name() == var->raw_name());
203 set_var(var); 202 set_var(var);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 void ForInStatement::AssignFeedbackVectorSlots(Isolate* isolate, 245 void ForInStatement::AssignFeedbackVectorSlots(Isolate* isolate,
247 FeedbackVectorSpec* spec, 246 FeedbackVectorSpec* spec,
248 FeedbackVectorSlotCache* cache) { 247 FeedbackVectorSlotCache* cache) {
249 AssignVectorSlots(each(), spec, &each_slot_); 248 AssignVectorSlots(each(), spec, &each_slot_);
250 for_in_feedback_slot_ = spec->AddGeneralSlot(); 249 for_in_feedback_slot_ = spec->AddGeneralSlot();
251 } 250 }
252 251
253 Assignment::Assignment(Token::Value op, Expression* target, Expression* value, 252 Assignment::Assignment(Token::Value op, Expression* target, Expression* value,
254 int pos) 253 int pos)
255 : Expression(pos, kAssignment), 254 : Expression(pos, kAssignment),
256 bit_field_(
257 IsUninitializedField::encode(false) | KeyTypeField::encode(ELEMENT) |
258 StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op)),
259 target_(target), 255 target_(target),
260 value_(value), 256 value_(value),
261 binary_operation_(NULL) {} 257 binary_operation_(NULL) {
258 bit_field_ |= IsUninitializedField::encode(false) |
259 KeyTypeField::encode(ELEMENT) |
260 StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op);
261 }
262 262
263 void Assignment::AssignFeedbackVectorSlots(Isolate* isolate, 263 void Assignment::AssignFeedbackVectorSlots(Isolate* isolate,
264 FeedbackVectorSpec* spec, 264 FeedbackVectorSpec* spec,
265 FeedbackVectorSlotCache* cache) { 265 FeedbackVectorSlotCache* cache) {
266 AssignVectorSlots(target(), spec, &slot_); 266 AssignVectorSlots(target(), spec, &slot_);
267 } 267 }
268 268
269 269
270 void CountOperation::AssignFeedbackVectorSlots(Isolate* isolate, 270 void CountOperation::AssignFeedbackVectorSlots(Isolate* isolate,
271 FeedbackVectorSpec* spec, 271 FeedbackVectorSpec* spec,
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 Handle<Object> key = property->key()->AsLiteral()->value(); 544 Handle<Object> key = property->key()->AsLiteral()->value();
545 Handle<Object> value = GetBoilerplateValue(property->value(), isolate); 545 Handle<Object> value = GetBoilerplateValue(property->value(), isolate);
546 546
547 // Ensure objects that may, at any point in time, contain fields with double 547 // Ensure objects that may, at any point in time, contain fields with double
548 // representation are always treated as nested objects. This is true for 548 // representation are always treated as nested objects. This is true for
549 // computed fields (value is undefined), and smi and double literals 549 // computed fields (value is undefined), and smi and double literals
550 // (value->IsNumber()). 550 // (value->IsNumber()).
551 // TODO(verwaest): Remove once we can store them inline. 551 // TODO(verwaest): Remove once we can store them inline.
552 if (FLAG_track_double_fields && 552 if (FLAG_track_double_fields &&
553 (value->IsNumber() || value->IsUninitialized(isolate))) { 553 (value->IsNumber() || value->IsUninitialized(isolate))) {
554 may_store_doubles_ = true; 554 bit_field_ = MayStoreDoublesField::update(bit_field_, true);
555 } 555 }
556 556
557 is_simple = is_simple && !value->IsUninitialized(isolate); 557 is_simple = is_simple && !value->IsUninitialized(isolate);
558 558
559 // Keep track of the number of elements in the object literal and 559 // Keep track of the number of elements in the object literal and
560 // the largest element index. If the largest element index is 560 // the largest element index. If the largest element index is
561 // much larger than the number of elements, creating an object 561 // much larger than the number of elements, creating an object
562 // literal with fast elements will be a waste of space. 562 // literal with fast elements will be a waste of space.
563 uint32_t element_index = 0; 563 uint32_t element_index = 0;
564 if (key->IsString() && String::cast(*key)->AsArrayIndex(&element_index)) { 564 if (key->IsString() && String::cast(*key)->AsArrayIndex(&element_index)) {
565 max_element_index = Max(element_index, max_element_index); 565 max_element_index = Max(element_index, max_element_index);
566 elements++; 566 elements++;
567 key = isolate->factory()->NewNumberFromUint(element_index); 567 key = isolate->factory()->NewNumberFromUint(element_index);
568 } else if (key->ToArrayIndex(&element_index)) { 568 } else if (key->ToArrayIndex(&element_index)) {
569 max_element_index = Max(element_index, max_element_index); 569 max_element_index = Max(element_index, max_element_index);
570 elements++; 570 elements++;
571 } else if (key->IsNumber()) { 571 } else if (key->IsNumber()) {
572 key = isolate->factory()->NumberToString(key); 572 key = isolate->factory()->NumberToString(key);
573 } 573 }
574 574
575 // Add name, value pair to the fixed array. 575 // Add name, value pair to the fixed array.
576 constant_properties->set(position++, *key); 576 constant_properties->set(position++, *key);
577 constant_properties->set(position++, *value); 577 constant_properties->set(position++, *value);
578 } 578 }
579 579
580 constant_properties_ = constant_properties; 580 constant_properties_ = constant_properties;
581 fast_elements_ = 581 bit_field_ = FastElementsField::update(
582 (max_element_index <= 32) || ((2 * elements) >= max_element_index); 582 bit_field_,
583 has_elements_ = elements > 0; 583 (max_element_index <= 32) || ((2 * elements) >= max_element_index));
584 bit_field_ = HasElementsField::update(bit_field_, elements > 0);
585
584 set_is_simple(is_simple); 586 set_is_simple(is_simple);
585 set_depth(depth_acc); 587 set_depth(depth_acc);
586 } 588 }
587 589
588 590
589 void ArrayLiteral::BuildConstantElements(Isolate* isolate) { 591 void ArrayLiteral::BuildConstantElements(Isolate* isolate) {
590 DCHECK_LT(first_spread_index_, 0); 592 DCHECK_LT(first_spread_index_, 0);
591 593
592 if (!constant_elements_.is_null()) return; 594 if (!constant_elements_.is_null()) return;
593 595
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 *expr = left->AsUnaryOperation()->expression(); 754 *expr = left->AsUnaryOperation()->expression();
753 *check = Handle<String>::cast(right->AsLiteral()->value()); 755 *check = Handle<String>::cast(right->AsLiteral()->value());
754 return true; 756 return true;
755 } 757 }
756 return false; 758 return false;
757 } 759 }
758 760
759 761
760 bool CompareOperation::IsLiteralCompareTypeof(Expression** expr, 762 bool CompareOperation::IsLiteralCompareTypeof(Expression** expr,
761 Handle<String>* check) { 763 Handle<String>* check) {
762 return MatchLiteralCompareTypeof(left_, op_, right_, expr, check) || 764 return MatchLiteralCompareTypeof(left_, op(), right_, expr, check) ||
763 MatchLiteralCompareTypeof(right_, op_, left_, expr, check); 765 MatchLiteralCompareTypeof(right_, op(), left_, expr, check);
764 } 766 }
765 767
766 768
767 static bool IsVoidOfLiteral(Expression* expr) { 769 static bool IsVoidOfLiteral(Expression* expr) {
768 UnaryOperation* maybe_unary = expr->AsUnaryOperation(); 770 UnaryOperation* maybe_unary = expr->AsUnaryOperation();
769 return maybe_unary != NULL && 771 return maybe_unary != NULL &&
770 maybe_unary->op() == Token::VOID && 772 maybe_unary->op() == Token::VOID &&
771 maybe_unary->expression()->IsLiteral(); 773 maybe_unary->expression()->IsLiteral();
772 } 774 }
773 775
774 776
775 // Check for the pattern: void <literal> equals <expression> or 777 // Check for the pattern: void <literal> equals <expression> or
776 // undefined equals <expression> 778 // undefined equals <expression>
777 static bool MatchLiteralCompareUndefined(Expression* left, 779 static bool MatchLiteralCompareUndefined(Expression* left,
778 Token::Value op, 780 Token::Value op,
779 Expression* right, 781 Expression* right,
780 Expression** expr) { 782 Expression** expr) {
781 if (IsVoidOfLiteral(left) && Token::IsEqualityOp(op)) { 783 if (IsVoidOfLiteral(left) && Token::IsEqualityOp(op)) {
782 *expr = right; 784 *expr = right;
783 return true; 785 return true;
784 } 786 }
785 if (left->IsUndefinedLiteral() && Token::IsEqualityOp(op)) { 787 if (left->IsUndefinedLiteral() && Token::IsEqualityOp(op)) {
786 *expr = right; 788 *expr = right;
787 return true; 789 return true;
788 } 790 }
789 return false; 791 return false;
790 } 792 }
791 793
792 bool CompareOperation::IsLiteralCompareUndefined(Expression** expr) { 794 bool CompareOperation::IsLiteralCompareUndefined(Expression** expr) {
793 return MatchLiteralCompareUndefined(left_, op_, right_, expr) || 795 return MatchLiteralCompareUndefined(left_, op(), right_, expr) ||
794 MatchLiteralCompareUndefined(right_, op_, left_, expr); 796 MatchLiteralCompareUndefined(right_, op(), left_, expr);
795 } 797 }
796 798
797 799
798 // Check for the pattern: null equals <expression> 800 // Check for the pattern: null equals <expression>
799 static bool MatchLiteralCompareNull(Expression* left, 801 static bool MatchLiteralCompareNull(Expression* left,
800 Token::Value op, 802 Token::Value op,
801 Expression* right, 803 Expression* right,
802 Expression** expr) { 804 Expression** expr) {
803 if (left->IsNullLiteral() && Token::IsEqualityOp(op)) { 805 if (left->IsNullLiteral() && Token::IsEqualityOp(op)) {
804 *expr = right; 806 *expr = right;
805 return true; 807 return true;
806 } 808 }
807 return false; 809 return false;
808 } 810 }
809 811
810 812
811 bool CompareOperation::IsLiteralCompareNull(Expression** expr) { 813 bool CompareOperation::IsLiteralCompareNull(Expression** expr) {
812 return MatchLiteralCompareNull(left_, op_, right_, expr) || 814 return MatchLiteralCompareNull(left_, op(), right_, expr) ||
813 MatchLiteralCompareNull(right_, op_, left_, expr); 815 MatchLiteralCompareNull(right_, op(), left_, expr);
814 } 816 }
815 817
816 818
817 // ---------------------------------------------------------------------------- 819 // ----------------------------------------------------------------------------
818 // Recording of type feedback 820 // Recording of type feedback
819 821
820 // TODO(rossberg): all RecordTypeFeedback functions should disappear 822 // TODO(rossberg): all RecordTypeFeedback functions should disappear
821 // once we use the common type field in the AST consistently. 823 // once we use the common type field in the AST consistently.
822 824
823 void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { 825 void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) {
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 // static 954 // static
953 bool Literal::Match(void* literal1, void* literal2) { 955 bool Literal::Match(void* literal1, void* literal2) {
954 const AstValue* x = static_cast<Literal*>(literal1)->raw_value(); 956 const AstValue* x = static_cast<Literal*>(literal1)->raw_value();
955 const AstValue* y = static_cast<Literal*>(literal2)->raw_value(); 957 const AstValue* y = static_cast<Literal*>(literal2)->raw_value();
956 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) || 958 return (x->IsString() && y->IsString() && x->AsString() == y->AsString()) ||
957 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber()); 959 (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber());
958 } 960 }
959 961
960 } // namespace internal 962 } // namespace internal
961 } // namespace v8 963 } // namespace v8
OLDNEW
« src/ast/ast.h ('K') | « src/ast/ast.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698