| 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 } c; | 51 } c; |
| 52 c.u[0] = *reinterpret_cast<uint32_t*>(p); | 52 c.u[0] = *reinterpret_cast<uint32_t*>(p); |
| 53 c.u[1] = *reinterpret_cast<uint32_t*>(p + 4); | 53 c.u[1] = *reinterpret_cast<uint32_t*>(p + 4); |
| 54 return c.d; | 54 return c.d; |
| 55 #endif // V8_HOST_CAN_READ_UNALIGNED | 55 #endif // V8_HOST_CAN_READ_UNALIGNED |
| 56 } | 56 } |
| 57 | 57 |
| 58 | 58 |
| 59 class FrameDescription; | 59 class FrameDescription; |
| 60 class TranslationIterator; | 60 class TranslationIterator; |
| 61 class DeoptimizingCodeListNode; | |
| 62 class DeoptimizedFrameInfo; | 61 class DeoptimizedFrameInfo; |
| 63 | 62 |
| 64 class HeapNumberMaterializationDescriptor BASE_EMBEDDED { | 63 class HeapNumberMaterializationDescriptor BASE_EMBEDDED { |
| 65 public: | 64 public: |
| 66 HeapNumberMaterializationDescriptor(Address slot_address, double val) | 65 HeapNumberMaterializationDescriptor(Address slot_address, double val) |
| 67 : slot_address_(slot_address), val_(val) { } | 66 : slot_address_(slot_address), val_(val) { } |
| 68 | 67 |
| 69 Address slot_address() const { return slot_address_; } | 68 Address slot_address() const { return slot_address_; } |
| 70 double value() const { return val_; } | 69 double value() const { return val_; } |
| 71 | 70 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 virtual void EnterContext(Context* context) = 0; | 113 virtual void EnterContext(Context* context) = 0; |
| 115 | 114 |
| 116 virtual void VisitFunction(JSFunction* function) = 0; | 115 virtual void VisitFunction(JSFunction* function) = 0; |
| 117 | 116 |
| 118 // Function which is called after iteration of all optimized functions | 117 // Function which is called after iteration of all optimized functions |
| 119 // from given native context. | 118 // from given native context. |
| 120 virtual void LeaveContext(Context* context) = 0; | 119 virtual void LeaveContext(Context* context) = 0; |
| 121 }; | 120 }; |
| 122 | 121 |
| 123 | 122 |
| 124 class OptimizedFunctionFilter BASE_EMBEDDED { | |
| 125 public: | |
| 126 virtual ~OptimizedFunctionFilter() {} | |
| 127 | |
| 128 virtual bool TakeFunction(JSFunction* function) = 0; | |
| 129 }; | |
| 130 | |
| 131 | |
| 132 class Deoptimizer; | |
| 133 | |
| 134 | |
| 135 class Deoptimizer : public Malloced { | 123 class Deoptimizer : public Malloced { |
| 136 public: | 124 public: |
| 137 enum BailoutType { | 125 enum BailoutType { |
| 138 EAGER, | 126 EAGER, |
| 139 LAZY, | 127 LAZY, |
| 140 SOFT, | 128 SOFT, |
| 141 OSR, | 129 OSR, |
| 142 // This last bailout type is not really a bailout, but used by the | 130 // This last bailout type is not really a bailout, but used by the |
| 143 // debugger to deoptimize stack frames to allow inspection. | 131 // debugger to deoptimize stack frames to allow inspection. |
| 144 DEBUGGER | 132 DEBUGGER |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 // patching. If there is not enough room a new relocation | 184 // patching. If there is not enough room a new relocation |
| 197 // information object is allocated and comments are added until it | 185 // information object is allocated and comments are added until it |
| 198 // is big enough. | 186 // is big enough. |
| 199 static void EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code); | 187 static void EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code); |
| 200 | 188 |
| 201 // Deoptimize the function now. Its current optimized code will never be run | 189 // Deoptimize the function now. Its current optimized code will never be run |
| 202 // again and any activations of the optimized code will get deoptimized when | 190 // again and any activations of the optimized code will get deoptimized when |
| 203 // execution returns. | 191 // execution returns. |
| 204 static void DeoptimizeFunction(JSFunction* function); | 192 static void DeoptimizeFunction(JSFunction* function); |
| 205 | 193 |
| 206 // Iterate over all the functions which share the same code object | 194 // Deoptimize all code in the given isolate. |
| 207 // and make them use unoptimized version. | |
| 208 static void ReplaceCodeForRelatedFunctions(JSFunction* function, Code* code); | |
| 209 | |
| 210 // Deoptimize all functions in the heap. | |
| 211 static void DeoptimizeAll(Isolate* isolate); | 195 static void DeoptimizeAll(Isolate* isolate); |
| 212 | 196 |
| 197 // Deoptimize code associated with the given global object. |
| 213 static void DeoptimizeGlobalObject(JSObject* object); | 198 static void DeoptimizeGlobalObject(JSObject* object); |
| 214 | 199 |
| 215 static void DeoptimizeAllFunctionsWith(Isolate* isolate, | 200 // Deoptimizes all optimized code that has been previously marked |
| 216 OptimizedFunctionFilter* filter); | 201 // (via code->set_marked_for_deoptimization) and unlinks all functions that |
| 202 // refer to that code. |
| 203 static void DeoptimizeMarkedCode(Isolate* isolate); |
| 217 | 204 |
| 218 static void DeoptimizeCodeList(Isolate* isolate, ZoneList<Code*>* codes); | 205 // Visit all the known optimized functions in a given isolate. |
| 219 | 206 static void VisitAllOptimizedFunctions( |
| 220 static void DeoptimizeAllFunctionsForContext( | 207 Isolate* isolate, OptimizedFunctionVisitor* visitor); |
| 221 Context* context, OptimizedFunctionFilter* filter); | |
| 222 | |
| 223 static void VisitAllOptimizedFunctionsForContext( | |
| 224 Context* context, OptimizedFunctionVisitor* visitor); | |
| 225 | |
| 226 static void VisitAllOptimizedFunctions(Isolate* isolate, | |
| 227 OptimizedFunctionVisitor* visitor); | |
| 228 | 208 |
| 229 // The size in bytes of the code required at a lazy deopt patch site. | 209 // The size in bytes of the code required at a lazy deopt patch site. |
| 230 static int patch_size(); | 210 static int patch_size(); |
| 231 | 211 |
| 232 // Patch all interrupts with allowed loop depth in the unoptimized code to | 212 // Patch all interrupts with allowed loop depth in the unoptimized code to |
| 233 // unconditionally call replacement_code. | 213 // unconditionally call replacement_code. |
| 234 static void PatchInterruptCode(Code* unoptimized_code, | 214 static void PatchInterruptCode(Code* unoptimized_code, |
| 235 Code* interrupt_code, | 215 Code* interrupt_code, |
| 236 Code* replacement_code); | 216 Code* replacement_code); |
| 237 | 217 |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 return jsframe_functions_[reverse_jsframe_index]; | 416 return jsframe_functions_[reverse_jsframe_index]; |
| 437 } | 417 } |
| 438 | 418 |
| 439 // Helper function for heap object materialization. | 419 // Helper function for heap object materialization. |
| 440 Handle<Object> MaterializeNextHeapObject(); | 420 Handle<Object> MaterializeNextHeapObject(); |
| 441 Handle<Object> MaterializeNextValue(); | 421 Handle<Object> MaterializeNextValue(); |
| 442 | 422 |
| 443 static void GenerateDeoptimizationEntries( | 423 static void GenerateDeoptimizationEntries( |
| 444 MacroAssembler* masm, int count, BailoutType type); | 424 MacroAssembler* masm, int count, BailoutType type); |
| 445 | 425 |
| 446 // Weak handle callback for deoptimizing code objects. | 426 // Marks all the code in the given context for deoptimization. |
| 447 static void HandleWeakDeoptimizedCode(v8::Isolate* isolate, | 427 static void MarkAllCodeForContext(Context* native_context); |
| 448 v8::Persistent<v8::Value>* obj, | |
| 449 void* data); | |
| 450 | 428 |
| 451 // Deoptimize the given code and add to appropriate deoptimization lists. | 429 // Visit all the known optimized functions in a given context. |
| 452 static void DeoptimizeCode(Isolate* isolate, Code* code); | 430 static void VisitAllOptimizedFunctionsForContext( |
| 431 Context* context, OptimizedFunctionVisitor* visitor); |
| 432 |
| 433 // Deoptimizes all code marked in the given context. |
| 434 static void DeoptimizeMarkedCodeForContext(Context* native_context); |
| 453 | 435 |
| 454 // Patch the given code so that it will deoptimize itself. | 436 // Patch the given code so that it will deoptimize itself. |
| 455 static void PatchCodeForDeoptimization(Isolate* isolate, Code* code); | 437 static void PatchCodeForDeoptimization(Isolate* isolate, Code* code); |
| 456 | 438 |
| 439 // Searches the list of known deoptimizing code for a Code object |
| 440 // containing the given address (which is supposedly faster than |
| 441 // searching all code objects). |
| 442 Code* FindDeoptimizingCode(Address addr); |
| 443 |
| 457 // Fill the input from from a JavaScript frame. This is used when | 444 // Fill the input from from a JavaScript frame. This is used when |
| 458 // the debugger needs to inspect an optimized frame. For normal | 445 // the debugger needs to inspect an optimized frame. For normal |
| 459 // deoptimizations the input frame is filled in generated code. | 446 // deoptimizations the input frame is filled in generated code. |
| 460 void FillInputFrame(Address tos, JavaScriptFrame* frame); | 447 void FillInputFrame(Address tos, JavaScriptFrame* frame); |
| 461 | 448 |
| 462 // Fill the given output frame's registers to contain the failure handler | 449 // Fill the given output frame's registers to contain the failure handler |
| 463 // address and the number of parameters for a stub failure trampoline. | 450 // address and the number of parameters for a stub failure trampoline. |
| 464 void SetPlatformCompiledStubRegisters(FrameDescription* output_frame, | 451 void SetPlatformCompiledStubRegisters(FrameDescription* output_frame, |
| 465 CodeStubInterfaceDescriptor* desc); | 452 CodeStubInterfaceDescriptor* desc); |
| 466 | 453 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 | 495 |
| 509 #ifdef DEBUG | 496 #ifdef DEBUG |
| 510 DisallowHeapAllocation* disallow_heap_allocation_; | 497 DisallowHeapAllocation* disallow_heap_allocation_; |
| 511 #endif // DEBUG | 498 #endif // DEBUG |
| 512 | 499 |
| 513 bool trace_; | 500 bool trace_; |
| 514 | 501 |
| 515 static const int table_entry_size_; | 502 static const int table_entry_size_; |
| 516 | 503 |
| 517 friend class FrameDescription; | 504 friend class FrameDescription; |
| 518 friend class DeoptimizingCodeListNode; | |
| 519 friend class DeoptimizedFrameInfo; | 505 friend class DeoptimizedFrameInfo; |
| 520 }; | 506 }; |
| 521 | 507 |
| 522 | 508 |
| 523 class FrameDescription { | 509 class FrameDescription { |
| 524 public: | 510 public: |
| 525 FrameDescription(uint32_t frame_size, | 511 FrameDescription(uint32_t frame_size, |
| 526 JSFunction* function); | 512 JSFunction* function); |
| 527 | 513 |
| 528 void* operator new(size_t size, uint32_t frame_size) { | 514 void* operator new(size_t size, uint32_t frame_size) { |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 682 | 668 |
| 683 class DeoptimizerData { | 669 class DeoptimizerData { |
| 684 public: | 670 public: |
| 685 explicit DeoptimizerData(MemoryAllocator* allocator); | 671 explicit DeoptimizerData(MemoryAllocator* allocator); |
| 686 ~DeoptimizerData(); | 672 ~DeoptimizerData(); |
| 687 | 673 |
| 688 #ifdef ENABLE_DEBUGGER_SUPPORT | 674 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 689 void Iterate(ObjectVisitor* v); | 675 void Iterate(ObjectVisitor* v); |
| 690 #endif | 676 #endif |
| 691 | 677 |
| 692 Code* FindDeoptimizingCode(Address addr); | |
| 693 void RemoveDeoptimizingCode(Code* code); | |
| 694 | |
| 695 private: | 678 private: |
| 696 MemoryAllocator* allocator_; | 679 MemoryAllocator* allocator_; |
| 697 int deopt_entry_code_entries_[Deoptimizer::kBailoutTypesWithCodeEntry]; | 680 int deopt_entry_code_entries_[Deoptimizer::kBailoutTypesWithCodeEntry]; |
| 698 MemoryChunk* deopt_entry_code_[Deoptimizer::kBailoutTypesWithCodeEntry]; | 681 MemoryChunk* deopt_entry_code_[Deoptimizer::kBailoutTypesWithCodeEntry]; |
| 699 Deoptimizer* current_; | |
| 700 | 682 |
| 701 #ifdef ENABLE_DEBUGGER_SUPPORT | 683 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 702 DeoptimizedFrameInfo* deoptimized_frame_info_; | 684 DeoptimizedFrameInfo* deoptimized_frame_info_; |
| 703 #endif | 685 #endif |
| 704 | 686 |
| 705 // List of deoptimized code which still have references from active stack | 687 Deoptimizer* current_; |
| 706 // frames. These code objects are needed by the deoptimizer when deoptimizing | |
| 707 // a frame for which the code object for the function function has been | |
| 708 // changed from the code present when deoptimizing was done. | |
| 709 DeoptimizingCodeListNode* deoptimizing_code_list_; | |
| 710 | 688 |
| 711 friend class Deoptimizer; | 689 friend class Deoptimizer; |
| 712 | 690 |
| 713 DISALLOW_COPY_AND_ASSIGN(DeoptimizerData); | 691 DISALLOW_COPY_AND_ASSIGN(DeoptimizerData); |
| 714 }; | 692 }; |
| 715 | 693 |
| 716 | 694 |
| 717 class TranslationBuffer BASE_EMBEDDED { | 695 class TranslationBuffer BASE_EMBEDDED { |
| 718 public: | 696 public: |
| 719 explicit TranslationBuffer(Zone* zone) : contents_(256, zone) { } | 697 explicit TranslationBuffer(Zone* zone) : contents_(256, zone) { } |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 // A literal id which refers to the JSFunction itself. | 795 // A literal id which refers to the JSFunction itself. |
| 818 static const int kSelfLiteralId = -239; | 796 static const int kSelfLiteralId = -239; |
| 819 | 797 |
| 820 private: | 798 private: |
| 821 TranslationBuffer* buffer_; | 799 TranslationBuffer* buffer_; |
| 822 int index_; | 800 int index_; |
| 823 Zone* zone_; | 801 Zone* zone_; |
| 824 }; | 802 }; |
| 825 | 803 |
| 826 | 804 |
| 827 // Linked list holding deoptimizing code objects. The deoptimizing code objects | |
| 828 // are kept as weak handles until they are no longer activated on the stack. | |
| 829 class DeoptimizingCodeListNode : public Malloced { | |
| 830 public: | |
| 831 explicit DeoptimizingCodeListNode(Code* code); | |
| 832 ~DeoptimizingCodeListNode(); | |
| 833 | |
| 834 DeoptimizingCodeListNode* next() const { return next_; } | |
| 835 void set_next(DeoptimizingCodeListNode* next) { next_ = next; } | |
| 836 Handle<Code> code() const { return code_; } | |
| 837 | |
| 838 private: | |
| 839 // Global (weak) handle to the deoptimizing code object. | |
| 840 Handle<Code> code_; | |
| 841 | |
| 842 // Next pointer for linked list. | |
| 843 DeoptimizingCodeListNode* next_; | |
| 844 }; | |
| 845 | |
| 846 | |
| 847 class SlotRef BASE_EMBEDDED { | 805 class SlotRef BASE_EMBEDDED { |
| 848 public: | 806 public: |
| 849 enum SlotRepresentation { | 807 enum SlotRepresentation { |
| 850 UNKNOWN, | 808 UNKNOWN, |
| 851 TAGGED, | 809 TAGGED, |
| 852 INT32, | 810 INT32, |
| 853 UINT32, | 811 UINT32, |
| 854 DOUBLE, | 812 DOUBLE, |
| 855 LITERAL | 813 LITERAL |
| 856 }; | 814 }; |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1005 Object** expression_stack_; | 963 Object** expression_stack_; |
| 1006 int source_position_; | 964 int source_position_; |
| 1007 | 965 |
| 1008 friend class Deoptimizer; | 966 friend class Deoptimizer; |
| 1009 }; | 967 }; |
| 1010 #endif | 968 #endif |
| 1011 | 969 |
| 1012 } } // namespace v8::internal | 970 } } // namespace v8::internal |
| 1013 | 971 |
| 1014 #endif // V8_DEOPTIMIZER_H_ | 972 #endif // V8_DEOPTIMIZER_H_ |
| OLD | NEW |