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

Side by Side Diff: src/hydrogen.h

Issue 9304001: Implement inlining of constructor calls. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed moar comments by Vyacheslav Egorov. Created 8 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « src/heap.h ('k') | src/hydrogen.cc » ('j') | 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 // 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 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 SetOncePointer<HConstant> constant_hole_; 330 SetOncePointer<HConstant> constant_hole_;
331 SetOncePointer<HArgumentsObject> arguments_object_; 331 SetOncePointer<HArgumentsObject> arguments_object_;
332 332
333 DISALLOW_COPY_AND_ASSIGN(HGraph); 333 DISALLOW_COPY_AND_ASSIGN(HGraph);
334 }; 334 };
335 335
336 336
337 Zone* HBasicBlock::zone() { return graph_->zone(); } 337 Zone* HBasicBlock::zone() { return graph_->zone(); }
338 338
339 339
340 // Type of stack frame an environment might refer to.
341 enum FrameType { JS_FUNCTION, JS_CONSTRUCT, ARGUMENTS_ADAPTOR };
342
343
340 class HEnvironment: public ZoneObject { 344 class HEnvironment: public ZoneObject {
341 public: 345 public:
342 HEnvironment(HEnvironment* outer, 346 HEnvironment(HEnvironment* outer,
343 Scope* scope, 347 Scope* scope,
344 Handle<JSFunction> closure); 348 Handle<JSFunction> closure);
345 349
346 bool is_arguments_adaptor() const {
347 return arguments_adaptor_;
348 }
349
350 HEnvironment* DiscardInlined(bool drop_extra) { 350 HEnvironment* DiscardInlined(bool drop_extra) {
351 HEnvironment* outer = outer_->is_arguments_adaptor() ? 351 HEnvironment* outer = outer_;
352 outer_->outer_ : outer_; 352 while (outer->frame_type() != JS_FUNCTION) outer = outer->outer_;
353 if (drop_extra) outer->Drop(1); 353 if (drop_extra) outer->Drop(1);
354 return outer; 354 return outer;
355 } 355 }
356 356
357 // Simple accessors. 357 // Simple accessors.
358 Handle<JSFunction> closure() const { return closure_; } 358 Handle<JSFunction> closure() const { return closure_; }
359 const ZoneList<HValue*>* values() const { return &values_; } 359 const ZoneList<HValue*>* values() const { return &values_; }
360 const ZoneList<int>* assigned_variables() const { 360 const ZoneList<int>* assigned_variables() const {
361 return &assigned_variables_; 361 return &assigned_variables_;
362 } 362 }
363 FrameType frame_type() const { return frame_type_; }
363 int parameter_count() const { return parameter_count_; } 364 int parameter_count() const { return parameter_count_; }
364 int specials_count() const { return specials_count_; } 365 int specials_count() const { return specials_count_; }
365 int local_count() const { return local_count_; } 366 int local_count() const { return local_count_; }
366 HEnvironment* outer() const { return outer_; } 367 HEnvironment* outer() const { return outer_; }
367 int pop_count() const { return pop_count_; } 368 int pop_count() const { return pop_count_; }
368 int push_count() const { return push_count_; } 369 int push_count() const { return push_count_; }
369 370
370 int ast_id() const { return ast_id_; } 371 int ast_id() const { return ast_id_; }
371 void set_ast_id(int id) { ast_id_ = id; } 372 void set_ast_id(int id) { ast_id_ = id; }
372 373
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 HEnvironment* CopyWithoutHistory() const; 435 HEnvironment* CopyWithoutHistory() const;
435 HEnvironment* CopyAsLoopHeader(HBasicBlock* block) const; 436 HEnvironment* CopyAsLoopHeader(HBasicBlock* block) const;
436 437
437 // Create an "inlined version" of this environment, where the original 438 // Create an "inlined version" of this environment, where the original
438 // environment is the outer environment but the top expression stack 439 // environment is the outer environment but the top expression stack
439 // elements are moved to an inner environment as parameters. 440 // elements are moved to an inner environment as parameters.
440 HEnvironment* CopyForInlining(Handle<JSFunction> target, 441 HEnvironment* CopyForInlining(Handle<JSFunction> target,
441 int arguments, 442 int arguments,
442 FunctionLiteral* function, 443 FunctionLiteral* function,
443 HConstant* undefined, 444 HConstant* undefined,
444 CallKind call_kind) const; 445 CallKind call_kind,
446 bool is_construct) const;
445 447
446 void AddIncomingEdge(HBasicBlock* block, HEnvironment* other); 448 void AddIncomingEdge(HBasicBlock* block, HEnvironment* other);
447 449
448 void ClearHistory() { 450 void ClearHistory() {
449 pop_count_ = 0; 451 pop_count_ = 0;
450 push_count_ = 0; 452 push_count_ = 0;
451 assigned_variables_.Rewind(0); 453 assigned_variables_.Rewind(0);
452 } 454 }
453 455
454 void SetValueAt(int index, HValue* value) { 456 void SetValueAt(int index, HValue* value) {
455 ASSERT(index < length()); 457 ASSERT(index < length());
456 values_[index] = value; 458 values_[index] = value;
457 } 459 }
458 460
459 void PrintTo(StringStream* stream); 461 void PrintTo(StringStream* stream);
460 void PrintToStd(); 462 void PrintToStd();
461 463
462 private: 464 private:
463 explicit HEnvironment(const HEnvironment* other); 465 explicit HEnvironment(const HEnvironment* other);
464 466
465 // Create an argument adaptor environment. 467 HEnvironment(HEnvironment* outer,
466 HEnvironment(HEnvironment* outer, Handle<JSFunction> closure, int arguments); 468 Handle<JSFunction> closure,
469 FrameType frame_type,
470 int arguments);
467 471
472 // Create an artificial stub environment (e.g. for argument adaptor or
473 // constructor stub).
474 HEnvironment* CreateStubEnvironment(HEnvironment* outer,
475 Handle<JSFunction> target,
476 FrameType frame_type,
477 int arguments) const;
468 478
469 // True if index is included in the expression stack part of the environment. 479 // True if index is included in the expression stack part of the environment.
470 bool HasExpressionAt(int index) const; 480 bool HasExpressionAt(int index) const;
471 481
472 void Initialize(int parameter_count, int local_count, int stack_height); 482 void Initialize(int parameter_count, int local_count, int stack_height);
473 void Initialize(const HEnvironment* other); 483 void Initialize(const HEnvironment* other);
474 484
475 // Map a variable to an environment index. Parameter indices are shifted 485 // Map a variable to an environment index. Parameter indices are shifted
476 // by 1 (receiver is parameter index -1 but environment index 0). 486 // by 1 (receiver is parameter index -1 but environment index 0).
477 // Stack-allocated local indices are shifted by the number of parameters. 487 // Stack-allocated local indices are shifted by the number of parameters.
478 int IndexFor(Variable* variable) const { 488 int IndexFor(Variable* variable) const {
479 ASSERT(variable->IsStackAllocated()); 489 ASSERT(variable->IsStackAllocated());
480 int shift = variable->IsParameter() 490 int shift = variable->IsParameter()
481 ? 1 491 ? 1
482 : parameter_count_ + specials_count_; 492 : parameter_count_ + specials_count_;
483 return variable->index() + shift; 493 return variable->index() + shift;
484 } 494 }
485 495
486 Handle<JSFunction> closure_; 496 Handle<JSFunction> closure_;
487 // Value array [parameters] [specials] [locals] [temporaries]. 497 // Value array [parameters] [specials] [locals] [temporaries].
488 ZoneList<HValue*> values_; 498 ZoneList<HValue*> values_;
489 ZoneList<int> assigned_variables_; 499 ZoneList<int> assigned_variables_;
500 FrameType frame_type_;
490 int parameter_count_; 501 int parameter_count_;
491 int specials_count_; 502 int specials_count_;
492 int local_count_; 503 int local_count_;
493 HEnvironment* outer_; 504 HEnvironment* outer_;
494 int pop_count_; 505 int pop_count_;
495 int push_count_; 506 int push_count_;
496 int ast_id_; 507 int ast_id_;
497 bool arguments_adaptor_;
498 }; 508 };
499 509
500 510
501 class HGraphBuilder; 511 class HGraphBuilder;
502 512
503 enum ArgumentsAllowedFlag { 513 enum ArgumentsAllowedFlag {
504 ARGUMENTS_NOT_ALLOWED, 514 ARGUMENTS_NOT_ALLOWED,
505 ARGUMENTS_ALLOWED 515 ARGUMENTS_ALLOWED
506 }; 516 };
507 517
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 // Build the shared core part of the translation unpacking a value into 625 // Build the shared core part of the translation unpacking a value into
616 // control flow. 626 // control flow.
617 void BuildBranch(HValue* value); 627 void BuildBranch(HValue* value);
618 628
619 Expression* condition_; 629 Expression* condition_;
620 HBasicBlock* if_true_; 630 HBasicBlock* if_true_;
621 HBasicBlock* if_false_; 631 HBasicBlock* if_false_;
622 }; 632 };
623 633
624 634
635 enum ReturnHandlingFlag {
636 NORMAL_RETURN,
637 DROP_EXTRA_ON_RETURN,
638 CONSTRUCT_CALL_RETURN
639 };
640
641
625 class FunctionState { 642 class FunctionState {
626 public: 643 public:
644
627 FunctionState(HGraphBuilder* owner, 645 FunctionState(HGraphBuilder* owner,
628 CompilationInfo* info, 646 CompilationInfo* info,
629 TypeFeedbackOracle* oracle, 647 TypeFeedbackOracle* oracle,
630 bool drop_extra); 648 ReturnHandlingFlag return_handling);
631 ~FunctionState(); 649 ~FunctionState();
632 650
633 CompilationInfo* compilation_info() { return compilation_info_; } 651 CompilationInfo* compilation_info() { return compilation_info_; }
634 TypeFeedbackOracle* oracle() { return oracle_; } 652 TypeFeedbackOracle* oracle() { return oracle_; }
635 AstContext* call_context() { return call_context_; } 653 AstContext* call_context() { return call_context_; }
636 bool drop_extra() { return drop_extra_; } 654 bool drop_extra() { return return_handling_ == DROP_EXTRA_ON_RETURN; }
655 bool is_construct() { return return_handling_ == CONSTRUCT_CALL_RETURN; }
637 HBasicBlock* function_return() { return function_return_; } 656 HBasicBlock* function_return() { return function_return_; }
638 TestContext* test_context() { return test_context_; } 657 TestContext* test_context() { return test_context_; }
639 void ClearInlinedTestContext() { 658 void ClearInlinedTestContext() {
640 delete test_context_; 659 delete test_context_;
641 test_context_ = NULL; 660 test_context_ = NULL;
642 } 661 }
643 662
644 FunctionState* outer() { return outer_; } 663 FunctionState* outer() { return outer_; }
645 664
646 private: 665 private:
647 HGraphBuilder* owner_; 666 HGraphBuilder* owner_;
648 667
649 CompilationInfo* compilation_info_; 668 CompilationInfo* compilation_info_;
650 TypeFeedbackOracle* oracle_; 669 TypeFeedbackOracle* oracle_;
651 670
652 // During function inlining, expression context of the call being 671 // During function inlining, expression context of the call being
653 // inlined. NULL when not inlining. 672 // inlined. NULL when not inlining.
654 AstContext* call_context_; 673 AstContext* call_context_;
655 674
656 // Indicate if we have to drop an extra value from the environment on 675 // Indicate whether we have to perform special handling on return from
657 // return from inlined functions. 676 // inlined functions.
658 bool drop_extra_; 677 // - DROP_EXTRA_ON_RETURN: Drop an extra value from the environment.
678 // - CONSTRUCT_CALL_RETURN: Either use allocated receiver or return value.
679 ReturnHandlingFlag return_handling_;
659 680
660 // When inlining in an effect of value context, this is the return block. 681 // When inlining in an effect or value context, this is the return block.
661 // It is NULL otherwise. When inlining in a test context, there are a 682 // It is NULL otherwise. When inlining in a test context, there are a
662 // pair of return blocks in the context. When not inlining, there is no 683 // pair of return blocks in the context. When not inlining, there is no
663 // local return point. 684 // local return point.
664 HBasicBlock* function_return_; 685 HBasicBlock* function_return_;
665 686
666 // When inlining a call in a test context, a context containing a pair of 687 // When inlining a call in a test context, a context containing a pair of
667 // return blocks. NULL in all other cases. 688 // return blocks. NULL in all other cases.
668 TestContext* test_context_; 689 TestContext* test_context_;
669 690
670 FunctionState* outer_; 691 FunctionState* outer_;
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 // Simple accessors. 803 // Simple accessors.
783 void set_function_state(FunctionState* state) { function_state_ = state; } 804 void set_function_state(FunctionState* state) { function_state_ = state; }
784 805
785 AstContext* ast_context() const { return ast_context_; } 806 AstContext* ast_context() const { return ast_context_; }
786 void set_ast_context(AstContext* context) { ast_context_ = context; } 807 void set_ast_context(AstContext* context) { ast_context_ = context; }
787 808
788 // Accessors forwarded to the function state. 809 // Accessors forwarded to the function state.
789 CompilationInfo* info() const { 810 CompilationInfo* info() const {
790 return function_state()->compilation_info(); 811 return function_state()->compilation_info();
791 } 812 }
792
793 AstContext* call_context() const { 813 AstContext* call_context() const {
794 return function_state()->call_context(); 814 return function_state()->call_context();
795 } 815 }
796 HBasicBlock* function_return() const { 816 HBasicBlock* function_return() const {
797 return function_state()->function_return(); 817 return function_state()->function_return();
798 } 818 }
799 TestContext* inlined_test_context() const { 819 TestContext* inlined_test_context() const {
800 return function_state()->test_context(); 820 return function_state()->test_context();
801 } 821 }
802 void ClearInlinedTestContext() { 822 void ClearInlinedTestContext() {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 898
879 // Visit a list of expressions from left to right, each in a value context. 899 // Visit a list of expressions from left to right, each in a value context.
880 void VisitExpressions(ZoneList<Expression*>* exprs); 900 void VisitExpressions(ZoneList<Expression*>* exprs);
881 901
882 void AddPhi(HPhi* phi); 902 void AddPhi(HPhi* phi);
883 903
884 void PushAndAdd(HInstruction* instr); 904 void PushAndAdd(HInstruction* instr);
885 905
886 // Remove the arguments from the bailout environment and emit instructions 906 // Remove the arguments from the bailout environment and emit instructions
887 // to push them as outgoing parameters. 907 // to push them as outgoing parameters.
888 template <int V> HInstruction* PreProcessCall(HCall<V>* call); 908 template <class Instruction> HInstruction* PreProcessCall(Instruction* call);
889 909
890 void TraceRepresentation(Token::Value op, 910 void TraceRepresentation(Token::Value op,
891 TypeInfo info, 911 TypeInfo info,
892 HValue* value, 912 HValue* value,
893 Representation rep); 913 Representation rep);
894 static Representation ToRepresentation(TypeInfo info); 914 static Representation ToRepresentation(TypeInfo info);
895 915
896 void SetUpScope(Scope* scope); 916 void SetUpScope(Scope* scope);
897 virtual void VisitStatements(ZoneList<Statement*>* statements); 917 virtual void VisitStatements(ZoneList<Statement*>* statements);
898 918
(...skipping 11 matching lines...) Expand all
910 }; 930 };
911 GlobalPropertyAccess LookupGlobalProperty(Variable* var, 931 GlobalPropertyAccess LookupGlobalProperty(Variable* var,
912 LookupResult* lookup, 932 LookupResult* lookup,
913 bool is_store); 933 bool is_store);
914 934
915 bool TryArgumentsAccess(Property* expr); 935 bool TryArgumentsAccess(Property* expr);
916 936
917 // Try to optimize fun.apply(receiver, arguments) pattern. 937 // Try to optimize fun.apply(receiver, arguments) pattern.
918 bool TryCallApply(Call* expr); 938 bool TryCallApply(Call* expr);
919 939
920 bool TryInline(Call* expr, bool drop_extra = false); 940 bool TryInline(CallKind call_kind,
941 Handle<JSFunction> target,
942 ZoneList<Expression*>* arguments,
943 HValue* receiver,
944 int ast_id,
945 int return_id,
946 ReturnHandlingFlag return_handling);
947
948 bool TryInlineCall(Call* expr, bool drop_extra = false);
949 bool TryInlineConstruct(CallNew* expr, HValue* receiver);
921 bool TryInlineBuiltinFunction(Call* expr, 950 bool TryInlineBuiltinFunction(Call* expr,
922 HValue* receiver, 951 HValue* receiver,
923 Handle<Map> receiver_map, 952 Handle<Map> receiver_map,
924 CheckType check_type); 953 CheckType check_type);
925 954
926 // If --trace-inlining, print a line of the inlining trace. Inlining 955 // If --trace-inlining, print a line of the inlining trace. Inlining
927 // succeeded if the reason string is NULL and failed if there is a 956 // succeeded if the reason string is NULL and failed if there is a
928 // non-NULL reason string. 957 // non-NULL reason string.
929 void TraceInline(Handle<JSFunction> target, 958 void TraceInline(Handle<JSFunction> target,
930 Handle<JSFunction> caller, 959 Handle<JSFunction> caller,
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 const char* filename_; 1304 const char* filename_;
1276 HeapStringAllocator string_allocator_; 1305 HeapStringAllocator string_allocator_;
1277 StringStream trace_; 1306 StringStream trace_;
1278 int indent_; 1307 int indent_;
1279 }; 1308 };
1280 1309
1281 1310
1282 } } // namespace v8::internal 1311 } } // namespace v8::internal
1283 1312
1284 #endif // V8_HYDROGEN_H_ 1313 #endif // V8_HYDROGEN_H_
OLDNEW
« no previous file with comments | « src/heap.h ('k') | src/hydrogen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698