| 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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 virtual void EnterContext(Context* context) = 0; | 98 virtual void EnterContext(Context* context) = 0; |
| 99 | 99 |
| 100 virtual void VisitFunction(JSFunction* function) = 0; | 100 virtual void VisitFunction(JSFunction* function) = 0; |
| 101 | 101 |
| 102 // Function which is called after iteration of all optimized functions | 102 // Function which is called after iteration of all optimized functions |
| 103 // from given native context. | 103 // from given native context. |
| 104 virtual void LeaveContext(Context* context) = 0; | 104 virtual void LeaveContext(Context* context) = 0; |
| 105 }; | 105 }; |
| 106 | 106 |
| 107 | 107 |
| 108 // Linked list holding deoptimizing code objects. The deoptimizing code objects |
| 109 // are kept as weak handles until they are no longer activated on the stack. |
| 110 class DeoptimizingCodeListNode : public Malloced { |
| 111 public: |
| 112 explicit DeoptimizingCodeListNode(Code* code); |
| 113 ~DeoptimizingCodeListNode(); |
| 114 |
| 115 DeoptimizingCodeListNode* next() const { return next_; } |
| 116 void set_next(DeoptimizingCodeListNode* next) { next_ = next; } |
| 117 Handle<Code> code() const { return code_; } |
| 118 |
| 119 private: |
| 120 // Global (weak) handle to the deoptimizing code object. |
| 121 Handle<Code> code_; |
| 122 |
| 123 // Next pointer for linked list. |
| 124 DeoptimizingCodeListNode* next_; |
| 125 }; |
| 126 |
| 127 |
| 108 class OptimizedFunctionFilter BASE_EMBEDDED { | 128 class OptimizedFunctionFilter BASE_EMBEDDED { |
| 109 public: | 129 public: |
| 110 virtual ~OptimizedFunctionFilter() {} | 130 virtual ~OptimizedFunctionFilter() {} |
| 111 | 131 |
| 112 virtual bool TakeFunction(JSFunction* function) = 0; | 132 virtual bool TakeFunction(JSFunction* function) = 0; |
| 113 }; | 133 }; |
| 114 | 134 |
| 115 | 135 |
| 116 class Deoptimizer; | |
| 117 | |
| 118 | |
| 119 class Deoptimizer : public Malloced { | 136 class Deoptimizer : public Malloced { |
| 120 public: | 137 public: |
| 121 enum BailoutType { | 138 enum BailoutType { |
| 122 EAGER, | 139 EAGER, |
| 123 LAZY, | 140 LAZY, |
| 124 SOFT, | 141 SOFT, |
| 125 OSR, | 142 OSR, |
| 126 // This last bailout type is not really a bailout, but used by the | 143 // This last bailout type is not really a bailout, but used by the |
| 127 // debugger to deoptimize stack frames to allow inspection. | 144 // debugger to deoptimize stack frames to allow inspection. |
| 128 DEBUGGER | 145 DEBUGGER |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 virtual void GeneratePrologue(); | 343 virtual void GeneratePrologue(); |
| 327 | 344 |
| 328 private: | 345 private: |
| 329 int count() const { return count_; } | 346 int count() const { return count_; } |
| 330 | 347 |
| 331 int count_; | 348 int count_; |
| 332 }; | 349 }; |
| 333 | 350 |
| 334 int ConvertJSFrameIndexToFrameIndex(int jsframe_index); | 351 int ConvertJSFrameIndexToFrameIndex(int jsframe_index); |
| 335 | 352 |
| 353 // Unregister a code object from lazy deoptimization. |
| 354 static void RemoveDeoptimizingCode(Code* code); |
| 355 |
| 336 static size_t GetMaxDeoptTableSize(); | 356 static size_t GetMaxDeoptTableSize(); |
| 337 | 357 |
| 338 static void EnsureCodeForDeoptimizationEntry(Isolate* isolate, | 358 static void EnsureCodeForDeoptimizationEntry(Isolate* isolate, |
| 339 BailoutType type, | 359 BailoutType type, |
| 340 int max_entry_id); | 360 int max_entry_id); |
| 341 | 361 |
| 342 Isolate* isolate() const { return isolate_; } | 362 Isolate* isolate() const { return isolate_; } |
| 343 | 363 |
| 344 private: | 364 private: |
| 345 static const int kMinNumberOfEntries = 64; | 365 static const int kMinNumberOfEntries = 64; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 // (e.g., a number conversion failed) and may or may not have updated the | 408 // (e.g., a number conversion failed) and may or may not have updated the |
| 389 // input offset. | 409 // input offset. |
| 390 bool DoOsrTranslateCommand(TranslationIterator* iterator, | 410 bool DoOsrTranslateCommand(TranslationIterator* iterator, |
| 391 int* input_offset); | 411 int* input_offset); |
| 392 | 412 |
| 393 unsigned ComputeInputFrameSize() const; | 413 unsigned ComputeInputFrameSize() const; |
| 394 unsigned ComputeFixedSize(JSFunction* function) const; | 414 unsigned ComputeFixedSize(JSFunction* function) const; |
| 395 | 415 |
| 396 unsigned ComputeIncomingArgumentSize(JSFunction* function) const; | 416 unsigned ComputeIncomingArgumentSize(JSFunction* function) const; |
| 397 unsigned ComputeOutgoingArgumentSize() const; | 417 unsigned ComputeOutgoingArgumentSize() const; |
| 418 unsigned ComputeHandlersSize() const; |
| 398 | 419 |
| 399 Object* ComputeLiteral(int index) const; | 420 Object* ComputeLiteral(int index) const; |
| 400 | 421 |
| 401 void AddObjectStart(intptr_t slot_address, int argc); | 422 void AddObjectStart(intptr_t slot_address, int argc); |
| 402 void AddObjectTaggedValue(intptr_t value); | 423 void AddObjectTaggedValue(intptr_t value); |
| 403 void AddObjectDoubleValue(double value); | 424 void AddObjectDoubleValue(double value); |
| 404 void AddDoubleValue(intptr_t slot_address, double value); | 425 void AddDoubleValue(intptr_t slot_address, double value); |
| 405 | 426 |
| 406 static void GenerateDeoptimizationEntries( | 427 static void GenerateDeoptimizationEntries( |
| 407 MacroAssembler* masm, int count, BailoutType type); | 428 MacroAssembler* masm, int count, BailoutType type); |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 } | 604 } |
| 584 | 605 |
| 585 static int continuation_offset() { | 606 static int continuation_offset() { |
| 586 return OFFSET_OF(FrameDescription, continuation_); | 607 return OFFSET_OF(FrameDescription, continuation_); |
| 587 } | 608 } |
| 588 | 609 |
| 589 static int frame_content_offset() { | 610 static int frame_content_offset() { |
| 590 return OFFSET_OF(FrameDescription, frame_content_); | 611 return OFFSET_OF(FrameDescription, frame_content_); |
| 591 } | 612 } |
| 592 | 613 |
| 614 unsigned frame_size() { return static_cast<unsigned>(frame_size_); } |
| 615 |
| 593 private: | 616 private: |
| 594 static const uint32_t kZapUint32 = 0xbeeddead; | 617 static const uint32_t kZapUint32 = 0xbeeddead; |
| 595 | 618 |
| 596 // Frame_size_ must hold a uint32_t value. It is only a uintptr_t to | 619 // Frame_size_ must hold a uint32_t value. It is only a uintptr_t to |
| 597 // keep the variable-size array frame_content_ of type intptr_t at | 620 // keep the variable-size array frame_content_ of type intptr_t at |
| 598 // the end of the structure aligned. | 621 // the end of the structure aligned. |
| 599 uintptr_t frame_size_; // Number of bytes. | 622 uintptr_t frame_size_; // Number of bytes. |
| 600 JSFunction* function_; | 623 JSFunction* function_; |
| 601 intptr_t registers_[Register::kNumRegisters]; | 624 intptr_t registers_[Register::kNumRegisters]; |
| 602 double double_registers_[DoubleRegister::kMaxNumRegisters]; | 625 double double_registers_[DoubleRegister::kMaxNumRegisters]; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 630 explicit DeoptimizerData(MemoryAllocator* allocator); | 653 explicit DeoptimizerData(MemoryAllocator* allocator); |
| 631 ~DeoptimizerData(); | 654 ~DeoptimizerData(); |
| 632 | 655 |
| 633 #ifdef ENABLE_DEBUGGER_SUPPORT | 656 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 634 void Iterate(ObjectVisitor* v); | 657 void Iterate(ObjectVisitor* v); |
| 635 #endif | 658 #endif |
| 636 | 659 |
| 637 Code* FindDeoptimizingCode(Address addr); | 660 Code* FindDeoptimizingCode(Address addr); |
| 638 void RemoveDeoptimizingCode(Code* code); | 661 void RemoveDeoptimizingCode(Code* code); |
| 639 | 662 |
| 663 void append_deoptimizing_code(Code* code) { |
| 664 DeoptimizingCodeListNode* head = new DeoptimizingCodeListNode(code); |
| 665 head->set_next(deoptimizing_code_list_); |
| 666 deoptimizing_code_list_ = head; |
| 667 } |
| 668 |
| 640 private: | 669 private: |
| 641 MemoryAllocator* allocator_; | 670 MemoryAllocator* allocator_; |
| 642 int deopt_entry_code_entries_[Deoptimizer::kBailoutTypesWithCodeEntry]; | 671 int deopt_entry_code_entries_[Deoptimizer::kBailoutTypesWithCodeEntry]; |
| 643 MemoryChunk* deopt_entry_code_[Deoptimizer::kBailoutTypesWithCodeEntry]; | 672 MemoryChunk* deopt_entry_code_[Deoptimizer::kBailoutTypesWithCodeEntry]; |
| 644 Deoptimizer* current_; | 673 Deoptimizer* current_; |
| 645 | 674 |
| 646 #ifdef ENABLE_DEBUGGER_SUPPORT | 675 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 647 DeoptimizedFrameInfo* deoptimized_frame_info_; | 676 DeoptimizedFrameInfo* deoptimized_frame_info_; |
| 648 #endif | 677 #endif |
| 649 | 678 |
| 650 // List of deoptimized code which still have references from active stack | 679 // List of deoptimized code which still have references from active stack |
| 651 // frames. These code objects are needed by the deoptimizer when deoptimizing | 680 // frames. These code objects are needed by the deoptimizer when deoptimizing |
| 652 // a frame for which the code object for the function function has been | 681 // a frame for which the code object for the function function has been |
| 653 // changed from the code present when deoptimizing was done. | 682 // changed from the code present when deoptimizing was done. |
| 654 DeoptimizingCodeListNode* deoptimizing_code_list_; | 683 DeoptimizingCodeListNode* deoptimizing_code_list_; |
| 655 | 684 |
| 656 friend class Deoptimizer; | 685 friend class Deoptimizer; |
| 686 friend class Isolate; |
| 657 | 687 |
| 658 DISALLOW_COPY_AND_ASSIGN(DeoptimizerData); | 688 DISALLOW_COPY_AND_ASSIGN(DeoptimizerData); |
| 659 }; | 689 }; |
| 660 | 690 |
| 661 | 691 |
| 662 class TranslationBuffer BASE_EMBEDDED { | 692 class TranslationBuffer BASE_EMBEDDED { |
| 663 public: | 693 public: |
| 664 explicit TranslationBuffer(Zone* zone) : contents_(256, zone) { } | 694 explicit TranslationBuffer(Zone* zone) : contents_(256, zone) { } |
| 665 | 695 |
| 666 int CurrentIndex() const { return contents_.length(); } | 696 int CurrentIndex() const { return contents_.length(); } |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 726 index_(buffer->CurrentIndex()), | 756 index_(buffer->CurrentIndex()), |
| 727 zone_(zone) { | 757 zone_(zone) { |
| 728 buffer_->Add(BEGIN, zone); | 758 buffer_->Add(BEGIN, zone); |
| 729 buffer_->Add(frame_count, zone); | 759 buffer_->Add(frame_count, zone); |
| 730 buffer_->Add(jsframe_count, zone); | 760 buffer_->Add(jsframe_count, zone); |
| 731 } | 761 } |
| 732 | 762 |
| 733 int index() const { return index_; } | 763 int index() const { return index_; } |
| 734 | 764 |
| 735 // Commands. | 765 // Commands. |
| 736 void BeginJSFrame(BailoutId node_id, int literal_id, unsigned height); | 766 void BeginJSFrame(BailoutId node_id, |
| 767 int literal_id, |
| 768 unsigned height, |
| 769 int handler_count); |
| 737 void BeginCompiledStubFrame(); | 770 void BeginCompiledStubFrame(); |
| 738 void BeginArgumentsAdaptorFrame(int literal_id, unsigned height); | 771 void BeginArgumentsAdaptorFrame(int literal_id, unsigned height); |
| 739 void BeginConstructStubFrame(int literal_id, unsigned height); | 772 void BeginConstructStubFrame(int literal_id, unsigned height); |
| 740 void BeginGetterStubFrame(int literal_id); | 773 void BeginGetterStubFrame(int literal_id); |
| 741 void BeginSetterStubFrame(int literal_id); | 774 void BeginSetterStubFrame(int literal_id); |
| 742 void BeginArgumentsObject(int args_length); | 775 void BeginArgumentsObject(int args_length); |
| 743 void StoreRegister(Register reg); | 776 void StoreRegister(Register reg); |
| 744 void StoreInt32Register(Register reg); | 777 void StoreInt32Register(Register reg); |
| 745 void StoreUint32Register(Register reg); | 778 void StoreUint32Register(Register reg); |
| 746 void StoreDoubleRegister(DoubleRegister reg); | 779 void StoreDoubleRegister(DoubleRegister reg); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 762 // A literal id which refers to the JSFunction itself. | 795 // A literal id which refers to the JSFunction itself. |
| 763 static const int kSelfLiteralId = -239; | 796 static const int kSelfLiteralId = -239; |
| 764 | 797 |
| 765 private: | 798 private: |
| 766 TranslationBuffer* buffer_; | 799 TranslationBuffer* buffer_; |
| 767 int index_; | 800 int index_; |
| 768 Zone* zone_; | 801 Zone* zone_; |
| 769 }; | 802 }; |
| 770 | 803 |
| 771 | 804 |
| 772 // Linked list holding deoptimizing code objects. The deoptimizing code objects | |
| 773 // are kept as weak handles until they are no longer activated on the stack. | |
| 774 class DeoptimizingCodeListNode : public Malloced { | |
| 775 public: | |
| 776 explicit DeoptimizingCodeListNode(Code* code); | |
| 777 ~DeoptimizingCodeListNode(); | |
| 778 | |
| 779 DeoptimizingCodeListNode* next() const { return next_; } | |
| 780 void set_next(DeoptimizingCodeListNode* next) { next_ = next; } | |
| 781 Handle<Code> code() const { return code_; } | |
| 782 | |
| 783 private: | |
| 784 // Global (weak) handle to the deoptimizing code object. | |
| 785 Handle<Code> code_; | |
| 786 | |
| 787 // Next pointer for linked list. | |
| 788 DeoptimizingCodeListNode* next_; | |
| 789 }; | |
| 790 | |
| 791 | |
| 792 class SlotRef BASE_EMBEDDED { | 805 class SlotRef BASE_EMBEDDED { |
| 793 public: | 806 public: |
| 794 enum SlotRepresentation { | 807 enum SlotRepresentation { |
| 795 UNKNOWN, | 808 UNKNOWN, |
| 796 TAGGED, | 809 TAGGED, |
| 797 INT32, | 810 INT32, |
| 798 UINT32, | 811 UINT32, |
| 799 DOUBLE, | 812 DOUBLE, |
| 800 LITERAL | 813 LITERAL |
| 801 }; | 814 }; |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 950 Object** expression_stack_; | 963 Object** expression_stack_; |
| 951 int source_position_; | 964 int source_position_; |
| 952 | 965 |
| 953 friend class Deoptimizer; | 966 friend class Deoptimizer; |
| 954 }; | 967 }; |
| 955 #endif | 968 #endif |
| 956 | 969 |
| 957 } } // namespace v8::internal | 970 } } // namespace v8::internal |
| 958 | 971 |
| 959 #endif // V8_DEOPTIMIZER_H_ | 972 #endif // V8_DEOPTIMIZER_H_ |
| OLD | NEW |