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 |