| Index: src/ast.h
|
| diff --git a/src/ast.h b/src/ast.h
|
| index c2d9412a90b227e59885504ed79effd08ad8dcdc..0f10fd6520542a19e08c5e76c448a80a3fe89f5a 100644
|
| --- a/src/ast.h
|
| +++ b/src/ast.h
|
| @@ -167,7 +167,6 @@ class AstNode: public ZoneObject {
|
| // True if the node is simple enough for us to inline calls containing it.
|
| virtual bool IsInlineable() const = 0;
|
|
|
| - static int Count() { return Isolate::Current()->ast_node_count(); }
|
| static void ResetIds() { Isolate::Current()->set_ast_node_id(0); }
|
|
|
| protected:
|
| @@ -181,6 +180,11 @@ class AstNode: public ZoneObject {
|
| return tmp;
|
| }
|
|
|
| + // See comment of FunctionLiteral::is_primitive for definition of "primitive".
|
| + void MarkFunctionAsNonPrimitive(Isolate* isolate) {
|
| + isolate->set_is_function_primitive(false);
|
| + }
|
| +
|
| private:
|
| // Hidden to prevent accidental usage. It would have to load the
|
| // current zone from the TLS.
|
| @@ -441,6 +445,8 @@ class IterationStatement: public BreakableStatement {
|
| : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
|
| body_(NULL),
|
| osr_entry_id_(GetNextId(isolate)) {
|
| + // Making the function non-primitive seems to give better performance.
|
| + MarkFunctionAsNonPrimitive(isolate);
|
| }
|
|
|
| void Initialize(Statement* body) {
|
| @@ -686,8 +692,12 @@ class ReturnStatement: public Statement {
|
|
|
| class WithStatement: public Statement {
|
| public:
|
| - WithStatement(Expression* expression, Statement* statement)
|
| - : expression_(expression), statement_(statement) { }
|
| + WithStatement(Isolate* isolate, Expression* expression, Statement* statement)
|
| + : expression_(expression), statement_(statement) {
|
| + // A "with" statement is not inlineable,
|
| + // so a function containing it is not primitive.
|
| + MarkFunctionAsNonPrimitive(isolate);
|
| + }
|
|
|
| DECLARE_NODE_TYPE(WithStatement)
|
|
|
| @@ -754,6 +764,9 @@ class SwitchStatement: public BreakableStatement {
|
| : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
|
| tag_(NULL),
|
| cases_(NULL) {
|
| + // A "switch" statement is not inlineable,
|
| + // so a function containing it is not primitive.
|
| + MarkFunctionAsNonPrimitive(isolate);
|
| }
|
|
|
|
|
| @@ -790,8 +803,7 @@ class IfStatement: public Statement {
|
| else_statement_(else_statement),
|
| if_id_(GetNextId(isolate)),
|
| then_id_(GetNextId(isolate)),
|
| - else_id_(GetNextId(isolate)) {
|
| - }
|
| + else_id_(GetNextId(isolate)) { }
|
|
|
| DECLARE_NODE_TYPE(IfStatement)
|
|
|
| @@ -843,10 +855,13 @@ class TargetCollector: public AstNode {
|
|
|
| class TryStatement: public Statement {
|
| public:
|
| - explicit TryStatement(int index, Block* try_block)
|
| + explicit TryStatement(Isolate* isolate, int index, Block* try_block)
|
| : index_(index),
|
| try_block_(try_block),
|
| escaping_targets_(NULL) {
|
| + // A "try" statement is not inlineable,
|
| + // so a function containing it is not primitive.
|
| + MarkFunctionAsNonPrimitive(isolate);
|
| }
|
|
|
| void set_escaping_targets(ZoneList<Label*>* targets) {
|
| @@ -869,16 +884,16 @@ class TryStatement: public Statement {
|
|
|
| class TryCatchStatement: public TryStatement {
|
| public:
|
| - TryCatchStatement(int index,
|
| + TryCatchStatement(Isolate* isolate,
|
| + int index,
|
| Block* try_block,
|
| Scope* scope,
|
| Variable* variable,
|
| Block* catch_block)
|
| - : TryStatement(index, try_block),
|
| + : TryStatement(isolate, index, try_block),
|
| scope_(scope),
|
| variable_(variable),
|
| - catch_block_(catch_block) {
|
| - }
|
| + catch_block_(catch_block) { }
|
|
|
| DECLARE_NODE_TYPE(TryCatchStatement)
|
|
|
| @@ -896,8 +911,11 @@ class TryCatchStatement: public TryStatement {
|
|
|
| class TryFinallyStatement: public TryStatement {
|
| public:
|
| - TryFinallyStatement(int index, Block* try_block, Block* finally_block)
|
| - : TryStatement(index, try_block),
|
| + TryFinallyStatement(Isolate* isolate,
|
| + int index,
|
| + Block* try_block,
|
| + Block* finally_block)
|
| + : TryStatement(isolate, index, try_block),
|
| finally_block_(finally_block) { }
|
|
|
| DECLARE_NODE_TYPE(TryFinallyStatement)
|
| @@ -985,7 +1003,11 @@ class MaterializedLiteral: public Expression {
|
| : Expression(isolate),
|
| literal_index_(literal_index),
|
| is_simple_(is_simple),
|
| - depth_(depth) {}
|
| + depth_(depth) {
|
| + // A materialized literal is not inlineable,
|
| + // so a function containing it is not primitive.
|
| + MarkFunctionAsNonPrimitive(isolate);
|
| + }
|
|
|
| virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
|
|
|
| @@ -1053,7 +1075,7 @@ class ObjectLiteral: public MaterializedLiteral {
|
| constant_properties_(constant_properties),
|
| properties_(properties),
|
| fast_elements_(fast_elements),
|
| - has_function_(has_function) {}
|
| + has_function_(has_function) { }
|
|
|
| DECLARE_NODE_TYPE(ObjectLiteral)
|
|
|
| @@ -1242,6 +1264,8 @@ class Call: public Expression {
|
| is_monomorphic_(false),
|
| check_type_(RECEIVER_MAP_CHECK),
|
| return_id_(GetNextId(isolate)) {
|
| + // Making the function non-primitive seems to give better performance.
|
| + MarkFunctionAsNonPrimitive(isolate);
|
| }
|
|
|
| DECLARE_NODE_TYPE(Call)
|
| @@ -1297,7 +1321,10 @@ class CallNew: public Expression {
|
| : Expression(isolate),
|
| expression_(expression),
|
| arguments_(arguments),
|
| - pos_(pos) { }
|
| + pos_(pos) {
|
| + // Making the function non-primitive seems to give better performance.
|
| + MarkFunctionAsNonPrimitive(isolate);
|
| + }
|
|
|
| DECLARE_NODE_TYPE(CallNew)
|
|
|
| @@ -1327,7 +1354,10 @@ class CallRuntime: public Expression {
|
| : Expression(isolate),
|
| name_(name),
|
| function_(function),
|
| - arguments_(arguments) { }
|
| + arguments_(arguments) {
|
| + // Making the function non-primitive seems to give better performance.
|
| + MarkFunctionAsNonPrimitive(isolate);
|
| + }
|
|
|
| DECLARE_NODE_TYPE(CallRuntime)
|
|
|
| @@ -1665,7 +1695,9 @@ class FunctionLiteral: public Expression {
|
| Handle<FixedArray> this_property_assignments,
|
| int parameter_count,
|
| Type type,
|
| - bool has_duplicate_parameters)
|
| + bool has_duplicate_parameters,
|
| + int ast_node_count,
|
| + bool is_primitive)
|
| : Expression(isolate),
|
| name_(name),
|
| scope_(scope),
|
| @@ -1676,7 +1708,9 @@ class FunctionLiteral: public Expression {
|
| expected_property_count_(expected_property_count),
|
| handler_count_(handler_count),
|
| parameter_count_(parameter_count),
|
| - function_token_position_(RelocInfo::kNoPosition) {
|
| + function_token_position_(RelocInfo::kNoPosition),
|
| + ast_node_count_(ast_node_count),
|
| + is_primitive_(is_primitive) {
|
| bitfield_ =
|
| HasOnlySimpleThisPropertyAssignments::encode(
|
| has_only_simple_this_property_assignments) |
|
| @@ -1684,6 +1718,9 @@ class FunctionLiteral: public Expression {
|
| IsAnonymous::encode(type == ANONYMOUS_EXPRESSION) |
|
| Pretenure::encode(false) |
|
| HasDuplicateParameters::encode(has_duplicate_parameters);
|
| + // A function literal is not inlineable,
|
| + // so a function containing it is not primitive.
|
| + MarkFunctionAsNonPrimitive(isolate);
|
| }
|
|
|
| DECLARE_NODE_TYPE(FunctionLiteral)
|
| @@ -1731,6 +1768,21 @@ class FunctionLiteral: public Expression {
|
| return HasDuplicateParameters::decode(bitfield_);
|
| }
|
|
|
| + // Returns the AST node count in the function if the function was parsed
|
| + // eagerly, otherwise returns 0.
|
| + int ast_node_count() {
|
| + return ast_node_count_;
|
| + }
|
| +
|
| + // Returns whether the function is primitive or not if the function was parsed
|
| + // eagerly, otherwise returns false.
|
| + // A function is primitive if it is inlinable and contains only
|
| + // simple statements: expression statement, assignment statement,
|
| + // "if" statement, "return" statement.
|
| + bool is_primitive() {
|
| + return is_primitive_;
|
| + }
|
| +
|
| private:
|
| Handle<String> name_;
|
| Scope* scope_;
|
| @@ -1744,6 +1796,9 @@ class FunctionLiteral: public Expression {
|
| int parameter_count_;
|
| int function_token_position_;
|
|
|
| + int ast_node_count_;
|
| + bool is_primitive_;
|
| +
|
| unsigned bitfield_;
|
| class HasOnlySimpleThisPropertyAssignments: public BitField<bool, 0, 1> {};
|
| class IsExpression: public BitField<bool, 1, 1> {};
|
| @@ -1758,7 +1813,9 @@ class SharedFunctionInfoLiteral: public Expression {
|
| SharedFunctionInfoLiteral(
|
| Isolate* isolate,
|
| Handle<SharedFunctionInfo> shared_function_info)
|
| - : Expression(isolate), shared_function_info_(shared_function_info) { }
|
| + : Expression(isolate), shared_function_info_(shared_function_info) {
|
| + MarkFunctionAsNonPrimitive(isolate);
|
| + }
|
|
|
| DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)
|
|
|
| @@ -1774,7 +1831,7 @@ class SharedFunctionInfoLiteral: public Expression {
|
|
|
| class ThisFunction: public Expression {
|
| public:
|
| - explicit ThisFunction(Isolate* isolate) : Expression(isolate) {}
|
| + explicit ThisFunction(Isolate* isolate) : Expression(isolate) { }
|
| DECLARE_NODE_TYPE(ThisFunction)
|
| virtual bool IsInlineable() const;
|
| };
|
|
|