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