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 21 matching lines...) Expand all Loading... |
32 | 32 |
33 #include "assembler.h" | 33 #include "assembler.h" |
34 #include "factory.h" | 34 #include "factory.h" |
35 #include "isolate.h" | 35 #include "isolate.h" |
36 #include "jsregexp.h" | 36 #include "jsregexp.h" |
37 #include "list-inl.h" | 37 #include "list-inl.h" |
38 #include "runtime.h" | 38 #include "runtime.h" |
39 #include "small-pointer-list.h" | 39 #include "small-pointer-list.h" |
40 #include "smart-pointers.h" | 40 #include "smart-pointers.h" |
41 #include "token.h" | 41 #include "token.h" |
| 42 #include "type-info.h" |
42 #include "utils.h" | 43 #include "utils.h" |
43 #include "variables.h" | 44 #include "variables.h" |
44 #include "interface.h" | 45 #include "interface.h" |
45 #include "zone-inl.h" | 46 #include "zone-inl.h" |
46 | 47 |
47 namespace v8 { | 48 namespace v8 { |
48 namespace internal { | 49 namespace internal { |
49 | 50 |
50 // The abstract syntax tree is an intermediate, light-weight | 51 // The abstract syntax tree is an intermediate, light-weight |
51 // representation of the parsed JavaScript code suitable for | 52 // representation of the parsed JavaScript code suitable for |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 ASSERT(IsMonomorphic()); | 364 ASSERT(IsMonomorphic()); |
364 SmallMapList* types = GetReceiverTypes(); | 365 SmallMapList* types = GetReceiverTypes(); |
365 ASSERT(types != NULL && types->length() == 1); | 366 ASSERT(types != NULL && types->length() == 1); |
366 return types->at(0); | 367 return types->at(0); |
367 } | 368 } |
368 virtual KeyedAccessStoreMode GetStoreMode() { | 369 virtual KeyedAccessStoreMode GetStoreMode() { |
369 UNREACHABLE(); | 370 UNREACHABLE(); |
370 return STANDARD_STORE; | 371 return STANDARD_STORE; |
371 } | 372 } |
372 | 373 |
| 374 // TODO(rossberg): this should move to its own AST node eventually. |
| 375 void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle); |
| 376 byte to_boolean_types() const { return to_boolean_types_; } |
| 377 |
373 BailoutId id() const { return id_; } | 378 BailoutId id() const { return id_; } |
374 TypeFeedbackId test_id() const { return test_id_; } | 379 TypeFeedbackId test_id() const { return test_id_; } |
375 | 380 |
376 protected: | 381 protected: |
377 explicit Expression(Isolate* isolate) | 382 explicit Expression(Isolate* isolate) |
378 : id_(GetNextId(isolate)), | 383 : id_(GetNextId(isolate)), |
379 test_id_(GetNextId(isolate)) {} | 384 test_id_(GetNextId(isolate)) {} |
380 | 385 |
381 private: | 386 private: |
| 387 byte to_boolean_types_; |
| 388 |
382 const BailoutId id_; | 389 const BailoutId id_; |
383 const TypeFeedbackId test_id_; | 390 const TypeFeedbackId test_id_; |
384 }; | 391 }; |
385 | 392 |
386 | 393 |
387 class BreakableStatement: public Statement { | 394 class BreakableStatement: public Statement { |
388 public: | 395 public: |
389 enum Type { | 396 enum Type { |
390 TARGET_FOR_ANONYMOUS, | 397 TARGET_FOR_ANONYMOUS, |
391 TARGET_FOR_NAMED_ONLY | 398 TARGET_FOR_NAMED_ONLY |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 osr_entry_id_(GetNextId(isolate)) { | 713 osr_entry_id_(GetNextId(isolate)) { |
707 } | 714 } |
708 | 715 |
709 void Initialize(Statement* body) { | 716 void Initialize(Statement* body) { |
710 body_ = body; | 717 body_ = body; |
711 } | 718 } |
712 | 719 |
713 private: | 720 private: |
714 Statement* body_; | 721 Statement* body_; |
715 Label continue_target_; | 722 Label continue_target_; |
| 723 |
716 const BailoutId osr_entry_id_; | 724 const BailoutId osr_entry_id_; |
717 }; | 725 }; |
718 | 726 |
719 | 727 |
720 class DoWhileStatement: public IterationStatement { | 728 class DoWhileStatement: public IterationStatement { |
721 public: | 729 public: |
722 DECLARE_NODE_TYPE(DoWhileStatement) | 730 DECLARE_NODE_TYPE(DoWhileStatement) |
723 | 731 |
724 void Initialize(Expression* cond, Statement* body) { | 732 void Initialize(Expression* cond, Statement* body) { |
725 IterationStatement::Initialize(body); | 733 IterationStatement::Initialize(body); |
(...skipping 15 matching lines...) Expand all Loading... |
741 DoWhileStatement(Isolate* isolate, ZoneStringList* labels) | 749 DoWhileStatement(Isolate* isolate, ZoneStringList* labels) |
742 : IterationStatement(isolate, labels), | 750 : IterationStatement(isolate, labels), |
743 cond_(NULL), | 751 cond_(NULL), |
744 condition_position_(-1), | 752 condition_position_(-1), |
745 continue_id_(GetNextId(isolate)), | 753 continue_id_(GetNextId(isolate)), |
746 back_edge_id_(GetNextId(isolate)) { | 754 back_edge_id_(GetNextId(isolate)) { |
747 } | 755 } |
748 | 756 |
749 private: | 757 private: |
750 Expression* cond_; | 758 Expression* cond_; |
| 759 |
751 int condition_position_; | 760 int condition_position_; |
| 761 |
752 const BailoutId continue_id_; | 762 const BailoutId continue_id_; |
753 const BailoutId back_edge_id_; | 763 const BailoutId back_edge_id_; |
754 }; | 764 }; |
755 | 765 |
756 | 766 |
757 class WhileStatement: public IterationStatement { | 767 class WhileStatement: public IterationStatement { |
758 public: | 768 public: |
759 DECLARE_NODE_TYPE(WhileStatement) | 769 DECLARE_NODE_TYPE(WhileStatement) |
760 | 770 |
761 void Initialize(Expression* cond, Statement* body) { | 771 void Initialize(Expression* cond, Statement* body) { |
(...skipping 16 matching lines...) Expand all Loading... |
778 protected: | 788 protected: |
779 WhileStatement(Isolate* isolate, ZoneStringList* labels) | 789 WhileStatement(Isolate* isolate, ZoneStringList* labels) |
780 : IterationStatement(isolate, labels), | 790 : IterationStatement(isolate, labels), |
781 cond_(NULL), | 791 cond_(NULL), |
782 may_have_function_literal_(true), | 792 may_have_function_literal_(true), |
783 body_id_(GetNextId(isolate)) { | 793 body_id_(GetNextId(isolate)) { |
784 } | 794 } |
785 | 795 |
786 private: | 796 private: |
787 Expression* cond_; | 797 Expression* cond_; |
| 798 |
788 // True if there is a function literal subexpression in the condition. | 799 // True if there is a function literal subexpression in the condition. |
789 bool may_have_function_literal_; | 800 bool may_have_function_literal_; |
| 801 |
790 const BailoutId body_id_; | 802 const BailoutId body_id_; |
791 }; | 803 }; |
792 | 804 |
793 | 805 |
794 class ForStatement: public IterationStatement { | 806 class ForStatement: public IterationStatement { |
795 public: | 807 public: |
796 DECLARE_NODE_TYPE(ForStatement) | 808 DECLARE_NODE_TYPE(ForStatement) |
797 | 809 |
798 void Initialize(Statement* init, | 810 void Initialize(Statement* init, |
799 Expression* cond, | 811 Expression* cond, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
833 may_have_function_literal_(true), | 845 may_have_function_literal_(true), |
834 loop_variable_(NULL), | 846 loop_variable_(NULL), |
835 continue_id_(GetNextId(isolate)), | 847 continue_id_(GetNextId(isolate)), |
836 body_id_(GetNextId(isolate)) { | 848 body_id_(GetNextId(isolate)) { |
837 } | 849 } |
838 | 850 |
839 private: | 851 private: |
840 Statement* init_; | 852 Statement* init_; |
841 Expression* cond_; | 853 Expression* cond_; |
842 Statement* next_; | 854 Statement* next_; |
| 855 |
843 // True if there is a function literal subexpression in the condition. | 856 // True if there is a function literal subexpression in the condition. |
844 bool may_have_function_literal_; | 857 bool may_have_function_literal_; |
845 Variable* loop_variable_; | 858 Variable* loop_variable_; |
| 859 |
846 const BailoutId continue_id_; | 860 const BailoutId continue_id_; |
847 const BailoutId body_id_; | 861 const BailoutId body_id_; |
848 }; | 862 }; |
849 | 863 |
850 | 864 |
851 class ForInStatement: public IterationStatement { | 865 class ForInStatement: public IterationStatement { |
852 public: | 866 public: |
853 DECLARE_NODE_TYPE(ForInStatement) | 867 DECLARE_NODE_TYPE(ForInStatement) |
854 | 868 |
855 void Initialize(Expression* each, Expression* enumerable, Statement* body) { | 869 void Initialize(Expression* each, Expression* enumerable, Statement* body) { |
856 IterationStatement::Initialize(body); | 870 IterationStatement::Initialize(body); |
857 each_ = each; | 871 each_ = each; |
858 enumerable_ = enumerable; | 872 enumerable_ = enumerable; |
| 873 for_in_type_ = SLOW_FOR_IN; |
859 } | 874 } |
860 | 875 |
861 Expression* each() const { return each_; } | 876 Expression* each() const { return each_; } |
862 Expression* enumerable() const { return enumerable_; } | 877 Expression* enumerable() const { return enumerable_; } |
863 | 878 |
864 virtual BailoutId ContinueId() const { return EntryId(); } | 879 virtual BailoutId ContinueId() const { return EntryId(); } |
865 virtual BailoutId StackCheckId() const { return body_id_; } | 880 virtual BailoutId StackCheckId() const { return body_id_; } |
866 BailoutId BodyId() const { return body_id_; } | 881 BailoutId BodyId() const { return body_id_; } |
867 BailoutId PrepareId() const { return prepare_id_; } | 882 BailoutId PrepareId() const { return prepare_id_; } |
868 | 883 |
869 TypeFeedbackId ForInFeedbackId() const { return reuse(PrepareId()); } | 884 TypeFeedbackId ForInFeedbackId() const { return reuse(PrepareId()); } |
| 885 void RecordTypeFeedback(TypeFeedbackOracle* oracle); |
| 886 enum ForInType { FAST_FOR_IN, SLOW_FOR_IN }; |
| 887 ForInType for_in_type() const { return for_in_type_; } |
870 | 888 |
871 protected: | 889 protected: |
872 ForInStatement(Isolate* isolate, ZoneStringList* labels) | 890 ForInStatement(Isolate* isolate, ZoneStringList* labels) |
873 : IterationStatement(isolate, labels), | 891 : IterationStatement(isolate, labels), |
874 each_(NULL), | 892 each_(NULL), |
875 enumerable_(NULL), | 893 enumerable_(NULL), |
876 body_id_(GetNextId(isolate)), | 894 body_id_(GetNextId(isolate)), |
877 prepare_id_(GetNextId(isolate)) { | 895 prepare_id_(GetNextId(isolate)) { |
878 } | 896 } |
879 | 897 |
880 private: | 898 private: |
881 Expression* each_; | 899 Expression* each_; |
882 Expression* enumerable_; | 900 Expression* enumerable_; |
| 901 |
| 902 ForInType for_in_type_; |
| 903 |
883 const BailoutId body_id_; | 904 const BailoutId body_id_; |
884 const BailoutId prepare_id_; | 905 const BailoutId prepare_id_; |
885 }; | 906 }; |
886 | 907 |
887 | 908 |
888 class ExpressionStatement: public Statement { | 909 class ExpressionStatement: public Statement { |
889 public: | 910 public: |
890 DECLARE_NODE_TYPE(ExpressionStatement) | 911 DECLARE_NODE_TYPE(ExpressionStatement) |
891 | 912 |
892 void set_expression(Expression* e) { expression_ = e; } | 913 void set_expression(Expression* e) { expression_ = e; } |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1013 }; | 1034 }; |
1014 | 1035 |
1015 | 1036 |
1016 class SwitchStatement: public BreakableStatement { | 1037 class SwitchStatement: public BreakableStatement { |
1017 public: | 1038 public: |
1018 DECLARE_NODE_TYPE(SwitchStatement) | 1039 DECLARE_NODE_TYPE(SwitchStatement) |
1019 | 1040 |
1020 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) { | 1041 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) { |
1021 tag_ = tag; | 1042 tag_ = tag; |
1022 cases_ = cases; | 1043 cases_ = cases; |
| 1044 switch_type_ = UNKNOWN_SWITCH; |
1023 } | 1045 } |
1024 | 1046 |
1025 Expression* tag() const { return tag_; } | 1047 Expression* tag() const { return tag_; } |
1026 ZoneList<CaseClause*>* cases() const { return cases_; } | 1048 ZoneList<CaseClause*>* cases() const { return cases_; } |
1027 | 1049 |
| 1050 enum SwitchType { UNKNOWN_SWITCH, SMI_SWITCH, STRING_SWITCH, GENERIC_SWITCH }; |
| 1051 SwitchType switch_type() const { return switch_type_; } |
| 1052 void set_switch_type(SwitchType switch_type) { switch_type_ = switch_type; } |
| 1053 |
1028 protected: | 1054 protected: |
1029 SwitchStatement(Isolate* isolate, ZoneStringList* labels) | 1055 SwitchStatement(Isolate* isolate, ZoneStringList* labels) |
1030 : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS), | 1056 : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS), |
1031 tag_(NULL), | 1057 tag_(NULL), |
1032 cases_(NULL) { } | 1058 cases_(NULL) { } |
1033 | 1059 |
1034 private: | 1060 private: |
1035 Expression* tag_; | 1061 Expression* tag_; |
1036 ZoneList<CaseClause*>* cases_; | 1062 ZoneList<CaseClause*>* cases_; |
| 1063 SwitchType switch_type_; |
1037 }; | 1064 }; |
1038 | 1065 |
1039 | 1066 |
1040 // If-statements always have non-null references to their then- and | 1067 // If-statements always have non-null references to their then- and |
1041 // else-parts. When parsing if-statements with no explicit else-part, | 1068 // else-parts. When parsing if-statements with no explicit else-part, |
1042 // the parser implicitly creates an empty statement. Use the | 1069 // the parser implicitly creates an empty statement. Use the |
1043 // HasThenStatement() and HasElseStatement() functions to check if a | 1070 // HasThenStatement() and HasElseStatement() functions to check if a |
1044 // given if-statement has a then- or an else-part containing code. | 1071 // given if-statement has a then- or an else-part containing code. |
1045 class IfStatement: public Statement { | 1072 class IfStatement: public Statement { |
1046 public: | 1073 public: |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1272 is_simple_(is_simple), | 1299 is_simple_(is_simple), |
1273 depth_(depth) {} | 1300 depth_(depth) {} |
1274 | 1301 |
1275 private: | 1302 private: |
1276 int literal_index_; | 1303 int literal_index_; |
1277 bool is_simple_; | 1304 bool is_simple_; |
1278 int depth_; | 1305 int depth_; |
1279 }; | 1306 }; |
1280 | 1307 |
1281 | 1308 |
| 1309 // Property is used for passing information |
| 1310 // about an object literal's properties from the parser |
| 1311 // to the code generator. |
| 1312 class ObjectLiteralProperty: public ZoneObject { |
| 1313 public: |
| 1314 enum Kind { |
| 1315 CONSTANT, // Property with constant value (compile time). |
| 1316 COMPUTED, // Property with computed value (execution time). |
| 1317 MATERIALIZED_LITERAL, // Property value is a materialized literal. |
| 1318 GETTER, SETTER, // Property is an accessor function. |
| 1319 PROTOTYPE // Property is __proto__. |
| 1320 }; |
| 1321 |
| 1322 ObjectLiteralProperty(Literal* key, Expression* value, Isolate* isolate); |
| 1323 |
| 1324 Literal* key() { return key_; } |
| 1325 Expression* value() { return value_; } |
| 1326 Kind kind() { return kind_; } |
| 1327 |
| 1328 // Type feedback information. |
| 1329 void RecordTypeFeedback(TypeFeedbackOracle* oracle); |
| 1330 bool IsMonomorphic() { return !receiver_type_.is_null(); } |
| 1331 Handle<Map> GetReceiverType() { return receiver_type_; } |
| 1332 |
| 1333 bool IsCompileTimeValue(); |
| 1334 |
| 1335 void set_emit_store(bool emit_store); |
| 1336 bool emit_store(); |
| 1337 |
| 1338 protected: |
| 1339 template<class> friend class AstNodeFactory; |
| 1340 |
| 1341 ObjectLiteralProperty(bool is_getter, FunctionLiteral* value); |
| 1342 void set_key(Literal* key) { key_ = key; } |
| 1343 |
| 1344 private: |
| 1345 Literal* key_; |
| 1346 Expression* value_; |
| 1347 Kind kind_; |
| 1348 bool emit_store_; |
| 1349 Handle<Map> receiver_type_; |
| 1350 }; |
| 1351 |
| 1352 |
1282 // An object literal has a boilerplate object that is used | 1353 // An object literal has a boilerplate object that is used |
1283 // for minimizing the work when constructing it at runtime. | 1354 // for minimizing the work when constructing it at runtime. |
1284 class ObjectLiteral: public MaterializedLiteral { | 1355 class ObjectLiteral: public MaterializedLiteral { |
1285 public: | 1356 public: |
1286 // Property is used for passing information | 1357 typedef ObjectLiteralProperty Property; |
1287 // about an object literal's properties from the parser | |
1288 // to the code generator. | |
1289 class Property: public ZoneObject { | |
1290 public: | |
1291 enum Kind { | |
1292 CONSTANT, // Property with constant value (compile time). | |
1293 COMPUTED, // Property with computed value (execution time). | |
1294 MATERIALIZED_LITERAL, // Property value is a materialized literal. | |
1295 GETTER, SETTER, // Property is an accessor function. | |
1296 PROTOTYPE // Property is __proto__. | |
1297 }; | |
1298 | |
1299 Property(Literal* key, Expression* value, Isolate* isolate); | |
1300 | |
1301 Literal* key() { return key_; } | |
1302 Expression* value() { return value_; } | |
1303 Kind kind() { return kind_; } | |
1304 | |
1305 // Type feedback information. | |
1306 void RecordTypeFeedback(TypeFeedbackOracle* oracle); | |
1307 bool IsMonomorphic() { return !receiver_type_.is_null(); } | |
1308 Handle<Map> GetReceiverType() { return receiver_type_; } | |
1309 | |
1310 bool IsCompileTimeValue(); | |
1311 | |
1312 void set_emit_store(bool emit_store); | |
1313 bool emit_store(); | |
1314 | |
1315 protected: | |
1316 template<class> friend class AstNodeFactory; | |
1317 | |
1318 Property(bool is_getter, FunctionLiteral* value); | |
1319 void set_key(Literal* key) { key_ = key; } | |
1320 | |
1321 private: | |
1322 Literal* key_; | |
1323 Expression* value_; | |
1324 Kind kind_; | |
1325 bool emit_store_; | |
1326 Handle<Map> receiver_type_; | |
1327 }; | |
1328 | 1358 |
1329 DECLARE_NODE_TYPE(ObjectLiteral) | 1359 DECLARE_NODE_TYPE(ObjectLiteral) |
1330 | 1360 |
1331 Handle<FixedArray> constant_properties() const { | 1361 Handle<FixedArray> constant_properties() const { |
1332 return constant_properties_; | 1362 return constant_properties_; |
1333 } | 1363 } |
1334 ZoneList<Property*>* properties() const { return properties_; } | 1364 ZoneList<Property*>* properties() const { return properties_; } |
1335 bool fast_elements() const { return fast_elements_; } | 1365 bool fast_elements() const { return fast_elements_; } |
1336 bool may_store_doubles() const { return may_store_doubles_; } | 1366 bool may_store_doubles() const { return may_store_doubles_; } |
1337 bool has_function() const { return has_function_; } | 1367 bool has_function() const { return has_function_; } |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1580 // as the holder! | 1610 // as the holder! |
1581 Handle<JSObject> holder() { return holder_; } | 1611 Handle<JSObject> holder() { return holder_; } |
1582 | 1612 |
1583 Handle<JSGlobalPropertyCell> cell() { return cell_; } | 1613 Handle<JSGlobalPropertyCell> cell() { return cell_; } |
1584 | 1614 |
1585 bool ComputeTarget(Handle<Map> type, Handle<String> name); | 1615 bool ComputeTarget(Handle<Map> type, Handle<String> name); |
1586 bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup); | 1616 bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup); |
1587 | 1617 |
1588 BailoutId ReturnId() const { return return_id_; } | 1618 BailoutId ReturnId() const { return return_id_; } |
1589 | 1619 |
| 1620 // TODO(rossberg): this should really move somewhere else (and be merged with |
| 1621 // various similar methods in objets.cc), but for now... |
| 1622 static Handle<JSObject> GetPrototypeForPrimitiveCheck( |
| 1623 CheckType check, Isolate* isolate); |
| 1624 |
1590 #ifdef DEBUG | 1625 #ifdef DEBUG |
1591 // Used to assert that the FullCodeGenerator records the return site. | 1626 // Used to assert that the FullCodeGenerator records the return site. |
1592 bool return_is_recorded_; | 1627 bool return_is_recorded_; |
1593 #endif | 1628 #endif |
1594 | 1629 |
1595 protected: | 1630 protected: |
1596 Call(Isolate* isolate, | 1631 Call(Isolate* isolate, |
1597 Expression* expression, | 1632 Expression* expression, |
1598 ZoneList<Expression*>* arguments, | 1633 ZoneList<Expression*>* arguments, |
1599 int pos) | 1634 int pos) |
(...skipping 26 matching lines...) Expand all Loading... |
1626 DECLARE_NODE_TYPE(CallNew) | 1661 DECLARE_NODE_TYPE(CallNew) |
1627 | 1662 |
1628 Expression* expression() const { return expression_; } | 1663 Expression* expression() const { return expression_; } |
1629 ZoneList<Expression*>* arguments() const { return arguments_; } | 1664 ZoneList<Expression*>* arguments() const { return arguments_; } |
1630 virtual int position() const { return pos_; } | 1665 virtual int position() const { return pos_; } |
1631 | 1666 |
1632 // Type feedback information. | 1667 // Type feedback information. |
1633 TypeFeedbackId CallNewFeedbackId() const { return reuse(id()); } | 1668 TypeFeedbackId CallNewFeedbackId() const { return reuse(id()); } |
1634 void RecordTypeFeedback(TypeFeedbackOracle* oracle); | 1669 void RecordTypeFeedback(TypeFeedbackOracle* oracle); |
1635 virtual bool IsMonomorphic() { return is_monomorphic_; } | 1670 virtual bool IsMonomorphic() { return is_monomorphic_; } |
1636 Handle<JSFunction> target() { return target_; } | 1671 Handle<JSFunction> target() const { return target_; } |
| 1672 ElementsKind elements_kind() const { return elements_kind_; } |
| 1673 Handle<Smi> allocation_elements_kind() const { return alloc_elements_kind_; } |
1637 | 1674 |
1638 BailoutId ReturnId() const { return return_id_; } | 1675 BailoutId ReturnId() const { return return_id_; } |
1639 ElementsKind elements_kind() const { return elements_kind_; } | |
1640 | 1676 |
1641 protected: | 1677 protected: |
1642 CallNew(Isolate* isolate, | 1678 CallNew(Isolate* isolate, |
1643 Expression* expression, | 1679 Expression* expression, |
1644 ZoneList<Expression*>* arguments, | 1680 ZoneList<Expression*>* arguments, |
1645 int pos) | 1681 int pos) |
1646 : Expression(isolate), | 1682 : Expression(isolate), |
1647 expression_(expression), | 1683 expression_(expression), |
1648 arguments_(arguments), | 1684 arguments_(arguments), |
1649 pos_(pos), | 1685 pos_(pos), |
1650 is_monomorphic_(false), | 1686 is_monomorphic_(false), |
1651 return_id_(GetNextId(isolate)), | 1687 elements_kind_(GetInitialFastElementsKind()), |
1652 elements_kind_(GetInitialFastElementsKind()) { } | 1688 return_id_(GetNextId(isolate)) { } |
1653 | 1689 |
1654 private: | 1690 private: |
1655 Expression* expression_; | 1691 Expression* expression_; |
1656 ZoneList<Expression*>* arguments_; | 1692 ZoneList<Expression*>* arguments_; |
1657 int pos_; | 1693 int pos_; |
1658 | 1694 |
1659 bool is_monomorphic_; | 1695 bool is_monomorphic_; |
1660 Handle<JSFunction> target_; | 1696 Handle<JSFunction> target_; |
| 1697 ElementsKind elements_kind_; |
| 1698 Handle<Smi> alloc_elements_kind_; |
1661 | 1699 |
1662 const BailoutId return_id_; | 1700 const BailoutId return_id_; |
1663 ElementsKind elements_kind_; | |
1664 }; | 1701 }; |
1665 | 1702 |
1666 | 1703 |
1667 // The CallRuntime class does not represent any official JavaScript | 1704 // The CallRuntime class does not represent any official JavaScript |
1668 // language construct. Instead it is used to call a C or JS function | 1705 // language construct. Instead it is used to call a C or JS function |
1669 // with a set of arguments. This is used from the builtins that are | 1706 // with a set of arguments. This is used from the builtins that are |
1670 // implemented in JavaScript (see "v8natives.js"). | 1707 // implemented in JavaScript (see "v8natives.js"). |
1671 class CallRuntime: public Expression { | 1708 class CallRuntime: public Expression { |
1672 public: | 1709 public: |
1673 DECLARE_NODE_TYPE(CallRuntime) | 1710 DECLARE_NODE_TYPE(CallRuntime) |
(...skipping 29 matching lines...) Expand all Loading... |
1703 virtual bool ResultOverwriteAllowed(); | 1740 virtual bool ResultOverwriteAllowed(); |
1704 | 1741 |
1705 Token::Value op() const { return op_; } | 1742 Token::Value op() const { return op_; } |
1706 Expression* expression() const { return expression_; } | 1743 Expression* expression() const { return expression_; } |
1707 virtual int position() const { return pos_; } | 1744 virtual int position() const { return pos_; } |
1708 | 1745 |
1709 BailoutId MaterializeTrueId() { return materialize_true_id_; } | 1746 BailoutId MaterializeTrueId() { return materialize_true_id_; } |
1710 BailoutId MaterializeFalseId() { return materialize_false_id_; } | 1747 BailoutId MaterializeFalseId() { return materialize_false_id_; } |
1711 | 1748 |
1712 TypeFeedbackId UnaryOperationFeedbackId() const { return reuse(id()); } | 1749 TypeFeedbackId UnaryOperationFeedbackId() const { return reuse(id()); } |
| 1750 void RecordTypeFeedback(TypeFeedbackOracle* oracle); |
| 1751 TypeInfo type() const { return type_; } |
1713 | 1752 |
1714 protected: | 1753 protected: |
1715 UnaryOperation(Isolate* isolate, | 1754 UnaryOperation(Isolate* isolate, |
1716 Token::Value op, | 1755 Token::Value op, |
1717 Expression* expression, | 1756 Expression* expression, |
1718 int pos) | 1757 int pos) |
1719 : Expression(isolate), | 1758 : Expression(isolate), |
1720 op_(op), | 1759 op_(op), |
1721 expression_(expression), | 1760 expression_(expression), |
1722 pos_(pos), | 1761 pos_(pos), |
1723 materialize_true_id_(GetNextId(isolate)), | 1762 materialize_true_id_(GetNextId(isolate)), |
1724 materialize_false_id_(GetNextId(isolate)) { | 1763 materialize_false_id_(GetNextId(isolate)) { |
1725 ASSERT(Token::IsUnaryOp(op)); | 1764 ASSERT(Token::IsUnaryOp(op)); |
1726 } | 1765 } |
1727 | 1766 |
1728 private: | 1767 private: |
1729 Token::Value op_; | 1768 Token::Value op_; |
1730 Expression* expression_; | 1769 Expression* expression_; |
1731 int pos_; | 1770 int pos_; |
1732 | 1771 |
| 1772 TypeInfo type_; |
| 1773 |
1733 // For unary not (Token::NOT), the AST ids where true and false will | 1774 // For unary not (Token::NOT), the AST ids where true and false will |
1734 // actually be materialized, respectively. | 1775 // actually be materialized, respectively. |
1735 const BailoutId materialize_true_id_; | 1776 const BailoutId materialize_true_id_; |
1736 const BailoutId materialize_false_id_; | 1777 const BailoutId materialize_false_id_; |
1737 }; | 1778 }; |
1738 | 1779 |
1739 | 1780 |
1740 class BinaryOperation: public Expression { | 1781 class BinaryOperation: public Expression { |
1741 public: | 1782 public: |
1742 DECLARE_NODE_TYPE(BinaryOperation) | 1783 DECLARE_NODE_TYPE(BinaryOperation) |
1743 | 1784 |
1744 virtual bool ResultOverwriteAllowed(); | 1785 virtual bool ResultOverwriteAllowed(); |
1745 | 1786 |
1746 Token::Value op() const { return op_; } | 1787 Token::Value op() const { return op_; } |
1747 Expression* left() const { return left_; } | 1788 Expression* left() const { return left_; } |
1748 Expression* right() const { return right_; } | 1789 Expression* right() const { return right_; } |
1749 virtual int position() const { return pos_; } | 1790 virtual int position() const { return pos_; } |
1750 | 1791 |
1751 BailoutId RightId() const { return right_id_; } | 1792 BailoutId RightId() const { return right_id_; } |
1752 | 1793 |
1753 TypeFeedbackId BinaryOperationFeedbackId() const { return reuse(id()); } | 1794 TypeFeedbackId BinaryOperationFeedbackId() const { return reuse(id()); } |
| 1795 void RecordTypeFeedback(TypeFeedbackOracle* oracle); |
| 1796 TypeInfo left_type() const { return left_type_; } |
| 1797 TypeInfo right_type() const { return right_type_; } |
| 1798 TypeInfo result_type() const { return result_type_; } |
1754 | 1799 |
1755 protected: | 1800 protected: |
1756 BinaryOperation(Isolate* isolate, | 1801 BinaryOperation(Isolate* isolate, |
1757 Token::Value op, | 1802 Token::Value op, |
1758 Expression* left, | 1803 Expression* left, |
1759 Expression* right, | 1804 Expression* right, |
1760 int pos) | 1805 int pos) |
1761 : Expression(isolate), | 1806 : Expression(isolate), |
1762 op_(op), | 1807 op_(op), |
1763 left_(left), | 1808 left_(left), |
1764 right_(right), | 1809 right_(right), |
1765 pos_(pos), | 1810 pos_(pos), |
1766 right_id_(GetNextId(isolate)) { | 1811 right_id_(GetNextId(isolate)) { |
1767 ASSERT(Token::IsBinaryOp(op)); | 1812 ASSERT(Token::IsBinaryOp(op)); |
1768 } | 1813 } |
1769 | 1814 |
1770 private: | 1815 private: |
1771 Token::Value op_; | 1816 Token::Value op_; |
1772 Expression* left_; | 1817 Expression* left_; |
1773 Expression* right_; | 1818 Expression* right_; |
1774 int pos_; | 1819 int pos_; |
| 1820 |
| 1821 TypeInfo left_type_; |
| 1822 TypeInfo right_type_; |
| 1823 TypeInfo result_type_; |
| 1824 |
1775 // The short-circuit logical operations need an AST ID for their | 1825 // The short-circuit logical operations need an AST ID for their |
1776 // right-hand subexpression. | 1826 // right-hand subexpression. |
1777 const BailoutId right_id_; | 1827 const BailoutId right_id_; |
1778 }; | 1828 }; |
1779 | 1829 |
1780 | 1830 |
1781 class CountOperation: public Expression { | 1831 class CountOperation: public Expression { |
1782 public: | 1832 public: |
1783 DECLARE_NODE_TYPE(CountOperation) | 1833 DECLARE_NODE_TYPE(CountOperation) |
1784 | 1834 |
1785 bool is_prefix() const { return is_prefix_; } | 1835 bool is_prefix() const { return is_prefix_; } |
1786 bool is_postfix() const { return !is_prefix_; } | 1836 bool is_postfix() const { return !is_prefix_; } |
1787 | 1837 |
1788 Token::Value op() const { return op_; } | 1838 Token::Value op() const { return op_; } |
1789 Token::Value binary_op() { | 1839 Token::Value binary_op() { |
1790 return (op() == Token::INC) ? Token::ADD : Token::SUB; | 1840 return (op() == Token::INC) ? Token::ADD : Token::SUB; |
1791 } | 1841 } |
1792 | 1842 |
1793 Expression* expression() const { return expression_; } | 1843 Expression* expression() const { return expression_; } |
1794 virtual int position() const { return pos_; } | 1844 virtual int position() const { return pos_; } |
1795 | 1845 |
1796 virtual void MarkAsStatement() { is_prefix_ = true; } | 1846 virtual void MarkAsStatement() { is_prefix_ = true; } |
1797 | 1847 |
1798 void RecordTypeFeedback(TypeFeedbackOracle* oracle, Zone* znoe); | 1848 void RecordTypeFeedback(TypeFeedbackOracle* oracle, Zone* znoe); |
1799 virtual bool IsMonomorphic() { return is_monomorphic_; } | 1849 virtual bool IsMonomorphic() { return is_monomorphic_; } |
1800 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; } | 1850 virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; } |
1801 virtual KeyedAccessStoreMode GetStoreMode() { | 1851 virtual KeyedAccessStoreMode GetStoreMode() { |
1802 return store_mode_; | 1852 return store_mode_; |
1803 } | 1853 } |
| 1854 TypeInfo type() const { return type_; } |
1804 | 1855 |
1805 BailoutId AssignmentId() const { return assignment_id_; } | 1856 BailoutId AssignmentId() const { return assignment_id_; } |
1806 | 1857 |
1807 TypeFeedbackId CountBinOpFeedbackId() const { return count_id_; } | 1858 TypeFeedbackId CountBinOpFeedbackId() const { return count_id_; } |
1808 TypeFeedbackId CountStoreFeedbackId() const { return reuse(id()); } | 1859 TypeFeedbackId CountStoreFeedbackId() const { return reuse(id()); } |
1809 | 1860 |
1810 protected: | 1861 protected: |
1811 CountOperation(Isolate* isolate, | 1862 CountOperation(Isolate* isolate, |
1812 Token::Value op, | 1863 Token::Value op, |
1813 bool is_prefix, | 1864 bool is_prefix, |
1814 Expression* expr, | 1865 Expression* expr, |
1815 int pos) | 1866 int pos) |
1816 : Expression(isolate), | 1867 : Expression(isolate), |
1817 op_(op), | 1868 op_(op), |
1818 is_prefix_(is_prefix), | 1869 is_prefix_(is_prefix), |
1819 is_monomorphic_(false), | 1870 is_monomorphic_(false), |
1820 store_mode_(STANDARD_STORE), | 1871 store_mode_(STANDARD_STORE), |
1821 expression_(expr), | 1872 expression_(expr), |
1822 pos_(pos), | 1873 pos_(pos), |
1823 assignment_id_(GetNextId(isolate)), | 1874 assignment_id_(GetNextId(isolate)), |
1824 count_id_(GetNextId(isolate)) {} | 1875 count_id_(GetNextId(isolate)) {} |
1825 | 1876 |
1826 private: | 1877 private: |
1827 Token::Value op_; | 1878 Token::Value op_; |
1828 bool is_prefix_ : 1; | 1879 bool is_prefix_ : 1; |
1829 bool is_monomorphic_ : 1; | 1880 bool is_monomorphic_ : 1; |
1830 KeyedAccessStoreMode store_mode_ : 5; // Windows treats as signed, | 1881 KeyedAccessStoreMode store_mode_ : 5; // Windows treats as signed, |
1831 // must have extra bit. | 1882 // must have extra bit. |
| 1883 TypeInfo type_; |
| 1884 |
1832 Expression* expression_; | 1885 Expression* expression_; |
1833 int pos_; | 1886 int pos_; |
1834 const BailoutId assignment_id_; | 1887 const BailoutId assignment_id_; |
1835 const TypeFeedbackId count_id_; | 1888 const TypeFeedbackId count_id_; |
1836 SmallMapList receiver_types_; | 1889 SmallMapList receiver_types_; |
1837 }; | 1890 }; |
1838 | 1891 |
1839 | 1892 |
1840 class CompareOperation: public Expression { | 1893 class CompareOperation: public Expression { |
1841 public: | 1894 public: |
1842 DECLARE_NODE_TYPE(CompareOperation) | 1895 DECLARE_NODE_TYPE(CompareOperation) |
1843 | 1896 |
1844 Token::Value op() const { return op_; } | 1897 Token::Value op() const { return op_; } |
1845 Expression* left() const { return left_; } | 1898 Expression* left() const { return left_; } |
1846 Expression* right() const { return right_; } | 1899 Expression* right() const { return right_; } |
1847 virtual int position() const { return pos_; } | 1900 virtual int position() const { return pos_; } |
1848 | 1901 |
1849 // Type feedback information. | 1902 // Type feedback information. |
1850 TypeFeedbackId CompareOperationFeedbackId() const { return reuse(id()); } | 1903 TypeFeedbackId CompareOperationFeedbackId() const { return reuse(id()); } |
| 1904 void RecordTypeFeedback(TypeFeedbackOracle* oracle); |
| 1905 TypeInfo left_type() const { return left_type_; } |
| 1906 TypeInfo right_type() const { return right_type_; } |
| 1907 TypeInfo overall_type() const { return overall_type_; } |
| 1908 byte compare_nil_types() const { return compare_nil_types_; } |
| 1909 Handle<Map> map() const { return map_; } |
1851 | 1910 |
1852 // Match special cases. | 1911 // Match special cases. |
1853 bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check); | 1912 bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check); |
1854 bool IsLiteralCompareUndefined(Expression** expr); | 1913 bool IsLiteralCompareUndefined(Expression** expr); |
1855 bool IsLiteralCompareNull(Expression** expr); | 1914 bool IsLiteralCompareNull(Expression** expr); |
1856 | 1915 |
1857 protected: | 1916 protected: |
1858 CompareOperation(Isolate* isolate, | 1917 CompareOperation(Isolate* isolate, |
1859 Token::Value op, | 1918 Token::Value op, |
1860 Expression* left, | 1919 Expression* left, |
1861 Expression* right, | 1920 Expression* right, |
1862 int pos) | 1921 int pos) |
1863 : Expression(isolate), | 1922 : Expression(isolate), |
1864 op_(op), | 1923 op_(op), |
1865 left_(left), | 1924 left_(left), |
1866 right_(right), | 1925 right_(right), |
1867 pos_(pos) { | 1926 pos_(pos) { |
1868 ASSERT(Token::IsCompareOp(op)); | 1927 ASSERT(Token::IsCompareOp(op)); |
1869 } | 1928 } |
1870 | 1929 |
1871 private: | 1930 private: |
1872 Token::Value op_; | 1931 Token::Value op_; |
1873 Expression* left_; | 1932 Expression* left_; |
1874 Expression* right_; | 1933 Expression* right_; |
1875 int pos_; | 1934 int pos_; |
| 1935 |
| 1936 TypeInfo left_type_; |
| 1937 TypeInfo right_type_; |
| 1938 TypeInfo overall_type_; |
| 1939 byte compare_nil_types_; |
| 1940 Handle<Map> map_; |
1876 }; | 1941 }; |
1877 | 1942 |
1878 | 1943 |
1879 class Conditional: public Expression { | 1944 class Conditional: public Expression { |
1880 public: | 1945 public: |
1881 DECLARE_NODE_TYPE(Conditional) | 1946 DECLARE_NODE_TYPE(Conditional) |
1882 | 1947 |
1883 Expression* condition() const { return condition_; } | 1948 Expression* condition() const { return condition_; } |
1884 Expression* then_expression() const { return then_expression_; } | 1949 Expression* then_expression() const { return then_expression_; } |
1885 Expression* else_expression() const { return else_expression_; } | 1950 Expression* else_expression() const { return else_expression_; } |
(...skipping 1163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3049 private: | 3114 private: |
3050 Isolate* isolate_; | 3115 Isolate* isolate_; |
3051 Zone* zone_; | 3116 Zone* zone_; |
3052 Visitor visitor_; | 3117 Visitor visitor_; |
3053 }; | 3118 }; |
3054 | 3119 |
3055 | 3120 |
3056 } } // namespace v8::internal | 3121 } } // namespace v8::internal |
3057 | 3122 |
3058 #endif // V8_AST_H_ | 3123 #endif // V8_AST_H_ |
OLD | NEW |