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

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: Removed test code 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
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 void MaterializeHeapNumbersForDebuggerInspectableFrame(
fschneider 2011/06/29 10:47:35 Maybe add #ifdef ENABLE_DEBUGGER_SUPPORT here t
Søren Thygesen Gjesse 2011/06/29 12:42:10 Done.
196 Address top, intptr_t size, DeoptimizedFrameInfo* info);
174 197
175 static void ComputeOutputFrames(Deoptimizer* deoptimizer); 198 static void ComputeOutputFrames(Deoptimizer* deoptimizer);
176 199
177 static Address GetDeoptimizationEntry(int id, BailoutType type); 200 static Address GetDeoptimizationEntry(int id, BailoutType type);
178 static int GetDeoptimizationId(Address addr, BailoutType type); 201 static int GetDeoptimizationId(Address addr, BailoutType type);
179 static int GetOutputInfo(DeoptimizationOutputData* data, 202 static int GetOutputInfo(DeoptimizationOutputData* data,
180 unsigned node_id, 203 unsigned node_id,
181 SharedFunctionInfo* shared); 204 SharedFunctionInfo* shared);
182 205
183 // Code generation support. 206 // Code generation support.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 }; 249 };
227 250
228 private: 251 private:
229 static const int kNumberOfEntries = 4096; 252 static const int kNumberOfEntries = 4096;
230 253
231 Deoptimizer(Isolate* isolate, 254 Deoptimizer(Isolate* isolate,
232 JSFunction* function, 255 JSFunction* function,
233 BailoutType type, 256 BailoutType type,
234 unsigned bailout_id, 257 unsigned bailout_id,
235 Address from, 258 Address from,
236 int fp_to_sp_delta); 259 int fp_to_sp_delta,
260 Code* optimized_code);
237 void DeleteFrameDescriptions(); 261 void DeleteFrameDescriptions();
238 262
239 void DoComputeOutputFrames(); 263 void DoComputeOutputFrames();
240 void DoComputeOsrOutputFrame(); 264 void DoComputeOsrOutputFrame();
241 void DoComputeFrame(TranslationIterator* iterator, int frame_index); 265 void DoComputeFrame(TranslationIterator* iterator, int frame_index);
242 void DoTranslateCommand(TranslationIterator* iterator, 266 void DoTranslateCommand(TranslationIterator* iterator,
243 int frame_index, 267 int frame_index,
244 unsigned output_offset); 268 unsigned output_offset);
245 // Translate a command for OSR. Updates the input offset to be used for 269 // 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 270 // the next command. Returns false if translation of the command failed
(...skipping 15 matching lines...) Expand all
262 static LargeObjectChunk* CreateCode(BailoutType type); 286 static LargeObjectChunk* CreateCode(BailoutType type);
263 static void GenerateDeoptimizationEntries( 287 static void GenerateDeoptimizationEntries(
264 MacroAssembler* masm, int count, BailoutType type); 288 MacroAssembler* masm, int count, BailoutType type);
265 289
266 // Weak handle callback for deoptimizing code objects. 290 // Weak handle callback for deoptimizing code objects.
267 static void HandleWeakDeoptimizedCode( 291 static void HandleWeakDeoptimizedCode(
268 v8::Persistent<v8::Value> obj, void* data); 292 v8::Persistent<v8::Value> obj, void* data);
269 static Code* FindDeoptimizingCodeFromAddress(Address addr); 293 static Code* FindDeoptimizingCodeFromAddress(Address addr);
270 static void RemoveDeoptimizingCode(Code* code); 294 static void RemoveDeoptimizingCode(Code* code);
271 295
296 // Fill the input from from a JavaScript frame. This is used when
297 // the debugger needs to inspect an optimized frame. For normal
298 // deoptimizations the input frame is filled in generated code.
299 void FillInputFrame(Address tos, JavaScriptFrame* frame);
300
272 Isolate* isolate_; 301 Isolate* isolate_;
273 JSFunction* function_; 302 JSFunction* function_;
274 Code* optimized_code_; 303 Code* optimized_code_;
275 unsigned bailout_id_; 304 unsigned bailout_id_;
276 BailoutType bailout_type_; 305 BailoutType bailout_type_;
277 Address from_; 306 Address from_;
278 int fp_to_sp_delta_; 307 int fp_to_sp_delta_;
279 308
280 // Input frame description. 309 // Input frame description.
281 FrameDescription* input_; 310 FrameDescription* input_;
282 // Number of output frames. 311 // Number of output frames.
283 int output_count_; 312 int output_count_;
284 // Array of output frame descriptions. 313 // Array of output frame descriptions.
285 FrameDescription** output_; 314 FrameDescription** output_;
286 315
287 List<HeapNumberMaterializationDescriptor> deferred_heap_numbers_; 316 List<HeapNumberMaterializationDescriptor> deferred_heap_numbers_;
288 317
289 static int table_entry_size_; 318 static int table_entry_size_;
290 319
291 friend class FrameDescription; 320 friend class FrameDescription;
292 friend class DeoptimizingCodeListNode; 321 friend class DeoptimizingCodeListNode;
322 friend class DeoptimizedFrameInfo;
293 }; 323 };
294 324
295 325
296 class FrameDescription { 326 class FrameDescription {
297 public: 327 public:
298 FrameDescription(uint32_t frame_size, 328 FrameDescription(uint32_t frame_size,
299 JSFunction* function); 329 JSFunction* function);
300 330
301 void* operator new(size_t size, uint32_t frame_size) { 331 void* operator new(size_t size, uint32_t frame_size) {
302 // Subtracts kPointerSize, as the member frame_content_ already supplies 332 // 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; } 383 void SetPc(intptr_t pc) { pc_ = pc; }
354 384
355 intptr_t GetFp() const { return fp_; } 385 intptr_t GetFp() const { return fp_; }
356 void SetFp(intptr_t fp) { fp_ = fp; } 386 void SetFp(intptr_t fp) { fp_ = fp; }
357 387
358 Smi* GetState() const { return state_; } 388 Smi* GetState() const { return state_; }
359 void SetState(Smi* state) { state_ = state; } 389 void SetState(Smi* state) { state_ = state; }
360 390
361 void SetContinuation(intptr_t pc) { continuation_ = pc; } 391 void SetContinuation(intptr_t pc) { continuation_ = pc; }
362 392
393 #ifdef DEBUG
394 Code::Kind GetKind() const { return kind_; }
395 void SetKind(Code::Kind kind) { kind_ = kind; }
396 #endif
397
398 // Get the expression stack height for a unoptimized frame.
399 unsigned GetExpressionCount(Deoptimizer* deoptimizer);
400
401 // Get the expression stack value for an unoptimized frame.
402 Object* GetExpression(Deoptimizer* deoptimizer, int index);
403
363 static int registers_offset() { 404 static int registers_offset() {
364 return OFFSET_OF(FrameDescription, registers_); 405 return OFFSET_OF(FrameDescription, registers_);
365 } 406 }
366 407
367 static int double_registers_offset() { 408 static int double_registers_offset() {
368 return OFFSET_OF(FrameDescription, double_registers_); 409 return OFFSET_OF(FrameDescription, double_registers_);
369 } 410 }
370 411
371 static int frame_size_offset() { 412 static int frame_size_offset() {
372 return OFFSET_OF(FrameDescription, frame_size_); 413 return OFFSET_OF(FrameDescription, frame_size_);
(...skipping 19 matching lines...) Expand all
392 static const uint32_t kZapUint32 = 0xbeeddead; 433 static const uint32_t kZapUint32 = 0xbeeddead;
393 434
394 uintptr_t frame_size_; // Number of bytes. 435 uintptr_t frame_size_; // Number of bytes.
395 JSFunction* function_; 436 JSFunction* function_;
396 intptr_t registers_[Register::kNumRegisters]; 437 intptr_t registers_[Register::kNumRegisters];
397 double double_registers_[DoubleRegister::kNumAllocatableRegisters]; 438 double double_registers_[DoubleRegister::kNumAllocatableRegisters];
398 intptr_t top_; 439 intptr_t top_;
399 intptr_t pc_; 440 intptr_t pc_;
400 intptr_t fp_; 441 intptr_t fp_;
401 Smi* state_; 442 Smi* state_;
443 #ifdef DEBUG
444 Code::Kind kind_;
445 #endif
402 446
403 // Continuation is the PC where the execution continues after 447 // Continuation is the PC where the execution continues after
404 // deoptimizing. 448 // deoptimizing.
405 intptr_t continuation_; 449 intptr_t continuation_;
406 450
407 // This must be at the end of the object as the object is allocated larger 451 // 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. 452 // than it's definition indicate to extend this array.
409 intptr_t frame_content_[1]; 453 intptr_t frame_content_[1];
410 454
411 intptr_t* GetFrameSlotPointer(unsigned offset) { 455 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); 634 return frame->fp() + offset - ((slot_index + 1) * kPointerSize);
591 } 635 }
592 } 636 }
593 637
594 static SlotRef ComputeSlotForNextArgument(TranslationIterator* iterator, 638 static SlotRef ComputeSlotForNextArgument(TranslationIterator* iterator,
595 DeoptimizationInputData* data, 639 DeoptimizationInputData* data,
596 JavaScriptFrame* frame); 640 JavaScriptFrame* frame);
597 }; 641 };
598 642
599 643
644 #ifdef ENABLE_DEBUGGER_SUPPORT
645 // Class used to represent an unoptimized frame when the debugger
646 // needs to inspect a frame that is part of an optimized frame. The
647 // internally used FrameDescription objects are not GC safe so for use
648 // by the debugger frame information is copied to an object of this type.
649 class DeoptimizedFrameInfo : public Malloced {
650 public:
651 DeoptimizedFrameInfo(Deoptimizer* deoptimizer, int frame_index);
652 virtual ~DeoptimizedFrameInfo();
653
654 // GC support.
655 void Iterate(ObjectVisitor* v);
656
657 // Return the height of the expression stack.
658 int expression_count() { return expression_count_; }
659
660 // Get an expression from the expression stack.
661 Object* GetExpression(int index) {
662 ASSERT(0 <= index && index < expression_count());
663 return expression_stack_[index];
664 }
665
666 private:
667 // Set an expression on the expression stack.
668 void SetExpression(int index, Object* obj) {
669 ASSERT(0 <= index && index < expression_count());
670 expression_stack_[index] = obj;
671 }
672
673 int expression_count_;
674 Object** expression_stack_;
675
676 friend class Deoptimizer;
677 };
678 #endif
679
600 } } // namespace v8::internal 680 } } // namespace v8::internal
601 681
602 #endif // V8_DEOPTIMIZER_H_ 682 #endif // V8_DEOPTIMIZER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698