Index: src/ast.h |
diff --git a/src/ast.h b/src/ast.h |
index 9ffb00db0de7f169e5266ead4d717808f362c716..edc23e95451d523674d46c4d20b8de1e30768114 100644 |
--- a/src/ast.h |
+++ b/src/ast.h |
@@ -39,6 +39,7 @@ |
#include "small-pointer-list.h" |
#include "smart-pointers.h" |
#include "token.h" |
+#include "type-info.h" |
#include "utils.h" |
#include "variables.h" |
#include "interface.h" |
@@ -370,6 +371,10 @@ class Expression: public AstNode { |
return STANDARD_STORE; |
} |
+ // TODO(rossberg): this should move to its own AST node eventually. |
+ void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle); |
+ byte to_boolean_types() const { return to_boolean_types_; } |
+ |
BailoutId id() const { return id_; } |
TypeFeedbackId test_id() const { return test_id_; } |
@@ -379,6 +384,8 @@ class Expression: public AstNode { |
test_id_(GetNextId(isolate)) {} |
private: |
+ byte to_boolean_types_; |
+ |
const BailoutId id_; |
const TypeFeedbackId test_id_; |
}; |
@@ -713,6 +720,7 @@ class IterationStatement: public BreakableStatement { |
private: |
Statement* body_; |
Label continue_target_; |
+ |
const BailoutId osr_entry_id_; |
}; |
@@ -748,7 +756,9 @@ class DoWhileStatement: public IterationStatement { |
private: |
Expression* cond_; |
+ |
int condition_position_; |
+ |
const BailoutId continue_id_; |
const BailoutId back_edge_id_; |
}; |
@@ -785,8 +795,10 @@ class WhileStatement: public IterationStatement { |
private: |
Expression* cond_; |
+ |
// True if there is a function literal subexpression in the condition. |
bool may_have_function_literal_; |
+ |
const BailoutId body_id_; |
}; |
@@ -840,9 +852,11 @@ class ForStatement: public IterationStatement { |
Statement* init_; |
Expression* cond_; |
Statement* next_; |
+ |
// True if there is a function literal subexpression in the condition. |
bool may_have_function_literal_; |
Variable* loop_variable_; |
+ |
const BailoutId continue_id_; |
const BailoutId body_id_; |
}; |
@@ -856,6 +870,7 @@ class ForInStatement: public IterationStatement { |
IterationStatement::Initialize(body); |
each_ = each; |
enumerable_ = enumerable; |
+ for_in_type_ = SLOW_FOR_IN; |
} |
Expression* each() const { return each_; } |
@@ -867,6 +882,9 @@ class ForInStatement: public IterationStatement { |
BailoutId PrepareId() const { return prepare_id_; } |
TypeFeedbackId ForInFeedbackId() const { return reuse(PrepareId()); } |
+ void RecordTypeFeedback(TypeFeedbackOracle* oracle); |
+ enum ForInType { FAST_FOR_IN, SLOW_FOR_IN }; |
+ ForInType for_in_type() const { return for_in_type_; } |
protected: |
ForInStatement(Isolate* isolate, ZoneStringList* labels) |
@@ -880,6 +898,9 @@ class ForInStatement: public IterationStatement { |
private: |
Expression* each_; |
Expression* enumerable_; |
+ |
+ ForInType for_in_type_; |
+ |
const BailoutId body_id_; |
const BailoutId prepare_id_; |
}; |
@@ -1020,11 +1041,16 @@ class SwitchStatement: public BreakableStatement { |
void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) { |
tag_ = tag; |
cases_ = cases; |
+ switch_type_ = UNKNOWN_SWITCH; |
} |
Expression* tag() const { return tag_; } |
ZoneList<CaseClause*>* cases() const { return cases_; } |
+ enum SwitchType { UNKNOWN_SWITCH, SMI_SWITCH, STRING_SWITCH, GENERIC_SWITCH }; |
+ SwitchType switch_type() const { return switch_type_; } |
+ void set_switch_type(SwitchType switch_type) { switch_type_ = switch_type; } |
+ |
protected: |
SwitchStatement(Isolate* isolate, ZoneStringList* labels) |
: BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS), |
@@ -1034,6 +1060,7 @@ class SwitchStatement: public BreakableStatement { |
private: |
Expression* tag_; |
ZoneList<CaseClause*>* cases_; |
+ SwitchType switch_type_; |
}; |
@@ -1279,52 +1306,55 @@ class MaterializedLiteral: public Expression { |
}; |
+// Property is used for passing information |
+// about an object literal's properties from the parser |
+// to the code generator. |
+class ObjectLiteralProperty: public ZoneObject { |
+ public: |
+ enum Kind { |
+ CONSTANT, // Property with constant value (compile time). |
+ COMPUTED, // Property with computed value (execution time). |
+ MATERIALIZED_LITERAL, // Property value is a materialized literal. |
+ GETTER, SETTER, // Property is an accessor function. |
+ PROTOTYPE // Property is __proto__. |
+ }; |
+ |
+ ObjectLiteralProperty(Literal* key, Expression* value, Isolate* isolate); |
+ |
+ Literal* key() { return key_; } |
+ Expression* value() { return value_; } |
+ Kind kind() { return kind_; } |
+ |
+ // Type feedback information. |
+ void RecordTypeFeedback(TypeFeedbackOracle* oracle); |
+ bool IsMonomorphic() { return !receiver_type_.is_null(); } |
+ Handle<Map> GetReceiverType() { return receiver_type_; } |
+ |
+ bool IsCompileTimeValue(); |
+ |
+ void set_emit_store(bool emit_store); |
+ bool emit_store(); |
+ |
+ protected: |
+ template<class> friend class AstNodeFactory; |
+ |
+ ObjectLiteralProperty(bool is_getter, FunctionLiteral* value); |
+ void set_key(Literal* key) { key_ = key; } |
+ |
+ private: |
+ Literal* key_; |
+ Expression* value_; |
+ Kind kind_; |
+ bool emit_store_; |
+ Handle<Map> receiver_type_; |
+}; |
+ |
+ |
// An object literal has a boilerplate object that is used |
// for minimizing the work when constructing it at runtime. |
class ObjectLiteral: public MaterializedLiteral { |
public: |
- // Property is used for passing information |
- // about an object literal's properties from the parser |
- // to the code generator. |
- class Property: public ZoneObject { |
- public: |
- enum Kind { |
- CONSTANT, // Property with constant value (compile time). |
- COMPUTED, // Property with computed value (execution time). |
- MATERIALIZED_LITERAL, // Property value is a materialized literal. |
- GETTER, SETTER, // Property is an accessor function. |
- PROTOTYPE // Property is __proto__. |
- }; |
- |
- Property(Literal* key, Expression* value, Isolate* isolate); |
- |
- Literal* key() { return key_; } |
- Expression* value() { return value_; } |
- Kind kind() { return kind_; } |
- |
- // Type feedback information. |
- void RecordTypeFeedback(TypeFeedbackOracle* oracle); |
- bool IsMonomorphic() { return !receiver_type_.is_null(); } |
- Handle<Map> GetReceiverType() { return receiver_type_; } |
- |
- bool IsCompileTimeValue(); |
- |
- void set_emit_store(bool emit_store); |
- bool emit_store(); |
- |
- protected: |
- template<class> friend class AstNodeFactory; |
- |
- Property(bool is_getter, FunctionLiteral* value); |
- void set_key(Literal* key) { key_ = key; } |
- |
- private: |
- Literal* key_; |
- Expression* value_; |
- Kind kind_; |
- bool emit_store_; |
- Handle<Map> receiver_type_; |
- }; |
+ typedef ObjectLiteralProperty Property; |
DECLARE_NODE_TYPE(ObjectLiteral) |
@@ -1587,6 +1617,11 @@ class Call: public Expression { |
BailoutId ReturnId() const { return return_id_; } |
+ // TODO(rossberg): this should really move somewhere else (and be merged with |
+ // various similar methods in objets.cc), but for now... |
+ static Handle<JSObject> GetPrototypeForPrimitiveCheck( |
+ CheckType check, Isolate* isolate); |
+ |
#ifdef DEBUG |
// Used to assert that the FullCodeGenerator records the return site. |
bool return_is_recorded_; |
@@ -1633,10 +1668,11 @@ class CallNew: public Expression { |
TypeFeedbackId CallNewFeedbackId() const { return reuse(id()); } |
void RecordTypeFeedback(TypeFeedbackOracle* oracle); |
virtual bool IsMonomorphic() { return is_monomorphic_; } |
- Handle<JSFunction> target() { return target_; } |
+ Handle<JSFunction> target() const { return target_; } |
+ ElementsKind elements_kind() const { return elements_kind_; } |
+ Handle<Smi> allocation_elements_kind() const { return alloc_elements_kind_; } |
BailoutId ReturnId() const { return return_id_; } |
- ElementsKind elements_kind() const { return elements_kind_; } |
protected: |
CallNew(Isolate* isolate, |
@@ -1648,8 +1684,8 @@ class CallNew: public Expression { |
arguments_(arguments), |
pos_(pos), |
is_monomorphic_(false), |
- return_id_(GetNextId(isolate)), |
- elements_kind_(GetInitialFastElementsKind()) { } |
+ elements_kind_(GetInitialFastElementsKind()), |
+ return_id_(GetNextId(isolate)) { } |
private: |
Expression* expression_; |
@@ -1658,9 +1694,10 @@ class CallNew: public Expression { |
bool is_monomorphic_; |
Handle<JSFunction> target_; |
+ ElementsKind elements_kind_; |
+ Handle<Smi> alloc_elements_kind_; |
const BailoutId return_id_; |
- ElementsKind elements_kind_; |
}; |
@@ -1710,6 +1747,8 @@ class UnaryOperation: public Expression { |
BailoutId MaterializeFalseId() { return materialize_false_id_; } |
TypeFeedbackId UnaryOperationFeedbackId() const { return reuse(id()); } |
+ void RecordTypeFeedback(TypeFeedbackOracle* oracle); |
+ TypeInfo type() const { return type_; } |
protected: |
UnaryOperation(Isolate* isolate, |
@@ -1730,6 +1769,8 @@ class UnaryOperation: public Expression { |
Expression* expression_; |
int pos_; |
+ TypeInfo type_; |
+ |
// For unary not (Token::NOT), the AST ids where true and false will |
// actually be materialized, respectively. |
const BailoutId materialize_true_id_; |
@@ -1751,6 +1792,10 @@ class BinaryOperation: public Expression { |
BailoutId RightId() const { return right_id_; } |
TypeFeedbackId BinaryOperationFeedbackId() const { return reuse(id()); } |
+ void RecordTypeFeedback(TypeFeedbackOracle* oracle); |
+ TypeInfo left_type() const { return left_type_; } |
+ TypeInfo right_type() const { return right_type_; } |
+ TypeInfo result_type() const { return result_type_; } |
protected: |
BinaryOperation(Isolate* isolate, |
@@ -1772,6 +1817,11 @@ class BinaryOperation: public Expression { |
Expression* left_; |
Expression* right_; |
int pos_; |
+ |
+ TypeInfo left_type_; |
+ TypeInfo right_type_; |
+ TypeInfo result_type_; |
+ |
// The short-circuit logical operations need an AST ID for their |
// right-hand subexpression. |
const BailoutId right_id_; |
@@ -1801,6 +1851,7 @@ class CountOperation: public Expression { |
virtual KeyedAccessStoreMode GetStoreMode() { |
return store_mode_; |
} |
+ TypeInfo type() const { return type_; } |
BailoutId AssignmentId() const { return assignment_id_; } |
@@ -1829,6 +1880,8 @@ class CountOperation: public Expression { |
bool is_monomorphic_ : 1; |
KeyedAccessStoreMode store_mode_ : 5; // Windows treats as signed, |
// must have extra bit. |
+ TypeInfo type_; |
+ |
Expression* expression_; |
int pos_; |
const BailoutId assignment_id_; |
@@ -1848,6 +1901,12 @@ class CompareOperation: public Expression { |
// Type feedback information. |
TypeFeedbackId CompareOperationFeedbackId() const { return reuse(id()); } |
+ void RecordTypeFeedback(TypeFeedbackOracle* oracle); |
+ TypeInfo left_type() const { return left_type_; } |
+ TypeInfo right_type() const { return right_type_; } |
+ TypeInfo overall_type() const { return overall_type_; } |
+ byte compare_nil_types() const { return compare_nil_types_; } |
+ Handle<Map> map() const { return map_; } |
// Match special cases. |
bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check); |
@@ -1873,6 +1932,12 @@ class CompareOperation: public Expression { |
Expression* left_; |
Expression* right_; |
int pos_; |
+ |
+ TypeInfo left_type_; |
+ TypeInfo right_type_; |
+ TypeInfo overall_type_; |
+ byte compare_nil_types_; |
+ Handle<Map> map_; |
}; |