Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/deoptimizer.h

Issue 7230045: Support debugger inspection of locals in optimized frames (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/compiler.cc ('k') | src/deoptimizer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 23 matching lines...) Expand all
34 #include "macro-assembler.h" 34 #include "macro-assembler.h"
35 #include "zone-inl.h" 35 #include "zone-inl.h"
36 36
37 37
38 namespace v8 { 38 namespace v8 {
39 namespace internal { 39 namespace internal {
40 40
41 class FrameDescription; 41 class FrameDescription;
42 class TranslationIterator; 42 class TranslationIterator;
43 class DeoptimizingCodeListNode; 43 class DeoptimizingCodeListNode;
44 44 class DeoptimizedFrameInfo;
45 45
46 class HeapNumberMaterializationDescriptor BASE_EMBEDDED { 46 class HeapNumberMaterializationDescriptor BASE_EMBEDDED {
47 public: 47 public:
48 HeapNumberMaterializationDescriptor(Address slot_address, double val) 48 HeapNumberMaterializationDescriptor(Address slot_address, double val)
49 : slot_address_(slot_address), val_(val) { } 49 : slot_address_(slot_address), val_(val) { }
50 50
51 Address slot_address() const { return slot_address_; } 51 Address slot_address() const { return slot_address_; }
52 double value() const { return val_; } 52 double value() const { return val_; }
53 53
54 private: 54 private:
(...skipping 19 matching lines...) Expand all
74 74
75 75
76 class Deoptimizer; 76 class Deoptimizer;
77 77
78 78
79 class DeoptimizerData { 79 class DeoptimizerData {
80 public: 80 public:
81 DeoptimizerData(); 81 DeoptimizerData();
82 ~DeoptimizerData(); 82 ~DeoptimizerData();
83 83
84 #ifdef ENABLE_DEBUGGER_SUPPORT
85 void Iterate(ObjectVisitor* v);
86 #endif
87
84 private: 88 private:
85 LargeObjectChunk* eager_deoptimization_entry_code_; 89 LargeObjectChunk* eager_deoptimization_entry_code_;
86 LargeObjectChunk* lazy_deoptimization_entry_code_; 90 LargeObjectChunk* lazy_deoptimization_entry_code_;
87 Deoptimizer* current_; 91 Deoptimizer* current_;
88 92
93 #ifdef ENABLE_DEBUGGER_SUPPORT
94 DeoptimizedFrameInfo* deoptimized_frame_info_;
95 #endif
96
89 // List of deoptimized code which still have references from active stack 97 // List of deoptimized code which still have references from active stack
90 // frames. These code objects are needed by the deoptimizer when deoptimizing 98 // frames. These code objects are needed by the deoptimizer when deoptimizing
91 // a frame for which the code object for the function function has been 99 // a frame for which the code object for the function function has been
92 // changed from the code present when deoptimizing was done. 100 // changed from the code present when deoptimizing was done.
93 DeoptimizingCodeListNode* deoptimizing_code_list_; 101 DeoptimizingCodeListNode* deoptimizing_code_list_;
94 102
95 friend class Deoptimizer; 103 friend class Deoptimizer;
96 104
97 DISALLOW_COPY_AND_ASSIGN(DeoptimizerData); 105 DISALLOW_COPY_AND_ASSIGN(DeoptimizerData);
98 }; 106 };
99 107
100 108
101 class Deoptimizer : public Malloced { 109 class Deoptimizer : public Malloced {
102 public: 110 public:
103 enum BailoutType { 111 enum BailoutType {
104 EAGER, 112 EAGER,
105 LAZY, 113 LAZY,
106 OSR 114 OSR,
115 // This last bailout type is not really a bailout, but used by the
116 // debugger to deoptimize stack frames to allow inspection.
117 DEBUGGER
107 }; 118 };
108 119
109 int output_count() const { return output_count_; } 120 int output_count() const { return output_count_; }
110 121
111 static Deoptimizer* New(JSFunction* function, 122 static Deoptimizer* New(JSFunction* function,
112 BailoutType type, 123 BailoutType type,
113 unsigned bailout_id, 124 unsigned bailout_id,
114 Address from, 125 Address from,
115 int fp_to_sp_delta, 126 int fp_to_sp_delta,
116 Isolate* isolate); 127 Isolate* isolate);
117 static Deoptimizer* Grab(Isolate* isolate); 128 static Deoptimizer* Grab(Isolate* isolate);
118 129
130 #ifdef ENABLE_DEBUGGER_SUPPORT
131 // The returned object with information on the optimized frame needs to be
132 // freed before another one can be generated.
133 static DeoptimizedFrameInfo* DebuggerInspectableFrame(JavaScriptFrame* frame,
134 int frame_index,
135 Isolate* isolate);
136 static void DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info,
137 Isolate* isolate);
138 #endif
139
119 // Makes sure that there is enough room in the relocation 140 // Makes sure that there is enough room in the relocation
120 // information of a code object to perform lazy deoptimization 141 // information of a code object to perform lazy deoptimization
121 // patching. If there is not enough room a new relocation 142 // patching. If there is not enough room a new relocation
122 // information object is allocated and comments are added until it 143 // information object is allocated and comments are added until it
123 // is big enough. 144 // is big enough.
124 static void EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code); 145 static void EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code);
125 146
126 // Deoptimize the function now. Its current optimized code will never be run 147 // Deoptimize the function now. Its current optimized code will never be run
127 // again and any activations of the optimized code will get deoptimized when 148 // again and any activations of the optimized code will get deoptimized when
128 // execution returns. 149 // execution returns.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 185
165 // Change all patched stack guard checks in the unoptimized code 186 // Change all patched stack guard checks in the unoptimized code
166 // back to a normal stack guard check. 187 // back to a normal stack guard check.
167 static void RevertStackCheckCodeAt(Address pc_after, 188 static void RevertStackCheckCodeAt(Address pc_after,
168 Code* check_code, 189 Code* check_code,
169 Code* replacement_code); 190 Code* replacement_code);
170 191
171 ~Deoptimizer(); 192 ~Deoptimizer();
172 193
173 void MaterializeHeapNumbers(); 194 void MaterializeHeapNumbers();
195 #ifdef ENABLE_DEBUGGER_SUPPORT
196 void MaterializeHeapNumbersForDebuggerInspectableFrame(
197 Address top, intptr_t size, DeoptimizedFrameInfo* info);
198 #endif
174 199
175 static void ComputeOutputFrames(Deoptimizer* deoptimizer); 200 static void ComputeOutputFrames(Deoptimizer* deoptimizer);
176 201
177 static Address GetDeoptimizationEntry(int id, BailoutType type); 202 static Address GetDeoptimizationEntry(int id, BailoutType type);
178 static int GetDeoptimizationId(Address addr, BailoutType type); 203 static int GetDeoptimizationId(Address addr, BailoutType type);
179 static int GetOutputInfo(DeoptimizationOutputData* data, 204 static int GetOutputInfo(DeoptimizationOutputData* data,
180 unsigned node_id, 205 unsigned node_id,
181 SharedFunctionInfo* shared); 206 SharedFunctionInfo* shared);
182 207
183 // Code generation support. 208 // Code generation support.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 }; 251 };
227 252
228 private: 253 private:
229 static const int kNumberOfEntries = 4096; 254 static const int kNumberOfEntries = 4096;
230 255
231 Deoptimizer(Isolate* isolate, 256 Deoptimizer(Isolate* isolate,
232 JSFunction* function, 257 JSFunction* function,
233 BailoutType type, 258 BailoutType type,
234 unsigned bailout_id, 259 unsigned bailout_id,
235 Address from, 260 Address from,
236 int fp_to_sp_delta); 261 int fp_to_sp_delta,
262 Code* optimized_code);
237 void DeleteFrameDescriptions(); 263 void DeleteFrameDescriptions();
238 264
239 void DoComputeOutputFrames(); 265 void DoComputeOutputFrames();
240 void DoComputeOsrOutputFrame(); 266 void DoComputeOsrOutputFrame();
241 void DoComputeFrame(TranslationIterator* iterator, int frame_index); 267 void DoComputeFrame(TranslationIterator* iterator, int frame_index);
242 void DoTranslateCommand(TranslationIterator* iterator, 268 void DoTranslateCommand(TranslationIterator* iterator,
243 int frame_index, 269 int frame_index,
244 unsigned output_offset); 270 unsigned output_offset);
245 // Translate a command for OSR. Updates the input offset to be used for 271 // Translate a command for OSR. Updates the input offset to be used for
246 // the next command. Returns false if translation of the command failed 272 // the next command. Returns false if translation of the command failed
(...skipping 15 matching lines...) Expand all
262 static LargeObjectChunk* CreateCode(BailoutType type); 288 static LargeObjectChunk* CreateCode(BailoutType type);
263 static void GenerateDeoptimizationEntries( 289 static void GenerateDeoptimizationEntries(
264 MacroAssembler* masm, int count, BailoutType type); 290 MacroAssembler* masm, int count, BailoutType type);
265 291
266 // Weak handle callback for deoptimizing code objects. 292 // Weak handle callback for deoptimizing code objects.
267 static void HandleWeakDeoptimizedCode( 293 static void HandleWeakDeoptimizedCode(
268 v8::Persistent<v8::Value> obj, void* data); 294 v8::Persistent<v8::Value> obj, void* data);
269 static Code* FindDeoptimizingCodeFromAddress(Address addr); 295 static Code* FindDeoptimizingCodeFromAddress(Address addr);
270 static void RemoveDeoptimizingCode(Code* code); 296 static void RemoveDeoptimizingCode(Code* code);
271 297
298 // Fill the input from from a JavaScript frame. This is used when
299 // the debugger needs to inspect an optimized frame. For normal
300 // deoptimizations the input frame is filled in generated code.
301 void FillInputFrame(Address tos, JavaScriptFrame* frame);
302
272 Isolate* isolate_; 303 Isolate* isolate_;
273 JSFunction* function_; 304 JSFunction* function_;
274 Code* optimized_code_; 305 Code* optimized_code_;
275 unsigned bailout_id_; 306 unsigned bailout_id_;
276 BailoutType bailout_type_; 307 BailoutType bailout_type_;
277 Address from_; 308 Address from_;
278 int fp_to_sp_delta_; 309 int fp_to_sp_delta_;
279 310
280 // Input frame description. 311 // Input frame description.
281 FrameDescription* input_; 312 FrameDescription* input_;
282 // Number of output frames. 313 // Number of output frames.
283 int output_count_; 314 int output_count_;
284 // Array of output frame descriptions. 315 // Array of output frame descriptions.
285 FrameDescription** output_; 316 FrameDescription** output_;
286 317
287 List<HeapNumberMaterializationDescriptor> deferred_heap_numbers_; 318 List<HeapNumberMaterializationDescriptor> deferred_heap_numbers_;
288 319
289 static int table_entry_size_; 320 static int table_entry_size_;
290 321
291 friend class FrameDescription; 322 friend class FrameDescription;
292 friend class DeoptimizingCodeListNode; 323 friend class DeoptimizingCodeListNode;
324 friend class DeoptimizedFrameInfo;
293 }; 325 };
294 326
295 327
296 class FrameDescription { 328 class FrameDescription {
297 public: 329 public:
298 FrameDescription(uint32_t frame_size, 330 FrameDescription(uint32_t frame_size,
299 JSFunction* function); 331 JSFunction* function);
300 332
301 void* operator new(size_t size, uint32_t frame_size) { 333 void* operator new(size_t size, uint32_t frame_size) {
302 // Subtracts kPointerSize, as the member frame_content_ already supplies 334 // Subtracts kPointerSize, as the member frame_content_ already supplies
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 void SetPc(intptr_t pc) { pc_ = pc; } 385 void SetPc(intptr_t pc) { pc_ = pc; }
354 386
355 intptr_t GetFp() const { return fp_; } 387 intptr_t GetFp() const { return fp_; }
356 void SetFp(intptr_t fp) { fp_ = fp; } 388 void SetFp(intptr_t fp) { fp_ = fp; }
357 389
358 Smi* GetState() const { return state_; } 390 Smi* GetState() const { return state_; }
359 void SetState(Smi* state) { state_ = state; } 391 void SetState(Smi* state) { state_ = state; }
360 392
361 void SetContinuation(intptr_t pc) { continuation_ = pc; } 393 void SetContinuation(intptr_t pc) { continuation_ = pc; }
362 394
395 #ifdef DEBUG
396 Code::Kind GetKind() const { return kind_; }
397 void SetKind(Code::Kind kind) { kind_ = kind; }
398 #endif
399
400 // Get the expression stack height for a unoptimized frame.
401 unsigned GetExpressionCount(Deoptimizer* deoptimizer);
402
403 // Get the expression stack value for an unoptimized frame.
404 Object* GetExpression(Deoptimizer* deoptimizer, int index);
405
363 static int registers_offset() { 406 static int registers_offset() {
364 return OFFSET_OF(FrameDescription, registers_); 407 return OFFSET_OF(FrameDescription, registers_);
365 } 408 }
366 409
367 static int double_registers_offset() { 410 static int double_registers_offset() {
368 return OFFSET_OF(FrameDescription, double_registers_); 411 return OFFSET_OF(FrameDescription, double_registers_);
369 } 412 }
370 413
371 static int frame_size_offset() { 414 static int frame_size_offset() {
372 return OFFSET_OF(FrameDescription, frame_size_); 415 return OFFSET_OF(FrameDescription, frame_size_);
(...skipping 19 matching lines...) Expand all
392 static const uint32_t kZapUint32 = 0xbeeddead; 435 static const uint32_t kZapUint32 = 0xbeeddead;
393 436
394 uintptr_t frame_size_; // Number of bytes. 437 uintptr_t frame_size_; // Number of bytes.
395 JSFunction* function_; 438 JSFunction* function_;
396 intptr_t registers_[Register::kNumRegisters]; 439 intptr_t registers_[Register::kNumRegisters];
397 double double_registers_[DoubleRegister::kNumAllocatableRegisters]; 440 double double_registers_[DoubleRegister::kNumAllocatableRegisters];
398 intptr_t top_; 441 intptr_t top_;
399 intptr_t pc_; 442 intptr_t pc_;
400 intptr_t fp_; 443 intptr_t fp_;
401 Smi* state_; 444 Smi* state_;
445 #ifdef DEBUG
446 Code::Kind kind_;
447 #endif
402 448
403 // Continuation is the PC where the execution continues after 449 // Continuation is the PC where the execution continues after
404 // deoptimizing. 450 // deoptimizing.
405 intptr_t continuation_; 451 intptr_t continuation_;
406 452
407 // This must be at the end of the object as the object is allocated larger 453 // This must be at the end of the object as the object is allocated larger
408 // than it's definition indicate to extend this array. 454 // than it's definition indicate to extend this array.
409 intptr_t frame_content_[1]; 455 intptr_t frame_content_[1];
410 456
411 intptr_t* GetFrameSlotPointer(unsigned offset) { 457 intptr_t* GetFrameSlotPointer(unsigned offset) {
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 return frame->fp() + offset - ((slot_index + 1) * kPointerSize); 636 return frame->fp() + offset - ((slot_index + 1) * kPointerSize);
591 } 637 }
592 } 638 }
593 639
594 static SlotRef ComputeSlotForNextArgument(TranslationIterator* iterator, 640 static SlotRef ComputeSlotForNextArgument(TranslationIterator* iterator,
595 DeoptimizationInputData* data, 641 DeoptimizationInputData* data,
596 JavaScriptFrame* frame); 642 JavaScriptFrame* frame);
597 }; 643 };
598 644
599 645
646 #ifdef ENABLE_DEBUGGER_SUPPORT
647 // Class used to represent an unoptimized frame when the debugger
648 // needs to inspect a frame that is part of an optimized frame. The
649 // internally used FrameDescription objects are not GC safe so for use
650 // by the debugger frame information is copied to an object of this type.
651 class DeoptimizedFrameInfo : public Malloced {
652 public:
653 DeoptimizedFrameInfo(Deoptimizer* deoptimizer, int frame_index);
654 virtual ~DeoptimizedFrameInfo();
655
656 // GC support.
657 void Iterate(ObjectVisitor* v);
658
659 // Return the height of the expression stack.
660 int expression_count() { return expression_count_; }
661
662 // Get an expression from the expression stack.
663 Object* GetExpression(int index) {
664 ASSERT(0 <= index && index < expression_count());
665 return expression_stack_[index];
666 }
667
668 private:
669 // Set an expression on the expression stack.
670 void SetExpression(int index, Object* obj) {
671 ASSERT(0 <= index && index < expression_count());
672 expression_stack_[index] = obj;
673 }
674
675 int expression_count_;
676 Object** expression_stack_;
677
678 friend class Deoptimizer;
679 };
680 #endif
681
600 } } // namespace v8::internal 682 } } // namespace v8::internal
601 683
602 #endif // V8_DEOPTIMIZER_H_ 684 #endif // V8_DEOPTIMIZER_H_
OLDNEW
« no previous file with comments | « src/compiler.cc ('k') | src/deoptimizer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698