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 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 // XXX | |
Vyacheslav Egorov (Chromium)
2012/02/13 15:01:39
XXX?
Michael Starzinger
2012/02/27 14:16:32
Done. Ooops.
| |
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 Loading... | |
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 // Create an argument adaptor environment. |
466 HEnvironment(HEnvironment* outer, Handle<JSFunction> closure, int arguments); | 468 HEnvironment(HEnvironment* outer, Handle<JSFunction> closure, int arguments); |
467 | 469 |
470 // Create an constructor stub environment. | |
471 HEnvironment(HEnvironment* outer, Handle<JSFunction> closure); | |
468 | 472 |
469 // True if index is included in the expression stack part of the environment. | 473 // True if index is included in the expression stack part of the environment. |
470 bool HasExpressionAt(int index) const; | 474 bool HasExpressionAt(int index) const; |
471 | 475 |
472 void Initialize(int parameter_count, int local_count, int stack_height); | 476 void Initialize(int parameter_count, int local_count, int stack_height); |
473 void Initialize(const HEnvironment* other); | 477 void Initialize(const HEnvironment* other); |
474 | 478 |
475 // Map a variable to an environment index. Parameter indices are shifted | 479 // Map a variable to an environment index. Parameter indices are shifted |
476 // by 1 (receiver is parameter index -1 but environment index 0). | 480 // by 1 (receiver is parameter index -1 but environment index 0). |
477 // Stack-allocated local indices are shifted by the number of parameters. | 481 // Stack-allocated local indices are shifted by the number of parameters. |
478 int IndexFor(Variable* variable) const { | 482 int IndexFor(Variable* variable) const { |
479 ASSERT(variable->IsStackAllocated()); | 483 ASSERT(variable->IsStackAllocated()); |
480 int shift = variable->IsParameter() | 484 int shift = variable->IsParameter() |
481 ? 1 | 485 ? 1 |
482 : parameter_count_ + specials_count_; | 486 : parameter_count_ + specials_count_; |
483 return variable->index() + shift; | 487 return variable->index() + shift; |
484 } | 488 } |
485 | 489 |
486 Handle<JSFunction> closure_; | 490 Handle<JSFunction> closure_; |
487 // Value array [parameters] [specials] [locals] [temporaries]. | 491 // Value array [parameters] [specials] [locals] [temporaries]. |
488 ZoneList<HValue*> values_; | 492 ZoneList<HValue*> values_; |
489 ZoneList<int> assigned_variables_; | 493 ZoneList<int> assigned_variables_; |
494 FrameType frame_type_; | |
490 int parameter_count_; | 495 int parameter_count_; |
491 int specials_count_; | 496 int specials_count_; |
492 int local_count_; | 497 int local_count_; |
493 HEnvironment* outer_; | 498 HEnvironment* outer_; |
494 int pop_count_; | 499 int pop_count_; |
495 int push_count_; | 500 int push_count_; |
496 int ast_id_; | 501 int ast_id_; |
497 bool arguments_adaptor_; | |
498 }; | 502 }; |
499 | 503 |
500 | 504 |
501 class HGraphBuilder; | 505 class HGraphBuilder; |
502 | 506 |
503 enum ArgumentsAllowedFlag { | 507 enum ArgumentsAllowedFlag { |
504 ARGUMENTS_NOT_ALLOWED, | 508 ARGUMENTS_NOT_ALLOWED, |
505 ARGUMENTS_ALLOWED | 509 ARGUMENTS_ALLOWED |
506 }; | 510 }; |
507 | 511 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
620 HBasicBlock* if_true_; | 624 HBasicBlock* if_true_; |
621 HBasicBlock* if_false_; | 625 HBasicBlock* if_false_; |
622 }; | 626 }; |
623 | 627 |
624 | 628 |
625 class FunctionState { | 629 class FunctionState { |
626 public: | 630 public: |
627 FunctionState(HGraphBuilder* owner, | 631 FunctionState(HGraphBuilder* owner, |
628 CompilationInfo* info, | 632 CompilationInfo* info, |
629 TypeFeedbackOracle* oracle, | 633 TypeFeedbackOracle* oracle, |
630 bool drop_extra); | 634 bool drop_extra, |
635 bool is_construct); | |
631 ~FunctionState(); | 636 ~FunctionState(); |
632 | 637 |
633 CompilationInfo* compilation_info() { return compilation_info_; } | 638 CompilationInfo* compilation_info() { return compilation_info_; } |
634 TypeFeedbackOracle* oracle() { return oracle_; } | 639 TypeFeedbackOracle* oracle() { return oracle_; } |
635 AstContext* call_context() { return call_context_; } | 640 AstContext* call_context() { return call_context_; } |
636 bool drop_extra() { return drop_extra_; } | 641 bool drop_extra() { return drop_extra_; } |
642 bool is_construct() { return is_construct_; } | |
637 HBasicBlock* function_return() { return function_return_; } | 643 HBasicBlock* function_return() { return function_return_; } |
638 TestContext* test_context() { return test_context_; } | 644 TestContext* test_context() { return test_context_; } |
639 void ClearInlinedTestContext() { | 645 void ClearInlinedTestContext() { |
640 delete test_context_; | 646 delete test_context_; |
641 test_context_ = NULL; | 647 test_context_ = NULL; |
642 } | 648 } |
643 | 649 |
644 FunctionState* outer() { return outer_; } | 650 FunctionState* outer() { return outer_; } |
645 | 651 |
646 private: | 652 private: |
647 HGraphBuilder* owner_; | 653 HGraphBuilder* owner_; |
648 | 654 |
649 CompilationInfo* compilation_info_; | 655 CompilationInfo* compilation_info_; |
650 TypeFeedbackOracle* oracle_; | 656 TypeFeedbackOracle* oracle_; |
651 | 657 |
652 // During function inlining, expression context of the call being | 658 // During function inlining, expression context of the call being |
653 // inlined. NULL when not inlining. | 659 // inlined. NULL when not inlining. |
654 AstContext* call_context_; | 660 AstContext* call_context_; |
655 | 661 |
656 // Indicate if we have to drop an extra value from the environment on | 662 // Indicate if we have to drop an extra value from the environment on |
657 // return from inlined functions. | 663 // return from inlined functions. |
658 bool drop_extra_; | 664 bool drop_extra_; |
659 | 665 |
666 // Indicate if we are inlining a constructor call and need to perform | |
667 // special handling of the return value. | |
668 bool is_construct_; | |
669 | |
660 // When inlining in an effect of value context, this is the return block. | 670 // When inlining in an effect of value context, this is the return block. |
661 // It is NULL otherwise. When inlining in a test context, there are a | 671 // 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 | 672 // pair of return blocks in the context. When not inlining, there is no |
663 // local return point. | 673 // local return point. |
664 HBasicBlock* function_return_; | 674 HBasicBlock* function_return_; |
665 | 675 |
666 // When inlining a call in a test context, a context containing a pair of | 676 // When inlining a call in a test context, a context containing a pair of |
667 // return blocks. NULL in all other cases. | 677 // return blocks. NULL in all other cases. |
668 TestContext* test_context_; | 678 TestContext* test_context_; |
669 | 679 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
782 // Simple accessors. | 792 // Simple accessors. |
783 void set_function_state(FunctionState* state) { function_state_ = state; } | 793 void set_function_state(FunctionState* state) { function_state_ = state; } |
784 | 794 |
785 AstContext* ast_context() const { return ast_context_; } | 795 AstContext* ast_context() const { return ast_context_; } |
786 void set_ast_context(AstContext* context) { ast_context_ = context; } | 796 void set_ast_context(AstContext* context) { ast_context_ = context; } |
787 | 797 |
788 // Accessors forwarded to the function state. | 798 // Accessors forwarded to the function state. |
789 CompilationInfo* info() const { | 799 CompilationInfo* info() const { |
790 return function_state()->compilation_info(); | 800 return function_state()->compilation_info(); |
791 } | 801 } |
792 | |
793 AstContext* call_context() const { | 802 AstContext* call_context() const { |
794 return function_state()->call_context(); | 803 return function_state()->call_context(); |
795 } | 804 } |
796 HBasicBlock* function_return() const { | 805 HBasicBlock* function_return() const { |
797 return function_state()->function_return(); | 806 return function_state()->function_return(); |
798 } | 807 } |
799 TestContext* inlined_test_context() const { | 808 TestContext* inlined_test_context() const { |
800 return function_state()->test_context(); | 809 return function_state()->test_context(); |
801 } | 810 } |
802 void ClearInlinedTestContext() { | 811 void ClearInlinedTestContext() { |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
910 }; | 919 }; |
911 GlobalPropertyAccess LookupGlobalProperty(Variable* var, | 920 GlobalPropertyAccess LookupGlobalProperty(Variable* var, |
912 LookupResult* lookup, | 921 LookupResult* lookup, |
913 bool is_store); | 922 bool is_store); |
914 | 923 |
915 bool TryArgumentsAccess(Property* expr); | 924 bool TryArgumentsAccess(Property* expr); |
916 | 925 |
917 // Try to optimize fun.apply(receiver, arguments) pattern. | 926 // Try to optimize fun.apply(receiver, arguments) pattern. |
918 bool TryCallApply(Call* expr); | 927 bool TryCallApply(Call* expr); |
919 | 928 |
920 bool TryInline(Call* expr, bool drop_extra = false); | 929 bool TryInline(CallKind call_kind, |
930 Handle<JSFunction> target, | |
931 ZoneList<Expression*>* arguments, | |
932 HValue* receiver, | |
933 int ast_id, | |
934 int return_id, | |
935 bool drop_extra, | |
936 bool is_construct); | |
937 | |
938 bool TryInlineCall(Call* expr, bool drop_extra = false); | |
939 bool TryInlineConstruct(CallNew* expr, HValue* receiver); | |
921 bool TryInlineBuiltinFunction(Call* expr, | 940 bool TryInlineBuiltinFunction(Call* expr, |
922 HValue* receiver, | 941 HValue* receiver, |
923 Handle<Map> receiver_map, | 942 Handle<Map> receiver_map, |
924 CheckType check_type); | 943 CheckType check_type); |
925 | 944 |
926 // If --trace-inlining, print a line of the inlining trace. Inlining | 945 // 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 | 946 // succeeded if the reason string is NULL and failed if there is a |
928 // non-NULL reason string. | 947 // non-NULL reason string. |
929 void TraceInline(Handle<JSFunction> target, | 948 void TraceInline(Handle<JSFunction> target, |
930 Handle<JSFunction> caller, | 949 Handle<JSFunction> caller, |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1275 const char* filename_; | 1294 const char* filename_; |
1276 HeapStringAllocator string_allocator_; | 1295 HeapStringAllocator string_allocator_; |
1277 StringStream trace_; | 1296 StringStream trace_; |
1278 int indent_; | 1297 int indent_; |
1279 }; | 1298 }; |
1280 | 1299 |
1281 | 1300 |
1282 } } // namespace v8::internal | 1301 } } // namespace v8::internal |
1283 | 1302 |
1284 #endif // V8_HYDROGEN_H_ | 1303 #endif // V8_HYDROGEN_H_ |
OLD | NEW |